diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 1cc314c45..bea5bd1dd 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -3015,6 +3015,21 @@ public: void cname(const string& cname) { m_cname = cname; } }; +class AstWith : public AstNodeStmt { +public: + AstWith(FileLine* fl, bool stmt, AstNode* funcrefp, AstNode* argsp) + : ASTGEN_SUPER(fl) { + statement(stmt); + setOp1p(funcrefp); + addNOp2p(argsp); + } + ASTNODE_NODE_FUNCS(With) + virtual V3Hash sameHash() const { return V3Hash(); } + virtual bool same(const AstNode* samep) const { return true; } + // + AstNode* funcrefp() const { return op1p(); } +}; + //###################################################################### class AstSenItem : public AstNodeSenItem { diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index bbb8011d6..e5591458e 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -2402,6 +2402,11 @@ private: } m_ds = lastStates; } + virtual void visit(AstWith* nodep) VL_OVERRIDE { + nodep->v3warn(E_UNSUPPORTED, "Unsupported: with statements"); + nodep->replaceWith(nodep->funcrefp()->unlinkFrBack()); + VL_DO_DANGLING(nodep->deleteTree(), nodep); + } virtual void visit(AstVar* nodep) VL_OVERRIDE { checkNoDot(nodep); iterateChildren(nodep); diff --git a/src/verilog.y b/src/verilog.y index 1a1cd7d62..0c37189f7 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -3430,9 +3430,9 @@ task_subroutine_callNoMethod: // function_subroutine_callNoMethod (as tas // // IEEE: tf_call taskRef { $$ = $1; } // // funcref below not task ref to avoid conflict, must later handle either - | funcRef yWITH__PAREN '(' expr ')' { $$ = $1; BBUNSUP($2, "Unsupported: 'with' on task call"); } + | funcRef yWITH__PAREN '(' expr ')' { $$ = new AstWith($2, true, $1, $4); } // // can call as method and yWITH without parenthesis - | id yWITH__PAREN '(' expr ')' { $$ = new AstFuncRef($1, *$1, NULL); BBUNSUP($2, "Unsupported: 'with' on task call"); } + | id yWITH__PAREN '(' expr ')' { $$ = new AstWith($2, true, new AstFuncRef($1, *$1, NULL), $4); } | system_t_call { $$ = $1; } // // IEEE: method_call requires a "." so is in expr // // IEEE: ['std::'] not needed, as normal std package resolution will find it @@ -3445,9 +3445,9 @@ task_subroutine_callNoMethod: // function_subroutine_callNoMethod (as tas function_subroutine_callNoMethod: // IEEE: function_subroutine_call (as function) // // IEEE: tf_call funcRef { $$ = $1; } - | funcRef yWITH__PAREN '(' expr ')' { $$ = $1; BBUNSUP($2, "Unsupported: 'with' on function call"); } + | funcRef yWITH__PAREN '(' expr ')' { $$ = new AstWith($2, false, $1, $4); } // // can call as method and yWITH without parenthesis - | id yWITH__PAREN '(' expr ')' { $$ = new AstFuncRef($1, *$1, NULL); BBUNSUP($2, "Unsupported: 'with' on function call"); } + | id yWITH__PAREN '(' expr ')' { $$ = new AstWith($2, false, new AstFuncRef($1, *$1, NULL), $4); } | system_f_call { $$ = $1; } // // IEEE: method_call requires a "." so is in expr // // IEEE: ['std::'] not needed, as normal std package resolution will find it @@ -3919,7 +3919,7 @@ parenE: // // IEEE: built_in_method_call // // method_call_root not needed, part of expr resolution // // What's left is below array_methodNoRoot -array_methodNoRoot: +array_methodNoRoot: yOR { $$ = new AstFuncRef($1, "or", NULL); } | yAND { $$ = new AstFuncRef($1, "and", NULL); } | yXOR { $$ = new AstFuncRef($1, "xor", NULL); } @@ -3929,9 +3929,9 @@ array_methodNoRoot: array_methodWith: array_methodNoRoot { $$ = $1; } | array_methodNoRoot parenE yWITH__PAREN '(' expr ')' - { $$ = $1; BBUNSUP($5, "Unsupported: 'with' on method call"); } + { $$ = new AstWith($3, false, $1, $5); } | array_methodNoRoot '(' expr ')' yWITH__PAREN '(' expr ')' - { $$ = $1; BBUNSUP($7, "Unsupported: 'with' on method call"); } + { $$ = new AstWith($5, false, $1, $7); $1->addPinsp($3); } ; dpi_import_export: // ==IEEE: dpi_import_export diff --git a/test_regress/t/t_with_unsup.out b/test_regress/t/t_with_unsup.out index 596929544..62705e280 100644 --- a/test_regress/t/t_with_unsup.out +++ b/test_regress/t/t_with_unsup.out @@ -1,31 +1,31 @@ -%Error-UNSUPPORTED: t/t_with_unsup.v:19:31: Unsupported: 'with' on function call +%Error-UNSUPPORTED: t/t_with_unsup.v:19:31: Unsupported: with statements 19 | found = aliases.find(i) with (i == to_find); | ^~~~ -%Error-UNSUPPORTED: t/t_with_unsup.v:21:23: Unsupported: 'with' on task call +%Error-UNSUPPORTED: t/t_with_unsup.v:21:23: Unsupported: with statements 21 | aliases.find(i) with (i == to_find); | ^~~~ -%Error-UNSUPPORTED: t/t_with_unsup.v:24:28: Unsupported: 'with' on function call +%Error-UNSUPPORTED: t/t_with_unsup.v:24:28: Unsupported: with statements 24 | found = aliases.find with (item == i); | ^~~~ -%Error-UNSUPPORTED: t/t_with_unsup.v:25:20: Unsupported: 'with' on task call +%Error-UNSUPPORTED: t/t_with_unsup.v:25:20: Unsupported: with statements 25 | aliases.find with (item == i); | ^~~~ -%Error-UNSUPPORTED: t/t_with_unsup.v:29:36: Unsupported: 'with' on method call +%Error-UNSUPPORTED: t/t_with_unsup.v:29:30: Unsupported: with statements 29 | found = aliases.unique with (id); - | ^~ -%Error-UNSUPPORTED: t/t_with_unsup.v:30:38: Unsupported: 'with' on method call + | ^~~~ +%Error-UNSUPPORTED: t/t_with_unsup.v:30:32: Unsupported: with statements 30 | found = aliases.unique() with (id); - | ^~ -%Error-UNSUPPORTED: t/t_with_unsup.v:31:39: Unsupported: 'with' on method call + | ^~~~ +%Error-UNSUPPORTED: t/t_with_unsup.v:31:33: Unsupported: with statements 31 | found = aliases.unique(i) with (id); - | ^~ -%Error-UNSUPPORTED: t/t_with_unsup.v:32:32: Unsupported: 'with' on method call + | ^~~~ +%Error-UNSUPPORTED: t/t_with_unsup.v:32:26: Unsupported: with statements 32 | found = aliases.or with (id); - | ^~ -%Error-UNSUPPORTED: t/t_with_unsup.v:33:33: Unsupported: 'with' on method call + | ^~~~ +%Error-UNSUPPORTED: t/t_with_unsup.v:33:27: Unsupported: with statements 33 | found = aliases.and with (id); - | ^~ -%Error-UNSUPPORTED: t/t_with_unsup.v:34:33: Unsupported: 'with' on method call + | ^~~~ +%Error-UNSUPPORTED: t/t_with_unsup.v:34:27: Unsupported: with statements 34 | found = aliases.xor with (id); - | ^~ + | ^~~~ %Error: Exiting due to