feat(ast): 添加完整的内置类型支持并重构类型定义

- 添加 va_list、bool、signed/unsigned 各种整数类型等内置类型
- 重新排列内置类型枚举顺序,增加 UNKNOWN 类型
- 为复合字面量、指针类型、数组类型添加初始化函数
- 添加结构体、联合体、枚举、typedef 类型的初始化函数
- 更新类型转储功能以支持新的内置类型显示

refactor(parser): 优化类型解析和声明处理逻辑

- 修改类型解析函数返回类型为通用 AST 节点
- 重构声明解析逻辑,支持变量和函数声明的不同处理路径
- 更新语法分析规则中的空格标记处理
- 简化表达式解析中的错误处理流程

fix(ast): 修复参数声明和类型转储相关问题

- 修正参数声明初始化函数中对 name 参数可为空的处理
- 修复类型转储中修饰符显示和指针类型显示问题
- 更新 AST 转储中空值检查使用正确的 null 比较
This commit is contained in:
zzy
2026-03-11 16:51:52 +08:00
parent 742bede02f
commit ce5414f2eb
14 changed files with 1717 additions and 1136 deletions

View File

@@ -3,28 +3,29 @@
#include "ast_def.h"
extern scc_ast_type_t scc_ast_builtin_type_va_list;
extern scc_ast_type_t scc_ast_builtin_type_void;
extern scc_ast_type_t scc_ast_builtin_type_bool;
extern scc_ast_type_t scc_ast_builtin_type_char;
extern scc_ast_type_t scc_ast_builtin_type_short;
extern scc_ast_type_t scc_ast_builtin_type_long;
extern scc_ast_type_t scc_ast_builtin_type_long_long;
extern scc_ast_type_t scc_ast_builtin_type_int;
extern scc_ast_type_t scc_ast_builtin_type_float;
extern scc_ast_type_t scc_ast_builtin_type_double;
extern scc_ast_type_t scc_ast_builtin_type_char;
extern scc_ast_type_t scc_ast_builtin_type_void;
extern scc_ast_type_t scc_ast_builtin_type_long;
extern scc_ast_type_t scc_ast_builtin_type_long_long;
extern scc_ast_type_t scc_ast_builtin_type_short;
extern scc_ast_type_t scc_ast_builtin_type_bool;
extern scc_ast_type_t scc_ast_builtin_type_long_double;
extern scc_ast_type_t scc_ast_builtin_type_complex_float;
extern scc_ast_type_t scc_ast_builtin_type_complex_double;
extern scc_ast_type_t scc_ast_builtin_type_complex_long_double;
extern scc_ast_type_t scc_ast_builtin_type_unsigned_char;
extern scc_ast_type_t scc_ast_builtin_type_unsigned_short;
extern scc_ast_type_t scc_ast_builtin_type_unsigned_int;
extern scc_ast_type_t scc_ast_builtin_type_unsigned_long;
extern scc_ast_type_t scc_ast_builtin_type_unsigned_long_long;
extern scc_ast_type_t scc_ast_builtin_type_unsigned_short;
extern scc_ast_type_t scc_ast_builtin_type_unsigned_char;
extern scc_ast_type_t scc_ast_builtin_type_signed_char;
extern scc_ast_type_t scc_ast_builtin_type_signed_short;
extern scc_ast_type_t scc_ast_builtin_type_signed_int;
extern scc_ast_type_t scc_ast_builtin_type_signed_long;
extern scc_ast_type_t scc_ast_builtin_type_signed_long_long;
extern scc_ast_type_t scc_ast_builtin_type_signed_short;
extern scc_ast_type_t scc_ast_builtin_type_signed_char;
#endif

View File

