Skip to content

Commit 22093c0

Browse files
author
Grégoire Geis
committed
Slightly improved docs and structure of *Value traits
1 parent 897fd3f commit 22093c0

File tree

2 files changed

+76
-4
lines changed

2 files changed

+76
-4
lines changed

src/values/enums.rs

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ 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

@@ -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: AnyValue {
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)