Handle default expressions anywhere in port expression list.

This commit is contained in:
Stephen Williams 2013-09-15 15:47:57 -07:00
parent d9e1bcf3d0
commit 46f551073e
3 changed files with 22 additions and 26 deletions

View File

@ -4604,14 +4604,8 @@ NetExpr* PENewClass::elaborate_expr(Design*des, NetScope*scope,
int parm_errors = 0;
for (size_t idx = 1 ; idx < parms.size() ; idx += 1) {
// While there are default arguments, check them.
if (idx <= parms_.size()) {
if (idx <= parms_.size() && parms_[idx-1]) {
PExpr*tmp = parms_[idx-1];
if (tmp == 0) {
parms[idx] = 0;
missing_parms += 1;
continue;
}
parms[idx] = elaborate_rval_expr(des, scope, def->port(idx)->data_type(),
def->port(idx)->vector_width(),
tmp, false);

38
parse.y
View File

@ -167,6 +167,18 @@ template <class T> void append(vector<T>&out, const vector<T>&in)
out.push_back(in[idx]);
}
/*
* Look at the list and pull null pointers off the end.
*/
static void strip_tail_items(list<PExpr*>*lst)
{
while (lst->size() > 0) {
if (lst->back() != 0)
return;
lst->pop_back();
}
}
/*
* This is a shorthand for making a PECallFunction that takes a single
* arg. This is used by some of the code that detects built-ins.
@ -855,13 +867,10 @@ class_item_qualifier_opt
;
class_new /* IEEE1800-2005 A.2.4 */
: K_new '(' ')'
{ PENewClass*tmp = new PENewClass;
FILE_NAME(tmp, @1);
$$ = tmp;
}
| K_new '(' expression_list_proper ')'
{ PENewClass*tmp = new PENewClass(*$3);
: K_new '(' expression_list_with_nuls ')'
{ list<PExpr*>*expr_list = $3;
strip_tail_items(expr_list);
PENewClass*tmp = new PENewClass(*expr_list);
FILE_NAME(tmp, @1);
delete $3;
$$ = tmp;
@ -3035,8 +3044,10 @@ expr_primary
function call. If a system identifier, then a system function
call. */
| hierarchy_identifier '(' expression_list_proper ')'
{ PECallFunction*tmp = pform_make_call_function(@1, *$1, *$3);
| hierarchy_identifier '(' expression_list_with_nuls ')'
{ list<PExpr*>*expr_list = $3;
strip_tail_items(expr_list);
PECallFunction*tmp = pform_make_call_function(@1, *$1, *expr_list);
delete $1;
$$ = tmp;
}
@ -3047,15 +3058,6 @@ expr_primary
delete[]$1;
$$ = tmp;
}
| hierarchy_identifier '(' ')'
{ const list<PExpr*> empty;
PECallFunction*tmp = pform_make_call_function(@1, *$1, empty);
delete $1;
$$ = tmp;
if (!gn_system_verilog()) {
yyerror(@1, "error: Empty function argument list requires SystemVerilog.");
}
}
| PACKAGE_IDENTIFIER K_SCOPE_RES IDENTIFIER '(' expression_list_proper ')'
{ perm_string use_name = lex_strings.make($3);
PECallFunction*tmp = new PECallFunction($1, use_name, *$5);

View File

@ -306,7 +306,7 @@ void PENewClass::dump(ostream&out) const
parms_[0]->dump(out);
for (size_t idx = 1 ; idx < parms_.size() ; idx += 1) {
out << ", ";
parms_[idx]->dump(out);
if (parms_[idx]) parms_[idx]->dump(out);
}
}
out << ")";