Internals: Use visitor to refactor Ctors, prep for (#3815)
This commit is contained in:
parent
bb44d4e4f2
commit
afd7c2ae25
106
src/V3CCtors.cpp
106
src/V3CCtors.cpp
|
|
@ -130,6 +130,72 @@ private:
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
|
|
||||||
|
// Link state, as a visitor of each AstNode
|
||||||
|
|
||||||
|
class CCtorsVisitor final : public VNVisitor {
|
||||||
|
private:
|
||||||
|
// NODE STATE
|
||||||
|
|
||||||
|
// STATE
|
||||||
|
AstNodeModule* m_modp = nullptr; // Current module
|
||||||
|
V3CCtorsBuilder* m_varResetp = nullptr; // Builder of _ctor_var_reset
|
||||||
|
|
||||||
|
// VISITs
|
||||||
|
void visit(AstNodeModule* nodep) override {
|
||||||
|
VL_RESTORER(m_modp);
|
||||||
|
VL_RESTORER(m_varResetp);
|
||||||
|
m_modp = nodep;
|
||||||
|
V3CCtorsBuilder var_reset{nodep, "_ctor_var_reset",
|
||||||
|
VN_IS(nodep, Class) ? VCtorType::CLASS : VCtorType::MODULE};
|
||||||
|
m_varResetp = &var_reset;
|
||||||
|
iterateChildren(nodep);
|
||||||
|
|
||||||
|
if (v3Global.opt.coverage()) {
|
||||||
|
V3CCtorsBuilder configure_coverage{nodep, "_configure_coverage", VCtorType::COVERAGE};
|
||||||
|
for (AstNode* np = nodep->stmtsp(); np; np = np->nextp()) {
|
||||||
|
if (AstCoverDecl* const coverp = VN_CAST(np, CoverDecl)) {
|
||||||
|
np = coverp->backp();
|
||||||
|
configure_coverage.add(coverp->unlinkFrBack());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (AstClass* const classp = VN_CAST(nodep, Class)) {
|
||||||
|
AstCFunc* const funcp = new AstCFunc{classp->fileline(), "~", nullptr, ""};
|
||||||
|
funcp->isDestructor(true);
|
||||||
|
funcp->isStatic(false);
|
||||||
|
// If can be referred to by base pointer, need virtual delete
|
||||||
|
funcp->isVirtual(classp->isExtended());
|
||||||
|
funcp->slow(false);
|
||||||
|
classp->addStmtsp(funcp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void visit(AstCFunc* nodep) override {
|
||||||
|
VL_RESTORER(m_varResetp);
|
||||||
|
m_varResetp = nullptr;
|
||||||
|
iterateChildren(nodep);
|
||||||
|
}
|
||||||
|
void visit(AstVar* nodep) override {
|
||||||
|
if (m_varResetp && !nodep->isIfaceParent() && !nodep->isIfaceRef() && !nodep->noReset()
|
||||||
|
&& !nodep->isParam()
|
||||||
|
&& !(nodep->basicp()
|
||||||
|
&& (nodep->basicp()->isEvent() || nodep->basicp()->isTriggerVec()))) {
|
||||||
|
const auto vrefp = new AstVarRef{nodep->fileline(), nodep, VAccess::WRITE};
|
||||||
|
m_varResetp->add(new AstCReset{nodep->fileline(), vrefp});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void visit(AstConstPool*) override {}
|
||||||
|
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||||
|
|
||||||
|
public:
|
||||||
|
// CONSTRUCTORS
|
||||||
|
CCtorsVisitor(AstNode* nodep) { iterate(nodep); }
|
||||||
|
~CCtorsVisitor() override = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
//######################################################################
|
||||||
|
|
||||||
void V3CCtors::evalAsserts() {
|
void V3CCtors::evalAsserts() {
|
||||||
AstNodeModule* const modp = v3Global.rootp()->modulesp(); // Top module wrapper
|
AstNodeModule* const modp = v3Global.rootp()->modulesp(); // Top module wrapper
|
||||||
AstCFunc* const funcp
|
AstCFunc* const funcp
|
||||||
|
|
@ -178,42 +244,6 @@ void V3CCtors::evalAsserts() {
|
||||||
void V3CCtors::cctorsAll() {
|
void V3CCtors::cctorsAll() {
|
||||||
UINFO(2, __FUNCTION__ << ": " << endl);
|
UINFO(2, __FUNCTION__ << ": " << endl);
|
||||||
evalAsserts();
|
evalAsserts();
|
||||||
for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp;
|
{ CCtorsVisitor{v3Global.rootp()}; }
|
||||||
modp = VN_AS(modp->nextp(), NodeModule)) {
|
V3Global::dumpCheckGlobalTree("cctors", 0, dumpTree() >= 3);
|
||||||
// Process each module in turn
|
|
||||||
{
|
|
||||||
V3CCtorsBuilder var_reset{modp, "_ctor_var_reset",
|
|
||||||
VN_IS(modp, Class) ? VCtorType::CLASS : VCtorType::MODULE};
|
|
||||||
|
|
||||||
for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) {
|
|
||||||
if (AstVar* const varp = VN_CAST(np, Var)) {
|
|
||||||
if (!varp->isIfaceParent() && !varp->isIfaceRef() && !varp->noReset()
|
|
||||||
&& !varp->isParam()
|
|
||||||
&& !(varp->basicp()
|
|
||||||
&& (varp->basicp()->isEvent() || varp->basicp()->isTriggerVec()))) {
|
|
||||||
const auto vrefp = new AstVarRef{varp->fileline(), varp, VAccess::WRITE};
|
|
||||||
var_reset.add(new AstCReset{varp->fileline(), vrefp});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (v3Global.opt.coverage()) {
|
|
||||||
V3CCtorsBuilder configure_coverage{modp, "_configure_coverage", VCtorType::COVERAGE};
|
|
||||||
for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) {
|
|
||||||
if (AstCoverDecl* const coverp = VN_CAST(np, CoverDecl)) {
|
|
||||||
np = coverp->backp();
|
|
||||||
configure_coverage.add(coverp->unlinkFrBack());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (const AstClass* const classp = VN_CAST(modp, Class)) {
|
|
||||||
AstCFunc* const funcp = new AstCFunc{modp->fileline(), "~", nullptr, ""};
|
|
||||||
funcp->isDestructor(true);
|
|
||||||
funcp->isStatic(false);
|
|
||||||
// If can be referred to by base pointer, need virtual delete
|
|
||||||
funcp->isVirtual(classp->isExtended());
|
|
||||||
funcp->slow(false);
|
|
||||||
modp->addStmtsp(funcp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue