From d025c8aa93110e2229d9e6bdf615de851ce4041e Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Fri, 20 Sep 2013 20:38:53 -0700 Subject: [PATCH] Non-method tasks/functions support default arguments. --- elab_expr.cc | 21 +++++++++++++++++---- elaborate.cc | 36 ++++++++++++------------------------ net_func.cc | 9 --------- 3 files changed, 29 insertions(+), 37 deletions(-) diff --git a/elab_expr.cc b/elab_expr.cc index 8aa0ac696..915634179 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -1972,12 +1972,15 @@ NetExpr* PECallFunction::elaborate_base_(Design*des, NetScope*scope, NetScope*ds pfunc->elaborate(des, dscope); } - unsigned parms_count = parms_.size(); - if ((parms_count == 1) && (parms_[0] == 0)) - parms_count = 0; - + unsigned parms_count = def->port_count(); vector parms (parms_count); + if (debug_elaborate) { + cerr << get_fileline() << ": PECallFunction::elaborate_base_: " + << "Expecting " << parms_count + << " for function " << scope_path(dscope) << "." << endl; + } + /* Elaborate the input expressions for the function. This is done in the scope of the function call, and not the scope of the function being called. The scope of the called @@ -2078,6 +2081,16 @@ unsigned PECallFunction::elaborate_arguments_(Design*des, NetScope*scope, << " arg " << (idx+1) << " argwid=" << parms[pidx]->expr_width() << ": " << *parms[idx] << endl; + + } else if (def->port_defe(pidx)) { + if (! gn_system_verilog()) { + cerr << get_fileline() << ": internal error: " + <<"Found (and using) default function argument " + << "requires SystemVerilog." << endl; + des->errors += 1; + } + parms[pidx] = def->port_defe(pidx); + } else { missing_parms += 1; parms[pidx] = 0; diff --git a/elaborate.cc b/elaborate.cc index 5e7ff9814..2e1ba1895 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -3246,29 +3246,7 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const assert(def); - unsigned parm_count = parms_.size(); - - if (debug_elaborate) { - cerr << get_fileline() << "PCallTask::elaborate_usr: " - << "Elaborate call to task " << task->basename() - << " width " << parm_count << " arguments." << endl; - } - - // Handle special case that the definition has no arguments - // but the parser found a single nul argument. This is an - // argument of the parser allowing for the possibility of - // default values for argumets: The parser cannot tell the - // difference between "func()" and "func()". - if (def->port_count() == 0 && parm_count == 1 && parms_[0] == 0) - parm_count = 0; - - if (parm_count != def->port_count()) { - cerr << get_fileline() << ": error: Port count mismatch in call to ``" - << path_ << "''. Got " << parm_count - << " ports, expecting " << def->port_count() << " ports." << endl; - des->errors += 1; - return 0; - } + unsigned parm_count = def->port_count(); /* Handle non-automatic tasks with no parameters specially. There is no need to make a sequential block to hold the generated code. */ @@ -3418,6 +3396,14 @@ NetProc* PCallTask::elaborate_build_call_(Design*des, NetScope*scope, unsigned parm_count = def->port_count(); + if (parms_.size() > parm_count) { + cerr << get_fileline() << ": error: " + << "Too many arguments (" << parms_.size() + << ", expecting " << parm_count << ")" + << " in call to task." << endl; + des->errors += 1; + } + NetBlock*block = new NetBlock(NetBlock::SEQU, 0); block->set_line(*this); @@ -3476,7 +3462,7 @@ NetProc* PCallTask::elaborate_build_call_(Design*des, NetScope*scope, NetExpr*rv = 0; - if (parms_[parms_idx]) { + if (parms_idx (rv)) { cerr << evt->get_fileline() << ": error: An event '" @@ -3494,6 +3480,8 @@ NetProc* PCallTask::elaborate_build_call_(Design*des, NetScope*scope, des->errors += 1; } rv = def->port_defe(idx); + if (lv_type==IVL_VT_BOOL||lv_type==IVL_VT_LOGIC) + rv = pad_to_width(rv->dup_expr(), wid, *this); } else { cerr << get_fileline() << ": error: " diff --git a/net_func.cc b/net_func.cc index 40838751f..8518fbd32 100644 --- a/net_func.cc +++ b/net_func.cc @@ -114,15 +114,6 @@ bool PECallFunction::check_call_matches_definition_(Design*des, NetScope*dscope) return false; } - if (parms_count != dscope->func_def()->port_count()) { - cerr << get_fileline() << ": error: Function " << scope_path(dscope) - << " expects " << (dscope->func_def()->port_count()) - << " arguments, you passed " << parms_count << "." - << endl; - des->errors += 1; - return false; - } - return true; }