mirror of
https://github.com/verilator/verilator.git
synced 2026-10-02 16:13:34 +02:00
Support for static method calls as default values of function arguments (#4378)
This commit is contained in:
+16
-5
@@ -1546,6 +1546,13 @@ private:
|
||||
iterateChildren(nodep);
|
||||
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 {
|
||||
m_insMode = IM_BEFORE;
|
||||
m_insStmtp = nodep;
|
||||
@@ -1658,7 +1665,14 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
|
||||
<< portp->prettyNameQ() << " in function call to "
|
||||
<< nodep->taskp()->prettyTypeName());
|
||||
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
|
||||
// expression that hasn't been folded yet. Try folding it
|
||||
// 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 "
|
||||
<< nodep->taskp()->prettyTypeName());
|
||||
newvaluep = new AstConst{nodep->fileline(), AstConst::Unsized32{}, 0};
|
||||
} else {
|
||||
newvaluep = newvaluep->cloneTree(true);
|
||||
}
|
||||
} else {
|
||||
newvaluep = VN_AS(portp->valuep(), NodeExpr)->cloneTree(true);
|
||||
}
|
||||
newvaluep = newvaluep->cloneTree(true);
|
||||
// To avoid problems with callee needing to know to deleteTree
|
||||
// or not, we make this into a pin
|
||||
UINFO(9, "Default pin for " << portp << endl);
|
||||
|
||||
@@ -19,6 +19,17 @@ function automatic logic [1:0] foo
|
||||
return x + y;
|
||||
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*/);
|
||||
logic [1:0] foo_val;
|
||||
|
||||
@@ -26,6 +37,11 @@ module t (/*AUTOARG*/);
|
||||
foo_val = foo();
|
||||
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");
|
||||
$finish;
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user