feat(argparse): 支持列表类型参数解析

当参数指定为列表类型时,验证和处理逻辑现在会检查
vec_store 是否为空或大小为0,而不是检查 str_store。

fix(hir): 初始化聚合类型值的数据结构

在 HIR 值初始化过程中,为聚合类型添加适当的初始化逻辑,
确保其字段向量被正确初始化。

refactor(hir_builder): 优化指针类型创建和GEP操作实现

- 简化全局分配器中的指针类型创建代码
- 扩展 GEP 操作以支持结构体和联合体字段访问
- 添加字段偏移计算支持

feat(hir_dump): 增强HIR类型和值的线性转储功能

- 实现类型定义的线性转储输出
- 改进结构体和联合体的转储格式
- 优化聚合值的转储表示

perf(hir_layout): 优化类型布局计算性能

改进结构体、联合体和聚合类型的对齐和大小计算算法,
提高字段偏移计算的准确性。

fix(hir_module): 完善模块资源清理机制

在模块析构时正确释放结构体和联合体类型的字段向量内存。

docs(lir): 更新文档注释中的空值表示

将初始化数据参数的空值描述从 NULL 统一为 nullptr。

refactor(hir2lir): 改进HIR到LIR的类型转换逻辑

- 重构类型到LIR大小扩展的转换函数
- 修复STORE指令的类型推导逻辑
- 增强GEP指令的规模因子和偏移量计算
- 添加对结构体/联合体字段访问的支持

refactor(x86_isel): 优化x86-64地址加载指令生成

改进LOAD_ADDR指令生成,更好地支持结构体字段访问的零比例因子。

docs(ir2mcode): 统一空值表示文档注释

更新初始化数据参数的空值描述为nullptr。

refactor(lexer): 简化词法分析器非空白标记预览逻辑

优化非空白标记预览函数,减少不必要的标记消费和销毁操作。
This commit is contained in:
zzy
2026-06-03 17:34:16 +08:00
parent be33eb3942
commit 0acea43e4e
17 changed files with 486 additions and 174 deletions

View File

