Internals: cppcheck fixes. No functional change. (#6687)

This commit is contained in:
Wilson Snyder 2025-11-12 18:54:22 -05:00 committed by GitHub
parent 67094f6a88
commit 5c0ad5bd1f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
38 changed files with 122 additions and 111 deletions

View File

@ -133,6 +133,7 @@ unsigned getProcessAvailableParallelism() VL_MT_SAFE {
unsigned getProcessDefaultParallelism() VL_MT_SAFE { unsigned getProcessDefaultParallelism() VL_MT_SAFE {
const unsigned n = getProcessAvailableParallelism(); const unsigned n = getProcessAvailableParallelism();
// cppcheck-suppress knownConditionTrueFalse
return n ? n : std::thread::hardware_concurrency(); return n ? n : std::thread::hardware_concurrency();
} }

View File

@ -280,9 +280,8 @@ class AssertVisitor final : public VNVisitor {
return newp; return newp;
} }
static AstIf* assertCond(AstNodeCoverOrAssert* nodep, AstNodeExpr* propp, AstNode* passsp, static AstIf* assertCond(const AstNodeCoverOrAssert* nodep, AstNodeExpr* propp,
AstNode* failsp) { AstNode* passsp, AstNode* failsp) {
AstIf* const ifp = new AstIf{nodep->fileline(), propp, passsp, failsp}; AstIf* const ifp = new AstIf{nodep->fileline(), propp, passsp, failsp};
// It's more LIKELY that we'll take the nullptr if clause // It's more LIKELY that we'll take the nullptr if clause
// than the sim-killing else clause: // than the sim-killing else clause:
@ -291,7 +290,7 @@ class AssertVisitor final : public VNVisitor {
return ifp; return ifp;
} }
AstNode* assertBody(AstNodeCoverOrAssert* nodep, AstNode* propp, AstNode* passsp, AstNode* assertBody(const AstNodeCoverOrAssert* nodep, AstNode* propp, AstNode* passsp,
AstNode* failsp) { AstNode* failsp) {
AstNode* bodyp = nullptr; AstNode* bodyp = nullptr;
if (AstPExpr* const pexprp = VN_CAST(propp, PExpr)) { if (AstPExpr* const pexprp = VN_CAST(propp, PExpr)) {

View File

@ -109,7 +109,7 @@ class AssertPropBuildVisitor final : public VNVisitorConst {
bool m_underSExpr = false; // Is under sequence expression, for creating a start node bool m_underSExpr = false; // Is under sequence expression, for creating a start node
size_t m_underLogNots = 0; // Number of 'not' operators before sequence size_t m_underLogNots = 0; // Number of 'not' operators before sequence
DfaStmtVertex* makeClause(AstSExpr* nodep, bool pass) { DfaStmtVertex* makeClause(const AstSExpr* nodep, bool pass) {
return new DfaStmtVertex{ return new DfaStmtVertex{
&m_graph, &m_graph,
new AstPExprClause{nodep->fileline(), m_underLogNots % 2 == 0 ? pass : !pass}}; new AstPExprClause{nodep->fileline(), m_underLogNots % 2 == 0 ? pass : !pass}};
@ -227,7 +227,7 @@ class AssertPropTransformer final {
m_current = passsp; m_current = passsp;
return processEdge(vtxp->outEdges().frontp()); return processEdge(vtxp->outEdges().frontp());
} }
V3GraphVertex* processEdge(V3GraphEdge* edgep) { V3GraphVertex* processEdge(const V3GraphEdge* edgep) {
if (edgep) return processVtx(edgep->top()); if (edgep) return processVtx(edgep->top());
return nullptr; return nullptr;
} }

View File

@ -55,14 +55,14 @@ V3AST_VCMETHOD_ITEMDATA_DECL;
// VCMethod information // VCMethod information
VCMethod VCMethod::arrayMethod(const string& name) { VCMethod VCMethod::arrayMethod(const string& name) {
for (auto& it : s_itemData) for (const auto& it : s_itemData)
if (it.m_name == name) return it.m_e; if (it.m_name == name) return it.m_e;
v3fatalSrc("Not a method name known to VCMethod::s_itemData: '" << name << '\''); v3fatalSrc("Not a method name known to VCMethod::s_itemData: '" << name << '\'');
return VCMethod{}; return VCMethod{};
} }
void VCMethod::selfTest() { void VCMethod::selfTest() {
int i = 0; int i = 0;
for (auto& it : s_itemData) { for (const auto& it : s_itemData) {
VCMethod exp{i}; VCMethod exp{i};
UASSERT_STATIC(it.m_e == exp, UASSERT_STATIC(it.m_e == exp,
"VCMethod::s_itemData table rows are out-of-order, starting at row "s "VCMethod::s_itemData table rows are out-of-order, starting at row "s

View File

@ -583,7 +583,7 @@ class AstCExpr final : public AstNodeExpr {
public: public:
class Pure {}; class Pure {};
AstCExpr(FileLine* fl, const string& text = "", int setwidth = 0) explicit AstCExpr(FileLine* fl, const string& text = "", int setwidth = 0)
: ASTGEN_SUPER_CExpr(fl) : ASTGEN_SUPER_CExpr(fl)
, m_pure{false} { , m_pure{false} {
init(text, setwidth); init(text, setwidth);
@ -617,7 +617,7 @@ class AstCExprUser final : public AstNodeExpr {
const bool m_pure; // Whether the function is pure const bool m_pure; // Whether the function is pure
public: public:
class Pure {}; class Pure {};
AstCExprUser(FileLine* fl) explicit AstCExprUser(FileLine* fl)
: ASTGEN_SUPER_CExprUser(fl) : ASTGEN_SUPER_CExprUser(fl)
, m_pure{false} {} , m_pure{false} {}
AstCExprUser(FileLine* fl, Pure) AstCExprUser(FileLine* fl, Pure)

View File

@ -1613,10 +1613,10 @@ class AstTextBlock final : public AstNode {
const std::string m_separator; // Separator to print between each element in 'nodesp' const std::string m_separator; // Separator to print between each element in 'nodesp'
const std::string m_suffix; // Suffix to pring after last element in 'nodesp' const std::string m_suffix; // Suffix to pring after last element in 'nodesp'
public: public:
AstTextBlock(FileLine* fl, // explicit AstTextBlock(FileLine* fl, //
const std::string& prefix = "", // const std::string& prefix = "", //
const std::string& separator = "", // const std::string& separator = "", //
const std::string& suffix = "") const std::string& suffix = "")
: ASTGEN_SUPER_TextBlock(fl) : ASTGEN_SUPER_TextBlock(fl)
, m_prefix{prefix} , m_prefix{prefix}
, m_separator{separator} , m_separator{separator}
@ -2641,7 +2641,7 @@ public:
, m_keyword{keyword} { , m_keyword{keyword} {
this->sentreep(sentreep); this->sentreep(sentreep);
} }
inline AstAlways(AstAssignW* assignp); explicit inline AstAlways(AstAssignW* assignp);
ASTGEN_MEMBERS_AstAlways; ASTGEN_MEMBERS_AstAlways;
// //
void dump(std::ostream& str) const override; void dump(std::ostream& str) const override;

View File

@ -289,7 +289,7 @@ class AstCStmt final : public AstNodeStmt {
// C statement emitted into output, with some arbitrary nodes interspersed // C statement emitted into output, with some arbitrary nodes interspersed
// @astgen op1 := nodesp : List[AstNode<AstNodeStmt|AstNodeExpr|AstText>] // @astgen op1 := nodesp : List[AstNode<AstNodeStmt|AstNodeExpr|AstText>]
public: public:
AstCStmt(FileLine* fl, const std::string& text = "") explicit AstCStmt(FileLine* fl, const std::string& text = "")
: ASTGEN_SUPER_CStmt(fl) { : ASTGEN_SUPER_CStmt(fl) {
if (!text.empty()) add(text); if (!text.empty()) add(text);
} }
@ -315,7 +315,7 @@ class AstCStmtUser final : public AstNodeStmt {
// @astgen op1 := nodesp : List[AstNode<AstNodeExpr|AstText>] // @astgen op1 := nodesp : List[AstNode<AstNodeExpr|AstText>]
const bool m_fromDollarC; // Is from source '$c', emit decoration const bool m_fromDollarC; // Is from source '$c', emit decoration
public: public:
AstCStmtUser(FileLine* fl, bool fromDollarC = false) explicit AstCStmtUser(FileLine* fl, bool fromDollarC = false)
: ASTGEN_SUPER_CStmtUser(fl) : ASTGEN_SUPER_CStmtUser(fl)
, m_fromDollarC{fromDollarC} {} , m_fromDollarC{fromDollarC} {}
ASTGEN_MEMBERS_AstCStmtUser; ASTGEN_MEMBERS_AstCStmtUser;
@ -763,7 +763,7 @@ class AstLoop final : public AstNodeStmt {
// @astgen op2 := contsp : List[AstNode] // Empty after LinkJump // @astgen op2 := contsp : List[AstNode] // Empty after LinkJump
VOptionBool m_unroll; // Full, none, or default unrolling VOptionBool m_unroll; // Full, none, or default unrolling
public: public:
AstLoop(FileLine* fl) explicit AstLoop(FileLine* fl)
: ASTGEN_SUPER_Loop(fl) {} : ASTGEN_SUPER_Loop(fl) {}
ASTGEN_MEMBERS_AstLoop; ASTGEN_MEMBERS_AstLoop;
void dump(std::ostream& str) const override; void dump(std::ostream& str) const override;

View File

@ -88,6 +88,7 @@ public:
} }
private: // for V3Broken only private: // for V3Broken only
// cppcheck-suppress unusedPrivateFunction
bool isAllocated(const AstNode* nodep) const VL_REQUIRES(m_mutex) { bool isAllocated(const AstNode* nodep) const VL_REQUIRES(m_mutex) {
return m_allocated.count(nodep) != 0; return m_allocated.count(nodep) != 0;
} }

View File

@ -1122,7 +1122,7 @@ class ConstVisitor final : public VNVisitor {
return true; return true;
} }
bool matchCondCond(AstCond* nodep) { bool matchCondCond(const AstCond* nodep) {
// Same condition on either leg of a condition means that // Same condition on either leg of a condition means that
// expression is either always true or always false // expression is either always true or always false
if (VN_IS(nodep->backp(), Cond)) return false; // Was checked when visited parent if (VN_IS(nodep->backp(), Cond)) return false; // Was checked when visited parent
@ -1133,14 +1133,14 @@ class ConstVisitor final : public VNVisitor {
matchCondCondRecurse(nodep, truesp /*ref*/, falsesp /*ref*/); matchCondCondRecurse(nodep, truesp /*ref*/, falsesp /*ref*/);
return false; // Can optimize further return false; // Can optimize further
} }
void matchCondCondRecurse(AstCond* nodep, std::vector<AstNodeExpr*>& truesp, void matchCondCondRecurse(const AstCond* nodep, std::vector<AstNodeExpr*>& truesp,
std::vector<AstNodeExpr*>& falsesp) { std::vector<AstNodeExpr*>& falsesp) {
// Avoid O(n^2) compares // Avoid O(n^2) compares
// Could reduce cost with hash table, but seems unlikely to be worth cost // Could reduce cost with hash table, but seems unlikely to be worth cost
if (truesp.size() > 4 || falsesp.size() > 4) return; if (truesp.size() > 4 || falsesp.size() > 4) return;
if (!nodep->condp()->isPure()) return; if (!nodep->condp()->isPure()) return;
bool replaced = false; bool replaced = false;
for (AstNodeExpr* condp : truesp) { for (const AstNodeExpr* condp : truesp) {
if (replaced) break; if (replaced) break;
if (!operandsSame(nodep->condp(), condp)) continue; if (!operandsSame(nodep->condp(), condp)) continue;
UINFO(9, "COND(c, CONDb(c, tt, tf), f) -> CONDb(1, tt, tf) " << nodep); UINFO(9, "COND(c, CONDb(c, tt, tf), f) -> CONDb(1, tt, tf) " << nodep);
@ -1148,7 +1148,7 @@ class ConstVisitor final : public VNVisitor {
replaced = true; replaced = true;
++m_statCondExprRedundant; ++m_statCondExprRedundant;
} }
for (AstNodeExpr* condp : falsesp) { for (const AstNodeExpr* condp : falsesp) {
if (replaced) break; if (replaced) break;
if (!operandsSame(nodep->condp(), condp)) continue; if (!operandsSame(nodep->condp(), condp)) continue;
UINFO(9, "COND(c, t, CONDb(c, ft, ff)) -> CONDb(0, ft, ff) " << nodep); UINFO(9, "COND(c, t, CONDb(c, ft, ff)) -> CONDb(0, ft, ff) " << nodep);
@ -1156,18 +1156,18 @@ class ConstVisitor final : public VNVisitor {
replaced = true; replaced = true;
++m_statCondExprRedundant; ++m_statCondExprRedundant;
} }
if (AstCond* subCondp = VN_CAST(nodep->thenp(), Cond)) { if (const AstCond* subCondp = VN_CAST(nodep->thenp(), Cond)) {
if (!replaced) truesp.emplace_back(nodep->condp()); if (!replaced) truesp.emplace_back(nodep->condp());
matchCondCondRecurse(subCondp, truesp /*ref*/, falsesp /*ref*/); matchCondCondRecurse(subCondp, truesp /*ref*/, falsesp /*ref*/);
if (!replaced) truesp.pop_back(); if (!replaced) truesp.pop_back();
} }
if (AstCond* subCondp = VN_CAST(nodep->elsep(), Cond)) { if (const AstCond* subCondp = VN_CAST(nodep->elsep(), Cond)) {
if (!replaced) falsesp.emplace_back(nodep->condp()); if (!replaced) falsesp.emplace_back(nodep->condp());
matchCondCondRecurse(subCondp, truesp /*ref*/, falsesp /*ref*/); matchCondCondRecurse(subCondp, truesp /*ref*/, falsesp /*ref*/);
if (!replaced) falsesp.pop_back(); if (!replaced) falsesp.pop_back();
} }
} }
void matchIfCondCond(AstNodeIf* nodep) { void matchIfCondCond(const AstNodeIf* nodep) {
// Same condition on either leg of a condition means that // Same condition on either leg of a condition means that
// expression is either always true or always false // expression is either always true or always false
if (VN_IS(nodep->backp(), If)) return; // Was checked when visited parent if (VN_IS(nodep->backp(), If)) return; // Was checked when visited parent
@ -1176,14 +1176,14 @@ class ConstVisitor final : public VNVisitor {
std::vector<AstNodeExpr*> falsesp; std::vector<AstNodeExpr*> falsesp;
matchIfCondCondRecurse(nodep, truesp /*ref*/, falsesp /*ref*/); matchIfCondCondRecurse(nodep, truesp /*ref*/, falsesp /*ref*/);
} }
void matchIfCondCondRecurse(AstNodeIf* nodep, std::vector<AstNodeExpr*>& truesp, void matchIfCondCondRecurse(const AstNodeIf* nodep, std::vector<AstNodeExpr*>& truesp,
std::vector<AstNodeExpr*>& falsesp) { std::vector<AstNodeExpr*>& falsesp) {
// Avoid O(n^2) compares // Avoid O(n^2) compares
// Could reduce cost with hash table, but seems unlikely to be worth cost // Could reduce cost with hash table, but seems unlikely to be worth cost
if (truesp.size() > 4 || falsesp.size() > 4) return; if (truesp.size() > 4 || falsesp.size() > 4) return;
if (!nodep->condp()->isPure()) return; if (!nodep->condp()->isPure()) return;
bool replaced = false; bool replaced = false;
for (AstNodeExpr* condp : truesp) { for (const AstNodeExpr* condp : truesp) {
if (replaced) break; if (replaced) break;
if (!operandsSame(nodep->condp(), condp)) continue; if (!operandsSame(nodep->condp(), condp)) continue;
UINFO(9, "COND(c, CONDb(c, tt, tf), f) -> CONDb(1, tt, tf) " << nodep); UINFO(9, "COND(c, CONDb(c, tt, tf), f) -> CONDb(1, tt, tf) " << nodep);
@ -1191,7 +1191,7 @@ class ConstVisitor final : public VNVisitor {
replaced = true; replaced = true;
++m_statIfCondExprRedundant; ++m_statIfCondExprRedundant;
} }
for (AstNodeExpr* condp : falsesp) { for (const AstNodeExpr* condp : falsesp) {
if (replaced) break; if (replaced) break;
if (!operandsSame(nodep->condp(), condp)) continue; if (!operandsSame(nodep->condp(), condp)) continue;
UINFO(9, "COND(c, t, CONDb(c, ft, ff)) -> CONDb(0, ft, ff) " << nodep); UINFO(9, "COND(c, t, CONDb(c, ft, ff)) -> CONDb(0, ft, ff) " << nodep);
@ -1202,12 +1202,12 @@ class ConstVisitor final : public VNVisitor {
// We only check the first statement of parent IF is an If // We only check the first statement of parent IF is an If
// So we don't need to check for effects in the executing thensp/elsesp // So we don't need to check for effects in the executing thensp/elsesp
// altering the child't condition. e.g. 'if (x) begin x=1; if (x) end' // altering the child't condition. e.g. 'if (x) begin x=1; if (x) end'
if (AstNodeIf* subIfp = VN_CAST(nodep->thensp(), NodeIf)) { if (const AstNodeIf* subIfp = VN_CAST(nodep->thensp(), NodeIf)) {
if (!replaced) truesp.emplace_back(nodep->condp()); if (!replaced) truesp.emplace_back(nodep->condp());
matchIfCondCondRecurse(subIfp, truesp /*ref*/, falsesp /*ref*/); matchIfCondCondRecurse(subIfp, truesp /*ref*/, falsesp /*ref*/);
if (!replaced) truesp.pop_back(); if (!replaced) truesp.pop_back();
} }
if (AstNodeIf* subIfp = VN_CAST(nodep->elsesp(), NodeIf)) { if (const AstNodeIf* subIfp = VN_CAST(nodep->elsesp(), NodeIf)) {
if (!replaced) falsesp.emplace_back(nodep->condp()); if (!replaced) falsesp.emplace_back(nodep->condp());
matchIfCondCondRecurse(subIfp, truesp /*ref*/, falsesp /*ref*/); matchIfCondCondRecurse(subIfp, truesp /*ref*/, falsesp /*ref*/);
if (!replaced) falsesp.pop_back(); if (!replaced) falsesp.pop_back();
@ -2635,7 +2635,7 @@ class ConstVisitor final : public VNVisitor {
} }
bool matchToStringNConst(AstToStringN* nodep) { bool matchToStringNConst(AstToStringN* nodep) {
iterateChildren(nodep); iterateChildren(nodep);
if (AstInitArray* const initp = VN_CAST(nodep->lhsp(), InitArray)) { if (const AstInitArray* const initp = VN_CAST(nodep->lhsp(), InitArray)) {
if (!(m_doExpensive || m_params)) return false; if (!(m_doExpensive || m_params)) return false;
// At present only support 1D unpacked arrays // At present only support 1D unpacked arrays
const auto initOfConst = [](const AstNode* const nodep) -> bool { // const auto initOfConst = [](const AstNode* const nodep) -> bool { //
@ -2823,9 +2823,9 @@ class ConstVisitor final : public VNVisitor {
// cppcheck-suppress constVariablePointer // children unlinked below // cppcheck-suppress constVariablePointer // children unlinked below
AstReplicate* const rep2p = VN_AS(nodep->srcp(), Replicate); AstReplicate* const rep2p = VN_AS(nodep->srcp(), Replicate);
AstNodeExpr* const from2p = rep2p->srcp(); AstNodeExpr* const from2p = rep2p->srcp();
AstConst* const cnt1p = VN_CAST(nodep->countp(), Const); const AstConst* const cnt1p = VN_CAST(nodep->countp(), Const);
if (!cnt1p) return false; if (!cnt1p) return false;
AstConst* const cnt2p = VN_CAST(rep2p->countp(), Const); const AstConst* const cnt2p = VN_CAST(rep2p->countp(), Const);
if (!cnt2p) return false; if (!cnt2p) return false;
// //
from2p->unlinkFrBack(); from2p->unlinkFrBack();
@ -3606,7 +3606,7 @@ class ConstVisitor final : public VNVisitor {
bool thisLoopHasJumpDelay = m_hasJumpDelay; bool thisLoopHasJumpDelay = m_hasJumpDelay;
m_hasJumpDelay = thisLoopHasJumpDelay || oldHasJumpDelay; m_hasJumpDelay = thisLoopHasJumpDelay || oldHasJumpDelay;
// If the first statement always break, the loop is useless // If the first statement always break, the loop is useless
if (AstLoopTest* const testp = VN_CAST(nodep->stmtsp(), LoopTest)) { if (const AstLoopTest* const testp = VN_CAST(nodep->stmtsp(), LoopTest)) {
if (testp->condp()->isZero()) { if (testp->condp()->isZero()) {
nodep->v3warn(UNUSEDLOOP, "Loop condition is always false"); nodep->v3warn(UNUSEDLOOP, "Loop condition is always false");
VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
@ -3680,8 +3680,8 @@ class ConstVisitor final : public VNVisitor {
return; return;
} }
// Remove calls to empty functions // Remove calls to empty functions
if (AstCCall* const callp = VN_CAST(nodep->exprp(), CCall)) { if (const AstCCall* const callp = VN_CAST(nodep->exprp(), CCall)) {
AstCFunc* const funcp = callp->funcp(); const AstCFunc* const funcp = callp->funcp();
if (!callp->argsp() && funcp->emptyBody()) { if (!callp->argsp() && funcp->emptyBody()) {
VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
return; return;

View File

@ -796,7 +796,7 @@ void V3Control::applyFTask(AstNodeModule* modulep, AstNodeFTask* ftaskp) {
void V3Control::applyVarAttr(const AstNodeModule* modulep, const AstNodeFTask* ftaskp, void V3Control::applyVarAttr(const AstNodeModule* modulep, const AstNodeFTask* ftaskp,
AstVar* varp) { AstVar* varp) {
V3ControlVar* vp; const V3ControlVar* vp;
V3ControlModule* const modp V3ControlModule* const modp
= V3ControlResolver::s().modules().resolve(modulep->prettyDehashOrigOrName()); = V3ControlResolver::s().modules().resolve(modulep->prettyDehashOrigOrName());
if (!modp) return; if (!modp) return;

View File

@ -378,7 +378,7 @@ class DeadVisitor final : public VNVisitor {
}); });
taskp->user1(-1); // we don't want to try deleting twice taskp->user1(-1); // we don't want to try deleting twice
deleting(taskp); deleting(taskp);
m_statFTasksDeadified++; ++m_statFTasksDeadified;
} }
} }
} }

View File

@ -181,7 +181,7 @@ class AstToDfgVisitor final : public VNVisitor {
const VAlwaysKwd kwd = nodep->keyword(); const VAlwaysKwd kwd = nodep->keyword();
if (kwd == VAlwaysKwd::CONT_ASSIGN) { if (kwd == VAlwaysKwd::CONT_ASSIGN) {
// TODO: simplify once CFG analysis can handle arrays // TODO: simplify once CFG analysis can handle arrays
if (AstAssignW* const ap = VN_CAST(nodep->stmtsp(), AssignW)) { if (const AstAssignW* const ap = VN_CAST(nodep->stmtsp(), AssignW)) {
if (ap->nextp()) return false; if (ap->nextp()) return false;
// Cannot handle assignment with timing control // Cannot handle assignment with timing control
if (ap->timingControlp()) return false; if (ap->timingControlp()) return false;

View File

@ -269,8 +269,9 @@ class DataflowOptimize final {
} }
// TODO: remove once Actives can tolerate NEVER SenItems // TODO: remove once Actives can tolerate NEVER SenItems
if (AstSenItem* senItemp = VN_CAST(nodep, SenItem)) { if (AstSenItem* senItemp = VN_CAST(nodep, SenItem)) {
senItemp->foreach( senItemp->foreach([](const AstVarRef* refp) {
[](AstVarRef* refp) { DfgVertexVar::setHasExtRdRefs(refp->varScopep()); }); DfgVertexVar::setHasExtRdRefs(refp->varScopep());
});
} }
} else { } else {
if (AstVar* const varp = VN_CAST(nodep, Var)) { if (AstVar* const varp = VN_CAST(nodep, Var)) {

View File

@ -273,7 +273,7 @@ std::pair<string, FileLine*> EmitCBaseVisitorConst::scSection(const AstNodeModul
FileLine* fl = nullptr; FileLine* fl = nullptr;
int last_line = -999; int last_line = -999;
for (AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) { for (AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) {
AstSystemCSection* const ssp = VN_CAST(nodep, SystemCSection); const AstSystemCSection* const ssp = VN_CAST(nodep, SystemCSection);
if (!ssp) continue; if (!ssp) continue;
if (ssp->sectionType() != type) continue; if (ssp->sectionType() != type) continue;
if (text.empty()) { if (text.empty()) {

View File

@ -64,7 +64,7 @@ public:
} }
// VISITOR // VISITOR
void visit(AstNode* nodep) { nodep->v3fatalSrc("Unused"); } void visit(AstNode* nodep) override { nodep->v3fatalSrc("Unused"); }
public: public:
explicit EmitCPch() { emitPch(); } explicit EmitCPch() { emitPch(); }

View File

@ -108,11 +108,11 @@ class EmitCSyms final : EmitCBaseVisitorConst {
void emitSymHdr(); void emitSymHdr();
void emitSymImpPreamble(); void emitSymImpPreamble();
void emitScopeHier(std::vector<std::string>& stmts, bool destroy); void emitScopeHier(std::vector<std::string>& stmts, bool destroy);
void emitSymImp(AstNetlist* netlistp); void emitSymImp(const AstNetlist* netlistp);
void emitDpiHdr(); void emitDpiHdr();
void emitDpiImp(); void emitDpiImp();
void emitSplit(std::vector<std::string>& stmts, const std::string name, size_t max_stmts); void emitSplit(std::vector<std::string>& stmts, const std::string& name, size_t max_stmts);
std::vector<std::string> getSymCtorStmts(); std::vector<std::string> getSymCtorStmts();
std::vector<std::string> getSymDtorStmts(); std::vector<std::string> getSymDtorStmts();
@ -863,7 +863,7 @@ std::vector<std::string> EmitCSyms::getSymDtorStmts() {
return stmts; return stmts;
} }
void EmitCSyms::emitSplit(std::vector<std::string>& stmts, const std::string name, void EmitCSyms::emitSplit(std::vector<std::string>& stmts, const std::string& name,
size_t maxCost) { size_t maxCost) {
size_t nSubFunctions = 0; size_t nSubFunctions = 0;
// Reduce into a balanced tree of sub-function calls until we end up with a single statement // Reduce into a balanced tree of sub-function calls until we end up with a single statement
@ -912,7 +912,7 @@ void EmitCSyms::emitSplit(std::vector<std::string>& stmts, const std::string nam
} }
} }
void EmitCSyms::emitSymImp(AstNetlist* netlistp) { void EmitCSyms::emitSymImp(const AstNetlist* netlistp) {
UINFO(6, __FUNCTION__ << ": "); UINFO(6, __FUNCTION__ << ": ");
// Get the body of the constructor and destructor // Get the body of the constructor and destructor

View File

@ -118,11 +118,11 @@ class V3EmitMkJsonEmitter final {
// really have to, but verilator-config.cmake.in depends on order. // really have to, but verilator-config.cmake.in depends on order.
for (const V3GraphVertex& vtx : vlstd::reverse_view(graphp->vertices())) { for (const V3GraphVertex& vtx : vlstd::reverse_view(graphp->vertices())) {
const V3HierBlock* const hblockp = vtx.as<V3HierBlock>(); const V3HierBlock* const hblockp = vtx.as<V3HierBlock>();
std::vector<std::string> deps; std::vector<std::string> hierDeps;
std::vector<std::string> sources; std::vector<std::string> sources;
for (const V3GraphEdge& edge : hblockp->outEdges()) { for (const V3GraphEdge& edge : hblockp->outEdges()) {
const V3HierBlock* const dependencyp = edge.top()->as<V3HierBlock>(); const V3HierBlock* const dependencyp = edge.top()->as<V3HierBlock>();
deps.emplace_back(dependencyp->hierPrefix()); hierDeps.emplace_back(dependencyp->hierPrefix());
sources.emplace_back(makeDir + "/" + dependencyp->hierWrapperFilename(true)); sources.emplace_back(makeDir + "/" + dependencyp->hierWrapperFilename(true));
} }
@ -137,7 +137,7 @@ class V3EmitMkJsonEmitter final {
of.begin() of.begin()
.put("prefix", hblockp->hierPrefix()) .put("prefix", hblockp->hierPrefix())
.put("top", hblockp->modp()->name()) .put("top", hblockp->modp()->name())
.putList("deps", deps) .putList("deps", hierDeps)
.put("directory", makeDir + "/" + hblockp->hierPrefix()) .put("directory", makeDir + "/" + hblockp->hierPrefix())
.putList("sources", sources) .putList("sources", sources)
.putList("cflags", {"-fPIC"}) .putList("cflags", {"-fPIC"})

View File

@ -35,13 +35,13 @@ VL_DEFINE_DEBUG_FUNCTIONS;
AstCFunc* ExecMTask::createCFunc(AstExecGraph* execGraphp, AstScope* scopep, AstNodeStmt* stmtsp, AstCFunc* ExecMTask::createCFunc(AstExecGraph* execGraphp, AstScope* scopep, AstNodeStmt* stmtsp,
uint32_t id) { uint32_t id) {
const std::string name = execGraphp->name() + "_mtask" + std::to_string(id); const std::string newName = execGraphp->name() + "_mtask" + std::to_string(id);
AstCFunc* const funcp = new AstCFunc{execGraphp->fileline(), name, scopep}; AstCFunc* const newp = new AstCFunc{execGraphp->fileline(), newName, scopep};
funcp->isLoose(true); newp->isLoose(true);
funcp->dontCombine(true); newp->dontCombine(true);
funcp->addStmtsp(stmtsp); newp->addStmtsp(stmtsp);
if (scopep) scopep->addBlocksp(funcp); if (scopep) scopep->addBlocksp(newp);
return funcp; return newp;
} }
ExecMTask::ExecMTask(AstExecGraph* execGraphp, AstScope* scopep, ExecMTask::ExecMTask(AstExecGraph* execGraphp, AstScope* scopep,

View File

@ -234,7 +234,7 @@ class ExpandVisitor final : public VNVisitor {
static AstNodeExpr* newWordIndex(AstNodeExpr* lsbp, uint32_t wordOffset = 0) { static AstNodeExpr* newWordIndex(AstNodeExpr* lsbp, uint32_t wordOffset = 0) {
// This is indexing a WordSel, so a 32 bit constants are fine // This is indexing a WordSel, so a 32 bit constants are fine
FileLine* const flp = lsbp->fileline(); FileLine* const flp = lsbp->fileline();
if (AstConst* constp = VN_CAST(lsbp, Const)) { if (const AstConst* constp = VN_CAST(lsbp, Const)) {
return new AstConst{flp, wordOffset + VL_BITWORD_E(constp->toUInt())}; return new AstConst{flp, wordOffset + VL_BITWORD_E(constp->toUInt())};
} }
@ -250,7 +250,7 @@ class ExpandVisitor final : public VNVisitor {
uint32_t wordOffset = 0) { uint32_t wordOffset = 0) {
UASSERT_OBJ(fromp->isWide(), fromp, "Only need AstWordSel on wide from's"); UASSERT_OBJ(fromp->isWide(), fromp, "Only need AstWordSel on wide from's");
if (AstConst* const constp = VN_CAST(indexp, Const)) { if (const AstConst* const constp = VN_CAST(indexp, Const)) {
indexp = nullptr; indexp = nullptr;
wordOffset += constp->toUInt(); wordOffset += constp->toUInt();
} }
@ -545,7 +545,7 @@ class ExpandVisitor final : public VNVisitor {
V3Const::constifyEditCpp(rhsp->lsbp()); V3Const::constifyEditCpp(rhsp->lsbp());
// If it's a constant select and aligned, we can just copy the words // If it's a constant select and aligned, we can just copy the words
if (AstConst* const lsbConstp = VN_CAST(rhsp->lsbp(), Const)) { if (const AstConst* const lsbConstp = VN_CAST(rhsp->lsbp(), Const)) {
const uint32_t lsb = lsbConstp->toUInt(); const uint32_t lsb = lsbConstp->toUInt();
if (VL_BITBIT_E(lsb) == 0) { if (VL_BITBIT_E(lsb) == 0) {
UINFO(8, " Wordize ASSIGN(SEL,align) " << nodep); UINFO(8, " Wordize ASSIGN(SEL,align) " << nodep);
@ -577,7 +577,7 @@ class ExpandVisitor final : public VNVisitor {
AstNodeExpr* loShftp = nullptr; AstNodeExpr* loShftp = nullptr;
AstNodeExpr* hiShftp = nullptr; AstNodeExpr* hiShftp = nullptr;
AstNodeExpr* hiMaskp = nullptr; AstNodeExpr* hiMaskp = nullptr;
if (AstConst* const lsbConstp = VN_CAST(rhsp->lsbp(), Const)) { if (const AstConst* const lsbConstp = VN_CAST(rhsp->lsbp(), Const)) {
const uint32_t bitOffset = VL_BITBIT_E(lsbConstp->toUInt()); const uint32_t bitOffset = VL_BITBIT_E(lsbConstp->toUInt());
// Must be unaligned, otherwise we would have handled it above // Must be unaligned, otherwise we would have handled it above
UASSERT_OBJ(bitOffset, nodep, "Missed aligned wide select"); UASSERT_OBJ(bitOffset, nodep, "Missed aligned wide select");

View File

@ -752,7 +752,7 @@ void V3OutFormatter::putns(const AstNode* nodep, const char* strg) {
} }
if (putNodeDecoration) { if (putNodeDecoration) {
FileLine* const flp = nodep->fileline(); const FileLine* const flp = nodep->fileline();
m_sourceLastLineno = flp->firstLineno(); m_sourceLastLineno = flp->firstLineno();
m_sourceLastFilenameno = flp->filenameno(); m_sourceLastFilenameno = flp->filenameno();
const std::string lineno = std::to_string(flp->lineno()); const std::string lineno = std::to_string(flp->lineno());

View File

@ -173,9 +173,7 @@ VStringList V3HierBlock::commandArgs(bool forMkJson) const {
const StrGParams gparamsStr = stringifyParams(m_params, true); const StrGParams gparamsStr = stringifyParams(m_params, true);
for (const StrGParam& param : gparamsStr) { for (const StrGParam& param : gparamsStr) {
const string name = param.first; opts.push_back("-G" + param.first + "=" + param.second + "");
const string value = param.second;
opts.push_back("-G" + name + "=" + value + "");
} }
if (!m_typeParams.empty()) { if (!m_typeParams.empty()) {
opts.push_back(" --hierarchical-params-file " + typeParametersFilename()); opts.push_back(" --hierarchical-params-file " + typeParametersFilename());
@ -382,7 +380,7 @@ class HierBlockUsageCollectVisitor final : public VNVisitorConst {
void visit(AstNode* nodep) override { iterateChildrenConst(nodep); } void visit(AstNode* nodep) override { iterateChildrenConst(nodep); }
// CONSTRUCTOR // CONSTRUCTOR
HierBlockUsageCollectVisitor(AstNetlist* netlistp) { explicit HierBlockUsageCollectVisitor(AstNetlist* netlistp) {
iterateChildrenConst(netlistp); iterateChildrenConst(netlistp);
if (dumpGraphLevel() >= 3) m_graphp->dumpDotFilePrefixed("hierblocks_initial"); if (dumpGraphLevel() >= 3) m_graphp->dumpDotFilePrefixed("hierblocks_initial");
// Simplify dependencies // Simplify dependencies

View File

@ -429,7 +429,7 @@ namespace ModuleInliner {
// against it later in V3Scope (and also for tracing, which is inserted // against it later in V3Scope (and also for tracing, which is inserted
//later). Returns ture iff the given port variable should be inlined, //later). Returns ture iff the given port variable should be inlined,
// and false if a continuous assignment should be used. // and false if a continuous assignment should be used.
bool inlinePort(AstVar* nodep) { bool inlinePort(const AstVar* nodep) {
// Interface references are always inlined // Interface references are always inlined
if (nodep->isIfaceRef()) return true; if (nodep->isIfaceRef()) return true;
// Ref ports must be always inlined // Ref ports must be always inlined
@ -544,7 +544,6 @@ void inlineCell(AstNodeModule* modp, AstCell* cellp, bool last) {
: cellp->modp()->cloneTree(false); : cellp->modp()->cloneTree(false);
// Compute map from original port variables and cells to their clones // Compute map from original port variables and cells to their clones
std::unordered_map<const AstVar*, AstVar*> modVar2Clone;
for (AstNode *ap = cellp->modp()->stmtsp(), *bp = inlinedp->stmtsp(); ap || bp; for (AstNode *ap = cellp->modp()->stmtsp(), *bp = inlinedp->stmtsp(); ap || bp;
ap = ap->nextp(), bp = bp->nextp()) { ap = ap->nextp(), bp = bp->nextp()) {
UASSERT_OBJ(ap && bp, ap ? ap : bp, "Clone has different number of children"); UASSERT_OBJ(ap && bp, ap ? ap : bp, "Clone has different number of children");

View File

@ -133,7 +133,7 @@ public:
, m_statep{statep} {} , m_statep{statep} {}
~LifeBlock() = default; ~LifeBlock() = default;
// METHODS // METHODS
void checkRemoveAssign(AstVarScope* vscp, LifeVarEntry& entr) { void checkRemoveAssign(const AstVarScope* vscp, LifeVarEntry& entr) {
const AstVar* const varp = vscp->varp(); const AstVar* const varp = vscp->varp();
// We don't optimize any public sigs // We don't optimize any public sigs
if (varp->isSigPublic()) return; if (varp->isSigPublic()) return;

View File

@ -920,6 +920,7 @@ string V3Number::emitC() const VL_MT_STABLE {
} else if (words() == 2) { // Quad } else if (words() == 2) { // Quad
const uint64_t qnum = static_cast<uint64_t>(toUQuad()); const uint64_t qnum = static_cast<uint64_t>(toUQuad());
const char* const fmt = (qnum < 10) ? ("%" PRIx64 "ULL") : ("0x%016" PRIx64 "ULL"); const char* const fmt = (qnum < 10) ? ("%" PRIx64 "ULL") : ("0x%016" PRIx64 "ULL");
// cppcheck-suppress wrongPrintfScanfArgNum
VL_SNPRINTF(sbuf, bufsize, fmt, qnum); VL_SNPRINTF(sbuf, bufsize, fmt, qnum);
return sbuf; return sbuf;
} else { } else {
@ -930,6 +931,7 @@ string V3Number::emitC() const VL_MT_STABLE {
: (width() > 16) ? ("0x%08" PRIx32 "U") : (width() > 16) ? ("0x%08" PRIx32 "U")
: (width() > 8) ? ("0x%04" PRIx32 "U") : (width() > 8) ? ("0x%04" PRIx32 "U")
: ("0x%02" PRIx32 "U"); : ("0x%02" PRIx32 "U");
// cppcheck-suppress wrongPrintfScanfArgNum
VL_SNPRINTF(sbuf, bufsize, fmt, unum); VL_SNPRINTF(sbuf, bufsize, fmt, unum);
return sbuf; return sbuf;
} }

View File

@ -486,7 +486,8 @@ std::vector<std::string> V3Options::traceClassBases() const VL_MT_SAFE {
} }
std::vector<std::string> V3Options::traceClassLangs() const VL_MT_SAFE { std::vector<std::string> V3Options::traceClassLangs() const VL_MT_SAFE {
std::vector<std::string> result; std::vector<std::string> result;
for (auto& cbase : traceClassBases()) result.emplace_back(cbase + (systemC() ? "Sc" : "C")); for (const auto& cbase : traceClassBases())
result.emplace_back(cbase + (systemC() ? "Sc" : "C"));
return result; return result;
} }
std::vector<std::string> V3Options::traceSourceBases() const VL_MT_SAFE { std::vector<std::string> V3Options::traceSourceBases() const VL_MT_SAFE {

View File

@ -55,7 +55,7 @@ AstNodeStmt* createSerial(OrderMoveGraph& moveGraph, //
const std::string& tag, // const std::string& tag, //
bool slow); bool slow);
AstNodeStmt* createParallel(OrderGraph& orderGraph, // AstNodeStmt* createParallel(const OrderGraph& orderGraph, //
OrderMoveGraph& moveGraph, // OrderMoveGraph& moveGraph, //
const std::string& tag, // const std::string& tag, //
bool slow); bool slow);

View File

@ -2394,7 +2394,7 @@ struct MTaskVxIdLessThan final {
} }
}; };
AstNodeStmt* V3Order::createParallel(OrderGraph& orderGraph, OrderMoveGraph& moveGraph, AstNodeStmt* V3Order::createParallel(const OrderGraph& orderGraph, OrderMoveGraph& moveGraph,
const std::string& tag, bool slow) { const std::string& tag, bool slow) {
UINFO(2, " Constructing parallel code for '" + tag + "'"); UINFO(2, " Constructing parallel code for '" + tag + "'");

View File

@ -771,10 +771,10 @@ class ParamProcessor final {
UINFOTREE(1, pinp, "", "errnode"); UINFOTREE(1, pinp, "", "errnode");
pinp->v3error("Can't convert defparam value to constant: Param " pinp->v3error("Can't convert defparam value to constant: Param "
<< pinp->prettyNameQ() << " of " << nodep->prettyNameQ()); << pinp->prettyNameQ() << " of " << nodep->prettyNameQ());
AstNode* const exprp = pinp->exprp(); AstNode* const pinExprp = pinp->exprp();
exprp->replaceWith(new AstConst{pinp->fileline(), AstConst::WidthedValue{}, pinExprp->replaceWith(new AstConst{pinp->fileline(), AstConst::WidthedValue{},
modvarp->width(), 0}); modvarp->width(), 0});
VL_DO_DANGLING(exprp->deleteTree(), exprp); VL_DO_DANGLING(pinExprp->deleteTree(), pinExprp);
} else if (origp && exprp->sameTree(origp)) { } else if (origp && exprp->sameTree(origp)) {
// Setting parameter to its default value. Just ignore it. // Setting parameter to its default value. Just ignore it.
// This prevents making additional modules, and makes coverage more // This prevents making additional modules, and makes coverage more
@ -1087,7 +1087,7 @@ class ParamProcessor final {
// We need to relink the pins to the new module // We need to relink the pins to the new module
relinkPinsByName(pinsp, paramedModp); relinkPinsByName(pinsp, paramedModp);
newModp = paramedModp; newModp = paramedModp;
any_overrides = true; // any_overrides = true; // Unused later, so not needed
} else if (!any_overrides) { } else if (!any_overrides) {
UINFO(8, "Cell parameters all match original values, skipping expansion."); UINFO(8, "Cell parameters all match original values, skipping expansion.");
// If it's the first use of the default instance, create a copy and store it in user3p. // If it's the first use of the default instance, create a copy and store it in user3p.
@ -1281,7 +1281,7 @@ class ParamVisitor final : public VNVisitor {
m_isCircular; // Stores information whether `AstRefDType` is circular m_isCircular; // Stores information whether `AstRefDType` is circular
// STATE - for current visit position (use VL_RESTORER) // STATE - for current visit position (use VL_RESTORER)
AstNodeModule* m_modp; // Module iterating AstNodeModule* m_modp = nullptr; // Module iterating
std::unordered_set<std::string> m_ifacePortNames; // Interface port names in current module std::unordered_set<std::string> m_ifacePortNames; // Interface port names in current module
std::unordered_set<std::string> m_ifaceInstNames; // Interface decl names in current module std::unordered_set<std::string> m_ifaceInstNames; // Interface decl names in current module
string m_generateHierName; // Generate portion of hierarchy name string m_generateHierName; // Generate portion of hierarchy name

View File

@ -64,7 +64,7 @@ public:
// METHODS // METHODS
AstArg* argWrapList(AstNodeExpr* nodep) VL_MT_DISABLED; AstArg* argWrapList(AstNodeExpr* nodep) VL_MT_DISABLED;
bool allTracingOn(FileLine* fl) { bool allTracingOn(const FileLine* fl) const {
return v3Global.opt.trace() && m_tracingParse && fl->tracingOn(); return v3Global.opt.trace() && m_tracingParse && fl->tracingOn();
} }
AstRange* scrubRange(AstNodeRange* rangep) VL_MT_DISABLED; AstRange* scrubRange(AstNodeRange* rangep) VL_MT_DISABLED;
@ -99,11 +99,13 @@ public:
nodep->addStmtsp(defaultVarp); nodep->addStmtsp(defaultVarp);
// IEEE: function void sample() // IEEE: function void sample()
AstFunc* const funcp = new AstFunc{nodep->fileline(), "sample", nullptr, nullptr}; {
funcp->addStmtsp(sampleArgs); AstFunc* const funcp = new AstFunc{nodep->fileline(), "sample", nullptr, nullptr};
funcp->classMethod(true); funcp->addStmtsp(sampleArgs);
funcp->dtypep(funcp->findVoidDType()); funcp->classMethod(true);
nodep->addMembersp(funcp); funcp->dtypep(funcp->findVoidDType());
nodep->addMembersp(funcp);
}
// IEEE: function void start(), void stop() // IEEE: function void start(), void stop()
for (const string& name : {"start"s, "stop"s}) { for (const string& name : {"start"s, "stop"s}) {
@ -200,10 +202,10 @@ public:
V3ParseImp::parsep()->tagNodep(nodep); V3ParseImp::parsep()->tagNodep(nodep);
return nodep; return nodep;
} }
void endLabel(FileLine* fl, AstNode* nodep, string* endnamep) { void endLabel(FileLine* fl, const AstNode* nodep, const string* endnamep) {
endLabel(fl, nodep->prettyName(), endnamep); endLabel(fl, nodep->prettyName(), endnamep);
} }
void endLabel(FileLine* fl, const string& name, string* endnamep) { void endLabel(FileLine* fl, const string& name, const string* endnamep) {
if (fl && endnamep && *endnamep != "" && name != *endnamep if (fl && endnamep && *endnamep != "" && name != *endnamep
&& name != AstNode::prettyName(*endnamep)) { && name != AstNode::prettyName(*endnamep)) {
fl->v3warn(ENDLABEL, "End label '" << *endnamep << "' does not match begin label '" fl->v3warn(ENDLABEL, "End label '" << *endnamep << "' does not match begin label '"

View File

@ -607,8 +607,8 @@ TriggerKit TriggerKit::create(AstNetlist* netlistp, //
for (uint32_t level = 0; level < WORD_SIZE_LOG2; ++level) { for (uint32_t level = 0; level < WORD_SIZE_LOG2; ++level) {
const uint32_t stride = 1 << level; const uint32_t stride = 1 << level;
for (uint32_t j = 0; j < WORD_SIZE; j += 2 * stride) { for (uint32_t j = 0; j < WORD_SIZE; j += 2 * stride) {
FileLine* const flp = trigps[i + j]->fileline(); trigps[i + j] = new AstConcat{trigps[i + j]->fileline(), trigps[i + j + stride],
trigps[i + j] = new AstConcat{flp, trigps[i + j + stride], trigps[i + j]}; trigps[i + j]};
trigps[i + j + stride] = nullptr; trigps[i + j + stride] = nullptr;
} }
} }
@ -668,11 +668,11 @@ TriggerKit TriggerKit::create(AstNetlist* netlistp, //
for (AstNodeStmt* const nodep : senResults.m_postUpdates) fp->addStmtsp(nodep); for (AstNodeStmt* const nodep : senResults.m_postUpdates) fp->addStmtsp(nodep);
// Add the initialization time triggers // Add the initialization time triggers
if (initialTrigsp) { if (initialTrigsp) {
AstVarScope* const vscp = scopep->createTemp("__V" + name + "DidInit", 1); AstVarScope* const initVscp = scopep->createTemp("__V" + name + "DidInit", 1);
AstIf* const ifp = new AstIf{flp, new AstNot{flp, rd(vscp)}}; AstIf* const ifp = new AstIf{flp, new AstNot{flp, rd(initVscp)}};
fp->addStmtsp(ifp); fp->addStmtsp(ifp);
ifp->branchPred(VBranchPred::BP_UNLIKELY); ifp->branchPred(VBranchPred::BP_UNLIKELY);
ifp->addThensp(util::setVar(vscp, 1)); ifp->addThensp(util::setVar(initVscp, 1));
ifp->addThensp(initialTrigsp); ifp->addThensp(initialTrigsp);
} }
// If there are 'pre' triggers, compute them // If there are 'pre' triggers, compute them

View File

@ -92,7 +92,7 @@ AstNodeStmt* checkIterationLimit(AstNetlist* netlistp, const string& name, AstVa
ifp->addThensp(dumpCallp); ifp->addThensp(dumpCallp);
AstCStmt* const stmtp = new AstCStmt{flp}; AstCStmt* const stmtp = new AstCStmt{flp};
ifp->addThensp(stmtp); ifp->addThensp(stmtp);
FileLine* const locp = netlistp->topModulep()->fileline(); const FileLine* const locp = netlistp->topModulep()->fileline();
const std::string& file = VIdProtect::protect(locp->filename()); const std::string& file = VIdProtect::protect(locp->filename());
const std::string& line = std::to_string(locp->lineno()); const std::string& line = std::to_string(locp->lineno());
stmtp->add("VL_FATAL_MT(\"" + V3OutFormatter::quoteNameControls(file) + "\", " + line stmtp->add("VL_FATAL_MT(\"" + V3OutFormatter::quoteNameControls(file) + "\", " + line

View File

@ -1204,7 +1204,7 @@ private:
} }
// Apply value to the function // Apply value to the function
if (!m_checkOnly && optimizable()) if (!m_checkOnly && optimizable())
for (auto& it : portValues) { for (const auto& it : portValues) {
if (!m_checkOnly && optimizable()) newValue(it.first, it.second); if (!m_checkOnly && optimizable()) newValue(it.first, it.second);
} }
SimStackNode stackNode{nodep, &tconnects}; SimStackNode stackNode{nodep, &tconnects};
@ -1222,7 +1222,7 @@ private:
// Evaluate the function // Evaluate the function
iterateConst(funcp); iterateConst(funcp);
m_callStack.pop_back(); m_callStack.pop_back();
AstNodeExpr* returnp = nullptr; const AstNodeExpr* returnp = nullptr;
if (!m_checkOnly && optimizable()) { if (!m_checkOnly && optimizable()) {
// Grab return value from output variable // Grab return value from output variable
UASSERT_OBJ(funcp->fvarp(), nodep, "Function reference points at non-function"); UASSERT_OBJ(funcp->fvarp(), nodep, "Function reference points at non-function");

View File

@ -551,10 +551,11 @@ class UnknownVisitor final : public VNVisitor {
} else if (!lvalue) { // Mid-multidimension read, just use zero } else if (!lvalue) { // Mid-multidimension read, just use zero
// ARRAYSEL(...) -> ARRAYSEL(COND(LT(bit<maxbit), bit, 0)) // ARRAYSEL(...) -> ARRAYSEL(COND(LT(bit<maxbit), bit, 0))
VNRelinker replaceHandle; VNRelinker replaceHandle;
AstNodeExpr* const bitp = nodep->bitp()->unlinkFrBack(&replaceHandle); AstNodeExpr* const asBitp = nodep->bitp()->unlinkFrBack(&replaceHandle);
AstNodeExpr* const newp = new AstCond{ AstNodeExpr* const newp
bitp->fileline(), condp, bitp, = new AstCond{asBitp->fileline(), condp, asBitp,
new AstConst{bitp->fileline(), AstConst::WidthedValue{}, bitp->width(), 0}}; new AstConst{asBitp->fileline(), AstConst::WidthedValue{},
asBitp->width(), 0}};
// Added X's, tristate them too // Added X's, tristate them too
UINFOTREE(9, newp, "", "_new"); UINFOTREE(9, newp, "", "_new");
replaceHandle.relink(newp); replaceHandle.relink(newp);

View File

@ -36,7 +36,7 @@ struct UnrollStats final {
const char* const m_name; // Name for stats file and UDEBUG const char* const m_name; // Name for stats file and UDEBUG
public: public:
Stat(const char* const name) explicit Stat(const char* const name)
: m_name{name} {} : m_name{name} {}
~Stat() { V3Stats::addStat("Optimizations, Loop unrolling, "s + m_name, m_value); } ~Stat() { V3Stats::addStat("Optimizations, Loop unrolling, "s + m_name, m_value); }
const char* name() const { return m_name; } const char* name() const { return m_name; }
@ -384,7 +384,7 @@ class UnrollAllVisitor final : VNVisitor {
void visit(AstNode* nodep) override { iterateChildren(nodep); } void visit(AstNode* nodep) override { iterateChildren(nodep); }
// CONSTRUCTOR // CONSTRUCTOR
UnrollAllVisitor(AstNetlist* netlistp) { iterate(netlistp); } explicit UnrollAllVisitor(AstNetlist* netlistp) { iterate(netlistp); }
public: public:
static void apply(AstNetlist* netlistp) { UnrollAllVisitor{netlistp}; } static void apply(AstNetlist* netlistp) { UnrollAllVisitor{netlistp}; }

View File

@ -124,7 +124,7 @@ class UnrollGenVisitor final : public VNVisitor {
return true; return true;
} }
bool simulateTree(AstNodeExpr* nodep, const V3Number* loopValue, AstNode* dtypep, bool simulateTree(AstNodeExpr* nodep, const V3Number* loopValue, const AstNode* dtypep,
V3Number& outNum) { V3Number& outNum) {
AstNode* clonep = nodep->cloneTree(true); AstNode* clonep = nodep->cloneTree(true);
UASSERT_OBJ(clonep, nodep, "Failed to clone tree"); UASSERT_OBJ(clonep, nodep, "Failed to clone tree");
@ -146,7 +146,7 @@ class UnrollGenVisitor final : public VNVisitor {
return false; return false;
} }
// Fetch the result // Fetch the result
V3Number* resp = simvis.fetchNumberNull(clonep); const V3Number* resp = simvis.fetchNumberNull(clonep);
if (!resp) { if (!resp) {
UINFO(3, "No number returned from simulation"); UINFO(3, "No number returned from simulation");
VL_DO_DANGLING(clonep->deleteTree(), clonep); VL_DO_DANGLING(clonep->deleteTree(), clonep);
@ -231,7 +231,7 @@ class UnrollGenVisitor final : public VNVisitor {
} }
// loopValue += valInc // loopValue += valInc
AstAssign* const incpass = VN_AS(incp, Assign); const AstAssign* const incpass = VN_AS(incp, Assign);
V3Number newLoopValue{nodep}; V3Number newLoopValue{nodep};
if (!simulateTree(incpass->rhsp(), &loopValue, incpass, newLoopValue)) { if (!simulateTree(incpass->rhsp(), &loopValue, incpass, newLoopValue)) {
nodep->v3error("Loop unrolling failed"); nodep->v3error("Loop unrolling failed");

View File

@ -748,7 +748,7 @@ static bool verilate(const string& argString) {
V3Error::abortIfWarnings(); V3Error::abortIfWarnings();
if (V3HierGraph* const hierGraphp if (const V3HierGraph* const hierGraphp
= v3Global.hierGraphp()) { // This run is for just write a makefile = v3Global.hierGraphp()) { // This run is for just write a makefile
UASSERT(v3Global.opt.hierarchical(), "hierarchical must be set"); UASSERT(v3Global.opt.hierarchical(), "hierarchical must be set");
UASSERT(!v3Global.opt.hierChild(), "This must not be a hierarchical-child run"); UASSERT(!v3Global.opt.hierChild(), "This must not be a hierarchical-child run");

View File

@ -27,6 +27,12 @@ unmatchedSuppression
*:verilog.c *:verilog.c
*:V3Lexer_pregen.yy.cpp *:V3Lexer_pregen.yy.cpp
*:V3PreLex_pregen.yy.cpp *:V3PreLex_pregen.yy.cpp
constParameterPointer:V3ParseBison.c
cstyleCast:../V3PreLex.l
cstyleCast:../verilog.l
cstyleCast:../verilog.y
cstyleCast:V3ParseBison.c
redundantContinue:V3ParseBison.c
// Just check the hand written code // Just check the hand written code
missingInclude:examples/* missingInclude:examples/*
// We intentionally redefine AstNode methods to improve type safety // We intentionally redefine AstNode methods to improve type safety

View File

@ -136,7 +136,7 @@ const VBasicDTypeKwd LOGIC_IMPLICIT = VBasicDTypeKwd::LOGIC_IMPLICIT;
#define DEL(...) \ #define DEL(...) \
{ \ { \
AstNode* nodeps[] = {__VA_ARGS__}; \ AstNode* const nodeps[] = {__VA_ARGS__}; \
for (AstNode* const nodep : nodeps) \ for (AstNode* const nodep : nodeps) \
if (nodep) nodep->deleteTree(); \ if (nodep) nodep->deleteTree(); \
} }
@ -5500,9 +5500,9 @@ gateBuf<nodep>:
AstAssignW* const ap = new AstAssignW{$<fl>1, $2, rhsp}; AstAssignW* const ap = new AstAssignW{$<fl>1, $2, rhsp};
$$->addNext(new AstAlways{ap}); $$->addNext(new AstAlways{ap});
for (AstNodeExpr* outp = $4; outp->nextp(); outp = VN_CAST(outp->nextp(), NodeExpr)) { for (AstNodeExpr* outp = $4; outp->nextp(); outp = VN_CAST(outp->nextp(), NodeExpr)) {
AstNodeExpr* const rhsp = GRAMMARP->createGatePin(inp->cloneTree(false)); AstNodeExpr* const pinRhsp = GRAMMARP->createGatePin(inp->cloneTree(false));
AstAssignW* const ap = new AstAssignW{$<fl>1, outp->cloneTree(false), rhsp}; AstAssignW* const pinAssp = new AstAssignW{$<fl>1, outp->cloneTree(false), pinRhsp};
$$->addNext(new AstAlways{ap}); $$->addNext(new AstAlways{pinAssp});
} }
DEL($1); DEL($4); } DEL($1); DEL($4); }
; ;
@ -5515,9 +5515,9 @@ gateNot<nodep>:
AstAssignW* const ap = new AstAssignW{$<fl>1, $2, rhsp}; AstAssignW* const ap = new AstAssignW{$<fl>1, $2, rhsp};
$$->addNext(new AstAlways{ap}); $$->addNext(new AstAlways{ap});
for (AstNodeExpr* outp = $4; outp->nextp(); outp = VN_CAST(outp->nextp(), NodeExpr)) { for (AstNodeExpr* outp = $4; outp->nextp(); outp = VN_CAST(outp->nextp(), NodeExpr)) {
AstNodeExpr* const rhsp = new AstNot{$<fl>1, GRAMMARP->createGatePin(inp->cloneTree(false))}; AstNodeExpr* const pinRhsp = new AstNot{$<fl>1, GRAMMARP->createGatePin(inp->cloneTree(false))};
AstAssignW* const ap = new AstAssignW{$<fl>1, outp->cloneTree(false), rhsp}; AstAssignW* const pinAssp = new AstAssignW{$<fl>1, outp->cloneTree(false), pinRhsp};
$$->addNext(new AstAlways{ap}); $$->addNext(new AstAlways{pinAssp});
} }
DEL($1, $4); } DEL($1, $4); }
; ;