From feae9ca4aac4e0ede4af718e80aaed460b998936 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 1 Dec 2023 00:58:16 +0000 Subject: [PATCH] Internals: Use astgen for cross-node pointers. No functional change intended. (#4727) --- src/V3Ast.h | 5 +- src/V3AstNodeDType.h | 126 +++++++++--------------- src/V3AstNodeExpr.h | 71 +++++--------- src/V3AstNodeOther.h | 185 +++++++++++++++-------------------- src/V3AstNodes.cpp | 225 +------------------------------------------ src/V3Broken.cpp | 2 +- src/astgen | 105 +++++++++++++++++++- 7 files changed, 255 insertions(+), 464 deletions(-) diff --git a/src/V3Ast.h b/src/V3Ast.h index f1755b171..e7dd18687 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -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; diff --git a/src/V3AstNodeDType.h b/src/V3AstNodeDType.h index 32679819c..07a00b96c 100644 --- a/src/V3AstNodeDType.h +++ b/src/V3AstNodeDType.h @@ -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(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; 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; diff --git a/src/V3AstNodeExpr.h b/src/V3AstNodeExpr.h index 37309f7ad..2d875707a 100644 --- a/src/V3AstNodeExpr.h +++ b/src/V3AstNodeExpr.h @@ -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; } diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index 8f9f93299..b555c0fad 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -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 m_tables; // Constant tables (unpacked arrays) std::unordered_multimap 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; @@ -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; } diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 5b717f513..8fcf46840 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -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 @@ -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(m_modp)->clonep()) { - static_cast(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() : ""; } 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); diff --git a/src/V3Broken.cpp b/src/V3Broken.cpp index 8d99282eb..1e6ba06e0 100644 --- a/src/V3Broken.cpp +++ b/src/V3Broken.cpp @@ -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(); diff --git a/src/astgen b/src/astgen index 70f102c60..a689216df 100755 --- a/src/astgen +++ b/src/astgen @@ -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 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(AstNode::unlinkFrBack(linkerp)); @@ -969,6 +1067,8 @@ def write_ast_macros(filename): }} Ast{t}* clonep() const {{ return static_cast(AstNode::clonep()); }} Ast{t}* addNext(Ast{t}* nodep) {{ return static_cast(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: