Emit: Factor out parent module access via user4
No functional change.
This commit is contained in:
parent
42d918c163
commit
8bb77f86ec
|
|
@ -20,11 +20,26 @@
|
||||||
#include "V3EmitCBase.h"
|
#include "V3EmitCBase.h"
|
||||||
#include "V3Task.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
|
// EmitCBaseVisitor implementation
|
||||||
|
|
||||||
string EmitCBaseVisitor::funcNameProtect(const AstCFunc* nodep, const AstNodeModule* modp) {
|
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;
|
string name;
|
||||||
if (nodep->isConstructor()) {
|
if (nodep->isConstructor()) {
|
||||||
name += prefixNameProtect(modp);
|
name += prefixNameProtect(modp);
|
||||||
|
|
@ -54,8 +69,7 @@ string EmitCBaseVisitor::cFuncArgs(const AstCFunc* nodep) {
|
||||||
string args;
|
string args;
|
||||||
if (nodep->isLoose() && !nodep->isStatic()) {
|
if (nodep->isLoose() && !nodep->isStatic()) {
|
||||||
if (nodep->isConst().trueKnown()) args += "const ";
|
if (nodep->isConst().trueKnown()) args += "const ";
|
||||||
AstNodeModule* modp = VN_CAST(nodep->user4p(), NodeModule);
|
args += prefixNameProtect(EmitCParentModule::get(nodep));
|
||||||
args += prefixNameProtect(modp);
|
|
||||||
args += "* vlSelf";
|
args += "* vlSelf";
|
||||||
}
|
}
|
||||||
if (!nodep->argTypes().empty()) {
|
if (!nodep->argTypes().empty()) {
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,24 @@
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
#include <cmath>
|
#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
|
// Base Visitor class -- holds output file pointer
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,8 +53,7 @@ class EmitCLazyDecls final : public AstNVisitor {
|
||||||
// Already declared manually
|
// Already declared manually
|
||||||
if (m_emittedManually.count(funcp->nameProtect())) return;
|
if (m_emittedManually.count(funcp->nameProtect())) return;
|
||||||
// Needs lazy declaration, emit one
|
// Needs lazy declaration, emit one
|
||||||
m_emitter.emitCFuncDecl(funcp, VN_CAST_CONST(funcp->user4p(), NodeModule),
|
m_emitter.emitCFuncDecl(funcp, EmitCParentModule::get(funcp), funcp->dpiImportPrototype());
|
||||||
funcp->dpiImportPrototype());
|
|
||||||
m_needsBlankLine = true;
|
m_needsBlankLine = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -82,7 +81,9 @@ class EmitCLazyDecls final : public AstNVisitor {
|
||||||
virtual void visit(AstVarRef* nodep) override {
|
virtual void visit(AstVarRef* nodep) override {
|
||||||
AstVar* const varp = nodep->varp();
|
AstVar* const varp = nodep->varp();
|
||||||
// Only constant pool symbols are lazy declared for now ...
|
// 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); }
|
virtual void visit(AstNode* nodep) override { iterateChildrenConst(nodep); }
|
||||||
|
|
@ -354,16 +355,17 @@ public:
|
||||||
}
|
}
|
||||||
virtual void visit(AstCCall* nodep) override {
|
virtual void visit(AstCCall* nodep) override {
|
||||||
const AstCFunc* const funcp = nodep->funcp();
|
const AstCFunc* const funcp = nodep->funcp();
|
||||||
|
const AstNodeModule* const funcModp = EmitCParentModule::get(funcp);
|
||||||
if (funcp->dpiImportPrototype()) {
|
if (funcp->dpiImportPrototype()) {
|
||||||
// Calling DPI import
|
// Calling DPI import
|
||||||
puts(funcp->name());
|
puts(funcp->name());
|
||||||
} else if (funcp->isProperMethod() && funcp->isStatic()) {
|
} else if (funcp->isProperMethod() && funcp->isStatic()) {
|
||||||
// Call static method via the containing class
|
// Call static method via the containing class
|
||||||
puts(prefixNameProtect(funcp->user4p()) + "::");
|
puts(prefixNameProtect(funcModp) + "::");
|
||||||
puts(funcp->nameProtect());
|
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
|
// Calling superclass method
|
||||||
puts(prefixNameProtect(funcp->user4p()) + "::");
|
puts(prefixNameProtect(funcModp) + "::");
|
||||||
puts(funcp->nameProtect());
|
puts(funcp->nameProtect());
|
||||||
} else if (funcp->isLoose()) {
|
} else if (funcp->isLoose()) {
|
||||||
// Calling loose method
|
// Calling loose method
|
||||||
|
|
@ -1100,15 +1102,16 @@ public:
|
||||||
// Terminals
|
// Terminals
|
||||||
virtual void visit(AstVarRef* nodep) override {
|
virtual void visit(AstVarRef* nodep) override {
|
||||||
const AstVar* const varp = nodep->varp();
|
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
|
// Reference to constant pool variable
|
||||||
puts(topClassName() + "__ConstPool__");
|
puts(topClassName() + "__ConstPool__");
|
||||||
} else if (varp->isStatic()) {
|
} else if (varp->isStatic()) {
|
||||||
// Access static variable via the containing class
|
// Access static variable via the containing class
|
||||||
puts(prefixNameProtect(varp->user4p()) + "::");
|
puts(prefixNameProtect(varModp) + "::");
|
||||||
} else if (VN_IS(varp->user4p(), Class) && varp->user4p() != m_modp) {
|
} else if (VN_IS(varModp, Class) && varModp != m_modp) {
|
||||||
// Superclass member reference
|
// Superclass member reference
|
||||||
puts(prefixNameProtect(varp->user4p()) + "::");
|
puts(prefixNameProtect(varModp) + "::");
|
||||||
} else if (!nodep->selfPointer().empty()) {
|
} else if (!nodep->selfPointer().empty()) {
|
||||||
emitDereference(nodep->selfPointerProtect(m_useSelfForThis));
|
emitDereference(nodep->selfPointerProtect(m_useSelfForThis));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -697,17 +697,8 @@ public:
|
||||||
|
|
||||||
void V3EmitC::emitcImp() {
|
void V3EmitC::emitcImp() {
|
||||||
UINFO(2, __FUNCTION__ << ": " << endl);
|
UINFO(2, __FUNCTION__ << ": " << endl);
|
||||||
// Set user4p in all CFunc and Var to point to the containing AstNodeModule
|
// Make parent module pointers available.
|
||||||
AstUser4InUse user4InUse;
|
EmitCParentModule emitCParentModule;
|
||||||
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());
|
|
||||||
|
|
||||||
// Process each module in turn
|
// Process each module in turn
|
||||||
for (const AstNode* nodep = v3Global.rootp()->modulesp(); nodep; nodep = nodep->nextp()) {
|
for (const AstNode* nodep = v3Global.rootp()->modulesp(); nodep; nodep = nodep->nextp()) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue