From f9cb69261a8cca0aad8270787cd03c9a566141f7 Mon Sep 17 00:00:00 2001 From: Daniel Kolsoi Date: Sat, 22 Sep 2018 09:16:45 -0400 Subject: [PATCH] Added ArrayType & PointerType docs --- src/types/array_type.rs | 186 ++++++++++++++++++++++++++++++++++ src/types/float_type.rs | 3 +- src/types/int_type.rs | 2 +- src/types/mod.rs | 2 + src/types/ptr_type.rs | 214 ++++++++++++++++++++++++++++++++++++++++ src/types/vec_type.rs | 15 +-- 6 files changed, 413 insertions(+), 9 deletions(-) diff --git a/src/types/array_type.rs b/src/types/array_type.rs index fdc7b65cfd8..eb9b474a1c1 100644 --- a/src/types/array_type.rs +++ b/src/types/array_type.rs @@ -8,6 +8,7 @@ use types::traits::AsTypeRef; use types::{Type, BasicTypeEnum, PointerType, FunctionType}; use values::{AsValueRef, ArrayValue, PointerValue, IntValue}; +/// An `ArrayType` is the type of contiguous constants or variables. #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub struct ArrayType { array_type: Type, @@ -23,11 +24,36 @@ impl ArrayType { } // REVIEW: Can be unsized if inner type is opaque struct + /// Gets whether or not this `ArrayType` is sized or not. + /// + /// # Example + /// + /// ```no_run + /// use inkwell::context::Context; + /// + /// let context = Context::create(); + /// let i8_type = context.i8_type(); + /// let i8_array_type = i8_type.array_type(3); + /// + /// assert!(i8_array_type.is_sized()); + /// ``` pub fn is_sized(&self) -> bool { self.array_type.is_sized() } // TODO: impl only for ArrayType> + /// Gets the size of this `ArrayType`. Value may vary depending on the target architecture. + /// + /// # Example + /// + /// ```no_run + /// use inkwell::context::Context; + /// + /// let context = Context::create(); + /// let i8_type = context.i8_type(); + /// let i8_array_type = i8_type.array_type(3); + /// let i8_array_type_size = i8_array_type.size_of(); + /// ``` pub fn size_of(&self) -> Option { if self.is_sized() { return Some(self.array_type.size_of()) @@ -36,26 +62,107 @@ impl ArrayType { None } + /// Gets the alignment of this `ArrayType`. Value may vary depending on the target architecture. + /// + /// # Example + /// + /// ```no_run + /// use inkwell::context::Context; + /// + /// let context = Context::create(); + /// let i8_type = context.i8_type(); + /// let i8_array_type = i8_type.array_type(3); + /// let i8_array_type_alignment = i8_array_type.get_alignment(); + /// ``` pub fn get_alignment(&self) -> IntValue { self.array_type.get_alignment() } + /// Creates a `PointerType` with this `ArrayType` for its element type. + /// + /// # Example + /// + /// ```no_run + /// use inkwell::context::Context; + /// use inkwell::AddressSpace; + /// + /// let context = Context::create(); + /// let i8_type = context.i8_type(); + /// let i8_array_type = i8_type.array_type(3); + /// let i8_array_ptr_type = i8_array_type.ptr_type(AddressSpace::Generic); + /// + /// assert_eq!(i8_array_ptr_type.get_element_type().into_array_type(), i8_array_type); + /// ``` pub fn ptr_type(&self, address_space: AddressSpace) -> PointerType { self.array_type.ptr_type(address_space) } + /// Gets a reference to the `Context` this `ArrayType` was created in. + /// + /// # Example + /// + /// ```no_run + /// use inkwell::context::Context; + /// + /// let context = Context::create(); + /// let i8_type = context.i8_type(); + /// let i8_array_type = i8_type.array_type(3); + /// + /// assert_eq!(*i8_array_type.get_context(), context); + /// ``` pub fn get_context(&self) -> ContextRef { self.array_type.get_context() } + /// Creates a `FunctionType` with this `ArrayType` for its return type. + /// + /// # Example + /// + /// ```no_run + /// use inkwell::context::Context; + /// + /// let context = Context::create(); + /// let i8_type = context.i8_type(); + /// let i8_array_type = i8_type.array_type(3); + /// let fn_type = i8_array_type.fn_type(&[], false); + /// ``` pub fn fn_type(&self, param_types: &[BasicTypeEnum], is_var_args: bool) -> FunctionType { self.array_type.fn_type(param_types, is_var_args) } + /// Creates an `ArrayType` with this `ArrayType` for its element type. + /// + /// # Example + /// + /// ```no_run + /// use inkwell::context::Context; + /// + /// let context = Context::create(); + /// let i8_type = context.i8_type(); + /// let i8_array_type = i8_type.array_type(3); + /// let i8_array_array_type = i8_array_type.array_type(3); + /// + /// assert_eq!(i8_array_array_type.len(), 3); + /// assert_eq!(i8_array_array_type.get_element_type().into_array_type(), i8_array_type); + /// ``` pub fn array_type(&self, size: u32) -> ArrayType { self.array_type.array_type(size) } + /// Creates a constant `ArrayValue`. + /// + /// # Example + /// ```no_run + /// use inkwell::context::Context; + /// + /// let context = Context::create(); + /// let f32_type = context.f32_type(); + /// let f32_array_type = f32_type.array_type(3); + /// let f32_array_val = f32_array_type.const_null(); + /// let f32_array_array = f32_array_type.const_array(&[f32_array_val, f32_array_val]); + /// + /// assert!(f32_array_array.is_const()); + /// ``` pub fn const_array(&self, values: &[ArrayValue]) -> ArrayValue { let mut values: Vec = values.iter() .map(|val| val.as_value_ref()) @@ -67,10 +174,48 @@ impl ArrayType { ArrayValue::new(value) } + /// Creates a `PointerValue` representing a constant value of zero (null pointer) pointing to this `ArrayType`. + /// It will be automatically assigned this `ArrayType`'s `Context`. + /// + /// # Example + /// ``` + /// use inkwell::context::Context; + /// use inkwell::types::FloatType; + /// use inkwell::AddressSpace; + /// + /// // Global Context + /// let f32_type = FloatType::f32_type(); + /// let f32_ptr_type = f32_type.ptr_type(AddressSpace::Generic); + /// let f32_ptr_ptr_value = f32_ptr_type.const_null_ptr(); + /// + /// assert!(f32_ptr_ptr_value.is_null()); + /// + /// // Custom Context + /// let context = Context::create(); + /// let f32_type = context.f32_type(); + /// let f32_ptr_type = f32_type.ptr_type(AddressSpace::Generic); + /// let f32_ptr_ptr_value = f32_ptr_type.const_null_ptr(); + /// + /// assert!(f32_ptr_ptr_value.is_null()); + /// ``` pub fn const_null_ptr(&self) -> PointerValue { self.array_type.const_null_ptr() } + /// Creates a constant null (zero) value of this `ArrayType`. + /// + /// # Example + /// + /// ```no_run + /// use inkwell::context::Context; + /// + /// let context = Context::create(); + /// let i8_type = context.i8_type(); + /// let i8_array_type = i8_type.array_type(3); + /// let i8_array_zero = i8_array_type.const_null(); + /// + /// assert!(i8_array_zero.is_null()); + /// ``` pub fn const_null(&self) -> ArrayValue { let null = unsafe { LLVMConstNull(self.as_type_ref()) @@ -79,27 +224,68 @@ impl ArrayType { ArrayValue::new(null) } + /// Gets the length of this `ArrayType`. + /// + /// # Example + /// + /// ```no_run + /// use inkwell::context::Context; + /// + /// let context = Context::create(); + /// let i8_type = context.i8_type(); + /// let i8_array_type = i8_type.array_type(3); + /// + /// assert_eq!(i8_array_type.len(), 3); + /// ``` pub fn len(&self) -> u32 { unsafe { LLVMGetArrayLength(self.as_type_ref()) } } + /// Prints the definition of a `ArrayType` to a `LLVMString`. pub fn print_to_string(&self) -> LLVMString { self.array_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.array_type.print_to_stderr() } + /// Creates an undefined instance of a `ArrayType`. + /// + /// # Example + /// ```no_run + /// use inkwell::context::Context; + /// + /// let context = Context::create(); + /// let i8_type = context.i8_type(); + /// let i8_array_type = i8_type.array_type(3); + /// let i8_array_undef = i8_array_type.get_undef(); + /// + /// assert!(i8_array_undef.is_undef()); + /// ``` pub fn get_undef(&self) -> ArrayValue { ArrayValue::new(self.array_type.get_undef()) } // SubType: ArrayType -> BT? + /// Gets the element type of this `ArrayType`. + /// + /// # Example + /// + /// ```no_run + /// use inkwell::context::Context; + /// + /// let context = Context::create(); + /// let i8_type = context.i8_type(); + /// let i8_array_type = i8_type.array_type(3); + /// + /// assert_eq!(i8_array_type.get_element_type().into_int_type(), i8_type); + /// ``` pub fn get_element_type(&self) -> BasicTypeEnum { self.array_type.get_element_type() } diff --git a/src/types/float_type.rs b/src/types/float_type.rs index 07091676d49..7f2123cd8c2 100644 --- a/src/types/float_type.rs +++ b/src/types/float_type.rs @@ -214,7 +214,7 @@ impl FloatType { self.float_type.size_of() } - /// Gets the aligment of this `FloatType`. Value may vary depending on the target architecture. + /// Gets the alignment of this `FloatType`. Value may vary depending on the target architecture. /// /// # Example /// @@ -402,7 +402,6 @@ impl FloatType { /// # Example /// ```no_run /// use inkwell::context::Context; - /// use inkwell::AddressSpace; /// /// let context = Context::create(); /// let f32_type = context.f32_type(); diff --git a/src/types/int_type.rs b/src/types/int_type.rs index 7efae33f89f..313c933b8c7 100644 --- a/src/types/int_type.rs +++ b/src/types/int_type.rs @@ -422,7 +422,7 @@ impl IntType { self.int_type.size_of() } - /// Gets the aligment of this `IntType`. Value may vary depending on the target architecture. + /// Gets the alignment of this `IntType`. Value may vary depending on the target architecture. /// /// # Example /// diff --git a/src/types/mod.rs b/src/types/mod.rs index b24ee85ef79..1dadece18d5 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -1,3 +1,4 @@ +#[deny(missing_docs)] mod array_type; mod enums; #[deny(missing_docs)] @@ -5,6 +6,7 @@ mod float_type; mod fn_type; #[deny(missing_docs)] mod int_type; +#[deny(missing_docs)] mod ptr_type; mod struct_type; mod traits; diff --git a/src/types/ptr_type.rs b/src/types/ptr_type.rs index d91d95ed966..97aa71018a6 100644 --- a/src/types/ptr_type.rs +++ b/src/types/ptr_type.rs @@ -8,6 +8,7 @@ use types::traits::AsTypeRef; use types::{Type, BasicTypeEnum, ArrayType, FunctionType, VectorType}; use values::{AsValueRef, ArrayValue, PointerValue, IntValue}; +/// A `PointerType` is the type of a pointer constant or variable. #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub struct PointerType { ptr_type: Type, @@ -22,54 +23,208 @@ impl PointerType { } } + // REVIEW: Always true -> const fn on trait? + /// Gets whether or not this `PointerType` is sized or not. This is likely + /// always true and may be removed in the future. + /// + /// # Example + /// + /// ```no_run + /// use inkwell::context::Context; + /// use inkwell::AddressSpace; + /// + /// let context = Context::create(); + /// let i8_type = context.i8_type(); + /// let i8_ptr_type = i8_type.ptr_type(AddressSpace::Generic); + /// + /// assert!(i8_ptr_type.is_sized()); + /// ``` pub fn is_sized(&self) -> bool { self.ptr_type.is_sized() } + /// Gets the size of this `PointerType`. Value may vary depending on the target architecture. + /// + /// # Example + /// + /// ```no_run + /// use inkwell::context::Context; + /// use inkwell::AddressSpace; + /// + /// let context = Context::create(); + /// let f32_type = context.f32_type(); + /// let f32_ptr_type = f32_type.ptr_type(AddressSpace::Generic); + /// let f32_ptr_type_size = f32_ptr_type.size_of(); + /// ``` pub fn size_of(&self) -> IntValue { self.ptr_type.size_of() } + /// Gets the alignment of this `PointerType`. Value may vary depending on the target architecture. + /// + /// # Example + /// + /// ```no_run + /// use inkwell::context::Context; + /// use inkwell::AddressSpace; + /// + /// let context = Context::create(); + /// let f32_type = context.f32_type(); + /// let f32_ptr_type = f32_type.ptr_type(AddressSpace::Generic); + /// let f32_ptr_type_alignment = f32_ptr_type.get_alignment(); + /// ``` pub fn get_alignment(&self) -> IntValue { self.ptr_type.get_alignment() } + /// Creates a `PointerType` with this `PointerType` 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 f32_ptr_type = f32_type.ptr_type(AddressSpace::Generic); + /// let f32_ptr_ptr_type = f32_ptr_type.ptr_type(AddressSpace::Generic); + /// + /// assert_eq!(f32_ptr_ptr_type.get_element_type().into_pointer_type(), f32_ptr_type); + /// ``` pub fn ptr_type(&self, address_space: AddressSpace) -> PointerType { self.ptr_type.ptr_type(address_space) } + /// Gets a reference to the `Context` this `PointerType` was created in. + /// + /// # Example + /// + /// ```no_run + /// use inkwell::context::Context; + /// use inkwell::AddressSpace; + /// + /// let context = Context::create(); + /// let f32_type = context.f32_type(); + /// let f32_ptr_type = f32_type.ptr_type(AddressSpace::Generic); + /// + /// assert_eq!(*f32_ptr_type.get_context(), context); + /// ``` pub fn get_context(&self) -> ContextRef { self.ptr_type.get_context() } + /// Creates a `FunctionType` with this `PointerType` for its return type. + /// + /// # Example + /// + /// ```no_run + /// use inkwell::context::Context; + /// use inkwell::AddressSpace; + /// + /// let context = Context::create(); + /// let f32_type = context.f32_type(); + /// let f32_ptr_type = f32_type.ptr_type(AddressSpace::Generic); + /// let fn_type = f32_ptr_type.fn_type(&[], false); + /// ``` pub fn fn_type(&self, param_types: &[BasicTypeEnum], is_var_args: bool) -> FunctionType { self.ptr_type.fn_type(param_types, is_var_args) } + /// Creates an `ArrayType` with this `PointerType` 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 f32_ptr_type = f32_type.ptr_type(AddressSpace::Generic); + /// let f32_ptr_array_type = f32_ptr_type.array_type(3); + /// + /// assert_eq!(f32_ptr_array_type.len(), 3); + /// assert_eq!(f32_ptr_array_type.get_element_type().into_pointer_type(), f32_ptr_type); + /// ``` pub fn array_type(&self, size: u32) -> ArrayType { self.ptr_type.array_type(size) } + /// Gets the `AddressSpace` a `PointerType` was created with. + /// + /// # Example + /// + /// ```no_run + /// use inkwell::context::Context; + /// use inkwell::AddressSpace; + /// + /// let context = Context::create(); + /// let f32_type = context.f32_type(); + /// let f32_ptr_type = f32_type.ptr_type(AddressSpace::Generic); + /// + /// assert_eq!(f32_ptr_type.get_address_space(), AddressSpace::Generic); + /// ``` pub fn get_address_space(&self) -> AddressSpace { unsafe { LLVMGetPointerAddressSpace(self.as_type_ref()).into() } } + /// Prints the definition of a `PointerType` to a `LLVMString`. pub fn print_to_string(&self) -> LLVMString { self.ptr_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.ptr_type.print_to_stderr() } + /// Creates a `PointerValue` representing a constant value of zero (null pointer) pointing to this `PointerType`. + /// It will be automatically assigned this `PointerType`'s `Context`. + /// + /// # Example + /// ``` + /// use inkwell::context::Context; + /// use inkwell::types::FloatType; + /// + /// // Global Context + /// let f32_type = FloatType::f32_type(); + /// let f32_array_type = f32_type.array_type(3); + /// let f32_array_ptr_value = f32_array_type.const_null_ptr(); + /// + /// assert!(f32_array_ptr_value.is_null()); + /// + /// // Custom Context + /// let context = Context::create(); + /// let f32_type = context.f32_type(); + /// let f32_array_type = f32_type.array_type(3); + /// let f32_array_ptr_value = f32_array_type.const_null_ptr(); + /// + /// assert!(f32_array_ptr_value.is_null()); + /// ``` pub fn const_null_ptr(&self) -> PointerValue { self.ptr_type.const_null_ptr() } + /// Creates a constant null (zero) value of this `PointerType`. + /// + /// # Example + /// + /// ```no_run + /// use inkwell::context::Context; + /// use inkwell::AddressSpace; + /// + /// let context = Context::create(); + /// let f32_type = context.f32_type(); + /// let f32_ptr_type = f32_type.ptr_type(AddressSpace::Generic); + /// let f32_ptr_zero = f32_ptr_type.const_null(); + /// + /// assert!(f32_ptr_zero.is_null()); + /// ``` pub fn const_null(&self) -> PointerValue { let null = unsafe { LLVMConstNull(self.as_type_ref()) @@ -78,19 +233,78 @@ impl PointerType { PointerValue::new(null) } + /// Creates an undefined instance of a `PointerType`. + /// + /// # Example + /// ```no_run + /// use inkwell::context::Context; + /// use inkwell::AddressSpace; + /// + /// let context = Context::create(); + /// let f32_type = context.f32_type(); + /// let f32_ptr_type = f32_type.ptr_type(AddressSpace::Generic); + /// let f32_ptr_undef = f32_ptr_type.get_undef(); + /// + /// assert!(f32_ptr_undef.is_undef()); + /// ``` pub fn get_undef(&self) -> PointerValue { PointerValue::new(self.ptr_type.get_undef()) } + /// Creates a `VectorType` with this `PointerType` 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 f32_ptr_type = f32_type.ptr_type(AddressSpace::Generic); + /// let f32_ptr_vec_type = f32_ptr_type.vec_type(3); + /// + /// assert_eq!(f32_ptr_vec_type.get_size(), 3); + /// assert_eq!(f32_ptr_vec_type.get_element_type().into_pointer_type(), f32_ptr_type); + /// ``` pub fn vec_type(&self, size: u32) -> VectorType { self.ptr_type.vec_type(size) } // SubType: PointerrType -> BT? + /// Gets the element type of this `PointerType`. + /// + /// # Example + /// + /// ```no_run + /// use inkwell::context::Context; + /// use inkwell::AddressSpace; + /// + /// let context = Context::create(); + /// let f32_type = context.f32_type(); + /// let f32_ptr_type = f32_type.ptr_type(AddressSpace::Generic); + /// + /// assert_eq!(f32_ptr_type.get_element_type().into_float_type(), f32_type); + /// ``` pub fn get_element_type(&self) -> BasicTypeEnum { self.ptr_type.get_element_type() } + /// Creates a constant `ArrayValue`. + /// + /// # Example + /// ```no_run + /// use inkwell::context::Context; + /// use inkwell::AddressSpace; + /// + /// let context = Context::create(); + /// let f32_type = context.f32_type(); + /// let f32_ptr_type = f32_type.ptr_type(AddressSpace::Generic); + /// let f32_ptr_val = f32_ptr_type.const_null(); + /// let f32_ptr_array = f32_ptr_type.const_array(&[f32_ptr_val, f32_ptr_val]); + /// + /// assert!(f32_ptr_array.is_const()); + /// ``` pub fn const_array(&self, values: &[PointerValue]) -> ArrayValue { let mut values: Vec = values.iter() .map(|val| val.as_value_ref()) diff --git a/src/types/vec_type.rs b/src/types/vec_type.rs index 4f4c4c336d7..a97baa56105 100644 --- a/src/types/vec_type.rs +++ b/src/types/vec_type.rs @@ -63,7 +63,7 @@ impl VectorType { None } - /// Gets the aligment of this `VectorType`. Value may vary depending on the target architecture. + /// Gets the alignment of this `VectorType`. Value may vary depending on the target architecture. /// /// # Example /// @@ -134,7 +134,7 @@ impl VectorType { } /// Creates a `PointerValue` representing a constant value of zero (null pointer) pointing to this `VectorType`. - /// It will be automatically assigned this `FloatType`'s `Context`. + /// It will be automatically assigned this `VectorType`'s `Context`. /// /// # Example /// ``` @@ -144,19 +144,23 @@ impl VectorType { /// // Global Context /// let f32_type = FloatType::f32_type(); /// let f32_vec_type = f32_type.vec_type(7); - /// let f32_value = f32_vec_type.const_null_ptr(); + /// let f32_vec_ptr_value = f32_vec_type.const_null_ptr(); + /// + /// assert!(f32_vec_ptr_value.is_null()); /// /// // Custom Context /// let context = Context::create(); /// let f32_type = context.f32_type(); /// let f32_vec_type = f32_type.vec_type(7); - /// let f32_value = f32_vec_type.const_null_ptr(); + /// let f32_vec_ptr_value = f32_vec_type.const_null_ptr(); + /// + /// assert!(f32_vec_ptr_value.is_null()); /// ``` pub fn const_null_ptr(&self) -> PointerValue { self.vec_type.const_null_ptr() } - /// Creates a constant null (zero) value of this `FloatType`. + /// Creates a constant null (zero) value of this `VectorType`. /// /// # Example /// @@ -169,7 +173,6 @@ impl VectorType { /// let f32_vec_zero = f32_vec_type.const_null(); /// /// assert!(f32_vec_zero.is_null()); - /// assert_eq!(f32_vec_zero.print_to_string().to_string(), "f32 0"); /// ``` pub fn const_null(&self) -> VectorValue { let null = unsafe {