[llvm-cov] Rearrange entries in report index.

Files which don't contain any functions are likely useless; don't
include them in the main table. Put the links at the bottom of the
page, in case someone wants to figure out coverage for code inside
a macro.

Not sure if this is the best solution, but it seems like an
improvement.

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

llvm-svn: 310518
diff --git a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
index 64b888e..7548a96 100644
--- a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
+++ b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
@@ -294,6 +294,18 @@
   OS << tag("tr", join(Columns.begin(), Columns.end(), ""));
 }
 
+std::string
+CoveragePrinterHTML::buildLinkToFile(StringRef SF,
+                                     const FileCoverageSummary &FCS) const {
+  SmallString<128> LinkTextStr(sys::path::relative_path(FCS.Name));
+  sys::path::remove_dots(LinkTextStr, /*remove_dot_dots=*/true);
+  sys::path::native(LinkTextStr);
+  std::string LinkText = escape(LinkTextStr, Opts);
+  std::string LinkTarget =
+      escape(getOutputPath(SF, "html", /*InToplevel=*/false), Opts);
+  return a(LinkTarget, LinkText);
+}
+
 /// Render a file coverage summary (\p FCS) in a table row. If \p IsTotals is
 /// false, link the summary to \p SF.
 void CoveragePrinterHTML::emitFileSummary(raw_ostream &OS, StringRef SF,
@@ -326,13 +338,7 @@
   if (IsTotals) {
     Filename = "TOTALS";
   } else {
-    SmallString<128> LinkTextStr(sys::path::relative_path(FCS.Name));
-    sys::path::remove_dots(LinkTextStr, /*remove_dot_dots=*/true);
-    sys::path::native(LinkTextStr);
-    std::string LinkText = escape(LinkTextStr, Opts);
-    std::string LinkTarget =
-        escape(getOutputPath(SF, "html", /*InToplevel=*/false), Opts);
-    Filename = a(LinkTarget, LinkText);
+    Filename = buildLinkToFile(SF, FCS);
   }
 
   Columns.emplace_back(tag("td", tag("pre", Filename)));
@@ -387,16 +393,39 @@
                         " for information about interpreting this report.");
 
   // Emit a table containing links to reports for each file in the covmapping.
+  // Exclude files which don't contain any regions.
   OSRef << BeginCenteredDiv << BeginTable;
   emitColumnLabelsForIndex(OSRef);
   FileCoverageSummary Totals("TOTALS");
   auto FileReports =
       CoverageReport::prepareFileReports(Coverage, Totals, SourceFiles);
-  for (unsigned I = 0, E = FileReports.size(); I < E; ++I)
-    emitFileSummary(OSRef, SourceFiles[I], FileReports[I]);
+  bool EmptyFiles = false;
+  for (unsigned I = 0, E = FileReports.size(); I < E; ++I) {
+    if (FileReports[I].FunctionCoverage.NumFunctions)
+      emitFileSummary(OSRef, SourceFiles[I], FileReports[I]);
+    else
+      EmptyFiles = true;
+  }
   emitFileSummary(OSRef, "Totals", Totals, /*IsTotals=*/true);
-  OSRef << EndTable << EndCenteredDiv
-        << tag("h5", escape(Opts.getLLVMVersionString(), Opts));
+  OSRef << EndTable << EndCenteredDiv;
+
+  // Emit links to files which don't contain any functions. These are normally
+  // not very useful, but could be relevant for code which abuses the
+  // preprocessor.
+  if (EmptyFiles) {
+    OSRef << tag("p", "Files which contain no functions. (These "
+                      "files contain code pulled into other files "
+                      "by the preprocessor.)\n");
+    OSRef << BeginCenteredDiv << BeginTable;
+    for (unsigned I = 0, E = FileReports.size(); I < E; ++I)
+      if (!FileReports[I].FunctionCoverage.NumFunctions) {
+        std::string Link = buildLinkToFile(SourceFiles[I], FileReports[I]);
+        OSRef << tag("tr", tag("td", tag("pre", Link)), "light-row") << '\n';
+      }
+    OSRef << EndTable << EndCenteredDiv;
+  }
+
+  OSRef << tag("h5", escape(Opts.getLLVMVersionString(), Opts));
   emitEpilog(OSRef);
 
   return Error::success();