mirror of
https://github.com/verilator/verilator.git
synced 2025-04-25 10:06:54 +00:00
Move swap to V3Ast, and tell which AstUser*InUse fails assertions
This commit is contained in:
parent
807aecdb11
commit
2c3c990019
@ -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
|
||||
|
||||
|
41
src/V3Ast.h
41
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(); }
|
||||
|
||||
|
@ -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
|
||||
|
@ -275,7 +275,7 @@ private:
|
||||
nodep->v3error("Unsupported: MSB < LSB of bit range: "<<msb<<"<"<<lsb);
|
||||
}
|
||||
// Correct it.
|
||||
swap(msbConstp, lsbConstp);
|
||||
msbConstp->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
|
||||
|
Loading…
Reference in New Issue
Block a user