From 8860ad4b3e2d49faa82cf4a23f30573ca52a5e2c Mon Sep 17 00:00:00 2001 From: Matthew Ballance Date: Sun, 1 Mar 2026 15:46:20 +0000 Subject: [PATCH] Parser clean-up Signed-off-by: Matthew Ballance --- docs/guide/exe_verilator_coverage.rst | 4 +- src/V3AstNodeOther.h | 6 +- src/V3LinkParse.cpp | 207 ++++++++++++++++++++++++++ src/V3ParseGrammar.h | 163 -------------------- src/verilog.y | 126 ++++------------ 5 files changed, 241 insertions(+), 265 deletions(-) diff --git a/docs/guide/exe_verilator_coverage.rst b/docs/guide/exe_verilator_coverage.rst index 1955128cb..1cb9916a7 100644 --- a/docs/guide/exe_verilator_coverage.rst +++ b/docs/guide/exe_verilator_coverage.rst @@ -129,10 +129,10 @@ verilator_coverage Arguments .. option:: --filter-type Skips records of coverage types that matches with - Possible values are `toggle`, `line`, `branch`, `expr`, `funccov`, `user` and + Possible values are `toggle`, `line`, `branch`, `expr`, `covergroup`, `user` and a wildcard with `\*` or `?`. The default value is `\*`. - The `funccov` type represents SystemVerilog functional coverage including + The `covergroup` type represents SystemVerilog functional coverage including covergroups, coverpoints, bins, and cross coverage as defined in IEEE 1800-2023 Section 19. diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index a648febe9..aae03f799 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -1157,13 +1157,17 @@ class AstCovergroup final : public AstNode { // @astgen op1 := argsp : List[AstVar] // @astgen op2 := membersp : List[AstNode] // @astgen op3 := eventp : Optional[AstSenTree] + // @astgen op4 := sampleArgsp : List[AstVar] string m_name; bool m_isClass = false; public: - AstCovergroup(FileLine* fl, const string& name, AstNode* membersp, AstSenTree* eventp) + AstCovergroup(FileLine* fl, const string& name, AstVar* argsp, AstVar* sampleArgsp, + AstNode* membersp, AstSenTree* eventp) : ASTGEN_SUPER_Covergroup(fl) , m_name{name} { + if (argsp) addArgsp(argsp); + if (sampleArgsp) addSampleArgsp(sampleArgsp); if (membersp) addMembersp(membersp); this->eventp(eventp); } diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index 244ed53e4..bda0bacda 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -1006,6 +1006,213 @@ class LinkParseVisitor final : public VNVisitor { iterateChildren(nodep); } + // Create boilerplate covergroup methods on the given AstClass. + // argsp/sampleArgsp are the raw arg lists still owned by the caller; they are iterated + // (cloned) but not deleted here. + static void createCovergroupMethods(AstClass* nodep, AstNode* argsp, AstNode* sampleArgsp) { + // Hidden static to take unspecified reference argument results + AstVar* const defaultVarp + = new AstVar{nodep->fileline(), VVarType::MEMBER, "__Vint", nodep->findIntDType()}; + defaultVarp->lifetime(VLifetime::STATIC_EXPLICIT); + nodep->addStmtsp(defaultVarp); + + // Handle constructor arguments - add function parameters and assignments + if (argsp) { + // Find the 'new' function to add parameters to + AstFunc* newFuncp = nullptr; + for (AstNode* memberp = nodep->membersp(); memberp; memberp = memberp->nextp()) { + if (AstFunc* const funcp = VN_CAST(memberp, Func)) { + if (funcp->name() == "new") { + newFuncp = funcp; + break; + } + } + } + if (newFuncp) { + // Save the existing body statements and unlink them + AstNode* const existingBodyp = newFuncp->stmtsp(); + if (existingBodyp) existingBodyp->unlinkFrBackWithNext(); + // Add function parameters and assignments + for (AstNode* argp = argsp; argp; argp = argp->nextp()) { + if (AstVar* const origVarp = VN_CAST(argp, Var)) { + AstVar* const paramp = origVarp->cloneTree(false); + paramp->funcLocal(true); + paramp->direction(VDirection::INPUT); + newFuncp->addStmtsp(paramp); + AstNodeExpr* const lhsp + = new AstParseRef{origVarp->fileline(), origVarp->name()}; + AstNodeExpr* const rhsp + = new AstParseRef{paramp->fileline(), paramp->name()}; + newFuncp->addStmtsp(new AstAssign{origVarp->fileline(), lhsp, rhsp}); + } + } + if (existingBodyp) newFuncp->addStmtsp(existingBodyp); + } + } + + // IEEE: option + { + v3Global.setUsesStdPackage(); + AstVar* const varp + = new AstVar{nodep->fileline(), VVarType::MEMBER, "option", VFlagChildDType{}, + new AstRefDType{nodep->fileline(), "vl_covergroup_options_t", + new AstClassOrPackageRef{nodep->fileline(), "std", + nullptr, nullptr}, + nullptr}}; + nodep->addMembersp(varp); + } + + // IEEE: type_option + { + v3Global.setUsesStdPackage(); + AstVar* const varp + = new AstVar{nodep->fileline(), VVarType::MEMBER, "type_option", VFlagChildDType{}, + new AstRefDType{nodep->fileline(), "vl_covergroup_type_options_t", + new AstClassOrPackageRef{nodep->fileline(), "std", + nullptr, nullptr}, + nullptr}}; + nodep->addMembersp(varp); + } + + // IEEE: function void sample([arguments]) + { + AstFunc* const funcp = new AstFunc{nodep->fileline(), "sample", nullptr, nullptr}; + if (sampleArgsp) { + for (AstNode* argp = sampleArgsp; argp; argp = argp->nextp()) { + if (AstVar* const origVarp = VN_CAST(argp, Var)) { + AstVar* const paramp = origVarp->cloneTree(false); + paramp->funcLocal(true); + paramp->direction(VDirection::INPUT); + funcp->addStmtsp(paramp); + AstNodeExpr* const lhsp + = new AstParseRef{origVarp->fileline(), origVarp->name()}; + AstNodeExpr* const rhsp + = new AstParseRef{paramp->fileline(), paramp->name()}; + funcp->addStmtsp(new AstAssign{origVarp->fileline(), lhsp, rhsp}); + } + } + } + funcp->classMethod(true); + funcp->dtypep(funcp->findVoidDType()); + nodep->addMembersp(funcp); + } + + // IEEE: function void start(), void stop() + for (const string& name : {"start"s, "stop"s}) { + AstFunc* const funcp = new AstFunc{nodep->fileline(), name, nullptr, nullptr}; + funcp->classMethod(true); + funcp->dtypep(funcp->findVoidDType()); + nodep->addMembersp(funcp); + } + + // IEEE: static function real get_coverage(optional ref int, optional ref int) + // IEEE: function real get_inst_coverage(optional ref int, optional ref int) + for (const string& name : {"get_coverage"s, "get_inst_coverage"s}) { + AstFunc* const funcp = new AstFunc{nodep->fileline(), name, nullptr, nullptr}; + funcp->fileline()->warnOff(V3ErrorCode::NORETURN, true); + funcp->isStatic(name == "get_coverage"); + funcp->classMethod(true); + funcp->dtypep(funcp->findVoidDType()); + nodep->addMembersp(funcp); + { + AstVar* const varp = new AstVar{nodep->fileline(), VVarType::MEMBER, name, + nodep->findDoubleDType()}; + varp->lifetime(VLifetime::AUTOMATIC_EXPLICIT); + varp->funcLocal(true); + varp->direction(VDirection::OUTPUT); + varp->funcReturn(true); + funcp->fvarp(varp); + } + for (const string& varname : {"covered_bins"s, "total_bins"s}) { + AstVar* const varp = new AstVar{nodep->fileline(), VVarType::MEMBER, varname, + nodep->findStringDType()}; + varp->lifetime(VLifetime::AUTOMATIC_EXPLICIT); + varp->funcLocal(true); + varp->direction(VDirection::INPUT); + varp->valuep(new AstVarRef{nodep->fileline(), defaultVarp, VAccess::READ}); + funcp->addStmtsp(varp); + } + } + + // IEEE: function void set_inst_name(string) + { + AstFunc* const funcp + = new AstFunc{nodep->fileline(), "set_inst_name", nullptr, nullptr}; + funcp->classMethod(true); + funcp->dtypep(funcp->findVoidDType()); + nodep->addMembersp(funcp); + AstVar* const varp = new AstVar{nodep->fileline(), VVarType::MEMBER, "name", + nodep->findStringDType()}; + varp->lifetime(VLifetime::AUTOMATIC_EXPLICIT); + varp->funcLocal(true); + varp->direction(VDirection::INPUT); + funcp->addStmtsp(varp); + } + } + + void visit(AstCovergroup* nodep) override { + // Transform raw parse-time AstCovergroup into a fully-formed AstClass + cleanFileline(nodep); + + const string libname = m_modp ? m_modp->libname() : ""; + AstClass* const cgClassp = new AstClass{nodep->fileline(), nodep->name(), libname}; + cgClassp->isCovergroup(true); + v3Global.useCovergroup(true); + + // Clocking event: unlink before deleteTree, attach as AstCovergroup child on class + if (AstSenTree* const eventp = nodep->eventp()) { + eventp->unlinkFrBack(); + AstCovergroup* const cgNodep + = new AstCovergroup{nodep->fileline(), nodep->name(), + nullptr, nullptr, nullptr, eventp}; + cgClassp->addMembersp(cgNodep); + } + + // Convert constructor args to member variables + for (AstNode* argp = nodep->argsp(); argp; argp = argp->nextp()) { + if (AstVar* const origVarp = VN_CAST(argp, Var)) { + AstVar* const memberp = origVarp->cloneTree(false); + memberp->varType(VVarType::MEMBER); + memberp->funcLocal(false); + memberp->direction(VDirection::NONE); + cgClassp->addMembersp(memberp); + } + } + + // Convert sample args to member variables + for (AstNode* argp = nodep->sampleArgsp(); argp; argp = argp->nextp()) { + if (AstVar* const origVarp = VN_CAST(argp, Var)) { + AstVar* const memberp = origVarp->cloneTree(false); + memberp->varType(VVarType::MEMBER); + memberp->funcLocal(false); + memberp->direction(VDirection::NONE); + cgClassp->addMembersp(memberp); + } + } + + // Create the constructor; detach membersp (coverage body) and use as its body + { + AstFunc* const newp = new AstFunc{nodep->fileline(), "new", nullptr, nullptr}; + newp->fileline()->warnOff(V3ErrorCode::NORETURN, true); + newp->classMethod(true); + newp->isConstructor(true); + newp->dtypep(cgClassp->dtypep()); + if (AstNode* const bodyp = nodep->membersp()) { + bodyp->unlinkFrBackWithNext(); + newp->addStmtsp(bodyp); + } + cgClassp->addMembersp(newp); + } + + // Add all boilerplate covergroup methods (reads argsp/sampleArgsp from nodep) + createCovergroupMethods(cgClassp, nodep->argsp(), nodep->sampleArgsp()); + + // Replace AstCovergroup with AstClass and process the new class normally + nodep->replaceWith(cgClassp); + VL_DO_DANGLING(nodep->deleteTree(), nodep); + iterate(cgClassp); + } + void visit(AstNode* nodep) override { // Default: Just iterate cleanFileline(nodep); diff --git a/src/V3ParseGrammar.h b/src/V3ParseGrammar.h index 93da2c019..fa3110ada 100644 --- a/src/V3ParseGrammar.h +++ b/src/V3ParseGrammar.h @@ -94,169 +94,6 @@ public: nodep->trace(singletonp()->allTracingOn(fileline)); return nodep; } - void createCoverGroupMethods(AstClass* nodep, AstNode* constructorArgs, AstNode* sampleArgs) { - // Hidden static to take unspecified reference argument results - AstVar* const defaultVarp - = new AstVar{nodep->fileline(), VVarType::MEMBER, "__Vint", nodep->findIntDType()}; - defaultVarp->lifetime(VLifetime::STATIC_EXPLICIT); - nodep->addStmtsp(defaultVarp); - - // Handle constructor arguments - add function parameters and assignments - // Member variables have already been created in verilog.y - if (constructorArgs) { - // Find the 'new' function to add parameters to - AstFunc* newFuncp = nullptr; - for (AstNode* memberp = nodep->membersp(); memberp; memberp = memberp->nextp()) { - if (AstFunc* funcp = VN_CAST(memberp, Func)) { - if (funcp->name() == "new") { - newFuncp = funcp; - break; - } - } - } - - if (newFuncp) { - // Save the existing body statements and unlink them - AstNode* const existingBodyp = newFuncp->stmtsp(); - if (existingBodyp) existingBodyp->unlinkFrBackWithNext(); - - // Add function parameters and assignments - AstNode* nextArgp = nullptr; - for (AstNode* argp = constructorArgs; argp; argp = nextArgp) { - nextArgp = argp->nextp(); // Save next before any modifications - if (AstVar* const origVarp = VN_CAST(argp, Var)) { - // Create a constructor parameter - AstVar* const paramp = origVarp->cloneTree(false); - paramp->funcLocal(true); - paramp->direction(VDirection::INPUT); - newFuncp->addStmtsp(paramp); - - // Create assignment: member = parameter - AstNodeExpr* const lhsp - = new AstParseRef{origVarp->fileline(), origVarp->name()}; - AstNodeExpr* const rhsp - = new AstParseRef{paramp->fileline(), paramp->name()}; - newFuncp->addStmtsp(new AstAssign{origVarp->fileline(), lhsp, rhsp}); - } - } - - // Finally, add back the existing body - if (existingBodyp) newFuncp->addStmtsp(existingBodyp); - } - } - - // IEEE: option - { - v3Global.setUsesStdPackage(); - AstVar* const varp - = new AstVar{nodep->fileline(), VVarType::MEMBER, "option", VFlagChildDType{}, - new AstRefDType{nodep->fileline(), "vl_covergroup_options_t", - new AstClassOrPackageRef{nodep->fileline(), "std", - nullptr, nullptr}, - nullptr}}; - nodep->addMembersp(varp); - } - - // IEEE: type_option - { - v3Global.setUsesStdPackage(); - AstVar* const varp - = new AstVar{nodep->fileline(), VVarType::MEMBER, "type_option", VFlagChildDType{}, - new AstRefDType{nodep->fileline(), "vl_covergroup_type_options_t", - new AstClassOrPackageRef{nodep->fileline(), "std", - nullptr, nullptr}, - nullptr}}; - nodep->addMembersp(varp); - } - - // IEEE: function void sample([arguments]) - { - AstFunc* const funcp = new AstFunc{nodep->fileline(), "sample", nullptr, nullptr}; - - // Add sample arguments as function parameters and assignments - // Member variables have already been created in verilog.y - if (sampleArgs) { - // Add function parameters and assignments - AstNode* nextArgp = nullptr; - for (AstNode* argp = sampleArgs; argp; argp = nextArgp) { - nextArgp = argp->nextp(); // Save next before any modifications - if (AstVar* const origVarp = VN_CAST(argp, Var)) { - // Create a function parameter - AstVar* const paramp = origVarp->cloneTree(false); - paramp->funcLocal(true); - paramp->direction(VDirection::INPUT); - funcp->addStmtsp(paramp); - - // Create assignment: member = parameter - AstNodeExpr* const lhsp - = new AstParseRef{origVarp->fileline(), origVarp->name()}; - AstNodeExpr* const rhsp - = new AstParseRef{paramp->fileline(), paramp->name()}; - funcp->addStmtsp(new AstAssign{origVarp->fileline(), lhsp, rhsp}); - } - } - } - - funcp->classMethod(true); - funcp->dtypep(funcp->findVoidDType()); - nodep->addMembersp(funcp); - } - - // IEEE: function void start(), void stop() - for (const string& name : {"start"s, "stop"s}) { - AstFunc* const funcp = new AstFunc{nodep->fileline(), name, nullptr, nullptr}; - funcp->classMethod(true); - funcp->dtypep(funcp->findVoidDType()); - nodep->addMembersp(funcp); - } - - // IEEE: static function real get_coverage(optional ref int, optional ref int) - // IEEE: function real get_inst_coverage(optional ref int, optional ref int) - for (const string& name : {"get_coverage"s, "get_inst_coverage"s}) { - AstFunc* const funcp = new AstFunc{nodep->fileline(), name, nullptr, nullptr}; - funcp->fileline()->warnOff(V3ErrorCode::NORETURN, true); - funcp->isStatic(name == "get_coverage"); - funcp->classMethod(true); - funcp->dtypep(funcp->findVoidDType()); - nodep->addMembersp(funcp); - { - AstVar* const varp = new AstVar{nodep->fileline(), VVarType::MEMBER, name, - nodep->findDoubleDType()}; - varp->lifetime(VLifetime::AUTOMATIC_EXPLICIT); - varp->funcLocal(true); - varp->direction(VDirection::OUTPUT); - varp->funcReturn(true); - funcp->fvarp(varp); - } - for (const string& varname : {"covered_bins"s, "total_bins"s}) { - AstVar* const varp = new AstVar{nodep->fileline(), VVarType::MEMBER, varname, - nodep->findStringDType()}; - varp->lifetime(VLifetime::AUTOMATIC_EXPLICIT); - varp->funcLocal(true); - varp->direction(VDirection::INPUT); - varp->valuep(new AstVarRef{nodep->fileline(), defaultVarp, VAccess::READ}); - funcp->addStmtsp(varp); - } - } - // IEEE: function void set_inst_name(string) - { - AstFunc* const funcp - = new AstFunc{nodep->fileline(), "set_inst_name", nullptr, nullptr}; - funcp->classMethod(true); - funcp->dtypep(funcp->findVoidDType()); - nodep->addMembersp(funcp); - AstVar* const varp = new AstVar{nodep->fileline(), VVarType::MEMBER, "name", - nodep->findStringDType()}; - varp->lifetime(VLifetime::AUTOMATIC_EXPLICIT); - varp->funcLocal(true); - varp->direction(VDirection::INPUT); - funcp->addStmtsp(varp); - } - - // The original arg lists were cloned above; delete the orphaned originals - if (constructorArgs) VL_DO_DANGLING(constructorArgs->deleteTree(), constructorArgs); - if (sampleArgs) VL_DO_DANGLING(sampleArgs->deleteTree(), sampleArgs); - } // Helper to move bins from parser list to coverpoint void addCoverpointBins(AstCoverpoint* cp, AstNode* binsList) { if (!binsList) return; diff --git a/src/verilog.y b/src/verilog.y index dbb704146..9af8218ad 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -6905,89 +6905,23 @@ covergroup_declaration: // ==IEEE: covergroup_declaration yCOVERGROUP idAny cgPortListE coverage_eventE ';' /*cont*/ coverage_spec_or_optionListE /*cont*/ yENDGROUP endLabelE - { AstClass *cgClassp = new AstClass{$2, *$2, PARSEP->libname()}; - cgClassp->isCovergroup(true); - v3Global.useCovergroup(true); - - AstNode* sampleArgs = nullptr; - - // coverage_eventE can be either a clocking event or sample arguments + { AstSenTree* clockp = nullptr; + AstNode* sampleArgsp = nullptr; if ($4) { - if (VN_IS($4, SenItem)) { - // Clocking event: @(posedge clk) - // Create an AstCovergroup node to hold the clocking event - AstSenTree* senTreep = new AstSenTree{$1, VN_AS($4, SenItem)}; - AstCovergroup* const cgNodep = new AstCovergroup{$1, *$2, nullptr, senTreep}; - cgClassp->addMembersp(cgNodep); - } else { - // Sample arguments: with function sample(...) - sampleArgs = $4; - } + if (VN_IS($4, SenItem)) + clockp = new AstSenTree{$1, VN_AS($4, SenItem)}; + else + sampleArgsp = $4; } - - // Convert constructor parameters to member variables - // This must happen BEFORE the covergroup body is added, - // so coverpoints can reference these members - // We iterate carefully to avoid issues with modified AST - if ($3) { - AstNode* nextArgp = nullptr; - for (AstNode* argp = $3; argp; argp = nextArgp) { - nextArgp = argp->nextp(); // Save next before any modifications - if (AstVar* origVarp = VN_CAST(argp, Var)) { - AstVar* memberp = origVarp->cloneTree(false); - memberp->varType(VVarType::MEMBER); - memberp->funcLocal(false); - memberp->direction(VDirection::NONE); - cgClassp->addMembersp(memberp); - } - } - } - - // Convert sample parameters to member variables - if (sampleArgs) { - AstNode* nextArgp = nullptr; - for (AstNode* argp = sampleArgs; argp; argp = nextArgp) { - nextArgp = argp->nextp(); // Save next before any modifications - if (AstVar* origVarp = VN_CAST(argp, Var)) { - AstVar* memberp = origVarp->cloneTree(false); - memberp->varType(VVarType::MEMBER); - memberp->funcLocal(false); - memberp->direction(VDirection::NONE); - cgClassp->addMembersp(memberp); - } - } - } - - AstFunc* const newp = new AstFunc{$1, "new", nullptr, nullptr}; - newp->fileline()->warnOff(V3ErrorCode::NORETURN, true); - newp->classMethod(true); - newp->isConstructor(true); - newp->dtypep(cgClassp->dtypep()); - newp->addStmtsp($6); - cgClassp->addMembersp(newp); - GRAMMARP->createCoverGroupMethods(cgClassp, $3, sampleArgs); - - $$ = cgClassp; - GRAMMARP->endLabel($8, $$, $8); - } + $$ = new AstCovergroup{$2, *$2, static_cast($3), + static_cast(sampleArgsp), $6, clockp}; + GRAMMARP->endLabel($8, $$, $8); } | yCOVERGROUP yEXTENDS idAny ';' /*cont*/ coverage_spec_or_optionListE /*cont*/ yENDGROUP endLabelE { BBCOVERIGN($1, "Ignoring unsupported: covergroup inheritance (extends)"); - AstClass *cgClassp = new AstClass{$3, *$3, PARSEP->libname()}; - cgClassp->isCovergroup(true); - AstFunc* const newp = new AstFunc{$1, "new", nullptr, nullptr}; - newp->fileline()->warnOff(V3ErrorCode::NORETURN, true); - newp->classMethod(true); - newp->isConstructor(true); - newp->dtypep(cgClassp->dtypep()); - newp->addStmtsp($5); - cgClassp->addMembersp(newp); - GRAMMARP->createCoverGroupMethods(cgClassp, nullptr, nullptr); - - $$ = cgClassp; - GRAMMARP->endLabel($7, $$, $7); - } + $$ = new AstCovergroup{$3, *$3, nullptr, nullptr, $5, nullptr}; + GRAMMARP->endLabel($7, $$, $7); } ; cgPortListE: @@ -7034,43 +6968,43 @@ coverage_option: // ==IEEE: coverage_option cover_point: // ==IEEE: cover_point // // [ [ data_type_or_implicit ] cover_point_identifier ':' ] yCOVERPOINT yCOVERPOINT expr iffE bins_or_empty - { auto* cp = new AstCoverpoint{$1, "", $2}; + { AstCoverpoint* const cp = new AstCoverpoint{$1, "", $2}; if ($3) cp->iffp(VN_AS($3, NodeExpr)); GRAMMARP->addCoverpointBins(cp, $4); $$ = cp; } // // IEEE-2012: class_scope before an ID | id/*cover_point_id*/ ':' yCOVERPOINT expr iffE bins_or_empty - { auto* cp = new AstCoverpoint{$3, *$1, $4}; + { AstCoverpoint* const cp = new AstCoverpoint{$3, *$1, $4}; if ($5) cp->iffp(VN_AS($5, NodeExpr)); GRAMMARP->addCoverpointBins(cp, $6); $$ = cp; } // // data_type_or_implicit expansion | data_type id/*cover_point_id*/ ':' yCOVERPOINT expr iffE bins_or_empty - { auto* cp = new AstCoverpoint{$4, *$2, $5}; + { AstCoverpoint* const cp = new AstCoverpoint{$4, *$2, $5}; if ($6) cp->iffp(VN_AS($6, NodeExpr)); GRAMMARP->addCoverpointBins(cp, $7); $$ = cp; DEL($1); } | yVAR data_type id/*cover_point_id*/ ':' yCOVERPOINT expr iffE bins_or_empty - { auto* cp = new AstCoverpoint{$5, *$3, $6}; + { AstCoverpoint* const cp = new AstCoverpoint{$5, *$3, $6}; if ($7) cp->iffp(VN_AS($7, NodeExpr)); GRAMMARP->addCoverpointBins(cp, $8); $$ = cp; DEL($2); } | yVAR implicit_typeE id/*cover_point_id*/ ':' yCOVERPOINT expr iffE bins_or_empty - { auto* cp = new AstCoverpoint{$5, *$3, $6}; + { AstCoverpoint* const cp = new AstCoverpoint{$5, *$3, $6}; if ($7) cp->iffp(VN_AS($7, NodeExpr)); GRAMMARP->addCoverpointBins(cp, $8); $$ = cp; DEL($2); } | signingE rangeList id/*cover_point_id*/ ':' yCOVERPOINT expr iffE bins_or_empty - { auto* cp = new AstCoverpoint{$5, *$3, $6}; + { AstCoverpoint* const cp = new AstCoverpoint{$5, *$3, $6}; if ($7) cp->iffp(VN_AS($7, NodeExpr)); GRAMMARP->addCoverpointBins(cp, $8); $$ = cp; DEL($2); } | signing id/*cover_point_id*/ ':' yCOVERPOINT expr iffE bins_or_empty - { auto* cp = new AstCoverpoint{$4, *$2, $5}; + { AstCoverpoint* const cp = new AstCoverpoint{$4, *$2, $5}; if ($6) cp->iffp(VN_AS($6, NodeExpr)); GRAMMARP->addCoverpointBins(cp, $7); $$ = cp; } @@ -7161,23 +7095,17 @@ bins_or_options: // ==IEEE: bins_or_options // // // cgexpr part of trans_list | yBINS idAny/*bin_identifier*/ bins_orBraE '=' trans_list iffE - { - FileLine* isArray = $3; - $$ = new AstCoverBin{$2, *$2, static_cast($5), false, false, isArray != nullptr}; - DEL($6); - } + { FileLine* isArray = $3; + $$ = new AstCoverBin{$2, *$2, static_cast($5), false, false, isArray != nullptr}; + DEL($6); } | yIGNORE_BINS idAny/*bin_identifier*/ bins_orBraE '=' trans_list iffE - { - FileLine* isArray = $3; - $$ = new AstCoverBin{$2, *$2, static_cast($5), true, false, isArray != nullptr}; - DEL($6); - } + { FileLine* isArray = $3; + $$ = new AstCoverBin{$2, *$2, static_cast($5), true, false, isArray != nullptr}; + DEL($6); } | yILLEGAL_BINS idAny/*bin_identifier*/ bins_orBraE '=' trans_list iffE - { - FileLine* isArray = $3; - $$ = new AstCoverBin{$2, *$2, static_cast($5), false, true, isArray != nullptr}; - DEL($6); - } + { FileLine* isArray = $3; + $$ = new AstCoverBin{$2, *$2, static_cast($5), false, true, isArray != nullptr}; + DEL($6); } | yWILDCARD yBINS idAny/*bin_identifier*/ bins_orBraE '=' trans_list iffE { $$ = nullptr; BBCOVERIGN($1, "Ignoring unsupported: cover bin 'wildcard' trans list"); DEL($6, $7);} | yWILDCARD yIGNORE_BINS idAny/*bin_identifier*/ bins_orBraE '=' trans_list iffE