llvm_lib/core/values/constants/
scalar.rs

1//! Functions in this group model `ValueRef` instances that correspond
2//! to constants referring to scalar types.
3
4use super::ValueRef;
5use crate::core::types::TypeRef;
6use crate::{CDouble, CInt, CString, CUint, GetRef};
7use llvm_sys::core;
8
9/// Obtain a constant value for an integer type.
10/// The returned value corresponds to a `llvm ConstantInt`.
11///
12/// # Details
13///
14/// Creates a constant integer value of a specified type.
15///
16/// This function wraps the `LLVMConstInt` function from the LLVM core library. It generates a constant integer
17/// value of the type specified by `ty`, using the provided `n` as the value. The `sign_extend` parameter determines
18/// whether the value should be sign-extended to the specified type if the type is larger than the original value.
19///
20/// # Parameters
21///
22/// - `ty`: A reference to the integer type (`TypeRef`) for the constant value. This specifies the bit width and signedness of the integer.
23/// - `n`: The integer value to be used for the constant. It will be interpreted according to the bit width and signedness of the target type.
24/// - `sign_extend`: A boolean value indicating whether the constant should be sign-extended to the target type. If `true`, the value will be sign-extended; if `false`, it will be zero-extended.
25///
26/// # Returns
27///
28/// Returns an instance of `ValueRef`, which encapsulates the constant integer value determined at compile time.
29#[must_use]
30pub fn const_int(ty: &TypeRef, n: u64, sign_extend: bool) -> ValueRef {
31    unsafe {
32        ValueRef(core::LLVMConstInt(
33            ty.get_ref(),
34            n,
35            *CInt::from(sign_extend),
36        ))
37    }
38}
39
40/// Obtain a constant value for an integer of arbitrary precision.
41///
42/// # Details
43///
44/// Creates a constant integer value of arbitrary precision.
45///
46/// This function wraps the `LLVMConstIntOfArbitraryPrecision` function from the LLVM core library. It generates a constant
47/// integer value of the specified type (`ty`) using an array of 64-bit words (`words`). This allows for the creation of
48/// integers that exceed the typical bit width limitations by providing multiple 64-bit words to represent the value.
49///
50/// # Parameters
51///
52/// - `ty`: A reference to the integer type (`TypeRef`) for the constant value. This type specifies the bit width and signedness of the integer.
53/// - `words`: A slice of 64-bit words (`u64`) that represents the value of the constant integer. Each word in the array contributes to the overall bit representation of the integer, allowing for arbitrary precision.
54///
55/// # Returns
56///
57/// Returns an instance of `ValueRef`, which encapsulates the constant integer value with arbitrary precision, as determined at compile time.
58#[must_use]
59pub fn const_int_of_arbitrary_precision(ty: &TypeRef, words: &[u64]) -> ValueRef {
60    unsafe {
61        ValueRef(core::LLVMConstIntOfArbitraryPrecision(
62            ty.get_ref(),
63            *CUint::from(words.len()),
64            words.as_ptr(),
65        ))
66    }
67}
68
69/// Obtain a constant value for an integer parsed from a string.
70///
71/// A similar API, `const_int_of_string_and_size` is also available. If the
72/// string's length is available, it is preferred to call that function
73/// instead.
74///
75/// # Details
76///
77/// Creates a constant integer value by parsing a string representation of the integer.
78///
79/// This function wraps the `LLVMConstIntOfString` function from the LLVM core library. It generates a constant
80/// integer value of the specified type (`ty`) by parsing the provided string (`text`) according to the specified
81/// radix (`radix`). This function is useful when you need to create constant integers from string literals in various bases
82/// (e.g., binary, octal, decimal, hexadecimal).
83///
84/// # Parameters
85///
86/// - `ty`: A reference to the integer type (`TypeRef`) for the constant value. This type specifies the bit width and signedness of the integer.
87/// - `text`: A string slice that represents the integer value to be parsed. The string should be a valid representation of an integer in the specified radix.
88/// - `radix`: The radix (or base) used to interpret the string. Common values include 2 (binary), 8 (octal), 10 (decimal), and 16 (hexadecimal).
89///
90/// # Returns
91///
92/// Returns an instance of `ValueRef`, which encapsulates the constant integer value parsed from the string at compile time.
93#[must_use]
94pub fn const_int_of_string(ty: &TypeRef, text: &str, radix: u8) -> ValueRef {
95    let c_text = CString::from(text);
96    unsafe {
97        ValueRef(core::LLVMConstIntOfString(
98            ty.get_ref(),
99            c_text.as_ptr(),
100            radix,
101        ))
102    }
103}
104
105/// Obtain a constant value for an integer parsed from a string with
106/// specified length.
107///
108/// # Details
109///
110/// Creates a constant integer value by parsing a string representation of the integer, with a specified string length.
111///
112/// This function wraps the `LLVMConstIntOfStringAndSize` function from the LLVM core library. It generates a constant
113/// integer value of the specified type (`ty`) by parsing the provided string (`text`) according to the specified
114/// radix (`radix`). The length of the string is explicitly provided, which can be more efficient when the string length
115/// is known or can be easily determined, as it avoids the need for additional computation or checks.
116///
117/// # Parameters
118///
119/// - `ty`: A reference to the integer type (`TypeRef`) for the constant value. This type specifies the bit width and signedness of the integer.
120/// - `text`: A string slice that represents the integer value to be parsed. The string should be a valid representation of an integer in the specified radix.
121/// - `radix`: The radix (or base) used to interpret the string. Common values include 2 (binary), 8 (octal), 10 (decimal), and 16 (hexadecimal).
122///
123/// # Returns
124///
125/// Returns an instance of `ValueRef`, which encapsulates the constant integer value parsed from the string at compile time.
126///
127/// # Efficiency
128///
129/// This function is recommended when the length of the string is known, as it may offer better performance
130/// compared to `const_int_of_string` by avoiding the overhead of calculating the string length within the function.
131#[must_use]
132pub fn const_int_of_string_and_size(ty: &TypeRef, text: &str, radix: u8) -> ValueRef {
133    let c_text = CString::from(text);
134    unsafe {
135        ValueRef(core::LLVMConstIntOfStringAndSize(
136            ty.get_ref(),
137            c_text.as_ptr(),
138            *CUint::from(text.len()),
139            radix,
140        ))
141    }
142}
143
144/// Obtain a constant value referring to a double floating point value.
145///
146/// # Details
147///
148/// Creates a constant floating-point value of a specified type.
149///
150/// This function wraps the `LLVMConstReal` function from the LLVM core library. It generates a constant
151/// floating-point value of the type specified by `ty`, using the provided floating-point number `n`. This is
152/// typically used to create floating-point constants within LLVM's Intermediate Representation (IR) at compile time.
153///
154/// # Parameters
155///
156/// - `ty`: A reference to the floating-point type (`TypeRef`) for the constant value. This type specifies the bit width of the floating-point value (e.g., `f32`, `f64`).
157/// - `n`: The floating-point value to be used for the constant. It will be interpreted according to the bit width of the target floating-point type.
158///
159/// # Returns
160///
161/// Returns an instance of `ValueRef`, which encapsulates the constant floating-point value determined at compile time.
162#[must_use]
163pub fn const_real(ty: &TypeRef, n: f64) -> ValueRef {
164    unsafe { ValueRef(core::LLVMConstReal(ty.get_ref(), *CDouble::from(n))) }
165}
166
167/// Obtain a constant for a floating point value parsed from a string.
168///
169/// A similar API, `const_real_of_string_and_size` is also available. It
170/// should be used if the input string's length is known.
171///
172/// # Details
173///
174/// Creates a constant floating-point value by parsing a string representation of the number.
175///
176/// This function wraps the `LLVMConstRealOfString` function from the LLVM core library. It generates a constant
177/// floating-point value of the specified type (`ty`) by parsing the provided string (`text`). This is useful when
178/// creating floating-point constants from string literals, especially when the value is specified in textual form
179/// rather than directly as a floating-point number.
180///
181/// # Parameters
182///
183/// - `ty`: A reference to the floating-point type (`TypeRef`) for the constant value. This type specifies the bit width of the floating-point value (e.g., `f32`, `f64`).
184/// - `text`: A string slice that represents the floating-point value to be parsed. The string should be a valid representation of a floating-point number in the expected format.
185///
186/// # Returns
187///
188/// Returns an instance of `ValueRef`, which encapsulates the constant floating-point value parsed from the string at compile time.
189#[must_use]
190pub fn const_real_of_string(ty: &TypeRef, text: &str) -> ValueRef {
191    let c_text = CString::from(text);
192    unsafe { ValueRef(core::LLVMConstRealOfString(ty.get_ref(), c_text.as_ptr())) }
193}
194
195/// Obtain a constant for a floating point value parsed from a string with specified length.
196///
197/// # Details
198///
199/// Creates a constant floating-point value by parsing a string representation of the number, with a specified string length.
200///
201/// This function wraps the `LLVMConstRealOfStringAndSize` function from the LLVM core library. It generates a constant
202/// floating-point value of the specified type (`ty`) by parsing the provided string (`text`) according to its length.
203/// This function is useful when the length of the input string is known, as it may provide better performance by
204/// avoiding the need to compute the string length internally.
205///
206/// # Parameters
207///
208/// - `ty`: A reference to the floating-point type (`TypeRef`) for the constant value. This type specifies the bit width of the floating-point value (e.g., `f32`, `f64`).
209/// - `text`: A string slice that represents the floating-point value to be parsed. The string should be a valid representation of a floating-point number in the expected format.
210///
211/// # Returns
212///
213/// Returns an instance of `ValueRef`, which encapsulates the constant floating-point value parsed from the string at compile time.
214///
215/// # Efficiency
216///
217/// This function is recommended when the length of the string is known, as it may offer better performance
218/// compared to `const_real_of_string` by avoiding the overhead of calculating the string length within the function.
219#[must_use]
220pub fn const_real_of_string_and_size(ty: &TypeRef, text: &str) -> ValueRef {
221    let c_text = CString::from(text);
222    unsafe {
223        ValueRef(core::LLVMConstRealOfStringAndSize(
224            ty.get_ref(),
225            c_text.as_ptr(),
226            *CUint::from(text.len()),
227        ))
228    }
229}
230
231/// Obtain the zero extended value for an integer constant value.
232///
233/// # Details
234///
235/// Retrieves the zero-extended value of a constant integer as a `u64`.
236///
237/// This function wraps the `LLVMConstIntGetZExtValue` function from the LLVM core library. It returns the value
238/// of the constant integer represented by `ValueRef`, zero-extending it to 64 bits if necessary. This is useful when you need
239/// to extract the numeric value of a constant integer in a form that can be used in regular Rust code.
240///
241/// # Returns
242///
243/// Returns a `u64` that represents the zero-extended value of the constant integer.
244#[must_use]
245pub fn const_int_get_zext_value(val: &ValueRef) -> u64 {
246    unsafe { core::LLVMConstIntGetZExtValue(val.get_ref()) }
247}
248
249/// Obtain the sign extended value for an integer constant value.
250///
251/// # Details
252///
253/// Retrieves the sign-extended value of a constant integer as an `i64`.
254///
255/// This function wraps the `LLVMConstIntGetSExtValue` function from the LLVM core library. It returns the value
256/// of the constant integer represented by `ValueRef`, sign-extending it to 64 bits if necessary. This is useful when you need
257/// to extract the numeric value of a constant integer in a signed form that can be used in regular Rust code.
258///
259/// # Returns
260///
261/// Returns an `i64` that represents the sign-extended value of the constant integer.
262#[must_use]
263pub fn const_int_get_sext_value(val: &ValueRef) -> i64 {
264    unsafe { core::LLVMConstIntGetSExtValue(val.get_ref()) }
265}
266
267/// Obtain the double value for a floating point constant value.
268/// `losesInfo` indicates if some precision was lost in the conversion.
269///
270/// # Details
271///
272/// Retrieves the double-precision floating-point value from a constant floating-point value.
273///
274/// This function wraps the `LLVMConstRealGetDouble` function from the LLVM core library. It extracts the value
275/// of the constant floating-point represented by `ValueRef` as an `f64`. The function also indicates if any precision
276/// was lost during the conversion by setting the `losesInfo` flag.
277///
278/// # Returns
279///
280/// Returns a tuple containing:
281/// - An `f64` representing the double-precision floating-point value.
282/// - A `bool` flag (`losesInfo`) indicating whether some precision was lost in the conversion (`true` if precision was lost, `false` otherwise).
283#[must_use]
284pub fn const_real_get_double(val: &ValueRef) -> (f64, bool) {
285    let mut loses_info_c = 0;
286    let result = unsafe { core::LLVMConstRealGetDouble(val.get_ref(), &mut loses_info_c) };
287    (result, loses_info_c != 0)
288}