diff --git a/PScope.h b/PScope.h index a6c11466c..d2b0feb53 100644 --- a/PScope.h +++ b/PScope.h @@ -83,6 +83,9 @@ class LexicalScope { mapparameters; maplocalparams; + // Defined types in the scope. + maptypedefs; + // Named events in the scope. mapevents; @@ -105,6 +108,8 @@ class LexicalScope { LexicalScope* parent_scope() const { return parent_; } protected: + void dump_typedefs_(ostream&out, unsigned indent) const; + void dump_parameters_(ostream&out, unsigned indent) const; void dump_localparams_(ostream&out, unsigned indent) const; diff --git a/lexor.lex b/lexor.lex index a197990fb..a6a683607 100644 --- a/lexor.lex +++ b/lexor.lex @@ -308,6 +308,13 @@ TU [munpf] } } + /* If this identifer names a previously declared type, then + return this as a TYPE_IDENTIFIER instead. */ + if (rc == IDENTIFIER && gn_system_verilog()) { + if (pform_test_type_identifier(yylval.text)) + rc = TYPE_IDENTIFIER; + } + return rc; } diff --git a/parse.y b/parse.y index f337e0670..08d9ba3cd 100644 --- a/parse.y +++ b/parse.y @@ -347,7 +347,7 @@ static void current_task_set_statement(vector*s) list *dimensions; }; -%token IDENTIFIER SYSTEM_IDENTIFIER STRING TIME_LITERAL +%token IDENTIFIER SYSTEM_IDENTIFIER TYPE_IDENTIFIER STRING TIME_LITERAL %token DISCIPLINE_IDENTIFIER %token PATHPULSE_IDENTIFIER %token BASED_NUMBER DEC_NUMBER @@ -706,10 +706,11 @@ block_item_decl if ($1) delete $1; } - /* variable declarations */ + /* variable declarations. Note that data_type can be 0 if we are + recovering from an error. */ | attribute_list_opt data_type register_variable_list ';' - { pform_set_data_type(@2, $2, $3); + { if ($2) pform_set_data_type(@2, $2, $3); if ($1) delete $1; } @@ -784,11 +785,18 @@ data_type { $$ = $1; } | enum_data_type { $$ = $1; } + | TYPE_IDENTIFIER + { yyerror(@1, "sorry: Named types not supported here"); + $$ = 0; + } ; type_declaration : K_typedef data_type IDENTIFIER ';' - { yyerror(@1, "sorry: typedef not yet supported."); } + { perm_string name = lex_strings.make($3); + pform_set_typedef(name, $2); + delete[]$3; + } ; /* The structure for an enumeration data type is the keyword "enum", diff --git a/parse_misc.h b/parse_misc.h index f3b5dfc9b..0217a0cda 100644 --- a/parse_misc.h +++ b/parse_misc.h @@ -77,6 +77,14 @@ extern UCDriveType uc_drive; extern bool have_timeunit_decl; extern bool have_timeprec_decl; +/* + * Test if this identifier is a type identifier in the current + * context. The pform code needs to help the lexor here because the + * parser detects typedefs and marks the typedef'ed identifiers as + * type names. + */ +extern bool pform_test_type_identifier(const char*txt); + /* * Export these functions because we have to generate PENumber class * in pform.cc for user defparam definition from command file. diff --git a/pform.cc b/pform.cc index a056b5f82..97e7c8303 100644 --- a/pform.cc +++ b/pform.cc @@ -401,6 +401,28 @@ PWire*pform_get_make_wire_in_scope(perm_string name, NetNet::Type net_type, NetN return cur; } +void pform_set_typedef(perm_string name, data_type_t*data_type) +{ + data_type_t*&ref = lexical_scope->typedefs[name]; + ivl_assert(*data_type, ref == 0); + ref = data_type; +} + +bool 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 false; + + perm_string name = lex_strings.make(txt); + map::iterator cur = lexical_scope->typedefs.find(name); + if (cur != lexical_scope->typedefs.end()) + return true; + else + return false; +} + static void pform_put_behavior_in_scope(PProcess*pp) { lexical_scope->behaviors.push_back(pp); diff --git a/pform.h b/pform.h index 56f0a4aac..dbdf85942 100644 --- a/pform.h +++ b/pform.h @@ -224,6 +224,8 @@ extern void pform_endgenerate(); */ extern PGenerate* pform_parent_generate(void); +extern void pform_set_typedef(perm_string name, data_type_t*data_type); + /* * The makewire functions announce to the pform code new wires. These * go into a module that is currently opened. diff --git a/pform_dump.cc b/pform_dump.cc index cd8829ccf..88fa71520 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -141,6 +141,11 @@ std::ostream& operator << (std::ostream&out, ivl_dis_domain_t dom) return out; } +void data_type_t::pform_dump(ostream&out, unsigned indent) const +{ + out << setw(indent) << "" << typeid(*this).name() << endl; +} + static void dump_attributes_map(ostream&out, const map&attributes, int ind) @@ -1050,6 +1055,15 @@ void PGenerate::dump(ostream&out, unsigned indent) const } } +void LexicalScope::dump_typedefs_(ostream&out, unsigned indent) const +{ + typedef map::const_iterator iter_t; + for (iter_t cur = typedefs.begin() ; cur != typedefs.end() ; ++ cur) { + out << setw(indent) << "" << "typedef of " << cur->first << ":" << endl; + cur->second->pform_dump(out, indent+4); + } +} + void LexicalScope::dump_parameters_(ostream&out, unsigned indent) const { typedef map::const_iterator parm_iter_t; @@ -1189,6 +1203,8 @@ void Module::dump(ostream&out) const out << ")" << endl; } + dump_typedefs_(out, 4); + dump_parameters_(out, 4); dump_localparams_(out, 4); diff --git a/pform_types.h b/pform_types.h index db0739552..354353dd4 100644 --- a/pform_types.h +++ b/pform_types.h @@ -70,6 +70,9 @@ struct decl_assignment_t { */ struct data_type_t : public LineInfo { virtual ~data_type_t() = 0; + + // This method is used by the pform dumper to diagnostic dump. + virtual void pform_dump(std::ostream&out, unsigned indent) const; }; /*