diff --git a/vhdlpp/architec_emit.cc b/vhdlpp/architec_emit.cc index e041d99cd..42e9ab035 100644 --- a/vhdlpp/architec_emit.cc +++ b/vhdlpp/architec_emit.cc @@ -23,6 +23,7 @@ # include "sequential.h" # include "subprogram.h" # include "vsignal.h" +# include "std_types.h" # include # include # include @@ -70,15 +71,16 @@ int Architecture::emit(ostream&out, Entity*entity) // of the full definition. typedef_context_t typedef_ctx; - //for (map::iterator cur = use_types_.begin() - //; cur != use_types_.end() ; ++cur) { + for (map::iterator cur = use_types_.begin() + ; cur != use_types_.end() ; ++cur) { + if(is_global_type(cur->first)) + continue; - //if(const VTypeDef*def = dynamic_cast(cur->second)) - //errors += def->emit_typedef(out, typedef_ctx); - //} + if(const VTypeDef*def = dynamic_cast(cur->second)) + errors += def->emit_typedef(out, typedef_ctx); + } for (map::iterator cur = cur_types_.begin() ; cur != cur_types_.end() ; ++cur) { - if(const VTypeDef*def = dynamic_cast(cur->second)) errors += def->emit_typedef(out, typedef_ctx); } diff --git a/vhdlpp/package.cc b/vhdlpp/package.cc index 40730f026..63215fee3 100644 --- a/vhdlpp/package.cc +++ b/vhdlpp/package.cc @@ -67,9 +67,6 @@ void Package::write_to_stream(ostream&fd) const // and identifiers. for (map::const_iterator cur = use_types_.begin() ; cur != use_types_.end() ; ++cur) { - const VTypeDef*def = dynamic_cast (cur->second); - if (def == 0) - continue; // Do not include global types in types dump if (is_global_type(cur->first)) @@ -79,9 +76,6 @@ void Package::write_to_stream(ostream&fd) const } for (map::const_iterator cur = cur_types_.begin() ; cur != cur_types_.end() ; ++cur) { - const VTypeDef*def = dynamic_cast (cur->second); - if (def == 0) - continue; // Do not include global types in types dump if (is_global_type(cur->first)) @@ -92,31 +86,11 @@ void Package::write_to_stream(ostream&fd) const for (map::const_iterator cur = use_types_.begin() ; cur != use_types_.end() ; ++cur) { - - // Do not include global types in types dump - if (is_global_type(cur->first)) - continue; - - if(!dynamic_cast(cur->second)) - fd << "sub"; - - fd << "type " << cur->first << " is "; - cur->second->write_type_to_stream(fd); - fd << "; -- imported" << endl; + cur->second->write_typedef_to_stream(fd, cur->first); } for (map::const_iterator cur = cur_types_.begin() ; cur != cur_types_.end() ; ++cur) { - - // Do not include global types in types dump - if (is_global_type(cur->first)) - continue; - - if(!dynamic_cast(cur->second)) - fd << "sub"; - - fd << "type " << cur->first << " is "; - cur->second->write_type_to_stream(fd); - fd << ";" << endl; + cur->second->write_typedef_to_stream(fd, cur->first); } for (map::const_iterator cur = cur_constants_.begin() diff --git a/vhdlpp/parse.y b/vhdlpp/parse.y index 970f21617..612d6acf4 100644 --- a/vhdlpp/parse.y +++ b/vhdlpp/parse.y @@ -547,6 +547,8 @@ block_declarative_item | subprogram_body + | subtype_declaration + | type_declaration | use_clause_lib @@ -2606,12 +2608,24 @@ subprogram_statement_part subtype_declaration : K_subtype IDENTIFIER K_is subtype_indication ';' { perm_string name = lex_strings.make($2); - delete[] $2; if ($4 == 0) { errormsg(@1, "Failed to declare type name %s.\n", name.str()); } else { - active_scope->bind_name(name, $4); + VTypeDef*tmp; + map::iterator cur = active_scope->incomplete_types.find(name); + if (cur == active_scope->incomplete_types.end()) { + tmp = new VSubTypeDef(name, $4); + active_scope->bind_name(name, tmp); + } else { + tmp = cur->second; + tmp->set_definition($4); + active_scope->incomplete_types.erase(cur); + } + if(const VTypeEnum*enum_type = dynamic_cast($4)) { + active_scope->use_enum(enum_type); + } } + delete[]$2; } ; diff --git a/vhdlpp/vtype.h b/vhdlpp/vtype.h index cc310ad90..b2212b6d6 100644 --- a/vhdlpp/vtype.h +++ b/vhdlpp/vtype.h @@ -72,6 +72,10 @@ class VType { // definitions. Most types accept the default definition of this. virtual void write_type_to_stream(std::ostream&fd) const; + // Emits a type definition. This is used to distinguish types and + // subtypes. + virtual void write_typedef_to_stream(std::ostream&fd, perm_string name) const; + // This virtual method writes a human-readable version of the // type to a given file for debug purposes. (Question: is this // really necessary given the write_to_stream method?) @@ -383,7 +387,7 @@ class VTypeDef : public VType { public: explicit VTypeDef(perm_string name); explicit VTypeDef(perm_string name, const VType*is); - ~VTypeDef(); + virtual ~VTypeDef(); VType*clone() const { return new VTypeDef(*this); } @@ -399,7 +403,7 @@ class VTypeDef : public VType { // type, and this method gets it for us. inline const VType* peek_definition(void) const { return type_; } - void write_to_stream(std::ostream&fd) const; + virtual void write_to_stream(std::ostream&fd) const; void write_type_to_stream(std::ostream&fd) const; int get_width(ScopeBase*scope) const { return type_->get_width(scope); } int emit_typedef(std::ostream&out, typedef_context_t&ctx) const; @@ -409,12 +413,20 @@ class VTypeDef : public VType { bool can_be_packed() const { return type_->can_be_packed(); } bool is_unbounded() const { return type_->is_unbounded(); } - private: - int emit_decl(std::ostream&out, perm_string name, bool reg_flag) const; - private: + protected: perm_string name_; const VType*type_; + + private: + int emit_decl(std::ostream&out, perm_string name, bool reg_flag) const; +}; + +class VSubTypeDef : public VTypeDef { + public: + explicit VSubTypeDef(perm_string name) : VTypeDef(name) {} + explicit VSubTypeDef(perm_string name, const VType*is) : VTypeDef(name, is) {} + void write_typedef_to_stream(std::ostream&fd, perm_string name) const; }; #endif /* IVL_vtype_H */ diff --git a/vhdlpp/vtype_stream.cc b/vhdlpp/vtype_stream.cc index 96d9eff4d..2869d6772 100644 --- a/vhdlpp/vtype_stream.cc +++ b/vhdlpp/vtype_stream.cc @@ -36,6 +36,16 @@ void VType::write_type_to_stream(ostream&fd) const write_to_stream(fd); } +void VType::write_typedef_to_stream(ostream&fd, perm_string name) const +{ + if(is_global_type(name)) + return; + + fd << "type " << name << " is "; + write_type_to_stream(fd); + fd << ";" << endl; +} + void VTypeArray::write_to_stream(ostream&fd) const { if(write_special_case(fd)) @@ -238,3 +248,12 @@ void VTypeEnum::write_to_stream(std::ostream&fd) const fd << ")"; } +void VSubTypeDef::write_typedef_to_stream(ostream&fd, perm_string name) const +{ + if(is_global_type(name)) + return; + + fd << "subtype " << name << " is "; + write_type_to_stream(fd); + fd << ";" << endl; +}