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
use crate::core::context::ContextRef;
use crate::core::types::TypeRef;
use crate::{CUint, GetRef};
use llvm_sys::core;
use llvm_sys::prelude::LLVMTypeRef;
/// These functions relate to `SequentialTypeRef` of `LLVMTypeRef` instances.
///
/// Sequential types represents "arrays" of types. This is a super class
/// for array, vector, and pointer types.
#[derive(Debug)]
pub struct SequentialTypeRef(LLVMTypeRef);
impl From<LLVMTypeRef> for SequentialTypeRef {
fn from(value: LLVMTypeRef) -> Self {
Self(value)
}
}
impl GetRef for SequentialTypeRef {
type RawRef = LLVMTypeRef;
fn get_ref(&self) -> Self::RawRef {
self.0
}
}
impl SequentialTypeRef {
/// Obtain the element type of array or vector type.
#[must_use]
pub fn get_element_type(&self) -> TypeRef {
unsafe { TypeRef(core::LLVMGetElementType(self.0)) }
}
/// Returns type's subtypes
#[must_use]
pub fn get_subtypes(&self) -> Vec<TypeRef> {
let count = self.get_num_contained_types() as usize;
let mut subtypes: Vec<LLVMTypeRef> = Vec::with_capacity(count);
unsafe {
core::LLVMGetSubtypes(self.0, subtypes.as_mut_ptr());
subtypes.set_len(count);
}
subtypes.into_iter().map(TypeRef).collect()
}
/// Return the number of types in the derived type.
#[must_use]
pub fn get_num_contained_types(&self) -> u32 {
unsafe { core::LLVMGetNumContainedTypes(self.0) }
}
/// Create a fixed size array type that refers to a specific type.
///
/// The created type will exist in the context that its element type exists in.
#[must_use]
pub fn array_type2(element_type: &TypeRef, element_count: u64) -> Self {
unsafe { Self(core::LLVMArrayType2(element_type.0, element_count)) }
}
/// Obtain the length of an array type.
///
/// This only works on types that represent arrays.
#[must_use]
pub fn get_array_length2(&self) -> u64 {
unsafe { core::LLVMGetArrayLength2(self.0) }
}
/// Create a pointer type that points to a defined type.
///
/// The created type will exist in the context that its pointee type exists in.
#[must_use]
pub fn pointer_type(element_type: &TypeRef, address_space: u32) -> Self {
unsafe { Self(core::LLVMPointerType(element_type.0, address_space)) }
}
/// Determine whether a pointer is opaque.
///
/// True if this is an instance of an opaque `PointerType`.
#[must_use]
pub fn is_pointer_opaque(&self) -> bool {
unsafe { core::LLVMPointerTypeIsOpaque(self.0) != 0 }
}
/// Create an opaque pointer type in a context.
#[must_use]
pub fn opaque_pointer_type_in_context(context: &ContextRef, address_space: u32) -> Self {
unsafe {
Self(core::LLVMPointerTypeInContext(
context.get_ref(),
address_space,
))
}
}
/// Obtain the address space of a pointer type.
///
/// This only works on types that represent pointers.
#[must_use]
pub fn get_pointer_address_space(&self) -> u32 {
unsafe { core::LLVMGetPointerAddressSpace(self.0) }
}
/// Create a vector type that contains a defined type and has a specific
/// number of elements.
///
/// The created type will exist in the context that its element type exists in.
#[must_use]
pub fn vector_type(element_type: &TypeRef, element_count: u32) -> Self {
unsafe {
Self(core::LLVMVectorType(
element_type.0,
*CUint::from(element_count),
))
}
}
/// Create a vector type that contains a defined type and has a scalable
/// number of elements.
///
/// The created type will exist in the context that its element type
/// exists in.
#[must_use]
pub fn scalable_vector_type(element_type: &TypeRef, element_count: u32) -> Self {
unsafe {
Self(core::LLVMScalableVectorType(
element_type.0,
*CUint::from(element_count),
))
}
}
/// Obtain the (possibly scalable) number of elements in a vector type.
///
/// This only works on types that represent vectors (fixed or scalable).
#[must_use]
pub fn get_vector_size(&self) -> u32 {
unsafe { core::LLVMGetVectorSize(self.0) }
}
}