Skip to content

Commit

Permalink
Added docs for type traits, fn types, and enum types
Browse files Browse the repository at this point in the history
  • Loading branch information
TheDan64 committed Sep 26, 2018
1 parent 10837f0 commit eab5006
Show file tree
Hide file tree
Showing 9 changed files with 201 additions and 13 deletions.
45 changes: 41 additions & 4 deletions src/types/enums.rs
Expand Up @@ -6,10 +6,12 @@ use types::{IntType, VoidType, FunctionType, PointerType, VectorType, ArrayType,
use types::traits::AsTypeRef;

macro_rules! enum_type_set {
($enum_name:ident: $($args:ident),*) => (
($(#[$enum_attrs:meta])* $enum_name:ident: { $($(#[$variant_attrs:meta])* $args:ident,)+ }) => (
#[derive(Debug, EnumAsGetters, EnumIntoGetters, EnumIsA, PartialEq, Eq, Clone, Copy)]
$(#[$enum_attrs])*
pub enum $enum_name {
$(
$(#[$variant_attrs])*
$args($args),
)*
}
Expand All @@ -34,9 +36,43 @@ macro_rules! enum_type_set {
);
}

enum_type_set! {AnyTypeEnum: IntType, FunctionType, FloatType, PointerType, StructType, ArrayType, VoidType, VectorType}
enum_type_set! {BasicTypeEnum: IntType, FloatType, PointerType, StructType, ArrayType, VectorType}

enum_type_set! {
/// A wrapper for any `BasicType`, `VoidType`, or `FunctionType`.
AnyTypeEnum: {
/// A contiguous homogeneous container type.
ArrayType,
/// A floating point type.
FloatType,
/// A function return and parameter definition.
FunctionType,
/// An integer type.
IntType,
/// A pointer type.
PointerType,
/// A contiguous heterogeneous container type.
StructType,
/// A contiguous homogeneous "SIMD" container type.
VectorType,
/// A valueless type.
VoidType,
}
}
enum_type_set! {
/// A wrapper for any `BasicType`.
BasicTypeEnum: {
/// A contiguous homogeneous container type.
ArrayType,
/// A floating point type.
FloatType,
IntType,
/// A pointer type.
PointerType,
/// A contiguous heterogeneous container type.
StructType,
/// A contiguous homogeneous "SIMD" container type.
VectorType,
}
}

impl AnyTypeEnum {
pub(crate) fn new(type_: LLVMTypeRef) -> AnyTypeEnum {
Expand Down Expand Up @@ -66,6 +102,7 @@ impl AnyTypeEnum {
}
}

/// This will panic if type is a void or function type.
pub(crate) fn to_basic_type_enum(&self) -> BasicTypeEnum {
BasicTypeEnum::new(self.as_type_ref())
}
Expand Down
88 changes: 87 additions & 1 deletion src/types/fn_type.rs
Expand Up @@ -11,7 +11,7 @@ use types::traits::AsTypeRef;
use types::{PointerType, Type, BasicTypeEnum};

// REVIEW: Add a get_return_type() -> Option<BasicTypeEnum>?

/// A `FunctionType` is the type of a function variable.
#[derive(PartialEq, Eq, Clone, Copy)]
pub struct FunctionType {
fn_type: Type,
Expand All @@ -26,16 +26,59 @@ impl FunctionType {
}
}

/// Creates a `PointerType` with this `FunctionType` for its element type.
///
/// # Example
///
/// ```no_run
/// use inkwell::context::Context;
/// use inkwell::AddressSpace;
///
/// let context = Context::create();
/// let f32_type = context.f32_type();
/// let fn_type = f32_type.fn_type(&[], false);
/// let fn_ptr_type = fn_type.ptr_type(AddressSpace::Global);
///
/// assert_eq!(fn_ptr_type.get_element_type().into_function_type(), fn_type);
/// ```
pub fn ptr_type(&self, address_space: AddressSpace) -> PointerType {
self.fn_type.ptr_type(address_space)
}

/// Determines whether or not a `FunctionType` is a variadic function.
///
/// # Example
///
/// ```no_run
/// use inkwell::context::Context;
///
/// let context = Context::create();
/// let f32_type = context.f32_type();
/// let fn_type = f32_type.fn_type(&[], true);
///
/// assert!(fn_type.is_var_arg());
/// ```
pub fn is_var_arg(&self) -> bool {
unsafe {
LLVMIsFunctionVarArg(self.as_type_ref()) != 0
}
}

/// Gets param types this `FunctionType` has.
///
/// # Example
///
/// ```no_run
/// use inkwell::context::Context;
///
/// let context = Context::create();
/// let f32_type = context.f32_type();
/// let fn_type = f32_type.fn_type(&[f32_type.into()], true);
/// let param_types = fn_type.get_param_types();
///
/// assert_eq!(param_types.len(), 1);
/// assert_eq!(param_types[0].into_float_type(), f32_type);
/// ```
pub fn get_param_types(&self) -> Vec<BasicTypeEnum> {
let count = self.count_param_types();
let mut raw_vec: Vec<LLVMTypeRef> = Vec::with_capacity(count as usize);
Expand All @@ -52,13 +95,40 @@ impl FunctionType {
raw_vec.iter().map(|val| BasicTypeEnum::new(*val)).collect()
}

/// Counts the number of param types this `FunctionType` has.
///
/// # Example
///
/// ```no_run
/// use inkwell::context::Context;
///
/// let context = Context::create();
/// let f32_type = context.f32_type();
/// let fn_type = f32_type.fn_type(&[f32_type.into()], true);
///
/// assert_eq!(fn_type.count_param_types(), 1);
/// ```
pub fn count_param_types(&self) -> u32 {
unsafe {
LLVMCountParamTypes(self.as_type_ref())
}
}

// REVIEW: Always false -> const fn?
/// Gets whether or not this `FunctionType` is sized or not. This is likely
/// always false and may be removed in the future.
///
/// # Example
///
/// ```no_run
/// use inkwell::context::Context;
///
/// let context = Context::create();
/// let f32_type = context.f32_type();
/// let fn_type = f32_type.fn_type(&[], true);
///
/// assert!(!fn_type.is_sized());
/// ```
pub fn is_sized(&self) -> bool {
self.fn_type.is_sized()
}
Expand All @@ -68,15 +138,30 @@ impl FunctionType {
// self.fn_type.get_alignment()
// }

/// Gets a reference to the `Context` this `FunctionType` was created in.
///
/// # Example
///
/// ```no_run
/// use inkwell::context::Context;
///
/// let context = Context::create();
/// let f32_type = context.f32_type();
/// let fn_type = f32_type.fn_type(&[], true);
///
/// assert_eq!(*fn_type.get_context(), context);
/// ```
pub fn get_context(&self) -> ContextRef {
self.fn_type.get_context()
}

/// Prints the definition of a `FunctionType` to a `LLVMString`.
pub fn print_to_string(&self) -> LLVMString {
self.fn_type.print_to_string()
}

// See Type::print_to_stderr note on 5.0+ status
/// Prints the definition of an `IntType` to stderr. Not available in newer LLVM versions.
#[cfg(not(any(feature = "llvm3-6", feature = "llvm5-0")))]
pub fn print_to_stderr(&self) {
self.fn_type.print_to_stderr()
Expand All @@ -96,6 +181,7 @@ impl fmt::Debug for FunctionType {

f.debug_struct("FunctionType")
.field("address", &self.as_type_ref())
.field("is_var_args", &self.is_var_arg())
.field("llvm_type", &llvm_type)
.finish()
}
Expand Down
4 changes: 4 additions & 0 deletions src/types/mod.rs
@@ -1,14 +1,18 @@
//! A type is a classification which determines how data is used.

#[deny(missing_docs)]
mod array_type;
mod enums;
#[deny(missing_docs)]
mod float_type;
#[deny(missing_docs)]
mod fn_type;
#[deny(missing_docs)]
mod int_type;
#[deny(missing_docs)]
mod ptr_type;
mod struct_type;
#[deny(missing_docs)]
mod traits;
#[deny(missing_docs)]
mod vec_type;
Expand Down
2 changes: 1 addition & 1 deletion src/types/ptr_type.rs
Expand Up @@ -212,7 +212,7 @@ impl PointerType {
}

// REVIEW: Unlike the other const_zero functions, this one becomes null instead of a 0 value. Maybe remove?
/// Creates a constant *null* value of this `PointerType`.
/// Creates a constant null value of this `PointerType`.
/// This is practically the same as calling `const_null` for this particular type and
/// so this function may be removed in the future.
///
Expand Down
58 changes: 55 additions & 3 deletions src/types/struct_type.rs
Expand Up @@ -10,9 +10,10 @@ use AddressSpace;
use context::ContextRef;
use support::LLVMString;
use types::traits::AsTypeRef;
use types::{Type, BasicType, BasicTypeEnum, ArrayType, PointerType, FunctionType, VectorType};
use types::{Type, BasicTypeEnum, ArrayType, PointerType, FunctionType, VectorType};
use values::{ArrayValue, BasicValueEnum, StructValue, IntValue, AsValueRef};

/// A `StructType` is the type of a heterogeneous container of types.
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub struct StructType {
struct_type: Type,
Expand Down Expand Up @@ -61,6 +62,7 @@ impl StructType {
StructValue::new(value)
}

// REVIEW: Is this equivalent to context.struct_type?
pub fn const_struct(values: &[BasicValueEnum], packed: bool) -> StructValue {
let mut args: Vec<LLVMValueRef> = values.iter()
.map(|val| val.as_value_ref())
Expand All @@ -72,10 +74,45 @@ impl StructType {
StructValue::new(value)
}

/// Creates a null `StructValue` of this `StructType`.
/// It will be automatically assigned this `StructType`'s `Context`.
///
/// # Example
/// ```
/// use inkwell::context::Context;
/// use inkwell::types::{FloatType, StructType};
///
/// // Global Context
/// let f32_type = FloatType::f32_type();
/// let struct_type = StructType::struct_type(&[f32_type.into(), f32_type.into()], false);
/// let struct_null = struct_type.const_null();
///
/// assert!(struct_null.is_null());
///
/// // Custom Context
/// let context = Context::create();
/// let f32_type = context.f32_type();
/// let struct_type = context.struct_type(&[f32_type.into(), f32_type.into()], false);
/// let struct_null = struct_type.const_null();
///
/// assert!(struct_null.is_null());
/// ```
pub fn const_null(&self) -> StructValue {
StructValue::new(self.struct_type.const_null())
}

/// Creates a constant zero value of this `StructType`.
///
/// # Example
///
/// ```no_run
/// use inkwell::context::Context;
///
/// let context = Context::create();
/// let f32_type = context.f32_type();
/// let struct_type = context.struct_type(&[f32_type.into(), f32_type.into()], false);
/// let struct_zero = struct_type.const_zero();
/// ```
pub fn const_zero(&self) -> StructValue {
StructValue::new(self.struct_type.const_zero())
}
Expand Down Expand Up @@ -131,13 +168,26 @@ impl StructType {
self.struct_type.array_type(size)
}

/// Determines whether or not a `StructType` is packed.
///
/// # Example
///
/// ```no_run
/// use inkwell::context::Context;
///
/// let context = Context::create();
/// let f32_type = context.f32_type();
/// let struct_type = context.struct_type(&[f32_type.into(), f32_type.into()], false);
///
/// assert!(struct_type.is_packed());
/// ```
pub fn is_packed(&self) -> bool {
unsafe {
LLVMIsPackedStruct(self.as_type_ref()) == 1
}
}

// TODO: Worth documenting that a sturct is opaque when types are not
// TODOC: Worth documenting that a struct is opaque when types are not
// yet assigned (empty array to struct_type)
pub fn is_opaque(&self) -> bool {
unsafe {
Expand Down Expand Up @@ -181,11 +231,13 @@ impl StructType {
raw_vec.iter().map(|val| BasicTypeEnum::new(*val)).collect()
}

/// Prints the definition of a `VectorType` to a `LLVMString`.
pub fn print_to_string(&self) -> LLVMString {
self.struct_type.print_to_string()
}

// See Type::print_to_stderr note on 5.0+ status
/// Prints the definition of an `StructType` to stderr. Not available in newer LLVM versions.
#[cfg(not(any(feature = "llvm3-6", feature = "llvm5-0")))]
pub fn print_to_stderr(&self) {
self.struct_type.print_to_stderr()
Expand All @@ -198,7 +250,7 @@ impl StructType {
// REVIEW: SubTypes should allow this to only be implemented for StructType<Opaque> one day
// but would have to return StructType<Tys>
// REVIEW: What happens if called with &[]? Should that still be opaque? Does the call break?
pub fn set_body(&self, field_types: &[&BasicType], packed: bool) -> bool {
pub fn set_body(&self, field_types: &[BasicTypeEnum], packed: bool) -> bool {
let is_opaque = self.is_opaque();
let mut field_types: Vec<LLVMTypeRef> = field_types.iter()
.map(|val| val.as_type_ref())
Expand Down

0 comments on commit eab5006

Please sign in to comment.