MikePopoloski / slang

SystemVerilog compiler and language services
MIT License
555 stars 120 forks source link

Unnamed scope issue #645

Closed HungMingWu closed 1 year ago

HungMingWu commented 1 year ago

Describe the bug I don't know whether it is a bug. But I see the difference behavior between verilator and slang

Here is the test case

class C;
        task T();
                int arr[5];
                blk_1: foreach(arr[j]) begin
                        int ccc;
                        foreach (arr[k]) begin
                                int ccc;
                                ccc = k;
                        end
                end
        endtask
endclass

They have two different symbols, but identical hierarchical path. I am not sure whether it is right.

MikePopoloski commented 1 year ago

Can you give more information about what the problem is? The variables are not actually accessibly via hierarchical path since they are in unnamed blocks so I'm not sure what you're observing.

HungMingWu commented 1 year ago

I am doing something like this

struct TestVisitor : public slang::ast::ASTVisitor<TestVisitor, false, false> {
    void traceScope(const slang::ast::Scope* scope) {
        while (scope) {
            std::cout << "Scope: " << scope << "\n";
            scope = scope->asSymbol().getParentScope();
        }
    }
    template<typename T>
    void handle(const T& symbol) {
        traceScope(symbol.getParentScope());
        visitDefault(symbol);
    };
};

From my observation, two ccc in the same scope, I don't rely hierarchical path really. I need to distinguish two symbols live in different scope.

MikePopoloski commented 1 year ago

Are you sure they're in the same scope? I don't think that's the case, otherwise there would be an error issued about duplicate variable names. There should be separate scopes (instances of StatementBlockSymbol), it's just that those blocks are unnamed. Could you post actual output that shows the problem?

HungMingWu commented 1 year ago

Soory, but I think I misunderstand the root problem. Here is modified test case

class C;
        task T();
                int arr[5];
                blk_1: foreach(arr[j]) begin
                        blk_2: foreach (arr[k]) begin
                                int ccc;
                                ccc = k;
                        end
                end
        endtask
endclass

For me, I want to distinguish j and blk_2 in different scope. The snapshot comes from SystemVerilog LRM Description May I keep the implicit scope my own?

MikePopoloski commented 1 year ago

Sorry, I'm still not following your question. Why do j and blk_2 need to be in different scopes?

When I run your example with --ast-json I get the following output describing the structure, which seems ok to me:

"members": [
            {
              "name": "T",
              "kind": "Subroutine",
              "addr": 1620316891400,
              "members": [
                {
                  "name": "arr",
                  "kind": "Variable",
                  "addr": 1620316891808,
                  "type": "int$[0:4]",
                  "lifetime": "Automatic"
                },
                {
                  "name": "blk_1",
                  "kind": "StatementBlock",
                  "addr": 1620316891984,
                  "members": [
                    {
                      "name": "j",
                      "kind": "Iterator",
                      "addr": 1620316897576,
                      "type": "int"
                    },
                    {
                      "name": "blk_2",
                      "kind": "StatementBlock",
                      "addr": 1620316892144,
                      "members": [
                        {
                          "name": "k",
                          "kind": "Iterator",
                          "addr": 1620316897944,
                          "type": "int"
                        },
                        {
                          "name": "",
                          "kind": "StatementBlock",
                          "addr": 1620316892304,
                          "members": [
                            {
                              "name": "ccc",
                              "kind": "Variable",
                              "addr": 1620316892464,
                              "type": "int",
                              "lifetime": "Automatic"
                            }
                          ]
                        }
                      ]
                    }
                  ]
                },
...
HungMingWu commented 1 year ago

After discussion with my colleague , I think you are right. Sorry for this, you can close the issue.

MikePopoloski commented 1 year ago

Ok, no problem.