diff --git a/vhdlpp/package_emit.cc b/vhdlpp/package_emit.cc index 5792cd728..2cc3b91fb 100644 --- a/vhdlpp/package_emit.cc +++ b/vhdlpp/package_emit.cc @@ -48,8 +48,8 @@ int Package::emit_package(ostream&fd) const for (map::const_iterator cur = cur_types_.begin() ; cur != cur_types_.end() ; ++ cur) { fd << "typedef "; - errors += cur->second->emit_def(fd); - fd << " \\" << cur->first << " ;" << endl; + errors += cur->second->emit_def(fd, cur->first); + fd << " ;" << endl; } for (map::const_iterator cur = use_constants_.begin() diff --git a/vhdlpp/subprogram_emit.cc b/vhdlpp/subprogram_emit.cc index efd586bd0..402b0a4cd 100644 --- a/vhdlpp/subprogram_emit.cc +++ b/vhdlpp/subprogram_emit.cc @@ -31,7 +31,7 @@ int Subprogram::emit_package(ostream&fd) const if (return_type_) { fd << "function "; - return_type_->emit_def(fd); + return_type_->emit_def(fd, empty_perm_string); fd << " " << name_; fd << "("; } else { @@ -55,8 +55,7 @@ int Subprogram::emit_package(ostream&fd) const break; } - errors += curp->type->emit_def(fd); - fd << " \\" << curp->name << " "; + errors += curp->type->emit_def(fd, curp->name); } fd << ");" << endl; diff --git a/vhdlpp/vtype.h b/vhdlpp/vtype.h index 003f8d937..ed264e762 100644 --- a/vhdlpp/vtype.h +++ b/vhdlpp/vtype.h @@ -74,7 +74,7 @@ class VType { // This virtual method emits a definition for the specific // type. It is used to emit typedef's. - virtual int emit_def(std::ostream&out) const =0; + virtual int emit_def(std::ostream&out, perm_string name) const =0; // This virtual method causes VTypeDef types to emit typedefs // of themselves. The VTypeDef implementation of this method @@ -118,7 +118,7 @@ extern void preload_global_types(void); */ class VTypeERROR : public VType { public: - int emit_def(std::ostream&out) const; + int emit_def(std::ostream&out, perm_string name) const; }; /* @@ -140,7 +140,7 @@ class VTypePrimitive : public VType { type_t type() const { return type_; } int emit_primitive_type(std::ostream&fd) const; - int emit_def(std::ostream&out) const; + int emit_def(std::ostream&out, perm_string name) const; bool can_be_packed() const { return packed_; } @@ -197,8 +197,9 @@ class VTypeArray : public VType { const VType* element_type() const; - int emit_def(std::ostream&out) const; + int emit_def(std::ostream&out, perm_string name) const; int emit_typedef(std::ostream&out, typedef_context_t&ctx) const; + int emit_dimensions(std::ostream&out) const; bool can_be_packed() const { return etype_->can_be_packed(); } @@ -220,7 +221,7 @@ class VTypeRange : public VType { public: // Virtual methods void write_to_stream(std::ostream&fd) const; - int emit_def(std::ostream&out) const; + int emit_def(std::ostream&out, perm_string name) const; private: const VType*base_; @@ -234,7 +235,7 @@ class VTypeEnum : public VType { ~VTypeEnum(); void show(std::ostream&) const; - int emit_def(std::ostream&out) const; + int emit_def(std::ostream&out, perm_string name) const; private: std::vectornames_; @@ -267,7 +268,7 @@ class VTypeRecord : public VType { void write_to_stream(std::ostream&fd) const; void show(std::ostream&) const; - int emit_def(std::ostream&out) const; + int emit_def(std::ostream&out, perm_string name) const; const element_t* element_by_name(perm_string name) const; @@ -296,7 +297,7 @@ class VTypeDef : public VType { void write_type_to_stream(ostream&fd) const; int emit_typedef(std::ostream&out, typedef_context_t&ctx) const; - int emit_def(std::ostream&out) const; + int emit_def(std::ostream&out, perm_string name) const; private: int emit_decl(std::ostream&out, perm_string name, bool reg_flag) const; diff --git a/vhdlpp/vtype_emit.cc b/vhdlpp/vtype_emit.cc index baea99a3d..a984db5b6 100644 --- a/vhdlpp/vtype_emit.cc +++ b/vhdlpp/vtype_emit.cc @@ -21,7 +21,7 @@ # include "vtype.h" # include "expression.h" -# include +# include # include # include @@ -33,7 +33,6 @@ int VType::decl_t::emit(ostream&out, perm_string name) const return type->emit_decl(out, name, reg_flag); } - int VType::emit_decl(ostream&out, perm_string name, bool reg_flag) const { int errors = 0; @@ -41,9 +40,8 @@ int VType::emit_decl(ostream&out, perm_string name, bool reg_flag) const if (!reg_flag) out << "wire "; - errors += emit_def(out); - - out << " \\" << name << " "; + errors += emit_def(out, name); + out << " "; return errors; } @@ -52,13 +50,55 @@ int VType::emit_typedef(std::ostream&, typedef_context_t&) const return 0; } -int VTypeERROR::emit_def(ostream&out) const +int VTypeERROR::emit_def(ostream&out, perm_string) const { out << "/* ERROR */"; return 1; } -int VTypeArray::emit_def(ostream&out) const +int VTypeArray::emit_def(ostream&out, perm_string name) const +{ + int errors = 0; + + const VTypeArray*cur = this; + while (const VTypeArray*sub = dynamic_cast (cur->etype_)) { + cur = sub; + } + + const VType*raw_base = cur->etype_; + const VTypePrimitive*base = dynamic_cast (raw_base); + stringstream buf; + + if (base) { + assert(dimensions() == 1); + + base->emit_def(buf, empty_perm_string); + if (signed_flag_) + buf << " signed"; + } else { + raw_base->emit_def(buf, empty_perm_string); + } + + string tmp(buf.str()); + out << tmp.substr(0, tmp.length() - 2); // drop the empty type name (\ ) + + if(raw_base->can_be_packed()) { + errors += emit_dimensions(out); + out << " \\" << name; + } else { + out << "\\" << name << " "; + errors += emit_dimensions(out); + } + + return errors; +} + +int VTypeArray::emit_typedef(std::ostream&out, typedef_context_t&ctx) const +{ + return etype_->emit_typedef(out, ctx); +} + +int VTypeArray::emit_dimensions(std::ostream&out) const { int errors = 0; @@ -68,21 +108,6 @@ int VTypeArray::emit_def(ostream&out) const dims.push_back(cur); cur = sub; } - - const VType*raw_base = cur->etype_; - - const VTypePrimitive*base = dynamic_cast (raw_base); - - if (base) { - assert(dimensions() == 1); - - base->emit_def(out); - if (signed_flag_) - out << " signed"; - } else { - raw_base->emit_def(out); - } - dims.push_back(cur); while (! dims.empty()) { @@ -102,12 +127,7 @@ int VTypeArray::emit_def(ostream&out) const return errors; } -int VTypeArray::emit_typedef(std::ostream&out, typedef_context_t&ctx) const -{ - return etype_->emit_typedef(out, ctx); -} - -int VTypeEnum::emit_def(ostream&out) const +int VTypeEnum::emit_def(ostream&out, perm_string name) const { int errors = 0; out << "enum {"; @@ -116,7 +136,7 @@ int VTypeEnum::emit_def(ostream&out) const for (size_t idx = 1 ; idx < names_.size() ; idx += 1) out << ", \\" << names_[idx] << " "; - out << "}"; + out << "} \\" << name << " "; return errors; } @@ -148,22 +168,23 @@ int VTypePrimitive::emit_primitive_type(ostream&out) const return errors; } -int VTypePrimitive::emit_def(ostream&out) const +int VTypePrimitive::emit_def(ostream&out, perm_string name) const { int errors = 0; errors += emit_primitive_type(out); + out << " \\" << name << " "; return errors; } -int VTypeRange::emit_def(ostream&out) const +int VTypeRange::emit_def(ostream&out, perm_string name) const { int errors = 0; out << "/* Internal error: Don't know how to emit range */"; - errors += base_->emit_def(out); + errors += base_->emit_def(out, name); return errors; } -int VTypeRecord::emit_def(ostream&out) const +int VTypeRecord::emit_def(ostream&out, perm_string name) const { int errors = 0; out << "struct packed {"; @@ -172,11 +193,11 @@ int VTypeRecord::emit_def(ostream&out) const ; cur != elements_.end() ; ++cur) { perm_string element_name = (*cur)->peek_name(); const VType*element_type = (*cur)->peek_type(); - element_type->emit_def(out); + element_type->emit_def(out, empty_perm_string); out << " \\" << element_name << " ; "; } - out << "}"; + out << "} \\ " << name << " "; return errors; } @@ -185,7 +206,7 @@ int VTypeRecord::emit_def(ostream&out) const * type. (We are defining a variable here, not the type itself.) The * emit_typedef() method was presumably called to define type already. */ -int VTypeDef::emit_def(ostream&out) const +int VTypeDef::emit_def(ostream&out, perm_string) const { int errors = 0; out << "\\" << name_ << " "; @@ -200,7 +221,7 @@ int VTypeDef::emit_decl(ostream&out, perm_string name, bool reg_flag) const else out << "wire "; - errors += type_->emit_def(out); + errors += type_->emit_def(out, name); out << " \\" << name << " "; return errors; } @@ -227,8 +248,14 @@ int VTypeDef::emit_typedef(ostream&out, typedef_context_t&ctx) const int errors = type_->emit_typedef(out, ctx); flag = MARKED; + // Array types are used directly anyway and typedefs for unpacked + // arrays do not work currently + if(dynamic_cast(type_)) + out << "// "; + out << "typedef "; - errors += type_->emit_def(out); - out << " \\" << name_ << " ;" << endl; + errors += type_->emit_def(out, name_); + out << " ;" << endl; + return errors; }