Internals: Move 'new' unsupported forward from parse into Ast.

This commit is contained in:
Wilson Snyder 2020-03-05 22:33:31 -05:00
parent 75ecad591a
commit 135cbcd79a
5 changed files with 70 additions and 15 deletions

View File

@ -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 {

View File

@ -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);

View File

@ -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 {

View File

@ -2903,15 +2903,14 @@ finc_or_dec_expression<nodep>: // ==IEEE: inc_or_dec_expression
class_new<nodep>: // ==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<nodep>: // ==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<nodep>: // ==IEEE: class_method
class_item_qualifier<nodep>: // 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"); }
;

View File

@ -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
^~~~~~~