diff --git a/parse.y b/parse.y index 32e4d15bb..d5c352583 100644 --- a/parse.y +++ b/parse.y @@ -1081,7 +1081,7 @@ description /* IEEE1800-2005: A.1.2 */ | nature_declaration | package_declaration | discipline_declaration - | timeunits_declaration + | package_item | KK_attribute '(' IDENTIFIER ',' STRING ',' STRING ')' { perm_string tmp3 = lex_strings.make($3); pform_set_type_attrib(tmp3, $5, $7); @@ -2362,6 +2362,11 @@ struct_union_member /* IEEE 1800-2012 A.2.2.1 */ tmp->names .reset($3); $$ = tmp; } + | error ';' + { yyerror(@2, "Error in struct/union member."); + yyerrok; + $$ = 0; + } ; case_item diff --git a/parse_api.h b/parse_api.h index e3526f348..e334c0443 100644 --- a/parse_api.h +++ b/parse_api.h @@ -28,6 +28,7 @@ class Module; class PPackage; class PUdp; +class data_type_t; /* * These are maps of the modules and primitives parsed from the @@ -36,6 +37,7 @@ class PUdp; */ extern std::map pform_modules; extern std::map pform_primitives; +extern std::map pform_typedefs; extern std::map pform_packages; extern void pform_dump(std::ostream&out, const PPackage*pac); diff --git a/pform.cc b/pform.cc index 4d2a03737..e67417ec5 100644 --- a/pform.cc +++ b/pform.cc @@ -46,12 +46,15 @@ /* * The pform_modules is a map of the modules that have been defined in * the top level. This should not contain nested modules/programs. + * pform_primitives is similar, but for UDP primitives. */ map pform_modules; -/* - */ map pform_primitives; +/* + * typedefs in the $root scope go here. + */ +mappform_typedefs; std::string vlltype::get_fileline() const { @@ -505,7 +508,13 @@ PWire*pform_get_make_wire_in_scope(perm_string name, NetNet::Type net_type, NetN void pform_set_typedef(perm_string name, data_type_t*data_type) { - data_type_t*&ref = lexical_scope->typedefs[name]; + // If we are in a lexical scope (i.e. a package or module) + // then put the typedef into that scope. Otherwise, put it + // into the $root scope. + data_type_t*&ref = lexical_scope + ? lexical_scope->typedefs[name] + : pform_typedefs[name]; + ivl_assert(*data_type, ref == 0); ref = data_type; @@ -514,15 +523,25 @@ void pform_set_typedef(perm_string name, data_type_t*data_type) } } +static data_type_t* test_type_identifier_in_root(perm_string name) +{ + map::iterator cur = pform_typedefs.find(name); + if (cur != pform_typedefs.end()) + return cur->second; + else + return 0; +} + data_type_t* pform_test_type_identifier(const char*txt) { - // If there is no lexical_scope yet, then there is NO WAY the - // identifier can be a type_identifier. - if (lexical_scope == 0) - return 0; - perm_string name = lex_strings.make(txt); + // If there is no lexical_scope yet, then look only in the + // $root scope for typedefs. + if (lexical_scope == 0) { + return test_type_identifier_in_root(name); + } + LexicalScope*cur_scope = lexical_scope; do { map::iterator cur; @@ -552,6 +571,10 @@ data_type_t* pform_test_type_identifier(const char*txt) cur_scope = cur_scope->parent_scope(); } while (cur_scope); + // See if there is a typedef in the $root scope. + if (data_type_t*tmp = test_type_identifier_in_root(name)) + return tmp; + return 0; } diff --git a/pform_dump.cc b/pform_dump.cc index fb2882123..b5ab2b348 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -170,7 +170,10 @@ void uarray_type_t::pform_dump(ostream&out, unsigned indent) const void struct_type_t::pform_dump(ostream&out, unsigned indent) const { out << setw(indent) << "" << "Struct " << (packed_flag?"packed":"unpacked") - << " with " << members->size() << " members" << endl; + << " with " << (members.get()==0? 0 : members->size()) << " members" << endl; + if (members.get()==0) + return; + for (list::iterator cur = members->begin() ; cur != members->end() ; ++ cur) { struct_member_t*curp = *cur; diff --git a/pform_struct_type.cc b/pform_struct_type.cc index 60219524b..4a4d91251 100644 --- a/pform_struct_type.cc +++ b/pform_struct_type.cc @@ -26,8 +26,12 @@ ivl_variable_type_t struct_type_t::figure_packed_base_type(void) const if (! packed_flag) return IVL_VT_NO_TYPE; + if (members.get() == 0) + return IVL_VT_NO_TYPE; + ivl_variable_type_t base_type = IVL_VT_BOOL; + ivl_assert(*this, members.get()); for (list::iterator cur = members->begin() ; cur != members->end() ; ++ cur) {