Skip to content

Commit caf378e

Browse files
authored
Merge pull request #949 from diffblue/scope-stack
Verilog: introduce scope stack
2 parents 2da61f0 + a6d8c6f commit caf378e

File tree

4 files changed

+45
-22
lines changed

4 files changed

+45
-22
lines changed

src/verilog/parser.y

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1447,8 +1447,7 @@ type_declaration:
14471447
data_type any_identifier ';'
14481448
{ $$ = $2;
14491449
// add to the scope as a type name
1450-
auto &name = PARSER.scopes.add_name(stack_expr($4).get(ID_identifier), "", verilog_scopet::TYPEDEF);
1451-
name.is_type = true;
1450+
PARSER.scopes.add_name(stack_expr($4).get(ID_identifier), "", verilog_scopet::TYPEDEF);
14521451
addswap($$, ID_type, $3);
14531452
stack_expr($4).id(ID_declarator);
14541453
mto($$, $4);
@@ -1537,7 +1536,7 @@ data_type:
15371536

15381537
// We attach a dummy id to distinguish two syntactically
15391538
// identical enum types.
1540-
auto id = PARSER.scopes.current_scope->prefix + "enum-" + PARSER.get_next_id();
1539+
auto id = PARSER.scopes.current_scope().prefix + "enum-" + PARSER.get_next_id();
15411540
stack_expr($$).set(ID_identifier, id);
15421541
}
15431542
| TOK_STRING
@@ -4429,7 +4428,7 @@ type_identifier: TOK_TYPE_IDENTIFIER
44294428
init($$, ID_typedef_type);
44304429
auto base_name = stack_expr($1).id();
44314430
stack_expr($$).set(ID_base_name, base_name);
4432-
stack_expr($$).set(ID_identifier, PARSER.scopes.current_scope->prefix+id2string(base_name));
4431+
stack_expr($$).set(ID_identifier, PARSER.scopes.current_scope().prefix+id2string(base_name));
44334432
}
44344433
;
44354434

src/verilog/scanner.l

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ static void preprocessor()
6767
stack_expr(yyveriloglval).id(irep_id); \
6868
auto name = PARSER.scopes.lookup(irep_id); \
6969
return name == nullptr ? TOK_NON_TYPE_IDENTIFIER : \
70-
name->is_type ? TOK_TYPE_IDENTIFIER : \
70+
name->kind == verilog_scopet::TYPEDEF ? TOK_TYPE_IDENTIFIER : \
7171
TOK_NON_TYPE_IDENTIFIER; \
7272
}
7373
#define KEYWORD(s, x) \

src/verilog/verilog_scope.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ Author: Daniel Kroening, [email protected]
88

99
#include "verilog_scope.h"
1010

11-
const verilog_scopet *verilog_scopest::lookup(irep_idt name) const
11+
#include "verilog_y.tab.h"
12+
13+
const verilog_scopet *verilog_scopest::lookup(irep_idt base_name) const
1214
{
1315
// we start from the current scope, and walk upwards to the root
14-
auto scope = current_scope;
16+
auto scope = &current_scope();
1517
while(scope != nullptr)
1618
{
17-
auto name_it = scope->scope_map.find(name);
19+
auto name_it = scope->scope_map.find(base_name);
1820
if(name_it == scope->scope_map.end())
1921
scope = scope->parent;
2022
else
@@ -24,3 +26,13 @@ const verilog_scopet *verilog_scopest::lookup(irep_idt name) const
2426
// not found, give up
2527
return nullptr;
2628
}
29+
30+
void verilog_scopest::enter_package_scope(irep_idt base_name)
31+
{
32+
// look in the global scope
33+
auto name_it = top_scope.scope_map.find(base_name);
34+
if(name_it == top_scope.scope_map.end())
35+
enter_scope(current_scope());
36+
else
37+
enter_scope(name_it->second); // found it
38+
}

src/verilog/verilog_scope.h

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ struct verilog_scopet
4747
}
4848

4949
verilog_scopet *parent = nullptr;
50-
bool is_type = false;
5150
irep_idt __base_name;
5251
std::string prefix;
5352
kindt kind;
@@ -73,42 +72,55 @@ class verilog_scopest
7372
public:
7473
using scopet = verilog_scopet;
7574

76-
scopet top_scope, *current_scope = &top_scope;
75+
scopet top_scope;
7776

7877
scopet &add_name(
7978
irep_idt _base_name,
8079
const std::string &separator,
8180
scopet::kindt kind)
8281
{
83-
auto result = current_scope->scope_map.emplace(
84-
_base_name, scopet{_base_name, separator, current_scope, kind});
82+
auto result = current_scope().scope_map.emplace(
83+
_base_name, scopet{_base_name, separator, &current_scope(), kind});
8584
return result.first->second;
8685
}
8786

88-
// Create the given sub-scope of the current scope.
87+
// Scope stack
88+
std::vector<scopet *> scope_stack = {&top_scope};
89+
90+
scopet &current_scope() const
91+
{
92+
// We never pop the top scope
93+
PRECONDITION(!scope_stack.empty());
94+
return *scope_stack.back();
95+
}
96+
97+
// find the package scope with given base name, and enter it
98+
void enter_package_scope(irep_idt base_name);
99+
100+
void enter_scope(scopet &scope)
101+
{
102+
scope_stack.push_back(&scope);
103+
}
104+
105+
// Create the given sub-scope of the current scope, and enter it.
89106
void push_scope(
90107
irep_idt _base_name,
91108
const std::string &separator,
92109
scopet::kindt kind)
93110
{
94-
current_scope = &add_name(_base_name, separator, kind);
111+
enter_scope(add_name(_base_name, separator, kind));
95112
}
96113

97114
void pop_scope()
98115
{
99-
PRECONDITION(current_scope->parent != nullptr);
100-
current_scope = current_scope->parent;
116+
// We never pop the top scope
117+
PRECONDITION(scope_stack.size() >= 2);
118+
scope_stack.pop_back();
101119
}
102120

103121
// Look up an identifier, starting from the current scope,
104122
// going upwards until found. Returns nullptr when not found.
105123
const scopet *lookup(irep_idt base_name) const;
106-
107-
bool is_type(irep_idt base_name) const
108-
{
109-
auto scope_ptr = lookup(base_name);
110-
return scope_ptr == nullptr ? false : scope_ptr->is_type;
111-
}
112124
};
113125

114126
#endif

0 commit comments

Comments
 (0)