diff --git a/parser.y b/parser.y index ebba762e..d514d1ec 100644 --- a/parser.y +++ b/parser.y @@ -395,6 +395,11 @@ decl: declaration_specifiers init_declarator_list_opt SEMICOLON { auto decl_list = std::vector>{}; if (std::holds_alternative>(decl_specifiers)) { auto type = std::move(std::get>(decl_specifiers)); + if (init_decl_list.empty()) { + // A stand-alone type that doesn't declare any identifier, e.g., `int;`. + decl_list.push_back(std::make_unique(Loc(@1), "", type->Clone())); + } + for (auto& init_decl : init_decl_list) { if (init_decl) { init_decl->type = ResolveType(type->Clone(), std::move(init_decl->type)); @@ -405,7 +410,13 @@ decl: declaration_specifiers init_declarator_list_opt SEMICOLON { } } else { auto decl = std::move(std::get>(decl_specifiers)); + // A record declaration that doesn't declare any identifier, e.g., `struct point {int x, int y};`. + if (init_decl_list.empty()) { + decl_list.push_back(std::move(decl)); + } + auto* rec_decl = dynamic_cast(decl.get()); + // Initialize record variable. for (auto& init_decl : init_decl_list) { if (init_decl) { init_decl->type = ResolveType(rec_decl->type->Clone(), std::move(init_decl->type)); diff --git a/test/typecheck/decl.exp b/test/typecheck/decl.exp index e4cefdc7..70f44130 100644 --- a/test/typecheck/decl.exp +++ b/test/typecheck/decl.exp @@ -7,6 +7,7 @@ ProgramNode <1:1> DeclStmtNode <3:3> VarDeclNode <3:7> j: int DeclStmtNode <4:3> + VarDeclNode <4:3> : int DeclStmtNode <5:3> VarDeclNode <5:7> a: int VarDeclNode <5:10> b: int diff --git a/test/typecheck/struct.exp b/test/typecheck/struct.exp index 09f5c8b7..c5cb2129 100644 --- a/test/typecheck/struct.exp +++ b/test/typecheck/struct.exp @@ -2,8 +2,17 @@ ProgramNode <1:1> FuncDefNode <1:5> main: int () CompoundStmtNode <1:12> DeclStmtNode <2:3> + RecordDeclNode <2:10> struct ss definition DeclStmtNode <4:3> + RecordDeclNode <4:10> struct birth definition + FieldNode <5:9> date: int + FieldNode <6:9> month: int + FieldNode <7:9> year: int DeclStmtNode <10:3> + RecordDeclNode <10:9> struct definition + FieldNode <11:9> quarter: int + FieldNode <12:9> dime: int + FieldNode <13:9> penny: int DeclStmtNode <16:3> RecordVarDeclNode <16:16> bd1: struct birth InitExprNode <17:5> diff --git a/test/typecheck/union.exp b/test/typecheck/union.exp index b0e3343a..c7f09db4 100644 --- a/test/typecheck/union.exp +++ b/test/typecheck/union.exp @@ -2,8 +2,19 @@ ProgramNode <1:1> FuncDefNode <1:5> main: int () CompoundStmtNode <1:12> DeclStmtNode <2:3> + RecordDeclNode <2:9> union u definition DeclStmtNode <4:3> + RecordDeclNode <4:9> union shape definition + FieldNode <5:9> square: int + FieldNode <6:9> circle: int + FieldNode <7:9> triangle: int DeclStmtNode <10:3> + RecordDeclNode <10:8> union definition + FieldNode <11:9> a: int + FieldNode <12:9> b: int + FieldNode <13:9> c: int + FieldNode <14:9> d: int + FieldNode <15:9> e: int DeclStmtNode <20:3> RecordVarDeclNode <20:15> s: union shape InitExprNode <20:20>