diff --git a/elab_scope.cc b/elab_scope.cc index b5890bb2f9..9063579920 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -428,6 +428,9 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass) netclass_t*use_class = new netclass_t(use_type->name, use_base_class); + ivl_assert(*pclass, use_type->save_elaborated_type == 0); + use_type->save_elaborated_type = use_class; + // Class scopes have no parent scope, because references are // not allowed to escape a class method. NetScope*class_scope = new NetScope(0, hname_t(pclass->pscope_name()), @@ -747,13 +750,14 @@ class generate_schemes_work_item_t : public elaborator_work_item_t { bool PPackage::elaborate_scope(Design*des, NetScope*scope) { if (debug_scopes) { - cerr << get_fileline() << ": debug: Elaborate package scope " - << scope_path(scope) << "." << endl; + cerr << get_fileline() << ": PPackage::elaborate_scope: " + << "Elaborate package " << scope_path(scope) << "." << endl; } collect_scope_parameters_(des, scope, parameters); collect_scope_localparams_(des, scope, localparams); elaborate_scope_enumerations(des, scope, enum_sets); + elaborate_scope_classes(des, scope, classes_lexical); elaborate_scope_funcs(des, scope, funcs); elaborate_scope_tasks(des, scope, tasks); return true; @@ -763,8 +767,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope, const replace_t&replacements) { if (debug_scopes) { - cerr << get_fileline() << ": debug: Elaborate scope " - << scope_path(scope) << "." << endl; + cerr << get_fileline() << ": Module::elaborate_scope: " + << "Elaborate " << scope_path(scope) << "." << endl; } // Add the genvars to the scope. diff --git a/elab_sig.cc b/elab_sig.cc index d12561c5eb..87c5c9b809 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -207,6 +207,11 @@ bool PPackage::elaborate_sig(Design*des, NetScope*scope) const { bool flag = true; + if (debug_elaborate) { + cerr << get_fileline() << ": PPackage::elaborate_sig: " + << "Start package scope=" << scope_path(scope) << endl; + } + flag = elaborate_sig_wires_(des, scope) && flag; // After all the wires are elaborated, we are free to @@ -215,6 +220,13 @@ bool PPackage::elaborate_sig(Design*des, NetScope*scope) const elaborate_sig_funcs(des, scope, funcs); elaborate_sig_tasks(des, scope, tasks); + elaborate_sig_classes(des, scope, classes); + + if (debug_elaborate) { + cerr << get_fileline() << ": PPackage::elaborate_sig: " + << "Done package scope=" << scope_path(scope) + << ", flag=" << flag << endl; + } return flag; } @@ -836,16 +848,6 @@ void PWhile::elaborate_sig(Design*des, NetScope*scope) const statement_->elaborate_sig(des, 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; -} - static ivl_type_s*elaborate_type(Design*des, NetScope*scope, data_type_t*pform_type) { @@ -1174,19 +1176,9 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const // should already have been elaborated. All we need to // do right now is locate the netclass_t object for the // class, and use that to build the net. - netclass_t*use_type = locate_class_type(des, scope, class_type); - if (use_type == 0) { - cerr << get_fileline() << ": internal error: " - << "Class " << class_type->name - << " isn't elaborated in scope=" << scope_path(scope) << endl; - des->errors += 1; - } - ivl_assert(*this, use_type); - if (debug_elaborate) { - cerr << get_fileline() << ": PWire::elaborate_sig: " - << "Create class instance signal " << wtype - << " " << packed_dimensions << name_ << unpacked_dimensions << endl; - } + + ivl_assert(*this, class_type->save_elaborated_type); + netclass_t*use_type = class_type->save_elaborated_type; sig = new NetNet(scope, name_, wtype, unpacked_dimensions, use_type); diff --git a/elab_type.cc b/elab_type.cc index 41c3c68cab..09e0c86daa 100644 --- a/elab_type.cc +++ b/elab_type.cc @@ -95,13 +95,10 @@ ivl_type_s* atom2_type_t::elaborate_type_raw(Design*des, NetScope*) const } } -ivl_type_s* class_type_t::elaborate_type_raw(Design*des, NetScope*scope) const +ivl_type_s* class_type_t::elaborate_type_raw(Design*, NetScope*) const { - ivl_type_s* found_class = scope->find_class(name); - if (found_class == 0) - found_class = des->find_class(name); - - return found_class; + ivl_assert(*this, save_elaborated_type); + return save_elaborated_type; } /* diff --git a/elaborate.cc b/elaborate.cc index 50ecd8bc2c..3095394b6e 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -5554,6 +5554,9 @@ bool PPackage::elaborate(Design*des, NetScope*scope) const // Elaborate task methods. elaborate_tasks(des, scope, tasks); + // Elaborate class definitions. + elaborate_classes(des, scope, classes); + return result_flag; } @@ -6046,6 +6049,7 @@ Design* elaborate(listroots) for (map::iterator pac = pform_packages.begin() ; pac != pform_packages.end() ; ++ pac) { + ivl_assert(*pac->second, pac->first == pac->second->pscope_name()); NetScope*scope = des->make_package_scope(pac->first); scope->set_line(pac->second); diff --git a/netlist.h b/netlist.h index d3700a80ae..d50213f444 100644 --- a/netlist.h +++ b/netlist.h @@ -901,6 +901,7 @@ class Definitions { std::map enum_sets_; std::map enum_names_; + // This is a map of all the classes (by name) in this scope. std::map classes_; }; diff --git a/pform_types.h b/pform_types.h index 833dbb7f5e..b36bb01e19 100644 --- a/pform_types.h +++ b/pform_types.h @@ -44,6 +44,7 @@ class PExpr; class PWire; class Statement; class ivl_type_s; +class netclass_t; class netenum_t; typedef named named_number_t; typedef named named_pexpr_t; @@ -273,7 +274,7 @@ struct string_type_t : public data_type_t { struct class_type_t : public data_type_t { inline explicit class_type_t(perm_string n) - : name(n), base_type(0) { } + : name(n), base_type(0), save_elaborated_type(0) { } void pform_dump(std::ostream&out, unsigned indent) const; void pform_dump_init(std::ostream&out, unsigned indent) const; @@ -308,6 +309,11 @@ struct class_type_t : public data_type_t { std::vector initialize_static; ivl_type_s* elaborate_type_raw(Design*, NetScope*) const; + // The save_elaborated_type member must be set to the pointer + // to the netclass_t object that is created to represent this + // type. The elaborate_type_raw() method uses this pointer, + // and it is used in some other situations as well. + netclass_t* save_elaborated_type; }; /* diff --git a/t-dll-proc.cc b/t-dll-proc.cc index e4a5851039..e668919ebc 100644 --- a/t-dll-proc.cc +++ b/t-dll-proc.cc @@ -80,6 +80,8 @@ void dll_target::task_def(const NetScope*net) ivl_scope_t scop = lookup_scope_(net); const NetTaskDef*def = net->task_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);