@@ -95,20 +95,34 @@ typedef struct {
* @brief 内置类型枚举
*/
typedef enum {
SCC_AST_BUILTIN_TYPE_UNKNOWN,
SCC_AST_BUILTIN_TYPE_VA_LIST,
SCC_AST_BUILTIN_TYPE_VOID,
SCC_AST_BUILTIN_TYPE_BOOL,
SCC_AST_BUILTIN_TYPE_CHAR,
SCC_AST_BUILTIN_TYPE_SHORT,
SCC_AST_BUILTIN_TYPE_INT,
SCC_AST_BUILTIN_TYPE_LONG,
SCC_AST_BUILTIN_TYPE_LONG_LONG,
SCC_AST_BUILTIN_TYPE_UNSIGNED_CHAR,
SCC_AST_BUILTIN_TYPE_UNSIGNED_SHORT,
SCC_AST_BUILTIN_TYPE_UNSIGNED_INT,
SCC_AST_BUILTIN_TYPE_UNSIGNED_LONG,
SCC_AST_BUILTIN_TYPE_UNSIGNED_LONG_LONG,
SCC_AST_BUILTIN_TYPE_SIGNED_CHAR,
SCC_AST_BUILTIN_TYPE_SIGNED_SHORT,
SCC_AST_BUILTIN_TYPE_SIGNED_INT,
SCC_AST_BUILTIN_TYPE_SIGNED_LONG,
SCC_AST_BUILTIN_TYPE_SIGNED_LONG_LONG,
SCC_AST_BUILTIN_TYPE_FLOAT,
SCC_AST_BUILTIN_TYPE_DOUBLE,
SCC_AST_BUILTIN_TYPE_LONG_DOUBLE,
SCC_AST_BUILTIN_TYPE_BOOL,
SCC_AST_BUILTIN_TYPE_COMPLEX_FLOAT,
SCC_AST_BUILTIN_TYPE_COMPLEX_DOUBLE,
SCC_AST_BUILTIN_TYPE_COMPLEX_LONG_DOUBLE,
SCC_AST_BUILTIN_TYPE_VA_LIST,
} scc_ast_builtin_type_t;
/**
@@ -284,7 +298,7 @@ struct scc_ast_expr {
const char *name;
usize _target_idx;
} member;
// 类型转换
// cast 类型转换
struct {
scc_ast_type_t *type;
scc_ast_expr_t *expr;

View File

@@ -46,12 +46,11 @@ static inline void scc_ast_decl_func_init(scc_ast_decl_t *decl,
decl->func.body = body;
}
// body can be null
// name can be null
static inline void scc_ast_decl_param_init(scc_ast_decl_t *decl,
scc_ast_type_t *type,
const char *name,
scc_ast_stmt_t *body) {
Assert(decl != null && name != null && type != null);
const char *name) {
Assert(decl != null && type != null);
decl->base.loc = scc_pos_create();
decl->base.type = SCC_AST_DECL_PARAM;
decl->name = name;
@@ -342,10 +341,26 @@ static inline void scc_ast_expr_ptr_member_init(scc_ast_expr_t *expr,
_scc_ast_expr_member_init(expr, SCC_AST_EXPR_PTR_MEMBER, object, member);
}
// TODO
// SCC_AST_EXPR_CAST, // 类型转换
// SCC_AST_EXPR_SIZE_OF, // sizeof
// SCC_AST_EXPR_ALIGN_OF, // _Alignof
// SCC_AST_EXPR_COMPOUND_LITERAL, // 复合字面量
// init can be null
static inline void
scc_ast_expr_compound_literal_init(scc_ast_expr_t *expr, scc_ast_type_t *type,
scc_ast_expr_vec_t *init) {
Assert(expr != null && type != null);
expr->base.loc = scc_pos_create();
expr->base.type = SCC_AST_EXPR_COMPOUND_LITERAL;
expr->compound_literal.type = type;
if (init == null) {
scc_vec_init(expr->compound_literal.init_list);
} else {
expr->compound_literal.init_list = *init;
scc_vec_init(*init);
}
}
static inline void scc_ast_expr_literal_init(scc_ast_expr_t *expr,
scc_ast_node_type_t type,
@@ -388,9 +403,36 @@ static inline void scc_ast_expr_identifier_init(scc_ast_expr_t *expr,
expr->identifier._target = null;
}
// SCC_AST_TYPE_BUILTIN, // 内置类型
// SCC_AST_TYPE_POINTER, // 指针类型
// SCC_AST_TYPE_ARRAY, // 数组类型
// have defined builtin type
static inline void _scc_ast_type_builtin_init(scc_ast_type_t *type,
scc_ast_builtin_type_t builtin) {
Assert(type != null);
type->base.loc = scc_pos_create();
type->base.type = SCC_AST_TYPE_BUILTIN;
type->builtin.type = builtin;
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
}
static inline void scc_ast_type_pointer_init(scc_ast_type_t *type,
scc_ast_type_t *pointee) {
Assert(type != null && pointee != null);
type->base.loc = scc_pos_create();
type->base.type = SCC_AST_TYPE_POINTER;
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
type->pointer.pointee = pointee;
}
// size can be null
static inline void scc_ast_type_array_init(scc_ast_type_t *type,
scc_ast_type_t *element,
scc_ast_expr_t *size) {
Assert(type != null && element != null);
type->base.loc = scc_pos_create();
type->base.type = SCC_AST_TYPE_ARRAY;
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
type->array.element = element;
type->array.size = size;
}
// return_type and params can be null
static inline void scc_ast_type_function_init(scc_ast_type_t *type,
@@ -400,6 +442,7 @@ static inline void scc_ast_type_function_init(scc_ast_type_t *type,
type->base.loc = scc_pos_create();
type->base.type = SCC_AST_TYPE_FUNCTION;
type->function.return_type = return_type;
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
if (params == null) {
scc_vec_init(type->function.param_types);
} else {
@@ -408,9 +451,62 @@ static inline void scc_ast_type_function_init(scc_ast_type_t *type,
}
}
// SCC_AST_TYPE_STRUCT, // 结构体类型
// SCC_AST_TYPE_UNION, // 联合类型
// SCC_AST_TYPE_ENUM, // 枚举类型
// SCC_AST_TYPE_TYPEDEF, // typedef 类型
static inline void _scc_ast_type_record_init(scc_ast_type_t *type,
scc_ast_node_type_t type_kind,
const char *name,
scc_ast_decl_vec_t *members) {
Assert(type != null && name != null);
type->base.loc = scc_pos_create();
type->base.type = type_kind;
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
if (members == null) {
scc_vec_init(type->record.fields);
} else {
type->record.fields = *members;
scc_vec_init(*members);
}
}
// name and members can be null
static inline void scc_ast_type_struct_init(scc_ast_type_t *type,
const char *name,
scc_ast_decl_vec_t *members) {
_scc_ast_type_record_init(type, SCC_AST_TYPE_STRUCT, name, members);
}
// name and members can be null
static inline void scc_ast_type_union_init(scc_ast_type_t *type,
const char *name,
scc_ast_decl_vec_t *members) {
_scc_ast_type_record_init(type, SCC_AST_TYPE_UNION, name, members);
}
// name and members can be null
static inline void scc_ast_type_enum_init(scc_ast_type_t *type,
const char *name,
scc_ast_expr_vec_t *members) {
Assert(type != null);
type->base.loc = scc_pos_create();
type->base.type = SCC_AST_TYPE_ENUM;
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
type->enumeration.name = name;
if (members == null) {
scc_vec_init(type->enumeration.enumerators);
} else {
type->enumeration.enumerators = *members;
scc_vec_init(*members);
}
}
static inline void scc_ast_type_typedef_init(scc_ast_type_t *type,
const char *name,
scc_ast_type_t *target) {
Assert(type != null && target != null);
type->base.loc = scc_pos_create();
type->base.type = SCC_AST_TYPE_TYPEDEF;
type->quals = (scc_ast_decl_specifier_t){0}; // FIXME
type->typedef_type.name = name;
type->typedef_type.underlying = target;
}
#endif /* __SCC_AST_H__ */

View File

@@ -4,6 +4,32 @@
.base.type = SCC_AST_TYPE_BUILTIN, .base.loc.col = 0, .base.loc.line = 0, \
.base.loc.name = "__scc_ast_builtin_type", .base.loc.offset = 0
// va_list
scc_ast_type_t scc_ast_builtin_type_va_list = {
SCC_AST_BUILTIN_TYPE_HEADER,
.builtin.type = SCC_AST_BUILTIN_TYPE_VA_LIST,
};
scc_ast_type_t scc_ast_builtin_type_void = {
SCC_AST_BUILTIN_TYPE_HEADER,
.builtin.type = SCC_AST_BUILTIN_TYPE_VOID,
};
scc_ast_type_t scc_ast_builtin_type_bool = {
SCC_AST_BUILTIN_TYPE_HEADER,
.builtin.type = SCC_AST_BUILTIN_TYPE_BOOL,
};
scc_ast_type_t scc_ast_builtin_type_char = {
SCC_AST_BUILTIN_TYPE_HEADER,
.builtin.type = SCC_AST_BUILTIN_TYPE_CHAR,
};
scc_ast_type_t scc_ast_builtin_type_short = {
SCC_AST_BUILTIN_TYPE_HEADER,
.builtin.type = SCC_AST_BUILTIN_TYPE_SHORT,
};
scc_ast_type_t scc_ast_builtin_type_int = {
SCC_AST_BUILTIN_TYPE_HEADER,
.builtin.type = SCC_AST_BUILTIN_TYPE_INT,
@@ -19,24 +45,56 @@ scc_ast_type_t scc_ast_builtin_type_long_long = {
.builtin.type = SCC_AST_BUILTIN_TYPE_LONG_LONG,
};
scc_ast_type_t scc_ast_builtin_type_short = {
// unsigned 类型
scc_ast_type_t scc_ast_builtin_type_unsigned_char = {
SCC_AST_BUILTIN_TYPE_HEADER,
.builtin.type = SCC_AST_BUILTIN_TYPE_SHORT,
.builtin.type = SCC_AST_BUILTIN_TYPE_UNSIGNED_CHAR,
};
scc_ast_type_t scc_ast_builtin_type_char = {
scc_ast_type_t scc_ast_builtin_type_unsigned_short = {
SCC_AST_BUILTIN_TYPE_HEADER,
.builtin.type = SCC_AST_BUILTIN_TYPE_CHAR,
.builtin.type = SCC_AST_BUILTIN_TYPE_UNSIGNED_SHORT,
};
scc_ast_type_t scc_ast_builtin_type_void = {
scc_ast_type_t scc_ast_builtin_type_unsigned_int = {
SCC_AST_BUILTIN_TYPE_HEADER,
.builtin.type = SCC_AST_BUILTIN_TYPE_VOID,
.builtin.type = SCC_AST_BUILTIN_TYPE_UNSIGNED_INT,
};
scc_ast_type_t scc_ast_builtin_type_bool = {
scc_ast_type_t scc_ast_builtin_type_unsigned_long = {
SCC_AST_BUILTIN_TYPE_HEADER,
.builtin.type = SCC_AST_BUILTIN_TYPE_BOOL,
.builtin.type = SCC_AST_BUILTIN_TYPE_UNSIGNED_LONG,
};
scc_ast_type_t scc_ast_builtin_type_unsigned_long_long = {
SCC_AST_BUILTIN_TYPE_HEADER,
.builtin.type = SCC_AST_BUILTIN_TYPE_UNSIGNED_LONG_LONG,
};
// signed 类型(实际上与默认相同,但为了完整性)
scc_ast_type_t scc_ast_builtin_type_signed_char = {
SCC_AST_BUILTIN_TYPE_HEADER,
.builtin.type = SCC_AST_BUILTIN_TYPE_SIGNED_CHAR,
};
scc_ast_type_t scc_ast_builtin_type_signed_short = {
SCC_AST_BUILTIN_TYPE_HEADER,
.builtin.type = SCC_AST_BUILTIN_TYPE_SIGNED_SHORT,
};
scc_ast_type_t scc_ast_builtin_type_signed_int = {
SCC_AST_BUILTIN_TYPE_HEADER,
.builtin.type = SCC_AST_BUILTIN_TYPE_SIGNED_INT,
};
scc_ast_type_t scc_ast_builtin_type_signed_long = {
SCC_AST_BUILTIN_TYPE_HEADER,
.builtin.type = SCC_AST_BUILTIN_TYPE_SIGNED_LONG,
};
scc_ast_type_t scc_ast_builtin_type_signed_long_long = {
SCC_AST_BUILTIN_TYPE_HEADER,
.builtin.type = SCC_AST_BUILTIN_TYPE_SIGNED_LONG_LONG,
};
scc_ast_type_t scc_ast_builtin_type_float = {

View File

@@ -14,148 +14,100 @@
#define PRINT_QUOTED_VALUE(ctx, str) \
SCC_TREE_DUMP_PRINT_AROUND(ctx, ctx->value_color, "'", "%s", str)
// 获取节点类型的字符串表示
static const char *node_type_names[] = {
[SCC_AST_UNKNOWN] = "Unknown",
[scc_ast_decl_t_BEGIN] = "ERROR",
[SCC_AST_DECL_VAR] = "VarDecl",
[SCC_AST_DECL_FUNC] = "FuncDecl",
[SCC_AST_DECL_PARAM] = "ParamDecl",
[SCC_AST_DECL_STRUCT] = "StructDecl",
[SCC_AST_DECL_UNION] = "UnionDecl",
[SCC_AST_DECL_ENUM] = "EnumDecl",
[SCC_AST_DECL_TYPEDEF] = "TypedefDecl",
[scc_ast_decl_t_END] = "ERROR",
[scc_ast_stmt_t_BEGIN] = "ERROR",
[SCC_AST_STMT_COMPOUND] = "CompoundStmt",
[SCC_AST_STMT_EXPR] = "ExprStmt",
[SCC_AST_STMT_IF] = "IfStmt",
[SCC_AST_STMT_WHILE] = "WhileStmt",
[SCC_AST_STMT_DO_WHILE] = "DoWhileStmt",
[SCC_AST_STMT_FOR] = "ForStmt",
[SCC_AST_STMT_SWITCH] = "SwitchStmt",
[SCC_AST_STMT_CASE] = "CaseStmt",
[SCC_AST_STMT_DEFAULT] = "DefaultStmt",
[SCC_AST_STMT_BREAK] = "BreakStmt",
[SCC_AST_STMT_CONTINUE] = "ContinueStmt",
[SCC_AST_STMT_RETURN] = "ReturnStmt",
[SCC_AST_STMT_GOTO] = "GotoStmt",
[SCC_AST_STMT_LABEL] = "LabelStmt",
[scc_ast_stmt_t_END] = "ERROR",
[scc_ast_expr_t_BEGIN] = "ERROR",
[SCC_AST_EXPR_BINARY] = "BinaryExpr",
[SCC_AST_EXPR_UNARY] = "UnaryExpr",
[SCC_AST_EXPR_COND] = "ConditionalExpr",
[SCC_AST_EXPR_CALL] = "CallExpr",
[SCC_AST_EXPR_ARRAY_SUBSCRIPT] = "ArraySubscriptExpr",
[SCC_AST_EXPR_MEMBER] = "MemberExpr",
[SCC_AST_EXPR_PTR_MEMBER] = "PtrMemberExpr",
[SCC_AST_EXPR_CAST] = "CastExpr",
[SCC_AST_EXPR_SIZE_OF] = "SizeofExpr",
[SCC_AST_EXPR_ALIGN_OF] = "AlignofExpr",
[SCC_AST_EXPR_COMPOUND_LITERAL] = "CompoundLiteralExpr",
[SCC_AST_EXPR_INT_LITERAL] = "IntLiteralExpr",
[SCC_AST_EXPR_FLOAT_LITERAL] = "FloatLiteralExpr",
[SCC_AST_EXPR_CHAR_LITERAL] = "CharLiteralExpr",
[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_TYPE_BUILTIN] = "BuiltinType",
[SCC_AST_TYPE_POINTER] = "PointerType",
[SCC_AST_TYPE_ARRAY] = "ArrayType",
[SCC_AST_TYPE_FUNCTION] = "FunctionType",
[SCC_AST_TYPE_STRUCT] = "StructType",
[SCC_AST_TYPE_UNION] = "UnionType",
[SCC_AST_TYPE_ENUM] = "EnumType",
[SCC_AST_TYPE_TYPEDEF] = "TypedefType",
[scc_ast_type_t_END] = "ERROR",
[scc_ast_translation_unit_t_BEGIN] = "ERROR",
[SCC_AST_TRANSLATION_UNIT] = "TranslationUnit",
[scc_ast_translation_unit_t_END] = "ERROR",
};
static const char *get_node_type_str(scc_ast_node_type_t type) {
switch (type) {
// 声明类型
case SCC_AST_DECL_VAR:
return "VarDecl";
case SCC_AST_DECL_FUNC:
return "FuncDecl";
case SCC_AST_DECL_PARAM:
return "ParamDecl";
case SCC_AST_DECL_STRUCT:
return "StructDecl";
case SCC_AST_DECL_UNION:
return "UnionDecl";
case SCC_AST_DECL_ENUM:
return "EnumDecl";
case SCC_AST_DECL_TYPEDEF:
return "TypedefDecl";
// 语句类型
case SCC_AST_STMT_COMPOUND:
return "CompoundStmt";
case SCC_AST_STMT_EXPR:
return "ExprStmt";
case SCC_AST_STMT_IF:
return "IfStmt";
case SCC_AST_STMT_WHILE:
return "WhileStmt";
case SCC_AST_STMT_DO_WHILE:
return "DoStmt";
case SCC_AST_STMT_FOR:
return "ForStmt";
case SCC_AST_STMT_SWITCH:
return "SwitchStmt";
case SCC_AST_STMT_CASE:
return "CaseStmt";
case SCC_AST_STMT_DEFAULT:
return "DefaultStmt";
case SCC_AST_STMT_BREAK:
return "BreakStmt";
case SCC_AST_STMT_CONTINUE:
return "ContinueStmt";
case SCC_AST_STMT_RETURN:
return "ReturnStmt";
case SCC_AST_STMT_GOTO:
return "GotoStmt";
case SCC_AST_STMT_LABEL:
return "LabelStmt";
// 表达式类型
case SCC_AST_EXPR_BINARY:
return "BinaryOperator";
case SCC_AST_EXPR_UNARY:
return "UnaryOperator";
case SCC_AST_EXPR_COND:
return "ConditionalOperator";
case SCC_AST_EXPR_CALL:
return "CallExpr";
case SCC_AST_EXPR_ARRAY_SUBSCRIPT:
return "ArraySubscriptExpr";
case SCC_AST_EXPR_MEMBER:
return "MemberExpr";
case SCC_AST_EXPR_PTR_MEMBER:
return "PtrMemberExpr";
case SCC_AST_EXPR_CAST:
return "CastExpr";
case SCC_AST_EXPR_SIZE_OF:
return "SizeOfExpr";
case SCC_AST_EXPR_ALIGN_OF:
return "AlignOfExpr";
case SCC_AST_EXPR_COMPOUND_LITERAL:
return "CompoundLiteralExpr";
case SCC_AST_EXPR_INT_LITERAL:
return "IntegerLiteral";
case SCC_AST_EXPR_FLOAT_LITERAL:
return "FloatingLiteral";
case SCC_AST_EXPR_CHAR_LITERAL:
return "CharacterLiteral";
case SCC_AST_EXPR_STRING_LITERAL:
return "StringLiteral";
case SCC_AST_EXPR_IDENTIFIER:
return "DeclRefExpr";
// 类型类型
case SCC_AST_TYPE_BUILTIN:
return "BuiltinType";
case SCC_AST_TYPE_POINTER:
return "PointerType";
case SCC_AST_TYPE_ARRAY:
return "ArrayType";
case SCC_AST_TYPE_FUNCTION:
return "FunctionType";
case SCC_AST_TYPE_STRUCT:
return "RecordType";
case SCC_AST_TYPE_UNION:
return "RecordType";
case SCC_AST_TYPE_ENUM:
return "EnumType";
case SCC_AST_TYPE_TYPEDEF:
return "TypedefType";
// 根节点
case SCC_AST_TRANSLATION_UNIT:
return "TranslationUnitDecl";
default:
return "UnknownNode";
}
return node_type_names[type];
}
// 获取内置类型名称
static const char *builtin_type_names[] = {
[SCC_AST_BUILTIN_TYPE_UNKNOWN] = "<unknown type>",
[SCC_AST_BUILTIN_TYPE_VA_LIST] = "...",
[SCC_AST_BUILTIN_TYPE_VOID] = "void",
[SCC_AST_BUILTIN_TYPE_BOOL] = "bool",
[SCC_AST_BUILTIN_TYPE_CHAR] = "char",
[SCC_AST_BUILTIN_TYPE_SHORT] = "short",
[SCC_AST_BUILTIN_TYPE_INT] = "int",
[SCC_AST_BUILTIN_TYPE_LONG] = "long",
[SCC_AST_BUILTIN_TYPE_LONG_LONG] = "long long",
[SCC_AST_BUILTIN_TYPE_UNSIGNED_CHAR] = "unsigned char",
[SCC_AST_BUILTIN_TYPE_UNSIGNED_SHORT] = "unsigned short",
[SCC_AST_BUILTIN_TYPE_UNSIGNED_INT] = "unsigned int",
[SCC_AST_BUILTIN_TYPE_UNSIGNED_LONG] = "unsigned long",
[SCC_AST_BUILTIN_TYPE_UNSIGNED_LONG_LONG] = "unsigned long long",
[SCC_AST_BUILTIN_TYPE_SIGNED_CHAR] = "signed char",
[SCC_AST_BUILTIN_TYPE_SIGNED_SHORT] = "signed short",
[SCC_AST_BUILTIN_TYPE_SIGNED_INT] = "signed int",
[SCC_AST_BUILTIN_TYPE_SIGNED_LONG] = "signed long",
[SCC_AST_BUILTIN_TYPE_SIGNED_LONG_LONG] = "signed long long",
[SCC_AST_BUILTIN_TYPE_FLOAT] = "float",
[SCC_AST_BUILTIN_TYPE_DOUBLE] = "double",
[SCC_AST_BUILTIN_TYPE_LONG_DOUBLE] = "long double",
[SCC_AST_BUILTIN_TYPE_COMPLEX_FLOAT] = "complex float",
[SCC_AST_BUILTIN_TYPE_COMPLEX_DOUBLE] = "complex double",
[SCC_AST_BUILTIN_TYPE_COMPLEX_LONG_DOUBLE] = "complex long double",
};
static const char *get_builtin_type_str(scc_ast_builtin_type_t type) {
switch (type) {
case SCC_AST_BUILTIN_TYPE_VOID:
return "void";
case SCC_AST_BUILTIN_TYPE_CHAR:
return "char";
case SCC_AST_BUILTIN_TYPE_SHORT:
return "short";
case SCC_AST_BUILTIN_TYPE_INT:
return "int";
case SCC_AST_BUILTIN_TYPE_LONG:
return "long";
case SCC_AST_BUILTIN_TYPE_LONG_LONG:
return "long long";
case SCC_AST_BUILTIN_TYPE_FLOAT:
return "float";
case SCC_AST_BUILTIN_TYPE_DOUBLE:
return "double";
case SCC_AST_BUILTIN_TYPE_LONG_DOUBLE:
return "long double";
case SCC_AST_BUILTIN_TYPE_BOOL:
return "_Bool";
case SCC_AST_BUILTIN_TYPE_COMPLEX_FLOAT:
return "float _Complex";
case SCC_AST_BUILTIN_TYPE_COMPLEX_DOUBLE:
return "double _Complex";
case SCC_AST_BUILTIN_TYPE_COMPLEX_LONG_DOUBLE:
return "long double _Complex";
default:
return "<unknown>";
}
return builtin_type_names[type];
}
// 获取操作符字符串
@@ -286,6 +238,28 @@ static inline void dump_child_node(scc_ast_node_t *child,
} \
} while (0)
static inline void dump_quals(scc_ast_decl_specifier_t quals,
scc_tree_dump_ctx_t *ctx) {
if (quals.is_atomic) {
PRINT_QUOTED_VALUE(ctx, "atomic");
}
if (quals.is_restrict) {
PRINT_QUOTED_VALUE(ctx, "restrict");
}
if (quals.is_volatile) {
PRINT_QUOTED_VALUE(ctx, "volatile");
}
if (quals.is_const) {
PRINT_QUOTED_VALUE(ctx, "const");
}
if (quals.is_inline) {
PRINT_QUOTED_VALUE(ctx, "inline");
}
if (quals.is_extern) {
PRINT_QUOTED_VALUE(ctx, "extern");
}
}
// 递归转储类型
static void dump_type_impl(scc_ast_type_t *type, scc_tree_dump_ctx_t *ctx) {
if (!type)
@@ -293,25 +267,15 @@ static void dump_type_impl(scc_ast_type_t *type, scc_tree_dump_ctx_t *ctx) {
start_node_dump(&type->base, ctx);
dump_quals(type->quals, ctx);
// 根据类型输出特定信息
switch (type->base.type) {
case SCC_AST_TYPE_BUILTIN:
PRINT_QUOTED_VALUE(ctx, get_builtin_type_str(type->builtin.type));
break;
case SCC_AST_TYPE_POINTER:
if (type->pointer.pointee &&
type->pointer.pointee->base.type == SCC_AST_TYPE_BUILTIN) {
const char *base_type =
get_builtin_type_str(type->pointer.pointee->builtin.type);
if (ctx->use_color) {
scc_tree_dump_printf(ctx, "%s'%s *'%s", ctx->value_color,
base_type, ctx->reset_color);
} else {
scc_tree_dump_printf(ctx, "'%s *'", base_type);
}
} else {
PRINT_QUOTED_VALUE(ctx, "pointer");
}
PRINT_QUOTED_VALUE(ctx, "pointer");
break;
case SCC_AST_TYPE_ARRAY:
PRINT_QUOTED_VALUE(ctx, "array");
@@ -331,10 +295,6 @@ static void dump_type_impl(scc_ast_type_t *type, scc_tree_dump_ctx_t *ctx) {
}
dump_type_impl(param->param.type, ctx);
}
} else {
start_node_dump(&type->base, ctx);
PRINT_QUOTED_VALUE(ctx, "void");
// TODO?
}
break;
case SCC_AST_TYPE_STRUCT:
@@ -620,7 +580,7 @@ static void dump_decl_impl(scc_ast_decl_t *decl, scc_tree_dump_ctx_t *ctx) {
case SCC_AST_DECL_FUNC:
if (decl->func.type) {
dump_child_node((scc_ast_node_t *)decl->func.type, ctx,
decl->func.body == NULL);
decl->func.body == null);
if (decl->func.body) {
dump_child_node((scc_ast_node_t *)decl->func.body, ctx, true);
}