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:
@@ -18,8 +18,8 @@ void scc_ast2ir_ctx_init(scc_ast2ir_ctx_t *ctx, const scc_abi_type_calc_t *abi,
|
||||
scc_hir_cprog_t *cprog);
|
||||
void scc_ast2ir_ctx_drop(scc_ast2ir_ctx_t *ctx);
|
||||
|
||||
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);
|
||||
void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, const scc_ast_decl_t *decl,
|
||||
cbool is_global);
|
||||
scc_hir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx,
|
||||
@@ -27,6 +27,6 @@ scc_hir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx,
|
||||
cbool is_lvalue);
|
||||
void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, const scc_ast_stmt_t *stmt);
|
||||
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);
|
||||
|
||||
#endif /* __SCC_AST2IR_H__ */
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user