From 50d71c8512a5420f18e0e51ced6f428dd15e9bc2 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sun, 29 Sep 2019 18:27:27 -0700 Subject: [PATCH] Support for enumerations in classes. --- elab_scope.cc | 32 ++++++++++++++++++++++++++++++-- parse.y | 13 +++++++++++-- pform_pclass.cc | 4 ++++ 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/elab_scope.cc b/elab_scope.cc index cfbc2a50d..5799c924a 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -480,7 +480,9 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass) if (debug_scopes) { cerr << pclass->get_fileline() <<": elaborate_scope_class: " - << "Elaborate scope class " << pclass->pscope_name() << endl; + << "Elaborate scope class " << pclass->pscope_name() + << " within scope " << scope_path(scope) + << endl; } class_type_t*base_class = dynamic_cast (use_type->base_type); @@ -518,12 +520,24 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass) use_class->set_definition_scope(scope); set_scope_timescale(des, class_scope, pclass); + // Elaborate enum types declared in the class. We need these + // now because enumeration constants can be used during scope + // elaboration. + if (debug_scopes) { + cerr << pclass->get_fileline() << ": elaborate_scope_class: " + << "Elaborate " << pclass->enum_sets.size() << " enumerations" + << " in class " << scope_path(class_scope) + << ", scope=" << scope_path(scope) << "." + << endl; + } + elaborate_scope_enumerations(des, class_scope, pclass->enum_sets); + // Collect the properties, elaborate them, and add them to the // 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_type_s*tmp = cur->second.type->elaborate_type(des, class_scope); ivl_assert(*pclass, tmp); if (debug_scopes) { cerr << pclass->get_fileline() << ": elaborate_scope_class: " @@ -789,7 +803,15 @@ bool PPackage::elaborate_scope(Design*des, NetScope*scope) collect_scope_parameters_(des, scope, parameters); collect_scope_localparams_(des, scope, localparams); + + if (debug_scopes) { + cerr << get_fileline() << ": PPackage::elaborate_scope: " + << "Elaborate " << enum_sets.size() << " enumerations" + << " in package scope " << scope_path(scope) << "." + << endl; + } 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); @@ -826,6 +848,12 @@ bool Module::elaborate_scope(Design*des, NetScope*scope, replace_scope_parameters_(scope, *this, replacements); + if (debug_scopes) { + cerr << get_fileline() << ": Module::elaborate_scope: " + << "Elaborate " << enum_sets.size() << " enumerations" + << " in scope " << scope_path(scope) << "." + << endl; + } elaborate_scope_enumerations(des, scope, enum_sets); assert(classes.size() == classes_lexical.size()); diff --git a/parse.y b/parse.y index ce8e18b3b..0f8474cad 100644 --- a/parse.y +++ b/parse.y @@ -864,7 +864,7 @@ class_item /* IEEE1800-2005: A.1.8 */ current_function = 0; } - /* Class properties... */ + /* IEEE1800-2017: A.1.9 Class items: Class properties... */ | property_qualifier_opt data_type list_of_variable_decl_assignments ';' { pform_class_property(@2, $1, $2, $3); } @@ -872,7 +872,16 @@ class_item /* IEEE1800-2005: A.1.8 */ | K_const class_item_qualifier_opt data_type list_of_variable_decl_assignments ';' { pform_class_property(@1, $2 | property_qualifier_t::make_const(), $3, $4); } - /* Class methods... */ + /* IEEEE1800-2017: A.1.9 Class items: class_item ::= { property_qualifier} data_declaration */ + + | property_qualifier_opt K_typedef data_type IDENTIFIER dimensions_opt ';' + { perm_string name = lex_strings.make($4); + delete[]$4; + yyerror(@2, "sorry: Class-local typedefs not yet supported."); + delete $3; + } + + /* IEEE1800-1017: A.1.9 Class items: Class methods... */ | method_qualifier_opt task_declaration { /* The task_declaration rule puts this into the class */ } diff --git a/pform_pclass.cc b/pform_pclass.cc index a3b7df4f0..c294f6000 100644 --- a/pform_pclass.cc +++ b/pform_pclass.cc @@ -67,6 +67,10 @@ void pform_class_property(const struct vlltype&loc, { assert(pform_cur_class); + if (enum_type_t*enum_set = dynamic_cast(data_type)) { + pform_cur_class->enum_sets .insert(enum_set); + } + // Add the non-static properties to the class type // object. Unwind the list of names to make a map of name to // type.