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:
@@ -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
42
libs/ast/src/scc_ast.c
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user