mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-05 03:36:43 +00:00
[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
This commit is contained in:
parent
556137fa8f
commit
4f3900ac66
BIN
test/tools/llvm-cov/Inputs/showProjectSummary.covmapping
Normal file
BIN
test/tools/llvm-cov/Inputs/showProjectSummary.covmapping
Normal file
Binary file not shown.
10
test/tools/llvm-cov/Inputs/showProjectSummary.proftext
Normal file
10
test/tools/llvm-cov/Inputs/showProjectSummary.proftext
Normal file
@ -0,0 +1,10 @@
|
||||
main
|
||||
# Func Hash:
|
||||
266
|
||||
# Num Counters:
|
||||
3
|
||||
# Counter Values:
|
||||
1
|
||||
20
|
||||
0
|
||||
|
46
test/tools/llvm-cov/showProjectSummary.cpp
Normal file
46
test/tools/llvm-cov/showProjectSummary.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
// RUN: llvm-profdata merge -o %t.profdata %S/Inputs/showProjectSummary.proftext
|
||||
|
||||
int main(int argc, char ** argv) {
|
||||
int x=0;
|
||||
for (int i = 0; i < 20; ++i)
|
||||
x *= 2;
|
||||
if (x >= 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: <div class='project-title'>
|
||||
// HTML-TITLE: <span>Test Suite</span>
|
||||
// HTML: <div class='report-title'>
|
||||
// HTML: <span>Code Coverage Report</span>
|
||||
// HTML: <div class='created-time'>
|
||||
// HTML: <span>Created:
|
||||
// HTML-FILE: <pre>Source:
|
||||
// HTML-FILE: showProjectSummary.cpp</pre>
|
||||
// HTML-FILE: <pre>Binary:
|
||||
// HTML-FILE: showProjectSummary.covmapping</pre>
|
||||
// HTML-FUNCTION: <pre>Function: main</pre>
|
||||
// HTML-HEADER: <tr><td><span><pre>Line No.</pre></span></td>
|
||||
// HTML-HEADER: <td><span><pre>Count No.</pre></span></td>
|
||||
// HTML-HEADER: <td><span><pre>Source</pre></span></td>
|
@ -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: <td class='line-number'><a name='L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre>
|
||||
// HTML-ALL: <td class='line-number'><a name='L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='covered-line'><pre>2</pre></td><td class='code'><pre>}
|
||||
|
||||
// HTML-SHARED: <div class='source-name-title'><pre>_Z4funcIbEiT_</pre></div><table>
|
||||
// HTML-SHARED: <div class='source-name-title'><pre>Function: _Z4funcIbEiT_</pre></div>
|
||||
// HTML-SHARED: <td class='line-number'><a name='L[[@LINE-53]]'><pre>[[@LINE-53]]</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>int func(T x) {
|
||||
// HTML-SHARED: <td class='line-number'><a name='L[[@LINE-53]]'><pre>[[@LINE-53]]</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> if(x)
|
||||
// HTML-SHARED: <td class='line-number'><a name='L[[@LINE-53]]'><pre>[[@LINE-53]]</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> ret
|
||||
@ -65,7 +65,7 @@ int main() { // ALL: [[@LINE]]| 1|int main() {
|
||||
// HTML-SHARED: <td class='line-number'><a name='L[[@LINE-53]]'><pre>[[@LINE-53]]</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre>
|
||||
// HTML-SHARED: <td class='line-number'><a name='L[[@LINE-53]]'><pre>[[@LINE-53]]</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>}
|
||||
|
||||
// HTML-ALL: <div class='source-name-title'><pre>_Z4funcIiEiT_</pre></div><table>
|
||||
// HTML-ALL: <div class='source-name-title'><pre>Function: _Z4funcIiEiT_</pre></div>
|
||||
// HTML-FILTER-NOT: <div class='source-name-title'><pre>_Z4funcIiEiT_</pre></div><table>
|
||||
// HTML-ALL: <td class='line-number'><a name='L[[@LINE-63]]'><pre>[[@LINE-63]]</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>int func(T x) {
|
||||
// HTML-ALL: <td class='line-number'><a name='L[[@LINE-63]]'><pre>[[@LINE-63]]</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> if(x)
|
||||
|
@ -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.
|
||||
|
@ -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(); }
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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) {}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user