diff options
Diffstat (limited to 'contrib/llvm-project/llvm/tools/llvm-cov/CodeCoverage.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/tools/llvm-cov/CodeCoverage.cpp | 96 |
1 files changed, 85 insertions, 11 deletions
diff --git a/contrib/llvm-project/llvm/tools/llvm-cov/CodeCoverage.cpp b/contrib/llvm-project/llvm/tools/llvm-cov/CodeCoverage.cpp index b3c895b44a6d..baa968820b63 100644 --- a/contrib/llvm-project/llvm/tools/llvm-cov/CodeCoverage.cpp +++ b/contrib/llvm-project/llvm/tools/llvm-cov/CodeCoverage.cpp @@ -88,6 +88,12 @@ private: ArrayRef<ExpansionRecord> Expansions, const CoverageMapping &Coverage); + /// Create source views for the branches of the view. + void attachBranchSubViews(SourceCoverageView &View, StringRef SourceName, + ArrayRef<CountedRegion> Branches, + const MemoryBuffer &File, + CoverageData &CoverageInfo); + /// Create the source view of a particular function. std::unique_ptr<SourceCoverageView> createFunctionView(const FunctionRecord &Function, @@ -130,6 +136,9 @@ private: CoverageFiltersMatchAll Filters; CoverageFilters IgnoreFilenameFilters; + /// True if InputSourceFiles are provided. + bool HadSourceFiles = false; + /// The path to the indexed profile. std::string PGOFilename; @@ -194,6 +203,7 @@ void CodeCoverageTool::addCollectedPath(const std::string &Path) { sys::path::remove_dots(EffectivePath, /*remove_dot_dots=*/true); if (!IgnoreFilenameFilters.matchesFilename(EffectivePath)) SourceFiles.emplace_back(EffectivePath.str()); + HadSourceFiles = !SourceFiles.empty(); } void CodeCoverageTool::collectPaths(const std::string &Path) { @@ -264,15 +274,45 @@ void CodeCoverageTool::attachExpansionSubViews( if (!SourceBuffer) continue; + auto SubViewBranches = ExpansionCoverage.getBranches(); auto SubViewExpansions = ExpansionCoverage.getExpansions(); auto SubView = SourceCoverageView::create(Expansion.Function.Name, SourceBuffer.get(), ViewOpts, std::move(ExpansionCoverage)); attachExpansionSubViews(*SubView, SubViewExpansions, Coverage); + attachBranchSubViews(*SubView, Expansion.Function.Name, SubViewBranches, + SourceBuffer.get(), ExpansionCoverage); View.addExpansion(Expansion.Region, std::move(SubView)); } } +void CodeCoverageTool::attachBranchSubViews(SourceCoverageView &View, + StringRef SourceName, + ArrayRef<CountedRegion> Branches, + const MemoryBuffer &File, + CoverageData &CoverageInfo) { + if (!ViewOpts.ShowBranchCounts && !ViewOpts.ShowBranchPercents) + return; + + const auto *NextBranch = Branches.begin(); + const auto *EndBranch = Branches.end(); + + // Group branches that have the same line number into the same subview. + while (NextBranch != EndBranch) { + std::vector<CountedRegion> ViewBranches; + unsigned CurrentLine = NextBranch->LineStart; + + while (NextBranch != EndBranch && CurrentLine == NextBranch->LineStart) + ViewBranches.push_back(*NextBranch++); + + if (!ViewBranches.empty()) { + auto SubView = SourceCoverageView::create(SourceName, File, ViewOpts, + std::move(CoverageInfo)); + View.addBranch(CurrentLine, ViewBranches, std::move(SubView)); + } + } +} + std::unique_ptr<SourceCoverageView> CodeCoverageTool::createFunctionView(const FunctionRecord &Function, const CoverageMapping &Coverage) { @@ -283,11 +323,14 @@ CodeCoverageTool::createFunctionView(const FunctionRecord &Function, if (!SourceBuffer) return nullptr; + auto Branches = FunctionCoverage.getBranches(); auto Expansions = FunctionCoverage.getExpansions(); auto View = SourceCoverageView::create(DC.demangle(Function.Name), SourceBuffer.get(), ViewOpts, std::move(FunctionCoverage)); attachExpansionSubViews(*View, Expansions, Coverage); + attachBranchSubViews(*View, DC.demangle(Function.Name), Branches, + SourceBuffer.get(), FunctionCoverage); return View; } @@ -302,10 +345,13 @@ CodeCoverageTool::createSourceFileView(StringRef SourceFile, if (FileCoverage.empty()) return nullptr; + auto Branches = FileCoverage.getBranches(); auto Expansions = FileCoverage.getExpansions(); auto View = SourceCoverageView::create(SourceFile, SourceBuffer.get(), ViewOpts, std::move(FileCoverage)); attachExpansionSubViews(*View, Expansions, Coverage); + attachBranchSubViews(*View, SourceFile, Branches, SourceBuffer.get(), + FileCoverage); if (!ViewOpts.ShowFunctionInstantiations) return View; @@ -322,9 +368,12 @@ CodeCoverageTool::createSourceFileView(StringRef SourceFile, if (Function->ExecutionCount > 0) { auto SubViewCoverage = Coverage.getCoverageForFunction(*Function); auto SubViewExpansions = SubViewCoverage.getExpansions(); + auto SubViewBranches = SubViewCoverage.getBranches(); SubView = SourceCoverageView::create( Funcname, SourceBuffer.get(), ViewOpts, std::move(SubViewCoverage)); attachExpansionSubViews(*SubView, SubViewExpansions, Coverage); + attachBranchSubViews(*SubView, SourceFile, SubViewBranches, + SourceBuffer.get(), SubViewCoverage); } unsigned FileID = Function->CountedRegions.front().FileID; @@ -395,6 +444,7 @@ void CodeCoverageTool::remapPathNames(const CoverageMapping &Coverage) { return ""; SmallString<128> NativePath; sys::path::native(Path, NativePath); + sys::path::remove_dots(NativePath, true); if (!sys::path::is_separator(NativePath.back())) NativePath += sys::path::get_separator(); return NativePath.c_str(); @@ -406,6 +456,7 @@ void CodeCoverageTool::remapPathNames(const CoverageMapping &Coverage) { for (StringRef Filename : Coverage.getUniqueSourceFiles()) { SmallString<128> NativeFilename; sys::path::native(Filename, NativeFilename); + sys::path::remove_dots(NativeFilename, true); if (NativeFilename.startswith(RemapFrom)) { RemappedFilenames[Filename] = RemapTo + NativeFilename.substr(RemapFrom.size()).str(); @@ -430,16 +481,11 @@ void CodeCoverageTool::remapPathNames(const CoverageMapping &Coverage) { void CodeCoverageTool::removeUnmappedInputs(const CoverageMapping &Coverage) { std::vector<StringRef> CoveredFiles = Coverage.getUniqueSourceFiles(); - auto UncoveredFilesIt = SourceFiles.end(); // The user may have specified source files which aren't in the coverage // mapping. Filter these files away. - UncoveredFilesIt = std::remove_if( - SourceFiles.begin(), SourceFiles.end(), [&](const std::string &SF) { - return !std::binary_search(CoveredFiles.begin(), CoveredFiles.end(), - SF); - }); - - SourceFiles.erase(UncoveredFilesIt, SourceFiles.end()); + llvm::erase_if(SourceFiles, [&](const std::string &SF) { + return !std::binary_search(CoveredFiles.begin(), CoveredFiles.end(), SF); + }); } void CodeCoverageTool::demangleSymbols(const CoverageMapping &Coverage) { @@ -544,8 +590,11 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) { cl::Positional, cl::desc("Covered executable or object file.")); cl::list<std::string> CovFilenames( - "object", cl::desc("Coverage executable or object file"), cl::ZeroOrMore, - cl::CommaSeparated); + "object", cl::desc("Coverage executable or object file"), cl::ZeroOrMore); + + cl::opt<bool> DebugDumpCollectedObjects( + "dump-collected-objects", cl::Optional, cl::Hidden, + cl::desc("Show the collected coverage object files")); cl::list<std::string> InputSourceFiles( cl::Positional, cl::desc("<Source files>"), cl::ZeroOrMore); @@ -641,6 +690,11 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) { cl::desc("Show region statistics in summary table"), cl::init(true)); + cl::opt<bool> BranchSummary( + "show-branch-summary", cl::Optional, + cl::desc("Show branch condition statistics in summary table"), + cl::init(true)); + cl::opt<bool> InstantiationSummary( "show-instantiation-summary", cl::Optional, cl::desc("Show instantiation statistics in summary table")); @@ -668,6 +722,12 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) { ::exit(1); } + if (DebugDumpCollectedObjects) { + for (StringRef OF : ObjectFilenames) + outs() << OF << '\n'; + ::exit(0); + } + ViewOpts.Format = Format; switch (ViewOpts.Format) { case CoverageViewOptions::OutputFormat::Text: @@ -778,6 +838,7 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) { ::exit(0); } + ViewOpts.ShowBranchSummary = BranchSummary; ViewOpts.ShowRegionSummary = RegionSummary; ViewOpts.ShowInstantiationSummary = InstantiationSummary; ViewOpts.ExportSummaryOnly = SummaryOnly; @@ -812,6 +873,15 @@ int CodeCoverageTool::doShow(int argc, const char **argv, cl::desc("Show the execution counts for each region"), cl::cat(ViewCategory)); + cl::opt<CoverageViewOptions::BranchOutputType> ShowBranches( + "show-branches", cl::Optional, + cl::desc("Show coverage for branch conditions"), cl::cat(ViewCategory), + cl::values(clEnumValN(CoverageViewOptions::BranchOutputType::Count, + "count", "Show True/False counts"), + clEnumValN(CoverageViewOptions::BranchOutputType::Percent, + "percent", "Show True/False percent")), + cl::init(CoverageViewOptions::BranchOutputType::Off)); + cl::opt<bool> ShowBestLineRegionsCounts( "show-line-counts-or-regions", cl::Optional, cl::desc("Show the execution counts for each line, or the execution " @@ -855,6 +925,10 @@ int CodeCoverageTool::doShow(int argc, const char **argv, !ShowRegions || ShowBestLineRegionsCounts; ViewOpts.ShowRegionMarkers = ShowRegions || ShowBestLineRegionsCounts; ViewOpts.ShowExpandedRegions = ShowExpansions; + ViewOpts.ShowBranchCounts = + ShowBranches == CoverageViewOptions::BranchOutputType::Count; + ViewOpts.ShowBranchPercents = + ShowBranches == CoverageViewOptions::BranchOutputType::Percent; ViewOpts.ShowFunctionInstantiations = ShowInstantiations; ViewOpts.ShowOutputDirectory = ShowOutputDirectory; ViewOpts.TabSize = TabSize; @@ -886,7 +960,7 @@ int CodeCoverageTool::doShow(int argc, const char **argv, auto Printer = CoveragePrinter::create(ViewOpts); - if (SourceFiles.empty()) + if (SourceFiles.empty() && !HadSourceFiles) // Get the source files from the function coverage mapping. for (StringRef Filename : Coverage->getUniqueSourceFiles()) { if (!IgnoreFilenameFilters.matchesFilename(Filename)) |