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:
@@ -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);
|
||||
|
||||
@@ -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: {
|
||||
// 目标指针大小,可以定义为 8(64位)或从 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);
|
||||
|
||||
Reference in New Issue
Block a user