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