Path: blob/main/contrib/llvm-project/llvm/tools/llvm-cov/CoverageSummaryInfo.h
35230 views
//===- CoverageSummaryInfo.h - Coverage summary for function/file ---------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// These structures are used to represent code coverage metrics9// for functions/files.10//11//===----------------------------------------------------------------------===//1213#ifndef LLVM_COV_COVERAGESUMMARYINFO_H14#define LLVM_COV_COVERAGESUMMARYINFO_H1516#include "llvm/ProfileData/Coverage/CoverageMapping.h"17#include "llvm/Support/raw_ostream.h"1819namespace llvm {2021/// Provides information about region coverage for a function/file.22class RegionCoverageInfo {23/// The number of regions that were executed at least once.24size_t Covered;2526/// The total number of regions in a function/file.27size_t NumRegions;2829public:30RegionCoverageInfo() : Covered(0), NumRegions(0) {}3132RegionCoverageInfo(size_t Covered, size_t NumRegions)33: Covered(Covered), NumRegions(NumRegions) {34assert(Covered <= NumRegions && "Covered regions over-counted");35}3637RegionCoverageInfo &operator+=(const RegionCoverageInfo &RHS) {38Covered += RHS.Covered;39NumRegions += RHS.NumRegions;40return *this;41}4243void merge(const RegionCoverageInfo &RHS) {44Covered = std::max(Covered, RHS.Covered);45NumRegions = std::max(NumRegions, RHS.NumRegions);46}4748size_t getCovered() const { return Covered; }4950size_t getNumRegions() const { return NumRegions; }5152bool isFullyCovered() const { return Covered == NumRegions; }5354double getPercentCovered() const {55assert(Covered <= NumRegions && "Covered regions over-counted");56if (NumRegions == 0)57return 0.0;58return double(Covered) / double(NumRegions) * 100.0;59}60};6162/// Provides information about line coverage for a function/file.63class LineCoverageInfo {64/// The number of lines that were executed at least once.65size_t Covered;6667/// The total number of lines in a function/file.68size_t NumLines;6970public:71LineCoverageInfo() : Covered(0), NumLines(0) {}7273LineCoverageInfo(size_t Covered, size_t NumLines)74: Covered(Covered), NumLines(NumLines) {75assert(Covered <= NumLines && "Covered lines over-counted");76}7778LineCoverageInfo &operator+=(const LineCoverageInfo &RHS) {79Covered += RHS.Covered;80NumLines += RHS.NumLines;81return *this;82}8384void merge(const LineCoverageInfo &RHS) {85Covered = std::max(Covered, RHS.Covered);86NumLines = std::max(NumLines, RHS.NumLines);87}8889size_t getCovered() const { return Covered; }9091size_t getNumLines() const { return NumLines; }9293bool isFullyCovered() const { return Covered == NumLines; }9495double getPercentCovered() const {96assert(Covered <= NumLines && "Covered lines over-counted");97if (NumLines == 0)98return 0.0;99return double(Covered) / double(NumLines) * 100.0;100}101};102103/// Provides information about branches coverage for a function/file.104class BranchCoverageInfo {105/// The number of branches that were executed at least once.106size_t Covered;107108/// The total number of branches in a function/file.109size_t NumBranches;110111public:112BranchCoverageInfo() : Covered(0), NumBranches(0) {}113114BranchCoverageInfo(size_t Covered, size_t NumBranches)115: Covered(Covered), NumBranches(NumBranches) {116assert(Covered <= NumBranches && "Covered branches over-counted");117}118119BranchCoverageInfo &operator+=(const BranchCoverageInfo &RHS) {120Covered += RHS.Covered;121NumBranches += RHS.NumBranches;122return *this;123}124125void merge(const BranchCoverageInfo &RHS) {126Covered = std::max(Covered, RHS.Covered);127NumBranches = std::max(NumBranches, RHS.NumBranches);128}129130size_t getCovered() const { return Covered; }131132size_t getNumBranches() const { return NumBranches; }133134bool isFullyCovered() const { return Covered == NumBranches; }135136double getPercentCovered() const {137assert(Covered <= NumBranches && "Covered branches over-counted");138if (NumBranches == 0)139return 0.0;140return double(Covered) / double(NumBranches) * 100.0;141}142};143144/// Provides information about MC/DC coverage for a function/file.145class MCDCCoverageInfo {146/// The number of Independence Pairs that were covered.147size_t CoveredPairs;148149/// The total number of Independence Pairs in a function/file.150size_t NumPairs;151152public:153MCDCCoverageInfo() : CoveredPairs(0), NumPairs(0) {}154155MCDCCoverageInfo(size_t CoveredPairs, size_t NumPairs)156: CoveredPairs(CoveredPairs), NumPairs(NumPairs) {157assert(CoveredPairs <= NumPairs && "Covered pairs over-counted");158}159160MCDCCoverageInfo &operator+=(const MCDCCoverageInfo &RHS) {161CoveredPairs += RHS.CoveredPairs;162NumPairs += RHS.NumPairs;163return *this;164}165166void merge(const MCDCCoverageInfo &RHS) {167CoveredPairs = std::max(CoveredPairs, RHS.CoveredPairs);168NumPairs = std::max(NumPairs, RHS.NumPairs);169}170171size_t getCoveredPairs() const { return CoveredPairs; }172173size_t getNumPairs() const { return NumPairs; }174175bool isFullyCovered() const { return CoveredPairs == NumPairs; }176177double getPercentCovered() const {178assert(CoveredPairs <= NumPairs && "Covered pairs over-counted");179if (NumPairs == 0)180return 0.0;181return double(CoveredPairs) / double(NumPairs) * 100.0;182}183};184185/// Provides information about function coverage for a file.186class FunctionCoverageInfo {187/// The number of functions that were executed.188size_t Executed;189190/// The total number of functions in this file.191size_t NumFunctions;192193public:194FunctionCoverageInfo() : Executed(0), NumFunctions(0) {}195196FunctionCoverageInfo(size_t Executed, size_t NumFunctions)197: Executed(Executed), NumFunctions(NumFunctions) {}198199FunctionCoverageInfo &operator+=(const FunctionCoverageInfo &RHS) {200Executed += RHS.Executed;201NumFunctions += RHS.NumFunctions;202return *this;203}204205void addFunction(bool Covered) {206if (Covered)207++Executed;208++NumFunctions;209}210211size_t getExecuted() const { return Executed; }212213size_t getNumFunctions() const { return NumFunctions; }214215bool isFullyCovered() const { return Executed == NumFunctions; }216217double getPercentCovered() const {218assert(Executed <= NumFunctions && "Covered functions over-counted");219if (NumFunctions == 0)220return 0.0;221return double(Executed) / double(NumFunctions) * 100.0;222}223};224225/// A summary of function's code coverage.226struct FunctionCoverageSummary {227std::string Name;228uint64_t ExecutionCount;229RegionCoverageInfo RegionCoverage;230LineCoverageInfo LineCoverage;231BranchCoverageInfo BranchCoverage;232MCDCCoverageInfo MCDCCoverage;233234FunctionCoverageSummary(const std::string &Name)235: Name(Name), ExecutionCount(0) {}236237FunctionCoverageSummary(const std::string &Name, uint64_t ExecutionCount,238const RegionCoverageInfo &RegionCoverage,239const LineCoverageInfo &LineCoverage,240const BranchCoverageInfo &BranchCoverage,241const MCDCCoverageInfo &MCDCCoverage)242: Name(Name), ExecutionCount(ExecutionCount),243RegionCoverage(RegionCoverage), LineCoverage(LineCoverage),244BranchCoverage(BranchCoverage), MCDCCoverage(MCDCCoverage) {}245246/// Compute the code coverage summary for the given function coverage247/// mapping record.248static FunctionCoverageSummary get(const coverage::CoverageMapping &CM,249const coverage::FunctionRecord &Function);250251/// Compute the code coverage summary for an instantiation group \p Group,252/// given a list of summaries for each instantiation in \p Summaries.253static FunctionCoverageSummary254get(const coverage::InstantiationGroup &Group,255ArrayRef<FunctionCoverageSummary> Summaries);256};257258/// A summary of file's code coverage.259struct FileCoverageSummary {260StringRef Name;261RegionCoverageInfo RegionCoverage;262LineCoverageInfo LineCoverage;263BranchCoverageInfo BranchCoverage;264MCDCCoverageInfo MCDCCoverage;265FunctionCoverageInfo FunctionCoverage;266FunctionCoverageInfo InstantiationCoverage;267268FileCoverageSummary() = default;269FileCoverageSummary(StringRef Name) : Name(Name) {}270271FileCoverageSummary &operator+=(const FileCoverageSummary &RHS) {272RegionCoverage += RHS.RegionCoverage;273LineCoverage += RHS.LineCoverage;274FunctionCoverage += RHS.FunctionCoverage;275BranchCoverage += RHS.BranchCoverage;276MCDCCoverage += RHS.MCDCCoverage;277InstantiationCoverage += RHS.InstantiationCoverage;278return *this;279}280281void addFunction(const FunctionCoverageSummary &Function) {282RegionCoverage += Function.RegionCoverage;283LineCoverage += Function.LineCoverage;284BranchCoverage += Function.BranchCoverage;285MCDCCoverage += Function.MCDCCoverage;286FunctionCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0);287}288289void addInstantiation(const FunctionCoverageSummary &Function) {290InstantiationCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0);291}292};293294/// A cache for demangled symbols.295struct DemangleCache {296StringMap<std::string> DemangledNames;297298/// Demangle \p Sym if possible. Otherwise, just return \p Sym.299StringRef demangle(StringRef Sym) const {300const auto DemangledName = DemangledNames.find(Sym);301if (DemangledName == DemangledNames.end())302return Sym;303return DemangledName->getValue();304}305};306307} // namespace llvm308309#endif // LLVM_COV_COVERAGESUMMARYINFO_H310311312