Internals: Use astgen for cross-node pointers. No functional change intended. (#4727)
This commit is contained in:
parent
d1ee9827a0
commit
feae9ca4aa
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
105
src/astgen
105
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<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:
|
||||
|
|
|
|||
Loading…
Reference in New Issue