vhdlpp: Aggregate expressions for records can be specified in any order.

This commit is contained in:
Maciej Suminski 2014-09-17 16:32:56 +02:00
parent 94abef195a
commit f5dd2ac87e
3 changed files with 18 additions and 13 deletions

View File

@ -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<const VTypeDef*>(type)) {
type = tdef->peek_definition();
}
if (const VTypeArray*array = dynamic_cast<const VTypeArray*>(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<const ExpName*>(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());
}

View File

@ -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<element_t*>::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;

View File

@ -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<element_t*> elements_;