mirror of
https://github.com/steveicarus/iverilog.git
synced 2026-08-29 01:03:29 +02:00
Do not create implicit nets for type identifiers
`PEIdent::declare_implicit_nets()` checks visible nets, parameters, genvars, events, and enum constants before creating an implicit net, but does not check typedefs. Type identifiers are currently filtered by the grammar before they can reach this code, but this is not true when type and hierarchy identifier parsing use the same path. Check local and imported typedefs while searching the lexical scopes. Stop the type search when another local declaration hides an outer typedef. Signed-off-by: Lars-Peter Clausen <[email protected]>
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
|
||||
# include "compiler.h"
|
||||
# include "PExpr.h"
|
||||
# include "PPackage.h"
|
||||
# include "PWire.h"
|
||||
# include "Module.h"
|
||||
# include "ivl_assert.h"
|
||||
@@ -419,6 +420,29 @@ static bool find_enum_constant(LexicalScope*scope, perm_string name)
|
||||
});
|
||||
}
|
||||
|
||||
static bool is_typedef_identifier(LexicalScope *scope, perm_string name)
|
||||
{
|
||||
while (scope) {
|
||||
auto import = scope->explicit_imports.find(name);
|
||||
if (import != scope->explicit_imports.end()) {
|
||||
// An explicit import shadows declarations in outer scopes.
|
||||
const auto &typedefs = import->second.package->typedefs;
|
||||
return typedefs.find(name) != typedefs.end();
|
||||
}
|
||||
|
||||
if (scope->typedefs.find(name) != scope->typedefs.end())
|
||||
return true;
|
||||
|
||||
// A local non-type declaration also hides outer typedefs.
|
||||
if (scope->local_symbols.find(name) != scope->local_symbols.end())
|
||||
return false;
|
||||
|
||||
scope = scope->parent_scope();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
|
||||
{
|
||||
/* We create an implicit wire if:
|
||||
@@ -432,6 +456,9 @@ void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
|
||||
return;
|
||||
if (path_.name.size() == 1 && path_.name.front().index.empty()) {
|
||||
perm_string name = path_.name.front().name;
|
||||
if (is_typedef_identifier(scope, name))
|
||||
return;
|
||||
|
||||
LexicalScope*ss = scope;
|
||||
while (ss) {
|
||||
if (ss->wires.find(name) != ss->wires.end())
|
||||
|
||||
Reference in New Issue
Block a user