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