vhdlpp: Turned elaborate_argument() into a SubprogramHeader method.

This commit is contained in:
Maciej Suminski 2016-01-22 14:33:26 +01:00
parent b707228171
commit 8298c96dee
5 changed files with 34 additions and 38 deletions

View File

@ -1004,8 +1004,4 @@ private:
Expression*delay_;
};
// Elaborates an expression used as an argument in a procedure/function call.
int elaborate_argument(Expression*expr, const SubprogramHeader*subp,
int idx, Entity*ent, ScopeBase*scope);
#endif /* IVL_expression_H */

View File

@ -817,7 +817,7 @@ int ExpFunc::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*)
// Elaborate arguments
for (size_t idx = 0; idx < argv_.size(); ++idx) {
errors += elaborate_argument(argv_[idx], prog, idx, ent, scope);
errors += prog->elaborate_argument(argv_[idx], idx, ent, scope);
}
// SystemVerilog functions work only with defined size data types, therefore
@ -1109,35 +1109,3 @@ int ExpDelay::elaborate_expr(Entity*ent, ScopeBase*scope, const VType*ltype)
return errors;
}
int elaborate_argument(Expression*expr, const SubprogramHeader*subp,
int idx, Entity*ent, ScopeBase*scope)
{
const VType*type = expr->probe_type(ent, scope);
if(subp) {
const InterfacePort*param = subp->peek_param(idx);
if(!param) {
cerr << expr->get_fileline()
<< ": error: Too many arguments when calling "
<< subp->name() << "." << endl;
return 1;
}
// Enable reg_flag for variables that might be modified in subprograms
if(param->mode == PORT_OUT || param->mode == PORT_INOUT) {
if(const ExpName*e = dynamic_cast<const ExpName*>(expr)) {
if(Signal*sig = scope->find_signal(e->peek_name()))
sig->count_ref_sequ();
else if(Variable*var = scope->find_variable(e->peek_name()))
var->count_ref_sequ();
}
}
if(!type)
type = param->type;
}
return expr->elaborate_expr(ent, scope, type);
}

View File

@ -190,7 +190,7 @@ int ProcedureCall::elaborate(Entity*ent, ScopeBase*scope)
if(param_list_) {
for(list<named_expr_t*>::iterator cur = param_list_->begin()
; cur != param_list_->end() ; ++cur) {
errors += elaborate_argument((*cur)->expr(), def_, idx, ent, scope);
errors += def_->elaborate_argument((*cur)->expr(), idx, ent, scope);
++idx;
}
}

View File

@ -201,6 +201,35 @@ void SubprogramHeader::set_body(SubprogramBody*bdy)
bdy->header_ = this;
}
int SubprogramHeader::elaborate_argument(Expression*expr, int idx,
Entity*ent, ScopeBase*scope)
{
const VType*type = expr->probe_type(ent, scope);
const InterfacePort*param = peek_param(idx);
if(!param) {
cerr << expr->get_fileline()
<< ": error: Too many arguments when calling "
<< name_ << "." << endl;
return 1;
}
// Enable reg_flag for variables that might be modified in subprograms
if(param->mode == PORT_OUT || param->mode == PORT_INOUT) {
if(const ExpName*e = dynamic_cast<const ExpName*>(expr)) {
if(Signal*sig = scope->find_signal(e->peek_name()))
sig->count_ref_sequ();
else if(Variable*var = scope->find_variable(e->peek_name()))
var->count_ref_sequ();
}
}
if(!type)
type = param->type;
return expr->elaborate_expr(ent, scope, type);
}
SubprogramHeader*SubprogramHeader::make_instance(std::vector<Expression*> arguments,
ScopeBase*scope) const {
assert(arguments.size() == ports_->size());

View File

@ -94,6 +94,9 @@ class SubprogramHeader : public LineInfo {
int elaborate() { return (body_ ? body_->elaborate() : 0); }
// Elaborates an argument basing on the types stored in the subprogram header.
int elaborate_argument(Expression*expr, int idx, Entity*ent, ScopeBase*scope);
// Emits the function name, including the package if required.
int emit_full_name(const std::vector<Expression*>&argv,
std::ostream&out, Entity*, ScopeBase*) const;