SourceCoverageView.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. //===- SourceCoverageView.h - Code coverage view for source code ----------===//
  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. // This class implements rendering for code coverage of source code.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_COV_SOURCECOVERAGEVIEW_H
  14. #define LLVM_COV_SOURCECOVERAGEVIEW_H
  15. #include "CoverageViewOptions.h"
  16. #include "llvm/ProfileData/CoverageMapping.h"
  17. #include "llvm/Support/MemoryBuffer.h"
  18. #include <vector>
  19. namespace llvm {
  20. class SourceCoverageView;
  21. /// \brief A view that represents a macro or include expansion
  22. struct ExpansionView {
  23. coverage::CounterMappingRegion Region;
  24. std::unique_ptr<SourceCoverageView> View;
  25. ExpansionView(const coverage::CounterMappingRegion &Region,
  26. std::unique_ptr<SourceCoverageView> View)
  27. : Region(Region), View(std::move(View)) {}
  28. ExpansionView(ExpansionView &&RHS)
  29. : Region(std::move(RHS.Region)), View(std::move(RHS.View)) {}
  30. ExpansionView &operator=(ExpansionView &&RHS) {
  31. Region = std::move(RHS.Region);
  32. View = std::move(RHS.View);
  33. return *this;
  34. }
  35. unsigned getLine() const { return Region.LineStart; }
  36. unsigned getStartCol() const { return Region.ColumnStart; }
  37. unsigned getEndCol() const { return Region.ColumnEnd; }
  38. friend bool operator<(const ExpansionView &LHS, const ExpansionView &RHS) {
  39. return LHS.Region.startLoc() < RHS.Region.startLoc();
  40. }
  41. };
  42. /// \brief A view that represents a function instantiation
  43. struct InstantiationView {
  44. StringRef FunctionName;
  45. unsigned Line;
  46. std::unique_ptr<SourceCoverageView> View;
  47. InstantiationView(StringRef FunctionName, unsigned Line,
  48. std::unique_ptr<SourceCoverageView> View)
  49. : FunctionName(FunctionName), Line(Line), View(std::move(View)) {}
  50. InstantiationView(InstantiationView &&RHS)
  51. : FunctionName(std::move(RHS.FunctionName)), Line(std::move(RHS.Line)),
  52. View(std::move(RHS.View)) {}
  53. InstantiationView &operator=(InstantiationView &&RHS) {
  54. FunctionName = std::move(RHS.FunctionName);
  55. Line = std::move(RHS.Line);
  56. View = std::move(RHS.View);
  57. return *this;
  58. }
  59. friend bool operator<(const InstantiationView &LHS,
  60. const InstantiationView &RHS) {
  61. return LHS.Line < RHS.Line;
  62. }
  63. };
  64. /// \brief A code coverage view of a specific source file.
  65. /// It can have embedded coverage views.
  66. class SourceCoverageView {
  67. private:
  68. /// \brief Coverage information for a single line.
  69. struct LineCoverageInfo {
  70. uint64_t ExecutionCount;
  71. unsigned RegionCount;
  72. bool Mapped;
  73. LineCoverageInfo() : ExecutionCount(0), RegionCount(0), Mapped(false) {}
  74. bool isMapped() const { return Mapped; }
  75. bool hasMultipleRegions() const { return RegionCount > 1; }
  76. void addRegionStartCount(uint64_t Count) {
  77. // The max of all region starts is the most interesting value.
  78. addRegionCount(RegionCount ? std::max(ExecutionCount, Count) : Count);
  79. ++RegionCount;
  80. }
  81. void addRegionCount(uint64_t Count) {
  82. Mapped = true;
  83. ExecutionCount = Count;
  84. }
  85. };
  86. const MemoryBuffer &File;
  87. const CoverageViewOptions &Options;
  88. coverage::CoverageData CoverageInfo;
  89. std::vector<ExpansionView> ExpansionSubViews;
  90. std::vector<InstantiationView> InstantiationSubViews;
  91. /// \brief Render a source line with highlighting.
  92. void renderLine(raw_ostream &OS, StringRef Line, int64_t LineNumber,
  93. const coverage::CoverageSegment *WrappedSegment,
  94. ArrayRef<const coverage::CoverageSegment *> Segments,
  95. unsigned ExpansionCol);
  96. void renderIndent(raw_ostream &OS, unsigned Level);
  97. void renderViewDivider(unsigned Offset, unsigned Length, raw_ostream &OS);
  98. /// \brief Render the line's execution count column.
  99. void renderLineCoverageColumn(raw_ostream &OS, const LineCoverageInfo &Line);
  100. /// \brief Render the line number column.
  101. void renderLineNumberColumn(raw_ostream &OS, unsigned LineNo);
  102. /// \brief Render all the region's execution counts on a line.
  103. void
  104. renderRegionMarkers(raw_ostream &OS,
  105. ArrayRef<const coverage::CoverageSegment *> Segments);
  106. static const unsigned LineCoverageColumnWidth = 7;
  107. static const unsigned LineNumberColumnWidth = 5;
  108. public:
  109. SourceCoverageView(const MemoryBuffer &File,
  110. const CoverageViewOptions &Options,
  111. coverage::CoverageData &&CoverageInfo)
  112. : File(File), Options(Options), CoverageInfo(std::move(CoverageInfo)) {}
  113. const CoverageViewOptions &getOptions() const { return Options; }
  114. /// \brief Add an expansion subview to this view.
  115. void addExpansion(const coverage::CounterMappingRegion &Region,
  116. std::unique_ptr<SourceCoverageView> View) {
  117. ExpansionSubViews.emplace_back(Region, std::move(View));
  118. }
  119. /// \brief Add a function instantiation subview to this view.
  120. void addInstantiation(StringRef FunctionName, unsigned Line,
  121. std::unique_ptr<SourceCoverageView> View) {
  122. InstantiationSubViews.emplace_back(FunctionName, Line, std::move(View));
  123. }
  124. /// \brief Print the code coverage information for a specific
  125. /// portion of a source file to the output stream.
  126. void render(raw_ostream &OS, bool WholeFile, unsigned IndentLevel = 0);
  127. };
  128. } // namespace llvm
  129. #endif // LLVM_COV_SOURCECOVERAGEVIEW_H