Internals: Use astgen for cross-node pointers. No functional change intended. (#4727)

This commit is contained in:
Wilson Snyder 2023-12-01 00:58:16 +00:00 committed by GitHub
parent d1ee9827a0
commit feae9ca4aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 255 additions and 464 deletions

View File

@ -1857,7 +1857,8 @@ protected:
// CONSTRUCTORS
AstNode(VNType t, FileLine* fl);
virtual AstNode* clone() = 0; // Generally, cloneTree is what you want instead
virtual void cloneRelink() {}
virtual void cloneRelink() { cloneRelinkGen(); }
virtual void cloneRelinkGen() = 0; // Generated by 'astgen'
void cloneRelinkTree();
// METHODS
@ -2264,6 +2265,8 @@ public:
virtual bool undead() const { return false; }
// Check if node is consistent, return nullptr if ok, else reason string
virtual const char* broken() const { return nullptr; }
// Generated by 'astgen'. Calls 'broken()', which can be used to add extra checks
virtual const char* brokenGen() const = 0; // Generated by 'astgen'
// INVOKERS
virtual void accept(VNVisitorConst& v) = 0;

View File

@ -137,8 +137,8 @@ class AstNodeArrayDType VL_NOT_FINAL : public AstNodeDType {
// Array data type, ie "some_dtype var_name [2:0]"
// @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
// @astgen op2 := rangep : Optional[AstRange] // array bounds
AstNodeDType* m_refDTypep = nullptr; // Elements of this type (after widthing)
//
// @astgen ptr := m_refDTypep : Optional[AstNodeDType] // Elements of this type (post-width)
AstNode* rangenp() const { return reinterpret_cast<AstNode*>(rangep()); }
protected:
@ -150,13 +150,9 @@ public:
void dump(std::ostream& str) const override;
void dumpSmall(std::ostream& str) const override;
const char* broken() const override {
BROKEN_RTN(!((m_refDTypep && !childDTypep() && m_refDTypep->brokeExists())
|| (!m_refDTypep && childDTypep())));
BROKEN_RTN(!((m_refDTypep && !childDTypep()) || (!m_refDTypep && childDTypep())));
return nullptr;
}
void cloneRelink() override {
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
}
bool same(const AstNode* samep) const override {
const AstNodeArrayDType* const asamep = VN_DBG_AS(samep, NodeArrayDType);
return (hi() == asamep->hi() && subDTypep() == asamep->subDTypep()
@ -196,9 +192,9 @@ public:
class AstNodeUOrStructDType VL_NOT_FINAL : public AstNodeDType {
// A struct or union; common handling
// @astgen op1 := membersp : List[AstMemberDType]
// MEMBERS
//
// @astgen ptr := m_classOrPackagep : Optional[AstNodeModule] // Package emitted with
string m_name; // Name from upper typedef, if any
AstNodeModule* m_classOrPackagep = nullptr; // Package it will be emitted with
const int m_uniqueNum;
bool m_packed;
bool m_isFourstate = false; // V3Width computes
@ -215,7 +211,6 @@ protected:
public:
ASTGEN_MEMBERS_AstNodeUOrStructDType;
int uniqueNum() const { return m_uniqueNum; }
const char* broken() const override;
void dump(std::ostream& str) const override;
bool isCompound() const override { return !packed(); }
// For basicp() we reuse the size to indicate a "fake" basic type of same size
@ -279,8 +274,9 @@ class AstAssocArrayDType final : public AstNodeDType {
// Associative array data type, ie "[some_dtype]"
// @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
// @astgen op2 := keyChildDTypep : Optional[AstNodeDType]
AstNodeDType* m_refDTypep; // Elements of this type (after widthing)
AstNodeDType* m_keyDTypep; // Keys of this type (after widthing)
//
// @astgen ptr := m_refDTypep : Optional[AstNodeDType] // Elements of this type (post-width)
// @astgen ptr := m_keyDTypep : Optional[AstNodeDType] // Keys of this type (post-width)
public:
AstAssocArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstNodeDType* keyDtp)
: ASTGEN_SUPER_AssocArrayDType(fl) {
@ -298,16 +294,10 @@ public:
}
ASTGEN_MEMBERS_AstAssocArrayDType;
const char* broken() const override {
BROKEN_RTN(!((m_refDTypep && !childDTypep() && m_refDTypep->brokeExists())
|| (!m_refDTypep && childDTypep())));
BROKEN_RTN(!((m_keyDTypep && !childDTypep() && m_keyDTypep->brokeExists())
|| (!m_keyDTypep && childDTypep())));
BROKEN_RTN(!((m_refDTypep && !childDTypep()) || (!m_refDTypep && childDTypep())));
BROKEN_RTN(!((m_keyDTypep && !childDTypep()) || (!m_keyDTypep && childDTypep())));
return nullptr;
}
void cloneRelink() override {
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
if (m_keyDTypep && m_keyDTypep->clonep()) m_keyDTypep = m_keyDTypep->clonep();
}
bool same(const AstNode* samep) const override {
const AstAssocArrayDType* const asamep = VN_DBG_AS(samep, AssocArrayDType);
if (!asamep->subDTypep()) return false;
@ -508,7 +498,6 @@ public:
bool similarDType(const AstNodeDType* samep) const override { return same(samep); }
string name() const override VL_MT_STABLE { return m_name; }
string prettyDTypeName() const override { return m_name; }
const char* broken() const override { return nullptr; }
// METHODS
AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; }
AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; }
@ -527,8 +516,9 @@ public:
class AstClassRefDType final : public AstNodeDType {
// Reference to a class
// @astgen op1 := paramsp: List[AstPin]
AstClass* m_classp; // data type pointed to, BELOW the AstTypedef
AstNodeModule* m_classOrPackagep = nullptr; // Package hierarchy
//
// @astgen ptr := m_classp : Optional[AstClass] // data type pointed to, BELOW the AstTypedef
// @astgen ptr := m_classOrPackagep : Optional[AstNodeModule] // Package hierarchy
public:
AstClassRefDType(FileLine* fl, AstClass* classp, AstPin* paramsp)
: ASTGEN_SUPER_ClassRefDType(fl)
@ -538,8 +528,6 @@ public:
}
ASTGEN_MEMBERS_AstClassRefDType;
// METHODS
const char* broken() const override;
void cloneRelink() override;
bool same(const AstNode* samep) const override {
const AstClassRefDType* const asamep = VN_DBG_AS(samep, ClassRefDType);
return (m_classp == asamep->m_classp && m_classOrPackagep == asamep->m_classOrPackagep);
@ -570,7 +558,8 @@ class AstConstDType final : public AstNodeDType {
// ConstDType are removed in V3LinkLValue and become AstVar::isConst.
// When more generic types are supported AstConstDType will be propagated further.
// @astgen op1 := childDTypep : Optional[AstNodeDType]
AstNodeDType* m_refDTypep = nullptr; // Inherit from this base data type
//
// @astgen ptr := m_refDTypep : Optional[AstNodeDType] // Inherit from this base data type
public:
AstConstDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp)
: ASTGEN_SUPER_ConstDType(fl) {
@ -581,13 +570,9 @@ public:
}
ASTGEN_MEMBERS_AstConstDType;
const char* broken() const override {
BROKEN_RTN(!((m_refDTypep && !childDTypep() && m_refDTypep->brokeExists())
|| (!m_refDTypep && childDTypep())));
BROKEN_RTN(!((m_refDTypep && !childDTypep()) || (!m_refDTypep && childDTypep())));
return nullptr;
}
void cloneRelink() override {
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
}
bool same(const AstNode* samep) const override {
const AstConstDType* const sp = VN_DBG_AS(samep, ConstDType);
return (m_refDTypep == sp->m_refDTypep);
@ -690,7 +675,8 @@ public:
class AstDynArrayDType final : public AstNodeDType {
// Dynamic array data type, ie "[]"
// @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
AstNodeDType* m_refDTypep = nullptr; // Elements of this type (after widthing)
//
// @astgen ptr := m_refDTypep : Optional[AstNodeDType] // Elements of this type (post-width)
public:
AstDynArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp)
: ASTGEN_SUPER_DynArrayDType(fl) {
@ -705,13 +691,9 @@ public:
}
ASTGEN_MEMBERS_AstDynArrayDType;
const char* broken() const override {
BROKEN_RTN(!((m_refDTypep && !childDTypep() && m_refDTypep->brokeExists())
|| (!m_refDTypep && childDTypep())));
BROKEN_RTN(!((m_refDTypep && !childDTypep()) || (!m_refDTypep && childDTypep())));
return nullptr;
}
void cloneRelink() override {
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
}
bool same(const AstNode* samep) const override {
const AstDynArrayDType* const asamep = VN_DBG_AS(samep, DynArrayDType);
if (!asamep->subDTypep()) return false;
@ -772,12 +754,13 @@ class AstEnumDType final : public AstNodeDType {
// Parents: TYPEDEF/MODULE
// @astgen op1 := childDTypep : Optional[AstNodeDType]
// @astgen op2 := itemsp : List[AstEnumItem]
//
// @astgen ptr := m_refDTypep : Optional[AstNodeDType] // Elements of this type (post-width)
public:
using TableMap = std::map<VAttrType, AstVar*>;
private:
string m_name; // Name from upper typedef, if any
AstNodeDType* m_refDTypep = nullptr; // Elements are of this type after V3Width
const int m_uniqueNum = 0;
TableMap m_tableMap; // Created table for V3Width only to remove duplicates
@ -794,9 +777,6 @@ public:
ASTGEN_MEMBERS_AstEnumDType;
const char* broken() const override;
void cloneRelink() override {
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
}
int uniqueNum() const { return m_uniqueNum; }
bool same(const AstNode* samep) const override {
const AstEnumDType* const sp = VN_DBG_AS(samep, EnumDType);
@ -834,13 +814,14 @@ public:
class AstIfaceRefDType final : public AstNodeDType {
// Reference to an interface, either for a port, or inside parent cell
// @astgen op1 := paramsp : List[AstPin]
//
// @astgen ptr := m_ifacep : Optional[AstIface] // Interface; cellp() should override
// @astgen ptr := m_cellp : Optional[AstCell] // When exact parent cell known; not a guess
// @astgen ptr := m_modportp : Optional[AstModport] // nullptr = unlinked or no modport
FileLine* m_modportFileline; // Where modport token was
string m_cellName; // "" = no cell, such as when connects to 'input' iface
string m_ifaceName; // Interface name
string m_modportName; // "" = no modport
AstIface* m_ifacep = nullptr; // Pointer to interface; note cellp() should override
AstCell* m_cellp = nullptr; // When exact parent cell known; not a guess
AstModport* m_modportp = nullptr; // nullptr = unlinked or no modport
public:
AstIfaceRefDType(FileLine* fl, const string& cellName, const string& ifaceName)
: ASTGEN_SUPER_IfaceRefDType(fl)
@ -865,10 +846,8 @@ public:
}
ASTGEN_MEMBERS_AstIfaceRefDType;
// METHODS
const char* broken() const override;
void dump(std::ostream& str = std::cout) const override;
void dumpSmall(std::ostream& str) const override;
void cloneRelink() override;
AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; }
AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; }
AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; }
@ -897,7 +876,8 @@ class AstMemberDType final : public AstNodeDType {
// PARENT: AstNodeUOrStructDType
// @astgen op1 := childDTypep : Optional[AstNodeDType]
// @astgen op3 := valuep : Optional[AstNode]
AstNodeDType* m_refDTypep = nullptr; // Elements of this type (after widthing)
//
// @astgen ptr := m_refDTypep : Optional[AstNodeDType] // Elements of this type (post-width)
string m_name; // Name of variable
string m_tag; // Holds the string of the verilator tag -- used in XML output.
int m_lsb = -1; // Within this level's packed struct, the LSB of the first bit of the member
@ -925,13 +905,6 @@ public:
string name() const override VL_MT_STABLE { return m_name; } // * = Var name
bool hasDType() const override { return true; }
bool maybePointedTo() const override { return true; }
const char* broken() const override {
BROKEN_RTN(m_refDTypep && !m_refDTypep->brokeExists());
return nullptr;
}
void cloneRelink() override {
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
}
AstNodeDType* getChildDTypep() const override { return childDTypep(); }
AstNodeUOrStructDType* getChildStructp() const;
AstNodeDType* subDTypep() const override VL_MT_STABLE {
@ -1038,7 +1011,8 @@ class AstQueueDType final : public AstNodeDType {
// Queue array data type, ie "[ $ ]"
// @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
// @astgen op2 := boundp : Optional[AstNodeExpr]
AstNodeDType* m_refDTypep = nullptr; // Elements of this type (after widthing)
//
// @astgen ptr := m_refDTypep : Optional[AstNodeDType] // Elements of this type (post-width)
public:
AstQueueDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstNodeExpr* boundp)
: ASTGEN_SUPER_QueueDType(fl) {
@ -1055,13 +1029,9 @@ public:
}
ASTGEN_MEMBERS_AstQueueDType;
const char* broken() const override {
BROKEN_RTN(!((m_refDTypep && !childDTypep() && m_refDTypep->brokeExists())
|| (!m_refDTypep && childDTypep())));
BROKEN_RTN(!((m_refDTypep && !childDTypep()) || (!m_refDTypep && childDTypep())));
return nullptr;
}
void cloneRelink() override {
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
}
bool same(const AstNode* samep) const override {
const AstQueueDType* const asamep = VN_DBG_AS(samep, QueueDType);
if (!asamep->subDTypep()) return false;
@ -1099,13 +1069,14 @@ class AstRefDType final : public AstNodeDType {
// @astgen op1 := typeofp : Optional[AstNode]
// @astgen op2 := classOrPackageOpp : Optional[AstNodeExpr]
// @astgen op3 := paramsp : List[AstPin]
//
// Pre-Width must reference the Typeref, not what it points to, as some child
// types like AstBracketArrayType will disappear and can't lose the handle
AstTypedef* m_typedefp = nullptr; // referenced type
// @astgen ptr := m_typedefp : Optional[AstTypedef] // Referenced type
// Post-width typedefs are removed and point to type directly
AstNodeDType* m_refDTypep = nullptr; // data type pointed to, BELOW the AstTypedef
// @astgen ptr := m_refDTypep : Optional[AstNodeDType] // Data type references
// @astgen ptr := m_classOrPackagep : Optional[AstNodeModule] // Class/package defined in
string m_name; // Name of an AstTypedef
AstNodeModule* m_classOrPackagep = nullptr; // Class/package in which it was defined
public:
AstRefDType(FileLine* fl, const string& name)
: ASTGEN_SUPER_RefDType(fl)
@ -1124,8 +1095,6 @@ public:
}
ASTGEN_MEMBERS_AstRefDType;
// METHODS
const char* broken() const override;
void cloneRelink() override;
bool same(const AstNode* samep) const override {
const AstRefDType* const asamep = VN_DBG_AS(samep, RefDType);
return (m_typedefp == asamep->m_typedefp && m_refDTypep == asamep->m_refDTypep
@ -1188,7 +1157,8 @@ public:
};
class AstSampleQueueDType final : public AstNodeDType {
// @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
AstNodeDType* m_refDTypep = nullptr; // Elements of this type (after widthing)
//
// @astgen ptr := m_refDTypep : Optional[AstNodeDType] // Elements of this type (post-width)
public:
AstSampleQueueDType(FileLine* fl, AstNodeDType* dtp)
: ASTGEN_SUPER_SampleQueueDType(fl) {
@ -1197,13 +1167,9 @@ public:
}
ASTGEN_MEMBERS_AstSampleQueueDType;
const char* broken() const override {
BROKEN_RTN(!((m_refDTypep && !childDTypep() && m_refDTypep->brokeExists())
|| (!m_refDTypep && childDTypep())));
BROKEN_RTN(!((m_refDTypep && !childDTypep()) || (!m_refDTypep && childDTypep())));
return nullptr;
}
void cloneRelink() override {
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
}
bool same(const AstNode* samep) const override {
const AstSampleQueueDType* const asamep = VN_DBG_AS(samep, SampleQueueDType);
if (!asamep->subDTypep()) return false;
@ -1264,7 +1230,8 @@ public:
class AstUnsizedArrayDType final : public AstNodeDType {
// Unsized/open-range Array data type, ie "some_dtype var_name []"
// @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
AstNodeDType* m_refDTypep; // Elements of this type (after widthing)
//
// @astgen ptr := m_refDTypep : Optional[AstNodeDType] // Elements of this type (post-width)
public:
AstUnsizedArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp)
: ASTGEN_SUPER_UnsizedArrayDType(fl) {
@ -1274,13 +1241,9 @@ public:
}
ASTGEN_MEMBERS_AstUnsizedArrayDType;
const char* broken() const override {
BROKEN_RTN(!((m_refDTypep && !childDTypep() && m_refDTypep->brokeExists())
|| (!m_refDTypep && childDTypep())));
BROKEN_RTN(!((m_refDTypep && !childDTypep()) || (!m_refDTypep && childDTypep())));
return nullptr;
}
void cloneRelink() override {
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
}
bool same(const AstNode* samep) const override;
bool similarDType(const AstNodeDType* samep) const override;
void dumpSmall(std::ostream& str) const override;
@ -1330,7 +1293,8 @@ public:
class AstWildcardArrayDType final : public AstNodeDType {
// Wildcard index type associative array data type, ie "some_dtype var_name [*]"
// @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width
AstNodeDType* m_refDTypep; // Elements of this type (after widthing)
//
// @astgen ptr := m_refDTypep : Optional[AstNodeDType] // Elements of this type (post-width)
public:
AstWildcardArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp)
: ASTGEN_SUPER_WildcardArrayDType(fl) {
@ -1340,13 +1304,9 @@ public:
}
ASTGEN_MEMBERS_AstWildcardArrayDType;
const char* broken() const override {
BROKEN_RTN(!((m_refDTypep && !childDTypep() && m_refDTypep->brokeExists())
|| (!m_refDTypep && childDTypep())));
BROKEN_RTN(!((m_refDTypep && !childDTypep()) || (!m_refDTypep && childDTypep())));
return nullptr;
}
void cloneRelink() override {
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
}
bool same(const AstNode* samep) const override;
bool similarDType(const AstNodeDType* samep) const override;
void dumpSmall(std::ostream& str) const override;

View File

@ -180,8 +180,9 @@ public:
};
class AstNodeCCall VL_NOT_FINAL : public AstNodeExpr {
// A call of a C++ function, perhaps a AstCFunc or perhaps globally named
// @astgen op2 := argsp : List[AstNodeExpr] // Note: op1 used by some sub-types only
AstCFunc* m_funcp;
// @astgen op2 := argsp : List[AstNodeExpr] // Note: op1 used by some sub-types only
//
// @astgen ptr := m_funcp : AstCFunc // Function being called
string m_argTypes;
bool m_superReference = false; // Called with super reference
@ -195,8 +196,6 @@ protected:
public:
ASTGEN_MEMBERS_AstNodeCCall;
void dump(std::ostream& str = std::cout) const override;
void cloneRelink() override;
const char* broken() const override;
int instrCount() const override { return INSTR_COUNT_CALL; }
bool same(const AstNode* samep) const override {
const AstNodeCCall* const asamep = VN_DBG_AS(samep, NodeCCall);
@ -223,8 +222,11 @@ class AstNodeFTaskRef VL_NOT_FINAL : public AstNodeExpr {
// op2 used by some sub-types only
// @astgen op3 := pinsp : List[AstNodeExpr]
// @astgen op4 := scopeNamep : Optional[AstScopeName]
AstNodeFTask* m_taskp = nullptr; // [AfterLink] Pointer to task referenced
AstNodeModule* m_classOrPackagep = nullptr; // Class/package of the task
//
// @astgen ptr := m_taskp : Optional[AstNodeFTask] // [AfterLink] Pointer to task referenced
// @astgen ptr := m_classOrPackagep : Optional[AstNodeModule] // Class/package of the task
ASTGEN_MEMBERS_AstNodeFTaskRef; // Gen pointers before other members for performance
private:
string m_name; // Name of variable
string m_dotted; // Dotted part of scope the name()ed task/func is under or ""
string m_inlinedDots; // Dotted hierarchy flattened out
@ -244,9 +246,7 @@ protected:
}
public:
ASTGEN_MEMBERS_AstNodeFTaskRef;
const char* broken() const override;
void cloneRelink() override;
void dump(std::ostream& str = std::cout) const override;
string name() const override VL_MT_STABLE { return m_name; } // * = Var name
bool isGateOptimizable() const override;
@ -486,10 +486,12 @@ public:
};
class AstNodeVarRef VL_NOT_FINAL : public AstNodeExpr {
// An AstVarRef or AstVarXRef
// @astgen ptr := m_varp : Optional[AstVar] // [AfterLink] Pointer to variable itself
// @astgen ptr := m_varScopep : Optional[AstVarScope] // Varscope for hierarchy
// @astgen ptr := m_classOrPackagep : Optional[AstNodeModule] // Class/package of the variable
ASTGEN_MEMBERS_AstNodeVarRef; // Gen pointers before other members for performance
private:
VAccess m_access; // Left hand side assignment
AstVar* m_varp; // [AfterLink] Pointer to variable itself
AstVarScope* m_varScopep = nullptr; // Varscope for hierarchy
AstNodeModule* m_classOrPackagep = nullptr; // Class/package of the variable
VSelfPointerText m_selfPointer
= VSelfPointerText{VSelfPointerText::Empty()}; // Output code object
// pointer (e.g.: 'this')
@ -507,11 +509,8 @@ protected:
}
public:
ASTGEN_MEMBERS_AstNodeVarRef;
void dump(std::ostream& str) const override;
const char* broken() const override;
int instrCount() const override { return widthInstrs(); }
void cloneRelink() override;
VAccess access() const { return m_access; }
void access(const VAccess& flag) { m_access = flag; } // Avoid using this; Set in constructor
AstVar* varp() const { return m_varp; } // [After Link] Pointer to variable
@ -538,7 +537,7 @@ public:
// === AstNodeExpr ===
class AstAddrOfCFunc final : public AstNodeExpr {
// Get address of CFunc
AstCFunc* m_funcp; // Pointer to function itself
// @astgen ptr := m_funcp : AstCFunc // Pointer to function itself
public:
AstAddrOfCFunc(FileLine* fl, AstCFunc* funcp)
@ -549,8 +548,6 @@ public:
public:
ASTGEN_MEMBERS_AstAddrOfCFunc;
void cloneRelink() override;
const char* broken() const override;
string emitVerilog() override { V3ERROR_NA_RETURN(""); }
string emitC() override { V3ERROR_NA_RETURN(""); }
bool cleanOut() const override { return true; }
@ -752,7 +749,7 @@ class AstClassOrPackageRef final : public AstNodeExpr {
// @astgen op1 := paramsp : List[AstPin]
string m_name;
// Node not NodeModule to appease some early parser usage
AstNode* m_classOrPackageNodep; // Pointer to class/package referenced
// @astgen ptr := m_classOrPackageNodep : Optional[AstNode] // Class/package referenced
public:
AstClassOrPackageRef(FileLine* fl, const string& name, AstNode* classOrPackageNodep,
AstPin* paramsp)
@ -763,15 +760,6 @@ public:
}
ASTGEN_MEMBERS_AstClassOrPackageRef;
// METHODS
const char* broken() const override {
BROKEN_RTN(m_classOrPackageNodep && !m_classOrPackageNodep->brokeExists());
return nullptr;
}
void cloneRelink() override {
if (m_classOrPackageNodep && m_classOrPackageNodep->clonep()) {
m_classOrPackageNodep = m_classOrPackageNodep->clonep();
}
}
bool same(const AstNode* samep) const override {
return (m_classOrPackageNodep
== VN_DBG_AS(samep, ClassOrPackageRef)->m_classOrPackageNodep);
@ -1064,7 +1052,8 @@ class AstConstraintRef final : public AstNodeExpr {
// A reference to a constraint identifier
// Not saving pointer to constraint yet, as constraint_mode is an unsupported construct
// @astgen op4 := scopeNamep : Optional[AstScopeName]
AstNodeModule* m_classOrPackagep = nullptr; // Class/package of the constraint
//
// @astgen ptr := m_classOrPackagep : Optional[AstNodeModule] // Class/package of constraint
string m_name; // Name of constraint
public:
@ -1148,8 +1137,8 @@ public:
bool cleanOut() const override { return true; }
};
class AstEnumItemRef final : public AstNodeExpr {
AstEnumItem* m_itemp; // [AfterLink] Pointer to item
AstNodeModule* m_classOrPackagep; // Class/package in which it was defined
// @astgen ptr := m_itemp : AstEnumItem // [AfterLink] Pointer to item
// @astgen ptr := m_classOrPackagep : Optional[AstNodeModule] // Class/package defined in
public:
AstEnumItemRef(FileLine* fl, AstEnumItem* itemp, AstNodeModule* classOrPackagep)
: ASTGEN_SUPER_EnumItemRef(fl)
@ -1161,8 +1150,6 @@ public:
void dump(std::ostream& str) const override;
string name() const override VL_MT_STABLE { return itemp()->name(); }
int instrCount() const override { return 0; }
const char* broken() const override;
void cloneRelink() override;
bool same(const AstNode* samep) const override {
const AstEnumItemRef* const sp = VN_DBG_AS(samep, EnumItemRef);
return itemp() == sp->itemp();
@ -1517,10 +1504,11 @@ public:
};
class AstMemberSel final : public AstNodeExpr {
// @astgen op1 := fromp : AstNodeExpr
//
// @astgen ptr := m_varp : Optional[AstVar] // Post link, variable in class that is selecting
// Don't need the class we are extracting from, as the "fromp()"'s datatype can get us to it
string m_name;
VAccess m_access; // Read or write, as in AstNodeVarRef
AstVar* m_varp = nullptr; // Post link, variable within class that is target of selection
public:
AstMemberSel(FileLine* fl, AstNodeExpr* fromp, VFlagChildDType, const string& name)
: ASTGEN_SUPER_MemberSel(fl)
@ -1535,8 +1523,6 @@ public:
dtypep(dtp);
}
ASTGEN_MEMBERS_AstMemberSel;
void cloneRelink() override;
const char* broken() const override;
void dump(std::ostream& str) const override;
string name() const override VL_MT_STABLE { return m_name; }
void name(const string& name) override { m_name = name; }
@ -4205,11 +4191,6 @@ public:
this->fromp(fromp);
}
ASTGEN_MEMBERS_AstCMethodCall;
const char* broken() const override {
BROKEN_BASE_RTN(AstNodeCCall::broken());
BROKEN_RTN(!fromp());
return nullptr;
}
};
class AstCNew final : public AstNodeCCall {
// C++ new() call
@ -4249,11 +4230,6 @@ public:
this->fromp(fromp);
}
ASTGEN_MEMBERS_AstMethodCall;
const char* broken() const override {
BROKEN_BASE_RTN(AstNodeFTaskRef::broken());
BROKEN_RTN(!fromp());
return nullptr;
}
};
class AstNew final : public AstNodeFTaskRef {
// New as constructor
@ -4735,15 +4711,14 @@ public:
class AstCAwait final : public AstNodeUniop {
// Emit C++'s co_await expression
// @astgen alias op1 := exprp
AstSenTree* m_sensesp; // Sentree related to this await
//
// @astgen ptr := m_sensesp : Optional[AstSenTree] // Sentree related to this await
public:
AstCAwait(FileLine* fl, AstNodeExpr* exprp, AstSenTree* sensesp = nullptr)
: ASTGEN_SUPER_CAwait(fl, exprp)
, m_sensesp{sensesp} {}
ASTGEN_MEMBERS_AstCAwait;
bool isTimingControl() const override { return true; }
const char* broken() const override;
void cloneRelink() override;
void dump(std::ostream& str) const override;
AstSenTree* sensesp() const { return m_sensesp; }
void clearSensesp() { m_sensesp = nullptr; }

View File

@ -541,8 +541,9 @@ class AstActive final : public AstNode {
// Parents: MODULE | CFUNC
// @astgen op1 := sensesStorep : Optional[AstSenTree] // Moved into m_sensesp in V3Active
// @astgen op2 := stmtsp : List[AstNode] // Logic
//
// @astgen ptr := m_sensesp : Optional[AstSenTree] // Sensitivity list for this process
string m_name;
AstSenTree* m_sensesp;
public:
AstActive(FileLine* fl, const string& name, AstSenTree* sensesp)
@ -554,8 +555,6 @@ public:
ASTGEN_MEMBERS_AstActive;
void dump(std::ostream& str = std::cout) const override;
string name() const override VL_MT_STABLE { return m_name; }
const char* broken() const override;
void cloneRelink() override;
// Statements are broken into pieces, as some must come before others.
void sensesp(AstSenTree* nodep) { m_sensesp = nodep; }
AstSenTree* sensesp() const { return m_sensesp; }
@ -588,7 +587,8 @@ class AstCFunc final : public AstNode {
// @astgen op2 := initsp : List[AstNode]
// @astgen op3 := stmtsp : List[AstNode]
// @astgen op4 := finalsp : List[AstNode]
AstScope* m_scopep;
//
// @astgen ptr := m_scopep : Optional[AstScope] // Scope that function is under
string m_name;
string m_cname; // C name, for dpiExports
string m_rtnType; // void, bool, or other return type
@ -651,8 +651,6 @@ public:
}
ASTGEN_MEMBERS_AstCFunc;
string name() const override VL_MT_STABLE { return m_name; }
const char* broken() const override;
void cloneRelink() override;
bool maybePointedTo() const override { return true; }
void dump(std::ostream& str = std::cout) const override;
bool same(const AstNode* samep) const override {
@ -782,11 +780,12 @@ class AstCell final : public AstNode {
// @astgen op2 := paramsp : List[AstPin] // List of parameter assignments
// @astgen op3 := rangep : Optional[AstRange] // Range for arrayed instances
// @astgen op4 := intfRefsp : List[AstIntfRef] // List of interface references, for tracing
//
// @astgen ptr := m_modp : Optional[AstNodeModule] // [AfterLink] Pointer to module instanced
FileLine* m_modNameFileline; // Where module the cell instances token was
string m_name; // Cell name
string m_origName; // Original name before dot addition
string m_modName; // Module the cell instances
AstNodeModule* m_modp = nullptr; // [AfterLink] Pointer to module instanced
bool m_hasIfaceVar : 1; // True if a Var has been created for this cell
bool m_hasNoParens : 1; // Instantiation has no parenthesis
bool m_recursive : 1; // Self-recursive module
@ -809,8 +808,8 @@ public:
}
ASTGEN_MEMBERS_AstCell;
// No cloneRelink, we presume cloneee's want the same module linkages
void cloneRelink() override {} // TODO V3Param shouldn't require avoiding cloneRelinkGen
void dump(std::ostream& str) const override;
const char* broken() const override;
bool maybePointedTo() const override { return true; }
// ACCESSORS
string name() const override VL_MT_STABLE { return m_name; } // * = Cell name
@ -837,10 +836,9 @@ class AstCellInline final : public AstNode {
// except for VPI runs where it exists until the end.
// It is augmented with the scope in V3Scope for VPI.
// Children: When 2 levels inlined, other CellInline under this
// @astgen ptr := m_scopep : Optional[AstScope] // The scope that the cell is inlined into
string m_name; // Cell name, possibly {a}__DOT__{b}...
const string
m_origModName; // Original name of the module, ignoring name() changes, for dot lookup
AstScope* m_scopep = nullptr; // The scope that the cell is inlined into
const string m_origModName; // Original name of module, ignoring name() changes, for LinkDot
VTimescale m_timeunit; // Parent module time unit
public:
AstCellInline(FileLine* fl, const string& name, const string& origModName,
@ -851,7 +849,6 @@ public:
, m_timeunit{timeunit} {}
ASTGEN_MEMBERS_AstCellInline;
void dump(std::ostream& str) const override;
const char* broken() const override;
// ACCESSORS
string name() const override VL_MT_STABLE { return m_name; } // * = Cell name
string origModName() const { return m_origModName; } // * = modp()->origName() before inlining
@ -940,10 +937,11 @@ public:
class AstConstPool final : public AstNode {
// Container for const static data
// @astgen op1 := modulep : AstModule // m_modp below TODO: fix this mess
//
// @astgen ptr := m_modp : AstModule // The Module holding the Scope below ...
// @astgen ptr := m_scopep : AstScope // Scope holding the constant variables
std::unordered_multimap<uint32_t, AstVarScope*> m_tables; // Constant tables (unpacked arrays)
std::unordered_multimap<uint32_t, AstVarScope*> m_consts; // Constant tables (scalars)
AstModule* const m_modp; // The Module holding the Scope below ...
AstScope* const m_scopep; // Scope holding the constant variables
AstVarScope* createNewEntry(const string& name, AstNodeExpr* initp);
@ -951,7 +949,6 @@ public:
explicit AstConstPool(FileLine* fl);
ASTGEN_MEMBERS_AstConstPool;
bool maybePointedTo() const override { return true; }
const char* broken() const override;
void cloneRelink() override { V3ERROR_NA; }
AstModule* modp() const { return m_modp; }
@ -1193,8 +1190,9 @@ class AstModportFTaskRef final : public AstNode {
// The storage for the function itself is inside the
// interface/instantiator, thus this is a reference
// PARENT: AstModport
//
// @astgen ptr := m_ftaskp : Optional[AstNodeFTask] // Link to the function
string m_name; // Name of the variable referenced
AstNodeFTask* m_ftaskp = nullptr; // Link to the function
bool m_export; // Type of the function (import/export)
public:
AstModportFTaskRef(FileLine* fl, const string& name, bool isExport)
@ -1202,8 +1200,6 @@ public:
, m_name{name}
, m_export{isExport} {}
ASTGEN_MEMBERS_AstModportFTaskRef;
const char* broken() const override;
void cloneRelink() override;
void dump(std::ostream& str) const override;
string name() const override VL_MT_STABLE { return m_name; }
bool isImport() const { return !m_export; }
@ -1215,8 +1211,9 @@ class AstModportVarRef final : public AstNode {
// A input/output/etc variable referenced under a modport
// The storage for the variable itself is inside the interface, thus this is a reference
// PARENT: AstModport
//
// @astgen ptr := m_varp : Optional[AstVar] // Link to the actual Var
string m_name; // Name of the variable referenced
AstVar* m_varp = nullptr; // Link to the actual Var
VDirection m_direction; // Direction of the variable (in/out)
public:
AstModportVarRef(FileLine* fl, const string& name, VDirection::en direction)
@ -1224,8 +1221,6 @@ public:
, m_name{name}
, m_direction{direction} {}
ASTGEN_MEMBERS_AstModportVarRef;
const char* broken() const override;
void cloneRelink() override;
void dump(std::ostream& str) const override;
string name() const override VL_MT_STABLE { return m_name; }
void direction(const VDirection& flag) { m_direction = flag; }
@ -1240,18 +1235,18 @@ class AstNetlist final : public AstNode {
// @astgen op1 := modulesp : List[AstNodeModule]
// @astgen op2 := filesp : List[AstNodeFile]
// @astgen op3 := miscsp : List[AstNode]
AstTypeTable* const m_typeTablep; // Reference to top type table, for faster lookup
AstConstPool* const m_constPoolp; // Reference to constant pool, for faster lookup
AstPackage* m_dollarUnitPkgp = nullptr; // $unit
AstPackage* m_stdPackagep = nullptr; // SystemVerilog std package
AstCFunc* m_evalp = nullptr; // The '_eval' function
AstCFunc* m_evalNbap = nullptr; // The '_eval__nba' function
AstVarScope* m_dpiExportTriggerp = nullptr; // The DPI export trigger variable
AstVar* m_delaySchedulerp = nullptr; // The delay scheduler variable
AstVarScope* m_nbaEventp = nullptr; // The NBA event variable
AstVarScope* m_nbaEventTriggerp = nullptr; // If set to 1, the NBA event should get triggered
AstTopScope* m_topScopep = nullptr; // The singleton AstTopScope under the top module
//
// @astgen ptr := m_typeTablep : AstTypeTable // Reference to type table, for faster lookup
// @astgen ptr := m_constPoolp : AstConstPool // Reference to constant pool, for faster lookup
// @astgen ptr := m_dollarUnitPkgp : Optional[AstPackage] // $unit
// @astgen ptr := m_stdPackagep : Optional[AstPackage] // SystemVerilog std package
// @astgen ptr := m_evalp : Optional[AstCFunc] // The '_eval' function
// @astgen ptr := m_evalNbap : Optional[AstCFunc] // The '_eval__nba' function
// @astgen ptr := m_dpiExportTriggerp : Optional[AstVarScope] // DPI export trigger variable
// @astgen ptr := m_delaySchedulerp : Optional[AstVar] // Delay scheduler variable
// @astgen ptr := m_nbaEventp : Optional[AstVarScope] // NBA event variable
// @astgen ptr := m_nbaEventTriggerp : Optional[AstVarScope] // NBA event trigger
// @astgen ptr := m_topScopep : Optional[AstTopScope] // Singleton AstTopScope
VTimescale m_timeunit; // Global time unit
VTimescale m_timeprecision; // Global time precision
bool m_timescaleSpecified = false; // Input HDL specified timescale
@ -1261,7 +1256,6 @@ class AstNetlist final : public AstNode {
public:
AstNetlist();
ASTGEN_MEMBERS_AstNetlist;
const char* broken() const override;
void cloneRelink() override { V3ERROR_NA; }
string name() const override VL_MT_STABLE { return "$root"; }
void dump(std::ostream& str) const override;
@ -1304,16 +1298,16 @@ public:
};
class AstPackageExport final : public AstNode {
// A package export declaration
//
// @astgen ptr := m_packagep : Optional[AstPackage] // Package hierarchy
string m_name;
AstPackage* m_packagep; // Package hierarchy
public:
AstPackageExport(FileLine* fl, AstPackage* packagep, const string& name)
: ASTGEN_SUPER_PackageExport(fl)
, m_name{name}
, m_packagep{packagep} {}
ASTGEN_MEMBERS_AstPackageExport;
const char* broken() const override;
void cloneRelink() override;
void dump(std::ostream& str) const override;
string name() const override VL_MT_STABLE { return m_name; }
AstPackage* packagep() const { return m_packagep; }
@ -1329,16 +1323,16 @@ public:
};
class AstPackageImport final : public AstNode {
// A package import declaration
//
// @astgen ptr := m_packagep : Optional[AstPackage] // Package hierarchy
string m_name;
AstPackage* m_packagep; // Package hierarchy
public:
AstPackageImport(FileLine* fl, AstPackage* packagep, const string& name)
: ASTGEN_SUPER_PackageImport(fl)
, m_name{name}
, m_packagep{packagep} {}
ASTGEN_MEMBERS_AstPackageImport;
const char* broken() const override;
void cloneRelink() override;
void dump(std::ostream& str) const override;
string name() const override VL_MT_STABLE { return m_name; }
AstPackage* packagep() const { return m_packagep; }
@ -1347,10 +1341,11 @@ public:
class AstPin final : public AstNode {
// A port or parameter assignment on an instantiation
// @astgen op1 := exprp : Optional[AstNode] // NodeExpr or NodeDType (nullptr if unconnected)
//
// @astgen ptr := m_modVarp : Optional[AstVar] // Input/output connects to on submodule
// @astgen ptr := m_modPTypep : Optional[AstParamTypeDType] // Param type connects to on sub
int m_pinNum; // Pin number
string m_name; // Pin name, or "" for number based interconnect
AstVar* m_modVarp = nullptr; // Input/output this pin connects to on submodule.
AstParamTypeDType* m_modPTypep = nullptr; // Param type this pin connects to on submodule.
bool m_param = false; // Pin connects to parameter
bool m_svDotName = false; // Pin is SystemVerilog .name'ed
bool m_svImplicit = false; // Pin is SystemVerilog .name'ed, allow implicit
@ -1363,8 +1358,8 @@ public:
}
inline AstPin(FileLine* fl, int pinNum, AstVarRef* varname, AstNode* exprp);
ASTGEN_MEMBERS_AstPin;
void cloneRelink() override {} // TODO V3Param shouldn't require avoiding cloneRelinkGen
void dump(std::ostream& str) const override;
const char* broken() const override;
string name() const override VL_MT_STABLE { return m_name; } // * = Pin name, ""=go by number
void name(const string& name) override { m_name = name; }
string prettyOperatorName() const override;
@ -1453,12 +1448,14 @@ class AstScope final : public AstNode {
// Children: NODEBLOCK
// @astgen op1 := varsp : List[AstVarScope]
// @astgen op2 := blocksp : List[AstNode] // Logic blocks/AstActive/AstCFunc
//
// Below scope and cell are nullptr if top scope
// @astgen ptr := m_aboveScopep : Optional[AstScope] // Scope above this one in the hierarchy
// @astgen ptr := m_aboveCellp : Optional[AstCell] // Cell above this in the hierarchy
// @astgen ptr := m_modp : AstNodeModule // Module scope corresponds to
// An AstScope->name() is special: . indicates an uninlined scope, __DOT__ an inlined scope
string m_name; // Name
AstScope* const m_aboveScopep; // Scope above this one in the hierarchy (nullptr if top)
AstCell* const m_aboveCellp; // Cell above this in the hierarchy (nullptr if top)
AstNodeModule* const m_modp; // Module scope corresponds to
public:
AstScope(FileLine* fl, AstNodeModule* modp, const string& name, AstScope* aboveScopep,
AstCell* aboveCellp)
@ -1468,8 +1465,10 @@ public:
, m_aboveCellp{aboveCellp}
, m_modp{modp} {}
ASTGEN_MEMBERS_AstScope;
void cloneRelink() override;
const char* broken() const override;
const char* broken() const override {
BROKEN_RTN(!m_modp);
return nullptr;
}
bool maybePointedTo() const override { return true; }
string name() const override VL_MT_STABLE { return m_name; } // * = Scope name
void name(const string& name) override { m_name = name; }
@ -1608,11 +1607,12 @@ public:
class AstTypeTable final : public AstNode {
// Container for hash of standard data types
// @astgen op1 := typesp : List[AstNodeDType]
AstConstraintRefDType* m_constraintRefp = nullptr;
AstEmptyQueueDType* m_emptyQueuep = nullptr;
AstQueueDType* m_queueIndexp = nullptr;
AstStreamDType* m_streamp = nullptr;
AstVoidDType* m_voidp = nullptr;
//
// @astgen ptr := m_constraintRefp : Optional[AstConstraintRefDType]
// @astgen ptr := m_emptyQueuep : Optional[AstEmptyQueueDType]
// @astgen ptr := m_queueIndexp : Optional[AstQueueDType]
// @astgen ptr := m_streamp : Optional[AstStreamDType]
// @astgen ptr := m_voidp : Optional[AstVoidDType]
AstBasicDType* m_basicps[VBasicDTypeKwd::_ENUM_MAX]{};
//
using DetailedMap = std::map<VBasicTypeKey, AstBasicDType*>;
@ -1622,12 +1622,6 @@ public:
explicit AstTypeTable(FileLine* fl);
ASTGEN_MEMBERS_AstTypeTable;
bool maybePointedTo() const override { return true; }
const char* broken() const override {
BROKEN_RTN(m_emptyQueuep && !m_emptyQueuep->brokeExists());
BROKEN_RTN(m_queueIndexp && !m_queueIndexp->brokeExists());
BROKEN_RTN(m_voidp && !m_voidp->brokeExists());
return nullptr;
}
void cloneRelink() override { V3ERROR_NA; }
AstBasicDType* findBasicDType(FileLine* fl, VBasicDTypeKwd kwd);
AstBasicDType* findLogicBitDType(FileLine* fl, VBasicDTypeKwd kwd, int width, int widthMin,
@ -2095,8 +2089,9 @@ class AstVarScope final : public AstNode {
// varscope for each var in the module
// Parents: MODULE
// Children: none
AstScope* m_scopep; // Scope variable is underneath
AstVar* m_varp; // [AfterLink] Pointer to variable itself
//
// @astgen ptr := m_scopep : Optional[AstScope] // Scope variable is underneath
// @astgen ptr := m_varp : Optional[AstVar] // [AfterLink] Pointer to variable itself
bool m_trace : 1; // Tracing is turned on for this scope
public:
AstVarScope(FileLine* fl, AstScope* scopep, AstVar* varp)
@ -2111,15 +2106,9 @@ public:
ASTGEN_MEMBERS_AstVarScope;
void cloneRelink() override {
if (m_varp && m_varp->clonep()) {
m_varp = m_varp->clonep();
UASSERT(m_scopep->clonep(), "No clone cross link: " << this);
m_scopep = m_scopep->clonep();
}
}
const char* broken() const override {
BROKEN_RTN(m_varp && !m_varp->brokeExists());
BROKEN_RTN(m_scopep && !m_scopep->brokeExists());
return nullptr;
cloneRelinkGen();
}
bool maybePointedTo() const override { return true; }
string name() const override VL_MT_STABLE { return scopep()->name() + "->" + varp()->name(); }
@ -2262,7 +2251,7 @@ public:
class AstClass final : public AstNodeModule {
// @astgen op4 := extendsp : List[AstClassExtends]
// MEMBERS
AstClassPackage* m_classOrPackagep = nullptr; // Package it will be emitted with
// @astgen ptr := m_classOrPackagep : Optional[AstClassPackage] // Package to be emitted with
bool m_extended = false; // Is extension or extended by other classes
bool m_interfaceClass = false; // Interface class
bool m_needRNG = false; // Need RNG, uses srandom/randomize
@ -2276,8 +2265,6 @@ public:
string verilogKwd() const override { return "class"; }
bool maybePointedTo() const override { return true; }
void dump(std::ostream& str) const override;
const char* broken() const override;
void cloneRelink() override;
bool timescaleMatters() const override { return false; }
AstClassPackage* classOrPackagep() const VL_MT_SAFE { return m_classOrPackagep; }
void classOrPackagep(AstClassPackage* classpackagep) { m_classOrPackagep = classpackagep; }
@ -2302,15 +2289,14 @@ public:
};
class AstClassPackage final : public AstNodeModule {
// The static information portion of a class (treated similarly to a package)
AstClass* m_classp
= nullptr; // Class package this is under (weak pointer, hard link is other way)
//
// @astgen ptr := m_classp : Optional[AstClass] // Class package this is under
// // (weak pointer, hard link is other way)
public:
AstClassPackage(FileLine* fl, const string& name)
: ASTGEN_SUPER_ClassPackage(fl, name) {}
ASTGEN_MEMBERS_AstClassPackage;
string verilogKwd() const override { return "classpackage"; }
const char* broken() const override;
void cloneRelink() override;
bool timescaleMatters() const override { return false; }
AstClass* classp() const VL_MT_SAFE { return m_classp; }
void classp(AstClass* classp) { m_classp = classp; }
@ -2647,8 +2633,9 @@ public:
};
class AstCoverDecl final : public AstNodeStmt {
// Coverage analysis point declaration
AstCoverDecl* m_dataDeclp = nullptr; // [After V3CoverageJoin] Pointer to duplicate
// declaration to get data from instead
//
// [After V3CoverageJoin] Duplicate declaration to get data from instead
// @astgen ptr := m_dataDeclp : Optional[AstCoverDecl]
string m_page;
string m_text;
string m_hier;
@ -2665,15 +2652,11 @@ public:
, m_offset{offset} {}
ASTGEN_MEMBERS_AstCoverDecl;
const char* broken() const override {
BROKEN_RTN(m_dataDeclp && !m_dataDeclp->brokeExists());
if (m_dataDeclp && m_dataDeclp->m_dataDeclp) { // Avoid O(n^2) accessing
v3fatalSrc("dataDeclp should point to real data, not be a list");
}
return nullptr;
}
void cloneRelink() override {
if (m_dataDeclp && m_dataDeclp->clonep()) m_dataDeclp = m_dataDeclp->clonep();
}
void dump(std::ostream& str) const override;
int instrCount() const override { return 1 + 2 * INSTR_COUNT_LD; }
bool maybePointedTo() const override { return true; }
@ -2700,19 +2683,13 @@ public:
};
class AstCoverInc final : public AstNodeStmt {
// Coverage analysis point; increment coverage count
AstCoverDecl* m_declp; // [After V3Coverage] Pointer to declaration
//
// @astgen ptr := m_declp : AstCoverDecl // [After V3CoverageJoin] Declaration
public:
AstCoverInc(FileLine* fl, AstCoverDecl* declp)
: ASTGEN_SUPER_CoverInc(fl)
, m_declp{declp} {}
ASTGEN_MEMBERS_AstCoverInc;
const char* broken() const override {
BROKEN_RTN(!declp()->brokeExists());
return nullptr;
}
void cloneRelink() override {
if (m_declp->clonep()) m_declp = m_declp->clonep();
}
void dump(std::ostream& str) const override;
int instrCount() const override { return 1 + 2 * INSTR_COUNT_LD; }
bool same(const AstNode* samep) const override {
@ -2947,7 +2924,8 @@ class AstJumpBlock final : public AstNodeStmt {
// Children: {statement list, with JumpGo and JumpLabel below}
// @astgen op1 := stmtsp : List[AstNode]
// @astgen op2 := endStmtsp : List[AstNode]
AstJumpLabel* m_labelp = nullptr; // [After V3Jump] Pointer to declaration
//
// @astgen ptr := m_labelp : AstJumpLabel // [After V3Jump] Pointer to declaration
int m_labelNum = 0; // Set by V3EmitCSyms to tell final V3Emit what to increment
public:
// After construction must call ->labelp to associate with appropriate label
@ -2955,9 +2933,8 @@ public:
: ASTGEN_SUPER_JumpBlock(fl) {
this->addStmtsp(stmtsp);
}
const char* broken() const override;
void cloneRelink() override;
ASTGEN_MEMBERS_AstJumpBlock;
const char* broken() const override;
int instrCount() const override { return 0; }
bool maybePointedTo() const override { return true; }
bool same(const AstNode* /*samep*/) const override { return true; }
@ -2971,14 +2948,14 @@ class AstJumpGo final : public AstNodeStmt {
// No support for backward jumps at present
// Parents: {statement list with JumpBlock above}
// Children: none
AstJumpLabel* m_labelp; // [After V3Jump] Pointer to declaration
//
// @astgen ptr := m_labelp : AstJumpLabel // [After V3Jump] Pointer to declaration
public:
AstJumpGo(FileLine* fl, AstJumpLabel* labelp)
: ASTGEN_SUPER_JumpGo(fl)
, m_labelp{labelp} {}
ASTGEN_MEMBERS_AstJumpGo;
const char* broken() const override;
void cloneRelink() override;
void dump(std::ostream& str) const override;
int instrCount() const override { return INSTR_COUNT_BRANCH; }
bool same(const AstNode* samep) const override {
@ -2994,7 +2971,7 @@ class AstJumpLabel final : public AstNodeStmt {
// Jump point declaration
// Parents: {statement list with JumpBlock above}
// Children: none
AstJumpBlock* m_blockp; // [After V3Jump] Pointer to declaration
// @astgen ptr := m_blockp : AstJumpBlock // [After V3Jump] Pointer to declaration
public:
AstJumpLabel(FileLine* fl, AstJumpBlock* blockp)
: ASTGEN_SUPER_JumpLabel(fl)
@ -3006,9 +2983,6 @@ public:
BROKEN_RTN(blockp()->labelp() != this);
return nullptr;
}
void cloneRelink() override {
if (m_blockp->clonep()) m_blockp = m_blockp->clonep();
}
void dump(std::ostream& str) const override;
int instrCount() const override { return 0; }
bool same(const AstNode* samep) const override {
@ -3281,29 +3255,22 @@ class AstTraceInc final : public AstNodeStmt {
// Trace point dump
// @astgen op1 := precondsp : List[AstNode] // Statements to emit before this node
// @astgen op2 := valuep : AstNodeExpr // Expression being traced (from decl)
AstTraceDecl* m_declp; // Pointer to declaration
//
// @astgen ptr := m_declp : AstTraceDecl // Pointer to declaration
const uint32_t m_baseCode; // Trace code base value in function containing this AstTraceInc
const VTraceType m_traceType; // Is this a const/full/incremental dump
public:
AstTraceInc(FileLine* fl, AstTraceDecl* declp, VTraceType traceType, uint32_t baseCode = 0)
: ASTGEN_SUPER_TraceInc(fl)
, m_declp{declp}
, m_baseCode{baseCode}
, m_traceType{traceType} {
, m_traceType{traceType}
, m_declp{declp} {
dtypeFrom(declp);
this->valuep(
declp->valuep()->cloneTree(true)); // TODO: maybe use reference to TraceDecl instead?
}
ASTGEN_MEMBERS_AstTraceInc;
const char* broken() const override {
BROKEN_RTN(!declp()->brokeExists());
return nullptr;
}
void cloneRelink() override {
if (m_declp->clonep()) m_declp = m_declp->clonep();
}
void dump(std::ostream& str) const override;
int instrCount() const override { return 10 + 2 * INSTR_COUNT_LD; }
bool hasDType() const override { return true; }

View File

@ -23,6 +23,7 @@
#include "V3PartitionGraph.h" // Just for mtask dumping
#include "V3String.h"
#include "V3Ast__gen_impl.h" // Generated by 'astgen'
#include "V3Ast__gen_macros.h" // Generated by 'astgen'
#include <iomanip>
@ -33,31 +34,15 @@
// Special methods
// We need these here, because the classes they point to aren't defined when we declare the class
const char* AstIfaceRefDType::broken() const {
BROKEN_RTN(m_ifacep && !m_ifacep->brokeExists());
BROKEN_RTN(m_cellp && !m_cellp->brokeExists());
BROKEN_RTN(m_modportp && !m_modportp->brokeExists());
return nullptr;
}
AstIface* AstIfaceRefDType::ifaceViaCellp() const {
return ((m_cellp && m_cellp->modp()) ? VN_AS(m_cellp->modp(), Iface) : m_ifacep);
}
const char* AstNodeFTaskRef::broken() const {
BROKEN_RTN(m_taskp && !m_taskp->brokeExists());
BROKEN_RTN(m_classOrPackagep && !m_classOrPackagep->brokeExists());
BROKEN_RTN(m_purity.isCached() && m_purity.get() != getPurityRecurse());
return nullptr;
}
void AstNodeFTaskRef::cloneRelink() {
if (m_taskp && m_taskp->clonep()) m_taskp = m_taskp->clonep();
if (m_classOrPackagep && m_classOrPackagep->clonep()) {
m_classOrPackagep = m_classOrPackagep->clonep();
}
}
bool AstNodeFTaskRef::isPure() {
if (!this->taskp()) {
// The task isn't linked yet, so it's assumed that it is impure, but the value shouldn't be
@ -83,40 +68,11 @@ bool AstNodeFTaskRef::getPurityRecurse() const {
}
bool AstNodeFTaskRef::isGateOptimizable() const { return m_taskp && m_taskp->isGateOptimizable(); }
const char* AstNodeVarRef::broken() const {
BROKEN_RTN(m_varp && !m_varp->brokeExists());
BROKEN_RTN(m_varScopep && !m_varScopep->brokeExists());
BROKEN_RTN(m_classOrPackagep && !m_classOrPackagep->brokeExists());
return nullptr;
}
void AstNodeVarRef::cloneRelink() {
if (m_varp && m_varp->clonep()) m_varp = m_varp->clonep();
if (m_varScopep && m_varScopep->clonep()) m_varScopep = m_varScopep->clonep();
if (m_classOrPackagep && m_classOrPackagep->clonep()) {
m_classOrPackagep = m_classOrPackagep->clonep();
}
}
void AstAddrOfCFunc::cloneRelink() {
if (m_funcp && m_funcp->clonep()) m_funcp = m_funcp->clonep();
}
const char* AstAddrOfCFunc::broken() const {
BROKEN_RTN(m_funcp && !m_funcp->brokeExists());
return nullptr;
}
int AstNodeSel::bitConst() const {
const AstConst* const constp = VN_AS(bitp(), Const);
return (constp ? constp->toSInt() : 0);
}
const char* AstNodeUOrStructDType::broken() const {
BROKEN_RTN(m_classOrPackagep && !m_classOrPackagep->brokeExists());
return nullptr;
}
void AstNodeStmt::dump(std::ostream& str) const { this->AstNode::dump(str); }
void AstNodeCCall::dump(std::ostream& str) const {
@ -128,13 +84,6 @@ void AstNodeCCall::dump(std::ostream& str) const {
str << " " << name();
}
}
void AstNodeCCall::cloneRelink() {
if (m_funcp && m_funcp->clonep()) m_funcp = m_funcp->clonep();
}
const char* AstNodeCCall::broken() const {
BROKEN_RTN(m_funcp && !m_funcp->brokeExists());
return nullptr;
}
bool AstNodeCCall::isPure() { return funcp()->dpiPure(); }
bool AstNodeUniop::isPure() {
if (!m_purity.isCached()) m_purity.set(lhsp()->isPure());
@ -954,24 +903,7 @@ const char* AstJumpBlock::broken() const {
BROKEN_RTN(!labelp()->brokeExistsBelow());
return nullptr;
}
void AstJumpBlock::cloneRelink() {
if (m_labelp->clonep()) m_labelp = m_labelp->clonep();
}
const char* AstScope::broken() const {
BROKEN_RTN(m_aboveScopep && !m_aboveScopep->brokeExists());
BROKEN_RTN(m_aboveCellp && !m_aboveCellp->brokeExists());
BROKEN_RTN(!m_modp);
BROKEN_RTN(m_modp && !m_modp->brokeExists());
return nullptr;
}
void AstScope::cloneRelink() {
if (m_aboveScopep && m_aboveScopep->clonep()) m_aboveScopep->clonep();
if (m_aboveCellp && m_aboveCellp->clonep()) m_aboveCellp->clonep();
if (m_modp && static_cast<AstNode*>(m_modp)->clonep()) {
static_cast<AstNode*>(m_modp)->clonep();
}
}
string AstScope::nameDotless() const {
string result = shortName();
string::size_type pos;
@ -1196,11 +1128,6 @@ AstConstPool::AstConstPool(FileLine* fl)
this->modulep(m_modp);
m_modp->addStmtsp(m_scopep);
}
const char* AstConstPool::broken() const {
BROKEN_RTN(m_modp && !m_modp->brokeExists());
BROKEN_RTN(m_scopep && !m_scopep->brokeExists());
return nullptr;
}
AstVarScope* AstConstPool::createNewEntry(const string& name, AstNodeExpr* initp) {
FileLine* const fl = initp->fileline();
@ -1450,27 +1377,11 @@ void AstCell::dump(std::ostream& str) const {
str << " ->UNLINKED:" << modName();
}
}
const char* AstCell::broken() const {
BROKEN_RTN(m_modp && !m_modp->brokeExists());
return nullptr;
}
void AstCellInline::dump(std::ostream& str) const {
this->AstNode::dump(str);
str << " -> " << origModName();
str << " [scopep=" << nodeAddr(scopep()) << "]";
}
const char* AstCellInline::broken() const {
BROKEN_RTN(m_scopep && !m_scopep->brokeExists());
return nullptr;
}
const char* AstClassPackage::broken() const {
BROKEN_BASE_RTN(AstNodeModule::broken());
BROKEN_RTN(m_classp && !m_classp->brokeExists());
return nullptr;
}
void AstClassPackage::cloneRelink() {
if (m_classp && m_classp->clonep()) m_classp = m_classp->clonep();
}
bool AstClass::isCacheableChild(const AstNode* nodep) {
return (VN_IS(nodep, Var) || VN_IS(nodep, Constraint) || VN_IS(nodep, EnumItemRef)
|| (VN_IS(nodep, NodeFTask) && !VN_AS(nodep, NodeFTask)->isExternProto())
@ -1496,17 +1407,6 @@ void AstClass::dump(std::ostream& str) const {
if (isInterfaceClass()) str << " [IFCCLS]";
if (isVirtual()) str << " [VIRT]";
}
const char* AstClass::broken() const {
BROKEN_BASE_RTN(AstNodeModule::broken());
BROKEN_RTN(m_classOrPackagep && !m_classOrPackagep->brokeExists());
return nullptr;
}
void AstClass::cloneRelink() {
AstNodeModule::cloneRelink();
if (m_classOrPackagep && m_classOrPackagep->clonep()) {
m_classOrPackagep = m_classOrPackagep->clonep();
}
}
void AstClassExtends::dump(std::ostream& str) const {
this->AstNode::dump(str);
if (isImplements()) str << " [IMPLEMENTS]";
@ -1540,17 +1440,6 @@ void AstClassRefDType::dumpSmall(std::ostream& str) const {
this->AstNodeDType::dumpSmall(str);
str << "class:" << name();
}
const char* AstClassRefDType::broken() const {
BROKEN_RTN(m_classp && !m_classp->brokeExists());
BROKEN_RTN(m_classOrPackagep && !m_classOrPackagep->brokeExists());
return nullptr;
}
void AstClassRefDType::cloneRelink() {
if (m_classp && m_classp->clonep()) m_classp = m_classp->clonep();
if (m_classOrPackagep && m_classOrPackagep->clonep()) {
m_classOrPackagep = m_classOrPackagep->clonep();
}
}
string AstClassRefDType::name() const { return classp() ? classp()->name() : "<unlinked>"; }
void AstNodeCoverOrAssert::dump(std::ostream& str) const {
this->AstNodeStmt::dump(str);
@ -1583,24 +1472,12 @@ void AstEnumItemRef::dump(std::ostream& str) const {
}
}
const char* AstEnumDType::broken() const {
BROKEN_RTN(!((m_refDTypep && !childDTypep() && m_refDTypep->brokeExists())
|| (!m_refDTypep && childDTypep())));
BROKEN_RTN(!((m_refDTypep && !childDTypep()) || (!m_refDTypep && childDTypep())));
BROKEN_RTN(std::any_of(m_tableMap.begin(), m_tableMap.end(),
[](const auto& p) { return !p.second->brokeExists(); }));
return nullptr;
}
const char* AstEnumItemRef::broken() const {
BROKEN_RTN(m_itemp && !m_itemp->brokeExists());
BROKEN_RTN(m_classOrPackagep && !m_classOrPackagep->brokeExists());
return nullptr;
}
void AstEnumItemRef::cloneRelink() {
if (m_itemp->clonep()) m_itemp = m_itemp->clonep();
if (m_classOrPackagep && m_classOrPackagep->clonep()) {
m_classOrPackagep = m_classOrPackagep->clonep();
}
}
void AstIfaceRefDType::dump(std::ostream& str) const {
this->AstNodeDType::dump(str);
if (cellName() != "") str << " cell=" << cellName();
@ -1620,11 +1497,6 @@ void AstIfaceRefDType::dumpSmall(std::ostream& str) const {
this->AstNodeDType::dumpSmall(str);
str << "iface";
}
void AstIfaceRefDType::cloneRelink() {
if (m_cellp && m_cellp->clonep()) m_cellp = m_cellp->clonep();
if (m_ifacep && m_ifacep->clonep()) m_ifacep = m_ifacep->clonep();
if (m_modportp && m_modportp->clonep()) m_modportp = m_modportp->clonep();
}
void AstInitArray::dump(std::ostream& str) const {
this->AstNode::dump(str);
int n = 0;
@ -1645,6 +1517,7 @@ const char* AstInitArray::broken() const {
return nullptr;
}
void AstInitArray::cloneRelink() {
cloneRelinkGen();
for (KeyItemMap::iterator it = m_map.begin(); it != m_map.end(); ++it) {
if (it->second->clonep()) it->second = it->second->clonep();
}
@ -1686,9 +1559,7 @@ const char* AstJumpGo::broken() const {
BROKEN_RTN(!labelp()->brokeExistsBelow());
return nullptr;
}
void AstJumpGo::cloneRelink() {
if (m_labelp->clonep()) m_labelp = m_labelp->clonep();
}
void AstJumpLabel::dump(std::ostream& str) const {
this->AstNodeStmt::dump(str);
str << " -> ";
@ -1726,13 +1597,6 @@ void AstMemberSel::dump(std::ostream& str) const {
str << "%Error:UNLINKED";
}
}
void AstMemberSel::cloneRelink() {
if (m_varp && m_varp->clonep()) m_varp = m_varp->clonep();
}
const char* AstMemberSel::broken() const {
BROKEN_RTN(m_varp && !m_varp->brokeExists());
return nullptr;
}
void AstModportFTaskRef::dump(std::ostream& str) const {
this->AstNode::dump(str);
if (isExport()) str << " EXPORT";
@ -1744,13 +1608,6 @@ void AstModportFTaskRef::dump(std::ostream& str) const {
str << " -> UNLINKED";
}
}
const char* AstModportFTaskRef::broken() const {
BROKEN_RTN(m_ftaskp && !m_ftaskp->brokeExists());
return nullptr;
}
void AstModportFTaskRef::cloneRelink() {
if (m_ftaskp && m_ftaskp->clonep()) m_ftaskp = m_ftaskp->clonep();
}
void AstModportVarRef::dump(std::ostream& str) const {
this->AstNode::dump(str);
if (direction().isAny()) str << " " << direction();
@ -1761,13 +1618,6 @@ void AstModportVarRef::dump(std::ostream& str) const {
str << " -> UNLINKED";
}
}
const char* AstModportVarRef::broken() const {
BROKEN_RTN(m_varp && !m_varp->brokeExists());
return nullptr;
}
void AstModportVarRef::cloneRelink() {
if (m_varp && m_varp->clonep()) m_varp = m_varp->clonep();
}
void AstPin::dump(std::ostream& str) const {
this->AstNode::dump(str);
if (modVarp()) {
@ -1779,11 +1629,6 @@ void AstPin::dump(std::ostream& str) const {
if (svDotName()) str << " [.n]";
if (svImplicit()) str << " [.SV]";
}
const char* AstPin::broken() const {
BROKEN_RTN(m_modVarp && !m_modVarp->brokeExists());
BROKEN_RTN(m_modPTypep && !m_modPTypep->brokeExists());
return nullptr;
}
string AstPin::prettyOperatorName() const {
return modVarp()
? ((modVarp()->direction().isAny() ? modVarp()->direction().prettyName() + " " : "")
@ -1852,19 +1697,6 @@ void AstRefDType::dumpSmall(std::ostream& str) const {
this->AstNodeDType::dumpSmall(str);
str << "ref";
}
const char* AstRefDType::broken() const {
BROKEN_RTN(m_typedefp && !m_typedefp->brokeExists());
BROKEN_RTN(m_refDTypep && !m_refDTypep->brokeExists());
BROKEN_RTN(m_classOrPackagep && !m_classOrPackagep->brokeExists());
return nullptr;
}
void AstRefDType::cloneRelink() {
if (m_typedefp && m_typedefp->clonep()) m_typedefp = m_typedefp->clonep();
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
if (m_classOrPackagep && m_classOrPackagep->clonep()) {
m_classOrPackagep = m_classOrPackagep->clonep();
}
}
AstNodeDType* AstRefDType::subDTypep() const VL_MT_STABLE {
if (typedefp()) return typedefp()->subDTypep();
return refDTypep(); // Maybe nullptr
@ -1940,18 +1772,6 @@ void AstNetlist::dump(std::ostream& str) const {
this->AstNode::dump(str);
str << " [" << timeunit() << "/" << timeprecision() << "]";
}
const char* AstNetlist::broken() const {
BROKEN_RTN(m_typeTablep && !m_typeTablep->brokeExists());
BROKEN_RTN(m_constPoolp && !m_constPoolp->brokeExists());
BROKEN_RTN(m_dollarUnitPkgp && !m_dollarUnitPkgp->brokeExists());
BROKEN_RTN(m_evalp && !m_evalp->brokeExists());
BROKEN_RTN(m_dpiExportTriggerp && !m_dpiExportTriggerp->brokeExists());
BROKEN_RTN(m_topScopep && !m_topScopep->brokeExists());
BROKEN_RTN(m_delaySchedulerp && !m_delaySchedulerp->brokeExists());
BROKEN_RTN(m_nbaEventp && !m_nbaEventp->brokeExists());
BROKEN_RTN(m_nbaEventTriggerp && !m_nbaEventTriggerp->brokeExists());
return nullptr;
}
AstPackage* AstNetlist::dollarUnitPkgAddp() {
if (!m_dollarUnitPkgp) {
m_dollarUnitPkgp = new AstPackage{fileline(), AstPackage::dollarUnitName()};
@ -1986,24 +1806,10 @@ void AstPackageExport::dump(std::ostream& str) const {
this->AstNode::dump(str);
str << " -> " << packagep();
}
const char* AstPackageExport::broken() const {
BROKEN_RTN(!m_packagep || !m_packagep->brokeExists());
return nullptr;
}
void AstPackageExport::cloneRelink() {
if (m_packagep && m_packagep->clonep()) m_packagep = m_packagep->clonep();
}
void AstPackageImport::dump(std::ostream& str) const {
this->AstNode::dump(str);
str << " -> " << packagep();
}
const char* AstPackageImport::broken() const {
BROKEN_RTN(!m_packagep || !m_packagep->brokeExists());
return nullptr;
}
void AstPackageImport::cloneRelink() {
if (m_packagep && m_packagep->clonep()) m_packagep = m_packagep->clonep();
}
void AstPatMember::dump(std::ostream& str) const {
this->AstNodeExpr::dump(str);
if (isDefault()) str << " [DEFAULT]";
@ -2157,7 +1963,7 @@ void AstVarRef::dump(std::ostream& str) const {
}
const char* AstVarRef::broken() const {
BROKEN_RTN(!varp());
return AstNodeVarRef::broken();
return nullptr;
}
bool AstVarRef::same(const AstNode* samep) const { return same(VN_DBG_AS(samep, VarRef)); }
int AstVarRef::instrCount() const {
@ -2268,13 +2074,6 @@ void AstActive::dump(std::ostream& str) const {
str << "UNLINKED";
}
}
const char* AstActive::broken() const {
BROKEN_RTN(m_sensesp && !m_sensesp->brokeExists());
return nullptr;
}
void AstActive::cloneRelink() {
if (m_sensesp->clonep()) m_sensesp = m_sensesp->clonep();
}
void AstNodeFTaskRef::dump(std::ostream& str) const {
this->AstNodeExpr::dump(str);
if (classOrPackagep()) str << " pkg=" << nodeAddr(classOrPackagep());
@ -2407,13 +2206,6 @@ void AstCFunc::dump(std::ostream& str) const {
if (needProcess()) str << " [NPRC]";
if (entryPoint()) str << " [ENTRY]";
}
const char* AstCAwait::broken() const {
BROKEN_RTN(m_sensesp && !m_sensesp->brokeExists());
return nullptr;
}
void AstCAwait::cloneRelink() {
if (m_sensesp && m_sensesp->clonep()) m_sensesp = m_sensesp->clonep();
}
void AstCAwait::dump(std::ostream& str) const {
this->AstNodeUniop::dump(str);
if (sensesp()) {
@ -2502,13 +2294,6 @@ void AstCMethodHard::setPurity() {
UASSERT_OBJ(isPureIt != isPureMethod.end(), this, "Unknown purity of method " + name());
m_pure = isPureIt->second;
}
const char* AstCFunc::broken() const {
BROKEN_RTN((m_scopep && !m_scopep->brokeExists()));
return nullptr;
}
void AstCFunc::cloneRelink() {
if (m_scopep && m_scopep->clonep()) m_scopep = m_scopep->clonep();
}
void AstCUse::dump(std::ostream& str) const {
this->AstNode::dump(str);

View File

@ -164,7 +164,7 @@ private:
void processEnter(AstNode* nodep) {
nodep->brokenState(m_brokenCntCurrentUnder);
const char* const whyp = nodep->broken();
const char* const whyp = nodep->brokenGen();
UASSERT_OBJ(!whyp, nodep,
"Broken link in node (or something without maybePointedTo): " << whyp);
if (!s_brokenAllowMidvisitorCheck) nodep->checkIter();

View File

@ -1,5 +1,5 @@
#!/usr/bin/env python3
# pylint: disable=C0103,C0114,C0115,C0116,C0123,C0209,C0301,C0302,R0902,R0913,R0914,R0912,R0915,W0621
# pylint: disable=C0103,C0114,C0115,C0116,C0123,C0209,C0301,C0302,R0902,R0904,R0913,R0914,R0912,R0915,W0511,W0621
######################################################################
import argparse
@ -29,6 +29,7 @@ class Node:
self._ordIdx = None # Ordering index of this class
self._arity = -1 # Arity of node
self._ops = {} # Operands of node
self._ptrs = [] # Pointer members of node (name, types)
@property
def name(self):
@ -54,6 +55,11 @@ class Node:
def lineno(self):
return self._lineno
@property
def ptrs(self):
assert self.isCompleted
return self._ptrs
# Pre completion methods
def addSubClass(self, subClass):
assert not self.isCompleted
@ -73,6 +79,10 @@ class Node:
return self.superClass.getOp(n)
return None
def addPtr(self, name, monad, kind):
name = re.sub(r'^m_', '', name)
self._ptrs.append({'name': name, 'monad': monad, 'kind': kind})
# Computes derived properties over entire class hierarchy.
# No more changes to the hierarchy are allowed once this was called
def complete(self, typeId=0, ordIdx=0):
@ -653,12 +663,38 @@ def read_types(filename, Nodes, prefix):
"Aliased op" + str(n) + " is not defined")
else:
node.addOp(n, ident, *op[1:])
elif what == "ptr":
ident, sep, kind = partitionAndStrip(rest, ":")
ident = ident.strip()
kind = parseOpType(kind)
if not kind:
error(
lineno, "Bad type for '@astgen " + what +
"' (expecting Ast*, Optional[Ast*], or List[Ast*]):"
+ decl)
if not re.match(r'^m_(\w+)$', ident):
error(
lineno, "Malformed '@astgen ptr'"
" identifier (expecting m_ in '" + ident + "')")
else:
node.addPtr(ident, *kind)
else:
error(
lineno,
"Malformed @astgen what (expecting 'op1'..'op4'," +
" 'alias op1'.., 'ptr'): " + what)
else:
line = re.sub(r'//.*$', '', line)
if re.match(r'.*[Oo]p[1-9].*', line):
error(lineno,
"Use generated accessors to access op<N> operands")
if re.match(
r'^\s*Ast[A-Z][A-Za-z0-9_]+\s*\*(\s*const)?\s+m_[A-Za-z0-9_]+\s*;',
line):
error(lineno,
"Use '@astgen ptr' for Ast pointer members: " + line)
checkFinishedNode(node)
if hasErrors:
sys.exit("%Error: Stopping due to errors reported above")
@ -944,6 +980,50 @@ def write_ast_type_info(filename):
))
def write_ast_impl(filename):
with open_file(filename) as fh:
def emitBlock(pattern, **fmt):
fh.write(
textwrap.indent(textwrap.dedent(pattern),
" ").format(**fmt))
for node in AstNodeList:
if node.name == "Node":
continue
emitBlock("const char* Ast{t}::brokenGen() const {{\n",
t=node.name)
for superClass in node.allSuperClasses:
if superClass.name != 'Node':
emitBlock(
" BROKEN_BASE_RTN(Ast{super}::brokenGen());\n",
super=superClass.name)
for ptr in node.ptrs:
if ptr['monad'] == 'Optional':
emitBlock(
" BROKEN_RTN(m_{name} && !m_{name}->brokeExists());\n",
name=ptr['name'])
else:
emitBlock(" BROKEN_RTN(!m_{name});\n" +
" BROKEN_RTN(!m_{name}->brokeExists());\n",
name=ptr['name'])
# Node's broken rules can be specialized by declaring broken()
emitBlock(" return Ast{t}::broken(); }}\n", t=node.name)
emitBlock("void Ast{t}::cloneRelinkGen() {{\n", t=node.name)
for superClass in node.allSuperClasses:
if superClass.name != 'Node':
emitBlock(" Ast{super}::cloneRelinkGen();\n",
super=superClass.name)
for ptr in node.ptrs:
emitBlock(
" if (m_{name} && m_{name}->clonep()) m_{name} = m_{name}->clonep();\n",
name=ptr['name'],
kind=ptr['kind'])
emitBlock("}}\n")
def write_ast_macros(filename):
with open_file(filename) as fh:
@ -954,6 +1034,24 @@ def write_ast_macros(filename):
for node in AstNodeList:
fh.write("#define ASTGEN_MEMBERS_Ast{t} \\\n".format(t=node.name))
any_ptr = False
for ptr in node.ptrs:
if not any_ptr:
fh.write("private: \\\n")
any_ptr = True
emitBlock("Ast{kind}* m_{name} = nullptr;",
name=ptr['name'],
kind=ptr['kind'])
if any_ptr:
fh.write("public: \\\n")
# TODO pointer accessors
# for ptr in node.ptrs:
# emitBlock(
# ("{kind}* {name}() const {{ return m_{name}; }}\n" +
# "void {name}({kind}* nodep) {{ m_{name} = nodep; }}"),
# name=ptr['name'],
# kind=ptr['kind'])
emitBlock('''\
Ast{t}* unlinkFrBack(VNRelinker* linkerp = nullptr) {{
return static_cast<Ast{t}*>(AstNode::unlinkFrBack(linkerp));
@ -969,6 +1067,8 @@ def write_ast_macros(filename):
}}
Ast{t}* clonep() const {{ return static_cast<Ast{t}*>(AstNode::clonep()); }}
Ast{t}* addNext(Ast{t}* nodep) {{ return static_cast<Ast{t}*>(AstNode::addNext(this, nodep)); }}
const char* brokenGen() const override;
void cloneRelinkGen() override;
''',
t=node.name)
@ -1315,6 +1415,7 @@ if Args.classes:
write_type_enum("Ast", AstNodeList)
write_type_tests("Ast", AstNodeList)
write_ast_type_info("V3Ast__gen_type_info.h")
write_ast_impl("V3Ast__gen_impl.h")
write_ast_macros("V3Ast__gen_macros.h")
write_ast_yystype("V3Ast__gen_yystype.h")
# Write Dfg code
@ -1337,5 +1438,5 @@ for cpt in Args.infiles:
######################################################################
# Local Variables:
# compile-command: "cd obj_dbg && ../astgen -I.. V3Const.cpp"
# compile-command: "touch src/V3AstNodeExpr.h ; v4make"
# End: