Emit: Factor out parent module access via user4

No functional change.
This commit is contained in:
Geza Lore 2021-07-22 15:53:42 +01:00
parent 42d918c163
commit 8bb77f86ec
4 changed files with 50 additions and 24 deletions

View File

@ -20,11 +20,26 @@
#include "V3EmitCBase.h"
#include "V3Task.h"
//######################################################################
// EmitCParentModule implementation
EmitCParentModule::EmitCParentModule() {
const auto setAll = [](AstNodeModule* modp) -> void {
for (AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (VN_IS(nodep, CFunc) || VN_IS(nodep, Var)) { nodep->user4p(modp); }
}
};
for (AstNode* modp = v3Global.rootp()->modulesp(); modp; modp = modp->nextp()) {
setAll(VN_CAST(modp, NodeModule));
}
setAll(v3Global.rootp()->constPoolp()->modp());
}
//######################################################################
// EmitCBaseVisitor implementation
string EmitCBaseVisitor::funcNameProtect(const AstCFunc* nodep, const AstNodeModule* modp) {
modp = modp ? modp : VN_CAST(nodep->user4p(), NodeModule);
modp = modp ? modp : EmitCParentModule::get(nodep);
string name;
if (nodep->isConstructor()) {
name += prefixNameProtect(modp);
@ -54,8 +69,7 @@ string EmitCBaseVisitor::cFuncArgs(const AstCFunc* nodep) {
string args;
if (nodep->isLoose() && !nodep->isStatic()) {
if (nodep->isConst().trueKnown()) args += "const ";
AstNodeModule* modp = VN_CAST(nodep->user4p(), NodeModule);
args += prefixNameProtect(modp);
args += prefixNameProtect(EmitCParentModule::get(nodep));
args += "* vlSelf";
}
if (!nodep->argTypes().empty()) {

View File

@ -27,6 +27,24 @@
#include <cstdarg>
#include <cmath>
//######################################################################
// Set user4p in all CFunc and Var to point to the containing AstNodeModule
class EmitCParentModule final {
// NODE STATE
// AstFunc::user4p() AstNodeModule* Parent module pointer
// AstVar::user4p() AstNodeModule* Parent module pointer
AstUser4InUse user4InUse;
public:
EmitCParentModule();
VL_UNCOPYABLE(EmitCParentModule);
static const AstNodeModule* get(const AstNode* nodep) {
return VN_CAST_CONST(nodep->user4p(), NodeModule);
}
};
//######################################################################
// Base Visitor class -- holds output file pointer

View File

@ -53,8 +53,7 @@ class EmitCLazyDecls final : public AstNVisitor {
// Already declared manually
if (m_emittedManually.count(funcp->nameProtect())) return;
// Needs lazy declaration, emit one
m_emitter.emitCFuncDecl(funcp, VN_CAST_CONST(funcp->user4p(), NodeModule),
funcp->dpiImportPrototype());
m_emitter.emitCFuncDecl(funcp, EmitCParentModule::get(funcp), funcp->dpiImportPrototype());
m_needsBlankLine = true;
}
@ -82,7 +81,9 @@ class EmitCLazyDecls final : public AstNVisitor {
virtual void visit(AstVarRef* nodep) override {
AstVar* const varp = nodep->varp();
// Only constant pool symbols are lazy declared for now ...
if (EmitCBaseVisitor::isConstPoolMod(varp->user4p())) { lazyDeclareConstPoolVar(varp); }
if (EmitCBaseVisitor::isConstPoolMod(EmitCParentModule::get(varp))) {
lazyDeclareConstPoolVar(varp);
}
}
virtual void visit(AstNode* nodep) override { iterateChildrenConst(nodep); }
@ -354,16 +355,17 @@ public:
}
virtual void visit(AstCCall* nodep) override {
const AstCFunc* const funcp = nodep->funcp();
const AstNodeModule* const funcModp = EmitCParentModule::get(funcp);
if (funcp->dpiImportPrototype()) {
// Calling DPI import
puts(funcp->name());
} else if (funcp->isProperMethod() && funcp->isStatic()) {
// Call static method via the containing class
puts(prefixNameProtect(funcp->user4p()) + "::");
puts(prefixNameProtect(funcModp) + "::");
puts(funcp->nameProtect());
} else if (VN_IS(funcp->user4p(), Class) && funcp->user4p() != m_modp) {
} else if (VN_IS(funcModp, Class) && funcModp != m_modp) {
// Calling superclass method
puts(prefixNameProtect(funcp->user4p()) + "::");
puts(prefixNameProtect(funcModp) + "::");
puts(funcp->nameProtect());
} else if (funcp->isLoose()) {
// Calling loose method
@ -1100,15 +1102,16 @@ public:
// Terminals
virtual void visit(AstVarRef* nodep) override {
const AstVar* const varp = nodep->varp();
if (isConstPoolMod(varp->user4p())) {
const AstNodeModule* const varModp = EmitCParentModule::get(varp);
if (isConstPoolMod(varModp)) {
// Reference to constant pool variable
puts(topClassName() + "__ConstPool__");
} else if (varp->isStatic()) {
// Access static variable via the containing class
puts(prefixNameProtect(varp->user4p()) + "::");
} else if (VN_IS(varp->user4p(), Class) && varp->user4p() != m_modp) {
puts(prefixNameProtect(varModp) + "::");
} else if (VN_IS(varModp, Class) && varModp != m_modp) {
// Superclass member reference
puts(prefixNameProtect(varp->user4p()) + "::");
puts(prefixNameProtect(varModp) + "::");
} else if (!nodep->selfPointer().empty()) {
emitDereference(nodep->selfPointerProtect(m_useSelfForThis));
}

View File

@ -697,17 +697,8 @@ public:
void V3EmitC::emitcImp() {
UINFO(2, __FUNCTION__ << ": " << endl);
// Set user4p in all CFunc and Var to point to the containing AstNodeModule
AstUser4InUse user4InUse;
const auto setAll = [](AstNodeModule* modp) -> void {
for (AstNode* nodep = VN_CAST(modp, NodeModule)->stmtsp(); nodep; nodep = nodep->nextp()) {
if (VN_IS(nodep, CFunc) || VN_IS(nodep, Var)) nodep->user4p(modp);
}
};
for (AstNode* modp = v3Global.rootp()->modulesp(); modp; modp = modp->nextp()) {
setAll(VN_CAST(modp, NodeModule));
}
setAll(v3Global.rootp()->constPoolp()->modp());
// Make parent module pointers available.
EmitCParentModule emitCParentModule;
// Process each module in turn
for (const AstNode* nodep = v3Global.rootp()->modulesp(); nodep; nodep = nodep->nextp()) {