diff --git a/src/V3Ast.cpp b/src/V3Ast.cpp index 1b33e452c..1fd013177 100644 --- a/src/V3Ast.cpp +++ b/src/V3Ast.cpp @@ -559,6 +559,15 @@ void AstNode::relinkOneLink(AstNode*& pointpr, // Ref to pointer that gets set pointpr = newp; } +void AstNode::swapWith (AstNode* bp) { + AstNRelinker aHandle; + AstNRelinker bHandle; + this->unlinkFrBack(&aHandle); + bp->unlinkFrBack(&bHandle); + aHandle.relink(bp); + bHandle.relink(this); +} + //====================================================================== // Clone diff --git a/src/V3Ast.h b/src/V3Ast.h index 5f3b48961..cdf216828 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -390,19 +390,19 @@ struct AstNUser { class AstUserInUseBase { protected: - static void allocate(uint32_t& cntGblRef, bool& userBusyRef) { + static void allocate(int id, uint32_t& cntGblRef, bool& userBusyRef) { // Perhaps there's still a AstUserInUse in scope for this? - UASSERT_STATIC(!userBusyRef, "Conflicting user use; AstUser*InUse request when under another AstUserInUse"); + UASSERT_STATIC(!userBusyRef, "Conflicting user use; AstUser"+cvtToStr(id)+"InUse request when under another AstUserInUse"); userBusyRef = true; - clearcnt(cntGblRef, userBusyRef); + clearcnt(id, cntGblRef, userBusyRef); } - static void free(uint32_t& cntGblRef, bool& userBusyRef) { - UASSERT_STATIC(userBusyRef, "Free of User*() not under AstUserInUse"); - clearcnt(cntGblRef, userBusyRef); // Includes a checkUse for us + static void free(int id, uint32_t& cntGblRef, bool& userBusyRef) { + UASSERT_STATIC(userBusyRef, "Free of User"+cvtToStr(id)+"() not under AstUserInUse"); + clearcnt(id, cntGblRef, userBusyRef); // Includes a checkUse for us userBusyRef = false; } - static void clearcnt(uint32_t& cntGblRef, bool& userBusyRef) { - UASSERT_STATIC(userBusyRef, "Clear of User*() not under AstUserInUse"); + static void clearcnt(int id, uint32_t& cntGblRef, bool& userBusyRef) { + UASSERT_STATIC(userBusyRef, "Clear of User"+cvtToStr(id)+"() not under AstUserInUse"); // If this really fires and is real (after 2^32 edits???) // we could just walk the tree and clear manually ++cntGblRef; @@ -419,9 +419,9 @@ protected: static uint32_t s_userCntGbl; // Count of which usage of userp() this is static bool s_userBusy; // Count is in use public: - AstUser1InUse() { allocate(s_userCntGbl/*ref*/, s_userBusy/*ref*/); } - ~AstUser1InUse() { free (s_userCntGbl/*ref*/, s_userBusy/*ref*/); } - static void clear() { clearcnt(s_userCntGbl/*ref*/, s_userBusy/*ref*/); } + AstUser1InUse() { allocate(1, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } + ~AstUser1InUse() { free (1, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } + static void clear() { clearcnt(1, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } }; class AstUser2InUse : AstUserInUseBase { protected: @@ -429,9 +429,9 @@ protected: static uint32_t s_userCntGbl; // Count of which usage of userp() this is static bool s_userBusy; // Count is in use public: - AstUser2InUse() { allocate(s_userCntGbl/*ref*/, s_userBusy/*ref*/); } - ~AstUser2InUse() { free (s_userCntGbl/*ref*/, s_userBusy/*ref*/); } - static void clear() { clearcnt(s_userCntGbl/*ref*/, s_userBusy/*ref*/); } + AstUser2InUse() { allocate(2, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } + ~AstUser2InUse() { free (2, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } + static void clear() { clearcnt(2, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } }; class AstUser3InUse : AstUserInUseBase { protected: @@ -439,9 +439,9 @@ protected: static uint32_t s_userCntGbl; // Count of which usage of userp() this is static bool s_userBusy; // Count is in use public: - AstUser3InUse() { allocate(s_userCntGbl/*ref*/, s_userBusy/*ref*/); } - ~AstUser3InUse() { free (s_userCntGbl/*ref*/, s_userBusy/*ref*/); } - static void clear() { clearcnt(s_userCntGbl/*ref*/, s_userBusy/*ref*/); } + AstUser3InUse() { allocate(3, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } + ~AstUser3InUse() { free (3, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } + static void clear() { clearcnt(3, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } }; class AstUser4InUse : AstUserInUseBase { protected: @@ -449,9 +449,9 @@ protected: static uint32_t s_userCntGbl; // Count of which usage of userp() this is static bool s_userBusy; // Count is in use public: - AstUser4InUse() { allocate(s_userCntGbl/*ref*/, s_userBusy/*ref*/); } - ~AstUser4InUse() { free (s_userCntGbl/*ref*/, s_userBusy/*ref*/); } - static void clear() { clearcnt(s_userCntGbl/*ref*/, s_userBusy/*ref*/); } + AstUser4InUse() { allocate(4, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } + ~AstUser4InUse() { free (4, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } + static void clear() { clearcnt(4, s_userCntGbl/*ref*/, s_userBusy/*ref*/); } }; //###################################################################### @@ -752,6 +752,7 @@ public: virtual void dump(ostream& str=cout); AstNode* unlinkFrBack(AstNRelinker* linkerp=NULL); // Unlink this from whoever points to it. AstNode* unlinkFrBackWithNext(AstNRelinker* linkerp=NULL); // Unlink this from whoever points to it, keep entire next list with unlinked node + void swapWith(AstNode* bp); void relink(AstNRelinker* linkerp); // Generally use linker->relink() instead void cloneRelinkNode() { cloneRelink(); } diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 33a742cdf..fd6f30e9e 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -46,6 +46,7 @@ struct AstConst : public AstNodeMath { private: V3Number m_num; // Constant value public: + class Unsized32 {}; // for creator type-overload selection AstConst(FileLine* fl, const V3Number& num) :AstNodeMath(fl) ,m_num(num) { @@ -55,6 +56,9 @@ public: AstConst(FileLine* fl, uint32_t num) :AstNodeMath(fl) ,m_num(V3Number(fl,32,num)) { width(m_num.width(), m_num.sized()?0:m_num.minWidth()); } + AstConst(FileLine* fl, Unsized32, uint32_t num) // Unsized 32-bit integer of specified value + :AstNodeMath(fl) + ,m_num(V3Number(fl,32,num)) { m_num.width(32,false); width(32,false); } ASTNODE_NODE_FUNCS(Const, CONST) virtual string name() const { return num().ascii(); } // * = Value virtual const V3Number& num() const { return m_num; } // * = Value diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 574f85949..ef73378b1 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -275,7 +275,7 @@ private: nodep->v3error("Unsupported: MSB < LSB of bit range: "<swapWith(lsbConstp); int x=msb; msb=lsb; lsb=x; } int width = msb-lsb+1; @@ -837,14 +837,6 @@ private: bool fixAutoExtend (AstNode*& nodepr, int expWidth); void fixWidthExtend (AstNode* nodep, int expWidth); void fixWidthReduce (AstNode* nodep, int expWidth); - void swap (AstNode* ap, AstNode* bp) { - AstNRelinker aHandle; - AstNRelinker bHandle; - ap->unlinkFrBack(&aHandle); - bp->unlinkFrBack(&bHandle); - aHandle.relink(bp); - bHandle.relink(ap); - } public: // CONSTUCTORS