[llvm-cov] Factor out logic to iterate over line coverage stats (NFC)
There were two copies of the logic needed to construct a line stats
object for each line in a range: this patch brings it down to one. In
the future, this will make it easier for IDE clients to display coverage
in-line in source editors. To do that, we just need to move the new
LineCoverageIterator class to libCoverage.
llvm-svn: 315789
diff --git a/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp b/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp
index 6a4cbd0..8994872 100644
--- a/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp
+++ b/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp
@@ -19,7 +19,9 @@
LineCoverageStats::LineCoverageStats(
ArrayRef<const coverage::CoverageSegment *> LineSegments,
- const coverage::CoverageSegment *WrappedSegment) {
+ const coverage::CoverageSegment *WrappedSegment, unsigned Line)
+ : ExecutionCount(0), HasMultipleRegions(false), Mapped(false), Line(Line),
+ LineSegments(LineSegments), WrappedSegment(WrappedSegment) {
// Find the minimum number of regions which start in this line.
unsigned MinRegionCount = 0;
auto isStartOfRegion = [](const coverage::CoverageSegment *S) {
@@ -33,7 +35,6 @@
!LineSegments.front()->HasCount &&
LineSegments.front()->IsRegionEntry;
- ExecutionCount = 0;
HasMultipleRegions = MinRegionCount > 1;
Mapped =
!StartOfSkippedRegion &&
@@ -61,6 +62,22 @@
ExecutionCount = WrappedSegment->Count;
}
+LineCoverageIterator &LineCoverageIterator::operator++() {
+ if (Next == CD.end()) {
+ Stats = LineCoverageStats();
+ Ended = true;
+ return *this;
+ }
+ if (Segments.size())
+ WrappedSegment = Segments.back();
+ Segments.clear();
+ while (Next != CD.end() && Next->Line == Line)
+ Segments.push_back(&*Next++);
+ Stats = LineCoverageStats(Segments, WrappedSegment, Line);
+ ++Line;
+ return *this;
+}
+
FunctionCoverageSummary
FunctionCoverageSummary::get(const CoverageMapping &CM,
const coverage::FunctionRecord &Function) {
@@ -77,27 +94,12 @@
// Compute the line coverage
size_t NumLines = 0, CoveredLines = 0;
CoverageData CD = CM.getCoverageForFunction(Function);
- auto NextSegment = CD.begin();
- auto EndSegment = CD.end();
- const coverage::CoverageSegment *WrappedSegment = nullptr;
- SmallVector<const coverage::CoverageSegment *, 4> LineSegments;
- unsigned Line = NextSegment->Line;
- while (NextSegment != EndSegment) {
- // Gather the segments on this line and the wrapped segment.
- if (LineSegments.size())
- WrappedSegment = LineSegments.back();
- LineSegments.clear();
- while (NextSegment != EndSegment && NextSegment->Line == Line)
- LineSegments.push_back(&*NextSegment++);
-
- LineCoverageStats LCS{LineSegments, WrappedSegment};
- if (LCS.isMapped()) {
- ++NumLines;
- if (LCS.ExecutionCount)
- ++CoveredLines;
- }
-
- ++Line;
+ for (const auto &LCS : getLineCoverageStats(CD)) {
+ if (!LCS.isMapped())
+ continue;
+ ++NumLines;
+ if (LCS.getExecutionCount())
+ ++CoveredLines;
}
return FunctionCoverageSummary(