Internals: Allow const & non-member CFuncs for class branch. No functional change.

This commit is contained in:
Wilson Snyder 2020-02-01 10:57:55 -05:00
parent f00ff61559
commit 80d94891e1
6 changed files with 43 additions and 24 deletions

View File

@ -544,9 +544,12 @@ public:
static const char* const names[] = {
"FALSE", "TRUE", "UNK"};
return names[m_e]; }
bool trueU() const { return m_e == BU_TRUE || m_e == BU_UNKNOWN; }
bool falseU() const { return m_e == BU_FALSE || m_e == BU_UNKNOWN; }
bool trueKnown() const { return m_e == BU_TRUE; }
bool trueUnknown() const { return m_e == BU_TRUE || m_e == BU_UNKNOWN; }
bool falseKnown() const { return m_e == BU_FALSE; }
bool falseUnknown() const { return m_e == BU_FALSE || m_e == BU_UNKNOWN; }
bool unknown() const { return m_e == BU_UNKNOWN; }
void setTrueOrFalse(bool flag) { m_e = flag ? BU_TRUE : BU_FALSE; }
};
inline bool operator==(VBoolOrUnknown lhs, VBoolOrUnknown rhs) { return (lhs.m_e == rhs.m_e); }
inline bool operator==(VBoolOrUnknown lhs, VBoolOrUnknown::en rhs) { return (lhs.m_e == rhs); }

View File

