Fix problem with enum types in re-used modules
When a module is instantiated multiple times, the enum types contained within would cause trouble. This fixes that by elaborating in proper scope context.
This commit is contained in:
parent
6ec31517a9
commit
fc42f40770
|
|
@ -1313,9 +1313,9 @@ void NetScope::dump(ostream&o) const
|
|||
o << " enum sets {" << endl;
|
||||
|
||||
/* Dump the enumerations and enum names in this scope. */
|
||||
for (list<netenum_t*>::const_iterator cur = enum_sets_.begin()
|
||||
for (map<const enum_type_t*,netenum_t*>::const_iterator cur = enum_sets_.begin()
|
||||
; cur != enum_sets_.end() ; ++ cur) {
|
||||
o << " " << *cur << endl;
|
||||
o << " " << cur->second << endl;
|
||||
}
|
||||
o << " }" << endl;
|
||||
|
||||
|
|
|
|||
|
|
@ -182,12 +182,9 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
|||
|
||||
use_enum->set_line(enum_type->li);
|
||||
if (scope)
|
||||
scope->add_enumeration_set(use_enum);
|
||||
scope->add_enumeration_set(enum_type, use_enum);
|
||||
else
|
||||
des->add_enumeration_set(use_enum);
|
||||
|
||||
ivl_assert(*enum_type, enum_type->net_type == 0);
|
||||
enum_type->net_type = use_enum;
|
||||
des->add_enumeration_set(enum_type, use_enum);
|
||||
|
||||
verinum cur_value (0);
|
||||
verinum one_value (1);
|
||||
|
|
|
|||
14
elab_type.cc
14
elab_type.cc
|
|
@ -80,10 +80,20 @@ ivl_type_s* class_type_t::elaborate_type_raw(Design*, NetScope*scope) const
|
|||
return scope->find_class(name);
|
||||
}
|
||||
|
||||
/*
|
||||
* elaborate_type_raw for enumerations is actually mostly performed
|
||||
* during scope elaboration so that the enumeration literals are
|
||||
* available at the right time. At tha time, the netenum_t* object is
|
||||
* stashed in the scope so that I can retrieve it here.
|
||||
*/
|
||||
ivl_type_s* enum_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
|
||||
{
|
||||
ivl_assert(*this, net_type);
|
||||
return net_type;
|
||||
ivl_assert(*this, scope);
|
||||
ivl_type_s*tmp = scope->enumeration_for_key(this);
|
||||
if (tmp) return tmp;
|
||||
|
||||
tmp = des->enumeration_for_key(this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
ivl_type_s* vector_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
|
||||
|
|
|
|||
4
emit.cc
4
emit.cc
|
|
@ -420,9 +420,9 @@ void NetScope::emit_scope(struct target_t*tgt) const
|
|||
tgt->class_type(this, cur->second);
|
||||
}
|
||||
|
||||
for (list<netenum_t*>::const_iterator cur = enum_sets_.begin()
|
||||
for (map<const enum_type_t*,netenum_t*>::const_iterator cur = enum_sets_.begin()
|
||||
; cur != enum_sets_.end() ; ++cur)
|
||||
tgt->enumeration(this, *cur);
|
||||
tgt->enumeration(this, cur->second);
|
||||
|
||||
for (map<hname_t,NetScope*>::const_iterator cur = children_.begin()
|
||||
; cur != children_.end() ; ++ cur )
|
||||
|
|
|
|||
17
net_scope.cc
17
net_scope.cc
|
|
@ -38,9 +38,11 @@ Definitions::~Definitions()
|
|||
{
|
||||
}
|
||||
|
||||
void Definitions::add_enumeration_set(netenum_t*enum_set)
|
||||
void Definitions::add_enumeration_set(const enum_type_t*key, netenum_t*enum_set)
|
||||
{
|
||||
enum_sets_.push_back(enum_set);
|
||||
netenum_t*&tmp = enum_sets_[key];
|
||||
assert(tmp == 0);
|
||||
tmp = enum_set;
|
||||
}
|
||||
|
||||
bool Definitions::add_enumeration_name(netenum_t*enum_set, perm_string name)
|
||||
|
|
@ -57,6 +59,17 @@ bool Definitions::add_enumeration_name(netenum_t*enum_set, perm_string name)
|
|||
return cur.second;
|
||||
}
|
||||
|
||||
netenum_t* Definitions::enumeration_for_key(const enum_type_t*key) const
|
||||
{
|
||||
map<const enum_type_t*,netenum_t*>::const_iterator cur;
|
||||
|
||||
cur = enum_sets_.find(key);
|
||||
if (cur != enum_sets_.end())
|
||||
return cur->second;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This locates the enumeration TYPE for the given enumeration literal.
|
||||
*/
|
||||
|
|
|
|||
14
netlist.h
14
netlist.h
|
|
@ -76,6 +76,7 @@ class NetEvTrig;
|
|||
class NetEvWait;
|
||||
class PExpr;
|
||||
class PFunction;
|
||||
class enum_type_t;
|
||||
class netclass_t;
|
||||
class netdarray_t;
|
||||
class netparray_t;
|
||||
|
|
@ -829,13 +830,22 @@ class Definitions {
|
|||
Definitions();
|
||||
~Definitions();
|
||||
|
||||
void add_enumeration_set(netenum_t*enum_set);
|
||||
// Add the enumeration to the set of enumerations in this
|
||||
// scope. Include a key that the elaboration can use to look
|
||||
// up this enumeration based on the pform type.
|
||||
void add_enumeration_set(const enum_type_t*key, netenum_t*enum_set);
|
||||
|
||||
bool add_enumeration_name(netenum_t*enum_set, perm_string enum_name);
|
||||
|
||||
// Look up the enumeration literal in this scope. if the name
|
||||
// is present, then return the enumeration type that declares it.
|
||||
const netenum_t* enumeration_for_name(perm_string name);
|
||||
|
||||
// Look up the enumeration set that was added with the given
|
||||
// key. This is used by enum_type_t::elaborate_type to locate
|
||||
// a previously elaborated enumeration.
|
||||
netenum_t* enumeration_for_key(const enum_type_t*key) const;
|
||||
|
||||
// Look up an enumeration literal in this scope. If the
|
||||
// literal is present, return the expression that defines its
|
||||
// value.
|
||||
|
|
@ -846,7 +856,7 @@ class Definitions {
|
|||
// enumerations present in this scope. The enum_names_ is a
|
||||
// map of all the enumeration names back to the sets that
|
||||
// contain them.
|
||||
std::list<netenum_t*> enum_sets_;
|
||||
std::map<const enum_type_t*,netenum_t*> enum_sets_;
|
||||
std::map<perm_string,NetEConstEnum*> enum_names_;
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -116,7 +116,6 @@ struct void_type_t : public data_type_t {
|
|||
* until it is elaborated in a scope.
|
||||
*/
|
||||
struct enum_type_t : public data_type_t {
|
||||
inline enum_type_t(void) : net_type(0) { }
|
||||
// Return the elaborated version of the type.
|
||||
virtual ivl_type_s*elaborate_type_raw(Design*des, NetScope*scope) const;
|
||||
|
||||
|
|
@ -125,11 +124,6 @@ struct enum_type_t : public data_type_t {
|
|||
std::auto_ptr< list<pform_range_t> > range;
|
||||
std::auto_ptr< list<named_pexpr_t> > names;
|
||||
LineInfo li;
|
||||
// This is the elaborated type. The enumeration type is
|
||||
// elaborated early so that names can be placed in the scope,
|
||||
// but that means the result needs to be saved for the actual
|
||||
// elaborate_type method to use.
|
||||
netenum_t*net_type;
|
||||
};
|
||||
|
||||
struct struct_member_t : public LineInfo {
|
||||
|
|
|
|||
Loading…
Reference in New Issue