llvm_lib/core/values/constants/global_values.rs
1use super::ValueRef;
2use crate::core::module::{MetadataRef, ModuleRef};
3use crate::core::types::TypeRef;
4use crate::core::{DLLStorageClass, Linkage, UnnamedAddr, Visibility};
5use crate::{CStr, CString, CUint, GetRef};
6use llvm_sys::core;
7use llvm_sys::prelude::LLVMValueMetadataEntry;
8
9/// Wrapper for `LLVMValueMetadataEntry`
10#[derive(Debug)]
11pub struct ValueMetadataEntry(LLVMValueMetadataEntry);
12
13impl From<LLVMValueMetadataEntry> for ValueMetadataEntry {
14 fn from(value: LLVMValueMetadataEntry) -> Self {
15 Self(value)
16 }
17}
18
19impl GetRef for ValueMetadataEntry {
20 type RawRef = LLVMValueMetadataEntry;
21 fn get_ref(&self) -> Self::RawRef {
22 self.0
23 }
24}
25
26/// Get the module that contains the global value.
27///
28/// ## Details
29///
30/// Retrieves the parent module of a global value.
31///
32/// This function wraps the `LLVMGetGlobalParent` function from the LLVM core library. It returns the `ModuleRef`
33/// representing the parent module in which the global value represented by `ValueRef` is defined. The parent module
34/// contains all the global values (such as functions and global variables) that are part of a given LLVM module.
35///
36/// # Returns
37///
38/// Returns a `ModuleRef` representing the parent module of the global value.
39#[must_use]
40pub fn get_global_parent(val: &ValueRef) -> ModuleRef {
41 unsafe { ModuleRef::from(core::LLVMGetGlobalParent(val.get_ref())) }
42}
43
44/// Determine if the global value is a declaration.
45///
46/// ## Details
47///
48/// Checks if the global value is a declaration.
49///
50/// This function wraps the `LLVMIsDeclaration` function from the LLVM core library. It determines whether
51/// the global value represented by `ValueRef` is merely a declaration (i.e., it declares the existence of a symbol
52/// but does not define it). Declarations are often used to reference functions or variables that are defined
53/// in another module or later in the same module.
54///
55/// # Returns
56///
57/// Returns `true` if the global value is a declaration, otherwise returns `false`.
58#[must_use]
59pub fn is_declaration(val: &ValueRef) -> bool {
60 unsafe { core::LLVMIsDeclaration(val.get_ref()) != 0 }
61}
62
63/// Get the linkage of the global value.
64///
65/// ## Details
66///
67/// Sets the linkage type for a global value.
68///
69/// This function wraps the `LLVMSetLinkage` function from the LLVM core library. It configures the linkage type
70/// for the global value represented by `ValueRef`. The linkage type determines how the symbol is treated during the
71/// linking process, particularly in relation to how it can be combined with other symbols and whether it is visible
72/// outside of the module.
73///
74/// # Parameters
75///
76/// - `linkage`: A `Linkage` enum value that specifies the linkage type for the global value. Common linkage types include:
77/// - `ExternalLinkage`: The symbol is visible to other modules and can be linked against.
78/// - `InternalLinkage`: The symbol is only visible within the current module.
79/// - `PrivateLinkage`: The symbol is local to the file and not exposed to other modules.
80/// - `LinkOnceODRLinkage`: Ensures that the symbol is defined only once across all modules, complying with the One Definition Rule (ODR).
81#[must_use]
82pub fn get_linkage(val: &ValueRef) -> Linkage {
83 unsafe { crate::core::Linkage::from(core::LLVMGetLinkage(val.get_ref())) }
84}
85
86/// Set the linkage of the global value.
87///
88/// ## Details
89///
90///
91pub fn set_linkage(val: &ValueRef, linkage: Linkage) {
92 unsafe { core::LLVMSetLinkage(val.get_ref(), linkage.into()) }
93}
94
95/// Get the section of the global value.
96///
97/// ## Details
98///
99/// Retrieves the section name in which a global value is placed.
100///
101/// This function wraps the `LLVMGetSection` function from the LLVM core library. It returns the name of the section
102/// where the global value represented by `ValueRef` is placed. Sections are used to organize global values in the object file,
103/// allowing the linker and loader to place related values together or handle them in a specific way.
104///
105/// # Returns
106///
107/// Returns an `Option<String>`:
108/// - `Some(String)` containing the name of the section if the global value is placed in a specific section.
109/// - `None` if the global value is not associated with any section.
110#[must_use]
111pub fn get_section(val: &ValueRef) -> Option<String> {
112 unsafe {
113 let section = core::LLVMGetSection(val.get_ref());
114 if section.is_null() {
115 None
116 } else {
117 Some(CStr::new(section).to_string())
118 }
119 }
120}
121
122/// Set the section of the global value.
123///
124/// ## Details
125///
126/// Sets the section in which a global value should be placed.
127///
128/// This function wraps the `LLVMSetSection` function from the LLVM core library. It specifies the section name
129/// for the global value represented by `ValueRef`. Sections are used to organize global values in the object file, allowing
130/// the linker and loader to place related values together or handle them in a specific way.
131///
132/// # Parameters
133///
134/// - `section`: A string slice (`&str`) representing the name of the section where the global value should be placed.
135pub fn set_section(val: &ValueRef, section: &str) {
136 let c_section = CString::from(section);
137 unsafe {
138 core::LLVMSetSection(val.get_ref(), c_section.as_ptr());
139 }
140}
141
142/// Get the visibility of the global value.
143///
144/// ## Details
145///
146/// Retrieves the visibility attribute of a global value.
147///
148/// This function wraps the `LLVMGetVisibility` function from the LLVM core library. It returns the visibility
149/// attribute of the global value represented by `ValueRef`. The visibility attribute determines how the symbol is
150/// treated by the linker and whether it can be seen by other modules or shared libraries.
151///
152/// # Returns
153///
154/// Returns a `Visibility` enum value representing the visibility attribute of the global value:
155/// - `DefaultVisibility`: The symbol is visible to other modules.
156/// - `HiddenVisibility`: The symbol is not visible to other modules or shared libraries.
157/// - `ProtectedVisibility`: The symbol is visible to other modules but cannot be overridden.
158#[must_use]
159pub fn get_visibility(val: &ValueRef) -> Visibility {
160 unsafe { crate::core::Visibility::from(core::LLVMGetVisibility(val.get_ref())) }
161}
162
163/// Set the visibility of the global value.
164///
165/// ## Details
166///
167/// Sets the visibility attribute for a global value.
168///
169/// This function wraps the `LLVMSetVisibility` function from the LLVM core library. It configures the visibility
170/// attribute for the global value represented by `ValueRef`. The visibility attribute determines how the symbol is
171/// treated by the linker and whether it can be seen by other modules or shared libraries.
172///
173/// # Parameters
174///
175/// - `visibility`: A `Visibility` enum value that specifies the visibility of the global value:
176/// - `DefaultVisibility`: The symbol is visible to other modules.
177/// - `HiddenVisibility`: The symbol is not visible to other modules or shared libraries.
178/// - `ProtectedVisibility`: The symbol is visible to other modules but cannot be overridden.
179pub fn set_visibility(val: &ValueRef, visibility: Visibility) {
180 unsafe {
181 core::LLVMSetVisibility(val.get_ref(), visibility.into());
182 }
183}
184
185/// Get the DLL storage class of a global value.
186///
187/// ## Details
188///
189/// Retrieves the DLL storage class of a global value.
190///
191/// This function wraps the `LLVMGetDLLStorageClass` function from the LLVM core library. It returns the
192/// `DLLStorageClass` of the global value represented by `ValueRef`. The DLL storage class determines how the global
193/// value is treated in relation to dynamic link libraries (DLLs) on platforms like Windows.
194///
195/// # Returns
196///
197/// Returns a `DLLStorageClass` enum value representing the DLL storage class of the global value:
198/// - `DefaultStorageClass`: The symbol is treated as a normal global symbol, not specifically marked for import or export from a DLL.
199/// - `DLLImportStorageClass`: The symbol is imported from a DLL.
200/// - `DLLExportStorageClass`: The symbol is exported to a DLL.
201#[must_use]
202pub fn get_dll_storage_class(val: &ValueRef) -> DLLStorageClass {
203 unsafe { DLLStorageClass::from(core::LLVMGetDLLStorageClass(val.get_ref())) }
204}
205
206/// Set the DLL storage class of a global value.
207///
208/// ## Details
209///
210/// Sets the DLL storage class for a global value.
211///
212/// This function wraps the `LLVMSetDLLStorageClass` function from the LLVM core library. It configures the DLL storage class
213/// for the global value represented by `ValueRef`. The `DLLStorageClass` attribute determines how the global value is treated
214/// in relation to dynamic link libraries (DLLs) on platforms like Windows.
215///
216/// # Parameters
217///
218/// - `class`: A `DLLStorageClass` enum value that specifies the DLL storage class for the global value.
219/// - `DefaultStorageClass`: The symbol is treated as a normal global symbol, not specifically marked for import or export from a DLL.
220/// - `DLLImportStorageClass`: The symbol is imported from a DLL.
221/// - `DLLExportStorageClass`: The symbol is exported to a DLL.
222pub fn set_dll_storage_class(val: &ValueRef, class: DLLStorageClass) {
223 unsafe {
224 core::LLVMSetDLLStorageClass(val.get_ref(), class.into());
225 }
226}
227
228/// Get the unnamed address of a global value.
229///
230/// ## Details
231///
232/// Retrieves the unnamed address attribute of a global value.
233///
234/// This function wraps the `LLVMGetUnnamedAddress` function from the LLVM core library. It returns the
235/// `UnnamedAddr` attribute of the global value represented by `ValueRef`. This attribute specifies whether the address
236/// of the global value is significant, which can influence certain optimizations in LLVM.
237///
238/// # Returns
239///
240/// Returns an `UnnamedAddr` enum value representing the unnamed address attribute of the global value:
241/// - `NoUnnamedAddr`: The address of the global value is significant and must be unique.
242/// - `LocalUnnamedAddr`: The address is not significant within the module, allowing certain optimizations.
243/// - `GlobalUnnamedAddr`: The address is not significant across the entire program, enabling more aggressive optimizations.
244#[must_use]
245pub fn get_unnamed_address(val: &ValueRef) -> UnnamedAddr {
246 unsafe { UnnamedAddr::from(core::LLVMGetUnnamedAddress(val.get_ref())) }
247}
248
249/// Set the unnamed address of a global value.
250///
251/// ## Details
252///
253/// Sets the unnamed address attribute for a global value.
254///
255/// This function wraps the `LLVMSetUnnamedAddress` function from the LLVM core library. It configures the
256/// unnamed address attribute for the global value represented by `ValueRef`. The `UnnamedAddr` attribute specifies
257/// whether the address of the global value is significant, which can influence certain optimizations in LLVM.
258///
259/// # Parameters
260///
261/// - `unnamed_addr`: An `UnnamedAddr` enum value that specifies the unnamed address attribute for the global value.
262/// - `NoUnnamedAddr`: The address of the global value is significant and must be unique.
263/// - `LocalUnnamedAddr`: The address is not significant within the module, allowing certain optimizations.
264/// - `GlobalUnnamedAddr`: The address is not significant across the entire program, enabling more aggressive optimizations.
265pub fn set_unnamed_address(val: &ValueRef, unnamed_addr: UnnamedAddr) {
266 unsafe {
267 core::LLVMSetUnnamedAddress(val.get_ref(), unnamed_addr.into());
268 }
269}
270
271/// Returns the "value type" of a global value. This differs from the formal
272/// type of a global value, which is always a pointer type.
273///
274/// ## Details
275///
276/// Retrieves the type of the global value.
277///
278/// This function wraps the `LLVMGlobalGetValueType` function from the LLVM core library. It returns the
279/// `TypeRef` representing the type of the global value associated with `ValueRef`. Knowing the type of the global value
280/// is essential for understanding what kind of data it holds or operates on, as well as for performing type-specific
281/// operations or optimizations.
282///
283/// # Returns
284///
285/// Returns a `TypeRef` representing the type of the global value.
286#[must_use]
287pub fn get_value_type(val: &ValueRef) -> TypeRef {
288 unsafe { TypeRef::from(core::LLVMGlobalGetValueType(val.get_ref())) }
289}
290
291/// Obtain the preferred alignment of the value.
292///
293/// ## Details
294///
295/// Retrieves the alignment of a global value in bytes.
296///
297/// This function wraps the `LLVMGetAlignment` function from the LLVM core library. It returns the alignment
298/// requirement of the global value represented by `ValueRef`, in terms of the number of bytes. Knowing the alignment
299/// can be useful for understanding how the global value is laid out in memory and ensuring that it meets the
300/// requirements of the target architecture.
301///
302/// # Returns
303///
304/// Returns a `u32` representing the alignment of the global value in bytes.
305#[must_use]
306pub fn get_alignment(val: &ValueRef) -> u32 {
307 unsafe { core::LLVMGetAlignment(val.get_ref()) as u32 }
308}
309
310/// Set the preferred alignment of the value.
311///
312/// ## Details
313///
314/// Sets the alignment for a global value in bytes.
315///
316/// This function wraps the `LLVMSetAlignment` function from the LLVM core library. It specifies the alignment
317/// requirement for the global value represented by `ValueRef`, in terms of the number of bytes. Proper alignment can be
318/// important for performance, particularly in low-level systems programming, where misaligned accesses can cause
319/// performance penalties or even hardware exceptions.
320///
321/// # Parameters
322///
323/// - `bytes`: A `u32` value representing the desired alignment in bytes. This value must be a power of two.
324pub fn set_alignment(val: &ValueRef, bytes: u32) {
325 unsafe {
326 core::LLVMSetAlignment(val.get_ref(), *CUint::from(bytes));
327 }
328}
329
330/// Sets a metadata attachment, erasing the existing metadata attachment if
331/// it already exists for the given kind.
332///
333/// ## Details
334///
335/// Sets metadata of a specific kind for a global value.
336///
337/// This function wraps the `LLVMGlobalSetMetadata` function from the LLVM core library. It attaches metadata of the
338/// specified kind to the global value represented by `ValueRef`. If metadata of this kind already exists, it will be replaced
339/// with the new metadata provided. Metadata in LLVM is used to attach additional information to global values, such as
340/// functions or variables, which can be useful for debugging, optimization, or other purposes.
341///
342/// # Parameters
343///
344/// - `kind`: A `u32` representing the kind of metadata to be set. The kind ID specifies the category or type of the metadata.
345/// - `md`: A `MetadataRef` representing the metadata to be attached to the global value.
346pub fn global_set_metadata(val: &ValueRef, kind: u32, md: &MetadataRef) {
347 unsafe {
348 core::LLVMGlobalSetMetadata(val.get_ref(), kind, md.get_ref());
349 }
350}
351
352/// Erases a metadata attachment of the given kind if it exists.
353///
354/// ## Details
355///
356/// Erases metadata of a specific kind from a global value.
357///
358/// This function wraps the `LLVMGlobalEraseMetadata` function from the LLVM core library. It removes the metadata
359/// entry of the specified kind associated with the global value represented by `ValueRef`. If the global value has multiple
360/// metadata entries, only the entry matching the specified kind will be erased, leaving other metadata intact.
361///
362/// # Parameters
363///
364/// - `kind`: A `u32` representing the kind of metadata to be erased. The kind ID specifies the category or type of the metadata.
365pub fn global_erase_metadata(val: &ValueRef, kind: u32) {
366 unsafe {
367 core::LLVMGlobalEraseMetadata(val.get_ref(), *CUint::from(kind));
368 }
369}
370
371/// Removes all metadata attachments from this value.
372///
373/// ## Details
374///
375/// Clears all metadata attached to a global value.
376///
377/// This function wraps the `LLVMGlobalClearMetadata` function from the LLVM core library. It removes all metadata
378/// entries associated with the global value represented by `ValueRef`. This operation effectively detaches any metadata
379/// from the global value, which might be useful in scenarios where the metadata is no longer needed or should be reset.
380pub fn global_clear_metadata(val: &ValueRef) {
381 unsafe {
382 core::LLVMGlobalClearMetadata(val.get_ref());
383 }
384}
385
386/// Destroys value metadata entries.
387///
388/// ## Panics
389/// This function is purely informative and panics with a message about the call
390/// being unavailable. Since there are no cases in which it can be called in
391/// safe code. For raw access, if there is such a need, must be called
392/// `LLVMDisposeValueMetadataEntries` directly.
393pub fn dispose_value_metadata_entries(_entries: &[ValueMetadataEntry]) {
394 unreachable!("LLVMDisposeValueMetadataEntries is unsafe adn restricted to operated to operate directly for safe code");
395}
396
397/// Retrieves an array of metadata entries representing the metadata attached to this value.
398///
399/// ## Details
400///
401/// Copies all metadata attached to a global value and returns it as a vector of `ValueMetadataEntry`.
402///
403/// This function wraps the `LLVMGlobalCopyAllMetadata` function from the LLVM core library. It retrieves all metadata
404/// entries associated with the global value represented by `ValueRef` and returns them as a vector of `ValueMetadataEntry`.
405/// Metadata in LLVM is used to attach additional information to various constructs, such as functions or global variables,
406/// which can be useful for debugging, optimization, or other purposes.
407///
408/// After copying the metadata entries, the function ensures that any allocated memory for the metadata entries is correctly
409/// freed by calling ``LLVMDisposeValueMetadataEntries``.
410///
411/// # Returns
412///
413/// Returns a `Vec<ValueMetadataEntry>` containing all metadata entries attached to the global value. If no metadata is
414/// attached, an empty vector is returned.
415#[must_use]
416pub fn global_copy_all_metadata(val: &ValueRef) -> Vec<ValueMetadataEntry> {
417 let mut num_entries: usize = 0;
418 let entries_ptr = unsafe { core::LLVMGlobalCopyAllMetadata(val.get_ref(), &mut num_entries) };
419
420 if entries_ptr.is_null() {
421 return Vec::new();
422 }
423 let entries_slice = unsafe { std::slice::from_raw_parts(entries_ptr, num_entries) };
424
425 let entries = entries_slice
426 .iter()
427 .map(|&entry| ValueMetadataEntry::from(entry))
428 .collect::<Vec<_>>();
429
430 // Free allocated memory
431 unsafe {
432 core::LLVMDisposeValueMetadataEntries(entries_ptr);
433 }
434
435 entries
436}
437
438/// Returns the kind of a value metadata entry at a specific index.
439///
440/// ## Details
441///
442/// Retrieves the metadata kind ID for a specific entry in a list of value metadata entries.
443///
444/// This function wraps the `LLVMValueMetadataEntriesGetKind` function from the LLVM core library. It retrieves
445/// the kind ID of the metadata entry at the specified index within the provided vector of `ValueMetadataEntry`.
446/// Metadata kinds in LLVM are used to categorize the type of metadata, allowing different kinds of information
447/// to be attached to values.
448///
449/// # Parameters
450///
451/// - `value_metadata_entries`: A vector of `ValueMetadataEntry` from which the metadata kind ID will be retrieved.
452/// - `index`: The index of the metadata entry within the vector for which the kind ID is requested.
453///
454/// # Returns
455///
456/// Returns a `u32` representing the metadata kind ID for the specified entry.
457///
458/// # Panics
459///
460/// The function may panic if the provided index is out of bounds for the vector, depending on how the underlying
461/// LLVM function handles invalid indices.
462#[must_use]
463pub fn value_metadata_entries_get_kind(
464 value_metadata_entries: &[ValueMetadataEntry],
465 index: u32,
466) -> u32 {
467 let entries_ptr = crate::to_mut_ptr!(value_metadata_entries);
468 unsafe { core::LLVMValueMetadataEntriesGetKind(entries_ptr, *CUint::from(index)) }
469}
470
471/// Returns the underlying metadata node of a value metadata entry at a specific index.
472///
473/// ## Details
474///
475/// Retrieves the metadata reference for a specific entry in a list of value metadata entries.
476///
477/// This function wraps the `LLVMValueMetadataEntriesGetMetadata` function from the LLVM core library. It retrieves
478/// the `MetadataRef` associated with the metadata entry at the specified index within the provided vector of `ValueMetadataEntry`.
479/// This allows you to access the metadata attached to a global value or other LLVM constructs.
480///
481/// # Parameters
482///
483/// - `value_metadata_entries`: A vector of `ValueMetadataEntry` from which the metadata reference will be retrieved.
484/// - `index`: The index of the metadata entry within the vector for which the metadata reference is requested.
485///
486/// # Returns
487///
488/// Returns a `MetadataRef` representing the metadata associated with the specified entry.
489///
490/// # Panics
491///
492/// The function may panic if the provided index is out of bounds for the vector, depending on how the underlying
493/// LLVM function handles invalid indices.
494#[must_use]
495pub fn value_metadata_entries_get_metadata(
496 value_metadata_entries: &[ValueMetadataEntry],
497 index: u32,
498) -> MetadataRef {
499 let entries_ptr = crate::to_mut_ptr!(value_metadata_entries);
500 unsafe {
501 MetadataRef::from(core::LLVMValueMetadataEntriesGetMetadata(
502 entries_ptr,
503 *CUint::from(index),
504 ))
505 }
506}