diff --git a/libs/ast/src/ast_dump.c b/libs/ast/src/ast_dump.c index 2b9b23c..f37a4c5 100644 --- a/libs/ast/src/ast_dump.c +++ b/libs/ast/src/ast_dump.c @@ -608,7 +608,6 @@ static void dump_decl_impl(scc_ast_decl_t *decl, scc_tree_dump_ctx_t *ctx) { if (decl->name) { PRINT_QUOTED_VALUE(ctx, decl->name); } - end_node_dump(ctx); // 递归转储子节点 @@ -616,7 +615,7 @@ static void dump_decl_impl(scc_ast_decl_t *decl, scc_tree_dump_ctx_t *ctx) { case SCC_AST_DECL_LIST: scc_vec_foreach(decl->list.vars, i) { dump_child_node((scc_ast_node_t *)scc_vec_at(decl->list.vars, i), - ctx, i + 1 != scc_vec_size(decl->list.vars)); + ctx, i + 1 == scc_vec_size(decl->list.vars)); } break; case SCC_AST_DECL_VAR: @@ -650,7 +649,7 @@ static void dump_decl_impl(scc_ast_decl_t *decl, scc_tree_dump_ctx_t *ctx) { scc_vec_foreach(decl->record.fields, i) { dump_child_node( (scc_ast_node_t *)scc_vec_at(decl->record.fields, i), ctx, - i + 1 != scc_vec_size(decl->record.fields)); + i + 1 == scc_vec_size(decl->record.fields)); } break; @@ -658,7 +657,7 @@ static void dump_decl_impl(scc_ast_decl_t *decl, scc_tree_dump_ctx_t *ctx) { scc_vec_foreach(decl->enumeration.enumerators, i) { dump_child_node( (scc_ast_node_t *)scc_vec_at(decl->enumeration.enumerators, i), - ctx, i + 1 != scc_vec_size(decl->enumeration.enumerators)); + ctx, i + 1 == scc_vec_size(decl->enumeration.enumerators)); } break; @@ -684,7 +683,7 @@ static void dump_unit_impl(scc_ast_translation_unit_t *unit, end_node_dump(ctx); scc_vec_foreach(unit->declarations, i) { dump_child_node((scc_ast_node_t *)scc_vec_at(unit->declarations, i), - ctx, i + 1 != scc_vec_size(unit->declarations)); + ctx, i + 1 == scc_vec_size(unit->declarations)); } } diff --git a/libs/parser/src/parse_decl.c b/libs/parser/src/parse_decl.c index e567927..1f5e1fd 100644 --- a/libs/parser/src/parse_decl.c +++ b/libs/parser/src/parse_decl.c @@ -299,19 +299,19 @@ CONTINUE: tok_ptr = scc_parser_peek(parser); if (tok_ptr->type == SCC_TOK_SEMICOLON) { scc_parser_next_consume(parser, null); + if (decl_list) + scc_vec_push(decl_list_vec, decl); if (spec.is_typedef) { if (decl_list) { scc_vec_foreach(decl_list_vec, i) { decl = scc_vec_at(decl_list_vec, i); - scc_ast_decl_typedef_init(decl, decl->name, type); + scc_ast_decl_typedef_init(decl, decl->name, decl->var.type); } } else { scc_ast_decl_typedef_init(decl, decl->name, decl->var.type); } } if (decl_list != null) { - scc_vec_push(decl_list_vec, decl); - scc_vec_foreach(decl_list_vec, i) { decl = scc_vec_at(decl_list_vec, i); scc_parse_decl_sema(parser, decl); diff --git a/libs/parser/src/parse_type.c b/libs/parser/src/parse_type.c index e7532d4..63cb362 100644 --- a/libs/parser/src/parse_type.c +++ b/libs/parser/src/parse_type.c @@ -626,20 +626,13 @@ static scc_ast_type_t *parse_record_type(scc_parser_t *parser, // FIXME memory leak return null; } - - decl = scc_malloc(sizeof(scc_ast_decl_t)); - Assert(decl != null); - if (type_kind == SCC_AST_TYPE_STRUCT) { - scc_ast_decl_struct_init(decl, name, null); - } else { - scc_ast_decl_union_init(decl, name, null); - } } scc_ast_type_t *type = ast_type_alloc(); _scc_ast_type_record_init(type, type_kind, name, decl); return type; } + static scc_ast_type_t *parse_enum_type(scc_parser_t *parser) { /* (6.7.2.2) @@ -713,9 +706,6 @@ static scc_ast_type_t *parse_enum_type(scc_parser_t *parser) { // FIXME memory leak return null; } - decl = scc_malloc(sizeof(scc_ast_decl_t)); - Assert(decl != null); - scc_ast_decl_enum_init(decl, name, null); } scc_ast_type_t *type = ast_type_alloc(); @@ -1182,20 +1172,27 @@ scc_ast_decl_t *scc_parse_declarator(scc_parser_t *parser, if (decl_type->base.type == SCC_AST_TYPE_STRUCT || decl_type->base.type == SCC_AST_TYPE_UNION) { if (decl_type->record.decl == null) { - SCC_ERROR(scc_parser_got_current_pos(parser), - "record don't have a decl"); - Panic(); + decl = scc_malloc(sizeof(scc_ast_decl_t)); + Assert(decl != null); + if (decl_type->base.type == SCC_AST_TYPE_STRUCT) { + scc_ast_decl_struct_init(decl, decl_type->record.name, + null); + } else { + scc_ast_decl_union_init(decl, decl_type->record.name, null); + } + } else { + decl = decl_type->record.decl; + scc_free(decl_type); // FIXME } - decl = decl_type->record.decl; - scc_free(decl_type); // FIXME } else if (decl_type->base.type == SCC_AST_TYPE_ENUM) { if (decl_type->enumeration.decl == null) { - SCC_ERROR(scc_parser_got_current_pos(parser), - "enum don't have a decl"); - Panic(); + decl = scc_malloc(sizeof(scc_ast_decl_t)); + Assert(decl != null); + scc_ast_decl_enum_init(decl, type->enumeration.name, null); + } else { + decl = type->enumeration.decl; + scc_free(decl_type); // FIXME } - decl = type->enumeration.decl; - scc_free(decl_type); // FIXME } else { decl = scc_malloc(sizeof(scc_ast_decl_t)); scc_ast_decl_unsafe_val_init(decl, type, null, null); @@ -1224,66 +1221,6 @@ scc_ast_type_t *scc_parse_declaration_specifiers(scc_parser_t *parser) { specifier->quals = spec; return specifier; - // scc_lexer_tok_t tok_ident = {0}; - // scc_ast_type_t *type = parse_declarator(parser, ret, null, &tok_ident); - - // scc_ast_decl_t *decl = null; - // if (tok_ident.type == SCC_TOK_IDENT) { - // decl = scc_malloc(sizeof(scc_ast_decl_t)); - // Assert(decl != null); - // } - // const char *name = decl ? scc_cstring_as_cstr(&tok_ident.lexeme) : null; - // if (is_typedef_decl) { - // if (decl == null) { - // SCC_ERROR(scc_parser_got_current_pos(parser), - // "typedef don't have a ident"); - // parser->errcode = 1; - // } else { - // scc_ast_decl_typedef_init(decl, name, type); - // } - // } else if (decl) { - // if (type->base.type == SCC_AST_TYPE_FUNCTION) { - // scc_ast_decl_func_init(decl, type, name, null); - // // TODO using sema to change it - // if (spec.is_inline) { - // type->quals.is_inline = true; - // } - // } else { - // scc_ast_decl_val_init(decl, type, name, null); - // } - // } - - // scc_ast_node_t *type_or_decl = decl != null ? &decl->base : &type->base; - // if (SCC_AST_IS_A(scc_ast_type_t, type_or_decl)) { - // scc_ast_type_t *type = SCC_AST_CAST_TO(scc_ast_type_t, type_or_decl); - // if (type->base.type == SCC_AST_TYPE_STRUCT || - // type->base.type == SCC_AST_TYPE_UNION) { - // if (type->record.decl == null) { - // SCC_ERROR(scc_parser_got_current_pos(parser), - // "record don't have a decl"); - // Panic(); - // } - // decl = type->record.decl; - // scc_free(type_or_decl); // FIXME - // } else if (type->base.type == SCC_AST_TYPE_ENUM) { - // if (type->enumeration.decl == null) { - // SCC_ERROR(scc_parser_got_current_pos(parser), - // "enum don't have a decl"); - // Panic(); - // } - // decl = type->enumeration.decl; - // scc_free(type_or_decl); // FIXME - // } else { - // decl = scc_malloc(sizeof(scc_ast_decl_t)); - // scc_ast_decl_unsafe_val_init(decl, type, null, null); - // } - // } else if (SCC_AST_IS_A(scc_ast_decl_t, type_or_decl)) { - // decl = SCC_AST_CAST_TO(scc_ast_decl_t, type_or_decl); - // } else { - // SCC_ERROR(scc_parser_got_current_pos(parser), "invalid declaration"); - // return null; - // } - // return decl; } scc_ast_type_t *scc_parse_type_name(scc_parser_t *parser) { diff --git a/libs/parser/tests/test_parser_unit.c b/libs/parser/tests/test_parser_unit.c index 0237e27..90a0657 100644 --- a/libs/parser/tests/test_parser_unit.c +++ b/libs/parser/tests/test_parser_unit.c @@ -545,7 +545,7 @@ static void test_parser_unit(void) { // 6. 函数声明 scc_ast_decl_t decl; - scc_ast_decl_func_init(&decl, &func_type, "call", NULL); + scc_ast_decl_func_init(&decl, &func_type, "call", null); // 7. 与解析结果比较 SCC_CHECK_AST_WITH_SEMA(&decl.base, @@ -735,8 +735,81 @@ static void test_parser_unit(void) { SCC_CHECK_AST(&decl_list.base, "int a = 1, b = 2;", scc_parse_declaration); } - "struct list_head *next, *prev;"; - "typedef struct { int a; } struct_t, *struct_ptr_t;"; + // 测试 "struct list_head *next, *prev;" + { + // 构造 struct list_head 类型(不完整) + scc_ast_type_t struct_list_head; + scc_ast_type_struct_init(&struct_list_head, "list_head", null); + + // 构造两个指针类型(分别用于 next 和 prev,指向同一结构体) + scc_ast_type_t ptr_to_struct1, ptr_to_struct2; + scc_ast_type_pointer_init(&ptr_to_struct1, &struct_list_head); + scc_ast_type_pointer_init(&ptr_to_struct2, &struct_list_head); + + // 构造变量声明 next 和 prev + scc_ast_decl_t next_decl, prev_decl; + scc_ast_decl_val_init(&next_decl, &ptr_to_struct1, "next", null); + scc_ast_decl_val_init(&prev_decl, &ptr_to_struct2, "prev", null); + + // 构造声明列表 + scc_ast_decl_vec_t decl_vec; + scc_vec_init(decl_vec); + scc_vec_push(decl_vec, &next_decl); + scc_vec_push(decl_vec, &prev_decl); + scc_ast_decl_t decl_list; + scc_ast_decl_list_init(&decl_list, &decl_vec); + + SCC_CHECK_AST(&decl_list.base, "struct list_head *next, *prev;", + scc_parse_declaration); + } + + // 测试 "typedef struct { int a; } struct_t, *struct_ptr_t;" + { + // 构造字段 int a; + scc_ast_decl_t field_a; + scc_ast_decl_val_init(&field_a, + (scc_ast_type_t *)&scc_ast_builtin_type_int, + "a", null); + + scc_ast_decl_vec_t fields; + scc_vec_init(fields); + scc_vec_push(fields, &field_a); + + // 构造匿名结构体定义声明 + scc_ast_decl_t struct_def; + scc_ast_decl_struct_init(&struct_def, null, + &fields); // fields 被移动 + + // 构造匿名结构体类型 + scc_ast_type_t anon_struct_type; + scc_ast_type_struct_init(&anon_struct_type, null, &struct_def); + + // 构造指针类型指向该匿名结构体 + scc_ast_type_t ptr_to_anon; + scc_ast_type_pointer_init(&ptr_to_anon, &anon_struct_type); + + // 构造 typedef 声明 struct_t + scc_ast_decl_t typedef_struct_t; + scc_ast_decl_typedef_init(&typedef_struct_t, "struct_t", + &anon_struct_type); + + // 构造 typedef 声明 struct_ptr_t + scc_ast_decl_t typedef_struct_ptr_t; + scc_ast_decl_typedef_init(&typedef_struct_ptr_t, "struct_ptr_t", + &ptr_to_anon); + + // 构造声明列表 + scc_ast_decl_vec_t typedef_vec; + scc_vec_init(typedef_vec); + scc_vec_push(typedef_vec, &typedef_struct_t); + scc_vec_push(typedef_vec, &typedef_struct_ptr_t); + scc_ast_decl_t decl_list; + scc_ast_decl_list_init(&decl_list, &typedef_vec); + + SCC_CHECK_AST(&decl_list.base, + "typedef struct { int a; } struct_t, *struct_ptr_t;", + scc_parse_declaration); + } "__scc_builtin_va_arg(ag, int)"; "__scc_builtin_va_arg(ag, long long)"; "typedef struct a;int a;struct a b;"; diff --git a/src/main.c b/src/main.c index bfa802a..e70eb6e 100644 --- a/src/main.c +++ b/src/main.c @@ -264,9 +264,27 @@ int main(int argc, const char **argv, const char **envp) { } scc_lexer_tok_vec_t pproc_tok_vec; scc_vec_init(pproc_tok_vec); - scc_cstring_t pproc_macro_name = scc_cstring_from_cstr("__SCC__"); - scc_pproc_add_object_macro(&(pproc.macro_table), &pproc_macro_name, - &pproc_tok_vec); + scc_lexer_tok_t tok = { + .lexeme = scc_cstring_from_cstr("1"), + .type = SCC_TOK_INT_LITERAL, + .loc.name = "", + .loc.line = 0, + .loc.col = 0, + .loc.offset = 0, + }; + scc_vec_push(pproc_tok_vec, tok); + scc_cstring_t pproc_predefined_macros[] = { + scc_cstring_from_cstr("__SCC__"), + scc_cstring_from_cstr("_WIN64"), + scc_cstring_from_cstr("__x86_64__"), + }; + for (usize i = 0; i < SCC_ARRLEN(pproc_predefined_macros); i += 1) { + scc_vec_init(pproc_tok_vec); + scc_lexer_tok_t coped_tok = scc_lexer_tok_copy(&tok); + scc_vec_push(pproc_tok_vec, coped_tok); + scc_pproc_add_object_macro(&pproc.macro_table, + &pproc_predefined_macros[i], &pproc_tok_vec); + } if (config.emit_pp) { scc_lexer_tok_ring_t *tok_ring = scc_pproc_to_ring(&pproc, 8, true, true);