refactor(ast2ir): 提取模块访问函数并优化类型大小计算

- 添加 scc_ast2ir_mir_module 内联函数统一访问模块
- 替换所有直接访问 ctx->builder.cprog->module 的地方
- 移除重复的 scc_hir_type_size 函数实现
- 添加 scc_hir_module_type_size 函数到模块接口
- 更新所有类型大小计算调用使用新函数

feat(hir): 增强构建器安全性和全局变量处理

- 为 scc_hir_builder_integer 添加空指针检查断言
- 修复 scc_hir_builder_global_alloca 中全局变量类型设置
- 改进 scc_hir_builder_get_elem_ptr 处理空指针索引情况
- 重构字符串常量生成使用 get_elem_ptr 构建器函数

refactor(lir): 简化地址表达式表示并增强内置函数支持

- 移除复杂地址结构体 scc_lir_addr_t
- 简化 scc_lir_instr 结构体中的地址表示
- 移除 STORE_ADDR 操作码
- 添加 memcpy 和 memset 内置函数操作码
- 在符号元数据中使用联合体替代嵌套结构体

feat(hir2lir): 完善 HIR 到 LIR 转换中的内置函数处理

- 添加 ensure_vreg 辅助函数确保虚拟寄存器操作数
- 正确处理全局变量地址符号引用
- 优化 GET_ELEM_PTR 转换使用类型大小计算
- 完整实现所有内置函数(BUILTIN)的 LIR 转换
- 包括 memcpy、memset、va_start、va_arg、va_end、va_copy 等
This commit is contained in:
zzy
2026-05-22 15:15:18 +08:00
parent 41d060d7e7
commit d78b91894e
27 changed files with 1272 additions and 563 deletions

View File

@@ -19,6 +19,10 @@ typedef struct {
scc_ast_ctx_t *ast_ctx;
} scc_ast2ir_ctx_t;
static inline scc_hir_module_t *scc_ast2ir_mir_module(scc_ast2ir_ctx_t *ctx) {
return &ctx->builder.cprog->module;
}
void scc_ast2ir_ctx_init(scc_ast2ir_ctx_t *ctx, const scc_abi_type_calc_t *abi,
scc_ast_ctx_t *ast_ctx, scc_hir_cprog_t *cprog);
void scc_ast2ir_ctx_drop(scc_ast2ir_ctx_t *ctx);

View File

