diff options
author | Ying Yi <maggieyi666@gmail.com> | 2016-08-24 14:27:23 +0000 |
---|---|---|
committer | Ying Yi <maggieyi666@gmail.com> | 2016-08-24 14:27:23 +0000 |
commit | 84dc971ee2bc444a41d01051dba5b83d103ad952 (patch) | |
tree | ed2637dc11ef83639d3aa81a281d6463dc8882fd /llvm/tools/llvm-cov | |
parent | c22e32deac405e042ffe4f05bf01bd5b6e3aa536 (diff) | |
download | llvm-84dc971ee2bc444a41d01051dba5b83d103ad952.zip llvm-84dc971ee2bc444a41d01051dba5b83d103ad952.tar.gz llvm-84dc971ee2bc444a41d01051dba5b83d103ad952.tar.bz2 |
[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
Diffstat (limited to 'llvm/tools/llvm-cov')
-rw-r--r-- | llvm/tools/llvm-cov/CodeCoverage.cpp | 36 | ||||
-rw-r--r-- | llvm/tools/llvm-cov/CoverageViewOptions.h | 9 | ||||
-rw-r--r-- | llvm/tools/llvm-cov/SourceCoverageView.cpp | 19 | ||||
-rw-r--r-- | llvm/tools/llvm-cov/SourceCoverageView.h | 20 | ||||
-rw-r--r-- | llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp | 99 | ||||
-rw-r--r-- | llvm/tools/llvm-cov/SourceCoverageViewHTML.h | 13 | ||||
-rw-r--r-- | llvm/tools/llvm-cov/SourceCoverageViewText.cpp | 21 | ||||
-rw-r--r-- | llvm/tools/llvm-cov/SourceCoverageViewText.h | 13 |
8 files changed, 194 insertions, 36 deletions
diff --git a/llvm/tools/llvm-cov/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp index 6d7c7ae..019f18a 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<std::string> 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 45f2d813..8e85245 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<std::string> 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 6fab1af..23f725f 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> 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<SourceCoverageViewText>(SourceName, File, Options, - std::move(CoverageInfo)); + return llvm::make_unique<SourceCoverageViewText>( + SourceName, File, Options, std::move(CoverageInfo), FunctionView); case CoverageViewOptions::OutputFormat::HTML: - return llvm::make_unique<SourceCoverageViewHTML>(SourceName, File, Options, - std::move(CoverageInfo)); + return llvm::make_unique<SourceCoverageViewHTML>( + 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 6f2c400..eb820e3 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<InstantiationView> InstantiationSubViews; + /// Specifies whether or not the view is a function view. + bool FunctionView; + protected: struct LineRef { StringRef Line; @@ -192,7 +195,7 @@ protected: 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 @@ protected: 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 @@ protected: 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<SourceCoverageView> 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 588b838..8245ebd 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 = "</head>"; @@ -197,6 +216,20 @@ const char *BeginTable = "<table>"; const char *EndTable = "</table>"; +const char *BeginProjectTitleDiv = "<div class='project-title'>"; + +const char *EndProjectTitleDiv = "</div>"; + +const char *BeginReportTitleDiv = "<div class='report-title'>"; + +const char *EndReportTitleDiv = "</div>"; + +const char *BeginCreatedTimeDiv = "<div class='created-time'>"; + +const char *EndCreatedTimeDiv = "</div>"; + +const char *LineBreak = "<br>"; + 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 << "<link rel='stylesheet' type='text/css' href='" << escape(PathToStyle, Opts) << "'>"; - OS << EndHeader << "<body>" << BeginCenteredDiv; + OS << EndHeader << "<body>"; } void emitEpilog(raw_ostream &OS) { - OS << EndCenteredDiv << "</body>" - "</html>"; + OS << "</body>" + << "</html>"; } } // anonymous namespace @@ -261,15 +294,26 @@ Error CoveragePrinterHTML::createIndexFile(ArrayRef<StringRef> 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<StringRef> 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 50ecf2b..dd9f949 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 ae9d6da..2f568b2 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 b2331247..fdf1a64 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 |