Support declaration names shadowing type identifiers

SystemVerilog allows a declaration in an inner scope to use the same name as a
type identifier from an outer scope. The lexer reports such names as
`TYPE_IDENTIFIER` before the new declaration has been installed, which made
constructs such as `int T;`, `wire T;`, and `input T` fail when `T` was a
visible typedef.

The affected declaration forms have a local type/name/dimension ambiguity. For
example, after `input T` or `wire T` the parser does not know whether `T` is the
declared name, or whether a following identifier will make `T` the declaration
type in `input T x` or `wire T x`. With dimensions, `input T [1:0]` and
`wire T [1:0]` can be either a declaration named `T` with unpacked dimensions or
a declaration using typedef `T` as a packed type followed by another name.

Parse these declaration forms with productions that decide the first declarator
and carry the selected declaration type across the rest of the list. This covers
variable declarations, net declarations, ANSI and non-ANSI module port
declarations, and task/function port declarations. Other identifier uses still
need separate grammar changes.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
Lars-Peter Clausen 2026-06-25 23:10:30 -07:00
parent a1c333ea6e
commit 7cffbf440d
2 changed files with 442 additions and 182 deletions

619
parse.y

File diff suppressed because it is too large Load Diff

View File

@ -510,4 +510,9 @@ extern std::ostream& operator<< (std::ostream&out, const name_component_t&that);
extern std::ostream& operator<< (std::ostream&out, const index_component_t&that); extern std::ostream& operator<< (std::ostream&out, const index_component_t&that);
extern std::ostream& operator<< (std::ostream&out, const type_restrict_t& type); extern std::ostream& operator<< (std::ostream&out, const type_restrict_t& type);
struct pform_port_list {
std::list<pform_port_t> *ports;
data_type_t *type;
};
#endif /* IVL_pform_types_H */ #endif /* IVL_pform_types_H */