diff options
Diffstat (limited to 'contrib/llvm/tools/llvm-cov')
-rw-r--r-- | contrib/llvm/tools/llvm-cov/CodeCoverage.cpp | 73 | ||||
-rw-r--r-- | contrib/llvm/tools/llvm-cov/CoverageReport.cpp | 40 | ||||
-rw-r--r-- | contrib/llvm/tools/llvm-cov/CoverageReport.h | 11 | ||||
-rw-r--r-- | contrib/llvm/tools/llvm-cov/CoverageSummary.cpp | 64 | ||||
-rw-r--r-- | contrib/llvm/tools/llvm-cov/CoverageSummary.h | 45 | ||||
-rw-r--r-- | contrib/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp | 25 | ||||
-rw-r--r-- | contrib/llvm/tools/llvm-cov/CoverageSummaryInfo.h | 53 | ||||
-rw-r--r-- | contrib/llvm/tools/llvm-cov/RenderingSupport.h | 2 | ||||
-rw-r--r-- | contrib/llvm/tools/llvm-cov/SourceCoverageView.cpp | 46 | ||||
-rw-r--r-- | contrib/llvm/tools/llvm-cov/SourceCoverageView.h | 7 | ||||
-rw-r--r-- | contrib/llvm/tools/llvm-cov/gcov.cpp | 9 | ||||
-rw-r--r-- | contrib/llvm/tools/llvm-cov/llvm-cov.cpp | 42 |
12 files changed, 176 insertions, 241 deletions
diff --git a/contrib/llvm/tools/llvm-cov/CodeCoverage.cpp b/contrib/llvm/tools/llvm-cov/CodeCoverage.cpp index 7cee4d4..8dc4d66 100644 --- a/contrib/llvm/tools/llvm-cov/CodeCoverage.cpp +++ b/contrib/llvm/tools/llvm-cov/CodeCoverage.cpp @@ -16,13 +16,12 @@ #include "RenderingSupport.h" #include "CoverageFilters.h" #include "CoverageReport.h" -#include "CoverageSummary.h" #include "CoverageViewOptions.h" #include "SourceCoverageView.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Triple.h" #include "llvm/ProfileData/CoverageMapping.h" -#include "llvm/ProfileData/CoverageMappingReader.h" #include "llvm/ProfileData/InstrProfReader.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" @@ -30,6 +29,7 @@ #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Path.h" #include "llvm/Support/PrettyStackTrace.h" +#include "llvm/Support/Process.h" #include "llvm/Support/Signals.h" #include <functional> #include <system_error> @@ -89,6 +89,7 @@ public: LoadedSourceFiles; bool CompareFilenamesOnly; StringMap<std::string> RemappedFilenames; + std::string CoverageArch; }; } @@ -115,8 +116,7 @@ CodeCoverageTool::getSourceFile(StringRef SourceFile) { error(EC.message(), SourceFile); return EC; } - LoadedSourceFiles.push_back( - std::make_pair(SourceFile, std::move(Buffer.get()))); + LoadedSourceFiles.emplace_back(SourceFile, std::move(Buffer.get())); return *LoadedSourceFiles.back().second; } @@ -194,8 +194,22 @@ CodeCoverageTool::createSourceFileView(StringRef SourceFile, return View; } +static bool modifiedTimeGT(StringRef LHS, StringRef RHS) { + sys::fs::file_status Status; + if (sys::fs::status(LHS, Status)) + return false; + auto LHSTime = Status.getLastModificationTime(); + if (sys::fs::status(RHS, Status)) + return false; + auto RHSTime = Status.getLastModificationTime(); + return LHSTime > RHSTime; +} + std::unique_ptr<CoverageMapping> CodeCoverageTool::load() { - auto CoverageOrErr = CoverageMapping::load(ObjectFilename, PGOFilename); + if (modifiedTimeGT(ObjectFilename, PGOFilename)) + errs() << "warning: profile data may be out of date - object is newer\n"; + auto CoverageOrErr = CoverageMapping::load(ObjectFilename, PGOFilename, + CoverageArch); if (std::error_code EC = CoverageOrErr.getError()) { colored_ostream(errs(), raw_ostream::RED) << "error: Failed to load coverage: " << EC.message(); @@ -244,6 +258,9 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) { cl::desc( "File with the profile data obtained after an instrumented run")); + cl::opt<std::string> Arch( + "arch", cl::desc("architecture of the coverage mapping binary")); + cl::opt<bool> DebugDump("dump", cl::Optional, cl::desc("Show internal debug dump")); @@ -289,11 +306,19 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) { "greater than the given threshold"), cl::cat(FilteringCategory)); + cl::opt<cl::boolOrDefault> UseColor( + "use-color", cl::desc("Emit colored output (default=autodetect)"), + cl::init(cl::BOU_UNSET)); + auto commandLineParser = [&, this](int argc, const char **argv) -> int { cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n"); ViewOpts.Debug = DebugDump; CompareFilenamesOnly = FilenameEquivalence; + ViewOpts.Colors = UseColor == cl::BOU_UNSET + ? sys::Process::StandardOutHasColors() + : UseColor == cl::BOU_TRUE; + // Create the function filters if (!NameFilters.empty() || !NameRegexFilters.empty()) { auto NameFilterer = new CoverageFilters; @@ -324,12 +349,20 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) { Filters.push_back(std::unique_ptr<CoverageFilter>(StatFilterer)); } + if (!Arch.empty() && + Triple(Arch).getArch() == llvm::Triple::ArchType::UnknownArch) { + errs() << "error: Unknown architecture: " << Arch << "\n"; + return 1; + } + CoverageArch = Arch; + for (const auto &File : InputSourceFiles) { SmallString<128> Path(File); - if (std::error_code EC = sys::fs::make_absolute(Path)) { - errs() << "error: " << File << ": " << EC.message(); - return 1; - } + if (!CompareFilenamesOnly) + if (std::error_code EC = sys::fs::make_absolute(Path)) { + errs() << "error: " << File << ": " << EC.message(); + return 1; + } SourceFiles.push_back(Path.str()); } return 0; @@ -373,15 +406,10 @@ int CodeCoverageTool::show(int argc, const char **argv, cl::desc("Show function instantiations"), cl::cat(ViewCategory)); - cl::opt<bool> NoColors("no-colors", cl::Optional, - cl::desc("Don't show text colors"), cl::init(false), - cl::cat(ViewCategory)); - auto Err = commandLineParser(argc, argv); if (Err) return Err; - ViewOpts.Colors = !NoColors; ViewOpts.ShowLineNumbers = true; ViewOpts.ShowLineStats = ShowLineExecutionCounts.getNumOccurrences() != 0 || !ShowRegions || ShowBestLineRegionsCounts; @@ -447,28 +475,19 @@ int CodeCoverageTool::show(int argc, const char **argv, int CodeCoverageTool::report(int argc, const char **argv, CommandLineParserType commandLineParser) { - cl::opt<bool> NoColors("no-colors", cl::Optional, - cl::desc("Don't show text colors"), cl::init(false)); - auto Err = commandLineParser(argc, argv); if (Err) return Err; - ViewOpts.Colors = !NoColors; - auto Coverage = load(); if (!Coverage) return 1; - CoverageSummary Summarizer; - Summarizer.createSummaries(*Coverage); - CoverageReport Report(ViewOpts, Summarizer); - if (SourceFiles.empty() && Filters.empty()) { + CoverageReport Report(ViewOpts, std::move(Coverage)); + if (SourceFiles.empty()) Report.renderFileReports(llvm::outs()); - return 0; - } - - Report.renderFunctionReports(llvm::outs()); + else + Report.renderFunctionReports(SourceFiles, llvm::outs()); return 0; } diff --git a/contrib/llvm/tools/llvm-cov/CoverageReport.cpp b/contrib/llvm/tools/llvm-cov/CoverageReport.cpp index 6ae6ba5..497c2f8 100644 --- a/contrib/llvm/tools/llvm-cov/CoverageReport.cpp +++ b/contrib/llvm/tools/llvm-cov/CoverageReport.cpp @@ -12,7 +12,6 @@ //===----------------------------------------------------------------------===// #include "CoverageReport.h" -#include "CoverageSummary.h" #include "RenderingSupport.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Format.h" @@ -156,14 +155,15 @@ void CoverageReport::render(const FunctionCoverageSummary &Function, OS << "\n"; } -void CoverageReport::renderFunctionReports(raw_ostream &OS) { +void CoverageReport::renderFunctionReports(ArrayRef<std::string> Files, + raw_ostream &OS) { bool isFirst = true; - for (const auto &File : Summary.getFileSummaries()) { + for (StringRef Filename : Files) { if (isFirst) isFirst = false; else OS << "\n"; - OS << "File '" << File.Name << "':\n"; + OS << "File '" << Filename << "':\n"; OS << column("Name", FunctionReportColumns[0]) << column("Regions", FunctionReportColumns[1], Column::RightAlignment) << column("Miss", FunctionReportColumns[2], Column::RightAlignment) @@ -174,13 +174,19 @@ void CoverageReport::renderFunctionReports(raw_ostream &OS) { OS << "\n"; renderDivider(FunctionReportColumns, OS); OS << "\n"; - for (const auto &Function : File.FunctionSummaries) + FunctionCoverageSummary Totals("TOTAL"); + for (const auto &F : Coverage->getCoveredFunctions(Filename)) { + FunctionCoverageSummary Function = FunctionCoverageSummary::get(F); + ++Totals.ExecutionCount; + Totals.RegionCoverage += Function.RegionCoverage; + Totals.LineCoverage += Function.LineCoverage; render(Function, OS); - renderDivider(FunctionReportColumns, OS); - OS << "\n"; - render(FunctionCoverageSummary("TOTAL", /*ExecutionCount=*/0, - File.RegionCoverage, File.LineCoverage), - OS); + } + if (Totals.ExecutionCount) { + renderDivider(FunctionReportColumns, OS); + OS << "\n"; + render(Totals, OS); + } } } @@ -194,9 +200,17 @@ void CoverageReport::renderFileReports(raw_ostream &OS) { << "\n"; renderDivider(FileReportColumns, OS); OS << "\n"; - for (const auto &File : Summary.getFileSummaries()) - render(File, OS); + FileCoverageSummary Totals("TOTAL"); + for (StringRef Filename : Coverage->getUniqueSourceFiles()) { + FileCoverageSummary Summary(Filename); + for (const auto &F : Coverage->getCoveredFunctions(Filename)) { + FunctionCoverageSummary Function = FunctionCoverageSummary::get(F); + Summary.addFunction(Function); + Totals.addFunction(Function); + } + render(Summary, OS); + } renderDivider(FileReportColumns, OS); OS << "\n"; - render(Summary.getCombinedFileSummaries(), OS); + render(Totals, OS); } diff --git a/contrib/llvm/tools/llvm-cov/CoverageReport.h b/contrib/llvm/tools/llvm-cov/CoverageReport.h index d186117..7ec3df9 100644 --- a/contrib/llvm/tools/llvm-cov/CoverageReport.h +++ b/contrib/llvm/tools/llvm-cov/CoverageReport.h @@ -14,7 +14,7 @@ #ifndef LLVM_COV_COVERAGEREPORT_H #define LLVM_COV_COVERAGEREPORT_H -#include "CoverageSummary.h" +#include "CoverageSummaryInfo.h" #include "CoverageViewOptions.h" namespace llvm { @@ -22,16 +22,17 @@ namespace llvm { /// \brief Displays the code coverage report. class CoverageReport { const CoverageViewOptions &Options; - CoverageSummary &Summary; + std::unique_ptr<coverage::CoverageMapping> Coverage; void render(const FileCoverageSummary &File, raw_ostream &OS); void render(const FunctionCoverageSummary &Function, raw_ostream &OS); public: - CoverageReport(const CoverageViewOptions &Options, CoverageSummary &Summary) - : Options(Options), Summary(Summary) {} + CoverageReport(const CoverageViewOptions &Options, + std::unique_ptr<coverage::CoverageMapping> Coverage) + : Options(Options), Coverage(std::move(Coverage)) {} - void renderFunctionReports(raw_ostream &OS); + void renderFunctionReports(ArrayRef<std::string> Files, raw_ostream &OS); void renderFileReports(raw_ostream &OS); }; diff --git a/contrib/llvm/tools/llvm-cov/CoverageSummary.cpp b/contrib/llvm/tools/llvm-cov/CoverageSummary.cpp deleted file mode 100644 index 059c8c8..0000000 --- a/contrib/llvm/tools/llvm-cov/CoverageSummary.cpp +++ /dev/null @@ -1,64 +0,0 @@ -//===- CoverageSummary.cpp - Code coverage summary ------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This class implements data management and rendering for the code coverage -// summaries of all files and functions. -// -//===----------------------------------------------------------------------===// - -#include "CoverageSummary.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Format.h" - -using namespace llvm; - -unsigned CoverageSummary::getFileID(StringRef Filename) { - for (unsigned I = 0, E = Filenames.size(); I < E; ++I) { - if (sys::fs::equivalent(Filenames[I], Filename)) - return I; - } - Filenames.push_back(Filename); - return Filenames.size() - 1; -} - -void -CoverageSummary::createSummaries(const coverage::CoverageMapping &Coverage) { - for (StringRef Filename : Coverage.getUniqueSourceFiles()) { - size_t PrevSize = FunctionSummaries.size(); - for (const auto &F : Coverage.getCoveredFunctions(Filename)) - FunctionSummaries.push_back(FunctionCoverageSummary::get(F)); - size_t Count = FunctionSummaries.size() - PrevSize; - if (Count == 0) - continue; - FileSummaries.push_back(FileCoverageSummary::get( - Filename, makeArrayRef(FunctionSummaries.data() + PrevSize, Count))); - } -} - -FileCoverageSummary CoverageSummary::getCombinedFileSummaries() { - size_t NumRegions = 0, CoveredRegions = 0; - size_t NumLines = 0, NonCodeLines = 0, CoveredLines = 0; - size_t NumFunctionsExecuted = 0, NumFunctions = 0; - for (const auto &File : FileSummaries) { - NumRegions += File.RegionCoverage.NumRegions; - CoveredRegions += File.RegionCoverage.Covered; - - NumLines += File.LineCoverage.NumLines; - NonCodeLines += File.LineCoverage.NonCodeLines; - CoveredLines += File.LineCoverage.Covered; - - NumFunctionsExecuted += File.FunctionCoverage.Executed; - NumFunctions += File.FunctionCoverage.NumFunctions; - } - return FileCoverageSummary( - "TOTAL", RegionCoverageInfo(CoveredRegions, NumRegions), - LineCoverageInfo(CoveredLines, NonCodeLines, NumLines), - FunctionCoverageInfo(NumFunctionsExecuted, NumFunctions), - None); -} diff --git a/contrib/llvm/tools/llvm-cov/CoverageSummary.h b/contrib/llvm/tools/llvm-cov/CoverageSummary.h deleted file mode 100644 index 9dbebde..0000000 --- a/contrib/llvm/tools/llvm-cov/CoverageSummary.h +++ /dev/null @@ -1,45 +0,0 @@ -//===- CoverageSummary.h - Code coverage summary --------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This class implements data management and rendering for the code coverage -// summaries of all files and functions. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_COV_COVERAGESUMMARY_H -#define LLVM_COV_COVERAGESUMMARY_H - -#include "CoverageSummaryInfo.h" -#include <vector> - -namespace llvm { - -/// \brief Manager for the function and file code coverage summaries. -class CoverageSummary { - std::vector<StringRef> Filenames; - std::vector<FunctionCoverageSummary> FunctionSummaries; - std::vector<std::pair<unsigned, unsigned>> FunctionSummariesFileIDs; - std::vector<FileCoverageSummary> FileSummaries; - - unsigned getFileID(StringRef Filename); - -public: - void createSummaries(const coverage::CoverageMapping &Coverage); - - ArrayRef<FileCoverageSummary> getFileSummaries() { return FileSummaries; } - - FileCoverageSummary getCombinedFileSummaries(); - - void render(const FunctionCoverageSummary &Summary, raw_ostream &OS); - - void render(raw_ostream &OS); -}; -} - -#endif // LLVM_COV_COVERAGESUMMARY_H diff --git a/contrib/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp b/contrib/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp index dd78ace..de89750 100644 --- a/contrib/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp +++ b/contrib/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp @@ -69,28 +69,3 @@ FunctionCoverageSummary::get(const coverage::FunctionRecord &Function) { RegionCoverageInfo(CoveredRegions, NumCodeRegions), LineCoverageInfo(CoveredLines, 0, NumLines)); } - -FileCoverageSummary -FileCoverageSummary::get(StringRef Name, - ArrayRef<FunctionCoverageSummary> FunctionSummaries) { - size_t NumRegions = 0, CoveredRegions = 0; - size_t NumLines = 0, NonCodeLines = 0, CoveredLines = 0; - size_t NumFunctionsExecuted = 0; - for (const auto &Func : FunctionSummaries) { - CoveredRegions += Func.RegionCoverage.Covered; - NumRegions += Func.RegionCoverage.NumRegions; - - CoveredLines += Func.LineCoverage.Covered; - NonCodeLines += Func.LineCoverage.NonCodeLines; - NumLines += Func.LineCoverage.NumLines; - - if (Func.ExecutionCount != 0) - ++NumFunctionsExecuted; - } - - return FileCoverageSummary( - Name, RegionCoverageInfo(CoveredRegions, NumRegions), - LineCoverageInfo(CoveredLines, NonCodeLines, NumLines), - FunctionCoverageInfo(NumFunctionsExecuted, FunctionSummaries.size()), - FunctionSummaries); -} diff --git a/contrib/llvm/tools/llvm-cov/CoverageSummaryInfo.h b/contrib/llvm/tools/llvm-cov/CoverageSummaryInfo.h index 0036032..c393b00 100644 --- a/contrib/llvm/tools/llvm-cov/CoverageSummaryInfo.h +++ b/contrib/llvm/tools/llvm-cov/CoverageSummaryInfo.h @@ -31,10 +31,19 @@ struct RegionCoverageInfo { /// \brief The total number of regions in a function/file. size_t NumRegions; + RegionCoverageInfo() : Covered(0), NotCovered(0), NumRegions(0) {} + RegionCoverageInfo(size_t Covered, size_t NumRegions) : Covered(Covered), NotCovered(NumRegions - Covered), NumRegions(NumRegions) {} + RegionCoverageInfo &operator+=(const RegionCoverageInfo &RHS) { + Covered += RHS.Covered; + NotCovered += RHS.NotCovered; + NumRegions += RHS.NumRegions; + return *this; + } + bool isFullyCovered() const { return Covered == NumRegions; } double getPercentCovered() const { @@ -56,10 +65,21 @@ struct LineCoverageInfo { /// \brief The total number of lines in a function/file. size_t NumLines; + LineCoverageInfo() + : Covered(0), NotCovered(0), NonCodeLines(0), NumLines(0) {} + LineCoverageInfo(size_t Covered, size_t NumNonCodeLines, size_t NumLines) : Covered(Covered), NotCovered(NumLines - NumNonCodeLines - Covered), NonCodeLines(NumNonCodeLines), NumLines(NumLines) {} + LineCoverageInfo &operator+=(const LineCoverageInfo &RHS) { + Covered += RHS.Covered; + NotCovered += RHS.NotCovered; + NonCodeLines += RHS.NonCodeLines; + NumLines += RHS.NumLines; + return *this; + } + bool isFullyCovered() const { return Covered == (NumLines - NonCodeLines); } double getPercentCovered() const { @@ -75,9 +95,17 @@ struct FunctionCoverageInfo { /// \brief The total number of functions in this file. size_t NumFunctions; + FunctionCoverageInfo() : Executed(0), NumFunctions(0) {} + FunctionCoverageInfo(size_t Executed, size_t NumFunctions) : Executed(Executed), NumFunctions(NumFunctions) {} + void addFunction(bool Covered) { + if (Covered) + ++Executed; + ++NumFunctions; + } + bool isFullyCovered() const { return Executed == NumFunctions; } double getPercentCovered() const { @@ -92,6 +120,8 @@ struct FunctionCoverageSummary { RegionCoverageInfo RegionCoverage; LineCoverageInfo LineCoverage; + FunctionCoverageSummary(StringRef Name) : Name(Name), ExecutionCount(0) {} + FunctionCoverageSummary(StringRef Name, uint64_t ExecutionCount, const RegionCoverageInfo &RegionCoverage, const LineCoverageInfo &LineCoverage) @@ -111,21 +141,14 @@ struct FileCoverageSummary { RegionCoverageInfo RegionCoverage; LineCoverageInfo LineCoverage; FunctionCoverageInfo FunctionCoverage; - /// \brief The summary of every function - /// in this file. - ArrayRef<FunctionCoverageSummary> FunctionSummaries; - - FileCoverageSummary(StringRef Name, const RegionCoverageInfo &RegionCoverage, - const LineCoverageInfo &LineCoverage, - const FunctionCoverageInfo &FunctionCoverage, - ArrayRef<FunctionCoverageSummary> FunctionSummaries) - : Name(Name), RegionCoverage(RegionCoverage), LineCoverage(LineCoverage), - FunctionCoverage(FunctionCoverage), - FunctionSummaries(FunctionSummaries) {} - - /// \brief Compute the code coverage summary for a file. - static FileCoverageSummary - get(StringRef Name, ArrayRef<FunctionCoverageSummary> FunctionSummaries); + + FileCoverageSummary(StringRef Name) : Name(Name) {} + + void addFunction(const FunctionCoverageSummary &Function) { + RegionCoverage += Function.RegionCoverage; + LineCoverage += Function.LineCoverage; + FunctionCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0); + } }; } // namespace llvm diff --git a/contrib/llvm/tools/llvm-cov/RenderingSupport.h b/contrib/llvm/tools/llvm-cov/RenderingSupport.h index 0271329..3ef155d 100644 --- a/contrib/llvm/tools/llvm-cov/RenderingSupport.h +++ b/contrib/llvm/tools/llvm-cov/RenderingSupport.h @@ -18,7 +18,7 @@ namespace llvm { /// \brief A helper class that resets the output stream's color if needed /// when destroyed. class ColoredRawOstream { - ColoredRawOstream(const ColoredRawOstream &OS) LLVM_DELETED_FUNCTION; + ColoredRawOstream(const ColoredRawOstream &OS) = delete; public: raw_ostream &OS; diff --git a/contrib/llvm/tools/llvm-cov/SourceCoverageView.cpp b/contrib/llvm/tools/llvm-cov/SourceCoverageView.cpp index 015099c..58c8a67 100644 --- a/contrib/llvm/tools/llvm-cov/SourceCoverageView.cpp +++ b/contrib/llvm/tools/llvm-cov/SourceCoverageView.cpp @@ -14,6 +14,7 @@ #include "SourceCoverageView.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/Support/LineIterator.h" using namespace llvm; @@ -77,6 +78,22 @@ void SourceCoverageView::renderViewDivider(unsigned Level, unsigned Length, OS << "-"; } +/// Format a count using engineering notation with 3 significant digits. +static std::string formatCount(uint64_t N) { + std::string Number = utostr(N); + int Len = Number.size(); + if (Len <= 3) + return Number; + int IntLen = Len % 3 == 0 ? 3 : Len % 3; + std::string Result(Number.data(), IntLen); + if (IntLen != 3) { + Result.push_back('.'); + Result += Number.substr(IntLen, 3 - IntLen); + } + Result.push_back(" kMGTPEZY"[(Len - 1) / 3]); + return Result; +} + void SourceCoverageView::renderLineCoverageColumn(raw_ostream &OS, const LineCoverageInfo &Line) { @@ -84,17 +101,11 @@ SourceCoverageView::renderLineCoverageColumn(raw_ostream &OS, OS.indent(LineCoverageColumnWidth) << '|'; return; } - SmallString<32> Buffer; - raw_svector_ostream BufferOS(Buffer); - BufferOS << Line.ExecutionCount; - auto Str = BufferOS.str(); - // Trim - Str = Str.substr(0, std::min(Str.size(), (size_t)LineCoverageColumnWidth)); - // Align to the right - OS.indent(LineCoverageColumnWidth - Str.size()); + std::string C = formatCount(Line.ExecutionCount); + OS.indent(LineCoverageColumnWidth - C.size()); colored_ostream(OS, raw_ostream::MAGENTA, Line.hasMultipleRegions() && Options.Colors) - << Str; + << C; OS << '|'; } @@ -111,9 +122,6 @@ void SourceCoverageView::renderLineNumberColumn(raw_ostream &OS, void SourceCoverageView::renderRegionMarkers( raw_ostream &OS, ArrayRef<const coverage::CoverageSegment *> Segments) { - SmallString<32> Buffer; - raw_svector_ostream BufferOS(Buffer); - unsigned PrevColumn = 1; for (const auto *S : Segments) { if (!S->IsRegionEntry) @@ -122,20 +130,16 @@ void SourceCoverageView::renderRegionMarkers( if (S->Col > PrevColumn) OS.indent(S->Col - PrevColumn); PrevColumn = S->Col + 1; - BufferOS << S->Count; - StringRef Str = BufferOS.str(); - // Trim the execution count - Str = Str.substr(0, std::min(Str.size(), (size_t)7)); - PrevColumn += Str.size(); - OS << '^' << Str; - Buffer.clear(); + std::string C = formatCount(S->Count); + PrevColumn += C.size(); + OS << '^' << C; } OS << "\n"; if (Options.Debug) for (const auto *S : Segments) - errs() << "Marker at " << S->Line << ":" << S->Col << " = " << S->Count - << (S->IsRegionEntry ? "\n" : " (pop)\n"); + errs() << "Marker at " << S->Line << ":" << S->Col << " = " + << formatCount(S->Count) << (S->IsRegionEntry ? "\n" : " (pop)\n"); } void SourceCoverageView::render(raw_ostream &OS, bool WholeFile, diff --git a/contrib/llvm/tools/llvm-cov/SourceCoverageView.h b/contrib/llvm/tools/llvm-cov/SourceCoverageView.h index d92a748..9e6fe5f 100644 --- a/contrib/llvm/tools/llvm-cov/SourceCoverageView.h +++ b/contrib/llvm/tools/llvm-cov/SourceCoverageView.h @@ -90,15 +90,14 @@ private: bool hasMultipleRegions() const { return RegionCount > 1; } void addRegionStartCount(uint64_t Count) { - Mapped = true; - ExecutionCount = Count; + // The max of all region starts is the most interesting value. + addRegionCount(RegionCount ? std::max(ExecutionCount, Count) : Count); ++RegionCount; } void addRegionCount(uint64_t Count) { Mapped = true; - if (!RegionCount) - ExecutionCount = Count; + ExecutionCount = Count; } }; diff --git a/contrib/llvm/tools/llvm-cov/gcov.cpp b/contrib/llvm/tools/llvm-cov/gcov.cpp index 12011ce..4377a50 100644 --- a/contrib/llvm/tools/llvm-cov/gcov.cpp +++ b/contrib/llvm/tools/llvm-cov/gcov.cpp @@ -23,9 +23,10 @@ #include <system_error> using namespace llvm; -void reportCoverage(StringRef SourceFile, StringRef ObjectDir, - const std::string &InputGCNO, const std::string &InputGCDA, - bool DumpGCOV, const GCOVOptions &Options) { +static void reportCoverage(StringRef SourceFile, StringRef ObjectDir, + const std::string &InputGCNO, + const std::string &InputGCDA, bool DumpGCOV, + const GCOVOptions &Options) { SmallString<128> CoverageFileStem(ObjectDir); if (CoverageFileStem.empty()) { // If no directory was specified with -o, look next to the source file. @@ -80,7 +81,7 @@ void reportCoverage(StringRef SourceFile, StringRef ObjectDir, FileInfo FI(Options); GF.collectLineCounts(FI); - FI.print(SourceFile, GCNO, GCDA); + FI.print(llvm::outs(), SourceFile, GCNO, GCDA); } int gcovMain(int argc, const char *argv[]) { diff --git a/contrib/llvm/tools/llvm-cov/llvm-cov.cpp b/contrib/llvm/tools/llvm-cov/llvm-cov.cpp index 86ec26d..8c5acae 100644 --- a/contrib/llvm/tools/llvm-cov/llvm-cov.cpp +++ b/contrib/llvm/tools/llvm-cov/llvm-cov.cpp @@ -13,7 +13,9 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Path.h" +#include "llvm/Support/Process.h" #include "llvm/Support/raw_ostream.h" #include <string> @@ -32,9 +34,19 @@ int convertForTestingMain(int argc, const char *argv[]); int gcovMain(int argc, const char *argv[]); /// \brief Top level help. -int helpMain(int argc, const char *argv[]) { - errs() << "OVERVIEW: LLVM code coverage tool\n\n" - << "USAGE: llvm-cov {gcov|report|show}\n"; +static int helpMain(int argc, const char *argv[]) { + errs() << "Usage: llvm-cov {gcov|report|show} [OPTION]...\n\n" + << "Shows code coverage information.\n\n" + << "Subcommands:\n" + << " gcov: Work with the gcov format.\n" + << " show: Annotate source files using instrprof style coverage.\n" + << " report: Summarize instrprof style coverage information.\n"; + return 0; +} + +/// \brief Top level version information. +static int versionMain(int argc, const char *argv[]) { + cl::PrintVersionMessage(); return 0; } @@ -52,6 +64,7 @@ int main(int argc, const char **argv) { .Case("report", reportMain) .Case("show", showMain) .Cases("-h", "-help", "--help", helpMain) + .Cases("-version", "--version", versionMain) .Default(nullptr); if (Func) { @@ -61,18 +74,13 @@ int main(int argc, const char **argv) { } } - // Give a warning and fall back to gcov - errs().changeColor(raw_ostream::RED); - errs() << "warning:"; - // Assume that argv[1] wasn't a command when it stats with a '-' or is a - // filename (i.e. contains a '.') - if (argc > 1 && !StringRef(argv[1]).startswith("-") && - StringRef(argv[1]).find(".") == StringRef::npos) - errs() << " Unrecognized command '" << argv[1] << "'."; - errs() << " Using the gcov compatible mode " - "(this behaviour may be dropped in the future)."; - errs().resetColor(); - errs() << "\n"; - - return gcovMain(argc, argv); + if (argc > 1) { + if (sys::Process::StandardErrHasColors()) + errs().changeColor(raw_ostream::RED); + errs() << "Unrecognized command: " << argv[1] << ".\n\n"; + if (sys::Process::StandardErrHasColors()) + errs().resetColor(); + } + helpMain(argc, argv); + return 1; } |