[llvm-cov] Add the "Go to first unexecuted line" feature.

This patch provides easy navigation to find the zero count lines, especially useful when the source file is very large.

Differential Revision: https://reviews.llvm.org/D23277

llvm-svn: 280739
diff --git a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
index 40bc650..7e069de 100644
--- a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
+++ b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
@@ -338,7 +338,8 @@
   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 @@
   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;
 }