core: Add gen_{var_alloc,store_target}_named
For assigning custom names to stack-alloc variables and pointers.
This commit is contained in:
parent
1e27986864
commit
aaf7ea74b8
|
@ -83,24 +83,49 @@ pub trait CodeGenerator {
|
||||||
|
|
||||||
/// Allocate memory for a variable and return a pointer pointing to it.
|
/// Allocate memory for a variable and return a pointer pointing to it.
|
||||||
/// The default implementation places the allocations at the start of the function.
|
/// The default implementation places the allocations at the start of the function.
|
||||||
|
fn gen_var_alloc_named<'ctx, 'a>(
|
||||||
|
&mut self,
|
||||||
|
ctx: &mut CodeGenContext<'ctx, 'a>,
|
||||||
|
ty: BasicTypeEnum<'ctx>,
|
||||||
|
name: &str,
|
||||||
|
) -> Result<PointerValue<'ctx>, String> {
|
||||||
|
gen_var(ctx, ty, Some(name))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Similar to [gen_var_alloc_named], but provides a default name for the created pointer
|
||||||
|
/// variable.
|
||||||
fn gen_var_alloc<'ctx, 'a>(
|
fn gen_var_alloc<'ctx, 'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, 'a>,
|
||||||
ty: BasicTypeEnum<'ctx>,
|
ty: BasicTypeEnum<'ctx>,
|
||||||
) -> Result<PointerValue<'ctx>, String> {
|
) -> Result<PointerValue<'ctx>, String> {
|
||||||
gen_var(ctx, ty)
|
gen_var(ctx, ty, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a pointer pointing to the target of the expression.
|
/// Return a pointer pointing to the target of the expression.
|
||||||
|
fn gen_store_target_named<'ctx, 'a>(
|
||||||
|
&mut self,
|
||||||
|
ctx: &mut CodeGenContext<'ctx, 'a>,
|
||||||
|
pattern: &Expr<Option<Type>>,
|
||||||
|
name: &str,
|
||||||
|
) -> Result<PointerValue<'ctx>, String>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
gen_store_target(self, ctx, pattern, Some(name))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Similar to [gen_store_target_named], but provides a default name for the created pointer
|
||||||
|
/// variable.
|
||||||
fn gen_store_target<'ctx, 'a>(
|
fn gen_store_target<'ctx, 'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, 'a>,
|
||||||
pattern: &Expr<Option<Type>>,
|
pattern: &Expr<Option<Type>>,
|
||||||
) -> Result<PointerValue<'ctx>, String>
|
) -> Result<PointerValue<'ctx>, String>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
gen_store_target(self, ctx, pattern)
|
gen_store_target(self, ctx, pattern, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate code for an assignment expression.
|
/// Generate code for an assignment expression.
|
||||||
|
|
|
@ -24,12 +24,13 @@ use std::convert::TryFrom;
|
||||||
pub fn gen_var<'ctx, 'a>(
|
pub fn gen_var<'ctx, 'a>(
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, 'a>,
|
||||||
ty: BasicTypeEnum<'ctx>,
|
ty: BasicTypeEnum<'ctx>,
|
||||||
|
name: Option<&str>,
|
||||||
) -> Result<PointerValue<'ctx>, String> {
|
) -> Result<PointerValue<'ctx>, String> {
|
||||||
// put the alloca in init block
|
// put the alloca in init block
|
||||||
let current = ctx.builder.get_insert_block().unwrap();
|
let current = ctx.builder.get_insert_block().unwrap();
|
||||||
// position before the last branching instruction...
|
// position before the last branching instruction...
|
||||||
ctx.builder.position_before(&ctx.init_bb.get_last_instruction().unwrap());
|
ctx.builder.position_before(&ctx.init_bb.get_last_instruction().unwrap());
|
||||||
let ptr = ctx.builder.build_alloca(ty, "tmp");
|
let ptr = ctx.builder.build_alloca(ty, name.unwrap_or("tmp"));
|
||||||
ctx.builder.position_at_end(current);
|
ctx.builder.position_at_end(current);
|
||||||
Ok(ptr)
|
Ok(ptr)
|
||||||
}
|
}
|
||||||
|
@ -38,6 +39,7 @@ pub fn gen_store_target<'ctx, 'a, G: CodeGenerator>(
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, 'a>,
|
||||||
pattern: &Expr<Option<Type>>,
|
pattern: &Expr<Option<Type>>,
|
||||||
|
name: Option<&str>,
|
||||||
) -> Result<PointerValue<'ctx>, String> {
|
) -> Result<PointerValue<'ctx>, String> {
|
||||||
// very similar to gen_expr, but we don't do an extra load at the end
|
// very similar to gen_expr, but we don't do an extra load at the end
|
||||||
// and we flatten nested tuples
|
// and we flatten nested tuples
|
||||||
|
@ -45,7 +47,7 @@ pub fn gen_store_target<'ctx, 'a, G: CodeGenerator>(
|
||||||
ExprKind::Name { id, .. } => match ctx.var_assignment.get(id) {
|
ExprKind::Name { id, .. } => match ctx.var_assignment.get(id) {
|
||||||
None => {
|
None => {
|
||||||
let ptr_ty = ctx.get_llvm_type(generator, pattern.custom.unwrap());
|
let ptr_ty = ctx.get_llvm_type(generator, pattern.custom.unwrap());
|
||||||
let ptr = generator.gen_var_alloc(ctx, ptr_ty)?;
|
let ptr = generator.gen_var_alloc_named(ctx, ptr_ty, name.unwrap_or("tmp"))?;
|
||||||
ctx.var_assignment.insert(*id, (ptr, None, 0));
|
ctx.var_assignment.insert(*id, (ptr, None, 0));
|
||||||
ptr
|
ptr
|
||||||
}
|
}
|
||||||
|
@ -74,7 +76,7 @@ pub fn gen_store_target<'ctx, 'a, G: CodeGenerator>(
|
||||||
ctx.ctx.i32_type().const_zero(),
|
ctx.ctx.i32_type().const_zero(),
|
||||||
ctx.ctx.i32_type().const_int(index as u64, false),
|
ctx.ctx.i32_type().const_int(index as u64, false),
|
||||||
],
|
],
|
||||||
"attr",
|
name.unwrap_or("attr"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,7 +137,7 @@ pub fn gen_store_target<'ctx, 'a, G: CodeGenerator>(
|
||||||
let arr_ptr = ctx
|
let arr_ptr = ctx
|
||||||
.build_gep_and_load(v, &[i32_type.const_zero(), i32_type.const_zero()])
|
.build_gep_and_load(v, &[i32_type.const_zero(), i32_type.const_zero()])
|
||||||
.into_pointer_value();
|
.into_pointer_value();
|
||||||
ctx.builder.build_gep(arr_ptr, &[index], "loadarrgep")
|
ctx.builder.build_gep(arr_ptr, &[index], name.unwrap_or("loadarrgep"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
|
Loading…
Reference in New Issue