Support for static method calls as default values of function arguments (#4378)

This commit is contained in:
Ryszard Rozak 2023-07-21 09:27:00 +02:00 committed by GitHub
parent 5a694ccb8a
commit a6015863d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 5 deletions

View File

@ -1546,6 +1546,13 @@ private:
iterateChildren(nodep); iterateChildren(nodep);
m_insStmtp = nullptr; // Next thing should be new statement m_insStmtp = nullptr; // Next thing should be new statement
} }
void visit(AstVar* nodep) override {
if (nodep->isFuncLocal() && nodep->direction() == VDirection::INPUT && nodep->valuep()) {
// It's the default value of optional argument.
// Such values are added to function calls on this stage and aren't needed here.
pushDeletep(nodep->valuep()->unlinkFrBack());
}
}
void visit(AstStmtExpr* nodep) override { void visit(AstStmtExpr* nodep) override {
m_insMode = IM_BEFORE; m_insMode = IM_BEFORE;
m_insStmtp = nodep; m_insStmtp = nodep;
@ -1658,7 +1665,14 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
<< portp->prettyNameQ() << " in function call to " << portp->prettyNameQ() << " in function call to "
<< nodep->taskp()->prettyTypeName()); << nodep->taskp()->prettyTypeName());
newvaluep = new AstConst{nodep->fileline(), AstConst::Unsized32{}, 0}; newvaluep = new AstConst{nodep->fileline(), AstConst::Unsized32{}, 0};
} else if (!VN_IS(portp->valuep(), Const)) { } else if (AstFuncRef* const funcRefp = VN_CAST(portp->valuep(), FuncRef)) {
const AstNodeFTask* const funcp = funcRefp->taskp();
if (funcp->classMethod() && funcp->lifetime().isStatic()) newvaluep = funcRefp;
} else if (AstConst* const constp = VN_CAST(portp->valuep(), Const)) {
newvaluep = constp;
}
if (!newvaluep) {
// The default value for this port might be a constant // The default value for this port might be a constant
// expression that hasn't been folded yet. Try folding it // expression that hasn't been folded yet. Try folding it
// now; we don't have much to lose if it fails. // now; we don't have much to lose if it fails.
@ -1672,12 +1686,9 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
<< portp->prettyNameQ() << " in function call to " << portp->prettyNameQ() << " in function call to "
<< nodep->taskp()->prettyTypeName()); << nodep->taskp()->prettyTypeName());
newvaluep = new AstConst{nodep->fileline(), AstConst::Unsized32{}, 0}; newvaluep = new AstConst{nodep->fileline(), AstConst::Unsized32{}, 0};
} else { }
}
newvaluep = newvaluep->cloneTree(true); newvaluep = newvaluep->cloneTree(true);
}
} else {
newvaluep = VN_AS(portp->valuep(), NodeExpr)->cloneTree(true);
}
// To avoid problems with callee needing to know to deleteTree // To avoid problems with callee needing to know to deleteTree
// or not, we make this into a pin // or not, we make this into a pin
UINFO(9, "Default pin for " << portp << endl); UINFO(9, "Default pin for " << portp << endl);

View File

@ -19,6 +19,17 @@ function automatic logic [1:0] foo
return x + y; return x + y;
endfunction endfunction
class Foo;
static int x;
function static int get_x;
return x;
endfunction
endclass
function int mult2(int x = Foo::get_x());
return 2 * x;
endfunction
module t (/*AUTOARG*/); module t (/*AUTOARG*/);
logic [1:0] foo_val; logic [1:0] foo_val;
@ -26,6 +37,11 @@ module t (/*AUTOARG*/);
foo_val = foo(); foo_val = foo();
if (foo_val != 2'b10) $stop; if (foo_val != 2'b10) $stop;
if (mult2(1) != 2) $stop;
if (mult2() != 0) $stop;
Foo::x = 30;
if (mult2() != 60) $stop;
$write("*-* All Finished *-*\n"); $write("*-* All Finished *-*\n");
$finish; $finish;
end end