-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathverilog_scope.h
139 lines (112 loc) · 2.85 KB
/
verilog_scope.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*******************************************************************\
Module: Verilog Scopes
Author: Daniel Kroening, [email protected]
\*******************************************************************/
#ifndef CPROVER_VERILOG_SCOPE_H
#define CPROVER_VERILOG_SCOPE_H
#include <util/irep.h>
#include <iosfwd>
#include <map>
// parser scopes and identifiers
struct verilog_scopet
{
using kindt = enum {
GLOBAL,
FILE,
PACKAGE,
MODULE,
INTERFACE,
CLASS,
ENUM_NAME,
TASK,
FUNCTION,
BLOCK,
TYPEDEF,
OTHER
};
verilog_scopet() : parent(nullptr), prefix("Verilog::"), kind(GLOBAL)
{
}
verilog_scopet(
irep_idt _base_name,
const std::string &separator,
verilog_scopet *_parent,
kindt _kind)
: parent(_parent),
__base_name(_base_name),
prefix(id2string(_parent->prefix) + id2string(_base_name) + separator),
kind(_kind)
{
}
verilog_scopet *parent = nullptr;
irep_idt __base_name;
std::string prefix;
kindt kind;
irep_idt identifier() const
{
PRECONDITION(parent != nullptr);
return parent->prefix + id2string(__base_name);
}
const irep_idt &base_name() const
{
return __base_name;
}
void print(std::ostream &out) const
{
print_rec(0, out);
}
void print_rec(std::size_t indent, std::ostream &) const;
// sub-scopes
using scope_mapt = std::map<irep_idt, verilog_scopet>;
scope_mapt scope_map;
};
class verilog_scopest
{
public:
using scopet = verilog_scopet;
scopet top_scope;
scopet &add_name(
irep_idt _base_name,
const std::string &separator,
scopet::kindt kind)
{
auto result = current_scope().scope_map.emplace(
_base_name, scopet{_base_name, separator, ¤t_scope(), kind});
return result.first->second;
}
// Scope stack
std::vector<scopet *> scope_stack = {&top_scope};
scopet ¤t_scope() const
{
// We never pop the top scope
PRECONDITION(!scope_stack.empty());
return *scope_stack.back();
}
// find the package scope with given base name, and enter it
void enter_package_scope(irep_idt base_name);
void enter_scope(scopet &scope)
{
scope_stack.push_back(&scope);
}
// Create the given sub-scope of the current scope, and enter it.
void push_scope(
irep_idt _base_name,
const std::string &separator,
scopet::kindt kind)
{
enter_scope(add_name(_base_name, separator, kind));
}
void pop_scope()
{
// We never pop the top scope
PRECONDITION(scope_stack.size() >= 2);
scope_stack.pop_back();
}
// Look up an identifier, starting from the current scope,
// going upwards until found. Returns nullptr when not found.
const scopet *lookup(irep_idt base_name) const;
// token to be returned by the scanner for the given identifier
// in the current scope
unsigned identifier_token(irep_idt base_name) const;
};
#endif