]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | //===- SourceCoverageView.h - Code coverage view for source code ----------===// |
2 | // | |
3 | // The LLVM Compiler Infrastructure | |
4 | // | |
5 | // This file is distributed under the University of Illinois Open Source | |
6 | // License. See LICENSE.TXT for details. | |
7 | // | |
8 | //===----------------------------------------------------------------------===// | |
9 | // | |
10 | // This class implements rendering for code coverage of source code. | |
11 | // | |
12 | //===----------------------------------------------------------------------===// | |
13 | ||
14 | #ifndef LLVM_COV_SOURCECOVERAGEVIEW_H | |
15 | #define LLVM_COV_SOURCECOVERAGEVIEW_H | |
16 | ||
17 | #include "CoverageViewOptions.h" | |
18 | #include "llvm/ProfileData/CoverageMapping.h" | |
19 | #include "llvm/Support/MemoryBuffer.h" | |
20 | #include <vector> | |
21 | ||
22 | namespace llvm { | |
23 | ||
24 | class SourceCoverageView; | |
25 | ||
26 | /// \brief A view that represents a macro or include expansion | |
27 | struct ExpansionView { | |
28 | coverage::CounterMappingRegion Region; | |
29 | std::unique_ptr<SourceCoverageView> View; | |
30 | ||
31 | ExpansionView(const coverage::CounterMappingRegion &Region, | |
32 | std::unique_ptr<SourceCoverageView> View) | |
33 | : Region(Region), View(std::move(View)) {} | |
34 | ExpansionView(ExpansionView &&RHS) | |
35 | : Region(std::move(RHS.Region)), View(std::move(RHS.View)) {} | |
36 | ExpansionView &operator=(ExpansionView &&RHS) { | |
37 | Region = std::move(RHS.Region); | |
38 | View = std::move(RHS.View); | |
39 | return *this; | |
40 | } | |
41 | ||
42 | unsigned getLine() const { return Region.LineStart; } | |
43 | unsigned getStartCol() const { return Region.ColumnStart; } | |
44 | unsigned getEndCol() const { return Region.ColumnEnd; } | |
45 | ||
46 | friend bool operator<(const ExpansionView &LHS, const ExpansionView &RHS) { | |
47 | return LHS.Region.startLoc() < RHS.Region.startLoc(); | |
48 | } | |
49 | }; | |
50 | ||
51 | /// \brief A view that represents a function instantiation | |
52 | struct InstantiationView { | |
53 | StringRef FunctionName; | |
54 | unsigned Line; | |
55 | std::unique_ptr<SourceCoverageView> View; | |
56 | ||
57 | InstantiationView(StringRef FunctionName, unsigned Line, | |
58 | std::unique_ptr<SourceCoverageView> 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 | ||
70 | friend bool operator<(const InstantiationView &LHS, | |
71 | const InstantiationView &RHS) { | |
72 | return LHS.Line < RHS.Line; | |
73 | } | |
74 | }; | |
75 | ||
76 | /// \brief A code coverage view of a specific source file. | |
77 | /// It can have embedded coverage views. | |
78 | class SourceCoverageView { | |
79 | private: | |
80 | /// \brief Coverage information for a single line. | |
81 | struct LineCoverageInfo { | |
82 | uint64_t ExecutionCount; | |
83 | unsigned RegionCount; | |
84 | bool Mapped; | |
85 | ||
86 | LineCoverageInfo() : ExecutionCount(0), RegionCount(0), Mapped(false) {} | |
87 | ||
88 | bool isMapped() const { return Mapped; } | |
89 | ||
90 | bool hasMultipleRegions() const { return RegionCount > 1; } | |
91 | ||
92 | void addRegionStartCount(uint64_t Count) { | |
93 | Mapped = true; | |
94 | ExecutionCount = Count; | |
95 | ++RegionCount; | |
96 | } | |
97 | ||
98 | void addRegionCount(uint64_t Count) { | |
99 | Mapped = true; | |
100 | if (!RegionCount) | |
101 | ExecutionCount = Count; | |
102 | } | |
103 | }; | |
104 | ||
105 | const MemoryBuffer &File; | |
106 | const CoverageViewOptions &Options; | |
107 | coverage::CoverageData CoverageInfo; | |
108 | std::vector<ExpansionView> ExpansionSubViews; | |
109 | std::vector<InstantiationView> InstantiationSubViews; | |
110 | ||
111 | /// \brief Render a source line with highlighting. | |
112 | void renderLine(raw_ostream &OS, StringRef Line, int64_t LineNumber, | |
113 | const coverage::CoverageSegment *WrappedSegment, | |
114 | ArrayRef<const coverage::CoverageSegment *> Segments, | |
115 | unsigned ExpansionCol); | |
116 | ||
117 | void renderIndent(raw_ostream &OS, unsigned Level); | |
118 | ||
119 | void renderViewDivider(unsigned Offset, unsigned Length, raw_ostream &OS); | |
120 | ||
121 | /// \brief Render the line's execution count column. | |
122 | void renderLineCoverageColumn(raw_ostream &OS, const LineCoverageInfo &Line); | |
123 | ||
124 | /// \brief Render the line number column. | |
125 | void renderLineNumberColumn(raw_ostream &OS, unsigned LineNo); | |
126 | ||
127 | /// \brief Render all the region's execution counts on a line. | |
128 | void | |
129 | renderRegionMarkers(raw_ostream &OS, | |
130 | ArrayRef<const coverage::CoverageSegment *> Segments); | |
131 | ||
132 | static const unsigned LineCoverageColumnWidth = 7; | |
133 | static const unsigned LineNumberColumnWidth = 5; | |
134 | ||
135 | public: | |
136 | SourceCoverageView(const MemoryBuffer &File, | |
137 | const CoverageViewOptions &Options, | |
138 | coverage::CoverageData &&CoverageInfo) | |
139 | : File(File), Options(Options), CoverageInfo(std::move(CoverageInfo)) {} | |
140 | ||
141 | const CoverageViewOptions &getOptions() const { return Options; } | |
142 | ||
143 | /// \brief Add an expansion subview to this view. | |
144 | void addExpansion(const coverage::CounterMappingRegion &Region, | |
145 | std::unique_ptr<SourceCoverageView> View) { | |
146 | ExpansionSubViews.emplace_back(Region, std::move(View)); | |
147 | } | |
148 | ||
149 | /// \brief Add a function instantiation subview to this view. | |
150 | void addInstantiation(StringRef FunctionName, unsigned Line, | |
151 | std::unique_ptr<SourceCoverageView> View) { | |
152 | InstantiationSubViews.emplace_back(FunctionName, Line, std::move(View)); | |
153 | } | |
154 | ||
155 | /// \brief Print the code coverage information for a specific | |
156 | /// portion of a source file to the output stream. | |
157 | void render(raw_ostream &OS, bool WholeFile, unsigned IndentLevel = 0); | |
158 | }; | |
159 | ||
160 | } // namespace llvm | |
161 | ||
162 | #endif // LLVM_COV_SOURCECOVERAGEVIEW_H |