@@ -8,7 +8,31 @@ use std::ops::{Deref, Index};
8
8
use block:: BasicBlock ;
9
9
use context:: { Context , GetContext } ;
10
10
use ty:: { FunctionType , Type } ;
11
- use util:: { self , CastFrom } ;
11
+ use util:: { self , Sub } ;
12
+
13
+ macro_rules! sub {
14
+ ( $this: ty, $name: ident) => (
15
+ sub!{ $this, $name, :: Value }
16
+ ) ;
17
+ ( $this: ty, $name: ident, $sup: ty) => (
18
+ unsafe impl Sub <$sup> for $this {
19
+ fn is( value: & $sup) -> bool {
20
+ unsafe {
21
+ !core:: $name( value. into( ) ) . is_null( )
22
+ }
23
+ }
24
+ fn from_super( value: & $sup) -> Option <& $this> {
25
+ unsafe { mem:: transmute( core:: $name( value. into( ) ) ) }
26
+ }
27
+ }
28
+ impl Deref for $this {
29
+ type Target = $sup;
30
+ fn deref( & self ) -> & $sup {
31
+ self . to_super( )
32
+ }
33
+ }
34
+ )
35
+ }
12
36
13
37
/// A typed value that can be used as an operand in instructions.
14
38
pub struct Value ;
@@ -66,12 +90,7 @@ pub enum Predicate {
66
90
/// An argument that is passed to a function.
67
91
pub struct Arg ;
68
92
native_ref ! ( & Arg = LLVMValueRef ) ;
69
- impl Deref for Arg {
70
- type Target = Value ;
71
- fn deref ( & self ) -> & Value {
72
- unsafe { mem:: transmute ( self ) }
73
- }
74
- }
93
+ sub ! { Arg , LLVMIsAArgument }
75
94
impl Arg {
76
95
/// Add the attribute given to this argument.
77
96
pub fn add_attribute ( & self , attr : Attribute ) {
@@ -114,21 +133,7 @@ impl Arg {
114
133
/// A value with global scope (eg: Function, Alias, Global variable)
115
134
pub struct GlobalValue ;
116
135
native_ref ! ( & GlobalValue = LLVMValueRef ) ;
117
- impl Deref for GlobalValue {
118
- type Target = Value ;
119
- fn deref ( & self ) -> & Value {
120
- unsafe { mem:: transmute ( self ) }
121
- }
122
- }
123
- impl CastFrom for GlobalValue {
124
- type From = Value ;
125
- fn cast < ' a > ( val : & ' a Value ) -> Option < & ' a GlobalValue > {
126
- unsafe {
127
- let global = mem:: transmute ( core:: LLVMIsAGlobalValue ( val. into ( ) ) ) ;
128
- util:: ptr_to_null ( global)
129
- }
130
- }
131
- }
136
+ sub ! { GlobalValue , LLVMIsAGlobalValue }
132
137
impl GlobalValue {
133
138
/// Set the linkage type for this global
134
139
pub fn set_linkage ( & self , linkage : Linkage ) {
@@ -154,21 +159,7 @@ impl GlobalValue {
154
159
/// A global variable
155
160
pub struct GlobalVariable ;
156
161
native_ref ! ( & GlobalVariable = LLVMValueRef ) ;
157
- impl Deref for GlobalVariable {
158
- type Target = GlobalValue ;
159
- fn deref ( & self ) -> & GlobalValue {
160
- unsafe { mem:: transmute ( self ) }
161
- }
162
- }
163
- impl CastFrom for GlobalVariable {
164
- type From = Value ;
165
- fn cast < ' a > ( val : & ' a Value ) -> Option < & ' a GlobalVariable > {
166
- unsafe {
167
- let global = mem:: transmute ( core:: LLVMIsAGlobalVariable ( val. into ( ) ) ) ;
168
- util:: ptr_to_null ( global)
169
- }
170
- }
171
- }
162
+ sub ! { GlobalVariable , LLVMIsAGlobalVariable , GlobalValue }
172
163
impl GlobalVariable {
173
164
/// Set the initial value of the global
174
165
pub fn set_initializer ( & self , val : & Value ) {
@@ -200,34 +191,14 @@ impl GlobalVariable {
200
191
/// An alias to another global value.
201
192
pub struct Alias ;
202
193
native_ref ! ( & Alias = LLVMValueRef ) ;
203
- impl Deref for Alias {
204
- type Target = GlobalValue ;
205
- fn deref ( & self ) -> & GlobalValue {
206
- unsafe { mem:: transmute ( self ) }
207
- }
208
- }
209
- impl CastFrom for Alias {
210
- type From = Value ;
211
- fn cast < ' a > ( val : & ' a Value ) -> Option < & ' a Alias > {
212
- unsafe {
213
- let alias = mem:: transmute ( core:: LLVMIsAGlobalAlias ( val. into ( ) ) ) ;
214
- util:: ptr_to_null ( alias)
215
- }
216
- }
217
- }
218
-
194
+ sub ! { Alias , LLVMIsAGlobalAlias , GlobalValue }
219
195
/// A function is a kind of value that can be called and contains blocks of code.
220
196
///
221
197
/// To get the value of each argument to a function, you can use the index operator.
222
198
/// For example, `&func[0]` is the value that represents the first argument to the function.
223
199
pub struct Function ;
224
200
native_ref ! ( & Function = LLVMValueRef ) ;
225
- impl Deref for Function {
226
- type Target = GlobalValue ;
227
- fn deref ( & self ) -> & GlobalValue {
228
- unsafe { mem:: transmute ( self ) }
229
- }
230
- }
201
+ sub ! { Function , LLVMIsAFunction , GlobalValue }
231
202
impl Index < usize > for Function {
232
203
type Output = Arg ;
233
204
fn index ( & self , index : usize ) -> & Arg {
@@ -240,19 +211,13 @@ impl Index<usize> for Function {
240
211
}
241
212
}
242
213
}
243
- impl CastFrom for Function {
244
- type From = Value ;
245
- fn cast < ' a > ( val : & ' a Value ) -> Option < & ' a Function > {
246
- let ty = val. get_type ( ) ;
247
- let mut is_func = ty. is_function ( ) ;
248
- if let Some ( elem) = ty. get_element ( ) {
249
- is_func = is_func || elem. is_function ( )
250
- }
251
- if is_func {
252
- Some ( unsafe { mem:: transmute ( val) } )
253
- } else {
254
- None
214
+ unsafe impl Sub < Value > for Function {
215
+ fn is ( value : & Value ) -> bool {
216
+ let mut ty = value. get_type ( ) ;
217
+ while let Some ( elem) = ty. get_element ( ) {
218
+ ty = elem;
255
219
}
220
+ ty. is_function ( )
256
221
}
257
222
}
258
223
impl Function {
0 commit comments