Skip to content

Commit

Permalink
Added Global Aliases (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
mrLSD authored Sep 26, 2024
1 parent b5718aa commit 0b3c9dc
Show file tree
Hide file tree
Showing 3 changed files with 180 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "llvm-lib"
version = "0.6.2"
version = "0.6.3"
authors = ["Evgeny Ukhanov <evgeny@ukhanov.org.ua>"]
description = "LLVM library with safe and flexibility in mind, without over complexity based on LLVM-C API"
categories = ["compilers", "development-tools", "development-tools::build-utils"]
Expand Down
178 changes: 178 additions & 0 deletions src/core/values/constants/global_aliases.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
use super::ValueRef;
use crate::core::module::ModuleRef;
use crate::core::types::TypeRef;
use crate::core::AddressSpace;
use crate::{CString, GetRef};
use llvm_sys::core;

impl ModuleRef {
/// Adds a `GlobalAlias` to the module.
///
/// This function wraps the `LLVMAddAlias2` function from the LLVM core library. It creates a new global alias within
/// the LLVM module represented by `self`. A global alias is an LLVM construct that allows one global value to alias
/// another, effectively creating an alternative name for the aliasee.
///
/// # Parameters
///
/// - `value_ty`: The LLVM type (`LLVMTypeRef`) of the alias.
/// - `addr_space`: The address space (`u32`) where the alias resides.
/// - `aliasee`: A reference to the `ValueRef` that the alias will point to.
/// - `name`: The name (`&str`) of the alias.
///
/// # Returns
///
/// Returns a `ValueRef` representing the newly created `GlobalAlias`. If the creation fails, the returned
/// `ValueRef` may be null, so users should ensure that the alias was created successfully.
#[must_use]
pub fn add_alias2(
&self,
value_ty: &TypeRef,
addr_space: &AddressSpace,
aliasee: &ValueRef,
name: &str,
) -> ValueRef {
let c_string = CString::from(name);
unsafe {
let alias = core::LLVMAddAlias2(
self.get_ref(),
value_ty.get_ref(),
***addr_space,
aliasee.get_ref(),
c_string.as_ptr(),
);
ValueRef::from(alias)
}
}

/// Retrieves a `GlobalAlias` by its name.
///
/// This function wraps the `LLVMGetNamedGlobalAlias` function from the LLVM core library. It searches the LLVM module
/// represented by `self` for a global alias with the specified name.
///
/// # Parameters
///
/// - `name`: The name (`&str`) of the alias to retrieve.
///
/// # Returns
///
/// Returns an `Option<ValueRef>` which is `Some(ValueRef)` if an alias with the given name exists, or `None` if
/// no such alias is found within the module.
#[must_use]
pub fn get_named_global_alias(&self, name: &str) -> Option<ValueRef> {
let c_string = CString::from(name);
unsafe {
let alias = core::LLVMGetNamedGlobalAlias(
self.get_ref(),
c_string.as_ptr(),
c_string.as_bytes().len(),
);
if alias.is_null() {
None
} else {
Some(ValueRef::from(alias))
}
}
}

/// Returns an iterator to the first `GlobalAlias` in the module.
///
/// This function wraps the `LLVMGetFirstGlobalAlias` function from the LLVM core library. It initializes an iterator
/// that starts at the first global alias within the LLVM module represented by `self`.
///
/// # Returns
///
/// Returns a `ValueRef` that can be used to traverse the global aliases in the module.
#[must_use]
pub fn get_first_global_alias(&self) -> ValueRef {
let val = unsafe { core::LLVMGetFirstGlobalAlias(self.get_ref()) };
ValueRef::from(val)
}

/// Returns an iterator to the last `GlobalAlias` in the module.
///
/// This function wraps the `LLVMGetLastGlobalAlias` function from the LLVM core library. It initializes an iterator
/// that starts at the last global alias within the LLVM module represented by `self`.
///
/// # Returns
///
/// Returns a `ValueRef` that can be used to traverse the global aliases in the module in reverse order.
#[must_use]
pub fn get_last_global_alias(&self) -> ValueRef {
let val = unsafe { core::LLVMGetLastGlobalAlias(self.get_ref()) };
ValueRef::from(val)
}
}

impl ValueRef {
/// Retrieves the next `GlobalAlias` in the module.
///
/// This function wraps the `LLVMGetNextGlobalAlias` function from the LLVM core library. It advances the iterator
/// to the next global alias relative to the current alias represented by `self`.
///
/// # Returns
///
/// Returns an `Option<ValueRef>` which is `Some(ValueRef)` if there is a next alias, or `None` if the current
/// alias is the last one in the module.
#[must_use]
pub fn get_next_global_alias(&self) -> Option<Self> {
unsafe {
let next = core::LLVMGetNextGlobalAlias(self.0);
if next.is_null() {
None
} else {
Some(Self(next))
}
}
}

/// Retrieves the previous `GlobalAlias` in the module.
///
/// This function wraps the `LLVMGetPreviousGlobalAlias` function from the LLVM core library. It moves the iterator
/// to the previous global alias relative to the current alias represented by `self`.
///
/// # Returns
///
/// Returns an `Option<ValueRef>` which is `Some(ValueRef)` if there is a previous alias, or `None` if the current
/// alias is the first one in the module.
#[must_use]
pub fn get_previous_global_alias(&self) -> Option<Self> {
unsafe {
let prev = core::LLVMGetPreviousGlobalAlias(self.0);
if prev.is_null() {
None
} else {
Some(Self(prev))
}
}
}

/// Retrieves the aliasee of this `GlobalAlias`.
///
/// This function wraps the `LLVMAliasGetAliasee` function from the LLVM core library. It obtains the value that
/// the alias represented by `self` is pointing to. The aliasee is typically another global value within the LLVM
/// module.
///
/// # Returns
///
/// Returns a `ValueRef` representing the aliasee of the alias. If the alias does not have a valid aliasee, the
/// returned `ValueRef` may be null.
#[must_use]
pub fn alias_get_aliasee(&self) -> Self {
unsafe { Self(core::LLVMAliasGetAliasee(self.0)) }
}

/// Sets the aliasee for an alias global value.
///
/// This function wraps the `LLVMAliasSetAliasee` function from the LLVM core library. It assigns a new aliasee
/// to the alias represented by `self`. An aliasee is the value that the alias points to, typically another global
/// value. By setting a new aliasee, you are changing the target of the alias.
///
/// # Parameters
///
/// - `new_aliasee`: A reference to the new global value (`ValueRef`) that the alias will point to.
pub fn alias_set_aliasee(&self, new_aliasee: &Self) {
unsafe {
core::LLVMAliasSetAliasee(self.0, new_aliasee.0);
}
}
}
1 change: 1 addition & 0 deletions src/core/values/constants/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

pub mod composite;
pub mod expressions;
pub mod global_aliases;
pub mod global_values;
pub mod global_variables;
pub mod scalar;
Expand Down

0 comments on commit 0b3c9dc

Please sign in to comment.