Internals: Move AstNodeCCall::m_selfPointer to AstCCall
Other sub-classes of AstNodeCCall do not need the self pointer. Moving it into the specific sub-class that needs it clarifies V3Descope and Emit. No functional change intended.
This commit is contained in:
parent
4081a1a539
commit
ddef61d62e
|
|
@ -2612,7 +2612,6 @@ class AstNodeCCall VL_NOT_FINAL : public AstNodeStmt {
|
|||
// A call of a C++ function, perhaps a AstCFunc or perhaps globally named
|
||||
// Functions are not statements, while tasks are. AstNodeStmt needs isStatement() to deal.
|
||||
AstCFunc* m_funcp;
|
||||
string m_selfPointer; // Output code object pointer (e.g.: 'this')
|
||||
string m_argTypes;
|
||||
|
||||
protected:
|
||||
|
|
@ -2638,9 +2637,6 @@ public:
|
|||
virtual bool isPure() const override;
|
||||
virtual bool isOutputter() const override { return !isPure(); }
|
||||
AstCFunc* funcp() const { return m_funcp; }
|
||||
string selfPointer() const { return m_selfPointer; }
|
||||
void selfPointer(const string& value) { m_selfPointer = value; }
|
||||
string selfPointerProtect(bool useSelfForThis) const;
|
||||
void argTypes(const string& str) { m_argTypes = str; }
|
||||
string argTypes() const { return m_argTypes; }
|
||||
// op1p reserved for AstCMethodCall
|
||||
|
|
|
|||
|
|
@ -121,7 +121,8 @@ const char* AstNodeCCall::broken() const {
|
|||
return nullptr;
|
||||
}
|
||||
bool AstNodeCCall::isPure() const { return funcp()->pure(); }
|
||||
string AstNodeCCall::selfPointerProtect(bool useSelfForThis) const {
|
||||
|
||||
string AstCCall::selfPointerProtect(bool useSelfForThis) const {
|
||||
const string& sp
|
||||
= useSelfForThis ? VString::replaceWord(selfPointer(), "this", "vlSelf") : selfPointer();
|
||||
return VIdProtect::protectWordsIf(sp, protect());
|
||||
|
|
|
|||
|
|
@ -8880,10 +8880,17 @@ class AstCCall final : public AstNodeCCall {
|
|||
// C++ function call
|
||||
// Parents: Anything above a statement
|
||||
// Children: Args to the function
|
||||
|
||||
string m_selfPointer; // Output code object pointer (e.g.: 'this')
|
||||
|
||||
public:
|
||||
AstCCall(FileLine* fl, AstCFunc* funcp, AstNode* argsp = nullptr)
|
||||
: ASTGEN_SUPER_CCall(fl, funcp, argsp) {}
|
||||
ASTNODE_NODE_FUNCS(CCall)
|
||||
|
||||
string selfPointer() const { return m_selfPointer; }
|
||||
void selfPointer(const string& value) { m_selfPointer = value; }
|
||||
string selfPointerProtect(bool useSelfForThis) const;
|
||||
};
|
||||
|
||||
class AstCMethodCall final : public AstNodeCCall {
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ private:
|
|||
// module.
|
||||
string descopedSelfPointer(const AstScope* scopep) {
|
||||
UASSERT(scopep, "Var/Func not scoped");
|
||||
UASSERT(!VN_IS(scopep->modp(), Class), "References to classes handled elsewhere");
|
||||
|
||||
// Static functions can't use relative references via 'this->'
|
||||
const bool relativeRefOk = !m_funcp->isStatic();
|
||||
|
|
@ -83,9 +84,7 @@ private:
|
|||
|
||||
if (relativeRefOk && scopep == m_scopep) {
|
||||
return "this";
|
||||
} else if (VN_IS(scopep->modp(), Class)) {
|
||||
return "this";
|
||||
} else if (!m_modSingleton && relativeRefOk && scopep->aboveScopep() == m_scopep
|
||||
} else if (relativeRefOk && !m_modSingleton && scopep->aboveScopep() == m_scopep
|
||||
&& VN_IS(scopep->modp(), Module)) {
|
||||
// Reference to scope of instance directly under this module, can just "this->cell",
|
||||
// which can potentially be V3Combined, but note this requires one extra pointer
|
||||
|
|
@ -215,20 +214,37 @@ private:
|
|||
UASSERT_OBJ(m_scopep, nodep, "Node not under scope");
|
||||
const AstVar* const varp = nodep->varScopep()->varp();
|
||||
const AstScope* const scopep = nodep->varScopep()->scopep();
|
||||
if (!varp->isFuncLocal()) { nodep->selfPointer(descopedSelfPointer(scopep)); }
|
||||
if (varp->isFuncLocal()) {
|
||||
// Reference to function locals need no self pointer
|
||||
nodep->selfPointer("");
|
||||
} else if (VN_IS(scopep->modp(), Class)) {
|
||||
// Direct reference to class members are from within the class itself, references from
|
||||
// outside the class must go via AstMemberSel
|
||||
nodep->selfPointer("this");
|
||||
} else {
|
||||
nodep->selfPointer(descopedSelfPointer(scopep));
|
||||
}
|
||||
nodep->varScopep(nullptr);
|
||||
UINFO(9, " refout " << nodep << endl);
|
||||
}
|
||||
virtual void visit(AstNodeCCall* nodep) override {
|
||||
virtual void visit(AstCCall* nodep) override {
|
||||
// UINFO(9, " " << nodep << endl);
|
||||
iterateChildren(nodep);
|
||||
// Convert the hierch name
|
||||
UASSERT_OBJ(m_scopep, nodep, "Node not under scope");
|
||||
const AstScope* const scopep = nodep->funcp()->scopep();
|
||||
nodep->selfPointer(descopedSelfPointer(scopep));
|
||||
if (VN_IS(scopep->modp(), Class)) {
|
||||
// Direct call to class methods are from within the class itself, method calls from
|
||||
// outside the class must go via AstCMethodCall
|
||||
nodep->selfPointer("this");
|
||||
} else {
|
||||
nodep->selfPointer(descopedSelfPointer(scopep));
|
||||
}
|
||||
// Can't do this, as we may have more calls later
|
||||
// nodep->funcp()->scopep(nullptr);
|
||||
}
|
||||
virtual void visit(AstCMethodCall* nodep) override { iterateChildren(nodep); }
|
||||
virtual void visit(AstCNew* nodep) override { iterateChildren(nodep); }
|
||||
virtual void visit(AstCFunc* nodep) override {
|
||||
VL_RESTORER(m_funcp);
|
||||
if (!nodep->user1()) {
|
||||
|
|
|
|||
|
|
@ -433,12 +433,12 @@ void EmitCFunc::displayNode(AstNode* nodep, AstScopeName* scopenamep, const stri
|
|||
displayEmit(nodep, isScan);
|
||||
}
|
||||
|
||||
void EmitCFunc::emitCCallArgs(AstNodeCCall* nodep) {
|
||||
void EmitCFunc::emitCCallArgs(const AstNodeCCall* nodep, const string& selfPointer) {
|
||||
puts("(");
|
||||
bool comma = false;
|
||||
if (nodep->funcp()->isLoose() && !nodep->funcp()->isStatic()) {
|
||||
UASSERT_OBJ(!nodep->selfPointer().empty(), nodep,
|
||||
"Call to loose method without self pointer");
|
||||
puts(nodep->selfPointerProtect(m_useSelfForThis));
|
||||
UASSERT_OBJ(!selfPointer.empty(), nodep, "Call to loose method without self pointer");
|
||||
puts(selfPointer);
|
||||
comma = true;
|
||||
}
|
||||
if (!nodep->argTypes().empty()) {
|
||||
|
|
@ -451,6 +451,12 @@ void EmitCFunc::emitCCallArgs(AstNodeCCall* nodep) {
|
|||
iterate(subnodep);
|
||||
comma = true;
|
||||
}
|
||||
if (VN_IS(nodep->backp(), NodeMath) || VN_IS(nodep->backp(), CReturn)) {
|
||||
// We should have a separate CCall for math and statement usage, but...
|
||||
puts(")");
|
||||
} else {
|
||||
puts(");\n");
|
||||
}
|
||||
}
|
||||
|
||||
void EmitCFunc::emitDereference(const string& pointer) {
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ public:
|
|||
}
|
||||
void emitOpName(AstNode* nodep, const string& format, AstNode* lhsp, AstNode* rhsp,
|
||||
AstNode* thsp);
|
||||
void emitCCallArgs(AstNodeCCall* nodep);
|
||||
void emitCCallArgs(const AstNodeCCall* nodep, const string& selfPointer);
|
||||
void emitDereference(const string& pointer);
|
||||
void emitCvtPackStr(AstNode* nodep);
|
||||
void emitCvtWideArray(AstNode* nodep, AstNode* fromp);
|
||||
|
|
@ -353,7 +353,7 @@ public:
|
|||
}
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstNodeCCall* nodep) override {
|
||||
virtual void visit(AstCCall* nodep) override {
|
||||
const AstCFunc* const funcp = nodep->funcp();
|
||||
if (AstCMethodCall* ccallp = VN_CAST(nodep, CMethodCall)) {
|
||||
UASSERT_OBJ(!funcp->isLoose(), nodep, "Loose method called via AstCMethodCall");
|
||||
|
|
@ -382,14 +382,22 @@ public:
|
|||
}
|
||||
puts(funcp->nameProtect());
|
||||
}
|
||||
puts("(");
|
||||
emitCCallArgs(nodep);
|
||||
if (VN_IS(nodep->backp(), NodeMath) || VN_IS(nodep->backp(), CReturn)) {
|
||||
// We should have a separate CCall for math and statement usage, but...
|
||||
puts(")");
|
||||
} else {
|
||||
puts(");\n");
|
||||
}
|
||||
emitCCallArgs(nodep, nodep->selfPointerProtect(m_useSelfForThis));
|
||||
}
|
||||
virtual void visit(AstCMethodCall* nodep) override {
|
||||
const AstCFunc* const funcp = nodep->funcp();
|
||||
UASSERT_OBJ(!funcp->isLoose(), nodep, "Loose method called via AstCMethodCall");
|
||||
iterate(nodep->fromp());
|
||||
putbs("->");
|
||||
puts(funcp->nameProtect());
|
||||
emitCCallArgs(nodep, "");
|
||||
}
|
||||
virtual void visit(AstCNew* nodep) override {
|
||||
puts("std::make_shared<" + prefixNameProtect(nodep->dtypep()) + ">(");
|
||||
puts("vlSymsp"); // TODO make this part of argsp, and eliminate when unnecessary
|
||||
if (nodep->argsp()) puts(", ");
|
||||
iterateAndNextNull(nodep->argsp());
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstCMethodHard* nodep) override {
|
||||
iterate(nodep->fromp());
|
||||
|
|
@ -1013,13 +1021,6 @@ public:
|
|||
puts(cvtToStr(nodep->fileline()->lineno()));
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstCNew* nodep) override {
|
||||
puts("std::make_shared<" + prefixNameProtect(nodep->dtypep()) + ">(");
|
||||
puts("vlSymsp"); // TODO make this part of argsp, and eliminate when unnecessary
|
||||
if (nodep->argsp()) puts(", ");
|
||||
iterateAndNextNull(nodep->argsp());
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstNewCopy* nodep) override {
|
||||
puts("std::make_shared<" + prefixNameProtect(nodep->dtypep()) + ">(");
|
||||
puts("*"); // i.e. make into a reference
|
||||
|
|
|
|||
Loading…
Reference in New Issue