Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix missing record declaration tests #162

Merged
merged 1 commit into from
Jun 16, 2024

Conversation

leewei05
Copy link
Contributor

My bad, missed this update on previous reviews. The current implementation only consider the case for struct and union variable initialization.

@leewei05 leewei05 self-assigned this Jun 16, 2024
@leewei05 leewei05 requested a review from Lai-YT June 16, 2024 06:49
Copy link
Collaborator

@Lai-YT Lai-YT left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like we have the same issue regarding to unnamed primitive types.
We check whether it declares an identifier or not inside the iteration over the init_decl_list; however, we don't even get into the loop when it doesn't declare an identifier, leading to an empty declaration node:

vitaminc/parser.y

Lines 398 to 405 in 2f6edee

for (auto& init_decl : init_decl_list) {
if (init_decl) {
init_decl->type = ResolveType(type->Clone(), std::move(init_decl->type));
} else { // unnamed primitive type
init_decl = std::make_unique<VarDeclNode>(Loc(@1), "", type->Clone());
}
decl_list.push_back(std::move(init_decl));
}


DeclStmtNode <4:3>
DeclStmtNode <5:3>

Would you mind addressing them together? Here's a possible modification:

    if (std::holds_alternative<std::unique_ptr<Type>>(decl_specifiers)) {
      auto type = std::move(std::get<std::unique_ptr<Type>>(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<VarDeclNode>(Loc(@1), "", type->Clone()));
      }

      // Declare primitive identifier.
      for (auto& init_decl : init_decl_list) {
        if (init_decl) {
          init_decl->type = ResolveType(type->Clone(), std::move(init_decl->type));
        }
        decl_list.push_back(std::move(init_decl));
      }
    } else {
      auto decl = std::move(std::get<std::unique_ptr<DeclNode>>(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<RecordDeclNode*>(decl.get());
      // Declare record identifier.
      for (auto& init_decl : init_decl_list) {
        if (init_decl) {
          init_decl->type = ResolveType(rec_decl->type->Clone(), std::move(init_decl->type));
        }
        decl_list.push_back(std::move(init_decl));
      }
    }
       DeclStmtNode <4:3>
+        VarDeclNode <4:3> : int
       DeclStmtNode <5:3>

parser.y Outdated Show resolved Hide resolved
@Lai-YT
Copy link
Collaborator

Lai-YT commented Jun 16, 2024

I just realized there is another issue. If we build a DeclNode with the name "", our code generator is likely to allocate space for it. We need to filter out these empty nodes. It is important to note that Clang doesn't build nodes for declarations that have no effect on the program.

`-FunctionDecl 0x1f690a0 <test/typecheck/decl.c:1:1, line:6:1> line:1:5 main 'int ()'
  `-CompoundStmt 0x1f69558 <col:12, line:6:1>
    |-DeclStmt 0x1f69228 <line:2:3, col:12>
    | `-VarDecl 0x1f691a0 <col:3, col:11> col:7 i 'int' cinit
    |   `-IntegerLiteral 0x1f69208 <col:11> 'int' 0
    |-DeclStmt 0x1f692c0 <line:3:3, col:8>
    | `-VarDecl 0x1f69258 <col:3, col:7> col:7 j 'int'
    `-DeclStmt 0x1f69540 <line:5:3, col:25>
      |-VarDecl 0x1f692f0 <col:3, col:7> col:7 a 'int'
      |-VarDecl 0x1f69370 <col:3, col:14> col:10 b 'int' cinit
      | `-IntegerLiteral 0x1f693d8 <col:14> 'int' 1
      |-VarDecl 0x1f69410 <col:3, col:17> col:17 c 'int'
      `-VarDecl 0x1f69490 <col:3, col:24> col:20 d 'int' cinit
        `-IntegerLiteral 0x1f694f8 <col:24> 'int' 0

@leewei05
Copy link
Contributor Author

leewei05 commented Jun 16, 2024

I just realized there is another issue. If we build a DeclNode with the name "", our code generator is likely to allocate space for it. We need to filter out these empty nodes. It is important to note that Clang doesn't build nodes for declarations that have no effect on the program.

Suggest fixing this in a future PR since it's related only to unnamed nodes.

@leewei05 leewei05 requested a review from Lai-YT June 16, 2024 07:36
Copy link
Collaborator

@Lai-YT Lai-YT left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 😄
We can resolve the code generation issue one day. 🤟

@Lai-YT Lai-YT merged commit c65978a into fruits-lab:main Jun 16, 2024
4 checks passed
@leewei05 leewei05 deleted the fix-record-test branch June 16, 2024 08:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants