Fix virtual methods (#4616)
This commit is contained in:
parent
17721aff55
commit
84125d7c92
|
|
@ -183,6 +183,7 @@ class AstNodeCCall VL_NOT_FINAL : public AstNodeExpr {
|
|||
// @astgen op2 := argsp : List[AstNodeExpr] // Note: op1 used by some sub-types only
|
||||
AstCFunc* m_funcp;
|
||||
string m_argTypes;
|
||||
bool m_superReference = false; // Called with super reference
|
||||
|
||||
protected:
|
||||
AstNodeCCall(VNType t, FileLine* fl, AstCFunc* funcp, AstNodeExpr* argsp = nullptr)
|
||||
|
|
@ -213,6 +214,8 @@ public:
|
|||
string emitVerilog() final override { V3ERROR_NA_RETURN(""); }
|
||||
string emitC() final override { V3ERROR_NA_RETURN(""); }
|
||||
bool cleanOut() const final override { return true; }
|
||||
bool superReference() const { return m_superReference; }
|
||||
void superReference(bool flag) { m_superReference = flag; }
|
||||
};
|
||||
class AstNodeFTaskRef VL_NOT_FINAL : public AstNodeExpr {
|
||||
// A reference to a task (or function)
|
||||
|
|
@ -4198,12 +4201,15 @@ public:
|
|||
// === AstNodeFTaskRef ===
|
||||
class AstFuncRef final : public AstNodeFTaskRef {
|
||||
// A reference to a function
|
||||
bool m_superReference = false; // Called with super reference
|
||||
public:
|
||||
AstFuncRef(FileLine* fl, AstParseRef* namep, AstNodeExpr* pinsp)
|
||||
: ASTGEN_SUPER_FuncRef(fl, (AstNode*)namep, pinsp) {}
|
||||
AstFuncRef(FileLine* fl, const string& name, AstNodeExpr* pinsp)
|
||||
: ASTGEN_SUPER_FuncRef(fl, name, pinsp) {}
|
||||
ASTGEN_MEMBERS_AstFuncRef;
|
||||
bool superReference() const { return m_superReference; }
|
||||
void superReference(bool flag) { m_superReference = flag; }
|
||||
};
|
||||
class AstMethodCall final : public AstNodeFTaskRef {
|
||||
// A reference to a member task (or function)
|
||||
|
|
@ -4240,6 +4246,7 @@ public:
|
|||
};
|
||||
class AstTaskRef final : public AstNodeFTaskRef {
|
||||
// A reference to a task
|
||||
bool m_superReference = false; // Called with super reference
|
||||
public:
|
||||
AstTaskRef(FileLine* fl, AstParseRef* namep, AstNodeExpr* pinsp)
|
||||
: ASTGEN_SUPER_TaskRef(fl, (AstNode*)namep, pinsp) {
|
||||
|
|
@ -4250,6 +4257,8 @@ public:
|
|||
dtypeSetVoid();
|
||||
}
|
||||
ASTGEN_MEMBERS_AstTaskRef;
|
||||
bool superReference() const { return m_superReference; }
|
||||
void superReference(bool flag) { m_superReference = flag; }
|
||||
};
|
||||
|
||||
// === AstNodePreSel ===
|
||||
|
|
|
|||
|
|
@ -486,7 +486,7 @@ public:
|
|||
// Call static method via the containing class
|
||||
puts(prefixNameProtect(funcModp) + "::");
|
||||
puts(funcp->nameProtect());
|
||||
} else if (VN_IS(funcModp, Class) && funcModp != m_modp) {
|
||||
} else if (nodep->superReference()) {
|
||||
// Calling superclass method
|
||||
puts(prefixNameProtect(funcModp) + "::");
|
||||
puts(funcp->nameProtect());
|
||||
|
|
|
|||
|
|
@ -2039,6 +2039,7 @@ private:
|
|||
DotPosition m_dotPos; // Scope part of dotted resolution
|
||||
VSymEnt* m_dotSymp; // SymEnt for dotted AstParse lookup
|
||||
const AstDot* m_dotp; // Current dot
|
||||
bool m_super; // Starts with super reference
|
||||
bool m_unresolvedCell; // Unresolved cell, needs help from V3Param
|
||||
bool m_unresolvedClass; // Unresolved class reference, needs help from V3Param
|
||||
AstNode* m_unlinkedScopep; // Unresolved scope, needs corresponding VarXRef
|
||||
|
|
@ -2050,6 +2051,7 @@ private:
|
|||
m_dotPos = DP_NONE;
|
||||
m_dotSymp = curSymp;
|
||||
m_dotp = nullptr;
|
||||
m_super = false;
|
||||
m_dotErr = false;
|
||||
m_dotText = "";
|
||||
m_unresolvedCell = false;
|
||||
|
|
@ -2061,6 +2063,7 @@ private:
|
|||
std::ostringstream sstr;
|
||||
sstr << "ds=" << names[m_dotPos];
|
||||
sstr << " dse" << cvtToHex(m_dotSymp);
|
||||
sstr << " sup=" << m_super;
|
||||
sstr << " txt=" << m_dotText;
|
||||
sstr << " unrCell=" << m_unresolvedCell;
|
||||
sstr << " unrClass=" << m_unresolvedClass;
|
||||
|
|
@ -2462,6 +2465,7 @@ private:
|
|||
const auto baseClassp = cextp->classp();
|
||||
UASSERT_OBJ(baseClassp, nodep, "Bad superclass");
|
||||
m_ds.m_dotSymp = m_statep->getNodeSym(baseClassp);
|
||||
m_ds.m_super = true;
|
||||
UINFO(8, " super. " << m_ds.ascii() << endl);
|
||||
}
|
||||
}
|
||||
|
|
@ -2538,7 +2542,6 @@ private:
|
|||
// Generally resolved during Primay, but might be at param time under AstUnlinkedRef
|
||||
UASSERT_OBJ(m_statep->forPrimary() || m_statep->forPrearray(), nodep,
|
||||
"ParseRefs should no longer exist");
|
||||
if (nodep->name() == "super") nodep->v3warn(E_UNSUPPORTED, "Unsupported: super");
|
||||
const DotStates lastStates = m_ds;
|
||||
const bool start = (m_ds.m_dotPos == DP_NONE); // Save, as m_dotp will be changed
|
||||
if (start) {
|
||||
|
|
@ -3079,6 +3082,14 @@ private:
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
if (m_ds.m_super) {
|
||||
if (AstFuncRef* const funcRefp = VN_CAST(nodep, FuncRef)) {
|
||||
funcRefp->superReference(true);
|
||||
} else if (AstTaskRef* const taskRefp = VN_CAST(nodep, TaskRef)) {
|
||||
taskRefp->superReference(true);
|
||||
}
|
||||
}
|
||||
|
||||
bool staticAccess = false;
|
||||
if (m_ds.m_unresolvedClass) {
|
||||
// Unable to link before V3Param
|
||||
|
|
|
|||
|
|
@ -310,6 +310,7 @@ private:
|
|||
baseRandCallp->taskp(baseRandomizep);
|
||||
baseRandCallp->dtypeFrom(baseRandomizep->dtypep());
|
||||
baseRandCallp->classOrPackagep(nodep->extendsp()->classp());
|
||||
baseRandCallp->superReference(true);
|
||||
beginValp = baseRandCallp;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -638,6 +638,12 @@ private:
|
|||
beginp->addNext(ccallp->makeStmt());
|
||||
}
|
||||
|
||||
if (const AstFuncRef* const funcRefp = VN_CAST(refp, FuncRef)) {
|
||||
ccallp->superReference(funcRefp->superReference());
|
||||
} else if (const AstTaskRef* const taskRefp = VN_CAST(refp, TaskRef)) {
|
||||
ccallp->superReference(taskRefp->superReference());
|
||||
}
|
||||
|
||||
// Convert complicated outputs to temp signals
|
||||
{
|
||||
const V3TaskConnects tconnects = V3Task::taskConnects(refp, refp->taskp()->stmtsp());
|
||||
|
|
|
|||
|
|
@ -22,12 +22,48 @@ class VB extends VBase;
|
|||
endfunction
|
||||
endclass
|
||||
|
||||
virtual class uvm_phase;
|
||||
virtual function int exec_func;
|
||||
return 0;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
class uvm_topdown_phase extends uvm_phase;
|
||||
function int get1;
|
||||
return exec_func();
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
class uvm_build_phase extends uvm_topdown_phase;
|
||||
virtual function int exec_func;
|
||||
return 1;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
virtual class Cls;
|
||||
uvm_phase ph;
|
||||
endclass
|
||||
|
||||
class ExtendsCls extends Cls;
|
||||
function new;
|
||||
uvm_build_phase bp = new;
|
||||
ph = bp;
|
||||
endfunction
|
||||
|
||||
function int get1;
|
||||
return super.ph.exec_func();
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
module t;
|
||||
initial begin
|
||||
VA va = new;
|
||||
VB vb = new;
|
||||
VBase b;
|
||||
|
||||
uvm_build_phase ph;
|
||||
ExtendsCls ec;
|
||||
|
||||
if (va.hello() != 2) $stop;
|
||||
if (vb.hello() != 3) $stop;
|
||||
|
||||
|
|
@ -35,6 +71,13 @@ module t;
|
|||
if (b.hello() != 2) $stop;
|
||||
b = vb;
|
||||
if (b.hello() != 3) $stop;
|
||||
|
||||
ph = new;
|
||||
if (ph.get1() != 1) $stop;
|
||||
|
||||
ec = new;
|
||||
if (ec.get1() != 1) $stop;
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in New Issue