================ @@ -1700,43 +1777,116 @@ struct CounterCoverageMappingBuilder Visit(S->getSubStmt()); } + void CoverIfConsteval(const IfStmt *S) { + assert(S->isConsteval()); + + const auto *Then = S->getThen(); + const auto *Else = S->getElse(); + + // I'm using 'propagateCounts' later as new region is better and allows me + // to properly calculate line coverage in llvm-cov utility + const Counter ParentCount = getRegion().getCounter(); + + extendRegion(S); + + if (S->isNegatedConsteval()) { + // ignore 'if consteval' + markSkipped(S->getIfLoc(), getStart(Then)); + propagateCounts(ParentCount, Then); + + if (Else) { + // ignore 'else <else>' + markSkipped(getEnd(Then), getEnd(Else)); + } + } else { + assert(S->isNonNegatedConsteval()); + // ignore 'if consteval <then> [else]' + markSkipped(S->getIfLoc(), Else ? getStart(Else) : getEnd(Then)); + + if (Else) + propagateCounts(ParentCount, Else); + } + } + + void CoverIfConstexpr(const IfStmt *S) { + assert(S->isConstexpr()); + + // evaluate constant condition... + const auto *E = dyn_cast<ConstantExpr>(S->getCond()); + assert(E != nullptr); + const bool isTrue = E->getResultAsAPSInt().getExtValue(); + + extendRegion(S); + + const auto *Init = S->getInit(); + const auto *Then = S->getThen(); + const auto *Else = S->getElse(); + + // I'm using 'propagateCounts' later as new region is better and allows me + // to properly calculate line coverage in llvm-cov utility + const Counter ParentCount = getRegion().getCounter(); + + // ignore 'if constexpr (' + SourceLocation startOfSkipped = S->getIfLoc(); + + if (Init) { + // don't mark initialisation as ignored + markSkipped(startOfSkipped, getStart(Init)); + propagateCounts(ParentCount, Init); + // ignore after initialisation: '; <condition>)'... + startOfSkipped = getEnd(Init); + } + + if (isTrue) { + // ignore '<condition>)' + markSkipped(startOfSkipped, getStart(Then)); + propagateCounts(ParentCount, Then); + + if (Else) + // ignore 'else <else>' + markSkipped(getEnd(Then), getEnd(Else)); + } else { + // ignore '<condition>) <then> [else]' + markSkipped(startOfSkipped, Else ? getStart(Else) : getEnd(Then)); + + if (Else) { + propagateCounts(ParentCount, Else); + } + } + } + void VisitIfStmt(const IfStmt *S) { + // "if constexpr" and "if consteval" are not normal conditional statements, + // they should behave more like a preprocessor conditions + if (S->isConsteval()) + return CoverIfConsteval(S); + else if (S->isConstexpr()) + return CoverIfConstexpr(S); ---------------- hanickadot wrote:
I did this dispatch here to keep `if` part clean, as `if consteval` and `if constexpr` have closer to "preprocessor" than runtime `if`. https://github.com/llvm/llvm-project/pull/78033 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits