1 //===- SourceCoverageView.h - Code coverage view for source code ----------===//
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
7 //===----------------------------------------------------------------------===//
9 /// \file This class implements rendering for code coverage of source code.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_COV_SOURCECOVERAGEVIEW_H
14 #define LLVM_COV_SOURCECOVERAGEVIEW_H
16 #include "CoverageViewOptions.h"
17 #include "CoverageSummaryInfo.h"
18 #include "llvm/ProfileData/Coverage/CoverageMapping.h"
19 #include "llvm/Support/MemoryBuffer.h"
24 using namespace coverage
;
26 class CoverageFiltersMatchAll
;
27 class SourceCoverageView
;
29 /// A view that represents a macro or include expansion.
30 struct ExpansionView
{
31 CounterMappingRegion Region
;
32 std::unique_ptr
<SourceCoverageView
> View
;
34 ExpansionView(const CounterMappingRegion
&Region
,
35 std::unique_ptr
<SourceCoverageView
> View
)
36 : Region(Region
), View(std::move(View
)) {}
37 ExpansionView(ExpansionView
&&RHS
)
38 : Region(std::move(RHS
.Region
)), View(std::move(RHS
.View
)) {}
39 ExpansionView
&operator=(ExpansionView
&&RHS
) {
40 Region
= std::move(RHS
.Region
);
41 View
= std::move(RHS
.View
);
45 unsigned getLine() const { return Region
.LineStart
; }
46 unsigned getStartCol() const { return Region
.ColumnStart
; }
47 unsigned getEndCol() const { return Region
.ColumnEnd
; }
49 friend bool operator<(const ExpansionView
&LHS
, const ExpansionView
&RHS
) {
50 return LHS
.Region
.startLoc() < RHS
.Region
.startLoc();
54 /// A view that represents a function instantiation.
55 struct InstantiationView
{
56 StringRef FunctionName
;
58 std::unique_ptr
<SourceCoverageView
> View
;
60 InstantiationView(StringRef FunctionName
, unsigned Line
,
61 std::unique_ptr
<SourceCoverageView
> View
)
62 : FunctionName(FunctionName
), Line(Line
), View(std::move(View
)) {}
64 friend bool operator<(const InstantiationView
&LHS
,
65 const InstantiationView
&RHS
) {
66 return LHS
.Line
< RHS
.Line
;
70 /// A file manager that handles format-aware file creation.
71 class CoveragePrinter
{
73 struct StreamDestructor
{
74 void operator()(raw_ostream
*OS
) const;
77 using OwnedStream
= std::unique_ptr
<raw_ostream
, StreamDestructor
>;
80 const CoverageViewOptions
&Opts
;
82 CoveragePrinter(const CoverageViewOptions
&Opts
) : Opts(Opts
) {}
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;
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;
95 /// Return the sub-directory name for file coverage reports.
96 static StringRef
getCoverageDir() { return "coverage"; }
99 static std::unique_ptr
<CoveragePrinter
>
100 create(const CoverageViewOptions
&Opts
);
102 virtual ~CoveragePrinter() {}
104 /// @name File Creation Interface
107 /// Create a file to print a coverage view into.
108 virtual Expected
<OwnedStream
> createViewFile(StringRef Path
,
109 bool InToplevel
) = 0;
111 /// Close a file which has been used to print a coverage view.
112 virtual void closeViewFile(OwnedStream OS
) = 0;
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;
122 /// A code coverage view of a source file or function.
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
;
131 /// A memory buffer backing the source on display.
132 const MemoryBuffer
&File
;
134 /// Various options to guide the coverage renderer.
135 const CoverageViewOptions
&Options
;
137 /// Complete coverage information about the source on display.
138 CoverageData CoverageInfo
;
140 /// A container for all expansions (e.g macros) in the source on display.
141 std::vector
<ExpansionView
> ExpansionSubViews
;
143 /// A container for all instantiations (e.g template functions) in the source
145 std::vector
<InstantiationView
> InstantiationSubViews
;
147 /// Get the first uncovered line number for the source file.
148 unsigned getFirstUncoveredLineNo();
155 LineRef(StringRef Line
, int64_t LineNo
) : Line(Line
), LineNo(LineNo
) {}
158 using CoverageSegmentArray
= ArrayRef
<const CoverageSegment
*>;
160 /// @name Rendering Interface
163 /// Render a header for the view.
164 virtual void renderViewHeader(raw_ostream
&OS
) = 0;
166 /// Render a footer for the view.
167 virtual void renderViewFooter(raw_ostream
&OS
) = 0;
169 /// Render the source name for the view.
170 virtual void renderSourceName(raw_ostream
&OS
, bool WholeFile
) = 0;
172 /// Render the line prefix at the given \p ViewDepth.
173 virtual void renderLinePrefix(raw_ostream
&OS
, unsigned ViewDepth
) = 0;
175 /// Render the line suffix at the given \p ViewDepth.
176 virtual void renderLineSuffix(raw_ostream
&OS
, unsigned ViewDepth
) = 0;
178 /// Render a view divider at the given \p ViewDepth.
179 virtual void renderViewDivider(raw_ostream
&OS
, unsigned ViewDepth
) = 0;
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;
186 /// Render the line's execution count column.
187 virtual void renderLineCoverageColumn(raw_ostream
&OS
,
188 const LineCoverageStats
&Line
) = 0;
190 /// Render the line number column.
191 virtual void renderLineNumberColumn(raw_ostream
&OS
, unsigned LineNo
) = 0;
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;
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;
204 /// Render an expansion view and any nested views.
205 virtual void renderExpansionView(raw_ostream
&OS
, ExpansionView
&ESV
,
206 unsigned ViewDepth
) = 0;
208 /// Render an instantiation view and any nested views.
209 virtual void renderInstantiationView(raw_ostream
&OS
, InstantiationView
&ISV
,
210 unsigned ViewDepth
) = 0;
212 /// Render \p Title, a project title if one is available, and the
214 virtual void renderTitle(raw_ostream
&OS
, StringRef CellText
) = 0;
216 /// Render the table header for a given source file.
217 virtual void renderTableHeader(raw_ostream
&OS
, unsigned FirstUncoveredLineNo
,
218 unsigned IndentLevel
) = 0;
222 /// Format a count using engineering notation with 3 significant
224 static std::string
formatCount(uint64_t N
);
226 /// Check if region marker output is expected for a line.
227 bool shouldRenderRegionMarkers(const LineCoverageStats
&LCS
) const;
229 /// Check if there are any sub-views attached to this view.
230 bool hasSubViews() const;
232 SourceCoverageView(StringRef SourceName
, const MemoryBuffer
&File
,
233 const CoverageViewOptions
&Options
,
234 CoverageData
&&CoverageInfo
)
235 : SourceName(SourceName
), File(File
), Options(Options
),
236 CoverageInfo(std::move(CoverageInfo
)) {}
239 static std::unique_ptr
<SourceCoverageView
>
240 create(StringRef SourceName
, const MemoryBuffer
&File
,
241 const CoverageViewOptions
&Options
, CoverageData
&&CoverageInfo
);
243 virtual ~SourceCoverageView() {}
245 /// Return the source name formatted for the host OS.
246 std::string
getSourceName() const;
248 const CoverageViewOptions
&getOptions() const { return Options
; }
250 /// Add an expansion subview to this view.
251 void addExpansion(const CounterMappingRegion
&Region
,
252 std::unique_ptr
<SourceCoverageView
> View
);
254 /// Add a function instantiation subview to this view.
255 void addInstantiation(StringRef FunctionName
, unsigned Line
,
256 std::unique_ptr
<SourceCoverageView
> View
);
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);
266 #endif // LLVM_COV_SOURCECOVERAGEVIEW_H