1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

[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
This commit is contained in:
Vedant Kumar 2016-06-29 00:38:21 +00:00
parent 5027d87263
commit 8a4b0078c7
6 changed files with 84 additions and 31 deletions

View File

@ -33,3 +33,10 @@ int main() {
bar();
return 0;
}
// Test that listing multiple functions in a function view works.
// RUN: llvm-cov show -o %t.dir %S/Inputs/report.covmapping -instr-profile=%S/Inputs/report.profdata -filename-equivalence -name-regex=".*" %s
// RUN: FileCheck -check-prefix=FUNCTIONS -input-file %t.dir/functions.txt %s
// FUNCTIONS: _Z3foob
// FUNCTIONS: _Z3barv
// FUNCTIONS: _Z4func

View File

@ -268,6 +268,13 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
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 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
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 @@ int CodeCoverageTool::show(int argc, const char **argv,
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 @@ int CodeCoverageTool::show(int argc, const char **argv,
ViewOpts.ShowLineStatsOrRegionMarkers = ShowBestLineRegionsCounts;
ViewOpts.ShowExpandedRegions = ShowExpansions;
ViewOpts.ShowFunctionInstantiations = ShowInstantiations;
ViewOpts.Format = Format;
ViewOpts.ShowOutputDirectory = ShowOutputDirectory;
if (ViewOpts.hasOutputDirectory()) {
@ -451,7 +455,14 @@ int CodeCoverageTool::show(int argc, const char **argv,
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 @@ int CodeCoverageTool::show(int argc, const char **argv,
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;
}

View File

@ -88,6 +88,16 @@ std::string SourceCoverageView::formatCount(uint64_t N) {
return Result;
}
bool SourceCoverageView::shouldRenderRegionMarkers(
bool LineHasMultipleRegions) const {
return getOptions().ShowRegionMarkers &&
(!getOptions().ShowLineStatsOrRegionMarkers || LineHasMultipleRegions);
}
bool SourceCoverageView::hasSubViews() const {
return !ExpansionSubViews.empty() || !InstantiationSubViews.empty();
}
std::unique_ptr<SourceCoverageView>
SourceCoverageView::create(StringRef SourceName, const MemoryBuffer &File,
const CoverageViewOptions &Options,
@ -117,6 +127,8 @@ void SourceCoverageView::print(raw_ostream &OS, bool WholeFile,
if (ShowSourceName)
renderSourceName(OS);
renderViewHeader(OS);
// We need the expansions and instantiations sorted so we can go through them
// while we iterate lines.
std::sort(ExpansionSubViews.begin(), ExpansionSubViews.end());
@ -175,12 +187,8 @@ void SourceCoverageView::print(raw_ostream &OS, bool WholeFile,
ExpansionColumn, ViewDepth);
// Show the region markers.
if (getOptions().ShowRegionMarkers &&
(!getOptions().ShowLineStatsOrRegionMarkers ||
LineCount.hasMultipleRegions()) &&
!LineSegments.empty()) {
if (shouldRenderRegionMarkers(LineCount.hasMultipleRegions()))
renderRegionMarkers(OS, LineSegments, ViewDepth);
}
// Show the expansions and instantiations for this line.
bool RenderedSubView = false;
@ -192,9 +200,8 @@ void SourceCoverageView::print(raw_ostream &OS, bool WholeFile,
// this subview.
if (RenderedSubView) {
ExpansionColumn = NextESV->getStartCol();
renderExpansionSite(
OS, *NextESV, {*LI, LI.line_number()}, WrappedSegment, LineSegments,
ExpansionColumn, ViewDepth);
renderExpansionSite(OS, {*LI, LI.line_number()}, WrappedSegment,
LineSegments, ExpansionColumn, ViewDepth);
renderViewDivider(OS, ViewDepth + 1);
}
@ -208,5 +215,8 @@ void SourceCoverageView::print(raw_ostream &OS, bool WholeFile,
}
if (RenderedSubView)
renderViewDivider(OS, ViewDepth + 1);
renderLineSuffix(OS, ViewDepth);
}
renderViewFooter(OS);
}

View File

@ -183,12 +183,21 @@ protected:
/// @name Rendering Interface
/// @{
/// \brief Render a header for the view.
virtual void renderViewHeader(raw_ostream &OS) = 0;
/// \brief Render a footer for the view.
virtual void renderViewFooter(raw_ostream &OS) = 0;
/// \brief Render the source name for the view.
virtual void renderSourceName(raw_ostream &OS) = 0;
/// \brief Render the line prefix at the given \p ViewDepth.
virtual void renderLinePrefix(raw_ostream &OS, unsigned ViewDepth) = 0;
/// \brief Render the line suffix at the given \p ViewDepth.
virtual void renderLineSuffix(raw_ostream &OS, unsigned ViewDepth) = 0;
/// \brief Render a view divider at the given \p ViewDepth.
virtual void renderViewDivider(raw_ostream &OS, unsigned ViewDepth) = 0;
@ -212,7 +221,7 @@ protected:
/// \brief Render the site of an expansion.
virtual void
renderExpansionSite(raw_ostream &OS, ExpansionView &ESV, LineRef L,
renderExpansionSite(raw_ostream &OS, LineRef L,
const coverage::CoverageSegment *WrappedSegment,
CoverageSegmentArray Segments, unsigned ExpansionCol,
unsigned ViewDepth) = 0;
@ -231,6 +240,12 @@ protected:
/// digits.
static std::string formatCount(uint64_t N);
/// \brief Check if region marker output is expected for a line.
bool shouldRenderRegionMarkers(bool LineHasMultipleRegions) const;
/// \brief Check if there are any sub-views attached to this view.
bool hasSubViews() const;
SourceCoverageView(StringRef SourceName, const MemoryBuffer &File,
const CoverageViewOptions &Options,
coverage::CoverageData &&CoverageInfo)

View File

@ -59,6 +59,10 @@ unsigned getDividerWidth(const CoverageViewOptions &Opts) {
} // anonymous namespace
void SourceCoverageViewText::renderViewHeader(raw_ostream &OS) { (void)OS; }
void SourceCoverageViewText::renderViewFooter(raw_ostream &OS) { (void)OS; }
void SourceCoverageViewText::renderSourceName(raw_ostream &OS) {
getOptions().colored_ostream(OS, raw_ostream::CYAN) << getSourceName()
<< ":\n";
@ -70,6 +74,12 @@ void SourceCoverageViewText::renderLinePrefix(raw_ostream &OS,
OS << " |";
}
void SourceCoverageViewText::renderLineSuffix(raw_ostream &OS,
unsigned ViewDepth) {
(void)OS;
(void)ViewDepth;
}
void SourceCoverageViewText::renderViewDivider(raw_ostream &OS,
unsigned ViewDepth) {
assert(ViewDepth != 0 && "Cannot render divider at top level");
@ -180,8 +190,7 @@ void SourceCoverageViewText::renderRegionMarkers(
}
void SourceCoverageViewText::renderExpansionSite(
raw_ostream &OS, ExpansionView &ESV, LineRef L,
const coverage::CoverageSegment *WrappedSegment,
raw_ostream &OS, LineRef L, const coverage::CoverageSegment *WrappedSegment,
CoverageSegmentArray Segments, unsigned ExpansionCol, unsigned ViewDepth) {
renderLinePrefix(OS, ViewDepth);
OS.indent(getCombinedColumnWidth(getOptions()) + (ViewDepth == 0 ? 0 : 1));

View File

@ -34,10 +34,16 @@ public:
/// \brief A code coverage view which supports text-based rendering.
class SourceCoverageViewText : public SourceCoverageView {
void renderViewHeader(raw_ostream &OS) override;
void renderViewFooter(raw_ostream &OS) override;
void renderSourceName(raw_ostream &OS) override;
void renderLinePrefix(raw_ostream &OS, unsigned ViewDepth) override;
void renderLineSuffix(raw_ostream &OS, unsigned ViewDepth) override;
void renderViewDivider(raw_ostream &OS, unsigned ViewDepth) override;
void renderLine(raw_ostream &OS, LineRef L,
@ -45,7 +51,7 @@ class SourceCoverageViewText : public SourceCoverageView {
CoverageSegmentArray Segments, unsigned ExpansionCol,
unsigned ViewDepth) override;
void renderExpansionSite(raw_ostream &OS, ExpansionView &ESV, LineRef L,
void renderExpansionSite(raw_ostream &OS, LineRef L,
const coverage::CoverageSegment *WrappedSegment,
CoverageSegmentArray Segments, unsigned ExpansionCol,
unsigned ViewDepth) override;