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