From cb03802a175a21e4303701304ff57f5c915fd7a2 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 15 Sep 2014 11:08:14 +0200 Subject: [PATCH] vhdlpp: Added VTypeArray::basic_type() to cope with arrays based on typedefs. --- vhdlpp/expression_emit.cc | 2 +- vhdlpp/vtype.cc | 23 +++++++++++++++++++++++ vhdlpp/vtype.h | 6 ++++++ vhdlpp/vtype_emit.cc | 6 +----- 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/vhdlpp/expression_emit.cc b/vhdlpp/expression_emit.cc index f2e312f8a..63bde19e1 100644 --- a/vhdlpp/expression_emit.cc +++ b/vhdlpp/expression_emit.cc @@ -767,7 +767,7 @@ int ExpString::emit_as_array_(ostream& out, Entity*, Architecture*, const VTypeA int errors = 0; assert(arr->dimensions() == 1); - const VTypePrimitive*etype = dynamic_cast (arr->element_type()); + const VTypePrimitive*etype = dynamic_cast (arr->basic_type()); assert(etype); // Detect the special case that this is an array of diff --git a/vhdlpp/vtype.cc b/vhdlpp/vtype.cc index 07dfc7e28..208482877 100644 --- a/vhdlpp/vtype.cc +++ b/vhdlpp/vtype.cc @@ -98,6 +98,29 @@ VTypeArray::~VTypeArray() { } +const VType* VTypeArray::basic_type(bool typedef_allowed) const +{ + const VType*t = etype_; + const VTypeDef*tdef = NULL; + bool progress = false; + + do { + progress = false; + + if((tdef = dynamic_cast(t))) { + t = tdef->peek_definition(); + } + + if(const VTypeArray*arr = dynamic_cast(t)) { + t = arr->element_type(); + progress = true; + } else if(tdef) { // return the typedef if it does not define an array + t = typedef_allowed ? tdef : tdef->peek_definition(); + } + } while(progress); + + return t; +} void VTypeArray::show(ostream&out) const { diff --git a/vhdlpp/vtype.h b/vhdlpp/vtype.h index bfaae2f61..09a44231d 100644 --- a/vhdlpp/vtype.h +++ b/vhdlpp/vtype.h @@ -206,6 +206,12 @@ class VTypeArray : public VType { // returns the type of element held in the array inline const VType* element_type() const { return etype_; } + // returns the basic type of element held in the array + // (unfolds typedefs and multidimensional arrays) + // typedef_allowed decides if VTypeDef can be returned or should + // it be unfolded + const VType* basic_type(bool typedef_allowed = true) 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; diff --git a/vhdlpp/vtype_emit.cc b/vhdlpp/vtype_emit.cc index a723dbda5..9dc17b5f2 100644 --- a/vhdlpp/vtype_emit.cc +++ b/vhdlpp/vtype_emit.cc @@ -60,12 +60,8 @@ 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 = basic_type(); - const VType*raw_base = cur->etype_; const VTypePrimitive*base = dynamic_cast (raw_base); if (base) {