Add support for classes defined in $root scope.
This commit is contained in:
parent
fa21527e9f
commit
480668fee6
|
|
@ -1879,6 +1879,12 @@ void Design::dump(ostream&o) const
|
|||
cur->second->dump(o);
|
||||
}
|
||||
|
||||
o << "$ROOT CLASSESS:" << endl;
|
||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
||||
; cur != classes_.end() ; ++cur) {
|
||||
cur->second->dump_scope(o);
|
||||
}
|
||||
|
||||
o << "SCOPES:" << endl;
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
scope != root_scopes_.end(); ++ scope ) {
|
||||
|
|
|
|||
|
|
@ -5093,6 +5093,8 @@ NetExpr* PENewClass::elaborate_expr_constructor_(Design*des, NetScope*scope,
|
|||
const netclass_t*ctype,
|
||||
NetExpr*obj, unsigned /*flags*/) const
|
||||
{
|
||||
ivl_assert(*this, ctype);
|
||||
|
||||
// If there is an initializer function, then pass the object
|
||||
// through that function first. Note that the initializer
|
||||
// function has no arguments other than the object itself.
|
||||
|
|
@ -5130,6 +5132,12 @@ NetExpr* PENewClass::elaborate_expr_constructor_(Design*des, NetScope*scope,
|
|||
|
||||
|
||||
NetFuncDef*def = new_scope->func_def();
|
||||
if (def == 0) {
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "Scope " << scope_path(new_scope)
|
||||
<< " is missing constructor definition." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
ivl_assert(*this, def);
|
||||
|
||||
// Are there too many arguments passed to the function. If so,
|
||||
|
|
|
|||
|
|
@ -442,21 +442,15 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
|
|||
for (map<perm_string, class_type_t::prop_info_t>::iterator cur = use_type->properties.begin()
|
||||
; cur != use_type->properties.end() ; ++ cur) {
|
||||
|
||||
if (scope) {
|
||||
ivl_type_s*tmp = cur->second.type->elaborate_type(des, scope);
|
||||
ivl_assert(*pclass, tmp);
|
||||
if (debug_scopes) {
|
||||
cerr << pclass->get_fileline() << ": elaborate_scope_class: "
|
||||
<< " Property " << cur->first
|
||||
<< " type=" << *tmp << endl;
|
||||
}
|
||||
use_class->set_property(cur->first, cur->second.qual, tmp);
|
||||
} else {
|
||||
cerr << pclass->get_fileline() << ": sorry: Don't know how to elaborate "
|
||||
<< "property " << cur->first
|
||||
<< " for class type in $root scope," << endl;
|
||||
des->errors += 1;
|
||||
ivl_type_s*tmp = cur->second.type->elaborate_type(des, scope);
|
||||
ivl_assert(*pclass, tmp);
|
||||
if (debug_scopes) {
|
||||
cerr << pclass->get_fileline() << ": elaborate_scope_class: "
|
||||
<< " Property " << cur->first
|
||||
<< " type=" << *tmp << endl;
|
||||
}
|
||||
use_class->set_property(cur->first, cur->second.qual, tmp);
|
||||
|
||||
}
|
||||
|
||||
for (map<perm_string,PTask*>::iterator cur = pclass->tasks.begin()
|
||||
|
|
@ -499,9 +493,7 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
|
|||
scope->add_class(use_class);
|
||||
|
||||
} else {
|
||||
cerr << pclass->get_fileline() << ": sorry: "
|
||||
<< "Don't know how to elaborate class in $root scope." << endl;
|
||||
des->errors += 1;
|
||||
des->add_class(use_class, pclass);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
18
elab_sig.cc
18
elab_sig.cc
|
|
@ -836,10 +836,13 @@ void PWhile::elaborate_sig(Design*des, NetScope*scope) const
|
|||
statement_->elaborate_sig(des, scope);
|
||||
}
|
||||
|
||||
static netclass_t* locate_class_type(Design*, NetScope*scope,
|
||||
static netclass_t* locate_class_type(Design*des, NetScope*scope,
|
||||
class_type_t*class_type)
|
||||
{
|
||||
netclass_t*use_class = scope->find_class(class_type->name);
|
||||
if (use_class) return use_class;
|
||||
|
||||
use_class = des->find_class(class_type->name);
|
||||
return use_class;
|
||||
}
|
||||
|
||||
|
|
@ -1301,3 +1304,16 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
|||
|
||||
return sig;
|
||||
}
|
||||
|
||||
|
||||
void Design::root_elaborate_sig(void)
|
||||
{
|
||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
||||
; cur != classes_.end() ; ++ cur) {
|
||||
|
||||
netclass_t*cur_class = cur->second;
|
||||
PClass*cur_pclass = class_to_pclass_[cur_class];
|
||||
|
||||
cur_class->elaborate_sig(this, cur_pclass);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
22
elab_type.cc
22
elab_type.cc
|
|
@ -38,8 +38,12 @@ using namespace std;
|
|||
*/
|
||||
ivl_type_s* data_type_t::elaborate_type(Design*des, NetScope*scope)
|
||||
{
|
||||
map<NetScope*,ivl_type_s*>::iterator pos = cache_type_elaborate_.lower_bound(scope);
|
||||
if (pos->first == scope)
|
||||
Definitions*use_definitions = scope;
|
||||
if (use_definitions == 0)
|
||||
use_definitions = des;
|
||||
|
||||
map<Definitions*,ivl_type_s*>::iterator pos = cache_type_elaborate_.lower_bound(use_definitions);
|
||||
if (pos->first == use_definitions)
|
||||
return pos->second;
|
||||
|
||||
ivl_type_s*tmp = elaborate_type_raw(des, scope);
|
||||
|
|
@ -91,9 +95,13 @@ ivl_type_s* atom2_type_t::elaborate_type_raw(Design*des, NetScope*) const
|
|||
}
|
||||
}
|
||||
|
||||
ivl_type_s* class_type_t::elaborate_type_raw(Design*, NetScope*scope) const
|
||||
ivl_type_s* class_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
|
||||
{
|
||||
return scope->find_class(name);
|
||||
ivl_type_s* found_class = scope->find_class(name);
|
||||
if (found_class == 0)
|
||||
found_class = des->find_class(name);
|
||||
|
||||
return found_class;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -219,6 +227,12 @@ ivl_type_s* uarray_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
|
|||
vector<netrange_t> dimensions;
|
||||
bool bad_range = evaluate_ranges(des, scope, dimensions, *dims);
|
||||
|
||||
if (bad_range) {
|
||||
cerr << get_fileline() << " : warning: "
|
||||
<< "Bad dimensions for type here." << endl;
|
||||
}
|
||||
|
||||
ivl_assert(*this, btype);
|
||||
ivl_type_s*res = new netuarray_t(dimensions, btype);
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
35
elaborate.cc
35
elaborate.cc
|
|
@ -2543,6 +2543,7 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
|
|||
ivl_assert(*this, lv->word());
|
||||
use_lv_type = utype->element_type();
|
||||
|
||||
ivl_assert(*this, use_lv_type);
|
||||
rv = elaborate_rval_(des, scope, use_lv_type);
|
||||
|
||||
} else {
|
||||
|
|
@ -5962,6 +5963,16 @@ bool Design::check_proc_delay() const
|
|||
return result_flag;
|
||||
}
|
||||
|
||||
void Design::root_elaborate(void)
|
||||
{
|
||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
||||
; cur != classes_.end() ; ++ cur) {
|
||||
netclass_t*cur_class = cur->second;
|
||||
PClass*cur_pclass = class_to_pclass_[cur_class];
|
||||
cur_class->elaborate(this, cur_pclass);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is the root of all elaboration. The input is the list
|
||||
* of root module names. The function locates the Module definitions
|
||||
|
|
@ -6093,6 +6104,11 @@ Design* elaborate(list<perm_string>roots)
|
|||
}
|
||||
}
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << "<toplevel>: elaborate: "
|
||||
<< "elaboration work list done. Start processing residual defparams." << endl;
|
||||
}
|
||||
|
||||
// Look for residual defparams (that point to a non-existent
|
||||
// scope) and clean them out.
|
||||
des->residual_defparams();
|
||||
|
|
@ -6102,6 +6118,11 @@ Design* elaborate(list<perm_string>roots)
|
|||
if (des->errors > 0)
|
||||
return des;
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << "<toplevel>: elaborate: "
|
||||
<< "Start calling Package elaborate_sig methods." << endl;
|
||||
}
|
||||
|
||||
// With the parameters evaluated down to constants, we have
|
||||
// what we need to elaborate signals and memories. This pass
|
||||
// creates all the NetNet and NetMemory objects for declared
|
||||
|
|
@ -6120,6 +6141,18 @@ Design* elaborate(list<perm_string>roots)
|
|||
}
|
||||
}
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << "<toplevel>: elaborate: "
|
||||
<< "Start calling $root elaborate_sig methods." << endl;
|
||||
}
|
||||
|
||||
des->root_elaborate_sig();
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << "<toplevel>: elaborate: "
|
||||
<< "Start calling root module elaborate_sig methods." << endl;
|
||||
}
|
||||
|
||||
for (i = 0; i < root_elems.size(); i++) {
|
||||
Module *rmod = root_elems[i].mod;
|
||||
NetScope *scope = root_elems[i].scope;
|
||||
|
|
@ -6176,6 +6209,8 @@ Design* elaborate(list<perm_string>roots)
|
|||
rc &= pkg->elaborate(des, scope);
|
||||
}
|
||||
|
||||
des->root_elaborate();
|
||||
|
||||
for (i = 0; i < root_elems.size(); i++) {
|
||||
Module *rmod = root_elems[i].mod;
|
||||
NetScope *scope = root_elems[i].scope;
|
||||
|
|
|
|||
8
emit.cc
8
emit.cc
|
|
@ -510,6 +510,14 @@ int Design::emit(struct target_t*tgt) const
|
|||
scope->second->emit_scope(tgt);
|
||||
}
|
||||
|
||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
||||
; cur != classes_.end() ; ++cur) {
|
||||
const NetScope*use_scope = cur->second->class_scope();
|
||||
cur->second->emit_scope(tgt);
|
||||
tgt->class_type(use_scope, cur->second);
|
||||
cur->second->emit_defs(tgt);
|
||||
}
|
||||
|
||||
// enumerate root scopes
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin()
|
||||
; scope != root_scopes_.end(); ++ scope ) {
|
||||
|
|
|
|||
|
|
@ -134,6 +134,21 @@ NetScope* Design::make_package_scope(perm_string name)
|
|||
return scope;
|
||||
}
|
||||
|
||||
void Design::add_class(netclass_t*cl, PClass*pclass)
|
||||
{
|
||||
Definitions::add_class(cl);
|
||||
class_to_pclass_[cl] = pclass;
|
||||
}
|
||||
|
||||
netclass_t* Design::find_class(perm_string name) const
|
||||
{
|
||||
map<perm_string,netclass_t*>::const_iterator cur = classes_.find(name);
|
||||
if (cur != classes_.end())
|
||||
return cur->second;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetScope* Design::find_package(perm_string name) const
|
||||
{
|
||||
map<perm_string,NetScope*>::const_iterator cur = packages_.find(name);
|
||||
|
|
|
|||
12
net_scope.cc
12
net_scope.cc
|
|
@ -96,6 +96,11 @@ const NetExpr* Definitions::enumeration_expr(perm_string key)
|
|||
}
|
||||
}
|
||||
|
||||
void Definitions::add_class(netclass_t*net_class)
|
||||
{
|
||||
classes_[net_class->get_name()] = net_class;
|
||||
}
|
||||
|
||||
/*
|
||||
* The NetScope class keeps a scope tree organized. Each node of the
|
||||
* scope tree points to its parent, its right sibling and its leftmost
|
||||
|
|
@ -632,14 +637,9 @@ NetNet* NetScope::find_signal(perm_string key)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void NetScope::add_class(netclass_t*net_class)
|
||||
{
|
||||
classes_[net_class->get_name()] = net_class;
|
||||
}
|
||||
|
||||
netclass_t*NetScope::find_class(perm_string name)
|
||||
{
|
||||
// Special class: The scope itself is the class that we are
|
||||
// Special case: The scope itself is the class that we are
|
||||
// looking for. This may happen for example when elaborating
|
||||
// methods within the class.
|
||||
if (type_==CLASS && name_==hname_t(name))
|
||||
|
|
|
|||
|
|
@ -56,10 +56,10 @@ void netclass_t::set_class_scope(NetScope*class_scope)
|
|||
class_scope_ = class_scope;
|
||||
}
|
||||
|
||||
void netclass_t::set_definition_scope(NetScope*definition_scope)
|
||||
void netclass_t::set_definition_scope(NetScope*use_definition_scope)
|
||||
{
|
||||
assert(definition_scope_ == 0);
|
||||
definition_scope_ = definition_scope;
|
||||
definition_scope_ = use_definition_scope;
|
||||
}
|
||||
|
||||
ivl_variable_type_t netclass_t::base_type() const
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ class netclass_t : public ivl_type_s {
|
|||
// (tasks/functions). In other words, this is the class itself.
|
||||
void set_class_scope(NetScope*cscope);
|
||||
|
||||
inline const NetScope* class_scope(void) const { return class_scope_; }
|
||||
|
||||
// Set the scope for the class definition. This is the scope
|
||||
// where the class definition was encountered, and may be used
|
||||
// to locate symbols that the class definition may inherit
|
||||
|
|
|
|||
21
netlist.h
21
netlist.h
|
|
@ -74,6 +74,7 @@ class NetRamDq;
|
|||
class NetTaskDef;
|
||||
class NetEvTrig;
|
||||
class NetEvWait;
|
||||
class PClass;
|
||||
class PExpr;
|
||||
class PFunction;
|
||||
struct enum_type_t;
|
||||
|
|
@ -888,6 +889,9 @@ class Definitions {
|
|||
// value.
|
||||
const NetExpr* enumeration_expr(perm_string key);
|
||||
|
||||
// Definitions scopes can also hold classes, by name.
|
||||
void add_class(netclass_t*class_type);
|
||||
|
||||
protected:
|
||||
// Enumerations. The enum_sets_ is a list of all the
|
||||
// enumerations present in this scope. The enum_names_ is a
|
||||
|
|
@ -896,6 +900,8 @@ class Definitions {
|
|||
std::map<const enum_type_t*,netenum_t*> enum_sets_;
|
||||
std::map<perm_string,NetEConstEnum*> enum_names_;
|
||||
|
||||
std::map<perm_string,netclass_t*> classes_;
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -980,7 +986,6 @@ class NetScope : public Definitions, public Attrib {
|
|||
void rem_signal(NetNet*);
|
||||
NetNet* find_signal(perm_string name);
|
||||
|
||||
void add_class(netclass_t*class_type);
|
||||
netclass_t* find_class(perm_string name);
|
||||
|
||||
/* The parent and child() methods allow users of NetScope
|
||||
|
|
@ -1239,8 +1244,6 @@ class NetScope : public Definitions, public Attrib {
|
|||
const PFunction*func_pform_;
|
||||
unsigned elab_stage_;
|
||||
|
||||
std::map<perm_string,netclass_t*> classes_;
|
||||
|
||||
NetScope*up_;
|
||||
map<hname_t,NetScope*> children_;
|
||||
|
||||
|
|
@ -4790,6 +4793,11 @@ class Design : public Definitions {
|
|||
// Look for defparams that never matched, and print warnings.
|
||||
void residual_defparams();
|
||||
|
||||
// Do elaborate_sig for objects in $root scope.
|
||||
void root_elaborate_sig(void);
|
||||
|
||||
void root_elaborate(void);
|
||||
|
||||
/* This method locates a signal, starting at a given
|
||||
scope. The name parameter may be partially hierarchical, so
|
||||
this method, unlike the NetScope::find_signal method,
|
||||
|
|
@ -4803,6 +4811,10 @@ class Design : public Definitions {
|
|||
// Tasks
|
||||
NetScope* find_task(NetScope*scope, const pform_name_t&name);
|
||||
|
||||
// Find a class in the $root scope.
|
||||
void add_class(netclass_t*cl, PClass*pclass);
|
||||
netclass_t* find_class(perm_string name) const;
|
||||
|
||||
// NODES
|
||||
void add_node(NetNode*);
|
||||
void del_node(NetNode*);
|
||||
|
|
@ -4837,6 +4849,9 @@ class Design : public Definitions {
|
|||
// packages do not nest.
|
||||
std::map<perm_string,NetScope*>packages_;
|
||||
|
||||
// Need this for elaboration of $root scope pclass objects.
|
||||
std::map<netclass_t*,PClass*> class_to_pclass_;
|
||||
|
||||
// List the nodes in the design.
|
||||
NetNode*nodes_;
|
||||
// These are in support of the node functor iterator.
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
class Design;
|
||||
class NetScope;
|
||||
class Definitions;
|
||||
class PExpr;
|
||||
class PWire;
|
||||
class Statement;
|
||||
|
|
@ -133,7 +134,7 @@ class data_type_t : public LineInfo {
|
|||
virtual ivl_type_s* elaborate_type_raw(Design*des, NetScope*scope) const;
|
||||
|
||||
// Keep per-scope elaboration results cached.
|
||||
std::map<NetScope*,ivl_type_s*> cache_type_elaborate_;
|
||||
std::map<Definitions*,ivl_type_s*> cache_type_elaborate_;
|
||||
};
|
||||
|
||||
struct void_type_t : public data_type_t {
|
||||
|
|
|
|||
|
|
@ -102,6 +102,8 @@ bool dll_target::func_def(const NetScope*net)
|
|||
ivl_scope_t scop = lookup_scope_(net);
|
||||
const NetFuncDef*def = net->func_def();
|
||||
|
||||
assert(def);
|
||||
assert(def->proc());
|
||||
assert(stmt_cur_ == 0);
|
||||
stmt_cur_ = (struct ivl_statement_s*)calloc(1, sizeof*stmt_cur_);
|
||||
def->proc()->emit_proc(this);
|
||||
|
|
|
|||
5
t-dll.cc
5
t-dll.cc
|
|
@ -2411,6 +2411,11 @@ void dll_target::scope(const NetScope*net)
|
|||
{
|
||||
if (net->parent()==0 && net->type()==NetScope::CLASS) {
|
||||
|
||||
if (debug_emit) {
|
||||
cerr << "dll_target::scope: "
|
||||
<< "Add class " << scope_path(net)
|
||||
<< " as a root scope." << endl;
|
||||
}
|
||||
add_root(net);
|
||||
|
||||
} if (net->parent() == 0) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue