Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit d1b4e60

Browse files
committed
llvm-cov: Distinguish expansion/instantiation from SourceCoverageView
SourceCoverageView currently has "Kind" and a list of child views, all of which must have either an expansion or an instantiation Kind. In addition to being an error-prone design, this makes it awkward to differentiate between the two child types and adds a number of optionally used members to the type. Split the subview types into their own separate objects, and maintain lists of each rather than one combined "Children" list. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@217940 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent d5f7353 commit d1b4e60

File tree

3 files changed

+108
-113
lines changed

3 files changed

+108
-113
lines changed

tools/llvm-cov/CodeCoverage.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -282,16 +282,16 @@ void CodeCoverageTool::createExpansionSubView(
282282
getSourceFile(Function.Filenames[ExpandedRegion.ExpandedFileID]);
283283
if (!SourceBuffer)
284284
return;
285-
auto SubView = llvm::make_unique<SourceCoverageView>(
286-
SourceBuffer.get(), Parent.getOptions(), ExpandedRegion);
285+
auto SubView = llvm::make_unique<SourceCoverageView>(SourceBuffer.get(),
286+
Parent.getOptions());
287287
SourceCoverageDataManager RegionManager;
288288
for (const auto &CR : Function.CountedRegions) {
289289
if (CR.FileID == ExpandedRegion.ExpandedFileID)
290290
RegionManager.insert(CR);
291291
}
292292
SubView->load(RegionManager);
293293
createExpansionSubViews(*SubView, ExpandedRegion.ExpandedFileID, Function);
294-
Parent.addChild(std::move(SubView));
294+
Parent.addExpansion(ExpandedRegion, std::move(SubView));
295295
}
296296

297297
void CodeCoverageTool::createExpansionSubViews(
@@ -362,10 +362,18 @@ bool CodeCoverageTool::createSourceFileView(
362362
if (InstantiationSet.second.size() < 2)
363363
continue;
364364
for (auto Function : InstantiationSet.second) {
365-
auto SubView =
366-
llvm::make_unique<SourceCoverageView>(View, Function->Name);
365+
unsigned FileID = Function->CountedRegions.front().FileID;
366+
unsigned Line = 0;
367+
for (const auto &CR : Function->CountedRegions)
368+
if (CR.FileID == FileID)
369+
Line = std::max(CR.LineEnd, Line);
370+
auto SourceBuffer = getSourceFile(Function->Filenames[FileID]);
371+
if (!SourceBuffer)
372+
continue;
373+
auto SubView = llvm::make_unique<SourceCoverageView>(SourceBuffer.get(),
374+
View.getOptions());
367375
createInstantiationSubView(SourceFile, *Function, *SubView);
368-
View.addChild(std::move(SubView));
376+
View.addInstantiation(Function->Name, Line, std::move(SubView));
369377
}
370378
}
371379
return false;

tools/llvm-cov/SourceCoverageView.cpp

Lines changed: 47 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,12 @@ void SourceCoverageView::renderRegionMarkers(raw_ostream &OS,
140140

141141
/// \brief Insert a new highlighting range into the line's highlighting ranges
142142
/// Return line's new highlighting ranges in result.
143-
static void insertHighlightRange(
143+
static void insertExpansionHighlightRange(
144144
ArrayRef<SourceCoverageView::HighlightRange> Ranges,
145-
SourceCoverageView::HighlightRange RangeToInsert,
145+
unsigned Line, unsigned StartCol, unsigned EndCol,
146146
SmallVectorImpl<SourceCoverageView::HighlightRange> &Result) {
147+
auto RangeToInsert = SourceCoverageView::HighlightRange(
148+
Line, StartCol, EndCol, SourceCoverageView::HighlightRange::Expanded);
147149
Result.clear();
148150
size_t I = 0;
149151
auto E = Ranges.size();
@@ -189,22 +191,6 @@ static void insertHighlightRange(
189191
Result.push_back(Ranges[I]);
190192
}
191193

192-
void SourceCoverageView::sortChildren() {
193-
for (auto &I : Children)
194-
I->sortChildren();
195-
std::sort(Children.begin(), Children.end(),
196-
[](const std::unique_ptr<SourceCoverageView> &LHS,
197-
const std::unique_ptr<SourceCoverageView> &RHS) {
198-
return LHS->ExpansionRegion < RHS->ExpansionRegion;
199-
});
200-
}
201-
202-
SourceCoverageView::HighlightRange
203-
SourceCoverageView::getExpansionHighlightRange() const {
204-
return HighlightRange(ExpansionRegion.LineStart, ExpansionRegion.ColumnStart,
205-
ExpansionRegion.ColumnEnd, HighlightRange::Expanded);
206-
}
207-
208194
template <typename T>
209195
ArrayRef<T> gatherLineItems(size_t &CurrentIdx, const std::vector<T> &Items,
210196
unsigned LineNo) {
@@ -215,24 +201,8 @@ ArrayRef<T> gatherLineItems(size_t &CurrentIdx, const std::vector<T> &Items,
215201
return ArrayRef<T>(Items.data() + PrevIdx, CurrentIdx - PrevIdx);
216202
}
217203

218-
ArrayRef<std::unique_ptr<SourceCoverageView>>
219-
gatherLineSubViews(size_t &CurrentIdx,
220-
ArrayRef<std::unique_ptr<SourceCoverageView>> Items,
221-
unsigned LineNo) {
222-
auto PrevIdx = CurrentIdx;
223-
auto E = Items.size();
224-
while (CurrentIdx < E &&
225-
Items[CurrentIdx]->getSubViewsExpansionLine() == LineNo)
226-
++CurrentIdx;
227-
return Items.slice(PrevIdx, CurrentIdx - PrevIdx);
228-
}
229-
230204
void SourceCoverageView::render(raw_ostream &OS, unsigned IndentLevel) {
231-
// Make sure that the children are in sorted order.
232-
sortChildren();
233-
234205
SmallVector<HighlightRange, 8> AdjustedLineHighlightRanges;
235-
size_t CurrentChild = 0;
236206
size_t CurrentHighlightRange = 0;
237207
size_t CurrentRegionMarker = 0;
238208

@@ -249,12 +219,18 @@ void SourceCoverageView::render(raw_ostream &OS, unsigned IndentLevel) {
249219
// subviews.
250220
unsigned DividerWidth = CombinedColumnWidth + 4;
251221

222+
// We need the expansions and instantiations sorted so we can go through them
223+
// while we iterate lines.
224+
std::sort(ExpansionSubViews.begin(), ExpansionSubViews.end());
225+
std::sort(InstantiationSubViews.begin(), InstantiationSubViews.end());
226+
auto NextESV = ExpansionSubViews.begin();
227+
auto EndESV = ExpansionSubViews.end();
228+
auto NextISV = InstantiationSubViews.begin();
229+
auto EndISV = InstantiationSubViews.end();
230+
252231
for (size_t I = 0, E = LineStats.size(); I < E; ++I) {
253232
unsigned LineNo = I + LineOffset;
254233

255-
// Gather the child subviews that are visible on this line.
256-
auto LineSubViews = gatherLineSubViews(CurrentChild, Children, LineNo);
257-
258234
renderIndent(OS, IndentLevel);
259235
if (Options.ShowLineStats)
260236
renderLineCoverageColumn(OS, LineStats[I]);
@@ -267,11 +243,10 @@ void SourceCoverageView::render(raw_ostream &OS, unsigned IndentLevel) {
267243
auto LineRanges = LineHighlightRanges;
268244
// Highlight the expansion range if there is an expansion subview on this
269245
// line.
270-
if (!LineSubViews.empty() && LineSubViews.front()->isExpansionSubView() &&
271-
Options.Colors) {
272-
insertHighlightRange(LineHighlightRanges,
273-
LineSubViews.front()->getExpansionHighlightRange(),
274-
AdjustedLineHighlightRanges);
246+
if (NextESV != EndESV && NextESV->getLine() == LineNo && Options.Colors) {
247+
insertExpansionHighlightRange(
248+
LineHighlightRanges, NextESV->getLine(), NextESV->getStartCol(),
249+
NextESV->getEndCol(), AdjustedLineHighlightRanges);
275250
LineRanges = AdjustedLineHighlightRanges;
276251
}
277252

@@ -294,40 +269,40 @@ void SourceCoverageView::render(raw_ostream &OS, unsigned IndentLevel) {
294269
renderRegionMarkers(OS, LineMarkers);
295270
}
296271

297-
// Show the line's expanded child subviews.
298-
bool FirstChildExpansion = true;
299-
if (LineSubViews.empty())
300-
continue;
272+
// Show the expansions and instantiations for this line.
301273
unsigned NestedIndent = IndentLevel + 1;
302-
renderViewDivider(NestedIndent, DividerWidth, OS);
303-
OS << "\n";
304-
for (const auto &Child : LineSubViews) {
305-
// If this subview shows a function instantiation, render the function's
306-
// name.
307-
if (Child->isInstantiationSubView()) {
308-
renderIndent(OS, NestedIndent);
309-
OS << ' ';
310-
Options.colored_ostream(OS, raw_ostream::CYAN) << Child->FunctionName
311-
<< ":";
274+
bool RenderedSubView = false;
275+
for (; NextESV != EndESV && NextESV->getLine() == LineNo; ++NextESV) {
276+
renderViewDivider(NestedIndent, DividerWidth, OS);
277+
OS << "\n";
278+
if (RenderedSubView) {
279+
// Re-render the current line and highlight the expansion range for
280+
// this subview.
281+
insertExpansionHighlightRange(
282+
LineHighlightRanges, NextESV->getLine(), NextESV->getStartCol(),
283+
NextESV->getEndCol(), AdjustedLineHighlightRanges);
284+
renderIndent(OS, IndentLevel);
285+
OS.indent(CombinedColumnWidth + (IndentLevel == 0 ? 0 : 1));
286+
renderLine(OS, Line, AdjustedLineHighlightRanges);
287+
renderViewDivider(NestedIndent, DividerWidth, OS);
312288
OS << "\n";
313-
} else {
314-
if (!FirstChildExpansion) {
315-
// Re-render the current line and highlight the expansion range for
316-
// this
317-
// subview.
318-
insertHighlightRange(LineHighlightRanges,
319-
Child->getExpansionHighlightRange(),
320-
AdjustedLineHighlightRanges);
321-
renderIndent(OS, IndentLevel);
322-
OS.indent(CombinedColumnWidth + (IndentLevel == 0 ? 0 : 1));
323-
renderLine(OS, Line, AdjustedLineHighlightRanges);
324-
renderViewDivider(NestedIndent, DividerWidth, OS);
325-
OS << "\n";
326-
} else
327-
FirstChildExpansion = false;
328289
}
329290
// Render the child subview
330-
Child->render(OS, NestedIndent);
291+
NextESV->View->render(OS, NestedIndent);
292+
RenderedSubView = true;
293+
}
294+
for (; NextISV != EndISV && NextISV->Line == LineNo; ++NextISV) {
295+
renderViewDivider(NestedIndent, DividerWidth, OS);
296+
OS << "\n";
297+
renderIndent(OS, NestedIndent);
298+
OS << ' ';
299+
Options.colored_ostream(OS, raw_ostream::CYAN) << NextISV->FunctionName
300+
<< ":";
301+
OS << "\n";
302+
NextISV->View->render(OS, NestedIndent);
303+
RenderedSubView = true;
304+
}
305+
if (RenderedSubView) {
331306
renderViewDivider(NestedIndent, DividerWidth, OS);
332307
OS << "\n";
333308
}

tools/llvm-cov/SourceCoverageView.h

Lines changed: 47 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,46 @@
2222

2323
namespace llvm {
2424

25+
class SourceCoverageView;
26+
27+
/// \brief A view that represents a macro or include expansion
28+
struct ExpansionView {
29+
coverage::CounterMappingRegion Region;
30+
std::unique_ptr<SourceCoverageView> View;
31+
32+
ExpansionView(const coverage::CounterMappingRegion &Region,
33+
std::unique_ptr<SourceCoverageView> View)
34+
: Region(Region), View(std::move(View)) {}
35+
36+
unsigned getLine() const { return Region.LineStart; }
37+
unsigned getStartCol() const { return Region.ColumnStart; }
38+
unsigned getEndCol() const { return Region.ColumnEnd; }
39+
40+
friend bool operator<(const ExpansionView &LHS, const ExpansionView &RHS) {
41+
return LHS.Region.startLoc() < RHS.Region.startLoc();
42+
}
43+
};
44+
45+
/// \brief A view that represents a function instantiation
46+
struct InstantiationView {
47+
StringRef FunctionName;
48+
unsigned Line;
49+
std::unique_ptr<SourceCoverageView> View;
50+
51+
InstantiationView(StringRef FunctionName, unsigned Line,
52+
std::unique_ptr<SourceCoverageView> View)
53+
: FunctionName(FunctionName), Line(Line), View(std::move(View)) {}
54+
55+
friend bool operator<(const InstantiationView &LHS,
56+
const InstantiationView &RHS) {
57+
return LHS.Line < RHS.Line;
58+
}
59+
};
60+
2561
/// \brief A code coverage view of a specific source file.
2662
/// It can have embedded coverage views.
2763
class SourceCoverageView {
2864
public:
29-
enum SubViewKind { View, ExpansionView, InstantiationView };
30-
3165
/// \brief Coverage information for a single line.
3266
struct LineCoverageInfo {
3367
uint64_t ExecutionCount;
@@ -111,13 +145,11 @@ class SourceCoverageView {
111145
const MemoryBuffer &File;
112146
const CoverageViewOptions &Options;
113147
unsigned LineOffset;
114-
SubViewKind Kind;
115-
coverage::CounterMappingRegion ExpansionRegion;
116-
std::vector<std::unique_ptr<SourceCoverageView>> Children;
148+
std::vector<ExpansionView> ExpansionSubViews;
149+
std::vector<InstantiationView> InstantiationSubViews;
117150
std::vector<LineCoverageInfo> LineStats;
118151
std::vector<HighlightRange> HighlightRanges;
119152
std::vector<RegionMarker> Markers;
120-
StringRef FunctionName;
121153

122154
/// \brief Initialize the visible source range for this view.
123155
void setUpVisibleRange(SourceCoverageDataManager &Data);
@@ -131,12 +163,6 @@ class SourceCoverageView {
131163
/// \brief Create the region markers using the coverage data.
132164
void createRegionMarkers(SourceCoverageDataManager &Data);
133165

134-
/// \brief Sort children by the starting location.
135-
void sortChildren();
136-
137-
/// \brief Return a highlight range for the expansion region of this view.
138-
HighlightRange getExpansionHighlightRange() const;
139-
140166
/// \brief Render a source line with highlighting.
141167
void renderLine(raw_ostream &OS, StringRef Line,
142168
ArrayRef<HighlightRange> Ranges);
@@ -160,34 +186,20 @@ class SourceCoverageView {
160186
public:
161187
SourceCoverageView(const MemoryBuffer &File,
162188
const CoverageViewOptions &Options)
163-
: File(File), Options(Options), LineOffset(0), Kind(View),
164-
ExpansionRegion(coverage::Counter(), 0, 0, 0, 0, 0) {}
165-
166-
SourceCoverageView(SourceCoverageView &Parent, StringRef FunctionName)
167-
: File(Parent.File), Options(Parent.Options), LineOffset(0),
168-
Kind(InstantiationView),
169-
ExpansionRegion(coverage::Counter(), 0, 0, 0, 0, 0),
170-
FunctionName(FunctionName) {}
171-
172-
SourceCoverageView(const MemoryBuffer &File,
173-
const CoverageViewOptions &Options,
174-
const coverage::CounterMappingRegion &ExpansionRegion)
175-
: File(File), Options(Options), LineOffset(0), Kind(ExpansionView),
176-
ExpansionRegion(ExpansionRegion) {}
189+
: File(File), Options(Options), LineOffset(0) {}
177190

178191
const CoverageViewOptions &getOptions() const { return Options; }
179192

180-
bool isExpansionSubView() const { return Kind == ExpansionView; }
181-
182-
bool isInstantiationSubView() const { return Kind == InstantiationView; }
183-
184-
/// \brief Return the line number after which the subview expansion is shown.
185-
unsigned getSubViewsExpansionLine() const {
186-
return ExpansionRegion.LineStart;
193+
/// \brief Add an expansion subview to this view.
194+
void addExpansion(const coverage::CounterMappingRegion &Region,
195+
std::unique_ptr<SourceCoverageView> View) {
196+
ExpansionSubViews.emplace_back(Region, std::move(View));
187197
}
188198

189-
void addChild(std::unique_ptr<SourceCoverageView> View) {
190-
Children.push_back(std::move(View));
199+
/// \brief Add a function instantiation subview to this view.
200+
void addInstantiation(StringRef FunctionName, unsigned Line,
201+
std::unique_ptr<SourceCoverageView> View) {
202+
InstantiationSubViews.emplace_back(FunctionName, Line, std::move(View));
191203
}
192204

193205
/// \brief Print the code coverage information for a specific

0 commit comments

Comments
 (0)