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}