@ -1336,7 +1336,7 @@ void AstCFunc::dump(std::ostream& str) const {
if (slow()) str<<" [SLOW]";
if (pure()) str<<" [PURE]";
if (isStatic().unknown()) str<<" [STATICU]";
else if (isStatic().trueU()) str<<" [STATIC]";
else if (isStatic().trueUnknown()) str<<" [STATIC]";
if (dpiImport()) str<<" [DPII]";
if (dpiExport()) str<<" [DPIX]";
if (dpiExportWrapper()) str<<" [DPIXWR]";

View File

@ -6629,6 +6629,7 @@ private:
string m_rtnType; // void, bool, or other return type
string m_argTypes;
string m_ifdef; // #ifdef symbol around this function
VBoolOrUnknown m_isConst; // Function is declared const (*this not changed)
VBoolOrUnknown m_isStatic; // Function is declared static (no this)
bool m_dontCombine:1; // V3Combine shouldn't compare this func tree, it's special
bool m_skipDecl:1; // Don't declare it
@ -6636,6 +6637,7 @@ private:
bool m_formCallTree:1; // Make a global function to call entire tree of functions
bool m_slow:1; // Slow routine, called once or just at init time
bool m_funcPublic:1; // From user public task/function
bool m_isMethod:1; // Is inside a class definition
bool m_isInline:1; // Inline function
bool m_symProlog:1; // Setup symbol table for later instructions
bool m_entryPoint:1; // User may call into this top level function
@ -6648,6 +6650,7 @@ public:
AstCFunc(FileLine* fl, const string& name, AstScope* scopep, const string& rtnType="")
: ASTGEN_SUPER(fl) {
m_funcType = AstCFuncType::FT_NORMAL;
m_isConst = VBoolOrUnknown::BU_UNKNOWN; // Unknown until analyzed
m_isStatic = VBoolOrUnknown::BU_UNKNOWN; // Unknown until see where thisp needed
m_scopep = scopep;
m_name = name;
@ -6658,6 +6661,7 @@ public:
m_formCallTree = false;
m_slow = false;
m_funcPublic = false;
m_isMethod = true;
m_isInline = false;
m_symProlog = false;
m_entryPoint = false;
@ -6683,8 +6687,11 @@ public:
//
virtual void name(const string& name) { m_name = name; }
virtual int instrCount() const { return dpiImport() ? instrCountDpi() : 0; }
VBoolOrUnknown isConst() const { return m_isConst; }
void isConst(bool flag) { m_isConst.setTrueOrFalse(flag); }
void isConst(VBoolOrUnknown flag) { m_isConst = flag; }
VBoolOrUnknown isStatic() const { return m_isStatic; }
void isStatic(bool flag) { m_isStatic = flag ? VBoolOrUnknown::BU_TRUE : VBoolOrUnknown::BU_FALSE; }
void isStatic(bool flag) { m_isStatic.setTrueOrFalse(flag); }
void isStatic(VBoolOrUnknown flag) { m_isStatic = flag; }
void cname(const string& name) { m_cname = name; }
string cname() const { return m_cname; }
@ -6710,6 +6717,8 @@ public:
string ifdef() const { return m_ifdef; }
void funcType(AstCFuncType flag) { m_funcType = flag; }
AstCFuncType funcType() const { return m_funcType; }
bool isMethod() const { return m_isMethod; }
void isMethod(bool flag) { m_isMethod = flag; }
bool isInline() const { return m_isInline; }
void isInline(bool flag) { m_isInline = flag; }
bool symProlog() const { return m_symProlog; }

View File

@ -138,7 +138,7 @@ private:
// (Here instead of new visitor after V3Descope just to avoid another visitor)
void needNonStaticFunc(AstNode* nodep) {
UASSERT_OBJ(m_funcp, nodep, "Non-static accessor not under a function");
if (m_funcp->isStatic().trueU()) {
if (m_funcp->isStatic().trueUnknown()) {
UINFO(5,"Mark non-public due to "<<nodep<<endl);
m_funcp->isStatic(false);
}

View File

@ -273,7 +273,7 @@ private:
virtual void visit(AstCFunc* nodep) VL_OVERRIDE {
if (!nodep->user1()) {
m_needThis = false;
m_allowThis = nodep->isStatic().falseU(); // Non-static or unknown if static
m_allowThis = nodep->isStatic().falseUnknown(); // Non-static or unknown if static
iterateChildren(nodep);
nodep->user1(true);
if (m_needThis) nodep->isStatic(false);

View File

@ -155,13 +155,17 @@ public:
return lhsp->name() < rhsp->name();
}
};
void emitIntFuncDecls(AstNodeModule* modp) {
void emitIntFuncDecls(AstNodeModule* modp, bool methodFuncs) {
typedef std::vector<const AstCFunc*> FuncVec;
FuncVec funcsp;
for (AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (const AstCFunc* funcp = VN_CAST(nodep, CFunc)) {
if (!funcp->skipDecl()) { funcsp.push_back(funcp); }
if (!funcp->skipDecl()
&& funcp->isMethod() == methodFuncs
&& !funcp->dpiImport()) { // DPI is prototyped in __Dpi.h
funcsp.push_back(funcp);
}
}
}
@ -169,21 +173,20 @@ public:
for (FuncVec::iterator it = funcsp.begin(); it != funcsp.end(); ++it) {
const AstCFunc* funcp = *it;
if (!funcp->dpiImport()) { // DPI is prototyped in __Dpi.h
ofp()->putsPrivate(funcp->declPrivate());
if (!funcp->ifdef().empty()) puts("#ifdef " + funcp->ifdef() + "\n");
if (funcp->isStatic().trueU()) puts("static ");
puts(funcp->rtnTypeVoid());
puts(" ");
puts(funcp->nameProtect());
puts("(" + cFuncArgs(funcp) + ")");
if (funcp->slow()) puts(" VL_ATTR_COLD");
puts(";\n");
if (!funcp->ifdef().empty()) puts("#endif // " + funcp->ifdef() + "\n");
}
ofp()->putsPrivate(funcp->declPrivate());
if (!funcp->ifdef().empty()) puts("#ifdef " + funcp->ifdef() + "\n");
if (funcp->isStatic().trueUnknown()) puts("static ");
puts(funcp->rtnTypeVoid());
puts(" ");
puts(funcp->nameProtect());
puts("(" + cFuncArgs(funcp) + ")");
if (funcp->isConst().trueKnown()) puts(" const");
if (funcp->slow()) puts(" VL_ATTR_COLD");
puts(";\n");
if (!funcp->ifdef().empty()) puts("#endif // " + funcp->ifdef() + "\n");
}
if (modp->isTop() && v3Global.opt.mtasks()) {
if (methodFuncs && modp->isTop() && v3Global.opt.mtasks()) {
// Emit the mtask func prototypes.
AstExecGraph* execGraphp = v3Global.rootp()->execGraphp();
UASSERT_OBJ(execGraphp, v3Global.rootp(), "Root should have an execGraphp");
@ -1245,8 +1248,10 @@ class EmitCImp : EmitCStmts {
if (nodep->ifdef()!="") puts("#ifdef "+nodep->ifdef()+"\n");
if (nodep->isInline()) puts("VL_INLINE_OPT ");
puts(nodep->rtnTypeVoid()); puts(" ");
puts(prefixNameProtect(m_modp) + "::" + nodep->nameProtect() + "(" + cFuncArgs(nodep)
+ ") {\n");
if (nodep->isMethod()) puts(prefixNameProtect(m_modp) + "::");
puts(nodep->nameProtect() + "(" + cFuncArgs(nodep) + ")");
if (nodep->isConst().trueKnown()) puts(" const");
puts(" {\n");
// "+" in the debug indicates a print from the model
puts("VL_DEBUG_IF(VL_DBG_MSGF(\"+ ");
@ -2738,7 +2743,7 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
ofp()->putsPrivate(false); // public:
puts("void "+protect("__Vconfigure")+"("+symClassName()+"* symsp, bool first);\n");
emitIntFuncDecls(modp);
emitIntFuncDecls(modp, true);
if (v3Global.opt.trace()) {
ofp()->putsPrivate(false); // public:
@ -2757,6 +2762,8 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
puts("} VL_ATTR_ALIGNED(128);\n");
emitIntFuncDecls(modp, false);
// Save/restore
if (v3Global.opt.savable() && modp->isTop()) {
puts("\n");