Home | History | Annotate | Download | only in llvm-cov
      1 //===- CoverageSummaryInfo.h - Coverage summary for function/file ---------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // These structures are used to represent code coverage metrics
     11 // for functions/files.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_COV_COVERAGESUMMARYINFO_H
     16 #define LLVM_COV_COVERAGESUMMARYINFO_H
     17 
     18 #include "llvm/ProfileData/Coverage/CoverageMapping.h"
     19 #include "llvm/Support/raw_ostream.h"
     20 
     21 namespace llvm {
     22 
     23 /// Provides information about region coverage for a function/file.
     24 class RegionCoverageInfo {
     25   /// The number of regions that were executed at least once.
     26   size_t Covered;
     27 
     28   /// The total number of regions in a function/file.
     29   size_t NumRegions;
     30 
     31 public:
     32   RegionCoverageInfo() : Covered(0), NumRegions(0) {}
     33 
     34   RegionCoverageInfo(size_t Covered, size_t NumRegions)
     35       : Covered(Covered), NumRegions(NumRegions) {
     36     assert(Covered <= NumRegions && "Covered regions over-counted");
     37   }
     38 
     39   RegionCoverageInfo &operator+=(const RegionCoverageInfo &RHS) {
     40     Covered += RHS.Covered;
     41     NumRegions += RHS.NumRegions;
     42     return *this;
     43   }
     44 
     45   void merge(const RegionCoverageInfo &RHS) {
     46     Covered = std::max(Covered, RHS.Covered);
     47     NumRegions = std::max(NumRegions, RHS.NumRegions);
     48   }
     49 
     50   size_t getCovered() const { return Covered; }
     51 
     52   size_t getNumRegions() const { return NumRegions; }
     53 
     54   bool isFullyCovered() const { return Covered == NumRegions; }
     55 
     56   double getPercentCovered() const {
     57     assert(Covered <= NumRegions && "Covered regions over-counted");
     58     if (NumRegions == 0)
     59       return 0.0;
     60     return double(Covered) / double(NumRegions) * 100.0;
     61   }
     62 };
     63 
     64 /// Provides information about line coverage for a function/file.
     65 class LineCoverageInfo {
     66   /// The number of lines that were executed at least once.
     67   size_t Covered;
     68 
     69   /// The total number of lines in a function/file.
     70   size_t NumLines;
     71 
     72 public:
     73   LineCoverageInfo() : Covered(0), NumLines(0) {}
     74 
     75   LineCoverageInfo(size_t Covered, size_t NumLines)
     76       : Covered(Covered), NumLines(NumLines) {
     77     assert(Covered <= NumLines && "Covered lines over-counted");
     78   }
     79 
     80   LineCoverageInfo &operator+=(const LineCoverageInfo &RHS) {
     81     Covered += RHS.Covered;
     82     NumLines += RHS.NumLines;
     83     return *this;
     84   }
     85 
     86   void merge(const LineCoverageInfo &RHS) {
     87     Covered = std::max(Covered, RHS.Covered);
     88     NumLines = std::max(NumLines, RHS.NumLines);
     89   }
     90 
     91   size_t getCovered() const { return Covered; }
     92 
     93   size_t getNumLines() const { return NumLines; }
     94 
     95   bool isFullyCovered() const { return Covered == NumLines; }
     96 
     97   double getPercentCovered() const {
     98     assert(Covered <= NumLines && "Covered lines over-counted");
     99     if (NumLines == 0)
    100       return 0.0;
    101     return double(Covered) / double(NumLines) * 100.0;
    102   }
    103 };
    104 
    105 /// Provides information about function coverage for a file.
    106 class FunctionCoverageInfo {
    107   /// The number of functions that were executed.
    108   size_t Executed;
    109 
    110   /// The total number of functions in this file.
    111   size_t NumFunctions;
    112 
    113 public:
    114   FunctionCoverageInfo() : Executed(0), NumFunctions(0) {}
    115 
    116   FunctionCoverageInfo(size_t Executed, size_t NumFunctions)
    117       : Executed(Executed), NumFunctions(NumFunctions) {}
    118 
    119   FunctionCoverageInfo &operator+=(const FunctionCoverageInfo &RHS) {
    120     Executed += RHS.Executed;
    121     NumFunctions += RHS.NumFunctions;
    122     return *this;
    123   }
    124 
    125   void addFunction(bool Covered) {
    126     if (Covered)
    127       ++Executed;
    128     ++NumFunctions;
    129   }
    130 
    131   size_t getExecuted() const { return Executed; }
    132 
    133   size_t getNumFunctions() const { return NumFunctions; }
    134 
    135   bool isFullyCovered() const { return Executed == NumFunctions; }
    136 
    137   double getPercentCovered() const {
    138     assert(Executed <= NumFunctions && "Covered functions over-counted");
    139     if (NumFunctions == 0)
    140       return 0.0;
    141     return double(Executed) / double(NumFunctions) * 100.0;
    142   }
    143 };
    144 
    145 /// A summary of function's code coverage.
    146 struct FunctionCoverageSummary {
    147   std::string Name;
    148   uint64_t ExecutionCount;
    149   RegionCoverageInfo RegionCoverage;
    150   LineCoverageInfo LineCoverage;
    151 
    152   FunctionCoverageSummary(const std::string &Name)
    153       : Name(Name), ExecutionCount(0), RegionCoverage(), LineCoverage() {}
    154 
    155   FunctionCoverageSummary(const std::string &Name, uint64_t ExecutionCount,
    156                           const RegionCoverageInfo &RegionCoverage,
    157                           const LineCoverageInfo &LineCoverage)
    158       : Name(Name), ExecutionCount(ExecutionCount),
    159         RegionCoverage(RegionCoverage), LineCoverage(LineCoverage) {}
    160 
    161   /// Compute the code coverage summary for the given function coverage
    162   /// mapping record.
    163   static FunctionCoverageSummary get(const coverage::CoverageMapping &CM,
    164                                      const coverage::FunctionRecord &Function);
    165 
    166   /// Compute the code coverage summary for an instantiation group \p Group,
    167   /// given a list of summaries for each instantiation in \p Summaries.
    168   static FunctionCoverageSummary
    169   get(const coverage::InstantiationGroup &Group,
    170       ArrayRef<FunctionCoverageSummary> Summaries);
    171 };
    172 
    173 /// A summary of file's code coverage.
    174 struct FileCoverageSummary {
    175   StringRef Name;
    176   RegionCoverageInfo RegionCoverage;
    177   LineCoverageInfo LineCoverage;
    178   FunctionCoverageInfo FunctionCoverage;
    179   FunctionCoverageInfo InstantiationCoverage;
    180 
    181   FileCoverageSummary(StringRef Name)
    182       : Name(Name), RegionCoverage(), LineCoverage(), FunctionCoverage(),
    183         InstantiationCoverage() {}
    184 
    185   FileCoverageSummary &operator+=(const FileCoverageSummary &RHS) {
    186     RegionCoverage += RHS.RegionCoverage;
    187     LineCoverage += RHS.LineCoverage;
    188     FunctionCoverage += RHS.FunctionCoverage;
    189     InstantiationCoverage += RHS.InstantiationCoverage;
    190     return *this;
    191   }
    192 
    193   void addFunction(const FunctionCoverageSummary &Function) {
    194     RegionCoverage += Function.RegionCoverage;
    195     LineCoverage += Function.LineCoverage;
    196     FunctionCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0);
    197   }
    198 
    199   void addInstantiation(const FunctionCoverageSummary &Function) {
    200     InstantiationCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0);
    201   }
    202 };
    203 
    204 /// A cache for demangled symbols.
    205 struct DemangleCache {
    206   StringMap<std::string> DemangledNames;
    207 
    208   /// Demangle \p Sym if possible. Otherwise, just return \p Sym.
    209   StringRef demangle(StringRef Sym) const {
    210     const auto DemangledName = DemangledNames.find(Sym);
    211     if (DemangledName == DemangledNames.end())
    212       return Sym;
    213     return DemangledName->getValue();
    214   }
    215 };
    216 
    217 } // namespace llvm
    218 
    219 #endif // LLVM_COV_COVERAGESUMMARYINFO_H
    220