diff --git a/nac3core/src/codegen/classes.rs b/nac3core/src/codegen/classes.rs index 42676404..d06b2c15 100644 --- a/nac3core/src/codegen/classes.rs +++ b/nac3core/src/codegen/classes.rs @@ -1,7 +1,7 @@ use crate::codegen::{CodeGenContext, CodeGenerator}; use inkwell::context::Context; -use inkwell::types::{ArrayType, BasicType, StructType}; -use inkwell::values::{ArrayValue, BasicValue, StructValue}; +use inkwell::types::{BasicType, StructType}; +use inkwell::values::{BasicValue, StructValue}; use inkwell::{ types::{AnyTypeEnum, BasicTypeEnum, IntType, PointerType}, values::{BasicValueEnum, IntValue, PointerValue}, @@ -873,266 +873,3 @@ impl<'ctx> ArrayLikeIndexer<'ctx> for ListDataProxy<'ctx, '_> { impl<'ctx> UntypedArrayLikeAccessor<'ctx> for ListDataProxy<'ctx, '_> {} impl<'ctx> UntypedArrayLikeMutator<'ctx> for ListDataProxy<'ctx, '_> {} - -/// Proxy type for a `range` type in LLVM. -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -pub struct RangeType<'ctx> { - ty: PointerType<'ctx>, -} - -impl<'ctx> RangeType<'ctx> { - /// Checks whether `llvm_ty` represents a `range` type, returning [Err] if it does not. - pub fn is_type(llvm_ty: PointerType<'ctx>) -> Result<(), String> { - let llvm_range_ty = llvm_ty.get_element_type(); - let AnyTypeEnum::ArrayType(llvm_range_ty) = llvm_range_ty else { - return Err(format!("Expected array type for `range` type, got {llvm_range_ty}")); - }; - if llvm_range_ty.len() != 3 { - return Err(format!( - "Expected 3 elements for `range` type, got {}", - llvm_range_ty.len() - )); - } - - let llvm_range_elem_ty = llvm_range_ty.get_element_type(); - let Ok(llvm_range_elem_ty) = IntType::try_from(llvm_range_elem_ty) else { - return Err(format!( - "Expected int type for `range` element type, got {llvm_range_elem_ty}" - )); - }; - if llvm_range_elem_ty.get_bit_width() != 32 { - return Err(format!( - "Expected 32-bit int type for `range` element type, got {}", - llvm_range_elem_ty.get_bit_width() - )); - } - - Ok(()) - } - - /// Creates an instance of [`RangeType`]. - #[must_use] - pub fn new(ctx: &'ctx Context) -> Self { - let llvm_i32 = ctx.i32_type(); - let llvm_range = llvm_i32.array_type(3).ptr_type(AddressSpace::default()); - - RangeType::from_type(llvm_range) - } - - /// Creates an [`RangeType`] from a [`PointerType`]. - #[must_use] - pub fn from_type(ptr_ty: PointerType<'ctx>) -> Self { - debug_assert!(Self::is_type(ptr_ty).is_ok()); - - RangeType { ty: ptr_ty } - } - - /// Returns the type of all fields of this `range` type. - #[must_use] - pub fn value_type(&self) -> IntType<'ctx> { - self.as_base_type().get_element_type().into_array_type().get_element_type().into_int_type() - } -} - -impl<'ctx> ProxyType<'ctx> for RangeType<'ctx> { - type Base = PointerType<'ctx>; - type Underlying = ArrayType<'ctx>; - type Value = RangeValue<'ctx>; - - fn new_value( - &self, - generator: &mut G, - ctx: &mut CodeGenContext<'ctx, '_>, - name: Option<&'ctx str>, - ) -> Self::Value { - self.create_value( - generator.gen_var_alloc(ctx, self.as_underlying_type().into(), name).unwrap(), - name, - ) - } - - fn create_value( - &self, - value: >::Base, - name: Option<&'ctx str>, - ) -> Self::Value { - debug_assert_eq!(value.get_type(), self.as_base_type()); - - RangeValue { value, name } - } - - fn as_base_type(&self) -> Self::Base { - self.ty - } - - fn as_underlying_type(&self) -> Self::Underlying { - self.as_base_type().get_element_type().into_array_type() - } -} - -impl<'ctx> From> for PointerType<'ctx> { - fn from(value: RangeType<'ctx>) -> Self { - value.as_base_type() - } -} - -/// Proxy type for accessing a `range` value in LLVM. -#[derive(Copy, Clone)] -pub struct RangeValue<'ctx> { - value: PointerValue<'ctx>, - name: Option<&'ctx str>, -} - -impl<'ctx> RangeValue<'ctx> { - /// Checks whether `value` is an instance of `range`, returning [Err] if `value` is not an instance. - pub fn is_instance(value: PointerValue<'ctx>) -> Result<(), String> { - RangeType::is_type(value.get_type()) - } - - /// Creates an [`RangeValue`] from a [`PointerValue`]. - #[must_use] - pub fn from_ptr_val(ptr: PointerValue<'ctx>, name: Option<&'ctx str>) -> Self { - debug_assert!(Self::is_instance(ptr).is_ok()); - - >::Type::from_type(ptr.get_type()).create_value(ptr, name) - } - - fn ptr_to_start(&self, ctx: &CodeGenContext<'ctx, '_>) -> PointerValue<'ctx> { - let llvm_i32 = ctx.ctx.i32_type(); - let var_name = self.name.map(|v| format!("{v}.start.addr")).unwrap_or_default(); - - unsafe { - ctx.builder - .build_in_bounds_gep( - self.as_base_value(), - &[llvm_i32.const_zero(), llvm_i32.const_int(0, false)], - var_name.as_str(), - ) - .unwrap() - } - } - - fn ptr_to_end(&self, ctx: &CodeGenContext<'ctx, '_>) -> PointerValue<'ctx> { - let llvm_i32 = ctx.ctx.i32_type(); - let var_name = self.name.map(|v| format!("{v}.end.addr")).unwrap_or_default(); - - unsafe { - ctx.builder - .build_in_bounds_gep( - self.as_base_value(), - &[llvm_i32.const_zero(), llvm_i32.const_int(1, false)], - var_name.as_str(), - ) - .unwrap() - } - } - - fn ptr_to_step(&self, ctx: &CodeGenContext<'ctx, '_>) -> PointerValue<'ctx> { - let llvm_i32 = ctx.ctx.i32_type(); - let var_name = self.name.map(|v| format!("{v}.step.addr")).unwrap_or_default(); - - unsafe { - ctx.builder - .build_in_bounds_gep( - self.as_base_value(), - &[llvm_i32.const_zero(), llvm_i32.const_int(2, false)], - var_name.as_str(), - ) - .unwrap() - } - } - - /// Stores the `start` value into this instance. - pub fn store_start(&self, ctx: &CodeGenContext<'ctx, '_>, start: IntValue<'ctx>) { - debug_assert_eq!(start.get_type().get_bit_width(), 32); - - let pstart = self.ptr_to_start(ctx); - ctx.builder.build_store(pstart, start).unwrap(); - } - - /// Returns the `start` value of this `range`. - pub fn load_start(&self, ctx: &CodeGenContext<'ctx, '_>, name: Option<&str>) -> IntValue<'ctx> { - let pstart = self.ptr_to_start(ctx); - let var_name = name - .map(ToString::to_string) - .or_else(|| self.name.map(|v| format!("{v}.start"))) - .unwrap_or_default(); - - ctx.builder - .build_load(pstart, var_name.as_str()) - .map(BasicValueEnum::into_int_value) - .unwrap() - } - - /// Stores the `end` value into this instance. - pub fn store_end(&self, ctx: &CodeGenContext<'ctx, '_>, end: IntValue<'ctx>) { - debug_assert_eq!(end.get_type().get_bit_width(), 32); - - let pend = self.ptr_to_end(ctx); - ctx.builder.build_store(pend, end).unwrap(); - } - - /// Returns the `end` value of this `range`. - pub fn load_end(&self, ctx: &CodeGenContext<'ctx, '_>, name: Option<&str>) -> IntValue<'ctx> { - let pend = self.ptr_to_end(ctx); - let var_name = name - .map(ToString::to_string) - .or_else(|| self.name.map(|v| format!("{v}.end"))) - .unwrap_or_default(); - - ctx.builder.build_load(pend, var_name.as_str()).map(BasicValueEnum::into_int_value).unwrap() - } - - /// Stores the `step` value into this instance. - pub fn store_step(&self, ctx: &CodeGenContext<'ctx, '_>, step: IntValue<'ctx>) { - debug_assert_eq!(step.get_type().get_bit_width(), 32); - - let pstep = self.ptr_to_step(ctx); - ctx.builder.build_store(pstep, step).unwrap(); - } - - /// Returns the `step` value of this `range`. - pub fn load_step(&self, ctx: &CodeGenContext<'ctx, '_>, name: Option<&str>) -> IntValue<'ctx> { - let pstep = self.ptr_to_step(ctx); - let var_name = name - .map(ToString::to_string) - .or_else(|| self.name.map(|v| format!("{v}.step"))) - .unwrap_or_default(); - - ctx.builder - .build_load(pstep, var_name.as_str()) - .map(BasicValueEnum::into_int_value) - .unwrap() - } -} - -impl<'ctx> ProxyValue<'ctx> for RangeValue<'ctx> { - type Base = PointerValue<'ctx>; - type Underlying = ArrayValue<'ctx>; - type Type = RangeType<'ctx>; - - fn get_type(&self) -> Self::Type { - RangeType::from_type(self.value.get_type()) - } - - fn as_base_value(&self) -> Self::Base { - self.value - } - - fn as_underlying_value( - &self, - ctx: &mut CodeGenContext<'ctx, '_>, - name: Option<&'ctx str>, - ) -> Self::Underlying { - ctx.builder - .build_load(self.as_base_value(), name.unwrap_or_default()) - .map(BasicValueEnum::into_array_value) - .unwrap() - } -} - -impl<'ctx> From> for PointerValue<'ctx> { - fn from(value: RangeValue<'ctx>) -> Self { - value.as_base_value() - } -} diff --git a/nac3core/src/codegen/test.rs b/nac3core/src/codegen/test.rs index 09c99553..0534a003 100644 --- a/nac3core/src/codegen/test.rs +++ b/nac3core/src/codegen/test.rs @@ -1,6 +1,6 @@ use crate::{ codegen::{ - classes::{ListType, ProxyType, RangeType}, + classes::{ListType, ProxyType}, concrete_type::ConcreteTypeStore, CodeGenContext, CodeGenLLVMOptions, CodeGenTargetMachineOptions, CodeGenTask, CodeGenerator, DefaultCodeGenerator, WithCall, WorkerRegistry, @@ -448,11 +448,3 @@ fn test_classes_list_type_new() { let llvm_list = ListType::new(&generator, &ctx, llvm_i32.into()); assert!(ListType::is_type(llvm_list.as_base_type(), llvm_usize).is_ok()); } - -#[test] -fn test_classes_range_type_new() { - let ctx = inkwell::context::Context::create(); - - let llvm_range = RangeType::new(&ctx); - assert!(RangeType::is_type(llvm_range.as_base_type()).is_ok()); -}