From f5dd2ac87e7f26497975a4728cec92341b145288 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 17 Sep 2014 16:32:56 +0200 Subject: [PATCH] vhdlpp: Aggregate expressions for records can be specified in any order. --- vhdlpp/expression_elaborate.cc | 20 +++++++++++--------- vhdlpp/vtype.cc | 8 ++++++-- vhdlpp/vtype.h | 3 +-- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/vhdlpp/expression_elaborate.cc b/vhdlpp/expression_elaborate.cc index ce8dd6ab9..1987be699 100644 --- a/vhdlpp/expression_elaborate.cc +++ b/vhdlpp/expression_elaborate.cc @@ -56,6 +56,10 @@ const VType* Expression::fit_type(Entity*ent, Architecture*arc, const VTypeArray const VType*ExpName::elaborate_adjust_type_with_range_(Entity*, Architecture*arc, const VType*type) { + // Unfold typedefs + while (const VTypeDef*tdef = dynamic_cast(type)) { + type = tdef->peek_definition(); + } if (const VTypeArray*array = dynamic_cast(type)) { if (index_ && !lsb_) { @@ -484,6 +488,8 @@ int ExpAggregate::elaborate_expr_record_(Entity*ent, Architecture*arc, const VTy int errors = 0; aggregate_.resize(elements_.size()); + choice_element tmp; + int idx; // Translate the elements_ array to the aggregate_ array. In // the target array, each expression is attached to a single @@ -494,24 +500,20 @@ int ExpAggregate::elaborate_expr_record_(Entity*ent, Architecture*arc, const VTy // it is invalid to have more than one choice in record assignment ivl_assert(*this, ecur->count_choices() == 1); - ecur->map_choices(&aggregate_[edx]); - } + ecur->map_choices(&tmp); + choice_t*ch = tmp.choice; - // Now run through the more convenient mapping and elaborate - // all the expressions that I find. - for (size_t idx = 0 ; idx < aggregate_.size() ; idx += 1) { - ivl_assert(*this, !aggregate_[idx].alias_flag); - - choice_t*ch = aggregate_[idx].choice; ivl_assert(*this, !ch->others()); + ivl_assert(*this, !tmp.alias_flag); // Get the appropriate type for a field const ExpName*field = dynamic_cast(ch->simple_expression(false)); ivl_assert(*this, field); perm_string field_name = field->peek_name(); - const VTypeRecord::element_t*el = ltype->element_by_name(field_name); + const VTypeRecord::element_t*el = ltype->element_by_name(field_name, &idx); + aggregate_[idx] = tmp; errors += aggregate_[idx].expr->elaborate_expr(ent, arc, el->peek_type()); } diff --git a/vhdlpp/vtype.cc b/vhdlpp/vtype.cc index 208482877..a7f9233aa 100644 --- a/vhdlpp/vtype.cc +++ b/vhdlpp/vtype.cc @@ -205,13 +205,17 @@ void VTypeRecord::show(ostream&out) const write_to_stream(out); } -const VTypeRecord::element_t* VTypeRecord::element_by_name(perm_string name) const +const VTypeRecord::element_t* VTypeRecord::element_by_name(perm_string name, int*index) const { for (vector::const_iterator cur = elements_.begin() ; cur != elements_.end() ; ++cur) { element_t*curp = *cur; - if (curp->peek_name() == name) + if (curp->peek_name() == name) { + if (index) + *index = std::distance(elements_.begin(), cur); + return curp; + } } return 0; diff --git a/vhdlpp/vtype.h b/vhdlpp/vtype.h index 09a44231d..247af6b51 100644 --- a/vhdlpp/vtype.h +++ b/vhdlpp/vtype.h @@ -288,8 +288,7 @@ class VTypeRecord : public VType { int emit_def(std::ostream&out, perm_string name) const; bool can_be_packed() const { return true; } - - const element_t* element_by_name(perm_string name) const; + const element_t* element_by_name(perm_string name, int*index = NULL) const; private: std::vector elements_;