SourceCoverageView.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. //===- SourceCoverageView.h - Code coverage view for source code ----------===//
  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. /// \file This class implements rendering for code coverage of source code.
  10. ///
  11. //===----------------------------------------------------------------------===//
  12. #ifndef LLVM_COV_SOURCECOVERAGEVIEW_H
  13. #define LLVM_COV_SOURCECOVERAGEVIEW_H
  14. #include "CoverageViewOptions.h"
  15. #include "CoverageSummaryInfo.h"
  16. #include "llvm/ProfileData/Coverage/CoverageMapping.h"
  17. #include "llvm/Support/MemoryBuffer.h"
  18. #include <vector>
  19. namespace llvm {
  20. using namespace coverage;
  21. class CoverageFiltersMatchAll;
  22. class SourceCoverageView;
  23. /// A view that represents a macro or include expansion.
  24. struct ExpansionView {
  25. CounterMappingRegion Region;
  26. std::unique_ptr<SourceCoverageView> View;
  27. ExpansionView(const CounterMappingRegion &Region,
  28. std::unique_ptr<SourceCoverageView> View)
  29. : Region(Region), View(std::move(View)) {}
  30. ExpansionView(ExpansionView &&RHS)
  31. : Region(std::move(RHS.Region)), View(std::move(RHS.View)) {}
  32. ExpansionView &operator=(ExpansionView &&RHS) {
  33. Region = std::move(RHS.Region);
  34. View = std::move(RHS.View);
  35. return *this;
  36. }
  37. unsigned getLine() const { return Region.LineStart; }
  38. unsigned getStartCol() const { return Region.ColumnStart; }
  39. unsigned getEndCol() const { return Region.ColumnEnd; }
  40. friend bool operator<(const ExpansionView &LHS, const ExpansionView &RHS) {
  41. return LHS.Region.startLoc() < RHS.Region.startLoc();
  42. }
  43. };
  44. /// A view that represents a function instantiation.
  45. struct InstantiationView {
  46. StringRef FunctionName;
  47. unsigned Line;
  48. std::unique_ptr<SourceCoverageView> View;
  49. InstantiationView(StringRef FunctionName, unsigned Line,
  50. std::unique_ptr<SourceCoverageView> View)
  51. : FunctionName(FunctionName), Line(Line), View(std::move(View)) {}
  52. friend bool operator<(const InstantiationView &LHS,
  53. const InstantiationView &RHS) {
  54. return LHS.Line < RHS.Line;
  55. }
  56. };
  57. /// A view that represents one or more branch regions on a given source line.
  58. struct BranchView {
  59. std::vector<CountedRegion> Regions;
  60. std::unique_ptr<SourceCoverageView> View;
  61. unsigned Line;
  62. BranchView(unsigned Line, ArrayRef<CountedRegion> Regions,
  63. std::unique_ptr<SourceCoverageView> View)
  64. : Regions(Regions), View(std::move(View)), Line(Line) {}
  65. unsigned getLine() const { return Line; }
  66. friend bool operator<(const BranchView &LHS, const BranchView &RHS) {
  67. return LHS.Line < RHS.Line;
  68. }
  69. };
  70. /// A file manager that handles format-aware file creation.
  71. class CoveragePrinter {
  72. public:
  73. struct StreamDestructor {
  74. void operator()(raw_ostream *OS) const;
  75. };
  76. using OwnedStream = std::unique_ptr<raw_ostream, StreamDestructor>;
  77. protected:
  78. const CoverageViewOptions &Opts;
  79. CoveragePrinter(const CoverageViewOptions &Opts) : Opts(Opts) {}
  80. /// Return `OutputDir/ToplevelDir/Path.Extension`. If \p InToplevel is
  81. /// false, skip the ToplevelDir component. If \p Relative is false, skip the
  82. /// OutputDir component.
  83. std::string getOutputPath(StringRef Path, StringRef Extension,
  84. bool InToplevel, bool Relative = true) const;
  85. /// If directory output is enabled, create a file in that directory
  86. /// at the path given by getOutputPath(). Otherwise, return stdout.
  87. Expected<OwnedStream> createOutputStream(StringRef Path, StringRef Extension,
  88. bool InToplevel) const;
  89. /// Return the sub-directory name for file coverage reports.
  90. static StringRef getCoverageDir() { return "coverage"; }
  91. public:
  92. static std::unique_ptr<CoveragePrinter>
  93. create(const CoverageViewOptions &Opts);
  94. virtual ~CoveragePrinter() {}
  95. /// @name File Creation Interface
  96. /// @{
  97. /// Create a file to print a coverage view into.
  98. virtual Expected<OwnedStream> createViewFile(StringRef Path,
  99. bool InToplevel) = 0;
  100. /// Close a file which has been used to print a coverage view.
  101. virtual void closeViewFile(OwnedStream OS) = 0;
  102. /// Create an index which lists reports for the given source files.
  103. virtual Error createIndexFile(ArrayRef<std::string> SourceFiles,
  104. const CoverageMapping &Coverage,
  105. const CoverageFiltersMatchAll &Filters) = 0;
  106. /// @}
  107. };
  108. /// A code coverage view of a source file or function.
  109. ///
  110. /// A source coverage view and its nested sub-views form a file-oriented
  111. /// representation of code coverage data. This view can be printed out by a
  112. /// renderer which implements the Rendering Interface.
  113. class SourceCoverageView {
  114. /// A function or file name.
  115. StringRef SourceName;
  116. /// A memory buffer backing the source on display.
  117. const MemoryBuffer &File;
  118. /// Various options to guide the coverage renderer.
  119. const CoverageViewOptions &Options;
  120. /// Complete coverage information about the source on display.
  121. CoverageData CoverageInfo;
  122. /// A container for all expansions (e.g macros) in the source on display.
  123. std::vector<ExpansionView> ExpansionSubViews;
  124. /// A container for all branches in the source on display.
  125. std::vector<BranchView> BranchSubViews;
  126. /// A container for all instantiations (e.g template functions) in the source
  127. /// on display.
  128. std::vector<InstantiationView> InstantiationSubViews;
  129. /// Get the first uncovered line number for the source file.
  130. unsigned getFirstUncoveredLineNo();
  131. protected:
  132. struct LineRef {
  133. StringRef Line;
  134. int64_t LineNo;
  135. LineRef(StringRef Line, int64_t LineNo) : Line(Line), LineNo(LineNo) {}
  136. };
  137. using CoverageSegmentArray = ArrayRef<const CoverageSegment *>;
  138. /// @name Rendering Interface
  139. /// @{
  140. /// Render a header for the view.
  141. virtual void renderViewHeader(raw_ostream &OS) = 0;
  142. /// Render a footer for the view.
  143. virtual void renderViewFooter(raw_ostream &OS) = 0;
  144. /// Render the source name for the view.
  145. virtual void renderSourceName(raw_ostream &OS, bool WholeFile) = 0;
  146. /// Render the line prefix at the given \p ViewDepth.
  147. virtual void renderLinePrefix(raw_ostream &OS, unsigned ViewDepth) = 0;
  148. /// Render the line suffix at the given \p ViewDepth.
  149. virtual void renderLineSuffix(raw_ostream &OS, unsigned ViewDepth) = 0;
  150. /// Render a view divider at the given \p ViewDepth.
  151. virtual void renderViewDivider(raw_ostream &OS, unsigned ViewDepth) = 0;
  152. /// Render a source line with highlighting.
  153. virtual void renderLine(raw_ostream &OS, LineRef L,
  154. const LineCoverageStats &LCS, unsigned ExpansionCol,
  155. unsigned ViewDepth) = 0;
  156. /// Render the line's execution count column.
  157. virtual void renderLineCoverageColumn(raw_ostream &OS,
  158. const LineCoverageStats &Line) = 0;
  159. /// Render the line number column.
  160. virtual void renderLineNumberColumn(raw_ostream &OS, unsigned LineNo) = 0;
  161. /// Render all the region's execution counts on a line.
  162. virtual void renderRegionMarkers(raw_ostream &OS,
  163. const LineCoverageStats &Line,
  164. unsigned ViewDepth) = 0;
  165. /// Render the site of an expansion.
  166. virtual void renderExpansionSite(raw_ostream &OS, LineRef L,
  167. const LineCoverageStats &LCS,
  168. unsigned ExpansionCol,
  169. unsigned ViewDepth) = 0;
  170. /// Render an expansion view and any nested views.
  171. virtual void renderExpansionView(raw_ostream &OS, ExpansionView &ESV,
  172. unsigned ViewDepth) = 0;
  173. /// Render an instantiation view and any nested views.
  174. virtual void renderInstantiationView(raw_ostream &OS, InstantiationView &ISV,
  175. unsigned ViewDepth) = 0;
  176. /// Render a branch view and any nested views.
  177. virtual void renderBranchView(raw_ostream &OS, BranchView &BRV,
  178. unsigned ViewDepth) = 0;
  179. /// Render \p Title, a project title if one is available, and the
  180. /// created time.
  181. virtual void renderTitle(raw_ostream &OS, StringRef CellText) = 0;
  182. /// Render the table header for a given source file.
  183. virtual void renderTableHeader(raw_ostream &OS, unsigned FirstUncoveredLineNo,
  184. unsigned IndentLevel) = 0;
  185. /// @}
  186. /// Format a count using engineering notation with 3 significant
  187. /// digits.
  188. static std::string formatCount(uint64_t N);
  189. /// Check if region marker output is expected for a line.
  190. bool shouldRenderRegionMarkers(const LineCoverageStats &LCS) const;
  191. /// Check if there are any sub-views attached to this view.
  192. bool hasSubViews() const;
  193. SourceCoverageView(StringRef SourceName, const MemoryBuffer &File,
  194. const CoverageViewOptions &Options,
  195. CoverageData &&CoverageInfo)
  196. : SourceName(SourceName), File(File), Options(Options),
  197. CoverageInfo(std::move(CoverageInfo)) {}
  198. public:
  199. static std::unique_ptr<SourceCoverageView>
  200. create(StringRef SourceName, const MemoryBuffer &File,
  201. const CoverageViewOptions &Options, CoverageData &&CoverageInfo);
  202. virtual ~SourceCoverageView() {}
  203. /// Return the source name formatted for the host OS.
  204. std::string getSourceName() const;
  205. const CoverageViewOptions &getOptions() const { return Options; }
  206. /// Add an expansion subview to this view.
  207. void addExpansion(const CounterMappingRegion &Region,
  208. std::unique_ptr<SourceCoverageView> View);
  209. /// Add a function instantiation subview to this view.
  210. void addInstantiation(StringRef FunctionName, unsigned Line,
  211. std::unique_ptr<SourceCoverageView> View);
  212. /// Add a branch subview to this view.
  213. void addBranch(unsigned Line, ArrayRef<CountedRegion> Regions,
  214. std::unique_ptr<SourceCoverageView> View);
  215. /// Print the code coverage information for a specific portion of a
  216. /// source file to the output stream.
  217. void print(raw_ostream &OS, bool WholeFile, bool ShowSourceName,
  218. bool ShowTitle, unsigned ViewDepth = 0);
  219. };
  220. } // namespace llvm
  221. #endif // LLVM_COV_SOURCECOVERAGEVIEW_H