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;
|
o << " enum sets {" << endl;
|
||||||
|
|
||||||
/* Dump the enumerations and enum names in this scope. */
|
/* 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) {
|
; cur != enum_sets_.end() ; ++ cur) {
|
||||||
o << " " << *cur << endl;
|
o << " " << cur->second << endl;
|
||||||
}
|
}
|
||||||
o << " }" << endl;
|
o << " }" << endl;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -182,12 +182,9 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
||||||
|
|
||||||
use_enum->set_line(enum_type->li);
|
use_enum->set_line(enum_type->li);
|
||||||
if (scope)
|
if (scope)
|
||||||
scope->add_enumeration_set(use_enum);
|
scope->add_enumeration_set(enum_type, use_enum);
|
||||||
else
|
else
|
||||||
des->add_enumeration_set(use_enum);
|
des->add_enumeration_set(enum_type, use_enum);
|
||||||
|
|
||||||
ivl_assert(*enum_type, enum_type->net_type == 0);
|
|
||||||
enum_type->net_type = use_enum;
|
|
||||||
|
|
||||||
verinum cur_value (0);
|
verinum cur_value (0);
|
||||||
verinum one_value (1);
|
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);
|
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_type_s* enum_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
|
||||||
{
|
{
|
||||||
ivl_assert(*this, net_type);
|
ivl_assert(*this, scope);
|
||||||
return net_type;
|
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
|
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);
|
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)
|
; cur != enum_sets_.end() ; ++cur)
|
||||||
tgt->enumeration(this, *cur);
|
tgt->enumeration(this, cur->second);
|
||||||
|
|
||||||
for (map<hname_t,NetScope*>::const_iterator cur = children_.begin()
|
for (map<hname_t,NetScope*>::const_iterator cur = children_.begin()
|
||||||
; cur != children_.end() ; ++ cur )
|
; 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)
|
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;
|
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.
|
* 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 NetEvWait;
|
||||||
class PExpr;
|
class PExpr;
|
||||||
class PFunction;
|
class PFunction;
|
||||||
|
class enum_type_t;
|
||||||
class netclass_t;
|
class netclass_t;
|
||||||
class netdarray_t;
|
class netdarray_t;
|
||||||
class netparray_t;
|
class netparray_t;
|
||||||
|
|
@ -829,13 +830,22 @@ class Definitions {
|
||||||
Definitions();
|
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);
|
bool add_enumeration_name(netenum_t*enum_set, perm_string enum_name);
|
||||||
|
|
||||||
// Look up the enumeration literal in this scope. if the name
|
// Look up the enumeration literal in this scope. if the name
|
||||||
// is present, then return the enumeration type that declares it.
|
// is present, then return the enumeration type that declares it.
|
||||||
const netenum_t* enumeration_for_name(perm_string name);
|
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
|
// Look up an enumeration literal in this scope. If the
|
||||||
// literal is present, return the expression that defines its
|
// literal is present, return the expression that defines its
|
||||||
// value.
|
// value.
|
||||||
|
|
@ -846,7 +856,7 @@ class Definitions {
|
||||||
// enumerations present in this scope. The enum_names_ is a
|
// enumerations present in this scope. The enum_names_ is a
|
||||||
// map of all the enumeration names back to the sets that
|
// map of all the enumeration names back to the sets that
|
||||||
// contain them.
|
// 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_;
|
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.
|
* until it is elaborated in a scope.
|
||||||
*/
|
*/
|
||||||
struct enum_type_t : public data_type_t {
|
struct enum_type_t : public data_type_t {
|
||||||
inline enum_type_t(void) : net_type(0) { }
|
|
||||||
// Return the elaborated version of the type.
|
// Return the elaborated version of the type.
|
||||||
virtual ivl_type_s*elaborate_type_raw(Design*des, NetScope*scope) const;
|
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<pform_range_t> > range;
|
||||||
std::auto_ptr< list<named_pexpr_t> > names;
|
std::auto_ptr< list<named_pexpr_t> > names;
|
||||||
LineInfo li;
|
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 {
|
struct struct_member_t : public LineInfo {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue