diff --git a/test/tools/llvm-cov/Inputs/hideUnexecutedSubviews.proftext b/test/tools/llvm-cov/Inputs/hideUnexecutedSubviews.proftext index e31d562d716..8ef6eaeaf54 100644 --- a/test/tools/llvm-cov/Inputs/hideUnexecutedSubviews.proftext +++ b/test/tools/llvm-cov/Inputs/hideUnexecutedSubviews.proftext @@ -13,4 +13,4 @@ _Z4funcIiEiT_ main 0 1 -0 +1 diff --git a/test/tools/llvm-cov/hideUnexecutedSubviews.test b/test/tools/llvm-cov/hideUnexecutedSubviews.test index 44a788401d8..646c6e5aec4 100644 --- a/test/tools/llvm-cov/hideUnexecutedSubviews.test +++ b/test/tools/llvm-cov/hideUnexecutedSubviews.test @@ -1,10 +1,26 @@ RUN: llvm-profdata merge %S/Inputs/hideUnexecutedSubviews.proftext -o %t.profdata -RUN: llvm-cov show %S/Inputs/templateInstantiations.covmapping -instr-profile %t.profdata -filename-equivalence %S/showTemplateInstantiations.cpp | FileCheck %s +RUN: llvm-cov show %S/Inputs/templateInstantiations.covmapping -instr-profile %t.profdata -filename-equivalence %S/showTemplateInstantiations.cpp | FileCheck -check-prefix=FILE %s RUN: llvm-cov show %S/Inputs/templateInstantiations.covmapping -instr-profile %t.profdata -format html -o %t.html.dir -filename-equivalence %S/showTemplateInstantiations.cpp -RUN: FileCheck %s -input-file %t.html.dir/coverage/tmp/showTemplateInstantiations.cpp.html +RUN: FileCheck -check-prefix=FILE %s -input-file %t.html.dir/coverage/tmp/showTemplateInstantiations.cpp.html -CHECK: Unexecuted instantiation: _Z4funcIbEiT_ -CHECK: Unexecuted instantiation: _Z4funcIiEiT_ -CHECK-NOT: Unexecuted instantiation +FILE: Unexecuted instantiation: _Z4funcIbEiT_ +FILE: Unexecuted instantiation: _Z4funcIiEiT_ +FILE-NOT: Unexecuted instantiation + +RUN: FileCheck -check-prefix=INDEX %s -input-file %t.html.dir/index.html + +INDEX: Filename +INDEX: Function Coverage +INDEX: Instantiation Coverage +INDEX: Line Coverage +INDEX: Region Coverage +INDEX: +INDEX: 50.00% (1/2) +INDEX: +INDEX: 33.33% (1/3) +INDEX: +INDEX: 41.67% (5/12) +INDEX: +INDEX: 20.00% (1/5) diff --git a/test/tools/llvm-cov/report.cpp b/test/tools/llvm-cov/report.cpp index e8563271dac..824442f99c4 100644 --- a/test/tools/llvm-cov/report.cpp +++ b/test/tools/llvm-cov/report.cpp @@ -1,11 +1,11 @@ // RUN: llvm-cov report %S/Inputs/report.covmapping -instr-profile %S/Inputs/report.profdata -filename-equivalence 2>&1 | FileCheck %s // RUN: llvm-cov report %S/Inputs/report.covmapping -instr-profile %S/Inputs/report.profdata -filename-equivalence report.cpp 2>&1 | FileCheck -check-prefix=FILT-NEXT %s -// CHECK: Filename Regions Missed Regions Cover Functions Missed Functions Executed Lines Missed Lines Cover +// CHECK: Regions Missed Regions Cover Functions Missed Functions Executed Instantiations Missed Insts. Executed Lines Missed Lines Cover // CHECK-NEXT: --- -// CHECK-NEXT: report.cpp 5 2 60.00% 4 1 75.00% 13 4 69.23% +// CHECK-NEXT: report.cpp 5 2 60.00% 4 1 75.00% 4 1 75.00% 13 4 69.23% // CHECK-NEXT: --- -// CHECK-NEXT: TOTAL 5 2 60.00% 4 1 75.00% 13 4 69.23% +// CHECK-NEXT: TOTAL 5 2 60.00% 4 1 75.00% 4 1 75.00% 13 4 69.23% // FILT: File 'report.cpp': // FILT-NEXT: Name Regions Miss Cover Lines Miss Cover diff --git a/test/tools/llvm-cov/showLineExecutionCounts.cpp b/test/tools/llvm-cov/showLineExecutionCounts.cpp index fcaedcd0d39..501eb0db6ea 100644 --- a/test/tools/llvm-cov/showLineExecutionCounts.cpp +++ b/test/tools/llvm-cov/showLineExecutionCounts.cpp @@ -80,11 +80,14 @@ int main() { // TEXT: [[@LINE]]| 161|int main( // HTML-INDEX-LABEL: // HTML-INDEX: // HTML-INDEX: +// HTML-INDEX: // HTML-INDEX: // HTML-INDEX: // HTML-INDEX: // HTML-INDEX:
FilenameFunction CoverageInstantiation CoverageLine CoverageRegion Coverage // HTML-INDEX: 100.00% (1/1) +// HTML-INDEX: +// HTML-INDEX: 100.00% (1/1) // HTML-INDEX: // HTML-INDEX: 80.00% (16/20) // HTML-INDEX: diff --git a/tools/llvm-cov/CoverageReport.cpp b/tools/llvm-cov/CoverageReport.cpp index 332268a2343..e70cce40a98 100644 --- a/tools/llvm-cov/CoverageReport.cpp +++ b/tools/llvm-cov/CoverageReport.cpp @@ -13,6 +13,7 @@ #include "CoverageReport.h" #include "RenderingSupport.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Format.h" #include "llvm/Support/Path.h" @@ -85,7 +86,8 @@ Column column(StringRef Str, unsigned Width, const T &Value) { } // Specify the default column widths. -size_t FileReportColumns[] = {25, 12, 18, 10, 12, 18, 10, 12, 18, 10}; +size_t FileReportColumns[] = {25, 12, 18, 10, 12, 18, 10, + 16, 16, 10, 12, 18, 10}; size_t FunctionReportColumns[] = {25, 10, 8, 8, 10, 8, 8}; /// \brief Adjust column widths to fit long file paths and function names. @@ -139,6 +141,8 @@ void CoverageReport::render(const FileCoverageSummary &File, determineCoveragePercentageColor(File.RegionCoverage); auto FuncCoverageColor = determineCoveragePercentageColor(File.FunctionCoverage); + auto InstantiationCoverageColor = + determineCoveragePercentageColor(File.InstantiationCoverage); auto LineCoverageColor = determineCoveragePercentageColor(File.LineCoverage); SmallString<256> FileName = File.Name; sys::path::remove_dots(FileName, /*remove_dot_dots=*/true); @@ -162,11 +166,20 @@ void CoverageReport::render(const FileCoverageSummary &File, File.FunctionCoverage.getPercentCovered()) << '%'; OS << format("%*u", FileReportColumns[7], + (unsigned)File.InstantiationCoverage.NumFunctions); + OS << format("%*u", FileReportColumns[8], + (unsigned)(File.InstantiationCoverage.NumFunctions - + File.InstantiationCoverage.Executed)); + Options.colored_ostream(OS, InstantiationCoverageColor) + << format("%*.2f", FileReportColumns[9] - 1, + File.InstantiationCoverage.getPercentCovered()) + << '%'; + OS << format("%*u", FileReportColumns[10], (unsigned)File.LineCoverage.NumLines); Options.colored_ostream(OS, LineCoverageColor) << format( - "%*u", FileReportColumns[8], (unsigned)File.LineCoverage.NotCovered); + "%*u", FileReportColumns[11], (unsigned)File.LineCoverage.NotCovered); Options.colored_ostream(OS, LineCoverageColor) - << format("%*.2f", FileReportColumns[9] - 1, + << format("%*.2f", FileReportColumns[12] - 1, File.LineCoverage.getPercentCovered()) << '%'; OS << "\n"; @@ -255,11 +268,28 @@ CoverageReport::prepareFileReports(FileCoverageSummary &Totals, for (StringRef Filename : Files) { FileCoverageSummary Summary(Filename.drop_front(LCP)); + + // Map source locations to aggregate function coverage summaries. + DenseMap, FunctionCoverageSummary> Summaries; + for (const auto &F : Coverage.getCoveredFunctions(Filename)) { FunctionCoverageSummary Function = FunctionCoverageSummary::get(F); - Summary.addFunction(Function); - Totals.addFunction(Function); + auto StartLoc = F.CountedRegions[0].startLoc(); + + auto UniquedSummary = Summaries.insert({StartLoc, Function}); + if (!UniquedSummary.second) + UniquedSummary.first->second.update(Function); + + Summary.addInstantiation(Function); + Totals.addInstantiation(Function); } + + for (const auto &UniquedSummary : Summaries) { + const FunctionCoverageSummary &FCS = UniquedSummary.second; + Summary.addFunction(FCS); + Totals.addFunction(FCS); + } + FileReports.push_back(Summary); } @@ -288,9 +318,12 @@ void CoverageReport::renderFileReports(raw_ostream &OS, << column("Functions", FileReportColumns[4], Column::RightAlignment) << column("Missed Functions", FileReportColumns[5], Column::RightAlignment) << column("Executed", FileReportColumns[6], Column::RightAlignment) - << column("Lines", FileReportColumns[7], Column::RightAlignment) - << column("Missed Lines", FileReportColumns[8], Column::RightAlignment) - << column("Cover", FileReportColumns[9], Column::RightAlignment) << "\n"; + << column("Instantiations", FileReportColumns[7], Column::RightAlignment) + << column("Missed Insts.", FileReportColumns[8], Column::RightAlignment) + << column("Executed", FileReportColumns[9], Column::RightAlignment) + << column("Lines", FileReportColumns[10], Column::RightAlignment) + << column("Missed Lines", FileReportColumns[11], Column::RightAlignment) + << column("Cover", FileReportColumns[12], Column::RightAlignment) << "\n"; renderDivider(FileReportColumns, OS); OS << "\n"; diff --git a/tools/llvm-cov/CoverageSummaryInfo.cpp b/tools/llvm-cov/CoverageSummaryInfo.cpp index ffdffbd4b7b..396cd655ca1 100644 --- a/tools/llvm-cov/CoverageSummaryInfo.cpp +++ b/tools/llvm-cov/CoverageSummaryInfo.cpp @@ -69,3 +69,15 @@ FunctionCoverageSummary::get(const coverage::FunctionRecord &Function) { RegionCoverageInfo(CoveredRegions, NumCodeRegions), LineCoverageInfo(CoveredLines, 0, NumLines)); } + +void FunctionCoverageSummary::update(const FunctionCoverageSummary &Summary) { + ExecutionCount += Summary.ExecutionCount; + RegionCoverage.Covered = + std::max(RegionCoverage.Covered, Summary.RegionCoverage.Covered); + RegionCoverage.NotCovered = + std::min(RegionCoverage.NotCovered, Summary.RegionCoverage.NotCovered); + LineCoverage.Covered = + std::max(LineCoverage.Covered, Summary.LineCoverage.Covered); + LineCoverage.NotCovered = + std::min(LineCoverage.NotCovered, Summary.LineCoverage.NotCovered); +} diff --git a/tools/llvm-cov/CoverageSummaryInfo.h b/tools/llvm-cov/CoverageSummaryInfo.h index 822742b635e..acf240d95de 100644 --- a/tools/llvm-cov/CoverageSummaryInfo.h +++ b/tools/llvm-cov/CoverageSummaryInfo.h @@ -139,6 +139,10 @@ struct FunctionCoverageSummary { /// mapping record. static FunctionCoverageSummary get(const coverage::FunctionRecord &Function); + + /// \brief Update the summary with information from another instantiation + /// of this function. + void update(const FunctionCoverageSummary &Summary); }; /// \brief A summary of file's code coverage. @@ -147,6 +151,7 @@ struct FileCoverageSummary { RegionCoverageInfo RegionCoverage; LineCoverageInfo LineCoverage; FunctionCoverageInfo FunctionCoverage; + FunctionCoverageInfo InstantiationCoverage; FileCoverageSummary(StringRef Name) : Name(Name) {} @@ -155,6 +160,10 @@ struct FileCoverageSummary { LineCoverage += Function.LineCoverage; FunctionCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0); } + + void addInstantiation(const FunctionCoverageSummary &Function) { + InstantiationCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0); + } }; } // namespace llvm diff --git a/tools/llvm-cov/SourceCoverageViewHTML.cpp b/tools/llvm-cov/SourceCoverageViewHTML.cpp index e64f31d546e..1ef3219b103 100644 --- a/tools/llvm-cov/SourceCoverageViewHTML.cpp +++ b/tools/llvm-cov/SourceCoverageViewHTML.cpp @@ -287,8 +287,8 @@ void CoveragePrinterHTML::closeViewFile(OwnedStream OS) { static void emitColumnLabelsForIndex(raw_ostream &OS) { SmallVector Columns; Columns.emplace_back(tag("td", "Filename", "column-entry-left")); - for (const char *Label : - {"Function Coverage", "Line Coverage", "Region Coverage"}) + for (const char *Label : {"Function Coverage", "Instantiation Coverage", + "Line Coverage", "Region Coverage"}) Columns.emplace_back(tag("td", Label, "column-entry")); OS << tag("tr", join(Columns.begin(), Columns.end(), "")); } @@ -334,6 +334,9 @@ void CoveragePrinterHTML::emitFileSummary(raw_ostream &OS, StringRef SF, AddCoverageTripleToColumn(FCS.FunctionCoverage.Executed, FCS.FunctionCoverage.NumFunctions, FCS.FunctionCoverage.getPercentCovered()); + AddCoverageTripleToColumn(FCS.InstantiationCoverage.Executed, + FCS.InstantiationCoverage.NumFunctions, + FCS.InstantiationCoverage.getPercentCovered()); AddCoverageTripleToColumn(FCS.LineCoverage.Covered, FCS.LineCoverage.NumLines, FCS.LineCoverage.getPercentCovered()); AddCoverageTripleToColumn(FCS.RegionCoverage.Covered,