CoverageSummaryInfo.h 8.0 KB

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