llvm_wrap/
val.rs

1//! A wrapper around a `LLVMValueRef`
2
3use super::*;
4use super::c_api::*;
5
6/// A wrapper around a `LLVMValueRef` for a specific context
7#[derive(Copy, Clone)]
8pub struct Value {
9    pub(crate) value: LLVMValueRef
10}
11
12impl Value {
13    /// Adds a block to this function
14    pub fn append_basic_block<S>(&self, name: S) -> BasicBlock where S: AsRef<str> {
15        BasicBlock {
16            basic_block: unsafe {
17                LLVMAppendBasicBlockInContext(context(), self.value, CString::new(name.as_ref()).expect("invalid module name").as_ptr() as *const i8)
18            }
19        }
20    }
21
22    /// Delete this function
23    pub fn delete_function(self) {
24        unsafe {
25            LLVMDeleteFunction(self.value)
26        }
27    }
28
29    /// Delete this global
30    pub fn delete_global(self) {
31        unsafe {
32            LLVMDeleteGlobal(self.value)
33        }
34    }
35
36    /// Set the calling convention of this function
37    pub fn set_call_conv(&self, cc: CallConv) -> Value {
38        unsafe {
39            LLVMSetFunctionCallConv(self.value, cc as u32);
40        }
41        *self
42    }
43
44    /// Set the linkage of this global
45    pub fn set_linkage(&self, link: Linkage) -> Value {
46        unsafe {
47            LLVMSetLinkage(self.value, link.inner());
48        }
49        *self
50    }
51
52    /// Set whether this is a tail call
53    pub fn set_tail_call(&self, tail: bool) -> Value {
54        unsafe {
55            LLVMSetTailCall(self.value, tail as i32);
56        }
57        *self
58    }
59
60    /// Set whether this global is a constant
61    pub fn set_global_const(&self, constant: bool) -> Value {
62        unsafe {
63            LLVMSetGlobalConstant(self.value, constant as i32);
64        }
65        *self
66    }
67
68    /// Returns true if this value is a constant
69    pub fn is_constant(&self) -> bool {
70        unsafe {
71            LLVMIsConstant(self.value) != 0
72        }
73    }
74
75    /// Returns true if this value is `undef`
76    pub fn is_undef(&self) -> bool {
77        unsafe {
78            LLVMIsUndef(self.value) != 0
79        }
80    }
81
82    /// Set whether the address of this global is significant
83    pub fn set_unnamed_addr(&self, unnamed_addr: bool) -> Value {
84        unsafe {
85            LLVMSetUnnamedAddr(self.value, unnamed_addr as i32);
86        }
87        *self
88    }
89
90    /// Set the initializer of this global
91    pub fn set_global_initializer(&self, init: Value) -> Value {
92        unsafe {
93            LLVMSetInitializer(self.value, init.value);
94        }
95        *self
96    }
97
98    /// Set the alignment of this value
99    pub fn set_alignment(&self, bytes: u32) -> Value {
100        unsafe {
101            LLVMSetAlignment(self.value, bytes);
102        }
103        *self
104    }
105
106    /// Get a parameter for this function
107    pub fn param(&self, param: u32) -> Value {
108        Value {
109            value: unsafe {
110                LLVMGetParam(self.value, param as u32)
111            }
112        }
113    }
114
115    /// Returns an iterator over all parameters in this function
116    pub fn params(&self) -> iter::Params {
117        iter::Params {
118            pointer: Value {
119                value: unsafe {
120                    LLVMGetFirstParam(self.value)
121                }
122            }
123        }
124    }
125
126    /// Set the alignment of this parameter
127    pub fn set_param_alignment(&self, bytes: u32) -> Value {
128        unsafe {
129            LLVMSetParamAlignment(self.value, bytes);
130        }
131        *self
132    }
133
134    /// Returns an iterator over all basic blocks in this function
135    pub fn blocks(&self) -> iter::Blocks {
136        iter::Blocks {
137            pointer: BasicBlock {
138                basic_block: unsafe {
139                    LLVMGetFirstBasicBlock(self.value)
140                }
141            }
142        }
143    }
144
145    /// Set the name of a value
146    pub fn name<S>(&self, name: S) -> Value where S: AsRef<str> {
147        unsafe {
148            LLVMSetValueName(self.value, into_c(name).as_ptr());
149        }
150        *self
151    }
152
153    /// Get the name of a value
154    pub fn get_name(&self) -> Option<String> {
155        unsafe {
156            from_c(LLVMGetValueName(self.value))
157        }
158    }
159
160    /// Get the type of this value
161    pub fn ty(&self) -> Type {
162        Type {
163            ty: unsafe {
164                LLVMTypeOf(self.value)
165            }
166        }
167    }
168
169    /// Dump the contents of the value to stderr
170    pub fn dump(&self) {
171        unsafe {
172            LLVMDumpValue(self.value);
173        }
174    }
175
176    /// Returns the internal value reference
177    pub fn inner(&self) -> LLVMValueRef {
178        self.value
179    }
180}
181
182impl Deref for Value {
183    type Target = LLVMValueRef;
184
185    fn deref(&self) -> &LLVMValueRef {
186        &self.value
187    }
188}
189
190impl Debug for Value {
191    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
192        if let Some(name) = self.get_name() {
193            write!(f, "Value({})", name)
194        } else {
195            write!(f, "Value")
196        }
197    }
198}