diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index b7ab752a8..65ef1bcd7 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -3938,22 +3938,66 @@ public: }; class AstNew : public AstNodeMath { + // New as constructor + // Don't need the class we are extracting from, as the "fromp()"'s datatype can get us to it // Parents: math|stmt // Children: varref|arraysel, math public: - explicit AstNew(FileLine* fl) + AstNew(FileLine* fl, AstNode* argsp) : ASTGEN_SUPER(fl) { dtypep(NULL); // V3Width will resolve + addNOp2p(argsp); } ASTNODE_NODE_FUNCS(New) - virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { - V3ERROR_NA; /* How can from be a const? */ } virtual V3Hash sameHash() const { return V3Hash(); } virtual string emitVerilog() { return "new"; } virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() const { return true; } virtual bool same(const AstNode* samep) const { return true; } virtual int instrCount() const { return widthInstrs(); } + AstNode* argsp() const { return op2p(); } +}; + +class AstNewCopy : public AstNodeMath { + // New as shallow copy + // Parents: math|stmt + // Children: varref|arraysel, math +public: + AstNewCopy(FileLine* fl, AstNode* rhsp) + : ASTGEN_SUPER(fl) { + dtypeFrom(rhsp); // otherwise V3Width will resolve + setNOp1p(rhsp); + } + ASTNODE_NODE_FUNCS(NewCopy) + virtual V3Hash sameHash() const { return V3Hash(); } + virtual string emitVerilog() { return "new"; } + virtual string emitC() { V3ERROR_NA; return ""; } + virtual bool cleanOut() const { return true; } + virtual bool same(const AstNode* samep) const { return true; } + virtual int instrCount() const { return widthInstrs(); } + AstNode* rhsp() const { return op1p(); } +}; + +class AstNewDynamic : public AstNodeMath { + // New for dynamic array + // Parents: math|stmt + // Children: varref|arraysel, math +public: + AstNewDynamic(FileLine* fl, AstNode* sizep, AstNode* rhsp) + : ASTGEN_SUPER(fl) { + dtypeFrom(rhsp); // otherwise V3Width will resolve + setNOp1p(sizep); + setNOp2p(rhsp); + } + ASTNODE_NODE_FUNCS(NewDynamic) + virtual V3Hash sameHash() const { return V3Hash(); } + virtual string emitVerilog() { return "new"; } + virtual string emitC() { V3ERROR_NA; return ""; } + virtual bool cleanOut() const { return true; } + virtual bool same(const AstNode* samep) const { return true; } + virtual int instrCount() const { return widthInstrs(); } + AstNode* sizep() const { return sizep(); } + AstNode* rhsp() const { return op2p(); } }; class AstPragma : public AstNode { diff --git a/src/V3EmitCInlines.cpp b/src/V3EmitCInlines.cpp index 39a78e140..9cd64af07 100644 --- a/src/V3EmitCInlines.cpp +++ b/src/V3EmitCInlines.cpp @@ -62,6 +62,10 @@ class EmitCInlines : EmitCBaseVisitor { v3Global.needHeavy(true); iterateChildren(nodep); } + virtual void visit(AstNew* nodep) VL_OVERRIDE { + if (v3Global.opt.savable()) v3error("Unsupported: --savable with dynamic new"); + iterateChildren(nodep); + } virtual void visit(AstAtoN* nodep) VL_OVERRIDE { v3Global.needHeavy(true); iterateChildren(nodep); diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 0f886eea2..497bc928c 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -2288,13 +2288,24 @@ private: virtual void visit(AstNew* nodep) VL_OVERRIDE { if (nodep->didWidthAndSet()) return; - userIterateChildren(nodep, WidthVP(SELF, BOTH).p()); AstClassRefDType* refp = VN_CAST(m_vup->dtypeNullp(), ClassRefDType); if (!refp) { // e.g. int a = new; nodep->v3error("new() not expected in this context"); return; } nodep->dtypep(refp); + if (nodep->argsp()) { + nodep->v3error("Unsupported: new with arguments"); + userIterateChildren(nodep, WidthVP(SELF, BOTH).p()); + } + } + virtual void visit(AstNewCopy* nodep) VL_OVERRIDE { + if (nodep->didWidthAndSet()) return; + nodep->v3error("Unsupported: new-as-copy"); + } + virtual void visit(AstNewDynamic* nodep) VL_OVERRIDE { + if (nodep->didWidthAndSet()) return; + nodep->v3error("Unsupported: Dynamic array new"); } virtual void visit(AstPattern* nodep) VL_OVERRIDE { diff --git a/src/verilog.y b/src/verilog.y index 70c6288e0..1a4d5cb00 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -2903,15 +2903,14 @@ finc_or_dec_expression: // ==IEEE: inc_or_dec_expression class_new: // ==IEEE: class_new // // Special precence so (...) doesn't match expr - yNEW__ETC { $$ = new AstNew($1); } - | yNEW__ETC expr { $$ = new AstNew($1); BBUNSUP($1, "Unsupported: new with expression"); } - // // Grammer abiguity; we assume "new (x)" the () are a argument, not expr - | yNEW__PAREN '(' list_of_argumentsE ')' { $$ = new AstNew($1); BBUNSUP($1, "Unsupported: new with arguments"); } + yNEW__ETC { $$ = new AstNew($1, NULL); } + | yNEW__ETC expr { $$ = new AstNewCopy($1, $2); } + | yNEW__PAREN '(' list_of_argumentsE ')' { $$ = new AstNew($1, $3); } ; dynamic_array_new: // ==IEEE: dynamic_array_new - yNEW__ETC '[' expr ']' { $$ = new AstNew($1); BBUNSUP($1, "Unsupported: Dynamic array new"); } - | yNEW__ETC '[' expr ']' '(' expr ')' { $$ = new AstNew($1); BBUNSUP($1, "Unsupported: Dynamic array new"); } + yNEW__ETC '[' expr ']' { $$ = new AstNewDynamic($1, $3, NULL); } + | yNEW__ETC '[' expr ']' '(' expr ')' { $$ = new AstNewDynamic($1, $3, $6); } ; //************************************************ @@ -5579,8 +5578,8 @@ class_method: // ==IEEE: class_method class_item_qualifier: // IEEE: class_item_qualifier minus ySTATIC // // IMPORTANT: yPROTECTED | yLOCAL is in a lex rule - yPROTECTED { $$ = NULL; } // Ignoring protected until implemented - | yLOCAL__ETC { $$ = NULL; BBUNSUP($1, "Unsupported: 'local' class item"); } + yPROTECTED { $$ = NULL; } // Ignoring protected until warning implemented + | yLOCAL__ETC { $$ = NULL; } // Ignoring local until warning implemented | ySTATIC__ETC { $$ = NULL; BBUNSUP($1, "Unsupported: 'static' class item"); } ; diff --git a/test_regress/t/t_class_unsup_bad.out b/test_regress/t/t_class_unsup_bad.out index 7d5a2eb29..db3c6788c 100644 --- a/test_regress/t/t_class_unsup_bad.out +++ b/test_regress/t/t_class_unsup_bad.out @@ -10,9 +10,6 @@ class C #(parameter P=1); %Error: t/t_class_unsup_bad.v:13: Unsupported: class parameters localparam LOCPAR = 10; ^ -%Error: t/t_class_unsup_bad.v:16: Unsupported: 'local' class item - local int loc; - ^~~~~ %Error: t/t_class_unsup_bad.v:24: Unsupported: virtual class member qualifier virtual function void func_virtual; endfunction ^~~~~~~