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
inline void AstNode::debugTreeChange(const AstNode* nodep, const char* prefix, int lineno,
bool next){
bool next) {
#ifdef VL_DEBUG
// Called on all major tree changers.
// 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
}
AstNode* AstNode::addNext(AstNode* nodep, AstNode* newp) {
template <>
AstNode* AstNode::addNext<AstNode, AstNode>(AstNode* nodep, AstNode* newp) {
// Add to m_nextp, returns this
UDEBUGONLY(UASSERT_OBJ(newp, nodep, "Null item passed to addNext"););
debugTreeChange(nodep, "-addNextThs: ", __LINE__, false);
@ -272,7 +273,8 @@ AstNode* AstNode::addNext(AstNode* nodep, AstNode* newp) {
return nodep;
}
AstNode* AstNode::addNextNull(AstNode* nodep, AstNode* newp) {
template <>
AstNode* AstNode::addNextNull<AstNode, AstNode>(AstNode* nodep, AstNode* newp) {
if (!newp) return nodep;
return addNext(nodep, newp);
}

View File

@ -1759,16 +1759,27 @@ public:
// METHODS - Tree modifications
// Returns nodep, adds newp to end of nodep's list
static AstNode* addNext(AstNode* nodep, AstNode* newp);
// Returns nodep, adds newp (maybe nullptr) to end of nodep's list
static AstNode* addNextNull(AstNode* nodep, AstNode* newp);
inline AstNode* addNext(AstNode* newp) { return addNext(this, newp); }
inline AstNode* addNextNull(AstNode* newp) { return addNextNull(this, newp); }
void addNextHere(AstNode* newp); // Insert newp at this->nextp
void addPrev(AstNode* newp) {
replaceWith(newp);
newp->addNext(this);
template <typename T_NodeResult, typename T_NodeNext>
static T_NodeResult* addNext(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*>(addNext<AstNode, AstNode>(nodep, newp));
}
// 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 replaceWith(AstNode* newp); // Replace current node in tree with new node
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
#include "V3Ast__gen_impl.h" // From ./astgen

View File

@ -23,7 +23,14 @@
#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::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);
// Make new assigns of same flavor as old one
//*** Not cloneTree; just one node.
AstNode* newp = nullptr;
AstNodeAssign* newp = nullptr;
if (!need_temp) {
AstNodeAssign* const asn1ap = VN_AS(nodep->cloneType(lc1p, sel1p), 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
AstNode* V3ParseGrammar::argWrapList(AstNode* nodep) {
AstArg* V3ParseGrammar::argWrapList(AstNode* nodep) {
// Convert list of expressions to list of arguments
if (!nodep) return nullptr;
AstNode* outp = nullptr;
AstArg* outp = nullptr;
AstBegin* const tempp = new AstBegin(nodep->fileline(), "[EditWrapper]", nodep);
while (nodep) {
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
// 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
AstNode* newlistp = nullptr;
AstNodeAssign* newlistp = nullptr;
const int elements = arrayp->rangep()->elementsConst();
for (int offset = 0; offset < elements; ++offset) {
AstNode* const newp = nodep->cloneType // AstNodeAssign
(cloneAndSel(nodep->lhsp(), elements, offset),
cloneAndSel(nodep->rhsp(), elements, offset));
AstNodeAssign* const newp
= VN_AS(nodep->cloneType(cloneAndSel(nodep->lhsp(), elements, offset),
cloneAndSel(nodep->rhsp(), elements, offset)),
NodeAssign);
if (debug() >= 9) newp->dumpTree(cout, "-new ");
newlistp = AstNode::addNextNull(newlistp, newp);
}

View File

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