mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 10:03:44 +02:00
Fix ++/-- under statements (#4399)
This commit is contained in:
+32
-11
@@ -61,13 +61,30 @@ private:
|
||||
|
||||
// STATE
|
||||
AstNodeFTask* m_ftaskp = nullptr; // Function or task we're inside
|
||||
AstNodeModule* m_modp = nullptr; // Module we're inside
|
||||
int m_modIncrementsNum = 0; // Var name counter
|
||||
InsertMode m_insMode = IM_BEFORE; // How to insert
|
||||
AstNode* m_insStmtp = nullptr; // Where to insert statement
|
||||
bool m_unsupportedHere = false; // Used to detect where it's not supported yet
|
||||
|
||||
// METHODS
|
||||
void insertBeforeStmt(AstNode* nodep, AstNode* newp) {
|
||||
void insertOnTop(AstNode* newp) {
|
||||
// Add the thing directly under the current TFunc/Module
|
||||
AstNode* stmtsp = nullptr;
|
||||
if (m_ftaskp) {
|
||||
stmtsp = m_ftaskp->stmtsp();
|
||||
} else if (m_modp) {
|
||||
stmtsp = m_modp->stmtsp();
|
||||
}
|
||||
UASSERT(stmtsp, "Variable not under FTASK/MODULE");
|
||||
newp->addNext(stmtsp->unlinkFrBackWithNext());
|
||||
if (m_ftaskp) {
|
||||
m_ftaskp->addStmtsp(newp);
|
||||
} else if (m_modp) {
|
||||
m_modp->addStmtsp(newp);
|
||||
}
|
||||
}
|
||||
void insertNextToStmt(AstNode* nodep, AstNode* newp) {
|
||||
// Return node that must be visited, if any
|
||||
if (debug() >= 9) newp->dumpTree("- newstmt: ");
|
||||
UASSERT_OBJ(m_insStmtp, nodep, "Function not underneath a statement");
|
||||
@@ -88,7 +105,9 @@ private:
|
||||
|
||||
// VISITORS
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
VL_RESTORER(m_modp);
|
||||
VL_RESTORER(m_modIncrementsNum);
|
||||
m_modp = nodep;
|
||||
m_modIncrementsNum = 0;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
@@ -248,11 +267,10 @@ private:
|
||||
|
||||
AstConst* const constp = VN_AS(nodep->lhsp(), Const);
|
||||
UASSERT_OBJ(nodep, constp, "Expecting CONST");
|
||||
const AstNode* const backp = nodep->backp();
|
||||
AstConst* const newconstp = constp->cloneTree(true);
|
||||
|
||||
// Prepare a temporary variable
|
||||
FileLine* const fl = backp->fileline();
|
||||
FileLine* const fl = nodep->fileline();
|
||||
const string name = string{"__Vincrement"} + cvtToStr(++m_modIncrementsNum);
|
||||
AstVar* const varp = new AstVar{
|
||||
fl, VVarType::BLOCKTEMP, name, VFlagChildDType{},
|
||||
@@ -260,7 +278,7 @@ private:
|
||||
if (m_ftaskp) varp->funcLocal(true);
|
||||
|
||||
// Declare the variable
|
||||
insertBeforeStmt(nodep, varp);
|
||||
insertOnTop(varp);
|
||||
|
||||
// Define what operation will we be doing
|
||||
AstNodeExpr* operp;
|
||||
@@ -273,17 +291,20 @@ private:
|
||||
if (VN_IS(nodep, PreAdd) || VN_IS(nodep, PreSub)) {
|
||||
// PreAdd/PreSub operations
|
||||
// Immediately after declaration - increment it by one
|
||||
varp->addNextHere(new AstAssign{fl, writep->cloneTree(true),
|
||||
new AstVarRef{fl, varp, VAccess::READ}});
|
||||
AstAssign* const assignp
|
||||
= new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE}, operp};
|
||||
insertNextToStmt(nodep, assignp);
|
||||
// Immediately after incrementing - assign it to the original variable
|
||||
varp->addNextHere(new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE}, operp});
|
||||
assignp->addNextHere(new AstAssign{fl, writep->cloneTree(true),
|
||||
new AstVarRef{fl, varp, VAccess::READ}});
|
||||
} else {
|
||||
// PostAdd/PostSub operations
|
||||
// assign the original variable to the temporary one
|
||||
varp->addNextHere(new AstAssign{fl, writep->cloneTree(true), operp});
|
||||
// Assign the original variable to the temporary one
|
||||
AstAssign* const assignp = new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE},
|
||||
readp->cloneTree(true)};
|
||||
insertNextToStmt(nodep, assignp);
|
||||
// Increment the original variable by one
|
||||
varp->addNextHere(new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE},
|
||||
readp->cloneTree(true)});
|
||||
assignp->addNextHere(new AstAssign{fl, writep->cloneTree(true), operp});
|
||||
}
|
||||
|
||||
// Replace the node with the temporary
|
||||
|
||||
Reference in New Issue
Block a user