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: Filename |
// HTML-INDEX: Function Coverage |
+// HTML-INDEX: Instantiation Coverage |
// HTML-INDEX: Line Coverage |
// HTML-INDEX: Region Coverage |
// HTML-INDEX:
// HTML-INDEX:
// 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,
| |