@@ -55,7 +55,7 @@ static void emit_array_initialization(scc_ast2ir_ctx_t *ctx,
Assert(array_type->tag == SCC_HIR_TYPE_ARRAY);
scc_hir_type_ref_t elem_type_ref = array_type->data.array.base;
const scc_hir_type_t *elem_type =
scc_hir_module_get_type(&ctx->builder.cprog->module, elem_type_ref);
scc_hir_module_get_type(scc_ast2ir_mir_module(ctx), elem_type_ref);
usize array_len = array_type->data.array.len;
// 字符串字面量初始化:直接 memcpy
@@ -124,8 +124,8 @@ static void emit_aggregate_initialization(scc_ast2ir_ctx_t *ctx,
scc_vec_at(init_expr->compound.rhs_exprs, i);
scc_hir_type_ref_t field_type_ref =
scc_vec_at(type->data.aggregate.fields, idx);
const scc_hir_type_t *field_type = scc_hir_module_get_type(
&ctx->builder.cprog->module, field_type_ref);
const scc_hir_type_t *field_type =
scc_hir_module_get_type(scc_ast2ir_mir_module(ctx), field_type_ref);
scc_ap_t idx_ap;
scc_ap_set_int(&idx_ap, idx);
@@ -149,68 +149,6 @@ static void emit_aggregate_initialization(scc_ast2ir_ctx_t *ctx,
}
// static inline void parse_struct_union_layout(scc_ast_qual_type_t *type) {}
usize scc_hir_type_size(scc_ast2ir_ctx_t *ctx, const scc_hir_type_t *type) {
switch (type->tag) {
case SCC_HIR_TYPE_void:
return 0;
case SCC_HIR_TYPE_i8:
return 1;
case SCC_HIR_TYPE_i16:
return 2;
case SCC_HIR_TYPE_i32:
return 4;
case SCC_HIR_TYPE_i64:
return 8;
case SCC_HIR_TYPE_i128:
return 16;
case SCC_HIR_TYPE_u8:
return 1;
case SCC_HIR_TYPE_u16:
return 2;
case SCC_HIR_TYPE_u32:
return 4;
case SCC_HIR_TYPE_u64:
return 8;
case SCC_HIR_TYPE_u128:
return 16;
case SCC_HIR_TYPE_f16:
return 2;
case SCC_HIR_TYPE_f32:
return 4;
case SCC_HIR_TYPE_f64:
return 8;
case SCC_HIR_TYPE_f128:
return 16;
case SCC_HIR_TYPE_PTR: {
// 目标指针大小,可以定义为 864位或从 ABI 获取
// 假设你的目标架构是 64 位
return 8;
}
case SCC_HIR_TYPE_ARRAY: {
usize elem_size = scc_hir_type_size(
ctx, scc_hir_module_get_type(&ctx->builder.cprog->module,
type->data.array.base));
return elem_size * type->data.array.len;
}
case SCC_HIR_TYPE_FUNC:
// 函数类型大小一般是指针大小
return 8;
case SCC_HIR_TYPE_STRUCT:
case SCC_HIR_TYPE_UNION:
// 暂时无法计算,保守返回 0 或报错
LOG_ERROR("Cannot compute size of struct/union without layout info");
return 0;
default:
LOG_ERROR("Unknown type tag %d", type->tag);
return 0;
}
}
// 辅助函数计算数组实际长度如果原长度为0
static void resolve_array_length(scc_ast2ir_ctx_t *ctx,
const scc_hir_type_t *orig_array_type,
@@ -334,7 +272,7 @@ scc_hir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx,
// === 3. 直接添加到模块,不经过 builder 的 uniquing ===
// 因为此时我们不需要类型去重,只需要一个确定不移的引用
scc_hir_type_ref_t place_ref =
scc_hir_module_add_type(&ctx->builder.cprog->module, &placeholder);
scc_hir_module_add_type(scc_ast2ir_mir_module(ctx), &placeholder);
// === 4. 将映射写入缓存(关键!必须在递归前) ===
scc_hashtable_set(&ctx->type_cache, canon, (void *)(usize)place_ref);
@@ -357,7 +295,7 @@ scc_hir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx,
// === 6. 将字段填入占位类型 ===
scc_hir_type_t *place_type =
scc_hir_module_get_type(&ctx->builder.cprog->module, place_ref);
scc_hir_module_get_type(scc_ast2ir_mir_module(ctx), place_ref);
// 注意scc_hir_type_init 已经为 struct/union 初始化了 fields 空向量
// 这里直接 push 即可(也可以先 scc_vec_free 再 init看需要
scc_vec_foreach(fields, i) {
@@ -895,13 +833,15 @@ scc_hir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx,
// 3. 确定转换模式SEXT / ZEXT / TRUNC
// 这里用简单的启发式:根据大小变化决定
scc_hir_type_t *src_type = scc_hir_module_get_type_by_value(
&ctx->builder.cprog->module, operand);
scc_ast2ir_mir_module(ctx), operand);
scc_hir_type_t *dst_type =
scc_hir_module_get_type(&ctx->builder.cprog->module, target_type);
scc_hir_module_get_type(scc_ast2ir_mir_module(ctx), target_type);
usize src_size =
scc_hir_type_size(ctx, src_type); // 你可能有这个函数,否则自行计算
usize dst_size = scc_hir_type_size(ctx, dst_type);
usize src_size = scc_hir_module_type_size(
scc_ast2ir_mir_module(ctx),
src_type); // 你可能有这个函数,否则自行计算
usize dst_size =
scc_hir_module_type_size(scc_ast2ir_mir_module(ctx), dst_type);
int conv_kind;
if (dst_size > src_size) {
@@ -923,8 +863,7 @@ scc_hir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx,
.data.conv.target_type = target_type,
.data.conv.conv_type = conv_kind,
};
return scc_hir_module_add_value(&ctx->builder.cprog->module,
&conv_node);
return scc_hir_module_add_value(scc_ast2ir_mir_module(ctx), &conv_node);
}
case SCC_AST_EXPR_SIZE_OF: {
// 1. 将 sizeof 的操作数(类型或表达式)转换为 IR 类型
@@ -939,7 +878,7 @@ scc_hir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx,
scc_hir_value_ref_t dummy =
scc_ast2ir_expr(ctx, expr->attr_of.expr, false);
hir_type =
scc_hir_module_get_value(&ctx->builder.cprog->module, dummy)
scc_hir_module_get_value(scc_ast2ir_mir_module(ctx), dummy)
->type;
} else {
scc_ap_t val;
@@ -951,8 +890,9 @@ scc_hir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx,
// 2. 计算大小
const scc_hir_type_t *type =
scc_hir_module_get_type(&ctx->builder.cprog->module, hir_type);
usize dst_size = scc_hir_type_size(ctx, type);
scc_hir_module_get_type(scc_ast2ir_mir_module(ctx), hir_type);
usize dst_size =
scc_hir_module_type_size(scc_ast2ir_mir_module(ctx), type);
scc_ap_t val;
val.data.digit = dst_size;
@@ -971,7 +911,7 @@ scc_hir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx,
scc_ast_qual_type_t *ast_type = expr->compound.base->lvalue.type;
scc_hir_type_ref_t type_ref = scc_ast2ir_type(ctx, ast_type);
const scc_hir_type_t *type =
scc_hir_module_get_type(&ctx->builder.cprog->module, type_ref);
scc_hir_module_get_type(scc_ast2ir_mir_module(ctx), type_ref);
// 2. 分配栈上临时存储
scc_hir_value_ref_t storage =
@@ -1073,10 +1013,10 @@ scc_hir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx,
} else {
// 右值:如果是数组类型,退化为指针(返回地址)
scc_hir_type_t *ir_type = scc_hir_module_get_type_by_value(
&ctx->builder.cprog->module, in);
scc_ast2ir_mir_module(ctx), in);
if (ir_type->tag == SCC_HIR_TYPE_PTR) {
scc_hir_type_t *target_type = scc_hir_module_get_type(
&ctx->builder.cprog->module, ir_type->data.pointer.base);
scc_ast2ir_mir_module(ctx), ir_type->data.pointer.base);
if (target_type->tag == SCC_HIR_TYPE_ARRAY) {
// 生成 getptr 获取数组首地址
return scc_hir_builder_get_elem_ptr(&ctx->builder, in,
@@ -1344,8 +1284,7 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, const scc_ast_decl_t *decl,
const scc_hir_type_t *orig_type;
SCC_HIR_BUILDER_BEGIN_BORROW(
&ctx->builder, orig_type,
scc_hir_module_get_type(&ctx->builder.cprog->module,
orig_type_ref));
scc_hir_module_get_type(scc_ast2ir_mir_module(ctx), orig_type_ref));
scc_hir_type_t final_type_desc = *orig_type;
SCC_HIR_BUILDER_END_BORROW(&ctx->builder);
@@ -1384,7 +1323,7 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, const scc_ast_decl_t *decl,
const scc_hir_type_t *final_type;
SCC_HIR_BUILDER_BEGIN_BORROW(
&ctx->builder, final_type,
scc_hir_module_get_type(&ctx->builder.cprog->module,
scc_hir_module_get_type(scc_ast2ir_mir_module(ctx),
final_type_ref));
scc_hir_type_t type = *final_type;
SCC_HIR_BUILDER_END_BORROW(&ctx->builder);