diff --git a/elab_scope.cc b/elab_scope.cc index fe39506e9..9d156ba52 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -489,29 +489,30 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass) << endl; } - class_type_t*base_class = dynamic_cast (use_type->base_type); - if (use_type->base_type && !base_class) { - cerr << pclass->get_fileline() << ": error: " - << "Base type of " << use_type->name - << " is not a class." << endl; - des->errors += 1; - } - netclass_t*use_base_class = 0; - if (base_class) { - use_base_class = base_class->save_elaborated_type; - if (use_base_class == 0) { + const netclass_t*use_base_class = 0; + if (use_type->base_type) { + ivl_type_t base_type = use_type->base_type->elaborate_type(des, scope); + use_base_class = dynamic_cast(base_type); + if (!use_base_class) { cerr << pclass->get_fileline() << ": error: " - << "Base class " << base_class->name - << " not found." << endl; + << "Base type of " << use_type->name + << " is not a class." << endl; des->errors += 1; } } 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; + // If this is a package we need to remember the elaborated type so that + // scoped type references work. Since there is only one instance for each + // package this works. For classes defined in modules there might be + // multiple instances though. Each module instance will have its own class + // type instance, so the same does not work there. + if (scope->type() == NetScope::PACKAGE) { + ivl_assert(*pclass, use_type->save_elaborated_type == 0); + use_type->save_elaborated_type = use_class; + } NetScope*class_scope = new NetScope(scope, hname_t(pclass->pscope_name()), NetScope::CLASS, scope->unit()); diff --git a/elab_type.cc b/elab_type.cc index 948836856..ecd81e098 100644 --- a/elab_type.cc +++ b/elab_type.cc @@ -101,10 +101,11 @@ ivl_type_t atom2_type_t::elaborate_type_raw(Design*des, NetScope*) const } } -ivl_type_t class_type_t::elaborate_type_raw(Design*, NetScope*) const +ivl_type_t class_type_t::elaborate_type_raw(Design*des, NetScope*scope) const { - ivl_assert(*this, save_elaborated_type); - return save_elaborated_type; + if (save_elaborated_type) + return save_elaborated_type; + return scope->find_class(des, name); } /*