Internals: More const. No functional change intended.

This commit is contained in:
Wilson Snyder 2021-11-26 17:55:36 -05:00
parent 010084201a
commit cd737065f2
110 changed files with 1917 additions and 1836 deletions

View File

@ -1445,7 +1445,7 @@ vpiHandle vpi_handle(PLI_INT32 type, vpiHandle object) {
if (const VerilatedVpioVarBase* const vop = VerilatedVpioVarBase::castp(object)) { if (const VerilatedVpioVarBase* const vop = VerilatedVpioVarBase::castp(object)) {
if (VL_UNLIKELY(!vop->rangep())) return nullptr; if (VL_UNLIKELY(!vop->rangep())) return nullptr;
return (new VerilatedVpioConst{vop->rangep()->left()})->castVpiHandle(); return (new VerilatedVpioConst{vop->rangep()->left()})->castVpiHandle();
} else if (VerilatedVpioRange* const vop = VerilatedVpioRange::castp(object)) { } else if (const VerilatedVpioRange* const vop = VerilatedVpioRange::castp(object)) {
if (VL_UNLIKELY(!vop->rangep())) return nullptr; if (VL_UNLIKELY(!vop->rangep())) return nullptr;
return (new VerilatedVpioConst{vop->rangep()->left()})->castVpiHandle(); return (new VerilatedVpioConst{vop->rangep()->left()})->castVpiHandle();
} }
@ -1458,7 +1458,7 @@ vpiHandle vpi_handle(PLI_INT32 type, vpiHandle object) {
if (const VerilatedVpioVarBase* const vop = VerilatedVpioVarBase::castp(object)) { if (const VerilatedVpioVarBase* const vop = VerilatedVpioVarBase::castp(object)) {
if (VL_UNLIKELY(!vop->rangep())) return nullptr; if (VL_UNLIKELY(!vop->rangep())) return nullptr;
return (new VerilatedVpioConst{vop->rangep()->right()})->castVpiHandle(); return (new VerilatedVpioConst{vop->rangep()->right()})->castVpiHandle();
} else if (VerilatedVpioRange* const vop = VerilatedVpioRange::castp(object)) { } else if (const VerilatedVpioRange* const vop = VerilatedVpioRange::castp(object)) {
if (VL_UNLIKELY(!vop->rangep())) return nullptr; if (VL_UNLIKELY(!vop->rangep())) return nullptr;
return (new VerilatedVpioConst{vop->rangep()->right()})->castVpiHandle(); return (new VerilatedVpioConst{vop->rangep()->right()})->castVpiHandle();
} }
@ -1905,7 +1905,7 @@ void vpi_get_value(vpiHandle object, p_vpi_value valuep) {
} else if (const VerilatedVpioParam* const vop = VerilatedVpioParam::castp(object)) { } else if (const VerilatedVpioParam* const vop = VerilatedVpioParam::castp(object)) {
vl_get_value(vop->varp(), vop->varDatap(), valuep, vop->fullname()); vl_get_value(vop->varp(), vop->varDatap(), valuep, vop->fullname());
return; return;
} else if (VerilatedVpioConst* const vop = VerilatedVpioConst::castp(object)) { } else if (const VerilatedVpioConst* const vop = VerilatedVpioConst::castp(object)) {
if (valuep->format == vpiIntVal) { if (valuep->format == vpiIntVal) {
valuep->value.integer = vop->num(); valuep->value.integer = vop->num();
return; return;

View File

@ -50,8 +50,8 @@ public:
enum VertexType : uint8_t { VT_BLOCK, VT_BRANCH, VT_OUTPUT }; enum VertexType : uint8_t { VT_BLOCK, VT_BRANCH, VT_OUTPUT };
private: private:
string m_name; // Only used for .dot file generation const string m_name; // Only used for .dot file generation
VertexType m_type; // Vertex type (BLOCK/BRANCH/OUTPUT) const VertexType m_type; // Vertex type (BLOCK/BRANCH/OUTPUT)
string typestr() const { // " string typestr() const { // "
switch (m_type) { switch (m_type) {
@ -342,8 +342,8 @@ public:
private: private:
const CheckType m_check; // Combo logic or other const CheckType m_check; // Combo logic or other
AstNode* const m_alwaysp; // Always we're under const AstNode* const m_alwaysp; // Always we're under
AstNode* m_assignp = nullptr; // In assign const AstNode* m_assignp = nullptr; // In assign
// VISITORS // VISITORS
virtual void visit(AstAssignDly* nodep) override { virtual void visit(AstAssignDly* nodep) override {
if (m_check != CT_SEQ) { if (m_check != CT_SEQ) {
@ -438,7 +438,7 @@ private:
virtual void visit(AstInitial* nodep) override { virtual void visit(AstInitial* nodep) override {
// Relink to IACTIVE, unless already under it // Relink to IACTIVE, unless already under it
UINFO(4, " INITIAL " << nodep << endl); UINFO(4, " INITIAL " << nodep << endl);
ActiveDlyVisitor dlyvisitor{nodep, ActiveDlyVisitor::CT_INITIAL}; const ActiveDlyVisitor dlyvisitor{nodep, ActiveDlyVisitor::CT_INITIAL};
AstActive* const wantactivep = m_namer.getIActive(nodep->fileline()); AstActive* const wantactivep = m_namer.getIActive(nodep->fileline());
nodep->unlinkFrBack(); nodep->unlinkFrBack();
wantactivep->addStmtsp(nodep); wantactivep->addStmtsp(nodep);
@ -471,7 +471,7 @@ private:
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
return; return;
} }
ActiveDlyVisitor dlyvisitor{nodep, ActiveDlyVisitor::CT_INITIAL}; const ActiveDlyVisitor dlyvisitor{nodep, ActiveDlyVisitor::CT_INITIAL};
if (!m_scopeFinalp) { if (!m_scopeFinalp) {
m_scopeFinalp = new AstCFunc( m_scopeFinalp = new AstCFunc(
nodep->fileline(), "_final_" + m_namer.scopep()->nameDotless(), m_namer.scopep()); nodep->fileline(), "_final_" + m_namer.scopep()->nameDotless(), m_namer.scopep());
@ -540,7 +540,7 @@ private:
// Warn and/or convert any delayed assignments // Warn and/or convert any delayed assignments
if (combo && !sequent) { if (combo && !sequent) {
ActiveLatchCheckVisitor latchvisitor{nodep, kwd}; const ActiveLatchCheckVisitor latchvisitor{nodep, kwd};
if (kwd == VAlwaysKwd::ALWAYS_LATCH) { if (kwd == VAlwaysKwd::ALWAYS_LATCH) {
ActiveDlyVisitor{nodep, ActiveDlyVisitor::CT_LATCH}; ActiveDlyVisitor{nodep, ActiveDlyVisitor::CT_LATCH};
} else { } else {

View File

@ -34,7 +34,7 @@ private:
// STATE // STATE
AstNodeModule* m_modp = nullptr; // Last module AstNodeModule* m_modp = nullptr; // Last module
AstBegin* m_beginp = nullptr; // Last begin const AstBegin* m_beginp = nullptr; // Last begin
unsigned m_monitorNum = 0; // Global $monitor numbering (not per module) unsigned m_monitorNum = 0; // Global $monitor numbering (not per module)
AstVar* m_monitorNumVarp = nullptr; // $monitor number variable AstVar* m_monitorNumVarp = nullptr; // $monitor number variable
AstVar* m_monitorOffVarp = nullptr; // $monitoroff variable AstVar* m_monitorOffVarp = nullptr; // $monitoroff variable

View File

@ -777,14 +777,14 @@ void AstNode::deleteTree() {
#ifdef VL_LEAK_CHECKS #ifdef VL_LEAK_CHECKS
void* AstNode::operator new(size_t size) { void* AstNode::operator new(size_t size) {
// Optimization note: Aligning to cache line is a loss, due to lost packing // Optimization note: Aligning to cache line is a loss, due to lost packing
AstNode* const objp = static_cast<AstNode*>(::operator new(size)); const AstNode* const objp = static_cast<AstNode*>(::operator new(size));
V3Broken::addNewed(objp); V3Broken::addNewed(objp);
return objp; return objp;
} }
void AstNode::operator delete(void* objp, size_t size) { void AstNode::operator delete(void* objp, size_t size) {
if (!objp) return; if (!objp) return;
AstNode* const nodep = static_cast<AstNode*>(objp); const AstNode* const nodep = static_cast<AstNode*>(objp);
V3Broken::deleted(nodep); V3Broken::deleted(nodep);
::operator delete(objp); ::operator delete(objp);
} }
@ -995,7 +995,7 @@ void AstNode::checkTreeIterList(AstNode* backp) {
// private: Check a (possible) list of nodes, this is always the head of the list // private: Check a (possible) list of nodes, this is always the head of the list
// Audited to make sure this is never nullptr // Audited to make sure this is never nullptr
AstNode* const headp = this; AstNode* const headp = this;
AstNode* tailp = this; const AstNode* tailp = this;
for (AstNode* nodep = headp; nodep; nodep = nodep->nextp()) { for (AstNode* nodep = headp; nodep; nodep = nodep->nextp()) {
nodep->checkTreeIter(backp); nodep->checkTreeIter(backp);
UASSERT_OBJ(headp == this || !nextp(), this, UASSERT_OBJ(headp == this || !nextp(), this,

View File

@ -1008,7 +1008,7 @@ public:
// MEMBERS // MEMBERS
void init(int hi, int lo, bool littleEndian) { void init(int hi, int lo, bool littleEndian) {
if (lo > hi) { if (lo > hi) {
int t = hi; const int t = hi;
hi = lo; hi = lo;
lo = t; lo = t;
} }
@ -1077,11 +1077,11 @@ inline std::ostream& operator<<(std::ostream& os, const VUseType& rhs) {
class VBasicTypeKey final { class VBasicTypeKey final {
public: public:
int m_width; // From AstNodeDType: Bit width of operation const int m_width; // From AstNodeDType: Bit width of operation
int m_widthMin; // From AstNodeDType: If unsized, bitwidth of minimum implementation const int m_widthMin; // From AstNodeDType: If unsized, bitwidth of minimum implementation
VSigning m_numeric; // From AstNodeDType: Node is signed const VSigning m_numeric; // From AstNodeDType: Node is signed
AstBasicDTypeKwd m_keyword; // From AstBasicDType: What keyword created basic type const AstBasicDTypeKwd m_keyword; // From AstBasicDType: What keyword created basic type
VNumRange m_nrange; // From AstBasicDType: Numeric msb/lsb (if non-opaque keyword) const VNumRange m_nrange; // From AstBasicDType: Numeric msb/lsb (if non-opaque keyword)
bool operator==(const VBasicTypeKey& rhs) const { bool operator==(const VBasicTypeKey& rhs) const {
return m_width == rhs.m_width && m_widthMin == rhs.m_widthMin && m_numeric == rhs.m_numeric return m_width == rhs.m_width && m_widthMin == rhs.m_widthMin && m_numeric == rhs.m_numeric
&& m_keyword == rhs.m_keyword && m_nrange == rhs.m_nrange; && m_keyword == rhs.m_keyword && m_nrange == rhs.m_nrange;
@ -2612,12 +2612,12 @@ public:
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep(); if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
} }
virtual bool same(const AstNode* samep) const override { virtual bool same(const AstNode* samep) const override {
const AstNodeArrayDType* asamep = static_cast<const AstNodeArrayDType*>(samep); const AstNodeArrayDType* const asamep = static_cast<const AstNodeArrayDType*>(samep);
return (hi() == asamep->hi() && subDTypep() == asamep->subDTypep() return (hi() == asamep->hi() && subDTypep() == asamep->subDTypep()
&& rangenp()->sameTree(asamep->rangenp())); && rangenp()->sameTree(asamep->rangenp()));
} // HashedDT doesn't recurse, so need to check children } // HashedDT doesn't recurse, so need to check children
virtual bool similarDType(AstNodeDType* samep) const override { virtual bool similarDType(AstNodeDType* samep) const override {
const AstNodeArrayDType* asamep = static_cast<const AstNodeArrayDType*>(samep); const AstNodeArrayDType* const asamep = static_cast<const AstNodeArrayDType*>(samep);
return (asamep && type() == samep->type() && hi() == asamep->hi() return (asamep && type() == samep->type() && hi() == asamep->hi()
&& rangenp()->sameTree(asamep->rangenp()) && rangenp()->sameTree(asamep->rangenp())
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp())); && subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()));
@ -2705,7 +2705,7 @@ public:
virtual const char* broken() const override; virtual const char* broken() const override;
virtual int instrCount() const override { return INSTR_COUNT_CALL; } virtual int instrCount() const override { return INSTR_COUNT_CALL; }
virtual bool same(const AstNode* samep) const override { virtual bool same(const AstNode* samep) const override {
const AstNodeCCall* asamep = static_cast<const AstNodeCCall*>(samep); const AstNodeCCall* const asamep = static_cast<const AstNodeCCall*>(samep);
return (funcp() == asamep->funcp() && argTypes() == asamep->argTypes()); return (funcp() == asamep->funcp() && argTypes() == asamep->argTypes());
} }
AstNode* exprsp() const { return op2p(); } // op2 = expressions to print AstNode* exprsp() const { return op2p(); } // op2 = expressions to print
@ -2901,7 +2901,7 @@ class AstNodeModule VL_NOT_FINAL : public AstNode {
// excluding $unit package stuff // excluding $unit package stuff
private: private:
string m_name; // Name of the module string m_name; // Name of the module
string m_origName; // Name of the module, ignoring name() changes, for dot lookup const string m_origName; // Name of the module, ignoring name() changes, for dot lookup
string m_hierName; // Hierarchical name for errors, etc. string m_hierName; // Hierarchical name for errors, etc.
bool m_modPublic : 1; // Module has public references bool m_modPublic : 1; // Module has public references
bool m_modTrace : 1; // Tracing this module bool m_modTrace : 1; // Tracing this module

View File

@ -226,11 +226,11 @@ AstConst* AstConst::parseParamLiteral(FileLine* fl, const string& literal) {
bool success = false; bool success = false;
if (literal[0] == '"') { if (literal[0] == '"') {
// This is a string // This is a string
string v = literal.substr(1, literal.find('"', 1) - 1); const string v = literal.substr(1, literal.find('"', 1) - 1);
return new AstConst(fl, AstConst::VerilogStringLiteral(), v); return new AstConst(fl, AstConst::VerilogStringLiteral(), v);
} else if (literal.find_first_of(".eEpP") != string::npos) { } else if (literal.find_first_of(".eEpP") != string::npos) {
// This may be a real // This may be a real
double v = VString::parseDouble(literal, &success); const double v = VString::parseDouble(literal, &success);
if (success) return new AstConst(fl, AstConst::RealDouble(), v); if (success) return new AstConst(fl, AstConst::RealDouble(), v);
} }
if (!success) { if (!success) {
@ -242,7 +242,7 @@ AstConst* AstConst::parseParamLiteral(FileLine* fl, const string& literal) {
// the string after the number, this is invalid C and we try // the string after the number, this is invalid C and we try
// the Verilog literal parser. // the Verilog literal parser.
char* endp; char* endp;
int v = strtol(literal.c_str(), &endp, 0); const int v = strtol(literal.c_str(), &endp, 0);
if ((v != 0) && (endp[0] == 0)) { // C literal if ((v != 0) && (endp[0] == 0)) { // C literal
return new AstConst(fl, AstConst::Signed32(), v); return new AstConst(fl, AstConst::Signed32(), v);
} else { // Try a Verilog literal (fatals if not) } else { // Try a Verilog literal (fatals if not)
@ -475,7 +475,7 @@ public:
string convert(const AstVar* varp) const { string convert(const AstVar* varp) const {
if (varp->isDpiOpenArray()) { if (varp->isDpiOpenArray()) {
return openArray(varp); return openArray(varp);
} else if (const AstBasicDType* basicp = varp->basicp()) { } else if (const AstBasicDType* const basicp = varp->basicp()) {
if (basicp->isDpiBitVec() || basicp->isDpiLogicVec()) { if (basicp->isDpiBitVec() || basicp->isDpiLogicVec()) {
return bitLogicVector(varp, basicp->isDpiBitVec()); return bitLogicVector(varp, basicp->isDpiBitVec());
} else { } else {
@ -515,9 +515,9 @@ string AstVar::dpiArgType(bool named, bool forReturn) const {
string AstVar::dpiTmpVarType(const string& varName) const { string AstVar::dpiTmpVarType(const string& varName) const {
class converter final : public dpiTypesToStringConverter { class converter final : public dpiTypesToStringConverter {
string m_name; const string m_name;
string arraySuffix(const AstVar* varp, size_t n) const { string arraySuffix(const AstVar* varp, size_t n) const {
if (AstUnpackArrayDType* unpackp if (AstUnpackArrayDType* const unpackp
= VN_CAST(varp->dtypep()->skipRefp(), UnpackArrayDType)) { = VN_CAST(varp->dtypep()->skipRefp(), UnpackArrayDType)) {
// Convert multi dimensional unpacked array to 1D array // Convert multi dimensional unpacked array to 1D array
if (n == 0) n = 1; if (n == 0) n = 1;
@ -583,7 +583,7 @@ AstVar* AstVar::scVarRecurse(AstNode* nodep) {
// See if this is a SC assignment; if so return that type // See if this is a SC assignment; if so return that type
// Historically sc variables are identified by a variable // Historically sc variables are identified by a variable
// attribute. TODO it would better be a data type attribute. // attribute. TODO it would better be a data type attribute.
if (AstVar* anodep = VN_CAST(nodep, Var)) { if (AstVar* const anodep = VN_CAST(nodep, Var)) {
if (anodep->isSc()) { if (anodep->isSc()) {
return anodep; return anodep;
} else { } else {
@ -642,29 +642,29 @@ AstNodeDType::CTypeRecursed AstNodeDType::cTypeRecurse(bool compound) const {
// Legacy compound argument currently just passed through and unused // Legacy compound argument currently just passed through and unused
CTypeRecursed info; CTypeRecursed info;
const AstNodeDType* dtypep = this->skipRefp(); const AstNodeDType* const dtypep = this->skipRefp();
if (const auto* adtypep = VN_CAST(dtypep, AssocArrayDType)) { if (const auto* const adtypep = VN_CAST(dtypep, AssocArrayDType)) {
const CTypeRecursed key = adtypep->keyDTypep()->cTypeRecurse(true); const CTypeRecursed key = adtypep->keyDTypep()->cTypeRecurse(true);
const CTypeRecursed val = adtypep->subDTypep()->cTypeRecurse(true); const CTypeRecursed val = adtypep->subDTypep()->cTypeRecurse(true);
info.m_type = "VlAssocArray<" + key.m_type + ", " + val.m_type + ">"; info.m_type = "VlAssocArray<" + key.m_type + ", " + val.m_type + ">";
} else if (const auto* adtypep = VN_CAST(dtypep, DynArrayDType)) { } else if (const auto* const adtypep = VN_CAST(dtypep, DynArrayDType)) {
const CTypeRecursed sub = adtypep->subDTypep()->cTypeRecurse(true); const CTypeRecursed sub = adtypep->subDTypep()->cTypeRecurse(true);
info.m_type = "VlQueue<" + sub.m_type + ">"; info.m_type = "VlQueue<" + sub.m_type + ">";
} else if (const auto* adtypep = VN_CAST(dtypep, QueueDType)) { } else if (const auto* const adtypep = VN_CAST(dtypep, QueueDType)) {
const CTypeRecursed sub = adtypep->subDTypep()->cTypeRecurse(true); const CTypeRecursed sub = adtypep->subDTypep()->cTypeRecurse(true);
info.m_type = "VlQueue<" + sub.m_type; info.m_type = "VlQueue<" + sub.m_type;
// + 1 below as VlQueue uses 0 to mean unlimited, 1 to mean size() max is 1 // + 1 below as VlQueue uses 0 to mean unlimited, 1 to mean size() max is 1
if (adtypep->boundp()) info.m_type += ", " + cvtToStr(adtypep->boundConst() + 1); if (adtypep->boundp()) info.m_type += ", " + cvtToStr(adtypep->boundConst() + 1);
info.m_type += ">"; info.m_type += ">";
} else if (const auto* adtypep = VN_CAST(dtypep, ClassRefDType)) { } else if (const auto* const adtypep = VN_CAST(dtypep, ClassRefDType)) {
info.m_type = "VlClassRef<" + EmitCBaseVisitor::prefixNameProtect(adtypep) + ">"; info.m_type = "VlClassRef<" + EmitCBaseVisitor::prefixNameProtect(adtypep) + ">";
} else if (const auto* adtypep = VN_CAST(dtypep, UnpackArrayDType)) { } else if (const auto* const adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
if (adtypep->isCompound()) compound = true; if (adtypep->isCompound()) compound = true;
const CTypeRecursed sub = adtypep->subDTypep()->cTypeRecurse(compound); const CTypeRecursed sub = adtypep->subDTypep()->cTypeRecurse(compound);
info.m_type = "VlUnpacked<" + sub.m_type; info.m_type = "VlUnpacked<" + sub.m_type;
info.m_type += ", " + cvtToStr(adtypep->declRange().elements()); info.m_type += ", " + cvtToStr(adtypep->declRange().elements());
info.m_type += ">"; info.m_type += ">";
} else if (const AstBasicDType* bdtypep = dtypep->basicp()) { } else if (const AstBasicDType* const bdtypep = dtypep->basicp()) {
// We don't print msb()/lsb() as multidim packed would require recursion, // We don't print msb()/lsb() as multidim packed would require recursion,
// and may confuse users as C++ data is stored always with bit 0 used // and may confuse users as C++ data is stored always with bit 0 used
const string bitvec = (!bdtypep->isOpaque() && !v3Global.opt.protectIds()) const string bitvec = (!bdtypep->isOpaque() && !v3Global.opt.protectIds())
@ -704,7 +704,7 @@ uint32_t AstNodeDType::arrayUnpackedElements() {
uint32_t entries = 1; uint32_t entries = 1;
for (AstNodeDType* dtypep = this; dtypep;) { for (AstNodeDType* dtypep = this; dtypep;) {
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
if (AstUnpackArrayDType* adtypep = VN_CAST(dtypep, UnpackArrayDType)) { if (AstUnpackArrayDType* const adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
entries *= adtypep->elementsConst(); entries *= adtypep->elementsConst();
dtypep = adtypep->subDTypep(); dtypep = adtypep->subDTypep();
} else { } else {
@ -721,7 +721,7 @@ std::pair<uint32_t, uint32_t> AstNodeDType::dimensions(bool includeBasic) {
uint32_t unpacked = 0; uint32_t unpacked = 0;
for (AstNodeDType* dtypep = this; dtypep;) { for (AstNodeDType* dtypep = this; dtypep;) {
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
if (const AstNodeArrayDType* adtypep = VN_CAST(dtypep, NodeArrayDType)) { if (const AstNodeArrayDType* const adtypep = VN_CAST(dtypep, NodeArrayDType)) {
if (VN_IS(adtypep, PackArrayDType)) { if (VN_IS(adtypep, PackArrayDType)) {
++packed; ++packed;
} else { } else {
@ -729,11 +729,11 @@ std::pair<uint32_t, uint32_t> AstNodeDType::dimensions(bool includeBasic) {
} }
dtypep = adtypep->subDTypep(); dtypep = adtypep->subDTypep();
continue; continue;
} else if (const AstQueueDType* qdtypep = VN_CAST(dtypep, QueueDType)) { } else if (const AstQueueDType* const qdtypep = VN_CAST(dtypep, QueueDType)) {
unpacked++; unpacked++;
dtypep = qdtypep->subDTypep(); dtypep = qdtypep->subDTypep();
continue; continue;
} else if (const AstBasicDType* adtypep = VN_CAST(dtypep, BasicDType)) { } else if (const AstBasicDType* const adtypep = VN_CAST(dtypep, BasicDType)) {
if (includeBasic && (adtypep->isRanged() || adtypep->isString())) packed++; if (includeBasic && (adtypep->isRanged() || adtypep->isString())) packed++;
} else if (VN_IS(dtypep, StructDType)) { } else if (VN_IS(dtypep, StructDType)) {
packed++; packed++;
@ -745,7 +745,7 @@ std::pair<uint32_t, uint32_t> AstNodeDType::dimensions(bool includeBasic) {
int AstNodeDType::widthPow2() const { int AstNodeDType::widthPow2() const {
// I.e. width 30 returns 32, width 32 returns 32. // I.e. width 30 returns 32, width 32 returns 32.
uint32_t width = this->width(); const uint32_t width = this->width();
for (int p2 = 30; p2 >= 0; p2--) { for (int p2 = 30; p2 >= 0; p2--) {
if (width > (1UL << p2)) return (1UL << (p2 + 1)); if (width > (1UL << p2)) return (1UL << (p2 + 1));
} }
@ -753,11 +753,11 @@ int AstNodeDType::widthPow2() const {
} }
bool AstNodeDType::isLiteralType() const { bool AstNodeDType::isLiteralType() const {
if (auto* const dtypep = VN_CAST(skipRefp(), BasicDType)) { if (const auto* const dtypep = VN_CAST(skipRefp(), BasicDType)) {
return dtypep->keyword().isLiteralType(); return dtypep->keyword().isLiteralType();
} else if (auto* const dtypep = VN_CAST(skipRefp(), UnpackArrayDType)) { } else if (const auto* const dtypep = VN_CAST(skipRefp(), UnpackArrayDType)) {
return dtypep->basicp()->isLiteralType(); return dtypep->basicp()->isLiteralType();
} else if (auto* const dtypep = VN_CAST(skipRefp(), StructDType)) { } else if (const auto* const dtypep = VN_CAST(skipRefp(), StructDType)) {
// Currently all structs are packed, later this can be expanded to // Currently all structs are packed, later this can be expanded to
// 'forall members _.isLiteralType()' // 'forall members _.isLiteralType()'
return dtypep->packed(); return dtypep->packed();
@ -894,7 +894,7 @@ void AstTypeTable::clearCache() {
m_detailedMap.clear(); m_detailedMap.clear();
// Clear generic()'s so dead detection will work // Clear generic()'s so dead detection will work
for (AstNode* nodep = typesp(); nodep; nodep = nodep->nextp()) { for (AstNode* nodep = typesp(); nodep; nodep = nodep->nextp()) {
if (AstBasicDType* bdtypep = VN_CAST(nodep, BasicDType)) bdtypep->generic(false); if (AstBasicDType* const bdtypep = VN_CAST(nodep, BasicDType)) bdtypep->generic(false);
} }
} }
@ -902,7 +902,7 @@ void AstTypeTable::repairCache() {
// After we mass-change widthMin in V3WidthCommit, we need to correct the table. // After we mass-change widthMin in V3WidthCommit, we need to correct the table.
clearCache(); clearCache();
for (AstNode* nodep = typesp(); nodep; nodep = nodep->nextp()) { for (AstNode* nodep = typesp(); nodep; nodep = nodep->nextp()) {
if (AstBasicDType* bdtypep = VN_CAST(nodep, BasicDType)) { if (AstBasicDType* const bdtypep = VN_CAST(nodep, BasicDType)) {
(void)findInsertSameDType(bdtypep); (void)findInsertSameDType(bdtypep);
} }
} }
@ -910,7 +910,7 @@ void AstTypeTable::repairCache() {
AstEmptyQueueDType* AstTypeTable::findEmptyQueueDType(FileLine* fl) { AstEmptyQueueDType* AstTypeTable::findEmptyQueueDType(FileLine* fl) {
if (VL_UNLIKELY(!m_emptyQueuep)) { if (VL_UNLIKELY(!m_emptyQueuep)) {
AstEmptyQueueDType* newp = new AstEmptyQueueDType{fl}; AstEmptyQueueDType* const newp = new AstEmptyQueueDType{fl};
addTypesp(newp); addTypesp(newp);
m_emptyQueuep = newp; m_emptyQueuep = newp;
} }
@ -919,7 +919,7 @@ AstEmptyQueueDType* AstTypeTable::findEmptyQueueDType(FileLine* fl) {
AstVoidDType* AstTypeTable::findVoidDType(FileLine* fl) { AstVoidDType* AstTypeTable::findVoidDType(FileLine* fl) {
if (VL_UNLIKELY(!m_voidp)) { if (VL_UNLIKELY(!m_voidp)) {
AstVoidDType* newp = new AstVoidDType{fl}; AstVoidDType* const newp = new AstVoidDType{fl};
addTypesp(newp); addTypesp(newp);
m_voidp = newp; m_voidp = newp;
} }
@ -928,7 +928,7 @@ AstVoidDType* AstTypeTable::findVoidDType(FileLine* fl) {
AstQueueDType* AstTypeTable::findQueueIndexDType(FileLine* fl) { AstQueueDType* AstTypeTable::findQueueIndexDType(FileLine* fl) {
if (VL_UNLIKELY(!m_queueIndexp)) { if (VL_UNLIKELY(!m_queueIndexp)) {
AstQueueDType* newp = new AstQueueDType(fl, AstNode::findUInt32DType(), nullptr); AstQueueDType* const newp = new AstQueueDType(fl, AstNode::findUInt32DType(), nullptr);
addTypesp(newp); addTypesp(newp);
m_queueIndexp = newp; m_queueIndexp = newp;
} }
@ -938,11 +938,11 @@ AstQueueDType* AstTypeTable::findQueueIndexDType(FileLine* fl) {
AstBasicDType* AstTypeTable::findBasicDType(FileLine* fl, AstBasicDTypeKwd kwd) { AstBasicDType* AstTypeTable::findBasicDType(FileLine* fl, AstBasicDTypeKwd kwd) {
if (m_basicps[kwd]) return m_basicps[kwd]; if (m_basicps[kwd]) return m_basicps[kwd];
// //
AstBasicDType* new1p = new AstBasicDType(fl, kwd); AstBasicDType* const new1p = new AstBasicDType(fl, kwd);
// Because the detailed map doesn't update this map, // Because the detailed map doesn't update this map,
// check the detailed map for this same node // check the detailed map for this same node
// Also adds this new node to the detailed map // Also adds this new node to the detailed map
AstBasicDType* newp = findInsertSameDType(new1p); AstBasicDType* const newp = findInsertSameDType(new1p);
if (newp != new1p) { if (newp != new1p) {
VL_DO_DANGLING(new1p->deleteTree(), new1p); VL_DO_DANGLING(new1p->deleteTree(), new1p);
} else { } else {
@ -955,8 +955,8 @@ AstBasicDType* AstTypeTable::findBasicDType(FileLine* fl, AstBasicDTypeKwd kwd)
AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd, int width, AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd, int width,
int widthMin, VSigning numeric) { int widthMin, VSigning numeric) {
AstBasicDType* new1p = new AstBasicDType(fl, kwd, numeric, width, widthMin); AstBasicDType* const new1p = new AstBasicDType(fl, kwd, numeric, width, widthMin);
AstBasicDType* newp = findInsertSameDType(new1p); AstBasicDType* const newp = findInsertSameDType(new1p);
if (newp != new1p) { if (newp != new1p) {
VL_DO_DANGLING(new1p->deleteTree(), new1p); VL_DO_DANGLING(new1p->deleteTree(), new1p);
} else { } else {
@ -968,8 +968,8 @@ AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kw
AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd, AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kwd,
const VNumRange& range, int widthMin, const VNumRange& range, int widthMin,
VSigning numeric) { VSigning numeric) {
AstBasicDType* new1p = new AstBasicDType(fl, kwd, numeric, range, widthMin); AstBasicDType* const new1p = new AstBasicDType(fl, kwd, numeric, range, widthMin);
AstBasicDType* newp = findInsertSameDType(new1p); AstBasicDType* const newp = findInsertSameDType(new1p);
if (newp != new1p) { if (newp != new1p) {
VL_DO_DANGLING(new1p->deleteTree(), new1p); VL_DO_DANGLING(new1p->deleteTree(), new1p);
} else { } else {
@ -979,8 +979,8 @@ AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, AstBasicDTypeKwd kw
} }
AstBasicDType* AstTypeTable::findInsertSameDType(AstBasicDType* nodep) { AstBasicDType* AstTypeTable::findInsertSameDType(AstBasicDType* nodep) {
VBasicTypeKey key(nodep->width(), nodep->widthMin(), nodep->numeric(), nodep->keyword(), const VBasicTypeKey key(nodep->width(), nodep->widthMin(), nodep->numeric(), nodep->keyword(),
nodep->nrange()); nodep->nrange());
DetailedMap& mapr = m_detailedMap; DetailedMap& mapr = m_detailedMap;
const auto it = mapr.find(key); const auto it = mapr.find(key);
if (it != mapr.end()) return it->second; if (it != mapr.end()) return it->second;
@ -1037,14 +1037,14 @@ static bool sameInit(const AstInitArray* ap, const AstInitArray* bp) {
} }
AstVarScope* AstConstPool::findTable(AstInitArray* initp) { AstVarScope* AstConstPool::findTable(AstInitArray* initp) {
AstNode* const defaultp = initp->defaultp(); const AstNode* const defaultp = initp->defaultp();
// Verify initializer is well formed // Verify initializer is well formed
UASSERT_OBJ(VN_IS(initp->dtypep(), UnpackArrayDType), initp, UASSERT_OBJ(VN_IS(initp->dtypep(), UnpackArrayDType), initp,
"Const pool table must have AstUnpackArrayDType dtype"); "Const pool table must have AstUnpackArrayDType dtype");
UASSERT_OBJ(!defaultp || VN_IS(defaultp, Const), initp, UASSERT_OBJ(!defaultp || VN_IS(defaultp, Const), initp,
"Const pool table default must be Const"); "Const pool table default must be Const");
for (AstNode* nodep = initp->initsp(); nodep; nodep = nodep->nextp()) { for (AstNode* nodep = initp->initsp(); nodep; nodep = nodep->nextp()) {
AstNode* const valuep = VN_AS(nodep, InitItem)->valuep(); const AstNode* const valuep = VN_AS(nodep, InitItem)->valuep();
UASSERT_OBJ(VN_IS(valuep, Const), valuep, "Const pool table entry must be Const"); UASSERT_OBJ(VN_IS(valuep, Const), valuep, "Const pool table entry must be Const");
} }
// Try to find an existing table with the same content // Try to find an existing table with the same content
@ -1192,7 +1192,7 @@ void AstNode::dump(std::ostream& str) const {
} else { } else {
str << " @dt=" << nodeAddr(dtypep()) << "@"; str << " @dt=" << nodeAddr(dtypep()) << "@";
} }
if (AstNodeDType* dtp = dtypep()) dtp->dumpSmall(str); if (AstNodeDType* const dtp = dtypep()) dtp->dumpSmall(str);
} else { // V3Broken will throw an error } else { // V3Broken will throw an error
if (dtypep()) str << " %Error-dtype-exp=null,got=" << nodeAddr(dtypep()); if (dtypep()) str << " %Error-dtype-exp=null,got=" << nodeAddr(dtypep());
} }
@ -1285,7 +1285,7 @@ void AstClass::dump(std::ostream& str) const {
if (isVirtual()) str << " [VIRT]"; if (isVirtual()) str << " [VIRT]";
} }
AstClass* AstClassExtends::classp() const { AstClass* AstClassExtends::classp() const {
AstClassRefDType* refp = VN_CAST(dtypep(), ClassRefDType); const AstClassRefDType* refp = VN_CAST(dtypep(), ClassRefDType);
if (VL_UNLIKELY(!refp)) { // LinkDot uses this for 'super.' if (VL_UNLIKELY(!refp)) { // LinkDot uses this for 'super.'
refp = VN_AS(childDTypep(), ClassRefDType); refp = VN_AS(childDTypep(), ClassRefDType);
} }
@ -1474,7 +1474,7 @@ void AstNodeUOrStructDType::dump(std::ostream& str) const {
void AstNodeDType::dump(std::ostream& str) const { void AstNodeDType::dump(std::ostream& str) const {
this->AstNode::dump(str); this->AstNode::dump(str);
if (generic()) str << " [GENERIC]"; if (generic()) str << " [GENERIC]";
if (AstNodeDType* dtp = virtRefDTypep()) { if (AstNodeDType* const dtp = virtRefDTypep()) {
str << " refdt=" << nodeAddr(dtp); str << " refdt=" << nodeAddr(dtp);
dtp->dumpSmall(str); dtp->dumpSmall(str);
} }
@ -1488,7 +1488,7 @@ void AstNodeDType::dumpSmall(std::ostream& str) const {
} }
void AstNodeArrayDType::dumpSmall(std::ostream& str) const { void AstNodeArrayDType::dumpSmall(std::ostream& str) const {
this->AstNodeDType::dumpSmall(str); this->AstNodeDType::dumpSmall(str);
if (auto* adtypep = VN_CAST(this, UnpackArrayDType)) { if (auto* const adtypep = VN_CAST(this, UnpackArrayDType)) {
// uc = packed compound object, u = unpacked POD // uc = packed compound object, u = unpacked POD
str << (adtypep->isCompound() ? "uc" : "u"); str << (adtypep->isCompound() ? "uc" : "u");
} else { } else {
@ -1524,7 +1524,7 @@ std::vector<AstUnpackArrayDType*> AstUnpackArrayDType::unpackDimensions() {
std::vector<AstUnpackArrayDType*> dims; std::vector<AstUnpackArrayDType*> dims;
for (AstUnpackArrayDType* unpackp = this; unpackp;) { for (AstUnpackArrayDType* unpackp = this; unpackp;) {
dims.push_back(unpackp); dims.push_back(unpackp);
if (AstNodeDType* subp = unpackp->subDTypep()) { if (AstNodeDType* const subp = unpackp->subDTypep()) {
unpackp = VN_CAST(subp, UnpackArrayDType); unpackp = VN_CAST(subp, UnpackArrayDType);
} else { } else {
unpackp = nullptr; unpackp = nullptr;
@ -1581,7 +1581,7 @@ void AstMTaskBody::dump(std::ostream& str) const {
void AstTypeTable::dump(std::ostream& str) const { void AstTypeTable::dump(std::ostream& str) const {
this->AstNode::dump(str); this->AstNode::dump(str);
for (int i = 0; i < static_cast<int>(AstBasicDTypeKwd::_ENUM_MAX); ++i) { for (int i = 0; i < static_cast<int>(AstBasicDTypeKwd::_ENUM_MAX); ++i) {
if (AstBasicDType* subnodep = m_basicps[i]) { if (AstBasicDType* const subnodep = m_basicps[i]) {
str << '\n'; // Newline from caller, so newline first str << '\n'; // Newline from caller, so newline first
str << "\t\t" << std::setw(8) << AstBasicDTypeKwd(i).ascii(); str << "\t\t" << std::setw(8) << AstBasicDTypeKwd(i).ascii();
str << " -> "; str << " -> ";
@ -1591,7 +1591,7 @@ void AstTypeTable::dump(std::ostream& str) const {
{ {
const DetailedMap& mapr = m_detailedMap; const DetailedMap& mapr = m_detailedMap;
for (const auto& itr : mapr) { for (const auto& itr : mapr) {
AstBasicDType* dtypep = itr.second; AstBasicDType* const dtypep = itr.second;
str << '\n'; // Newline from caller, so newline first str << '\n'; // Newline from caller, so newline first
str << "\t\tdetailed -> "; str << "\t\tdetailed -> ";
dtypep->dump(str); dtypep->dump(str);

View File

@ -172,7 +172,7 @@ public:
virtual string emitC() override { V3ERROR_NA_RETURN(""); } virtual string emitC() override { V3ERROR_NA_RETURN(""); }
virtual bool cleanOut() const override { return true; } virtual bool cleanOut() const override { return true; }
virtual bool same(const AstNode* samep) const override { virtual bool same(const AstNode* samep) const override {
const AstConst* sp = static_cast<const AstConst*>(samep); const AstConst* const sp = static_cast<const AstConst*>(samep);
return num().isCaseEq(sp->num()); return num().isCaseEq(sp->num());
} }
virtual int instrCount() const override { return widthInstrs(); } virtual int instrCount() const override { return widthInstrs(); }
@ -216,21 +216,21 @@ public:
AstNode* leftp() const { return op2p(); } AstNode* leftp() const { return op2p(); }
AstNode* rightp() const { return op3p(); } AstNode* rightp() const { return op3p(); }
int leftConst() const { int leftConst() const {
AstConst* constp = VN_CAST(leftp(), Const); AstConst* const constp = VN_CAST(leftp(), Const);
return (constp ? constp->toSInt() : 0); return (constp ? constp->toSInt() : 0);
} }
int rightConst() const { int rightConst() const {
AstConst* constp = VN_CAST(rightp(), Const); AstConst* const constp = VN_CAST(rightp(), Const);
return (constp ? constp->toSInt() : 0); return (constp ? constp->toSInt() : 0);
} }
int hiConst() const { int hiConst() const {
int l = leftConst(); const int l = leftConst();
int r = rightConst(); const int r = rightConst();
return l > r ? l : r; return l > r ? l : r;
} }
int loConst() const { int loConst() const {
int l = leftConst(); const int l = leftConst();
int r = rightConst(); const int r = rightConst();
return l > r ? r : l; return l > r ? r : l;
} }
int elementsConst() const { return hiConst() - loConst() + 1; } int elementsConst() const { return hiConst() - loConst() + 1; }
@ -375,7 +375,7 @@ class AstParamTypeDType final : public AstNodeDType {
// Parents: MODULE // Parents: MODULE
// A parameter type statement; much like a var or typedef // A parameter type statement; much like a var or typedef
private: private:
AstVarType m_varType; // Type of variable (for localparam vs. param) const AstVarType m_varType; // Type of variable (for localparam vs. param)
string m_name; // Name of variable string m_name; // Name of variable
public: public:
AstParamTypeDType(FileLine* fl, AstVarType type, const string& name, VFlagChildDType, AstParamTypeDType(FileLine* fl, AstVarType type, const string& name, VFlagChildDType,
@ -401,7 +401,7 @@ public:
} }
virtual AstNodeDType* skipRefToEnump() const override { return subDTypep()->skipRefToEnump(); } virtual AstNodeDType* skipRefToEnump() const override { return subDTypep()->skipRefToEnump(); }
virtual bool similarDType(AstNodeDType* samep) const override { virtual bool similarDType(AstNodeDType* samep) const override {
const AstParamTypeDType* sp = static_cast<const AstParamTypeDType*>(samep); const AstParamTypeDType* const sp = static_cast<const AstParamTypeDType*>(samep);
return type() == samep->type() && sp return type() == samep->type() && sp
&& this->subDTypep()->skipRefp()->similarDType(sp->subDTypep()->skipRefp()); && this->subDTypep()->skipRefp()->similarDType(sp->subDTypep()->skipRefp());
} }
@ -494,7 +494,7 @@ public:
ASTNODE_NODE_FUNCS(DefImplicitDType) ASTNODE_NODE_FUNCS(DefImplicitDType)
int uniqueNum() const { return m_uniqueNum; } int uniqueNum() const { return m_uniqueNum; }
virtual bool same(const AstNode* samep) const override { virtual bool same(const AstNode* samep) const override {
const AstDefImplicitDType* sp = static_cast<const AstDefImplicitDType*>(samep); const AstDefImplicitDType* const sp = static_cast<const AstDefImplicitDType*>(samep);
return uniqueNum() == sp->uniqueNum(); return uniqueNum() == sp->uniqueNum();
} }
virtual bool similarDType(AstNodeDType* samep) const override { virtual bool similarDType(AstNodeDType* samep) const override {
@ -551,13 +551,13 @@ public:
if (m_keyDTypep && m_keyDTypep->clonep()) m_keyDTypep = m_keyDTypep->clonep(); if (m_keyDTypep && m_keyDTypep->clonep()) m_keyDTypep = m_keyDTypep->clonep();
} }
virtual bool same(const AstNode* samep) const override { virtual bool same(const AstNode* samep) const override {
const AstAssocArrayDType* asamep = static_cast<const AstAssocArrayDType*>(samep); const AstAssocArrayDType* const asamep = static_cast<const AstAssocArrayDType*>(samep);
if (!asamep->subDTypep()) return false; if (!asamep->subDTypep()) return false;
if (!asamep->keyDTypep()) return false; if (!asamep->keyDTypep()) return false;
return (subDTypep() == asamep->subDTypep() && keyDTypep() == asamep->keyDTypep()); return (subDTypep() == asamep->subDTypep() && keyDTypep() == asamep->keyDTypep());
} }
virtual bool similarDType(AstNodeDType* samep) const override { virtual bool similarDType(AstNodeDType* samep) const override {
const AstAssocArrayDType* asamep = static_cast<const AstAssocArrayDType*>(samep); const AstAssocArrayDType* const asamep = static_cast<const AstAssocArrayDType*>(samep);
return type() == samep->type() && asamep->subDTypep() return type() == samep->type() && asamep->subDTypep()
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()); && subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp());
} }
@ -650,12 +650,12 @@ public:
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep(); if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
} }
virtual bool same(const AstNode* samep) const override { virtual bool same(const AstNode* samep) const override {
const AstAssocArrayDType* asamep = static_cast<const AstAssocArrayDType*>(samep); const AstAssocArrayDType* const asamep = static_cast<const AstAssocArrayDType*>(samep);
if (!asamep->subDTypep()) return false; if (!asamep->subDTypep()) return false;
return subDTypep() == asamep->subDTypep(); return subDTypep() == asamep->subDTypep();
} }
virtual bool similarDType(AstNodeDType* samep) const override { virtual bool similarDType(AstNodeDType* samep) const override {
const AstAssocArrayDType* asamep = static_cast<const AstAssocArrayDType*>(samep); const AstAssocArrayDType* const asamep = static_cast<const AstAssocArrayDType*>(samep);
return type() == samep->type() && asamep->subDTypep() return type() == samep->type() && asamep->subDTypep()
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()); && subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp());
} }
@ -736,7 +736,7 @@ public:
ASTNODE_NODE_FUNCS(UnpackArrayDType) ASTNODE_NODE_FUNCS(UnpackArrayDType)
virtual string prettyDTypeName() const override; virtual string prettyDTypeName() const override;
virtual bool same(const AstNode* samep) const override { virtual bool same(const AstNode* samep) const override {
const AstUnpackArrayDType* sp = static_cast<const AstUnpackArrayDType*>(samep); const AstUnpackArrayDType* const sp = static_cast<const AstUnpackArrayDType*>(samep);
return m_isCompound == sp->m_isCompound; return m_isCompound == sp->m_isCompound;
} }
// Outer dimension comes first. The first element is this node. // Outer dimension comes first. The first element is this node.
@ -767,12 +767,12 @@ public:
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep(); if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
} }
virtual bool same(const AstNode* samep) const override { virtual bool same(const AstNode* samep) const override {
const AstNodeArrayDType* asamep = static_cast<const AstNodeArrayDType*>(samep); const AstNodeArrayDType* const asamep = static_cast<const AstNodeArrayDType*>(samep);
if (!asamep->subDTypep()) return false; if (!asamep->subDTypep()) return false;
return (subDTypep() == asamep->subDTypep()); return (subDTypep() == asamep->subDTypep());
} }
virtual bool similarDType(AstNodeDType* samep) const override { virtual bool similarDType(AstNodeDType* samep) const override {
const AstNodeArrayDType* asamep = static_cast<const AstNodeArrayDType*>(samep); const AstNodeArrayDType* const asamep = static_cast<const AstNodeArrayDType*>(samep);
return type() == samep->type() && asamep->subDTypep() return type() == samep->type() && asamep->subDTypep()
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()); && subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp());
} }
@ -876,7 +876,7 @@ public:
virtual void dump(std::ostream& str) const override; virtual void dump(std::ostream& str) const override;
// width/widthMin/numeric compared elsewhere // width/widthMin/numeric compared elsewhere
virtual bool same(const AstNode* samep) const override { virtual bool same(const AstNode* samep) const override {
const AstBasicDType* sp = static_cast<const AstBasicDType*>(samep); const AstBasicDType* const sp = static_cast<const AstBasicDType*>(samep);
return m == sp->m; return m == sp->m;
} }
virtual bool similarDType(AstNodeDType* samep) const override { virtual bool similarDType(AstNodeDType* samep) const override {
@ -973,7 +973,7 @@ public:
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep(); if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
} }
virtual bool same(const AstNode* samep) const override { virtual bool same(const AstNode* samep) const override {
const AstConstDType* sp = static_cast<const AstConstDType*>(samep); const AstConstDType* const sp = static_cast<const AstConstDType*>(samep);
return (m_refDTypep == sp->m_refDTypep); return (m_refDTypep == sp->m_refDTypep);
} }
virtual bool similarDType(AstNodeDType* samep) const override { virtual bool similarDType(AstNodeDType* samep) const override {
@ -1025,7 +1025,7 @@ public:
if (m_classp && m_classp->clonep()) m_classp = m_classp->clonep(); if (m_classp && m_classp->clonep()) m_classp = m_classp->clonep();
} }
virtual bool same(const AstNode* samep) const override { virtual bool same(const AstNode* samep) const override {
const AstClassRefDType* asamep = static_cast<const AstClassRefDType*>(samep); const AstClassRefDType* const asamep = static_cast<const AstClassRefDType*>(samep);
return (m_classp == asamep->m_classp && m_classOrPackagep == asamep->m_classOrPackagep); return (m_classp == asamep->m_classp && m_classOrPackagep == asamep->m_classOrPackagep);
} }
virtual bool similarDType(AstNodeDType* samep) const override { virtual bool similarDType(AstNodeDType* samep) const override {
@ -1134,12 +1134,12 @@ public:
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep(); if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
} }
virtual bool same(const AstNode* samep) const override { virtual bool same(const AstNode* samep) const override {
const AstQueueDType* asamep = static_cast<const AstQueueDType*>(samep); const AstQueueDType* const asamep = static_cast<const AstQueueDType*>(samep);
if (!asamep->subDTypep()) return false; if (!asamep->subDTypep()) return false;
return (subDTypep() == asamep->subDTypep()); return (subDTypep() == asamep->subDTypep());
} }
virtual bool similarDType(AstNodeDType* samep) const override { virtual bool similarDType(AstNodeDType* samep) const override {
const AstQueueDType* asamep = static_cast<const AstQueueDType*>(samep); const AstQueueDType* const asamep = static_cast<const AstQueueDType*>(samep);
return type() == samep->type() && asamep->subDTypep() return type() == samep->type() && asamep->subDTypep()
&& subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()); && subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp());
} }
@ -1156,7 +1156,7 @@ public:
AstNode* boundp() const { return op2p(); } // op2 = Bound, nullptr = none AstNode* boundp() const { return op2p(); } // op2 = Bound, nullptr = none
void boundp(AstNode* nodep) { setNOp2p(nodep); } void boundp(AstNode* nodep) { setNOp2p(nodep); }
int boundConst() const { int boundConst() const {
AstConst* constp = VN_CAST(boundp(), Const); AstConst* const constp = VN_CAST(boundp(), Const);
return (constp ? constp->toSInt() : 0); return (constp ? constp->toSInt() : 0);
} }
virtual AstNodeDType* virtRefDTypep() const override { return m_refDTypep; } virtual AstNodeDType* virtRefDTypep() const override { return m_refDTypep; }
@ -1210,7 +1210,7 @@ public:
if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep(); if (m_refDTypep && m_refDTypep->clonep()) m_refDTypep = m_refDTypep->clonep();
} }
virtual bool same(const AstNode* samep) const override { virtual bool same(const AstNode* samep) const override {
const AstRefDType* asamep = static_cast<const AstRefDType*>(samep); const AstRefDType* const asamep = static_cast<const AstRefDType*>(samep);
return (m_typedefp == asamep->m_typedefp && m_refDTypep == asamep->m_refDTypep return (m_typedefp == asamep->m_typedefp && m_refDTypep == asamep->m_refDTypep
&& m_name == asamep->m_name && m_classOrPackagep == asamep->m_classOrPackagep); && m_name == asamep->m_name && m_classOrPackagep == asamep->m_classOrPackagep);
} }
@ -1458,7 +1458,7 @@ public:
if (m_itemp->clonep()) m_itemp = m_itemp->clonep(); if (m_itemp->clonep()) m_itemp = m_itemp->clonep();
} }
virtual bool same(const AstNode* samep) const override { virtual bool same(const AstNode* samep) const override {
const AstEnumItemRef* sp = static_cast<const AstEnumItemRef*>(samep); const AstEnumItemRef* const sp = static_cast<const AstEnumItemRef*>(samep);
return itemp() == sp->itemp(); return itemp() == sp->itemp();
} }
AstEnumItem* itemp() const { return m_itemp; } AstEnumItem* itemp() const { return m_itemp; }
@ -1498,7 +1498,7 @@ public:
} }
int uniqueNum() const { return m_uniqueNum; } int uniqueNum() const { return m_uniqueNum; }
virtual bool same(const AstNode* samep) const override { virtual bool same(const AstNode* samep) const override {
const AstEnumDType* sp = static_cast<const AstEnumDType*>(samep); const AstEnumDType* const sp = static_cast<const AstEnumDType*>(samep);
return uniqueNum() == sp->uniqueNum(); return uniqueNum() == sp->uniqueNum();
} }
virtual bool similarDType(AstNodeDType* samep) const override { return this == samep; } virtual bool similarDType(AstNodeDType* samep) const override { return this == samep; }
@ -2572,7 +2572,7 @@ public:
class AstModule final : public AstNodeModule { class AstModule final : public AstNodeModule {
// A module declaration // A module declaration
private: private:
bool m_isProgram; // Module represents a program const bool m_isProgram; // Module represents a program
public: public:
AstModule(FileLine* fl, const string& name, bool program = false) AstModule(FileLine* fl, const string& name, bool program = false)
: ASTGEN_SUPER_Module(fl, name) : ASTGEN_SUPER_Module(fl, name)
@ -2884,7 +2884,8 @@ class AstCellInline final : public AstNode {
// Children: When 2 levels inlined, other CellInline under this // Children: When 2 levels inlined, other CellInline under this
private: private:
string m_name; // Cell name, possibly {a}__DOT__{b}... string m_name; // Cell name, possibly {a}__DOT__{b}...
string m_origModName; // Original name of the module, ignoring name() changes, for dot lookup const string
m_origModName; // Original name of the module, ignoring name() changes, for dot lookup
AstScope* m_scopep = nullptr; // The scope that the cell is inlined into AstScope* m_scopep = nullptr; // The scope that the cell is inlined into
VTimescale m_timeunit; // Parent module time unit VTimescale m_timeunit; // Parent module time unit
public: public:
@ -3022,7 +3023,7 @@ public:
virtual void dump(std::ostream& str) const override; virtual void dump(std::ostream& str) const override;
virtual string name() const override { return m_name; } // * = Var name virtual string name() const override { return m_name; } // * = Var name
virtual bool same(const AstNode* samep) const override { virtual bool same(const AstNode* samep) const override {
const AstParseRef* asamep = static_cast<const AstParseRef*>(samep); const AstParseRef* const asamep = static_cast<const AstParseRef*>(samep);
return (expect() == asamep->expect() && m_name == asamep->m_name); return (expect() == asamep->expect() && m_name == asamep->m_name);
} }
virtual void name(const string& name) override { m_name = name; } virtual void name(const string& name) override { m_name = name; }
@ -3075,7 +3076,7 @@ public:
class AstDot final : public AstNode { class AstDot final : public AstNode {
// A dot separating paths in an AstVarXRef, AstFuncRef or AstTaskRef // A dot separating paths in an AstVarXRef, AstFuncRef or AstTaskRef
// These are eliminated in the link stage // These are eliminated in the link stage
bool m_colon; // Is a "::" instead of a "." (lhs must be package/class) const bool m_colon; // Is a "::" instead of a "." (lhs must be package/class)
public: public:
AstDot(FileLine* fl, bool colon, AstNode* lhsp, AstNode* rhsp) AstDot(FileLine* fl, bool colon, AstNode* lhsp, AstNode* rhsp)
: ASTGEN_SUPER_Dot(fl) : ASTGEN_SUPER_Dot(fl)
@ -3343,7 +3344,7 @@ public:
}; };
class AstAlways final : public AstNodeProcedure { class AstAlways final : public AstNodeProcedure {
VAlwaysKwd m_keyword; const VAlwaysKwd m_keyword;
public: public:
AstAlways(FileLine* fl, VAlwaysKwd keyword, AstSenTree* sensesp, AstNode* bodysp) AstAlways(FileLine* fl, VAlwaysKwd keyword, AstSenTree* sensesp, AstNode* bodysp)
@ -3447,10 +3448,10 @@ public:
} }
virtual bool brokeLhsMustBeLvalue() const override { return true; } virtual bool brokeLhsMustBeLvalue() const override { return true; }
AstAlways* convertToAlways() { AstAlways* convertToAlways() {
AstNode* lhs1p = lhsp()->unlinkFrBack(); AstNode* const lhs1p = lhsp()->unlinkFrBack();
AstNode* rhs1p = rhsp()->unlinkFrBack(); AstNode* const rhs1p = rhsp()->unlinkFrBack();
AstAlways* newp = new AstAlways(fileline(), VAlwaysKwd::ALWAYS, nullptr, AstAlways* const newp = new AstAlways(fileline(), VAlwaysKwd::ALWAYS, nullptr,
new AstAssign(fileline(), lhs1p, rhs1p)); new AstAssign(fileline(), lhs1p, rhs1p));
replaceWith(newp); // User expected to then deleteTree(); replaceWith(newp); // User expected to then deleteTree();
return newp; return newp;
} }
@ -3552,8 +3553,8 @@ class AstComment final : public AstNodeStmt {
// Parents: {statement list} // Parents: {statement list}
// Children: none // Children: none
private: private:
bool m_showAt; // Show "at <fileline>" const bool m_showAt; // Show "at <fileline>"
string m_name; // Text of comment const string m_name; // Text of comment
public: public:
AstComment(FileLine* fl, const string& name, bool showAt = false) AstComment(FileLine* fl, const string& name, bool showAt = false)
: ASTGEN_SUPER_Comment(fl) : ASTGEN_SUPER_Comment(fl)
@ -3641,7 +3642,7 @@ public:
void hier(const string& flag) { m_hier = flag; } void hier(const string& flag) { m_hier = flag; }
void comment(const string& flag) { m_text = flag; } void comment(const string& flag) { m_text = flag; }
virtual bool same(const AstNode* samep) const override { virtual bool same(const AstNode* samep) const override {
const AstCoverDecl* asamep = static_cast<const AstCoverDecl*>(samep); const AstCoverDecl* const asamep = static_cast<const AstCoverDecl*>(samep);
return (fileline() == asamep->fileline() && linescov() == asamep->linescov() return (fileline() == asamep->fileline() && linescov() == asamep->linescov()
&& hier() == asamep->hier() && comment() == asamep->comment()); && hier() == asamep->hier() && comment() == asamep->comment());
} }
@ -3798,9 +3799,9 @@ class AstSFormatF final : public AstNode {
// Convert format to string, generally under an AstDisplay or AstSFormat // Convert format to string, generally under an AstDisplay or AstSFormat
// Also used as "real" function for /*verilator sformat*/ functions // Also used as "real" function for /*verilator sformat*/ functions
string m_text; string m_text;
bool m_hidden; // Under display, etc const bool m_hidden; // Under display, etc
bool m_hasFormat; // Has format code bool m_hasFormat; // Has format code
char m_missingArgChar; // Format code when argument without format, 'h'/'o'/'b' const char m_missingArgChar; // Format code when argument without format, 'h'/'o'/'b'
VTimescale m_timeunit; // Parent module time unit VTimescale m_timeunit; // Parent module time unit
public: public:
class NoFormat {}; class NoFormat {};
@ -3908,7 +3909,7 @@ class AstDumpCtl final : public AstNodeStmt {
// $dumpon etc // $dumpon etc
// Parents: expr // Parents: expr
// Child: expr based on type of control statement // Child: expr based on type of control statement
VDumpCtlType m_ctlType; // Type of operation const VDumpCtlType m_ctlType; // Type of operation
public: public:
AstDumpCtl(FileLine* fl, VDumpCtlType ctlType, AstNode* exprp = nullptr) AstDumpCtl(FileLine* fl, VDumpCtlType ctlType, AstNode* exprp = nullptr)
: ASTGEN_SUPER_DumpCtl(fl) : ASTGEN_SUPER_DumpCtl(fl)
@ -4305,7 +4306,7 @@ public:
class AstNodeReadWriteMem VL_NOT_FINAL : public AstNodeStmt { class AstNodeReadWriteMem VL_NOT_FINAL : public AstNodeStmt {
private: private:
bool m_isHex; // readmemh, not readmemb const bool m_isHex; // readmemh, not readmemb
public: public:
AstNodeReadWriteMem(AstType t, FileLine* fl, bool hex, AstNode* filenamep, AstNode* memp, AstNodeReadWriteMem(AstType t, FileLine* fl, bool hex, AstNode* filenamep, AstNode* memp,
AstNode* lsbp, AstNode* msbp) AstNode* lsbp, AstNode* msbp)
@ -4353,7 +4354,7 @@ public:
}; };
class AstMonitorOff final : public AstNodeStmt { class AstMonitorOff final : public AstNodeStmt {
bool m_off; // Monitor off. Using 0=on allows faster init and comparison const bool m_off; // Monitor off. Using 0=on allows faster init and comparison
public: public:
AstMonitorOff(FileLine* fl, bool off) AstMonitorOff(FileLine* fl, bool off)
@ -4857,7 +4858,7 @@ class AstBegin final : public AstNodeBlock {
// Children: statements // Children: statements
private: private:
bool m_generate; // Underneath a generate bool m_generate; // Underneath a generate
bool m_implied; // Not inserted by user const bool m_implied; // Not inserted by user
public: public:
// Node that simply puts name into the output stream // Node that simply puts name into the output stream
AstBegin(FileLine* fl, const string& name, AstNode* stmtsp, bool generate = false, AstBegin(FileLine* fl, const string& name, AstNode* stmtsp, bool generate = false,
@ -4994,7 +4995,7 @@ public:
oldp = it->second->valuep(); oldp = it->second->valuep();
it->second->valuep(newp); it->second->valuep(newp);
} else { } else {
AstInitItem* itemp = new AstInitItem(fileline(), newp); AstInitItem* const itemp = new AstInitItem(fileline(), newp);
m_map.emplace(index, itemp); m_map.emplace(index, itemp);
addOp2p(itemp); addOp2p(itemp);
} }
@ -5072,7 +5073,7 @@ public:
class AstPragma final : public AstNode { class AstPragma final : public AstNode {
private: private:
AstPragmaType m_pragType; // Type of pragma const AstPragmaType m_pragType; // Type of pragma
public: public:
// Pragmas don't result in any output code, they're just flags that affect // Pragmas don't result in any output code, they're just flags that affect
// other processing in verilator. // other processing in verilator.
@ -5443,8 +5444,8 @@ class AstRand final : public AstNodeMath {
// $random/$random(seed) or $urandom/$urandom(seed) // $random/$random(seed) or $urandom/$urandom(seed)
// Return a random number, based upon width() // Return a random number, based upon width()
private: private:
bool m_urandom = false; // $urandom vs $random const bool m_urandom = false; // $urandom vs $random
bool m_reset = false; // Random reset, versus always random const bool m_reset = false; // Random reset, versus always random
public: public:
class Reset {}; class Reset {};
AstRand(FileLine* fl, Reset, AstNodeDType* dtp, bool reset) AstRand(FileLine* fl, Reset, AstNodeDType* dtp, bool reset)
@ -5642,7 +5643,7 @@ public:
virtual string emitC() override { return "VL_REDXOR_%lq(%lW, %P, %li)"; } virtual string emitC() override { return "VL_REDXOR_%lq(%lW, %P, %li)"; }
virtual bool cleanOut() const override { return false; } virtual bool cleanOut() const override { return false; }
virtual bool cleanLhs() const override { virtual bool cleanLhs() const override {
int w = lhsp()->width(); const int w = lhsp()->width();
return (w != 1 && w != 2 && w != 4 && w != 8 && w != 16); return (w != 1 && w != 2 && w != 4 && w != 8 && w != 16);
} }
virtual bool sizeMattersLhs() const override { return false; } virtual bool sizeMattersLhs() const override { return false; }
@ -6527,7 +6528,7 @@ public:
enum FmtType { ATOI = 10, ATOHEX = 16, ATOOCT = 8, ATOBIN = 2, ATOREAL = -1 }; enum FmtType { ATOI = 10, ATOHEX = 16, ATOOCT = 8, ATOBIN = 2, ATOREAL = -1 };
private: private:
FmtType m_fmt; // Operation type const FmtType m_fmt; // Operation type
public: public:
AstAtoN(FileLine* fl, AstNode* lhsp, FmtType fmt) AstAtoN(FileLine* fl, AstNode* lhsp, FmtType fmt)
: ASTGEN_SUPER_AtoN(fl, lhsp) : ASTGEN_SUPER_AtoN(fl, lhsp)
@ -7965,7 +7966,7 @@ public:
AstReplicate(FileLine* fl, AstNode* lhsp, AstNode* rhsp) AstReplicate(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
: ASTGEN_SUPER_Replicate(fl, lhsp, rhsp) { : ASTGEN_SUPER_Replicate(fl, lhsp, rhsp) {
if (lhsp) { if (lhsp) {
if (const AstConst* constp = VN_CAST(rhsp, Const)) { if (const AstConst* const constp = VN_CAST(rhsp, Const)) {
dtypeSetLogicSized(lhsp->width() * constp->toUInt(), VSigning::UNSIGNED); dtypeSetLogicSized(lhsp->width() * constp->toUInt(), VSigning::UNSIGNED);
} }
} }
@ -8255,7 +8256,7 @@ public:
class AstCompareNN final : public AstNodeBiop { class AstCompareNN final : public AstNodeBiop {
// Verilog str.compare() and str.icompare() // Verilog str.compare() and str.icompare()
private: private:
bool m_ignoreCase; // True for str.icompare() const bool m_ignoreCase; // True for str.icompare()
public: public:
AstCompareNN(FileLine* fl, AstNode* lhsp, AstNode* rhsp, bool ignoreCase) AstCompareNN(FileLine* fl, AstNode* lhsp, AstNode* rhsp, bool ignoreCase)
: ASTGEN_SUPER_CompareNN(fl, lhsp, rhsp) : ASTGEN_SUPER_CompareNN(fl, lhsp, rhsp)
@ -8510,7 +8511,7 @@ class AstNodeCoverOrAssert VL_NOT_FINAL : public AstNodeStmt {
// Parents: {statement list} // Parents: {statement list}
// Children: expression, report string // Children: expression, report string
private: private:
bool m_immediate; // Immediate assertion/cover const bool m_immediate; // Immediate assertion/cover
string m_name; // Name to report string m_name; // Name to report
public: public:
AstNodeCoverOrAssert(AstType t, FileLine* fl, AstNode* propp, AstNode* passsp, bool immediate, AstNodeCoverOrAssert(AstType t, FileLine* fl, AstNode* propp, AstNode* passsp, bool immediate,
@ -8816,7 +8817,7 @@ public:
virtual bool maybePointedTo() const override { return true; } virtual bool maybePointedTo() const override { return true; }
virtual void dump(std::ostream& str = std::cout) const override; virtual void dump(std::ostream& str = std::cout) const override;
virtual bool same(const AstNode* samep) const override { virtual bool same(const AstNode* samep) const override {
const AstCFunc* asamep = static_cast<const AstCFunc*>(samep); const AstCFunc* const asamep = static_cast<const AstCFunc*>(samep);
return ((isTrace() == asamep->isTrace()) && (rtnTypeVoid() == asamep->rtnTypeVoid()) return ((isTrace() == asamep->isTrace()) && (rtnTypeVoid() == asamep->rtnTypeVoid())
&& (argTypes() == asamep->argTypes()) && (ctorInits() == asamep->ctorInits()) && (argTypes() == asamep->argTypes()) && (ctorInits() == asamep->ctorInits())
&& isLoose() == asamep->isLoose() && isLoose() == asamep->isLoose()
@ -8969,7 +8970,7 @@ public:
class AstCMath final : public AstNodeMath { class AstCMath final : public AstNodeMath {
private: private:
bool m_cleanOut; const bool m_cleanOut;
bool m_pure; // Pure optimizable bool m_pure; // Pure optimizable
public: public:
// Emit C textual math function (like AstUCFunc) // Emit C textual math function (like AstUCFunc)

View File

@ -103,7 +103,7 @@ public:
// Get a reference to the user data // Get a reference to the user data
T_Data& operator()(const T_Node* nodep) { T_Data& operator()(const T_Node* nodep) {
T_Data* userp = getUserp(nodep); T_Data* const userp = getUserp(nodep);
UASSERT_OBJ(userp, nodep, "Missing User data on const AstNode"); UASSERT_OBJ(userp, nodep, "Missing User data on const AstNode");
return *userp; return *userp;
} }

View File

@ -61,7 +61,7 @@ private:
// STATE // STATE
BeginState* const m_statep; // Current global state BeginState* const m_statep; // Current global state
AstNodeModule* m_modp = nullptr; // Current module AstNodeModule* m_modp = nullptr; // Current module
AstNodeFTask* m_ftaskp = nullptr; // Current function/task const AstNodeFTask* m_ftaskp = nullptr; // Current function/task
AstNode* m_liftedp = nullptr; // Local nodes we are lifting into m_ftaskp AstNode* m_liftedp = nullptr; // Local nodes we are lifting into m_ftaskp
string m_namedScope; // Name of begin blocks above us string m_namedScope; // Name of begin blocks above us
string m_unnamedScope; // Name of begin blocks, including unnamed blocks string m_unnamedScope; // Name of begin blocks, including unnamed blocks
@ -149,7 +149,7 @@ private:
m_unnamedScope = dot(m_unnamedScope, ident); m_unnamedScope = dot(m_unnamedScope, ident);
// Create CellInline for dotted var resolution // Create CellInline for dotted var resolution
if (!m_ftaskp) { if (!m_ftaskp) {
AstCellInline* inlinep = new AstCellInline( AstCellInline* const inlinep = new AstCellInline(
nodep->fileline(), m_unnamedScope, "__BEGIN__", m_modp->timeunit()); nodep->fileline(), m_unnamedScope, "__BEGIN__", m_modp->timeunit());
m_modp->addInlinesp(inlinep); // Must be parsed before any AstCells m_modp->addInlinesp(inlinep); // Must be parsed before any AstCells
} }
@ -162,7 +162,7 @@ private:
// Cleanup // Cleanup
AstNode* addsp = nullptr; AstNode* addsp = nullptr;
if (AstNode* stmtsp = nodep->stmtsp()) { if (AstNode* const stmtsp = nodep->stmtsp()) {
stmtsp->unlinkFrBackWithNext(); stmtsp->unlinkFrBackWithNext();
if (addsp) { if (addsp) {
addsp = addsp->addNextNull(stmtsp); addsp = addsp->addNextNull(stmtsp);
@ -222,7 +222,7 @@ private:
if (nodep->user1SetOnce()) return; // Don't double-add text's if (nodep->user1SetOnce()) return; // Don't double-add text's
if (m_namedScope != "") { if (m_namedScope != "") {
// To keep correct visual order, must add before other Text's // To keep correct visual order, must add before other Text's
AstNode* afterp = nodep->scopeAttrp(); AstNode* const afterp = nodep->scopeAttrp();
if (afterp) afterp->unlinkFrBackWithNext(); if (afterp) afterp->unlinkFrBackWithNext();
nodep->scopeAttrp(new AstText(nodep->fileline(), string("__DOT__") + m_namedScope)); nodep->scopeAttrp(new AstText(nodep->fileline(), string("__DOT__") + m_namedScope));
if (afterp) nodep->scopeAttrp(afterp); if (afterp) nodep->scopeAttrp(afterp);

View File

@ -343,8 +343,8 @@ void V3Broken::brokenAll(AstNetlist* nodep) {
UINFO(1, "Broken called under broken, skipping recursion.\n"); // LCOV_EXCL_LINE UINFO(1, "Broken called under broken, skipping recursion.\n"); // LCOV_EXCL_LINE
} else { } else {
inBroken = true; inBroken = true;
BrokenMarkVisitor mvisitor{nodep}; const BrokenMarkVisitor mvisitor{nodep};
BrokenCheckVisitor cvisitor{nodep}; const BrokenCheckVisitor cvisitor{nodep};
s_allocTable.checkForLeaks(); s_allocTable.checkForLeaks();
s_linkableTable.clear(); s_linkableTable.clear();
s_brokenCntGlobal.inc(); s_brokenCntGlobal.inc();

View File

@ -39,7 +39,7 @@ public:
enum en : uint8_t { MODULE, CLASS, COVERAGE }; enum en : uint8_t { MODULE, CLASS, COVERAGE };
private: private:
enum en m_e; const enum en m_e;
public: public:
// cppcheck-suppress noExplicitConstructor // cppcheck-suppress noExplicitConstructor
@ -139,7 +139,8 @@ void V3CCtors::evalAsserts() {
for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) { for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) {
if (AstVar* const varp = VN_CAST(np, Var)) { if (AstVar* const varp = VN_CAST(np, Var)) {
if (varp->isPrimaryInish() && !varp->isSc()) { if (varp->isPrimaryInish() && !varp->isSc()) {
if (const AstBasicDType* basicp = VN_CAST(varp->dtypeSkipRefp(), BasicDType)) { if (const AstBasicDType* const basicp
= VN_CAST(varp->dtypeSkipRefp(), BasicDType)) {
const int storedWidth = basicp->widthAlignBytes() * 8; const int storedWidth = basicp->widthAlignBytes() * 8;
const int lastWordWidth = varp->width() % storedWidth; const int lastWordWidth = varp->width() % storedWidth;
if (lastWordWidth != 0) { if (lastWordWidth != 0) {

View File

@ -52,7 +52,7 @@
class CaseLintVisitor final : public AstNVisitor { class CaseLintVisitor final : public AstNVisitor {
private: private:
AstNodeCase* m_caseExprp const AstNodeCase* m_caseExprp
= nullptr; // Under a CASE value node, if so the relevant case statement = nullptr; // Under a CASE value node, if so the relevant case statement
// METHODS // METHODS
@ -127,7 +127,7 @@ private:
// STATE // STATE
VDouble0 m_statCaseFast; // Statistic tracking VDouble0 m_statCaseFast; // Statistic tracking
VDouble0 m_statCaseSlow; // Statistic tracking VDouble0 m_statCaseSlow; // Statistic tracking
AstNode* m_alwaysp = nullptr; // Always in which case is located const AstNode* m_alwaysp = nullptr; // Always in which case is located
// Per-CASE // Per-CASE
int m_caseWidth = 0; // Width of valueItems int m_caseWidth = 0; // Width of valueItems
@ -159,7 +159,7 @@ private:
return false; // Too wide for analysis return false; // Too wide for analysis
} }
UINFO(8, "Simple case statement: " << nodep << endl); UINFO(8, "Simple case statement: " << nodep << endl);
uint32_t numCases = 1UL << m_caseWidth; const uint32_t numCases = 1UL << m_caseWidth;
// Zero list of items for each value // Zero list of items for each value
for (uint32_t i = 0; i < numCases; ++i) m_valueItem[i] = nullptr; for (uint32_t i = 0; i < numCases; ++i) m_valueItem[i] = nullptr;
// Now pick up the values for each assignment // Now pick up the values for each assignment
@ -177,10 +177,10 @@ private:
} else { } else {
V3Number nummask(itemp, iconstp->width()); V3Number nummask(itemp, iconstp->width());
nummask.opBitsNonX(iconstp->num()); nummask.opBitsNonX(iconstp->num());
uint32_t mask = nummask.toUInt(); const uint32_t mask = nummask.toUInt();
V3Number numval(itemp, iconstp->width()); V3Number numval(itemp, iconstp->width());
numval.opBitsOne(iconstp->num()); numval.opBitsOne(iconstp->num());
uint32_t val = numval.toUInt(); const uint32_t val = numval.toUInt();
uint32_t firstOverlap = 0; uint32_t firstOverlap = 0;
bool foundOverlap = false; bool foundOverlap = false;
@ -364,7 +364,7 @@ private:
// For simplicity, make expression that is not equal, and let later // For simplicity, make expression that is not equal, and let later
// optimizations remove it // optimizations remove it
condp = new AstConst(itemp->fileline(), AstConst::BitFalse()); condp = new AstConst(itemp->fileline(), AstConst::BitFalse());
} else if (AstInsideRange* irangep = VN_CAST(icondp, InsideRange)) { } else if (AstInsideRange* const irangep = VN_CAST(icondp, InsideRange)) {
// Similar logic in V3Width::visit(AstInside) // Similar logic in V3Width::visit(AstInside)
condp = irangep->newAndFromInside(cexprp, irangep->lhsp()->unlinkFrBack(), condp = irangep->newAndFromInside(cexprp, irangep->lhsp()->unlinkFrBack(),
irangep->rhsp()->unlinkFrBack()); irangep->rhsp()->unlinkFrBack());

View File

@ -225,7 +225,7 @@ private:
V3Graph m_graph; // Scoreboard of var usages/dependencies V3Graph m_graph; // Scoreboard of var usages/dependencies
CdcLogicVertex* m_logicVertexp = nullptr; // Current statement being tracked, nullptr=ignored CdcLogicVertex* m_logicVertexp = nullptr; // Current statement being tracked, nullptr=ignored
AstScope* m_scopep = nullptr; // Current scope being processed AstScope* m_scopep = nullptr; // Current scope being processed
AstNodeModule* m_modp = nullptr; // Current module const AstNodeModule* m_modp = nullptr; // Current module
AstSenTree* m_domainp = nullptr; // Current sentree AstSenTree* m_domainp = nullptr; // Current sentree
bool m_inDly = false; // In delayed assign bool m_inDly = false; // In delayed assign
int m_inSenItem = 0; // Number of senitems int m_inSenItem = 0; // Number of senitems
@ -337,7 +337,7 @@ private:
int filelineWidth() { int filelineWidth() {
if (!m_filelineWidth) { if (!m_filelineWidth) {
CdcWidthVisitor visitor{v3Global.rootp()}; const CdcWidthVisitor visitor{v3Global.rootp()};
m_filelineWidth = visitor.maxWidth(); m_filelineWidth = visitor.maxWidth();
} }
return m_filelineWidth; return m_filelineWidth;
@ -385,7 +385,7 @@ private:
// Any logic considered bad, at the moment, anyhow // Any logic considered bad, at the moment, anyhow
if (vvertexp->hazard() && !mark_outp) mark_outp = vvertexp; if (vvertexp->hazard() && !mark_outp) mark_outp = vvertexp;
// And keep tracing back so the user can understand what's up // And keep tracing back so the user can understand what's up
} else if (CdcVarVertex* vvertexp = dynamic_cast<CdcVarVertex*>(vertexp)) { } else if (CdcVarVertex* const vvertexp = dynamic_cast<CdcVarVertex*>(vertexp)) {
if (mark) vvertexp->asyncPath(true); if (mark) vvertexp->asyncPath(true);
// If primary I/O, it's ok here back // If primary I/O, it's ok here back
if (vvertexp->varScp()->varp()->isPrimaryInish()) { if (vvertexp->varScp()->varp()->isPrimaryInish()) {
@ -461,7 +461,7 @@ private:
// Dump single variable/logic block // Dump single variable/logic block
// See also OrderGraph::loopsVertexCb(V3GraphVertex* vertexp) // See also OrderGraph::loopsVertexCb(V3GraphVertex* vertexp)
AstNode* const nodep = vertexp->nodep(); AstNode* const nodep = vertexp->nodep();
string front const string front
= pad(filelineWidth(), nodep->fileline()->ascii() + ":") + " " + prefix + " +- "; = pad(filelineWidth(), nodep->fileline()->ascii() + ":") + " " + prefix + " +- ";
if (VN_IS(nodep, VarScope)) { if (VN_IS(nodep, VarScope)) {
*m_ofp << front << "Variable: " << nodep->prettyName() << '\n'; *m_ofp << front << "Variable: " << nodep->prettyName() << '\n';
@ -562,7 +562,7 @@ private:
std::set<AstSenTree*> senouts; // List of all sensitivities for new signal std::set<AstSenTree*> senouts; // List of all sensitivities for new signal
if (const CdcLogicVertex* const vvertexp = dynamic_cast<CdcLogicVertex*>(vertexp)) { if (const CdcLogicVertex* const vvertexp = dynamic_cast<CdcLogicVertex*>(vertexp)) {
if (vvertexp) {} // Unused if (vvertexp) {} // Unused
} else if (CdcVarVertex* vvertexp = dynamic_cast<CdcVarVertex*>(vertexp)) { } else if (const CdcVarVertex* const vvertexp = dynamic_cast<CdcVarVertex*>(vertexp)) {
// If primary I/O, give it domain of the input // If primary I/O, give it domain of the input
const AstVar* const varp = vvertexp->varScp()->varp(); const AstVar* const varp = vvertexp->varScp()->varp();
if (varp->isPrimaryIO() && varp->isNonOutput() && !traceDests) { if (varp->isPrimaryIO() && varp->isNonOutput() && !traceDests) {

View File

@ -154,7 +154,7 @@ private:
// Later code will expand words which adds to GCC compile time, // Later code will expand words which adds to GCC compile time,
// so add penalty based on word width also // so add penalty based on word width also
EmitCBaseCounterVisitor visitor{initp}; const EmitCBaseCounterVisitor visitor{initp};
m_statep->m_numStmts += visitor.count() + m_varEqnp->widthWords(); m_statep->m_numStmts += visitor.count() + m_varEqnp->widthWords();
} }
@ -214,8 +214,8 @@ public:
m_detects = 0; m_detects = 0;
{ {
AstVar* const varp = m_vscp->varp(); AstVar* const varp = m_vscp->varp();
string newvarname{"__Vchglast__" + m_vscp->scopep()->nameDotless() + "__" const string newvarname{"__Vchglast__" + m_vscp->scopep()->nameDotless() + "__"
+ varp->shortName()}; + varp->shortName()};
// Create: VARREF(_last) // Create: VARREF(_last)
// ASSIGN(VARREF(_last), VARREF(var)) // ASSIGN(VARREF(_last), VARREF(var))
// ... // ...
@ -250,7 +250,7 @@ private:
const AstUser1InUse m_inuser1; const AstUser1InUse m_inuser1;
// STATE // STATE
ChangedState* m_statep; // Shared state across visitors ChangedState* const m_statep; // Shared state across visitors
// METHODS // METHODS
VL_DEBUG_FUNC; // Declare debug() VL_DEBUG_FUNC; // Declare debug()

View File

@ -34,9 +34,9 @@ private:
// MEMBERS // MEMBERS
const AstUser1InUse m_inuser1; const AstUser1InUse m_inuser1;
string m_prefix; // String prefix to add to name based on hier string m_prefix; // String prefix to add to name based on hier
AstScope* m_classScopep = nullptr; // Package moving scopes into const AstScope* m_classScopep = nullptr; // Package moving scopes into
AstScope* m_packageScopep = nullptr; // Class package scope AstScope* m_packageScopep = nullptr; // Class package scope
AstNodeFTask* m_ftaskp = nullptr; // Current task const AstNodeFTask* m_ftaskp = nullptr; // Current task
std::vector<std::pair<AstNode*, AstScope*>> m_moves; std::vector<std::pair<AstNode*, AstScope*>> m_moves;
// NODE STATE // NODE STATE
@ -67,7 +67,7 @@ private:
v3Global.rootp()->topModulep()->addStmtp(cellp); v3Global.rootp()->topModulep()->addStmtp(cellp);
// Find class's scope // Find class's scope
// Alternative would be to move this and related to V3Scope // Alternative would be to move this and related to V3Scope
AstScope* classScopep = nullptr; const AstScope* classScopep = nullptr;
for (AstNode* itp = nodep->stmtsp(); itp; itp = itp->nextp()) { for (AstNode* itp = nodep->stmtsp(); itp; itp = itp->nextp()) {
if ((classScopep = VN_CAST(itp, Scope))) break; if ((classScopep = VN_CAST(itp, Scope))) break;
} }

View File

@ -50,7 +50,7 @@ private:
enum CleanState : uint8_t { CS_UNKNOWN, CS_CLEAN, CS_DIRTY }; enum CleanState : uint8_t { CS_UNKNOWN, CS_CLEAN, CS_DIRTY };
// STATE // STATE
AstNodeModule* m_modp = nullptr; const AstNodeModule* m_modp = nullptr;
// METHODS // METHODS
VL_DEBUG_FUNC; // Declare debug() VL_DEBUG_FUNC; // Declare debug()

View File

@ -77,7 +77,7 @@ private:
// STATE // STATE
AstNodeModule* m_modp = nullptr; // Current module AstNodeModule* m_modp = nullptr; // Current module
AstTopScope* m_topScopep = nullptr; // Current top scope const AstTopScope* m_topScopep = nullptr; // Current top scope
AstScope* m_scopep = nullptr; // Current scope AstScope* m_scopep = nullptr; // Current scope
AstCFunc* m_evalFuncp = nullptr; // Top eval function we are creating AstCFunc* m_evalFuncp = nullptr; // Top eval function we are creating
AstCFunc* m_initFuncp = nullptr; // Top initial function we are creating AstCFunc* m_initFuncp = nullptr; // Top initial function we are creating
@ -97,7 +97,7 @@ private:
varp->v3warn(E_UNSUPPORTED, "Unsupported: Clock edge on non-single bit signal: " varp->v3warn(E_UNSUPPORTED, "Unsupported: Clock edge on non-single bit signal: "
<< varp->prettyNameQ()); << varp->prettyNameQ());
} }
string newvarname const string newvarname
= (string("__Vclklast__") + vscp->scopep()->nameDotless() + "__" + varp->name()); = (string("__Vclklast__") + vscp->scopep()->nameDotless() + "__" + varp->name());
AstVar* const newvarp = new AstVar(vscp->fileline(), AstVarType::MODULETEMP, newvarname, AstVar* const newvarp = new AstVar(vscp->fileline(), AstVarType::MODULETEMP, newvarname,
VFlagLogicPacked(), 1); VFlagLogicPacked(), 1);
@ -184,9 +184,9 @@ private:
return senEqnp; return senEqnp;
} }
AstIf* makeActiveIf(AstSenTree* sensesp) { AstIf* makeActiveIf(AstSenTree* sensesp) {
AstNode* senEqnp = createSenseEquation(sensesp->sensesp()); AstNode* const senEqnp = createSenseEquation(sensesp->sensesp());
UASSERT_OBJ(senEqnp, sensesp, "No sense equation, shouldn't be in sequent activation."); UASSERT_OBJ(senEqnp, sensesp, "No sense equation, shouldn't be in sequent activation.");
AstIf* newifp = new AstIf(sensesp->fileline(), senEqnp, nullptr, nullptr); AstIf* const newifp = new AstIf(sensesp->fileline(), senEqnp, nullptr, nullptr);
return newifp; return newifp;
} }
void clearLastSen() { void clearLastSen() {
@ -215,11 +215,11 @@ private:
AstCFunc* funcp = nullptr; AstCFunc* funcp = nullptr;
// Unlink all statements, then add item by item to new sub-functions // Unlink all statements, then add item by item to new sub-functions
AstBegin* tempp = new AstBegin{ofuncp->fileline(), "[EditWrapper]", AstBegin* const tempp = new AstBegin{ofuncp->fileline(), "[EditWrapper]",
ofuncp->stmtsp()->unlinkFrBackWithNext()}; ofuncp->stmtsp()->unlinkFrBackWithNext()};
if (ofuncp->finalsp()) tempp->addStmtsp(ofuncp->finalsp()->unlinkFrBackWithNext()); if (ofuncp->finalsp()) tempp->addStmtsp(ofuncp->finalsp()->unlinkFrBackWithNext());
while (tempp->stmtsp()) { while (tempp->stmtsp()) {
AstNode* itemp = tempp->stmtsp()->unlinkFrBack(); AstNode* const itemp = tempp->stmtsp()->unlinkFrBack();
const int stmts = EmitCBaseCounterVisitor(itemp).count(); const int stmts = EmitCBaseCounterVisitor(itemp).count();
if (!funcp || (func_stmts + stmts) > v3Global.opt.outputSplitCFuncs()) { if (!funcp || (func_stmts + stmts) > v3Global.opt.outputSplitCFuncs()) {
// Make a new function // Make a new function
@ -231,7 +231,7 @@ private:
funcp->slow(ofuncp->slow()); funcp->slow(ofuncp->slow());
m_topScopep->scopep()->addActivep(funcp); m_topScopep->scopep()->addActivep(funcp);
// //
AstCCall* callp = new AstCCall{funcp->fileline(), funcp}; AstCCall* const callp = new AstCCall{funcp->fileline(), funcp};
ofuncp->addStmtsp(callp); ofuncp->addStmtsp(callp);
func_stmts = 0; func_stmts = 0;
} }
@ -289,7 +289,7 @@ private:
// UINFO(4, " SCOPE " << nodep << endl); // UINFO(4, " SCOPE " << nodep << endl);
m_scopep = nodep; m_scopep = nodep;
iterateChildren(nodep); iterateChildren(nodep);
if (AstNode* movep = nodep->finalClksp()) { if (AstNode* const movep = nodep->finalClksp()) {
UASSERT_OBJ(m_topScopep, nodep, "Final clocks under non-top scope"); UASSERT_OBJ(m_topScopep, nodep, "Final clocks under non-top scope");
movep->unlinkFrBackWithNext(); movep->unlinkFrBackWithNext();
m_evalFuncp->addFinalsp(movep); m_evalFuncp->addFinalsp(movep);
@ -297,7 +297,7 @@ private:
m_scopep = nullptr; m_scopep = nullptr;
} }
virtual void visit(AstNodeProcedure* nodep) override { virtual void visit(AstNodeProcedure* nodep) override {
if (AstNode* stmtsp = nodep->bodysp()) { if (AstNode* const stmtsp = nodep->bodysp()) {
stmtsp->unlinkFrBackWithNext(); stmtsp->unlinkFrBackWithNext();
nodep->addNextHere(stmtsp); nodep->addNextHere(stmtsp);
} }
@ -307,12 +307,12 @@ private:
// nodep->dumpTree(cout, "ct:"); // nodep->dumpTree(cout, "ct:");
// COVERTOGGLE(INC, ORIG, CHANGE) -> // COVERTOGGLE(INC, ORIG, CHANGE) ->
// IF(ORIG ^ CHANGE) { INC; CHANGE = ORIG; } // IF(ORIG ^ CHANGE) { INC; CHANGE = ORIG; }
AstNode* incp = nodep->incp()->unlinkFrBack(); AstNode* const incp = nodep->incp()->unlinkFrBack();
AstNode* origp = nodep->origp()->unlinkFrBack(); AstNode* const origp = nodep->origp()->unlinkFrBack();
AstNode* changeWrp = nodep->changep()->unlinkFrBack(); AstNode* const changeWrp = nodep->changep()->unlinkFrBack();
AstNode* changeRdp = ConvertWriteRefsToRead::main(changeWrp->cloneTree(false)); AstNode* const changeRdp = ConvertWriteRefsToRead::main(changeWrp->cloneTree(false));
AstIf* newp = new AstIf(nodep->fileline(), new AstXor(nodep->fileline(), origp, changeRdp), AstIf* const newp = new AstIf(
incp, nullptr); nodep->fileline(), new AstXor(nodep->fileline(), origp, changeRdp), incp, nullptr);
// We could add another IF to detect posedges, and only increment if so. // We could add another IF to detect posedges, and only increment if so.
// It's another whole branch though versus a potential memory miss. // It's another whole branch though versus a potential memory miss.
// We'll go with the miss. // We'll go with the miss.
@ -325,7 +325,7 @@ private:
// Link to global function // Link to global function
if (nodep->formCallTree()) { if (nodep->formCallTree()) {
UINFO(4, " formCallTree " << nodep << endl); UINFO(4, " formCallTree " << nodep << endl);
AstCCall* callp = new AstCCall(nodep->fileline(), nodep); AstCCall* const callp = new AstCCall(nodep->fileline(), nodep);
m_finalFuncp->addStmtsp(callp); m_finalFuncp->addStmtsp(callp);
} }
} }
@ -353,7 +353,7 @@ private:
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
} else if (m_mtaskBodyp) { } else if (m_mtaskBodyp) {
UINFO(4, " TR ACTIVE " << nodep << endl); UINFO(4, " TR ACTIVE " << nodep << endl);
AstNode* stmtsp = nodep->stmtsp()->unlinkFrBackWithNext(); AstNode* const stmtsp = nodep->stmtsp()->unlinkFrBackWithNext();
if (nodep->hasClocked()) { if (nodep->hasClocked()) {
UASSERT_OBJ(!nodep->hasInitial(), nodep, UASSERT_OBJ(!nodep->hasInitial(), nodep,
"Initial block should not have clock sensitivity"); "Initial block should not have clock sensitivity");
@ -378,7 +378,7 @@ private:
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
} else { } else {
UINFO(4, " ACTIVE " << nodep << endl); UINFO(4, " ACTIVE " << nodep << endl);
AstNode* stmtsp = nodep->stmtsp()->unlinkFrBackWithNext(); AstNode* const stmtsp = nodep->stmtsp()->unlinkFrBackWithNext();
if (nodep->hasClocked()) { if (nodep->hasClocked()) {
// Remember the latest sensitivity so we can compare it next time // Remember the latest sensitivity so we can compare it next time
UASSERT_OBJ(!nodep->hasInitial(), nodep, UASSERT_OBJ(!nodep->hasInitial(), nodep,

View File

@ -190,7 +190,7 @@ public:
void apply(AstNodeModule* modp) { void apply(AstNodeModule* modp) {
if (m_inline) { if (m_inline) {
AstPragmaType type const AstPragmaType type
= m_inlineValue ? AstPragmaType::INLINE_MODULE : AstPragmaType::NO_INLINE_MODULE; = m_inlineValue ? AstPragmaType::INLINE_MODULE : AstPragmaType::NO_INLINE_MODULE;
AstNode* const nodep = new AstPragma(modp->fileline(), type); AstNode* const nodep = new AstPragma(modp->fileline(), type);
modp->addStmtp(nodep); modp->addStmtp(nodep);
@ -223,9 +223,9 @@ using V3ConfigModuleResolver = V3ConfigWildcardResolver<V3ConfigModule>;
// lint/coverage/tracing on/off // lint/coverage/tracing on/off
class V3ConfigIgnoresLine final { class V3ConfigIgnoresLine final {
public: public:
int m_lineno; // Line number to make change at const int m_lineno; // Line number to make change at
V3ErrorCode m_code; // Error code const V3ErrorCode m_code; // Error code
bool m_on; // True to enable message const bool m_on; // True to enable message
V3ConfigIgnoresLine(V3ErrorCode code, int lineno, bool on) V3ConfigIgnoresLine(V3ErrorCode code, int lineno, bool on)
: m_lineno{lineno} : m_lineno{lineno}
, m_code{code} , m_code{code}
@ -502,7 +502,7 @@ void V3Config::applyFTask(AstNodeModule* modulep, AstNodeFTask* ftaskp) {
const string& modname = modulep->name(); const string& modname = modulep->name();
V3ConfigModule* modp = V3ConfigResolver::s().modules().resolve(modname); V3ConfigModule* modp = V3ConfigResolver::s().modules().resolve(modname);
if (!modp) return; if (!modp) return;
V3ConfigFTask* ftp = modp->ftasks().resolve(ftaskp->name()); const V3ConfigFTask* const ftp = modp->ftasks().resolve(ftaskp->name());
if (ftp) ftp->apply(ftaskp); if (ftp) ftp->apply(ftaskp);
} }

File diff suppressed because it is too large Load Diff

View File

@ -43,7 +43,7 @@ private:
using LinenoSet = std::set<int>; using LinenoSet = std::set<int>;
struct ToggleEnt { struct ToggleEnt {
string m_comment; // Comment for coverage dump const string m_comment; // Comment for coverage dump
AstNode* m_varRefp; // How to get to this element AstNode* m_varRefp; // How to get to this element
AstNode* m_chgRefp; // How to get to this element AstNode* m_chgRefp; // How to get to this element
ToggleEnt(const string& comment, AstNode* vp, AstNode* cp) ToggleEnt(const string& comment, AstNode* vp, AstNode* cp)
@ -209,7 +209,7 @@ private:
// VISITORS - BOTH // VISITORS - BOTH
virtual void visit(AstNodeModule* nodep) override { virtual void visit(AstNodeModule* nodep) override {
AstNodeModule* const origModp = m_modp; const AstNodeModule* const origModp = m_modp;
VL_RESTORER(m_modp); VL_RESTORER(m_modp);
VL_RESTORER(m_state); VL_RESTORER(m_state);
{ {
@ -245,9 +245,9 @@ private:
linesCov(m_state, nodep), 0, traceNameForLine(nodep, "block")); linesCov(m_state, nodep), 0, traceNameForLine(nodep, "block"));
if (AstNodeProcedure* const itemp = VN_CAST(nodep, NodeProcedure)) { if (AstNodeProcedure* const itemp = VN_CAST(nodep, NodeProcedure)) {
itemp->addStmtp(newp); itemp->addStmtp(newp);
} else if (AstNodeFTask* itemp = VN_CAST(nodep, NodeFTask)) { } else if (AstNodeFTask* const itemp = VN_CAST(nodep, NodeFTask)) {
itemp->addStmtsp(newp); itemp->addStmtsp(newp);
} else if (AstWhile* itemp = VN_CAST(nodep, While)) { } else if (AstWhile* const itemp = VN_CAST(nodep, While)) {
itemp->addBodysp(newp); itemp->addBodysp(newp);
} else { } else {
nodep->v3fatalSrc("Bad node type"); nodep->v3fatalSrc("Bad node type");
@ -324,7 +324,7 @@ private:
} else { } else {
toggleVarBottom(above, varp); toggleVarBottom(above, varp);
} }
} else if (AstUnpackArrayDType* adtypep = VN_CAST(dtypep, UnpackArrayDType)) { } else if (const AstUnpackArrayDType* const adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
for (int index_docs = adtypep->lo(); index_docs <= adtypep->hi(); ++index_docs) { for (int index_docs = adtypep->lo(); index_docs <= adtypep->hi(); ++index_docs) {
const int index_code = index_docs - adtypep->lo(); const int index_code = index_docs - adtypep->lo();
ToggleEnt newent(above.m_comment + string("[") + cvtToStr(index_docs) + "]", ToggleEnt newent(above.m_comment + string("[") + cvtToStr(index_docs) + "]",
@ -336,9 +336,9 @@ private:
chgVarp); chgVarp);
newent.cleanup(); newent.cleanup();
} }
} else if (AstPackArrayDType* adtypep = VN_CAST(dtypep, PackArrayDType)) { } else if (const AstPackArrayDType* const adtypep = VN_CAST(dtypep, PackArrayDType)) {
for (int index_docs = adtypep->lo(); index_docs <= adtypep->hi(); ++index_docs) { for (int index_docs = adtypep->lo(); index_docs <= adtypep->hi(); ++index_docs) {
AstNodeDType* const subtypep = adtypep->subDTypep()->skipRefp(); const AstNodeDType* const subtypep = adtypep->subDTypep()->skipRefp();
const int index_code = index_docs - adtypep->lo(); const int index_code = index_docs - adtypep->lo();
ToggleEnt newent(above.m_comment + string("[") + cvtToStr(index_docs) + "]", ToggleEnt newent(above.m_comment + string("[") + cvtToStr(index_docs) + "]",
new AstSel(varp->fileline(), above.m_varRefp->cloneTree(true), new AstSel(varp->fileline(), above.m_varRefp->cloneTree(true),
@ -349,7 +349,7 @@ private:
chgVarp); chgVarp);
newent.cleanup(); newent.cleanup();
} }
} else if (AstStructDType* adtypep = VN_CAST(dtypep, StructDType)) { } else if (const AstStructDType* const adtypep = VN_CAST(dtypep, StructDType)) {
// For now it's packed, so similar to array // For now it's packed, so similar to array
for (AstMemberDType* itemp = adtypep->membersp(); itemp; for (AstMemberDType* itemp = adtypep->membersp(); itemp;
itemp = VN_AS(itemp->nextp(), MemberDType)) { itemp = VN_AS(itemp->nextp(), MemberDType)) {
@ -363,9 +363,9 @@ private:
toggleVarRecurse(subtypep, depth + 1, newent, varp, chgVarp); toggleVarRecurse(subtypep, depth + 1, newent, varp, chgVarp);
newent.cleanup(); newent.cleanup();
} }
} else if (AstUnionDType* adtypep = VN_CAST(dtypep, UnionDType)) { } else if (const AstUnionDType* const adtypep = VN_CAST(dtypep, UnionDType)) {
// Arbitrarily handle only the first member of the union // Arbitrarily handle only the first member of the union
if (AstMemberDType* const itemp = adtypep->membersp()) { if (const AstMemberDType* const itemp = adtypep->membersp()) {
AstNodeDType* const subtypep = itemp->subDTypep()->skipRefp(); AstNodeDType* const subtypep = itemp->subDTypep()->skipRefp();
ToggleEnt newent(above.m_comment + string(".") + itemp->name(), ToggleEnt newent(above.m_comment + string(".") + itemp->name(),
above.m_varRefp->cloneTree(true), above.m_varRefp->cloneTree(true),

View File

@ -382,7 +382,7 @@ private:
for (AstVarScope* vscp : m_vscsp) { for (AstVarScope* vscp : m_vscsp) {
if (vscp->user1() == 0) { if (vscp->user1() == 0) {
UINFO(4, " Dead " << vscp << endl); UINFO(4, " Dead " << vscp << endl);
std::pair<AssignMap::iterator, AssignMap::iterator> eqrange const std::pair<AssignMap::iterator, AssignMap::iterator> eqrange
= m_assignMap.equal_range(vscp); = m_assignMap.equal_range(vscp);
for (AssignMap::iterator itr = eqrange.first; itr != eqrange.second; ++itr) { for (AssignMap::iterator itr = eqrange.first; itr != eqrange.second; ++itr) {
AstNodeAssign* const assp = itr->second; AstNodeAssign* const assp = itr->second;

View File

@ -89,7 +89,7 @@ private:
// STATE // STATE
AstActive* m_activep = nullptr; // Current activate AstActive* m_activep = nullptr; // Current activate
AstCFunc* m_cfuncp = nullptr; // Current public C Function const AstCFunc* m_cfuncp = nullptr; // Current public C Function
AstAssignDly* m_nextDlyp = nullptr; // Next delayed assignment in a list of assignments AstAssignDly* m_nextDlyp = nullptr; // Next delayed assignment in a list of assignments
bool m_inDly = false; // True in delayed assignments bool m_inDly = false; // True in delayed assignments
bool m_inLoop = false; // True in for loops bool m_inLoop = false; // True in for loops
@ -106,7 +106,7 @@ private:
if (blocking) nodep->user5(true); if (blocking) nodep->user5(true);
AstVarScope* const vscp = nodep->varScopep(); AstVarScope* const vscp = nodep->varScopep();
// UINFO(4, " MVU " << blocking << " " << nodep << endl); // UINFO(4, " MVU " << blocking << " " << nodep << endl);
AstNode* const lastrefp = vscp->user5p(); const AstNode* const lastrefp = vscp->user5p();
if (!lastrefp) { if (!lastrefp) {
vscp->user5p(nodep); vscp->user5p(nodep);
} else { } else {
@ -275,7 +275,7 @@ private:
// vval = constant, can just push constant into where we use it // vval = constant, can just push constant into where we use it
valreadp = nodep->rhsp()->unlinkFrBack(); valreadp = nodep->rhsp()->unlinkFrBack();
} else { } else {
string valvarname const string valvarname
= (string("__Vdlyvval__") + oldvarp->shortName() + "__v" + cvtToStr(modVecNum)); = (string("__Vdlyvval__") + oldvarp->shortName() + "__v" + cvtToStr(modVecNum));
AstVarScope* const valvscp AstVarScope* const valvscp
= createVarSc(varrefp->varScopep(), valvarname, 0, nodep->rhsp()->dtypep()); = createVarSc(varrefp->varScopep(), valvarname, 0, nodep->rhsp()->dtypep());
@ -295,7 +295,7 @@ private:
setvscp = VN_AS(nodep->user3p(), VarScope); setvscp = VN_AS(nodep->user3p(), VarScope);
++m_statSharedSet; ++m_statSharedSet;
} else { // Create new one } else { // Create new one
string setvarname const string setvarname
= (string("__Vdlyvset__") + oldvarp->shortName() + "__v" + cvtToStr(modVecNum)); = (string("__Vdlyvset__") + oldvarp->shortName() + "__v" + cvtToStr(modVecNum));
setvscp = createVarSc(varrefp->varScopep(), setvarname, 1, nullptr); setvscp = createVarSc(varrefp->varScopep(), setvarname, 1, nullptr);
setinitp = new AstAssignPre(nodep->fileline(), setinitp = new AstAssignPre(nodep->fileline(),

View File

@ -37,8 +37,8 @@ private:
// NODE STATE // NODE STATE
// STATE // STATE
AstNodeModule* m_modp = nullptr; // Current module const AstNodeModule* m_modp = nullptr; // Current module
AstCFunc* m_cfuncp = nullptr; // Current function const AstCFunc* m_cfuncp = nullptr; // Current function
int m_depth = 0; // How deep in an expression int m_depth = 0; // How deep in an expression
int m_deepNum = 0; // How many functions made int m_deepNum = 0; // How many functions made
@ -94,9 +94,9 @@ private:
if (m_depth > v3Global.opt.compLimitBlocks() if (m_depth > v3Global.opt.compLimitBlocks()
&& !VN_IS(nodep, NodeCCall)) { // Already done && !VN_IS(nodep, NodeCCall)) { // Already done
UINFO(4, "DeepBlocks " << m_depth << " " << nodep << endl); UINFO(4, "DeepBlocks " << m_depth << " " << nodep << endl);
const AstNode* backp = nodep->backp(); // Only for debug const AstNode* const backp = nodep->backp(); // Only for debug
if (debug() >= 9) backp->dumpTree(cout, "- pre : "); if (debug() >= 9) backp->dumpTree(cout, "- pre : ");
AstCFunc* funcp = createDeepFunc(nodep); AstCFunc* const funcp = createDeepFunc(nodep);
iterate(funcp); iterate(funcp);
if (debug() >= 9) backp->dumpTree(cout, "- post: "); if (debug() >= 9) backp->dumpTree(cout, "- post: ");
if (debug() >= 9) funcp->dumpTree(cout, "- func: "); if (debug() >= 9) funcp->dumpTree(cout, "- func: ");

View File

@ -110,7 +110,7 @@ private:
AstCFunc* const topFuncp = it->second; AstCFunc* const topFuncp = it->second;
auto nextIt1 = it; auto nextIt1 = it;
++nextIt1; ++nextIt1;
bool moreOfSame1 = (nextIt1 != m_modFuncs.end() && nextIt1->first == name); const bool moreOfSame1 = (nextIt1 != m_modFuncs.end() && nextIt1->first == name);
if (moreOfSame1) { if (moreOfSame1) {
// Multiple functions under this name, need a wrapper function // Multiple functions under this name, need a wrapper function
UINFO(6, " Wrapping " << name << " multifuncs\n"); UINFO(6, " Wrapping " << name << " multifuncs\n");

View File

@ -220,7 +220,7 @@ void EmitCBaseVisitor::emitVarDecl(const AstVar* nodep, bool asRef) {
void EmitCBaseVisitor::emitModCUse(const AstNodeModule* modp, VUseType useType) { void EmitCBaseVisitor::emitModCUse(const AstNodeModule* modp, VUseType useType) {
string nl; string nl;
for (AstNode* itemp = modp->stmtsp(); itemp; itemp = itemp->nextp()) { for (AstNode* itemp = modp->stmtsp(); itemp; itemp = itemp->nextp()) {
if (AstCUse* usep = VN_CAST(itemp, CUse)) { if (AstCUse* const usep = VN_CAST(itemp, CUse)) {
if (usep->useType() == useType) { if (usep->useType() == useType) {
if (usep->useType().isInclude()) { if (usep->useType().isInclude()) {
puts("#include \"" + prefixNameProtect(usep) + ".h\"\n"); puts("#include \"" + prefixNameProtect(usep) + ".h\"\n");
@ -238,7 +238,7 @@ void EmitCBaseVisitor::emitModCUse(const AstNodeModule* modp, VUseType useType)
void EmitCBaseVisitor::emitTextSection(const AstNodeModule* modp, AstType type) { void EmitCBaseVisitor::emitTextSection(const AstNodeModule* modp, AstType type) {
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()) {
if (const AstNodeText* textp = VN_CAST(nodep, NodeText)) { if (const AstNodeText* const textp = VN_CAST(nodep, NodeText)) {
if (nodep->type() == type) { if (nodep->type() == type) {
if (last_line != nodep->fileline()->lineno()) { if (last_line != nodep->fileline()->lineno()) {
if (last_line < 0) { if (last_line < 0) {

View File

@ -72,7 +72,7 @@ protected:
virtual void visit(AstConst* nodep) override { virtual void visit(AstConst* nodep) override {
const V3Number& num = nodep->num(); const V3Number& num = nodep->num();
UASSERT_OBJ(!num.isFourState(), nodep, "4-state value in constant pool"); UASSERT_OBJ(!num.isFourState(), nodep, "4-state value in constant pool");
AstNodeDType* const dtypep = nodep->dtypep(); const AstNodeDType* const dtypep = nodep->dtypep();
if (num.isString()) { if (num.isString()) {
// Note: putsQuoted does not track indentation, so we use this instead // Note: putsQuoted does not track indentation, so we use this instead
puts("\""); puts("\"");

View File

@ -202,7 +202,7 @@ void EmitCFunc::displayEmit(AstNode* nodep, bool isScan) {
puts("VL_FSCANF_IX("); puts("VL_FSCANF_IX(");
iterate(dispp->filep()); iterate(dispp->filep());
puts(","); puts(",");
} else if (const AstSScanF* dispp = VN_CAST(nodep, SScanF)) { } else if (const AstSScanF* const dispp = VN_CAST(nodep, SScanF)) {
isStmt = false; isStmt = false;
checkMaxWords(dispp->fromp()); checkMaxWords(dispp->fromp());
puts("VL_SSCANF_I"); puts("VL_SSCANF_I");
@ -212,7 +212,7 @@ void EmitCFunc::displayEmit(AstNode* nodep, bool isScan) {
puts(","); puts(",");
iterate(dispp->fromp()); iterate(dispp->fromp());
puts(","); puts(",");
} else if (const AstDisplay* dispp = VN_CAST(nodep, Display)) { } else if (const AstDisplay* const dispp = VN_CAST(nodep, Display)) {
isStmt = true; isStmt = true;
if (dispp->filep()) { if (dispp->filep()) {
puts("VL_FWRITEF("); puts("VL_FWRITEF(");
@ -221,7 +221,7 @@ void EmitCFunc::displayEmit(AstNode* nodep, bool isScan) {
} else { } else {
puts("VL_WRITEF("); puts("VL_WRITEF(");
} }
} else if (const AstSFormat* dispp = VN_CAST(nodep, SFormat)) { } else if (const AstSFormat* const dispp = VN_CAST(nodep, SFormat)) {
isStmt = true; isStmt = true;
puts("VL_SFORMAT_X("); puts("VL_SFORMAT_X(");
puts(cvtToStr(dispp->lhsp()->widthMin())); puts(cvtToStr(dispp->lhsp()->widthMin()));
@ -315,13 +315,14 @@ void EmitCFunc::displayArg(AstNode* dispp, AstNode** elistp, bool isScan, const
} }
emitDispState.pushArg(fmtLetter, argp, ""); emitDispState.pushArg(fmtLetter, argp, "");
if (fmtLetter == 't' || fmtLetter == '^') { if (fmtLetter == 't' || fmtLetter == '^') {
AstSFormatF* fmtp = nullptr; const AstSFormatF* fmtp = nullptr;
if (AstDisplay* const nodep = VN_CAST(dispp, Display)) if (const AstDisplay* const nodep = VN_CAST(dispp, Display)) {
fmtp = nodep->fmtp(); fmtp = nodep->fmtp();
else if (AstSFormat* nodep = VN_CAST(dispp, SFormat)) } else if (const AstSFormat* const nodep = VN_CAST(dispp, SFormat)) {
fmtp = nodep->fmtp(); fmtp = nodep->fmtp();
else } else {
fmtp = VN_CAST(dispp, SFormatF); fmtp = VN_CAST(dispp, SFormatF);
}
UASSERT_OBJ(fmtp, dispp, UASSERT_OBJ(fmtp, dispp,
"Use of %t must be under AstDisplay, AstSFormat, or AstSFormatF"); "Use of %t must be under AstDisplay, AstSFormat, or AstSFormatF");
UASSERT_OBJ(!fmtp->timeunit().isNone(), fmtp, "timenunit must be set"); UASSERT_OBJ(!fmtp->timeunit().isNone(), fmtp, "timenunit must be set");
@ -580,14 +581,14 @@ void EmitCFunc::emitConstant(AstConst* nodep, AstVarRef* assigntop, const string
ofp()->printf("%.17e", nodep->num().toDouble()); ofp()->printf("%.17e", nodep->num().toDouble());
} }
} else if (nodep->isQuad()) { } else if (nodep->isQuad()) {
vluint64_t num = nodep->toUQuad(); const vluint64_t num = nodep->toUQuad();
if (num < 10) { if (num < 10) {
ofp()->printf("%" VL_PRI64 "uULL", num); ofp()->printf("%" VL_PRI64 "uULL", num);
} else { } else {
ofp()->printf("0x%" VL_PRI64 "xULL", num); ofp()->printf("0x%" VL_PRI64 "xULL", num);
} }
} else { } else {
uint32_t num = nodep->toUInt(); const uint32_t num = nodep->toUInt();
// Only 32 bits - llx + long long here just to appease CPP format warning // Only 32 bits - llx + long long here just to appease CPP format warning
if (num < 10) { if (num < 10) {
puts(cvtToStr(num)); puts(cvtToStr(num));
@ -620,8 +621,8 @@ void EmitCFunc::emitVarReset(AstVar* varp) {
// If a simple CONST value we initialize it using an enum // If a simple CONST value we initialize it using an enum
// If an ARRAYINIT we initialize it using an initial block similar to a signal // If an ARRAYINIT we initialize it using an initial block similar to a signal
// puts("// parameter "+varp->nameProtect()+" = "+varp->valuep()->name()+"\n"); // puts("// parameter "+varp->nameProtect()+" = "+varp->valuep()->name()+"\n");
} else if (AstInitArray* initarp = VN_CAST(varp->valuep(), InitArray)) { } else if (const AstInitArray* const initarp = VN_CAST(varp->valuep(), InitArray)) {
if (AstUnpackArrayDType* adtypep = VN_CAST(dtypep, UnpackArrayDType)) { if (AstUnpackArrayDType* const adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
if (initarp->defaultp()) { if (initarp->defaultp()) {
puts("for (int __Vi=0; __Vi<" + cvtToStr(adtypep->elementsConst())); puts("for (int __Vi=0; __Vi<" + cvtToStr(adtypep->elementsConst()));
puts("; ++__Vi) {\n"); puts("; ++__Vi) {\n");
@ -630,7 +631,7 @@ void EmitCFunc::emitVarReset(AstVar* varp) {
} }
const AstInitArray::KeyItemMap& mapr = initarp->map(); const AstInitArray::KeyItemMap& mapr = initarp->map();
for (const auto& itr : mapr) { for (const auto& itr : mapr) {
AstNode* valuep = itr.second->valuep(); AstNode* const valuep = itr.second->valuep();
emitSetVarConstant(varNameProtected + "[" + cvtToStr(itr.first) + "]", emitSetVarConstant(varNameProtected + "[" + cvtToStr(itr.first) + "]",
VN_AS(valuep, Const)); VN_AS(valuep, Const));
} }
@ -645,26 +646,26 @@ void EmitCFunc::emitVarReset(AstVar* varp) {
string EmitCFunc::emitVarResetRecurse(const AstVar* varp, const string& varNameProtected, string EmitCFunc::emitVarResetRecurse(const AstVar* varp, const string& varNameProtected,
AstNodeDType* dtypep, int depth, const string& suffix) { AstNodeDType* dtypep, int depth, const string& suffix) {
dtypep = dtypep->skipRefp(); dtypep = dtypep->skipRefp();
AstBasicDType* basicp = dtypep->basicp(); AstBasicDType* const basicp = dtypep->basicp();
// Returns string to do resetting, empty to do nothing (which caller should handle) // Returns string to do resetting, empty to do nothing (which caller should handle)
if (AstAssocArrayDType* adtypep = VN_CAST(dtypep, AssocArrayDType)) { if (AstAssocArrayDType* const adtypep = VN_CAST(dtypep, AssocArrayDType)) {
// Access std::array as C array // Access std::array as C array
const string cvtarray = (adtypep->subDTypep()->isWide() ? ".data()" : ""); const string cvtarray = (adtypep->subDTypep()->isWide() ? ".data()" : "");
return emitVarResetRecurse(varp, varNameProtected, adtypep->subDTypep(), depth + 1, return emitVarResetRecurse(varp, varNameProtected, adtypep->subDTypep(), depth + 1,
suffix + ".atDefault()" + cvtarray); suffix + ".atDefault()" + cvtarray);
} else if (VN_IS(dtypep, ClassRefDType)) { } else if (VN_IS(dtypep, ClassRefDType)) {
return ""; // Constructor does it return ""; // Constructor does it
} else if (AstDynArrayDType* adtypep = VN_CAST(dtypep, DynArrayDType)) { } else if (const AstDynArrayDType* const adtypep = VN_CAST(dtypep, DynArrayDType)) {
// Access std::array as C array // Access std::array as C array
const string cvtarray = (adtypep->subDTypep()->isWide() ? ".data()" : ""); const string cvtarray = (adtypep->subDTypep()->isWide() ? ".data()" : "");
return emitVarResetRecurse(varp, varNameProtected, adtypep->subDTypep(), depth + 1, return emitVarResetRecurse(varp, varNameProtected, adtypep->subDTypep(), depth + 1,
suffix + ".atDefault()" + cvtarray); suffix + ".atDefault()" + cvtarray);
} else if (AstQueueDType* adtypep = VN_CAST(dtypep, QueueDType)) { } else if (const AstQueueDType* const adtypep = VN_CAST(dtypep, QueueDType)) {
// Access std::array as C array // Access std::array as C array
const string cvtarray = (adtypep->subDTypep()->isWide() ? ".data()" : ""); const string cvtarray = (adtypep->subDTypep()->isWide() ? ".data()" : "");
return emitVarResetRecurse(varp, varNameProtected, adtypep->subDTypep(), depth + 1, return emitVarResetRecurse(varp, varNameProtected, adtypep->subDTypep(), depth + 1,
suffix + ".atDefault()" + cvtarray); suffix + ".atDefault()" + cvtarray);
} else if (AstUnpackArrayDType* adtypep = VN_CAST(dtypep, UnpackArrayDType)) { } else if (const AstUnpackArrayDType* const adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
UASSERT_OBJ(adtypep->hi() >= adtypep->lo(), varp, UASSERT_OBJ(adtypep->hi() >= adtypep->lo(), varp,
"Should have swapped msb & lsb earlier."); "Should have swapped msb & lsb earlier.");
const string ivar = string("__Vi") + cvtToStr(depth); const string ivar = string("__Vi") + cvtToStr(depth);
@ -678,7 +679,7 @@ string EmitCFunc::emitVarResetRecurse(const AstVar* varp, const string& varNameP
// String's constructor deals with it // String's constructor deals with it
return ""; return "";
} else if (basicp) { } else if (basicp) {
bool zeroit const bool zeroit
= (varp->attrFileDescr() // Zero so we don't do file IO if never $fopen = (varp->attrFileDescr() // Zero so we don't do file IO if never $fopen
|| (basicp && basicp->isZeroInit()) || (basicp && basicp->isZeroInit())
|| (v3Global.opt.underlineZero() && !varp->name().empty() && varp->name()[0] == '_') || (v3Global.opt.underlineZero() && !varp->name().empty() && varp->name()[0] == '_')
@ -687,7 +688,7 @@ string EmitCFunc::emitVarResetRecurse(const AstVar* varp, const string& varNameP
if (dtypep->isWide()) { // Handle unpacked; not basicp->isWide if (dtypep->isWide()) { // Handle unpacked; not basicp->isWide
string out; string out;
if (varp->valuep()) { if (varp->valuep()) {
AstConst* const constp = VN_AS(varp->valuep(), Const); const AstConst* const constp = VN_AS(varp->valuep(), Const);
if (!constp) varp->v3fatalSrc("non-const initializer for variable"); if (!constp) varp->v3fatalSrc("non-const initializer for variable");
for (int w = 0; w < varp->widthWords(); ++w) { for (int w = 0; w < varp->widthWords(); ++w) {
out += varNameProtected + suffix + "[" + cvtToStr(w) + "] = "; out += varNameProtected + suffix + "[" + cvtToStr(w) + "] = ";
@ -732,8 +733,8 @@ void EmitCFunc::doubleOrDetect(AstChangeDet* changep, bool& gotOne) {
} }
iterateAndNextNull(changep->lhsp()); iterateAndNextNull(changep->lhsp());
} else { } else {
AstNode* lhsp = changep->lhsp(); AstNode* const lhsp = changep->lhsp();
AstNode* rhsp = changep->rhsp(); AstNode* const rhsp = changep->rhsp();
UASSERT_OBJ(VN_IS(lhsp, VarRef) || VN_IS(lhsp, ArraySel), changep, "Not ref?"); UASSERT_OBJ(VN_IS(lhsp, VarRef) || VN_IS(lhsp, ArraySel), changep, "Not ref?");
UASSERT_OBJ(VN_IS(rhsp, VarRef) || VN_IS(rhsp, ArraySel), changep, "Not ref?"); UASSERT_OBJ(VN_IS(rhsp, VarRef) || VN_IS(rhsp, ArraySel), changep, "Not ref?");
for (int word = 0; word < (changep->lhsp()->isWide() ? changep->lhsp()->widthWords() : 1); for (int word = 0; word < (changep->lhsp()->isWide() ? changep->lhsp()->widthWords() : 1);

View File

@ -126,7 +126,7 @@ protected:
EmitCLazyDecls m_lazyDecls; // Visitor for emitting lazy declarations EmitCLazyDecls m_lazyDecls; // Visitor for emitting lazy declarations
bool m_useSelfForThis = false; // Replace "this" with "vlSelf" bool m_useSelfForThis = false; // Replace "this" with "vlSelf"
const AstNodeModule* m_modp = nullptr; // Current module being emitted const AstNodeModule* m_modp = nullptr; // Current module being emitted
AstCFunc* m_cfuncp = nullptr; // Current function being emitted const AstCFunc* m_cfuncp = nullptr; // Current function being emitted
public: public:
// METHODS // METHODS
@ -229,7 +229,7 @@ public:
puts(nodep->nameProtect() + "\\n\"); );\n"); puts(nodep->nameProtect() + "\\n\"); );\n");
for (AstNode* subnodep = nodep->argsp(); subnodep; subnodep = subnodep->nextp()) { for (AstNode* subnodep = nodep->argsp(); subnodep; subnodep = subnodep->nextp()) {
if (AstVar* varp = VN_CAST(subnodep, Var)) { if (AstVar* const varp = VN_CAST(subnodep, Var)) {
if (varp->isFuncReturn()) emitVarDecl(varp); if (varp->isFuncReturn()) emitVarDecl(varp);
} }
} }
@ -265,7 +265,7 @@ public:
virtual void visit(AstNodeAssign* nodep) override { virtual void visit(AstNodeAssign* nodep) override {
bool paren = true; bool paren = true;
bool decind = false; bool decind = false;
if (AstSel* selp = VN_CAST(nodep->lhsp(), Sel)) { if (AstSel* const selp = VN_CAST(nodep->lhsp(), Sel)) {
if (selp->widthMin() == 1) { if (selp->widthMin() == 1) {
putbs("VL_ASSIGNBIT_"); putbs("VL_ASSIGNBIT_");
emitIQW(selp->fromp()); emitIQW(selp->fromp());
@ -292,7 +292,7 @@ public:
iterateAndNextNull(selp->fromp()); iterateAndNextNull(selp->fromp());
puts(", "); puts(", ");
} }
} else if (AstGetcRefN* selp = VN_CAST(nodep->lhsp(), GetcRefN)) { } else if (const AstGetcRefN* const selp = VN_CAST(nodep->lhsp(), GetcRefN)) {
iterateAndNextNull(selp->lhsp()); iterateAndNextNull(selp->lhsp());
puts(" = "); puts(" = ");
putbs("VL_PUTC_N("); putbs("VL_PUTC_N(");
@ -300,7 +300,7 @@ public:
puts(", "); puts(", ");
iterateAndNextNull(selp->rhsp()); iterateAndNextNull(selp->rhsp());
puts(", "); puts(", ");
} else if (AstVar* varp = AstVar::scVarRecurse(nodep->lhsp())) { } else if (AstVar* const varp = AstVar::scVarRecurse(nodep->lhsp())) {
putbs("VL_ASSIGN_"); // Set a systemC variable putbs("VL_ASSIGN_"); // Set a systemC variable
emitScIQW(varp); emitScIQW(varp);
emitIQW(nodep); emitIQW(nodep);
@ -308,7 +308,7 @@ public:
puts(cvtToStr(nodep->widthMin()) + ","); puts(cvtToStr(nodep->widthMin()) + ",");
iterateAndNextNull(nodep->lhsp()); iterateAndNextNull(nodep->lhsp());
puts(", "); puts(", ");
} else if (AstVar* varp = AstVar::scVarRecurse(nodep->rhsp())) { } else if (AstVar* const varp = AstVar::scVarRecurse(nodep->rhsp())) {
putbs("VL_ASSIGN_"); // Get a systemC variable putbs("VL_ASSIGN_"); // Get a systemC variable
emitIQW(nodep); emitIQW(nodep);
emitScIQW(varp); emitScIQW(varp);
@ -348,7 +348,7 @@ public:
virtual void visit(AstAssocSel* nodep) override { virtual void visit(AstAssocSel* nodep) override {
iterateAndNextNull(nodep->fromp()); iterateAndNextNull(nodep->fromp());
putbs(".at("); putbs(".at(");
AstAssocArrayDType* adtypep = VN_AS(nodep->fromp()->dtypep(), AssocArrayDType); AstAssocArrayDType* const adtypep = VN_AS(nodep->fromp()->dtypep(), AssocArrayDType);
UASSERT_OBJ(adtypep, nodep, "Associative select on non-associative type"); UASSERT_OBJ(adtypep, nodep, "Associative select on non-associative type");
if (adtypep->keyDTypep()->isWide()) { if (adtypep->keyDTypep()->isWide()) {
emitCvtWideArray(nodep->bitp(), nodep->fromp()); emitCvtWideArray(nodep->bitp(), nodep->fromp());
@ -429,11 +429,11 @@ public:
virtual void visit(AstWith* nodep) override { virtual void visit(AstWith* nodep) override {
// With uses a C++11 lambda // With uses a C++11 lambda
putbs("[=]("); putbs("[=](");
if (auto* argrefp = nodep->indexArgRefp()) { if (auto* const argrefp = nodep->indexArgRefp()) {
putbs(argrefp->dtypep()->cType(argrefp->nameProtect(), false, false)); putbs(argrefp->dtypep()->cType(argrefp->nameProtect(), false, false));
puts(","); puts(",");
} }
if (auto* argrefp = nodep->valueArgRefp()) { if (auto* const argrefp = nodep->valueArgRefp()) {
putbs(argrefp->dtypep()->cType(argrefp->nameProtect(), false, false)); putbs(argrefp->dtypep()->cType(argrefp->nameProtect(), false, false));
} }
// Probably fragile, V3Task may need to convert to a AstCReturn // Probably fragile, V3Task may need to convert to a AstCReturn
@ -632,12 +632,12 @@ public:
puts(cvtToStr(nodep->memp()->dtypep()->subDTypep()->widthMin())); puts(cvtToStr(nodep->memp()->dtypep()->subDTypep()->widthMin()));
uint32_t array_lo = 0; uint32_t array_lo = 0;
{ {
const AstVarRef* varrefp = VN_CAST(nodep->memp(), VarRef); const AstVarRef* const varrefp = VN_CAST(nodep->memp(), VarRef);
if (!varrefp) { if (!varrefp) {
nodep->v3error(nodep->verilogKwd() << " loading non-variable"); nodep->v3error(nodep->verilogKwd() << " loading non-variable");
} else if (VN_IS(varrefp->varp()->dtypeSkipRefp(), AssocArrayDType)) { } else if (VN_IS(varrefp->varp()->dtypeSkipRefp(), AssocArrayDType)) {
// nodep->memp() below will when verilated code is compiled create a C++ template // nodep->memp() below will when verilated code is compiled create a C++ template
} else if (const AstUnpackArrayDType* adtypep } else if (const AstUnpackArrayDType* const adtypep
= VN_CAST(varrefp->varp()->dtypeSkipRefp(), UnpackArrayDType)) { = VN_CAST(varrefp->varp()->dtypeSkipRefp(), UnpackArrayDType)) {
putbs(", "); putbs(", ");
puts(cvtToStr(varrefp->varp()->dtypep()->arrayUnpackedElements())); puts(cvtToStr(varrefp->varp()->dtypep()->arrayUnpackedElements()));
@ -716,11 +716,11 @@ public:
uint32_t array_lo = 0; uint32_t array_lo = 0;
uint32_t array_size = 0; uint32_t array_size = 0;
{ {
const AstVarRef* varrefp = VN_CAST(nodep->memp(), VarRef); const AstVarRef* const varrefp = VN_CAST(nodep->memp(), VarRef);
if (!varrefp) { if (!varrefp) {
nodep->v3error(nodep->verilogKwd() << " loading non-variable"); nodep->v3error(nodep->verilogKwd() << " loading non-variable");
} else if (VN_CAST(varrefp->varp()->dtypeSkipRefp(), BasicDType)) { } else if (VN_CAST(varrefp->varp()->dtypeSkipRefp(), BasicDType)) {
} else if (const AstUnpackArrayDType* adtypep } else if (const AstUnpackArrayDType* const adtypep
= VN_CAST(varrefp->varp()->dtypeSkipRefp(), UnpackArrayDType)) { = VN_CAST(varrefp->varp()->dtypeSkipRefp(), UnpackArrayDType)) {
array_lo = adtypep->lo(); array_lo = adtypep->lo();
array_size = adtypep->elementsConst(); array_size = adtypep->elementsConst();
@ -980,7 +980,7 @@ public:
if (nodep->lhsp()->isWide()) { if (nodep->lhsp()->isWide()) {
visit(static_cast<AstNodeUniop*>(nodep)); visit(static_cast<AstNodeUniop*>(nodep));
} else { } else {
AstVarRef* const vrefp = VN_CAST(nodep->lhsp(), VarRef); const AstVarRef* const vrefp = VN_CAST(nodep->lhsp(), VarRef);
const int widthPow2 = vrefp ? vrefp->varp()->dtypep()->widthPow2() const int widthPow2 = vrefp ? vrefp->varp()->dtypep()->widthPow2()
: nodep->lhsp()->dtypep()->widthPow2(); : nodep->lhsp()->dtypep()->widthPow2();
UASSERT_OBJ(widthPow2 > 1, nodep, UASSERT_OBJ(widthPow2 > 1, nodep,
@ -1064,8 +1064,8 @@ public:
virtual void visit(AstStreamL* nodep) override { virtual void visit(AstStreamL* nodep) override {
// Attempt to use a "fast" stream function for slice size = power of 2 // Attempt to use a "fast" stream function for slice size = power of 2
if (!nodep->isWide()) { if (!nodep->isWide()) {
uint32_t isPow2 = VN_AS(nodep->rhsp(), Const)->num().countOnes() == 1; const uint32_t isPow2 = VN_AS(nodep->rhsp(), Const)->num().countOnes() == 1;
uint32_t sliceSize = VN_AS(nodep->rhsp(), Const)->toUInt(); const uint32_t sliceSize = VN_AS(nodep->rhsp(), Const)->toUInt();
if (isPow2 && sliceSize <= (nodep->isQuad() ? sizeof(uint64_t) : sizeof(uint32_t))) { if (isPow2 && sliceSize <= (nodep->isQuad() ? sizeof(uint64_t) : sizeof(uint32_t))) {
puts("VL_STREAML_FAST_"); puts("VL_STREAML_FAST_");
emitIQW(nodep); emitIQW(nodep);
@ -1077,7 +1077,7 @@ public:
puts(","); puts(",");
iterateAndNextNull(nodep->lhsp()); iterateAndNextNull(nodep->lhsp());
puts(", "); puts(", ");
uint32_t rd_log2 = V3Number::log2b(VN_AS(nodep->rhsp(), Const)->toUInt()); const uint32_t rd_log2 = V3Number::log2b(VN_AS(nodep->rhsp(), Const)->toUInt());
puts(cvtToStr(rd_log2) + ")"); puts(cvtToStr(rd_log2) + ")");
return; return;
} }
@ -1133,7 +1133,7 @@ public:
} }
virtual void visit(AstAddrOfCFunc* nodep) override { virtual void visit(AstAddrOfCFunc* nodep) override {
// Note: Can be thought to handle more, but this is all that is needed right now // Note: Can be thought to handle more, but this is all that is needed right now
AstCFunc* const funcp = nodep->funcp(); const AstCFunc* const funcp = nodep->funcp();
UASSERT_OBJ(funcp->isLoose(), nodep, "Cannot take address of non-loose method"); UASSERT_OBJ(funcp->isLoose(), nodep, "Cannot take address of non-loose method");
puts("&"); puts("&");
puts(funcNameProtect(funcp)); puts(funcNameProtect(funcp));
@ -1205,7 +1205,7 @@ public:
} }
} }
virtual void visit(AstCReset* nodep) override { virtual void visit(AstCReset* nodep) override {
AstVar* varp = nodep->varrefp()->varp(); AstVar* const varp = nodep->varrefp()->varp();
emitVarReset(varp); emitVarReset(varp);
} }
virtual void visit(AstExecGraph* nodep) override { virtual void visit(AstExecGraph* nodep) override {

View File

@ -135,7 +135,7 @@ class EmitCGatherDependencies final : AstNVisitor {
public: public:
static const std::set<std::string> gather(AstCFunc* cfuncp) { static const std::set<std::string> gather(AstCFunc* cfuncp) {
EmitCGatherDependencies visitor{cfuncp}; const EmitCGatherDependencies visitor{cfuncp};
return std::move(visitor.m_dependencies); return std::move(visitor.m_dependencies);
} }
}; };
@ -348,7 +348,7 @@ class EmitCImp final : EmitCFunc {
// just looking for loading the wrong model // just looking for loading the wrong model
VHashSha256 hash; VHashSha256 hash;
for (AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) { for (AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (const AstVar* varp = VN_CAST(nodep, Var)) { if (const AstVar* const varp = VN_CAST(nodep, Var)) {
hash.insert(varp->name()); hash.insert(varp->name());
hash.insert(varp->dtypep()->width()); hash.insert(varp->dtypep()->width());
} }
@ -369,7 +369,7 @@ class EmitCImp final : EmitCFunc {
// Save all members // Save all members
for (AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) { for (AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (const AstVar* varp = VN_CAST(nodep, Var)) { if (const AstVar* const varp = VN_CAST(nodep, Var)) {
if (varp->isIO() && modp->isTop() && optSystemC()) { if (varp->isIO() && modp->isTop() && optSystemC()) {
// System C top I/O doesn't need loading, as the // System C top I/O doesn't need loading, as the
// lower level subinst code does it. // lower level subinst code does it.
@ -576,7 +576,7 @@ class EmitCTrace final : EmitCFunc {
if (m_slow) filename += "__Slow"; if (m_slow) filename += "__Slow";
filename += ".cpp"; filename += ".cpp";
AstCFile* cfilep = newCFile(filename, m_slow, true /*source*/); AstCFile* const cfilep = newCFile(filename, m_slow, true /*source*/);
cfilep->support(true); cfilep->support(true);
if (optSystemC()) { if (optSystemC()) {
@ -595,23 +595,23 @@ class EmitCTrace final : EmitCFunc {
} }
bool emitTraceIsScBv(AstTraceInc* nodep) { bool emitTraceIsScBv(AstTraceInc* nodep) {
const AstVarRef* varrefp = VN_CAST(nodep->declp()->valuep(), VarRef); const AstVarRef* const varrefp = VN_CAST(nodep->declp()->valuep(), VarRef);
if (!varrefp) return false; if (!varrefp) return false;
AstVar* varp = varrefp->varp(); AstVar* const varp = varrefp->varp();
return varp->isSc() && varp->isScBv(); return varp->isSc() && varp->isScBv();
} }
bool emitTraceIsScBigUint(AstTraceInc* nodep) { bool emitTraceIsScBigUint(AstTraceInc* nodep) {
const AstVarRef* varrefp = VN_CAST(nodep->declp()->valuep(), VarRef); const AstVarRef* const varrefp = VN_CAST(nodep->declp()->valuep(), VarRef);
if (!varrefp) return false; if (!varrefp) return false;
AstVar* varp = varrefp->varp(); AstVar* const varp = varrefp->varp();
return varp->isSc() && varp->isScBigUint(); return varp->isSc() && varp->isScBigUint();
} }
bool emitTraceIsScUint(AstTraceInc* nodep) { bool emitTraceIsScUint(AstTraceInc* nodep) {
const AstVarRef* varrefp = VN_CAST(nodep->declp()->valuep(), VarRef); const AstVarRef* const varrefp = VN_CAST(nodep->declp()->valuep(), VarRef);
if (!varrefp) return false; if (!varrefp) return false;
AstVar* varp = varrefp->varp(); AstVar* const varp = varrefp->varp();
return varp->isSc() && varp->isScUint(); return varp->isSc() && varp->isScUint();
} }
@ -714,7 +714,7 @@ class EmitCTrace final : EmitCFunc {
if (v3Global.opt.traceFormat().fst()) { if (v3Global.opt.traceFormat().fst()) {
// Skip over refs-to-refs, but stop before final ref so can get data type name // Skip over refs-to-refs, but stop before final ref so can get data type name
// Alternatively back in V3Width we could push enum names from upper typedefs // Alternatively back in V3Width we could push enum names from upper typedefs
if (AstEnumDType* enump = VN_CAST(nodep->skipRefToEnump(), EnumDType)) { if (AstEnumDType* const enump = VN_CAST(nodep->skipRefToEnump(), EnumDType)) {
int enumNum = enump->user1(); int enumNum = enump->user1();
if (!enumNum) { if (!enumNum) {
enumNum = ++m_enumNum; enumNum = ++m_enumNum;
@ -734,7 +734,7 @@ class EmitCTrace final : EmitCFunc {
puts("= {"); puts("= {");
for (AstEnumItem* itemp = enump->itemsp(); itemp; for (AstEnumItem* itemp = enump->itemsp(); itemp;
itemp = VN_AS(itemp->nextp(), EnumItem)) { itemp = VN_AS(itemp->nextp(), EnumItem)) {
AstConst* constp = VN_AS(itemp->valuep(), Const); AstConst* const constp = VN_AS(itemp->valuep(), Const);
if (++nvals > 1) puts(", "); if (++nvals > 1) puts(", ");
putbs("\"" + constp->num().displayed(nodep, "%0b") + "\""); putbs("\"" + constp->num().displayed(nodep, "%0b") + "\"");
} }
@ -785,7 +785,7 @@ class EmitCTrace final : EmitCFunc {
void emitTraceValue(AstTraceInc* nodep, int arrayindex) { void emitTraceValue(AstTraceInc* nodep, int arrayindex) {
if (AstVarRef* const varrefp = VN_CAST(nodep->valuep(), VarRef)) { if (AstVarRef* const varrefp = VN_CAST(nodep->valuep(), VarRef)) {
AstVar* varp = varrefp->varp(); AstVar* const varp = varrefp->varp();
puts("("); puts("(");
if (emitTraceIsScBigUint(nodep)) { if (emitTraceIsScBigUint(nodep)) {
puts("(vluint32_t*)"); puts("(vluint32_t*)");
@ -882,7 +882,7 @@ public:
void V3EmitC::emitcImp() { void V3EmitC::emitcImp() {
UINFO(2, __FUNCTION__ << ": " << endl); UINFO(2, __FUNCTION__ << ": " << endl);
// Make parent module pointers available. // Make parent module pointers available.
EmitCParentModule emitCParentModule; const EmitCParentModule emitCParentModule;
// Process each module in turn // Process each module in turn
for (const AstNode* nodep = v3Global.rootp()->modulesp(); nodep; nodep = nodep->nextp()) { for (const AstNode* nodep = v3Global.rootp()->modulesp(); nodep; nodep = nodep->nextp()) {
@ -903,12 +903,12 @@ void V3EmitC::emitcFiles() {
UINFO(2, __FUNCTION__ << ": " << endl); UINFO(2, __FUNCTION__ << ": " << endl);
for (AstNodeFile* filep = v3Global.rootp()->filesp(); filep; for (AstNodeFile* filep = v3Global.rootp()->filesp(); filep;
filep = VN_AS(filep->nextp(), NodeFile)) { filep = VN_AS(filep->nextp(), NodeFile)) {
AstCFile* cfilep = VN_CAST(filep, CFile); AstCFile* const cfilep = VN_CAST(filep, CFile);
if (cfilep && cfilep->tblockp()) { if (cfilep && cfilep->tblockp()) {
V3OutCFile of(cfilep->name()); V3OutCFile of(cfilep->name());
of.puts("// DESCR" of.puts("// DESCR"
"IPTION: Verilator generated C++\n"); "IPTION: Verilator generated C++\n");
EmitCFunc visitor(cfilep->tblockp(), &of, true); const EmitCFunc visitor(cfilep->tblockp(), &of, true);
} }
} }
} }

View File

@ -199,7 +199,7 @@ class CMakeEmitter final {
*of << "# User .cpp files (from .cpp's on Verilator command line)\n"; *of << "# User .cpp files (from .cpp's on Verilator command line)\n";
cmake_set_raw(*of, name + "_USER_CLASSES", deslash(cmake_list(v3Global.opt.cppFiles()))); cmake_set_raw(*of, name + "_USER_CLASSES", deslash(cmake_list(v3Global.opt.cppFiles())));
if (const V3HierBlockPlan* planp = v3Global.hierPlanp()) { if (const V3HierBlockPlan* const planp = v3Global.hierPlanp()) {
*of << "# Verilate hierarchical blocks\n"; *of << "# Verilate hierarchical blocks\n";
// Sorted hierarchical blocks in order of leaf-first. // Sorted hierarchical blocks in order of leaf-first.
const V3HierBlockPlan::HierVector& hierBlocks = planp->hierBlocksSorted(); const V3HierBlockPlan::HierVector& hierBlocks = planp->hierBlocksSorted();
@ -260,5 +260,5 @@ public:
void V3EmitCMake::emit() { void V3EmitCMake::emit() {
UINFO(2, __FUNCTION__ << ": " << endl); UINFO(2, __FUNCTION__ << ": " << endl);
CMakeEmitter emitter; const CMakeEmitter emitter;
} }

View File

@ -136,7 +136,7 @@ class EmitCModel final : public EmitCFunc {
puts("\n"); puts("\n");
ofp()->putsPrivate(false); // public: ofp()->putsPrivate(false); // public:
puts("// API METHODS\n"); puts("// API METHODS\n");
string callEvalEndStep const string callEvalEndStep
= (v3Global.needTraceDumper() && !optSystemC()) ? "eval_end_step(); " : ""; = (v3Global.needTraceDumper() && !optSystemC()) ? "eval_end_step(); " : "";
if (optSystemC()) { if (optSystemC()) {
ofp()->putsPrivate(true); ///< eval() is invoked by our sensitive() calls. ofp()->putsPrivate(true); ///< eval() is invoked by our sensitive() calls.
@ -190,7 +190,7 @@ class EmitCModel final : public EmitCFunc {
std::vector<const AstCFunc*> funcps; std::vector<const AstCFunc*> funcps;
for (AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) { for (AstNode* nodep = modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (const AstCFunc* funcp = VN_CAST(nodep, CFunc)) { if (const AstCFunc* const funcp = VN_CAST(nodep, CFunc)) {
if (!funcp->dpiExportDispatcher()) continue; if (!funcp->dpiExportDispatcher()) continue;
funcps.push_back(funcp); funcps.push_back(funcp);
} }
@ -422,7 +422,7 @@ class EmitCModel final : public EmitCFunc {
+ "(vlSymsp);\n"); + "(vlSymsp);\n");
if (v3Global.opt.threads() == 1) { if (v3Global.opt.threads() == 1) {
uint32_t mtaskId = 0; const uint32_t mtaskId = 0;
putsDecoration("// MTask " + cvtToStr(mtaskId) + " start\n"); putsDecoration("// MTask " + cvtToStr(mtaskId) + " start\n");
puts("VL_DEBUG_IF(VL_DBG_MSGF(\"MTask" + cvtToStr(mtaskId) + " starting\\n\"););\n"); puts("VL_DEBUG_IF(VL_DBG_MSGF(\"MTask" + cvtToStr(mtaskId) + " starting\\n\"););\n");
puts("Verilated::mtaskId(" + cvtToStr(mtaskId) + ");\n"); puts("Verilated::mtaskId(" + cvtToStr(mtaskId) + ");\n");

View File

@ -38,9 +38,9 @@ class EmitCSyms final : EmitCBaseVisitor {
// TYPES // TYPES
struct ScopeData { struct ScopeData {
string m_symName; const string m_symName;
string m_prettyName; const string m_prettyName;
int m_timeunit; const int m_timeunit;
string m_type; string m_type;
ScopeData(const string& symName, const string& prettyName, int timeunit, ScopeData(const string& symName, const string& prettyName, int timeunit,
const string& type) const string& type)
@ -59,13 +59,13 @@ class EmitCSyms final : EmitCBaseVisitor {
, m_modp{modp} {} , m_modp{modp} {}
}; };
struct ScopeVarData { struct ScopeVarData {
string m_scopeName; const string m_scopeName;
string m_varBasePretty; const string m_varBasePretty;
AstVar* const m_varp; AstVar* const m_varp;
AstNodeModule* const m_modp; const AstNodeModule* const m_modp;
AstScope* const m_scopep; AstScope* const m_scopep;
ScopeVarData(const string& scopeName, const string& varBasePretty, AstVar* varp, ScopeVarData(const string& scopeName, const string& varBasePretty, AstVar* varp,
AstNodeModule* modp, AstScope* scopep) const AstNodeModule* modp, AstScope* scopep)
: m_scopeName{scopeName} : m_scopeName{scopeName}
, m_varBasePretty{varBasePretty} , m_varBasePretty{varBasePretty}
, m_varp{varp} , m_varp{varp}
@ -104,7 +104,7 @@ class EmitCSyms final : EmitCBaseVisitor {
ScopeNames m_vpiScopeCandidates; // All scopes for VPI ScopeNames m_vpiScopeCandidates; // All scopes for VPI
ScopeNameHierarchy m_vpiScopeHierarchy; // The actual hierarchy of scopes ScopeNameHierarchy m_vpiScopeHierarchy; // The actual hierarchy of scopes
int m_coverBins = 0; // Coverage bin number int m_coverBins = 0; // Coverage bin number
bool m_dpiHdrOnly; // Only emit the DPI header const bool m_dpiHdrOnly; // Only emit the DPI header
int m_numStmts = 0; // Number of statements output int m_numStmts = 0; // Number of statements output
int m_funcNum = 0; // CFunc split function number int m_funcNum = 0; // CFunc split function number
V3OutCFile* m_ofpBase = nullptr; // Base (not split) C file V3OutCFile* m_ofpBase = nullptr; // Base (not split) C file
@ -197,7 +197,7 @@ class EmitCSyms final : EmitCBaseVisitor {
const AstNodeModule* const smodp = itsc->second; const AstNodeModule* const smodp = itsc->second;
for (std::vector<ModVarPair>::iterator it = m_modVars.begin(); it != m_modVars.end(); for (std::vector<ModVarPair>::iterator it = m_modVars.begin(); it != m_modVars.end();
++it) { ++it) {
AstNodeModule* const modp = it->first; const AstNodeModule* const modp = it->first;
AstVar* const varp = it->second; AstVar* const varp = it->second;
if (modp == smodp) { if (modp == smodp) {
// Need to split the module + var name into the // Need to split the module + var name into the
@ -208,7 +208,7 @@ class EmitCSyms final : EmitCBaseVisitor {
string scpName; string scpName;
string varBase; string varBase;
if (whole.substr(0, 10) == "__DOT__TOP") whole.replace(0, 10, ""); if (whole.substr(0, 10) == "__DOT__TOP") whole.replace(0, 10, "");
string::size_type dpos = whole.rfind("__DOT__"); const string::size_type dpos = whole.rfind("__DOT__");
if (dpos != string::npos) { if (dpos != string::npos) {
scpName = whole.substr(0, dpos); scpName = whole.substr(0, dpos);
varBase = whole.substr(dpos + strlen("__DOT__")); varBase = whole.substr(dpos + strlen("__DOT__"));
@ -245,7 +245,7 @@ class EmitCSyms final : EmitCBaseVisitor {
if (above.substr(0, 4) == "TOP.") above.replace(0, 4, ""); if (above.substr(0, 4) == "TOP.") above.replace(0, 4, "");
while (!above.empty()) { while (!above.empty()) {
string::size_type pos = above.rfind("__"); const string::size_type pos = above.rfind("__");
if (pos == string::npos) break; if (pos == string::npos) break;
above.resize(pos); above.resize(pos);
if (m_vpiScopeHierarchy.find(above) != m_vpiScopeHierarchy.end()) { if (m_vpiScopeHierarchy.find(above) != m_vpiScopeHierarchy.end()) {
@ -552,7 +552,7 @@ void EmitCSyms::checkSplit(bool usesVfinal) {
v3Global.useParallelBuild(true); v3Global.useParallelBuild(true);
m_numStmts = 0; m_numStmts = 0;
string filename const string filename
= v3Global.opt.makeDir() + "/" + symClassName() + "__" + cvtToStr(++m_funcNum) + ".cpp"; = v3Global.opt.makeDir() + "/" + symClassName() + "__" + cvtToStr(++m_funcNum) + ".cpp";
AstCFile* const cfilep = newCFile(filename, true /*slow*/, true /*source*/); AstCFile* const cfilep = newCFile(filename, true /*slow*/, true /*source*/);
cfilep->support(true); cfilep->support(true);
@ -637,7 +637,7 @@ void EmitCSyms::emitScopeHier(bool destroy) {
void EmitCSyms::emitSymImp() { void EmitCSyms::emitSymImp() {
UINFO(6, __FUNCTION__ << ": " << endl); UINFO(6, __FUNCTION__ << ": " << endl);
const string filename = v3Global.opt.makeDir() + "/" + symClassName() + ".cpp"; const string filename = v3Global.opt.makeDir() + "/" + symClassName() + ".cpp";
AstCFile* cfilep = newCFile(filename, true /*slow*/, true /*source*/); AstCFile* const cfilep = newCFile(filename, true /*slow*/, true /*source*/);
cfilep->support(true); cfilep->support(true);
if (v3Global.opt.systemC()) { if (v3Global.opt.systemC()) {
@ -747,7 +747,7 @@ void EmitCSyms::emitSymImp() {
for (const V3GraphVertex* vxp for (const V3GraphVertex* vxp
= v3Global.rootp()->execGraphp()->depGraphp()->verticesBeginp(); = v3Global.rootp()->execGraphp()->depGraphp()->verticesBeginp();
vxp; vxp = vxp->verticesNextp()) { vxp; vxp = vxp->verticesNextp()) {
ExecMTask* mtp = dynamic_cast<ExecMTask*>(const_cast<V3GraphVertex*>(vxp)); ExecMTask* const mtp = dynamic_cast<ExecMTask*>(const_cast<V3GraphVertex*>(vxp));
puts("_vm_profiler.addCounter(" + cvtToStr(mtp->profilerId()) + ", \"" puts("_vm_profiler.addCounter(" + cvtToStr(mtp->profilerId()) + ", \""
+ mtp->hashName() + "\");\n"); + mtp->hashName() + "\");\n");
} }
@ -789,8 +789,8 @@ void EmitCSyms::emitSymImp() {
puts("// Setup each module's pointer back to symbol table (for public functions)\n"); puts("// Setup each module's pointer back to symbol table (for public functions)\n");
for (const auto& i : m_scopes) { for (const auto& i : m_scopes) {
AstScope* scopep = i.first; AstScope* const scopep = i.first;
AstNodeModule* modp = i.second; AstNodeModule* const modp = i.second;
checkSplit(false); checkSplit(false);
// first is used by AstCoverDecl's call to __vlCoverInsert // first is used by AstCoverDecl's call to __vlCoverInsert
const bool first = !modp->user1(); const bool first = !modp->user1();
@ -824,9 +824,9 @@ void EmitCSyms::emitSymImp() {
m_ofpBase->puts("// Setup export functions\n"); m_ofpBase->puts("// Setup export functions\n");
m_ofpBase->puts("for (int __Vfinal=0; __Vfinal<2; __Vfinal++) {\n"); m_ofpBase->puts("for (int __Vfinal=0; __Vfinal<2; __Vfinal++) {\n");
for (auto it = m_scopeFuncs.begin(); it != m_scopeFuncs.end(); ++it) { for (auto it = m_scopeFuncs.begin(); it != m_scopeFuncs.end(); ++it) {
AstScopeName* scopep = it->second.m_scopep; AstScopeName* const scopep = it->second.m_scopep;
AstCFunc* funcp = it->second.m_cfuncp; AstCFunc* const funcp = it->second.m_cfuncp;
AstNodeModule* modp = it->second.m_modp; AstNodeModule* const modp = it->second.m_modp;
if (funcp->dpiExportImpl()) { if (funcp->dpiExportImpl()) {
checkSplit(true); checkSplit(true);
puts(protect("__Vscope_" + scopep->scopeSymName()) + ".exportInsert(__Vfinal, "); puts(protect("__Vscope_" + scopep->scopeSymName()) + ".exportInsert(__Vfinal, ");
@ -843,14 +843,14 @@ void EmitCSyms::emitSymImp() {
// Someday. For now public isn't common. // Someday. For now public isn't common.
for (auto it = m_scopeVars.begin(); it != m_scopeVars.end(); ++it) { for (auto it = m_scopeVars.begin(); it != m_scopeVars.end(); ++it) {
checkSplit(true); checkSplit(true);
AstScope* scopep = it->second.m_scopep; AstScope* const scopep = it->second.m_scopep;
AstVar* varp = it->second.m_varp; AstVar* const varp = it->second.m_varp;
// //
int pwidth = 1; int pwidth = 1;
int pdim = 0; int pdim = 0;
int udim = 0; int udim = 0;
string bounds; string bounds;
if (AstBasicDType* basicp = varp->basicp()) { if (AstBasicDType* const basicp = varp->basicp()) {
// Range is always first, it's not in "C" order // Range is always first, it's not in "C" order
if (basicp->isRanged()) { if (basicp->isRanged()) {
bounds += " ,"; bounds += " ,";
@ -863,7 +863,7 @@ void EmitCSyms::emitSymImp() {
for (AstNodeDType* dtypep = varp->dtypep(); dtypep;) { for (AstNodeDType* dtypep = varp->dtypep(); dtypep;) {
dtypep dtypep
= dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
if (const AstNodeArrayDType* adtypep = VN_CAST(dtypep, NodeArrayDType)) { if (const AstNodeArrayDType* const adtypep = VN_CAST(dtypep, NodeArrayDType)) {
bounds += " ,"; bounds += " ,";
bounds += cvtToStr(adtypep->left()); bounds += cvtToStr(adtypep->left());
bounds += ","; bounds += ",";
@ -965,7 +965,7 @@ void EmitCSyms::emitSymImp() {
void EmitCSyms::emitDpiHdr() { void EmitCSyms::emitDpiHdr() {
UINFO(6, __FUNCTION__ << ": " << endl); UINFO(6, __FUNCTION__ << ": " << endl);
const string filename = v3Global.opt.makeDir() + "/" + topClassName() + "__Dpi.h"; const string filename = v3Global.opt.makeDir() + "/" + topClassName() + "__Dpi.h";
AstCFile* cfilep = newCFile(filename, false /*slow*/, false /*source*/); AstCFile* const cfilep = newCFile(filename, false /*slow*/, false /*source*/);
cfilep->support(true); cfilep->support(true);
V3OutCFile hf(filename); V3OutCFile hf(filename);
m_ofp = &hf; m_ofp = &hf;
@ -1019,7 +1019,7 @@ void EmitCSyms::emitDpiHdr() {
void EmitCSyms::emitDpiImp() { void EmitCSyms::emitDpiImp() {
UINFO(6, __FUNCTION__ << ": " << endl); UINFO(6, __FUNCTION__ << ": " << endl);
const string filename = v3Global.opt.makeDir() + "/" + topClassName() + "__Dpi.cpp"; const string filename = v3Global.opt.makeDir() + "/" + topClassName() + "__Dpi.cpp";
AstCFile* cfilep = newCFile(filename, false /*slow*/, true /*source*/); AstCFile* const cfilep = newCFile(filename, false /*slow*/, true /*source*/);
cfilep->support(true); cfilep->support(true);
V3OutCFile hf(filename); V3OutCFile hf(filename);
m_ofp = &hf; m_ofp = &hf;
@ -1053,7 +1053,7 @@ void EmitCSyms::emitDpiImp() {
puts("return " + topClassName() + "::" + nodep->name() + "("); puts("return " + topClassName() + "::" + nodep->name() + "(");
string args; string args;
for (AstNode* stmtp = nodep->argsp(); stmtp; stmtp = stmtp->nextp()) { for (AstNode* stmtp = nodep->argsp(); stmtp; stmtp = stmtp->nextp()) {
if (const AstVar* portp = VN_CAST(stmtp, Var)) { if (const AstVar* const portp = VN_CAST(stmtp, Var)) {
if (portp->isIO() && !portp->isFuncReturn()) { if (portp->isIO() && !portp->isFuncReturn()) {
if (args != "") args += ", "; if (args != "") args += ", ";
args += portp->name(); args += portp->name();

View File

@ -407,7 +407,7 @@ public:
void V3EmitMk::emitmk() { void V3EmitMk::emitmk() {
UINFO(2, __FUNCTION__ << ": " << endl); UINFO(2, __FUNCTION__ << ": " << endl);
EmitMk emitter; const EmitMk emitter;
} }
void V3EmitMk::emitHierVerilation(const V3HierBlockPlan* planp) { void V3EmitMk::emitHierVerilation(const V3HierBlockPlan* planp) {

View File

@ -31,7 +31,7 @@
class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor { class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
// MEMBERS // MEMBERS
bool m_suppressSemi = false; bool m_suppressSemi = false;
bool m_suppressUnknown = false; const bool m_suppressUnknown = false;
AstSenTree* m_sensesp; // Domain for printing one a ALWAYS under a ACTIVE AstSenTree* m_sensesp; // Domain for printing one a ALWAYS under a ACTIVE
// METHODS // METHODS
@ -650,7 +650,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
std::vector<const AstUnpackArrayDType*> unpackps; std::vector<const AstUnpackArrayDType*> unpackps;
for (AstNodeDType* dtypep = nodep->dtypep(); dtypep;) { for (AstNodeDType* dtypep = nodep->dtypep(); dtypep;) {
dtypep = dtypep->skipRefp(); dtypep = dtypep->skipRefp();
if (AstUnpackArrayDType* const unpackp = VN_CAST(dtypep, UnpackArrayDType)) { if (const AstUnpackArrayDType* const unpackp = VN_CAST(dtypep, UnpackArrayDType)) {
unpackps.push_back(unpackp); unpackps.push_back(unpackp);
dtypep = unpackp->subDTypep(); dtypep = unpackp->subDTypep();
} else { } else {
@ -752,8 +752,8 @@ public:
class EmitVPrefixedFormatter final : public V3OutFormatter { class EmitVPrefixedFormatter final : public V3OutFormatter {
std::ostream& m_os; std::ostream& m_os;
string m_prefix; // What to print at beginning of each line const string m_prefix; // What to print at beginning of each line
int m_flWidth; // Padding of fileline const int m_flWidth; // Padding of fileline
int m_column; // Rough location; need just zero or non-zero int m_column; // Rough location; need just zero or non-zero
FileLine* m_prefixFl; FileLine* m_prefixFl;
// METHODS // METHODS

View File

@ -409,7 +409,7 @@ private:
<< nodep->fileline()->xmlDetailedLocation() << " name=\"" << nodep->name() << "\"" << nodep->fileline()->xmlDetailedLocation() << " name=\"" << nodep->name() << "\""
<< " submodname=\"" << nodep->modName() << "\"" << " submodname=\"" << nodep->modName() << "\""
<< " hier=\"" << m_hier + nodep->name() << "\""; << " hier=\"" << m_hier + nodep->name() << "\"";
std::string hier = m_hier; const std::string hier = m_hier;
m_hier += nodep->name() + "."; m_hier += nodep->name() + ".";
m_hasChildren = false; m_hasChildren = false;
iterateChildren(nodep->modp()); iterateChildren(nodep->modp());
@ -455,10 +455,10 @@ void V3EmitXml::emitxml() {
} }
{ {
std::stringstream sstr; std::stringstream sstr;
ModuleFilesXmlVisitor moduleFilesVisitor{v3Global.rootp(), sstr}; const ModuleFilesXmlVisitor moduleFilesVisitor{v3Global.rootp(), sstr};
HierCellsXmlVisitor cellsVisitor{v3Global.rootp(), sstr}; const HierCellsXmlVisitor cellsVisitor{v3Global.rootp(), sstr};
of.puts(sstr.str()); of.puts(sstr.str());
} }
EmitXmlFileVisitor visitor{v3Global.rootp(), &of}; const EmitXmlFileVisitor visitor{v3Global.rootp(), &of};
of.puts("</verilator_xml>\n"); of.puts("</verilator_xml>\n");
} }

View File

@ -54,7 +54,7 @@ v3errorIniter v3errorInit;
V3ErrorCode::V3ErrorCode(const char* msgp) { V3ErrorCode::V3ErrorCode(const char* msgp) {
// Return error encoding for given string, or ERROR, which is a bad code // Return error encoding for given string, or ERROR, which is a bad code
for (int codei = V3ErrorCode::EC_MIN; codei < V3ErrorCode::_ENUM_MAX; codei++) { for (int codei = V3ErrorCode::EC_MIN; codei < V3ErrorCode::_ENUM_MAX; codei++) {
V3ErrorCode code = V3ErrorCode(codei); const V3ErrorCode code = V3ErrorCode(codei);
if (0 == VL_STRCASECMP(msgp, code.ascii())) { if (0 == VL_STRCASECMP(msgp, code.ascii())) {
m_e = code; m_e = code;
return; return;
@ -131,7 +131,7 @@ bool V3Error::isError(V3ErrorCode code, bool supp) {
} }
string V3Error::msgPrefix() { string V3Error::msgPrefix() {
V3ErrorCode code = s_errorCode; const V3ErrorCode code = s_errorCode;
const bool supp = s_errorSuppressed; const bool supp = s_errorSuppressed;
if (supp) { if (supp) {
return "-arning-suppressed: "; return "-arning-suppressed: ";

View File

@ -678,10 +678,10 @@ private:
newp = new AstNegate{fl, lhsp}; newp = new AstNegate{fl, lhsp};
} else { } else {
UINFO(8, " REPLICATE " << nodep << endl); UINFO(8, " REPLICATE " << nodep << endl);
const AstConst* constp = VN_AS(nodep->rhsp(), Const); const AstConst* const constp = VN_AS(nodep->rhsp(), Const);
UASSERT_OBJ(constp, nodep, UASSERT_OBJ(constp, nodep,
"Replication value isn't a constant. Checked earlier!"); "Replication value isn't a constant. Checked earlier!");
uint32_t times = constp->toUInt(); const uint32_t times = constp->toUInt();
if (nodep->isQuad() && !lhsp->isQuad()) { lhsp = new AstCCast{fl, lhsp, nodep}; } if (nodep->isQuad() && !lhsp->isQuad()) { lhsp = new AstCCast{fl, lhsp, nodep}; }
newp = lhsp->cloneTree(true); newp = lhsp->cloneTree(true);
for (unsigned repnum = 1; repnum < times; repnum++) { for (unsigned repnum = 1; repnum < times; repnum++) {

View File

@ -66,9 +66,9 @@ class V3FileDependImp final {
// TYPES // TYPES
class DependFile final { class DependFile final {
// A single file // A single file
bool m_target; // True if write, else read const bool m_target; // True if write, else read
bool m_exists = true; bool m_exists = true;
string m_filename; // Filename const string m_filename; // Filename
struct stat m_stat; // Stat information struct stat m_stat; // Stat information
public: public:
DependFile(const string& filename, bool target) DependFile(const string& filename, bool target)
@ -335,7 +335,7 @@ class VInFilterImp final {
#ifdef INFILTER_PIPE #ifdef INFILTER_PIPE
pid_t m_pid = 0; // fork() process id pid_t m_pid = 0; // fork() process id
#else #else
int m_pid = 0; // fork() process id - always zero as disabled const int m_pid = 0; // fork() process id - always zero as disabled
#endif #endif
bool m_pidExited = false; bool m_pidExited = false;
int m_pidStatus = 0; int m_pidStatus = 0;
@ -632,7 +632,7 @@ string V3OutFormatter::indentSpaces(int num) {
--num; --num;
} }
*cp++ = '\0'; *cp++ = '\0';
string st(str); string st{str}; // No const, move optimization
return st; return st;
} }
@ -1053,7 +1053,7 @@ public:
private: private:
void trySep(const string& old, string::size_type start, const string& trySep, void trySep(const string& old, string::size_type start, const string& trySep,
string::size_type& posr, string& separatorr) { string::size_type& posr, string& separatorr) {
string::size_type trypos = old.find(trySep, start); const string::size_type trypos = old.find(trySep, start);
if (trypos != string::npos) { if (trypos != string::npos) {
if (posr == string::npos || (posr > trypos)) { if (posr == string::npos || (posr > trypos)) {
posr = trypos; posr = trypos;

View File

@ -113,8 +113,8 @@ public:
private: private:
// MEMBERS // MEMBERS
string m_filename; const string m_filename;
Language m_lang; // Indenting Verilog code const Language m_lang; // Indenting Verilog code
int m_blockIndent; // Characters per block indent int m_blockIndent; // Characters per block indent
int m_commaWidth; // Width after which to break at ,'s int m_commaWidth; // Width after which to break at ,'s
int m_lineno = 1; int m_lineno = 1;

View File

@ -101,9 +101,9 @@ void VFileContent::pushText(const string& text) {
// Insert line-by-line // Insert line-by-line
string::size_type line_start = 0; string::size_type line_start = 0;
while (true) { while (true) {
string::size_type line_end = leftover.find('\n', line_start); const string::size_type line_end = leftover.find('\n', line_start);
if (line_end != string::npos) { if (line_end != string::npos) {
string oneline(leftover, line_start, line_end - line_start + 1); const string oneline(leftover, line_start, line_end - line_start + 1);
m_lines.push_back(oneline); // Keeps newline m_lines.push_back(oneline); // Keeps newline
UINFO(9, "PushStream[ct" << m_id << "+" << (m_lines.size() - 1) << "]: " << oneline); UINFO(9, "PushStream[ct" << m_id << "+" << (m_lines.size() - 1) << "]: " << oneline);
line_start = line_end + 1; line_start = line_end + 1;
@ -148,7 +148,7 @@ FileLine::FileLine(FileLine::EmptySecret) {
m_warnOn = 0; m_warnOn = 0;
for (int codei = V3ErrorCode::EC_MIN; codei < V3ErrorCode::_ENUM_MAX; codei++) { for (int codei = V3ErrorCode::EC_MIN; codei < V3ErrorCode::_ENUM_MAX; codei++) {
V3ErrorCode code = V3ErrorCode(codei); const V3ErrorCode code = V3ErrorCode(codei);
warnOff(code, code.defaultsOff()); warnOff(code, code.defaultsOff());
} }
} }
@ -264,8 +264,8 @@ string FileLine::filebasenameNoExt() const {
} }
string FileLine::firstColumnLetters() const { string FileLine::firstColumnLetters() const {
char a = ((firstColumn() / 26) % 26) + 'a'; const char a = ((firstColumn() / 26) % 26) + 'a';
char b = (firstColumn() % 26) + 'a'; const char b = (firstColumn() % 26) + 'a';
return string(1, a) + string(1, b); return string(1, a) + string(1, b);
} }
@ -297,7 +297,7 @@ std::ostream& operator<<(std::ostream& os, FileLine* fileline) {
} }
bool FileLine::warnOff(const string& msg, bool flag) { bool FileLine::warnOff(const string& msg, bool flag) {
V3ErrorCode code(msg.c_str()); const V3ErrorCode code(msg.c_str());
if (code < V3ErrorCode::EC_FIRST_WARN) { if (code < V3ErrorCode::EC_FIRST_WARN) {
return false; return false;
} else { } else {
@ -308,14 +308,14 @@ bool FileLine::warnOff(const string& msg, bool flag) {
void FileLine::warnLintOff(bool flag) { void FileLine::warnLintOff(bool flag) {
for (int codei = V3ErrorCode::EC_MIN; codei < V3ErrorCode::_ENUM_MAX; codei++) { for (int codei = V3ErrorCode::EC_MIN; codei < V3ErrorCode::_ENUM_MAX; codei++) {
V3ErrorCode code = V3ErrorCode(codei); const V3ErrorCode code = V3ErrorCode(codei);
if (code.lintError()) warnOff(code, flag); if (code.lintError()) warnOff(code, flag);
} }
} }
void FileLine::warnStyleOff(bool flag) { void FileLine::warnStyleOff(bool flag) {
for (int codei = V3ErrorCode::EC_MIN; codei < V3ErrorCode::_ENUM_MAX; codei++) { for (int codei = V3ErrorCode::EC_MIN; codei < V3ErrorCode::_ENUM_MAX; codei++) {
V3ErrorCode code = V3ErrorCode(codei); const V3ErrorCode code = V3ErrorCode(codei);
if (code.styleError()) warnOff(code, flag); if (code.styleError()) warnOff(code, flag);
} }
} }
@ -334,7 +334,7 @@ bool FileLine::warnIsOff(V3ErrorCode code) const {
void FileLine::modifyStateInherit(const FileLine* fromp) { void FileLine::modifyStateInherit(const FileLine* fromp) {
// Any warnings that are off in "from", become off in "this". // Any warnings that are off in "from", become off in "this".
for (int codei = V3ErrorCode::EC_MIN; codei < V3ErrorCode::_ENUM_MAX; codei++) { for (int codei = V3ErrorCode::EC_MIN; codei < V3ErrorCode::_ENUM_MAX; codei++) {
V3ErrorCode code = V3ErrorCode(codei); const V3ErrorCode code = V3ErrorCode(codei);
if (fromp->warnIsOff(code)) warnOff(code, true); if (fromp->warnIsOff(code)) warnOff(code, true);
} }
} }
@ -388,7 +388,7 @@ string FileLine::source() const {
string FileLine::prettySource() const { string FileLine::prettySource() const {
string out = source(); string out = source();
// Drop ignore trailing newline // Drop ignore trailing newline
string::size_type pos = out.find('\n'); const string::size_type pos = out.find('\n');
if (pos != string::npos) out = string(out, 0, pos); if (pos != string::npos) out = string(out, 0, pos);
// Column tracking counts tabs = 1, so match that when print source // Column tracking counts tabs = 1, so match that when print source
return VString::spaceUnprintable(out); return VString::spaceUnprintable(out);

View File

@ -166,7 +166,7 @@ public:
class GateLogicVertex final : public GateEitherVertex { class GateLogicVertex final : public GateEitherVertex {
AstNode* const m_nodep; AstNode* const m_nodep;
AstActive* const m_activep; // Under what active; nullptr is ok (under cfunc or such) AstActive* const m_activep; // Under what active; nullptr is ok (under cfunc or such)
bool m_slow; // In slow block const bool m_slow; // In slow block
public: public:
GateLogicVertex(V3Graph* graphp, AstScope* scopep, AstNode* nodep, AstActive* activep, GateLogicVertex(V3Graph* graphp, AstScope* scopep, AstNode* nodep, AstActive* activep,
bool slow) bool slow)
@ -200,7 +200,8 @@ private:
AstNode* m_substTreep = nullptr; // What to replace the variable with AstNode* m_substTreep = nullptr; // What to replace the variable with
// STATE // STATE
bool m_buffersOnly; // Set when we only allow simple buffering, no equations (for clocks) bool m_buffersOnly; // Set when we only allow simple buffering, no equations (for clocks)
AstNodeVarRef* m_lhsVarRef = nullptr; // VarRef on lhs of assignment (what we're replacing) const AstNodeVarRef* m_lhsVarRef
= nullptr; // VarRef on lhs of assignment (what we're replacing)
bool m_dedupe; // Set when we use isGateDedupable instead of isGateOptimizable bool m_dedupe; // Set when we use isGateDedupable instead of isGateOptimizable
int m_ops = 0; // Operation count int m_ops = 0; // Operation count
@ -315,7 +316,7 @@ private:
V3Graph m_graph; // Scoreboard of var usages/dependencies V3Graph m_graph; // Scoreboard of var usages/dependencies
GateLogicVertex* m_logicVertexp = nullptr; // Current statement being tracked, nullptr=ignored GateLogicVertex* m_logicVertexp = nullptr; // Current statement being tracked, nullptr=ignored
AstScope* m_scopep = nullptr; // Current scope being processed AstScope* m_scopep = nullptr; // Current scope being processed
AstNodeModule* m_modp = nullptr; // Current module const AstNodeModule* m_modp = nullptr; // Current module
AstActive* m_activep = nullptr; // Current active AstActive* m_activep = nullptr; // Current active
bool m_activeReducible = true; // Is activation block reducible? bool m_activeReducible = true; // Is activation block reducible?
bool m_inSenItem = false; // Underneath AstSenItem; any varrefs are clocks bool m_inSenItem = false; // Underneath AstSenItem; any varrefs are clocks
@ -568,7 +569,7 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) {
AstNode* logicp = logicVertexp->nodep(); AstNode* logicp = logicVertexp->nodep();
if (logicVertexp->reducible()) { if (logicVertexp->reducible()) {
// Can we eliminate? // Can we eliminate?
GateOkVisitor okVisitor{logicp, vvertexp->isClock(), false}; const GateOkVisitor okVisitor{logicp, vvertexp->isClock(), false};
const bool multiInputs = okVisitor.rhsVarRefs().size() > 1; const bool multiInputs = okVisitor.rhsVarRefs().size() > 1;
// Was it ok? // Was it ok?
bool doit = okVisitor.isSimple(); bool doit = okVisitor.isSimple();
@ -651,7 +652,7 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) {
} }
if (removedAllUsages) { if (removedAllUsages) {
// Remove input links // Remove input links
while (V3GraphEdge* edgep = vvertexp->inBeginp()) { while (V3GraphEdge* const edgep = vvertexp->inBeginp()) {
VL_DO_DANGLING(edgep->unlinkDelete(), edgep); VL_DO_DANGLING(edgep->unlinkDelete(), edgep);
} }
// Clone tree so we remember it for tracing, and keep the pointer // Clone tree so we remember it for tracing, and keep the pointer
@ -825,7 +826,7 @@ class GateElimVisitor final : public GateBaseVisitor {
private: private:
// NODE STATE // NODE STATE
// STATE // STATE
AstVarScope* m_elimVarScp; // Variable being eliminated const AstVarScope* m_elimVarScp; // Variable being eliminated
AstNode* m_replaceTreep; // What to replace the variable with AstNode* m_replaceTreep; // What to replace the variable with
bool m_didReplace; // Did we do any replacements bool m_didReplace; // Did we do any replacements
GateDedupeVarVisitor* m_varVisp; // Callback to keep hash up to date GateDedupeVarVisitor* m_varVisp; // Callback to keep hash up to date
@ -881,7 +882,7 @@ public:
void GateVisitor::optimizeElimVar(AstVarScope* varscp, AstNode* substp, AstNode* consumerp) { void GateVisitor::optimizeElimVar(AstVarScope* varscp, AstNode* substp, AstNode* consumerp) {
if (debug() >= 5) consumerp->dumpTree(cout, " elimUsePre: "); if (debug() >= 5) consumerp->dumpTree(cout, " elimUsePre: ");
GateElimVisitor elimVisitor{consumerp, varscp, substp, nullptr}; const GateElimVisitor elimVisitor{consumerp, varscp, substp, nullptr};
if (elimVisitor.didReplace()) { if (elimVisitor.didReplace()) {
if (debug() >= 9) consumerp->dumpTree(cout, " elimUseCns: "); if (debug() >= 9) consumerp->dumpTree(cout, " elimUseCns: ");
// Caution: Can't let V3Const change our handle to consumerp, such as by // Caution: Can't let V3Const change our handle to consumerp, such as by
@ -978,7 +979,8 @@ public:
&& node1p->user2p()->type() == node2p->user2p()->type(); && node1p->user2p()->type() == node2p->user2p()->type();
} }
AstNodeAssign* hashAndFindDupe(AstNodeAssign* assignp, AstNode* extra1p, AstNode* extra2p) { const AstNodeAssign* hashAndFindDupe(AstNodeAssign* assignp, AstNode* extra1p,
AstNode* extra2p) {
// Legal for extra1p/2p to be nullptr, we'll compare with other assigns with extras also // Legal for extra1p/2p to be nullptr, we'll compare with other assigns with extras also
// nullptr // nullptr
AstNode* const rhsp = assignp->rhsp(); AstNode* const rhsp = assignp->rhsp();
@ -1094,7 +1096,7 @@ public:
m_dedupable = true; m_dedupable = true;
iterate(nodep); iterate(nodep);
if (m_dedupable && m_assignp) { if (m_dedupable && m_assignp) {
AstNode* const lhsp = m_assignp->lhsp(); const AstNode* const lhsp = m_assignp->lhsp();
// Possible todo, handle more complex lhs expressions // Possible todo, handle more complex lhs expressions
if (const AstNodeVarRef* const lhsVarRefp = VN_CAST(lhsp, NodeVarRef)) { if (const AstNodeVarRef* const lhsVarRefp = VN_CAST(lhsp, NodeVarRef)) {
UASSERT_OBJ(lhsVarRefp->varScopep() == consumerVarScopep, consumerVarScopep, UASSERT_OBJ(lhsVarRefp->varScopep() == consumerVarScopep, consumerVarScopep,
@ -1141,12 +1143,12 @@ private:
AstNodeVarRef* const dupVarRefp = static_cast<AstNodeVarRef*>( AstNodeVarRef* const dupVarRefp = static_cast<AstNodeVarRef*>(
vvertexp->iterateInEdges(*this, VNUser(vvertexp)).toNodep()); vvertexp->iterateInEdges(*this, VNUser(vvertexp)).toNodep());
if (dupVarRefp) { // visit(GateLogicVertex*...) returned match if (dupVarRefp) { // visit(GateLogicVertex*...) returned match
V3GraphEdge* edgep = vvertexp->inBeginp(); const V3GraphEdge* edgep = vvertexp->inBeginp();
GateLogicVertex* const lvertexp = static_cast<GateLogicVertex*>(edgep->fromp()); GateLogicVertex* const lvertexp = static_cast<GateLogicVertex*>(edgep->fromp());
UASSERT_OBJ(vvertexp->dedupable(), vvertexp->varScp(), UASSERT_OBJ(vvertexp->dedupable(), vvertexp->varScp(),
"GateLogicVertex* visit should have returned nullptr " "GateLogicVertex* visit should have returned nullptr "
"if consumer var vertex is not dedupable."); "if consumer var vertex is not dedupable.");
GateOkVisitor okVisitor{lvertexp->nodep(), false, true}; const GateOkVisitor okVisitor{lvertexp->nodep(), false, true};
if (okVisitor.isSimple()) { if (okVisitor.isSimple()) {
const AstVarScope* const dupVarScopep = dupVarRefp->varScopep(); const AstVarScope* const dupVarScopep = dupVarRefp->varScopep();
GateVarVertex* const dupVvertexp GateVarVertex* const dupVvertexp
@ -1169,15 +1171,15 @@ private:
if (lvertexp == consumeVertexp) { if (lvertexp == consumeVertexp) {
UINFO(9, "skipping as self-recirculates\n"); UINFO(9, "skipping as self-recirculates\n");
} else { } else {
GateElimVisitor elimVisitor(consumerp, vvertexp->varScp(), dupVarRefp, const GateElimVisitor elimVisitor(consumerp, vvertexp->varScp(),
&m_varVisitor); dupVarRefp, &m_varVisitor);
} }
outedgep = outedgep->relinkFromp(dupVvertexp); outedgep = outedgep->relinkFromp(dupVvertexp);
} }
// Propagate attributes // Propagate attributes
dupVvertexp->propagateAttrClocksFrom(vvertexp); dupVvertexp->propagateAttrClocksFrom(vvertexp);
// Remove inputs links // Remove inputs links
while (V3GraphEdge* inedgep = vvertexp->inBeginp()) { while (V3GraphEdge* const inedgep = vvertexp->inBeginp()) {
VL_DO_DANGLING(inedgep->unlinkDelete(), inedgep); VL_DO_DANGLING(inedgep->unlinkDelete(), inedgep);
} }
// replaceAssigns() does the deleteTree on lvertexNodep in a later step // replaceAssigns() does the deleteTree on lvertexNodep in a later step
@ -1252,7 +1254,7 @@ class GateMergeAssignsGraphVisitor final : public GateGraphBaseVisitor {
private: private:
// NODE STATE // NODE STATE
AstNodeAssign* m_assignp = nullptr; AstNodeAssign* m_assignp = nullptr;
AstActive* m_activep = nullptr; const AstActive* m_activep = nullptr;
GateLogicVertex* m_logicvp = nullptr; GateLogicVertex* m_logicvp = nullptr;
VDouble0 m_numMergedAssigns; // Statistic tracking VDouble0 m_numMergedAssigns; // Statistic tracking
@ -1382,7 +1384,7 @@ void GateVisitor::mergeAssigns() {
class GateConcatVisitor final : public GateBaseVisitor { class GateConcatVisitor final : public GateBaseVisitor {
private: private:
// STATE // STATE
AstVarScope* m_vscp = nullptr; // Varscope we're trying to find const AstVarScope* m_vscp = nullptr; // Varscope we're trying to find
int m_offset = 0; // Current offset of varscope int m_offset = 0; // Current offset of varscope
int m_found_offset = 0; // Found offset of varscope int m_found_offset = 0; // Found offset of varscope
bool m_found = false; // Offset found bool m_found = false; // Offset found
@ -1432,7 +1434,7 @@ public:
class GateClkDecompState final { class GateClkDecompState final {
public: public:
int m_offset; const int m_offset;
AstVarScope* const m_last_vsp; AstVarScope* const m_last_vsp;
GateClkDecompState(int offset, AstVarScope* vsp) GateClkDecompState(int offset, AstVarScope* vsp)
: m_offset{offset} : m_offset{offset}
@ -1460,7 +1462,7 @@ private:
m_seen_clk_vectors++; m_seen_clk_vectors++;
m_total_seen_clk_vectors++; m_total_seen_clk_vectors++;
} }
GateClkDecompState* const currState = reinterpret_cast<GateClkDecompState*>(vu.c()); const GateClkDecompState* const currState = reinterpret_cast<GateClkDecompState*>(vu.c());
GateClkDecompState nextState(currState->m_offset, vsp); GateClkDecompState nextState(currState->m_offset, vsp);
vvertexp->iterateCurrentOutEdges(*this, VNUser(&nextState)); vvertexp->iterateCurrentOutEdges(*this, VNUser(&nextState));
if (vsp->varp()->width() > 1) --m_seen_clk_vectors; if (vsp->varp()->width() > 1) --m_seen_clk_vectors;
@ -1469,13 +1471,13 @@ private:
} }
virtual VNUser visit(GateLogicVertex* lvertexp, VNUser vu) override { virtual VNUser visit(GateLogicVertex* lvertexp, VNUser vu) override {
GateClkDecompState* const currState = reinterpret_cast<GateClkDecompState*>(vu.c()); const GateClkDecompState* const currState = reinterpret_cast<GateClkDecompState*>(vu.c());
int clk_offset = currState->m_offset; int clk_offset = currState->m_offset;
if (const AstAssignW* const assignp = VN_CAST(lvertexp->nodep(), AssignW)) { if (const AstAssignW* const assignp = VN_CAST(lvertexp->nodep(), AssignW)) {
UINFO(9, "CLK DECOMP Logic (off = " << clk_offset << ") - " << lvertexp << " : " UINFO(9, "CLK DECOMP Logic (off = " << clk_offset << ") - " << lvertexp << " : "
<< m_clk_vsp << endl); << m_clk_vsp << endl);
// RHS // RHS
if (AstSel* const rselp = VN_CAST(assignp->rhsp(), Sel)) { if (const AstSel* const rselp = VN_CAST(assignp->rhsp(), Sel)) {
if (VN_IS(rselp->lsbp(), Const) && VN_IS(rselp->widthp(), Const)) { if (VN_IS(rselp->lsbp(), Const) && VN_IS(rselp->widthp(), Const)) {
if (clk_offset < rselp->lsbConst() || clk_offset > rselp->msbConst()) { if (clk_offset < rselp->lsbConst() || clk_offset > rselp->msbConst()) {
UINFO(9, "CLK DECOMP Sel [ " << rselp->msbConst() << " : " UINFO(9, "CLK DECOMP Sel [ " << rselp->msbConst() << " : "
@ -1487,7 +1489,7 @@ private:
} else { } else {
return VNUser(0); return VNUser(0);
} }
} else if (AstConcat* catp = VN_CAST(assignp->rhsp(), Concat)) { } else if (AstConcat* const catp = VN_CAST(assignp->rhsp(), Concat)) {
UINFO(9, "CLK DECOMP Concat searching - " << assignp->lhsp() << endl); UINFO(9, "CLK DECOMP Concat searching - " << assignp->lhsp() << endl);
int concat_offset; int concat_offset;
if (!m_concat_visitor.concatOffset(catp, currState->m_last_vsp, if (!m_concat_visitor.concatOffset(catp, currState->m_last_vsp,
@ -1507,7 +1509,7 @@ private:
} else { } else {
return VNUser(0); return VNUser(0);
} }
} else if (const AstVarRef* vrp = VN_CAST(assignp->lhsp(), VarRef)) { } else if (const AstVarRef* const vrp = VN_CAST(assignp->lhsp(), VarRef)) {
if (vrp->dtypep()->width() == 1 && m_seen_clk_vectors) { if (vrp->dtypep()->width() == 1 && m_seen_clk_vectors) {
if (clk_offset != 0) { if (clk_offset != 0) {
UINFO(9, "Should only make it here with clk_offset = 0" << endl); UINFO(9, "Should only make it here with clk_offset = 0" << endl);
@ -1517,7 +1519,7 @@ private:
UINFO(9, " to - " << m_clk_vsp << endl); UINFO(9, " to - " << m_clk_vsp << endl);
AstNode* const rhsp = assignp->rhsp(); AstNode* const rhsp = assignp->rhsp();
rhsp->replaceWith(new AstVarRef(rhsp->fileline(), m_clk_vsp, VAccess::READ)); rhsp->replaceWith(new AstVarRef(rhsp->fileline(), m_clk_vsp, VAccess::READ));
while (V3GraphEdge* edgep = lvertexp->inBeginp()) { while (V3GraphEdge* const edgep = lvertexp->inBeginp()) {
VL_DO_DANGLING(edgep->unlinkDelete(), edgep); VL_DO_DANGLING(edgep->unlinkDelete(), edgep);
} }
new V3GraphEdge(m_graphp, m_clk_vvertexp, lvertexp, 1); new V3GraphEdge(m_graphp, m_clk_vvertexp, lvertexp, 1);
@ -1556,7 +1558,7 @@ void GateVisitor::decomposeClkVectors() {
GateClkDecompGraphVisitor decomposer{&m_graph}; GateClkDecompGraphVisitor decomposer{&m_graph};
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) { for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
if (GateVarVertex* const vertp = dynamic_cast<GateVarVertex*>(itp)) { if (GateVarVertex* const vertp = dynamic_cast<GateVarVertex*>(itp)) {
AstVarScope* const vsp = vertp->varScp(); const AstVarScope* const vsp = vertp->varScp();
if (vsp->varp()->attrClocker() == VVarAttrClocker::CLOCKER_YES) { if (vsp->varp()->attrClocker() == VVarAttrClocker::CLOCKER_YES) {
if (vsp->varp()->width() > 1) { if (vsp->varp()->width() > 1) {
UINFO(9, "Clocker > 1 bit, not decomposing: " << vsp << endl); UINFO(9, "Clocker > 1 bit, not decomposing: " << vsp << endl);
@ -1601,7 +1603,7 @@ public:
void V3Gate::gateAll(AstNetlist* nodep) { void V3Gate::gateAll(AstNetlist* nodep) {
UINFO(2, __FUNCTION__ << ": " << endl); UINFO(2, __FUNCTION__ << ": " << endl);
{ {
GateVisitor visitor{nodep}; const GateVisitor visitor{nodep};
GateDeassignVisitor{nodep}; GateDeassignVisitor{nodep};
} // Destruct before checking } // Destruct before checking
V3Global::dumpCheckGlobalTree("gate", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3); V3Global::dumpCheckGlobalTree("gate", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);

View File

@ -47,7 +47,7 @@ private:
const AstUser3InUse m_inuser3; const AstUser3InUse m_inuser3;
// STATE // STATE
AstActive* m_activep = nullptr; // Inside activate statement const AstActive* m_activep = nullptr; // Inside activate statement
AstNodeModule* const m_topModp; // Top module AstNodeModule* const m_topModp; // Top module
AstScope* const m_scopetopp = v3Global.rootp()->topScopep()->scopep(); // The top AstScope AstScope* const m_scopetopp = v3Global.rootp()->topScopep()->scopep(); // The top AstScope
@ -70,7 +70,7 @@ private:
UASSERT_OBJ(vscp != v3Global.rootp()->dpiExportTriggerp(), vscp, UASSERT_OBJ(vscp != v3Global.rootp()->dpiExportTriggerp(), vscp,
"DPI export trigger should not need __VinpClk"); "DPI export trigger should not need __VinpClk");
AstVar* const varp = vscp->varp(); AstVar* const varp = vscp->varp();
string newvarname const string newvarname
= "__VinpClk__" + vscp->scopep()->nameDotless() + "__" + varp->name(); = "__VinpClk__" + vscp->scopep()->nameDotless() + "__" + varp->name();
// Create: VARREF(inpclk) // Create: VARREF(inpclk)
// ... // ...
@ -145,8 +145,8 @@ private:
// STATE // STATE
bool m_tracingCall = false; // Iterating into a call to a cfunc bool m_tracingCall = false; // Iterating into a call to a cfunc
AstActive* m_activep = nullptr; // Inside activate statement const AstActive* m_activep = nullptr; // Inside activate statement
AstNodeAssign* m_assignp = nullptr; // Inside assigndly statement const AstNodeAssign* m_assignp = nullptr; // Inside assigndly statement
AstNodeModule* m_topModp = nullptr; // Top module AstNodeModule* m_topModp = nullptr; // Top module
// VISITORS // VISITORS

View File

@ -327,7 +327,7 @@ void V3Graph::dumpDotFile(const string& filename, bool colorAsSubgraph) const {
// List of all possible subgraphs // List of all possible subgraphs
std::multimap<std::string, V3GraphVertex*> subgraphs; std::multimap<std::string, V3GraphVertex*> subgraphs;
for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp = vertexp->verticesNextp()) { for (V3GraphVertex* vertexp = verticesBeginp(); vertexp; vertexp = vertexp->verticesNextp()) {
string vertexSubgraph const string vertexSubgraph
= (colorAsSubgraph && vertexp->color()) ? cvtToStr(vertexp->color()) : ""; = (colorAsSubgraph && vertexp->color()) ? cvtToStr(vertexp->color()) : "";
subgraphs.emplace(vertexSubgraph, vertexp); subgraphs.emplace(vertexSubgraph, vertexp);
} }
@ -341,7 +341,7 @@ void V3Graph::dumpDotFile(const string& filename, bool colorAsSubgraph) const {
string subgr; string subgr;
for (auto it = subgraphs.cbegin(); it != subgraphs.cend(); ++it) { for (auto it = subgraphs.cbegin(); it != subgraphs.cend(); ++it) {
const string vertexSubgraph = it->first; const string vertexSubgraph = it->first;
V3GraphVertex* vertexp = it->second; const V3GraphVertex* vertexp = it->second;
numMap[vertexp] = n; numMap[vertexp] = n;
if (subgr != vertexSubgraph) { if (subgr != vertexSubgraph) {
if (subgr != "") *logp << "\t};\n"; if (subgr != "") *logp << "\t};\n";

View File

@ -102,7 +102,8 @@ private:
V3Graph m_breakGraph; // Graph with only breakable edges represented V3Graph m_breakGraph; // Graph with only breakable edges represented
V3List<GraphAcycVertex*> m_work; // List of vertices with optimization work left V3List<GraphAcycVertex*> m_work; // List of vertices with optimization work left
std::vector<OrigEdgeList*> m_origEdgeDelp; // List of deletions to do when done std::vector<OrigEdgeList*> m_origEdgeDelp; // List of deletions to do when done
V3EdgeFuncP m_origEdgeFuncp; // Function that says we follow this edge (in original graph) const V3EdgeFuncP
m_origEdgeFuncp; // Function that says we follow this edge (in original graph)
uint32_t m_placeStep = 0; // Number that user() must be equal to to indicate processing uint32_t m_placeStep = 0; // Number that user() must be equal to to indicate processing
static int debug() { return V3Graph::debug(); } static int debug() { return V3Graph::debug(); }
@ -223,7 +224,7 @@ void GraphAcyc::buildGraphIterate(V3GraphVertex* overtexp, GraphAcycVertex* aver
// Make new edges // Make new edges
for (V3GraphEdge* edgep = overtexp->outBeginp(); edgep; edgep = edgep->outNextp()) { for (V3GraphEdge* edgep = overtexp->outBeginp(); edgep; edgep = edgep->outNextp()) {
if (origFollowEdge(edgep)) { // not cut if (origFollowEdge(edgep)) { // not cut
V3GraphVertex* toVertexp = edgep->top(); const V3GraphVertex* toVertexp = edgep->top();
if (toVertexp->color()) { if (toVertexp->color()) {
GraphAcycVertex* const toAVertexp GraphAcycVertex* const toAVertexp
= static_cast<GraphAcycVertex*>(toVertexp->userp()); = static_cast<GraphAcycVertex*>(toVertexp->userp());
@ -282,13 +283,13 @@ void GraphAcyc::simplifyNone(GraphAcycVertex* avertexp) {
UINFO(9, " SimplifyNoneRemove " << avertexp << endl); UINFO(9, " SimplifyNoneRemove " << avertexp << endl);
avertexp->setDelete(); // Mark so we won't delete it twice avertexp->setDelete(); // Mark so we won't delete it twice
// Remove edges // Remove edges
while (V3GraphEdge* edgep = avertexp->outBeginp()) { while (V3GraphEdge* const edgep = avertexp->outBeginp()) {
V3GraphVertex* otherVertexp = edgep->top(); V3GraphVertex* otherVertexp = edgep->top();
// UINFO(9, " out " << otherVertexp << endl); // UINFO(9, " out " << otherVertexp << endl);
VL_DO_DANGLING(edgep->unlinkDelete(), edgep); VL_DO_DANGLING(edgep->unlinkDelete(), edgep);
workPush(otherVertexp); workPush(otherVertexp);
} }
while (V3GraphEdge* edgep = avertexp->inBeginp()) { while (V3GraphEdge* const edgep = avertexp->inBeginp()) {
V3GraphVertex* otherVertexp = edgep->fromp(); V3GraphVertex* otherVertexp = edgep->fromp();
// UINFO(9, " in " << otherVertexp << endl); // UINFO(9, " in " << otherVertexp << endl);
VL_DO_DANGLING(edgep->unlinkDelete(), edgep); VL_DO_DANGLING(edgep->unlinkDelete(), edgep);
@ -484,7 +485,7 @@ void GraphAcyc::placeTryEdge(V3GraphEdge* edgep) {
// Vertex::m_user begin: number indicates this edge was completed // Vertex::m_user begin: number indicates this edge was completed
// Try to assign ranks, presuming this edge is in place // Try to assign ranks, presuming this edge is in place
// If we come across user()==placestep, we've detected a loop and must back out // If we come across user()==placestep, we've detected a loop and must back out
bool loop const bool loop
= placeIterate(static_cast<GraphAcycVertex*>(edgep->top()), edgep->fromp()->rank() + 1); = placeIterate(static_cast<GraphAcycVertex*>(edgep->top()), edgep->fromp()->rank() + 1);
if (!loop) { if (!loop) {
// No loop, we can keep it as uncutable // No loop, we can keep it as uncutable

View File

@ -31,7 +31,7 @@
// Algorithms - weakly connected components // Algorithms - weakly connected components
class GraphRemoveRedundant final : GraphAlg<> { class GraphRemoveRedundant final : GraphAlg<> {
bool m_sumWeights; ///< Sum, rather then maximize weights const bool m_sumWeights; ///< Sum, rather then maximize weights
private: private:
void main() { void main() {
for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp; for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp;
@ -213,7 +213,7 @@ private:
} }
void vertexIterate(V3GraphVertex* vertexp) { void vertexIterate(V3GraphVertex* vertexp) {
uint32_t thisDfsNum = m_currentDfs++; const uint32_t thisDfsNum = m_currentDfs++;
vertexp->user(thisDfsNum); vertexp->user(thisDfsNum);
vertexp->color(0); vertexp->color(0);
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) { for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) {

View File

@ -30,8 +30,8 @@
template <class T_Graph = V3Graph> // Or sometimes const V3Graph template <class T_Graph = V3Graph> // Or sometimes const V3Graph
class GraphAlg VL_NOT_FINAL { class GraphAlg VL_NOT_FINAL {
protected: protected:
T_Graph* m_graphp; // Graph we're operating upon T_Graph* const m_graphp; // Graph we're operating upon
V3EdgeFuncP m_edgeFuncp; // Function that says we follow this edge const V3EdgeFuncP m_edgeFuncp; // Function that says we follow this edge
// CONSTRUCTORS // CONSTRUCTORS
GraphAlg(T_Graph* graphp, V3EdgeFuncP edgeFuncp) GraphAlg(T_Graph* graphp, V3EdgeFuncP edgeFuncp)
: m_graphp{graphp} : m_graphp{graphp}

View File

@ -74,12 +74,12 @@ GraphPathChecker::~GraphPathChecker() {
void GraphPathChecker::initHalfCriticalPaths(GraphWay way, bool checkOnly) { void GraphPathChecker::initHalfCriticalPaths(GraphWay way, bool checkOnly) {
GraphStreamUnordered order(m_graphp, way); GraphStreamUnordered order(m_graphp, way);
const GraphWay rev = way.invert(); const GraphWay rev = way.invert();
while (const V3GraphVertex* vertexp = order.nextp()) { while (const V3GraphVertex* const vertexp = order.nextp()) {
unsigned critPathCost = 0; unsigned critPathCost = 0;
for (V3GraphEdge* edgep = vertexp->beginp(rev); edgep; edgep = edgep->nextp(rev)) { for (V3GraphEdge* edgep = vertexp->beginp(rev); edgep; edgep = edgep->nextp(rev)) {
if (!m_edgeFuncp(edgep)) continue; if (!m_edgeFuncp(edgep)) continue;
V3GraphVertex* wrelativep = edgep->furtherp(rev); const V3GraphVertex* wrelativep = edgep->furtherp(rev);
const GraphPCNode* const wrelUserp = static_cast<GraphPCNode*>(wrelativep->userp()); const GraphPCNode* const wrelUserp = static_cast<GraphPCNode*>(wrelativep->userp());
critPathCost = std::max(critPathCost, wrelUserp->m_cp[way] + 1); critPathCost = std::max(critPathCost, wrelUserp->m_cp[way] + 1);
} }

View File

@ -44,7 +44,7 @@ private:
public: public:
// MEMBERS // MEMBERS
const V3GraphVertex* m_vxp; // [mtask] Vertex const V3GraphVertex* m_vxp; // [mtask] Vertex
uint32_t m_pos; // Sort position const uint32_t m_pos; // Sort position
uint32_t m_numBlockingEdges; // Number of blocking edges uint32_t m_numBlockingEdges; // Number of blocking edges
// CONSTRUCTORS // CONSTRUCTORS
VxHolder(const V3GraphVertex* vxp, uint32_t pos, uint32_t numBlockingEdges) VxHolder(const V3GraphVertex* vxp, uint32_t pos, uint32_t numBlockingEdges)
@ -65,7 +65,7 @@ private:
class VxHolderCmp final { class VxHolderCmp final {
public: public:
// MEMBERS // MEMBERS
T_Compare m_lessThan; // Sorting functor const T_Compare m_lessThan; // Sorting functor
// CONSTRUCTORS // CONSTRUCTORS
explicit VxHolderCmp(const T_Compare& lessThan) explicit VxHolderCmp(const T_Compare& lessThan)
: m_lessThan{lessThan} {} : m_lessThan{lessThan} {}
@ -87,7 +87,7 @@ private:
ReadyVertices m_readyVertices; // List of ready vertices ReadyVertices m_readyVertices; // List of ready vertices
std::map<const V3GraphVertex*, VxHolder> m_waitingVertices; // List of waiting vertices std::map<const V3GraphVertex*, VxHolder> m_waitingVertices; // List of waiting vertices
typename ReadyVertices::iterator m_last; // Previously returned element typename ReadyVertices::iterator m_last; // Previously returned element
GraphWay m_way; // FORWARD or REVERSE order of traversal const GraphWay m_way; // FORWARD or REVERSE order of traversal
public: public:
// CONSTRUCTORS // CONSTRUCTORS
@ -106,26 +106,26 @@ public:
// Every vertex initially is waiting, or ready. // Every vertex initially is waiting, or ready.
if (way == GraphWay::FORWARD) { if (way == GraphWay::FORWARD) {
if (vxp->inEmpty()) { if (vxp->inEmpty()) {
VxHolder newVx(vxp, pos++, 0); const VxHolder newVx(vxp, pos++, 0);
m_readyVertices.insert(newVx); m_readyVertices.insert(newVx);
} else { } else {
uint32_t depCount = 0; uint32_t depCount = 0;
for (V3GraphEdge* depp = vxp->inBeginp(); depp; depp = depp->inNextp()) { for (V3GraphEdge* depp = vxp->inBeginp(); depp; depp = depp->inNextp()) {
++depCount; ++depCount;
} }
VxHolder newVx(vxp, pos++, depCount); const VxHolder newVx(vxp, pos++, depCount);
m_waitingVertices.emplace(vxp, newVx); m_waitingVertices.emplace(vxp, newVx);
} }
} else { // REVERSE } else { // REVERSE
if (vxp->outEmpty()) { if (vxp->outEmpty()) {
VxHolder newVx(vxp, pos++, 0); const VxHolder newVx(vxp, pos++, 0);
m_readyVertices.insert(newVx); m_readyVertices.insert(newVx);
} else { } else {
uint32_t depCount = 0; uint32_t depCount = 0;
for (V3GraphEdge* depp = vxp->outBeginp(); depp; depp = depp->outNextp()) { for (V3GraphEdge* depp = vxp->outBeginp(); depp; depp = depp->outNextp()) {
++depCount; ++depCount;
} }
VxHolder newVx(vxp, pos++, depCount); const VxHolder newVx(vxp, pos++, depCount);
m_waitingVertices.emplace(vxp, newVx); m_waitingVertices.emplace(vxp, newVx);
} }
} }
@ -194,7 +194,7 @@ private:
void unblockDeps(const V3GraphVertex* vertexp) { void unblockDeps(const V3GraphVertex* vertexp) {
if (m_way == GraphWay::FORWARD) { if (m_way == GraphWay::FORWARD) {
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) { for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) {
V3GraphVertex* const toVertexp = edgep->top(); const V3GraphVertex* const toVertexp = edgep->top();
const auto it = m_waitingVertices.find(toVertexp); const auto it = m_waitingVertices.find(toVertexp);
UASSERT_OBJ(it != m_waitingVertices.end(), toVertexp, UASSERT_OBJ(it != m_waitingVertices.end(), toVertexp,
@ -206,7 +206,7 @@ private:
} }
} else { } else {
for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) { for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) {
V3GraphVertex* const fromVertexp = edgep->fromp(); const V3GraphVertex* const fromVertexp = edgep->fromp();
const auto it = m_waitingVertices.find(fromVertexp); const auto it = m_waitingVertices.find(fromVertexp);
UASSERT_OBJ(it != m_waitingVertices.end(), fromVertexp, UASSERT_OBJ(it != m_waitingVertices.end(), fromVertexp,

View File

@ -50,7 +50,7 @@ public:
// Vertices and nodes // Vertices and nodes
class V3GraphTestVertex VL_NOT_FINAL : public V3GraphVertex { class V3GraphTestVertex VL_NOT_FINAL : public V3GraphVertex {
string m_name; const string m_name;
public: public:
V3GraphTestVertex(V3Graph* graphp, const string& name) V3GraphTestVertex(V3Graph* graphp, const string& name)

View File

@ -496,6 +496,6 @@ V3Hash V3Hasher::operator()(AstNode* nodep) const {
} }
V3Hash V3Hasher::uncachedHash(const AstNode* nodep) { V3Hash V3Hasher::uncachedHash(const AstNode* nodep) {
HasherVisitor visitor{nodep}; const HasherVisitor visitor{nodep};
return visitor.finalHash(); return visitor.finalHash();
} }

View File

@ -210,7 +210,7 @@ string V3HierBlock::vFileIfNecessary() const {
} }
void V3HierBlock::writeCommandArgsFile(bool forCMake) const { void V3HierBlock::writeCommandArgsFile(bool forCMake) const {
std::unique_ptr<std::ofstream> of{V3File::new_ofstream(commandArgsFileName(forCMake))}; const std::unique_ptr<std::ofstream> of{V3File::new_ofstream(commandArgsFileName(forCMake))};
*of << "--cc\n"; *of << "--cc\n";
if (!forCMake) { if (!forCMake) {
@ -279,7 +279,7 @@ class HierBlockUsageCollectVisitor final : public AstNVisitor {
virtual void visit(AstCell* nodep) override { virtual void visit(AstCell* nodep) override {
// Visit used module here to know that the module is hier_block or not. // Visit used module here to know that the module is hier_block or not.
// This visitor behaves almost depth first search // This visitor behaves almost depth first search
if (AstModule* modp = VN_CAST(nodep->modp(), Module)) { if (AstModule* const modp = VN_CAST(nodep->modp(), Module)) {
iterate(modp); iterate(modp);
m_referred.insert(modp); m_referred.insert(modp);
} }
@ -336,7 +336,7 @@ void V3HierBlockPlan::createPlan(AstNetlist* nodep) {
// When processing a hierarchical block, no need to create a plan anymore. // When processing a hierarchical block, no need to create a plan anymore.
if (v3Global.opt.hierChild()) return; if (v3Global.opt.hierChild()) return;
AstNodeModule* modp = nodep->topModulep(); AstNodeModule* const modp = nodep->topModulep();
if (modp->hierBlock()) { if (modp->hierBlock()) {
modp->v3warn(HIERBLOCK, modp->v3warn(HIERBLOCK,
"Top module illegally marked hierarchical block, ignoring marking\n" "Top module illegally marked hierarchical block, ignoring marking\n"
@ -400,7 +400,8 @@ void V3HierBlockPlan::writeCommandArgsFiles(bool forCMake) const {
it->second->writeCommandArgsFile(forCMake); it->second->writeCommandArgsFile(forCMake);
} }
// For the top module // For the top module
std::unique_ptr<std::ofstream> of{V3File::new_ofstream(topCommandArgsFileName(forCMake))}; const std::unique_ptr<std::ofstream> of{
V3File::new_ofstream(topCommandArgsFileName(forCMake))};
if (!forCMake) { if (!forCMake) {
// Load wrappers first not to be overwritten by the original HDL // Load wrappers first not to be overwritten by the original HDL
for (const_iterator it = begin(); it != end(); ++it) { for (const_iterator it = begin(); it != end(); ++it) {

View File

@ -49,13 +49,13 @@ private:
using StrGParams = std::vector<std::pair<std::string, std::string>>; using StrGParams = std::vector<std::pair<std::string, std::string>>;
// MEMBERS // MEMBERS
const AstNodeModule* m_modp; // Hierarchical block module const AstNodeModule* const m_modp; // Hierarchical block module
// Hierarchical blocks that directly or indirectly instantiate this block // Hierarchical blocks that directly or indirectly instantiate this block
HierBlockSet m_parents; HierBlockSet m_parents;
// Hierarchical blocks that this block directly or indirectly instantiates // Hierarchical blocks that this block directly or indirectly instantiates
HierBlockSet m_children; HierBlockSet m_children;
// Parameters that are overridden by #(.param(value)) syntax. // Parameters that are overridden by #(.param(value)) syntax.
GParams m_gparams; const GParams m_gparams;
// METHODS // METHODS
VL_UNCOPYABLE(V3HierBlock); VL_UNCOPYABLE(V3HierBlock);

View File

@ -271,7 +271,7 @@ private:
// STATE // STATE
std::unordered_set<std::string> m_renamedInterfaces; // Name of renamed interface variables std::unordered_set<std::string> m_renamedInterfaces; // Name of renamed interface variables
AstNodeModule* const m_modp; // Current module AstNodeModule* const m_modp; // Current module
AstCell* const m_cellp; // Cell being cloned const AstCell* const m_cellp; // Cell being cloned
// METHODS // METHODS
VL_DEBUG_FUNC; // Declare debug() VL_DEBUG_FUNC; // Declare debug()
@ -423,7 +423,7 @@ private:
break; break;
} }
// If foo.bar, and foo is an interface, then need to search again for foo // If foo.bar, and foo is an interface, then need to search again for foo
string::size_type pos = tryname.rfind('.'); const string::size_type pos = tryname.rfind('.');
if (pos == string::npos || pos == 0) { if (pos == string::npos || pos == 0) {
break; break;
} else { } else {

View File

@ -195,7 +195,7 @@ class InstDeVisitor final : public AstNVisitor {
private: private:
// STATE // STATE
// Range for arrayed instantiations, nullptr for normal instantiations // Range for arrayed instantiations, nullptr for normal instantiations
AstRange* m_cellRangep = nullptr; const AstRange* m_cellRangep = nullptr;
int m_instSelNum = 0; // Current instantiation count 0..N-1 int m_instSelNum = 0; // Current instantiation count 0..N-1
InstDeModVarVisitor m_deModVars; // State of variables for current cell module InstDeModVarVisitor m_deModVars; // State of variables for current cell module
@ -322,8 +322,10 @@ private:
UINFO(4, " PIN " << nodep << endl); UINFO(4, " PIN " << nodep << endl);
const int pinwidth = nodep->modVarp()->width(); const int pinwidth = nodep->modVarp()->width();
const int expwidth = nodep->exprp()->width(); const int expwidth = nodep->exprp()->width();
std::pair<uint32_t, uint32_t> pinDim = nodep->modVarp()->dtypep()->dimensions(false); const std::pair<uint32_t, uint32_t> pinDim
std::pair<uint32_t, uint32_t> expDim = nodep->exprp()->dtypep()->dimensions(false); = nodep->modVarp()->dtypep()->dimensions(false);
const std::pair<uint32_t, uint32_t> expDim
= nodep->exprp()->dtypep()->dimensions(false);
UINFO(4, " PINVAR " << nodep->modVarp() << endl); UINFO(4, " PINVAR " << nodep->modVarp() << endl);
UINFO(4, " EXP " << nodep->exprp() << endl); UINFO(4, " EXP " << nodep->exprp() << endl);
UINFO(4, " pinwidth ew=" << expwidth << " pw=" << pinwidth << " ed=" << expDim.first UINFO(4, " pinwidth ew=" << expwidth << " pw=" << pinwidth << " ed=" << expDim.first
@ -331,7 +333,7 @@ private:
<< pinDim.second << endl); << pinDim.second << endl);
if (expDim.first == pinDim.first && expDim.second == pinDim.second + 1) { if (expDim.first == pinDim.first && expDim.second == pinDim.second + 1) {
// Connection to array, where array dimensions match the instant dimension // Connection to array, where array dimensions match the instant dimension
AstRange* const rangep const AstRange* const rangep
= VN_AS(nodep->exprp()->dtypep(), UnpackArrayDType)->rangep(); = VN_AS(nodep->exprp()->dtypep(), UnpackArrayDType)->rangep();
const int arraySelNum = rangep->littleEndian() const int arraySelNum = rangep->littleEndian()
? (rangep->elementsConst() - 1 - m_instSelNum) ? (rangep->elementsConst() - 1 - m_instSelNum)
@ -366,8 +368,8 @@ private:
nodep->v3fatalSrc("Width mismatch; V3Width should have errored out."); nodep->v3fatalSrc("Width mismatch; V3Width should have errored out.");
} }
} // end expanding ranged cell } // end expanding ranged cell
else if (AstArraySel* arrselp = VN_CAST(nodep->exprp(), ArraySel)) { else if (AstArraySel* const arrselp = VN_CAST(nodep->exprp(), ArraySel)) {
if (AstUnpackArrayDType* const arrp if (const AstUnpackArrayDType* const arrp
= VN_CAST(arrselp->lhsp()->dtypep(), UnpackArrayDType)) { = VN_CAST(arrselp->lhsp()->dtypep(), UnpackArrayDType)) {
if (!VN_IS(arrp->subDTypep(), IfaceRefDType)) return; if (!VN_IS(arrp->subDTypep(), IfaceRefDType)) return;
// Interface pin attaches to one element of arrayed interface // Interface pin attaches to one element of arrayed interface
@ -382,7 +384,7 @@ private:
const string index = AstNode::encodeNumber(constp->toSInt()); const string index = AstNode::encodeNumber(constp->toSInt());
if (VN_IS(arrselp->lhsp(), SliceSel)) if (VN_IS(arrselp->lhsp(), SliceSel))
arrselp->lhsp()->v3error("Unsupported: interface slices"); arrselp->lhsp()->v3error("Unsupported: interface slices");
AstVarRef* const varrefp = VN_CAST(arrselp->lhsp(), VarRef); const AstVarRef* const varrefp = VN_CAST(arrselp->lhsp(), VarRef);
UASSERT_OBJ(varrefp, arrselp, "No interface varref under array"); UASSERT_OBJ(varrefp, arrselp, "No interface varref under array");
AstVarXRef* const newp = new AstVarXRef( AstVarXRef* const newp = new AstVarXRef(
nodep->fileline(), varrefp->name() + "__BRA__" + index + "__KET__", "", nodep->fileline(), varrefp->name() + "__BRA__" + index + "__KET__", "",
@ -394,7 +396,8 @@ private:
} }
} else { } else {
AstVar* const pinVarp = nodep->modVarp(); AstVar* const pinVarp = nodep->modVarp();
AstUnpackArrayDType* const pinArrp = VN_CAST(pinVarp->dtypep(), UnpackArrayDType); const AstUnpackArrayDType* const pinArrp
= VN_CAST(pinVarp->dtypep(), UnpackArrayDType);
if (!pinArrp || !VN_IS(pinArrp->subDTypep(), IfaceRefDType)) return; if (!pinArrp || !VN_IS(pinArrp->subDTypep(), IfaceRefDType)) return;
// Arrayed pin/var attaches to arrayed submodule lower port/var, expand it // Arrayed pin/var attaches to arrayed submodule lower port/var, expand it
AstNode* prevp = nullptr; AstNode* prevp = nullptr;
@ -402,7 +405,7 @@ private:
// Clone the var referenced by the pin, and clone each var referenced by the varref // Clone the var referenced by the pin, and clone each var referenced by the varref
// Clone pin varp: // Clone pin varp:
for (int in = 0; in < pinArrp->elementsConst(); ++in) { // 0 = leftmost for (int in = 0; in < pinArrp->elementsConst(); ++in) { // 0 = leftmost
int i = pinArrp->left() + in * pinArrp->declRange().leftToRightInc(); const int i = pinArrp->left() + in * pinArrp->declRange().leftToRightInc();
const string varNewName = pinVarp->name() + "__BRA__" + cvtToStr(i) + "__KET__"; const string varNewName = pinVarp->name() + "__BRA__" + cvtToStr(i) + "__KET__";
AstVar* varNewp = nullptr; AstVar* varNewp = nullptr;
@ -437,17 +440,18 @@ private:
// And replace exprp with a new varxref // And replace exprp with a new varxref
const AstVarRef* varrefp = VN_CAST(newp->exprp(), VarRef); // Maybe null const AstVarRef* varrefp = VN_CAST(newp->exprp(), VarRef); // Maybe null
int expr_i = i; int expr_i = i;
if (AstSliceSel* const slicep = VN_CAST(newp->exprp(), SliceSel)) { if (const AstSliceSel* const slicep = VN_CAST(newp->exprp(), SliceSel)) {
varrefp = VN_AS(slicep->fromp(), VarRef); varrefp = VN_AS(slicep->fromp(), VarRef);
UASSERT(VN_IS(slicep->rhsp(), Const), "Slices should be constant"); UASSERT(VN_IS(slicep->rhsp(), Const), "Slices should be constant");
int slice_index const int slice_index
= slicep->declRange().left() + in * slicep->declRange().leftToRightInc(); = slicep->declRange().left() + in * slicep->declRange().leftToRightInc();
auto* const exprArrp = VN_AS(varrefp->dtypep(), UnpackArrayDType); const auto* const exprArrp = VN_AS(varrefp->dtypep(), UnpackArrayDType);
UASSERT_OBJ(exprArrp, slicep, "Slice of non-array"); UASSERT_OBJ(exprArrp, slicep, "Slice of non-array");
expr_i = slice_index + exprArrp->lo(); expr_i = slice_index + exprArrp->lo();
} else if (!varrefp) { } else if (!varrefp) {
newp->exprp()->v3error("Unexpected connection to arrayed port"); newp->exprp()->v3error("Unexpected connection to arrayed port");
} else if (auto* exprArrp = VN_CAST(varrefp->dtypep(), UnpackArrayDType)) { } else if (const auto* const exprArrp
= VN_CAST(varrefp->dtypep(), UnpackArrayDType)) {
expr_i = exprArrp->left() + in * exprArrp->declRange().leftToRightInc(); expr_i = exprArrp->left() + in * exprArrp->declRange().leftToRightInc();
} }
@ -526,10 +530,11 @@ public:
return nullptr; return nullptr;
} }
} }
AstVarRef* const connectRefp = VN_CAST(pinp->exprp(), VarRef); const AstVarRef* const connectRefp = VN_CAST(pinp->exprp(), VarRef);
AstVarXRef* const connectXRefp = VN_CAST(pinp->exprp(), VarXRef); const AstVarXRef* const connectXRefp = VN_CAST(pinp->exprp(), VarXRef);
AstBasicDType* const pinBasicp = VN_CAST(pinVarp->dtypep(), BasicDType); // Maybe nullptr const AstBasicDType* const pinBasicp
AstBasicDType* connBasicp = nullptr; = VN_CAST(pinVarp->dtypep(), BasicDType); // Maybe nullptr
const AstBasicDType* connBasicp = nullptr;
AstAssignW* assignp = nullptr; AstAssignW* assignp = nullptr;
if (connectRefp) connBasicp = VN_CAST(connectRefp->varp()->dtypep(), BasicDType); if (connectRefp) connBasicp = VN_CAST(connectRefp->varp()->dtypep(), BasicDType);
// //
@ -554,7 +559,7 @@ public:
// if (1 || debug() >= 9) pinp->dumpTree(cout, "-in_pin:"); // if (1 || debug() >= 9) pinp->dumpTree(cout, "-in_pin:");
V3Inst::checkOutputShort(pinp); V3Inst::checkOutputShort(pinp);
AstNode* const pinexprp = pinp->exprp()->unlinkFrBack(); AstNode* const pinexprp = pinp->exprp()->unlinkFrBack();
string newvarname const string newvarname
= (string(pinVarp->isWritable() ? "__Vcellout" : "__Vcellinp") = (string(pinVarp->isWritable() ? "__Vcellout" : "__Vcellinp")
// Prevent name conflict if both tri & non-tri add signals // Prevent name conflict if both tri & non-tri add signals
+ (forTristate ? "t" : "") + "__" + cellp->name() + "__" + pinp->name()); + (forTristate ? "t" : "") + "__" + cellp->name() + "__" + pinp->name());

View File

@ -41,8 +41,8 @@ private:
const AstNode* const m_startNodep; // Start node of count const AstNode* const m_startNodep; // Start node of count
bool m_tracingCall = false; // Iterating into a CCall to a CFunc bool m_tracingCall = false; // Iterating into a CCall to a CFunc
bool m_inCFunc = false; // Inside AstCFunc bool m_inCFunc = false; // Inside AstCFunc
bool m_assertNoDups; // Check for duplicates const bool m_assertNoDups; // Check for duplicates
std::ostream* m_osp; // Dump file const std::ostream* m_osp; // Dump file
// TYPES // TYPES
// Little class to cleanly call startVisitBase/endVisitBase // Little class to cleanly call startVisitBase/endVisitBase
@ -102,7 +102,7 @@ private:
// Save the count, and add it back in during ~VisitBase This allows // Save the count, and add it back in during ~VisitBase This allows
// debug prints to show local cost of each subtree, so we can see a // debug prints to show local cost of each subtree, so we can see a
// hierarchical view of the cost when in debug mode. // hierarchical view of the cost when in debug mode.
uint32_t savedCount = m_instrCount; const uint32_t savedCount = m_instrCount;
m_instrCount = nodep->instrCount(); m_instrCount = nodep->instrCount();
return savedCount; return savedCount;
} }
@ -124,7 +124,7 @@ private:
// //
// Hence, exclude the child of the AstWordSel from the computation, // Hence, exclude the child of the AstWordSel from the computation,
// whose cost scales with the size of the entire (maybe large) vector. // whose cost scales with the size of the entire (maybe large) vector.
VisitBase vb(this, nodep); const VisitBase vb{this, nodep};
iterateAndNextNull(nodep->bitp()); iterateAndNextNull(nodep->bitp());
} }
virtual void visit(AstSel* nodep) override { virtual void visit(AstSel* nodep) override {
@ -132,7 +132,7 @@ private:
// is not expensive. Count the cost of the AstSel itself (scales with // is not expensive. Count the cost of the AstSel itself (scales with
// its width) and the cost of the lsbp() and widthp() nodes, but not // its width) and the cost of the lsbp() and widthp() nodes, but not
// the fromp() node which could be disproportionately large. // the fromp() node which could be disproportionately large.
VisitBase vb(this, nodep); const VisitBase vb{this, nodep};
iterateAndNextNull(nodep->lsbp()); iterateAndNextNull(nodep->lsbp());
iterateAndNextNull(nodep->widthp()); iterateAndNextNull(nodep->widthp());
} }
@ -163,9 +163,9 @@ private:
markCost(nodep); markCost(nodep);
} }
virtual void visit(AstNodeIf* nodep) override { virtual void visit(AstNodeIf* nodep) override {
VisitBase vb(this, nodep); const VisitBase vb{this, nodep};
iterateAndNextNull(nodep->condp()); iterateAndNextNull(nodep->condp());
uint32_t savedCount = m_instrCount; const uint32_t savedCount = m_instrCount;
UINFO(8, "ifsp:\n"); UINFO(8, "ifsp:\n");
m_instrCount = 0; m_instrCount = 0;
@ -190,19 +190,19 @@ private:
virtual void visit(AstNodeCond* nodep) override { virtual void visit(AstNodeCond* nodep) override {
// Just like if/else above, the ternary operator only evaluates // Just like if/else above, the ternary operator only evaluates
// one of the two expressions, so only count the max. // one of the two expressions, so only count the max.
VisitBase vb(this, nodep); const VisitBase vb{this, nodep};
iterateAndNextNull(nodep->condp()); iterateAndNextNull(nodep->condp());
uint32_t savedCount = m_instrCount; const uint32_t savedCount = m_instrCount;
UINFO(8, "?\n"); UINFO(8, "?\n");
m_instrCount = 0; m_instrCount = 0;
iterateAndNextNull(nodep->expr1p()); iterateAndNextNull(nodep->expr1p());
uint32_t ifCount = m_instrCount; const uint32_t ifCount = m_instrCount;
UINFO(8, ":\n"); UINFO(8, ":\n");
m_instrCount = 0; m_instrCount = 0;
iterateAndNextNull(nodep->expr2p()); iterateAndNextNull(nodep->expr2p());
uint32_t elseCount = m_instrCount; const uint32_t elseCount = m_instrCount;
if (ifCount < elseCount) { if (ifCount < elseCount) {
m_instrCount = savedCount + elseCount; m_instrCount = savedCount + elseCount;
@ -229,7 +229,7 @@ private:
UASSERT_OBJ(nodep == m_startNodep, nodep, "Multiple actives, or not start node"); UASSERT_OBJ(nodep == m_startNodep, nodep, "Multiple actives, or not start node");
} }
virtual void visit(AstNodeCCall* nodep) override { virtual void visit(AstNodeCCall* nodep) override {
VisitBase vb(this, nodep); const VisitBase vb{this, nodep};
iterateChildren(nodep); iterateChildren(nodep);
m_tracingCall = true; m_tracingCall = true;
iterate(nodep->funcp()); iterate(nodep->funcp());
@ -244,12 +244,12 @@ private:
VL_RESTORER(m_inCFunc); VL_RESTORER(m_inCFunc);
{ {
m_inCFunc = true; m_inCFunc = true;
VisitBase vb(this, nodep); const VisitBase vb{this, nodep};
iterateChildren(nodep); iterateChildren(nodep);
} }
} }
virtual void visit(AstNode* nodep) override { virtual void visit(AstNode* nodep) override {
VisitBase vb(this, nodep); const VisitBase vb{this, nodep};
iterateChildren(nodep); iterateChildren(nodep);
} }
@ -294,7 +294,7 @@ private:
}; };
uint32_t V3InstrCount::count(AstNode* nodep, bool assertNoDups, std::ostream* osp) { uint32_t V3InstrCount::count(AstNode* nodep, bool assertNoDups, std::ostream* osp) {
InstrCountVisitor visitor{nodep, assertNoDups, osp}; const InstrCountVisitor visitor{nodep, assertNoDups, osp};
if (osp) InstrCountDumpVisitor dumper(nodep, osp); if (osp) InstrCountDumpVisitor dumper(nodep, osp);
return visitor.instrCount(); return visitor.instrCount();
} }

View File

@ -303,7 +303,7 @@ private:
virtual void visit(AstNodeAssign* nodep) override { virtual void visit(AstNodeAssign* nodep) override {
// Collect any used variables first, as lhs may also be on rhs // Collect any used variables first, as lhs may also be on rhs
// Similar code in V3Dead // Similar code in V3Dead
vluint64_t lastEdit = AstNode::editCountGbl(); // When it was last edited const vluint64_t lastEdit = AstNode::editCountGbl(); // When it was last edited
m_sideEffect = false; m_sideEffect = false;
iterateAndNextNull(nodep->rhsp()); iterateAndNextNull(nodep->rhsp());
if (lastEdit != AstNode::editCountGbl()) { if (lastEdit != AstNode::editCountGbl()) {

View File

@ -186,9 +186,9 @@ private:
} }
void squashAssignposts() { void squashAssignposts() {
for (auto& itr : m_assignposts) { for (auto& itr : m_assignposts) {
LifePostLocation* const app = &itr.second; const LifePostLocation* const app = &itr.second;
AstVarRef* const lhsp = VN_AS(app->nodep->lhsp(), VarRef); // original var const AstVarRef* const lhsp = VN_AS(app->nodep->lhsp(), VarRef); // original var
AstVarRef* const rhsp = VN_AS(app->nodep->rhsp(), VarRef); // dly var const AstVarRef* const rhsp = VN_AS(app->nodep->rhsp(), VarRef); // dly var
AstVarScope* const dlyVarp = rhsp->varScopep(); AstVarScope* const dlyVarp = rhsp->varScopep();
AstVarScope* const origVarp = lhsp->varScopep(); AstVarScope* const origVarp = lhsp->varScopep();
@ -275,10 +275,10 @@ private:
} }
virtual void visit(AstVarRef* nodep) override { virtual void visit(AstVarRef* nodep) override {
// Consumption/generation of a variable, // Consumption/generation of a variable,
AstVarScope* const vscp = nodep->varScopep(); const AstVarScope* const vscp = nodep->varScopep();
UASSERT_OBJ(vscp, nodep, "Scope not assigned"); UASSERT_OBJ(vscp, nodep, "Scope not assigned");
LifeLocation loc(m_execMTaskp, ++m_sequence); const LifeLocation loc(m_execMTaskp, ++m_sequence);
if (nodep->access().isWriteOrRW()) m_writes[vscp].insert(loc); if (nodep->access().isWriteOrRW()) m_writes[vscp].insert(loc);
if (nodep->access().isReadOrRW()) m_reads[vscp].insert(loc); if (nodep->access().isReadOrRW()) m_reads[vscp].insert(loc);
} }
@ -292,12 +292,12 @@ private:
virtual void visit(AstAssignPost* nodep) override { virtual void visit(AstAssignPost* nodep) override {
// Don't record ASSIGNPOST in the read/write maps, record them in a // Don't record ASSIGNPOST in the read/write maps, record them in a
// separate map // separate map
if (AstVarRef* const rhsp = VN_CAST(nodep->rhsp(), VarRef)) { if (const AstVarRef* const rhsp = VN_CAST(nodep->rhsp(), VarRef)) {
// rhsp is the dly var // rhsp is the dly var
AstVarScope* const dlyVarp = rhsp->varScopep(); const AstVarScope* const dlyVarp = rhsp->varScopep();
UASSERT_OBJ(m_assignposts.find(dlyVarp) == m_assignposts.end(), nodep, UASSERT_OBJ(m_assignposts.find(dlyVarp) == m_assignposts.end(), nodep,
"LifePostLocation attempted duplicate dlyvar map addition"); "LifePostLocation attempted duplicate dlyvar map addition");
LifeLocation loc(m_execMTaskp, ++m_sequence); const LifeLocation loc(m_execMTaskp, ++m_sequence);
m_assignposts[dlyVarp] = LifePostLocation(loc, nodep); m_assignposts[dlyVarp] = LifePostLocation(loc, nodep);
} }
} }
@ -318,7 +318,7 @@ private:
m_mtasksGraphp = nodep->depGraphp(); m_mtasksGraphp = nodep->depGraphp();
for (V3GraphVertex* mtaskVxp = m_mtasksGraphp->verticesBeginp(); mtaskVxp; for (V3GraphVertex* mtaskVxp = m_mtasksGraphp->verticesBeginp(); mtaskVxp;
mtaskVxp = mtaskVxp->verticesNextp()) { mtaskVxp = mtaskVxp->verticesNextp()) {
ExecMTask* const mtaskp = dynamic_cast<ExecMTask*>(mtaskVxp); const ExecMTask* const mtaskp = dynamic_cast<ExecMTask*>(mtaskVxp);
m_execMTaskp = mtaskp; m_execMTaskp = mtaskp;
m_sequence = 0; m_sequence = 0;
iterate(mtaskp->bodyp()); iterate(mtaskp->bodyp());

View File

@ -113,7 +113,7 @@ private:
VSymGraph m_mods; // Symbol table of all module names VSymGraph m_mods; // Symbol table of all module names
LinkCellsGraph m_graph; // Linked graph of all cell interconnects LinkCellsGraph m_graph; // Linked graph of all cell interconnects
LibraryVertex* m_libVertexp = nullptr; // Vertex at root of all libraries LibraryVertex* m_libVertexp = nullptr; // Vertex at root of all libraries
V3GraphVertex* m_topVertexp = nullptr; // Vertex of top module const V3GraphVertex* m_topVertexp = nullptr; // Vertex of top module
std::unordered_set<string> m_declfnWarned; // Files we issued DECLFILENAME on std::unordered_set<string> m_declfnWarned; // Files we issued DECLFILENAME on
string m_origTopModuleName; // original name of the top module string m_origTopModuleName; // original name of the top module
@ -474,7 +474,7 @@ private:
nodep->name(hierIt->first); // Change name of this module to be mangled name nodep->name(hierIt->first); // Change name of this module to be mangled name
// considering parameter // considering parameter
} }
AstNodeModule* const foundp = findModuleSym(nodep->name()); const AstNodeModule* const foundp = findModuleSym(nodep->name());
if (foundp && foundp != nodep) { if (foundp && foundp != nodep) {
if (!(foundp->fileline()->warnIsOff(V3ErrorCode::MODDUP) if (!(foundp->fileline()->warnIsOff(V3ErrorCode::MODDUP)
|| nodep->fileline()->warnIsOff(V3ErrorCode::MODDUP) || nodep->fileline()->warnIsOff(V3ErrorCode::MODDUP)

View File

@ -249,7 +249,7 @@ public:
// //
// Note we only check for conflicts at the same level; it's ok if one block hides another // Note we only check for conflicts at the same level; it's ok if one block hides another
// We also wouldn't want to not insert it even though it's lower down // We also wouldn't want to not insert it even though it's lower down
VSymEnt* const foundp = lookupSymp->findIdFlat(name); const VSymEnt* const foundp = lookupSymp->findIdFlat(name);
AstNode* const fnodep = foundp ? foundp->nodep() : nullptr; AstNode* const fnodep = foundp ? foundp->nodep() : nullptr;
if (!fnodep) { if (!fnodep) {
// Not found, will add in a moment. // Not found, will add in a moment.
@ -431,9 +431,9 @@ public:
static AstIfaceRefDType* ifaceRefFromArray(AstNodeDType* nodep) { static AstIfaceRefDType* ifaceRefFromArray(AstNodeDType* nodep) {
AstIfaceRefDType* ifacerefp = VN_CAST(nodep, IfaceRefDType); AstIfaceRefDType* ifacerefp = VN_CAST(nodep, IfaceRefDType);
if (!ifacerefp) { if (!ifacerefp) {
if (AstBracketArrayDType* const arrp = VN_CAST(nodep, BracketArrayDType)) { if (const AstBracketArrayDType* const arrp = VN_CAST(nodep, BracketArrayDType)) {
ifacerefp = VN_CAST(arrp->subDTypep(), IfaceRefDType); ifacerefp = VN_CAST(arrp->subDTypep(), IfaceRefDType);
} else if (AstUnpackArrayDType* arrp = VN_CAST(nodep, UnpackArrayDType)) { } else if (const AstUnpackArrayDType* const arrp = VN_CAST(nodep, UnpackArrayDType)) {
ifacerefp = VN_CAST(arrp->subDTypep(), IfaceRefDType); ifacerefp = VN_CAST(arrp->subDTypep(), IfaceRefDType);
} }
} }
@ -441,7 +441,7 @@ public:
} }
void computeIfaceVarSyms() { void computeIfaceVarSyms() {
for (VSymEnt* varSymp : m_ifaceVarSyms) { for (VSymEnt* varSymp : m_ifaceVarSyms) {
AstVar* const varp = varSymp ? VN_AS(varSymp->nodep(), Var) : nullptr; const AstVar* const varp = varSymp ? VN_AS(varSymp->nodep(), Var) : nullptr;
UINFO(9, " insAllIface se" << cvtToHex(varSymp) << " " << varp << endl); UINFO(9, " insAllIface se" << cvtToHex(varSymp) << " " << varp << endl);
AstIfaceRefDType* const ifacerefp = ifaceRefFromArray(varp->subDTypep()); AstIfaceRefDType* const ifacerefp = ifaceRefFromArray(varp->subDTypep());
UASSERT_OBJ(ifacerefp, varp, "Non-ifacerefs on list!"); UASSERT_OBJ(ifacerefp, varp, "Non-ifacerefs on list!");
@ -578,10 +578,11 @@ public:
// then look up (inst name or modname) // then look up (inst name or modname)
if (firstId) { if (firstId) {
// Check this module - subcellnames // Check this module - subcellnames
AstCell* cellp = lookupSymp ? VN_CAST(lookupSymp->nodep(), Cell) const AstCell* cellp = lookupSymp ? VN_CAST(lookupSymp->nodep(), Cell)
: nullptr; // Replicated below : nullptr; // Replicated below
AstCellInline* inlinep = lookupSymp ? VN_CAST(lookupSymp->nodep(), CellInline) const AstCellInline* inlinep = lookupSymp
: nullptr; // Replicated below ? VN_CAST(lookupSymp->nodep(), CellInline)
: nullptr; // Replicated below
if (VSymEnt* const findSymp = findWithAltFallback(lookupSymp, ident, altIdent)) { if (VSymEnt* const findSymp = findWithAltFallback(lookupSymp, ident, altIdent)) {
lookupSymp = findSymp; lookupSymp = findSymp;
} }
@ -613,7 +614,7 @@ public:
if ((cellp && cellp->modp()->origName() == ident) if ((cellp && cellp->modp()->origName() == ident)
|| (inlinep && inlinep->origModName() == ident)) { || (inlinep && inlinep->origModName() == ident)) {
break; break;
} else if (VSymEnt* findSymp } else if (VSymEnt* const findSymp
= findWithAltFallback(lookupSymp, ident, altIdent)) { = findWithAltFallback(lookupSymp, ident, altIdent)) {
lookupSymp = findSymp; lookupSymp = findSymp;
if (crossedCell && VN_IS(lookupSymp->nodep(), Var)) { if (crossedCell && VN_IS(lookupSymp->nodep(), Var)) {
@ -636,8 +637,8 @@ public:
} }
} }
if (lookupSymp) { if (lookupSymp) {
if (AstCell* const cellp = VN_CAST(lookupSymp->nodep(), Cell)) { if (const AstCell* const cellp = VN_CAST(lookupSymp->nodep(), Cell)) {
if (AstNodeModule* const modp = cellp->modp()) { if (const AstNodeModule* const modp = cellp->modp()) {
if (modp->hierBlock()) { if (modp->hierBlock()) {
refLocationp->v3error("Cannot access inside hierarchical block"); refLocationp->v3error("Cannot access inside hierarchical block");
} else if (VN_IS(modp, NotFoundModule)) { } else if (VN_IS(modp, NotFoundModule)) {
@ -713,8 +714,8 @@ class LinkDotFindVisitor final : public AstNVisitor {
VSymEnt* m_modSymp = nullptr; // Symbol Entry for current module VSymEnt* m_modSymp = nullptr; // Symbol Entry for current module
VSymEnt* m_curSymp = nullptr; // Symbol Entry for current table, where to lookup/insert VSymEnt* m_curSymp = nullptr; // Symbol Entry for current table, where to lookup/insert
string m_scope; // Scope text string m_scope; // Scope text
AstNodeBlock* m_blockp = nullptr; // Current Begin/end block const AstNodeBlock* m_blockp = nullptr; // Current Begin/end block
AstNodeFTask* m_ftaskp = nullptr; // Current function/task const AstNodeFTask* m_ftaskp = nullptr; // Current function/task
bool m_inRecursion = false; // Inside a recursive module bool m_inRecursion = false; // Inside a recursive module
int m_paramNum = 0; // Parameter number, for position based connection int m_paramNum = 0; // Parameter number, for position based connection
bool m_explicitNew = false; // Hit a "new" function bool m_explicitNew = false; // Hit a "new" function
@ -975,13 +976,13 @@ class LinkDotFindVisitor final : public AstNVisitor {
{ {
// Change to appropriate package if extern declaration (vs definition) // Change to appropriate package if extern declaration (vs definition)
if (nodep->classOrPackagep()) { if (nodep->classOrPackagep()) {
AstClassOrPackageRef* cpackagerefp AstClassOrPackageRef* const cpackagerefp
= VN_CAST(nodep->classOrPackagep(), ClassOrPackageRef); = VN_CAST(nodep->classOrPackagep(), ClassOrPackageRef);
if (!cpackagerefp) { if (!cpackagerefp) {
nodep->v3warn(E_UNSUPPORTED, nodep->v3warn(E_UNSUPPORTED,
"Unsupported: extern function definition with class-in-class"); "Unsupported: extern function definition with class-in-class");
} else { } else {
AstClass* classp = VN_CAST(cpackagerefp->classOrPackagep(), Class); AstClass* const classp = VN_CAST(cpackagerefp->classOrPackagep(), Class);
if (!classp) { if (!classp) {
nodep->v3error("Extern declaration's scope is not a defined class"); nodep->v3error("Extern declaration's scope is not a defined class");
} else { } else {
@ -1017,8 +1018,9 @@ class LinkDotFindVisitor final : public AstNVisitor {
} else { } else {
dtypep = new AstBasicDType(nodep->fileline(), AstBasicDTypeKwd::LOGIC); dtypep = new AstBasicDType(nodep->fileline(), AstBasicDTypeKwd::LOGIC);
} }
AstVar* newvarp = new AstVar(nodep->fileline(), AstVarType::VAR, nodep->name(), AstVar* const newvarp
VFlagChildDType(), dtypep); // Not dtype resolved yet = new AstVar(nodep->fileline(), AstVarType::VAR, nodep->name(),
VFlagChildDType(), dtypep); // Not dtype resolved yet
newvarp->direction(VDirection::OUTPUT); newvarp->direction(VDirection::OUTPUT);
newvarp->lifetime(VLifetime::AUTOMATIC); newvarp->lifetime(VLifetime::AUTOMATIC);
newvarp->funcReturn(true); newvarp->funcReturn(true);
@ -1045,11 +1047,11 @@ class LinkDotFindVisitor final : public AstNVisitor {
} }
if (!m_statep->forScopeCreation()) { if (!m_statep->forScopeCreation()) {
// Find under either a task or the module's vars // Find under either a task or the module's vars
VSymEnt* foundp = m_curSymp->findIdFallback(nodep->name()); const VSymEnt* foundp = m_curSymp->findIdFallback(nodep->name());
if (!foundp && m_modSymp && nodep->name() == m_modSymp->nodep()->name()) { if (!foundp && m_modSymp && nodep->name() == m_modSymp->nodep()->name()) {
foundp = m_modSymp; // Conflicts with modname? foundp = m_modSymp; // Conflicts with modname?
} }
AstVar* findvarp = foundp ? VN_CAST(foundp->nodep(), Var) : nullptr; AstVar* const findvarp = foundp ? VN_CAST(foundp->nodep(), Var) : nullptr;
bool ins = false; bool ins = false;
if (!foundp) { if (!foundp) {
ins = true; ins = true;
@ -1063,7 +1065,7 @@ class LinkDotFindVisitor final : public AstNVisitor {
<< cvtToHex(foundp->parentp()) << endl); << cvtToHex(foundp->parentp()) << endl);
if (foundp->parentp() == m_curSymp // Only when on same level if (foundp->parentp() == m_curSymp // Only when on same level
&& !foundp->imported()) { // and not from package && !foundp->imported()) { // and not from package
bool nansiBad const bool nansiBad
= ((findvarp->isDeclTyped() && nodep->isDeclTyped()) = ((findvarp->isDeclTyped() && nodep->isDeclTyped())
|| (findvarp->isIO() && nodep->isIO())); // e.g. !(output && output) || (findvarp->isIO() && nodep->isIO())); // e.g. !(output && output)
const bool ansiBad const bool ansiBad
@ -1091,11 +1093,12 @@ class LinkDotFindVisitor final : public AstNVisitor {
} else { } else {
findvarp->combineType(nodep); findvarp->combineType(nodep);
findvarp->fileline()->modifyStateInherit(nodep->fileline()); findvarp->fileline()->modifyStateInherit(nodep->fileline());
AstBasicDType* bdtypep = VN_CAST(findvarp->childDTypep(), BasicDType); AstBasicDType* const bdtypep
= VN_CAST(findvarp->childDTypep(), BasicDType);
if (bdtypep && bdtypep->implicit()) { if (bdtypep && bdtypep->implicit()) {
// Then have "input foo" and "real foo" so the // Then have "input foo" and "real foo" so the
// dtype comes from the other side. // dtype comes from the other side.
AstNodeDType* newdtypep = nodep->subDTypep(); AstNodeDType* const newdtypep = nodep->subDTypep();
UASSERT_OBJ(newdtypep && nodep->childDTypep(), findvarp, UASSERT_OBJ(newdtypep && nodep->childDTypep(), findvarp,
"No child type?"); "No child type?");
VL_DO_DANGLING(bdtypep->unlinkFrBack()->deleteTree(), bdtypep); VL_DO_DANGLING(bdtypep->unlinkFrBack()->deleteTree(), bdtypep);
@ -1129,12 +1132,12 @@ class LinkDotFindVisitor final : public AstNVisitor {
// We first search if the parameter is overwritten and then replace it with a // We first search if the parameter is overwritten and then replace it with a
// new value. It will keep the same FileLine information. // new value. It will keep the same FileLine information.
if (v3Global.opt.hasParameter(nodep->name())) { if (v3Global.opt.hasParameter(nodep->name())) {
AstVar* newp AstVar* const newp
= new AstVar(nodep->fileline(), AstVarType(AstVarType::GPARAM), = new AstVar(nodep->fileline(), AstVarType(AstVarType::GPARAM),
nodep->name(), nodep); nodep->name(), nodep);
newp->combineType(nodep); newp->combineType(nodep);
const string svalue = v3Global.opt.parameter(nodep->name()); const string svalue = v3Global.opt.parameter(nodep->name());
if (AstNode* valuep if (AstNode* const valuep
= AstConst::parseParamLiteral(nodep->fileline(), svalue)) { = AstConst::parseParamLiteral(nodep->fileline(), svalue)) {
newp->valuep(valuep); newp->valuep(valuep);
UINFO(9, " replace parameter " << nodep << endl); UINFO(9, " replace parameter " << nodep << endl);
@ -1145,16 +1148,17 @@ class LinkDotFindVisitor final : public AstNVisitor {
} }
} }
} }
VSymEnt* insp VSymEnt* const insp
= m_statep->insertSym(m_curSymp, nodep->name(), nodep, m_classOrPackagep); = m_statep->insertSym(m_curSymp, nodep->name(), nodep, m_classOrPackagep);
if (m_statep->forPrimary() && nodep->isGParam()) { if (m_statep->forPrimary() && nodep->isGParam()) {
++m_paramNum; ++m_paramNum;
VSymEnt* symp VSymEnt* const symp
= m_statep->insertSym(m_curSymp, "__paramNumber" + cvtToStr(m_paramNum), = m_statep->insertSym(m_curSymp, "__paramNumber" + cvtToStr(m_paramNum),
nodep, m_classOrPackagep); nodep, m_classOrPackagep);
symp->exported(false); symp->exported(false);
} }
AstIfaceRefDType* ifacerefp = LinkDotState::ifaceRefFromArray(nodep->subDTypep()); AstIfaceRefDType* const ifacerefp
= LinkDotState::ifaceRefFromArray(nodep->subDTypep());
if (ifacerefp) { if (ifacerefp) {
// Can't resolve until interfaces and modport names are // Can't resolve until interfaces and modport names are
// known; see notes at top // known; see notes at top
@ -1193,11 +1197,11 @@ class LinkDotFindVisitor final : public AstNVisitor {
// EnumItem: Remember its name for later resolution // EnumItem: Remember its name for later resolution
iterateChildren(nodep); iterateChildren(nodep);
// Find under either a task or the module's vars // Find under either a task or the module's vars
VSymEnt* foundp = m_curSymp->findIdFallback(nodep->name()); const VSymEnt* foundp = m_curSymp->findIdFallback(nodep->name());
if (!foundp && m_modSymp && nodep->name() == m_modSymp->nodep()->name()) { if (!foundp && m_modSymp && nodep->name() == m_modSymp->nodep()->name()) {
foundp = m_modSymp; // Conflicts with modname? foundp = m_modSymp; // Conflicts with modname?
} }
AstEnumItem* findvarp = foundp ? VN_AS(foundp->nodep(), EnumItem) : nullptr; AstEnumItem* const findvarp = foundp ? VN_AS(foundp->nodep(), EnumItem) : nullptr;
bool ins = false; bool ins = false;
if (!foundp) { if (!foundp) {
ins = true; ins = true;
@ -1230,13 +1234,13 @@ class LinkDotFindVisitor final : public AstNVisitor {
} }
virtual void visit(AstPackageImport* nodep) override { virtual void visit(AstPackageImport* nodep) override {
UINFO(4, " Link: " << nodep << endl); UINFO(4, " Link: " << nodep << endl);
VSymEnt* srcp = m_statep->getNodeSym(nodep->packagep()); VSymEnt* const srcp = m_statep->getNodeSym(nodep->packagep());
if (nodep->name() == "*") { if (nodep->name() == "*") {
if (m_curSymp == m_statep->dunitEntp()) { if (m_curSymp == m_statep->dunitEntp()) {
nodep->v3warn(IMPORTSTAR, "Import::* in $unit scope may pollute global namespace"); nodep->v3warn(IMPORTSTAR, "Import::* in $unit scope may pollute global namespace");
} }
} else { } else {
VSymEnt* impp = srcp->findIdFlat(nodep->name()); VSymEnt* const impp = srcp->findIdFlat(nodep->name());
if (!impp) { if (!impp) {
nodep->v3error("Import object not found: '" << nodep->packagep()->prettyName() nodep->v3error("Import object not found: '" << nodep->packagep()->prettyName()
<< "::" << nodep->prettyName() << "'"); << "::" << nodep->prettyName() << "'");
@ -1248,9 +1252,9 @@ class LinkDotFindVisitor final : public AstNVisitor {
} }
virtual void visit(AstPackageExport* nodep) override { virtual void visit(AstPackageExport* nodep) override {
UINFO(9, " Link: " << nodep << endl); UINFO(9, " Link: " << nodep << endl);
VSymEnt* srcp = m_statep->getNodeSym(nodep->packagep()); VSymEnt* const srcp = m_statep->getNodeSym(nodep->packagep());
if (nodep->name() != "*") { if (nodep->name() != "*") {
VSymEnt* impp = srcp->findIdFlat(nodep->name()); VSymEnt* const impp = srcp->findIdFlat(nodep->name());
if (!impp) { if (!impp) {
nodep->v3error("Export object not found: '" << nodep->packagep()->prettyName() nodep->v3error("Export object not found: '" << nodep->packagep()->prettyName()
<< "::" << nodep->prettyName() << "'"); << "::" << nodep->prettyName() << "'");
@ -1335,7 +1339,7 @@ private:
// *::user4() -> See LinkDotState // *::user4() -> See LinkDotState
// STATE // STATE
LinkDotState* m_statep; // State to pass between visitors, including symbol table LinkDotState* const m_statep; // State to pass between visitors, including symbol table
AstNodeModule* m_modp = nullptr; // Current module AstNodeModule* m_modp = nullptr; // Current module
static int debug() { return LinkDotState::debug(); } static int debug() { return LinkDotState::debug(); }
@ -1397,18 +1401,18 @@ private:
<< nodep->warnMore() << nodep->warnMore()
<< "... Suggest use instantiation with #(." << "... Suggest use instantiation with #(."
<< nodep->prettyName() << "(...etc...))"); << nodep->prettyName() << "(...etc...))");
VSymEnt* foundp = m_statep->getNodeSym(nodep)->findIdFallback(nodep->path()); VSymEnt* const foundp = m_statep->getNodeSym(nodep)->findIdFallback(nodep->path());
AstCell* cellp = foundp ? VN_AS(foundp->nodep(), Cell) : nullptr; AstCell* const cellp = foundp ? VN_AS(foundp->nodep(), Cell) : nullptr;
if (!cellp) { if (!cellp) {
nodep->v3error("In defparam, instance " << nodep->path() << " never declared"); nodep->v3error("In defparam, instance " << nodep->path() << " never declared");
} else { } else {
AstNode* exprp = nodep->rhsp()->unlinkFrBack(); AstNode* const exprp = nodep->rhsp()->unlinkFrBack();
UINFO(9, "Defparam cell " << nodep->path() << "." << nodep->name() << " attach-to " UINFO(9, "Defparam cell " << nodep->path() << "." << nodep->name() << " attach-to "
<< cellp << " <= " << exprp << endl); << cellp << " <= " << exprp << endl);
// Don't need to check the name of the defparam exists. V3Param does. // Don't need to check the name of the defparam exists. V3Param does.
AstPin* pinp = new AstPin(nodep->fileline(), AstPin* const pinp = new AstPin(nodep->fileline(),
-1, // Pin# not relevant -1, // Pin# not relevant
nodep->name(), exprp); nodep->name(), exprp);
cellp->addParamsp(pinp); cellp->addParamsp(pinp);
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
} }
@ -1417,8 +1421,8 @@ private:
// Port: Stash the pin number // Port: Stash the pin number
// Need to set pin numbers after varnames are created // Need to set pin numbers after varnames are created
// But before we do the final resolution based on names // But before we do the final resolution based on names
VSymEnt* foundp = m_statep->getNodeSym(m_modp)->findIdFlat(nodep->name()); VSymEnt* const foundp = m_statep->getNodeSym(m_modp)->findIdFlat(nodep->name());
AstVar* refp = foundp ? VN_AS(foundp->nodep(), Var) : nullptr; AstVar* const refp = foundp ? VN_AS(foundp->nodep(), Var) : nullptr;
if (!refp) { if (!refp) {
nodep->v3error( nodep->v3error(
"Input/output/inout declaration not found for port: " << nodep->prettyNameQ()); "Input/output/inout declaration not found for port: " << nodep->prettyNameQ());
@ -1433,9 +1437,9 @@ private:
<< refp->warnContextSecondary()); << refp->warnContextSecondary());
} }
refp->user4(true); refp->user4(true);
VSymEnt* symp = m_statep->insertSym(m_statep->getNodeSym(m_modp), VSymEnt* const symp = m_statep->insertSym(m_statep->getNodeSym(m_modp),
"__pinNumber" + cvtToStr(nodep->pinNum()), refp, "__pinNumber" + cvtToStr(nodep->pinNum()),
nullptr /*classOrPackagep*/); refp, nullptr /*classOrPackagep*/);
symp->exported(false); symp->exported(false);
refp->pinNum(nodep->pinNum()); refp->pinNum(nodep->pinNum());
} }
@ -1453,10 +1457,10 @@ private:
// tran gates need implicit creation // tran gates need implicit creation
// As VarRefs don't exist in forPrimary, sanity check // As VarRefs don't exist in forPrimary, sanity check
UASSERT_OBJ(!m_statep->forPrimary(), nodep, "Assign aliases unexpected pre-dot"); UASSERT_OBJ(!m_statep->forPrimary(), nodep, "Assign aliases unexpected pre-dot");
if (AstVarRef* forrefp = VN_CAST(nodep->lhsp(), VarRef)) { if (AstVarRef* const forrefp = VN_CAST(nodep->lhsp(), VarRef)) {
pinImplicitExprRecurse(forrefp); pinImplicitExprRecurse(forrefp);
} }
if (AstVarRef* forrefp = VN_CAST(nodep->rhsp(), VarRef)) { if (AstVarRef* const forrefp = VN_CAST(nodep->rhsp(), VarRef)) {
pinImplicitExprRecurse(forrefp); pinImplicitExprRecurse(forrefp);
} }
iterateChildren(nodep); iterateChildren(nodep);
@ -1468,9 +1472,9 @@ private:
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
} }
virtual void visit(AstClassOrPackageRef* nodep) override { virtual void visit(AstClassOrPackageRef* nodep) override {
if (auto* fwdp = VN_CAST(nodep->classOrPackageNodep(), TypedefFwd)) { if (auto* const fwdp = VN_CAST(nodep->classOrPackageNodep(), TypedefFwd)) {
// Relink forward definitions to the "real" definition // Relink forward definitions to the "real" definition
VSymEnt* foundp = m_statep->getNodeSym(fwdp)->findIdFallback(fwdp->name()); VSymEnt* const foundp = m_statep->getNodeSym(fwdp)->findIdFallback(fwdp->name());
if (foundp && (VN_IS(foundp->nodep(), Class) || VN_IS(foundp->nodep(), Package))) { if (foundp && (VN_IS(foundp->nodep(), Class) || VN_IS(foundp->nodep(), Package))) {
nodep->classOrPackagep(VN_AS(foundp->nodep(), NodeModule)); nodep->classOrPackagep(VN_AS(foundp->nodep(), NodeModule));
} else if (foundp && VN_IS(foundp->nodep(), ParamTypeDType)) { } else if (foundp && VN_IS(foundp->nodep(), ParamTypeDType)) {
@ -1490,7 +1494,7 @@ private:
iterateChildren(nodep); iterateChildren(nodep);
} }
virtual void visit(AstTypedefFwd* nodep) override { virtual void visit(AstTypedefFwd* nodep) override {
VSymEnt* foundp = m_statep->getNodeSym(nodep)->findIdFallback(nodep->name()); VSymEnt* const foundp = m_statep->getNodeSym(nodep)->findIdFallback(nodep->name());
if (!foundp && v3Global.opt.pedantic()) { if (!foundp && v3Global.opt.pedantic()) {
// We only check it was ever really defined in pedantic mode, as it // We only check it was ever really defined in pedantic mode, as it
// might have been in a header file referring to a module we never // might have been in a header file referring to a module we never
@ -1521,8 +1525,8 @@ public:
class LinkDotScopeVisitor final : public AstNVisitor { class LinkDotScopeVisitor final : public AstNVisitor {
// STATE // STATE
LinkDotState* m_statep; // State to pass between visitors, including symbol table LinkDotState* const m_statep; // State to pass between visitors, including symbol table
AstScope* m_scopep = nullptr; // The current scope const AstScope* m_scopep = nullptr; // The current scope
VSymEnt* m_modSymp = nullptr; // Symbol entry for current module VSymEnt* m_modSymp = nullptr; // Symbol entry for current module
static int debug() { return LinkDotState::debug(); } static int debug() { return LinkDotState::debug(); }
@ -1547,12 +1551,12 @@ class LinkDotScopeVisitor final : public AstNVisitor {
} }
virtual void visit(AstVarScope* nodep) override { virtual void visit(AstVarScope* nodep) override {
if (!nodep->varp()->isFuncLocal() && !nodep->varp()->isClassMember()) { if (!nodep->varp()->isFuncLocal() && !nodep->varp()->isClassMember()) {
VSymEnt* varSymp VSymEnt* const varSymp
= m_statep->insertSym(m_modSymp, nodep->varp()->name(), nodep, nullptr); = m_statep->insertSym(m_modSymp, nodep->varp()->name(), nodep, nullptr);
if (nodep->varp()->isIfaceRef() && nodep->varp()->isIfaceParent()) { if (nodep->varp()->isIfaceRef() && nodep->varp()->isIfaceParent()) {
UINFO(9, "Iface parent ref var " << nodep->varp()->name() << " " << nodep << endl); UINFO(9, "Iface parent ref var " << nodep->varp()->name() << " " << nodep << endl);
// Find the interface cell the var references // Find the interface cell the var references
AstIfaceRefDType* dtypep AstIfaceRefDType* const dtypep
= LinkDotState::ifaceRefFromArray(nodep->varp()->dtypep()); = LinkDotState::ifaceRefFromArray(nodep->varp()->dtypep());
UASSERT_OBJ(dtypep, nodep, "Non AstIfaceRefDType on isIfaceRef() var"); UASSERT_OBJ(dtypep, nodep, "Non AstIfaceRefDType on isIfaceRef() var");
UINFO(9, "Iface parent dtype " << dtypep << endl); UINFO(9, "Iface parent dtype " << dtypep << endl);
@ -1567,8 +1571,8 @@ class LinkDotScopeVisitor final : public AstNVisitor {
UINFO(5, " Found interface instance: se" << cvtToHex(cellSymp) << " " UINFO(5, " Found interface instance: se" << cvtToHex(cellSymp) << " "
<< cellSymp->nodep() << endl); << cellSymp->nodep() << endl);
if (dtypep->modportName() != "") { if (dtypep->modportName() != "") {
VSymEnt* mpSymp = m_statep->findDotted(nodep->fileline(), m_modSymp, VSymEnt* const mpSymp = m_statep->findDotted(nodep->fileline(), m_modSymp,
ifcellname, baddot, okSymp); ifcellname, baddot, okSymp);
UASSERT_OBJ(mpSymp, nodep, UASSERT_OBJ(mpSymp, nodep,
"No symbol for interface modport: " "No symbol for interface modport: "
<< nodep->prettyNameQ(dtypep->modportName())); << nodep->prettyNameQ(dtypep->modportName()));
@ -1584,12 +1588,12 @@ class LinkDotScopeVisitor final : public AstNVisitor {
} }
} }
virtual void visit(AstNodeFTask* nodep) override { virtual void visit(AstNodeFTask* nodep) override {
VSymEnt* symp = m_statep->insertBlock(m_modSymp, nodep->name(), nodep, nullptr); VSymEnt* const symp = m_statep->insertBlock(m_modSymp, nodep->name(), nodep, nullptr);
symp->fallbackp(m_modSymp); symp->fallbackp(m_modSymp);
// No recursion, we don't want to pick up variables // No recursion, we don't want to pick up variables
} }
virtual void visit(AstWith* nodep) override { virtual void visit(AstWith* nodep) override {
VSymEnt* symp = m_statep->insertBlock(m_modSymp, nodep->name(), nodep, nullptr); VSymEnt* const symp = m_statep->insertBlock(m_modSymp, nodep->name(), nodep, nullptr);
symp->fallbackp(m_modSymp); symp->fallbackp(m_modSymp);
// No recursion, we don't want to pick up variables // No recursion, we don't want to pick up variables
} }
@ -1597,8 +1601,8 @@ class LinkDotScopeVisitor final : public AstNVisitor {
// Track aliases created by V3Inline; if we get a VARXREF(aliased_from) // Track aliases created by V3Inline; if we get a VARXREF(aliased_from)
// we'll need to replace it with a VARXREF(aliased_to) // we'll need to replace it with a VARXREF(aliased_to)
if (debug() >= 9) nodep->dumpTree(cout, "- alias: "); if (debug() >= 9) nodep->dumpTree(cout, "- alias: ");
AstVarScope* fromVscp = VN_AS(nodep->lhsp(), VarRef)->varScopep(); AstVarScope* const fromVscp = VN_AS(nodep->lhsp(), VarRef)->varScopep();
AstVarScope* toVscp = VN_AS(nodep->rhsp(), VarRef)->varScopep(); AstVarScope* const toVscp = VN_AS(nodep->rhsp(), VarRef)->varScopep();
UASSERT_OBJ(fromVscp && toVscp, nodep, "Bad alias scopes"); UASSERT_OBJ(fromVscp && toVscp, nodep, "Bad alias scopes");
fromVscp->user2p(toVscp); fromVscp->user2p(toVscp);
iterateChildren(nodep); iterateChildren(nodep);
@ -1608,8 +1612,8 @@ class LinkDotScopeVisitor final : public AstNVisitor {
if (debug() >= 9) nodep->dumpTree(cout, "- avs: "); if (debug() >= 9) nodep->dumpTree(cout, "- avs: ");
VSymEnt* rhsSymp; VSymEnt* rhsSymp;
{ {
AstVarRef* refp = VN_CAST(nodep->rhsp(), VarRef); AstVarRef* const refp = VN_CAST(nodep->rhsp(), VarRef);
AstVarXRef* xrefp = VN_CAST(nodep->rhsp(), VarXRef); AstVarXRef* const xrefp = VN_CAST(nodep->rhsp(), VarXRef);
UASSERT_OBJ(refp || xrefp, nodep, UASSERT_OBJ(refp || xrefp, nodep,
"Unsupported: Non Var(X)Ref attached to interface pin"); "Unsupported: Non Var(X)Ref attached to interface pin");
string inl string inl
@ -1638,8 +1642,8 @@ class LinkDotScopeVisitor final : public AstNVisitor {
} }
VSymEnt* lhsSymp; VSymEnt* lhsSymp;
{ {
const AstVarXRef* xrefp = VN_CAST(nodep->lhsp(), VarXRef); const AstVarXRef* const xrefp = VN_CAST(nodep->lhsp(), VarXRef);
const AstVarRef* refp = VN_CAST(nodep->lhsp(), VarRef); const AstVarRef* const refp = VN_CAST(nodep->lhsp(), VarRef);
UASSERT_OBJ(refp || xrefp, nodep, UASSERT_OBJ(refp || xrefp, nodep,
"Unsupported: Non Var(X)Ref attached to interface pin"); "Unsupported: Non Var(X)Ref attached to interface pin");
@ -1647,8 +1651,8 @@ class LinkDotScopeVisitor final : public AstNVisitor {
= refp ? refp->varp()->name() : xrefp->dotted() + "." + xrefp->name(); = refp ? refp->varp()->name() : xrefp->dotted() + "." + xrefp->name();
string baddot; string baddot;
VSymEnt* okSymp; VSymEnt* okSymp;
VSymEnt* symp = m_statep->findDotted(nodep->lhsp()->fileline(), m_modSymp, scopename, VSymEnt* const symp = m_statep->findDotted(nodep->lhsp()->fileline(), m_modSymp,
baddot, okSymp); scopename, baddot, okSymp);
UASSERT_OBJ(symp, nodep, "No symbol for interface alias lhs"); UASSERT_OBJ(symp, nodep, "No symbol for interface alias lhs");
UINFO(5, " Found a linked scope LHS: " << scopename << " se" << cvtToHex(symp) UINFO(5, " Found a linked scope LHS: " << scopename << " se" << cvtToHex(symp)
<< " " << symp->nodep() << endl); << " " << symp->nodep() << endl);
@ -1705,13 +1709,13 @@ class LinkDotIfaceVisitor final : public AstNVisitor {
UINFO(5, " fif: " << nodep << endl); UINFO(5, " fif: " << nodep << endl);
iterateChildren(nodep); iterateChildren(nodep);
if (nodep->isExport()) nodep->v3warn(E_UNSUPPORTED, "Unsupported: modport export"); if (nodep->isExport()) nodep->v3warn(E_UNSUPPORTED, "Unsupported: modport export");
VSymEnt* symp = m_curSymp->findIdFallback(nodep->name()); VSymEnt* const symp = m_curSymp->findIdFallback(nodep->name());
if (!symp) { if (!symp) {
nodep->v3error("Modport item not found: " << nodep->prettyNameQ()); nodep->v3error("Modport item not found: " << nodep->prettyNameQ());
} else if (AstNodeFTask* ftaskp = VN_CAST(symp->nodep(), NodeFTask)) { } else if (AstNodeFTask* const ftaskp = VN_CAST(symp->nodep(), NodeFTask)) {
// Make symbol under modport that points at the _interface_'s var, not the modport. // Make symbol under modport that points at the _interface_'s var, not the modport.
nodep->ftaskp(ftaskp); nodep->ftaskp(ftaskp);
VSymEnt* subSymp VSymEnt* const subSymp
= m_statep->insertSym(m_curSymp, nodep->name(), ftaskp, nullptr /*package*/); = m_statep->insertSym(m_curSymp, nodep->name(), ftaskp, nullptr /*package*/);
m_statep->insertScopeAlias(LinkDotState::SAMN_MODPORT, subSymp, symp); m_statep->insertScopeAlias(LinkDotState::SAMN_MODPORT, subSymp, symp);
} else { } else {
@ -1727,15 +1731,15 @@ class LinkDotIfaceVisitor final : public AstNVisitor {
virtual void visit(AstModportVarRef* nodep) override { virtual void visit(AstModportVarRef* nodep) override {
UINFO(5, " fiv: " << nodep << endl); UINFO(5, " fiv: " << nodep << endl);
iterateChildren(nodep); iterateChildren(nodep);
VSymEnt* symp = m_curSymp->findIdFallback(nodep->name()); VSymEnt* const symp = m_curSymp->findIdFallback(nodep->name());
if (!symp) { if (!symp) {
nodep->v3error("Modport item not found: " << nodep->prettyNameQ()); nodep->v3error("Modport item not found: " << nodep->prettyNameQ());
} else if (AstVar* varp = VN_CAST(symp->nodep(), Var)) { } else if (AstVar* const varp = VN_CAST(symp->nodep(), Var)) {
// Make symbol under modport that points at the _interface_'s var via the modport. // Make symbol under modport that points at the _interface_'s var via the modport.
// (Need modport still to test input/output markings) // (Need modport still to test input/output markings)
nodep->varp(varp); nodep->varp(varp);
m_statep->insertSym(m_curSymp, nodep->name(), nodep, nullptr /*package*/); m_statep->insertSym(m_curSymp, nodep->name(), nodep, nullptr /*package*/);
} else if (AstVarScope* vscp = VN_CAST(symp->nodep(), VarScope)) { } else if (AstVarScope* const vscp = VN_CAST(symp->nodep(), VarScope)) {
// Make symbol under modport that points at the _interface_'s var, not the modport. // Make symbol under modport that points at the _interface_'s var, not the modport.
nodep->varp(vscp->varp()); nodep->varp(vscp->varp());
m_statep->insertSym(m_curSymp, nodep->name(), vscp, nullptr /*package*/); m_statep->insertSym(m_curSymp, nodep->name(), vscp, nullptr /*package*/);
@ -1764,8 +1768,8 @@ public:
void LinkDotState::computeIfaceModSyms() { void LinkDotState::computeIfaceModSyms() {
for (const auto& itr : m_ifaceModSyms) { for (const auto& itr : m_ifaceModSyms) {
AstIface* nodep = itr.first; AstIface* const nodep = itr.first;
VSymEnt* symp = itr.second; VSymEnt* const symp = itr.second;
LinkDotIfaceVisitor{nodep, symp, this}; LinkDotIfaceVisitor{nodep, symp, this};
} }
m_ifaceModSyms.clear(); m_ifaceModSyms.clear();
@ -1796,19 +1800,19 @@ private:
}; // DOT {member-name} [DOT...] }; // DOT {member-name} [DOT...]
// STATE // STATE
LinkDotState* m_statep; // State, including dotted symbol table LinkDotState* const m_statep; // State, including dotted symbol table
VSymEnt* m_curSymp = nullptr; // SymEnt for current lookup point VSymEnt* m_curSymp = nullptr; // SymEnt for current lookup point
VSymEnt* m_modSymp = nullptr; // SymEnt for current module VSymEnt* m_modSymp = nullptr; // SymEnt for current module
VSymEnt* m_pinSymp = nullptr; // SymEnt for pin lookups VSymEnt* m_pinSymp = nullptr; // SymEnt for pin lookups
AstCell* m_cellp = nullptr; // Current cell const AstCell* m_cellp = nullptr; // Current cell
AstNodeModule* m_modp = nullptr; // Current module AstNodeModule* m_modp = nullptr; // Current module
AstNodeFTask* m_ftaskp = nullptr; // Current function/task const AstNodeFTask* m_ftaskp = nullptr; // Current function/task
int m_modportNum = 0; // Uniqueify modport numbers int m_modportNum = 0; // Uniqueify modport numbers
struct DotStates { struct DotStates {
DotPosition m_dotPos; // Scope part of dotted resolution DotPosition m_dotPos; // Scope part of dotted resolution
VSymEnt* m_dotSymp; // SymEnt for dotted AstParse lookup VSymEnt* m_dotSymp; // SymEnt for dotted AstParse lookup
AstDot* m_dotp; // Current dot const AstDot* m_dotp; // Current dot
bool m_unresolved; // Unresolved, needs help from V3Param bool m_unresolved; // Unresolved, needs help from V3Param
AstNode* m_unlinkedScopep; // Unresolved scope, needs corresponding VarXRef AstNode* m_unlinkedScopep; // Unresolved scope, needs corresponding VarXRef
bool m_dotErr; // Error found in dotted resolution, ignore upwards bool m_dotErr; // Error found in dotted resolution, ignore upwards
@ -1863,8 +1867,8 @@ private:
<< (suggest.empty() ? "" : nodep->warnMore() + suggest)); << (suggest.empty() ? "" : nodep->warnMore() + suggest));
} }
} }
AstVar* newp = new AstVar(nodep->fileline(), AstVarType::WIRE, nodep->name(), AstVar* const newp = new AstVar(nodep->fileline(), AstVarType::WIRE, nodep->name(),
VFlagLogicPacked(), 1); VFlagLogicPacked(), 1);
newp->trace(modp->modTrace()); newp->trace(modp->modTrace());
nodep->varp(newp); nodep->varp(newp);
modp->addStmtp(newp); modp->addStmtp(newp);
@ -1880,8 +1884,8 @@ private:
} else if (VN_IS(symp->nodep(), Var)) { } else if (VN_IS(symp->nodep(), Var)) {
return VN_AS(symp->nodep(), Var); return VN_AS(symp->nodep(), Var);
} else if (VN_IS(symp->nodep(), ModportVarRef)) { } else if (VN_IS(symp->nodep(), ModportVarRef)) {
AstModportVarRef* snodep = VN_AS(symp->nodep(), ModportVarRef); AstModportVarRef* const snodep = VN_AS(symp->nodep(), ModportVarRef);
AstVar* varp = snodep->varp(); AstVar* const varp = snodep->varp();
if (access.isWriteOrRW() && snodep->direction().isReadOnly()) { if (access.isWriteOrRW() && snodep->direction().isReadOnly()) {
nodep->v3error("Attempt to drive input-only modport: " << nodep->prettyNameQ()); nodep->v3error("Attempt to drive input-only modport: " << nodep->prettyNameQ());
} // else other simulators don't warn about reading, and IEEE doesn't say illegal } // else other simulators don't warn about reading, and IEEE doesn't say illegal
@ -1906,8 +1910,8 @@ private:
} }
AstVar* findIfaceTopVarp(AstNode* nodep, VSymEnt* parentEntp, const string& name) { AstVar* findIfaceTopVarp(AstNode* nodep, VSymEnt* parentEntp, const string& name) {
const string findName = name + "__Viftop"; const string findName = name + "__Viftop";
VSymEnt* ifaceSymp = parentEntp->findIdFallback(findName); VSymEnt* const ifaceSymp = parentEntp->findIdFallback(findName);
AstVar* ifaceTopVarp = ifaceSymp ? VN_AS(ifaceSymp->nodep(), Var) : nullptr; AstVar* const ifaceTopVarp = ifaceSymp ? VN_AS(ifaceSymp->nodep(), Var) : nullptr;
UASSERT_OBJ(ifaceTopVarp, nodep, "Can't find interface var ref: " << findName); UASSERT_OBJ(ifaceTopVarp, nodep, "Can't find interface var ref: " << findName);
return ifaceTopVarp; return ifaceTopVarp;
} }
@ -2014,8 +2018,8 @@ private:
iterateChildren(nodep); iterateChildren(nodep);
if (!nodep->modVarp()) { if (!nodep->modVarp()) {
UASSERT_OBJ(m_pinSymp, nodep, "Pin not under instance?"); UASSERT_OBJ(m_pinSymp, nodep, "Pin not under instance?");
VSymEnt* foundp = m_pinSymp->findIdFlat(nodep->name()); VSymEnt* const foundp = m_pinSymp->findIdFlat(nodep->name());
const char* whatp = nodep->param() ? "parameter pin" : "pin"; const char* const whatp = nodep->param() ? "parameter pin" : "pin";
if (!foundp) { if (!foundp) {
if (nodep->name() == "__paramNumber1" && m_cellp if (nodep->name() == "__paramNumber1" && m_cellp
&& VN_IS(m_cellp->modp(), Primitive)) { && VN_IS(m_cellp->modp(), Primitive)) {
@ -2023,7 +2027,7 @@ private:
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
return; return;
} }
string suggest const string suggest
= (nodep->param() ? m_statep->suggestSymFlat(m_pinSymp, nodep->name(), = (nodep->param() ? m_statep->suggestSymFlat(m_pinSymp, nodep->name(),
LinkNodeMatcherVarParam()) LinkNodeMatcherVarParam())
: m_statep->suggestSymFlat(m_pinSymp, nodep->name(), : m_statep->suggestSymFlat(m_pinSymp, nodep->name(),
@ -2032,7 +2036,7 @@ private:
ucfirst(whatp) ucfirst(whatp)
<< " not found: " << nodep->prettyNameQ() << '\n' << " not found: " << nodep->prettyNameQ() << '\n'
<< (suggest.empty() ? "" : nodep->warnMore() + suggest)); << (suggest.empty() ? "" : nodep->warnMore() + suggest));
} else if (AstVar* refp = VN_CAST(foundp->nodep(), Var)) { } else if (AstVar* const refp = VN_CAST(foundp->nodep(), Var)) {
if (!refp->isIO() && !refp->isParam() && !refp->isIfaceRef()) { if (!refp->isIO() && !refp->isParam() && !refp->isIfaceRef()) {
nodep->v3error(ucfirst(whatp) << " is not an in/out/inout/param/interface: " nodep->v3error(ucfirst(whatp) << " is not an in/out/inout/param/interface: "
<< nodep->prettyNameQ()); << nodep->prettyNameQ());
@ -2040,7 +2044,7 @@ private:
nodep->modVarp(refp); nodep->modVarp(refp);
markAndCheckPinDup(nodep, refp, whatp); markAndCheckPinDup(nodep, refp, whatp);
} }
} else if (AstParamTypeDType* refp = VN_CAST(foundp->nodep(), ParamTypeDType)) { } else if (AstParamTypeDType* const refp = VN_CAST(foundp->nodep(), ParamTypeDType)) {
nodep->modPTypep(refp); nodep->modPTypep(refp);
markAndCheckPinDup(nodep, refp, whatp); markAndCheckPinDup(nodep, refp, whatp);
} else { } else {
@ -2080,7 +2084,7 @@ private:
UINFO(8, " this. " << m_ds.ascii() << endl); UINFO(8, " this. " << m_ds.ascii() << endl);
} }
} else if (VN_IS(nodep->lhsp(), ParseRef) && nodep->lhsp()->name() == "super") { } else if (VN_IS(nodep->lhsp(), ParseRef) && nodep->lhsp()->name() == "super") {
VSymEnt* classSymp = m_ds.m_dotSymp; const VSymEnt* classSymp = m_ds.m_dotSymp;
do { do {
classSymp = classSymp->parentp(); classSymp = classSymp->parentp();
} while (classSymp && !VN_IS(classSymp->nodep(), Class)); } while (classSymp && !VN_IS(classSymp->nodep(), Class));
@ -2137,8 +2141,8 @@ private:
} else { // Dot midpoint } else { // Dot midpoint
AstNode* newp = nodep->rhsp()->unlinkFrBack(); AstNode* newp = nodep->rhsp()->unlinkFrBack();
if (m_ds.m_unresolved) { if (m_ds.m_unresolved) {
AstCellRef* crp = new AstCellRef(nodep->fileline(), nodep->name(), AstCellRef* const crp = new AstCellRef(nodep->fileline(), nodep->name(),
nodep->lhsp()->unlinkFrBack(), newp); nodep->lhsp()->unlinkFrBack(), newp);
newp = crp; newp = crp;
} }
nodep->replaceWith(newp); nodep->replaceWith(newp);
@ -2182,8 +2186,8 @@ private:
return; return;
} else if (m_ds.m_dotPos == DP_MEMBER) { } else if (m_ds.m_dotPos == DP_MEMBER) {
// Found a Var, everything following is membership. {scope}.{var}.HERE {member} // Found a Var, everything following is membership. {scope}.{var}.HERE {member}
AstNode* varEtcp = m_ds.m_dotp->lhsp()->unlinkFrBack(); AstNode* const varEtcp = m_ds.m_dotp->lhsp()->unlinkFrBack();
AstNode* newp AstNode* const newp
= new AstMemberSel(nodep->fileline(), varEtcp, VFlagChildDType(), nodep->name()); = new AstMemberSel(nodep->fileline(), varEtcp, VFlagChildDType(), nodep->name());
if (m_ds.m_dotErr) { if (m_ds.m_dotErr) {
nodep->unlinkFrBack(); // Avoid circular node loop on errors nodep->unlinkFrBack(); // Avoid circular node loop on errors
@ -2204,7 +2208,8 @@ private:
allowVar = true; allowVar = true;
UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), ClassOrPackageRef), m_ds.m_dotp->lhsp(), UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), ClassOrPackageRef), m_ds.m_dotp->lhsp(),
"Bad package link"); "Bad package link");
AstClassOrPackageRef* cpackagerefp = VN_AS(m_ds.m_dotp->lhsp(), ClassOrPackageRef); AstClassOrPackageRef* const cpackagerefp
= VN_AS(m_ds.m_dotp->lhsp(), ClassOrPackageRef);
classOrPackagep = cpackagerefp->classOrPackagep(); classOrPackagep = cpackagerefp->classOrPackagep();
UASSERT_OBJ(classOrPackagep, m_ds.m_dotp->lhsp(), "Bad package link"); UASSERT_OBJ(classOrPackagep, m_ds.m_dotp->lhsp(), "Bad package link");
m_ds.m_dotSymp = m_statep->getNodeSym(classOrPackagep); m_ds.m_dotSymp = m_statep->getNodeSym(classOrPackagep);
@ -2249,22 +2254,23 @@ private:
m_ds.m_dotPos = DP_SCOPE; m_ds.m_dotPos = DP_SCOPE;
// Upper AstDot visitor will handle it from here // Upper AstDot visitor will handle it from here
} else if (VN_IS(foundp->nodep(), Cell) && allowVar && m_cellp) { } else if (VN_IS(foundp->nodep(), Cell) && allowVar && m_cellp) {
AstCell* cellp = VN_AS(foundp->nodep(), Cell); AstCell* const cellp = VN_AS(foundp->nodep(), Cell);
if (VN_IS(cellp->modp(), Iface)) { if (VN_IS(cellp->modp(), Iface)) {
// Interfaces can be referenced like a variable for interconnect // Interfaces can be referenced like a variable for interconnect
VSymEnt* cellEntp = m_statep->getNodeSym(cellp); VSymEnt* const cellEntp = m_statep->getNodeSym(cellp);
UASSERT_OBJ(cellEntp, nodep, "No interface sym entry"); UASSERT_OBJ(cellEntp, nodep, "No interface sym entry");
VSymEnt* parentEntp VSymEnt* const parentEntp
= cellEntp->parentp(); // Container of the var; probably a module or = cellEntp->parentp(); // Container of the var; probably a module or
// generate begin // generate begin
AstVar* ifaceRefVarp = findIfaceTopVarp(nodep, parentEntp, nodep->name()); AstVar* const ifaceRefVarp
= findIfaceTopVarp(nodep, parentEntp, nodep->name());
// //
ok = true; ok = true;
m_ds.m_dotText = VString::dot(m_ds.m_dotText, ".", nodep->name()); m_ds.m_dotText = VString::dot(m_ds.m_dotText, ".", nodep->name());
m_ds.m_dotSymp = foundp; m_ds.m_dotSymp = foundp;
m_ds.m_dotPos = DP_SCOPE; m_ds.m_dotPos = DP_SCOPE;
UINFO(9, " cell -> iface varref " << foundp->nodep() << endl); UINFO(9, " cell -> iface varref " << foundp->nodep() << endl);
AstNode* newp AstNode* const newp
= new AstVarRef(ifaceRefVarp->fileline(), ifaceRefVarp, VAccess::READ); = new AstVarRef(ifaceRefVarp->fileline(), ifaceRefVarp, VAccess::READ);
nodep->replaceWith(newp); nodep->replaceWith(newp);
VL_DO_DANGLING(pushDeletep(nodep), nodep); VL_DO_DANGLING(pushDeletep(nodep), nodep);
@ -2273,8 +2279,9 @@ private:
<< cellp->modp()->prettyNameQ()); << cellp->modp()->prettyNameQ());
} }
} }
} else if (AstVar* varp = foundToVarp(foundp, nodep, VAccess::READ)) { } else if (AstVar* const varp = foundToVarp(foundp, nodep, VAccess::READ)) {
AstIfaceRefDType* ifacerefp = LinkDotState::ifaceRefFromArray(varp->subDTypep()); AstIfaceRefDType* const ifacerefp
= LinkDotState::ifaceRefFromArray(varp->subDTypep());
if (ifacerefp) { if (ifacerefp) {
UASSERT_OBJ(ifacerefp->ifaceViaCellp(), ifacerefp, "Unlinked interface"); UASSERT_OBJ(ifacerefp->ifaceViaCellp(), ifacerefp, "Unlinked interface");
// Really this is a scope reference into an interface // Really this is a scope reference into an interface
@ -2283,13 +2290,13 @@ private:
m_ds.m_dotSymp = m_statep->getNodeSym(ifacerefp->ifaceViaCellp()); m_ds.m_dotSymp = m_statep->getNodeSym(ifacerefp->ifaceViaCellp());
m_ds.m_dotPos = DP_SCOPE; m_ds.m_dotPos = DP_SCOPE;
ok = true; ok = true;
AstNode* newp = new AstVarRef(nodep->fileline(), varp, VAccess::READ); AstNode* const newp = new AstVarRef(nodep->fileline(), varp, VAccess::READ);
nodep->replaceWith(newp); nodep->replaceWith(newp);
VL_DO_DANGLING(pushDeletep(nodep), nodep); VL_DO_DANGLING(pushDeletep(nodep), nodep);
} else if (allowVar) { } else if (allowVar) {
AstNode* newp; AstNode* newp;
if (m_ds.m_dotText != "") { if (m_ds.m_dotText != "") {
AstVarXRef* refp AstVarXRef* const refp
= new AstVarXRef(nodep->fileline(), nodep->name(), m_ds.m_dotText, = new AstVarXRef(nodep->fileline(), nodep->name(), m_ds.m_dotText,
VAccess::READ); // lvalue'ness computed later VAccess::READ); // lvalue'ness computed later
refp->varp(varp); refp->varp(varp);
@ -2320,7 +2327,7 @@ private:
newp = refp; newp = refp;
} }
} else { } else {
AstVarRef* refp AstVarRef* const refp
= new AstVarRef(nodep->fileline(), varp, = new AstVarRef(nodep->fileline(), varp,
VAccess::READ); // lvalue'ness computed later VAccess::READ); // lvalue'ness computed later
refp->classOrPackagep(foundp->classOrPackagep()); refp->classOrPackagep(foundp->classOrPackagep());
@ -2332,7 +2339,7 @@ private:
m_ds.m_dotPos = DP_MEMBER; m_ds.m_dotPos = DP_MEMBER;
ok = true; ok = true;
} }
} else if (AstModport* modportp = VN_CAST(foundp->nodep(), Modport)) { } else if (const AstModport* const modportp = VN_CAST(foundp->nodep(), Modport)) {
// A scope reference into an interface's modport (not // A scope reference into an interface's modport (not
// necessarily at a pin connection) // necessarily at a pin connection)
UINFO(9, "cell-ref-to-modport " << m_ds.m_dotText << " " << nodep << endl); UINFO(9, "cell-ref-to-modport " << m_ds.m_dotText << " " << nodep << endl);
@ -2349,14 +2356,16 @@ private:
nodep->v3error("Modport not referenced from underneath an interface: " nodep->v3error("Modport not referenced from underneath an interface: "
<< modportp->prettyNameQ()); << modportp->prettyNameQ());
} else { } else {
AstCell* cellp = VN_AS(m_ds.m_dotSymp->nodep(), Cell); AstCell* const cellp = VN_AS(m_ds.m_dotSymp->nodep(), Cell);
UASSERT_OBJ(cellp, nodep, "Modport not referenced from an instance"); UASSERT_OBJ(cellp, nodep, "Modport not referenced from an instance");
VSymEnt* cellEntp = m_statep->getNodeSym(cellp); VSymEnt* const cellEntp = m_statep->getNodeSym(cellp);
UASSERT_OBJ(cellEntp, nodep, "No interface sym entry"); UASSERT_OBJ(cellEntp, nodep, "No interface sym entry");
VSymEnt* parentEntp = cellEntp->parentp(); // Container of the var; probably a VSymEnt* const parentEntp
// module or generate begin = cellEntp->parentp(); // Container of the var; probably a
// module or generate begin
// We drop __BRA__??__KET__ as cells don't have that naming yet // We drop __BRA__??__KET__ as cells don't have that naming yet
AstVar* ifaceRefVarp = findIfaceTopVarp(nodep, parentEntp, cellp->name()); AstVar* const ifaceRefVarp
= findIfaceTopVarp(nodep, parentEntp, cellp->name());
// //
ok = true; ok = true;
m_ds.m_dotText = VString::dot(m_ds.m_dotText, ".", nodep->name()); m_ds.m_dotText = VString::dot(m_ds.m_dotText, ".", nodep->name());
@ -2365,7 +2374,7 @@ private:
UINFO(9, " cell -> iface varref " << foundp->nodep() << endl); UINFO(9, " cell -> iface varref " << foundp->nodep() << endl);
AstNode* newp AstNode* newp
= new AstVarRef(ifaceRefVarp->fileline(), ifaceRefVarp, VAccess::READ); = new AstVarRef(ifaceRefVarp->fileline(), ifaceRefVarp, VAccess::READ);
auto* cellarrayrefp = VN_CAST(m_ds.m_unlinkedScopep, CellArrayRef); auto* const cellarrayrefp = VN_CAST(m_ds.m_unlinkedScopep, CellArrayRef);
if (cellarrayrefp) { if (cellarrayrefp) {
// iface[vec].modport became CellArrayRef(iface, lsb) // iface[vec].modport became CellArrayRef(iface, lsb)
// Convert back to SelBit(iface, lsb) // Convert back to SelBit(iface, lsb)
@ -2379,18 +2388,20 @@ private:
nodep->replaceWith(newp); nodep->replaceWith(newp);
VL_DO_DANGLING(pushDeletep(nodep), nodep); VL_DO_DANGLING(pushDeletep(nodep), nodep);
} }
} else if (AstEnumItem* valuep = VN_CAST(foundp->nodep(), EnumItem)) { } else if (AstEnumItem* const valuep = VN_CAST(foundp->nodep(), EnumItem)) {
if (allowVar) { if (allowVar) {
AstNode* newp AstNode* const newp
= new AstEnumItemRef(nodep->fileline(), valuep, foundp->classOrPackagep()); = new AstEnumItemRef(nodep->fileline(), valuep, foundp->classOrPackagep());
nodep->replaceWith(newp); nodep->replaceWith(newp);
VL_DO_DANGLING(pushDeletep(nodep), nodep); VL_DO_DANGLING(pushDeletep(nodep), nodep);
ok = true; ok = true;
m_ds.m_dotText = ""; m_ds.m_dotText = "";
} }
} else if (AstLambdaArgRef* argrefp = VN_CAST(foundp->nodep(), LambdaArgRef)) { } else if (const AstLambdaArgRef* const argrefp
= VN_CAST(foundp->nodep(), LambdaArgRef)) {
if (allowVar) { if (allowVar) {
AstNode* newp = new AstLambdaArgRef(nodep->fileline(), argrefp->name(), false); AstNode* const newp
= new AstLambdaArgRef(nodep->fileline(), argrefp->name(), false);
nodep->replaceWith(newp); nodep->replaceWith(newp);
VL_DO_DANGLING(pushDeletep(nodep), nodep); VL_DO_DANGLING(pushDeletep(nodep), nodep);
ok = true; ok = true;
@ -2433,7 +2444,7 @@ private:
if (checkImplicit) { if (checkImplicit) {
// Create if implicit, and also if error (so only complain once) // Create if implicit, and also if error (so only complain once)
// Else if a scope is allowed, making a signal won't help error cascade // Else if a scope is allowed, making a signal won't help error cascade
AstVarRef* newp AstVarRef* const newp
= new AstVarRef(nodep->fileline(), nodep->name(), VAccess::READ); = new AstVarRef(nodep->fileline(), nodep->name(), VAccess::READ);
nodep->replaceWith(newp); nodep->replaceWith(newp);
VL_DO_DANGLING(pushDeletep(nodep), nodep); VL_DO_DANGLING(pushDeletep(nodep), nodep);
@ -2452,8 +2463,9 @@ private:
if (!nodep->varp()) { if (!nodep->varp()) {
UINFO(9, " linkVarRef se" << cvtToHex(m_curSymp) << " n=" << nodep << endl); UINFO(9, " linkVarRef se" << cvtToHex(m_curSymp) << " n=" << nodep << endl);
UASSERT_OBJ(m_curSymp, nodep, "nullptr lookup symbol table"); UASSERT_OBJ(m_curSymp, nodep, "nullptr lookup symbol table");
VSymEnt* foundp = m_curSymp->findIdFallback(nodep->name()); VSymEnt* const foundp = m_curSymp->findIdFallback(nodep->name());
if (AstVar* varp = foundp ? foundToVarp(foundp, nodep, nodep->access()) : nullptr) { if (AstVar* const varp
= foundp ? foundToVarp(foundp, nodep, nodep->access()) : nullptr) {
nodep->varp(varp); nodep->varp(varp);
// Generally set by parse, but might be an import // Generally set by parse, but might be an import
nodep->classOrPackagep(foundp->classOrPackagep()); nodep->classOrPackagep(foundp->classOrPackagep());
@ -2493,8 +2505,9 @@ private:
dotSymp = m_statep->findDotted(nodep->fileline(), dotSymp, nodep->dotted(), baddot, dotSymp = m_statep->findDotted(nodep->fileline(), dotSymp, nodep->dotted(), baddot,
okSymp); // Maybe nullptr okSymp); // Maybe nullptr
if (!m_statep->forScopeCreation()) { if (!m_statep->forScopeCreation()) {
VSymEnt* foundp = m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot); VSymEnt* const foundp = m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot);
AstVar* varp = foundp ? foundToVarp(foundp, nodep, nodep->access()) : nullptr; AstVar* const varp
= foundp ? foundToVarp(foundp, nodep, nodep->access()) : nullptr;
nodep->varp(varp); nodep->varp(varp);
UINFO(7, " Resolved " << nodep << endl); // Also prints varp UINFO(7, " Resolved " << nodep << endl); // Also prints varp
if (!nodep->varp()) { if (!nodep->varp()) {
@ -2509,14 +2522,14 @@ private:
// this and convert to normal VarRefs // this and convert to normal VarRefs
if (!m_statep->forPrearray() && !m_statep->forScopeCreation()) { if (!m_statep->forPrearray() && !m_statep->forScopeCreation()) {
if (VN_IS(nodep->dtypep(), IfaceRefDType)) { if (VN_IS(nodep->dtypep(), IfaceRefDType)) {
AstVarRef* newrefp AstVarRef* const newrefp
= new AstVarRef(nodep->fileline(), nodep->varp(), nodep->access()); = new AstVarRef(nodep->fileline(), nodep->varp(), nodep->access());
nodep->replaceWith(newrefp); nodep->replaceWith(newrefp);
VL_DO_DANGLING(nodep->deleteTree(), nodep); VL_DO_DANGLING(nodep->deleteTree(), nodep);
} }
} }
} else { } else {
VSymEnt* foundp = m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot); VSymEnt* const foundp = m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot);
AstVarScope* vscp = foundp ? VN_AS(foundp->nodep(), VarScope) : nullptr; AstVarScope* vscp = foundp ? VN_AS(foundp->nodep(), VarScope) : nullptr;
if (!vscp) { if (!vscp) {
nodep->v3error("Can't find varpin scope of " nodep->v3error("Can't find varpin scope of "
@ -2534,7 +2547,8 @@ private:
nodep->varp(vscp->varp()); nodep->varp(vscp->varp());
nodep->varScopep(vscp); nodep->varScopep(vscp);
UINFO(7, " Resolved " << nodep << endl); // Also prints taskp UINFO(7, " Resolved " << nodep << endl); // Also prints taskp
AstVarRef* newvscp = new AstVarRef(nodep->fileline(), vscp, nodep->access()); AstVarRef* const newvscp
= new AstVarRef(nodep->fileline(), vscp, nodep->access());
nodep->replaceWith(newvscp); nodep->replaceWith(newvscp);
VL_DO_DANGLING(nodep->deleteTree(), nodep); VL_DO_DANGLING(nodep->deleteTree(), nodep);
UINFO(9, " new " << newvscp << endl); // Also prints taskp UINFO(9, " new " << newvscp << endl); // Also prints taskp
@ -2544,7 +2558,7 @@ private:
} }
virtual void visit(AstEnumDType* nodep) override { virtual void visit(AstEnumDType* nodep) override {
iterateChildren(nodep); iterateChildren(nodep);
AstRefDType* refdtypep = VN_CAST(nodep->subDTypep(), RefDType); AstRefDType* const refdtypep = VN_CAST(nodep->subDTypep(), RefDType);
if (refdtypep && (nodep == refdtypep->subDTypep())) { if (refdtypep && (nodep == refdtypep->subDTypep())) {
refdtypep->v3error("Self-referential enumerated type definition"); refdtypep->v3error("Self-referential enumerated type definition");
} }
@ -2576,7 +2590,8 @@ private:
if (m_ds.m_dotp && m_ds.m_dotPos == DP_PACKAGE) { if (m_ds.m_dotp && m_ds.m_dotPos == DP_PACKAGE) {
UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), ClassOrPackageRef), m_ds.m_dotp->lhsp(), UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), ClassOrPackageRef), m_ds.m_dotp->lhsp(),
"Bad package link"); "Bad package link");
AstClassOrPackageRef* cpackagerefp = VN_AS(m_ds.m_dotp->lhsp(), ClassOrPackageRef); AstClassOrPackageRef* const cpackagerefp
= VN_AS(m_ds.m_dotp->lhsp(), ClassOrPackageRef);
if (cpackagerefp->name() == "process" || cpackagerefp->name() == "local") { if (cpackagerefp->name() == "process" || cpackagerefp->name() == "local") {
nodep->v3warn(E_UNSUPPORTED, nodep->v3warn(E_UNSUPPORTED,
"Unsupported: " << AstNode::prettyNameQ(cpackagerefp->name())); "Unsupported: " << AstNode::prettyNameQ(cpackagerefp->name()));
@ -2587,10 +2602,11 @@ private:
m_ds.m_dotp = nullptr; m_ds.m_dotp = nullptr;
} else if (m_ds.m_dotp && m_ds.m_dotPos == DP_FINAL) { } else if (m_ds.m_dotp && m_ds.m_dotPos == DP_FINAL) {
if (m_ds.m_unresolved && m_ds.m_unlinkedScopep) { if (m_ds.m_unresolved && m_ds.m_unlinkedScopep) {
AstNodeFTaskRef* newftaskp = nodep->cloneTree(false); AstNodeFTaskRef* const newftaskp = nodep->cloneTree(false);
newftaskp->dotted(m_ds.m_dotText); newftaskp->dotted(m_ds.m_dotText);
AstNode* newp = new AstUnlinkedRef(nodep->fileline(), newftaskp, nodep->name(), AstNode* const newp
m_ds.m_unlinkedScopep->unlinkFrBack()); = new AstUnlinkedRef(nodep->fileline(), newftaskp, nodep->name(),
m_ds.m_unlinkedScopep->unlinkFrBack());
m_ds.m_unlinkedScopep = nullptr; m_ds.m_unlinkedScopep = nullptr;
m_ds.m_unresolved = false; m_ds.m_unresolved = false;
nodep->replaceWith(newp); nodep->replaceWith(newp);
@ -2601,11 +2617,11 @@ private:
} else if (m_ds.m_dotp && m_ds.m_dotPos == DP_MEMBER) { } else if (m_ds.m_dotp && m_ds.m_dotPos == DP_MEMBER) {
// Found a Var, everything following is method call. // Found a Var, everything following is method call.
// {scope}.{var}.HERE {method} ( ARGS ) // {scope}.{var}.HERE {method} ( ARGS )
AstNode* varEtcp = m_ds.m_dotp->lhsp()->unlinkFrBack(); AstNode* const varEtcp = m_ds.m_dotp->lhsp()->unlinkFrBack();
AstNode* argsp = nullptr; AstNode* argsp = nullptr;
if (nodep->pinsp()) argsp = nodep->pinsp()->unlinkFrBackWithNext(); if (nodep->pinsp()) argsp = nodep->pinsp()->unlinkFrBackWithNext();
AstNode* newp = new AstMethodCall(nodep->fileline(), varEtcp, VFlagChildDType(), AstNode* const newp = new AstMethodCall(nodep->fileline(), varEtcp, VFlagChildDType(),
nodep->name(), argsp); nodep->name(), argsp);
nodep->replaceWith(newp); nodep->replaceWith(newp);
VL_DO_DANGLING(pushDeletep(nodep), nodep); VL_DO_DANGLING(pushDeletep(nodep), nodep);
return; return;
@ -2653,8 +2669,8 @@ private:
dotSymp = m_statep->findDotted(nodep->fileline(), dotSymp, nodep->dotted(), baddot, dotSymp = m_statep->findDotted(nodep->fileline(), dotSymp, nodep->dotted(), baddot,
okSymp); // Maybe nullptr okSymp); // Maybe nullptr
} }
VSymEnt* foundp = m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot); VSymEnt* const foundp = m_statep->findSymPrefixed(dotSymp, nodep->name(), baddot);
AstNodeFTask* taskp AstNodeFTask* const taskp
= foundp ? VN_CAST(foundp->nodep(), NodeFTask) : nullptr; // Maybe nullptr = foundp ? VN_CAST(foundp->nodep(), NodeFTask) : nullptr; // Maybe nullptr
if (taskp) { if (taskp) {
nodep->taskp(taskp); nodep->taskp(taskp);
@ -2688,9 +2704,9 @@ private:
} else { } else {
AstNode* outp = nullptr; AstNode* outp = nullptr;
while (nodep->pinsp()) { while (nodep->pinsp()) {
AstNode* pinp = nodep->pinsp()->unlinkFrBack(); AstNode* const pinp = nodep->pinsp()->unlinkFrBack();
AstNode* addp = pinp; AstNode* addp = pinp;
if (AstArg* argp = VN_CAST(pinp, Arg)) { if (AstArg* const argp = VN_CAST(pinp, Arg)) {
addp = argp->exprp()->unlinkFrBack(); addp = argp->exprp()->unlinkFrBack();
VL_DO_DANGLING(pinp->deleteTree(), pinp); VL_DO_DANGLING(pinp->deleteTree(), pinp);
} }
@ -2751,8 +2767,8 @@ private:
} }
} }
if (m_ds.m_unresolved && m_ds.m_dotPos == DP_SCOPE) { if (m_ds.m_unresolved && m_ds.m_dotPos == DP_SCOPE) {
AstNode* exprp = nodep->bitp()->unlinkFrBack(); AstNode* const exprp = nodep->bitp()->unlinkFrBack();
AstCellArrayRef* newp AstCellArrayRef* const newp
= new AstCellArrayRef(nodep->fileline(), nodep->fromp()->name(), exprp); = new AstCellArrayRef(nodep->fileline(), nodep->fromp()->name(), exprp);
nodep->replaceWith(newp); nodep->replaceWith(newp);
VL_DO_DANGLING(pushDeletep(nodep), nodep); VL_DO_DANGLING(pushDeletep(nodep), nodep);
@ -2784,7 +2800,7 @@ private:
virtual void visit(AstNodeBlock* nodep) override { virtual void visit(AstNodeBlock* nodep) override {
UINFO(5, " " << nodep << endl); UINFO(5, " " << nodep << endl);
checkNoDot(nodep); checkNoDot(nodep);
VSymEnt* oldCurSymp = m_curSymp; VSymEnt* const oldCurSymp = m_curSymp;
{ {
if (nodep->name() != "") { if (nodep->name() != "") {
m_ds.m_dotSymp = m_curSymp = m_statep->getNodeSym(nodep); m_ds.m_dotSymp = m_curSymp = m_statep->getNodeSym(nodep);
@ -2808,7 +2824,7 @@ private:
nodep->v3error("definition not found for extern " + nodep->prettyNameQ()); nodep->v3error("definition not found for extern " + nodep->prettyNameQ());
} }
} }
VSymEnt* oldCurSymp = m_curSymp; VSymEnt* const oldCurSymp = m_curSymp;
{ {
m_ftaskp = nodep; m_ftaskp = nodep;
m_ds.m_dotSymp = m_curSymp = m_statep->getNodeSym(nodep); m_ds.m_dotSymp = m_curSymp = m_statep->getNodeSym(nodep);
@ -2820,7 +2836,7 @@ private:
virtual void visit(AstWith* nodep) override { virtual void visit(AstWith* nodep) override {
UINFO(5, " " << nodep << endl); UINFO(5, " " << nodep << endl);
checkNoDot(nodep); checkNoDot(nodep);
VSymEnt* oldCurSymp = m_curSymp; VSymEnt* const oldCurSymp = m_curSymp;
{ {
m_ds.m_dotSymp = m_curSymp = m_statep->getNodeSym(nodep); m_ds.m_dotSymp = m_curSymp = m_statep->getNodeSym(nodep);
iterateChildren(nodep); iterateChildren(nodep);
@ -2843,19 +2859,19 @@ private:
m_ds.m_dotSymp = m_curSymp = m_modSymp = m_statep->getNodeSym(nodep); m_ds.m_dotSymp = m_curSymp = m_modSymp = m_statep->getNodeSym(nodep);
m_modp = nodep; m_modp = nodep;
for (AstNode* itemp = nodep->extendsp(); itemp; itemp = itemp->nextp()) { for (AstNode* itemp = nodep->extendsp(); itemp; itemp = itemp->nextp()) {
if (AstClassExtends* cextp = VN_CAST(itemp, ClassExtends)) { if (AstClassExtends* const cextp = VN_CAST(itemp, ClassExtends)) {
// Replace abstract reference with hard pointer // Replace abstract reference with hard pointer
// Will need later resolution when deal with parameters // Will need later resolution when deal with parameters
if (cextp->childDTypep() || cextp->dtypep()) continue; // Already converted if (cextp->childDTypep() || cextp->dtypep()) continue; // Already converted
AstClassOrPackageRef* cpackagerefp AstClassOrPackageRef* const cpackagerefp
= VN_CAST(cextp->classOrPkgsp(), ClassOrPackageRef); = VN_CAST(cextp->classOrPkgsp(), ClassOrPackageRef);
if (!cpackagerefp) { if (!cpackagerefp) {
cextp->v3error("Attempting to extend using a non-class "); cextp->v3error("Attempting to extend using a non-class ");
} else { } else {
VSymEnt* foundp = m_curSymp->findIdFallback(cpackagerefp->name()); VSymEnt* const foundp = m_curSymp->findIdFallback(cpackagerefp->name());
bool ok = false; bool ok = false;
if (foundp) { if (foundp) {
if (AstClass* classp = VN_CAST(foundp->nodep(), Class)) { if (AstClass* const classp = VN_CAST(foundp->nodep(), Class)) {
UINFO(8, "Import to " << nodep << " from export class " << classp UINFO(8, "Import to " << nodep << " from export class " << classp
<< endl); << endl);
if (classp == nodep) { if (classp == nodep) {
@ -2869,7 +2885,7 @@ private:
cextp->childDTypep(newp); cextp->childDTypep(newp);
classp->isExtended(true); classp->isExtended(true);
nodep->isExtended(true); nodep->isExtended(true);
VSymEnt* srcp = m_statep->getNodeSym(classp); VSymEnt* const srcp = m_statep->getNodeSym(classp);
m_curSymp->importFromClass(m_statep->symsp(), srcp); m_curSymp->importFromClass(m_statep->symsp(), srcp);
VL_DO_DANGLING(cpackagerefp->unlinkFrBack()->deleteTree(), VL_DO_DANGLING(cpackagerefp->unlinkFrBack()->deleteTree(),
cpackagerefp); cpackagerefp);
@ -2895,11 +2911,11 @@ private:
{ {
nodep->repairCache(); nodep->repairCache();
for (VSymEnt::const_iterator it = m_curSymp->begin(); it != m_curSymp->end(); ++it) { for (VSymEnt::const_iterator it = m_curSymp->begin(); it != m_curSymp->end(); ++it) {
AstNode* itemp = it->second->nodep(); AstNode* const itemp = it->second->nodep();
if (!nodep->findMember(it->first)) { if (!nodep->findMember(it->first)) {
if (AstEnumItem* aitemp = VN_CAST(itemp, EnumItem)) { if (AstEnumItem* const aitemp = VN_CAST(itemp, EnumItem)) {
AstEnumItemRef* newp = new AstEnumItemRef(aitemp->fileline(), aitemp, AstEnumItemRef* const newp = new AstEnumItemRef(
it->second->classOrPackagep()); aitemp->fileline(), aitemp, it->second->classOrPackagep());
UINFO(8, "Class import noderef '" << it->first << "' " << newp << endl); UINFO(8, "Class import noderef '" << it->first << "' " << newp << endl);
nodep->addMembersp(newp); nodep->addMembersp(newp);
} }
@ -2910,8 +2926,8 @@ private:
virtual void visit(AstRefDType* nodep) override { virtual void visit(AstRefDType* nodep) override {
// Resolve its reference // Resolve its reference
if (nodep->user3SetOnce()) return; if (nodep->user3SetOnce()) return;
if (AstNode* cpackagep = nodep->classOrPackageOpp()) { if (AstNode* const cpackagep = nodep->classOrPackageOpp()) {
if (AstClassOrPackageRef* cpackagerefp = VN_CAST(cpackagep, ClassOrPackageRef)) { if (AstClassOrPackageRef* const cpackagerefp = VN_CAST(cpackagep, ClassOrPackageRef)) {
nodep->classOrPackagep(cpackagerefp->classOrPackagep()); nodep->classOrPackagep(cpackagerefp->classOrPackagep());
if (!VN_IS(nodep->classOrPackagep(), Class) if (!VN_IS(nodep->classOrPackagep(), Class)
&& !VN_IS(nodep->classOrPackagep(), Package)) { && !VN_IS(nodep->classOrPackagep(), Package)) {
@ -2931,7 +2947,7 @@ private:
if (m_ds.m_dotp && m_ds.m_dotPos == DP_PACKAGE) { if (m_ds.m_dotp && m_ds.m_dotPos == DP_PACKAGE) {
UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), ClassOrPackageRef), m_ds.m_dotp->lhsp(), UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), ClassOrPackageRef), m_ds.m_dotp->lhsp(),
"Bad package link"); "Bad package link");
auto* cpackagerefp = VN_AS(m_ds.m_dotp->lhsp(), ClassOrPackageRef); auto* const cpackagerefp = VN_AS(m_ds.m_dotp->lhsp(), ClassOrPackageRef);
UASSERT_OBJ(cpackagerefp->classOrPackagep(), m_ds.m_dotp->lhsp(), "Bad package link"); UASSERT_OBJ(cpackagerefp->classOrPackagep(), m_ds.m_dotp->lhsp(), "Bad package link");
nodep->classOrPackagep(cpackagerefp->classOrPackagep()); nodep->classOrPackagep(cpackagerefp->classOrPackagep());
m_ds.m_dotPos = DP_SCOPE; m_ds.m_dotPos = DP_SCOPE;
@ -2941,16 +2957,16 @@ private:
} }
if (nodep->typeofp()) { // Really is a typeof not a reference if (nodep->typeofp()) { // Really is a typeof not a reference
} else if (!nodep->typedefp() && !nodep->subDTypep()) { } else if (!nodep->typedefp() && !nodep->subDTypep()) {
VSymEnt* foundp; const VSymEnt* foundp;
if (nodep->classOrPackagep()) { if (nodep->classOrPackagep()) {
foundp = m_statep->getNodeSym(nodep->classOrPackagep())->findIdFlat(nodep->name()); foundp = m_statep->getNodeSym(nodep->classOrPackagep())->findIdFlat(nodep->name());
} else { } else {
foundp = m_curSymp->findIdFallback(nodep->name()); foundp = m_curSymp->findIdFallback(nodep->name());
} }
if (AstTypedef* defp = foundp ? VN_CAST(foundp->nodep(), Typedef) : nullptr) { if (AstTypedef* const defp = foundp ? VN_CAST(foundp->nodep(), Typedef) : nullptr) {
nodep->typedefp(defp); nodep->typedefp(defp);
nodep->classOrPackagep(foundp->classOrPackagep()); nodep->classOrPackagep(foundp->classOrPackagep());
} else if (AstParamTypeDType* defp } else if (AstParamTypeDType* const defp
= foundp ? VN_CAST(foundp->nodep(), ParamTypeDType) : nullptr) { = foundp ? VN_CAST(foundp->nodep(), ParamTypeDType) : nullptr) {
if (defp == nodep->backp()) { // Where backp is typically typedef if (defp == nodep->backp()) { // Where backp is typically typedef
nodep->v3error("Reference to '" << m_ds.m_dotText nodep->v3error("Reference to '" << m_ds.m_dotText
@ -2962,10 +2978,11 @@ private:
nodep->refDTypep(defp); nodep->refDTypep(defp);
nodep->classOrPackagep(foundp->classOrPackagep()); nodep->classOrPackagep(foundp->classOrPackagep());
} }
} else if (AstClass* defp = foundp ? VN_AS(foundp->nodep(), Class) : nullptr) { } else if (AstClass* const defp = foundp ? VN_AS(foundp->nodep(), Class) : nullptr) {
AstNode* paramsp = nodep->paramsp(); AstNode* const paramsp = nodep->paramsp();
if (paramsp) paramsp->unlinkFrBackWithNext(); if (paramsp) paramsp->unlinkFrBackWithNext();
AstClassRefDType* newp = new AstClassRefDType{nodep->fileline(), defp, paramsp}; AstClassRefDType* const newp
= new AstClassRefDType{nodep->fileline(), defp, paramsp};
newp->classOrPackagep(foundp->classOrPackagep()); newp->classOrPackagep(foundp->classOrPackagep());
nodep->replaceWith(newp); nodep->replaceWith(newp);
VL_DO_DANGLING(nodep->deleteTree(), nodep); VL_DO_DANGLING(nodep->deleteTree(), nodep);
@ -2981,8 +2998,8 @@ private:
// AstDpiExport: Make sure the function referenced exists, then dump it // AstDpiExport: Make sure the function referenced exists, then dump it
iterateChildren(nodep); iterateChildren(nodep);
checkNoDot(nodep); checkNoDot(nodep);
VSymEnt* foundp = m_curSymp->findIdFallback(nodep->name()); VSymEnt* const foundp = m_curSymp->findIdFallback(nodep->name());
AstNodeFTask* taskp = foundp ? VN_AS(foundp->nodep(), NodeFTask) : nullptr; AstNodeFTask* const taskp = foundp ? VN_AS(foundp->nodep(), NodeFTask) : nullptr;
if (!taskp) { if (!taskp) {
nodep->v3error( nodep->v3error(
"Can't find definition of exported task/function: " << nodep->prettyNameQ()); "Can't find definition of exported task/function: " << nodep->prettyNameQ());
@ -3048,13 +3065,13 @@ void V3LinkDot::linkDotGuts(AstNetlist* rootp, VLinkDotStep step) {
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot.tree")); v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot.tree"));
} }
LinkDotState state(rootp, step); LinkDotState state(rootp, step);
LinkDotFindVisitor visitor{rootp, &state}; const LinkDotFindVisitor visitor{rootp, &state};
if (LinkDotState::debug() >= 5 || v3Global.opt.dumpTree() >= 9) { if (LinkDotState::debug() >= 5 || v3Global.opt.dumpTree() >= 9) {
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot-find.tree")); v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot-find.tree"));
} }
if (step == LDS_PRIMARY || step == LDS_PARAMED) { if (step == LDS_PRIMARY || step == LDS_PARAMED) {
// Initial link stage, resolve parameters // Initial link stage, resolve parameters
LinkDotParamVisitor visitors{rootp, &state}; const LinkDotParamVisitor visitors{rootp, &state};
if (LinkDotState::debug() >= 5 || v3Global.opt.dumpTree() >= 9) { if (LinkDotState::debug() >= 5 || v3Global.opt.dumpTree() >= 9) {
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot-param.tree")); v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot-param.tree"));
} }
@ -3062,7 +3079,7 @@ void V3LinkDot::linkDotGuts(AstNetlist* rootp, VLinkDotStep step) {
} else if (step == LDS_SCOPED) { } else if (step == LDS_SCOPED) {
// Well after the initial link when we're ready to operate on the flat design, // Well after the initial link when we're ready to operate on the flat design,
// process AstScope's. This needs to be separate pass after whole hierarchy graph created. // process AstScope's. This needs to be separate pass after whole hierarchy graph created.
LinkDotScopeVisitor visitors{rootp, &state}; const LinkDotScopeVisitor visitors{rootp, &state};
v3Global.assertScoped(true); v3Global.assertScoped(true);
if (LinkDotState::debug() >= 5 || v3Global.opt.dumpTree() >= 9) { if (LinkDotState::debug() >= 5 || v3Global.opt.dumpTree() >= 9) {
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot-scoped.tree")); v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot-scoped.tree"));

View File

@ -259,7 +259,7 @@ private:
// if (debug() >= 9) { UINFO(0, "\n"); blockp->dumpTree(cout, " labeli: "); } // if (debug() >= 9) { UINFO(0, "\n"); blockp->dumpTree(cout, " labeli: "); }
if (!blockp) { if (!blockp) {
nodep->v3error("disable isn't underneath a begin with name: " << nodep->prettyNameQ()); nodep->v3error("disable isn't underneath a begin with name: " << nodep->prettyNameQ());
} else if (AstBegin* beginp = VN_CAST(blockp, Begin)) { } else if (AstBegin* const beginp = VN_CAST(blockp, Begin)) {
// Jump to the end of the named block // Jump to the end of the named block
AstJumpLabel* const labelp = findAddLabel(beginp, false); AstJumpLabel* const labelp = findAddLabel(beginp, false);
nodep->addNextHere(new AstJumpGo(nodep->fileline(), labelp)); nodep->addNextHere(new AstJumpGo(nodep->fileline(), labelp));

View File

@ -142,13 +142,13 @@ void V3LinkLevel::timescaling(const ModVec& mods) {
void V3LinkLevel::wrapTop(AstNetlist* rootp) { void V3LinkLevel::wrapTop(AstNetlist* rootp) {
UINFO(2, __FUNCTION__ << ": " << endl); UINFO(2, __FUNCTION__ << ": " << endl);
// We do ONLY the top module // We do ONLY the top module
AstNodeModule* oldmodp = rootp->modulesp(); AstNodeModule* const oldmodp = rootp->modulesp();
if (!oldmodp) { // Later V3LinkDot will warn if (!oldmodp) { // Later V3LinkDot will warn
UINFO(1, "No module found to wrap\n"); UINFO(1, "No module found to wrap\n");
return; return;
} }
AstNodeModule* newmodp = new AstModule(oldmodp->fileline(), "$root"); AstNodeModule* const newmodp = new AstModule(oldmodp->fileline(), "$root");
newmodp->name(AstNode::encodeName(newmodp->name())); // so origName is nice newmodp->name(AstNode::encodeName(newmodp->name())); // so origName is nice
// Make the new module first in the list // Make the new module first in the list
oldmodp->unlinkFrBackWithNext(); oldmodp->unlinkFrBackWithNext();
@ -167,10 +167,11 @@ void V3LinkLevel::wrapTop(AstNetlist* rootp) {
// This way all later SCOPE based optimizations can ignore packages // This way all later SCOPE based optimizations can ignore packages
for (AstNodeModule* modp = rootp->modulesp(); modp; modp = VN_AS(modp->nextp(), NodeModule)) { for (AstNodeModule* modp = rootp->modulesp(); modp; modp = VN_AS(modp->nextp(), NodeModule)) {
if (VN_IS(modp, Package)) { if (VN_IS(modp, Package)) {
AstCell* cellp = new AstCell(modp->fileline(), modp->fileline(), AstCell* const cellp
// Could add __03a__03a="::" to prevent conflict = new AstCell(modp->fileline(), modp->fileline(),
// with module names/"v" // Could add __03a__03a="::" to prevent conflict
modp->name(), modp->name(), nullptr, nullptr, nullptr); // with module names/"v"
modp->name(), modp->name(), nullptr, nullptr, nullptr);
cellp->modp(modp); cellp->modp(modp);
newmodp->addStmtp(cellp); newmodp->addStmtp(cellp);
} }
@ -180,7 +181,7 @@ void V3LinkLevel::wrapTop(AstNetlist* rootp) {
} }
void V3LinkLevel::wrapTopCell(AstNetlist* rootp) { void V3LinkLevel::wrapTopCell(AstNetlist* rootp) {
AstNodeModule* newmodp = rootp->modulesp(); AstNodeModule* const newmodp = rootp->modulesp();
UASSERT_OBJ(newmodp && newmodp->isTop(), rootp, "No TOP module found to insert under"); UASSERT_OBJ(newmodp && newmodp->isTop(), rootp, "No TOP module found to insert under");
// Find all duplicate signal names (if multitop) // Find all duplicate signal names (if multitop)
@ -191,7 +192,7 @@ void V3LinkLevel::wrapTopCell(AstNetlist* rootp) {
for (AstNodeModule* oldmodp = VN_AS(rootp->modulesp()->nextp(), NodeModule); for (AstNodeModule* oldmodp = VN_AS(rootp->modulesp()->nextp(), NodeModule);
oldmodp && oldmodp->level() <= 2; oldmodp = VN_AS(oldmodp->nextp(), NodeModule)) { oldmodp && oldmodp->level() <= 2; oldmodp = VN_AS(oldmodp->nextp(), NodeModule)) {
for (AstNode* subnodep = oldmodp->stmtsp(); subnodep; subnodep = subnodep->nextp()) { for (AstNode* subnodep = oldmodp->stmtsp(); subnodep; subnodep = subnodep->nextp()) {
if (AstVar* oldvarp = VN_CAST(subnodep, Var)) { if (AstVar* const oldvarp = VN_CAST(subnodep, Var)) {
if (oldvarp->isIO()) { if (oldvarp->isIO()) {
if (ioNames.find(oldvarp->name()) != ioNames.end()) { if (ioNames.find(oldvarp->name()) != ioNames.end()) {
// UINFO(8, "Multitop dup I/O found: " << oldvarp << endl); // UINFO(8, "Multitop dup I/O found: " << oldvarp << endl);
@ -210,7 +211,7 @@ void V3LinkLevel::wrapTopCell(AstNetlist* rootp) {
if (VN_IS(oldmodp, Package)) continue; if (VN_IS(oldmodp, Package)) continue;
// Add instance // Add instance
UINFO(5, "LOOP " << oldmodp << endl); UINFO(5, "LOOP " << oldmodp << endl);
AstCell* cellp = new AstCell( AstCell* const cellp = new AstCell(
newmodp->fileline(), newmodp->fileline(), newmodp->fileline(), newmodp->fileline(),
(!v3Global.opt.l2Name().empty() ? v3Global.opt.l2Name() : oldmodp->name()), (!v3Global.opt.l2Name().empty() ? v3Global.opt.l2Name() : oldmodp->name()),
oldmodp->name(), nullptr, nullptr, nullptr); oldmodp->name(), nullptr, nullptr, nullptr);
@ -219,7 +220,7 @@ void V3LinkLevel::wrapTopCell(AstNetlist* rootp) {
// Add pins // Add pins
for (AstNode* subnodep = oldmodp->stmtsp(); subnodep; subnodep = subnodep->nextp()) { for (AstNode* subnodep = oldmodp->stmtsp(); subnodep; subnodep = subnodep->nextp()) {
if (AstVar* oldvarp = VN_CAST(subnodep, Var)) { if (AstVar* const oldvarp = VN_CAST(subnodep, Var)) {
UINFO(8, "VARWRAP " << oldvarp << endl); UINFO(8, "VARWRAP " << oldvarp << endl);
if (oldvarp->isIO()) { if (oldvarp->isIO()) {
string name = oldvarp->name(); string name = oldvarp->name();
@ -228,7 +229,7 @@ void V3LinkLevel::wrapTopCell(AstNetlist* rootp) {
name = oldmodp->name() + "__02E" + name; name = oldmodp->name() + "__02E" + name;
} }
AstVar* varp = oldvarp->cloneTree(false); AstVar* const varp = oldvarp->cloneTree(false);
varp->name(name); varp->name(name);
varp->protect(false); varp->protect(false);
newmodp->addStmtp(varp); newmodp->addStmtp(varp);
@ -249,7 +250,7 @@ void V3LinkLevel::wrapTopCell(AstNetlist* rootp) {
varp->trace(false); varp->trace(false);
} }
AstPin* pinp = new AstPin( AstPin* const pinp = new AstPin(
oldvarp->fileline(), 0, varp->name(), oldvarp->fileline(), 0, varp->name(),
new AstVarRef(varp->fileline(), varp, new AstVarRef(varp->fileline(), varp,
oldvarp->isWritable() ? VAccess::WRITE : VAccess::READ)); oldvarp->isWritable() ? VAccess::WRITE : VAccess::READ));

View File

@ -185,7 +185,7 @@ private:
nodep->fileline(), nodep->valuep()->cloneTree(true), nodep->fileline(), nodep->valuep()->cloneTree(true),
new AstConst(nodep->fileline(), AstConst::Unsized32(), offset_from_init)); new AstConst(nodep->fileline(), AstConst::Unsized32(), offset_from_init));
} }
AstNode* newp = new AstEnumItem(nodep->fileline(), name, nullptr, valuep); AstNode* const newp = new AstEnumItem(nodep->fileline(), name, nullptr, valuep);
if (addp) { if (addp) {
addp = addp->addNextNull(newp); addp = addp->addNextNull(newp);
} else { } else {
@ -212,15 +212,15 @@ private:
} }
if (VN_IS(nodep->subDTypep(), ParseTypeDType)) { if (VN_IS(nodep->subDTypep(), ParseTypeDType)) {
// It's a parameter type. Use a different node type for this. // It's a parameter type. Use a different node type for this.
AstNodeDType* dtypep = VN_CAST(nodep->valuep(), NodeDType); AstNodeDType* const dtypep = VN_CAST(nodep->valuep(), NodeDType);
if (!dtypep) { if (!dtypep) {
nodep->v3error( nodep->v3error(
"Parameter type's initial value isn't a type: " << nodep->prettyNameQ()); "Parameter type's initial value isn't a type: " << nodep->prettyNameQ());
nodep->unlinkFrBack(); nodep->unlinkFrBack();
} else { } else {
dtypep->unlinkFrBack(); dtypep->unlinkFrBack();
AstNode* newp = new AstParamTypeDType(nodep->fileline(), nodep->varType(), AstNode* const newp = new AstParamTypeDType(
nodep->name(), VFlagChildDType(), dtypep); nodep->fileline(), nodep->varType(), nodep->name(), VFlagChildDType(), dtypep);
nodep->replaceWith(newp); nodep->replaceWith(newp);
VL_DO_DANGLING(nodep->deleteTree(), nodep); VL_DO_DANGLING(nodep->deleteTree(), nodep);
} }
@ -256,7 +256,7 @@ private:
if (m_inAlways) nodep->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true); if (m_inAlways) nodep->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true);
if (nodep->valuep()) { if (nodep->valuep()) {
// A variable with an = value can be three things: // A variable with an = value can be three things:
FileLine* fl = nodep->valuep()->fileline(); FileLine* const fl = nodep->valuep()->fileline();
if (nodep->isParam() || (m_ftaskp && nodep->isNonOutput())) { if (nodep->isParam() || (m_ftaskp && nodep->isNonOutput())) {
// 1. Parameters and function inputs: It's a default to use if not overridden // 1. Parameters and function inputs: It's a default to use if not overridden
} else if (!m_ftaskp && !VN_IS(m_modp, Class) && nodep->isNonOutput()) { } else if (!m_ftaskp && !VN_IS(m_modp, Class) && nodep->isNonOutput()) {
@ -267,9 +267,9 @@ private:
// AstInitial // AstInitial
else if (m_valueModp) { else if (m_valueModp) {
// Making an AstAssign (vs AstAssignW) to a wire is an error, suppress it // Making an AstAssign (vs AstAssignW) to a wire is an error, suppress it
FileLine* newfl = new FileLine(fl); FileLine* const newfl = new FileLine(fl);
newfl->warnOff(V3ErrorCode::PROCASSWIRE, true); newfl->warnOff(V3ErrorCode::PROCASSWIRE, true);
auto* assp auto* const assp
= new AstAssign(newfl, new AstVarRef(newfl, nodep->name(), VAccess::WRITE), = new AstAssign(newfl, new AstVarRef(newfl, nodep->name(), VAccess::WRITE),
nodep->valuep()->unlinkFrBack()); nodep->valuep()->unlinkFrBack());
nodep->addNextHere(new AstInitial(newfl, assp)); nodep->addNextHere(new AstInitial(newfl, assp));
@ -295,7 +295,7 @@ private:
cleanFileline(nodep); cleanFileline(nodep);
iterateChildren(nodep); iterateChildren(nodep);
if (nodep->attrType() == AstAttrType::DT_PUBLIC) { if (nodep->attrType() == AstAttrType::DT_PUBLIC) {
AstTypedef* typep = VN_AS(nodep->backp(), Typedef); AstTypedef* const typep = VN_AS(nodep->backp(), Typedef);
UASSERT_OBJ(typep, nodep, "Attribute not attached to typedef"); UASSERT_OBJ(typep, nodep, "Attribute not attached to typedef");
typep->attrPublic(true); typep->attrPublic(true);
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
@ -379,7 +379,7 @@ private:
// Unique name space under each containerp() so that an addition of // Unique name space under each containerp() so that an addition of
// a new type won't change every verilated module. // a new type won't change every verilated module.
AstTypedef* defp = nullptr; AstTypedef* defp = nullptr;
ImplTypedefMap::iterator it const ImplTypedefMap::iterator it
= m_implTypedef.find(std::make_pair(nodep->containerp(), nodep->name())); = m_implTypedef.find(std::make_pair(nodep->containerp(), nodep->name()));
if (it != m_implTypedef.end()) { if (it != m_implTypedef.end()) {
defp = it->second; defp = it->second;
@ -392,7 +392,7 @@ private:
} }
UASSERT_OBJ(backp, nodep, UASSERT_OBJ(backp, nodep,
"Implicit enum/struct type created under unexpected node type"); "Implicit enum/struct type created under unexpected node type");
AstNodeDType* dtypep = nodep->childDTypep(); AstNodeDType* const dtypep = nodep->childDTypep();
dtypep->unlinkFrBack(); dtypep->unlinkFrBack();
if (VN_IS(backp, Typedef)) { if (VN_IS(backp, Typedef)) {
// A typedef doesn't need us to make yet another level of typedefing // A typedef doesn't need us to make yet another level of typedefing
@ -435,11 +435,11 @@ private:
AstNode* bracketp = nodep->arrayp(); AstNode* bracketp = nodep->arrayp();
AstNode* firstVarsp = nullptr; AstNode* firstVarsp = nullptr;
while (AstDot* dotp = VN_CAST(bracketp, Dot)) { bracketp = dotp->rhsp(); } while (AstDot* dotp = VN_CAST(bracketp, Dot)) { bracketp = dotp->rhsp(); }
if (AstSelBit* selp = VN_CAST(bracketp, SelBit)) { if (AstSelBit* const selp = VN_CAST(bracketp, SelBit)) {
firstVarsp = selp->rhsp()->unlinkFrBackWithNext(); firstVarsp = selp->rhsp()->unlinkFrBackWithNext();
selp->replaceWith(selp->fromp()->unlinkFrBack()); selp->replaceWith(selp->fromp()->unlinkFrBack());
VL_DO_DANGLING(selp->deleteTree(), selp); VL_DO_DANGLING(selp->deleteTree(), selp);
} else if (AstSelLoopVars* selp = VN_CAST(bracketp, SelLoopVars)) { } else if (AstSelLoopVars* const selp = VN_CAST(bracketp, SelLoopVars)) {
firstVarsp = selp->elementsp()->unlinkFrBackWithNext(); firstVarsp = selp->elementsp()->unlinkFrBackWithNext();
selp->replaceWith(selp->fromp()->unlinkFrBack()); selp->replaceWith(selp->fromp()->unlinkFrBack());
VL_DO_DANGLING(selp->deleteTree(), selp); VL_DO_DANGLING(selp->deleteTree(), selp);
@ -449,7 +449,7 @@ private:
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
return; return;
} }
AstNode* arrayp = nodep->arrayp(); // Maybe different node since bracketp looked AstNode* const arrayp = nodep->arrayp(); // Maybe different node since bracketp looked
if (!VN_IS(arrayp, ParseRef) && !VN_IS(arrayp, Dot)) { if (!VN_IS(arrayp, ParseRef) && !VN_IS(arrayp, Dot)) {
// Code below needs to use other then attributes to figure out the bounds // Code below needs to use other then attributes to figure out the bounds
// Also need to deal with queues, etc // Also need to deal with queues, etc
@ -467,26 +467,27 @@ private:
} }
for (AstNode* varsp = lastVarsp; varsp; varsp = varsp->backp()) { for (AstNode* varsp = lastVarsp; varsp; varsp = varsp->backp()) {
UINFO(9, "foreachVar " << varsp << endl); UINFO(9, "foreachVar " << varsp << endl);
FileLine* fl = varsp->fileline(); FileLine* const fl = varsp->fileline();
AstNode* varp AstNode* const varp
= new AstVar(fl, AstVarType::BLOCKTEMP, varsp->name(), nodep->findSigned32DType()); = new AstVar(fl, AstVarType::BLOCKTEMP, varsp->name(), nodep->findSigned32DType());
// These will be the left and right dimensions and size of the array: // These will be the left and right dimensions and size of the array:
AstNode* leftp = new AstAttrOf(fl, AstAttrType::DIM_LEFT, arrayp->cloneTree(false), AstNode* const leftp = new AstAttrOf(
new AstConst(fl, dimension)); fl, AstAttrType::DIM_LEFT, arrayp->cloneTree(false), new AstConst(fl, dimension));
AstNode* rightp = new AstAttrOf(fl, AstAttrType::DIM_RIGHT, arrayp->cloneTree(false), AstNode* const rightp = new AstAttrOf(
new AstConst(fl, dimension)); fl, AstAttrType::DIM_RIGHT, arrayp->cloneTree(false), new AstConst(fl, dimension));
AstNode* sizep = new AstAttrOf(fl, AstAttrType::DIM_SIZE, arrayp->cloneTree(false), AstNode* const sizep = new AstAttrOf(
new AstConst(fl, dimension)); fl, AstAttrType::DIM_SIZE, arrayp->cloneTree(false), new AstConst(fl, dimension));
AstNode* stmtsp = varp; AstNode* const stmtsp = varp;
// Assign left-dimension into the loop var: // Assign left-dimension into the loop var:
stmtsp->addNext( stmtsp->addNext(
new AstAssign(fl, new AstVarRef(fl, varp->name(), VAccess::WRITE), leftp)); new AstAssign(fl, new AstVarRef(fl, varp->name(), VAccess::WRITE), leftp));
// This will turn into a constant bool for static arrays // This will turn into a constant bool for static arrays
AstNode* notemptyp = new AstGt(fl, sizep, new AstConst(fl, 0)); AstNode* const notemptyp = new AstGt(fl, sizep, new AstConst(fl, 0));
// This will turn into a bool constant, indicating whether // This will turn into a bool constant, indicating whether
// we count the loop variable up or down: // we count the loop variable up or down:
AstNode* countupp = new AstLte(fl, leftp->cloneTree(true), rightp->cloneTree(true)); AstNode* const countupp
AstNode* comparep = new AstCond( = new AstLte(fl, leftp->cloneTree(true), rightp->cloneTree(true));
AstNode* const comparep = new AstCond(
fl, countupp->cloneTree(true), fl, countupp->cloneTree(true),
// Left increments up to right // Left increments up to right
new AstLte(fl, new AstVarRef(fl, varp->name(), VAccess::READ), new AstLte(fl, new AstVarRef(fl, varp->name(), VAccess::READ),
@ -494,8 +495,8 @@ private:
// Left decrements down to right // Left decrements down to right
new AstGte(fl, new AstVarRef(fl, varp->name(), VAccess::READ), rightp)); new AstGte(fl, new AstVarRef(fl, varp->name(), VAccess::READ), rightp));
// This will reduce to comparep for static arrays // This will reduce to comparep for static arrays
AstNode* condp = new AstAnd(fl, notemptyp, comparep); AstNode* const condp = new AstAnd(fl, notemptyp, comparep);
AstNode* incp = new AstAssign( AstNode* const incp = new AstAssign(
fl, new AstVarRef(fl, varp->name(), VAccess::WRITE), fl, new AstVarRef(fl, varp->name(), VAccess::WRITE),
new AstAdd(fl, new AstVarRef(fl, varp->name(), VAccess::READ), new AstAdd(fl, new AstVarRef(fl, varp->name(), VAccess::READ),
new AstCond(fl, countupp, new AstConst(fl, 1), new AstConst(fl, -1)))); new AstCond(fl, countupp, new AstConst(fl, 1), new AstConst(fl, -1))));
@ -590,7 +591,7 @@ private:
} }
virtual void visit(AstGenIf* nodep) override { virtual void visit(AstGenIf* nodep) override {
cleanFileline(nodep); cleanFileline(nodep);
bool nestedIf const bool nestedIf
= (VN_IS(nodep->backp(), Begin) && nestedIfBegin(VN_CAST(nodep->backp(), Begin))); = (VN_IS(nodep->backp(), Begin) && nestedIfBegin(VN_CAST(nodep->backp(), Begin)));
if (nestedIf) { if (nestedIf) {
iterateChildren(nodep); iterateChildren(nodep);
@ -638,7 +639,7 @@ private:
virtual void visit(AstTimingControl* nodep) override { virtual void visit(AstTimingControl* nodep) override {
cleanFileline(nodep); cleanFileline(nodep);
iterateChildren(nodep); iterateChildren(nodep);
AstAlways* alwaysp = VN_CAST(nodep->backp(), Always); AstAlways* const alwaysp = VN_CAST(nodep->backp(), Always);
if (alwaysp && alwaysp->keyword() == VAlwaysKwd::ALWAYS_COMB) { if (alwaysp && alwaysp->keyword() == VAlwaysKwd::ALWAYS_COMB) {
alwaysp->v3error("Timing control statements not legal under always_comb " alwaysp->v3error("Timing control statements not legal under always_comb "
"(IEEE 1800-2017 9.2.2.2.2)\n" "(IEEE 1800-2017 9.2.2.2.2)\n"
@ -648,7 +649,7 @@ private:
// Verilator is still ony supporting SenTrees under an always, // Verilator is still ony supporting SenTrees under an always,
// so allow the parser to handle everything and shim to // so allow the parser to handle everything and shim to
// historical AST here // historical AST here
if (AstSenTree* sensesp = nodep->sensesp()) { if (AstSenTree* const sensesp = nodep->sensesp()) {
sensesp->unlinkFrBackWithNext(); sensesp->unlinkFrBackWithNext();
alwaysp->sensesp(sensesp); alwaysp->sensesp(sensesp);
} }

View File

@ -225,17 +225,17 @@ private:
= VN_CAST(basefromp, NodeVarRef)) { // Maybe varxref - so need to clone = VN_CAST(basefromp, NodeVarRef)) { // Maybe varxref - so need to clone
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::VAR_BASE, nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::VAR_BASE,
varrefp->cloneTree(false))); varrefp->cloneTree(false)));
} else if (AstUnlinkedRef* uvxrp } else if (AstUnlinkedRef* const uvxrp
= VN_CAST(basefromp, UnlinkedRef)) { // Maybe unlinked - so need to clone = VN_CAST(basefromp, UnlinkedRef)) { // Maybe unlinked - so need to clone
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::VAR_BASE, nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::VAR_BASE,
uvxrp->cloneTree(false))); uvxrp->cloneTree(false)));
} else if (auto* fromp = VN_CAST(basefromp, LambdaArgRef)) { } else if (auto* const fromp = VN_CAST(basefromp, LambdaArgRef)) {
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::VAR_BASE, nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::VAR_BASE,
fromp->cloneTree(false))); fromp->cloneTree(false)));
} else if (AstMemberSel* fromp = VN_CAST(basefromp, MemberSel)) { } else if (AstMemberSel* const fromp = VN_CAST(basefromp, MemberSel)) {
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::MEMBER_BASE, nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::MEMBER_BASE,
fromp->cloneTree(false))); fromp->cloneTree(false)));
} else if (AstEnumItemRef* fromp = VN_CAST(basefromp, EnumItemRef)) { } else if (AstEnumItemRef* const fromp = VN_CAST(basefromp, EnumItemRef)) {
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::ENUM_BASE, nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::ENUM_BASE,
fromp->cloneTree(false))); fromp->cloneTree(false)));
} else if (VN_IS(basefromp, Replicate)) { } else if (VN_IS(basefromp, Replicate)) {
@ -364,7 +364,7 @@ private:
bool inpercent = false; bool inpercent = false;
for (int i = 0; i < numchars; i++) { for (int i = 0; i < numchars; i++) {
const int ii = numchars - i - 1; const int ii = numchars - i - 1;
char c = constp->num().dataByte(ii); const char c = constp->num().dataByte(ii);
str[i] = c; str[i] = c;
if (!inpercent && c == '%') { if (!inpercent && c == '%') {
inpercent = true; inpercent = true;
@ -584,7 +584,7 @@ public:
void V3LinkResolve::linkResolve(AstNetlist* rootp) { void V3LinkResolve::linkResolve(AstNetlist* rootp) {
UINFO(4, __FUNCTION__ << ": " << endl); UINFO(4, __FUNCTION__ << ": " << endl);
{ {
LinkResolveVisitor visitor{rootp}; const LinkResolveVisitor visitor{rootp};
LinkBotupVisitor{rootp}; LinkBotupVisitor{rootp};
} // Destruct before checking } // Destruct before checking
V3Global::dumpCheckGlobalTree("linkresolve", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6); V3Global::dumpCheckGlobalTree("linkresolve", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);

View File

@ -141,7 +141,7 @@ private:
AstNode* m_mgFirstp = nullptr; // First node in merged sequence AstNode* m_mgFirstp = nullptr; // First node in merged sequence
AstNode* m_mgCondp = nullptr; // The condition of the first node AstNode* m_mgCondp = nullptr; // The condition of the first node
AstNode* m_mgLastp = nullptr; // Last node in merged sequence const AstNode* m_mgLastp = nullptr; // Last node in merged sequence
const AstNode* m_mgNextp = nullptr; // Next node in list being examined const AstNode* m_mgNextp = nullptr; // Next node in list being examined
uint32_t m_listLenght = 0; // Length of current list uint32_t m_listLenght = 0; // Length of current list
@ -158,7 +158,7 @@ private:
static AstNodeCond* extractCond(AstNode* rhsp) { static AstNodeCond* extractCond(AstNode* rhsp) {
if (AstNodeCond* const condp = VN_CAST(rhsp, NodeCond)) { if (AstNodeCond* const condp = VN_CAST(rhsp, NodeCond)) {
return condp; return condp;
} else if (AstAnd* const andp = VN_CAST(rhsp, And)) { } else if (const AstAnd* const andp = VN_CAST(rhsp, And)) {
if (AstNodeCond* const condp = VN_CAST(andp->rhsp(), NodeCond)) { if (AstNodeCond* const condp = VN_CAST(andp->rhsp(), NodeCond)) {
if (VN_IS(andp->lhsp(), Const)) return condp; if (VN_IS(andp->lhsp(), Const)) return condp;
} }
@ -173,7 +173,7 @@ private:
return constp->num().toUQuad() <= 1; return constp->num().toUQuad() <= 1;
} }
if (const AstVarRef* const vrefp = VN_CAST(nodep, VarRef)) { if (const AstVarRef* const vrefp = VN_CAST(nodep, VarRef)) {
AstVar* const varp = vrefp->varp(); const AstVar* const varp = vrefp->varp();
return varp->widthMin() == 1 && !varp->dtypep()->isSigned(); return varp->widthMin() == 1 && !varp->dtypep()->isSigned();
} }
if (const AstShiftR* const shiftp = VN_CAST(nodep, ShiftR)) { if (const AstShiftR* const shiftp = VN_CAST(nodep, ShiftR)) {
@ -225,17 +225,17 @@ private:
AstNode* foldAndUnlink(AstNode* rhsp, bool condTrue) { AstNode* foldAndUnlink(AstNode* rhsp, bool condTrue) {
if (rhsp->sameTree(m_mgCondp)) { if (rhsp->sameTree(m_mgCondp)) {
return new AstConst(rhsp->fileline(), AstConst::BitTrue{}, condTrue); return new AstConst(rhsp->fileline(), AstConst::BitTrue{}, condTrue);
} else if (AstNodeCond* const condp = extractCond(rhsp)) { } else if (const AstNodeCond* const condp = extractCond(rhsp)) {
AstNode* const resp AstNode* const resp
= condTrue ? condp->expr1p()->unlinkFrBack() : condp->expr2p()->unlinkFrBack(); = condTrue ? condp->expr1p()->unlinkFrBack() : condp->expr2p()->unlinkFrBack();
if (condp == rhsp) { // if (condp == rhsp) { //
return resp; return resp;
} }
if (AstAnd* const andp = VN_CAST(rhsp, And)) { if (const AstAnd* const andp = VN_CAST(rhsp, And)) {
UASSERT_OBJ(andp->rhsp() == condp, rhsp, "Should not try to fold this"); UASSERT_OBJ(andp->rhsp() == condp, rhsp, "Should not try to fold this");
return new AstAnd{andp->fileline(), andp->lhsp()->cloneTree(false), resp}; return new AstAnd{andp->fileline(), andp->lhsp()->cloneTree(false), resp};
} }
} else if (AstAnd* const andp = VN_CAST(rhsp, And)) { } else if (const AstAnd* const andp = VN_CAST(rhsp, And)) {
if (andp->lhsp()->sameTree(m_mgCondp)) { if (andp->lhsp()->sameTree(m_mgCondp)) {
return condTrue ? maskLsb(andp->rhsp()->unlinkFrBack()) return condTrue ? maskLsb(andp->rhsp()->unlinkFrBack())
: new AstConst{rhsp->fileline(), AstConst::BitFalse()}; : new AstConst{rhsp->fileline(), AstConst::BitFalse()};
@ -255,11 +255,11 @@ private:
void mergeEnd(int lineno) { void mergeEnd(int lineno) {
UASSERT(m_mgFirstp, "mergeEnd without list " << lineno); UASSERT(m_mgFirstp, "mergeEnd without list " << lineno);
// We might want to recursively merge an AstIf. We stash it in this variable. // We might want to recursively merge an AstIf. We stash it in this variable.
AstNodeIf* recursivep = nullptr; const AstNodeIf* recursivep = nullptr;
// Drop leading cheap nodes. These were only added in the hope of finding // Drop leading cheap nodes. These were only added in the hope of finding
// an earlier reduced form, but we failed to do so. // an earlier reduced form, but we failed to do so.
while (m_mgFirstp->user2() && m_mgFirstp != m_mgLastp) { while (m_mgFirstp->user2() && m_mgFirstp != m_mgLastp) {
AstNode* const backp = m_mgFirstp; const AstNode* const backp = m_mgFirstp;
m_mgFirstp = m_mgFirstp->nextp(); m_mgFirstp = m_mgFirstp->nextp();
--m_listLenght; --m_listLenght;
UASSERT_OBJ(m_mgFirstp && m_mgFirstp->backp() == backp, m_mgLastp, UASSERT_OBJ(m_mgFirstp && m_mgFirstp->backp() == backp, m_mgLastp,
@ -268,7 +268,7 @@ private:
// Drop trailing cheap nodes. These were only added in the hope of finding // Drop trailing cheap nodes. These were only added in the hope of finding
// a later conditional to merge, but we failed to do so. // a later conditional to merge, but we failed to do so.
while (m_mgLastp->user2() && m_mgFirstp != m_mgLastp) { while (m_mgLastp->user2() && m_mgFirstp != m_mgLastp) {
AstNode* const nextp = m_mgLastp; const AstNode* const nextp = m_mgLastp;
m_mgLastp = m_mgLastp->backp(); m_mgLastp = m_mgLastp->backp();
--m_listLenght; --m_listLenght;
UASSERT_OBJ(m_mgLastp && m_mgLastp->nextp() == nextp, m_mgFirstp, UASSERT_OBJ(m_mgLastp && m_mgLastp->nextp() == nextp, m_mgFirstp,
@ -328,7 +328,7 @@ private:
} while (nextp); } while (nextp);
// Recursively merge the resulting AstIf // Recursively merge the resulting AstIf
recursivep = resultp; recursivep = resultp;
} else if (AstNodeIf* const ifp = VN_CAST(m_mgFirstp, NodeIf)) { } else if (const AstNodeIf* const ifp = VN_CAST(m_mgFirstp, NodeIf)) {
// There was nothing to merge this AstNodeIf with, but try to merge it's branches // There was nothing to merge this AstNodeIf with, but try to merge it's branches
recursivep = ifp; recursivep = ifp;
} }
@ -353,11 +353,11 @@ private:
// Check if the node can be simplified if included under the if // Check if the node can be simplified if included under the if
bool isSimplifiableNode(AstNode* nodep) { bool isSimplifiableNode(AstNode* nodep) {
UASSERT_OBJ(m_mgFirstp, nodep, "Cannot check with empty list"); UASSERT_OBJ(m_mgFirstp, nodep, "Cannot check with empty list");
if (AstNodeAssign* const assignp = VN_CAST(nodep, NodeAssign)) { if (const AstNodeAssign* const assignp = VN_CAST(nodep, NodeAssign)) {
// If it's an assignment to a 1-bit signal, try reduced forms // If it's an assignment to a 1-bit signal, try reduced forms
if (assignp->lhsp()->widthMin() == 1) { if (assignp->lhsp()->widthMin() == 1) {
// Is it a 'lhs = cond & value' or 'lhs = value & cond'? // Is it a 'lhs = cond & value' or 'lhs = value & cond'?
if (AstAnd* const andp = VN_CAST(assignp->rhsp(), And)) { if (const AstAnd* const andp = VN_CAST(assignp->rhsp(), And)) {
if (andp->lhsp()->sameTree(m_mgCondp) || andp->rhsp()->sameTree(m_mgCondp)) { if (andp->lhsp()->sameTree(m_mgCondp) || andp->rhsp()->sameTree(m_mgCondp)) {
return true; return true;
} }
@ -373,7 +373,7 @@ private:
// AstIf and is hence not likely to cause a performance degradation if doing so. // AstIf and is hence not likely to cause a performance degradation if doing so.
bool isCheapNode(AstNode* nodep) const { bool isCheapNode(AstNode* nodep) const {
if (VN_IS(nodep, Comment)) return true; if (VN_IS(nodep, Comment)) return true;
if (AstNodeAssign* const assignp = VN_CAST(nodep, NodeAssign)) { if (const AstNodeAssign* const assignp = VN_CAST(nodep, NodeAssign)) {
// Check LHS // Check LHS
AstNode* lhsp = assignp->lhsp(); AstNode* lhsp = assignp->lhsp();
while (AstWordSel* const wselp = VN_CAST(lhsp, WordSel)) { while (AstWordSel* const wselp = VN_CAST(lhsp, WordSel)) {
@ -479,7 +479,7 @@ private:
// VISITORS // VISITORS
virtual void visit(AstNodeAssign* nodep) override { virtual void visit(AstNodeAssign* nodep) override {
AstNode* const rhsp = nodep->rhsp(); AstNode* const rhsp = nodep->rhsp();
if (AstNodeCond* const condp = extractCond(rhsp)) { if (const AstNodeCond* const condp = extractCond(rhsp)) {
// Check if mergeable // Check if mergeable
if (!checkOrMakeMergeable(nodep)) return; if (!checkOrMakeMergeable(nodep)) return;
// Close potentially incompatible pending merge // Close potentially incompatible pending merge

View File

@ -40,7 +40,7 @@ private:
const AstUser1InUse m_inuser1; const AstUser1InUse m_inuser1;
// STATE // STATE
AstNodeModule* m_modp = nullptr; const AstNodeModule* m_modp = nullptr;
// METHODS // METHODS
VL_DEBUG_FUNC; // Declare debug() VL_DEBUG_FUNC; // Declare debug()

View File

@ -220,8 +220,8 @@ void V3Number::V3NumberCreate(AstNode* nodep, const char* sourcep, FileLine* fl)
// this = (this * 10)/*product*/ + (*cp-'0')/*addend*/ // this = (this * 10)/*product*/ + (*cp-'0')/*addend*/
// Assumed rare; lots of optimizations are possible here // Assumed rare; lots of optimizations are possible here
V3Number product(this, width() + 4); // +4 for overflow detection V3Number product(this, width() + 4); // +4 for overflow detection
V3Number ten(this, width() + 4, 10); const V3Number ten(this, width() + 4, 10);
V3Number addend(this, width(), (*cp - '0')); const V3Number addend(this, width(), (*cp - '0'));
product.opMul(*this, ten); product.opMul(*this, ten);
this->opAdd(product, addend); this->opAdd(product, addend);
if (product.bitsValue(width(), 4)) { // Overflowed if (product.bitsValue(width(), 4)) { // Overflowed
@ -623,7 +623,7 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const {
str += 'Z'; str += 'Z';
continue; continue;
} }
int v = bitsValue(bit - 2, 3); const int v = bitsValue(bit - 2, 3);
str += static_cast<char>('0' + v); str += static_cast<char>('0' + v);
} }
return str; return str;
@ -653,7 +653,7 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const {
str += 'Z'; str += 'Z';
continue; continue;
} }
int v = bitsValue(bit - 3, 4); const int v = bitsValue(bit - 3, 4);
if (v >= 10) { if (v >= 10) {
str += static_cast<char>('a' + v - 10); str += static_cast<char>('a' + v - 10);
} else { } else {
@ -664,7 +664,7 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const {
} }
case 'c': { case 'c': {
if (width() > 8) fl->v3warn(WIDTH, "$display-like format of %c format of > 8 bit value"); if (width() > 8) fl->v3warn(WIDTH, "$display-like format of %c format of > 8 bit value");
unsigned int v = bitsValue(0, 8); const unsigned int v = bitsValue(0, 8);
char strc[2]; char strc[2];
strc[0] = v & 0xff; strc[0] = v & 0xff;
strc[1] = '\0'; strc[1] = '\0';
@ -677,7 +677,7 @@ string V3Number::displayed(FileLine* fl, const string& vformat) const {
bool start = true; bool start = true;
while ((bit % 8) != 7) bit++; while ((bit % 8) != 7) bit++;
for (; bit >= 0; bit -= 8) { for (; bit >= 0; bit -= 8) {
int v = bitsValue(bit - 7, 8); const int v = bitsValue(bit - 7, 8);
if (!start || v) { if (!start || v) {
str += static_cast<char>((v == 0) ? ' ' : v); str += static_cast<char>((v == 0) ? ' ' : v);
start = false; // Drop leading 0s start = false; // Drop leading 0s
@ -880,9 +880,9 @@ double V3Number::toDouble() const {
vlsint32_t V3Number::toSInt() const { vlsint32_t V3Number::toSInt() const {
if (isSigned()) { if (isSigned()) {
uint32_t v = toUInt(); const uint32_t v = toUInt();
uint32_t signExtend = (-(v & (1UL << (width() - 1)))); const uint32_t signExtend = (-(v & (1UL << (width() - 1))));
uint32_t extended = v | signExtend; const uint32_t extended = v | signExtend;
return static_cast<vlsint32_t>(extended); return static_cast<vlsint32_t>(extended);
} else { } else {
// Where we use this (widths, etc) and care about signedness, // Where we use this (widths, etc) and care about signedness,
@ -908,9 +908,9 @@ vluint64_t V3Number::toUQuad() const {
vlsint64_t V3Number::toSQuad() const { vlsint64_t V3Number::toSQuad() const {
if (isDouble()) return static_cast<vlsint64_t>(toDouble()); if (isDouble()) return static_cast<vlsint64_t>(toDouble());
vluint64_t v = toUQuad(); const vluint64_t v = toUQuad();
vluint64_t signExtend = (-(v & (1ULL << (width() - 1)))); const vluint64_t signExtend = (-(v & (1ULL << (width() - 1))));
vluint64_t extended = v | signExtend; const vluint64_t extended = v | signExtend;
return static_cast<vlsint64_t>(extended); return static_cast<vlsint64_t>(extended);
} }
@ -923,7 +923,7 @@ string V3Number::toString() const {
while ((bit % 8) != 7) bit++; while ((bit % 8) != 7) bit++;
string str; string str;
for (; bit >= 0; bit -= 8) { for (; bit >= 0; bit -= 8) {
int v = bitsValue(bit - 7, 8); const int v = bitsValue(bit - 7, 8);
if (!start || v) { if (!start || v) {
str += static_cast<char>((v == 0) ? ' ' : v); str += static_cast<char>((v == 0) ? ' ' : v);
start = false; // Drop leading 0s start = false; // Drop leading 0s
@ -1745,7 +1745,7 @@ V3Number& V3Number::opShiftR(const V3Number& lhs, const V3Number& rhs) {
for (int bit = 32; bit < rhs.width(); bit++) { for (int bit = 32; bit < rhs.width(); bit++) {
if (rhs.bitIs1(bit)) return *this; // shift of over 2^32 must be zero if (rhs.bitIs1(bit)) return *this; // shift of over 2^32 must be zero
} }
uint32_t rhsval = rhs.toUInt(); const uint32_t rhsval = rhs.toUInt();
if (rhsval < static_cast<uint32_t>(lhs.width())) { if (rhsval < static_cast<uint32_t>(lhs.width())) {
for (int bit = 0; bit < this->width(); bit++) setBit(bit, lhs.bitIs(bit + rhsval)); for (int bit = 0; bit < this->width(); bit++) setBit(bit, lhs.bitIs(bit + rhsval));
} }
@ -1767,7 +1767,7 @@ V3Number& V3Number::opShiftRS(const V3Number& lhs, const V3Number& rhs, uint32_t
if (rhs.bitIs1(lbits - 1)) setAllBits1(); // -1 else 0 if (rhs.bitIs1(lbits - 1)) setAllBits1(); // -1 else 0
return *this; // shift of over 2^32 must be -1/0 return *this; // shift of over 2^32 must be -1/0
} }
uint32_t rhsval = rhs.toUInt(); const uint32_t rhsval = rhs.toUInt();
if (rhsval < static_cast<uint32_t>(lhs.width())) { if (rhsval < static_cast<uint32_t>(lhs.width())) {
for (int bit = 0; bit < this->width(); bit++) { for (int bit = 0; bit < this->width(); bit++) {
setBit(bit, lhs.bitIsExtend(bit + rhsval, lbits)); setBit(bit, lhs.bitIsExtend(bit + rhsval, lbits));
@ -1789,7 +1789,7 @@ V3Number& V3Number::opShiftL(const V3Number& lhs, const V3Number& rhs) {
for (int bit = 32; bit < rhs.width(); bit++) { for (int bit = 32; bit < rhs.width(); bit++) {
if (rhs.bitIs1(bit)) return *this; // shift of over 2^32 must be zero if (rhs.bitIs1(bit)) return *this; // shift of over 2^32 must be zero
} }
uint32_t rhsval = rhs.toUInt(); const uint32_t rhsval = rhs.toUInt();
for (int bit = 0; bit < this->width(); bit++) { for (int bit = 0; bit < this->width(); bit++) {
if (bit >= static_cast<int>(rhsval)) setBit(bit, lhs.bitIs(bit - rhsval)); if (bit >= static_cast<int>(rhsval)) setBit(bit, lhs.bitIs(bit - rhsval));
} }
@ -1806,7 +1806,7 @@ V3Number& V3Number::opNegate(const V3Number& lhs) {
if (lhs.isFourState()) return setAllBitsX(); if (lhs.isFourState()) return setAllBitsX();
V3Number notlhs(&lhs, width()); V3Number notlhs(&lhs, width());
notlhs.opNot(lhs); notlhs.opNot(lhs);
V3Number one(&lhs, width(), 1); const V3Number one(&lhs, width(), 1);
opAdd(notlhs, one); opAdd(notlhs, one);
return *this; return *this;
} }
@ -1872,7 +1872,7 @@ V3Number& V3Number::opMulS(const V3Number& lhs, const V3Number& rhs) {
if (lhs.isNegative()) lhsNoSign.opNegate(lhs); if (lhs.isNegative()) lhsNoSign.opNegate(lhs);
V3Number rhsNoSign = rhs; V3Number rhsNoSign = rhs;
if (rhs.isNegative()) rhsNoSign.opNegate(rhs); if (rhs.isNegative()) rhsNoSign.opNegate(rhs);
V3Number qNoSign = opMul(lhsNoSign, rhsNoSign); const V3Number qNoSign = opMul(lhsNoSign, rhsNoSign);
if ((lhs.isNegative() && !rhs.isNegative()) || (!lhs.isNegative() && rhs.isNegative())) { if ((lhs.isNegative() && !rhs.isNegative()) || (!lhs.isNegative() && rhs.isNegative())) {
opNegate(qNoSign); opNegate(qNoSign);
} else { } else {
@ -1906,7 +1906,7 @@ V3Number& V3Number::opDivS(const V3Number& lhs, const V3Number& rhs) {
if (lhs.isNegative()) lhsNoSign.opNegate(lhs); if (lhs.isNegative()) lhsNoSign.opNegate(lhs);
V3Number rhsNoSign = rhs; V3Number rhsNoSign = rhs;
if (rhs.isNegative()) rhsNoSign.opNegate(rhs); if (rhs.isNegative()) rhsNoSign.opNegate(rhs);
V3Number qNoSign = opDiv(lhsNoSign, rhsNoSign); const V3Number qNoSign = opDiv(lhsNoSign, rhsNoSign);
// UINFO(9, " >divs-mid "<<lhs<<" "<<rhs<<" "<<qNoSign<<endl); // UINFO(9, " >divs-mid "<<lhs<<" "<<rhs<<" "<<qNoSign<<endl);
if ((lhs.isNegative() && !rhs.isNegative()) || (!lhs.isNegative() && rhs.isNegative())) { if ((lhs.isNegative() && !rhs.isNegative()) || (!lhs.isNegative() && rhs.isNegative())) {
opNegate(qNoSign); opNegate(qNoSign);
@ -1940,7 +1940,7 @@ V3Number& V3Number::opModDivS(const V3Number& lhs, const V3Number& rhs) {
if (lhs.isNegative()) lhsNoSign.opNegate(lhs); if (lhs.isNegative()) lhsNoSign.opNegate(lhs);
V3Number rhsNoSign = rhs; V3Number rhsNoSign = rhs;
if (rhs.isNegative()) rhsNoSign.opNegate(rhs); if (rhs.isNegative()) rhsNoSign.opNegate(rhs);
V3Number qNoSign = opModDiv(lhsNoSign, rhsNoSign); const V3Number qNoSign = opModDiv(lhsNoSign, rhsNoSign);
if (lhs.isNegative()) { // Just lhs' sign (*DIFFERENT FROM PERL, which uses rhs sign*) if (lhs.isNegative()) { // Just lhs' sign (*DIFFERENT FROM PERL, which uses rhs sign*)
opNegate(qNoSign); opNegate(qNoSign);
} else { } else {
@ -1956,8 +1956,8 @@ V3Number& V3Number::opModDivGuts(const V3Number& lhs, const V3Number& rhs, bool
setZero(); setZero();
// Find MSB and check for zero. // Find MSB and check for zero.
const int words = lhs.words(); const int words = lhs.words();
int umsbp1 = lhs.mostSetBitP1(); // dividend const int umsbp1 = lhs.mostSetBitP1(); // dividend
int vmsbp1 = rhs.mostSetBitP1(); // divisor const int vmsbp1 = rhs.mostSetBitP1(); // divisor
if (VL_UNLIKELY(vmsbp1 == 0) // rwp==0 so division by zero. Return 0. if (VL_UNLIKELY(vmsbp1 == 0) // rwp==0 so division by zero. Return 0.
|| VL_UNLIKELY(umsbp1 == 0)) { // 0/x so short circuit and return 0 || VL_UNLIKELY(umsbp1 == 0)) { // 0/x so short circuit and return 0
UINFO(9, " opmoddiv-zero " << lhs << " " << rhs << " now=" << *this << endl); UINFO(9, " opmoddiv-zero " << lhs << " " << rhs << " now=" << *this << endl);
@ -1970,7 +1970,8 @@ V3Number& V3Number::opModDivGuts(const V3Number& lhs, const V3Number& rhs, bool
if (vw == 1) { // Single divisor word breaks rest of algorithm if (vw == 1) { // Single divisor word breaks rest of algorithm
vluint64_t k = 0; vluint64_t k = 0;
for (int j = uw - 1; j >= 0; j--) { for (int j = uw - 1; j >= 0; j--) {
vluint64_t unw64 = ((k << 32ULL) + static_cast<vluint64_t>(lhs.m_value[j].m_value)); const vluint64_t unw64
= ((k << 32ULL) + static_cast<vluint64_t>(lhs.m_value[j].m_value));
m_value[j].m_value = unw64 / static_cast<vluint64_t>(rhs.m_value[0].m_value); m_value[j].m_value = unw64 / static_cast<vluint64_t>(rhs.m_value[0].m_value);
k = unw64 k = unw64
- (static_cast<vluint64_t>(m_value[j].m_value) - (static_cast<vluint64_t>(m_value[j].m_value)
@ -1996,8 +1997,8 @@ V3Number& V3Number::opModDivGuts(const V3Number& lhs, const V3Number& rhs, bool
// Algorithm requires divisor MSB to be set // Algorithm requires divisor MSB to be set
// Copy and shift to normalize divisor so MSB of vn[vw-1] is set // Copy and shift to normalize divisor so MSB of vn[vw-1] is set
int s = 31 - ((vmsbp1 - 1) & 31); // shift amount (0...31) const int s = 31 - ((vmsbp1 - 1) & 31); // shift amount (0...31)
uint32_t shift_mask = s ? 0xffffffff : 0; // otherwise >> 32 won't mask the value const uint32_t shift_mask = s ? 0xffffffff : 0; // otherwise >> 32 won't mask the value
for (int i = vw - 1; i > 0; i--) { for (int i = vw - 1; i > 0; i--) {
vn[i] = (rhs.m_value[i].m_value << s) vn[i] = (rhs.m_value[i].m_value << s)
| (shift_mask & (rhs.m_value[i - 1].m_value >> (32 - s))); | (shift_mask & (rhs.m_value[i - 1].m_value >> (32 - s)));
@ -2023,8 +2024,8 @@ V3Number& V3Number::opModDivGuts(const V3Number& lhs, const V3Number& rhs, bool
// Main loop // Main loop
for (int j = uw - vw; j >= 0; j--) { for (int j = uw - vw; j >= 0; j--) {
// Estimate // Estimate
vluint64_t unw64 = (static_cast<vluint64_t>(un[j + vw]) << 32ULL const vluint64_t unw64 = (static_cast<vluint64_t>(un[j + vw]) << 32ULL
| static_cast<vluint64_t>(un[j + vw - 1])); | static_cast<vluint64_t>(un[j + vw - 1]));
vluint64_t qhat = unw64 / static_cast<vluint64_t>(vn[vw - 1]); vluint64_t qhat = unw64 / static_cast<vluint64_t>(vn[vw - 1]);
vluint64_t rhat = unw64 - qhat * static_cast<vluint64_t>(vn[vw - 1]); vluint64_t rhat = unw64 - qhat * static_cast<vluint64_t>(vn[vw - 1]);
@ -2038,7 +2039,7 @@ V3Number& V3Number::opModDivGuts(const V3Number& lhs, const V3Number& rhs, bool
vlsint64_t t = 0; // Must be signed vlsint64_t t = 0; // Must be signed
vluint64_t k = 0; vluint64_t k = 0;
for (int i = 0; i < vw; i++) { for (int i = 0; i < vw; i++) {
vluint64_t p = qhat * vn[i]; // Multiply by estimate const vluint64_t p = qhat * vn[i]; // Multiply by estimate
t = un[i + j] - k - (p & 0xFFFFFFFFULL); // Subtract t = un[i + j] - k - (p & 0xFFFFFFFFULL); // Subtract
un[i + j] = t; un[i + j] = t;
k = (p >> 32ULL) - (t >> 32ULL); k = (p >> 32ULL) - (t >> 32ULL);
@ -2192,8 +2193,8 @@ void V3Number::opCleanThis(bool warnOnTruncation) {
// Clean MSB of number // Clean MSB of number
NUM_ASSERT_LOGIC_ARGS1(*this); NUM_ASSERT_LOGIC_ARGS1(*this);
const ValueAndX v = m_value[words() - 1]; const ValueAndX v = m_value[words() - 1];
uint32_t newValueMsb = v.m_value & hiWordMask(); const uint32_t newValueMsb = v.m_value & hiWordMask();
uint32_t newValueXMsb = v.m_valueX & hiWordMask(); const uint32_t newValueXMsb = v.m_valueX & hiWordMask();
if (warnOnTruncation && (newValueMsb != v.m_value || newValueXMsb != v.m_valueX)) { if (warnOnTruncation && (newValueMsb != v.m_value || newValueXMsb != v.m_valueX)) {
// Displaying in decimal avoids hiWordMask truncation // Displaying in decimal avoids hiWordMask truncation
v3warn(WIDTH, "Value too large for " << width() << " bit number: " << displayed("%d")); v3warn(WIDTH, "Value too large for " << width() << " bit number: " << displayed("%d"));
@ -2258,7 +2259,7 @@ V3Number& V3Number::opIToRD(const V3Number& lhs, bool isSigned) {
double d = 0; double d = 0;
const bool negate = isSigned && noxz.isNegative(); const bool negate = isSigned && noxz.isNegative();
if (negate) { if (negate) {
V3Number noxz_signed = noxz; const V3Number noxz_signed = noxz;
noxz.opNegate(noxz_signed); noxz.opNegate(noxz_signed);
} }
for (int bit = noxz.width() - 1; bit >= 0; bit--) { for (int bit = noxz.width() - 1; bit >= 0; bit--) {
@ -2271,14 +2272,14 @@ V3Number& V3Number::opIToRD(const V3Number& lhs, bool isSigned) {
V3Number& V3Number::opRToIS(const V3Number& lhs) { V3Number& V3Number::opRToIS(const V3Number& lhs) {
NUM_ASSERT_OP_ARGS1(lhs); NUM_ASSERT_OP_ARGS1(lhs);
NUM_ASSERT_DOUBLE_ARGS1(lhs); NUM_ASSERT_DOUBLE_ARGS1(lhs);
double v = VL_TRUNC(lhs.toDouble()); const double v = VL_TRUNC(lhs.toDouble());
vlsint32_t i = static_cast<vlsint32_t>(v); // C converts from double to vlsint32 const vlsint32_t i = static_cast<vlsint32_t>(v); // C converts from double to vlsint32
return setLongS(i); return setLongS(i);
} }
V3Number& V3Number::opRToIRoundS(const V3Number& lhs) { V3Number& V3Number::opRToIRoundS(const V3Number& lhs) {
NUM_ASSERT_OP_ARGS1(lhs); NUM_ASSERT_OP_ARGS1(lhs);
NUM_ASSERT_DOUBLE_ARGS1(lhs); NUM_ASSERT_DOUBLE_ARGS1(lhs);
double v = VL_ROUND(lhs.toDouble()); const double v = VL_ROUND(lhs.toDouble());
setZero(); setZero();
union { union {
double d; double d;
@ -2289,7 +2290,7 @@ V3Number& V3Number::opRToIRoundS(const V3Number& lhs) {
const int exp = static_cast<int>((u.q >> 52ULL) & VL_MASK_Q(11)) - 1023; const int exp = static_cast<int>((u.q >> 52ULL) & VL_MASK_Q(11)) - 1023;
const int lsb = exp - 52; const int lsb = exp - 52;
vluint64_t mantissa = (u.q & VL_MASK_Q(52)) | (1ULL << 52); const vluint64_t mantissa = (u.q & VL_MASK_Q(52)) | (1ULL << 52);
if (v != 0) { if (v != 0) {
// IEEE format: [63]=sign [62:52]=exp+1023 [51:0]=mantissa // IEEE format: [63]=sign [62:52]=exp+1023 [51:0]=mantissa
// This does not need to support subnormals as they are sub-integral // This does not need to support subnormals as they are sub-integral
@ -2300,7 +2301,7 @@ V3Number& V3Number::opRToIRoundS(const V3Number& lhs) {
} }
} }
if (v < 0) { if (v < 0) {
V3Number noSign = *this; const V3Number noSign = *this;
opNegate(noSign); opNegate(noSign);
} }
} }

View File

@ -116,7 +116,7 @@ public:
V3Number& setDouble(double value); V3Number& setDouble(double value);
void setBit(int bit, char value) { // Note must be pre-zeroed! void setBit(int bit, char value) { // Note must be pre-zeroed!
if (bit >= m_width) return; if (bit >= m_width) return;
uint32_t mask = (1UL << (bit & 31)); const uint32_t mask = (1UL << (bit & 31));
ValueAndX& v = m_value[bit / 32]; ValueAndX& v = m_value[bit / 32];
if (value == '0' || value == 0) { if (value == '0' || value == 0) {
v.m_value &= ~mask; v.m_value &= ~mask;

View File

@ -153,7 +153,7 @@ int V3OptionParser::parse(int idx, int argc, char* argv[]) {
UASSERT(m_pimpl->m_isFinalized, "finalize() must be called before parse()"); UASSERT(m_pimpl->m_isFinalized, "finalize() must be called before parse()");
const char* optp = argv[idx]; const char* optp = argv[idx];
if (optp[0] == '-' && optp[1] == '-') ++optp; if (optp[0] == '-' && optp[1] == '-') ++optp;
ActionIfs* actp = find(optp); ActionIfs* const actp = find(optp);
if (!actp) return 0; if (!actp) return 0;
if (!actp->isValueNeeded()) { if (!actp->isValueNeeded()) {
actp->exec(optp, nullptr); actp->exec(optp, nullptr);
@ -224,7 +224,7 @@ V3OptionParser::ActionIfs&
V3OptionParser::AppendHelper::operator()(const char* optp, CbPartialMatchVal, V3OptionParser::AppendHelper::operator()(const char* optp, CbPartialMatchVal,
Impl::ActionCbPartialMatchVal::CbType cb) const { Impl::ActionCbPartialMatchVal::CbType cb) const {
const size_t prefixLen = std::strlen(optp); const size_t prefixLen = std::strlen(optp);
auto wrap const auto wrap
= [prefixLen, cb](const char* optp, const char* argp) { cb(optp + prefixLen, argp); }; = [prefixLen, cb](const char* optp, const char* argp) { cb(optp + prefixLen, argp); };
return m_parser.add<Impl::ActionCbPartialMatchVal>(optp, std::move(wrap)); return m_parser.add<Impl::ActionCbPartialMatchVal>(optp, std::move(wrap));
} }

View File

@ -61,7 +61,7 @@ public:
private: private:
// MEMBERS // MEMBERS
std::unique_ptr<Impl> m_pimpl; const std::unique_ptr<Impl> m_pimpl;
// METHODS // METHODS
ActionIfs* find(const char* optp); ActionIfs* find(const char* optp);

View File

@ -111,7 +111,7 @@ public:
V3LangCode::V3LangCode(const char* textp) { V3LangCode::V3LangCode(const char* textp) {
// Return code for given string, or ERROR, which is a bad code // Return code for given string, or ERROR, which is a bad code
for (int codei = V3LangCode::L_ERROR; codei < V3LangCode::_ENUM_END; ++codei) { for (int codei = V3LangCode::L_ERROR; codei < V3LangCode::_ENUM_END; ++codei) {
V3LangCode code = V3LangCode(codei); const V3LangCode code = V3LangCode(codei);
if (0 == VL_STRCASECMP(textp, code.ascii())) { if (0 == VL_STRCASECMP(textp, code.ascii())) {
m_e = code; m_e = code;
return; return;
@ -128,7 +128,7 @@ VTimescale::VTimescale(const string& value, bool& badr)
badr = true; badr = true;
const string spaceless = VString::removeWhitespace(value); const string spaceless = VString::removeWhitespace(value);
for (int i = TS_100S; i < _ENUM_END; ++i) { for (int i = TS_100S; i < _ENUM_END; ++i) {
VTimescale ts(i); const VTimescale ts(i);
if (spaceless == ts.ascii()) { if (spaceless == ts.ascii()) {
badr = false; badr = false;
m_e = ts.m_e; m_e = ts.m_e;
@ -236,7 +236,7 @@ void VTimescale::parseSlashed(FileLine* fl, const char* textp, VTimescale& unitr
for (; isspace(*cp); ++cp) {} for (; isspace(*cp); ++cp) {}
const char* const unitp = cp; const char* const unitp = cp;
for (; *cp && *cp != '/'; ++cp) {} for (; *cp && *cp != '/'; ++cp) {}
string unitStr(unitp, cp - unitp); const string unitStr(unitp, cp - unitp);
for (; isspace(*cp); ++cp) {} for (; isspace(*cp); ++cp) {}
string precStr; string precStr;
if (*cp == '/') { if (*cp == '/') {
@ -253,7 +253,7 @@ void VTimescale::parseSlashed(FileLine* fl, const char* textp, VTimescale& unitr
} }
bool unitbad; bool unitbad;
VTimescale unit(unitStr, unitbad /*ref*/); const VTimescale unit(unitStr, unitbad /*ref*/);
if (unitbad && !(unitStr.empty() && allowEmpty)) { if (unitbad && !(unitStr.empty() && allowEmpty)) {
fl->v3error("`timescale timeunit syntax error: '" << unitStr << "'"); fl->v3error("`timescale timeunit syntax error: '" << unitStr << "'");
return; return;
@ -471,7 +471,7 @@ string V3Options::fileExists(const string& filename) {
} }
} }
// Find it // Find it
std::set<string>* filesetp = &(diriter->second); const std::set<string>* filesetp = &(diriter->second);
const auto fileiter = filesetp->find(basename); const auto fileiter = filesetp->find(basename);
if (fileiter == filesetp->end()) { if (fileiter == filesetp->end()) {
return ""; // Not found return ""; // Not found
@ -894,7 +894,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
} }
V3OptionParser parser; V3OptionParser parser;
V3OptionParser::AppendHelper DECL_OPTION{parser}; const V3OptionParser::AppendHelper DECL_OPTION{parser};
V3OPTION_PARSER_DECL_TAGS; V3OPTION_PARSER_DECL_TAGS;
const auto callStrSetter = [this](void (V3Options::*cbStr)(const string&)) { const auto callStrSetter = [this](void (V3Options::*cbStr)(const string&)) {
@ -1086,7 +1086,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
DECL_OPTION("-hierarchical", OnOff, &m_hierarchical); DECL_OPTION("-hierarchical", OnOff, &m_hierarchical);
DECL_OPTION("-hierarchical-block", CbVal, [this](const char* valp) { DECL_OPTION("-hierarchical-block", CbVal, [this](const char* valp) {
V3HierarchicalBlockOption opt(valp); const V3HierarchicalBlockOption opt(valp);
m_hierBlocks.emplace(opt.mangledName(), opt); m_hierBlocks.emplace(opt.mangledName(), opt);
}); });
DECL_OPTION("-hierarchical-child", OnOff, &m_hierChild); DECL_OPTION("-hierarchical-child", OnOff, &m_hierChild);
@ -1103,7 +1103,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
DECL_OPTION("-LDFLAGS", CbVal, callStrSetter(&V3Options::addLdLibs)); DECL_OPTION("-LDFLAGS", CbVal, callStrSetter(&V3Options::addLdLibs));
const auto setLang = [this, fl](const char* valp) { const auto setLang = [this, fl](const char* valp) {
V3LangCode optval = V3LangCode(valp); const V3LangCode optval = V3LangCode(valp);
if (optval.legal()) { if (optval.legal()) {
m_defaultLanguage = optval; m_defaultLanguage = optval;
} else { } else {
@ -1367,7 +1367,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
FileLine::globalWarnStyleOff(false); FileLine::globalWarnStyleOff(false);
}); });
DECL_OPTION("-Werror-", CbPartialMatch, [this, fl](const char* optp) { DECL_OPTION("-Werror-", CbPartialMatch, [this, fl](const char* optp) {
V3ErrorCode code(optp); const V3ErrorCode code(optp);
if (code == V3ErrorCode::EC_ERROR) { if (code == V3ErrorCode::EC_ERROR) {
if (!isFuture(optp)) fl->v3fatal("Unknown warning specified: -Werror-" << optp); if (!isFuture(optp)) fl->v3fatal("Unknown warning specified: -Werror-" << optp);
} else { } else {

View File

@ -179,11 +179,11 @@ static bool isClockerAssignment(AstNodeAssign* nodep) {
void OrderGraph::loopsVertexCb(V3GraphVertex* vertexp) { void OrderGraph::loopsVertexCb(V3GraphVertex* vertexp) {
if (debug()) cout << "-Info-Loop: " << vertexp << "\n"; if (debug()) cout << "-Info-Loop: " << vertexp << "\n";
if (OrderLogicVertex* vvertexp = dynamic_cast<OrderLogicVertex*>(vertexp)) { if (OrderLogicVertex* const vvertexp = dynamic_cast<OrderLogicVertex*>(vertexp)) {
std::cerr << vvertexp->nodep()->fileline()->warnOther() std::cerr << vvertexp->nodep()->fileline()->warnOther()
<< " Example path: " << vvertexp->nodep()->typeName() << endl; << " Example path: " << vvertexp->nodep()->typeName() << endl;
} }
if (OrderVarVertex* vvertexp = dynamic_cast<OrderVarVertex*>(vertexp)) { if (OrderVarVertex* const vvertexp = dynamic_cast<OrderVarVertex*>(vertexp)) {
std::cerr << vvertexp->varScp()->fileline()->warnOther() std::cerr << vvertexp->varScp()->fileline()->warnOther()
<< " Example path: " << vvertexp->varScp()->prettyName() << endl; << " Example path: " << vvertexp->varScp()->prettyName() << endl;
} }
@ -229,7 +229,7 @@ class OrderClkMarkVisitor final : public AstNVisitor {
return; // skip the marking return; // skip the marking
} }
const AstVarRef* lhsp = VN_CAST(nodep->lhsp(), VarRef); const AstVarRef* const lhsp = VN_CAST(nodep->lhsp(), VarRef);
if (lhsp && (lhsp->varp()->attrClocker() == VVarAttrClocker::CLOCKER_UNKNOWN)) { if (lhsp && (lhsp->varp()->attrClocker() == VVarAttrClocker::CLOCKER_UNKNOWN)) {
lhsp->varp()->attrClocker(VVarAttrClocker::CLOCKER_YES); // mark as clocker lhsp->varp()->attrClocker(VVarAttrClocker::CLOCKER_YES); // mark as clocker
m_newClkMarked = true; // enable a further run since new clocker is marked m_newClkMarked = true; // enable a further run since new clocker is marked
@ -724,7 +724,7 @@ class OrderBuildVisitor final : public AstNVisitor {
for (AstVarScope* vscp = nodep->topScopep()->scopep()->varsp(); vscp; for (AstVarScope* vscp = nodep->topScopep()->scopep()->varsp(); vscp;
vscp = VN_AS(vscp->nextp(), VarScope)) { vscp = VN_AS(vscp->nextp(), VarScope)) {
if (vscp->varp()->isNonOutput()) { if (vscp->varp()->isNonOutput()) {
OrderVarVertex* varVxp = getVarVertex(vscp, VarVertexType::STD); OrderVarVertex* const varVxp = getVarVertex(vscp, VarVertexType::STD);
new OrderEdge(m_graphp, m_inputsVxp, varVxp, WEIGHT_INPUT); new OrderEdge(m_graphp, m_inputsVxp, varVxp, WEIGHT_INPUT);
} }
} }
@ -753,8 +753,8 @@ public:
V3List<OrderMoveVertex*> m_readyVertices; // Ready vertices with same domain & scope V3List<OrderMoveVertex*> m_readyVertices; // Ready vertices with same domain & scope
private: private:
bool m_onReadyList = false; // True if DomScope is already on list of ready dom/scopes bool m_onReadyList = false; // True if DomScope is already on list of ready dom/scopes
const AstSenTree* m_domainp; // Domain all vertices belong to const AstSenTree* const m_domainp; // Domain all vertices belong to
const AstScope* m_scopep; // Scope all vertices belong to const AstScope* const m_scopep; // Scope all vertices belong to
using DomScopeKey = std::pair<const AstSenTree*, const AstScope*>; using DomScopeKey = std::pair<const AstSenTree*, const AstScope*>;
using DomScopeMap = std::map<DomScopeKey, OrderMoveDomScope*>; using DomScopeMap = std::map<DomScopeKey, OrderMoveDomScope*>;
@ -840,7 +840,7 @@ private:
// MEMBERS // MEMBERS
const V3Graph* m_graphp; // Input graph of OrderLogicVertex's etc const V3Graph* m_graphp; // Input graph of OrderLogicVertex's etc
V3Graph* m_outGraphp; // Output graph of T_MoveVertex's V3Graph* m_outGraphp; // Output graph of T_MoveVertex's
MoveVertexMaker* m_vxMakerp; // Factory class for T_MoveVertex's MoveVertexMaker* const m_vxMakerp; // Factory class for T_MoveVertex's
Logic2Move m_logic2move; // Map Logic to Vertex Logic2Move m_logic2move; // Map Logic to Vertex
// Maps an (original graph vertex, domain) pair to a T_MoveVertex // Maps an (original graph vertex, domain) pair to a T_MoveVertex
// Not std::unordered_map, because std::pair doesn't provide std::hash // Not std::unordered_map, because std::pair doesn't provide std::hash
@ -872,8 +872,8 @@ public:
// For each logic node, make a T_MoveVertex // For each logic node, make a T_MoveVertex
for (V3GraphVertex* itp = m_graphp->verticesBeginp(); itp; itp = itp->verticesNextp()) { for (V3GraphVertex* itp = m_graphp->verticesBeginp(); itp; itp = itp->verticesNextp()) {
if (OrderLogicVertex* lvertexp = dynamic_cast<OrderLogicVertex*>(itp)) { if (OrderLogicVertex* const lvertexp = dynamic_cast<OrderLogicVertex*>(itp)) {
T_MoveVertex* moveVxp = m_vxMakerp->makeVertexp( T_MoveVertex* const moveVxp = m_vxMakerp->makeVertexp(
lvertexp, nullptr, lvertexp->scopep(), lvertexp->domainp()); lvertexp, nullptr, lvertexp->scopep(), lvertexp->domainp());
if (moveVxp) { if (moveVxp) {
// Cross link so we can find it later // Cross link so we can find it later
@ -883,8 +883,8 @@ public:
} }
// Build edges between logic vertices // Build edges between logic vertices
for (V3GraphVertex* itp = m_graphp->verticesBeginp(); itp; itp = itp->verticesNextp()) { for (V3GraphVertex* itp = m_graphp->verticesBeginp(); itp; itp = itp->verticesNextp()) {
if (OrderLogicVertex* lvertexp = dynamic_cast<OrderLogicVertex*>(itp)) { if (OrderLogicVertex* const lvertexp = dynamic_cast<OrderLogicVertex*>(itp)) {
T_MoveVertex* moveVxp = m_logic2move[lvertexp]; T_MoveVertex* const moveVxp = m_logic2move[lvertexp];
if (moveVxp) iterate(moveVxp, lvertexp, lvertexp->domainp()); if (moveVxp) iterate(moveVxp, lvertexp, lvertexp->domainp());
} }
} }
@ -901,7 +901,7 @@ private:
continue; continue;
} }
const int weight = edgep->weight(); const int weight = edgep->weight();
if (const OrderLogicVertex* toLVertexp if (const OrderLogicVertex* const toLVertexp
= dynamic_cast<const OrderLogicVertex*>(edgep->top())) { = dynamic_cast<const OrderLogicVertex*>(edgep->top())) {
// Do not construct dependencies across exclusive domains. // Do not construct dependencies across exclusive domains.
@ -916,11 +916,11 @@ private:
// This is an OrderVarVertex or other vertex representing // This is an OrderVarVertex or other vertex representing
// data. (Could be var, settle, or input type vertex.) // data. (Could be var, settle, or input type vertex.)
const V3GraphVertex* nonLogicVxp = edgep->top(); const V3GraphVertex* nonLogicVxp = edgep->top();
VxDomPair key(nonLogicVxp, domainp); const VxDomPair key(nonLogicVxp, domainp);
if (!m_var2move[key]) { if (!m_var2move[key]) {
const OrderEitherVertex* eithp const OrderEitherVertex* const eithp
= dynamic_cast<const OrderEitherVertex*>(nonLogicVxp); = dynamic_cast<const OrderEitherVertex*>(nonLogicVxp);
T_MoveVertex* newMoveVxp T_MoveVertex* const newMoveVxp
= m_vxMakerp->makeVertexp(nullptr, eithp, eithp->scopep(), domainp); = m_vxMakerp->makeVertexp(nullptr, eithp, eithp->scopep(), domainp);
m_var2move[key] = newMoveVxp; m_var2move[key] = newMoveVxp;
@ -962,7 +962,7 @@ public:
virtual OrderMoveVertex* makeVertexp(OrderLogicVertex* lvertexp, const OrderEitherVertex*, virtual OrderMoveVertex* makeVertexp(OrderLogicVertex* lvertexp, const OrderEitherVertex*,
const AstScope* scopep, const AstScope* scopep,
const AstSenTree* domainp) override { const AstSenTree* domainp) override {
OrderMoveVertex* resultp = new OrderMoveVertex(m_pomGraphp, lvertexp); OrderMoveVertex* const resultp = new OrderMoveVertex(m_pomGraphp, lvertexp);
resultp->domScopep(OrderMoveDomScope::findCreate(domainp, scopep)); resultp->domScopep(OrderMoveDomScope::findCreate(domainp, scopep));
resultp->m_pomWaitingE.pushBack(*m_pomWaitingp, resultp); resultp->m_pomWaitingE.pushBack(*m_pomWaitingp, resultp);
return resultp; return resultp;
@ -1005,8 +1005,8 @@ class OrderVerticesByDomainThenScope final {
public: public:
virtual bool operator()(const V3GraphVertex* lhsp, const V3GraphVertex* rhsp) const { virtual bool operator()(const V3GraphVertex* lhsp, const V3GraphVertex* rhsp) const {
const MTaskMoveVertex* l_vxp = dynamic_cast<const MTaskMoveVertex*>(lhsp); const MTaskMoveVertex* const l_vxp = dynamic_cast<const MTaskMoveVertex*>(lhsp);
const MTaskMoveVertex* r_vxp = dynamic_cast<const MTaskMoveVertex*>(rhsp); const MTaskMoveVertex* const r_vxp = dynamic_cast<const MTaskMoveVertex*>(rhsp);
vluint64_t l_id = m_ids.findId(l_vxp->domainp()); vluint64_t l_id = m_ids.findId(l_vxp->domainp());
vluint64_t r_id = m_ids.findId(r_vxp->domainp()); vluint64_t r_id = m_ids.findId(r_vxp->domainp());
if (l_id < r_id) return true; if (l_id < r_id) return true;
@ -1025,8 +1025,8 @@ public:
// Sort vertex's, which must be AbstractMTask's, into a deterministic // Sort vertex's, which must be AbstractMTask's, into a deterministic
// order by comparing their serial IDs. // order by comparing their serial IDs.
virtual bool operator()(const V3GraphVertex* lhsp, const V3GraphVertex* rhsp) const { virtual bool operator()(const V3GraphVertex* lhsp, const V3GraphVertex* rhsp) const {
const AbstractMTask* lmtaskp = dynamic_cast<const AbstractLogicMTask*>(lhsp); const AbstractMTask* const lmtaskp = dynamic_cast<const AbstractLogicMTask*>(lhsp);
const AbstractMTask* rmtaskp = dynamic_cast<const AbstractLogicMTask*>(rhsp); const AbstractMTask* const rmtaskp = dynamic_cast<const AbstractLogicMTask*>(rhsp);
return lmtaskp->id() < rmtaskp->id(); return lmtaskp->id() < rmtaskp->id();
} }
}; };
@ -1119,8 +1119,8 @@ class OrderProcess final : AstNDeleter {
AstVarScope* const nodep = vertexp->varScp(); AstVarScope* const nodep = vertexp->varScp();
UASSERT(nodep != v3Global.rootp()->dpiExportTriggerp(), UASSERT(nodep != v3Global.rootp()->dpiExportTriggerp(),
"DPI export trigger should not be marked circular"); "DPI export trigger should not be marked circular");
OrderLogicVertex* fromLVtxp = nullptr; const OrderLogicVertex* fromLVtxp = nullptr;
OrderLogicVertex* toLVtxp = nullptr; const OrderLogicVertex* toLVtxp = nullptr;
if (edgep) { if (edgep) {
fromLVtxp = dynamic_cast<OrderLogicVertex*>(edgep->fromp()); fromLVtxp = dynamic_cast<OrderLogicVertex*>(edgep->fromp());
toLVtxp = dynamic_cast<OrderLogicVertex*>(edgep->top()); toLVtxp = dynamic_cast<OrderLogicVertex*>(edgep->top());
@ -1217,8 +1217,8 @@ class OrderProcess final : AstNDeleter {
std::unordered_set<const AstVar*> canSplitList; std::unordered_set<const AstVar*> canSplitList;
int lim = m_unoptflatVars.size() < 10 ? m_unoptflatVars.size() : 10; int lim = m_unoptflatVars.size() < 10 ? m_unoptflatVars.size() : 10;
for (int i = 0; i < lim; i++) { for (int i = 0; i < lim; i++) {
OrderVarStdVertex* vsvertexp = m_unoptflatVars[i]; OrderVarStdVertex* const vsvertexp = m_unoptflatVars[i];
AstVar* varp = vsvertexp->varScp()->varp(); AstVar* const varp = vsvertexp->varScp()->varp();
const bool canSplit = V3SplitVar::canSplitVar(varp); const bool canSplit = V3SplitVar::canSplitVar(varp);
std::cerr << V3Error::warnMore() << " " << varp->fileline() << " " std::cerr << V3Error::warnMore() << " " << varp->fileline() << " "
<< varp->prettyName() << std::dec << ", width " << varp->width() << varp->prettyName() << std::dec << ", width " << varp->width()
@ -1237,8 +1237,8 @@ class OrderProcess final : AstNDeleter {
}); });
lim = m_unoptflatVars.size() < 10 ? m_unoptflatVars.size() : 10; lim = m_unoptflatVars.size() < 10 ? m_unoptflatVars.size() : 10;
for (int i = 0; i < lim; i++) { for (int i = 0; i < lim; i++) {
OrderVarStdVertex* vsvertexp = m_unoptflatVars[i]; OrderVarStdVertex* const vsvertexp = m_unoptflatVars[i];
AstVar* varp = vsvertexp->varScp()->varp(); AstVar* const varp = vsvertexp->varScp()->varp();
const bool canSplit = V3SplitVar::canSplitVar(varp); const bool canSplit = V3SplitVar::canSplitVar(varp);
std::cerr << V3Error::warnMore() << " " << varp->fileline() << " " std::cerr << V3Error::warnMore() << " " << varp->fileline() << " "
<< varp->prettyName() << ", width " << std::dec << varp->width() << varp->prettyName() << ", width " << std::dec << varp->width()
@ -1261,9 +1261,9 @@ class OrderProcess final : AstNDeleter {
void reportLoopVarsIterate(V3GraphVertex* vertexp, uint32_t color) { void reportLoopVarsIterate(V3GraphVertex* vertexp, uint32_t color) {
if (vertexp->user()) return; // Already done if (vertexp->user()) return; // Already done
vertexp->user(1); vertexp->user(1);
if (OrderVarStdVertex* vsvertexp = dynamic_cast<OrderVarStdVertex*>(vertexp)) { if (OrderVarStdVertex* const vsvertexp = dynamic_cast<OrderVarStdVertex*>(vertexp)) {
// Only reporting on standard variable vertices // Only reporting on standard variable vertices
AstVar* varp = vsvertexp->varScp()->varp(); AstVar* const varp = vsvertexp->varScp()->varp();
if (!varp->user3()) { if (!varp->user3()) {
const string name = varp->prettyName(); const string name = varp->prettyName();
if ((varp->width() != 1) && (name.find("__Vdly") == string::npos) if ((varp->width() != 1) && (name.find("__Vdly") == string::npos)
@ -1286,7 +1286,7 @@ class OrderProcess final : AstNDeleter {
// Only for member initialization in constructor // Only for member initialization in constructor
static OrderInputsVertex& findInputVertex(OrderGraph& graph) { static OrderInputsVertex& findInputVertex(OrderGraph& graph) {
for (V3GraphVertex* vtxp = graph.verticesBeginp(); vtxp; vtxp = vtxp->verticesNextp()) { for (V3GraphVertex* vtxp = graph.verticesBeginp(); vtxp; vtxp = vtxp->verticesNextp()) {
if (auto* ivtxp = dynamic_cast<OrderInputsVertex*>(vtxp)) return *ivtxp; if (auto* const ivtxp = dynamic_cast<OrderInputsVertex*>(vtxp)) return *ivtxp;
} }
VL_UNREACHABLE VL_UNREACHABLE
} }
@ -1357,7 +1357,7 @@ void OrderProcess::processInputs() {
todoVec.push_front(&m_inputsVtx); todoVec.push_front(&m_inputsVtx);
m_inputsVtx.isFromInput(true); // By definition m_inputsVtx.isFromInput(true); // By definition
while (!todoVec.empty()) { while (!todoVec.empty()) {
OrderEitherVertex* vertexp = todoVec.back(); OrderEitherVertex* const vertexp = todoVec.back();
todoVec.pop_back(); todoVec.pop_back();
processInputsOutIterate(vertexp, todoVec); processInputsOutIterate(vertexp, todoVec);
} }
@ -1368,7 +1368,7 @@ void OrderProcess::processInputsInIterate(OrderEitherVertex* vertexp, VertexVec&
if (vertexp->user()) return; // Already processed if (vertexp->user()) return; // Already processed
if (false && debug() >= 9) { if (false && debug() >= 9) {
UINFO(9, " InIIter " << vertexp << endl); UINFO(9, " InIIter " << vertexp << endl);
if (OrderLogicVertex* vvertexp = dynamic_cast<OrderLogicVertex*>(vertexp)) { if (OrderLogicVertex* const vvertexp = dynamic_cast<OrderLogicVertex*>(vertexp)) {
vvertexp->nodep()->dumpTree(cout, "- TT: "); vvertexp->nodep()->dumpTree(cout, "- TT: ");
} }
} }
@ -1377,7 +1377,7 @@ void OrderProcess::processInputsInIterate(OrderEitherVertex* vertexp, VertexVec&
// Also, determine if this vertex is an input // Also, determine if this vertex is an input
int inonly = 1; // 0=no, 1=maybe, 2=yes until a no int inonly = 1; // 0=no, 1=maybe, 2=yes until a no
for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) { for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) {
OrderEitherVertex* frVertexp = static_cast<OrderEitherVertex*>(edgep->fromp()); OrderEitherVertex* const frVertexp = static_cast<OrderEitherVertex*>(edgep->fromp());
processInputsInIterate(frVertexp, todoVec); processInputsInIterate(frVertexp, todoVec);
if (frVertexp->isFromInput()) { if (frVertexp->isFromInput()) {
if (inonly == 1) inonly = 2; if (inonly == 1) inonly = 2;
@ -1416,11 +1416,11 @@ void OrderProcess::processInputsOutIterate(OrderEitherVertex* vertexp, VertexVec
{ {
// Propagate PrimaryIn through simple assignments, following target of vertex // Propagate PrimaryIn through simple assignments, following target of vertex
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) { for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) {
OrderEitherVertex* toVertexp = static_cast<OrderEitherVertex*>(edgep->top()); OrderEitherVertex* const toVertexp = static_cast<OrderEitherVertex*>(edgep->top());
if (OrderVarStdVertex* vvertexp = dynamic_cast<OrderVarStdVertex*>(toVertexp)) { if (OrderVarStdVertex* const vvertexp = dynamic_cast<OrderVarStdVertex*>(toVertexp)) {
processInputsInIterate(vvertexp, todoVec); processInputsInIterate(vvertexp, todoVec);
} }
if (OrderLogicVertex* vvertexp = dynamic_cast<OrderLogicVertex*>(toVertexp)) { if (OrderLogicVertex* const vvertexp = dynamic_cast<OrderLogicVertex*>(toVertexp)) {
if (VN_IS(vvertexp->nodep(), NodeAssign)) { if (VN_IS(vvertexp->nodep(), NodeAssign)) {
processInputsInIterate(vvertexp, todoVec); processInputsInIterate(vvertexp, todoVec);
} }
@ -1436,7 +1436,7 @@ void OrderProcess::processCircular() {
// Take broken edges and add circular flags // Take broken edges and add circular flags
// The change detect code will use this to force changedets // The change detect code will use this to force changedets
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) { for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
if (OrderVarStdVertex* vvertexp = dynamic_cast<OrderVarStdVertex*>(itp)) { if (OrderVarStdVertex* const vvertexp = dynamic_cast<OrderVarStdVertex*>(itp)) {
if (vvertexp->isClock() && !vvertexp->isFromInput()) { if (vvertexp->isClock() && !vvertexp->isFromInput()) {
// If a clock is generated internally, we need to do another // If a clock is generated internally, we need to do another
// loop through the entire evaluation. This fixes races; see // loop through the entire evaluation. This fixes races; see
@ -1459,7 +1459,7 @@ void OrderProcess::processCircular() {
// Also mark any cut edges // Also mark any cut edges
for (V3GraphEdge* edgep = vvertexp->outBeginp(); edgep; edgep = edgep->outNextp()) { for (V3GraphEdge* edgep = vvertexp->outBeginp(); edgep; edgep = edgep->outNextp()) {
if (edgep->weight() == 0) { // was cut if (edgep->weight() == 0) { // was cut
OrderEdge* oedgep = dynamic_cast<OrderEdge*>(edgep); OrderEdge* const oedgep = dynamic_cast<OrderEdge*>(edgep);
UASSERT_OBJ(oedgep, vvertexp->varScp(), "Cutable edge not of proper type"); UASSERT_OBJ(oedgep, vvertexp->varScp(), "Cutable edge not of proper type");
UINFO(6, " CutCircularO: " << vvertexp->name() << endl); UINFO(6, " CutCircularO: " << vvertexp->name() << endl);
nodeMarkCircular(vvertexp, oedgep); nodeMarkCircular(vvertexp, oedgep);
@ -1467,7 +1467,7 @@ void OrderProcess::processCircular() {
} }
for (V3GraphEdge* edgep = vvertexp->inBeginp(); edgep; edgep = edgep->inNextp()) { for (V3GraphEdge* edgep = vvertexp->inBeginp(); edgep; edgep = edgep->inNextp()) {
if (edgep->weight() == 0) { // was cut if (edgep->weight() == 0) { // was cut
OrderEdge* oedgep = dynamic_cast<OrderEdge*>(edgep); OrderEdge* const oedgep = dynamic_cast<OrderEdge*>(edgep);
UASSERT_OBJ(oedgep, vvertexp->varScp(), "Cutable edge not of proper type"); UASSERT_OBJ(oedgep, vvertexp->varScp(), "Cutable edge not of proper type");
UINFO(6, " CutCircularI: " << vvertexp->name() << endl); UINFO(6, " CutCircularI: " << vvertexp->name() << endl);
nodeMarkCircular(vvertexp, oedgep); nodeMarkCircular(vvertexp, oedgep);
@ -1481,12 +1481,12 @@ void OrderProcess::processSensitive() {
// Sc sensitives are required on all inputs that go to a combo // Sc sensitives are required on all inputs that go to a combo
// block. (Not inputs that go only to clocked blocks.) // block. (Not inputs that go only to clocked blocks.)
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) { for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
if (OrderVarStdVertex* vvertexp = dynamic_cast<OrderVarStdVertex*>(itp)) { if (OrderVarStdVertex* const vvertexp = dynamic_cast<OrderVarStdVertex*>(itp)) {
if (vvertexp->varScp()->varp()->isNonOutput()) { if (vvertexp->varScp()->varp()->isNonOutput()) {
// UINFO(0, " scsen " << vvertexp << endl); // UINFO(0, " scsen " << vvertexp << endl);
for (V3GraphEdge* edgep = vvertexp->outBeginp(); edgep; for (V3GraphEdge* edgep = vvertexp->outBeginp(); edgep;
edgep = edgep->outNextp()) { edgep = edgep->outNextp()) {
if (OrderEitherVertex* toVertexp if (OrderEitherVertex* const toVertexp
= dynamic_cast<OrderEitherVertex*>(edgep->top())) { = dynamic_cast<OrderEitherVertex*>(edgep->top())) {
if (edgep->weight() && toVertexp->domainp()) { if (edgep->weight() && toVertexp->domainp()) {
// UINFO(0, " " << toVertexp->domainp() << endl); // UINFO(0, " " << toVertexp->domainp() << endl);
@ -1503,7 +1503,7 @@ void OrderProcess::processSensitive() {
void OrderProcess::processDomains() { void OrderProcess::processDomains() {
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) { for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
OrderEitherVertex* vertexp = dynamic_cast<OrderEitherVertex*>(itp); OrderEitherVertex* const vertexp = dynamic_cast<OrderEitherVertex*>(itp);
UASSERT(vertexp, "Null or vertex not derived from EitherVertex"); UASSERT(vertexp, "Null or vertex not derived from EitherVertex");
processDomainsIterate(vertexp); processDomainsIterate(vertexp);
} }
@ -1518,13 +1518,13 @@ void OrderProcess::processDomainsIterate(OrderEitherVertex* vertexp) {
// else, it's full combo code // else, it's full combo code
if (vertexp->domainp()) return; // Already processed, or sequential logic if (vertexp->domainp()) return; // Already processed, or sequential logic
UINFO(5, " pdi: " << vertexp << endl); UINFO(5, " pdi: " << vertexp << endl);
OrderVarVertex* vvertexp = dynamic_cast<OrderVarVertex*>(vertexp); OrderVarVertex* const vvertexp = dynamic_cast<OrderVarVertex*>(vertexp);
AstSenTree* domainp = nullptr; AstSenTree* domainp = nullptr;
if (vvertexp && vvertexp->varScp()->varp()->isNonOutput()) domainp = m_comboDomainp; if (vvertexp && vvertexp->varScp()->varp()->isNonOutput()) domainp = m_comboDomainp;
if (vvertexp && vvertexp->varScp()->isCircular()) domainp = m_comboDomainp; if (vvertexp && vvertexp->varScp()->isCircular()) domainp = m_comboDomainp;
if (!domainp) { if (!domainp) {
for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) { for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) {
OrderEitherVertex* fromVertexp = static_cast<OrderEitherVertex*>(edgep->fromp()); OrderEitherVertex* const fromVertexp = static_cast<OrderEitherVertex*>(edgep->fromp());
if (edgep->weight() && fromVertexp->domainMatters()) { if (edgep->weight() && fromVertexp->domainMatters()) {
UINFO(9, " from d=" << cvtToHex(fromVertexp->domainp()) << " " << fromVertexp UINFO(9, " from d=" << cvtToHex(fromVertexp->domainp()) << " " << fromVertexp
<< endl); << endl);
@ -1553,7 +1553,7 @@ void OrderProcess::processDomainsIterate(OrderEitherVertex* vertexp) {
UINFO(0, " d2 =" << fromVertexp->domainp() << endl); UINFO(0, " d2 =" << fromVertexp->domainp() << endl);
fromVertexp->domainp()->dumpTree(cout); fromVertexp->domainp()->dumpTree(cout);
} // LCOV_EXCL_STOP } // LCOV_EXCL_STOP
AstSenTree* newtreep = domainp->cloneTree(false); AstSenTree* const newtreep = domainp->cloneTree(false);
AstSenItem* newtree2p = fromVertexp->domainp()->sensesp()->cloneTree(true); AstSenItem* newtree2p = fromVertexp->domainp()->sensesp()->cloneTree(true);
UASSERT_OBJ(newtree2p, fromVertexp->domainp(), UASSERT_OBJ(newtree2p, fromVertexp->domainp(),
"No senitem found under clocked domain"); "No senitem found under clocked domain");
@ -1602,7 +1602,7 @@ void OrderProcess::processEdgeReport() {
std::deque<string> report; std::deque<string> report;
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) { for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
if (OrderVarVertex* vvertexp = dynamic_cast<OrderVarVertex*>(itp)) { if (OrderVarVertex* const vvertexp = dynamic_cast<OrderVarVertex*>(itp)) {
string name(vvertexp->varScp()->prettyName()); string name(vvertexp->varScp()->prettyName());
if (dynamic_cast<OrderVarPreVertex*>(itp)) { if (dynamic_cast<OrderVarPreVertex*>(itp)) {
name += " {PRE}"; name += " {PRE}";
@ -1614,7 +1614,7 @@ void OrderProcess::processEdgeReport() {
std::ostringstream os; std::ostringstream os;
os.setf(std::ios::left); os.setf(std::ios::left);
os << " " << cvtToHex(vvertexp->varScp()) << " " << std::setw(50) << name << " "; os << " " << cvtToHex(vvertexp->varScp()) << " " << std::setw(50) << name << " ";
AstSenTree* sentreep = vvertexp->domainp(); AstSenTree* const sentreep = vvertexp->domainp();
if (sentreep) V3EmitV::verilogForTree(sentreep, os); if (sentreep) V3EmitV::verilogForTree(sentreep, os);
report.push_back(os.str()); report.push_back(os.str());
} }
@ -1668,7 +1668,8 @@ void OrderProcess::processMove() {
while (!m_pomReadyDomScope.empty()) { while (!m_pomReadyDomScope.empty()) {
// Start with top node on ready list's domain & scope // Start with top node on ready list's domain & scope
OrderMoveDomScope* domScopep = m_pomReadyDomScope.begin(); OrderMoveDomScope* domScopep = m_pomReadyDomScope.begin();
OrderMoveVertex* topVertexp = domScopep->readyVertices().begin(); // lintok-begin-on-ref OrderMoveVertex* const topVertexp
= domScopep->readyVertices().begin(); // lintok-begin-on-ref
UASSERT(topVertexp, "domScope on ready list without any nodes ready under it"); UASSERT(topVertexp, "domScope on ready list without any nodes ready under it");
// Work on all scopes ready inside this domain // Work on all scopes ready inside this domain
while (domScopep) { while (domScopep) {
@ -1702,7 +1703,7 @@ void OrderProcess::processMovePrepReady() {
// Make list of ready nodes // Make list of ready nodes
UINFO(5, " MovePrepReady\n"); UINFO(5, " MovePrepReady\n");
for (OrderMoveVertex* vertexp = m_pomWaiting.begin(); vertexp;) { for (OrderMoveVertex* vertexp = m_pomWaiting.begin(); vertexp;) {
OrderMoveVertex* nextp = vertexp->pomWaitingNextp(); OrderMoveVertex* const nextp = vertexp->pomWaitingNextp();
if (vertexp->isWait() && vertexp->inEmpty()) processMoveReadyOne(vertexp); if (vertexp->isWait() && vertexp->inEmpty()) processMoveReadyOne(vertexp);
vertexp = nextp; vertexp = nextp;
} }
@ -1737,7 +1738,7 @@ void OrderProcess::processMoveDoneOne(OrderMoveVertex* vertexp) {
// Mark our outputs as one closer to ready // Mark our outputs as one closer to ready
for (V3GraphEdge *edgep = vertexp->outBeginp(), *nextp; edgep; edgep = nextp) { for (V3GraphEdge *edgep = vertexp->outBeginp(), *nextp; edgep; edgep = nextp) {
nextp = edgep->outNextp(); nextp = edgep->outNextp();
OrderMoveVertex* toVertexp = static_cast<OrderMoveVertex*>(edgep->top()); OrderMoveVertex* const toVertexp = static_cast<OrderMoveVertex*>(edgep->top());
UINFO(9, " Clear to " << (toVertexp->inEmpty() ? "[EMP] " : " ") << toVertexp UINFO(9, " Clear to " << (toVertexp->inEmpty() ? "[EMP] " : " ") << toVertexp
<< endl); << endl);
// Delete this edge // Delete this edge
@ -1754,11 +1755,11 @@ void OrderProcess::processMoveDoneOne(OrderMoveVertex* vertexp) {
void OrderProcess::processMoveOne(OrderMoveVertex* vertexp, OrderMoveDomScope* domScopep, void OrderProcess::processMoveOne(OrderMoveVertex* vertexp, OrderMoveDomScope* domScopep,
int level) { int level) {
UASSERT_OBJ(vertexp->domScopep() == domScopep, vertexp, "Domain mismatch; list misbuilt?"); UASSERT_OBJ(vertexp->domScopep() == domScopep, vertexp, "Domain mismatch; list misbuilt?");
const OrderLogicVertex* lvertexp = vertexp->logicp(); const OrderLogicVertex* const lvertexp = vertexp->logicp();
const AstScope* scopep = lvertexp->scopep(); const AstScope* const scopep = lvertexp->scopep();
UINFO(5, " POSmove l" << std::setw(3) << level << " d=" << cvtToHex(lvertexp->domainp()) UINFO(5, " POSmove l" << std::setw(3) << level << " d=" << cvtToHex(lvertexp->domainp())
<< " s=" << cvtToHex(scopep) << " " << lvertexp << endl); << " s=" << cvtToHex(scopep) << " " << lvertexp << endl);
AstActive* newActivep AstActive* const newActivep
= processMoveOneLogic(lvertexp, m_pomNewFuncp /*ref*/, m_pomNewStmts /*ref*/); = processMoveOneLogic(lvertexp, m_pomNewFuncp /*ref*/, m_pomNewStmts /*ref*/);
if (newActivep) m_scopetop.addActivep(newActivep); if (newActivep) m_scopetop.addActivep(newActivep);
processMoveDoneOne(vertexp); processMoveDoneOne(vertexp);
@ -1827,7 +1828,7 @@ AstActive* OrderProcess::processMoveOneLogic(const OrderLogicVertex* lvertexp,
newFuncpr->addStmtsp(nodep); newFuncpr->addStmtsp(nodep);
if (v3Global.opt.outputSplitCFuncs()) { if (v3Global.opt.outputSplitCFuncs()) {
// Add in the number of nodes we're adding // Add in the number of nodes we're adding
EmitCBaseCounterVisitor visitor{nodep}; const EmitCBaseCounterVisitor visitor{nodep};
newStmtsr += visitor.count(); newStmtsr += visitor.count();
} }
} }
@ -1844,10 +1845,10 @@ void OrderProcess::processMTasksInitial(InitialLogicE logic_type) {
// //
int initStmts = 0; int initStmts = 0;
AstCFunc* initCFunc = nullptr; AstCFunc* initCFunc = nullptr;
AstScope* lastScopep = nullptr; const AstScope* lastScopep = nullptr;
for (V3GraphVertex* initVxp = m_graph.verticesBeginp(); initVxp; for (V3GraphVertex* initVxp = m_graph.verticesBeginp(); initVxp;
initVxp = initVxp->verticesNextp()) { initVxp = initVxp->verticesNextp()) {
OrderLogicVertex* initp = dynamic_cast<OrderLogicVertex*>(initVxp); OrderLogicVertex* const initp = dynamic_cast<OrderLogicVertex*>(initVxp);
if (!initp) continue; if (!initp) continue;
if ((logic_type == LOGIC_INITIAL) && !initp->domainp()->hasInitial()) continue; if ((logic_type == LOGIC_INITIAL) && !initp->domainp()->hasInitial()) continue;
if ((logic_type == LOGIC_SETTLE) && !initp->domainp()->hasSettle()) continue; if ((logic_type == LOGIC_SETTLE) && !initp->domainp()->hasSettle()) continue;
@ -1856,7 +1857,8 @@ void OrderProcess::processMTasksInitial(InitialLogicE logic_type) {
initCFunc = nullptr; initCFunc = nullptr;
lastScopep = initp->scopep(); lastScopep = initp->scopep();
} }
AstActive* newActivep = processMoveOneLogic(initp, initCFunc /*ref*/, initStmts /*ref*/); AstActive* const newActivep
= processMoveOneLogic(initp, initCFunc /*ref*/, initStmts /*ref*/);
if (newActivep) m_scopetop.addActivep(newActivep); if (newActivep) m_scopetop.addActivep(newActivep);
} }
} }
@ -1899,7 +1901,7 @@ void OrderProcess::processMTasks() {
GraphStream<OrderVerticesByDomainThenScope> emit_logic(&logicGraph); GraphStream<OrderVerticesByDomainThenScope> emit_logic(&logicGraph);
const V3GraphVertex* moveVxp; const V3GraphVertex* moveVxp;
while ((moveVxp = emit_logic.nextp())) { while ((moveVxp = emit_logic.nextp())) {
const MTaskMoveVertex* movep = dynamic_cast<const MTaskMoveVertex*>(moveVxp); const MTaskMoveVertex* const movep = dynamic_cast<const MTaskMoveVertex*>(moveVxp);
const unsigned mtaskId = movep->color(); const unsigned mtaskId = movep->color();
UASSERT(mtaskId > 0, "Every MTaskMoveVertex should have an mtask assignment >0"); UASSERT(mtaskId > 0, "Every MTaskMoveVertex should have an mtask assignment >0");
if (movep->logicp()) { if (movep->logicp()) {
@ -1910,22 +1912,22 @@ void OrderProcess::processMTasks() {
// take this opportunity to annotate each AstVar with the id's // take this opportunity to annotate each AstVar with the id's
// of mtasks that consume it and produce it. We'll use this // of mtasks that consume it and produce it. We'll use this
// information in V3EmitC when we lay out var's in memory. // information in V3EmitC when we lay out var's in memory.
const OrderLogicVertex* logicp = movep->logicp(); const OrderLogicVertex* const logicp = movep->logicp();
for (const V3GraphEdge* edgep = logicp->inBeginp(); edgep; edgep = edgep->inNextp()) { for (const V3GraphEdge* edgep = logicp->inBeginp(); edgep; edgep = edgep->inNextp()) {
const OrderVarVertex* pre_varp const OrderVarVertex* const pre_varp
= dynamic_cast<const OrderVarVertex*>(edgep->fromp()); = dynamic_cast<const OrderVarVertex*>(edgep->fromp());
if (!pre_varp) continue; if (!pre_varp) continue;
AstVar* varp = pre_varp->varScp()->varp(); AstVar* const varp = pre_varp->varScp()->varp();
// varp depends on logicp, so logicp produces varp, // varp depends on logicp, so logicp produces varp,
// and vice-versa below // and vice-versa below
varp->addProducingMTaskId(mtaskId); varp->addProducingMTaskId(mtaskId);
} }
for (const V3GraphEdge* edgep = logicp->outBeginp(); edgep; for (const V3GraphEdge* edgep = logicp->outBeginp(); edgep;
edgep = edgep->outNextp()) { edgep = edgep->outNextp()) {
const OrderVarVertex* post_varp const OrderVarVertex* const post_varp
= dynamic_cast<const OrderVarVertex*>(edgep->top()); = dynamic_cast<const OrderVarVertex*>(edgep->top());
if (!post_varp) continue; if (!post_varp) continue;
AstVar* varp = post_varp->varScp()->varp(); AstVar* const varp = post_varp->varScp()->varp();
varp->addConsumingMTaskId(mtaskId); varp->addConsumingMTaskId(mtaskId);
} }
// TODO? We ignore IO vars here, so those will have empty mtask // TODO? We ignore IO vars here, so those will have empty mtask
@ -1935,8 +1937,8 @@ void OrderProcess::processMTasks() {
// Create the AstExecGraph node which represents the execution // Create the AstExecGraph node which represents the execution
// of the MTask graph. // of the MTask graph.
FileLine* rootFlp = v3Global.rootp()->fileline(); FileLine* const rootFlp = v3Global.rootp()->fileline();
AstExecGraph* execGraphp = new AstExecGraph(rootFlp); AstExecGraph* const execGraphp = new AstExecGraph(rootFlp);
m_scopetop.addActivep(execGraphp); m_scopetop.addActivep(execGraphp);
v3Global.rootp()->execGraphp(execGraphp); v3Global.rootp()->execGraphp(execGraphp);
@ -1944,10 +1946,10 @@ void OrderProcess::processMTasks() {
GraphStream<MTaskVxIdLessThan> emit_mtasks(&mtasks); GraphStream<MTaskVxIdLessThan> emit_mtasks(&mtasks);
const V3GraphVertex* mtaskVxp; const V3GraphVertex* mtaskVxp;
while ((mtaskVxp = emit_mtasks.nextp())) { while ((mtaskVxp = emit_mtasks.nextp())) {
const AbstractLogicMTask* mtaskp = dynamic_cast<const AbstractLogicMTask*>(mtaskVxp); const AbstractLogicMTask* const mtaskp = dynamic_cast<const AbstractLogicMTask*>(mtaskVxp);
// Create a body for this mtask // Create a body for this mtask
AstMTaskBody* bodyp = new AstMTaskBody(rootFlp); AstMTaskBody* const bodyp = new AstMTaskBody(rootFlp);
MTaskState& state = mtaskStates[mtaskp->id()]; MTaskState& state = mtaskStates[mtaskp->id()];
state.m_mtaskBodyp = bodyp; state.m_mtaskBodyp = bodyp;
@ -1964,7 +1966,7 @@ void OrderProcess::processMTasks() {
} }
last_domainp = logicp->domainp(); last_domainp = logicp->domainp();
AstActive* newActivep AstActive* const newActivep
= processMoveOneLogic(logicp, leafCFuncp /*ref*/, leafStmts /*ref*/); = processMoveOneLogic(logicp, leafCFuncp /*ref*/, leafStmts /*ref*/);
if (newActivep) bodyp->addStmtsp(newActivep); if (newActivep) bodyp->addStmtsp(newActivep);
} }
@ -1984,8 +1986,9 @@ void OrderProcess::processMTasks() {
state.m_mtaskBodyp->execMTaskp(state.m_execMTaskp); state.m_mtaskBodyp->execMTaskp(state.m_execMTaskp);
for (V3GraphEdge* inp = mtaskp->inBeginp(); inp; inp = inp->inNextp()) { for (V3GraphEdge* inp = mtaskp->inBeginp(); inp; inp = inp->inNextp()) {
const V3GraphVertex* fromVxp = inp->fromp(); const V3GraphVertex* fromVxp = inp->fromp();
const AbstractLogicMTask* fromp = dynamic_cast<const AbstractLogicMTask*>(fromVxp); const AbstractLogicMTask* const fromp
MTaskState& fromState = mtaskStates[fromp->id()]; = dynamic_cast<const AbstractLogicMTask*>(fromVxp);
const MTaskState& fromState = mtaskStates[fromp->id()];
new V3GraphEdge(execGraphp->mutableDepGraphp(), fromState.m_execMTaskp, new V3GraphEdge(execGraphp->mutableDepGraphp(), fromState.m_execMTaskp,
state.m_execMTaskp, 1); state.m_execMTaskp, 1);
} }

View File

@ -121,7 +121,7 @@ public:
// Vertex types // Vertex types
class OrderEitherVertex VL_NOT_FINAL : public V3GraphVertex { class OrderEitherVertex VL_NOT_FINAL : public V3GraphVertex {
AstScope* m_scopep; // Scope the vertex is in AstScope* const m_scopep; // Scope the vertex is in
AstSenTree* m_domainp; // Clock domain (nullptr = to be computed as we iterate) AstSenTree* m_domainp; // Clock domain (nullptr = to be computed as we iterate)
bool m_isFromInput = false; // From input, or derived therefrom (conservatively false) bool m_isFromInput = false; // From input, or derived therefrom (conservatively false)
protected: protected:
@ -172,7 +172,7 @@ public:
}; };
class OrderLogicVertex final : public OrderEitherVertex { class OrderLogicVertex final : public OrderEitherVertex {
AstNode* m_nodep; AstNode* const m_nodep;
protected: protected:
OrderLogicVertex(V3Graph* graphp, const OrderLogicVertex& old) OrderLogicVertex(V3Graph* graphp, const OrderLogicVertex& old)
@ -200,7 +200,7 @@ public:
}; };
class OrderVarVertex VL_NOT_FINAL : public OrderEitherVertex { class OrderVarVertex VL_NOT_FINAL : public OrderEitherVertex {
AstVarScope* m_varScp; AstVarScope* const m_varScp;
bool m_isClock = false; // Used as clock bool m_isClock = false; // Used as clock
bool m_isDelayed = false; // Set in a delayed assignment bool m_isDelayed = false; // Set in a delayed assignment
protected: protected:
@ -306,7 +306,7 @@ public:
class OrderMoveVertex final : public V3GraphVertex { class OrderMoveVertex final : public V3GraphVertex {
enum OrderMState : uint8_t { POM_WAIT, POM_READY, POM_MOVED }; enum OrderMState : uint8_t { POM_WAIT, POM_READY, POM_MOVED };
OrderLogicVertex* m_logicp; OrderLogicVertex* const m_logicp;
OrderMState m_state; // Movement state OrderMState m_state; // Movement state
OrderMoveDomScope* m_domScopep; // Domain/scope list information OrderMoveDomScope* m_domScopep; // Domain/scope list information
@ -376,10 +376,10 @@ class MTaskMoveVertex final : public V3GraphVertex {
// This could be more compact, since we know m_varp and m_logicp // This could be more compact, since we know m_varp and m_logicp
// cannot both be set. Each MTaskMoveVertex represents a logic node // cannot both be set. Each MTaskMoveVertex represents a logic node
// or a var node, it can't be both. // or a var node, it can't be both.
OrderLogicVertex* m_logicp; // Logic represented by this vertex OrderLogicVertex* const m_logicp; // Logic represented by this vertex
const OrderEitherVertex* m_varp; // Var represented by this vertex const OrderEitherVertex* const m_varp; // Var represented by this vertex
const AstScope* m_scopep; const AstScope* const m_scopep;
const AstSenTree* m_domainp; const AstSenTree* const m_domainp;
protected: protected:
friend class OrderVisitor; friend class OrderVisitor;
@ -449,7 +449,7 @@ public:
// involving pre/pos variables // involving pre/pos variables
virtual bool followComboConnected() const { return true; } virtual bool followComboConnected() const { return true; }
static bool followComboConnected(const V3GraphEdge* edgep) { static bool followComboConnected(const V3GraphEdge* edgep) {
const OrderEdge* oedgep = dynamic_cast<const OrderEdge*>(edgep); const OrderEdge* const oedgep = dynamic_cast<const OrderEdge*>(edgep);
if (!oedgep) v3fatalSrc("Following edge of non-OrderEdge type"); if (!oedgep) v3fatalSrc("Following edge of non-OrderEdge type");
return (oedgep->followComboConnected()); return (oedgep->followComboConnected());
} }

View File

@ -256,7 +256,7 @@ void V3Os::unlinkRegexp(const string& dir, const string& regexp) {
vluint64_t V3Os::rand64(std::array<vluint64_t, 2>& stater) { vluint64_t V3Os::rand64(std::array<vluint64_t, 2>& stater) {
// Xoroshiro128+ algorithm // Xoroshiro128+ algorithm
vluint64_t result = stater[0] + stater[1]; const vluint64_t result = stater[0] + stater[1];
stater[1] ^= stater[0]; stater[1] ^= stater[0];
stater[0] = (((stater[0] << 55) | (stater[0] >> 9)) ^ stater[1] ^ (stater[1] << 14)); stater[0] = (((stater[0] << 55) | (stater[0] >> 9)) ^ stater[1] ^ (stater[1] << 14));
stater[1] = (stater[1] << 36) | (stater[1] >> 28); stater[1] = (stater[1] << 36) | (stater[1] >> 28);

View File

@ -142,7 +142,7 @@ public:
if (!pinp->exprp()) continue; if (!pinp->exprp()) continue;
UASSERT_OBJ(!pinp->modPTypep(), pinp, UASSERT_OBJ(!pinp->modPTypep(), pinp,
"module with type parameter must not be a hierarchical block"); "module with type parameter must not be a hierarchical block");
if (const AstVar* modvarp = pinp->modVarp()) { if (const AstVar* const modvarp = pinp->modVarp()) {
AstConst* const constp = VN_AS(pinp->exprp(), Const); AstConst* const constp = VN_AS(pinp->exprp(), Const);
UASSERT_OBJ(constp, pinp, UASSERT_OBJ(constp, pinp,
"parameter for a hierarchical block must have been constified"); "parameter for a hierarchical block must have been constified");
@ -237,7 +237,7 @@ class ParamProcessor final {
// STATE // STATE
using CloneMap = std::unordered_map<const AstNode*, AstNode*>; using CloneMap = std::unordered_map<const AstNode*, AstNode*>;
struct ModInfo { struct ModInfo {
AstNodeModule* m_modp; // Module with specified name AstNodeModule* const m_modp; // Module with specified name
CloneMap m_cloneMap; // Map of old-varp -> new cloned varp CloneMap m_cloneMap; // Map of old-varp -> new cloned varp
explicit ModInfo(AstNodeModule* modp) explicit ModInfo(AstNodeModule* modp)
: m_modp{modp} {} : m_modp{modp} {}
@ -256,7 +256,7 @@ class ParamProcessor final {
std::map<const V3Hash, ValueMapValue> m_valueMap; // Hash of node hash to (param value, name) std::map<const V3Hash, ValueMapValue> m_valueMap; // Hash of node hash to (param value, name)
int m_nextValue = 1; // Next value to use in m_valueMap int m_nextValue = 1; // Next value to use in m_valueMap
AstNodeModule* m_modp = nullptr; // Current module being processed const AstNodeModule* m_modp = nullptr; // Current module being processed
// Database to get lib-create wrapper that matches parameters in hierarchical Verilation // Database to get lib-create wrapper that matches parameters in hierarchical Verilation
ParameterizedHierBlocks m_hierBlocks; ParameterizedHierBlocks m_hierBlocks;
@ -386,14 +386,14 @@ class ParamProcessor final {
if (AstVar* const varp = VN_CAST(stmtp, Var)) { if (AstVar* const varp = VN_CAST(stmtp, Var)) {
if (varp->isIO() || varp->isGParam() || varp->isIfaceRef()) { if (varp->isIO() || varp->isGParam() || varp->isIfaceRef()) {
// Cloning saved a pointer to the new node for us, so just follow that link. // Cloning saved a pointer to the new node for us, so just follow that link.
AstVar* const oldvarp = varp->clonep(); const AstVar* const oldvarp = varp->clonep();
// UINFO(8,"Clone list 0x"<<hex<<(uint32_t)oldvarp // UINFO(8,"Clone list 0x"<<hex<<(uint32_t)oldvarp
// <<" -> 0x"<<(uint32_t)varp<<endl); // <<" -> 0x"<<(uint32_t)varp<<endl);
clonemapp->emplace(oldvarp, varp); clonemapp->emplace(oldvarp, varp);
} }
} else if (AstParamTypeDType* ptp = VN_CAST(stmtp, ParamTypeDType)) { } else if (AstParamTypeDType* const ptp = VN_CAST(stmtp, ParamTypeDType)) {
if (ptp->isGParam()) { if (ptp->isGParam()) {
AstParamTypeDType* const oldptp = ptp->clonep(); const AstParamTypeDType* const oldptp = ptp->clonep();
clonemapp->emplace(oldptp, ptp); clonemapp->emplace(oldptp, ptp);
} }
} }
@ -428,7 +428,7 @@ class ParamProcessor final {
} }
} }
for (AstPin* pinp = startpinp; pinp; pinp = VN_AS(pinp->nextp(), Pin)) { for (AstPin* pinp = startpinp; pinp; pinp = VN_AS(pinp->nextp(), Pin)) {
if (AstVar* const varp = pinp->modVarp()) { if (const AstVar* const varp = pinp->modVarp()) {
const auto varIt = vlstd::as_const(nameToPin).find(varp->name()); const auto varIt = vlstd::as_const(nameToPin).find(varp->name());
UASSERT_OBJ(varIt != nameToPin.end(), varp, UASSERT_OBJ(varIt != nameToPin.end(), varp,
"Not found in " << modp->prettyNameQ()); "Not found in " << modp->prettyNameQ());
@ -471,10 +471,10 @@ class ParamProcessor final {
std::map<string, AstConst*> pins; std::map<string, AstConst*> pins;
for (AstPin* pinp = paramPinsp; pinp; pinp = VN_AS(pinp->nextp(), Pin)) { for (AstPin* pinp = paramPinsp; pinp; pinp = VN_AS(pinp->nextp(), Pin)) {
checkSupportedParam(modp, pinp); checkSupportedParam(modp, pinp);
if (AstVar* const varp = pinp->modVarp()) { if (const AstVar* const varp = pinp->modVarp()) {
if (!pinp->exprp()) continue; if (!pinp->exprp()) continue;
if (varp->isGParam()) { if (varp->isGParam()) {
AstConst* constp = VN_CAST(pinp->exprp(), Const); AstConst* const constp = VN_CAST(pinp->exprp(), Const);
pins.emplace(varp->name(), constp); pins.emplace(varp->name(), constp);
} }
} }
@ -575,8 +575,8 @@ class ParamProcessor final {
relinkPins(clonemapp, paramsp); relinkPins(clonemapp, paramsp);
// Fix any interface references // Fix any interface references
for (auto it = ifaceRefRefs.cbegin(); it != ifaceRefRefs.cend(); ++it) { for (auto it = ifaceRefRefs.cbegin(); it != ifaceRefRefs.cend(); ++it) {
AstIfaceRefDType* const portIrefp = it->first; const AstIfaceRefDType* const portIrefp = it->first;
AstIfaceRefDType* const pinIrefp = it->second; const AstIfaceRefDType* const pinIrefp = it->second;
AstIfaceRefDType* const cloneIrefp = portIrefp->clonep(); AstIfaceRefDType* const cloneIrefp = portIrefp->clonep();
UINFO(8, " IfaceOld " << portIrefp << endl); UINFO(8, " IfaceOld " << portIrefp << endl);
UINFO(8, " IfaceTo " << pinIrefp << endl); UINFO(8, " IfaceTo " << pinIrefp << endl);
@ -589,7 +589,7 @@ class ParamProcessor final {
// DOES clone() so must be finished with module clonep() before here // DOES clone() so must be finished with module clonep() before here
for (AstPin* pinp = paramsp; pinp; pinp = VN_AS(pinp->nextp(), Pin)) { for (AstPin* pinp = paramsp; pinp; pinp = VN_AS(pinp->nextp(), Pin)) {
if (pinp->exprp()) { if (pinp->exprp()) {
if (AstVar* modvarp = pinp->modVarp()) { if (AstVar* const modvarp = pinp->modVarp()) {
AstNode* const newp = pinp->exprp(); // Const or InitArray AstNode* const newp = pinp->exprp(); // Const or InitArray
AstConst* const exprp = VN_CAST(newp, Const); AstConst* const exprp = VN_CAST(newp, Const);
AstConst* const origp = VN_CAST(modvarp->valuep(), Const); AstConst* const origp = VN_CAST(modvarp->valuep(), Const);
@ -694,15 +694,15 @@ class ParamProcessor final {
void cellInterfaceCleanup(AstCell* nodep, AstNodeModule* srcModp, string& longnamer, void cellInterfaceCleanup(AstCell* nodep, AstNodeModule* srcModp, string& longnamer,
bool& any_overridesr, IfaceRefRefs& ifaceRefRefs) { bool& any_overridesr, IfaceRefRefs& ifaceRefRefs) {
for (AstPin* pinp = nodep->pinsp(); pinp; pinp = VN_AS(pinp->nextp(), Pin)) { for (AstPin* pinp = nodep->pinsp(); pinp; pinp = VN_AS(pinp->nextp(), Pin)) {
AstVar* const modvarp = pinp->modVarp(); const AstVar* const modvarp = pinp->modVarp();
if (modvarp->isIfaceRef()) { if (modvarp->isIfaceRef()) {
AstIfaceRefDType* portIrefp = VN_CAST(modvarp->subDTypep(), IfaceRefDType); AstIfaceRefDType* portIrefp = VN_CAST(modvarp->subDTypep(), IfaceRefDType);
if (!portIrefp && arraySubDTypep(modvarp->subDTypep())) { if (!portIrefp && arraySubDTypep(modvarp->subDTypep())) {
portIrefp = VN_CAST(arraySubDTypep(modvarp->subDTypep()), IfaceRefDType); portIrefp = VN_CAST(arraySubDTypep(modvarp->subDTypep()), IfaceRefDType);
} }
AstIfaceRefDType* pinIrefp = nullptr; AstIfaceRefDType* pinIrefp = nullptr;
AstNode* const exprp = pinp->exprp(); const AstNode* const exprp = pinp->exprp();
AstVar* const varp const AstVar* const varp
= (exprp && VN_IS(exprp, VarRef)) ? VN_AS(exprp, VarRef)->varp() : nullptr; = (exprp && VN_IS(exprp, VarRef)) ? VN_AS(exprp, VarRef)->varp() : nullptr;
if (varp && varp->subDTypep() && VN_IS(varp->subDTypep(), IfaceRefDType)) { if (varp && varp->subDTypep() && VN_IS(varp->subDTypep(), IfaceRefDType)) {
pinIrefp = VN_AS(varp->subDTypep(), IfaceRefDType); pinIrefp = VN_AS(varp->subDTypep(), IfaceRefDType);
@ -974,7 +974,7 @@ class ParamVisitor final : public AstNVisitor {
UINFO(9, "Found interface parameter: " << varp << endl); UINFO(9, "Found interface parameter: " << varp << endl);
nodep->varp(varp); nodep->varp(varp);
return true; return true;
} else if (AstPin* const pinp = VN_CAST(candp, Pin)) { } else if (const AstPin* const pinp = VN_CAST(candp, Pin)) {
UINFO(9, "Found interface parameter: " << pinp << endl); UINFO(9, "Found interface parameter: " << pinp << endl);
UASSERT_OBJ(pinp->exprp(), pinp, "Interface parameter pin missing expression"); UASSERT_OBJ(pinp->exprp(), pinp, "Interface parameter pin missing expression");
VL_DO_DANGLING(nodep->replaceWith(pinp->exprp()->cloneTree(false)), nodep); VL_DO_DANGLING(nodep->replaceWith(pinp->exprp()->cloneTree(false)), nodep);
@ -988,7 +988,7 @@ class ParamVisitor final : public AstNVisitor {
// Check to see if the scope is just an interface because interfaces are special // Check to see if the scope is just an interface because interfaces are special
const string dotted = nodep->dotted(); const string dotted = nodep->dotted();
if (!dotted.empty() && nodep->varp() && nodep->varp()->isParam()) { if (!dotted.empty() && nodep->varp() && nodep->varp()->isParam()) {
AstNode* backp = nodep; const AstNode* backp = nodep;
while ((backp = backp->backp())) { while ((backp = backp->backp())) {
if (VN_IS(backp, NodeModule)) { if (VN_IS(backp, NodeModule)) {
UINFO(9, "Hit module boundary, done looking for interface" << endl); UINFO(9, "Hit module boundary, done looking for interface" << endl);
@ -1000,14 +1000,14 @@ class ParamVisitor final : public AstNVisitor {
|| (VN_CAST(VN_CAST(backp, Var)->childDTypep(), UnpackArrayDType) || (VN_CAST(VN_CAST(backp, Var)->childDTypep(), UnpackArrayDType)
&& VN_CAST(VN_CAST(backp, Var)->childDTypep()->getChildDTypep(), && VN_CAST(VN_CAST(backp, Var)->childDTypep()->getChildDTypep(),
IfaceRefDType)))) { IfaceRefDType)))) {
AstIfaceRefDType* ifacerefp const AstIfaceRefDType* ifacerefp
= VN_CAST(VN_CAST(backp, Var)->childDTypep(), IfaceRefDType); = VN_CAST(VN_CAST(backp, Var)->childDTypep(), IfaceRefDType);
if (!ifacerefp) { if (!ifacerefp) {
ifacerefp = VN_CAST(VN_CAST(backp, Var)->childDTypep()->getChildDTypep(), ifacerefp = VN_CAST(VN_CAST(backp, Var)->childDTypep()->getChildDTypep(),
IfaceRefDType); IfaceRefDType);
} }
// Interfaces passed in on the port map have ifaces // Interfaces passed in on the port map have ifaces
if (AstIface* const ifacep = ifacerefp->ifacep()) { if (const AstIface* const ifacep = ifacerefp->ifacep()) {
if (dotted == backp->name()) { if (dotted == backp->name()) {
UINFO(9, "Iface matching scope: " << ifacep << endl); UINFO(9, "Iface matching scope: " << ifacep << endl);
if (ifaceParamReplace(nodep, ifacep->stmtsp())) { // if (ifaceParamReplace(nodep, ifacep->stmtsp())) { //
@ -1016,7 +1016,7 @@ class ParamVisitor final : public AstNVisitor {
} }
} }
// Interfaces declared in this module have cells // Interfaces declared in this module have cells
else if (AstCell* const cellp = ifacerefp->cellp()) { else if (const AstCell* const cellp = ifacerefp->cellp()) {
if (dotted == cellp->name()) { if (dotted == cellp->name()) {
UINFO(9, "Iface matching scope: " << cellp << endl); UINFO(9, "Iface matching scope: " << cellp << endl);
if (ifaceParamReplace(nodep, cellp->paramsp())) { // if (ifaceParamReplace(nodep, cellp->paramsp())) { //
@ -1140,7 +1140,7 @@ class ParamVisitor final : public AstNVisitor {
V3Width::widthParamsEdit(nodep); // Param typed widthing will NOT recurse the body, V3Width::widthParamsEdit(nodep); // Param typed widthing will NOT recurse the body,
// don't trigger errors yet. // don't trigger errors yet.
V3Const::constifyParamsEdit(nodep->exprp()); // exprp may change V3Const::constifyParamsEdit(nodep->exprp()); // exprp may change
AstConst* const exprp = VN_AS(nodep->exprp(), Const); const AstConst* const exprp = VN_AS(nodep->exprp(), Const);
// Constify // Constify
for (AstCaseItem* itemp = nodep->itemsp(); itemp; for (AstCaseItem* itemp = nodep->itemsp(); itemp;
itemp = VN_AS(itemp->nextp(), CaseItem)) { itemp = VN_AS(itemp->nextp(), CaseItem)) {

View File

@ -193,8 +193,8 @@ double V3ParseImp::lexParseTimenum(const char* textp) {
if (*sp != '_') *dp++ = *sp; if (*sp != '_') *dp++ = *sp;
} }
*dp++ = '\0'; *dp++ = '\0';
double d = strtod(strgp, nullptr); const double d = strtod(strgp, nullptr);
string suffix(sp); const string suffix(sp);
double divisor = 1; double divisor = 1;
if (suffix == "s") { if (suffix == "s") {
@ -288,7 +288,7 @@ void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool i
if (v3Global.opt.preprocOnly() || v3Global.opt.keepTempFiles()) { if (v3Global.opt.preprocOnly() || v3Global.opt.keepTempFiles()) {
// Create output file with all the preprocessor output we buffered up // Create output file with all the preprocessor output we buffered up
string vppfilename const string vppfilename
= v3Global.opt.hierTopDataDir() + "/" + v3Global.opt.prefix() + "_" + modname + ".vpp"; = v3Global.opt.hierTopDataDir() + "/" + v3Global.opt.prefix() + "_" + modname + ".vpp";
std::ofstream* ofp = nullptr; std::ofstream* ofp = nullptr;
std::ostream* osp; std::ostream* osp;
@ -392,7 +392,7 @@ void V3ParseImp::tokenPipeline() {
if (debugFlex() >= 6) { if (debugFlex() >= 6) {
cout << " tokenPipeline: reading ahead to find possible strength" << endl; cout << " tokenPipeline: reading ahead to find possible strength" << endl;
} }
V3ParseBisonYYSType curValue = yylval; // Remember value, as about to read ahead const V3ParseBisonYYSType curValue = yylval; // Remember value, as about to read ahead
const V3ParseBisonYYSType* nexttokp = tokenPeekp(0); const V3ParseBisonYYSType* nexttokp = tokenPeekp(0);
const int nexttok = nexttokp->token; const int nexttok = nexttokp->token;
yylval = curValue; yylval = curValue;
@ -467,7 +467,8 @@ void V3ParseImp::tokenPipeline() {
if (nexttok == yP_COLONCOLON) { if (nexttok == yP_COLONCOLON) {
token = yaID__CC; token = yaID__CC;
} else if (nexttok == '#') { } else if (nexttok == '#') {
V3ParseBisonYYSType curValue = yylval; // Remember value, as about to read ahead const V3ParseBisonYYSType curValue
= yylval; // Remember value, as about to read ahead
{ {
const size_t depth = tokenPipeScanParam(0); const size_t depth = tokenPipeScanParam(0);
if (tokenPeekp(depth)->token == yP_COLONCOLON) token = yaID__CC; if (tokenPeekp(depth)->token == yP_COLONCOLON) token = yaID__CC;
@ -487,8 +488,8 @@ void V3ParseImp::tokenPipelineSym() {
tokenPipeline(); // sets yylval tokenPipeline(); // sets yylval
int token = yylval.token; int token = yylval.token;
if (token == yaID__LEX || token == yaID__CC) { if (token == yaID__LEX || token == yaID__CC) {
VSymEnt* foundp; const VSymEnt* foundp;
if (VSymEnt* const look_underp = V3ParseImp::parsep()->symp()->nextId()) { if (const VSymEnt* const look_underp = V3ParseImp::parsep()->symp()->nextId()) {
UINFO(7, " tokenPipelineSym: next id lookup forced under " << look_underp << endl); UINFO(7, " tokenPipelineSym: next id lookup forced under " << look_underp << endl);
// if (debug() >= 7) V3ParseImp::parsep()->symp()->dump(cout, " -symtree: "); // if (debug() >= 7) V3ParseImp::parsep()->symp()->dump(cout, " -symtree: ");
foundp = look_underp->findIdFallback(*(yylval.strp)); foundp = look_underp->findIdFallback(*(yylval.strp));

View File

@ -133,8 +133,8 @@ std::ostream& operator<<(std::ostream& os, const V3ParseBisonYYSType& rhs);
class V3ParseImp final { class V3ParseImp final {
// MEMBERS // MEMBERS
AstNetlist* m_rootp; // Root of the design AstNetlist* const m_rootp; // Root of the design
VInFilter* m_filterp; // Reading filter VInFilter* const m_filterp; // Reading filter
V3ParseSym* m_symp; // Symbol table V3ParseSym* m_symp; // Symbol table
V3Lexer* m_lexerp; // Current FlexLexer V3Lexer* m_lexerp; // Current FlexLexer
@ -229,18 +229,18 @@ public:
// These can be called by either parser or lexer, as not lex/parser-position aware // These can be called by either parser or lexer, as not lex/parser-position aware
string* newString(const string& text) { string* newString(const string& text) {
// Allocate a string, remembering it so we can reclaim storage at lex end // Allocate a string, remembering it so we can reclaim storage at lex end
string* strp = new string(text); string* const strp = new string(text);
m_stringps.push_back(strp); m_stringps.push_back(strp);
return strp; return strp;
} }
string* newString(const char* text) { string* newString(const char* text) {
// Allocate a string, remembering it so we can reclaim storage at lex end // Allocate a string, remembering it so we can reclaim storage at lex end
string* strp = new string(text); string* const strp = new string(text);
m_stringps.push_back(strp); m_stringps.push_back(strp);
return strp; return strp;
} }
string* newString(const char* text, size_t length) { string* newString(const char* text, size_t length) {
string* strp = new string(text, length); string* const strp = new string(text, length);
m_stringps.push_back(strp); m_stringps.push_back(strp);
return strp; return strp;
} }
@ -275,7 +275,8 @@ public:
V3ParseSym* symp() { return m_symp; } V3ParseSym* symp() { return m_symp; }
AstPackage* unitPackage(FileLine* fl) { AstPackage* unitPackage(FileLine* fl) {
// Find one made earlier? // Find one made earlier?
VSymEnt* const rootSymp = symp()->symRootp()->findIdFlat(AstPackage::dollarUnitName()); const VSymEnt* const rootSymp
= symp()->symRootp()->findIdFlat(AstPackage::dollarUnitName());
AstPackage* pkgp; AstPackage* pkgp;
if (!rootSymp) { if (!rootSymp) {
pkgp = parsep()->rootp()->dollarUnitPkgAddp(); pkgp = parsep()->rootp()->dollarUnitPkgAddp();

View File

@ -66,7 +66,7 @@ public:
VSymEnt* findNewTable(AstNode* nodep) { VSymEnt* findNewTable(AstNode* nodep) {
if (!nodep->user4p()) { if (!nodep->user4p()) {
VSymEnt* symsp = new VSymEnt(&m_syms, nodep); VSymEnt* const symsp = new VSymEnt(&m_syms, nodep);
nodep->user4p(symsp); nodep->user4p(symsp);
} }
return getTable(nodep); return getTable(nodep);
@ -93,7 +93,7 @@ public:
void pushNew(AstNode* nodep) { pushNewUnder(nodep, nullptr); } void pushNew(AstNode* nodep) { pushNewUnder(nodep, nullptr); }
void pushNewUnder(AstNode* nodep, VSymEnt* parentp) { void pushNewUnder(AstNode* nodep, VSymEnt* parentp) {
if (!parentp) parentp = symCurrentp(); if (!parentp) parentp = symCurrentp();
VSymEnt* symp VSymEnt* const symp
= findNewTable(nodep); // Will set user4p, which is how we connect table to node = findNewTable(nodep); // Will set user4p, which is how we connect table to node
symp->fallbackp(parentp); symp->fallbackp(parentp);
reinsert(nodep, parentp); reinsert(nodep, parentp);
@ -128,7 +128,7 @@ public:
void showUpward() { // LCOV_EXCL_START void showUpward() { // LCOV_EXCL_START
UINFO(1, "ParseSym Stack:\n"); UINFO(1, "ParseSym Stack:\n");
for (auto it = m_sympStack.rbegin(); it != m_sympStack.rend(); ++it) { for (auto it = m_sympStack.rbegin(); it != m_sympStack.rend(); ++it) {
VSymEnt* symp = *it; VSymEnt* const symp = *it;
UINFO(1, " " << symp->nodep() << endl); UINFO(1, " " << symp->nodep() << endl);
} }
UINFO(1, "ParseSym Current: " << symCurrentp()->nodep() << endl); UINFO(1, "ParseSym Current: " << symCurrentp()->nodep() << endl);
@ -136,7 +136,7 @@ public:
void dump(std::ostream& os, const string& indent = "") { m_syms.dump(os, indent); } void dump(std::ostream& os, const string& indent = "") { m_syms.dump(os, indent); }
AstNode* findEntUpward(const string& name) const { AstNode* findEntUpward(const string& name) const {
// Lookup the given string as an identifier, return type of the id, scanning upward // Lookup the given string as an identifier, return type of the id, scanning upward
VSymEnt* foundp = symCurrentp()->findIdFallback(name); VSymEnt* const foundp = symCurrentp()->findIdFallback(name);
if (foundp) { if (foundp) {
return foundp->nodep(); return foundp->nodep();
} else { } else {
@ -145,7 +145,7 @@ public:
} }
void importExtends(AstNode* classp) { void importExtends(AstNode* classp) {
// Import from package::id_or_star to this // Import from package::id_or_star to this
VSymEnt* symp = getTable(classp); VSymEnt* const symp = getTable(classp);
UASSERT_OBJ(symp, classp, // Internal problem, because we earlier found it UASSERT_OBJ(symp, classp, // Internal problem, because we earlier found it
"Extends class package not found"); "Extends class package not found");
// Walk old sym table and reinsert into current table // Walk old sym table and reinsert into current table
@ -154,7 +154,7 @@ public:
} }
void importItem(AstNode* packagep, const string& id_or_star) { void importItem(AstNode* packagep, const string& id_or_star) {
// Import from package::id_or_star to this // Import from package::id_or_star to this
VSymEnt* symp = getTable(packagep); VSymEnt* const symp = getTable(packagep);
UASSERT_OBJ(symp, packagep, // Internal problem, because we earlier found it UASSERT_OBJ(symp, packagep, // Internal problem, because we earlier found it
"Import package not found"); "Import package not found");
// Walk old sym table and reinsert into current table // Walk old sym table and reinsert into current table
@ -163,7 +163,7 @@ public:
} }
void exportItem(AstNode* packagep, const string& id_or_star) { void exportItem(AstNode* packagep, const string& id_or_star) {
// Export from this the remote package::id_or_star // Export from this the remote package::id_or_star
VSymEnt* symp = getTable(packagep); VSymEnt* const symp = getTable(packagep);
UASSERT_OBJ(symp, packagep, // Internal problem, because we earlier found it UASSERT_OBJ(symp, packagep, // Internal problem, because we earlier found it
"Export package not found"); "Export package not found");
symCurrentp()->exportFromPackage(&m_syms, symp, id_or_star); symCurrentp()->exportFromPackage(&m_syms, symp, id_or_star);

View File

@ -162,12 +162,12 @@ static void partCheckCachedScoreVsActual(uint32_t cached, uint32_t actual) {
template <class T_CostAccessor> class PartPropagateCp : GraphAlg<> { template <class T_CostAccessor> class PartPropagateCp : GraphAlg<> {
private: private:
// MEMBERS // MEMBERS
GraphWay m_way; // CPs oriented in this direction: either FORWARD const GraphWay m_way; // CPs oriented in this direction: either FORWARD
// // from graph-start to current node, or REVERSE // // from graph-start to current node, or REVERSE
// // from graph-end to current node. // // from graph-end to current node.
T_CostAccessor* const m_accessp; // Access cost and CPs on V3GraphVertex's. T_CostAccessor* const m_accessp; // Access cost and CPs on V3GraphVertex's.
// // confirm we only process each vertex once. // // confirm we only process each vertex once.
bool m_slowAsserts; // Enable nontrivial asserts const bool m_slowAsserts; // Enable nontrivial asserts
SortByValueMap<V3GraphVertex*, uint32_t> m_pending; // Pending rescores SortByValueMap<V3GraphVertex*, uint32_t> m_pending; // Pending rescores
public: public:
@ -291,7 +291,7 @@ private:
// direction, it assumes REVERSE is symmetrical and would be // direction, it assumes REVERSE is symmetrical and would be
// redundant to test. // redundant to test.
GraphStreamUnordered order(&m_graph); GraphStreamUnordered order(&m_graph);
while (const V3GraphVertex* cvxp = order.nextp()) { while (const V3GraphVertex* const cvxp = order.nextp()) {
V3GraphVertex* const vxp = const_cast<V3GraphVertex*>(cvxp); V3GraphVertex* const vxp = const_cast<V3GraphVertex*>(cvxp);
uint32_t cpCost = 0; uint32_t cpCost = 0;
for (V3GraphEdge* edgep = vxp->inBeginp(); edgep; edgep = edgep->inNextp()) { for (V3GraphEdge* edgep = vxp->inBeginp(); edgep; edgep = edgep->inNextp()) {
@ -401,7 +401,7 @@ public:
// Check that CP matches that of the longest edge wayward of vxp. // Check that CP matches that of the longest edge wayward of vxp.
void checkNewCpVersusEdges(V3GraphVertex* vxp, GraphWay way, uint32_t cp) const { void checkNewCpVersusEdges(V3GraphVertex* vxp, GraphWay way, uint32_t cp) const {
LogicMTask* const mtaskp = dynamic_cast<LogicMTask*>(vxp); LogicMTask* const mtaskp = dynamic_cast<LogicMTask*>(vxp);
EdgeSet& edges = mtaskp->m_edges[way.invert()]; const EdgeSet& edges = mtaskp->m_edges[way.invert()];
// This is mtaskp's relative with longest !wayward inclusive CP: // This is mtaskp's relative with longest !wayward inclusive CP:
const auto edgeIt = edges.rbegin(); const auto edgeIt = edges.rbegin();
const uint32_t edgeCp = (*edgeIt).value(); const uint32_t edgeCp = (*edgeIt).value();
@ -454,7 +454,7 @@ public:
for (unsigned int& i : m_critPathCost) i = 0; for (unsigned int& i : m_critPathCost) i = 0;
if (mtmvVxp) { // Else null for test if (mtmvVxp) { // Else null for test
m_vertices.push_back(mtmvVxp); m_vertices.push_back(mtmvVxp);
if (OrderLogicVertex* const olvp = mtmvVxp->logicp()) { if (const OrderLogicVertex* const olvp = mtmvVxp->logicp()) {
m_cost += V3InstrCount::count(olvp->nodep(), true); m_cost += V3InstrCount::count(olvp->nodep(), true);
} }
} }
@ -527,7 +527,7 @@ public:
void checkRelativesCp(GraphWay way) const { void checkRelativesCp(GraphWay way) const {
const EdgeSet& edges = m_edges[way]; const EdgeSet& edges = m_edges[way];
for (EdgeSet::const_reverse_iterator it = edges.rbegin(); it != edges.rend(); ++it) { for (EdgeSet::const_reverse_iterator it = edges.rbegin(); it != edges.rend(); ++it) {
LogicMTask* const relativep = (*it).key(); const LogicMTask* const relativep = (*it).key();
const uint32_t cachedCp = (*it).value(); const uint32_t cachedCp = (*it).value();
partCheckCachedScoreVsActual(cachedCp, relativep->critPathCost(way.invert()) partCheckCachedScoreVsActual(cachedCp, relativep->critPathCost(way.invert())
+ relativep->stepCost()); + relativep->stepCost());
@ -625,7 +625,7 @@ public:
static void dumpCpFilePrefixed(const V3Graph* graphp, const string& nameComment) { static void dumpCpFilePrefixed(const V3Graph* graphp, const string& nameComment) {
const string filename = v3Global.debugFilename(nameComment) + ".txt"; const string filename = v3Global.debugFilename(nameComment) + ".txt";
UINFO(1, "Writing " << filename << endl); UINFO(1, "Writing " << filename << endl);
std::unique_ptr<std::ofstream> ofp{V3File::new_ofstream(filename)}; const std::unique_ptr<std::ofstream> ofp{V3File::new_ofstream(filename)};
std::ostream* const osp = &(*ofp); // &* needed to deref unique_ptr std::ostream* const osp = &(*ofp); // &* needed to deref unique_ptr
if (osp->fail()) v3fatalStatic("Can't write " << filename); if (osp->fail()) v3fatalStatic("Can't write " << filename);
@ -652,7 +652,7 @@ public:
totalCost += nextp->cost(); totalCost += nextp->cost();
const EdgeSet& children = nextp->m_edges[GraphWay::FORWARD]; const EdgeSet& children = nextp->m_edges[GraphWay::FORWARD];
EdgeSet::const_reverse_iterator it = children.rbegin(); const EdgeSet::const_reverse_iterator it = children.rbegin();
if (it == children.rend()) { if (it == children.rend()) {
nextp = nullptr; nextp = nullptr;
} else { } else {
@ -976,7 +976,7 @@ static void partInitHalfCriticalPaths(GraphWay way, V3Graph* mtasksp, bool check
"Should be no redundant edges in mtasks graph"); "Should be no redundant edges in mtasks graph");
relatives.insert(edgep->furtherp(rev)); relatives.insert(edgep->furtherp(rev));
#endif #endif
LogicMTask* const relativep = dynamic_cast<LogicMTask*>(edgep->furtherp(rev)); const LogicMTask* const relativep = dynamic_cast<LogicMTask*>(edgep->furtherp(rev));
cpCost = std::max(cpCost, (relativep->critPathCost(way) cpCost = std::max(cpCost, (relativep->critPathCost(way)
+ static_cast<uint32_t>(relativep->stepCost()))); + static_cast<uint32_t>(relativep->stepCost())));
} }
@ -1009,7 +1009,7 @@ static void partCheckCriticalPaths(V3Graph* mtasksp) {
partInitHalfCriticalPaths(GraphWay::FORWARD, mtasksp, true); partInitHalfCriticalPaths(GraphWay::FORWARD, mtasksp, true);
partInitHalfCriticalPaths(GraphWay::REVERSE, mtasksp, true); partInitHalfCriticalPaths(GraphWay::REVERSE, mtasksp, true);
for (V3GraphVertex* vxp = mtasksp->verticesBeginp(); vxp; vxp = vxp->verticesNextp()) { for (V3GraphVertex* vxp = mtasksp->verticesBeginp(); vxp; vxp = vxp->verticesNextp()) {
LogicMTask* const mtaskp = dynamic_cast<LogicMTask*>(vxp); const LogicMTask* const mtaskp = dynamic_cast<LogicMTask*>(vxp);
mtaskp->checkRelativesCp(GraphWay::FORWARD); mtaskp->checkRelativesCp(GraphWay::FORWARD);
mtaskp->checkRelativesCp(GraphWay::REVERSE); mtaskp->checkRelativesCp(GraphWay::REVERSE);
} }
@ -1059,12 +1059,12 @@ static void partMergeEdgesFrom(V3Graph* mtasksp, LogicMTask* recipientp, LogicMT
V3Scoreboard<MergeCandidate, uint32_t>* sbp) { V3Scoreboard<MergeCandidate, uint32_t>* sbp) {
for (const auto& way : {GraphWay::FORWARD, GraphWay::REVERSE}) { for (const auto& way : {GraphWay::FORWARD, GraphWay::REVERSE}) {
for (V3GraphEdge* edgep = donorp->beginp(way); edgep; edgep = partBlastEdgep(way, edgep)) { for (V3GraphEdge* edgep = donorp->beginp(way); edgep; edgep = partBlastEdgep(way, edgep)) {
MTaskEdge* const tedgep = MTaskEdge::cast(edgep); const MTaskEdge* const tedgep = MTaskEdge::cast(edgep);
if (sbp && !tedgep->removedFromSb()) sbp->removeElem(tedgep); if (sbp && !tedgep->removedFromSb()) sbp->removeElem(tedgep);
// Existing edge; mark it in need of a rescore // Existing edge; mark it in need of a rescore
if (recipientp->hasRelative(way, tedgep->furtherMTaskp(way))) { if (recipientp->hasRelative(way, tedgep->furtherMTaskp(way))) {
if (sbp) { if (sbp) {
MTaskEdge* const existMTaskEdgep = MTaskEdge::cast( const MTaskEdge* const existMTaskEdgep = MTaskEdge::cast(
recipientp->findConnectingEdgep(way, tedgep->furtherMTaskp(way))); recipientp->findConnectingEdgep(way, tedgep->furtherMTaskp(way)));
UASSERT(existMTaskEdgep, "findConnectingEdge didn't find edge"); UASSERT(existMTaskEdgep, "findConnectingEdge didn't find edge");
if (!existMTaskEdgep->removedFromSb()) { if (!existMTaskEdgep->removedFromSb()) {
@ -1073,7 +1073,7 @@ static void partMergeEdgesFrom(V3Graph* mtasksp, LogicMTask* recipientp, LogicMT
} }
} else { } else {
// No existing edge into *this, make one. // No existing edge into *this, make one.
MTaskEdge* newEdgep; const MTaskEdge* newEdgep;
if (way == GraphWay::REVERSE) { if (way == GraphWay::REVERSE) {
newEdgep = new MTaskEdge(mtasksp, tedgep->fromMTaskp(), recipientp, 1); newEdgep = new MTaskEdge(mtasksp, tedgep->fromMTaskp(), recipientp, 1);
} else { } else {
@ -1112,7 +1112,7 @@ private:
uint32_t m_scoreLimit; // Sloppy score allowed when picking merges uint32_t m_scoreLimit; // Sloppy score allowed when picking merges
uint32_t m_scoreLimitBeforeRescore = 0xffffffff; // Next score rescore at uint32_t m_scoreLimitBeforeRescore = 0xffffffff; // Next score rescore at
unsigned m_mergesSinceRescore = 0; // Merges since last rescore unsigned m_mergesSinceRescore = 0; // Merges since last rescore
bool m_slowAsserts; // Take extra time to validate algorithm const bool m_slowAsserts; // Take extra time to validate algorithm
V3Scoreboard<MergeCandidate, uint32_t> m_sb; // Scoreboard V3Scoreboard<MergeCandidate, uint32_t> m_sb; // Scoreboard
SibSet m_pairs; // Storage for each SiblingMC SibSet m_pairs; // Storage for each SiblingMC
MTask2Sibs m_mtask2sibs; // SiblingMC set for each mtask MTask2Sibs m_mtask2sibs; // SiblingMC set for each mtask
@ -1210,7 +1210,7 @@ public:
++mtaskCount; ++mtaskCount;
} }
if (mtaskCount > maxMTasks) { if (mtaskCount > maxMTasks) {
uint32_t oldLimit = m_scoreLimit; const uint32_t oldLimit = m_scoreLimit;
m_scoreLimit = (m_scoreLimit * 120) / 100; m_scoreLimit = (m_scoreLimit * 120) / 100;
v3Global.rootp()->fileline()->v3warn( v3Global.rootp()->fileline()->v3warn(
UNOPTTHREADS, "Thread scheduler is unable to provide requested " UNOPTTHREADS, "Thread scheduler is unable to provide requested "
@ -1309,7 +1309,7 @@ private:
++it) { ++it) {
const SiblingMC* const pairp = *it; const SiblingMC* const pairp = *it;
if (!pairp->removedFromSb()) m_sb.removeElem(pairp); if (!pairp->removedFromSb()) m_sb.removeElem(pairp);
LogicMTask* const otherp = (pairp->bp() == mtaskp) ? pairp->ap() : pairp->bp(); const LogicMTask* const otherp = (pairp->bp() == mtaskp) ? pairp->ap() : pairp->bp();
size_t erased = m_mtask2sibs[otherp].erase(pairp); size_t erased = m_mtask2sibs[otherp].erase(pairp);
UASSERT_OBJ(erased > 0, otherp, "Expected existing mtask"); UASSERT_OBJ(erased > 0, otherp, "Expected existing mtask");
erased = m_pairs.erase(*pairp); erased = m_pairs.erase(*pairp);
@ -1323,7 +1323,7 @@ private:
LogicMTask* top = nullptr; LogicMTask* top = nullptr;
LogicMTask* fromp = nullptr; LogicMTask* fromp = nullptr;
MTaskEdge* mergeEdgep = mergeCanp->toMTaskEdge(); MTaskEdge* mergeEdgep = mergeCanp->toMTaskEdge();
SiblingMC* mergeSibsp = nullptr; const SiblingMC* mergeSibsp = nullptr;
if (mergeEdgep) { if (mergeEdgep) {
top = dynamic_cast<LogicMTask*>(mergeEdgep->top()); top = dynamic_cast<LogicMTask*>(mergeEdgep->top());
fromp = dynamic_cast<LogicMTask*>(mergeEdgep->fromp()); fromp = dynamic_cast<LogicMTask*>(mergeEdgep->fromp());
@ -1490,8 +1490,8 @@ private:
// Score this edge. Lower is better. The score is the new local CP // Score this edge. Lower is better. The score is the new local CP
// length if we merge these mtasks. ("Local" means the longest // length if we merge these mtasks. ("Local" means the longest
// critical path running through the merged node.) // critical path running through the merged node.)
LogicMTask* const top = dynamic_cast<LogicMTask*>(edgep->top()); const LogicMTask* const top = dynamic_cast<LogicMTask*>(edgep->top());
LogicMTask* const fromp = dynamic_cast<LogicMTask*>(edgep->fromp()); const LogicMTask* const fromp = dynamic_cast<LogicMTask*>(edgep->fromp());
const uint32_t mergedCpCostFwd const uint32_t mergedCpCostFwd
= std::max(fromp->critPathCost(GraphWay::FORWARD), = std::max(fromp->critPathCost(GraphWay::FORWARD),
top->critPathCostWithout(GraphWay::FORWARD, edgep)); top->critPathCostWithout(GraphWay::FORWARD, edgep));
@ -1503,8 +1503,8 @@ private:
} }
void makeSiblingMC(LogicMTask* ap, LogicMTask* bp) { void makeSiblingMC(LogicMTask* ap, LogicMTask* bp) {
SiblingMC newSibs(ap, bp); const SiblingMC newSibs(ap, bp);
std::pair<SibSet::iterator, bool> insertResult = m_pairs.insert(newSibs); const std::pair<SibSet::iterator, bool> insertResult = m_pairs.insert(newSibs);
if (insertResult.second) { if (insertResult.second) {
const SiblingMC* const newSibsp = &(*insertResult.first); const SiblingMC* const newSibsp = &(*insertResult.first);
m_mtask2sibs[ap].insert(newSibsp); m_mtask2sibs[ap].insert(newSibsp);
@ -1592,7 +1592,7 @@ private:
static vluint64_t partitionChainUsecs(unsigned chain_len) { static vluint64_t partitionChainUsecs(unsigned chain_len) {
// NOTE: To get a dot file run with --debugi-V3Partition 4 or more. // NOTE: To get a dot file run with --debugi-V3Partition 4 or more.
vluint64_t startUsecs = V3Os::timeUsecs(); const vluint64_t startUsecs = V3Os::timeUsecs();
V3Graph mtasks; V3Graph mtasks;
LogicMTask* lastp = nullptr; LogicMTask* lastp = nullptr;
for (unsigned i = 0; i < chain_len; ++i) { for (unsigned i = 0; i < chain_len; ++i) {
@ -1839,7 +1839,7 @@ private:
void findAdjacentTasks(OvvSet::iterator ovvIt, TasksByRank* tasksByRankp) { void findAdjacentTasks(OvvSet::iterator ovvIt, TasksByRank* tasksByRankp) {
// Find all writer tasks for this variable, group by rank. // Find all writer tasks for this variable, group by rank.
for (V3GraphEdge* edgep = (*ovvIt)->inBeginp(); edgep; edgep = edgep->inNextp()) { for (V3GraphEdge* edgep = (*ovvIt)->inBeginp(); edgep; edgep = edgep->inNextp()) {
OrderLogicVertex* const logicp = dynamic_cast<OrderLogicVertex*>(edgep->fromp()); const OrderLogicVertex* const logicp = dynamic_cast<OrderLogicVertex*>(edgep->fromp());
if (!logicp) continue; if (!logicp) continue;
if (logicp->domainp()->hasInitial() || logicp->domainp()->hasSettle()) continue; if (logicp->domainp()->hasInitial() || logicp->domainp()->hasSettle()) continue;
LogicMTask* const writerMtaskp = m_olv2mtask.at(logicp); LogicMTask* const writerMtaskp = m_olv2mtask.at(logicp);
@ -1847,7 +1847,7 @@ private:
} }
// Find all reader tasks for this variable, group by rank. // Find all reader tasks for this variable, group by rank.
for (V3GraphEdge* edgep = (*ovvIt)->outBeginp(); edgep; edgep = edgep->outNextp()) { for (V3GraphEdge* edgep = (*ovvIt)->outBeginp(); edgep; edgep = edgep->outNextp()) {
OrderLogicVertex* const logicp = dynamic_cast<OrderLogicVertex*>(edgep->fromp()); const OrderLogicVertex* const logicp = dynamic_cast<OrderLogicVertex*>(edgep->fromp());
if (!logicp) continue; if (!logicp) continue;
if (logicp->domainp()->hasInitial() || logicp->domainp()->hasSettle()) continue; if (logicp->domainp()->hasInitial() || logicp->domainp()->hasSettle()) continue;
LogicMTask* const readerMtaskp = m_olv2mtask.at(logicp); LogicMTask* const readerMtaskp = m_olv2mtask.at(logicp);
@ -1882,8 +1882,8 @@ private:
// Fix up the map, so donor's OLVs map to mergedp // Fix up the map, so donor's OLVs map to mergedp
for (LogicMTask::VxList::const_iterator tmvit = donorp->vertexListp()->begin(); for (LogicMTask::VxList::const_iterator tmvit = donorp->vertexListp()->begin();
tmvit != donorp->vertexListp()->end(); ++tmvit) { tmvit != donorp->vertexListp()->end(); ++tmvit) {
MTaskMoveVertex* const tmvp = *tmvit; const MTaskMoveVertex* const tmvp = *tmvit;
OrderLogicVertex* const logicp = tmvp->logicp(); const OrderLogicVertex* const logicp = tmvp->logicp();
if (logicp) m_olv2mtask[logicp] = mergedp; if (logicp) m_olv2mtask[logicp] = mergedp;
} }
// Move all vertices from donorp to mergedp // Move all vertices from donorp to mergedp
@ -1942,15 +1942,15 @@ public:
// stage, but whatever, write it as a loop: // stage, but whatever, write it as a loop:
for (LogicMTask::VxList::const_iterator it = mtaskp->vertexListp()->begin(); for (LogicMTask::VxList::const_iterator it = mtaskp->vertexListp()->begin();
it != mtaskp->vertexListp()->end(); ++it) { it != mtaskp->vertexListp()->end(); ++it) {
MTaskMoveVertex* const tmvp = *it; const MTaskMoveVertex* const tmvp = *it;
if (OrderLogicVertex* const logicp = tmvp->logicp()) { if (const OrderLogicVertex* const logicp = tmvp->logicp()) {
m_olv2mtask[logicp] = mtaskp; m_olv2mtask[logicp] = mtaskp;
// Look at downstream vars. // Look at downstream vars.
for (V3GraphEdge* edgep = logicp->outBeginp(); edgep; for (V3GraphEdge* edgep = logicp->outBeginp(); edgep;
edgep = edgep->outNextp()) { edgep = edgep->outNextp()) {
// Only consider OrderVarStdVertex which reflects // Only consider OrderVarStdVertex which reflects
// an actual lvalue assignment; the others do not. // an actual lvalue assignment; the others do not.
OrderVarStdVertex* const ovvp const OrderVarStdVertex* const ovvp
= dynamic_cast<OrderVarStdVertex*>(edgep->top()); = dynamic_cast<OrderVarStdVertex*>(edgep->top());
if (!ovvp) continue; if (!ovvp) continue;
if (ovvp->varScp()->varp()->isSc()) { if (ovvp->varScp()->varp()->isSc()) {
@ -2145,7 +2145,7 @@ void ThreadSchedule::dumpDotFile(const string& filename) const {
// This generates a file used by graphviz, https://www.graphviz.org // This generates a file used by graphviz, https://www.graphviz.org
const std::unique_ptr<std::ofstream> logp{V3File::new_ofstream(filename)}; const std::unique_ptr<std::ofstream> logp{V3File::new_ofstream(filename)};
if (logp->fail()) v3fatal("Can't write " << filename); if (logp->fail()) v3fatal("Can't write " << filename);
auto* depGraph = v3Global.rootp()->execGraphp()->depGraphp(); auto* const depGraph = v3Global.rootp()->execGraphp()->depGraphp();
// Header // Header
*logp << "digraph v3graph {\n"; *logp << "digraph v3graph {\n";
@ -2172,18 +2172,18 @@ void ThreadSchedule::dumpDotFile(const string& filename) const {
} }
} }
const double minWidth = 2.0; const double minWidth = 2.0;
auto mtaskXPos = [&](const ExecMTask* mtaskp, const double nodeWidth) { const auto mtaskXPos = [&](const ExecMTask* mtaskp, const double nodeWidth) {
const double startPosX = (minWidth * startTime(mtaskp)) / minCost; const double startPosX = (minWidth * startTime(mtaskp)) / minCost;
return nodeWidth / minWidth + startPosX; return nodeWidth / minWidth + startPosX;
}; };
auto emitMTask = [&](const ExecMTask* mtaskp) { const auto emitMTask = [&](const ExecMTask* mtaskp) {
const int thread = threadId(mtaskp); const int thread = threadId(mtaskp);
const double nodeWidth = minWidth * (static_cast<double>(mtaskp->cost()) / minCost); const double nodeWidth = minWidth * (static_cast<double>(mtaskp->cost()) / minCost);
const double x = mtaskXPos(mtaskp, nodeWidth); const double x = mtaskXPos(mtaskp, nodeWidth);
const int y = -thread; const int y = -thread;
string label = "label=\"" + mtaskp->name() + " (" + cvtToStr(startTime(mtaskp)) + ":" const string label = "label=\"" + mtaskp->name() + " (" + cvtToStr(startTime(mtaskp)) + ":"
+ std::to_string(endTime(mtaskp)) + ")" + "\""; + std::to_string(endTime(mtaskp)) + ")" + "\"";
*logp << " " << mtaskp->name() << " [" << label << " width=" << nodeWidth << " pos=\"" *logp << " " << mtaskp->name() << " [" << label << " width=" << nodeWidth << " pos=\""
<< x << "," << y << "!\"]\n"; << x << "," << y << "!\"]\n";
}; };
@ -2625,7 +2625,8 @@ void V3Partition::go(V3Graph* mtasksp) {
// when scheduling them. // when scheduling them.
const unsigned fudgeNumerator = 3; const unsigned fudgeNumerator = 3;
const unsigned fudgeDenominator = 5; const unsigned fudgeDenominator = 5;
uint32_t cpLimit = ((totalGraphCost * fudgeNumerator) / (targetParFactor * fudgeDenominator)); const uint32_t cpLimit
= ((totalGraphCost * fudgeNumerator) / (targetParFactor * fudgeDenominator));
UINFO(4, "V3Partition set cpLimit = " << cpLimit << endl); UINFO(4, "V3Partition set cpLimit = " << cpLimit << endl);
// Merge MTask nodes together, repeatedly, until the CP budget is // Merge MTask nodes together, repeatedly, until the CP budget is
@ -2672,7 +2673,7 @@ void V3Partition::go(V3Graph* mtasksp) {
// Set color to indicate an mtaskId on every underlying MTaskMoveVertex. // Set color to indicate an mtaskId on every underlying MTaskMoveVertex.
for (V3GraphVertex* itp = mtasksp->verticesBeginp(); itp; itp = itp->verticesNextp()) { for (V3GraphVertex* itp = mtasksp->verticesBeginp(); itp; itp = itp->verticesNextp()) {
LogicMTask* const mtaskp = dynamic_cast<LogicMTask*>(itp); const LogicMTask* const mtaskp = dynamic_cast<LogicMTask*>(itp);
for (LogicMTask::VxList::const_iterator it = mtaskp->vertexListp()->begin(); for (LogicMTask::VxList::const_iterator it = mtaskp->vertexListp()->begin();
it != mtaskp->vertexListp()->end(); ++it) { it != mtaskp->vertexListp()->end(); ++it) {
MTaskMoveVertex* const mvertexp = *it; MTaskMoveVertex* const mvertexp = *it;
@ -2728,7 +2729,7 @@ static void normalizeCosts(Costs& costs) {
UINFO(9, UINFO(9,
"Post uint scale: ce = " << est.second.first << " cp=" << est.second.second << endl); "Post uint scale: ce = " << est.second.first << " cp=" << est.second.second << endl);
} }
vluint64_t scaleDownTo = 10000000; // Extra room for future algorithms to add costs const vluint64_t scaleDownTo = 10000000; // Extra room for future algorithms to add costs
if (maxCost > scaleDownTo) { if (maxCost > scaleDownTo) {
const double scaleup = static_cast<double>(scaleDownTo) / static_cast<double>(maxCost); const double scaleup = static_cast<double>(scaleDownTo) / static_cast<double>(maxCost);
UINFO(5, "Scaling data to within 32-bits by multiply by=" << scaleup << ", maxCost=" UINFO(5, "Scaling data to within 32-bits by multiply by=" << scaleup << ", maxCost="
@ -2826,7 +2827,7 @@ static void fillinCosts(V3Graph* execMTaskGraphp) {
static void finalizeCosts(V3Graph* execMTaskGraphp) { static void finalizeCosts(V3Graph* execMTaskGraphp) {
GraphStreamUnordered ser(execMTaskGraphp, GraphWay::REVERSE); GraphStreamUnordered ser(execMTaskGraphp, GraphWay::REVERSE);
while (const V3GraphVertex* vxp = ser.nextp()) { while (const V3GraphVertex* const vxp = ser.nextp()) {
ExecMTask* const mtp = dynamic_cast<ExecMTask*>(const_cast<V3GraphVertex*>(vxp)); ExecMTask* const mtp = dynamic_cast<ExecMTask*>(const_cast<V3GraphVertex*>(vxp));
// "Priority" is the critical path from the start of the mtask, to // "Priority" is the critical path from the start of the mtask, to
// the end of the graph reachable from this mtask. Given the // the end of the graph reachable from this mtask. Given the
@ -2834,7 +2835,7 @@ static void finalizeCosts(V3Graph* execMTaskGraphp) {
// highest priority one first, so we're always working on the "long // highest priority one first, so we're always working on the "long
// pole" // pole"
for (V3GraphEdge* edgep = mtp->outBeginp(); edgep; edgep = edgep->outNextp()) { for (V3GraphEdge* edgep = mtp->outBeginp(); edgep; edgep = edgep->outNextp()) {
ExecMTask* const followp = dynamic_cast<ExecMTask*>(edgep->top()); const ExecMTask* const followp = dynamic_cast<ExecMTask*>(edgep->top());
if ((followp->priority() + mtp->cost()) > mtp->priority()) { if ((followp->priority() + mtp->cost()) > mtp->priority()) {
mtp->priority(followp->priority() + mtp->cost()); mtp->priority(followp->priority() + mtp->cost());
} }

View File

@ -47,9 +47,9 @@ class VDefine final {
// Define class. One for each define. // Define class. One for each define.
// string m_name; // Name of the define (list is keyed by this) // string m_name; // Name of the define (list is keyed by this)
FileLine* const m_fileline; // Where it was declared FileLine* const m_fileline; // Where it was declared
string m_value; // Value of define const string m_value; // Value of define
string m_params; // Parameters const string m_params; // Parameters
bool m_cmdline; // Set on command line, don't `undefineall const bool m_cmdline; // Set on command line, don't `undefineall
public: public:
VDefine(FileLine* fl, const string& value, const string& params, bool cmdline) VDefine(FileLine* fl, const string& value, const string& params, bool cmdline)
: m_fileline{fl} : m_fileline{fl}
@ -66,8 +66,8 @@ public:
class VDefineRef final { class VDefineRef final {
// One for each pending define substitution // One for each pending define substitution
string m_name; // Define last name being defined const string m_name; // Define last name being defined
string m_params; // Define parameter list for next expansion const string m_params; // Define parameter list for next expansion
string m_nextarg; // String being built for next argument string m_nextarg; // String being built for next argument
int m_parenLevel = 0; // Parenthesis counting inside def args (for PARENT not child) int m_parenLevel = 0; // Parenthesis counting inside def args (for PARENT not child)
@ -91,8 +91,8 @@ public:
class VPreIfEntry final { class VPreIfEntry final {
// One for each pending ifdef/ifndef // One for each pending ifdef/ifndef
bool m_on; // Current parse for this ifdef level is "on" const bool m_on; // Current parse for this ifdef level is "on"
bool m_everOn; // Some if term in elsif tree has been on const bool m_everOn; // Some if term in elsif tree has been on
public: public:
bool on() const { return m_on; } bool on() const { return m_on; }
bool everOn() const { return m_everOn; } bool everOn() const { return m_everOn; }
@ -117,7 +117,7 @@ public:
DefinesMap m_defines; ///< Map of defines DefinesMap m_defines; ///< Map of defines
// STATE // STATE
V3PreProc* m_preprocp = nullptr; ///< Object we're holding data for const V3PreProc* m_preprocp = nullptr; ///< Object we're holding data for
V3PreLex* m_lexp = nullptr; ///< Current lexer state (nullptr = closed) V3PreLex* m_lexp = nullptr; ///< Current lexer state (nullptr = closed)
std::stack<V3PreLex*> m_includeStack; ///< Stack of includers above current m_lexp std::stack<V3PreLex*> m_includeStack; ///< Stack of includers above current m_lexp
int m_lastLineno = 0; // Last line number (stall detection) int m_lastLineno = 0; // Last line number (stall detection)
@ -496,7 +496,7 @@ void V3PreProc::debug(int level) {
} }
FileLine* V3PreProc::fileline() { FileLine* V3PreProc::fileline() {
V3PreProcImp* idatap = static_cast<V3PreProcImp*>(this); const V3PreProcImp* idatap = static_cast<V3PreProcImp*>(this);
return idatap->m_lexp->m_tokFilelinep; return idatap->m_lexp->m_tokFilelinep;
} }
@ -1180,7 +1180,7 @@ int V3PreProcImp::getStateToken() {
if (VL_UNCOVERABLE(m_defRefs.empty())) { if (VL_UNCOVERABLE(m_defRefs.empty())) {
fatalSrc("Shouldn't be in DEFPAREN w/o active defref"); fatalSrc("Shouldn't be in DEFPAREN w/o active defref");
} }
VDefineRef* const refp = &(m_defRefs.top()); const VDefineRef* const refp = &(m_defRefs.top());
error(string("Expecting ( to begin argument list for define reference `") error(string("Expecting ( to begin argument list for define reference `")
+ refp->name() + "\n"); + refp->name() + "\n");
statePop(); statePop();
@ -1612,7 +1612,7 @@ string V3PreProcImp::getline() {
// Make new string with data up to the newline. // Make new string with data up to the newline.
const int len = rtnp - m_lineChars.c_str() + 1; const int len = rtnp - m_lineChars.c_str() + 1;
string theLine(m_lineChars, 0, len); const string theLine(m_lineChars, 0, len);
m_lineChars = m_lineChars.erase(0, len); // Remove returned characters m_lineChars = m_lineChars.erase(0, len); // Remove returned characters
if (debug() >= 4) { if (debug() >= 4) {
const string lncln = V3PreLex::cleanDbgStrg(theLine); const string lncln = V3PreLex::cleanDbgStrg(theLine);

View File

@ -266,7 +266,7 @@ private:
// Shifts of > 32/64 bits in C++ will wrap-around and generate non-0s // Shifts of > 32/64 bits in C++ will wrap-around and generate non-0s
if (!nodep->user2SetOnce()) { if (!nodep->user2SetOnce()) {
UINFO(4, " ShiftFix " << nodep << endl); UINFO(4, " ShiftFix " << nodep << endl);
const AstConst* shiftp = VN_CAST(nodep->rhsp(), Const); const AstConst* const shiftp = VN_CAST(nodep->rhsp(), Const);
if (shiftp && shiftp->num().mostSetBitP1() > 32) { if (shiftp && shiftp->num().mostSetBitP1() > 32) {
shiftp->v3error( shiftp->v3error(
"Unsupported: Shifting of by over 32-bit number isn't supported." "Unsupported: Shifting of by over 32-bit number isn't supported."
@ -279,7 +279,7 @@ private:
AstNRelinker replaceHandle; AstNRelinker replaceHandle;
nodep->unlinkFrBack(&replaceHandle); nodep->unlinkFrBack(&replaceHandle);
AstNode* constzerop; AstNode* constzerop;
int m1value const int m1value
= nodep->widthMin() - 1; // Constant of width-1; not changing dtype width = nodep->widthMin() - 1; // Constant of width-1; not changing dtype width
if (nodep->signedFlavor()) { if (nodep->signedFlavor()) {
// Then over shifting gives the sign bit, not all zeros // Then over shifting gives the sign bit, not all zeros
@ -295,10 +295,11 @@ private:
} }
constzerop->dtypeFrom(nodep); // unsigned constzerop->dtypeFrom(nodep); // unsigned
AstNode* constwidthp = new AstConst(nodep->fileline(), AstConst::WidthedValue(), AstNode* const constwidthp
nodep->rhsp()->widthMin(), m1value); = new AstConst(nodep->fileline(), AstConst::WidthedValue(),
nodep->rhsp()->widthMin(), m1value);
constwidthp->dtypeFrom(nodep->rhsp()); // unsigned constwidthp->dtypeFrom(nodep->rhsp()); // unsigned
AstCond* newp = new AstCond( AstCond* const newp = new AstCond(
nodep->fileline(), nodep->fileline(),
new AstGte(nodep->fileline(), constwidthp, nodep->rhsp()->cloneTree(false)), new AstGte(nodep->fileline(), constwidthp, nodep->rhsp()->cloneTree(false)),
nodep, constzerop); nodep, constzerop);
@ -381,7 +382,7 @@ private:
iterateChildren(nodep); iterateChildren(nodep);
m_stmtp = nullptr; m_stmtp = nullptr;
if (v3Global.opt.autoflush()) { if (v3Global.opt.autoflush()) {
AstNode* searchp = nodep->nextp(); const AstNode* searchp = nodep->nextp();
while (searchp && VN_IS(searchp, Comment)) searchp = searchp->nextp(); while (searchp && VN_IS(searchp, Comment)) searchp = searchp->nextp();
if (searchp && VN_IS(searchp, Display) if (searchp && VN_IS(searchp, Display)
&& nodep->filep()->sameGateTree(VN_AS(searchp, Display)->filep())) { && nodep->filep()->sameGateTree(VN_AS(searchp, Display)->filep())) {

View File

@ -87,7 +87,7 @@ private:
iterateChildren(nodep); iterateChildren(nodep);
V3Hash hash = V3Hasher::uncachedHash(m_cfilep); const V3Hash hash = V3Hasher::uncachedHash(m_cfilep);
m_hashValuep->addText(fl, cvtToStr(hash.value()) + ";\n"); m_hashValuep->addText(fl, cvtToStr(hash.value()) + ";\n");
m_cHashValuep->addText(fl, cvtToStr(hash.value()) + "U;\n"); m_cHashValuep->addText(fl, cvtToStr(hash.value()) + "U;\n");
m_foundTop = true; m_foundTop = true;

View File

@ -217,7 +217,7 @@ private:
= new AstVarRef(nodep->fileline(), memberVarp, VAccess::WRITE); = new AstVarRef(nodep->fileline(), memberVarp, VAccess::WRITE);
auto* const stmtp = newRandStmtsp(nodep->fileline(), refp); auto* const stmtp = newRandStmtsp(nodep->fileline(), refp);
funcp->addStmtsp(stmtp); funcp->addStmtsp(stmtp);
} else if (auto* classRefp = VN_CAST(dtypep, ClassRefDType)) { } else if (const auto* const classRefp = VN_CAST(dtypep, ClassRefDType)) {
auto* const refp auto* const refp
= new AstVarRef(nodep->fileline(), memberVarp, VAccess::WRITE); = new AstVarRef(nodep->fileline(), memberVarp, VAccess::WRITE);
auto* const memberFuncp = V3Randomize::newRandomizeFunc(classRefp->classp()); auto* const memberFuncp = V3Randomize::newRandomizeFunc(classRefp->classp());
@ -253,7 +253,7 @@ public:
void V3Randomize::randomizeNetlist(AstNetlist* nodep) { void V3Randomize::randomizeNetlist(AstNetlist* nodep) {
UINFO(2, __FUNCTION__ << ": " << endl); UINFO(2, __FUNCTION__ << ": " << endl);
{ {
RandomizeMarkVisitor markVisitor{nodep}; const RandomizeMarkVisitor markVisitor{nodep};
RandomizeVisitor{nodep}; RandomizeVisitor{nodep};
} }
V3Global::dumpCheckGlobalTree("randomize", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3); V3Global::dumpCheckGlobalTree("randomize", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);

View File

@ -54,13 +54,13 @@ private:
std::vector<AstNodeAssign*> m_mgAssignps; // List of assignments merging std::vector<AstNodeAssign*> m_mgAssignps; // List of assignments merging
AstCFunc* m_mgCfuncp = nullptr; // Parent C function AstCFunc* m_mgCfuncp = nullptr; // Parent C function
AstNode* m_mgNextp = nullptr; // Next node const AstNode* m_mgNextp = nullptr; // Next node
AstNodeSel* m_mgSelLp = nullptr; // Parent select, nullptr = idle const AstNodeSel* m_mgSelLp = nullptr; // Parent select, nullptr = idle
AstNodeSel* m_mgSelRp = nullptr; // Parent select, nullptr = constant const AstNodeSel* m_mgSelRp = nullptr; // Parent select, nullptr = constant
AstNodeVarRef* m_mgVarrefLp = nullptr; // Parent varref const AstNodeVarRef* m_mgVarrefLp = nullptr; // Parent varref
AstNodeVarRef* m_mgVarrefRp = nullptr; // Parent varref, nullptr = constant const AstNodeVarRef* m_mgVarrefRp = nullptr; // Parent varref, nullptr = constant
int64_t m_mgOffset = 0; // Index offset int64_t m_mgOffset = 0; // Index offset
AstConst* m_mgConstRp = nullptr; // Parent RHS constant, nullptr = sel const AstConst* m_mgConstRp = nullptr; // Parent RHS constant, nullptr = sel
uint32_t m_mgIndexLo = 0; // Merge range uint32_t m_mgIndexLo = 0; // Merge range
uint32_t m_mgIndexHi = 0; // Merge range uint32_t m_mgIndexHi = 0; // Merge range
@ -80,7 +80,7 @@ private:
} }
void mergeEnd() { void mergeEnd() {
if (!m_mgAssignps.empty()) { if (!m_mgAssignps.empty()) {
uint32_t items = m_mgIndexHi - m_mgIndexLo + 1; const uint32_t items = m_mgIndexHi - m_mgIndexLo + 1;
UINFO(9, "End merge iter=" << items << " " << m_mgIndexHi << ":" << m_mgIndexLo << " " UINFO(9, "End merge iter=" << items << " " << m_mgIndexHi << ":" << m_mgIndexLo << " "
<< m_mgOffset << " " << m_mgAssignps[0] << endl); << m_mgOffset << " " << m_mgAssignps[0] << endl);
if (items >= static_cast<uint32_t>(v3Global.opt.reloopLimit())) { if (items >= static_cast<uint32_t>(v3Global.opt.reloopLimit())) {
@ -162,7 +162,7 @@ private:
if (!m_cfuncp) return; if (!m_cfuncp) return;
// Left select WordSel or ArraySel // Left select WordSel or ArraySel
AstNodeSel* lselp = VN_CAST(nodep->lhsp(), NodeSel); AstNodeSel* const lselp = VN_CAST(nodep->lhsp(), NodeSel);
if (!lselp) { // Not ever merged if (!lselp) { // Not ever merged
mergeEnd(); mergeEnd();
return; return;
@ -179,16 +179,16 @@ private:
} }
const uint32_t lindex = lbitp->toUInt(); const uint32_t lindex = lbitp->toUInt();
// Of variable // Of variable
AstNodeVarRef* const lvarrefp = VN_CAST(lselp->fromp(), NodeVarRef); const AstNodeVarRef* const lvarrefp = VN_CAST(lselp->fromp(), NodeVarRef);
if (!lvarrefp) { if (!lvarrefp) {
mergeEnd(); mergeEnd();
return; return;
} }
// RHS is a constant or a select // RHS is a constant or a select
AstConst* const rconstp = VN_CAST(nodep->rhsp(), Const); const AstConst* const rconstp = VN_CAST(nodep->rhsp(), Const);
AstNodeSel* const rselp = VN_CAST(nodep->rhsp(), NodeSel); const AstNodeSel* const rselp = VN_CAST(nodep->rhsp(), NodeSel);
AstNodeVarRef* rvarrefp = nullptr; const AstNodeVarRef* rvarrefp = nullptr;
uint32_t rindex = lindex; uint32_t rindex = lindex;
if (rconstp) { // Ok if (rconstp) { // Ok
} else if (rselp) { } else if (rselp) {

View File

@ -401,7 +401,7 @@ public:
void V3Scope::scopeAll(AstNetlist* nodep) { void V3Scope::scopeAll(AstNetlist* nodep) {
UINFO(2, __FUNCTION__ << ": " << endl); UINFO(2, __FUNCTION__ << ": " << endl);
{ {
ScopeVisitor visitor{nodep}; const ScopeVisitor visitor{nodep};
ScopeCleanupVisitor{nodep}; ScopeCleanupVisitor{nodep};
} // Destruct before checking } // Destruct before checking
V3Global::dumpCheckGlobalTree("scope", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3); V3Global::dumpCheckGlobalTree("scope", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);

View File

@ -355,7 +355,7 @@ private:
class CmpElems final { class CmpElems final {
public: public:
bool operator()(const T_Elem* const& ap, const T_Elem* const& bp) const { bool operator()(const T_Elem* const& ap, const T_Elem* const& bp) const {
T_ElemCompare cmp; const T_ElemCompare cmp;
return cmp.operator()(*ap, *bp); return cmp.operator()(*ap, *bp);
} }
}; };
@ -369,8 +369,8 @@ private:
// set members, set is better performant. // set members, set is better performant.
std::set<const T_Elem*> m_unknown; // Elements with unknown scores std::set<const T_Elem*> m_unknown; // Elements with unknown scores
SortedMap m_sorted; // Set of elements with known scores SortedMap m_sorted; // Set of elements with known scores
UserScoreFnp m_scoreFnp; // Scoring function const UserScoreFnp m_scoreFnp; // Scoring function
bool m_slowAsserts; // Do some asserts that require extra lookups const bool m_slowAsserts; // Do some asserts that require extra lookups
public: public:
// CONSTRUCTORS // CONSTRUCTORS

View File

@ -115,10 +115,10 @@ private:
// Potentially very slow, intended for debugging // Potentially very slow, intended for debugging
string prettyNumber(const V3Number* nump, AstNodeDType* dtypep) { string prettyNumber(const V3Number* nump, AstNodeDType* dtypep) {
if (AstRefDType* refdtypep = VN_CAST(dtypep, RefDType)) { // if (AstRefDType* const refdtypep = VN_CAST(dtypep, RefDType)) { //
dtypep = refdtypep->skipRefp(); dtypep = refdtypep->skipRefp();
} }
if (AstStructDType* stp = VN_CAST(dtypep, StructDType)) { if (AstStructDType* const stp = VN_CAST(dtypep, StructDType)) {
if (stp->packed()) { if (stp->packed()) {
std::ostringstream out; std::ostringstream out;
out << "'{"; out << "'{";
@ -130,7 +130,7 @@ private:
V3Number fieldNum(nump, width); V3Number fieldNum(nump, width);
fieldNum.opSel(*nump, msb, lsb); fieldNum.opSel(*nump, msb, lsb);
out << itemp->name() << ": "; out << itemp->name() << ": ";
if (AstNodeDType* childTypep = itemp->subDTypep()) { if (AstNodeDType* const childTypep = itemp->subDTypep()) {
out << prettyNumber(&fieldNum, childTypep); out << prettyNumber(&fieldNum, childTypep);
} else { } else {
out << fieldNum; out << fieldNum;
@ -140,8 +140,8 @@ private:
out << "}"; out << "}";
return out.str(); return out.str();
} }
} else if (AstPackArrayDType* arrayp = VN_CAST(dtypep, PackArrayDType)) { } else if (const AstPackArrayDType* const arrayp = VN_CAST(dtypep, PackArrayDType)) {
if (AstNodeDType* childTypep = arrayp->subDTypep()) { if (AstNodeDType* const childTypep = arrayp->subDTypep()) {
std::ostringstream out; std::ostringstream out;
out << "["; out << "[";
const int arrayElements = arrayp->elementsConst(); const int arrayElements = arrayp->elementsConst();
@ -180,16 +180,16 @@ public:
m_whyNotOptimizable = why; m_whyNotOptimizable = why;
std::ostringstream stack; std::ostringstream stack;
for (auto it = m_callStack.rbegin(); it != m_callStack.rend(); ++it) { for (auto it = m_callStack.rbegin(); it != m_callStack.rend(); ++it) {
AstFuncRef* funcp = (*it)->m_funcp; AstFuncRef* const funcp = (*it)->m_funcp;
stack << "\n " << funcp->fileline() << "... Called from " stack << "\n " << funcp->fileline() << "... Called from "
<< funcp->prettyName() << "() with parameters:"; << funcp->prettyName() << "() with parameters:";
V3TaskConnects* tconnects = (*it)->m_tconnects; V3TaskConnects* tconnects = (*it)->m_tconnects;
for (V3TaskConnects::iterator conIt = tconnects->begin(); for (V3TaskConnects::iterator conIt = tconnects->begin();
conIt != tconnects->end(); ++conIt) { conIt != tconnects->end(); ++conIt) {
AstVar* portp = conIt->first; AstVar* const portp = conIt->first;
AstNode* pinp = conIt->second->exprp(); AstNode* const pinp = conIt->second->exprp();
AstNodeDType* dtypep = pinp->dtypep(); AstNodeDType* const dtypep = pinp->dtypep();
if (AstConst* valp = fetchConstNull(pinp)) if (AstConst* const valp = fetchConstNull(pinp))
stack << "\n " << portp->prettyName() << " = " stack << "\n " << portp->prettyName() << " = "
<< prettyNumber(&valp->num(), dtypep); << prettyNumber(&valp->num(), dtypep);
} }
@ -245,7 +245,7 @@ private:
public: public:
void newValue(AstNode* nodep, const AstNode* valuep) { void newValue(AstNode* nodep, const AstNode* valuep) {
if (const AstConst* constp = VN_CAST(valuep, Const)) { if (const AstConst* const constp = VN_CAST(valuep, Const)) {
newConst(nodep)->num().opAssign(constp->num()); newConst(nodep)->num().opAssign(constp->num());
} else if (fetchValueNull(nodep) != valuep) { } else if (fetchValueNull(nodep) != valuep) {
// const_cast, as clonep() is set on valuep, but nothing should care // const_cast, as clonep() is set on valuep, but nothing should care
@ -253,7 +253,7 @@ public:
} }
} }
void newOutValue(AstNode* nodep, const AstNode* valuep) { void newOutValue(AstNode* nodep, const AstNode* valuep) {
if (const AstConst* constp = VN_CAST(valuep, Const)) { if (const AstConst* const constp = VN_CAST(valuep, Const)) {
newOutConst(nodep)->num().opAssign(constp->num()); newOutConst(nodep)->num().opAssign(constp->num());
} else if (fetchOutValueNull(nodep) != valuep) { } else if (fetchOutValueNull(nodep) != valuep) {
// const_cast, as clonep() is set on valuep, but nothing should care // const_cast, as clonep() is set on valuep, but nothing should care
@ -263,14 +263,14 @@ public:
private: private:
AstNode* newTrackedClone(AstNode* nodep) { AstNode* newTrackedClone(AstNode* nodep) {
AstNode* newp = nodep->cloneTree(false); AstNode* const newp = nodep->cloneTree(false);
m_reclaimValuesp.push_back(newp); m_reclaimValuesp.push_back(newp);
return newp; return newp;
} }
AstConst* newConst(AstNode* nodep) { AstConst* newConst(AstNode* nodep) {
// Set a constant value for this node // Set a constant value for this node
if (!VN_IS(nodep->user3p(), Const)) { if (!VN_IS(nodep->user3p(), Const)) {
AstConst* constp = allocConst(nodep); AstConst* const constp = allocConst(nodep);
setValue(nodep, constp); setValue(nodep, constp);
return constp; return constp;
} else { } else {
@ -280,7 +280,7 @@ private:
AstConst* newOutConst(AstNode* nodep) { AstConst* newOutConst(AstNode* nodep) {
// Set a var-output constant value for this node // Set a var-output constant value for this node
if (!VN_IS(nodep->user2p(), Const)) { if (!VN_IS(nodep->user2p(), Const)) {
AstConst* constp = allocConst(nodep); AstConst* const constp = allocConst(nodep);
setOutValue(nodep, constp); setOutValue(nodep, constp);
return constp; return constp;
} else { } else {
@ -298,31 +298,31 @@ private:
return VN_CAST(fetchOutValueNull(nodep), Const); return VN_CAST(fetchOutValueNull(nodep), Const);
} }
AstNode* fetchValue(AstNode* nodep) { AstNode* fetchValue(AstNode* nodep) {
AstNode* valuep = fetchValueNull(nodep); AstNode* const valuep = fetchValueNull(nodep);
UASSERT_OBJ(valuep, nodep, "No value found for node."); UASSERT_OBJ(valuep, nodep, "No value found for node.");
// UINFO(9, " fetch val " << *valuep << " on " << nodep << endl); // UINFO(9, " fetch val " << *valuep << " on " << nodep << endl);
return valuep; return valuep;
} }
AstConst* fetchConst(AstNode* nodep) { AstConst* fetchConst(AstNode* nodep) {
AstConst* constp = fetchConstNull(nodep); AstConst* const constp = fetchConstNull(nodep);
UASSERT_OBJ(constp, nodep, "No value found for node."); UASSERT_OBJ(constp, nodep, "No value found for node.");
// UINFO(9, " fetch num " << *constp << " on " << nodep << endl); // UINFO(9, " fetch num " << *constp << " on " << nodep << endl);
return constp; return constp;
} }
AstConst* fetchOutConst(AstNode* nodep) { AstConst* fetchOutConst(AstNode* nodep) {
AstConst* constp = fetchOutConstNull(nodep); AstConst* const constp = fetchOutConstNull(nodep);
UASSERT_OBJ(constp, nodep, "No value found for node."); UASSERT_OBJ(constp, nodep, "No value found for node.");
return constp; return constp;
} }
public: public:
V3Number* fetchNumberNull(AstNode* nodep) { V3Number* fetchNumberNull(AstNode* nodep) {
AstConst* constp = fetchConstNull(nodep); AstConst* const constp = fetchConstNull(nodep);
if (constp) return &constp->num(); if (constp) return &constp->num();
return nullptr; return nullptr;
} }
V3Number* fetchOutNumberNull(AstNode* nodep) { V3Number* fetchOutNumberNull(AstNode* nodep) {
AstConst* constp = fetchOutConstNull(nodep); AstConst* const constp = fetchOutConstNull(nodep);
if (constp) return &constp->num(); if (constp) return &constp->num();
return nullptr; return nullptr;
} }
@ -405,7 +405,7 @@ private:
if (!optimizable()) return; // Accelerate if (!optimizable()) return; // Accelerate
UASSERT_OBJ(nodep->varp(), nodep, "Unlinked"); UASSERT_OBJ(nodep->varp(), nodep, "Unlinked");
iterateChildren(nodep->varp()); iterateChildren(nodep->varp());
AstNode* vscp = varOrScope(nodep); AstNode* const vscp = varOrScope(nodep);
// We can't have non-delayed assignments with same value on LHS and RHS // We can't have non-delayed assignments with same value on LHS and RHS
// as we don't figure out variable ordering. // as we don't figure out variable ordering.
@ -438,7 +438,8 @@ private:
} }
vscp->user1(vscp->user1() | VU_RV); vscp->user1(vscp->user1() | VU_RV);
const bool isConst = nodep->varp()->isParam() && nodep->varp()->valuep(); const bool isConst = nodep->varp()->isParam() && nodep->varp()->valuep();
AstNode* valuep = isConst ? fetchValueNull(nodep->varp()->valuep()) : nullptr; AstNode* const valuep
= isConst ? fetchValueNull(nodep->varp()->valuep()) : nullptr;
if (isConst if (isConst
&& valuep) { // Propagate PARAM constants for constant function analysis && valuep) { // Propagate PARAM constants for constant function analysis
if (!m_checkOnly && optimizable()) newValue(vscp, valuep); if (!m_checkOnly && optimizable()) newValue(vscp, valuep);
@ -526,7 +527,7 @@ private:
checkNodeInfo(nodep); checkNodeInfo(nodep);
UASSERT_OBJ(nodep->itemp(), nodep, "Not linked"); UASSERT_OBJ(nodep->itemp(), nodep, "Not linked");
if (!m_checkOnly && optimizable()) { if (!m_checkOnly && optimizable()) {
AstNode* valuep = nodep->itemp()->valuep(); AstNode* const valuep = nodep->itemp()->valuep();
if (valuep) { if (valuep) {
iterateAndNextNull(valuep); iterateAndNextNull(valuep);
if (optimizable()) newValue(nodep, fetchValue(valuep)); if (optimizable()) newValue(nodep, fetchValue(valuep));
@ -619,7 +620,8 @@ private:
iterate(nodep->lhsp()); iterate(nodep->lhsp());
if (optimizable()) { if (optimizable()) {
if (fetchConst(nodep->lhsp())->num().isEqZero()) { if (fetchConst(nodep->lhsp())->num().isEqZero()) {
AstConst cnst(nodep->fileline(), AstConst::WidthedValue(), 1, 1); // a one const AstConst cnst(nodep->fileline(), AstConst::WidthedValue(), 1,
1); // a one
newValue(nodep, &cnst); // a one newValue(nodep, &cnst); // a one
} else { } else {
iterate(nodep->rhsp()); iterate(nodep->rhsp());
@ -656,29 +658,30 @@ private:
// To do better, we need the concept of lvalues, or similar, to know where/how to insert // To do better, we need the concept of lvalues, or similar, to know where/how to insert
checkNodeInfo(selp); checkNodeInfo(selp);
iterateAndNextNull(selp->bitp()); // Bit index iterateAndNextNull(selp->bitp()); // Bit index
AstVarRef* varrefp = VN_CAST(selp->fromp(), VarRef); AstVarRef* const varrefp = VN_CAST(selp->fromp(), VarRef);
if (!varrefp) { if (!varrefp) {
clearOptimizable(nodep, "Array select LHS isn't simple variable"); clearOptimizable(nodep, "Array select LHS isn't simple variable");
return; return;
} }
AstUnpackArrayDType* arrayp = VN_AS(varrefp->varp()->dtypeSkipRefp(), UnpackArrayDType); AstUnpackArrayDType* const arrayp
= VN_AS(varrefp->varp()->dtypeSkipRefp(), UnpackArrayDType);
UASSERT_OBJ(arrayp, nodep, "Array select of non-array dtype"); UASSERT_OBJ(arrayp, nodep, "Array select of non-array dtype");
AstBasicDType* basicp = VN_CAST(arrayp->subDTypep()->skipRefp(), BasicDType); AstBasicDType* const basicp = VN_CAST(arrayp->subDTypep()->skipRefp(), BasicDType);
if (!basicp) { if (!basicp) {
clearOptimizable(nodep, "Array of non-basic dtype (e.g. array-of-array)"); clearOptimizable(nodep, "Array of non-basic dtype (e.g. array-of-array)");
return; return;
} }
if (!m_checkOnly && optimizable()) { if (!m_checkOnly && optimizable()) {
AstNode* vscp = varOrScope(varrefp); AstNode* const vscp = varOrScope(varrefp);
AstInitArray* initp = nullptr; AstInitArray* initp = nullptr;
if (AstInitArray* vscpnump = VN_CAST(fetchOutValueNull(vscp), InitArray)) { if (AstInitArray* const vscpnump = VN_CAST(fetchOutValueNull(vscp), InitArray)) {
initp = vscpnump; initp = vscpnump;
} else if (AstInitArray* vscpnump = VN_CAST(fetchValueNull(vscp), InitArray)) { } else if (AstInitArray* const vscpnump = VN_CAST(fetchValueNull(vscp), InitArray)) {
initp = vscpnump; initp = vscpnump;
} else { // Assignment to unassigned variable, all bits are X } else { // Assignment to unassigned variable, all bits are X
// TODO generic initialization which builds X/arrays by recursion // TODO generic initialization which builds X/arrays by recursion
AstConst* outconstp = new AstConst(nodep->fileline(), AstConst::WidthedValue(), AstConst* const outconstp = new AstConst(
basicp->widthMin(), 0); nodep->fileline(), AstConst::WidthedValue(), basicp->widthMin(), 0);
if (basicp->isZeroInit()) { if (basicp->isZeroInit()) {
outconstp->num().setAllBits0(); outconstp->num().setAllBits0();
} else { } else {
@ -688,8 +691,8 @@ private:
initp = new AstInitArray(nodep->fileline(), arrayp, outconstp); initp = new AstInitArray(nodep->fileline(), arrayp, outconstp);
m_reclaimValuesp.push_back(initp); m_reclaimValuesp.push_back(initp);
} }
uint32_t index = fetchConst(selp->bitp())->toUInt(); const uint32_t index = fetchConst(selp->bitp())->toUInt();
AstNode* valuep = newTrackedClone(fetchValue(nodep->rhsp())); AstNode* const valuep = newTrackedClone(fetchValue(nodep->rhsp()));
UINFO(9, " set val[" << index << "] = " << valuep << endl); UINFO(9, " set val[" << index << "] = " << valuep << endl);
// Values are in the "real" tree under the InitArray so can eventually extract it, // Values are in the "real" tree under the InitArray so can eventually extract it,
// Not in the usual setValue (pointed to by user2/3p) // Not in the usual setValue (pointed to by user2/3p)
@ -706,11 +709,11 @@ private:
if (!m_checkOnly && optimizable()) { if (!m_checkOnly && optimizable()) {
UASSERT_OBJ(varrefp, nodep, UASSERT_OBJ(varrefp, nodep,
"Indicated optimizable, but no variable found on RHS of select"); "Indicated optimizable, but no variable found on RHS of select");
AstNode* vscp = varOrScope(varrefp); AstNode* const vscp = varOrScope(varrefp);
AstConst* outconstp = nullptr; AstConst* outconstp = nullptr;
if (AstConst* vscpnump = fetchOutConstNull(vscp)) { if (AstConst* const vscpnump = fetchOutConstNull(vscp)) {
outconstp = vscpnump; outconstp = vscpnump;
} else if (AstConst* vscpnump = fetchConstNull(vscp)) { } else if (AstConst* const vscpnump = fetchConstNull(vscp)) {
outconstp = vscpnump; outconstp = vscpnump;
} else { // Assignment to unassigned variable, all bits are X or 0 } else { // Assignment to unassigned variable, all bits are X or 0
outconstp = new AstConst(nodep->fileline(), AstConst::WidthedValue(), outconstp = new AstConst(nodep->fileline(), AstConst::WidthedValue(),
@ -731,11 +734,11 @@ private:
// lsb to be eventually set on lsbRef // lsb to be eventually set on lsbRef
checkNodeInfo(selp); checkNodeInfo(selp);
iterateAndNextNull(selp->lsbp()); // Bit index iterateAndNextNull(selp->lsbp()); // Bit index
if (AstVarRef* varrefp = VN_CAST(selp->fromp(), VarRef)) { if (AstVarRef* const varrefp = VN_CAST(selp->fromp(), VarRef)) {
outVarrefpRef = varrefp; outVarrefpRef = varrefp;
lsbRef = fetchConst(selp->lsbp())->num(); lsbRef = fetchConst(selp->lsbp())->num();
return; // And presumably still optimizable() return; // And presumably still optimizable()
} else if (AstSel* subselp = VN_CAST(selp->lhsp(), Sel)) { } else if (AstSel* const subselp = VN_CAST(selp->lhsp(), Sel)) {
V3Number sublsb(nodep); V3Number sublsb(nodep);
handleAssignSelRecurse(nodep, subselp, outVarrefpRef, sublsb /*ref*/, depth + 1); handleAssignSelRecurse(nodep, subselp, outVarrefpRef, sublsb /*ref*/, depth + 1);
if (optimizable()) { if (optimizable()) {
@ -759,13 +762,13 @@ private:
m_anyAssignComb = true; m_anyAssignComb = true;
} }
if (AstSel* selp = VN_CAST(nodep->lhsp(), Sel)) { if (AstSel* const selp = VN_CAST(nodep->lhsp(), Sel)) {
if (!m_params) { if (!m_params) {
clearOptimizable(nodep, "LHS has select"); clearOptimizable(nodep, "LHS has select");
return; return;
} }
handleAssignSel(nodep, selp); handleAssignSel(nodep, selp);
} else if (AstArraySel* selp = VN_CAST(nodep->lhsp(), ArraySel)) { } else if (AstArraySel* const selp = VN_CAST(nodep->lhsp(), ArraySel)) {
if (!m_params) { if (!m_params) {
clearOptimizable(nodep, "LHS has select"); clearOptimizable(nodep, "LHS has select");
return; return;
@ -778,7 +781,7 @@ private:
} else if (optimizable()) { } else if (optimizable()) {
iterateAndNextNull(nodep->rhsp()); iterateAndNextNull(nodep->rhsp());
if (optimizable()) { if (optimizable()) {
AstNode* vscp = varOrScope(VN_CAST(nodep->lhsp(), VarRef)); AstNode* const vscp = varOrScope(VN_CAST(nodep->lhsp(), VarRef));
assignOutValue(nodep, vscp, fetchValue(nodep->rhsp())); assignOutValue(nodep, vscp, fetchValue(nodep->rhsp()));
} }
} }
@ -787,10 +790,10 @@ private:
virtual void visit(AstArraySel* nodep) override { virtual void visit(AstArraySel* nodep) override {
checkNodeInfo(nodep); checkNodeInfo(nodep);
iterateChildren(nodep); iterateChildren(nodep);
if (AstInitArray* initp = VN_CAST(fetchValueNull(nodep->fromp()), InitArray)) { if (AstInitArray* const initp = VN_CAST(fetchValueNull(nodep->fromp()), InitArray)) {
AstConst* indexp = fetchConst(nodep->bitp()); AstConst* const indexp = fetchConst(nodep->bitp());
uint32_t offset = indexp->num().toUInt(); const uint32_t offset = indexp->num().toUInt();
AstNode* itemp = initp->getIndexDefaultedValuep(offset); AstNode* const itemp = initp->getIndexDefaultedValuep(offset);
if (!itemp) { if (!itemp) {
clearOptimizable(nodep, "Array initialization has too few elements, need element " clearOptimizable(nodep, "Array initialization has too few elements, need element "
+ cvtToStr(offset)); + cvtToStr(offset));
@ -977,8 +980,8 @@ private:
// Must do this in two steps, eval all params, then apply them // Must do this in two steps, eval all params, then apply them
// Otherwise chained functions may have the wrong results // Otherwise chained functions may have the wrong results
for (V3TaskConnects::iterator it = tconnects.begin(); it != tconnects.end(); ++it) { for (V3TaskConnects::iterator it = tconnects.begin(); it != tconnects.end(); ++it) {
AstVar* portp = it->first; AstVar* const portp = it->first;
AstNode* pinp = it->second->exprp(); AstNode* const pinp = it->second->exprp();
if (pinp) { // Else too few arguments in function call - ignore it if (pinp) { // Else too few arguments in function call - ignore it
if (portp->isWritable()) { if (portp->isWritable()) {
clearOptimizable( clearOptimizable(
@ -991,8 +994,8 @@ private:
} }
} }
for (V3TaskConnects::iterator it = tconnects.begin(); it != tconnects.end(); ++it) { for (V3TaskConnects::iterator it = tconnects.begin(); it != tconnects.end(); ++it) {
AstVar* portp = it->first; AstVar* const portp = it->first;
AstNode* pinp = it->second->exprp(); AstNode* const pinp = it->second->exprp();
if (pinp) { // Else too few arguments in function call - ignore it if (pinp) { // Else too few arguments in function call - ignore it
// Apply value to the function // Apply value to the function
if (!m_checkOnly && optimizable()) newValue(portp, fetchValue(pinp)); if (!m_checkOnly && optimizable()) newValue(portp, fetchValue(pinp));
@ -1002,7 +1005,7 @@ private:
// cppcheck-suppress danglingLifetime // cppcheck-suppress danglingLifetime
m_callStack.push_back(&stackNode); m_callStack.push_back(&stackNode);
// Clear output variable // Clear output variable
if (auto* const basicp = VN_CAST(funcp->fvarp(), Var)->basicp()) { if (const auto* const basicp = VN_CAST(funcp->fvarp(), Var)->basicp()) {
AstConst cnst(funcp->fvarp()->fileline(), AstConst::WidthedValue(), basicp->widthMin(), AstConst cnst(funcp->fvarp()->fileline(), AstConst::WidthedValue(), basicp->widthMin(),
0); 0);
if (basicp->isZeroInit()) { if (basicp->isZeroInit()) {
@ -1055,9 +1058,9 @@ private:
inPct = false; inPct = false;
if (V3Number::displayedFmtLegal(tolower(pos[0]), false)) { if (V3Number::displayedFmtLegal(tolower(pos[0]), false)) {
AstNode* argp = nextArgp; AstNode* const argp = nextArgp;
nextArgp = nextArgp->nextp(); nextArgp = nextArgp->nextp();
AstConst* constp = fetchConstNull(argp); AstConst* const constp = fetchConstNull(argp);
if (!constp) { if (!constp) {
clearOptimizable( clearOptimizable(
nodep, "Argument for $display like statement is not constant"); nodep, "Argument for $display like statement is not constant");
@ -1081,7 +1084,8 @@ private:
} }
} }
AstConst* resultConstp = new AstConst(nodep->fileline(), AstConst::String(), result); AstConst* const resultConstp
= new AstConst(nodep->fileline(), AstConst::String(), result);
setValue(nodep, resultConstp); setValue(nodep, resultConstp);
m_reclaimValuesp.push_back(resultConstp); m_reclaimValuesp.push_back(resultConstp);
} }
@ -1092,7 +1096,7 @@ private:
if (!optimizable()) return; // Accelerate if (!optimizable()) return; // Accelerate
iterateChildren(nodep); iterateChildren(nodep);
if (m_params) { if (m_params) {
AstConst* textp = fetchConst(nodep->fmtp()); AstConst* const textp = fetchConst(nodep->fmtp());
switch (nodep->displayType()) { switch (nodep->displayType()) {
case AstDisplayType::DT_DISPLAY: // FALLTHRU case AstDisplayType::DT_DISPLAY: // FALLTHRU
case AstDisplayType::DT_INFO: v3warn(USERINFO, textp->name()); break; case AstDisplayType::DT_INFO: v3warn(USERINFO, textp->name()); break;

View File

@ -97,12 +97,12 @@ class SliceVisitor final : public AstNVisitor {
itemp = initp->initsp(); itemp = initp->initsp();
} }
newp = itemp->cloneTree(false); newp = itemp->cloneTree(false);
} else if (AstNodeCond* snodep = VN_CAST(nodep, NodeCond)) { } else if (AstNodeCond* const snodep = VN_CAST(nodep, NodeCond)) {
UINFO(9, " cloneCond(" << elements << "," << offset << ") " << nodep << endl); UINFO(9, " cloneCond(" << elements << "," << offset << ") " << nodep << endl);
return snodep->cloneType(snodep->condp()->cloneTree(false), return snodep->cloneType(snodep->condp()->cloneTree(false),
cloneAndSel(snodep->expr1p(), elements, offset), cloneAndSel(snodep->expr1p(), elements, offset),
cloneAndSel(snodep->expr2p(), elements, offset)); cloneAndSel(snodep->expr2p(), elements, offset));
} else if (AstSliceSel* snodep = VN_CAST(nodep, SliceSel)) { } else if (const AstSliceSel* const snodep = VN_CAST(nodep, SliceSel)) {
UINFO(9, " cloneSliceSel(" << elements << "," << offset << ") " << nodep << endl); UINFO(9, " cloneSliceSel(" << elements << "," << offset << ") " << nodep << endl);
const int leOffset = (snodep->declRange().lo() const int leOffset = (snodep->declRange().lo()
+ (!snodep->declRange().littleEndian() + (!snodep->declRange().littleEndian()

View File

@ -322,7 +322,7 @@ protected:
vertexp = vertexp->verticesNextp()) { vertexp = vertexp->verticesNextp()) {
if (!vertexp->outBeginp() && dynamic_cast<SplitVarStdVertex*>(vertexp)) { if (!vertexp->outBeginp() && dynamic_cast<SplitVarStdVertex*>(vertexp)) {
if (debug() >= 9) { if (debug() >= 9) {
SplitVarStdVertex* const stdp = static_cast<SplitVarStdVertex*>(vertexp); const SplitVarStdVertex* const stdp = static_cast<SplitVarStdVertex*>(vertexp);
UINFO(0, "Will prune deps on var " << stdp->nodep() << endl); UINFO(0, "Will prune deps on var " << stdp->nodep() << endl);
stdp->nodep()->dumpTree(cout, "- "); stdp->nodep()->dumpTree(cout, "- ");
} }
@ -477,7 +477,8 @@ protected:
// vertexes not involved with this step as unimportant // vertexes not involved with this step as unimportant
for (V3GraphVertex* vertexp = m_graph.verticesBeginp(); vertexp; for (V3GraphVertex* vertexp = m_graph.verticesBeginp(); vertexp;
vertexp = vertexp->verticesNextp()) { vertexp = vertexp->verticesNextp()) {
if (SplitLogicVertex* const vvertexp = dynamic_cast<SplitLogicVertex*>(vertexp)) { if (const SplitLogicVertex* const vvertexp
= dynamic_cast<SplitLogicVertex*>(vertexp)) {
if (!vvertexp->user()) { if (!vvertexp->user()) {
for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep;
edgep = edgep->inNextp()) { edgep = edgep->inNextp()) {
@ -502,7 +503,7 @@ protected:
for (AstNode* nextp = nodep; nextp; nextp = nextp->nextp()) { for (AstNode* nextp = nodep; nextp; nextp = nextp->nextp()) {
SplitLogicVertex* const vvertexp SplitLogicVertex* const vvertexp
= reinterpret_cast<SplitLogicVertex*>(nextp->user3p()); = reinterpret_cast<SplitLogicVertex*>(nextp->user3p());
uint32_t color = vvertexp->color(); const uint32_t color = vvertexp->color();
UASSERT_OBJ(color, nextp, "No node color assigned"); UASSERT_OBJ(color, nextp, "No node color assigned");
if (lastOfColor[color]) { if (lastOfColor[color]) {
new SplitStrictEdge(&m_graph, lastOfColor[color], vvertexp); new SplitStrictEdge(&m_graph, lastOfColor[color], vvertexp);
@ -526,7 +527,7 @@ protected:
std::multimap<uint32_t, AstNode*> rankMap; std::multimap<uint32_t, AstNode*> rankMap;
int currOrder = 0; // Existing sequence number of assignment int currOrder = 0; // Existing sequence number of assignment
for (AstNode* nextp = nodep; nextp; nextp = nextp->nextp()) { for (AstNode* nextp = nodep; nextp; nextp = nextp->nextp()) {
SplitLogicVertex* const vvertexp const SplitLogicVertex* const vvertexp
= reinterpret_cast<SplitLogicVertex*>(nextp->user3p()); = reinterpret_cast<SplitLogicVertex*>(nextp->user3p());
rankMap.emplace(vvertexp->rank(), nextp); rankMap.emplace(vvertexp->rank(), nextp);
nextp->user4(++currOrder); // Record current ordering nextp->user4(++currOrder); // Record current ordering
@ -536,7 +537,7 @@ protected:
bool leaveAlone = true; bool leaveAlone = true;
int newOrder = 0; // New sequence number of assignment int newOrder = 0; // New sequence number of assignment
for (auto it = rankMap.cbegin(); it != rankMap.cend(); ++it) { for (auto it = rankMap.cbegin(); it != rankMap.cend(); ++it) {
AstNode* const nextp = it->second; const AstNode* const nextp = it->second;
if (++newOrder != nextp->user4()) leaveAlone = false; if (++newOrder != nextp->user4()) leaveAlone = false;
} }
if (leaveAlone) { if (leaveAlone) {
@ -650,8 +651,9 @@ public:
private: private:
void trackNode(AstNode* nodep) { void trackNode(AstNode* nodep) {
if (nodep->user3p()) { if (nodep->user3p()) {
SplitLogicVertex* const vertexp = reinterpret_cast<SplitLogicVertex*>(nodep->user3p()); const SplitLogicVertex* const vertexp
uint32_t color = vertexp->color(); = reinterpret_cast<SplitLogicVertex*>(nodep->user3p());
const uint32_t color = vertexp->color();
m_colors.insert(color); m_colors.insert(color);
UINFO(8, " SVL " << vertexp << " has color " << color << "\n"); UINFO(8, " SVL " << vertexp << " has color " << color << "\n");
@ -681,7 +683,7 @@ private:
class EmitSplitVisitor final : public AstNVisitor { class EmitSplitVisitor final : public AstNVisitor {
// MEMBERS // MEMBERS
AstAlways* const m_origAlwaysp; // Block that *this will split const AstAlways* const m_origAlwaysp; // Block that *this will split
const IfColorVisitor* const m_ifColorp; // Digest of results of prior coloring const IfColorVisitor* const m_ifColorp; // Digest of results of prior coloring
// Map each color to our current place within the color's new always // Map each color to our current place within the color's new always
@ -747,8 +749,8 @@ protected:
UASSERT_OBJ(nodep->user3p(), nodep, "null user3p in V3Split leaf"); UASSERT_OBJ(nodep->user3p(), nodep, "null user3p in V3Split leaf");
// Clone the leaf into its new always block // Clone the leaf into its new always block
SplitLogicVertex* const vxp = reinterpret_cast<SplitLogicVertex*>(nodep->user3p()); const SplitLogicVertex* const vxp = reinterpret_cast<SplitLogicVertex*>(nodep->user3p());
uint32_t color = vxp->color(); const uint32_t color = vxp->color();
AstNode* const clonedp = nodep->cloneTree(false); AstNode* const clonedp = nodep->cloneTree(false);
m_addAfter[color]->addNextHere(clonedp); m_addAfter[color]->addNextHere(clonedp);
m_addAfter[color] = clonedp; m_addAfter[color] = clonedp;
@ -765,7 +767,7 @@ protected:
AstSplitPlaceholder* const else_placeholderp = makePlaceholderp(); AstSplitPlaceholder* const else_placeholderp = makePlaceholderp();
AstIf* const clonep = new AstIf(nodep->fileline(), nodep->condp()->cloneTree(true), AstIf* const clonep = new AstIf(nodep->fileline(), nodep->condp()->cloneTree(true),
if_placeholderp, else_placeholderp); if_placeholderp, else_placeholderp);
AstIf* const origp = VN_CAST(nodep, If); const AstIf* const origp = VN_CAST(nodep, If);
if (origp) { if (origp) {
// Preserve pragmas from unique if's // Preserve pragmas from unique if's
// so assertions work properly // so assertions work properly
@ -817,7 +819,7 @@ private:
std::unordered_map<AstAlways*, AlwaysVec> m_replaceBlocks; std::unordered_map<AstAlways*, AlwaysVec> m_replaceBlocks;
// AstNodeIf* whose condition we're currently visiting // AstNodeIf* whose condition we're currently visiting
AstNode* m_curIfConditional = nullptr; const AstNode* m_curIfConditional = nullptr;
// CONSTRUCTORS // CONSTRUCTORS
public: public:
@ -832,7 +834,7 @@ public:
for (AlwaysVec::iterator addme = it->second.begin(); addme != it->second.end(); for (AlwaysVec::iterator addme = it->second.begin(); addme != it->second.end();
++addme) { ++addme) {
origp->addNextHere(*addme); origp->addNextHere(*addme);
RemovePlaceholdersVisitor removePlaceholders(*addme); RemovePlaceholdersVisitor{*addme};
} }
origp->unlinkFrBack(); // Without next origp->unlinkFrBack(); // Without next
VL_DO_DANGLING(origp->deleteTree(), origp); VL_DO_DANGLING(origp->deleteTree(), origp);
@ -847,7 +849,7 @@ protected:
// Each 'if' depends on rvalues in its own conditional ONLY, // Each 'if' depends on rvalues in its own conditional ONLY,
// not rvalues in the if/else bodies. // not rvalues in the if/else bodies.
for (auto it = m_stmtStackps.cbegin(); it != m_stmtStackps.cend(); ++it) { for (auto it = m_stmtStackps.cbegin(); it != m_stmtStackps.cend(); ++it) {
AstNodeIf* const ifNodep = VN_CAST((*it)->nodep(), NodeIf); const AstNodeIf* const ifNodep = VN_CAST((*it)->nodep(), NodeIf);
if (ifNodep && (m_curIfConditional != ifNodep)) continue; if (ifNodep && (m_curIfConditional != ifNodep)) continue;
new SplitRVEdge(&m_graph, *it, vstdp); new SplitRVEdge(&m_graph, *it, vstdp);
} }
@ -871,15 +873,15 @@ protected:
// inputs) prune all edges that depend on the 'if'. // inputs) prune all edges that depend on the 'if'.
for (V3GraphVertex* vertexp = m_graph.verticesBeginp(); vertexp; for (V3GraphVertex* vertexp = m_graph.verticesBeginp(); vertexp;
vertexp = vertexp->verticesNextp()) { vertexp = vertexp->verticesNextp()) {
SplitLogicVertex* const logicp = dynamic_cast<SplitLogicVertex*>(vertexp); const SplitLogicVertex* const logicp = dynamic_cast<SplitLogicVertex*>(vertexp);
if (!logicp) continue; if (!logicp) continue;
AstNodeIf* const ifNodep = VN_CAST(logicp->nodep(), NodeIf); const AstNodeIf* const ifNodep = VN_CAST(logicp->nodep(), NodeIf);
if (!ifNodep) continue; if (!ifNodep) continue;
bool pruneMe = true; bool pruneMe = true;
for (V3GraphEdge* edgep = logicp->outBeginp(); edgep; edgep = edgep->outNextp()) { for (V3GraphEdge* edgep = logicp->outBeginp(); edgep; edgep = edgep->outNextp()) {
SplitEdge* const oedgep = dynamic_cast<SplitEdge*>(edgep); const SplitEdge* const oedgep = dynamic_cast<SplitEdge*>(edgep);
if (!oedgep->ignoreThisStep()) { if (!oedgep->ignoreThisStep()) {
// This if conditional depends on something we can't // This if conditional depends on something we can't
// prune -- a variable generated in the current block. // prune -- a variable generated in the current block.
@ -889,7 +891,7 @@ protected:
// give a hint about why... // give a hint about why...
if (debug() >= 9) { if (debug() >= 9) {
V3GraphVertex* vxp = oedgep->top(); V3GraphVertex* vxp = oedgep->top();
SplitNodeVertex* const nvxp = dynamic_cast<SplitNodeVertex*>(vxp); const SplitNodeVertex* const nvxp = dynamic_cast<SplitNodeVertex*>(vxp);
UINFO(0, "Cannot prune if-node due to edge " UINFO(0, "Cannot prune if-node due to edge "
<< oedgep << " pointing to node " << nvxp->nodep() << endl); << oedgep << " pointing to node " << nvxp->nodep() << endl);
nvxp->nodep()->dumpTree(cout, "- "); nvxp->nodep()->dumpTree(cout, "- ");
@ -936,7 +938,7 @@ protected:
// Map each AstNodeIf to the set of colors (split always blocks) // Map each AstNodeIf to the set of colors (split always blocks)
// it must participate in. Also find the whole set of colors. // it must participate in. Also find the whole set of colors.
IfColorVisitor ifColor{nodep}; const IfColorVisitor ifColor{nodep};
if (ifColor.colors().size() > 1) { if (ifColor.colors().size() > 1) {
// Counting original always blocks rather than newly-split // Counting original always blocks rather than newly-split

View File

@ -70,7 +70,7 @@ class SplitAsCleanVisitor final : public SplitAsBaseVisitor {
private: private:
// STATE // STATE
AstVarScope* const m_splitVscp; // Variable we want to split AstVarScope* const m_splitVscp; // Variable we want to split
bool m_modeMatch; // Remove matching Vscp, else non-matching const bool m_modeMatch; // Remove matching Vscp, else non-matching
bool m_keepStmt = false; // Current Statement must be preserved bool m_keepStmt = false; // Current Statement must be preserved
bool m_matches = false; // Statement below has matching lvalue reference bool m_matches = false; // Statement below has matching lvalue reference
@ -144,11 +144,11 @@ private:
newp->user1(true); // So we don't clone it again newp->user1(true); // So we don't clone it again
nodep->addNextHere(newp); nodep->addNextHere(newp);
{ // Delete stuff we don't want in old { // Delete stuff we don't want in old
SplitAsCleanVisitor visitor{nodep, m_splitVscp, false}; const SplitAsCleanVisitor visitor{nodep, m_splitVscp, false};
if (debug() >= 9) nodep->dumpTree(cout, "-out0: "); if (debug() >= 9) nodep->dumpTree(cout, "-out0: ");
} }
{ // Delete stuff we don't want in new { // Delete stuff we don't want in new
SplitAsCleanVisitor visitor{newp, m_splitVscp, true}; const SplitAsCleanVisitor visitor{newp, m_splitVscp, true};
if (debug() >= 9) newp->dumpTree(cout, "-out1: "); if (debug() >= 9) newp->dumpTree(cout, "-out1: ");
} }
} }
@ -159,7 +159,7 @@ private:
const AstVarScope* lastSplitVscp = nullptr; const AstVarScope* lastSplitVscp = nullptr;
while (!nodep->user1()) { while (!nodep->user1()) {
// Find any splittable variables // Find any splittable variables
SplitAsFindVisitor visitor{nodep}; const SplitAsFindVisitor visitor{nodep};
m_splitVscp = visitor.splitVscp(); m_splitVscp = visitor.splitVscp();
if (m_splitVscp && m_splitVscp == lastSplitVscp) { if (m_splitVscp && m_splitVscp == lastSplitVscp) {
// We did this last time! Something's stuck! // We did this last time! Something's stuck!

View File

@ -249,13 +249,13 @@ struct AstNodeComparator {
class UnpackRef final { class UnpackRef final {
// m_nodep is called in this context (AstNodeStmt, AstCell, AstNodeFTask, or AstAlways) // m_nodep is called in this context (AstNodeStmt, AstCell, AstNodeFTask, or AstAlways)
AstNode* m_contextp; AstNode* const m_contextp;
AstNode* m_nodep; // ArraySel, SliceSel, ArrayVarRef (entire value) AstNode* const m_nodep; // ArraySel, SliceSel, ArrayVarRef (entire value)
int m_index; // for ArraySel const int m_index; // for ArraySel
int m_msb; // for SliceSel const int m_msb; // for SliceSel
int m_lsb; // for SliceSel const int m_lsb; // for SliceSel
VAccess m_access; const VAccess m_access;
bool m_ftask; // true if the reference is in function/task. false if in module. const bool m_ftask; // true if the reference is in function/task. false if in module.
public: public:
UnpackRef(AstNode* stmtp, AstVarRef* nodep, bool ftask) UnpackRef(AstNode* stmtp, AstVarRef* nodep, bool ftask)
: m_contextp{stmtp} : m_contextp{stmtp}
@ -402,7 +402,7 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
AstNodeModule* m_modp = nullptr; AstNodeModule* m_modp = nullptr;
// AstNodeStmt, AstCell, AstNodeFTaskRef, or AstAlways(Public) for sensitivity // AstNodeStmt, AstCell, AstNodeFTaskRef, or AstAlways(Public) for sensitivity
AstNode* m_contextp = nullptr; AstNode* m_contextp = nullptr;
AstNodeFTask* m_inFTask = nullptr; const AstNodeFTask* m_inFTask = nullptr;
size_t m_numSplit = 0; size_t m_numSplit = 0;
// List for SplitPackedVarVisitor // List for SplitPackedVarVisitor
SplitVarRefsMap m_refsForPackedSplit; SplitVarRefsMap m_refsForPackedSplit;
@ -490,13 +490,13 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
VL_RESTORER(m_contextp); VL_RESTORER(m_contextp);
{ {
m_contextp = nodep; m_contextp = nodep;
AstNodeFTask* const ftaskp = nodep->taskp(); const AstNodeFTask* const ftaskp = nodep->taskp();
UASSERT_OBJ(ftaskp, nodep, "Unlinked"); UASSERT_OBJ(ftaskp, nodep, "Unlinked");
// Iterate arguments of a function/task. // Iterate arguments of a function/task.
for (AstNode *argp = nodep->pinsp(), *paramp = ftaskp->stmtsp(); argp; for (AstNode *argp = nodep->pinsp(), *paramp = ftaskp->stmtsp(); argp;
argp = argp->nextp(), paramp = paramp ? paramp->nextp() : nullptr) { argp = argp->nextp(), paramp = paramp ? paramp->nextp() : nullptr) {
const char* reason = nullptr; const char* reason = nullptr;
AstVar* vparamp = nullptr; const AstVar* vparamp = nullptr;
while (paramp) { while (paramp) {
vparamp = VN_CAST(paramp, Var); vparamp = VN_CAST(paramp, Var);
if (vparamp && vparamp->isIO()) { if (vparamp && vparamp->isIO()) {
@ -527,7 +527,7 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
if (!exprp) return; // Not connected pin if (!exprp) return; // Not connected pin
m_foundTargetVar.clear(); m_foundTargetVar.clear();
iterate(exprp); iterate(exprp);
if (const char* reason = cannotSplitConnectedPortReason(nodep)) { if (const char* const reason = cannotSplitConnectedPortReason(nodep)) {
for (AstVar* const varp : m_foundTargetVar) { for (AstVar* const varp : m_foundTargetVar) {
warnNoSplit(varp, nodep, reason); warnNoSplit(varp, nodep, reason);
m_refs.remove(varp); m_refs.remove(varp);
@ -564,7 +564,7 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
} }
virtual void visit(AstArraySel* nodep) override { virtual void visit(AstArraySel* nodep) override {
if (AstVarRef* const refp = isTargetVref(nodep->fromp())) { if (AstVarRef* const refp = isTargetVref(nodep->fromp())) {
AstConst* const indexp = VN_CAST(nodep->bitp(), Const); const AstConst* const indexp = VN_CAST(nodep->bitp(), Const);
if (indexp) { // OK if (indexp) { // OK
UINFO(4, "add " << nodep << " for " << refp->varp()->prettyName() << "\n"); UINFO(4, "add " << nodep << " for " << refp->varp()->prettyName() << "\n");
if (indexp->toSInt() < outerMostSizeOfUnpackedArray(refp->varp())) { if (indexp->toSInt() < outerMostSizeOfUnpackedArray(refp->varp())) {
@ -601,7 +601,7 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
} }
} }
AstNode* toInsertPoint(AstNode* insertp) { AstNode* toInsertPoint(AstNode* insertp) {
if (AstNodeStmt* const stmtp = VN_CAST(insertp, NodeStmt)) { if (const AstNodeStmt* const stmtp = VN_CAST(insertp, NodeStmt)) {
if (!stmtp->isStatement()) insertp = stmtp->backp(); if (!stmtp->isStatement()) insertp = stmtp->backp();
} }
return insertp; return insertp;
@ -630,7 +630,7 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
= newVarRef(fl, vars.at(start_idx + i), lvalue ? VAccess::WRITE : VAccess::READ); = newVarRef(fl, vars.at(start_idx + i), lvalue ? VAccess::WRITE : VAccess::READ);
AstNode* rhsp = new AstArraySel{ AstNode* rhsp = new AstArraySel{
fl, newVarRef(fl, varp, !lvalue ? VAccess::WRITE : VAccess::READ), i}; fl, newVarRef(fl, varp, !lvalue ? VAccess::WRITE : VAccess::READ), i};
AstNode* refp = lhsp; AstNode* const refp = lhsp;
UINFO(9, "Creating assign idx:" << i << " + " << start_idx << "\n"); UINFO(9, "Creating assign idx:" << i << " + " << start_idx << "\n");
if (!lvalue) std::swap(lhsp, rhsp); if (!lvalue) std::swap(lhsp, rhsp);
AstNode* newassignp; AstNode* newassignp;
@ -699,7 +699,7 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
// Unpacked array is traced as var(idx), not var[idx]. // Unpacked array is traced as var(idx), not var[idx].
const std::string name const std::string name
= varp->name() + AstNode::encodeName('(' + cvtToStr(i + dtypep->lo()) + ')'); = varp->name() + AstNode::encodeName('(' + cvtToStr(i + dtypep->lo()) + ')');
AstVar* newp = newVar(varp->fileline(), AstVarType::VAR, name, subTypep); AstVar* const newp = newVar(varp->fileline(), AstVarType::VAR, name, subTypep);
newp->propagateAttrFrom(varp); newp->propagateAttrFrom(varp);
// If varp is an IO, varp will remain and will be traced. // If varp is an IO, varp will remain and will be traced.
newp->trace(!varp->isIO() && varp->isTrace()); newp->trace(!varp->isIO() && varp->isTrace());
@ -721,7 +721,7 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
if (refp) { if (refp) {
adtypep = VN_AS(refp->dtypep()->skipRefp(), UnpackArrayDType); adtypep = VN_AS(refp->dtypep()->skipRefp(), UnpackArrayDType);
} else { } else {
AstSliceSel* selp = VN_AS(ref.nodep(), SliceSel); AstSliceSel* const selp = VN_AS(ref.nodep(), SliceSel);
UASSERT_OBJ(selp, ref.nodep(), "Unexpected op is registered"); UASSERT_OBJ(selp, ref.nodep(), "Unexpected op is registered");
refp = VN_AS(selp->fromp(), VarRef); refp = VN_AS(selp->fromp(), VarRef);
UASSERT_OBJ(refp, selp, "Unexpected op is registered"); UASSERT_OBJ(refp, selp, "Unexpected op is registered");
@ -809,8 +809,8 @@ public:
// Split variable // Split variable
class SplitNewVar final { class SplitNewVar final {
int m_lsb; // LSB in the original bitvector const int m_lsb; // LSB in the original bitvector
int m_bitwidth; const int m_bitwidth;
AstVar* m_varp; // The LSB of this variable is always 0, not m_lsb AstVar* m_varp; // The LSB of this variable is always 0, not m_lsb
public: public:
SplitNewVar(int lsb, int bitwidth, AstVar* varp = nullptr) SplitNewVar(int lsb, int bitwidth, AstVar* varp = nullptr)
@ -835,9 +835,9 @@ public:
// One Entry instance for an AstVarRef instance // One Entry instance for an AstVarRef instance
class PackedVarRefEntry final { class PackedVarRefEntry final {
AstNode* m_nodep; // Either AstSel or AstVarRef is expected. AstNode* const m_nodep; // Either AstSel or AstVarRef is expected.
int m_lsb; const int m_lsb;
int m_bitwidth; const int m_bitwidth;
public: public:
PackedVarRefEntry(AstSel* selp, int lsb, int bitwidth) PackedVarRefEntry(AstSel* selp, int lsb, int bitwidth)
@ -859,7 +859,7 @@ public:
// If this is AstVarRef and referred in the sensitivity list of always@, // If this is AstVarRef and referred in the sensitivity list of always@,
// return the sensitivity item // return the sensitivity item
AstSenItem* backSenItemp() const { AstSenItem* backSenItemp() const {
if (AstVarRef* const refp = VN_CAST(m_nodep, VarRef)) { if (const AstVarRef* const refp = VN_CAST(m_nodep, VarRef)) {
return VN_CAST(refp->backp(), SenItem); return VN_CAST(refp->backp(), SenItem);
} }
return nullptr; return nullptr;
@ -875,7 +875,7 @@ class PackedVarRef final {
} }
}; };
std::vector<PackedVarRefEntry> m_lhs, m_rhs; std::vector<PackedVarRefEntry> m_lhs, m_rhs;
AstBasicDType* m_basicp; // Cache the ptr since varp->dtypep()->basicp() is expensive AstBasicDType* const m_basicp; // Cache the ptr since varp->dtypep()->basicp() is expensive
bool m_dedupDone = false; bool m_dedupDone = false;
static void dedupRefs(std::vector<PackedVarRefEntry>& refs) { static void dedupRefs(std::vector<PackedVarRefEntry>& refs) {
// Use raw pointer to dedup // Use raw pointer to dedup
@ -959,8 +959,8 @@ public:
}; };
class SplitPackedVarVisitor final : public AstNVisitor, public SplitVarImpl { class SplitPackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
AstNetlist* m_netp; AstNetlist* const m_netp;
AstNodeModule* m_modp = nullptr; // Current module (just for log) const AstNodeModule* m_modp = nullptr; // Current module (just for log)
int m_numSplit = 0; // Total number of split variables int m_numSplit = 0; // Total number of split variables
// key:variable to be split. value:location where the variable is referenced. // key:variable to be split. value:location where the variable is referenced.
std::map<AstVar*, PackedVarRef, AstNodeComparator> m_refs; std::map<AstVar*, PackedVarRef, AstNodeComparator> m_refs;
@ -985,14 +985,14 @@ class SplitPackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
UASSERT_OBJ(varp->attrSplitVar(), varp, "split_var attribute must be attached"); UASSERT_OBJ(varp->attrSplitVar(), varp, "split_var attribute must be attached");
UASSERT_OBJ(!nodep->classOrPackagep(), nodep, UASSERT_OBJ(!nodep->classOrPackagep(), nodep,
"variable in package must have been dropped beforehand."); "variable in package must have been dropped beforehand.");
const AstBasicDType* basicp = refit->second.basicp(); const AstBasicDType* const basicp = refit->second.basicp();
refit->second.append(PackedVarRefEntry(nodep, basicp->lo(), varp->width()), refit->second.append(PackedVarRefEntry(nodep, basicp->lo(), varp->width()),
nodep->access()); nodep->access());
UINFO(5, varp->prettyName() UINFO(5, varp->prettyName()
<< " Entire bit of [" << basicp->lo() << "+:" << varp->width() << "] \n"); << " Entire bit of [" << basicp->lo() << "+:" << varp->width() << "] \n");
} }
virtual void visit(AstSel* nodep) override { virtual void visit(AstSel* nodep) override {
AstVarRef* const vrefp = VN_CAST(nodep->fromp(), VarRef); const AstVarRef* const vrefp = VN_CAST(nodep->fromp(), VarRef);
if (!vrefp) { if (!vrefp) {
iterateChildren(nodep); iterateChildren(nodep);
return; return;
@ -1006,7 +1006,7 @@ class SplitPackedVarVisitor final : public AstNVisitor, public SplitVarImpl {
} }
UASSERT_OBJ(varp->attrSplitVar(), varp, "split_var attribute must be attached"); UASSERT_OBJ(varp->attrSplitVar(), varp, "split_var attribute must be attached");
std::array<AstConst*, 2> consts const std::array<AstConst*, 2> consts
= {{VN_CAST(nodep->lsbp(), Const), = {{VN_CAST(nodep->lsbp(), Const),
VN_CAST(nodep->widthp(), Const)}}; // GCC 3.8.0 wants {{}} VN_CAST(nodep->widthp(), Const)}}; // GCC 3.8.0 wants {{}}
if (consts[0] && consts[1]) { // OK if (consts[0] && consts[1]) { // OK
@ -1224,7 +1224,7 @@ public:
// when the access to the variable cannot be determined statically. // when the access to the variable cannot be determined statically.
static const char* cannotSplitReason(const AstVar* nodep, bool checkUnpacked) { static const char* cannotSplitReason(const AstVar* nodep, bool checkUnpacked) {
const char* reason = nullptr; const char* reason = nullptr;
if (AstBasicDType* const basicp = nodep->dtypep()->basicp()) { if (const AstBasicDType* const basicp = nodep->dtypep()->basicp()) {
const std::pair<uint32_t, uint32_t> dim = nodep->dtypep()->dimensions(false); const std::pair<uint32_t, uint32_t> dim = nodep->dtypep()->dimensions(false);
// Unpacked array will be split in SplitUnpackedVarVisitor() beforehand // Unpacked array will be split in SplitUnpackedVarVisitor() beforehand
if (!((!checkUnpacked || dim.second == 0) && nodep->dtypep()->widthMin() > 1)) if (!((!checkUnpacked || dim.second == 0) && nodep->dtypep()->widthMin() > 1))
@ -1255,7 +1255,7 @@ void V3SplitVar::splitVariable(AstNetlist* nodep) {
UINFO(2, __FUNCTION__ << ": " << endl); UINFO(2, __FUNCTION__ << ": " << endl);
SplitVarRefsMap refs; SplitVarRefsMap refs;
{ {
SplitUnpackedVarVisitor visitor{nodep}; const SplitUnpackedVarVisitor visitor{nodep};
refs = visitor.getPackedVarRefs(); refs = visitor.getPackedVarRefs();
} }
V3Global::dumpCheckGlobalTree("split_var", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 9); V3Global::dumpCheckGlobalTree("split_var", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 9);

View File

@ -37,12 +37,12 @@ private:
using NameMap = std::map<const std::string, int>; // Number of times a name appears using NameMap = std::map<const std::string, int>; // Number of times a name appears
// STATE // STATE
string m_stage; // Name of the stage we are scanning const string m_stage; // Name of the stage we are scanning
/// m_fast = true: Counting only critical branch of fastpath /// m_fast = true: Counting only critical branch of fastpath
/// m_fast = false: Counting every node, ignoring structure of program /// m_fast = false: Counting every node, ignoring structure of program
bool m_fast; const bool m_fast;
AstCFunc* m_cfuncp; // Current CFUNC const AstCFunc* m_cfuncp; // Current CFUNC
bool m_counting; // Currently counting bool m_counting; // Currently counting
double m_instrs; // Current instr count (for determining branch direction) double m_instrs; // Current instr count (for determining branch direction)
bool m_tracingCall; // Iterating into a CCall to a CFunc bool m_tracingCall; // Iterating into a CCall to a CFunc
@ -233,7 +233,7 @@ public:
const double count = double(m_statVarWidths.at(i)); const double count = double(m_statVarWidths.at(i));
if (count != 0.0) { if (count != 0.0) {
if (v3Global.opt.statsVars()) { if (v3Global.opt.statsVars()) {
NameMap& nameMapr = m_statVarWidthNames.at(i); const NameMap& nameMapr = m_statVarWidthNames.at(i);
for (const auto& itr : nameMapr) { for (const auto& itr : nameMapr) {
std::ostringstream os; std::ostringstream os;
os << "Vars, width " << std::setw(5) << std::dec << i << " " << itr.first; os << "Vars, width " << std::setw(5) << std::dec << i << " " << itr.first;

View File

@ -67,11 +67,11 @@ public:
class V3Statistic final { class V3Statistic final {
// A statistical entry we want published into the database // A statistical entry we want published into the database
string m_name; ///< Nameiption of this statistic const string m_name; ///< Name of this statistic
double m_count; ///< Count of occurrences/ value double m_count; ///< Count of occurrences/ value
string m_stage; ///< Runtime stage const string m_stage; ///< Runtime stage
bool m_sumit; ///< Do summation of similar stats const bool m_sumit; ///< Do summation of similar stats
bool m_perf; ///< Performance section const bool m_perf; ///< Performance section
bool m_printit = true; ///< Print the results bool m_printit = true; ///< Print the results
public: public:
// METHODS // METHODS

View File

@ -225,7 +225,7 @@ void V3Stats::statsReport() {
std::ofstream* ofp{V3File::new_ofstream(filename)}; std::ofstream* ofp{V3File::new_ofstream(filename)};
if (ofp->fail()) v3fatal("Can't write " << filename); if (ofp->fail()) v3fatal("Can't write " << filename);
StatsReport reporter(ofp); const StatsReport reporter(ofp);
// Cleanup // Cleanup
ofp->close(); ofp->close();

View File

@ -148,7 +148,7 @@ double VString::parseDouble(const string& str, bool* successp) {
} }
*dp++ = '\0'; *dp++ = '\0';
char* endp = strgp; char* endp = strgp;
double d = strtod(strgp, &endp); const double d = strtod(strgp, &endp);
const size_t parsed_len = endp - strgp; const size_t parsed_len = endp - strgp;
if (parsed_len != strlen(strgp)) { if (parsed_len != strlen(strgp)) {
if (successp) *successp = false; if (successp) *successp = false;
@ -321,7 +321,7 @@ uint64_t VHashSha256::digestUInt64() {
const string& binhash = digestBinary(); const string& binhash = digestBinary();
uint64_t out = 0; uint64_t out = 0;
for (size_t byte = 0; byte < sizeof(uint64_t); ++byte) { for (size_t byte = 0; byte < sizeof(uint64_t); ++byte) {
unsigned char c = binhash[byte]; const unsigned char c = binhash[byte];
out = (out << 8) | c; out = (out << 8) | c;
} }
return out; return out;
@ -411,14 +411,14 @@ string VName::dehash(const string& in) {
const string::size_type next_dot_pos = in.find("__DOT__", last_dot_pos); const string::size_type next_dot_pos = in.find("__DOT__", last_dot_pos);
// Two iterators defining the range between the last and next dots. // Two iterators defining the range between the last and next dots.
const auto search_begin = std::begin(in) + last_dot_pos; const auto search_begin = std::begin(in) + last_dot_pos;
auto search_end const auto search_end
= next_dot_pos == string::npos ? std::end(in) : std::begin(in) + next_dot_pos; = next_dot_pos == string::npos ? std::end(in) : std::begin(in) + next_dot_pos;
// Search for __Vhsh between the two dots. // Search for __Vhsh between the two dots.
auto begin_vhsh const auto begin_vhsh
= std::search(search_begin, search_end, std::begin(VHSH), std::end(VHSH) - 1); = std::search(search_begin, search_end, std::begin(VHSH), std::end(VHSH) - 1);
if (begin_vhsh != search_end) { if (begin_vhsh != search_end) {
std::string vhsh(begin_vhsh, search_end); const std::string vhsh(begin_vhsh, search_end);
const auto& it = s_dehashMap.find(vhsh); const auto& it = s_dehashMap.find(vhsh);
UASSERT(it != s_dehashMap.end(), "String not in reverse hash map '" << vhsh << "'"); UASSERT(it != s_dehashMap.end(), "String not in reverse hash map '" << vhsh << "'");
// Is this not the first component, but the first to require dehashing? // Is this not the first component, but the first to require dehashing?
@ -582,7 +582,7 @@ void VSpellCheck::selfTest() {
selfTestSuggestOne(false, "sqrt", "assert", 3); selfTestSuggestOne(false, "sqrt", "assert", 3);
} }
{ {
VSpellCheck speller; const VSpellCheck speller;
UASSERT_SELFTEST(string, "", speller.bestCandidate("")); UASSERT_SELFTEST(string, "", speller.bestCandidate(""));
} }
{ {

View File

@ -180,7 +180,7 @@ private:
// See SubstVisitor // See SubstVisitor
// //
// STATE // STATE
int m_origStep; // Step number where subst was recorded const int m_origStep; // Step number where subst was recorded
bool m_ok = true; // No misassignments found bool m_ok = true; // No misassignments found
// METHODS // METHODS
@ -274,7 +274,7 @@ private:
entryp->assignWhole(m_assignStep, nodep); entryp->assignWhole(m_assignStep, nodep);
} }
} }
} else if (AstWordSel* wordp = VN_CAST(nodep->lhsp(), WordSel)) { } else if (const AstWordSel* const wordp = VN_CAST(nodep->lhsp(), WordSel)) {
if (AstVarRef* const varrefp = VN_CAST(wordp->lhsp(), VarRef)) { if (AstVarRef* const varrefp = VN_CAST(wordp->lhsp(), VarRef)) {
if (VN_IS(wordp->rhsp(), Const) && isSubstVar(varrefp->varp())) { if (VN_IS(wordp->rhsp(), Const) && isSubstVar(varrefp->varp())) {
const int word = VN_AS(wordp->rhsp(), Const)->toUInt(); const int word = VN_AS(wordp->rhsp(), Const)->toUInt();
@ -315,7 +315,7 @@ private:
SubstVarEntry* const entryp = getEntryp(varrefp); SubstVarEntry* const entryp = getEntryp(varrefp);
if (AstNode* const substp = entryp->substWord(nodep, word)) { if (AstNode* const substp = entryp->substWord(nodep, word)) {
// Check that the RHS hasn't changed value since we recorded it. // Check that the RHS hasn't changed value since we recorded it.
SubstUseVisitor visitor{substp, entryp->getWordStep(word)}; const SubstUseVisitor visitor{substp, entryp->getWordStep(word)};
if (visitor.ok()) { if (visitor.ok()) {
VL_DO_DANGLING(replaceSubstEtc(nodep, substp), nodep); VL_DO_DANGLING(replaceSubstEtc(nodep, substp), nodep);
} else { } else {
@ -340,9 +340,9 @@ private:
if (nodep->access().isWriteOrRW()) { if (nodep->access().isWriteOrRW()) {
UINFO(8, " ASSIGNcpx " << nodep << endl); UINFO(8, " ASSIGNcpx " << nodep << endl);
entryp->assignComplex(); entryp->assignComplex();
} else if (AstNode* substp = entryp->substWhole(nodep)) { } else if (AstNode* const substp = entryp->substWhole(nodep)) {
// Check that the RHS hasn't changed value since we recorded it. // Check that the RHS hasn't changed value since we recorded it.
SubstUseVisitor visitor{substp, entryp->getWholeStep()}; const SubstUseVisitor visitor{substp, entryp->getWholeStep()};
if (visitor.ok()) { if (visitor.ok()) {
UINFO(8, " USEwhole " << nodep << endl); UINFO(8, " USEwhole " << nodep << endl);
VL_DO_DANGLING(replaceSubstEtc(nodep, substp), nodep); VL_DO_DANGLING(replaceSubstEtc(nodep, substp), nodep);

View File

@ -158,7 +158,7 @@ public:
VSymEnt* findIdFallback(const string& name) const { VSymEnt* findIdFallback(const string& name) const {
// Find identifier looking upward through symbol hierarchy // Find identifier looking upward through symbol hierarchy
// First, scan this begin/end block or module for the name // First, scan this begin/end block or module for the name
if (VSymEnt* entp = findIdFlat(name)) return entp; if (VSymEnt* const entp = findIdFlat(name)) return entp;
// Then scan the upper begin/end block or module for the name // Then scan the upper begin/end block or module for the name
if (m_fallbackp) return m_fallbackp->findIdFallback(name); if (m_fallbackp) return m_fallbackp->findIdFallback(name);
return nullptr; return nullptr;
@ -166,7 +166,7 @@ public:
void candidateIdFlat(VSpellCheck* spellerp, const VNodeMatcher* matcherp) const { void candidateIdFlat(VSpellCheck* spellerp, const VNodeMatcher* matcherp) const {
// Suggest alternative symbol candidates without looking upward through symbol hierarchy // Suggest alternative symbol candidates without looking upward through symbol hierarchy
for (IdNameMap::const_iterator it = m_idNameMap.begin(); it != m_idNameMap.end(); ++it) { for (IdNameMap::const_iterator it = m_idNameMap.begin(); it != m_idNameMap.end(); ++it) {
const AstNode* itemp = it->second->nodep(); const AstNode* const itemp = it->second->nodep();
if (itemp && (!matcherp || matcherp->nodeMatch(itemp))) { if (itemp && (!matcherp || matcherp->nodeMatch(itemp))) {
spellerp->pushCandidate(itemp->prettyName()); spellerp->pushCandidate(itemp->prettyName());
} }
@ -185,7 +185,7 @@ private:
bool honorExport) { bool honorExport) {
if ((!honorExport || srcp->exported()) if ((!honorExport || srcp->exported())
&& !findIdFlat(name)) { // Don't insert over existing entry && !findIdFlat(name)) { // Don't insert over existing entry
VSymEnt* symp = new VSymEnt(graphp, srcp); VSymEnt* const symp = new VSymEnt(graphp, srcp);
symp->exported(false); // Can't reimport an import without an export symp->exported(false); // Can't reimport an import without an export
symp->imported(true); symp->imported(true);
reinsert(name, symp); reinsert(name, symp);
@ -193,7 +193,7 @@ private:
} }
void exportOneSymbol(VSymGraph* graphp, const string& name, const VSymEnt* srcp) const { void exportOneSymbol(VSymGraph* graphp, const string& name, const VSymEnt* srcp) const {
if (srcp->exported()) { if (srcp->exported()) {
if (VSymEnt* symp = findIdFlat(name)) { // Should already exist in current table if (VSymEnt* const symp = findIdFlat(name)) { // Should already exist in current table
if (!symp->exported()) symp->exported(true); if (!symp->exported()) symp->exported(true);
} }
} }
@ -237,7 +237,7 @@ public:
void exportStarStar(VSymGraph* graphp) { void exportStarStar(VSymGraph* graphp) {
// Export *:*: Export all tokens from imported packages // Export *:*: Export all tokens from imported packages
for (IdNameMap::const_iterator it = m_idNameMap.begin(); it != m_idNameMap.end(); ++it) { for (IdNameMap::const_iterator it = m_idNameMap.begin(); it != m_idNameMap.end(); ++it) {
VSymEnt* symp = it->second; VSymEnt* const symp = it->second;
if (!symp->exported()) symp->exported(true); if (!symp->exported()) symp->exported(true);
} }
} }
@ -247,10 +247,10 @@ public:
for (IdNameMap::const_iterator it = srcp->m_idNameMap.begin(); for (IdNameMap::const_iterator it = srcp->m_idNameMap.begin();
it != srcp->m_idNameMap.end(); ++it) { it != srcp->m_idNameMap.end(); ++it) {
const string& name = it->first; const string& name = it->first;
VSymEnt* subSrcp = it->second; VSymEnt* const subSrcp = it->second;
const AstVar* varp = VN_CAST(subSrcp->nodep(), Var); const AstVar* const varp = VN_CAST(subSrcp->nodep(), Var);
if (!onlyUnmodportable || (varp && varp->isParam())) { if (!onlyUnmodportable || (varp && varp->isParam())) {
VSymEnt* subSymp = new VSymEnt(graphp, subSrcp); VSymEnt* const subSymp = new VSymEnt(graphp, subSrcp);
reinsert(name, subSymp); reinsert(name, subSymp);
// And recurse to create children // And recurse to create children
subSymp->importFromIface(graphp, subSrcp); subSymp->importFromIface(graphp, subSrcp);
@ -261,7 +261,7 @@ public:
if (prettyName == "") prettyName = lookp->prettyName(); if (prettyName == "") prettyName = lookp->prettyName();
string scopes; string scopes;
for (IdNameMap::iterator it = m_idNameMap.begin(); it != m_idNameMap.end(); ++it) { for (IdNameMap::iterator it = m_idNameMap.begin(); it != m_idNameMap.end(); ++it) {
AstNode* itemp = it->second->nodep(); AstNode* const itemp = it->second->nodep();
if (VN_IS(itemp, Cell) || (VN_IS(itemp, Module) && VN_AS(itemp, Module)->isTop())) { if (VN_IS(itemp, Cell) || (VN_IS(itemp, Module) && VN_AS(itemp, Module)->isTop())) {
if (scopes != "") scopes += ", "; if (scopes != "") scopes += ", ";
scopes += AstNode::prettyName(it->first); scopes += AstNode::prettyName(it->first);

View File

@ -53,7 +53,7 @@ VL_DEBUG_FUNC; // Declare debug()
// Vertex that tracks a per-vertex key // Vertex that tracks a per-vertex key
template <typename T_Key> class TspVertexTmpl : public V3GraphVertex { template <typename T_Key> class TspVertexTmpl : public V3GraphVertex {
private: private:
T_Key m_key; const T_Key m_key;
public: public:
TspVertexTmpl(V3Graph* graphp, const T_Key& k) TspVertexTmpl(V3Graph* graphp, const T_Key& k)
@ -112,7 +112,7 @@ public:
bool empty() const { return m_vertices.empty(); } bool empty() const { return m_vertices.empty(); }
std::list<Vertex*> keysToVertexList(const std::vector<T_Key>& odds) { const std::list<Vertex*> keysToVertexList(const std::vector<T_Key>& odds) {
std::list<Vertex*> vertices; std::list<Vertex*> vertices;
for (unsigned i = 0; i < odds.size(); ++i) { vertices.push_back(findVertex(odds.at(i))); } for (unsigned i = 0; i < odds.size(); ++i) { vertices.push_back(findVertex(odds.at(i))); }
return vertices; return vertices;
@ -177,7 +177,7 @@ public:
unsigned edges_made = 0; unsigned edges_made = 0;
while (!pendingEdges.empty()) { while (!pendingEdges.empty()) {
const auto firstIt = pendingEdges.cbegin(); const auto firstIt = pendingEdges.cbegin();
V3GraphEdge* bestEdgep = *firstIt; const V3GraphEdge* bestEdgep = *firstIt;
pendingEdges.erase(firstIt); pendingEdges.erase(firstIt);
// bestEdgep->fromp() should be already seen // bestEdgep->fromp() should be already seen
@ -298,7 +298,7 @@ public:
// Look for an arbitrary edge we've not yet marked // Look for an arbitrary edge we've not yet marked
for (V3GraphEdge* edgep = cur_vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) { for (V3GraphEdge* edgep = cur_vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) {
vluint32_t edgeId = edgep->user(); const vluint32_t edgeId = edgep->user();
if (markedEdgesp->end() == markedEdgesp->find(edgeId)) { if (markedEdgesp->end() == markedEdgesp->find(edgeId)) {
// This edge is not yet marked, so follow it. // This edge is not yet marked, so follow it.
markedEdgesp->insert(edgeId); markedEdgesp->insert(edgeId);
@ -322,7 +322,7 @@ public:
recursed = false; recursed = false;
// Look for an arbitrary edge at vxp we've not yet marked // Look for an arbitrary edge at vxp we've not yet marked
for (V3GraphEdge* edgep = vxp->outBeginp(); edgep; edgep = edgep->outNextp()) { for (V3GraphEdge* edgep = vxp->outBeginp(); edgep; edgep = edgep->outNextp()) {
vluint32_t edgeId = edgep->user(); const vluint32_t edgeId = edgep->user();
if (markedEdgesp->end() == markedEdgesp->find(edgeId)) { if (markedEdgesp->end() == markedEdgesp->find(edgeId)) {
UINFO(6, "Recursing.\n"); UINFO(6, "Recursing.\n");
findEulerTourRecurse(markedEdgesp, vxp, sortedOutp); findEulerTourRecurse(markedEdgesp, vxp, sortedOutp);
@ -423,7 +423,7 @@ void V3TSP::tspSort(const V3TSP::StateVec& states, V3TSP::StateVec* resultp) {
graph.makeMinSpanningTree(&minGraph); graph.makeMinSpanningTree(&minGraph);
if (debug() >= 6) minGraph.dumpGraphFilePrefixed("minGraph"); if (debug() >= 6) minGraph.dumpGraphFilePrefixed("minGraph");
std::vector<const TspStateBase*> oddDegree = minGraph.getOddDegreeKeys(); const std::vector<const TspStateBase*> oddDegree = minGraph.getOddDegreeKeys();
Graph matching; Graph matching;
graph.perfectMatching(oddDegree, &matching); graph.perfectMatching(oddDegree, &matching);
if (debug() >= 6) matching.dumpGraphFilePrefixed("matching"); if (debug() >= 6) matching.dumpGraphFilePrefixed("matching");
@ -526,9 +526,9 @@ public:
bool operator<(const TspTestState& other) const { return m_serial < other.m_serial; } bool operator<(const TspTestState& other) const { return m_serial < other.m_serial; }
private: private:
unsigned m_xpos; const unsigned m_xpos;
unsigned m_ypos; const unsigned m_ypos;
unsigned m_serial; const unsigned m_serial;
static unsigned s_serialNext; static unsigned s_serialNext;
}; };
@ -538,11 +538,11 @@ void V3TSP::selfTestStates() {
// Linear test -- coords all along the x-axis // Linear test -- coords all along the x-axis
{ {
V3TSP::StateVec states; V3TSP::StateVec states;
TspTestState s10(10, 0); const TspTestState s10(10, 0);
TspTestState s60(60, 0); const TspTestState s60(60, 0);
TspTestState s20(20, 0); const TspTestState s20(20, 0);
TspTestState s100(100, 0); const TspTestState s100(100, 0);
TspTestState s5(5, 0); const TspTestState s5(5, 0);
states.push_back(&s10); states.push_back(&s10);
states.push_back(&s60); states.push_back(&s60);
states.push_back(&s20); states.push_back(&s20);
@ -572,13 +572,13 @@ void V3TSP::selfTestStates() {
// Test that tspSort() will rotate the list for minimum cost. // Test that tspSort() will rotate the list for minimum cost.
{ {
V3TSP::StateVec states; V3TSP::StateVec states;
TspTestState a(0, 0); const TspTestState a(0, 0);
TspTestState b(100, 0); const TspTestState b(100, 0);
TspTestState c(200, 0); const TspTestState c(200, 0);
TspTestState d(200, 100); const TspTestState d(200, 100);
TspTestState e(150, 150); const TspTestState e(150, 150);
TspTestState f(0, 150); const TspTestState f(0, 150);
TspTestState g(0, 100); const TspTestState g(0, 100);
states.push_back(&a); states.push_back(&a);
states.push_back(&b); states.push_back(&b);
@ -631,7 +631,7 @@ void V3TSP::selfTestString() {
graph.makeMinSpanningTree(&minGraph); graph.makeMinSpanningTree(&minGraph);
if (debug() >= 6) minGraph.dumpGraphFilePrefixed("minGraph"); if (debug() >= 6) minGraph.dumpGraphFilePrefixed("minGraph");
std::vector<string> oddDegree = minGraph.getOddDegreeKeys(); const std::vector<string> oddDegree = minGraph.getOddDegreeKeys();
Graph matching; Graph matching;
graph.perfectMatching(oddDegree, &matching); graph.perfectMatching(oddDegree, &matching);
if (debug() >= 6) matching.dumpGraphFilePrefixed("matching"); if (debug() >= 6) matching.dumpGraphFilePrefixed("matching");

View File

@ -174,7 +174,7 @@ public:
void simulateVarRefCb(AstVarRef* nodep) { void simulateVarRefCb(AstVarRef* nodep) {
// Called by TableSimulateVisitor on each unique varref encountered // Called by TableSimulateVisitor on each unique varref encountered
UINFO(9, " SimVARREF " << nodep << endl); UINFO(9, " SimVARREF " << nodep << endl);
AstVarScope* vscp = nodep->varScopep(); AstVarScope* const vscp = nodep->varScopep();
if (nodep->access().isWriteOrRW()) { if (nodep->access().isWriteOrRW()) {
// We'll make the table with a separate natural alignment for each output var, so // We'll make the table with a separate natural alignment for each output var, so
// always have 8, 16 or 32 bit widths, so use widthTotalBytes // always have 8, 16 or 32 bit widths, so use widthTotalBytes
@ -265,7 +265,7 @@ private:
// Populate the tables // Populate the tables
createTables(nodep, outputAssignedTableBuilder); createTables(nodep, outputAssignedTableBuilder);
AstNode* stmtsp = createLookupInput(fl, indexVscp); AstNode* const stmtsp = createLookupInput(fl, indexVscp);
createOutputAssigns(nodep, stmtsp, indexVscp, outputAssignedTableBuilder.varScopep()); createOutputAssigns(nodep, stmtsp, indexVscp, outputAssignedTableBuilder.varScopep());
// Link it in. // Link it in.
@ -333,7 +333,7 @@ private:
// First var in inVars becomes the LSB of the concat // First var in inVars becomes the LSB of the concat
AstNode* concatp = nullptr; AstNode* concatp = nullptr;
for (AstVarScope* invscp : m_inVarps) { for (AstVarScope* invscp : m_inVarps) {
AstVarRef* refp = new AstVarRef(fl, invscp, VAccess::READ); AstVarRef* const refp = new AstVarRef(fl, invscp, VAccess::READ);
if (concatp) { if (concatp) {
concatp = new AstConcat(fl, refp, concatp); concatp = new AstConcat(fl, refp, concatp);
} else { } else {

View File

@ -391,7 +391,7 @@ class TaskGatherWrittenVisitor final : public AstNVisitor {
public: public:
// Gather all written non-local variables // Gather all written non-local variables
static const std::vector<AstVarScope*> gather(AstCFunc* funcp) { static const std::vector<AstVarScope*> gather(AstCFunc* funcp) {
TaskGatherWrittenVisitor visitor{funcp}; const TaskGatherWrittenVisitor visitor{funcp};
return std::move(visitor.m_writtenVariables); return std::move(visitor.m_writtenVariables);
} }
}; };
@ -419,7 +419,7 @@ private:
using DpiCFuncs = std::map<const string, std::tuple<AstNodeFTask*, std::string, AstCFunc*>>; using DpiCFuncs = std::map<const string, std::tuple<AstNodeFTask*, std::string, AstCFunc*>>;
// STATE // STATE
TaskStateVisitor* m_statep; // Common state between visitors TaskStateVisitor* const m_statep; // Common state between visitors
AstNodeModule* m_modp = nullptr; // Current module AstNodeModule* m_modp = nullptr; // Current module
AstTopScope* const m_topScopep = v3Global.rootp()->topScopep(); // The AstTopScope AstTopScope* const m_topScopep = v3Global.rootp()->topScopep(); // The AstTopScope
AstScope* m_scopep = nullptr; // Current scope AstScope* m_scopep = nullptr; // Current scope
@ -432,20 +432,21 @@ private:
VL_DEBUG_FUNC; // Declare debug() VL_DEBUG_FUNC; // Declare debug()
AstVarScope* createFuncVar(AstCFunc* funcp, const string& name, AstVar* examplep) { AstVarScope* createFuncVar(AstCFunc* funcp, const string& name, AstVar* examplep) {
AstVar* newvarp = new AstVar(funcp->fileline(), AstVarType::BLOCKTEMP, name, examplep); AstVar* const newvarp
= new AstVar(funcp->fileline(), AstVarType::BLOCKTEMP, name, examplep);
newvarp->funcLocal(true); newvarp->funcLocal(true);
funcp->addInitsp(newvarp); funcp->addInitsp(newvarp);
AstVarScope* newvscp = new AstVarScope(funcp->fileline(), m_scopep, newvarp); AstVarScope* const newvscp = new AstVarScope(funcp->fileline(), m_scopep, newvarp);
m_scopep->addVarp(newvscp); m_scopep->addVarp(newvscp);
return newvscp; return newvscp;
} }
AstVarScope* createInputVar(AstCFunc* funcp, const string& name, AstBasicDTypeKwd kwd) { AstVarScope* createInputVar(AstCFunc* funcp, const string& name, AstBasicDTypeKwd kwd) {
AstVar* newvarp = new AstVar(funcp->fileline(), AstVarType::BLOCKTEMP, name, AstVar* const newvarp = new AstVar(funcp->fileline(), AstVarType::BLOCKTEMP, name,
funcp->findBasicDType(kwd)); funcp->findBasicDType(kwd));
newvarp->funcLocal(true); newvarp->funcLocal(true);
newvarp->direction(VDirection::INPUT); newvarp->direction(VDirection::INPUT);
funcp->addArgsp(newvarp); funcp->addArgsp(newvarp);
AstVarScope* newvscp = new AstVarScope(funcp->fileline(), m_scopep, newvarp); AstVarScope* const newvscp = new AstVarScope(funcp->fileline(), m_scopep, newvarp);
m_scopep->addVarp(newvscp); m_scopep->addVarp(newvscp);
return newvscp; return newvscp;
} }
@ -458,11 +459,12 @@ private:
// It shouldn't matter, as they are only local variables. // It shouldn't matter, as they are only local variables.
// We choose to do it under whichever called this function, which results // We choose to do it under whichever called this function, which results
// in more cache locality. // in more cache locality.
AstVar* newvarp = new AstVar{invarp->fileline(), AstVarType::BLOCKTEMP, name, invarp}; AstVar* const newvarp
= new AstVar{invarp->fileline(), AstVarType::BLOCKTEMP, name, invarp};
newvarp->funcLocal(false); newvarp->funcLocal(false);
newvarp->propagateAttrFrom(invarp); newvarp->propagateAttrFrom(invarp);
m_modp->addStmtp(newvarp); m_modp->addStmtp(newvarp);
AstVarScope* newvscp = new AstVarScope{newvarp->fileline(), m_scopep, newvarp}; AstVarScope* const newvscp = new AstVarScope{newvarp->fileline(), m_scopep, newvarp};
m_scopep->addVarp(newvscp); m_scopep->addVarp(newvscp);
return newvscp; return newvscp;
} }
@ -472,20 +474,20 @@ private:
AstVarScope* outvscp) { AstVarScope* outvscp) {
// outvscp is the variable for functions only, if nullptr, it's a task // outvscp is the variable for functions only, if nullptr, it's a task
UASSERT_OBJ(refp->taskp(), refp, "Unlinked?"); UASSERT_OBJ(refp->taskp(), refp, "Unlinked?");
AstNode* newbodysp AstNode* const newbodysp
= AstNode::cloneTreeNull(refp->taskp()->stmtsp(), true); // Maybe nullptr = AstNode::cloneTreeNull(refp->taskp()->stmtsp(), true); // Maybe nullptr
AstNode* beginp AstNode* const beginp
= new AstComment(refp->fileline(), string("Function: ") + refp->name(), true); = new AstComment(refp->fileline(), string("Function: ") + refp->name(), true);
if (newbodysp) beginp->addNext(newbodysp); if (newbodysp) beginp->addNext(newbodysp);
if (debug() >= 9) beginp->dumpTreeAndNext(cout, "-newbegi:"); if (debug() >= 9) beginp->dumpTreeAndNext(cout, "-newbegi:");
// //
// Create input variables // Create input variables
AstNode::user2ClearTree(); AstNode::user2ClearTree();
V3TaskConnects tconnects = V3Task::taskConnects(refp, beginp); const V3TaskConnects tconnects = V3Task::taskConnects(refp, beginp);
for (const auto& itr : tconnects) { for (const auto& itr : tconnects) {
AstVar* portp = itr.first; AstVar* const portp = itr.first;
AstArg* argp = itr.second; AstArg* const argp = itr.second;
AstNode* pinp = argp->exprp(); AstNode* const pinp = argp->exprp();
portp->unlinkFrBack(); portp->unlinkFrBack();
pushDeletep(portp); // Remove it from the clone (not original) pushDeletep(portp); // Remove it from the clone (not original)
if (!pinp) { if (!pinp) {
@ -504,9 +506,9 @@ private:
// Correct lvalue; see comments below // Correct lvalue; see comments below
V3LinkLValue::linkLValueSet(pinp); V3LinkLValue::linkLValueSet(pinp);
if (AstVarRef* varrefp = VN_CAST(pinp, VarRef)) { if (AstVarRef* const varrefp = VN_CAST(pinp, VarRef)) {
// Connect to this exact variable // Connect to this exact variable
AstVarScope* localVscp = varrefp->varScopep(); AstVarScope* const localVscp = varrefp->varScopep();
UASSERT_OBJ(localVscp, varrefp, "Null var scope"); UASSERT_OBJ(localVscp, varrefp, "Null var scope");
portp->user2p(localVscp); portp->user2p(localVscp);
pushDeletep(pinp); pushDeletep(pinp);
@ -525,10 +527,10 @@ private:
// Even if it's referencing a varref, we still make a temporary // Even if it's referencing a varref, we still make a temporary
// Else task(x,x,x) might produce incorrect results // Else task(x,x,x) might produce incorrect results
AstVarScope* tempvscp AstVarScope* const tempvscp
= createVarScope(portp, namePrefix + "__" + portp->shortName()); = createVarScope(portp, namePrefix + "__" + portp->shortName());
portp->user2p(tempvscp); portp->user2p(tempvscp);
AstAssign* assp = new AstAssign( AstAssign* const assp = new AstAssign(
pinp->fileline(), pinp, pinp->fileline(), pinp,
new AstVarRef(tempvscp->fileline(), tempvscp, VAccess::READ)); new AstVarRef(tempvscp->fileline(), tempvscp, VAccess::READ));
assp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, assp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ,
@ -537,16 +539,16 @@ private:
beginp->addNext(assp); beginp->addNext(assp);
} else if (portp->isNonOutput()) { } else if (portp->isNonOutput()) {
// Make input variable // Make input variable
AstVarScope* inVscp AstVarScope* const inVscp
= createVarScope(portp, namePrefix + "__" + portp->shortName()); = createVarScope(portp, namePrefix + "__" + portp->shortName());
portp->user2p(inVscp); portp->user2p(inVscp);
AstAssign* assp = new AstAssign( AstAssign* const assp = new AstAssign(
pinp->fileline(), pinp->fileline(),
new AstVarRef(inVscp->fileline(), inVscp, VAccess::WRITE), pinp); new AstVarRef(inVscp->fileline(), inVscp, VAccess::WRITE), pinp);
assp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, assp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ,
true); // Ok if in <= block true); // Ok if in <= block
// Put assignment in FRONT of all other statements // Put assignment in FRONT of all other statements
if (AstNode* afterp = beginp->nextp()) { if (AstNode* const afterp = beginp->nextp()) {
afterp->unlinkFrBackWithNext(); afterp->unlinkFrBackWithNext();
assp->addNext(afterp); assp->addNext(afterp);
} }
@ -559,13 +561,13 @@ private:
AstNode* nextstmtp; AstNode* nextstmtp;
for (AstNode* stmtp = beginp; stmtp; stmtp = nextstmtp) { for (AstNode* stmtp = beginp; stmtp; stmtp = nextstmtp) {
nextstmtp = stmtp->nextp(); nextstmtp = stmtp->nextp();
if (AstVar* portp = VN_CAST(stmtp, Var)) { if (AstVar* const portp = VN_CAST(stmtp, Var)) {
// Any I/O variables that fell out of above loop were already linked // Any I/O variables that fell out of above loop were already linked
if (!portp->user2p()) { if (!portp->user2p()) {
// Move it to a new localized variable // Move it to a new localized variable
portp->unlinkFrBack(); portp->unlinkFrBack();
pushDeletep(portp); // Remove it from the clone (not original) pushDeletep(portp); // Remove it from the clone (not original)
AstVarScope* localVscp AstVarScope* const localVscp
= createVarScope(portp, namePrefix + "__" + portp->shortName()); = createVarScope(portp, namePrefix + "__" + portp->shortName());
portp->user2p(localVscp); portp->user2p(localVscp);
} }
@ -580,8 +582,8 @@ private:
// Replace variable refs // Replace variable refs
// Iteration requires a back, so put under temporary node // Iteration requires a back, so put under temporary node
{ {
AstBegin* tempp = new AstBegin(beginp->fileline(), "[EditWrapper]", beginp); AstBegin* const tempp = new AstBegin(beginp->fileline(), "[EditWrapper]", beginp);
TaskRelinkVisitor visitor{tempp}; const TaskRelinkVisitor visitor{tempp};
tempp->stmtsp()->unlinkFrBackWithNext(); tempp->stmtsp()->unlinkFrBackWithNext();
VL_DO_DANGLING(tempp->deleteTree(), tempp); VL_DO_DANGLING(tempp->deleteTree(), tempp);
} }
@ -594,19 +596,19 @@ private:
AstVarScope* outvscp, AstCNew*& cnewpr) { AstVarScope* outvscp, AstCNew*& cnewpr) {
// outvscp is the variable for functions only, if nullptr, it's a task // outvscp is the variable for functions only, if nullptr, it's a task
UASSERT_OBJ(refp->taskp(), refp, "Unlinked?"); UASSERT_OBJ(refp->taskp(), refp, "Unlinked?");
AstCFunc* cfuncp = m_statep->ftaskCFuncp(refp->taskp()); AstCFunc* const cfuncp = m_statep->ftaskCFuncp(refp->taskp());
UASSERT_OBJ(cfuncp, refp, "No non-inline task associated with this task call?"); UASSERT_OBJ(cfuncp, refp, "No non-inline task associated with this task call?");
// //
AstNode* beginp AstNode* const beginp
= new AstComment(refp->fileline(), string("Function: ") + refp->name(), true); = new AstComment(refp->fileline(), string("Function: ") + refp->name(), true);
AstNodeCCall* ccallp; AstNodeCCall* ccallp;
if (VN_IS(refp, New)) { if (VN_IS(refp, New)) {
AstCNew* cnewp = new AstCNew(refp->fileline(), cfuncp); AstCNew* const cnewp = new AstCNew(refp->fileline(), cfuncp);
cnewp->dtypep(refp->dtypep()); cnewp->dtypep(refp->dtypep());
ccallp = cnewp; ccallp = cnewp;
// Parent AstNew will replace with this CNew // Parent AstNew will replace with this CNew
cnewpr = cnewp; cnewpr = cnewp;
} else if (AstMethodCall* mrefp = VN_CAST(refp, MethodCall)) { } else if (const AstMethodCall* const mrefp = VN_CAST(refp, MethodCall)) {
ccallp = new AstCMethodCall(refp->fileline(), mrefp->fromp()->unlinkFrBack(), cfuncp); ccallp = new AstCMethodCall(refp->fileline(), mrefp->fromp()->unlinkFrBack(), cfuncp);
beginp->addNext(ccallp); beginp->addNext(ccallp);
} else { } else {
@ -615,10 +617,10 @@ private:
} }
// Convert complicated outputs to temp signals // Convert complicated outputs to temp signals
V3TaskConnects tconnects = V3Task::taskConnects(refp, refp->taskp()->stmtsp()); const V3TaskConnects tconnects = V3Task::taskConnects(refp, refp->taskp()->stmtsp());
for (const auto& itr : tconnects) { for (const auto& itr : tconnects) {
AstVar* portp = itr.first; AstVar* const portp = itr.first;
AstNode* pinp = itr.second->exprp(); AstNode* const pinp = itr.second->exprp();
if (!pinp) { if (!pinp) {
// Too few arguments in function call // Too few arguments in function call
} else { } else {
@ -649,11 +651,11 @@ private:
// Even if it's referencing a varref, we still make a temporary // Even if it's referencing a varref, we still make a temporary
// Else task(x,x,x) might produce incorrect results // Else task(x,x,x) might produce incorrect results
AstVarScope* newvscp AstVarScope* const newvscp
= createVarScope(portp, namePrefix + "__" + portp->shortName()); = createVarScope(portp, namePrefix + "__" + portp->shortName());
portp->user2p(newvscp); portp->user2p(newvscp);
pinp->replaceWith(new AstVarRef(newvscp->fileline(), newvscp, VAccess::WRITE)); pinp->replaceWith(new AstVarRef(newvscp->fileline(), newvscp, VAccess::WRITE));
AstAssign* assp = new AstAssign( AstAssign* const assp = new AstAssign(
pinp->fileline(), pinp, pinp->fileline(), pinp,
new AstVarRef(newvscp->fileline(), newvscp, VAccess::READ)); new AstVarRef(newvscp->fileline(), newvscp, VAccess::READ));
assp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, assp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ,
@ -669,7 +671,7 @@ private:
if (refp->taskp()->dpiContext()) { if (refp->taskp()->dpiContext()) {
// __Vscopep // __Vscopep
AstNode* snp = refp->scopeNamep()->unlinkFrBack(); AstNode* const snp = refp->scopeNamep()->unlinkFrBack();
UASSERT_OBJ(snp, refp, "Missing scoping context"); UASSERT_OBJ(snp, refp, "Missing scoping context");
ccallp->addArgsp(snp); ccallp->addArgsp(snp);
// __Vfilenamep // __Vfilenamep
@ -684,7 +686,7 @@ private:
for (AstNode* pinp = refp->pinsp(); pinp; pinp = nextpinp) { for (AstNode* pinp = refp->pinsp(); pinp; pinp = nextpinp) {
nextpinp = pinp->nextp(); nextpinp = pinp->nextp();
// Move pin to the CCall, removing all Arg's // Move pin to the CCall, removing all Arg's
AstNode* exprp = VN_AS(pinp, Arg)->exprp(); AstNode* const exprp = VN_AS(pinp, Arg)->exprp();
exprp->unlinkFrBack(); exprp->unlinkFrBack();
ccallp->addArgsp(exprp); ccallp->addArgsp(exprp);
} }
@ -705,7 +707,7 @@ private:
dpiproto += " " + nodep->cname() + " ("; dpiproto += " " + nodep->cname() + " (";
string args; string args;
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) { for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
if (const AstVar* portp = VN_CAST(stmtp, Var)) { if (const AstVar* const portp = VN_CAST(stmtp, Var)) {
if (portp->isIO() && !portp->isFuncReturn() && portp != rtnvarp) { if (portp->isIO() && !portp->isFuncReturn() && portp != rtnvarp) {
if (args != "") { if (args != "") {
args += ", "; args += ", ";
@ -735,7 +737,7 @@ private:
// Create assignment from DPI temporary into internal format // Create assignment from DPI temporary into internal format
// DPI temporary is scalar or 1D array (if unpacked array) // DPI temporary is scalar or 1D array (if unpacked array)
// Internal representation is scalar, 1D, or multi-dimensional array (similar to SV) // Internal representation is scalar, 1D, or multi-dimensional array (similar to SV)
AstVar* portp = portvscp->varp(); AstVar* const portp = portvscp->varp();
string frstmt; string frstmt;
string ket; string ket;
const bool useSetWSvlv = TaskDpiUtils::dpiToInternalFrStmt(portp, frName, frstmt, ket); const bool useSetWSvlv = TaskDpiUtils::dpiToInternalFrStmt(portp, frName, frstmt, ket);
@ -766,7 +768,7 @@ private:
AstNode* stmtp = nullptr; AstNode* stmtp = nullptr;
// extract a scalar from DPI temporary var that is scalar or 1D array // extract a scalar from DPI temporary var that is scalar or 1D array
if (useSetWSvlv) { if (useSetWSvlv) {
AstNode* linesp = new AstText(portvscp->fileline(), frstmt + ket); AstNode* const linesp = new AstText(portvscp->fileline(), frstmt + ket);
linesp->addNext(srcp); linesp->addNext(srcp);
linesp->addNext( linesp->addNext(
new AstText(portvscp->fileline(), new AstText(portvscp->fileline(),
@ -780,9 +782,9 @@ private:
from += "[" + cvtToStr(i * coef) + "]"; from += "[" + cvtToStr(i * coef) + "]";
} }
from += ket; from += ket;
AstNode* rhsp = new AstSel(portp->fileline(), AstNode* const rhsp = new AstSel(
new AstCMath(portp->fileline(), from, cwidth, false), 0, portp->fileline(), new AstCMath(portp->fileline(), from, cwidth, false), 0,
portp->width()); portp->width());
stmtp = new AstAssign(portp->fileline(), srcp, rhsp); stmtp = new AstAssign(portp->fileline(), srcp, rhsp);
} }
if (i > 0) { if (i > 0) {
@ -827,7 +829,7 @@ private:
// If the find fails, it will throw an error // If the find fails, it will throw an error
stmt += "const VerilatedScope* __Vscopep = Verilated::dpiScope();\n"; stmt += "const VerilatedScope* __Vscopep = Verilated::dpiScope();\n";
// If dpiScope is fails and is null; the exportFind function throws and error // If dpiScope is fails and is null; the exportFind function throws and error
string cbtype const string cbtype
= VIdProtect::protect(v3Global.opt.prefix() + "__Vcb_" + nodep->cname() + "_t"); = VIdProtect::protect(v3Global.opt.prefix() + "__Vcb_" + nodep->cname() + "_t");
stmt += cbtype + " __Vcb = (" + cbtype stmt += cbtype + " __Vcb = (" + cbtype
+ ")(VerilatedScope::exportFind(__Vscopep, __Vfuncnum));\n"; // Can't use + ")(VerilatedScope::exportFind(__Vscopep, __Vfuncnum));\n"; // Can't use
@ -842,7 +844,7 @@ private:
+ "*)(__Vscopep->symsp())"); // Upcast w/o overhead + "*)(__Vscopep->symsp())"); // Upcast w/o overhead
AstNode* argnodesp = nullptr; AstNode* argnodesp = nullptr;
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) { for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
if (AstVar* portp = VN_CAST(stmtp, Var)) { if (AstVar* const portp = VN_CAST(stmtp, Var)) {
if (portp->isIO() && !portp->isFuncReturn() && portp != rtnvarp) { if (portp->isIO() && !portp->isFuncReturn() && portp != rtnvarp) {
// No createDpiTemp; we make a real internal variable instead // No createDpiTemp; we make a real internal variable instead
// SAME CODE BELOW // SAME CODE BELOW
@ -851,11 +853,12 @@ private:
argnodesp = argnodesp->addNext(new AstText(portp->fileline(), args, true)); argnodesp = argnodesp->addNext(new AstText(portp->fileline(), args, true));
args = ""; args = "";
} }
AstVarScope* outvscp = createFuncVar(funcp, portp->name() + tmpSuffixp, portp); AstVarScope* const outvscp
= createFuncVar(funcp, portp->name() + tmpSuffixp, portp);
// No information exposure; is already visible in import/export func template // No information exposure; is already visible in import/export func template
outvscp->varp()->protect(false); outvscp->varp()->protect(false);
portp->protect(false); portp->protect(false);
AstVarRef* refp AstVarRef* const refp
= new AstVarRef(portp->fileline(), outvscp, = new AstVarRef(portp->fileline(), outvscp,
portp->isWritable() ? VAccess::WRITE : VAccess::READ); portp->isWritable() ? VAccess::WRITE : VAccess::READ);
argnodesp = argnodesp->addNextNull(refp); argnodesp = argnodesp->addNextNull(refp);
@ -874,18 +877,18 @@ private:
} }
if (rtnvarp) { if (rtnvarp) {
AstVar* portp = rtnvarp; AstVar* const portp = rtnvarp;
// SAME CODE ABOVE // SAME CODE ABOVE
args += ", "; args += ", ";
if (args != "") { if (args != "") {
argnodesp = argnodesp->addNext(new AstText(portp->fileline(), args, true)); argnodesp = argnodesp->addNext(new AstText(portp->fileline(), args, true));
args = ""; args = "";
} }
AstVarScope* outvscp = createFuncVar(funcp, portp->name() + tmpSuffixp, portp); AstVarScope* const outvscp = createFuncVar(funcp, portp->name() + tmpSuffixp, portp);
// No information exposure; is already visible in import/export func template // No information exposure; is already visible in import/export func template
outvscp->varp()->protect(false); outvscp->varp()->protect(false);
AstVarRef* refp = new AstVarRef(portp->fileline(), outvscp, AstVarRef* const refp = new AstVarRef(
portp->isWritable() ? VAccess::WRITE : VAccess::READ); portp->fileline(), outvscp, portp->isWritable() ? VAccess::WRITE : VAccess::READ);
argnodesp = argnodesp->addNextNull(refp); argnodesp = argnodesp->addNextNull(refp);
} }
@ -893,7 +896,7 @@ private:
// Add the variables referenced as VarRef's so that lifetime analysis // Add the variables referenced as VarRef's so that lifetime analysis
// doesn't rip up the variables on us // doesn't rip up the variables on us
args += ");\n"; args += ");\n";
AstCStmt* newp = new AstCStmt(nodep->fileline(), "(*__Vcb)("); AstCStmt* const newp = new AstCStmt(nodep->fileline(), "(*__Vcb)(");
newp->addBodysp(argnodesp); newp->addBodysp(argnodesp);
VL_DANGLING(argnodesp); VL_DANGLING(argnodesp);
newp->addBodysp(new AstText(nodep->fileline(), args, true)); newp->addBodysp(new AstText(nodep->fileline(), args, true));
@ -902,7 +905,7 @@ private:
// Convert output/inout arguments back to internal type // Convert output/inout arguments back to internal type
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) { for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
if (AstVar* portp = VN_CAST(stmtp, Var)) { if (AstVar* const portp = VN_CAST(stmtp, Var)) {
if (portp->isIO() && portp->isWritable() && !portp->isFuncReturn()) { if (portp->isIO() && portp->isWritable() && !portp->isFuncReturn()) {
funcp->addStmtsp(createAssignInternalToDpi(portp, true, tmpSuffixp, "")); funcp->addStmtsp(createAssignInternalToDpi(portp, true, tmpSuffixp, ""));
} }
@ -984,10 +987,10 @@ private:
static void makePortList(AstNodeFTask* nodep, AstCFunc* dpip) { static void makePortList(AstNodeFTask* nodep, AstCFunc* dpip) {
// Copy nodep's list of function I/O to the new dpip c function // Copy nodep's list of function I/O to the new dpip c function
for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) { for (AstNode* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
if (AstVar* portp = VN_CAST(stmtp, Var)) { if (AstVar* const portp = VN_CAST(stmtp, Var)) {
if (portp->isIO()) { if (portp->isIO()) {
// Move it to new function // Move it to new function
AstVar* newPortp = portp->cloneTree(false); AstVar* const newPortp = portp->cloneTree(false);
newPortp->funcLocal(true); newPortp->funcLocal(true);
dpip->addArgsp(newPortp); dpip->addArgsp(newPortp);
if (!portp->basicp()) { if (!portp->basicp()) {
@ -1011,8 +1014,8 @@ private:
// Convert input/inout arguments to DPI types // Convert input/inout arguments to DPI types
string args; string args;
for (AstNode* stmtp = cfuncp->argsp(); stmtp; stmtp = stmtp->nextp()) { for (AstNode* stmtp = cfuncp->argsp(); stmtp; stmtp = stmtp->nextp()) {
if (AstVar* portp = VN_CAST(stmtp, Var)) { if (AstVar* const portp = VN_CAST(stmtp, Var)) {
AstVarScope* portvscp AstVarScope* const portvscp
= VN_AS(portp->user2p(), VarScope); // Remembered when we created it earlier = VN_AS(portp->user2p(), VarScope); // Remembered when we created it earlier
if (portp->isIO() && !portp->isFuncReturn() && portvscp != rtnvscp if (portp->isIO() && !portp->isFuncReturn() && portvscp != rtnvscp
&& portp->name() != "__Vscopep" // Passed to dpiContext, not callee && portp->name() != "__Vscopep" // Passed to dpiContext, not callee
@ -1021,7 +1024,7 @@ private:
if (args != "") args += ", "; if (args != "") args += ", ";
if (portp->isDpiOpenArray()) { if (portp->isDpiOpenArray()) {
AstNodeDType* dtypep = portp->dtypep()->skipRefp(); AstNodeDType* const dtypep = portp->dtypep()->skipRefp();
if (VN_IS(dtypep, DynArrayDType) || VN_IS(dtypep, QueueDType)) { if (VN_IS(dtypep, DynArrayDType) || VN_IS(dtypep, QueueDType)) {
v3fatalSrc("Passing dynamic array or queue as actual argument to DPI " v3fatalSrc("Passing dynamic array or queue as actual argument to DPI "
"open array is not yet supported"); "open array is not yet supported");
@ -1038,7 +1041,7 @@ private:
// point to this task & thread's data, in addition // point to this task & thread's data, in addition
// to static info about the variable // to static info about the variable
const string name = portp->name() + "__Vopenarray"; const string name = portp->name() + "__Vopenarray";
string varCode const string varCode
= ("VerilatedDpiOpenVar " = ("VerilatedDpiOpenVar "
// NOLINTNEXTLINE(performance-inefficient-string-concatenation) // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
+ name + " (&" + propName + ", &" + portp->name() + ");\n"); + name + " (&" + propName + ", &" + portp->name() + ");\n");
@ -1082,11 +1085,11 @@ private:
// Convert output/inout arguments back to internal type // Convert output/inout arguments back to internal type
for (AstNode* stmtp = cfuncp->argsp(); stmtp; stmtp = stmtp->nextp()) { for (AstNode* stmtp = cfuncp->argsp(); stmtp; stmtp = stmtp->nextp()) {
if (AstVar* portp = VN_CAST(stmtp, Var)) { if (AstVar* const portp = VN_CAST(stmtp, Var)) {
portp->protect(false); // No additional exposure - already part of shown proto portp->protect(false); // No additional exposure - already part of shown proto
if (portp->isIO() && (portp->isWritable() || portp->isFuncReturn()) if (portp->isIO() && (portp->isWritable() || portp->isFuncReturn())
&& !portp->isDpiOpenArray()) { && !portp->isDpiOpenArray()) {
AstVarScope* portvscp = VN_AS( AstVarScope* const portvscp = VN_AS(
portp->user2p(), VarScope); // Remembered when we created it earlier portp->user2p(), VarScope); // Remembered when we created it earlier
cfuncp->addStmtsp( cfuncp->addStmtsp(
createAssignDpiToInternal(portvscp, portp->name() + tmpSuffixp)); createAssignDpiToInternal(portvscp, portp->name() + tmpSuffixp));
@ -1118,11 +1121,11 @@ private:
AstNode::user2ClearTree(); AstNode::user2ClearTree();
AstVar* rtnvarp = nullptr; AstVar* rtnvarp = nullptr;
if (nodep->isFunction()) { if (nodep->isFunction()) {
AstVar* portp = VN_AS(nodep->fvarp(), Var); AstVar* const portp = VN_AS(nodep->fvarp(), Var);
UASSERT_OBJ(portp, nodep, "function without function output variable"); UASSERT_OBJ(portp, nodep, "function without function output variable");
if (!portp->isFuncReturn()) nodep->v3error("Not marked as function return var"); if (!portp->isFuncReturn()) nodep->v3error("Not marked as function return var");
if (nodep->dpiImport() || nodep->dpiExport()) { if (nodep->dpiImport() || nodep->dpiExport()) {
AstBasicDType* bdtypep = portp->dtypep()->basicp(); AstBasicDType* const bdtypep = portp->dtypep()->basicp();
if (!bdtypep->isDpiPrimitive()) { if (!bdtypep->isDpiPrimitive()) {
if (bdtypep->isDpiBitVec() && portp->width() > 32) { if (bdtypep->isDpiBitVec() && portp->width() > 32) {
portp->v3error("DPI function may not return a > 32 bits wide type " portp->v3error("DPI function may not return a > 32 bits wide type "
@ -1190,7 +1193,7 @@ private:
string suffix; // So, make them unique string suffix; // So, make them unique
if (!nodep->taskPublic() && !nodep->classMethod()) suffix = "_" + m_scopep->nameDotless(); if (!nodep->taskPublic() && !nodep->classMethod()) suffix = "_" + m_scopep->nameDotless();
const string name = ((nodep->name() == "new") ? "new" : prefix + nodep->name() + suffix); const string name = ((nodep->name() == "new") ? "new" : prefix + nodep->name() + suffix);
AstCFunc* cfuncp = new AstCFunc( AstCFunc* const cfuncp = new AstCFunc(
nodep->fileline(), name, m_scopep, nodep->fileline(), name, m_scopep,
((nodep->taskPublic() && rtnvarp) ? rtnvarp->cPubArgType(true, true) : "")); ((nodep->taskPublic() && rtnvarp) ? rtnvarp->cPubArgType(true, true) : ""));
// It's ok to combine imports because this is just a wrapper; // It's ok to combine imports because this is just a wrapper;
@ -1211,7 +1214,7 @@ private:
cfuncp->pure(nodep->pure()); cfuncp->pure(nodep->pure());
if (nodep->name() == "new") { if (nodep->name() == "new") {
cfuncp->isConstructor(true); cfuncp->isConstructor(true);
AstClass* classp = m_statep->getClassp(nodep); AstClass* const classp = m_statep->getClassp(nodep);
if (classp->extendsp()) { if (classp->extendsp()) {
cfuncp->ctorInits(EmitCBaseVisitor::prefixNameProtect(classp->extendsp()->classp()) cfuncp->ctorInits(EmitCBaseVisitor::prefixNameProtect(classp->extendsp()->classp())
+ "(vlSymsp)"); + "(vlSymsp)");
@ -1235,7 +1238,7 @@ private:
} }
if (nodep->dpiExport()) { if (nodep->dpiExport()) {
AstScopeName* snp = nodep->scopeNamep(); AstScopeName* const snp = nodep->scopeNamep();
UASSERT_OBJ(snp, nodep, "Missing scoping context"); UASSERT_OBJ(snp, nodep, "Missing scoping context");
snp->dpiExport( snp->dpiExport(
true); // The AstScopeName is really a statement(ish) for tracking, not a function true); // The AstScopeName is really a statement(ish) for tracking, not a function
@ -1246,7 +1249,7 @@ private:
// Create list of arguments and move to function // Create list of arguments and move to function
for (AstNode *nextp, *stmtp = nodep->stmtsp(); stmtp; stmtp = nextp) { for (AstNode *nextp, *stmtp = nodep->stmtsp(); stmtp; stmtp = nextp) {
nextp = stmtp->nextp(); nextp = stmtp->nextp();
if (AstVar* portp = VN_CAST(stmtp, Var)) { if (AstVar* const portp = VN_CAST(stmtp, Var)) {
if (portp->isParam() && VN_IS(portp->valuep(), InitArray)) { if (portp->isParam() && VN_IS(portp->valuep(), InitArray)) {
// Move array parameters in functions into constant pool // Move array parameters in functions into constant pool
portp->unlinkFrBack(); portp->unlinkFrBack();
@ -1264,7 +1267,8 @@ private:
// "Normal" variable, mark inside function // "Normal" variable, mark inside function
portp->funcLocal(true); portp->funcLocal(true);
} }
AstVarScope* newvscp = new AstVarScope{portp->fileline(), m_scopep, portp}; AstVarScope* const newvscp
= new AstVarScope{portp->fileline(), m_scopep, portp};
m_scopep->addVarp(newvscp); m_scopep->addVarp(newvscp);
portp->user2p(newvscp); portp->user2p(newvscp);
} }
@ -1278,7 +1282,7 @@ private:
if (rtnvarp) cfuncp->addArgsp(rtnvarp); if (rtnvarp) cfuncp->addArgsp(rtnvarp);
// Move body // Move body
AstNode* bodysp = nodep->stmtsp(); AstNode* const bodysp = nodep->stmtsp();
if (bodysp) { if (bodysp) {
bodysp->unlinkFrBackWithNext(); bodysp->unlinkFrBackWithNext();
cfuncp->addStmtsp(bodysp); cfuncp->addStmtsp(bodysp);
@ -1293,8 +1297,8 @@ private:
// Replace variable refs // Replace variable refs
// Iteration requires a back, so put under temporary node // Iteration requires a back, so put under temporary node
{ {
AstBegin* tempp = new AstBegin(cfuncp->fileline(), "[EditWrapper]", cfuncp); AstBegin* const tempp = new AstBegin(cfuncp->fileline(), "[EditWrapper]", cfuncp);
TaskRelinkVisitor visitor{tempp}; const TaskRelinkVisitor visitor{tempp};
tempp->stmtsp()->unlinkFrBackWithNext(); tempp->stmtsp()->unlinkFrBackWithNext();
VL_DO_DANGLING(tempp->deleteTree(), tempp); VL_DO_DANGLING(tempp->deleteTree(), tempp);
} }
@ -1367,7 +1371,7 @@ private:
m_insStmtp->addNextHere(newp); m_insStmtp->addNextHere(newp);
} else if (m_insMode == IM_WHILE_PRECOND) { } else if (m_insMode == IM_WHILE_PRECOND) {
UINFO(5, " IM_While_Precond " << m_insStmtp << endl); UINFO(5, " IM_While_Precond " << m_insStmtp << endl);
AstWhile* whilep = VN_AS(m_insStmtp, While); AstWhile* const whilep = VN_AS(m_insStmtp, While);
UASSERT_OBJ(whilep, nodep, "Insert should be under WHILE"); UASSERT_OBJ(whilep, nodep, "Insert should be under WHILE");
whilep->addPrecondsp(newp); whilep->addPrecondsp(newp);
visitp = newp; visitp = newp;
@ -1430,7 +1434,7 @@ private:
visitp = insertBeforeStmt(nodep, beginp); visitp = insertBeforeStmt(nodep, beginp);
} else if (!nodep->isStatement()) { } else if (!nodep->isStatement()) {
UASSERT_OBJ(nodep->taskp()->isFunction(), nodep, "func reference to non-function"); UASSERT_OBJ(nodep->taskp()->isFunction(), nodep, "func reference to non-function");
AstVarRef* outrefp = new AstVarRef(nodep->fileline(), outvscp, VAccess::READ); AstVarRef* const outrefp = new AstVarRef(nodep->fileline(), outvscp, VAccess::READ);
nodep->replaceWith(outrefp); nodep->replaceWith(outrefp);
// Insert new statements // Insert new statements
visitp = insertBeforeStmt(nodep, beginp); visitp = insertBeforeStmt(nodep, beginp);
@ -1482,10 +1486,10 @@ private:
if (m_statep->ftaskNoInline(nodep) && !nodep->classMethod()) { if (m_statep->ftaskNoInline(nodep) && !nodep->classMethod()) {
m_statep->checkPurity(nodep); m_statep->checkPurity(nodep);
} }
AstNodeFTask* clonedFuncp = nodep->cloneTree(false); AstNodeFTask* const clonedFuncp = nodep->cloneTree(false);
if (nodep->isConstructor()) m_statep->remapFuncClassp(nodep, clonedFuncp); if (nodep->isConstructor()) m_statep->remapFuncClassp(nodep, clonedFuncp);
AstCFunc* cfuncp = makeUserFunc(clonedFuncp, m_statep->ftaskNoInline(nodep)); AstCFunc* const cfuncp = makeUserFunc(clonedFuncp, m_statep->ftaskNoInline(nodep));
if (cfuncp) { if (cfuncp) {
nodep->addNextHere(cfuncp); nodep->addNextHere(cfuncp);
if (nodep->dpiImport() || m_statep->ftaskNoInline(nodep)) { if (nodep->dpiImport() || m_statep->ftaskNoInline(nodep)) {
@ -1498,16 +1502,16 @@ private:
// Any variables inside the function still have varscopes pointing to them. // Any variables inside the function still have varscopes pointing to them.
// We're going to delete the vars, so delete the varscopes. // We're going to delete the vars, so delete the varscopes.
if (nodep->isFunction()) { if (nodep->isFunction()) {
if (AstVar* portp = VN_CAST(nodep->fvarp(), Var)) { if (AstVar* const portp = VN_CAST(nodep->fvarp(), Var)) {
AstVarScope* vscp = m_statep->findVarScope(m_scopep, portp); AstVarScope* const vscp = m_statep->findVarScope(m_scopep, portp);
UINFO(9, " funcremovevsc " << vscp << endl); UINFO(9, " funcremovevsc " << vscp << endl);
VL_DO_DANGLING(pushDeletep(vscp->unlinkFrBack()), vscp); VL_DO_DANGLING(pushDeletep(vscp->unlinkFrBack()), vscp);
} }
} }
for (AstNode *nextp, *stmtp = nodep->stmtsp(); stmtp; stmtp = nextp) { for (AstNode *nextp, *stmtp = nodep->stmtsp(); stmtp; stmtp = nextp) {
nextp = stmtp->nextp(); nextp = stmtp->nextp();
if (AstVar* portp = VN_CAST(stmtp, Var)) { if (AstVar* const portp = VN_CAST(stmtp, Var)) {
AstVarScope* vscp = m_statep->findVarScope(m_scopep, portp); AstVarScope* const vscp = m_statep->findVarScope(m_scopep, portp);
UINFO(9, " funcremovevsc " << vscp << endl); UINFO(9, " funcremovevsc " << vscp << endl);
VL_DO_DANGLING(pushDeletep(vscp->unlinkFrBack()), vscp); VL_DO_DANGLING(pushDeletep(vscp->unlinkFrBack()), vscp);
} }
@ -1578,7 +1582,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
int tpinnum = 0; int tpinnum = 0;
AstVar* sformatp = nullptr; AstVar* sformatp = nullptr;
for (AstNode* stmtp = taskStmtsp; stmtp; stmtp = stmtp->nextp()) { for (AstNode* stmtp = taskStmtsp; stmtp; stmtp = stmtp->nextp()) {
if (AstVar* portp = VN_CAST(stmtp, Var)) { if (AstVar* const portp = VN_CAST(stmtp, Var)) {
if (portp->isIO()) { if (portp->isIO()) {
tconnects.push_back(std::make_pair(portp, static_cast<AstArg*>(nullptr))); tconnects.push_back(std::make_pair(portp, static_cast<AstArg*>(nullptr)));
nameToIndex.insert( nameToIndex.insert(
@ -1599,7 +1603,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
bool reorganize = false; bool reorganize = false;
for (AstNode *nextp, *pinp = nodep->pinsp(); pinp; pinp = nextp) { for (AstNode *nextp, *pinp = nodep->pinsp(); pinp; pinp = nextp) {
nextp = pinp->nextp(); nextp = pinp->nextp();
AstArg* argp = VN_AS(pinp, Arg); AstArg* const argp = VN_AS(pinp, Arg);
UASSERT_OBJ(argp, pinp, "Non-arg under ftask reference"); UASSERT_OBJ(argp, pinp, "Non-arg under ftask reference");
if (argp->name() != "") { if (argp->name() != "") {
// By name // By name
@ -1640,7 +1644,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
// Connect missing ones // Connect missing ones
for (int i = 0; i < tpinnum; ++i) { for (int i = 0; i < tpinnum; ++i) {
AstVar* portp = tconnects[i].first; AstVar* const portp = tconnects[i].first;
if (!tconnects[i].second || !tconnects[i].second->exprp()) { if (!tconnects[i].second || !tconnects[i].second->exprp()) {
AstNode* newvaluep = nullptr; AstNode* newvaluep = nullptr;
if (!portp->valuep()) { if (!portp->valuep()) {
@ -1671,7 +1675,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
// To avoid problems with callee needing to know to deleteTree // To avoid problems with callee needing to know to deleteTree
// or not, we make this into a pin // or not, we make this into a pin
UINFO(9, "Default pin for " << portp << endl); UINFO(9, "Default pin for " << portp << endl);
AstArg* newp = new AstArg(nodep->fileline(), portp->name(), newvaluep); AstArg* const newp = new AstArg(nodep->fileline(), portp->name(), newvaluep);
if (tconnects[i].second) { // Have a "nullptr" pin already defined for it if (tconnects[i].second) { // Have a "nullptr" pin already defined for it
VL_DO_CLEAR(tconnects[i].second->unlinkFrBack()->deleteTree(), VL_DO_CLEAR(tconnects[i].second->unlinkFrBack()->deleteTree(),
tconnects[i].second = nullptr); tconnects[i].second = nullptr);
@ -1693,7 +1697,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
nodep->pinsp()->unlinkFrBack(); nodep->pinsp()->unlinkFrBack();
} }
for (int i = 0; i < tpinnum; ++i) { for (int i = 0; i < tpinnum; ++i) {
AstArg* argp = tconnects[i].second; AstArg* const argp = tconnects[i].second;
UASSERT_OBJ(argp, nodep, "Lost argument in func conversion"); UASSERT_OBJ(argp, nodep, "Lost argument in func conversion");
nodep->addPinsp(argp); nodep->addPinsp(argp);
} }
@ -1721,7 +1725,8 @@ string V3Task::assignInternalToDpi(AstVar* portp, bool isPtr, const string& frSu
const string toName = portp->name() + toSuffix; const string toName = portp->name() + toSuffix;
size_t unpackSize = 1; // non-unpacked array is treated as size 1 size_t unpackSize = 1; // non-unpacked array is treated as size 1
int unpackDim = 0; int unpackDim = 0;
if (AstUnpackArrayDType* unpackp = VN_CAST(portp->dtypep()->skipRefp(), UnpackArrayDType)) { if (AstUnpackArrayDType* const unpackp
= VN_CAST(portp->dtypep()->skipRefp(), UnpackArrayDType)) {
unpackSize = unpackp->arrayUnpackedElements(); unpackSize = unpackp->arrayUnpackedElements();
unpackDim = unpackp->dimensions(false).second; unpackDim = unpackp->dimensions(false).second;
if (unpackDim > 0) UASSERT_OBJ(unpackSize > 0, portp, "size must be greater than 0"); if (unpackDim > 0) UASSERT_OBJ(unpackSize > 0, portp, "size must be greater than 0");
@ -1825,7 +1830,7 @@ void V3Task::taskAll(AstNetlist* nodep) {
UINFO(2, __FUNCTION__ << ": " << endl); UINFO(2, __FUNCTION__ << ": " << endl);
{ {
TaskStateVisitor visitors{nodep}; TaskStateVisitor visitors{nodep};
TaskVisitor visitor{nodep, &visitors}; const TaskVisitor visitor{nodep, &visitors};
} // Destruct before checking } // Destruct before checking
V3Global::dumpCheckGlobalTree("task", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3); V3Global::dumpCheckGlobalTree("task", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
} }

View File

@ -215,7 +215,7 @@ private:
// Find if there are any duplicates // Find if there are any duplicates
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) { for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp = itp->verticesNextp()) {
if (TraceTraceVertex* const vvertexp = dynamic_cast<TraceTraceVertex*>(itp)) { if (TraceTraceVertex* const vvertexp = dynamic_cast<TraceTraceVertex*>(itp)) {
AstTraceDecl* const nodep = vvertexp->nodep(); const AstTraceDecl* const nodep = vvertexp->nodep();
if (nodep->valuep() && !vvertexp->duplicatep()) { if (nodep->valuep() && !vvertexp->duplicatep()) {
const auto dupit = dupFinder.findDuplicate(nodep->valuep()); const auto dupit = dupFinder.findDuplicate(nodep->valuep());
if (dupit != dupFinder.end()) { if (dupit != dupFinder.end()) {
@ -387,7 +387,7 @@ private:
for (; it != end && it->first == actSet; ++it) { for (; it != end && it->first == actSet; ++it) {
if (!it->second->duplicatep()) { if (!it->second->duplicatep()) {
uint32_t cost = 0; uint32_t cost = 0;
AstTraceDecl* const declp = it->second->nodep(); const AstTraceDecl* const declp = it->second->nodep();
// The number of comparisons required by tracep->chg* // The number of comparisons required by tracep->chg*
cost += declp->isWide() ? declp->codeInc() : 1; cost += declp->isWide() ? declp->codeInc() : 1;
// Arrays are traced by element // Arrays are traced by element
@ -532,7 +532,7 @@ private:
} }
} }
// Add call to top function // Add call to top function
AstCCall* callp = new AstCCall(funcp->fileline(), funcp); AstCCall* const callp = new AstCCall(funcp->fileline(), funcp);
callp->argTypes("tracep"); callp->argTypes("tracep");
topFuncp->addStmtsp(callp); topFuncp->addStmtsp(callp);
} }
@ -562,7 +562,7 @@ private:
// This is a duplicate trace node. We will assign the signal // This is a duplicate trace node. We will assign the signal
// number to the canonical node, and emit this as an alias, so // number to the canonical node, and emit this as an alias, so
// no need to create a TraceInc node. // no need to create a TraceInc node.
AstTraceDecl* const canonDeclp = canonVtxp->nodep(); const AstTraceDecl* const canonDeclp = canonVtxp->nodep();
UASSERT_OBJ(!canonVtxp->duplicatep(), canonDeclp, UASSERT_OBJ(!canonVtxp->duplicatep(), canonDeclp,
"Canonical node is a duplicate"); "Canonical node is a duplicate");
UASSERT_OBJ(canonDeclp->code() != 0, canonDeclp, UASSERT_OBJ(canonDeclp->code() != 0, canonDeclp,

Some files were not shown because too many files have changed in this diff Show More