Skip to content

Commit b75c231

Browse files
authored
Merge pull request rust-lang#22 from 6A/master
Made type and value enums clone- and copy-able.
2 parents 322cf13 + db6f82c commit b75c231

File tree

4 files changed

+94
-8
lines changed

4 files changed

+94
-8
lines changed

src/types/enums.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use types::traits::AsTypeRef;
77

88
macro_rules! enum_type_set {
99
($enum_name:ident: $($args:ident),*) => (
10-
#[derive(Debug, EnumAsGetters, EnumIntoGetters, EnumIsA, PartialEq, Eq)]
10+
#[derive(Debug, EnumAsGetters, EnumIntoGetters, EnumIsA, PartialEq, Eq, Clone, Copy)]
1111
pub enum $enum_name {
1212
$(
1313
$args($args),

src/types/traits.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,27 @@ pub trait AsTypeRef {
1414

1515
macro_rules! trait_type_set {
1616
($trait_name:ident: $($args:ident),*) => (
17-
pub trait $trait_name: AsTypeRef + Debug {}
18-
1917
$(
2018
impl $trait_name for $args {}
2119
)*
2220
);
2321
}
2422

23+
/// Represents any LLVM type.
24+
pub trait AnyType: AsTypeRef + Debug {
25+
/// Returns an `AnyTypeEnum` that represents the current type.
26+
fn as_any_type_enum(&self) -> AnyTypeEnum {
27+
AnyTypeEnum::new(self.as_type_ref())
28+
}
29+
}
30+
31+
/// Represents a basic LLVM type, that may be used in functions and struct declarations.
32+
pub trait BasicType: AnyType {
33+
/// Returns a `BasicTypeEnum` that represents the current type.
34+
fn as_basic_type_enum(&self) -> BasicTypeEnum {
35+
BasicTypeEnum::new(self.as_type_ref())
36+
}
37+
}
38+
2539
trait_type_set! {AnyType: AnyTypeEnum, BasicTypeEnum, IntType, FunctionType, FloatType, PointerType, StructType, ArrayType, VoidType, VectorType}
2640
trait_type_set! {BasicType: BasicTypeEnum, IntType, FloatType, PointerType, StructType, ArrayType, VectorType}

src/values/enums.rs

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ use llvm_sys::core::{LLVMTypeOf, LLVMGetTypeKind};
22
use llvm_sys::LLVMTypeKind;
33
use llvm_sys::prelude::LLVMValueRef;
44

5-
use types::BasicTypeEnum;
5+
use types::{AnyTypeEnum, BasicTypeEnum};
66
use values::traits::AsValueRef;
77
use values::{IntValue, FunctionValue, PointerValue, VectorValue, ArrayValue, StructValue, FloatValue, PhiValue, InstructionValue, MetadataValue};
88

99
macro_rules! enum_value_set {
1010
($enum_name:ident: $($args:ident),*) => (
11-
#[derive(Debug, EnumAsGetters, EnumIntoGetters, EnumIsA)]
11+
#[derive(Debug, EnumAsGetters, EnumIntoGetters, EnumIsA, Clone, Copy)]
1212
pub enum $enum_name {
1313
$(
1414
$args($args),
@@ -43,6 +43,40 @@ enum_value_set! {AnyValueEnum: ArrayValue, IntValue, FloatValue, PhiValue, Funct
4343
enum_value_set! {BasicValueEnum: ArrayValue, IntValue, FloatValue, PointerValue, StructValue, VectorValue}
4444
enum_value_set! {BasicMetadataValueEnum: ArrayValue, IntValue, FloatValue, PointerValue, StructValue, VectorValue, MetadataValue}
4545

46+
impl AnyValueEnum {
47+
pub(crate) fn new(value: LLVMValueRef) -> AnyValueEnum {
48+
let type_kind = unsafe {
49+
LLVMGetTypeKind(LLVMTypeOf(value))
50+
};
51+
52+
match type_kind {
53+
LLVMTypeKind::LLVMFloatTypeKind |
54+
LLVMTypeKind::LLVMFP128TypeKind |
55+
LLVMTypeKind::LLVMDoubleTypeKind |
56+
LLVMTypeKind::LLVMHalfTypeKind |
57+
LLVMTypeKind::LLVMX86_FP80TypeKind |
58+
LLVMTypeKind::LLVMPPC_FP128TypeKind => AnyValueEnum::FloatValue(FloatValue::new(value)),
59+
LLVMTypeKind::LLVMIntegerTypeKind => AnyValueEnum::IntValue(IntValue::new(value)),
60+
LLVMTypeKind::LLVMStructTypeKind => AnyValueEnum::StructValue(StructValue::new(value)),
61+
LLVMTypeKind::LLVMPointerTypeKind => AnyValueEnum::PointerValue(PointerValue::new(value)),
62+
LLVMTypeKind::LLVMArrayTypeKind => AnyValueEnum::ArrayValue(ArrayValue::new(value)),
63+
LLVMTypeKind::LLVMVectorTypeKind => AnyValueEnum::VectorValue(VectorValue::new(value)),
64+
LLVMTypeKind::LLVMFunctionTypeKind => AnyValueEnum::FunctionValue(FunctionValue::new(value).unwrap()),
65+
LLVMTypeKind::LLVMVoidTypeKind => panic!("Void values shouldn't exist."),
66+
LLVMTypeKind::LLVMMetadataTypeKind => panic!("Metadata values are not supported as AnyValue's."),
67+
_ => panic!("The given type is not supported.")
68+
}
69+
}
70+
71+
pub fn get_type(&self) -> AnyTypeEnum {
72+
let type_ = unsafe {
73+
LLVMTypeOf(self.as_value_ref())
74+
};
75+
76+
AnyTypeEnum::new(type_)
77+
}
78+
}
79+
4680
impl BasicValueEnum {
4781
pub(crate) fn new(value: LLVMValueRef) -> BasicValueEnum {
4882
let type_kind = unsafe {
@@ -61,7 +95,7 @@ impl BasicValueEnum {
6195
LLVMTypeKind::LLVMPointerTypeKind => BasicValueEnum::PointerValue(PointerValue::new(value)),
6296
LLVMTypeKind::LLVMArrayTypeKind => BasicValueEnum::ArrayValue(ArrayValue::new(value)),
6397
LLVMTypeKind::LLVMVectorTypeKind => BasicValueEnum::VectorValue(VectorValue::new(value)),
64-
_ => unreachable!("Unsupported type"),
98+
_ => unreachable!("The given type is not a basic type."),
6599
}
66100
}
67101

@@ -85,6 +119,20 @@ impl BasicValueEnum {
85119
}
86120
}
87121

122+
impl AggregateValueEnum {
123+
pub(crate) fn new(value: LLVMValueRef) -> AggregateValueEnum {
124+
let type_kind = unsafe {
125+
LLVMGetTypeKind(LLVMTypeOf(value))
126+
};
127+
128+
match type_kind {
129+
LLVMTypeKind::LLVMArrayTypeKind => AggregateValueEnum::ArrayValue(ArrayValue::new(value)),
130+
LLVMTypeKind::LLVMStructTypeKind => AggregateValueEnum::StructValue(StructValue::new(value)),
131+
_ => unreachable!("The given type is not an aggregate type."),
132+
}
133+
}
134+
}
135+
88136
impl BasicMetadataValueEnum {
89137
pub(crate) fn new(value: LLVMValueRef) -> BasicMetadataValueEnum {
90138
let type_kind = unsafe {

src/values/traits.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use llvm_sys::prelude::LLVMValueRef;
22

3+
use std::fmt::Debug;
4+
35
use values::{ArrayValue, AggregateValueEnum, StructValue, BasicValueEnum, AnyValueEnum, IntValue, FloatValue, PointerValue, PhiValue, VectorValue, FunctionValue, InstructionValue};
46

57
// This is an ugly privacy hack so that Type can stay private to this module
@@ -11,8 +13,6 @@ pub trait AsValueRef {
1113

1214
macro_rules! trait_value_set {
1315
($trait_name:ident: $($args:ident),*) => (
14-
pub trait $trait_name: AsValueRef {}
15-
1616
$(
1717
impl $trait_name for $args {}
1818
)*
@@ -22,6 +22,30 @@ macro_rules! trait_value_set {
2222
);
2323
}
2424

25+
/// Represents an aggregate value, built on top of other values.
26+
pub trait AggregateValue: BasicValue {
27+
/// Returns an enum containing a typed version of the `AggregateValue`.
28+
fn as_aggregate_value_enum(&self) -> AggregateValueEnum {
29+
AggregateValueEnum::new(self.as_value_ref())
30+
}
31+
}
32+
33+
/// Represents a basic value, which can be used both by itself, or in an `AggregateValue`.
34+
pub trait BasicValue: AnyValue {
35+
/// Returns an enum containing a typed version of the `BasicValue`.
36+
fn as_basic_value_enum(&self) -> BasicValueEnum {
37+
BasicValueEnum::new(self.as_value_ref())
38+
}
39+
}
40+
41+
/// Defines any struct wrapping an LLVM value.
42+
pub trait AnyValue: AsValueRef + Debug {
43+
/// Returns an enum containing a typed version of `AnyValue`.
44+
fn as_any_value_enum(&self) -> AnyValueEnum {
45+
AnyValueEnum::new(self.as_value_ref())
46+
}
47+
}
48+
2549
trait_value_set! {AggregateValue: ArrayValue, AggregateValueEnum, StructValue}
2650
trait_value_set! {AnyValue: AnyValueEnum, BasicValueEnum, AggregateValueEnum, ArrayValue, IntValue, FloatValue, PhiValue, PointerValue, FunctionValue, StructValue, VectorValue, InstructionValue}
2751
trait_value_set! {BasicValue: ArrayValue, BasicValueEnum, AggregateValueEnum, IntValue, FloatValue, StructValue, PointerValue, VectorValue}

0 commit comments

Comments
 (0)