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: RegionCoverageInfo()32 RegionCoverageInfo() : Covered(0), NumRegions(0) {} 33 RegionCoverageInfo(size_t Covered,size_t NumRegions)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 merge(const RegionCoverageInfo & RHS)45 void merge(const RegionCoverageInfo &RHS) { 46 Covered = std::max(Covered, RHS.Covered); 47 NumRegions = std::max(NumRegions, RHS.NumRegions); 48 } 49 getCovered()50 size_t getCovered() const { return Covered; } 51 getNumRegions()52 size_t getNumRegions() const { return NumRegions; } 53 isFullyCovered()54 bool isFullyCovered() const { return Covered == NumRegions; } 55 getPercentCovered()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: LineCoverageInfo()73 LineCoverageInfo() : Covered(0), NumLines(0) {} 74 LineCoverageInfo(size_t Covered,size_t NumLines)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 merge(const LineCoverageInfo & RHS)86 void merge(const LineCoverageInfo &RHS) { 87 Covered = std::max(Covered, RHS.Covered); 88 NumLines = std::max(NumLines, RHS.NumLines); 89 } 90 getCovered()91 size_t getCovered() const { return Covered; } 92 getNumLines()93 size_t getNumLines() const { return NumLines; } 94 isFullyCovered()95 bool isFullyCovered() const { return Covered == NumLines; } 96 getPercentCovered()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: FunctionCoverageInfo()114 FunctionCoverageInfo() : Executed(0), NumFunctions(0) {} 115 FunctionCoverageInfo(size_t Executed,size_t NumFunctions)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 addFunction(bool Covered)125 void addFunction(bool Covered) { 126 if (Covered) 127 ++Executed; 128 ++NumFunctions; 129 } 130 getExecuted()131 size_t getExecuted() const { return Executed; } 132 getNumFunctions()133 size_t getNumFunctions() const { return NumFunctions; } 134 isFullyCovered()135 bool isFullyCovered() const { return Executed == NumFunctions; } 136 getPercentCovered()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 FunctionCoverageSummaryFunctionCoverageSummary152 FunctionCoverageSummary(const std::string &Name) 153 : Name(Name), ExecutionCount(0), RegionCoverage(), LineCoverage() {} 154 FunctionCoverageSummaryFunctionCoverageSummary155 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 FileCoverageSummaryFileCoverageSummary181 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 addFunctionFileCoverageSummary193 void addFunction(const FunctionCoverageSummary &Function) { 194 RegionCoverage += Function.RegionCoverage; 195 LineCoverage += Function.LineCoverage; 196 FunctionCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0); 197 } 198 addInstantiationFileCoverageSummary199 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. demangleDemangleCache209 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