@@ -481,7 +481,8 @@ static scc_ast_expr_t *parse_cast_expression(scc_parser_t *parser) {
scc_ast_expr_t *operand = parse_cast_expression(parser);
if (!operand) {
// FIXME postfix-expression
scc_ast_expr_t *expr = SCC_AST_ALLOC_EXPR(parser->ast_module);
scc_ast_expr_t *expr =
SCC_AST_ALLOC_EXPR(parser->ast_module);
// FIXME pos
scc_ast_expr_lvalue_init(expr, type, type->base.loc);
operand = scc_parse_initializer(parser, expr);
@@ -681,7 +682,7 @@ static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) {
case SCC_TOK_L_PAREN: // left(args)
{
if (!scc_parser_next_consume(parser, nullptr))
return left;
goto done;
pos = left->base.loc;
scc_ast_expr_vec_t args;
scc_vec_init(args);
@@ -719,7 +720,7 @@ static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) {
case SCC_TOK_DEREF: {
scc_lexer_tok_t op_tok;
if (!scc_parser_next_consume(parser, &op_tok))
return left;
goto done;
scc_lexer_tok_t ident_tok;
if (!scc_parser_next_consume(parser, &ident_tok) ||
ident_tok.type != SCC_TOK_IDENT) {
@@ -729,18 +730,22 @@ static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) {
parser_sync(parser);
return nullptr;
}
const char *name = scc_ast_module_intern(parser->ast_module, scc_str_as_cstr(&ident_tok.lexeme));
const char *name = scc_ast_module_intern(
parser->ast_module, scc_str_as_cstr(&ident_tok.lexeme));
scc_ast_expr_t *member = SCC_AST_ALLOC_EXPR(parser->ast_module);
Assert(member != nullptr);
if (op_tok.type == SCC_TOK_DOT) {
scc_ast_expr_member_init(member, left, name, ident_tok.loc);
} else {
} else if (op_tok.type == SCC_TOK_DEREF) {
scc_ast_expr_ptr_member_init(member, left, name, ident_tok.loc);
} else {
UNREACHABLE();
}
scc_lexer_tok_drop(&op_tok);
left = member;
scc_parse_expr_sema(parser, member);
break;
}
case SCC_TOK_ADD_ADD: // left++
@@ -748,7 +753,7 @@ static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) {
{
scc_lexer_tok_t op_tok;
if (!scc_parser_next_consume(parser, &op_tok))
return left;
goto done;
scc_ast_expr_op_t op = map_token_to_unary_op(op_tok.type, false);
scc_ast_expr_t *expr = SCC_AST_ALLOC_EXPR(parser->ast_module);
Assert(expr != nullptr);
@@ -762,6 +767,7 @@ static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) {
}
}
done:
scc_parse_expr_sema(parser, left);
return left;
}
@@ -787,8 +793,11 @@ static scc_ast_expr_t *parse_primary_expression(scc_parser_t *parser) {
return nullptr;
expr = SCC_AST_ALLOC_EXPR(parser->ast_module);
Assert(expr != nullptr);
scc_ast_expr_identifier_init(expr, scc_ast_module_intern(parser->ast_module, scc_str_as_cstr(&tok.lexeme)),
tok.loc);
scc_ast_expr_identifier_init(
expr,
scc_ast_module_intern(parser->ast_module,
scc_str_as_cstr(&tok.lexeme)),
tok.loc);
break;
}
case SCC_TOK_INT_LITERAL: {
@@ -796,8 +805,11 @@ static scc_ast_expr_t *parse_primary_expression(scc_parser_t *parser) {
return nullptr;
expr = SCC_AST_ALLOC_EXPR(parser->ast_module);
Assert(expr != nullptr);
scc_ast_expr_literal_int_init(expr, scc_ast_module_intern(parser->ast_module, scc_str_as_cstr(&tok.lexeme)), false,
tok.loc);
scc_ast_expr_literal_int_init(
expr,
scc_ast_module_intern(parser->ast_module,
scc_str_as_cstr(&tok.lexeme)),
false, tok.loc);
break;
}
case SCC_TOK_FLOAT_LITERAL: {
@@ -805,8 +817,11 @@ static scc_ast_expr_t *parse_primary_expression(scc_parser_t *parser) {
return nullptr;
expr = SCC_AST_ALLOC_EXPR(parser->ast_module);
Assert(expr != nullptr);
scc_ast_expr_literal_float_init(expr, scc_ast_module_intern(parser->ast_module, scc_str_as_cstr(&tok.lexeme)),
false, tok.loc);
scc_ast_expr_literal_float_init(
expr,
scc_ast_module_intern(parser->ast_module,
scc_str_as_cstr(&tok.lexeme)),
false, tok.loc);
break;
}
case SCC_TOK_CHAR_LITERAL: {
@@ -814,8 +829,11 @@ static scc_ast_expr_t *parse_primary_expression(scc_parser_t *parser) {
return nullptr;
expr = SCC_AST_ALLOC_EXPR(parser->ast_module);
Assert(expr != nullptr);
scc_ast_expr_literal_char_init(expr, scc_ast_module_intern(parser->ast_module, scc_str_as_cstr(&tok.lexeme)),
false, tok.loc);
scc_ast_expr_literal_char_init(
expr,
scc_ast_module_intern(parser->ast_module,
scc_str_as_cstr(&tok.lexeme)),
false, tok.loc);
break;
}
case SCC_TOK_STRING_LITERAL: {
@@ -835,13 +853,13 @@ static scc_ast_expr_t *parse_primary_expression(scc_parser_t *parser) {
scc_str_append(&string, &tmp);
}
const char *pooled_str = scc_ast_module_intern(parser->ast_module, scc_str_as_cstr(&string));
const char *pooled_str =
scc_ast_module_intern(parser->ast_module, scc_str_as_cstr(&string));
scc_str_drop(&string);
expr = SCC_AST_ALLOC_EXPR(parser->ast_module);
Assert(expr != nullptr);
// FIXME loc
scc_ast_expr_literal_string_init(expr, pooled_str, false,
tok.loc);
scc_ast_expr_literal_string_init(expr, pooled_str, false, tok.loc);
break;
}
case SCC_TOK_L_PAREN:

View File

@@ -36,8 +36,8 @@ static void symtab_add_symbol(scc_sema_symtab_t *sema_symtab,
if (scc_str_is_empty(&name)) {
scc_sema_symtab_add_symbol(sema_symtab, decl->name, ast_node_ref);
} else {
const char *pooled = scc_strpool_intern(&sema_symtab->name_pool,
scc_str_as_cstr(&name));
const char *pooled =
scc_strpool_intern(&sema_symtab->name_pool, scc_str_as_cstr(&name));
scc_sema_symtab_add_symbol(sema_symtab, pooled, ast_node_ref);
scc_str_drop(&name);
}
@@ -58,6 +58,100 @@ static void type_callback(scc_sema_ctx_t *sema_ctx,
return;
}
/* ---------- 类型解析辅助函数 (用于成员访问) ---------- */
// 从 qual_type 解析到底层的 struct/union 声明(跟随 typedef 链)
static scc_ast_decl_t *resolve_to_struct_decl(scc_ast_qual_type_t *type) {
if (!type)
return nullptr;
// 跟随 typedef 链
while (type->base.type == SCC_AST_TYPE_TYPEDEF) {
if (!type->type || !type->type->typedef_type.decl)
return nullptr;
if (type->type->typedef_type.decl->base.type != SCC_AST_DECL_TYPEDEF)
return nullptr;
type = type->type->typedef_type.decl->typedef_decl.type;
if (!type)
return nullptr;
}
if (type->base.type == SCC_AST_TYPE_STRUCT ||
type->base.type == SCC_AST_TYPE_UNION) {
if (type->type)
return type->type->record.decl;
}
return nullptr;
}
// 从表达式中解析出其 qual_type用于确定基表达式的类型
static scc_ast_qual_type_t *resolve_expr_qual_type(scc_sema_ctx_t *sema_ctx,
scc_ast_expr_t *expr) {
if (!expr)
return nullptr;
switch (expr->base.type) {
case SCC_AST_EXPR_IDENTIFIER: {
scc_ast_decl_t *decl = expr->identifier._target;
if (!decl)
return nullptr;
if (decl->base.type == SCC_AST_DECL_VAR)
return decl->var.type;
if (decl->base.type == SCC_AST_DECL_PARAM)
return decl->param.type;
return nullptr;
}
case SCC_AST_EXPR_MEMBER: {
scc_ast_qual_type_t *base_type =
resolve_expr_qual_type(sema_ctx, expr->member.base);
if (!base_type)
return nullptr;
scc_ast_decl_t *sd = resolve_to_struct_decl(base_type);
if (!sd)
return nullptr;
scc_ast_decl_vec_t *fields = &sd->record.fields;
if (expr->member._target_idx >= scc_vec_size(*fields))
return nullptr;
scc_ast_decl_t *field = scc_vec_at(*fields, expr->member._target_idx);
if (field->base.type == SCC_AST_DECL_VAR)
return field->var.type;
return nullptr;
}
case SCC_AST_EXPR_PTR_MEMBER: {
scc_ast_qual_type_t *base_type =
resolve_expr_qual_type(sema_ctx, expr->member.base);
if (!base_type || base_type->base.type != SCC_AST_TYPE_POINTER)
return nullptr;
scc_ast_qual_type_t *pointee =
base_type->type ? base_type->type->pointer.pointee : nullptr;
if (!pointee)
return nullptr;
scc_ast_decl_t *sd = resolve_to_struct_decl(pointee);
if (!sd)
return nullptr;
scc_ast_decl_vec_t *fields = &sd->record.fields;
if (expr->member._target_idx >= scc_vec_size(*fields))
return nullptr;
scc_ast_decl_t *field = scc_vec_at(*fields, expr->member._target_idx);
if (field->base.type == SCC_AST_DECL_VAR)
return field->var.type;
return nullptr;
}
case SCC_AST_EXPR_UNARY: {
if (expr->unary.op == SCC_AST_OP_INDIRECTION) {
scc_ast_qual_type_t *op_type =
resolve_expr_qual_type(sema_ctx, expr->unary.operand);
if (!op_type || op_type->base.type != SCC_AST_TYPE_POINTER)
return nullptr;
return op_type->type ? op_type->type->pointer.pointee : nullptr;
}
return nullptr;
}
default:
return nullptr;
}
}
static void expr_callback(scc_sema_ctx_t *sema_ctx,
scc_ast_node_kind_t node_type, void *node) {
scc_sema_symtab_t *sema_symtab = sema_ctx->context;
@@ -67,18 +161,78 @@ static void expr_callback(scc_sema_ctx_t *sema_ctx,
}
scc_ast_expr_t *expr = SCC_AST_CAST_TO(scc_ast_expr_t, node);
if (node_type == SCC_AST_EXPR_IDENTIFIER) {
scc_ast_node_t *node =
scc_ast_node_t *sym_node =
scc_sema_symtab_lookup_symbol(sema_symtab, expr->identifier.name);
if (node == nullptr) {
if (sym_node == nullptr) {
SCC_ERROR(expr->base.loc, "sema error: Identifier '%s' not found",
expr->identifier.name);
} else if (!SCC_AST_IS_A(scc_ast_decl_t, node)) {
} else if (!SCC_AST_IS_A(scc_ast_decl_t, sym_node)) {
SCC_ERROR(expr->base.loc,
"sema error: Identifier '%s' is not a variable",
expr->identifier.name);
} else {
expr->identifier._target = SCC_AST_CAST_TO(scc_ast_decl_t, node);
expr->identifier._target =
SCC_AST_CAST_TO(scc_ast_decl_t, sym_node);
}
return;
}
if (node_type == SCC_AST_EXPR_MEMBER ||
node_type == SCC_AST_EXPR_PTR_MEMBER) {
scc_ast_expr_t *base = expr->member.base;
// 获取基表达式的 qual_type
scc_ast_qual_type_t *base_type = resolve_expr_qual_type(sema_ctx, base);
if (!base_type) {
SCC_ERROR(expr->base.loc,
"cannot determine type for member access");
return;
}
// 对于 ->,基表达式应为指针类型,解引用得到目标 struct/union
scc_ast_decl_t *struct_decl = nullptr;
if (node_type == SCC_AST_EXPR_PTR_MEMBER) {
if (base_type->base.type != SCC_AST_TYPE_POINTER) {
SCC_ERROR(expr->base.loc,
"base expression of '->' must be a pointer");
return;
}
scc_ast_qual_type_t *pointee =
base_type->type ? base_type->type->pointer.pointee : nullptr;
if (!pointee) {
SCC_ERROR(expr->base.loc,
"cannot dereference pointer for '->'");
return;
}
struct_decl = resolve_to_struct_decl(pointee);
} else {
struct_decl = resolve_to_struct_decl(base_type);
}
if (!struct_decl) {
SCC_ERROR(expr->base.loc,
"base expression is not a struct or union");
return;
}
// 按名称查找字段,计算 field index
scc_ast_decl_vec_t *fields = &struct_decl->record.fields;
cbool found = false;
for (usize i = 0; i < scc_vec_size(*fields); i++) {
scc_ast_decl_t *field = scc_vec_at(*fields, i);
if (field && field->name &&
scc_strcmp(field->name, expr->member.name) == 0) {
expr->member._target_idx = i;
found = true;
break;
}
}
if (!found) {
SCC_ERROR(expr->base.loc, "struct/union has no member '%s'",
expr->member.name);
}
return;
}
return;