vhdlpp: Subprograms return types have their ranges evaluated if possible.

Added VTypeArray::evaluate_ranges() method.
This commit is contained in:
Maciej Suminski 2015-01-26 17:51:42 +01:00
parent abbcea64d0
commit 48265ecd9b
3 changed files with 24 additions and 1 deletions

View File

@ -268,8 +268,14 @@ bool Subprogram::fixed_return_type(void)
(*s)->visit(r);
}
const VType*return_type = r.get_type();
VType*return_type = const_cast<VType*>(r.get_type());
if(return_type && !return_type->is_unbounded()) {
// Let's check if the variable length can be evaluated without any scope.
// If not, then it is depends on information about e.g. function params
if(return_type->is_variable_length(NULL)) {
if(VTypeArray*arr = dynamic_cast<VTypeArray*>(return_type))
arr->evaluate_ranges(this);
}
return_type_ = return_type;
return true;
} else {

View File

@ -186,6 +186,19 @@ bool VTypeArray::is_variable_length(ScopeBase*scope) const {
return etype_->is_variable_length(scope);
}
void VTypeArray::evaluate_ranges(ScopeBase*scope) {
for(std::vector<range_t>::iterator it = ranges_.begin(); it != ranges_.end(); ++it ) {
int64_t lsb_val = -1, msb_val = -1;
bool dir = it->is_downto();
if(it->msb()->evaluate(scope, msb_val) && it->lsb()->evaluate(scope, lsb_val)) {
assert(lsb_val >= 0);
assert(msb_val >= 0);
*it = range_t(new ExpInteger(msb_val), new ExpInteger(lsb_val), dir);
}
}
}
VTypeRange::VTypeRange(const VType*base, int64_t max_val, int64_t min_val)
: base_(base)
{

View File

@ -238,6 +238,10 @@ class VTypeArray : public VType {
// To handle subtypes
inline void set_parent_type(const VTypeArray*parent) { parent_ = parent; }
// Wherever it is possible, replaces range lsb & msb expressions with
// constant integers.
void evaluate_ranges(ScopeBase*scope);
private:
int emit_with_dims_(std::ostream&out, bool packed, perm_string name) const;