Add support for classes defined in $root scope.

This commit is contained in:
Stephen Williams 2014-09-15 17:33:56 -07:00
parent fa21527e9f
commit 480668fee6
15 changed files with 153 additions and 34 deletions

View File

@ -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 ) {

View File

@ -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,

View File

@ -442,7 +442,6 @@ 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) {
@ -451,12 +450,7 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
<< " 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;
}
}
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);
}
}

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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 ) {

View File

@ -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);

View File

@ -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))

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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 {

View File

@ -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);

View File

@ -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) {