diff options
Diffstat (limited to 'llvm/tools/llvm-cov/CoverageSummaryInfo.h')
-rw-r--r-- | llvm/tools/llvm-cov/CoverageSummaryInfo.h | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/llvm/tools/llvm-cov/CoverageSummaryInfo.h b/llvm/tools/llvm-cov/CoverageSummaryInfo.h new file mode 100644 index 000000000000..97beacb26d07 --- /dev/null +++ b/llvm/tools/llvm-cov/CoverageSummaryInfo.h @@ -0,0 +1,218 @@ +//===- CoverageSummaryInfo.h - Coverage summary for function/file ---------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// These structures are used to represent code coverage metrics +// for functions/files. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_COV_COVERAGESUMMARYINFO_H +#define LLVM_COV_COVERAGESUMMARYINFO_H + +#include "llvm/ProfileData/Coverage/CoverageMapping.h" +#include "llvm/Support/raw_ostream.h" + +namespace llvm { + +/// Provides information about region coverage for a function/file. +class RegionCoverageInfo { + /// The number of regions that were executed at least once. + size_t Covered; + + /// The total number of regions in a function/file. + size_t NumRegions; + +public: + RegionCoverageInfo() : Covered(0), NumRegions(0) {} + + RegionCoverageInfo(size_t Covered, size_t NumRegions) + : Covered(Covered), NumRegions(NumRegions) { + assert(Covered <= NumRegions && "Covered regions over-counted"); + } + + RegionCoverageInfo &operator+=(const RegionCoverageInfo &RHS) { + Covered += RHS.Covered; + NumRegions += RHS.NumRegions; + return *this; + } + + void merge(const RegionCoverageInfo &RHS) { + Covered = std::max(Covered, RHS.Covered); + NumRegions = std::max(NumRegions, RHS.NumRegions); + } + + size_t getCovered() const { return Covered; } + + size_t getNumRegions() const { return NumRegions; } + + bool isFullyCovered() const { return Covered == NumRegions; } + + double getPercentCovered() const { + assert(Covered <= NumRegions && "Covered regions over-counted"); + if (NumRegions == 0) + return 0.0; + return double(Covered) / double(NumRegions) * 100.0; + } +}; + +/// Provides information about line coverage for a function/file. +class LineCoverageInfo { + /// The number of lines that were executed at least once. + size_t Covered; + + /// The total number of lines in a function/file. + size_t NumLines; + +public: + LineCoverageInfo() : Covered(0), NumLines(0) {} + + LineCoverageInfo(size_t Covered, size_t NumLines) + : Covered(Covered), NumLines(NumLines) { + assert(Covered <= NumLines && "Covered lines over-counted"); + } + + LineCoverageInfo &operator+=(const LineCoverageInfo &RHS) { + Covered += RHS.Covered; + NumLines += RHS.NumLines; + return *this; + } + + void merge(const LineCoverageInfo &RHS) { + Covered = std::max(Covered, RHS.Covered); + NumLines = std::max(NumLines, RHS.NumLines); + } + + size_t getCovered() const { return Covered; } + + size_t getNumLines() const { return NumLines; } + + bool isFullyCovered() const { return Covered == NumLines; } + + double getPercentCovered() const { + assert(Covered <= NumLines && "Covered lines over-counted"); + if (NumLines == 0) + return 0.0; + return double(Covered) / double(NumLines) * 100.0; + } +}; + +/// Provides information about function coverage for a file. +class FunctionCoverageInfo { + /// The number of functions that were executed. + size_t Executed; + + /// The total number of functions in this file. + size_t NumFunctions; + +public: + FunctionCoverageInfo() : Executed(0), NumFunctions(0) {} + + FunctionCoverageInfo(size_t Executed, size_t NumFunctions) + : Executed(Executed), NumFunctions(NumFunctions) {} + + FunctionCoverageInfo &operator+=(const FunctionCoverageInfo &RHS) { + Executed += RHS.Executed; + NumFunctions += RHS.NumFunctions; + return *this; + } + + void addFunction(bool Covered) { + if (Covered) + ++Executed; + ++NumFunctions; + } + + size_t getExecuted() const { return Executed; } + + size_t getNumFunctions() const { return NumFunctions; } + + bool isFullyCovered() const { return Executed == NumFunctions; } + + double getPercentCovered() const { + assert(Executed <= NumFunctions && "Covered functions over-counted"); + if (NumFunctions == 0) + return 0.0; + return double(Executed) / double(NumFunctions) * 100.0; + } +}; + +/// A summary of function's code coverage. +struct FunctionCoverageSummary { + std::string Name; + uint64_t ExecutionCount; + RegionCoverageInfo RegionCoverage; + LineCoverageInfo LineCoverage; + + FunctionCoverageSummary(const std::string &Name) + : Name(Name), ExecutionCount(0), RegionCoverage(), LineCoverage() {} + + FunctionCoverageSummary(const std::string &Name, uint64_t ExecutionCount, + const RegionCoverageInfo &RegionCoverage, + const LineCoverageInfo &LineCoverage) + : Name(Name), ExecutionCount(ExecutionCount), + RegionCoverage(RegionCoverage), LineCoverage(LineCoverage) {} + + /// Compute the code coverage summary for the given function coverage + /// mapping record. + static FunctionCoverageSummary get(const coverage::CoverageMapping &CM, + const coverage::FunctionRecord &Function); + + /// Compute the code coverage summary for an instantiation group \p Group, + /// given a list of summaries for each instantiation in \p Summaries. + static FunctionCoverageSummary + get(const coverage::InstantiationGroup &Group, + ArrayRef<FunctionCoverageSummary> Summaries); +}; + +/// A summary of file's code coverage. +struct FileCoverageSummary { + StringRef Name; + RegionCoverageInfo RegionCoverage; + LineCoverageInfo LineCoverage; + FunctionCoverageInfo FunctionCoverage; + FunctionCoverageInfo InstantiationCoverage; + + FileCoverageSummary(StringRef Name) + : Name(Name), RegionCoverage(), LineCoverage(), FunctionCoverage(), + InstantiationCoverage() {} + + FileCoverageSummary &operator+=(const FileCoverageSummary &RHS) { + RegionCoverage += RHS.RegionCoverage; + LineCoverage += RHS.LineCoverage; + FunctionCoverage += RHS.FunctionCoverage; + InstantiationCoverage += RHS.InstantiationCoverage; + return *this; + } + + void addFunction(const FunctionCoverageSummary &Function) { + RegionCoverage += Function.RegionCoverage; + LineCoverage += Function.LineCoverage; + FunctionCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0); + } + + void addInstantiation(const FunctionCoverageSummary &Function) { + InstantiationCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0); + } +}; + +/// A cache for demangled symbols. +struct DemangleCache { + StringMap<std::string> DemangledNames; + + /// Demangle \p Sym if possible. Otherwise, just return \p Sym. + StringRef demangle(StringRef Sym) const { + const auto DemangledName = DemangledNames.find(Sym); + if (DemangledName == DemangledNames.end()) + return Sym; + return DemangledName->getValue(); + } +}; + +} // namespace llvm + +#endif // LLVM_COV_COVERAGESUMMARYINFO_H |