[core] codegen: Add StructProxy{Type,Value}

This commit is contained in:
David Mak 2025-01-23 14:46:30 +08:00
parent da8480148a
commit 91130da483
3 changed files with 61 additions and 1 deletions

View File

@ -2,13 +2,51 @@ use std::marker::PhantomData;
use inkwell::{
context::AsContextRef,
types::{BasicTypeEnum, IntType, StructType},
types::{BasicTypeEnum, IntType, PointerType, StructType},
values::{BasicValue, BasicValueEnum, IntValue, PointerValue, StructValue},
AddressSpace,
};
use itertools::Itertools;
use super::ProxyType;
use crate::codegen::CodeGenContext;
/// A LLVM type that is used to represent a corresponding structure-like type in NAC3.
pub trait StructProxyType<'ctx>: ProxyType<'ctx, Base = PointerType<'ctx>> {
/// The concrete type of [`StructFields`].
type StructFields: StructFields<'ctx>;
fn has_same_struct_repr(
llvm_ty: StructType<'ctx>,
llvm_usize: IntType<'ctx>,
) -> Result<(), String> {
Self::has_same_pointer_repr(llvm_ty.ptr_type(AddressSpace::default()), llvm_usize)
}
fn has_same_pointer_repr(
llvm_ty: PointerType<'ctx>,
llvm_usize: IntType<'ctx>,
) -> Result<(), String> {
Self::has_same_repr(llvm_ty, llvm_usize)
}
/// Returns the fields present in this [`StructProxyType`].
#[must_use]
fn get_fields(&self) -> Self::StructFields;
/// Returns the [`StructType`].
#[must_use]
fn get_struct_type(&self) -> StructType<'ctx> {
self.as_base_type().get_element_type().into_struct_type()
}
/// Returns the [`PointerType`] representing this type.
#[must_use]
fn get_pointer_type(&self) -> PointerType<'ctx> {
self.as_base_type()
}
}
/// Trait indicating that the structure is a field-wise representation of an LLVM structure.
///
/// # Usage

View File

@ -10,6 +10,7 @@ mod array;
mod list;
pub mod ndarray;
mod range;
pub mod structure;
mod tuple;
pub mod utils;

View File

@ -0,0 +1,21 @@
use inkwell::values::{BasicValueEnum, PointerValue, StructValue};
use super::ProxyValue;
use crate::codegen::{types::structure::StructProxyType, CodeGenContext};
pub trait StructProxyValue<'ctx>:
ProxyValue<'ctx, Base = PointerValue<'ctx>, Type: StructProxyType<'ctx, Value = Self>>
{
#[must_use]
fn get_struct_value(&self, ctx: &CodeGenContext<'ctx, '_>) -> StructValue<'ctx> {
ctx.builder
.build_load(self.get_pointer_value(ctx), "")
.map(BasicValueEnum::into_struct_value)
.unwrap()
}
#[must_use]
fn get_pointer_value(&self, _: &CodeGenContext<'ctx, '_>) -> PointerValue<'ctx> {
self.as_base_value()
}
}