llvm_lib/core/values/
general.rs

1//! Functions in this section work on all `ValueRef` instances,
2//! regardless of their sub-type. They correspond to functions available
3//! on `C LLVM Value`.
4
5use super::{ValueKind, ValueRef};
6use crate::core::types::TypeRef;
7use crate::{CStr, CString, GetRef, SizeT};
8use llvm_sys::core;
9
10/// Obtain the type of the value.
11///
12/// # Details
13///
14/// Retrieves the LLVM type of the value.
15///
16/// This function wraps the `LLVMTypeOf` function from the LLVM core library. It returns the `TypeRef` representing
17/// the LLVM type of the value represented by `ValueRef`. This is useful for inspecting the type information of values
18/// within LLVM IR, such as determining whether a value is an integer, floating-point, pointer, or another type.
19///
20/// # Returns
21///
22/// Returns a `TypeRef` that represents the LLVM type of the value.
23#[must_use]
24pub fn type_of(val: &ValueRef) -> TypeRef {
25    unsafe { TypeRef::from(core::LLVMTypeOf(val.get_ref())) }
26}
27
28/// Returns the kind of the given LLVM value (Obtain the enumerated type of the Value instance.).
29///
30/// # Details
31///
32/// Retrieves the kind of value represented by this LLVM value.
33///
34/// This function wraps the `LLVMGetValueKind` function from the LLVM core library. It returns a `ValueKind`
35/// enumeration that identifies the specific kind of the value, such as whether it is an instruction, a constant,
36/// a global variable, a function, etc. This is useful for understanding what kind of entity a value represents within
37/// the LLVM IR.
38///
39/// # Returns
40///
41/// Returns a `ValueKind` enumeration that represents the kind of the value.
42#[must_use]
43pub fn get_value_kind(val: &ValueRef) -> ValueKind {
44    unsafe { ValueKind::from(core::LLVMGetValueKind(val.get_ref())) }
45}
46
47/// Obtain the string name of a value.
48///
49/// # Details
50///
51/// Retrieves the name of the LLVM value, if it has one.
52///
53/// This function wraps the `LLVMGetValueName2` function from the LLVM core library. It returns the name of the
54/// value represented by `ValueRef` as a `String`, if the value has a name. In LLVM IR, named values typically include
55/// functions, global variables, and named instructions. If the value does not have a name, the function returns `None`.
56///
57/// # Returns
58///
59/// Returns an `Option<String>`:
60/// - `Some(String)` containing the name of the value if it has one.
61/// - `None` if the value does not have a name.
62#[must_use]
63pub fn get_value_name(val: &ValueRef) -> Option<String> {
64    unsafe {
65        let mut length = SizeT::from(0);
66        let c_str = core::LLVMGetValueName2(val.get_ref(), &mut *length);
67        if c_str.is_null() {
68            return None;
69        }
70        Some(CStr::new(c_str).to_string())
71    }
72}
73
74/// Set the string name of a value.
75///
76/// # Details
77///
78/// Sets the name of the LLVM value.
79///
80/// This function wraps the `LLVMSetValueName2` function from the LLVM core library. It assigns a new name
81/// to the value represented by `ValueRef`. Naming a value in LLVM IR is useful for debugging, readability, and
82/// when generating human-readable IR. Named values typically include functions, global variables, and named
83/// instructions.
84///
85/// # Parameters
86///
87/// - `name`: A string slice (`&str`) representing the new name to assign to the value.
88///
89/// # Example
90///
91/// ```rust
92/// let my_value: ValueRef; // Assume this is an LLVM value.
93/// my_value.set_value_name("my_value_name");
94/// ```
95///
96/// After calling this function, the value will be named "`my_value_name`" in the LLVM IR.
97pub fn set_value_name(val: &ValueRef, name: &str) {
98    let c_string = CString::from(name);
99    unsafe {
100        core::LLVMSetValueName2(val.get_ref(), c_string.as_ptr(), *SizeT::from(name.len()));
101    }
102}
103
104/// Dump a representation of a value to stderr.
105///
106/// # Details
107///
108/// Dumps a textual representation of the LLVM value to standard output.
109///
110/// This function wraps the `LLVMDumpValue` function from the LLVM core library. It prints a human-readable
111/// representation of the value represented by `ValueRef` to standard output. This is useful for debugging or
112/// inspecting the contents of a value during development.
113pub fn dump_value(val: &ValueRef) {
114    unsafe { core::LLVMDumpValue(val.get_ref()) }
115}
116
117/// Return a string representation of the value. Use
118/// `dispose_message` to free the string.
119///
120/// # Details
121///
122/// Converts the LLVM value to a human-readable string representation.
123///
124/// This function wraps the `LLVMPrintValueToString` function from the LLVM core library. It returns a
125/// string containing a human-readable representation of the value represented by `ValueRef`. This is useful
126/// for debugging or inspecting the contents of a value programmatically.
127///
128/// The function returns `None` if the conversion fails or if the value cannot be represented as a string.
129///
130/// # Returns
131///
132/// Returns an `Option<String>`:
133/// - `Some(String)` containing the string representation of the value if successful.
134/// - `None` if the conversion fails or the value cannot be represented as a string.
135#[must_use]
136pub fn print_value_to_string(val: &ValueRef) -> Option<String> {
137    unsafe {
138        let c_str = core::LLVMPrintValueToString(val.get_ref());
139        if c_str.is_null() {
140            return None;
141        }
142        let result = CStr::new(c_str).to_string();
143        core::LLVMDisposeMessage(c_str);
144        Some(result)
145    }
146}
147
148/// Replace all uses of a value with another one.
149///
150/// # Details
151///
152/// Replaces all uses of this value with another value in the LLVM IR.
153///
154/// This function wraps the `LLVMReplaceAllUsesWith` function from the LLVM core library. It replaces
155/// every use of the value represented by `ValueRef` with the value represented by `new_val`. This is useful
156/// for modifying LLVM IR when you need to substitute one value with another throughout the IR.
157///
158/// # Parameters
159///
160/// - `new_val`: A reference to the value that will replace all uses of `ValueRef`.
161pub fn replace_all_uses_with(val: &ValueRef, new_val: &ValueRef) {
162    unsafe { core::LLVMReplaceAllUsesWith(val.get_ref(), new_val.get_ref()) }
163}
164
165/// Determines whether the specified value instance is constant.
166///
167/// # Details
168///
169/// Checks if the value is a constant in LLVM IR.
170///
171/// This function wraps the `LLVMIsConstant` function from the LLVM core library. It determines whether
172/// the value represented by `ValueRef` is a constant. In LLVM IR, constants are values that are known at compile time,
173/// such as integer literals, floating-point literals, or constant expressions.
174///
175/// # Returns
176///
177/// Returns `true` if the value is a constant, otherwise returns `false`.
178#[must_use]
179pub fn is_constant(val: &ValueRef) -> bool {
180    unsafe { core::LLVMIsConstant(val.get_ref()) != 0 }
181}
182
183/// Determine whether a value instance is undefined.
184///
185/// # Details
186///
187/// Checks if the value is an 'undefined' value in LLVM IR.
188///
189/// This function wraps the `LLVMIsUndef` function from the LLVM core library. It determines whether
190/// the value represented by `ValueRef` is an 'undefined' value. In LLVM IR, an undefined value is a placeholder
191/// that can take any value of the specified type during program execution, often used in optimization phases.
192///
193/// # Returns
194///
195/// Returns `true` if the value is an undefined value, otherwise returns `false`.
196#[must_use]
197pub fn is_undef(val: &ValueRef) -> bool {
198    unsafe { core::LLVMIsUndef(val.get_ref()) != 0 }
199}
200
201/// Determine whether a value instance is poisonous.
202///
203/// # Details
204///
205/// Checks if the value is a 'poison' value in LLVM IR.
206///
207/// This function wraps the `LLVMIsPoison` function from the LLVM core library. It determines whether
208/// the value represented by `ValueRef` is a 'poison' value. In LLVM IR, a poison value results from an operation
209/// with undefined behavior and can propagate through further operations, potentially leading to incorrect results.
210///
211/// # Returns
212///
213/// Returns `true` if the value is a poison value, otherwise returns `false`.
214#[must_use]
215pub fn is_poison(val: &ValueRef) -> bool {
216    unsafe { core::LLVMIsPoison(val.get_ref()) != 0 }
217}
218
219/// Determines whether the specified value instance is an `AMD` node.
220///
221/// # Details
222///
223/// Checks if the value is an AMD node in LLVM IR and returns the corresponding value.
224///
225/// This function wraps the `LLVMIsAMDNode` function from the LLVM core library. It determines whether
226/// the value represented by `ValueRef` is an AMD node and returns the corresponding value if it is. AMD nodes
227/// are specific to AMD's extensions in LLVM, and this function is used to identify and work with those nodes.
228///
229/// # Returns
230///
231/// Returns an instance of `ValueRef` that represents the value if it is an AMD node.
232#[must_use]
233pub fn is_amd_node(val: &ValueRef) -> ValueRef {
234    unsafe { ValueRef(core::LLVMIsAMDNode(val.get_ref())) }
235}
236
237/// Determines whether the specified value instance is a value as metadata.
238///
239/// # Details
240///
241/// Checks if the value can be treated as metadata in LLVM IR and returns the corresponding value.
242///
243/// This function wraps the `LLVMIsAValueAsMetadata` function from the LLVM core library. It determines whether
244/// the value represented by `ValueRef` can be treated as metadata and returns the corresponding value if it can. In LLVM IR,
245/// some values can also be used as metadata, which is often used for attaching additional information to instructions
246/// or other IR elements.
247///
248/// # Returns
249///
250/// Returns an instance of `ValueRef` that represents the value if it can be treated as metadata.
251#[must_use]
252pub fn is_value_as_metadata(val: &ValueRef) -> ValueRef {
253    unsafe { ValueRef(core::LLVMIsAValueAsMetadata(val.get_ref())) }
254}
255
256/// Determines whether the specified value instance is an `AMD` string.
257///
258/// # Details
259///
260/// Checks if the value is an AMD string in LLVM IR and returns the corresponding value.
261///
262/// This function wraps the `LLVMIsAMDString` function from the LLVM core library. It determines whether
263/// the value represented by `ValueRef` is an AMD string and returns the corresponding value if it is. AMD strings
264/// are specific to AMD's extensions in LLVM, and this function is used to identify and work with those strings.
265///
266/// # Returns
267///
268/// Returns an instance of `ValueRef` that represents the value if it is an AMD string.
269#[must_use]
270pub fn is_amd_string(val: &ValueRef) -> ValueRef {
271    unsafe { ValueRef(core::LLVMIsAMDString(val.get_ref())) }
272}