diff --git a/test/tools/llvm-cov/showHighlightedRanges.cpp b/test/tools/llvm-cov/showHighlightedRanges.cpp index dddbc2b1f16..c53a6c92fe2 100644 --- a/test/tools/llvm-cov/showHighlightedRanges.cpp +++ b/test/tools/llvm-cov/showHighlightedRanges.cpp @@ -1,39 +1,39 @@ -// RUN: llvm-cov show %S/Inputs/highlightedRanges.covmapping -instr-profile %S/Inputs/highlightedRanges.profdata -dump -filename-equivalence %s 2>&1 | FileCheck %s +// RUN: llvm-cov show %S/Inputs/highlightedRanges.covmapping -instr-profile %S/Inputs/highlightedRanges.profdata -dump -filename-equivalence %s 2>&1 | FileCheck %s -check-prefixes=TEXT,SHARED void func() { - return; - int i = 0; // CHECK: Highlighted line [[@LINE]], 3 -> ? -} // CHECK: Highlighted line [[@LINE]], 1 -> 2 + return; // TEXT: Highlighted line [[@LINE+1]], 3 -> ? + int i = 0; // HTML: Highlighted line [[@LINE]], 1 -> +} // SHARED: Highlighted line [[@LINE]], 1 -> 2 void func2(int x) { if(x > 5) { while(x >= 9) { return; - --x; // CHECK: Highlighted line [[@LINE]], 7 -> ? - } // CHECK: Highlighted line [[@LINE]], 1 -> 6 - int i = 0; // CHECK: Highlighted line [[@LINE]], 5 -> ? - } // CHECK: Highlighted line [[@LINE]], 1 -> 4 + --x; // TEXT: Highlighted line [[@LINE]], 7 -> ? + } // SHARED: Highlighted line [[@LINE]], 1 -> 6 + int i = 0; // TEXT: Highlighted line [[@LINE]], 5 -> ? + } // SHARED: Highlighted line [[@LINE]], 1 -> 4 } void test() { int x = 0; - if (x) { // CHECK: Highlighted line [[@LINE]], 10 -> ? - x = 0; // CHECK: Highlighted line [[@LINE]], 1 -> ? - } else { // CHECK: Highlighted line [[@LINE]], 1 -> 4 + if (x) { // TEXT: Highlighted line [[@LINE]], 10 -> ? + x = 0; // SHARED: Highlighted line [[@LINE]], 1 -> ? + } else { // TEXT: Highlighted line [[@LINE]], 1 -> 4 x = 1; } - // CHECK: Highlighted line [[@LINE+1]], 26 -> 29 - for (int i = 0; i < 0; ++i) { // CHECK: Highlighted line [[@LINE]], 31 -> ? - x = 1; // CHECK: Highlighted line [[@LINE]], 1 -> ? - } // CHECK: Highlighted line [[@LINE]], 1 -> 4 + // TEXT: Highlighted line [[@LINE+1]], 26 -> 29 + for (int i = 0; i < 0; ++i) { // TEXT: Highlighted line [[@LINE]], 31 -> ? + x = 1; // TEXT: Highlighted line [[@LINE]], 1 -> ? + } // SHARED: Highlighted line [[@LINE]], 1 -> 4 x = x < 10 ? x + 1 - : x - 1; // CHECK: Highlighted line [[@LINE]], 16 -> 21 - x = x > 10 ? x + // CHECK: Highlighted line [[@LINE]], 16 -> ? - 1 // CHECK: Highlighted line [[@LINE]], 1 -> 17 + : x - 1; // TEXT: Highlighted line [[@LINE]], 16 -> 21 + x = x > 10 ? x + // TEXT: Highlighted line [[@LINE]], 16 -> ? + 1 // SHARED: Highlighted line [[@LINE]], 1 -> 17 : x - 1; } @@ -44,4 +44,5 @@ int main() { return 0; } +// RUN: llvm-cov show %S/Inputs/highlightedRanges.covmapping -instr-profile %S/Inputs/highlightedRanges.profdata -format html -dump -filename-equivalence %s 2>&1 | FileCheck %s -check-prefixes=HTML,SHARED // RUN: llvm-cov export %S/Inputs/highlightedRanges.covmapping -instr-profile %S/Inputs/highlightedRanges.profdata 2>&1 | FileCheck %S/Inputs/highlightedRanges.json diff --git a/tools/llvm-cov/SourceCoverageViewHTML.cpp b/tools/llvm-cov/SourceCoverageViewHTML.cpp index ef81ceaee17..53a18b42505 100644 --- a/tools/llvm-cov/SourceCoverageViewHTML.cpp +++ b/tools/llvm-cov/SourceCoverageViewHTML.cpp @@ -304,6 +304,7 @@ void SourceCoverageViewHTML::renderLine( raw_ostream &OS, LineRef L, const coverage::CoverageSegment *WrappedSegment, CoverageSegmentArray Segments, unsigned ExpansionCol, unsigned) { StringRef Line = L.Line; + unsigned LineNo = L.LineNo; // Steps for handling text-escaping, highlighting, and tooltip creation: // @@ -337,27 +338,34 @@ void SourceCoverageViewHTML::renderLine( for (unsigned I = 0, E = Snippets.size(); I < E; ++I) Snippets[I] = escape(Snippets[I]); - // 3. Use \p WrappedSegment to set the highlight for snippets 0 and 1. Use - // segment 1 to set the highlight for snippet 2, segment 2 to set the - // highlight for snippet 3, and so on. + // 3. Use \p WrappedSegment to set the highlight for snippet 0. Use segment + // 1 to set the highlight for snippet 2, segment 2 to set the highlight for + // snippet 3, and so on. Optional Color; - auto Highlight = [&](const std::string &Snippet) { + SmallVector, 4> HighlightedRanges; + auto Highlight = [&](const std::string &Snippet, unsigned LC, unsigned RC) { + if (getOptions().Debug) { + if (!HighlightedRanges.empty() && + HighlightedRanges.back().second == LC - 1) { + HighlightedRanges.back().second = RC; + } else + HighlightedRanges.emplace_back(LC, RC); + } return tag("span", Snippet, Color.getValue()); }; auto CheckIfUncovered = [](const coverage::CoverageSegment *S) { - return S && S->HasCount && S->Count == 0; + return S && (S->HasCount && S->Count == 0); }; if (CheckIfUncovered(WrappedSegment) || CheckIfUncovered(Segments.empty() ? nullptr : Segments.front())) { Color = "red"; - Snippets[0] = Highlight(Snippets[0]); - Snippets[1] = Highlight(Snippets[1]); + Snippets[0] = Highlight(Snippets[0], 0, Snippets[0].size()); } - for (unsigned I = 1, E = Segments.size(); I < E; ++I) { + for (unsigned I = 0, E = Segments.size(); I < E; ++I) { const auto *CurSeg = Segments[I]; if (CurSeg->Col == ExpansionCol) Color = "cyan"; @@ -367,7 +375,23 @@ void SourceCoverageViewHTML::renderLine( Color = None; if (Color.hasValue()) - Snippets[I + 1] = Highlight(Snippets[I + 1]); + Snippets[I + 1] = Highlight(Snippets[I + 1], CurSeg->Col, + CurSeg->Col + Snippets[I + 1].size()); + } + + if (Color.hasValue() && Segments.empty()) + Snippets.back() = Highlight(Snippets.back(), Snippets[0].size(), 0); + + if (getOptions().Debug) { + for (const auto &Range : HighlightedRanges) { + errs() << "Highlighted line " << LineNo << ", " << Range.first + 1 + << " -> "; + if (Range.second == 0) + errs() << "?"; + else + errs() << Range.second + 1; + errs() << "\n"; + } } // 4. Snippets[1:N+1] correspond to \p Segments[0:N]: use these to generate @@ -390,7 +414,7 @@ void SourceCoverageViewHTML::renderLine( Snippets[I + 1] = tag("div", Snippets[I + 1] + tag("span", formatCount(CurSeg->Count), - "tooltip-content"), + "tooltip-content"), "tooltip"); } }