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

@@ -53,7 +53,7 @@ static const char *node_type_names[] = {
[SCC_AST_EXPR_STRING_LITERAL] = "StringLiteralExpr",
[SCC_AST_EXPR_IDENTIFIER] = "IdentifierExpr",
[scc_ast_expr_t_END] = "ERROR",
[scc_ast_type_t_BEGIN] = "ERROR",
[scc_ast_qual_type_t_BEGIN] = "ERROR",
[SCC_AST_TYPE_BUILTIN] = "BuiltinType",
[SCC_AST_TYPE_POINTER] = "PointerType",
[SCC_AST_TYPE_ARRAY] = "ArrayType",
@@ -62,7 +62,7 @@ static const char *node_type_names[] = {
[SCC_AST_TYPE_UNION] = "UnionType",
[SCC_AST_TYPE_ENUM] = "EnumType",
[SCC_AST_TYPE_TYPEDEF] = "TypedefType",
[scc_ast_type_t_END] = "ERROR",
[scc_ast_qual_type_t_END] = "ERROR",
[scc_ast_translation_unit_t_BEGIN] = "ERROR",
[SCC_AST_TRANSLATION_UNIT] = "TranslationUnit",
[scc_ast_translation_unit_t_END] = "ERROR",
@@ -200,8 +200,8 @@ static inline void dump_child_node(scc_tree_dump_t *td, scc_ast_node_t *child,
scc_tree_dump_pop(td);
}
static inline void dump_quals(scc_ast_decl_specifier_t quals,
scc_tree_dump_t *td) {
static inline void dump_quals(scc_tree_dump_t *td,
scc_ast_decl_specifier_t quals) {
if (quals.is_atomic)
scc_tree_dump_value(td, " atomic");
if (quals.is_restrict)
@@ -216,18 +216,20 @@ static inline void dump_quals(scc_ast_decl_specifier_t quals,
scc_tree_dump_value(td, " extern");
}
static void dump_type_impl(scc_ast_type_t *type, scc_tree_dump_t *td) {
static void dump_type_impl(scc_tree_dump_t *td,
const scc_ast_qual_type_t *type) {
if (!type)
return;
scc_tree_dump_begin_line(td);
scc_tree_dump_node(td, "%s", get_node_type_str(type->base.type));
dump_quals(type->quals, td);
dump_quals(td, type->quals);
switch (type->base.type) {
case SCC_AST_TYPE_BUILTIN:
scc_tree_dump_value(td, " '%s'",
get_builtin_type_str(type->builtin.type));
scc_tree_dump_value(
td, " '%s'",
get_builtin_type_str(scc_ast_canon_type(type)->builtin.type));
break;
case SCC_AST_TYPE_POINTER:
scc_tree_dump_value(td, " pointer");
@@ -239,25 +241,29 @@ static void dump_type_impl(scc_ast_type_t *type, scc_tree_dump_t *td) {
scc_tree_dump_value(td, " function");
break;
case SCC_AST_TYPE_STRUCT:
if (type->record.name)
scc_tree_dump_value(td, " 'struct %s'", type->record.name);
if (scc_ast_canon_type(type)->record.name)
scc_tree_dump_value(td, " 'struct %s'",
scc_ast_canon_type(type)->record.name);
else
scc_tree_dump_value(td, " <anonymous struct>");
break;
case SCC_AST_TYPE_UNION:
if (type->record.name)
scc_tree_dump_value(td, " 'union %s'", type->record.name);
if (scc_ast_canon_type(type)->record.name)
scc_tree_dump_value(td, " 'union %s'",
scc_ast_canon_type(type)->record.name);
else
scc_tree_dump_value(td, " <anonymous union>");
break;
case SCC_AST_TYPE_ENUM:
if (type->record.name)
scc_tree_dump_value(td, " 'enum %s'", type->record.name);
if (scc_ast_canon_type(type)->record.name)
scc_tree_dump_value(td, " 'enum %s'",
scc_ast_canon_type(type)->record.name);
else
scc_tree_dump_value(td, " anonymous enum");
break;
case SCC_AST_TYPE_TYPEDEF:
scc_tree_dump_value(td, " '%s'", type->typedef_type.name);
scc_tree_dump_value(td, " '%s'",
scc_ast_canon_type(type)->typedef_type.name);
break;
default:
break;
@@ -265,26 +271,35 @@ static void dump_type_impl(scc_ast_type_t *type, scc_tree_dump_t *td) {
switch (type->base.type) {
case SCC_AST_TYPE_POINTER:
dump_child_node(td, (scc_ast_node_t *)type->pointer.pointee, true);
dump_child_node(
td, (scc_ast_node_t *)scc_ast_canon_type(type)->pointer.pointee,
true);
break;
case SCC_AST_TYPE_ARRAY:
dump_child_node(td, (scc_ast_node_t *)type->array.element,
type->array.size == nullptr);
if (type->array.size)
dump_child_node(td, (scc_ast_node_t *)type->array.size, true);
dump_child_node(
td, (scc_ast_node_t *)scc_ast_canon_type(type)->array.element,
scc_ast_canon_type(type)->array.size == nullptr);
if (scc_ast_canon_type(type)->array.size)
dump_child_node(
td, (scc_ast_node_t *)scc_ast_canon_type(type)->array.size,
true);
break;
case SCC_AST_TYPE_FUNCTION:
scc_tree_dump_push(td, false);
scc_tree_dump_begin_line(td);
scc_tree_dump_node(td, "%s", "ReturnType");
dump_child_node(td, (scc_ast_node_t *)type->function.return_type, true);
dump_child_node(
td,
(scc_ast_node_t *)scc_ast_canon_type(type)->function.return_type,
true);
scc_tree_dump_pop(td);
scc_tree_dump_push(td, true);
if (scc_vec_size(type->function.params) != 0) {
scc_vec_foreach(type->function.params, i) {
scc_ast_decl_t *param = scc_vec_at(type->function.params, i);
dump_type_impl(param->param.type, td);
if (scc_vec_size(scc_ast_canon_type(type)->function.params) != 0) {
scc_vec_foreach(scc_ast_canon_type(type)->function.params, i) {
scc_ast_decl_t *param =
scc_vec_at(scc_ast_canon_type(type)->function.params, i);
dump_type_impl(td, param->param.type);
}
} else {
scc_tree_dump_begin_line(td);
@@ -297,7 +312,7 @@ static void dump_type_impl(scc_ast_type_t *type, scc_tree_dump_t *td) {
}
}
static void dump_expr_impl(scc_ast_expr_t *expr, scc_tree_dump_t *td) {
static void dump_expr_impl(scc_tree_dump_t *td, const scc_ast_expr_t *expr) {
if (!expr)
return;
@@ -401,7 +416,7 @@ static void dump_expr_impl(scc_ast_expr_t *expr, scc_tree_dump_t *td) {
}
}
static void dump_stmt_impl(scc_ast_stmt_t *stmt, scc_tree_dump_t *td) {
static void dump_stmt_impl(scc_tree_dump_t *td, const scc_ast_stmt_t *stmt) {
if (!stmt)
return;
@@ -479,7 +494,7 @@ static void dump_stmt_impl(scc_ast_stmt_t *stmt, scc_tree_dump_t *td) {
}
}
static void dump_decl_impl(scc_ast_decl_t *decl, scc_tree_dump_t *td) {
static void dump_decl_impl(scc_tree_dump_t *td, const scc_ast_decl_t *decl) {
if (!decl)
return;
@@ -535,8 +550,8 @@ static void dump_decl_impl(scc_ast_decl_t *decl, scc_tree_dump_t *td) {
}
}
static void dump_unit_impl(scc_ast_translation_unit_t *unit,
scc_tree_dump_t *td) {
static void dump_unit_impl(scc_tree_dump_t *td,
const scc_ast_translation_unit_t *unit) {
if (!unit)
return;
@@ -552,13 +567,13 @@ void scc_ast_dump_node(scc_tree_dump_t *td, const scc_ast_node_t *node) {
if (!node)
return;
if (SCC_AST_IS_A(scc_ast_expr_t, node))
dump_expr_impl(SCC_AST_CAST_TO(scc_ast_expr_t, node), td);
dump_expr_impl(td, SCC_AST_CAST_TO(scc_ast_expr_t, node));
else if (SCC_AST_IS_A(scc_ast_stmt_t, node))
dump_stmt_impl(SCC_AST_CAST_TO(scc_ast_stmt_t, node), td);
dump_stmt_impl(td, SCC_AST_CAST_TO(scc_ast_stmt_t, node));
else if (SCC_AST_IS_A(scc_ast_decl_t, node))
dump_decl_impl(SCC_AST_CAST_TO(scc_ast_decl_t, node), td);
else if (SCC_AST_IS_A(scc_ast_type_t, node))
dump_type_impl(SCC_AST_CAST_TO(scc_ast_type_t, node), td);
dump_decl_impl(td, SCC_AST_CAST_TO(scc_ast_decl_t, node));
else if (SCC_AST_IS_A(scc_ast_qual_type_t, node))
dump_type_impl(td, SCC_AST_CAST_TO(scc_ast_qual_type_t, node));
else if (SCC_AST_IS_A(scc_ast_translation_unit_t, node))
dump_unit_impl(SCC_AST_CAST_TO(scc_ast_translation_unit_t, node), td);
dump_unit_impl(td, SCC_AST_CAST_TO(scc_ast_translation_unit_t, node));
}

42
libs/ast/src/scc_ast.c Normal file
View File

@@ -0,0 +1,42 @@
#include <scc_ast.h>
static scc_ast_canon_type_t *alloc_canonical_type(scc_ast_ctx_t *ctx) {
scc_ast_canon_type_t *type = scc_malloc(sizeof(scc_ast_canon_type_t));
if (type == nullptr) {
Panic("alloc_canonical_type: malloc failed");
}
scc_vec_push(ctx->canonical_type_pool, type);
return type;
}
void scc_ast_ctx_init(scc_ast_ctx_t *ctx) {
scc_vec_init(ctx->canonical_type_pool);
scc_vec_init(ctx->all_nodes);
// 创建全部内置类型
for (int i = 0; i < SCC_AST_BUILTIN_TYPE_COUNT; i += 1) {
scc_ast_canon_type_t *t = alloc_canonical_type(ctx);
t->builtin.type = (scc_ast_builtin_type_t)i; // 直接按顺序对应
ctx->builtin_types[i] = t;
}
}
void scc_ast_ctx_drop(scc_ast_ctx_t *ctx) {
// 释放所有规范类型
scc_vec_foreach(ctx->canonical_type_pool, i) {
scc_free(ctx->canonical_type_pool.data[i]);
}
scc_vec_foreach(ctx->all_nodes, i) { scc_free(ctx->all_nodes.data[i]); }
scc_vec_free(ctx->canonical_type_pool);
}
scc_ast_canon_type_t *
scc_ast_ctx_get_builtin_type(scc_ast_ctx_t *ctx, scc_ast_builtin_type_t kind) {
assert(kind < SCC_AST_BUILTIN_TYPE_COUNT &&
kind > SCC_AST_BUILTIN_TYPE_UNKNOWN);
return ctx->builtin_types[kind];
}
scc_ast_canon_type_t *scc_ast_ctx_alloc_type(scc_ast_ctx_t *ctx) {
return alloc_canonical_type(ctx);
}