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