Cleaner elaboration of void functions.
This fixed githun issue # 281.
This commit is contained in:
parent
a621fa48a6
commit
7feb26ff6b
|
|
@ -232,6 +232,8 @@ class PCallTask : public Statement {
|
|||
NetProc*elaborate_method_(Design*des, NetScope*scope,
|
||||
bool add_this_flag = false) const;
|
||||
NetProc*elaborate_function_(Design*des, NetScope*scope) const;
|
||||
NetProc*elaborate_void_function_(Design*des, NetScope*scope,
|
||||
NetFuncDef*def) const;
|
||||
|
||||
NetProc*elaborate_build_call_(Design*des, NetScope*scope,
|
||||
NetScope*task, NetExpr*use_this) const;
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
|||
print a useful error message. */
|
||||
if (reg == 0) {
|
||||
if (use_scope->type()==NetScope::FUNC
|
||||
&& use_scope->func_def()->return_sig()==0
|
||||
&& use_scope->func_def()->is_void()
|
||||
&& use_scope->basename()==peek_tail_name(path_)) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "Cannot assign to " << path_
|
||||
|
|
|
|||
18
elaborate.cc
18
elaborate.cc
|
|
@ -3672,6 +3672,9 @@ NetProc* PCallTask::elaborate_function_(Design*des, NetScope*scope) const
|
|||
// call with a missing return assignment.
|
||||
if (! func) return 0;
|
||||
|
||||
if (gn_system_verilog() && func->is_void())
|
||||
return elaborate_void_function_(des, scope, func);
|
||||
|
||||
// Generate a function call version of this task call.
|
||||
PExpr*rval = new PECallFunction(package_, path_, parms_);
|
||||
rval->set_file(get_file());
|
||||
|
|
@ -3686,6 +3689,21 @@ NetProc* PCallTask::elaborate_function_(Design*des, NetScope*scope) const
|
|||
return tmp->elaborate(des, scope);
|
||||
}
|
||||
|
||||
NetProc* PCallTask::elaborate_void_function_(Design*des, NetScope*scope,
|
||||
NetFuncDef*def) const
|
||||
{
|
||||
NetScope*dscope = def->scope();
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PCallTask::elaborate_void_function_: "
|
||||
<< "function void " << scope_path(dscope)
|
||||
<< endl;
|
||||
}
|
||||
|
||||
ivl_assert(*this, dscope->elab_stage() >= 3);
|
||||
return elaborate_build_call_(des, scope, dscope, 0);
|
||||
}
|
||||
|
||||
NetProc* PCallTask::elaborate_build_call_(Design*des, NetScope*scope,
|
||||
NetScope*task, NetExpr*use_this) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3650,6 +3650,13 @@ class NetFuncDef : public NetBaseDef {
|
|||
const std::vector<NetExpr*>&pd);
|
||||
~NetFuncDef();
|
||||
|
||||
// Return true if the function returns "void". We still treat
|
||||
// it as a function since we need to check that the contents
|
||||
// meet the requirements of a function, but we need to know
|
||||
// that it is void because it can be evaluated differently.
|
||||
inline bool is_void() const { return result_sig_ == 0; }
|
||||
|
||||
// Non-void functions have a return value as a signal.
|
||||
const NetNet*return_sig() const;
|
||||
|
||||
// When we want to evaluate the function during compile time,
|
||||
|
|
|
|||
4
t-dll.cc
4
t-dll.cc
|
|
@ -596,14 +596,14 @@ static void fill_in_scope_function(ivl_scope_t scope, const NetScope*net)
|
|||
const NetFuncDef*def = net->func_def();
|
||||
assert(def);
|
||||
|
||||
const NetNet*return_sig = def->return_sig();
|
||||
if (return_sig == 0) {
|
||||
if (def->is_void()) {
|
||||
// Special case: If there is no return signal, this is
|
||||
// apparently a VOID function.
|
||||
scope->func_type = IVL_VT_VOID;
|
||||
scope->func_signed = 0;
|
||||
scope->func_width = 0;
|
||||
} else {
|
||||
const NetNet*return_sig = def->return_sig();
|
||||
scope->func_type = return_sig->data_type();
|
||||
scope->func_signed = return_sig->get_signed();
|
||||
scope->func_width = return_sig->vector_width();
|
||||
|
|
|
|||
Loading…
Reference in New Issue