Preserve return type of `AstNode::addNext` via templating (#3597)

No functional change intended.

Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
This commit is contained in:
Krzysztof Bieganski 2022-08-29 15:26:00 +02:00 committed by Geza Lore
parent fb931087ab
commit 6b6790fc50
7 changed files with 49 additions and 22 deletions

View File

@ -213,7 +213,7 @@ string AstNode::prettyTypeName() const {
// Insertion // Insertion
inline void AstNode::debugTreeChange(const AstNode* nodep, const char* prefix, int lineno, inline void AstNode::debugTreeChange(const AstNode* nodep, const char* prefix, int lineno,
bool next){ bool next) {
#ifdef VL_DEBUG #ifdef VL_DEBUG
// Called on all major tree changers. // Called on all major tree changers.
// Only for use for those really nasty bugs relating to internals // Only for use for those really nasty bugs relating to internals
@ -234,7 +234,8 @@ inline void AstNode::debugTreeChange(const AstNode* nodep, const char* prefix, i
#endif #endif
} }
AstNode* AstNode::addNext(AstNode* nodep, AstNode* newp) { template <>
AstNode* AstNode::addNext<AstNode, AstNode>(AstNode* nodep, AstNode* newp) {
// Add to m_nextp, returns this // Add to m_nextp, returns this
UDEBUGONLY(UASSERT_OBJ(newp, nodep, "Null item passed to addNext");); UDEBUGONLY(UASSERT_OBJ(newp, nodep, "Null item passed to addNext"););
debugTreeChange(nodep, "-addNextThs: ", __LINE__, false); debugTreeChange(nodep, "-addNextThs: ", __LINE__, false);
@ -272,7 +273,8 @@ AstNode* AstNode::addNext(AstNode* nodep, AstNode* newp) {
return nodep; return nodep;
} }
AstNode* AstNode::addNextNull(AstNode* nodep, AstNode* newp) { template <>
AstNode* AstNode::addNextNull<AstNode, AstNode>(AstNode* nodep, AstNode* newp) {
if (!newp) return nodep; if (!newp) return nodep;
return addNext(nodep, newp); return addNext(nodep, newp);
} }

View File

@ -1759,16 +1759,27 @@ public:
// METHODS - Tree modifications // METHODS - Tree modifications
// Returns nodep, adds newp to end of nodep's list // Returns nodep, adds newp to end of nodep's list
static AstNode* addNext(AstNode* nodep, AstNode* newp); template <typename T_NodeResult, typename T_NodeNext>
// Returns nodep, adds newp (maybe nullptr) to end of nodep's list static T_NodeResult* addNext(T_NodeResult* nodep, T_NodeNext* newp) {
static AstNode* addNextNull(AstNode* nodep, AstNode* newp); static_assert(std::is_base_of<AstNode, T_NodeResult>::value,
inline AstNode* addNext(AstNode* newp) { return addNext(this, newp); } "'T_NodeResult' must be a subtype of AstNode");
inline AstNode* addNextNull(AstNode* newp) { return addNextNull(this, newp); } static_assert(std::is_base_of<T_NodeResult, T_NodeNext>::value,
void addNextHere(AstNode* newp); // Insert newp at this->nextp "'T_NodeNext' must be a subtype of 'T_NodeResult'");
void addPrev(AstNode* newp) { return static_cast<T_NodeResult*>(addNext<AstNode, AstNode>(nodep, newp));
replaceWith(newp);
newp->addNext(this);
} }
// Returns nodep, adds newp (maybe nullptr) to end of nodep's list
template <typename T_NodeResult, typename T_NodeNext>
static T_NodeResult* addNextNull(T_NodeResult* nodep, T_NodeNext* newp) {
static_assert(std::is_base_of<AstNode, T_NodeResult>::value,
"'T_NodeResult' must be a subtype of AstNode");
static_assert(std::is_base_of<T_NodeResult, T_NodeNext>::value,
"'T_NodeNext' must be a subtype of 'T_NodeResult'");
return static_cast<T_NodeResult*>(addNextNull<AstNode, AstNode>(nodep, newp));
}
inline AstNode* addNext(AstNode* newp);
inline AstNode* addNextNull(AstNode* newp);
void addNextHere(AstNode* newp); // Insert newp at this->nextp
inline void addPrev(AstNode* newp);
void addHereThisAsNext(AstNode* newp); // Adds at old place of this, this becomes next void addHereThisAsNext(AstNode* newp); // Adds at old place of this, this becomes next
void replaceWith(AstNode* newp); // Replace current node in tree with new node void replaceWith(AstNode* newp); // Replace current node in tree with new node
AstNode* unlinkFrBack(VNRelinker* linkerp AstNode* unlinkFrBack(VNRelinker* linkerp
@ -2056,6 +2067,12 @@ public:
} }
}; };
// Forward declarations of specializations defined in V3Ast.cpp
template <>
AstNode* AstNode::addNext<AstNode, AstNode>(AstNode* nodep, AstNode* newp);
template <>
AstNode* AstNode::addNextNull<AstNode, AstNode>(AstNode* nodep, AstNode* newp);
// Specialisations of privateTypeTest // Specialisations of privateTypeTest
#include "V3Ast__gen_impl.h" // From ./astgen #include "V3Ast__gen_impl.h" // From ./astgen

View File

@ -23,7 +23,14 @@
#endif #endif
//###################################################################### //######################################################################
// Inline ACCESSORS // Inline METHODS
inline AstNode* AstNode::addNext(AstNode* newp) { return addNext(this, newp); }
inline AstNode* AstNode::addNextNull(AstNode* newp) { return addNextNull(this, newp); }
inline void AstNode::addPrev(AstNode* newp) {
replaceWith(newp);
newp->addNext(this);
}
inline int AstNode::width() const { return dtypep() ? dtypep()->width() : 0; } inline int AstNode::width() const { return dtypep() ? dtypep()->width() : 0; }
inline int AstNode::widthMin() const { return dtypep() ? dtypep()->widthMin() : 0; } inline int AstNode::widthMin() const { return dtypep() ? dtypep()->widthMin() : 0; }

View File

@ -2079,7 +2079,7 @@ private:
AstSel* const sel2p = new AstSel(conp->fileline(), rhs2p, lsb2, msb2 - lsb2 + 1); AstSel* const sel2p = new AstSel(conp->fileline(), rhs2p, lsb2, msb2 - lsb2 + 1);
// Make new assigns of same flavor as old one // Make new assigns of same flavor as old one
//*** Not cloneTree; just one node. //*** Not cloneTree; just one node.
AstNode* newp = nullptr; AstNodeAssign* newp = nullptr;
if (!need_temp) { if (!need_temp) {
AstNodeAssign* const asn1ap = VN_AS(nodep->cloneType(lc1p, sel1p), NodeAssign); AstNodeAssign* const asn1ap = VN_AS(nodep->cloneType(lc1p, sel1p), NodeAssign);
AstNodeAssign* const asn2ap = VN_AS(nodep->cloneType(lc2p, sel2p), NodeAssign); AstNodeAssign* const asn2ap = VN_AS(nodep->cloneType(lc2p, sel2p), NodeAssign);

View File

@ -67,10 +67,10 @@ void V3ParseImp::parserClear() {
//====================================================================== //======================================================================
// V3ParseGrammar functions requiring bison state // V3ParseGrammar functions requiring bison state
AstNode* V3ParseGrammar::argWrapList(AstNode* nodep) { AstArg* V3ParseGrammar::argWrapList(AstNode* nodep) {
// Convert list of expressions to list of arguments // Convert list of expressions to list of arguments
if (!nodep) return nullptr; if (!nodep) return nullptr;
AstNode* outp = nullptr; AstArg* outp = nullptr;
AstBegin* const tempp = new AstBegin(nodep->fileline(), "[EditWrapper]", nodep); AstBegin* const tempp = new AstBegin(nodep->fileline(), "[EditWrapper]", nodep);
while (nodep) { while (nodep) {
AstNode* const nextp = nodep->nextp(); AstNode* const nextp = nodep->nextp();

View File

@ -139,12 +139,13 @@ class SliceVisitor final : public VNVisitor {
// Left and right could have different msb/lsbs/endianness, but #elements is common // Left and right could have different msb/lsbs/endianness, but #elements is common
// and all variables are realigned to start at zero // and all variables are realigned to start at zero
// Assign of a little endian'ed slice to a big endian one must reverse the elements // Assign of a little endian'ed slice to a big endian one must reverse the elements
AstNode* newlistp = nullptr; AstNodeAssign* newlistp = nullptr;
const int elements = arrayp->rangep()->elementsConst(); const int elements = arrayp->rangep()->elementsConst();
for (int offset = 0; offset < elements; ++offset) { for (int offset = 0; offset < elements; ++offset) {
AstNode* const newp = nodep->cloneType // AstNodeAssign AstNodeAssign* const newp
(cloneAndSel(nodep->lhsp(), elements, offset), = VN_AS(nodep->cloneType(cloneAndSel(nodep->lhsp(), elements, offset),
cloneAndSel(nodep->rhsp(), elements, offset)); cloneAndSel(nodep->rhsp(), elements, offset)),
NodeAssign);
if (debug() >= 9) newp->dumpTree(cout, "-new "); if (debug() >= 9) newp->dumpTree(cout, "-new ");
newlistp = AstNode::addNextNull(newlistp, newp); newlistp = AstNode::addNextNull(newlistp, newp);
} }

View File

@ -91,7 +91,7 @@ public:
} }
// METHODS // METHODS
AstNode* argWrapList(AstNode* nodep); AstArg* argWrapList(AstNode* nodep);
bool allTracingOn(FileLine* fl) { bool allTracingOn(FileLine* fl) {
return v3Global.opt.trace() && m_tracingParse && fl->tracingOn(); return v3Global.opt.trace() && m_tracingParse && fl->tracingOn();
} }
@ -5103,7 +5103,7 @@ idArrayedForeach<nodep>: // IEEE: id + select (under foreach expression)
| idArrayed '[' expr ',' loop_variables ']' | idArrayed '[' expr ',' loop_variables ']'
{ $3 = AstNode::addNextNull($3, $5); $$ = new AstSelLoopVars($2, $1, $3); } { $3 = AstNode::addNextNull($3, $5); $$ = new AstSelLoopVars($2, $1, $3); }
| idArrayed '[' ',' loop_variables ']' | idArrayed '[' ',' loop_variables ']'
{ $4 = AstNode::addNextNull(new AstEmpty{$3}, $4); $$ = new AstSelLoopVars($2, $1, $4); } { $4 = AstNode::addNextNull(static_cast<AstNode*>(new AstEmpty{$3}), $4); $$ = new AstSelLoopVars($2, $1, $4); }
; ;
// VarRef without any dots or vectorizaion // VarRef without any dots or vectorizaion