Elaborate enums in the order they have been declared

enums for a scope are stored in a std::set. This means when iterating over
the enums during elaboration it is possible that they are elaborated in a
different order than they have been declared in. This causes problems if
one enum references items of the other enum. E.g.

```
enum {
  A
} a;

enum {
  B = A
} b;
```

In the current implementation whether this works or not depends on the
pointer values of the enum_type_t for `a` and `b`, which can change between
environments.

To make sure that enums are elaborated in the same order use a std::vector
instead of a std::set.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
Lars-Peter Clausen 2022-01-22 11:30:48 +01:00
parent 9898bffd41
commit e75ad281fc
5 changed files with 10 additions and 8 deletions

View File

@ -390,7 +390,7 @@ PEIdent::~PEIdent()
static bool find_enum_constant(LexicalScope*scope, perm_string name)
{
for (set<enum_type_t*,netenum_t*>::const_iterator cur = scope->enum_sets.begin() ;
for (vector<enum_type_t*>::const_iterator cur = scope->enum_sets.begin() ;
cur != scope->enum_sets.end() ; ++ cur) {
for (list<named_pexpr_t>::const_iterator idx = (*cur)->names->begin() ;
idx != (*cur)->names->end() ; ++ idx) {

View File

@ -139,7 +139,7 @@ class LexicalScope {
std::list<PCallTask*> elab_tasks;
// Enumeration sets.
std::set<enum_type_t*> enum_sets;
std::vector<enum_type_t*> enum_sets;
// A count of the generate constructs in this scope. This is
// used to automatically name unnamed generate blocks, as

View File

@ -393,7 +393,7 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
}
static void elaborate_scope_enumerations(Design*des, NetScope*scope,
const set<enum_type_t*>&enum_types)
const vector<enum_type_t*>&enum_types)
{
if (debug_scopes) {
cerr << scope->get_fileline() << ": " << __func__ << ": "
@ -402,7 +402,7 @@ static void elaborate_scope_enumerations(Design*des, NetScope*scope,
<< endl;
}
for (set<enum_type_t*>::const_iterator cur = enum_types.begin()
for (vector<enum_type_t*>::const_iterator cur = enum_types.begin()
; cur != enum_types.end() ; ++ cur) {
enum_type_t*curp = *cur;
elaborate_scope_enumeration(des, scope, curp);

View File

@ -829,8 +829,10 @@ static void pform_put_wire_in_scope(perm_string name, PWire*net)
void pform_put_enum_type_in_scope(enum_type_t*enum_set)
{
if (lexical_scope->enum_sets.count(enum_set))
return;
if (std::find(lexical_scope->enum_sets.begin(),
lexical_scope->enum_sets.end(), enum_set) !=
lexical_scope->enum_sets.end())
return;
set<perm_string> enum_names;
list<named_pexpr_t>::const_iterator cur;
@ -846,7 +848,7 @@ void pform_put_enum_type_in_scope(enum_type_t*enum_set)
}
}
lexical_scope->enum_sets.insert(enum_set);
lexical_scope->enum_sets.push_back(enum_set);
}
PWire*pform_get_make_wire_in_scope(const struct vlltype&, perm_string name,

View File

@ -1544,7 +1544,7 @@ void LexicalScope::dump_localparams_(ostream&out, unsigned indent) const
void LexicalScope::dump_enumerations_(ostream&out, unsigned indent) const
{
for (set<enum_type_t*>::const_iterator cur = enum_sets.begin()
for (vector<enum_type_t*>::const_iterator cur = enum_sets.begin()
; cur != enum_sets.end() ; ++ cur) {
out << setw(indent) << "" << "enum {" << endl;