vhdlpp: VType::get_width() uses information from Scope to determine the type width.
This commit is contained in:
parent
9128eb67b9
commit
e33b8b4dde
|
|
@ -668,11 +668,11 @@ class ExpName : public Expression {
|
||||||
bool try_workarounds_(ostream&out, Entity*ent, ScopeBase*scope,
|
bool try_workarounds_(ostream&out, Entity*ent, ScopeBase*scope,
|
||||||
list<index_t*>&indices, int&data_size);
|
list<index_t*>&indices, int&data_size);
|
||||||
|
|
||||||
bool check_const_array_workaround_(const VTypeArray*arr, list<index_t*>&indices,
|
bool check_const_array_workaround_(const VTypeArray*arr, ScopeBase*scope,
|
||||||
int&data_size) const;
|
list<index_t*>&indices, int&data_size) const;
|
||||||
|
|
||||||
bool check_const_record_workaround_(const VTypeRecord*rec, list<index_t*>&indices,
|
bool check_const_record_workaround_(const VTypeRecord*rec, ScopeBase*scope,
|
||||||
int&data_size) const;
|
list<index_t*>&indices, int&data_size) const;
|
||||||
|
|
||||||
int emit_workaround_(ostream&out, Entity*ent, ScopeBase*scope,
|
int emit_workaround_(ostream&out, Entity*ent, ScopeBase*scope,
|
||||||
const list<index_t*>&indices, int field_size);
|
const list<index_t*>&indices, int field_size);
|
||||||
|
|
|
||||||
|
|
@ -771,7 +771,7 @@ bool ExpName::try_workarounds_(ostream&out, Entity*ent, ScopeBase*scope,
|
||||||
|
|
||||||
const VTypeArray*arr = dynamic_cast<const VTypeArray*>(type);
|
const VTypeArray*arr = dynamic_cast<const VTypeArray*>(type);
|
||||||
assert(arr);
|
assert(arr);
|
||||||
wrkand_required |= check_const_array_workaround_(arr, indices, data_size);
|
wrkand_required |= check_const_array_workaround_(arr, scope, indices, data_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(prefix_.get() && scope->find_constant(prefix_->name_, type, exp)) {
|
if(prefix_.get() && scope->find_constant(prefix_->name_, type, exp)) {
|
||||||
|
|
@ -780,7 +780,7 @@ bool ExpName::try_workarounds_(ostream&out, Entity*ent, ScopeBase*scope,
|
||||||
const VTypeArray*arr = dynamic_cast<const VTypeArray*>(type);
|
const VTypeArray*arr = dynamic_cast<const VTypeArray*>(type);
|
||||||
assert(arr);
|
assert(arr);
|
||||||
type = arr->element_type();
|
type = arr->element_type();
|
||||||
data_size = type->get_width();
|
data_size = type->get_width(scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
while(const VTypeDef*type_def = dynamic_cast<const VTypeDef*>(type)) {
|
while(const VTypeDef*type_def = dynamic_cast<const VTypeDef*>(type)) {
|
||||||
|
|
@ -790,23 +790,26 @@ bool ExpName::try_workarounds_(ostream&out, Entity*ent, ScopeBase*scope,
|
||||||
const VTypeRecord*rec = dynamic_cast<const VTypeRecord*>(type);
|
const VTypeRecord*rec = dynamic_cast<const VTypeRecord*>(type);
|
||||||
assert(rec);
|
assert(rec);
|
||||||
|
|
||||||
wrkand_required |= check_const_record_workaround_(rec, indices, data_size);
|
wrkand_required |= check_const_record_workaround_(rec, scope, indices, data_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return wrkand_required;
|
return wrkand_required;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ExpName::check_const_array_workaround_(const VTypeArray*arr,
|
bool ExpName::check_const_array_workaround_(const VTypeArray*arr,
|
||||||
list<index_t*>&indices, int&data_size) const
|
ScopeBase*scope, list<index_t*>&indices, int&data_size) const
|
||||||
{
|
{
|
||||||
const VType*element = arr->element_type();
|
const VType*element = arr->element_type();
|
||||||
data_size = element->get_width();
|
data_size = element->get_width(scope);
|
||||||
|
if(data_size < 0)
|
||||||
|
return false;
|
||||||
indices.push_back(new index_t(index_, new ExpInteger(data_size)));
|
indices.push_back(new index_t(index_, new ExpInteger(data_size)));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ExpName::check_const_record_workaround_(const VTypeRecord*rec,
|
bool ExpName::check_const_record_workaround_(const VTypeRecord*rec,
|
||||||
list<index_t*>&indices, int&data_size) const
|
ScopeBase*scope, list<index_t*>&indices, int&data_size) const
|
||||||
{
|
{
|
||||||
int tmp_offset = 0;
|
int tmp_offset = 0;
|
||||||
const vector<VTypeRecord::element_t*>& elements = rec->get_elements();
|
const vector<VTypeRecord::element_t*>& elements = rec->get_elements();
|
||||||
|
|
@ -818,7 +821,7 @@ bool ExpName::check_const_record_workaround_(const VTypeRecord*rec,
|
||||||
if(el->peek_name() == name_) {
|
if(el->peek_name() == name_) {
|
||||||
const VType*type = el->peek_type();
|
const VType*type = el->peek_type();
|
||||||
|
|
||||||
int tmp_field = type->get_width();
|
int tmp_field = type->get_width(scope);
|
||||||
if(tmp_field < 0)
|
if(tmp_field < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
@ -828,13 +831,13 @@ bool ExpName::check_const_record_workaround_(const VTypeRecord*rec,
|
||||||
if(index_) {
|
if(index_) {
|
||||||
const VTypeArray*arr = dynamic_cast<const VTypeArray*>(type);
|
const VTypeArray*arr = dynamic_cast<const VTypeArray*>(type);
|
||||||
assert(arr);
|
assert(arr);
|
||||||
return check_const_array_workaround_(arr, indices, data_size);
|
return check_const_array_workaround_(arr, scope, indices, data_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int w = el->peek_type()->get_width();
|
int w = el->peek_type()->get_width(scope);
|
||||||
|
|
||||||
if(w < 0)
|
if(w < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@ bool Expression::evaluate(Entity*, ScopeBase*scope, int64_t&val) const
|
||||||
return evaluate(scope, val);
|
return evaluate(scope, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ExpArithmetic::evaluate(ScopeBase*scope, int64_t&val) const
|
bool ExpArithmetic::evaluate(ScopeBase*scope, int64_t&val) const
|
||||||
{
|
{
|
||||||
int64_t val1, val2;
|
int64_t val1, val2;
|
||||||
|
|
@ -113,20 +112,12 @@ bool ExpAttribute::evaluate(ScopeBase*scope, int64_t&val) const
|
||||||
}
|
}
|
||||||
|
|
||||||
if(name_ == "length") {
|
if(name_ == "length") {
|
||||||
int64_t size = 1;
|
int64_t size = arr->get_width(scope);
|
||||||
for (size_t idx = 0 ; idx < arr->dimensions() ; idx += 1) {
|
|
||||||
const VTypeArray::range_t&dim = arr->dimension(idx);
|
|
||||||
int64_t msb_val, lsb_val;
|
|
||||||
|
|
||||||
if(dim.is_box())
|
if(size > 0)
|
||||||
return false;
|
val = size;
|
||||||
|
else
|
||||||
dim.msb()->evaluate(scope, msb_val);
|
return false;
|
||||||
dim.lsb()->evaluate(scope, lsb_val);
|
|
||||||
|
|
||||||
size *= 1 + labs(msb_val - lsb_val);
|
|
||||||
}
|
|
||||||
val = size;
|
|
||||||
} else if(name_ == "left") {
|
} else if(name_ == "left") {
|
||||||
arr->dimension(0).msb()->evaluate(scope, val);
|
arr->dimension(0).msb()->evaluate(scope, val);
|
||||||
} else if(name_ == "right") {
|
} else if(name_ == "right") {
|
||||||
|
|
|
||||||
|
|
@ -79,13 +79,12 @@ void VTypePrimitive::show(ostream&out) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int VTypePrimitive::get_width() const
|
int VTypePrimitive::get_width(ScopeBase*) const
|
||||||
{
|
{
|
||||||
switch(type_) {
|
switch(type_) {
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
case BIT:
|
case BIT:
|
||||||
case STDLOGIC:
|
case STDLOGIC:
|
||||||
case REAL:
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case INTEGER:
|
case INTEGER:
|
||||||
|
|
@ -196,7 +195,7 @@ void VTypeArray::show(ostream&out) const
|
||||||
out << "<nil>";
|
out << "<nil>";
|
||||||
}
|
}
|
||||||
|
|
||||||
int VTypeArray::get_width() const
|
int VTypeArray::get_width(ScopeBase*scope) const
|
||||||
{
|
{
|
||||||
int64_t size = 1;
|
int64_t size = 1;
|
||||||
|
|
||||||
|
|
@ -208,16 +207,16 @@ int VTypeArray::get_width() const
|
||||||
if(dim.is_box())
|
if(dim.is_box())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if(!dim.msb()->evaluate(NULL, msb_val))
|
if(!dim.msb()->evaluate(scope, msb_val))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if(!dim.lsb()->evaluate(NULL, lsb_val))
|
if(!dim.lsb()->evaluate(scope, lsb_val))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
size *= 1 + labs(msb_val - lsb_val);
|
size *= 1 + labs(msb_val - lsb_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
return element_type()->get_width() * size;
|
return element_type()->get_width(scope) * size;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VTypeArray::is_unbounded() const {
|
bool VTypeArray::is_unbounded() const {
|
||||||
|
|
@ -325,13 +324,13 @@ void VTypeRecord::show(ostream&out) const
|
||||||
write_to_stream(out);
|
write_to_stream(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
int VTypeRecord::get_width() const
|
int VTypeRecord::get_width(ScopeBase*scope) const
|
||||||
{
|
{
|
||||||
int width = 0;
|
int width = 0;
|
||||||
|
|
||||||
for(vector<element_t*>::const_iterator it = elements_.begin();
|
for(vector<element_t*>::const_iterator it = elements_.begin();
|
||||||
it != elements_.end(); ++it) {
|
it != elements_.end(); ++it) {
|
||||||
int w = (*it)->peek_type()->get_width();
|
int w = (*it)->peek_type()->get_width(scope);
|
||||||
|
|
||||||
if(w < 0)
|
if(w < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ class VType {
|
||||||
|
|
||||||
// Returns the type width in bits or negative number if it is impossible
|
// Returns the type width in bits or negative number if it is impossible
|
||||||
// to evaluate.
|
// to evaluate.
|
||||||
virtual int get_width() const { return -1; }
|
virtual int get_width(ScopeBase*) const { return -1; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend struct decl_t;
|
friend struct decl_t;
|
||||||
|
|
@ -166,7 +166,7 @@ class VTypePrimitive : public VType {
|
||||||
|
|
||||||
void write_to_stream(std::ostream&fd) const;
|
void write_to_stream(std::ostream&fd) const;
|
||||||
void show(std::ostream&) const;
|
void show(std::ostream&) const;
|
||||||
int get_width() const;
|
int get_width(ScopeBase*scope) const;
|
||||||
|
|
||||||
type_t type() const { return type_; }
|
type_t type() const { return type_; }
|
||||||
|
|
||||||
|
|
@ -227,7 +227,7 @@ class VTypeArray : public VType {
|
||||||
void write_to_stream(std::ostream&fd) const;
|
void write_to_stream(std::ostream&fd) const;
|
||||||
void write_type_to_stream(std::ostream&fd) const;
|
void write_type_to_stream(std::ostream&fd) const;
|
||||||
void show(std::ostream&) const;
|
void show(std::ostream&) const;
|
||||||
int get_width() const;
|
int get_width(ScopeBase*scope) const;
|
||||||
|
|
||||||
inline size_t dimensions() const { return ranges_.size(); };
|
inline size_t dimensions() const { return ranges_.size(); };
|
||||||
const range_t&dimension(size_t idx) const
|
const range_t&dimension(size_t idx) const
|
||||||
|
|
@ -301,7 +301,7 @@ class VTypeEnum : public VType {
|
||||||
|
|
||||||
void write_to_stream(std::ostream&fd) const;
|
void write_to_stream(std::ostream&fd) const;
|
||||||
void show(std::ostream&) const;
|
void show(std::ostream&) const;
|
||||||
int get_width() const { return 32; }
|
int get_width(ScopeBase*) const { return 32; }
|
||||||
|
|
||||||
int emit_def(std::ostream&out, perm_string name) const;
|
int emit_def(std::ostream&out, perm_string name) const;
|
||||||
|
|
||||||
|
|
@ -341,7 +341,7 @@ class VTypeRecord : public VType {
|
||||||
|
|
||||||
void write_to_stream(std::ostream&fd) const;
|
void write_to_stream(std::ostream&fd) const;
|
||||||
void show(std::ostream&) const;
|
void show(std::ostream&) const;
|
||||||
int get_width() const;
|
int get_width(ScopeBase*scope) const;
|
||||||
int emit_def(std::ostream&out, perm_string name) const;
|
int emit_def(std::ostream&out, perm_string name) const;
|
||||||
|
|
||||||
bool can_be_packed() const { return true; }
|
bool can_be_packed() const { return true; }
|
||||||
|
|
@ -373,7 +373,7 @@ class VTypeDef : public VType {
|
||||||
|
|
||||||
void write_to_stream(std::ostream&fd) const;
|
void write_to_stream(std::ostream&fd) const;
|
||||||
void write_type_to_stream(std::ostream&fd) const;
|
void write_type_to_stream(std::ostream&fd) const;
|
||||||
int get_width() const { return type_->get_width(); }
|
int get_width(ScopeBase*scope) const { return type_->get_width(scope); }
|
||||||
int emit_typedef(std::ostream&out, typedef_context_t&ctx) const;
|
int emit_typedef(std::ostream&out, typedef_context_t&ctx) const;
|
||||||
|
|
||||||
int emit_def(std::ostream&out, perm_string name) const;
|
int emit_def(std::ostream&out, perm_string name) const;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue