refactor(ast): 将AST类型系统重构为规范类型系统

- 将scc_ast_type_t替换为scc_ast_qual_type_t,引入规范类型概念
- 添加scc_ast_canonical_type_t联合体用于表示规范类型
- 修改头文件结构,移除大量内联初始化函数,改为使用AST上下文分配器
- 添加SCC_AST_ALLOC宏用于统一节点分配管理
- 更新builtin类型枚举定义,添加类型计数常量

feat(ast): 引入AST上下文管理器

- 创建scc_ast_ctx_t结构体用于管理AST节点生命周期
- 实现类型池化机制,支持内置类型的统一管理
- 添加canonical类型获取和分配接口

refactor(abi): 适配新的AST类型系统

- 更新头文件包含,从<scc_ir.h>改为<scc_hir.h>
- 适配函数参数类型,使用qual_type替代原始type
- 使用scc_ast_canon_type()函数获取规范类型进行处理

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
zzy
2026-04-27 20:40:03 +08:00
parent d7ac5fd30b
commit f6bc40ae4a
20 changed files with 1302 additions and 1045 deletions

View File

@@ -1,10 +1,11 @@
#include <scc_ast2ir.h>
#include <scc_ast_def.h>
#include <scc_ast_utils.h>
#include <scc_hir_builder.h>
#include <scc_hir_def.h>
static scc_hir_type_ref_t parse_base_type(scc_ast2ir_ctx_t *ctx,
const scc_ast_type_t *ast_type) {
const scc_ast_qual_type_t *ast_type) {
scc_abi_type_layout_t layout;
// 映射内置类型
ctx->abi->compute_type_layout(ctx->abi, (void *)ast_type, &layout);
@@ -26,7 +27,7 @@ static scc_hir_type_ref_t parse_base_type(scc_ast2ir_ctx_t *ctx,
return SCC_HIR_REF_nullptr;
}
static inline void parse_struct_union_layout(scc_ast_type_t *type) {}
static inline void parse_struct_union_layout(scc_ast_qual_type_t *type) {}
// 辅助函数计算数组实际长度如果原长度为0
static void resolve_array_length(scc_ast2ir_ctx_t *ctx,
@@ -123,7 +124,7 @@ static void emit_array_initialization(scc_ast2ir_ctx_t *ctx,
}
scc_hir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx,
const scc_ast_type_t *ast_type) {
const scc_ast_qual_type_t *ast_type) {
if (ctx == nullptr || ast_type == nullptr) {
LOG_ERROR("args is nullptr");
return 0;
@@ -137,7 +138,7 @@ scc_hir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx,
case SCC_AST_TYPE_POINTER: {
scc_hir_type_init(&ir_type, SCC_HIR_TYPE_PTR);
scc_hir_type_ref_t pointee_type =
scc_ast2ir_type(ctx, ast_type->pointer.pointee);
scc_ast2ir_type(ctx, scc_ast_canon_type(ast_type)->pointer.pointee);
ir_type.data.pointer.base = pointee_type;
break;
}
@@ -145,17 +146,20 @@ scc_hir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx,
scc_hir_type_init(&ir_type, SCC_HIR_TYPE_ARRAY);
scc_hir_type_ref_t element_type =
scc_ast2ir_type(ctx, ast_type->array.element);
scc_ast2ir_type(ctx, scc_ast_canon_type(ast_type)->array.element);
ir_type.data.array.base = element_type;
ir_type.data.array.len = 0;
if (ast_type->array.size) {
if (scc_ast_canon_type(ast_type)->array.size) {
// TODO constant expression
if (ast_type->array.size->base.type != SCC_AST_EXPR_INT_LITERAL) {
if (scc_ast_canon_type(ast_type)->array.size->base.type !=
SCC_AST_EXPR_INT_LITERAL) {
Panic("TODO: array size expression");
}
scc_ap_t value;
scc_ap_from_cstr(&value, ast_type->array.size->literal.lexme, 10);
scc_ap_from_cstr(
&value, scc_ast_canon_type(ast_type)->array.size->literal.lexme,
10);
// FIXME hack
ir_type.data.array.len = value.data.digit;
}
@@ -165,8 +169,8 @@ scc_hir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx,
scc_hir_type_init(&ir_type, SCC_HIR_TYPE_FUNC);
// 处理返回类型
scc_hir_type_ref_t ret_type =
scc_ast2ir_type(ctx, ast_type->function.return_type);
scc_hir_type_ref_t ret_type = scc_ast2ir_type(
ctx, scc_ast_canon_type(ast_type)->function.return_type);
// 将返回类型添加到程序的类型容器中
ir_type.data.function.ret_type = ret_type;
@@ -174,9 +178,9 @@ scc_hir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx,
// 转换参数类型
scc_hir_type_ref_vec_t params;
scc_vec_init(params);
scc_vec_foreach(ast_type->function.params, i) {
scc_vec_foreach(scc_ast_canon_type(ast_type)->function.params, i) {
scc_ast_decl_t *decl_param =
scc_vec_at(ast_type->function.params, i);
scc_vec_at(scc_ast_canon_type(ast_type)->function.params, i);
Assert(decl_param->base.type == SCC_AST_DECL_PARAM);
scc_hir_type_ref_t tmp_type =
scc_ast2ir_type(ctx, decl_param->param.type);
@@ -190,10 +194,14 @@ scc_hir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx,
scc_hir_type_init(&ir_type, ast_type->base.type == SCC_AST_TYPE_STRUCT
? SCC_HIR_TYPE_STRUCT
: SCC_HIR_TYPE_UNION);
Assert(ast_type->record.decl != nullptr);
scc_vec_foreach(ast_type->record.decl->record.fields, i) {
scc_ast_decl_t *decl_field =
scc_vec_at(ast_type->record.decl->record.fields, i);
if (scc_ast_canon_type(ast_type)->record.decl == nullptr) {
Panic("%s record fields is nullptr",
scc_ast_canon_type(ast_type)->record.name);
}
scc_vec_foreach(
scc_ast_canon_type(ast_type)->record.decl->record.fields, i) {
scc_ast_decl_t *decl_field = scc_vec_at(
scc_ast_canon_type(ast_type)->record.decl->record.fields, i);
Assert(decl_field->base.type == SCC_AST_DECL_VAR);
scc_hir_type_ref_t field_type =
scc_ast2ir_type(ctx, decl_field->var.type);
@@ -202,13 +210,19 @@ scc_hir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx,
break;
}
case SCC_AST_TYPE_ENUM:
return parse_base_type(
ctx, &(scc_ast_type_t){.base.type = SCC_AST_TYPE_BUILTIN,
.builtin = SCC_AST_BUILTIN_TYPE_INT});
scc_ast_canon_type_t int_canon_type = {
.builtin = SCC_AST_BUILTIN_TYPE_INT,
};
scc_ast_qual_type_t int_type = {
.base.type = SCC_AST_TYPE_BUILTIN,
.type = &int_canon_type,
};
return parse_base_type(ctx, &int_type);
case SCC_AST_TYPE_TYPEDEF:
// TODO maybe using cache
return scc_ast2ir_type(ctx,
ast_type->typedef_type.decl->typedef_decl.type);
return scc_ast2ir_type(
ctx,
scc_ast_canon_type(ast_type)->typedef_type.decl->typedef_decl.type);
default:
LOG_FATAL("Unsupported AST type: %d", ast_type->base.type);
return 0;
@@ -560,10 +574,45 @@ scc_hir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx,
elem_ptr); // 作为右值:加载值
}
}
case SCC_AST_EXPR_MEMBER:
break;
case SCC_AST_EXPR_PTR_MEMBER:
break;
case SCC_AST_EXPR_MEMBER: {
// 1. 获取基对象的左值(地址)
scc_hir_value_ref_t base_ptr =
scc_ast2ir_expr(ctx, expr->member.base, true);
// 2. 通过偏移生成字段地址
// 需要基对象类型来计算索引:假设 sema 填好了 _target_idx
usize field_idx = expr->member._target_idx;
scc_ap_t idx_ap;
scc_ap_set_int(&idx_ap, field_idx);
scc_hir_value_ref_t idx_val = scc_hir_builder_integer(
&ctx->builder, scc_hir_builder_type_u64(&ctx->builder), &idx_ap);
scc_hir_value_ref_t field_ptr =
scc_hir_builder_get_elem_ptr(&ctx->builder, base_ptr, idx_val);
if (is_lvalue)
return field_ptr;
else
return scc_hir_builder_load(&ctx->builder, field_ptr);
}
case SCC_AST_EXPR_PTR_MEMBER: {
// 1. 计算指针值obj->field 等价于 (*obj).field
scc_hir_value_ref_t obj_ptr =
scc_ast2ir_expr(ctx, expr->member.base, false);
// 2. 解引用得到对象地址,再访问成员
// 但更简单:先 load 出对象值不对obj
// 是指向结构体的指针,我们需要指针的地址? 实际上obj->field 相当于
// (*(obj)).field所以可以直接用 obj 作为基地址进行 get_elem_ptr
// 因为 get_elem_ptr 接收一个指针obj 本身就是指向结构体的指针。
usize field_idx = expr->member._target_idx;
scc_ap_t idx_ap;
scc_ap_set_int(&idx_ap, field_idx);
scc_hir_value_ref_t idx_val = scc_hir_builder_integer(
&ctx->builder, scc_hir_builder_type_u64(&ctx->builder), &idx_ap);
scc_hir_value_ref_t field_ptr =
scc_hir_builder_get_elem_ptr(&ctx->builder, obj_ptr, idx_val);
if (is_lvalue)
return field_ptr;
else
return scc_hir_builder_load(&ctx->builder, field_ptr);
}
case SCC_AST_EXPR_CAST:
break;
case SCC_AST_EXPR_SIZE_OF: {
@@ -576,8 +625,9 @@ scc_hir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx,
// return scc_hir_builder_integer(
// &ctx->builder, scc_hir_builder_type_u64(&ctx->builder), val);
}
case SCC_AST_EXPR_COMPOUND:
case SCC_AST_EXPR_COMPOUND: {
break;
}
case SCC_AST_EXPR_LVALUE:
break;
// SCC_AST_EXPR_BUILTIN,// 内置表达式 ... directive map to ir builtin
@@ -945,9 +995,10 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, const scc_ast_decl_t *decl,
scc_hir_builder_begin_func(&ctx->builder, func_ref);
scc_hir_builder_begin_bblock(&ctx->builder, "entry");
scc_vec_foreach(decl->func.type->function.params, i) {
scc_ast_decl_t *param =
scc_vec_at(decl->func.type->function.params, i);
scc_vec_foreach(scc_ast_canon_type(decl->func.type)->function.params,
i) {
scc_ast_decl_t *param = scc_vec_at(
scc_ast_canon_type(decl->func.type)->function.params, i);
scc_ast2ir_decl(ctx, param, false);
}
@@ -968,7 +1019,8 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, const scc_ast_decl_t *decl,
}
case SCC_AST_DECL_PARAM: {
if (decl->param.type->base.type == SCC_AST_TYPE_BUILTIN &&
decl->param.type->builtin.type == SCC_AST_BUILTIN_TYPE_VOID) {
scc_ast_canon_type(decl->param.type)->builtin.type ==
SCC_AST_BUILTIN_TYPE_VOID) {
break;
}
scc_hir_type_ref_t parma_type_ref =
@@ -988,12 +1040,15 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, const scc_ast_decl_t *decl,
}
case SCC_AST_DECL_STRUCT:
case SCC_AST_DECL_UNION:
scc_ast_type_t type = {
.base.type =
SCC_AST_DECL_STRUCT ? SCC_AST_TYPE_STRUCT : SCC_AST_TYPE_UNION,
scc_ast_canon_type_t canon_type = {
.record.decl = decl,
.record.name = decl->name,
};
scc_ast_qual_type_t type = {
.base.type =
SCC_AST_DECL_STRUCT ? SCC_AST_TYPE_STRUCT : SCC_AST_TYPE_UNION,
.type = &canon_type,
};
scc_hir_type_ref_t type_ref = scc_ast2ir_type(ctx, &type);
// scc_hir_builder_global_alloca(&ctx->builder, type_ref,
// SCC_HIR_REF_nullptr);
@@ -1024,8 +1079,8 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, const scc_ast_decl_t *decl,
}
}
void scc_ast2ir_translation_unit(scc_ast2ir_ctx_t *ctx,
const scc_ast_translation_unit_t *tu) {
void scc_ast2ir_run(scc_ast2ir_ctx_t *ctx,
const scc_ast_translation_unit_t *tu) {
Assert(ctx != nullptr && tu != nullptr);
scc_vec_foreach(tu->declarations, i) {