Fix handling of super.new calls (#4366)
This commit is contained in:
parent
4bdda3f240
commit
4de1b22672
|
|
@ -234,6 +234,21 @@ public:
|
|||
string optionalProcArg(const T* const nodep) {
|
||||
return (nodep && constructorNeedsProcess(nodep)) ? "vlProcess, " : "";
|
||||
}
|
||||
const AstCNew* getSuperNewCallRecursep(AstNode* const nodep) {
|
||||
// Get the super.new call
|
||||
if (!nodep) return nullptr;
|
||||
if (const AstCNew* const cnewp = VN_CAST(nodep, CNew)) return cnewp;
|
||||
if (const AstStmtExpr* const stmtp = VN_CAST(nodep, StmtExpr)) {
|
||||
if (const AstCNew* const cnewp = VN_CAST(stmtp->exprp(), CNew)) return cnewp;
|
||||
}
|
||||
if (const AstJumpBlock* const blockp = VN_CAST(nodep, JumpBlock)) {
|
||||
if (const AstCNew* const cnewp = getSuperNewCallRecursep(blockp->stmtsp())) {
|
||||
return cnewp;
|
||||
}
|
||||
}
|
||||
if (const AstCNew* const cnewp = getSuperNewCallRecursep(nodep->nextp())) return cnewp;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
using EmitCConstInit::visit;
|
||||
|
|
@ -256,24 +271,16 @@ public:
|
|||
puts(": ");
|
||||
puts(nodep->baseCtors());
|
||||
const AstClass* const classp = VN_CAST(nodep->scopep()->modp(), Class);
|
||||
bool baseCtorCall = false;
|
||||
// Find call to super.new to get the arguments
|
||||
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
AstNode* exprp;
|
||||
if (VN_IS(stmtp, StmtExpr)) {
|
||||
exprp = VN_CAST(stmtp, StmtExpr)->exprp();
|
||||
} else {
|
||||
exprp = stmtp;
|
||||
}
|
||||
if (AstCNew* const newRefp = VN_CAST(exprp, CNew)) {
|
||||
puts("(" + optionalProcArg(classp) + "vlSymsp");
|
||||
baseCtorCall = true;
|
||||
putCommaIterateNext(newRefp->argsp(), true);
|
||||
puts(")");
|
||||
break;
|
||||
}
|
||||
if (classp && constructorNeedsProcess(classp)) {
|
||||
puts("(vlProcess, vlSymsp");
|
||||
} else {
|
||||
puts("(vlSymsp");
|
||||
}
|
||||
if (!baseCtorCall) { puts("(" + optionalProcArg(classp) + "vlSymsp)"); }
|
||||
const AstCNew* const superNewCallp = getSuperNewCallRecursep(nodep->stmtsp());
|
||||
UASSERT_OBJ(superNewCallp, nodep, "super.new call not found");
|
||||
putCommaIterateNext(superNewCallp->argsp(), true);
|
||||
puts(")");
|
||||
}
|
||||
puts(" {\n");
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,16 @@ class BarArg extends FooArg;
|
|||
endfunction
|
||||
endclass
|
||||
|
||||
class BarArgWithReturnInIf extends FooArg;
|
||||
function new (int a);
|
||||
super.new(a);
|
||||
if (a < 10) begin
|
||||
return;
|
||||
end
|
||||
this.x = 20;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
class BarExpr extends FooArg;
|
||||
function new (int a, string b);
|
||||
super.new(a + b.len());
|
||||
|
|
@ -114,6 +124,7 @@ module t (/*AUTOARG*/
|
|||
NewWithoutSuper newWithoutSuper;
|
||||
NoNewParam#(2) noNewParam;
|
||||
NewWithoutSuperParam#(1) newWithoutSuperParam;
|
||||
BarArgWithReturnInIf barIf1, barIf10;
|
||||
|
||||
initial begin
|
||||
bar = new;
|
||||
|
|
@ -136,6 +147,10 @@ module t (/*AUTOARG*/
|
|||
`checkh(noNewParam.x, 1);
|
||||
newWithoutSuperParam = new;
|
||||
`checkh(newWithoutSuperParam.x, 1);
|
||||
barIf1 = new(1);
|
||||
`checkh(barIf1.x, 1);
|
||||
barIf10 = new(10);
|
||||
`checkh(barIf10.x, 20);
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
|
|
|
|||
Loading…
Reference in New Issue