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