CoverageSummaryInfo.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. //===- CoverageSummaryInfo.cpp - 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. #include "CoverageSummaryInfo.h"
  15. using namespace llvm;
  16. using namespace coverage;
  17. LineCoverageStats::LineCoverageStats(
  18. ArrayRef<const coverage::CoverageSegment *> LineSegments,
  19. const coverage::CoverageSegment *WrappedSegment) {
  20. // Find the minimum number of regions which start in this line.
  21. unsigned MinRegionCount = 0;
  22. auto isStartOfRegion = [](const coverage::CoverageSegment *S) {
  23. return !S->IsGapRegion && S->HasCount && S->IsRegionEntry;
  24. };
  25. for (unsigned I = 0; I < LineSegments.size() && MinRegionCount < 2; ++I)
  26. if (isStartOfRegion(LineSegments[I]))
  27. ++MinRegionCount;
  28. bool StartOfSkippedRegion = !LineSegments.empty() &&
  29. !LineSegments.front()->HasCount &&
  30. LineSegments.front()->IsRegionEntry;
  31. ExecutionCount = 0;
  32. HasMultipleRegions = MinRegionCount > 1;
  33. Mapped =
  34. !StartOfSkippedRegion &&
  35. ((WrappedSegment && WrappedSegment->HasCount) || (MinRegionCount > 0));
  36. if (!Mapped)
  37. return;
  38. // Pick the max count among regions which start and end on this line, to
  39. // avoid erroneously using the wrapped count, and to avoid picking region
  40. // counts which come from deferred regions.
  41. if (LineSegments.size() > 1) {
  42. for (unsigned I = 0; I < LineSegments.size() - 1; ++I) {
  43. if (!LineSegments[I]->IsGapRegion)
  44. ExecutionCount = std::max(ExecutionCount, LineSegments[I]->Count);
  45. }
  46. return;
  47. }
  48. // If a non-gap region starts here, use its count. Otherwise use the wrapped
  49. // count.
  50. if (MinRegionCount == 1)
  51. ExecutionCount = LineSegments[0]->Count;
  52. else
  53. ExecutionCount = WrappedSegment->Count;
  54. }
  55. FunctionCoverageSummary
  56. FunctionCoverageSummary::get(const CoverageMapping &CM,
  57. const coverage::FunctionRecord &Function) {
  58. // Compute the region coverage.
  59. size_t NumCodeRegions = 0, CoveredRegions = 0;
  60. for (auto &CR : Function.CountedRegions) {
  61. if (CR.Kind != CounterMappingRegion::CodeRegion)
  62. continue;
  63. ++NumCodeRegions;
  64. if (CR.ExecutionCount != 0)
  65. ++CoveredRegions;
  66. }
  67. // Compute the line coverage
  68. size_t NumLines = 0, CoveredLines = 0;
  69. CoverageData CD = CM.getCoverageForFunction(Function);
  70. auto NextSegment = CD.begin();
  71. auto EndSegment = CD.end();
  72. const coverage::CoverageSegment *WrappedSegment = nullptr;
  73. SmallVector<const coverage::CoverageSegment *, 4> LineSegments;
  74. unsigned Line = NextSegment->Line;
  75. while (NextSegment != EndSegment) {
  76. // Gather the segments on this line and the wrapped segment.
  77. if (LineSegments.size())
  78. WrappedSegment = LineSegments.back();
  79. LineSegments.clear();
  80. while (NextSegment != EndSegment && NextSegment->Line == Line)
  81. LineSegments.push_back(&*NextSegment++);
  82. LineCoverageStats LCS{LineSegments, WrappedSegment};
  83. if (LCS.isMapped()) {
  84. ++NumLines;
  85. if (LCS.ExecutionCount)
  86. ++CoveredLines;
  87. }
  88. ++Line;
  89. }
  90. return FunctionCoverageSummary(
  91. Function.Name, Function.ExecutionCount,
  92. RegionCoverageInfo(CoveredRegions, NumCodeRegions),
  93. LineCoverageInfo(CoveredLines, NumLines));
  94. }
  95. FunctionCoverageSummary
  96. FunctionCoverageSummary::get(const InstantiationGroup &Group,
  97. ArrayRef<FunctionCoverageSummary> Summaries) {
  98. std::string Name;
  99. if (Group.hasName()) {
  100. Name = Group.getName();
  101. } else {
  102. llvm::raw_string_ostream OS(Name);
  103. OS << "Definition at line " << Group.getLine() << ", column "
  104. << Group.getColumn();
  105. }
  106. FunctionCoverageSummary Summary(Name);
  107. Summary.ExecutionCount = Group.getTotalExecutionCount();
  108. Summary.RegionCoverage = Summaries[0].RegionCoverage;
  109. Summary.LineCoverage = Summaries[0].LineCoverage;
  110. for (const auto &FCS : Summaries.drop_front()) {
  111. Summary.RegionCoverage.merge(FCS.RegionCoverage);
  112. Summary.LineCoverage.merge(FCS.LineCoverage);
  113. }
  114. return Summary;
  115. }