Index: include/llvm/ProfileData/CoverageMapping.h =================================================================== --- include/llvm/ProfileData/CoverageMapping.h +++ include/llvm/ProfileData/CoverageMapping.h @@ -228,9 +228,13 @@ std::vector Filenames; /// \brief Regions in the function along with their counts. std::vector CountedRegions; + /// \brief The number of times this function was executed. + uint64_t ExecutionCount; - FunctionRecord(StringRef Name, ArrayRef Filenames) - : Name(Name), Filenames(Filenames.begin(), Filenames.end()) {} + FunctionRecord(StringRef Name, ArrayRef Filenames, + uint64_t ExecutionCount) + : Name(Name), Filenames(Filenames.begin(), Filenames.end()), + ExecutionCount(ExecutionCount) {} }; /// \brief Coverage information for a macro expansion or #included file. Index: lib/ProfileData/CoverageMapping.cpp =================================================================== --- lib/ProfileData/CoverageMapping.cpp +++ lib/ProfileData/CoverageMapping.cpp @@ -167,7 +167,8 @@ continue; } - FunctionRecord Function(Record.FunctionName, Record.Filenames); + FunctionRecord Function(Record.FunctionName, Record.Filenames, + Counts.front()); CounterMappingContext Ctx(Record.Expressions, Counts); for (const auto &Region : Record.MappingRegions) { ErrorOr ExecutionCount = Ctx.evaluate(Region.Count); Index: test/tools/llvm-cov/report.cpp =================================================================== --- /dev/null +++ test/tools/llvm-cov/report.cpp @@ -0,0 +1,24 @@ +// RUN: llvm-cov report %S/Inputs/report.covmapping -instr-profile %S/Inputs/report.profdata -no-colors 2>&1 | FileCheck %s + +// CHECK: Filename Regions Miss Cover Functions Executed +// CHECK: TOTAL 5 2 60.00% 4 75.00% + +void foo(bool cond) { + if (cond) { + } +} + +void bar() { +} + +void func() { +} + +int main() { + foo(false); + bar(); + return 0; +} + +// llvm-cov doesn't work on big endian yet +// XFAIL: powerpc64-, s390x, mips-, mips64-, sparc Index: tools/llvm-cov/CoverageReport.cpp =================================================================== --- tools/llvm-cov/CoverageReport.cpp +++ tools/llvm-cov/CoverageReport.cpp @@ -85,7 +85,7 @@ return Column(Str, Width).set(Value); } -static const unsigned FileReportColumns[] = {25, 10, 8, 8, 10, 8}; +static const unsigned FileReportColumns[] = {25, 10, 8, 8, 10, 10}; static const unsigned FunctionReportColumns[] = {25, 10, 8, 8, 10, 8, 8}; /// \brief Prints a horizontal divider which spans across the given columns. @@ -178,8 +178,8 @@ render(Function, OS); renderDivider(FunctionReportColumns, OS); OS << "\n"; - render(FunctionCoverageSummary("TOTAL", File.RegionCoverage, - File.LineCoverage), + render(FunctionCoverageSummary("TOTAL", /*ExecutionCount=*/0, + File.RegionCoverage, File.LineCoverage), OS); } } @@ -190,7 +190,8 @@ << column("Miss", FileReportColumns[2], Column::RightAlignment) << column("Cover", FileReportColumns[3], Column::RightAlignment) << column("Functions", FileReportColumns[4], Column::RightAlignment) - << column("Cover", FileReportColumns[5], Column::RightAlignment) << "\n"; + << column("Executed", FileReportColumns[5], Column::RightAlignment) + << "\n"; renderDivider(FileReportColumns, OS); OS << "\n"; for (const auto &File : Summary.getFileSummaries()) Index: tools/llvm-cov/CoverageSummary.cpp =================================================================== --- tools/llvm-cov/CoverageSummary.cpp +++ tools/llvm-cov/CoverageSummary.cpp @@ -72,7 +72,7 @@ FileCoverageSummary CoverageSummary::getCombinedFileSummaries() { size_t NumRegions = 0, CoveredRegions = 0; size_t NumLines = 0, NonCodeLines = 0, CoveredLines = 0; - size_t NumFunctionsCovered = 0, NumFunctions = 0; + size_t NumFunctionsExecuted = 0, NumFunctions = 0; for (const auto &File : FileSummaries) { NumRegions += File.RegionCoverage.NumRegions; CoveredRegions += File.RegionCoverage.Covered; @@ -81,12 +81,12 @@ NonCodeLines += File.LineCoverage.NonCodeLines; CoveredLines += File.LineCoverage.Covered; - NumFunctionsCovered += File.FunctionCoverage.FullyCovered; + NumFunctionsExecuted += File.FunctionCoverage.Executed; NumFunctions += File.FunctionCoverage.NumFunctions; } return FileCoverageSummary( "TOTAL", RegionCoverageInfo(CoveredRegions, NumRegions), LineCoverageInfo(CoveredLines, NonCodeLines, NumLines), - FunctionCoverageInfo(NumFunctionsCovered, NumFunctions), + FunctionCoverageInfo(NumFunctionsExecuted, NumFunctions), None); } Index: tools/llvm-cov/CoverageSummaryInfo.h =================================================================== --- tools/llvm-cov/CoverageSummaryInfo.h +++ tools/llvm-cov/CoverageSummaryInfo.h @@ -69,33 +69,34 @@ /// \brief Provides information about function coverage for a file. struct FunctionCoverageInfo { - /// \brief The number of functions that have full - /// region coverage. - size_t FullyCovered; + /// \brief The number of functions that were executed. + size_t Executed; /// \brief The total number of functions in this file. size_t NumFunctions; - FunctionCoverageInfo(size_t FullyCovered, size_t NumFunctions) - : FullyCovered(FullyCovered), NumFunctions(NumFunctions) {} + FunctionCoverageInfo(size_t Executed, size_t NumFunctions) + : Executed(Executed), NumFunctions(NumFunctions) {} - bool isFullyCovered() const { return FullyCovered == NumFunctions; } + bool isFullyCovered() const { return Executed == NumFunctions; } double getPercentCovered() const { - return double(FullyCovered) / double(NumFunctions) * 100.0; + return double(Executed) / double(NumFunctions) * 100.0; } }; /// \brief A summary of function's code coverage. struct FunctionCoverageSummary { StringRef Name; + uint64_t ExecutionCount; RegionCoverageInfo RegionCoverage; LineCoverageInfo LineCoverage; - FunctionCoverageSummary(StringRef Name, + FunctionCoverageSummary(StringRef Name, uint64_t ExecutionCount, const RegionCoverageInfo &RegionCoverage, const LineCoverageInfo &LineCoverage) - : Name(Name), RegionCoverage(RegionCoverage), LineCoverage(LineCoverage) { + : Name(Name), ExecutionCount(ExecutionCount), + RegionCoverage(RegionCoverage), LineCoverage(LineCoverage) { } /// \brief Compute the code coverage summary for the given function coverage Index: tools/llvm-cov/CoverageSummaryInfo.cpp =================================================================== --- tools/llvm-cov/CoverageSummaryInfo.cpp +++ tools/llvm-cov/CoverageSummaryInfo.cpp @@ -65,7 +65,8 @@ NumLines += LineCount; } return FunctionCoverageSummary( - Function.Name, RegionCoverageInfo(CoveredRegions, NumCodeRegions), + Function.Name, Function.ExecutionCount, + RegionCoverageInfo(CoveredRegions, NumCodeRegions), LineCoverageInfo(CoveredLines, 0, NumLines)); } @@ -74,7 +75,7 @@ ArrayRef FunctionSummaries) { size_t NumRegions = 0, CoveredRegions = 0; size_t NumLines = 0, NonCodeLines = 0, CoveredLines = 0; - size_t NumFunctionsCovered = 0; + size_t NumFunctionsExecuted = 0; for (const auto &Func : FunctionSummaries) { CoveredRegions += Func.RegionCoverage.Covered; NumRegions += Func.RegionCoverage.NumRegions; @@ -83,13 +84,13 @@ NonCodeLines += Func.LineCoverage.NonCodeLines; NumLines += Func.LineCoverage.NumLines; - if (Func.RegionCoverage.isFullyCovered()) - ++NumFunctionsCovered; + if (Func.ExecutionCount != 0) + ++NumFunctionsExecuted; } return FileCoverageSummary( Name, RegionCoverageInfo(CoveredRegions, NumRegions), LineCoverageInfo(CoveredLines, NonCodeLines, NumLines), - FunctionCoverageInfo(NumFunctionsCovered, FunctionSummaries.size()), + FunctionCoverageInfo(NumFunctionsExecuted, FunctionSummaries.size()), FunctionSummaries); }