diff --git a/elab_scope.cc b/elab_scope.cc index 5c3db1c34..e611a9073 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -416,6 +416,7 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass) netclass_t*use_base_class = 0; if (base_class) { + ivl_assert(*pclass, scope); use_base_class = scope->find_class(base_class->name); if (use_base_class == 0) { cerr << pclass->get_fileline() << ": error: " @@ -440,14 +441,22 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass) // elaborated class definition. for (map::iterator cur = use_type->properties.begin() ; cur != use_type->properties.end() ; ++ cur) { - 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; + + 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; } - use_class->set_property(cur->first, cur->second.qual, tmp); } for (map::iterator cur = pclass->tasks.begin() @@ -486,7 +495,14 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass) cur->second->elaborate_scope(des, method_scope); } - scope->add_class(use_class); + if (scope) { + 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; + } } static void elaborate_scope_classes(Design*des, NetScope*scope, @@ -498,6 +514,18 @@ static void elaborate_scope_classes(Design*des, NetScope*scope, } } +void elaborate_rootscope_classes(Design*des) +{ + if (pform_classes.empty()) + return; + + for (map::iterator cur = pform_classes.begin() + ; cur != pform_classes.end() ; ++ cur) { + blend_class_constructors(cur->second); + elaborate_scope_class(des, 0, cur->second); + } +} + static void replace_scope_parameters_(NetScope*scope, const LineInfo&loc, const Module::replace_t&replacements) { diff --git a/elaborate.cc b/elaborate.cc index ec5f0544e..c63566d47 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -5993,6 +5993,9 @@ Design* elaborate(listroots) // Elaborate enum sets in $root scope. elaborate_rootscope_enumerations(des); + // Elaborate classes in $root scope. + elaborate_rootscope_classes(des); + // Elaborate the packages. Package elaboration is simpler // because there are fewer sub-scopes involved. i = 0; diff --git a/parse_api.h b/parse_api.h index e58b0963e..d80948c2f 100644 --- a/parse_api.h +++ b/parse_api.h @@ -28,6 +28,7 @@ class Design; class Module; +class PClass; class PPackage; class PUdp; class data_type_t; @@ -42,11 +43,13 @@ extern std::map pform_modules; extern std::map pform_primitives; extern std::map pform_typedefs; extern std::set pform_enum_sets; - +extern std::map pform_classes; extern std::map pform_packages; + extern void pform_dump(std::ostream&out, const PPackage*pac); extern void elaborate_rootscope_enumerations(Design*des); +extern void elaborate_rootscope_classes(Design*des); /* * This code actually invokes the parser to make modules. The first diff --git a/pform.cc b/pform.cc index f637f9b06..da7bc964f 100644 --- a/pform.cc +++ b/pform.cc @@ -66,6 +66,11 @@ map pform_primitives; mappform_typedefs; setpform_enum_sets; +/* + * Class definitions in the $root scope go here. + */ +map pform_classes; + std::string vlltype::get_fileline() const { ostringstream buf; @@ -331,10 +336,7 @@ PClass* pform_push_class_scope(const struct vlltype&loc, perm_string name) /* If no scope was found then this is being defined in the * compilation unit scope. */ if (scopex == 0) { - cerr << class_scope->get_fileline() << ": sorry: class " - "declarations in the compilation unit scope are not yet " - "supported." << endl; - error_count += 1; + pform_classes[name] = class_scope; lexical_scope = class_scope; return class_scope; }