llvm_lib/core/values/mod.rs
1use crate::core::module::InlineAsmDialect;
2use crate::core::types::TypeRef;
3use crate::{CStr, CUint, GetRef, SizeT};
4use llvm_sys::core;
5use llvm_sys::prelude::LLVMValueRef;
6use llvm_sys::LLVMValueKind;
7use std::ops::Deref;
8
9pub mod constants;
10pub mod function_values;
11pub mod general;
12pub mod uses;
13
14/// Represents the different kinds of values in LLVM IR.
15///
16/// The `ValueKind` enum categorizes the various types of values that can exist within LLVM IR. Each variant
17/// of this enum corresponds to a specific kind of value or entity in the LLVM IR, such as a function, global variable,
18/// instruction, or constant. This enum is useful for identifying the type of a value when working with LLVM IR structures.
19#[derive(Clone, Copy, Debug, Eq, PartialEq)]
20pub enum ValueKind {
21 /// Represents a function argument. Each argument passed to a function is an instance of this kind.
22 Argument,
23 /// Represents a basic block within a function. Basic blocks are the building blocks of a function's control flow.
24 BasicBlock,
25 /// Represents a memory use in the `MemorySSA`. This kind tracks the use of memory locations within SSA form.
26 MemoryUse,
27 /// Represents a memory definition in the `MemorySSA`. This kind tracks the definition of memory locations within SSA form.
28 MemoryDef,
29 /// Represents a memory PHI node in the `MemorySSA`. This kind handles merging memory states from different control flow paths.
30 MemoryPhi,
31 /// Represents a function. Functions are the primary callable entities in LLVM IR.
32 Function,
33 /// Represents a global alias. Global aliases are alternative names for global variables or functions.
34 GlobalAlias,
35 /// Represents an indirect function. This is a function pointer that can be resolved at runtime to a specific implementation.
36 GlobalIFunc,
37 /// Represents a global variable. Global variables are variables that are globally accessible across the entire module.
38 GlobalVariable,
39 /// Represents a block address. This is used to refer to the address of a basic block within a function.
40 BlockAddress,
41 /// Represents a constant expression. Constant expressions are constant values that are computed at compile time from other constants.
42 ConstantExpr,
43 /// Represents a constant array. Constant arrays are arrays whose elements are all constant values.
44 ConstantArray,
45 /// Represents a constant struct. Constant structs are structures whose fields are all constant values.
46 ConstantStruct,
47 /// Represents a constant vector. Constant vectors are vectors whose elements are all constant values.
48 ConstantVector,
49 /// Represents an undefined value. Undefined values are placeholders that can take any value of their type during execution.
50 Undef,
51 /// Represents a constant aggregate with all elements set to zero. This includes arrays, structs, and vectors with all elements set to zero.
52 ConstantAggregateZero,
53 /// Represents a constant data array. These are arrays of simple data types like integers or floating-point numbers, stored as constants.
54 ConstantDataArray,
55 /// Represents a constant data vector. These are vectors of simple data types like integers or floating-point numbers, stored as constants.
56 ConstantDataVector,
57 /// Represents a constant integer. Constant integers are fixed integer values known at compile time.
58 ConstantInt,
59 /// Represents a constant floating-point value. Constant floating-point values are fixed floating-point numbers known at compile time.
60 ConstantFP,
61 /// Represents a constant null pointer. This is a pointer that is explicitly set to null.
62 ConstantPointerNull,
63 /// Represents a constant token with no value. Used in certain intrinsic functions that deal with tokens.
64 ConstantTokenNone,
65 /// Represents metadata used as a value. Metadata can be used to store extra information for optimizations, debugging, or analysis.
66 MetadataAsValue,
67 /// Represents inline assembly code. Inline assembly allows embedding low-level assembly code within LLVM IR.
68 InlineAsm,
69 /// Represents an instruction. Instructions are the individual operations that make up the body of functions.
70 Instruction,
71 /// Represents a poison value. Poison values result from operations with undefined behavior and can propagate to cause further undefined behavior.
72 Poison,
73 /// Represents a target-specific constant value that has no direct representation in the source code.
74 ConstantTargetNone,
75 /// Represents a constant pointer with pointer authentication. This is a pointer with additional authentication information.
76 ConstantPtrAuthValueKind,
77}
78
79impl From<LLVMValueKind> for ValueKind {
80 fn from(value: LLVMValueKind) -> Self {
81 match value {
82 LLVMValueKind::LLVMArgumentValueKind => Self::Argument,
83 LLVMValueKind::LLVMBasicBlockValueKind => Self::BasicBlock,
84 LLVMValueKind::LLVMMemoryUseValueKind => Self::MemoryUse,
85 LLVMValueKind::LLVMMemoryDefValueKind => Self::MemoryDef,
86 LLVMValueKind::LLVMMemoryPhiValueKind => Self::MemoryPhi,
87 LLVMValueKind::LLVMFunctionValueKind => Self::Function,
88 LLVMValueKind::LLVMGlobalAliasValueKind => Self::GlobalAlias,
89 LLVMValueKind::LLVMGlobalIFuncValueKind => Self::GlobalIFunc,
90 LLVMValueKind::LLVMGlobalVariableValueKind => Self::GlobalVariable,
91 LLVMValueKind::LLVMBlockAddressValueKind => Self::BlockAddress,
92 LLVMValueKind::LLVMConstantExprValueKind => Self::ConstantExpr,
93 LLVMValueKind::LLVMConstantArrayValueKind => Self::ConstantArray,
94 LLVMValueKind::LLVMConstantStructValueKind => Self::ConstantStruct,
95 LLVMValueKind::LLVMConstantVectorValueKind => Self::ConstantVector,
96 LLVMValueKind::LLVMUndefValueValueKind => Self::Undef,
97 LLVMValueKind::LLVMConstantAggregateZeroValueKind => Self::ConstantAggregateZero,
98 LLVMValueKind::LLVMConstantDataArrayValueKind => Self::ConstantDataArray,
99 LLVMValueKind::LLVMConstantDataVectorValueKind => Self::ConstantDataVector,
100 LLVMValueKind::LLVMConstantIntValueKind => Self::ConstantInt,
101 LLVMValueKind::LLVMConstantFPValueKind => Self::ConstantFP,
102 LLVMValueKind::LLVMConstantPointerNullValueKind => Self::ConstantPointerNull,
103 LLVMValueKind::LLVMConstantTokenNoneValueKind => Self::ConstantTokenNone,
104 LLVMValueKind::LLVMMetadataAsValueValueKind => Self::MetadataAsValue,
105 LLVMValueKind::LLVMInlineAsmValueKind => Self::InlineAsm,
106 LLVMValueKind::LLVMInstructionValueKind => Self::Instruction,
107 LLVMValueKind::LLVMPoisonValueKind => Self::Poison,
108 LLVMValueKind::LLVMConstantTargetNoneValueKind => Self::ConstantTargetNone,
109 LLVMValueKind::LLVMConstantPtrAuthValueKind => Self::ConstantPtrAuthValueKind,
110 }
111 }
112}
113
114/// LLVM Value wrapper
115#[derive(Debug)]
116pub struct ValueRef(LLVMValueRef);
117
118impl Deref for ValueRef {
119 type Target = LLVMValueRef;
120 fn deref(&self) -> &Self::Target {
121 &self.0
122 }
123}
124
125impl GetRef for ValueRef {
126 type RawRef = LLVMValueRef;
127 fn get_ref(&self) -> Self::RawRef {
128 self.0
129 }
130}
131
132impl From<LLVMValueRef> for ValueRef {
133 fn from(value_ref: LLVMValueRef) -> Self {
134 Self(value_ref)
135 }
136}
137
138/// That implementations related to LLVM Modules `MemoryDef`.
139impl ValueRef {
140 /// Get the template string used for an inline assembly snippet.
141 ///
142 /// # Details
143 ///
144 /// Retrieves the assembly code string from the inline assembly block in LLVM IR.
145 ///
146 /// This function wraps the `LLVMGetInlineAsmAsmString` function from the LLVM core library. It returns the
147 /// assembly code string used by the inline assembly block associated with `self`. This string contains the
148 /// actual assembly instructions that will be executed as part of the inline assembly.
149 ///
150 /// If the assembly string cannot be retrieved, the function returns `None`.
151 ///
152 /// # Returns
153 ///
154 /// Returns an `Option<String>`:
155 /// - `Some(String)` containing the assembly code string if successful.
156 /// - `None` if the assembly string cannot be retrieved.
157 #[must_use]
158 pub fn get_inline_asm_asm_string(&self) -> Option<String> {
159 unsafe {
160 let mut length = SizeT::from(0_usize);
161 let c_str = core::LLVMGetInlineAsmAsmString(self.0, &mut *length);
162 if c_str.is_null() {
163 return None;
164 }
165 Some(CStr::new(c_str).to_string())
166 }
167 }
168
169 /// Get the raw constraint string for an inline assembly snippet.
170 ///
171 /// # Details
172 ///
173 /// Retrieves the constraint string associated with the inline assembly block in LLVM IR.
174 ///
175 /// This function wraps the `LLVMGetInlineAsmConstraintString` function from the LLVM core library. It returns the
176 /// constraint string used by the inline assembly block associated with `self`. The constraint string specifies the
177 /// constraints on the operands used in the inline assembly, such as register classes or memory addressing modes.
178 ///
179 /// If the constraint string cannot be retrieved, the function returns `None`.
180 ///
181 /// # Returns
182 ///
183 /// Returns an `Option<String>`:
184 /// - `Some(String)` containing the constraint string if successful.
185 /// - `None` if the constraint string cannot be retrieved.
186 #[must_use]
187 pub fn get_inline_asm_constraint_string(&self) -> Option<String> {
188 unsafe {
189 let mut length = SizeT::from(0_usize);
190 let c_str = core::LLVMGetInlineAsmConstraintString(self.0, &mut *length);
191 if c_str.is_null() {
192 return None;
193 }
194 Some(CStr::new(c_str).to_string())
195 }
196 }
197
198 /// Get the dialect used by the inline asm snippet.
199 ///
200 /// # Details
201 ///
202 /// Retrieves the dialect of the inline assembly block in LLVM IR.
203 ///
204 /// This function wraps the `LLVMGetInlineAsmDialect` function from the LLVM core library. It returns the
205 /// `InlineAsmDialect` representing the dialect used by the inline assembly block associated with `self`.
206 /// The dialect determines the syntax and conventions used in the inline assembly, which may vary between
207 /// different assemblers (e.g., AT&T vs. Intel syntax).
208 ///
209 /// # Returns
210 ///
211 /// Returns an `InlineAsmDialect` that represents the dialect of the inline assembly block.
212 #[must_use]
213 pub fn get_inline_asm_dialect(&self) -> InlineAsmDialect {
214 let inline_asm_dialect = unsafe { core::LLVMGetInlineAsmDialect(self.0) };
215 inline_asm_dialect.into()
216 }
217
218 /// Get the function type of the inline assembly snippet.
219 ///
220 /// This is the same type that was passed into `LLVMGetInlineAsm` originally.
221 ///
222 /// # Returns
223 ///
224 /// Retrieves the function type of the inline assembly block in LLVM IR.
225 ///
226 /// This function wraps the `LLVMGetInlineAsmFunctionType` function from the LLVM core library. It returns the
227 /// `TypeRef` representing the function type of the inline assembly block associated with `self`. The function type
228 /// defines the signature of the inline assembly, including the types of its arguments and return value.
229 ///
230 /// # Returns
231 ///
232 /// Returns a `TypeRef` that represents the function type of the inline assembly block.
233 #[must_use]
234 pub fn get_inline_asm_function_type(&self) -> TypeRef {
235 TypeRef::from(unsafe { core::LLVMGetInlineAsmFunctionType(self.0) })
236 }
237
238 /// Get if the inline asm snippet has side effects
239 ///
240 /// # Details
241 ///
242 /// Checks whether an inline assembly block has side effects in LLVM IR.
243 ///
244 /// This function wraps the `LLVMGetInlineAsmHasSideEffects` function from the LLVM core library. It determines
245 /// whether the inline assembly represented by `self` has side effects, meaning that it may alter state or interact
246 /// with external systems in ways that are not visible within the LLVM IR. This flag is important for optimizations,
247 /// as it indicates that the inline assembly cannot be removed or reordered without potentially affecting program behavior.
248 ///
249 /// # Returns
250 ///
251 /// Returns `true` if the inline assembly block has side effects, otherwise returns `false`.
252 #[must_use]
253 pub fn get_inline_asm_has_side_effects(&self) -> bool {
254 unsafe { core::LLVMGetInlineAsmHasSideEffects(self.0) != 0 }
255 }
256
257 /// Get if the inline asm snippet needs an aligned stack
258 ///
259 /// # Details
260 ///
261 /// Checks whether an inline assembly block requires an aligned stack in LLVM IR.
262 ///
263 /// This function wraps the `LLVMGetInlineAsmNeedsAlignedStack` function from the LLVM core library. It determines
264 /// whether the inline assembly represented by `self` requires the stack to be aligned. Proper stack alignment
265 /// may be necessary for certain instructions or calling conventions, and this flag indicates whether such alignment
266 /// is needed.
267 ///
268 /// # Returns
269 ///
270 /// Returns `true` if the inline assembly block requires an aligned stack, otherwise returns `false`.
271 #[must_use]
272 pub fn get_inline_asm_needs_aligned_stack(&self) -> bool {
273 unsafe { core::LLVMGetInlineAsmNeedsAlignedStack(self.0) != 0 }
274 }
275
276 /// Get if the inline asm snippet may unwind the stack
277 ///
278 /// # Details
279 ///
280 /// Checks whether an inline assembly block can unwind in LLVM IR.
281 ///
282 /// This function wraps the `LLVMGetInlineAsmCanUnwind` function from the LLVM core library. It determines whether
283 /// the inline assembly represented by `self` is capable of unwinding, which can affect how exceptions and
284 /// other control flows are handled during execution.
285 ///
286 /// # Returns
287 ///
288 /// Returns `true` if the inline assembly block can unwind, otherwise returns `false`.
289 #[must_use]
290 pub fn get_inline_asm_can_unwind(&self) -> bool {
291 unsafe { core::LLVMGetInlineAsmCanUnwind(self.0) != 0 }
292 }
293
294 /// Return the directory of the debug location for this value, which must be
295 /// an LLVM `Instruction`, `GlobalVariable`, or `Function`.
296 ///
297 /// # Details
298 ///
299 /// Retrieves the directory from the debug location associated with this value in LLVM IR.
300 ///
301 /// This function wraps the `LLVMGetDebugLocDirectory` function from the LLVM core library. It returns the
302 /// directory of the source code location associated with the debug information for the value represented by `self`.
303 /// If the directory cannot be retrieved, the function returns `None`.
304 ///
305 /// # Returns
306 ///
307 /// Returns an `Option<String>`:
308 /// - `Some(String)` containing the directory associated with the value's debug location if successful.
309 /// - `None` if the directory cannot be retrieved.
310 #[must_use]
311 pub fn get_debug_loc_directory(&self) -> Option<String> {
312 unsafe {
313 let mut length = CUint::from(0_usize);
314 let c_str = core::LLVMGetDebugLocDirectory(self.0, &mut *length);
315 if c_str.is_null() {
316 return None;
317 }
318 Some(CStr::new(c_str).to_string())
319 }
320 }
321
322 /// Return the filename of the debug location for this value, which must be
323 /// an LLVM `Instruction`, `lGlobalVariable`, or `Function`.
324 ///
325 /// # Details
326 ///
327 /// Retrieves the filename from the debug location associated with this value in LLVM IR.
328 ///
329 /// This function wraps the `LLVMGetDebugLocFilename` function from the LLVM core library. It returns the
330 /// filename of the source code location associated with the debug information for the value represented by `self`.
331 /// If the filename cannot be retrieved, the function returns `None`.
332 ///
333 /// # Returns
334 ///
335 /// Returns an `Option<String>`:
336 /// - `Some(String)` containing the filename associated with the value's debug location if successful.
337 /// - `None` if the filename cannot be retrieved.
338 #[must_use]
339 pub fn get_debug_loc_filename(&self) -> Option<String> {
340 unsafe {
341 let mut length = CUint::from(0_usize);
342 let c_str = core::LLVMGetDebugLocFilename(self.0, &mut *length);
343 if c_str.is_null() {
344 return None;
345 }
346 Some(CStr::new(c_str).to_string())
347 }
348 }
349
350 /// Return the line number of the debug location for this value, which must be
351 /// an LLVM `Instruction`, `GlobalVariable`, or `Function`.
352 ///
353 /// # Details
354 ///
355 /// Retrieves the line number from the debug location associated with this value in LLVM IR.
356 ///
357 /// This function wraps the `LLVMGetDebugLocLine` function from the LLVM core library. It returns the
358 /// line number of the source code location associated with the debug information for the value represented by `self`.
359 /// This is useful for debugging and for tools that need to report precise source locations.
360 ///
361 /// # Returns
362 ///
363 /// Returns a `u32` representing the line number in the source code associated with this value's debug location.
364 #[must_use]
365 pub fn get_debug_loc_line(&self) -> u32 {
366 unsafe { core::LLVMGetDebugLocLine(self.0) }
367 }
368
369 /// Return the column number of the debug location for this value, which must be
370 /// an LLVM `Instruction`.
371 ///
372 /// # Details
373 ///
374 /// Retrieves the column number from the debug location associated with this value in LLVM IR.
375 ///
376 /// This function wraps the `LLVMGetDebugLocColumn` function from the LLVM core library. It returns the
377 /// column number of the source code location associated with the debug information for the value represented by `self`.
378 /// This is useful for debugging and for tools that need to report precise source locations.
379 ///
380 /// # Returns
381 ///
382 /// Returns a `u32` representing the column number in the source code associated with this value's debug location.
383 #[must_use]
384 pub fn get_debug_loc_column(&self) -> u32 {
385 unsafe { core::LLVMGetDebugLocColumn(self.0) }
386 }
387
388 /// Advance a `Function` iterator to the next Function.
389 ///
390 /// Returns `None` if the iterator was already at the end and there are no more functions.
391 ///
392 /// # Details
393 ///
394 /// Retrieves the next function in the module relative to this function, if it exists.
395 ///
396 /// This function wraps the `LLVMGetNextFunction` function from the LLVM core library. It returns the
397 /// next function in the module relative to the function represented by `self`. If there is no next
398 /// function, the function returns `None`. This is useful for iterating over functions within a module in LLVM IR.
399 ///
400 /// # Returns
401 ///
402 /// Returns an `Option<ValueRef>`:
403 /// - `Some(ValueRef)` containing the next function if it exists.
404 /// - `None` if there is no next function in the module.
405 #[must_use]
406 pub fn get_next_function(&self) -> Option<Self> {
407 unsafe {
408 let next_func = core::LLVMGetNextFunction(self.0);
409 if next_func.is_null() {
410 None
411 } else {
412 Some(Self(next_func))
413 }
414 }
415 }
416
417 /// Decrement a `Function` iterator to the previous Function.
418 ///
419 /// Returns `None` if the iterator was already at the beginning and there are no previous functions.
420 ///
421 /// # Details
422 ///
423 /// Retrieves the previous function in the module relative to this function, if it exists.
424 ///
425 /// This function wraps the `LLVMGetPreviousFunction` function from the LLVM core library. It returns the
426 /// previous function in the module relative to the function represented by `self`. If there is no previous
427 /// function, the function returns `None`. This is useful for iterating over functions within a module in LLVM IR.
428 ///
429 /// # Returns
430 ///
431 /// Returns an `Option<ValueRef>`:
432 /// - `Some(ValueRef)` containing the previous function if it exists.
433 /// - `None` if there is no previous function in the module.
434 #[must_use]
435 pub fn get_previous_function(&self) -> Option<Self> {
436 unsafe {
437 let prev_func = core::LLVMGetPreviousFunction(self.0);
438 if prev_func.is_null() {
439 None
440 } else {
441 Some(Self(prev_func))
442 }
443 }
444 }
445}