[llvm-cov] Minor cleanups to prepare for the html format patch

- Add renderView{Header,Footer}, renderLineSuffix, and hasSubViews to
  support creating tables with nested views.

- Move the 'Format' cl::opt to make it easier to extend.

- Just create one function view file, instead of overwriting the same
  file for every new function. Add a regression test for this.

llvm-svn: 274086
diff --git a/llvm/tools/llvm-cov/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp
index f2f9716..4fdb895 100644
--- a/llvm/tools/llvm-cov/CodeCoverage.cpp
+++ b/llvm/tools/llvm-cov/CodeCoverage.cpp
@@ -268,6 +268,13 @@
   cl::opt<bool> DebugDump("dump", cl::Optional,
                           cl::desc("Show internal debug dump"));
 
+  cl::opt<CoverageViewOptions::OutputFormat> Format(
+      "format", cl::desc("Output format for line-based coverage reports"),
+      cl::values(clEnumValN(CoverageViewOptions::OutputFormat::Text, "text",
+                            "Text output"),
+                 clEnumValEnd),
+      cl::init(CoverageViewOptions::OutputFormat::Text));
+
   cl::opt<bool> FilenameEquivalence(
       "filename-equivalence", cl::Optional,
       cl::desc("Treat source files as equivalent to paths in the coverage data "
@@ -319,9 +326,14 @@
     ViewOpts.Debug = DebugDump;
     CompareFilenamesOnly = FilenameEquivalence;
 
-    ViewOpts.Colors = UseColor == cl::BOU_UNSET
-                          ? sys::Process::StandardOutHasColors()
-                          : UseColor == cl::BOU_TRUE;
+    ViewOpts.Format = Format;
+    switch (ViewOpts.Format) {
+    case CoverageViewOptions::OutputFormat::Text:
+      ViewOpts.Colors = UseColor == cl::BOU_UNSET
+                            ? sys::Process::StandardOutHasColors()
+                            : UseColor == cl::BOU_TRUE;
+      break;
+    }
 
     // Create the function filters
     if (!NameFilters.empty() || !NameRegexFilters.empty()) {
@@ -410,13 +422,6 @@
                                    cl::desc("Show function instantiations"),
                                    cl::cat(ViewCategory));
 
-  cl::opt<CoverageViewOptions::OutputFormat> Format(
-      "format", cl::desc("Output format for line-based coverage reports"),
-      cl::values(clEnumValN(CoverageViewOptions::OutputFormat::Text, "text",
-                            "Text output"),
-                 clEnumValEnd),
-      cl::init(CoverageViewOptions::OutputFormat::Text));
-
   cl::opt<std::string> ShowOutputDirectory(
       "output-dir", cl::init(""),
       cl::desc("Directory in which coverage information is written out"));
@@ -434,7 +439,6 @@
   ViewOpts.ShowLineStatsOrRegionMarkers = ShowBestLineRegionsCounts;
   ViewOpts.ShowExpandedRegions = ShowExpansions;
   ViewOpts.ShowFunctionInstantiations = ShowInstantiations;
-  ViewOpts.Format = Format;
   ViewOpts.ShowOutputDirectory = ShowOutputDirectory;
 
   if (ViewOpts.hasOutputDirectory()) {
@@ -451,7 +455,14 @@
   auto Printer = CoveragePrinter::create(ViewOpts);
 
   if (!Filters.empty()) {
-    // Show functions
+    auto OSOrErr = Printer->createViewFile("functions", /*InToplevel=*/true);
+    if (Error E = OSOrErr.takeError()) {
+      error(toString(std::move(E)));
+      return 1;
+    }
+    auto OS = std::move(OSOrErr.get());
+
+    // Show functions.
     for (const auto &Function : Coverage->getCoveredFunctions()) {
       if (!Filters.matches(Function))
         continue;
@@ -464,15 +475,10 @@
         continue;
       }
 
-      auto OSOrErr = Printer->createViewFile("functions", /*InToplevel=*/true);
-      if (Error E = OSOrErr.takeError()) {
-        error(toString(std::move(E)));
-        return 1;
-      }
-      auto OS = std::move(OSOrErr.get());
       mainView->print(*OS.get(), /*WholeFile=*/false, /*ShowSourceName=*/true);
-      Printer->closeViewFile(std::move(OS));
     }
+
+    Printer->closeViewFile(std::move(OS));
     return 0;
   }