Internals: Improve astgen type enums to be switch statement friendly (#6362)

- Remove _ENUM_END, so -Wswitch does not demand it's covered. Use the
  new NUM_TYPES constexpr member instead.
- Remove 'at' prefix. This seems historical and is not particularly  useful.
- Fix some cppcheck warts while at it
This commit is contained in:
Geza Lore 2025-09-03 13:56:11 +01:00 committed by GitHub
parent 8bf2240d40
commit 5161cea8cd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 119 additions and 124 deletions

View File

@ -52,7 +52,7 @@ int AstNodeDType::s_uniqueNum = 0;
//###################################################################### //######################################################################
// VNType // VNType
const VNTypeInfo VNType::typeInfoTable[] = { const VNTypeInfo VNType::s_typeInfoTable[VNType::NUM_TYPES()] = {
#include "V3Ast__gen_type_info.h" // From ./astgen #include "V3Ast__gen_type_info.h" // From ./astgen
}; };
@ -1162,8 +1162,7 @@ bool AstNode::sameTreeIter(const AstNode* node1p, const AstNode* node2p, bool ig
void AstNode::checkTreeIter(const AstNode* prevBackp) const VL_MT_STABLE { void AstNode::checkTreeIter(const AstNode* prevBackp) const VL_MT_STABLE {
// private: Check a tree and children // private: Check a tree and children
UASSERT_OBJ(prevBackp == this->backp(), this, "Back node inconsistent"); UASSERT_OBJ(prevBackp == this->backp(), this, "Back node inconsistent");
// cppcheck-suppress danglingTempReference const VNTypeInfo& typeInfo = VNType::typeInfo(this->type());
const VNTypeInfo& typeInfo = *type().typeInfo();
for (int i = 1; i <= 4; i++) { for (int i = 1; i <= 4; i++) {
AstNode* nodep = nullptr; AstNode* nodep = nullptr;
switch (i) { switch (i) {

View File

@ -109,22 +109,20 @@ struct VNTypeInfo final {
}; };
class VNType final { class VNType final {
static const VNTypeInfo typeInfoTable[]; static const VNTypeInfo s_typeInfoTable[];
public: public:
#include "V3Ast__gen_type_enum.h" // From ./astgen #include "V3Ast__gen_type_enum.h" // From ./astgen
// Above include has: const en m_e;
// enum en {...};
// const char* ascii() const {...};
const enum en m_e;
VNType() = delete; VNType() = delete;
// VNType is interconvetible with VNType::en
// cppcheck-suppress noExplicitConstructor // cppcheck-suppress noExplicitConstructor
constexpr VNType(en _e) VL_MT_SAFE : m_e{_e} {} constexpr VNType(en _e) VL_MT_SAFE : m_e{_e} {}
explicit VNType(int _e)
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
// cppcheck-suppress danglingTempReference
const VNTypeInfo* typeInfo() const VL_MT_SAFE { return &typeInfoTable[m_e]; }
constexpr operator en() const VL_MT_SAFE { return m_e; } constexpr operator en() const VL_MT_SAFE { return m_e; }
// Retrieve VNTypeInfo for the given type
static const VNTypeInfo& typeInfo(VNType t) VL_MT_SAFE { return s_typeInfoTable[t.m_e]; }
}; };
constexpr bool operator==(const VNType& lhs, const VNType& rhs) VL_PURE { constexpr bool operator==(const VNType& lhs, const VNType& rhs) VL_PURE {
return lhs.m_e == rhs.m_e; return lhs.m_e == rhs.m_e;

View File

@ -387,9 +387,9 @@ static AstNode* createForeachLoop(AstNodeForeach* nodep, AstNode* bodysp, AstVar
AstNodeExpr* condp; AstNodeExpr* condp;
bool inc = true; bool inc = true;
switch (nodeType) { switch (nodeType) {
case VNType::atLteS: condp = new AstLteS{fl, varRefp, rightp}; break; case VNType::LteS: condp = new AstLteS{fl, varRefp, rightp}; break;
case VNType::atLt: condp = new AstLt{fl, varRefp, rightp}; break; case VNType::Lt: condp = new AstLt{fl, varRefp, rightp}; break;
case VNType::atGteS: case VNType::GteS:
condp = new AstGteS{fl, varRefp, rightp}; condp = new AstGteS{fl, varRefp, rightp};
inc = false; inc = false;
break; break;
@ -419,8 +419,7 @@ static AstNode* createForeachLoopRanged(AstNodeForeach* nodep, AstNode* bodysp,
AstNodeExpr* const leftp = new AstConst{fl, left}; AstNodeExpr* const leftp = new AstConst{fl, left};
AstNodeExpr* const rightp = new AstConst{fl, right}; AstNodeExpr* const rightp = new AstConst{fl, right};
return createForeachLoop(nodep, bodysp, varp, leftp, rightp, return createForeachLoop(nodep, bodysp, varp, leftp, rightp,
declRange.left() <= declRange.right() ? VNType::atLteS declRange.left() <= declRange.right() ? VNType::LteS : VNType::GteS);
: VNType::atGteS);
} }
AstNode* V3Begin::convertToWhile(AstForeach* nodep) { AstNode* V3Begin::convertToWhile(AstForeach* nodep) {
// UINFOTREE(1, nodep, "", "foreach-old"); // UINFOTREE(1, nodep, "", "foreach-old");
@ -459,8 +458,7 @@ AstNode* V3Begin::convertToWhile(AstForeach* nodep) {
if (adtypep->isString()) { if (adtypep->isString()) {
AstConst* const leftp = new AstConst{fl, 0}; AstConst* const leftp = new AstConst{fl, 0};
AstNodeExpr* const rightp = new AstLenN{fl, fromp->cloneTreePure(false)}; AstNodeExpr* const rightp = new AstLenN{fl, fromp->cloneTreePure(false)};
loopp loopp = createForeachLoop(nodep, bodyPointp, varp, leftp, rightp, VNType::Lt);
= createForeachLoop(nodep, bodyPointp, varp, leftp, rightp, VNType::atLt);
} else { } else {
UASSERT_OBJ(adtypep->isRanged(), varp, "foreach on basic " << adtypep); UASSERT_OBJ(adtypep->isRanged(), varp, "foreach on basic " << adtypep);
loopp = createForeachLoopRanged(nodep, bodyPointp, varp, adtypep->declRange()); loopp = createForeachLoopRanged(nodep, bodyPointp, varp, adtypep->declRange());
@ -479,7 +477,7 @@ AstNode* V3Begin::convertToWhile(AstForeach* nodep) {
subfromp->dtypep(fromDtp); subfromp->dtypep(fromDtp);
rightp->dtypeSetSigned32(); rightp->dtypeSetSigned32();
rightp->protect(false); rightp->protect(false);
loopp = createForeachLoop(nodep, bodyPointp, varp, leftp, rightp, VNType::atLt); loopp = createForeachLoop(nodep, bodyPointp, varp, leftp, rightp, VNType::Lt);
} else if (VN_IS(fromDtp, AssocArrayDType)) { } else if (VN_IS(fromDtp, AssocArrayDType)) {
// Make this: var KEY_TYPE index; // Make this: var KEY_TYPE index;
// bit index__Vfirst; // bit index__Vfirst;

View File

@ -177,7 +177,7 @@ class CCtorsVisitor final : public VNVisitor {
// If can be referred to by base pointer, need virtual delete // If can be referred to by base pointer, need virtual delete
funcp->isVirtual(classp->isExtended()); funcp->isVirtual(classp->isExtended());
funcp->slow(false); funcp->slow(false);
insertSc(funcp, classp, VNType::atScDtor); insertSc(funcp, classp, VNType::ScDtor);
classp->addStmtsp(funcp); classp->addStmtsp(funcp);
} }
} }
@ -188,7 +188,7 @@ class CCtorsVisitor final : public VNVisitor {
m_varResetp = nullptr; m_varResetp = nullptr;
m_cfuncp = nodep; m_cfuncp = nodep;
iterateChildren(nodep); iterateChildren(nodep);
if (nodep->name() == "new") insertSc(nodep, m_modp, VNType::atScCtor); if (nodep->name() == "new") insertSc(nodep, m_modp, VNType::ScCtor);
} }
void visit(AstVar* nodep) override { void visit(AstVar* nodep) override {
if (nodep->needsCReset()) { if (nodep->needsCReset()) {

View File

@ -81,7 +81,7 @@ std::unique_ptr<DfgGraph> DfgGraph::clone() const {
DfgVertexVar* cp = nullptr; DfgVertexVar* cp = nullptr;
switch (vtx.type()) { switch (vtx.type()) {
case VDfgType::atVarArray: { case VDfgType::VarArray: {
if (scoped) { if (scoped) {
cp = new DfgVarArray{*clonep, vp->varScopep()}; cp = new DfgVarArray{*clonep, vp->varScopep()};
} else { } else {
@ -90,7 +90,7 @@ std::unique_ptr<DfgGraph> DfgGraph::clone() const {
vtxp2clonep.emplace(&vtx, cp); vtxp2clonep.emplace(&vtx, cp);
break; break;
} }
case VDfgType::atVarPacked: { case VDfgType::VarPacked: {
if (scoped) { if (scoped) {
cp = new DfgVarPacked{*clonep, vp->varScopep()}; cp = new DfgVarPacked{*clonep, vp->varScopep()};
} else { } else {
@ -112,38 +112,38 @@ std::unique_ptr<DfgGraph> DfgGraph::clone() const {
for (const DfgVertex& vtx : m_opVertices) { for (const DfgVertex& vtx : m_opVertices) {
switch (vtx.type()) { switch (vtx.type()) {
#include "V3Dfg__gen_clone_cases.h" // From ./astgen #include "V3Dfg__gen_clone_cases.h" // From ./astgen
case VDfgType::atSel: { case VDfgType::Sel: {
DfgSel* const cp = new DfgSel{*clonep, vtx.fileline(), vtx.dtypep()}; DfgSel* const cp = new DfgSel{*clonep, vtx.fileline(), vtx.dtypep()};
cp->lsb(vtx.as<DfgSel>()->lsb()); cp->lsb(vtx.as<DfgSel>()->lsb());
vtxp2clonep.emplace(&vtx, cp); vtxp2clonep.emplace(&vtx, cp);
break; break;
} }
case VDfgType::atUnitArray: { case VDfgType::UnitArray: {
DfgUnitArray* const cp = new DfgUnitArray{*clonep, vtx.fileline(), vtx.dtypep()}; DfgUnitArray* const cp = new DfgUnitArray{*clonep, vtx.fileline(), vtx.dtypep()};
vtxp2clonep.emplace(&vtx, cp); vtxp2clonep.emplace(&vtx, cp);
break; break;
} }
case VDfgType::atMux: { case VDfgType::Mux: {
DfgMux* const cp = new DfgMux{*clonep, vtx.fileline(), vtx.dtypep()}; DfgMux* const cp = new DfgMux{*clonep, vtx.fileline(), vtx.dtypep()};
vtxp2clonep.emplace(&vtx, cp); vtxp2clonep.emplace(&vtx, cp);
break; break;
} }
case VDfgType::atSpliceArray: { case VDfgType::SpliceArray: {
DfgSpliceArray* const cp = new DfgSpliceArray{*clonep, vtx.fileline(), vtx.dtypep()}; DfgSpliceArray* const cp = new DfgSpliceArray{*clonep, vtx.fileline(), vtx.dtypep()};
vtxp2clonep.emplace(&vtx, cp); vtxp2clonep.emplace(&vtx, cp);
break; break;
} }
case VDfgType::atSplicePacked: { case VDfgType::SplicePacked: {
DfgSplicePacked* const cp = new DfgSplicePacked{*clonep, vtx.fileline(), vtx.dtypep()}; DfgSplicePacked* const cp = new DfgSplicePacked{*clonep, vtx.fileline(), vtx.dtypep()};
vtxp2clonep.emplace(&vtx, cp); vtxp2clonep.emplace(&vtx, cp);
break; break;
} }
case VDfgType::atLogic: { case VDfgType::Logic: {
vtx.v3fatalSrc("DfgLogic cannot be cloned"); vtx.v3fatalSrc("DfgLogic cannot be cloned");
VL_UNREACHABLE; VL_UNREACHABLE;
break; break;
} }
case VDfgType::atUnresolved: { case VDfgType::Unresolved: {
vtx.v3fatalSrc("DfgUnresolved cannot be cloned"); vtx.v3fatalSrc("DfgUnresolved cannot be cloned");
VL_UNREACHABLE; VL_UNREACHABLE;
break; break;
@ -168,8 +168,8 @@ std::unique_ptr<DfgGraph> DfgGraph::clone() const {
for (const DfgVertex& vtx : m_opVertices) { for (const DfgVertex& vtx : m_opVertices) {
if (vtx.is<DfgVertexVariadic>()) { if (vtx.is<DfgVertexVariadic>()) {
switch (vtx.type()) { switch (vtx.type()) {
case VDfgType::atSpliceArray: case VDfgType::SpliceArray:
case VDfgType::atSplicePacked: { case VDfgType::SplicePacked: {
const DfgVertexSplice* const vp = vtx.as<DfgVertexSplice>(); const DfgVertexSplice* const vp = vtx.as<DfgVertexSplice>();
DfgVertexSplice* const cp = vtxp2clonep.at(vp)->as<DfgVertexSplice>(); DfgVertexSplice* const cp = vtxp2clonep.at(vp)->as<DfgVertexSplice>();
vp->foreachDriver([&](const DfgVertex& src, uint32_t lo, FileLine* flp) { vp->foreachDriver([&](const DfgVertex& src, uint32_t lo, FileLine* flp) {

View File

@ -150,8 +150,10 @@ inline AstNodeDType* toDfgDType(const AstNodeDType* dtypep) {
class VDfgType final { class VDfgType final {
public: public:
#include "V3Dfg__gen_type_enum.h" // From ./astgen #include "V3Dfg__gen_type_enum.h" // From ./astgen
const enum en m_e; const en m_e;
VDfgType() = delete; VDfgType() = delete;
// VDfgType is interconvetible with VDfgType::en
// cppcheck-suppress noExplicitConstructor // cppcheck-suppress noExplicitConstructor
constexpr VDfgType(en _e) constexpr VDfgType(en _e)
: m_e{_e} {} : m_e{_e} {}

View File

@ -564,7 +564,7 @@ class EmitCHeader final : public EmitCConstInit {
puts("\nclass " + EmitCUtil::symClassName() + ";\n"); puts("\nclass " + EmitCUtil::symClassName() + ";\n");
// From `systemc_header // From `systemc_header
emitTextSection(modp, VNType::atScHdr); emitTextSection(modp, VNType::ScHdr);
emitStructs(modp); emitStructs(modp);
@ -607,7 +607,7 @@ class EmitCHeader final : public EmitCConstInit {
emitFuncDecls(modp, /* inClassBody: */ true); emitFuncDecls(modp, /* inClassBody: */ true);
// From `systemc_interface // From `systemc_interface
emitTextSection(modp, VNType::atScInt); emitTextSection(modp, VNType::ScInt);
// Close class body // Close class body
puts("};\n"); puts("};\n");
@ -616,7 +616,7 @@ class EmitCHeader final : public EmitCConstInit {
// Emit out of class function declarations // Emit out of class function declarations
puts("\n"); puts("\n");
emitFuncDecls(modp, /* inClassBody: */ false); emitFuncDecls(modp, /* inClassBody: */ false);
emitTextSection(modp, VNType::atScHdrPost); emitTextSection(modp, VNType::ScHdrPost);
} }
explicit EmitCHeader(const AstNodeModule* modp) { explicit EmitCHeader(const AstNodeModule* modp) {

View File

@ -200,7 +200,7 @@ class EmitCImp final : EmitCFunc {
puts("#include \"" + EmitCUtil::pchClassName() + ".h\"\n"); puts("#include \"" + EmitCUtil::pchClassName() + ".h\"\n");
for (const string& name : headers) puts("#include \"" + name + ".h\"\n"); for (const string& name : headers) puts("#include \"" + name + ".h\"\n");
emitTextSection(m_modp, VNType::atScImpHdr); emitTextSection(m_modp, VNType::ScImpHdr);
} }
void emitStaticVarDefns(const AstNodeModule* modp) { void emitStaticVarDefns(const AstNodeModule* modp) {
@ -286,7 +286,7 @@ class EmitCImp final : EmitCFunc {
putsDecoration(modp, "// Reset structure values\n"); putsDecoration(modp, "// Reset structure values\n");
puts(modName + "__" + protect("_ctor_var_reset") + "(this);\n"); puts(modName + "__" + protect("_ctor_var_reset") + "(this);\n");
emitTextSection(modp, VNType::atScCtor); emitTextSection(modp, VNType::ScCtor);
puts("}\n"); puts("}\n");
} }
@ -393,7 +393,7 @@ class EmitCImp final : EmitCFunc {
puts("\n"); puts("\n");
putns(modp, EmitCUtil::prefixNameProtect(modp) + "::~" + EmitCUtil::prefixNameProtect(modp) putns(modp, EmitCUtil::prefixNameProtect(modp) + "::~" + EmitCUtil::prefixNameProtect(modp)
+ "() {\n"); + "() {\n");
emitTextSection(modp, VNType::atScDtor); emitTextSection(modp, VNType::ScDtor);
puts("}\n"); puts("}\n");
splitSizeInc(10); splitSizeInc(10);
} }
@ -507,7 +507,7 @@ class EmitCImp final : EmitCFunc {
emitSavableImp(modp); emitSavableImp(modp);
} else { } else {
// From `systemc_implementation // From `systemc_implementation
emitTextSection(modp, VNType::atScImp); emitTextSection(modp, VNType::ScImp);
} }
} }
void emitCommonImp(const AstNodeModule* modp) { void emitCommonImp(const AstNodeModule* modp) {

View File

@ -350,12 +350,12 @@ class SliceVisitor final : public VNVisitor {
logp = clonep; logp = clonep;
} else { } else {
switch (nodep->type()) { switch (nodep->type()) {
case VNType::atEq: // FALLTHRU case VNType::Eq: // FALLTHRU
case VNType::atEqCase: case VNType::EqCase:
logp = new AstLogAnd{nodep->fileline(), logp, clonep}; logp = new AstLogAnd{nodep->fileline(), logp, clonep};
break; break;
case VNType::atNeq: // FALLTHRU case VNType::Neq: // FALLTHRU
case VNType::atNeqCase: case VNType::NeqCase:
logp = new AstLogOr{nodep->fileline(), logp, clonep}; logp = new AstLogOr{nodep->fileline(), logp, clonep};
break; break;
default: nodep->v3fatalSrc("Unknown node type processing array slice"); break; default: nodep->v3fatalSrc("Unknown node type processing array slice"); break;

View File

@ -34,11 +34,11 @@ V3Mutex V3Stats::s_mutex;
class StatsVisitor final : public VNVisitorConst { class StatsVisitor final : public VNVisitorConst {
struct Counters final { struct Counters final {
// Nodes of given type // Nodes of given type
std::array<uint64_t, VNType::_ENUM_END> m_statTypeCount = {}; std::array<uint64_t, VNType::NUM_TYPES()> m_statTypeCount{};
// Nodes of given type with given type immediate child // Nodes of given type with given type immediate child
std::array<std::array<uint64_t, VNType::_ENUM_END>, VNType::_ENUM_END> m_statAbove = {}; std::array<std::array<uint64_t, VNType::NUM_TYPES()>, VNType::NUM_TYPES()> m_statAbove{};
// Prediction of given type // Prediction of given type
std::array<uint64_t, VBranchPred::_ENUM_END> m_statPred = {}; std::array<uint64_t, VBranchPred::_ENUM_END> m_statPred{};
}; };
// STATE // STATE
@ -127,10 +127,12 @@ public:
} }
// Node types (also total memory usage) // Node types (also total memory usage)
const auto typeName = [](int type) { return std::string{VNType{type}.ascii()}; }; const auto typeName
const auto typeSize = [](int type) { return VNType{type}.typeInfo()->m_sizeof; }; = [](size_t t) { return std::string{VNType{static_cast<VNType::en>(t)}.ascii()}; };
const auto typeSize
= [](size_t t) { return VNType::typeInfo(static_cast<VNType::en>(t)).m_sizeof; };
size_t totalNodeMemoryUsage = 0; size_t totalNodeMemoryUsage = 0;
for (int t = 0; t < VNType::_ENUM_END; ++t) { for (size_t t = 0; t < VNType::NUM_TYPES(); ++t) {
if (const uint64_t count = m_counters.m_statTypeCount[t]) { if (const uint64_t count = m_counters.m_statTypeCount[t]) {
totalNodeMemoryUsage += count * typeSize(t); totalNodeMemoryUsage += count * typeSize(t);
addStat("Node count, " + typeName(t), count); addStat("Node count, " + typeName(t), count);
@ -139,7 +141,7 @@ public:
addStat("Node memory TOTAL (MiB)", totalNodeMemoryUsage >> 20); addStat("Node memory TOTAL (MiB)", totalNodeMemoryUsage >> 20);
// Node Memory usage // Node Memory usage
for (int t = 0; t < VNType::_ENUM_END; ++t) { for (size_t t = 0; t < VNType::NUM_TYPES(); ++t) {
if (const uint64_t count = m_counters.m_statTypeCount[t]) { if (const uint64_t count = m_counters.m_statTypeCount[t]) {
const double share = 100.0 * count * typeSize(t) / totalNodeMemoryUsage; const double share = 100.0 * count * typeSize(t) / totalNodeMemoryUsage;
addStat("Node memory share (%), " + typeName(t), share, 2); addStat("Node memory share (%), " + typeName(t), share, 2);
@ -147,8 +149,8 @@ public:
} }
// Expression combinations // Expression combinations
for (int t1 = 0; t1 < VNType::_ENUM_END; ++t1) { for (size_t t1 = 0; t1 < VNType::NUM_TYPES(); ++t1) {
for (int t2 = 0; t2 < VNType::_ENUM_END; ++t2) { for (size_t t2 = 0; t2 < VNType::NUM_TYPES(); ++t2) {
if (const uint64_t c = m_counters.m_statAbove[t1][t2]) { if (const uint64_t c = m_counters.m_statAbove[t1][t2]) {
addStat("Expr combination, " + typeName(t1) + " over " + typeName(t2), c); addStat("Expr combination, " + typeName(t1) + " over " + typeName(t2), c);
} }

View File

@ -8015,15 +8015,15 @@ class WidthVisitor final : public VNVisitor {
if (!nodep->dtypep()) nodep->dtypeFrom(nodep->lhsp()); if (!nodep->dtypep()) nodep->dtypeFrom(nodep->lhsp());
// To simplify callers, some node types don't need to change // To simplify callers, some node types don't need to change
switch (nodep->type()) { switch (nodep->type()) {
case VNType::atEq: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr; case VNType::Eq: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr;
case VNType::atNeq: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr; case VNType::Neq: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr;
case VNType::atEqCase: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr; case VNType::EqCase: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr;
case VNType::atNeqCase: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr; case VNType::NeqCase: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr;
case VNType::atEqWild: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr; case VNType::EqWild: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr;
case VNType::atNeqWild: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr; case VNType::NeqWild: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr;
case VNType::atAdd: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr; case VNType::Add: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr;
case VNType::atSub: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr; case VNType::Sub: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr;
case VNType::atShiftL: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr; case VNType::ShiftL: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr;
default: break; default: break;
} }
FileLine* const fl = nodep->fileline(); FileLine* const fl = nodep->fileline();
@ -8031,22 +8031,22 @@ class WidthVisitor final : public VNVisitor {
AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack(); AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack();
AstNodeBiop* newp = nullptr; AstNodeBiop* newp = nullptr;
switch (nodep->type()) { switch (nodep->type()) {
case VNType::atGt: newp = new AstGtS{fl, lhsp, rhsp}; break; case VNType::Gt: newp = new AstGtS{fl, lhsp, rhsp}; break;
case VNType::atGtS: newp = new AstGt{fl, lhsp, rhsp}; break; case VNType::GtS: newp = new AstGt{fl, lhsp, rhsp}; break;
case VNType::atGte: newp = new AstGteS{fl, lhsp, rhsp}; break; case VNType::Gte: newp = new AstGteS{fl, lhsp, rhsp}; break;
case VNType::atGteS: newp = new AstGte{fl, lhsp, rhsp}; break; case VNType::GteS: newp = new AstGte{fl, lhsp, rhsp}; break;
case VNType::atLt: newp = new AstLtS{fl, lhsp, rhsp}; break; case VNType::Lt: newp = new AstLtS{fl, lhsp, rhsp}; break;
case VNType::atLtS: newp = new AstLt{fl, lhsp, rhsp}; break; case VNType::LtS: newp = new AstLt{fl, lhsp, rhsp}; break;
case VNType::atLte: newp = new AstLteS{fl, lhsp, rhsp}; break; case VNType::Lte: newp = new AstLteS{fl, lhsp, rhsp}; break;
case VNType::atLteS: newp = new AstLte{fl, lhsp, rhsp}; break; case VNType::LteS: newp = new AstLte{fl, lhsp, rhsp}; break;
case VNType::atDiv: newp = new AstDivS{fl, lhsp, rhsp}; break; case VNType::Div: newp = new AstDivS{fl, lhsp, rhsp}; break;
case VNType::atDivS: newp = new AstDiv{fl, lhsp, rhsp}; break; case VNType::DivS: newp = new AstDiv{fl, lhsp, rhsp}; break;
case VNType::atModDiv: newp = new AstModDivS{fl, lhsp, rhsp}; break; case VNType::ModDiv: newp = new AstModDivS{fl, lhsp, rhsp}; break;
case VNType::atModDivS: newp = new AstModDiv{fl, lhsp, rhsp}; break; case VNType::ModDivS: newp = new AstModDiv{fl, lhsp, rhsp}; break;
case VNType::atMul: newp = new AstMulS{fl, lhsp, rhsp}; break; case VNType::Mul: newp = new AstMulS{fl, lhsp, rhsp}; break;
case VNType::atMulS: newp = new AstMul{fl, lhsp, rhsp}; break; case VNType::MulS: newp = new AstMul{fl, lhsp, rhsp}; break;
case VNType::atShiftR: newp = new AstShiftRS{fl, lhsp, rhsp}; break; case VNType::ShiftR: newp = new AstShiftRS{fl, lhsp, rhsp}; break;
case VNType::atShiftRS: newp = new AstShiftR{fl, lhsp, rhsp}; break; case VNType::ShiftRS: newp = new AstShiftR{fl, lhsp, rhsp}; break;
default: // LCOV_EXCL_LINE default: // LCOV_EXCL_LINE
nodep->v3fatalSrc("Node needs sign change, but bad case: " << nodep); nodep->v3fatalSrc("Node needs sign change, but bad case: " << nodep);
break; break;
@ -8066,25 +8066,25 @@ class WidthVisitor final : public VNVisitor {
AstNodeBiop* newp = nullptr; AstNodeBiop* newp = nullptr;
// No width change on output;... // All below have bool or double outputs // No width change on output;... // All below have bool or double outputs
switch (nodep->type()) { switch (nodep->type()) {
case VNType::atAdd: newp = new AstAddD{fl, lhsp, rhsp}; break; case VNType::Add: newp = new AstAddD{fl, lhsp, rhsp}; break;
case VNType::atSub: newp = new AstSubD{fl, lhsp, rhsp}; break; case VNType::Sub: newp = new AstSubD{fl, lhsp, rhsp}; break;
case VNType::atPow: newp = new AstPowD{fl, lhsp, rhsp}; break; case VNType::Pow: newp = new AstPowD{fl, lhsp, rhsp}; break;
case VNType::atEq: case VNType::Eq:
case VNType::atEqCase: newp = new AstEqD{fl, lhsp, rhsp}; break; case VNType::EqCase: newp = new AstEqD{fl, lhsp, rhsp}; break;
case VNType::atNeq: case VNType::Neq:
case VNType::atNeqCase: newp = new AstNeqD{fl, lhsp, rhsp}; break; case VNType::NeqCase: newp = new AstNeqD{fl, lhsp, rhsp}; break;
case VNType::atGt: case VNType::Gt:
case VNType::atGtS: newp = new AstGtD{fl, lhsp, rhsp}; break; case VNType::GtS: newp = new AstGtD{fl, lhsp, rhsp}; break;
case VNType::atGte: case VNType::Gte:
case VNType::atGteS: newp = new AstGteD{fl, lhsp, rhsp}; break; case VNType::GteS: newp = new AstGteD{fl, lhsp, rhsp}; break;
case VNType::atLt: case VNType::Lt:
case VNType::atLtS: newp = new AstLtD{fl, lhsp, rhsp}; break; case VNType::LtS: newp = new AstLtD{fl, lhsp, rhsp}; break;
case VNType::atLte: case VNType::Lte:
case VNType::atLteS: newp = new AstLteD{fl, lhsp, rhsp}; break; case VNType::LteS: newp = new AstLteD{fl, lhsp, rhsp}; break;
case VNType::atDiv: case VNType::Div:
case VNType::atDivS: newp = new AstDivD{fl, lhsp, rhsp}; break; case VNType::DivS: newp = new AstDivD{fl, lhsp, rhsp}; break;
case VNType::atMul: case VNType::Mul:
case VNType::atMulS: newp = new AstMulD{fl, lhsp, rhsp}; break; case VNType::MulS: newp = new AstMulD{fl, lhsp, rhsp}; break;
default: // LCOV_EXCL_LINE default: // LCOV_EXCL_LINE
nodep->v3fatalSrc("Node needs conversion to double, but bad case: " << nodep); nodep->v3fatalSrc("Node needs conversion to double, but bad case: " << nodep);
break; break;
@ -8105,18 +8105,18 @@ class WidthVisitor final : public VNVisitor {
AstNodeBiop* newp = nullptr; AstNodeBiop* newp = nullptr;
// No width change on output;... // All below have bool or double outputs // No width change on output;... // All below have bool or double outputs
switch (nodep->type()) { switch (nodep->type()) {
case VNType::atEq: case VNType::Eq:
case VNType::atEqCase: newp = new AstEqN{fl, lhsp, rhsp}; break; case VNType::EqCase: newp = new AstEqN{fl, lhsp, rhsp}; break;
case VNType::atNeq: case VNType::Neq:
case VNType::atNeqCase: newp = new AstNeqN{fl, lhsp, rhsp}; break; case VNType::NeqCase: newp = new AstNeqN{fl, lhsp, rhsp}; break;
case VNType::atGt: case VNType::Gt:
case VNType::atGtS: newp = new AstGtN{fl, lhsp, rhsp}; break; case VNType::GtS: newp = new AstGtN{fl, lhsp, rhsp}; break;
case VNType::atGte: case VNType::Gte:
case VNType::atGteS: newp = new AstGteN{fl, lhsp, rhsp}; break; case VNType::GteS: newp = new AstGteN{fl, lhsp, rhsp}; break;
case VNType::atLt: case VNType::Lt:
case VNType::atLtS: newp = new AstLtN{fl, lhsp, rhsp}; break; case VNType::LtS: newp = new AstLtN{fl, lhsp, rhsp}; break;
case VNType::atLte: case VNType::Lte:
case VNType::atLteS: newp = new AstLteN{fl, lhsp, rhsp}; break; case VNType::LteS: newp = new AstLteN{fl, lhsp, rhsp}; break;
default: // LCOV_EXCL_LINE default: // LCOV_EXCL_LINE
nodep->v3fatalSrc("Node needs conversion to string, but bad case: " << nodep); nodep->v3fatalSrc("Node needs conversion to string, but bad case: " << nodep);
break; break;
@ -8135,7 +8135,7 @@ class WidthVisitor final : public VNVisitor {
AstNodeExpr* const lhsp = nodep->lhsp()->unlinkFrBack(); AstNodeExpr* const lhsp = nodep->lhsp()->unlinkFrBack();
AstNodeUniop* newp = nullptr; AstNodeUniop* newp = nullptr;
switch (nodep->type()) { switch (nodep->type()) {
case VNType::atNegate: newp = new AstNegateD{fl, lhsp}; break; case VNType::Negate: newp = new AstNegateD{fl, lhsp}; break;
default: // LCOV_EXCL_LINE default: // LCOV_EXCL_LINE
nodep->v3fatalSrc("Node needs conversion to double, but bad case: " << nodep); nodep->v3fatalSrc("Node needs conversion to double, but bad case: " << nodep);
break; break;

View File

@ -832,22 +832,21 @@ def write_type_enum(prefix, nodeList):
fh.write(" enum en : uint16_t {\n") fh.write(" enum en : uint16_t {\n")
for node in sorted(filter(lambda _: _.isLeaf, nodeList), key=lambda _: _.typeId): for node in sorted(filter(lambda _: _.isLeaf, nodeList), key=lambda _: _.typeId):
fh.write(" at{t} = {n},\n".format(t=node.name, n=node.typeId)) fh.write(" {t} = {n},\n".format(t=node.name, n=node.typeId))
fh.write(" _ENUM_END = {n}\n".format(n=root.typeIdMax + 1))
fh.write(" };\n") fh.write(" };\n")
fh.write(" static constexpr size_t NUM_TYPES() {{ return {n}; }}\n".format(
n=root.typeIdMax + 1))
fh.write(" enum bounds : uint16_t {\n") fh.write(" enum bounds : uint16_t {\n")
for node in sorted(filter(lambda _: not _.isLeaf, nodeList), key=lambda _: _.typeIdMin): for node in sorted(filter(lambda _: not _.isLeaf, nodeList), key=lambda _: _.typeIdMin):
fh.write(" first{t} = {n},\n".format(t=node.name, n=node.typeIdMin)) fh.write(" first{t} = {n},\n".format(t=node.name, n=node.typeIdMin))
fh.write(" last{t} = {n},\n".format(t=node.name, n=node.typeIdMax)) fh.write(" last{t} = {n},\n".format(t=node.name, n=node.typeIdMax))
fh.write(" _BOUNDS_END\n")
fh.write(" };\n") fh.write(" };\n")
fh.write(" const char* ascii() const VL_MT_SAFE {\n") fh.write(" const char* ascii() const VL_MT_SAFE {\n")
fh.write(" static const char* const names[_ENUM_END + 1] = {\n") fh.write(" static const char* const names[] = {\n")
for node in sorted(filter(lambda _: _.isLeaf, nodeList), key=lambda _: _.typeId): for node in sorted(filter(lambda _: _.isLeaf, nodeList), key=lambda _: _.typeId):
fh.write(' "{T}",\n'.format(T=node.name.upper())) fh.write(' "{T}",\n'.format(T=node.name.upper()))
fh.write(" \"_ENUM_END\"\n")
fh.write(" };\n") fh.write(" };\n")
fh.write(" return names[m_e];\n") fh.write(" return names[m_e];\n")
fh.write(" }\n") fh.write(" }\n")
@ -879,9 +878,7 @@ def write_type_tests(prefix, nodeList):
"return static_cast<int>({v}->type()) >= static_cast<int>({e}::first{t}) && static_cast<int>({v}->type()) <= static_cast<int>({e}::last{t});" "return static_cast<int>({v}->type()) >= static_cast<int>({e}::first{t}) && static_cast<int>({v}->type()) <= static_cast<int>({e}::last{t});"
.format(v=variable, e=enum, t=node.name)) .format(v=variable, e=enum, t=node.name))
else: else:
fh.write("return {v}->type() == {e}::at{t};".format(v=variable, fh.write("return {v}->type() == {e}::{t};".format(v=variable, e=enum, t=node.name))
e=enum,
t=node.name))
fh.write(" }\n") fh.write(" }\n")
@ -1147,9 +1144,8 @@ def write_ast_macros(filename):
# Only care about leaf classes for the rest # Only care about leaf classes for the rest
if node.isLeaf: if node.isLeaf:
fh.write( fh.write("#define ASTGEN_SUPER_{t}(...) Ast{b}(VNType::{t}, __VA_ARGS__)\n".format(
"#define ASTGEN_SUPER_{t}(...) Ast{b}(VNType::at{t}, __VA_ARGS__)\n".format( t=node.name, b=node.superClass.name))
t=node.name, b=node.superClass.name))
fh.write("\n") fh.write("\n")
@ -1180,7 +1176,7 @@ def write_dfg_macros(filename):
if node.isLeaf: if node.isLeaf:
emitBlock('''\ emitBlock('''\
static constexpr VDfgType dfgType() {{ return VDfgType::at{t}; }}; static constexpr VDfgType dfgType() {{ return VDfgType::{t}; }};
using Super = Dfg{s}; using Super = Dfg{s};
void accept(DfgVisitor& v) override {{ v.visit(this); }} void accept(DfgVisitor& v) override {{ v.visit(this); }}
''', ''',
@ -1249,7 +1245,7 @@ def write_dfg_clone_cases(filename):
continue continue
emitBlock('''\ emitBlock('''\
case VDfgType::at{t}: {{ case VDfgType::{t}: {{
Dfg{t}* const cp = new Dfg{t}{{*clonep, vtx.fileline(), vtx.dtypep()}}; Dfg{t}* const cp = new Dfg{t}{{*clonep, vtx.fileline(), vtx.dtypep()}};
vtxp2clonep.emplace(&vtx, cp); vtxp2clonep.emplace(&vtx, cp);
break; break;