From 84dc971ee2bc444a41d01051dba5b83d103ad952 Mon Sep 17 00:00:00 2001 From: Ying Yi Date: Wed, 24 Aug 2016 14:27:23 +0000 Subject: [PATCH] [llvm-cov] Add the project summary to each source file coverage report. This patch includes the following changes: - Included header "Code coverage report" and include the date that the report was created. - Included title (as specified in a command line option, (i.e llvm-cov -project-title="Simple Test") - In the summary, list the elf files that the source code file has contributed to. - Used column heading for "Line No.", "Count No.", Source". Differential Revision: https://reviews.llvm.org/D23345 llvm-svn: 279628 --- .../Inputs/showProjectSummary.covmapping | Bin 0 -> 144 bytes .../Inputs/showProjectSummary.proftext | 10 ++ .../tools/llvm-cov/showProjectSummary.cpp | 46 ++++++++ .../llvm-cov/showTemplateInstantiations.cpp | 8 +- llvm/tools/llvm-cov/CodeCoverage.cpp | 36 ++++++- llvm/tools/llvm-cov/CoverageViewOptions.h | 9 ++ llvm/tools/llvm-cov/SourceCoverageView.cpp | 19 ++-- llvm/tools/llvm-cov/SourceCoverageView.h | 20 +++- .../tools/llvm-cov/SourceCoverageViewHTML.cpp | 99 ++++++++++++++++-- llvm/tools/llvm-cov/SourceCoverageViewHTML.h | 13 ++- .../tools/llvm-cov/SourceCoverageViewText.cpp | 21 +++- llvm/tools/llvm-cov/SourceCoverageViewText.h | 13 ++- 12 files changed, 254 insertions(+), 40 deletions(-) create mode 100644 llvm/test/tools/llvm-cov/Inputs/showProjectSummary.covmapping create mode 100644 llvm/test/tools/llvm-cov/Inputs/showProjectSummary.proftext create mode 100644 llvm/test/tools/llvm-cov/showProjectSummary.cpp diff --git a/llvm/test/tools/llvm-cov/Inputs/showProjectSummary.covmapping b/llvm/test/tools/llvm-cov/Inputs/showProjectSummary.covmapping new file mode 100644 index 0000000000000000000000000000000000000000..d95caf27f2bdea530e3655dc7163d246a80cddc7 GIT binary patch literal 144 zcmd1FDa%dHFUu`SEiOq(EJ~wf=hFA6N@VKk_!qL8JHMZ89CV*nUy%1n3;qbBv~1x8RS?Q USsAz)8QB^5Ie{!bHYOke0B`*l!T= 100) + x = x / 2; + else + x = x * 2; + return x; +} + +// Test console output. +// RUN: llvm-cov show %S/Inputs/showProjectSummary.covmapping -instr-profile %t.profdata -filename-equivalence %s | FileCheck -check-prefixes=TEXT,TEXT-FILE,TEXT-HEADER %s +// RUN: llvm-cov show %S/Inputs/showProjectSummary.covmapping -instr-profile %t.profdata -project-title "Test Suite" -filename-equivalence %s | FileCheck -check-prefixes=TEXT-TITLE,TEXT,TEXT-FILE,TEXT-HEADER %s +// RUN: llvm-cov show %S/Inputs/showProjectSummary.covmapping -instr-profile %t.profdata -project-title "Test Suite" -name=main -filename-equivalence %s | FileCheck -check-prefixes=TEXT-FUNCTION,TEXT-HEADER %s +// TEXT-TITLE: Test Suite +// TEXT: Code Coverage Report +// TEXT: Created: +// TEXT-FILE: showProjectSummary.cpp: +// TEXT-FILE: showProjectSummary.covmapping: +// TEXT-FUNCTION: main: + +// Test html output. +// RUN: llvm-cov show %S/Inputs/showProjectSummary.covmapping -format=html -o %t.dir -instr-profile %t.profdata -filename-equivalence %s +// RUN: FileCheck -check-prefixes=HTML,HTML-FILE,HTML-HEADER -input-file %t.dir/coverage/tmp/showProjectSummary.cpp.html %s +// RUN: llvm-cov show %S/Inputs/showProjectSummary.covmapping -format=html -o %t.dir -instr-profile %t.profdata -project-title "Test Suite" -filename-equivalence %s +// RUN: FileCheck -check-prefixes=HTML-TITLE,HTML,HTML-FILE,HTML-HEADER -input-file %t.dir/coverage/tmp/showProjectSummary.cpp.html %s +// RUN: FileCheck -check-prefixes=HTML-TITLE,HTML -input-file %t.dir/index.html %s +// RUN: llvm-cov show %S/Inputs/showProjectSummary.covmapping -format=html -o %t.dir -instr-profile %t.profdata -project-title "Test Suite" -filename-equivalence -name=main %s +// RUN: FileCheck -check-prefixes=HTML-FUNCTION,HTML-HEADER -input-file %t.dir/functions.html %s +// HTML-TITLE:
+// HTML-TITLE: Test Suite +// HTML:
+// HTML: Code Coverage Report +// HTML:
+// HTML: Created: +// HTML-FILE:
Source:
+// HTML-FILE: showProjectSummary.cpp
+// HTML-FILE:
Binary:
+// HTML-FILE: showProjectSummary.covmapping
+// HTML-FUNCTION:
Function: main
+// HTML-HEADER:
Line No.
+// HTML-HEADER:
Count No.
+// HTML-HEADER:
Source
diff --git a/llvm/test/tools/llvm-cov/showTemplateInstantiations.cpp b/llvm/test/tools/llvm-cov/showTemplateInstantiations.cpp index 198ebd3b199b7..5a656db980958 100644 --- a/llvm/test/tools/llvm-cov/showTemplateInstantiations.cpp +++ b/llvm/test/tools/llvm-cov/showTemplateInstantiations.cpp @@ -13,7 +13,7 @@ int func(T x) { // ALL-NEXT: [[@LINE]]| 2|int func(T x) { } // ALL-NEXT: [[@LINE]]| 2|} // SHARED: {{^ *(\| )?}}_Z4funcIbEiT_: - // SHARED-NEXT: [[@LINE-9]]| 1|int func(T x) { + // SHARED: [[@LINE-9]]| 1|int func(T x) { // SHARED-NEXT: [[@LINE-9]]| 1| if(x) // SHARED-NEXT: [[@LINE-9]]| 1| return 0; // SHARED-NEXT: [[@LINE-9]]| 1| else @@ -23,7 +23,7 @@ int func(T x) { // ALL-NEXT: [[@LINE]]| 2|int func(T x) { // ALL: {{^ *}}| _Z4funcIiEiT_: // FILTER-NOT: {{^ *(\| )?}} _Z4funcIiEiT_: - // ALL-NEXT: [[@LINE-19]]| 1|int func(T x) { + // ALL: [[@LINE-19]]| 1|int func(T x) { // ALL-NEXT: [[@LINE-19]]| 1| if(x) // ALL-NEXT: [[@LINE-19]]| 0| return 0; // ALL-NEXT: [[@LINE-19]]| 1| else @@ -56,7 +56,7 @@ int main() { // ALL: [[@LINE]]| 1|int main() { // HTML-ALL:
[[@LINE-44]]
0
 // HTML-ALL: 
[[@LINE-44]]
2
}
 
-// HTML-SHARED: 
_Z4funcIbEiT_
+// HTML-SHARED:
Function: _Z4funcIbEiT_
// HTML-SHARED:
[[@LINE-53]]
1
int func(T x) {
 // HTML-SHARED: 
[[@LINE-53]]
1
  if(x)
 // HTML-SHARED: 
[[@LINE-53]]
1
    ret
@@ -65,7 +65,7 @@ int main() {         // ALL:         [[@LINE]]| 1|int main() {
 // HTML-SHARED: 
[[@LINE-53]]
0
 // HTML-SHARED: 
[[@LINE-53]]
1
}
 
-// HTML-ALL: 
_Z4funcIiEiT_
+// HTML-ALL:
Function: _Z4funcIiEiT_
// HTML-FILTER-NOT:
_Z4funcIiEiT_
// HTML-ALL:
[[@LINE-63]]
1
int func(T x) {
 // HTML-ALL: 
[[@LINE-63]]
1
  if(x)
diff --git a/llvm/tools/llvm-cov/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp
index 6d7c7aef44efb..019f18a54579f 100644
--- a/llvm/tools/llvm-cov/CodeCoverage.cpp
+++ b/llvm/tools/llvm-cov/CodeCoverage.cpp
@@ -210,9 +210,9 @@ CodeCoverageTool::createFunctionView(const FunctionRecord &Function,
     return nullptr;
 
   auto Expansions = FunctionCoverage.getExpansions();
-  auto View = SourceCoverageView::create(getSymbolForHumans(Function.Name),
-                                         SourceBuffer.get(), ViewOpts,
-                                         std::move(FunctionCoverage));
+  auto View = SourceCoverageView::create(
+      getSymbolForHumans(Function.Name), SourceBuffer.get(), ViewOpts,
+      std::move(FunctionCoverage), /*FunctionView=*/true);
   attachExpansionSubViews(*View, Expansions, Coverage);
 
   return View;
@@ -238,7 +238,7 @@ CodeCoverageTool::createSourceFileView(StringRef SourceFile,
     auto SubViewExpansions = SubViewCoverage.getExpansions();
     auto SubView = SourceCoverageView::create(
         getSymbolForHumans(Function->Name), SourceBuffer.get(), ViewOpts,
-        std::move(SubViewCoverage));
+        std::move(SubViewCoverage), /*FunctionView=*/true);
     attachExpansionSubViews(*SubView, SubViewExpansions, Coverage);
 
     if (SubView) {
@@ -463,6 +463,12 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
     CompareFilenamesOnly = FilenameEquivalence;
 
     ViewOpts.Format = Format;
+    SmallString<128> ObjectFilePath(this->ObjectFilename);
+    if (std::error_code EC = sys::fs::make_absolute(ObjectFilePath)) {
+      error(EC.message(), this->ObjectFilename);
+      return 1;
+    }
+    ViewOpts.ObjectFilename = ObjectFilePath.c_str();
     switch (ViewOpts.Format) {
     case CoverageViewOptions::OutputFormat::Text:
       ViewOpts.Colors = UseColor == cl::BOU_UNSET
@@ -589,6 +595,10 @@ int CodeCoverageTool::show(int argc, const char **argv,
       cl::desc(
           "Set tab expansion size for html coverage reports (default = 2)"));
 
+  cl::opt ProjectTitle(
+      "project-title", cl::Optional,
+      cl::desc("Set project title for the coverage report"));
+
   auto Err = commandLineParser(argc, argv);
   if (Err)
     return Err;
@@ -602,6 +612,7 @@ int CodeCoverageTool::show(int argc, const char **argv,
   ViewOpts.ShowFunctionInstantiations = ShowInstantiations;
   ViewOpts.ShowOutputDirectory = ShowOutputDirectory;
   ViewOpts.TabSize = TabSize;
+  ViewOpts.ProjectTitle = ProjectTitle;
 
   if (ViewOpts.hasOutputDirectory()) {
     if (auto E = sys::fs::create_directories(ViewOpts.ShowOutputDirectory)) {
@@ -610,6 +621,19 @@ int CodeCoverageTool::show(int argc, const char **argv,
     }
   }
 
+  sys::fs::file_status Status;
+  if (sys::fs::status(PGOFilename, Status)) {
+    error("profdata file error: can not get the file status. \n");
+    return 1;
+  }
+
+  auto ModifiedTime = Status.getLastModificationTime();
+  std::string ModifiedTimeStr = ModifiedTime.str();
+  size_t found = ModifiedTimeStr.rfind(":");
+  ViewOpts.CreatedTimeStr = (found != std::string::npos)
+                                ? "Created: " + ModifiedTimeStr.substr(0, found)
+                                : "Created: " + ModifiedTimeStr;
+
   auto Coverage = load();
   if (!Coverage)
     return 1;
@@ -643,7 +667,9 @@ int CodeCoverageTool::show(int argc, const char **argv,
   }
 
   // Show files
-  bool ShowFilenames = SourceFiles.size() != 1;
+  bool ShowFilenames =
+      (SourceFiles.size() != 1) ||
+      (ViewOpts.Format == CoverageViewOptions::OutputFormat::HTML);
 
   if (SourceFiles.empty())
     // Get the source files from the function coverage mapping.
diff --git a/llvm/tools/llvm-cov/CoverageViewOptions.h b/llvm/tools/llvm-cov/CoverageViewOptions.h
index 45f2d8139870b..8e852459771d6 100644
--- a/llvm/tools/llvm-cov/CoverageViewOptions.h
+++ b/llvm/tools/llvm-cov/CoverageViewOptions.h
@@ -35,6 +35,9 @@ struct CoverageViewOptions {
   std::string ShowOutputDirectory;
   std::vector DemanglerOpts;
   uint32_t TabSize;
+  std::string ProjectTitle;
+  std::string ObjectFilename;
+  std::string CreatedTimeStr;
 
   /// \brief Change the output's stream color if the colors are enabled.
   ColoredRawOstream colored_ostream(raw_ostream &OS,
@@ -47,6 +50,12 @@ struct CoverageViewOptions {
 
   /// \brief Check if a demangler has been specified.
   bool hasDemangler() const { return !DemanglerOpts.empty(); }
+
+  /// \brief Check if a project title has been specified.
+  bool hasProjectTitle() const { return !ProjectTitle.empty(); }
+
+  /// \brief Check if the created time of the profile data file is available.
+  bool hasCreatedTime() const { return !CreatedTimeStr.empty(); }
 };
 }
 
diff --git a/llvm/tools/llvm-cov/SourceCoverageView.cpp b/llvm/tools/llvm-cov/SourceCoverageView.cpp
index 6fab1afd6b685..23f725fccdccc 100644
--- a/llvm/tools/llvm-cov/SourceCoverageView.cpp
+++ b/llvm/tools/llvm-cov/SourceCoverageView.cpp
@@ -109,14 +109,15 @@ bool SourceCoverageView::hasSubViews() const {
 std::unique_ptr
 SourceCoverageView::create(StringRef SourceName, const MemoryBuffer &File,
                            const CoverageViewOptions &Options,
-                           coverage::CoverageData &&CoverageInfo) {
+                           coverage::CoverageData &&CoverageInfo,
+                           bool FunctionView) {
   switch (Options.Format) {
   case CoverageViewOptions::OutputFormat::Text:
-    return llvm::make_unique(SourceName, File, Options,
-                                                     std::move(CoverageInfo));
+    return llvm::make_unique(
+        SourceName, File, Options, std::move(CoverageInfo), FunctionView);
   case CoverageViewOptions::OutputFormat::HTML:
-    return llvm::make_unique(SourceName, File, Options,
-                                                     std::move(CoverageInfo));
+    return llvm::make_unique(
+        SourceName, File, Options, std::move(CoverageInfo), FunctionView);
   }
   llvm_unreachable("Unknown coverage output format!");
 }
@@ -135,11 +136,15 @@ void SourceCoverageView::addInstantiation(
 
 void SourceCoverageView::print(raw_ostream &OS, bool WholeFile,
                                bool ShowSourceName, unsigned ViewDepth) {
-  if (ShowSourceName)
-    renderSourceName(OS);
+  if (WholeFile)
+    renderCellInTitle(OS, "Code Coverage Report");
 
   renderViewHeader(OS);
 
+  if (ShowSourceName)
+    renderSourceName(OS, WholeFile);
+
+  renderTableHeader(OS, ViewDepth);
   // We need the expansions and instantiations sorted so we can go through them
   // while we iterate lines.
   std::sort(ExpansionSubViews.begin(), ExpansionSubViews.end());
diff --git a/llvm/tools/llvm-cov/SourceCoverageView.h b/llvm/tools/llvm-cov/SourceCoverageView.h
index 6f2c4004c9b17..eb820e316b4ca 100644
--- a/llvm/tools/llvm-cov/SourceCoverageView.h
+++ b/llvm/tools/llvm-cov/SourceCoverageView.h
@@ -172,6 +172,9 @@ class SourceCoverageView {
   /// on display.
   std::vector InstantiationSubViews;
 
+  /// Specifies whether or not the view is a function view.
+  bool FunctionView;
+
 protected:
   struct LineRef {
     StringRef Line;
@@ -192,7 +195,7 @@ class SourceCoverageView {
   virtual void renderViewFooter(raw_ostream &OS) = 0;
 
   /// \brief Render the source name for the view.
-  virtual void renderSourceName(raw_ostream &OS) = 0;
+  virtual void renderSourceName(raw_ostream &OS, bool WholeFile) = 0;
 
   /// \brief Render the line prefix at the given \p ViewDepth.
   virtual void renderLinePrefix(raw_ostream &OS, unsigned ViewDepth) = 0;
@@ -236,6 +239,13 @@ class SourceCoverageView {
   virtual void renderInstantiationView(raw_ostream &OS, InstantiationView &ISV,
                                        unsigned ViewDepth) = 0;
 
+  /// \brief Render the project title, the report title \p CellText and the
+  /// created time for the view.
+  virtual void renderCellInTitle(raw_ostream &OS, StringRef CellText) = 0;
+
+  /// \brief Render the table header for a given source file
+  virtual void renderTableHeader(raw_ostream &OS, unsigned IndentLevel = 0) = 0;
+
   /// @}
 
   /// \brief Format a count using engineering notation with 3 significant
@@ -250,20 +260,22 @@ class SourceCoverageView {
 
   SourceCoverageView(StringRef SourceName, const MemoryBuffer &File,
                      const CoverageViewOptions &Options,
-                     coverage::CoverageData &&CoverageInfo)
+                     coverage::CoverageData &&CoverageInfo, bool FunctionView)
       : SourceName(SourceName), File(File), Options(Options),
-        CoverageInfo(std::move(CoverageInfo)) {}
+        CoverageInfo(std::move(CoverageInfo)), FunctionView(FunctionView) {}
 
 public:
   static std::unique_ptr
   create(StringRef SourceName, const MemoryBuffer &File,
          const CoverageViewOptions &Options,
-         coverage::CoverageData &&CoverageInfo);
+         coverage::CoverageData &&CoverageInfo, bool FucntionView = false);
 
   virtual ~SourceCoverageView() {}
 
   StringRef getSourceName() const { return SourceName; }
 
+  bool isFunctionView() const { return FunctionView; }
+
   const CoverageViewOptions &getOptions() const { return Options; }
 
   /// \brief Add an expansion subview to this view.
diff --git a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
index 588b83850ac3f..8245ebdf37f31 100644
--- a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
+++ b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
@@ -15,6 +15,7 @@
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 
 using namespace llvm;
@@ -88,10 +89,11 @@ pre {
   padding: 5px 10px;
   border-bottom: 1px solid #dbdbdb;
   background-color: #eee;
+  line-height: 35px;
 }
 .centered {
   display: table;
-  margin-left: auto;
+  margin-left: left;
   margin-right: auto;
   border: 1px solid #dbdbdb;
   border-radius: 3px;
@@ -169,6 +171,23 @@ td:first-child {
 td:last-child {
   border-right: none;
 }
+.project-title {
+  font-size:36.0pt;
+  line-height:200%;
+  font-family:Calibri;
+  font-weight: bold;
+}
+.report-title {
+  font-size:16.0pt;
+  line-height:120%;
+  font-family:Arial;
+  font-weight: bold;
+}
+.created-time {
+  font-size:14.0pt;
+  line-height:120%;
+  font-family:Arial;
+}
 )";
 
 const char *EndHeader = "";
@@ -197,6 +216,20 @@ const char *BeginTable = "";
 
 const char *EndTable = "
"; +const char *BeginProjectTitleDiv = "
"; + +const char *EndProjectTitleDiv = "
"; + +const char *BeginReportTitleDiv = "
"; + +const char *EndReportTitleDiv = "
"; + +const char *BeginCreatedTimeDiv = "
"; + +const char *EndCreatedTimeDiv = "
"; + +const char *LineBreak = "
"; + std::string getPathToStyle(StringRef ViewPath) { std::string PathToStyle = ""; std::string PathSep = sys::path::get_separator(); @@ -219,12 +252,12 @@ void emitPrelude(raw_ostream &OS, const CoverageViewOptions &Opts, OS << ""; - OS << EndHeader << "" << BeginCenteredDiv; + OS << EndHeader << ""; } void emitEpilog(raw_ostream &OS) { - OS << EndCenteredDiv << "" - ""; + OS << "" + << ""; } } // anonymous namespace @@ -261,15 +294,26 @@ Error CoveragePrinterHTML::createIndexFile(ArrayRef SourceFiles) { // Emit a table containing links to reports for each file in the covmapping. assert(Opts.hasOutputDirectory() && "No output directory for index file"); emitPrelude(OSRef, Opts, getPathToStyle("")); + if (Opts.hasProjectTitle()) + OSRef << BeginProjectTitleDiv + << tag("span", escape(Opts.ProjectTitle, Opts)) << EndProjectTitleDiv; + OSRef << BeginReportTitleDiv + << tag("span", escape("Code Coverage Report", Opts)) + << EndReportTitleDiv; + if (Opts.hasCreatedTime()) + OSRef << BeginCreatedTimeDiv + << tag("span", escape(Opts.CreatedTimeStr, Opts)) + << EndCreatedTimeDiv; + OSRef << LineBreak; + OSRef << BeginCenteredDiv << BeginTable; OSRef << BeginSourceNameDiv << "Index" << EndSourceNameDiv; - OSRef << BeginTable; for (StringRef SF : SourceFiles) { std::string LinkText = escape(sys::path::relative_path(SF), Opts); std::string LinkTarget = escape(getOutputPath(SF, "html", /*InToplevel=*/false), Opts); OSRef << tag("tr", tag("td", tag("pre", a(LinkTarget, LinkText), "code"))); } - OSRef << EndTable; + OSRef << EndTable << EndCenteredDiv; emitEpilog(OSRef); // Emit the default stylesheet. @@ -284,16 +328,24 @@ Error CoveragePrinterHTML::createIndexFile(ArrayRef SourceFiles) { } void SourceCoverageViewHTML::renderViewHeader(raw_ostream &OS) { - OS << BeginTable; + OS << LineBreak << BeginCenteredDiv << BeginTable; } void SourceCoverageViewHTML::renderViewFooter(raw_ostream &OS) { - OS << EndTable; + OS << EndTable << EndCenteredDiv; } -void SourceCoverageViewHTML::renderSourceName(raw_ostream &OS) { - OS << BeginSourceNameDiv << tag("pre", escape(getSourceName(), getOptions())) - << EndSourceNameDiv; +void SourceCoverageViewHTML::renderSourceName(raw_ostream &OS, bool WholeFile) { + OS << BeginSourceNameDiv; + // Render the source name for the view. + std::string SourceFile = isFunctionView() ? "Function: " : "Source: "; + SourceFile += getSourceName().str(); + OS << tag("pre", escape(SourceFile, getOptions())); + // Render the object file name for the view. + if (WholeFile) + OS << tag("pre", + escape("Binary: " + getOptions().ObjectFilename, getOptions())); + OS << EndSourceNameDiv; } void SourceCoverageViewHTML::renderLinePrefix(raw_ostream &OS, unsigned) { @@ -489,3 +541,28 @@ void SourceCoverageViewHTML::renderInstantiationView(raw_ostream &OS, ISV.View->print(OS, /*WholeFile=*/false, /*ShowSourceName=*/true, ViewDepth); OS << EndExpansionDiv; } + +void SourceCoverageViewHTML::renderCellInTitle(raw_ostream &OS, + StringRef CellText) { + if (getOptions().hasProjectTitle()) + OS << BeginProjectTitleDiv + << tag("span", escape(getOptions().ProjectTitle, getOptions())) + << EndProjectTitleDiv; + + OS << BeginReportTitleDiv << tag("span", escape(CellText, getOptions())) + << EndReportTitleDiv; + + if (getOptions().hasCreatedTime()) + OS << BeginCreatedTimeDiv + << tag("span", escape(getOptions().CreatedTimeStr, getOptions())) + << EndCreatedTimeDiv; +} + +void SourceCoverageViewHTML::renderTableHeader(raw_ostream &OS, + unsigned ViewDepth) { + renderLinePrefix(OS, ViewDepth); + OS << tag("td", tag("span", tag("pre", escape("Line No.", getOptions())))) + << tag("td", tag("span", tag("pre", escape("Count No.", getOptions())))) + << tag("td", tag("span", tag("pre", escape("Source", getOptions())))); + renderLineSuffix(OS, ViewDepth); +} diff --git a/llvm/tools/llvm-cov/SourceCoverageViewHTML.h b/llvm/tools/llvm-cov/SourceCoverageViewHTML.h index 50ecf2bf89970..dd9f949e04a65 100644 --- a/llvm/tools/llvm-cov/SourceCoverageViewHTML.h +++ b/llvm/tools/llvm-cov/SourceCoverageViewHTML.h @@ -38,7 +38,7 @@ class SourceCoverageViewHTML : public SourceCoverageView { void renderViewFooter(raw_ostream &OS) override; - void renderSourceName(raw_ostream &OS) override; + void renderSourceName(raw_ostream &OS, bool WholeFile) override; void renderLinePrefix(raw_ostream &OS, unsigned ViewDepth) override; @@ -70,12 +70,17 @@ class SourceCoverageViewHTML : public SourceCoverageView { void renderRegionMarkers(raw_ostream &OS, CoverageSegmentArray Segments, unsigned ViewDepth) override; + void renderCellInTitle(raw_ostream &OS, StringRef CellText) override; + + void renderTableHeader(raw_ostream &OS, unsigned IndentLevel) override; + public: SourceCoverageViewHTML(StringRef SourceName, const MemoryBuffer &File, const CoverageViewOptions &Options, - coverage::CoverageData &&CoverageInfo) - : SourceCoverageView(SourceName, File, Options, std::move(CoverageInfo)) { - } + coverage::CoverageData &&CoverageInfo, + bool FunctionView) + : SourceCoverageView(SourceName, File, Options, std::move(CoverageInfo), + FunctionView) {} }; } // namespace llvm diff --git a/llvm/tools/llvm-cov/SourceCoverageViewText.cpp b/llvm/tools/llvm-cov/SourceCoverageViewText.cpp index ae9d6daed08f7..2f568b2b8386b 100644 --- a/llvm/tools/llvm-cov/SourceCoverageViewText.cpp +++ b/llvm/tools/llvm-cov/SourceCoverageViewText.cpp @@ -63,9 +63,13 @@ void SourceCoverageViewText::renderViewHeader(raw_ostream &) {} void SourceCoverageViewText::renderViewFooter(raw_ostream &) {} -void SourceCoverageViewText::renderSourceName(raw_ostream &OS) { +void SourceCoverageViewText::renderSourceName(raw_ostream &OS, bool WholeFile) { getOptions().colored_ostream(OS, raw_ostream::CYAN) << getSourceName() << ":\n"; + if (WholeFile) { + getOptions().colored_ostream(OS, raw_ostream::CYAN) + << getOptions().ObjectFilename << ":\n"; + } } void SourceCoverageViewText::renderLinePrefix(raw_ostream &OS, @@ -211,3 +215,18 @@ void SourceCoverageViewText::renderInstantiationView(raw_ostream &OS, OS << ' '; ISV.View->print(OS, /*WholeFile=*/false, /*ShowSourceName=*/true, ViewDepth); } + +void SourceCoverageViewText::renderCellInTitle(raw_ostream &OS, + StringRef CellText) { + if (getOptions().hasProjectTitle()) + getOptions().colored_ostream(OS, raw_ostream::CYAN) + << getOptions().ProjectTitle << "\n"; + + getOptions().colored_ostream(OS, raw_ostream::CYAN) << CellText << "\n"; + + if (getOptions().hasCreatedTime()) + getOptions().colored_ostream(OS, raw_ostream::CYAN) + << getOptions().CreatedTimeStr << "\n"; +} + +void SourceCoverageViewText::renderTableHeader(raw_ostream &, unsigned) {} diff --git a/llvm/tools/llvm-cov/SourceCoverageViewText.h b/llvm/tools/llvm-cov/SourceCoverageViewText.h index b2331247b37b7..fdf1a64ad3055 100644 --- a/llvm/tools/llvm-cov/SourceCoverageViewText.h +++ b/llvm/tools/llvm-cov/SourceCoverageViewText.h @@ -38,7 +38,7 @@ class SourceCoverageViewText : public SourceCoverageView { void renderViewFooter(raw_ostream &OS) override; - void renderSourceName(raw_ostream &OS) override; + void renderSourceName(raw_ostream &OS, bool WholeFile) override; void renderLinePrefix(raw_ostream &OS, unsigned ViewDepth) override; @@ -70,12 +70,17 @@ class SourceCoverageViewText : public SourceCoverageView { void renderRegionMarkers(raw_ostream &OS, CoverageSegmentArray Segments, unsigned ViewDepth) override; + void renderCellInTitle(raw_ostream &OS, StringRef CellText) override; + + void renderTableHeader(raw_ostream &OS, unsigned IndentLevel) override; + public: SourceCoverageViewText(StringRef SourceName, const MemoryBuffer &File, const CoverageViewOptions &Options, - coverage::CoverageData &&CoverageInfo) - : SourceCoverageView(SourceName, File, Options, std::move(CoverageInfo)) { - } + coverage::CoverageData &&CoverageInfo, + bool FunctionView) + : SourceCoverageView(SourceName, File, Options, std::move(CoverageInfo), + FunctionView) {} }; } // namespace llvm