summaryrefslogtreecommitdiffstats
path: root/llvm/tools
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools')
-rw-r--r--llvm/tools/llvm-cov/SourceCoverageView.cpp25
-rw-r--r--llvm/tools/llvm-cov/SourceCoverageView.h6
-rw-r--r--llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp15
-rw-r--r--llvm/tools/llvm-cov/SourceCoverageViewHTML.h3
-rw-r--r--llvm/tools/llvm-cov/SourceCoverageViewText.cpp3
-rw-r--r--llvm/tools/llvm-cov/SourceCoverageViewText.h3
6 files changed, 47 insertions, 8 deletions
diff --git a/llvm/tools/llvm-cov/SourceCoverageView.cpp b/llvm/tools/llvm-cov/SourceCoverageView.cpp
index b61d7919444..323352a5174 100644
--- a/llvm/tools/llvm-cov/SourceCoverageView.cpp
+++ b/llvm/tools/llvm-cov/SourceCoverageView.cpp
@@ -82,6 +82,25 @@ CoveragePrinter::create(const CoverageViewOptions &Opts) {
llvm_unreachable("Unknown coverage output format!");
}
+unsigned SourceCoverageView::getFirstUncoveredLineNo() {
+ auto CheckIfUncovered = [](const coverage::CoverageSegment &S) {
+ return S.HasCount && S.Count == 0;
+ };
+ // L is less than R if (1) it's an uncovered segment (has a 0 count), and (2)
+ // either R is not an uncovered segment, or L has a lower line number than R.
+ const auto MinSegIt =
+ std::min_element(CoverageInfo.begin(), CoverageInfo.end(),
+ [CheckIfUncovered](const coverage::CoverageSegment &L,
+ const coverage::CoverageSegment &R) {
+ return (CheckIfUncovered(L) &&
+ (!CheckIfUncovered(R) || (L.Line < R.Line)));
+ });
+ if (CheckIfUncovered(*MinSegIt))
+ return (*MinSegIt).Line;
+ // There is no uncovered line, return zero.
+ return 0;
+}
+
std::string SourceCoverageView::formatCount(uint64_t N) {
std::string Number = utostr(N);
int Len = Number.size();
@@ -142,8 +161,12 @@ void SourceCoverageView::print(raw_ostream &OS, bool WholeFile,
renderViewHeader(OS);
+ unsigned FirstUncoveredLineNo = 0;
+ if (WholeFile)
+ FirstUncoveredLineNo = getFirstUncoveredLineNo();
+
if (ShowSourceName)
- renderSourceName(OS, WholeFile);
+ renderSourceName(OS, WholeFile, FirstUncoveredLineNo);
renderTableHeader(OS, ViewDepth);
// We need the expansions and instantiations sorted so we can go through them
diff --git a/llvm/tools/llvm-cov/SourceCoverageView.h b/llvm/tools/llvm-cov/SourceCoverageView.h
index eb820e316b4..410c8fd1c26 100644
--- a/llvm/tools/llvm-cov/SourceCoverageView.h
+++ b/llvm/tools/llvm-cov/SourceCoverageView.h
@@ -175,6 +175,9 @@ class SourceCoverageView {
/// Specifies whether or not the view is a function view.
bool FunctionView;
+ /// Get the first uncovered line number for the source file.
+ unsigned getFirstUncoveredLineNo();
+
protected:
struct LineRef {
StringRef Line;
@@ -195,7 +198,8 @@ protected:
virtual void renderViewFooter(raw_ostream &OS) = 0;
/// \brief Render the source name for the view.
- virtual void renderSourceName(raw_ostream &OS, bool WholeFile) = 0;
+ virtual void renderSourceName(raw_ostream &OS, bool WholeFile,
+ unsigned FirstUncoveredLineNo) = 0;
/// \brief Render the line prefix at the given \p ViewDepth.
virtual void renderLinePrefix(raw_ostream &OS, unsigned ViewDepth) = 0;
diff --git a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
index 40bc650cfc9..7e069de849c 100644
--- a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
+++ b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
@@ -338,7 +338,8 @@ void SourceCoverageViewHTML::renderViewFooter(raw_ostream &OS) {
OS << EndTable << EndCenteredDiv;
}
-void SourceCoverageViewHTML::renderSourceName(raw_ostream &OS, bool WholeFile) {
+void SourceCoverageViewHTML::renderSourceName(raw_ostream &OS, bool WholeFile,
+ unsigned FirstUncoveredLineNo) {
OS << BeginSourceNameDiv;
// Render the source name for the view.
std::string SourceFile = isFunctionView() ? "Function: " : "Source: ";
@@ -347,10 +348,18 @@ void SourceCoverageViewHTML::renderSourceName(raw_ostream &OS, bool WholeFile) {
sys::path::remove_dots(SourceText, /*remove_dot_dots=*/true);
sys::path::native(SourceText);
OS << tag("pre", escape(SourceText, getOptions()));
- // Render the object file name for the view.
- if (WholeFile)
+ if (WholeFile) {
+ // Render the object file name for the view.
OS << tag("pre",
escape("Binary: " + getOptions().ObjectFilename, getOptions()));
+ // Render the "Go to first unexecuted line" link for the view.
+ if (FirstUncoveredLineNo != 0) { // The file is not fully covered
+ std::string LinkText =
+ escape("Go to first unexecuted line", getOptions());
+ std::string LinkTarget = "#L" + utostr(uint64_t(FirstUncoveredLineNo));
+ OS << tag("pre", a(LinkTarget, LinkText));
+ }
+ }
OS << EndSourceNameDiv;
}
diff --git a/llvm/tools/llvm-cov/SourceCoverageViewHTML.h b/llvm/tools/llvm-cov/SourceCoverageViewHTML.h
index dd9f949e04a..42fec6fd31f 100644
--- a/llvm/tools/llvm-cov/SourceCoverageViewHTML.h
+++ b/llvm/tools/llvm-cov/SourceCoverageViewHTML.h
@@ -38,7 +38,8 @@ class SourceCoverageViewHTML : public SourceCoverageView {
void renderViewFooter(raw_ostream &OS) override;
- void renderSourceName(raw_ostream &OS, bool WholeFile) override;
+ void renderSourceName(raw_ostream &OS, bool WholeFile,
+ unsigned FirstUncoveredLineNo) override;
void renderLinePrefix(raw_ostream &OS, unsigned ViewDepth) override;
diff --git a/llvm/tools/llvm-cov/SourceCoverageViewText.cpp b/llvm/tools/llvm-cov/SourceCoverageViewText.cpp
index 2f568b2b838..52e405e298d 100644
--- a/llvm/tools/llvm-cov/SourceCoverageViewText.cpp
+++ b/llvm/tools/llvm-cov/SourceCoverageViewText.cpp
@@ -63,7 +63,8 @@ void SourceCoverageViewText::renderViewHeader(raw_ostream &) {}
void SourceCoverageViewText::renderViewFooter(raw_ostream &) {}
-void SourceCoverageViewText::renderSourceName(raw_ostream &OS, bool WholeFile) {
+void SourceCoverageViewText::renderSourceName(raw_ostream &OS, bool WholeFile,
+ unsigned FirstUncoveredLineNo) {
getOptions().colored_ostream(OS, raw_ostream::CYAN) << getSourceName()
<< ":\n";
if (WholeFile) {
diff --git a/llvm/tools/llvm-cov/SourceCoverageViewText.h b/llvm/tools/llvm-cov/SourceCoverageViewText.h
index fdf1a64ad30..dd78d3ad73c 100644
--- a/llvm/tools/llvm-cov/SourceCoverageViewText.h
+++ b/llvm/tools/llvm-cov/SourceCoverageViewText.h
@@ -38,7 +38,8 @@ class SourceCoverageViewText : public SourceCoverageView {
void renderViewFooter(raw_ostream &OS) override;
- void renderSourceName(raw_ostream &OS, bool WholeFile) override;
+ void renderSourceName(raw_ostream &OS, bool WholeFile,
+ unsigned FirstUncoveredLineNo) override;
void renderLinePrefix(raw_ostream &OS, unsigned ViewDepth) override;
OpenPOWER on IntegriCloud