mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-02 19:24:25 +00:00
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
This commit is contained in:
@ -282,8 +282,8 @@ void CodeCoverageTool::createExpansionSubView(
|
|||||||
getSourceFile(Function.Filenames[ExpandedRegion.ExpandedFileID]);
|
getSourceFile(Function.Filenames[ExpandedRegion.ExpandedFileID]);
|
||||||
if (!SourceBuffer)
|
if (!SourceBuffer)
|
||||||
return;
|
return;
|
||||||
auto SubView = llvm::make_unique<SourceCoverageView>(
|
auto SubView = llvm::make_unique<SourceCoverageView>(SourceBuffer.get(),
|
||||||
SourceBuffer.get(), Parent.getOptions(), ExpandedRegion);
|
Parent.getOptions());
|
||||||
SourceCoverageDataManager RegionManager;
|
SourceCoverageDataManager RegionManager;
|
||||||
for (const auto &CR : Function.CountedRegions) {
|
for (const auto &CR : Function.CountedRegions) {
|
||||||
if (CR.FileID == ExpandedRegion.ExpandedFileID)
|
if (CR.FileID == ExpandedRegion.ExpandedFileID)
|
||||||
@ -291,7 +291,7 @@ void CodeCoverageTool::createExpansionSubView(
|
|||||||
}
|
}
|
||||||
SubView->load(RegionManager);
|
SubView->load(RegionManager);
|
||||||
createExpansionSubViews(*SubView, ExpandedRegion.ExpandedFileID, Function);
|
createExpansionSubViews(*SubView, ExpandedRegion.ExpandedFileID, Function);
|
||||||
Parent.addChild(std::move(SubView));
|
Parent.addExpansion(ExpandedRegion, std::move(SubView));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeCoverageTool::createExpansionSubViews(
|
void CodeCoverageTool::createExpansionSubViews(
|
||||||
@ -362,10 +362,18 @@ bool CodeCoverageTool::createSourceFileView(
|
|||||||
if (InstantiationSet.second.size() < 2)
|
if (InstantiationSet.second.size() < 2)
|
||||||
continue;
|
continue;
|
||||||
for (auto Function : InstantiationSet.second) {
|
for (auto Function : InstantiationSet.second) {
|
||||||
auto SubView =
|
unsigned FileID = Function->CountedRegions.front().FileID;
|
||||||
llvm::make_unique<SourceCoverageView>(View, Function->Name);
|
unsigned Line = 0;
|
||||||
|
for (const auto &CR : Function->CountedRegions)
|
||||||
|
if (CR.FileID == FileID)
|
||||||
|
Line = std::max(CR.LineEnd, Line);
|
||||||
|
auto SourceBuffer = getSourceFile(Function->Filenames[FileID]);
|
||||||
|
if (!SourceBuffer)
|
||||||
|
continue;
|
||||||
|
auto SubView = llvm::make_unique<SourceCoverageView>(SourceBuffer.get(),
|
||||||
|
View.getOptions());
|
||||||
createInstantiationSubView(SourceFile, *Function, *SubView);
|
createInstantiationSubView(SourceFile, *Function, *SubView);
|
||||||
View.addChild(std::move(SubView));
|
View.addInstantiation(Function->Name, Line, std::move(SubView));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -140,10 +140,12 @@ void SourceCoverageView::renderRegionMarkers(raw_ostream &OS,
|
|||||||
|
|
||||||
/// \brief Insert a new highlighting range into the line's highlighting ranges
|
/// \brief Insert a new highlighting range into the line's highlighting ranges
|
||||||
/// Return line's new highlighting ranges in result.
|
/// Return line's new highlighting ranges in result.
|
||||||
static void insertHighlightRange(
|
static void insertExpansionHighlightRange(
|
||||||
ArrayRef<SourceCoverageView::HighlightRange> Ranges,
|
ArrayRef<SourceCoverageView::HighlightRange> Ranges,
|
||||||
SourceCoverageView::HighlightRange RangeToInsert,
|
unsigned Line, unsigned StartCol, unsigned EndCol,
|
||||||
SmallVectorImpl<SourceCoverageView::HighlightRange> &Result) {
|
SmallVectorImpl<SourceCoverageView::HighlightRange> &Result) {
|
||||||
|
auto RangeToInsert = SourceCoverageView::HighlightRange(
|
||||||
|
Line, StartCol, EndCol, SourceCoverageView::HighlightRange::Expanded);
|
||||||
Result.clear();
|
Result.clear();
|
||||||
size_t I = 0;
|
size_t I = 0;
|
||||||
auto E = Ranges.size();
|
auto E = Ranges.size();
|
||||||
@ -189,22 +191,6 @@ static void insertHighlightRange(
|
|||||||
Result.push_back(Ranges[I]);
|
Result.push_back(Ranges[I]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SourceCoverageView::sortChildren() {
|
|
||||||
for (auto &I : Children)
|
|
||||||
I->sortChildren();
|
|
||||||
std::sort(Children.begin(), Children.end(),
|
|
||||||
[](const std::unique_ptr<SourceCoverageView> &LHS,
|
|
||||||
const std::unique_ptr<SourceCoverageView> &RHS) {
|
|
||||||
return LHS->ExpansionRegion < RHS->ExpansionRegion;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
SourceCoverageView::HighlightRange
|
|
||||||
SourceCoverageView::getExpansionHighlightRange() const {
|
|
||||||
return HighlightRange(ExpansionRegion.LineStart, ExpansionRegion.ColumnStart,
|
|
||||||
ExpansionRegion.ColumnEnd, HighlightRange::Expanded);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
ArrayRef<T> gatherLineItems(size_t &CurrentIdx, const std::vector<T> &Items,
|
ArrayRef<T> gatherLineItems(size_t &CurrentIdx, const std::vector<T> &Items,
|
||||||
unsigned LineNo) {
|
unsigned LineNo) {
|
||||||
@ -215,24 +201,8 @@ ArrayRef<T> gatherLineItems(size_t &CurrentIdx, const std::vector<T> &Items,
|
|||||||
return ArrayRef<T>(Items.data() + PrevIdx, CurrentIdx - PrevIdx);
|
return ArrayRef<T>(Items.data() + PrevIdx, CurrentIdx - PrevIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayRef<std::unique_ptr<SourceCoverageView>>
|
|
||||||
gatherLineSubViews(size_t &CurrentIdx,
|
|
||||||
ArrayRef<std::unique_ptr<SourceCoverageView>> Items,
|
|
||||||
unsigned LineNo) {
|
|
||||||
auto PrevIdx = CurrentIdx;
|
|
||||||
auto E = Items.size();
|
|
||||||
while (CurrentIdx < E &&
|
|
||||||
Items[CurrentIdx]->getSubViewsExpansionLine() == LineNo)
|
|
||||||
++CurrentIdx;
|
|
||||||
return Items.slice(PrevIdx, CurrentIdx - PrevIdx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SourceCoverageView::render(raw_ostream &OS, unsigned IndentLevel) {
|
void SourceCoverageView::render(raw_ostream &OS, unsigned IndentLevel) {
|
||||||
// Make sure that the children are in sorted order.
|
|
||||||
sortChildren();
|
|
||||||
|
|
||||||
SmallVector<HighlightRange, 8> AdjustedLineHighlightRanges;
|
SmallVector<HighlightRange, 8> AdjustedLineHighlightRanges;
|
||||||
size_t CurrentChild = 0;
|
|
||||||
size_t CurrentHighlightRange = 0;
|
size_t CurrentHighlightRange = 0;
|
||||||
size_t CurrentRegionMarker = 0;
|
size_t CurrentRegionMarker = 0;
|
||||||
|
|
||||||
@ -249,12 +219,18 @@ void SourceCoverageView::render(raw_ostream &OS, unsigned IndentLevel) {
|
|||||||
// subviews.
|
// subviews.
|
||||||
unsigned DividerWidth = CombinedColumnWidth + 4;
|
unsigned DividerWidth = CombinedColumnWidth + 4;
|
||||||
|
|
||||||
|
// We need the expansions and instantiations sorted so we can go through them
|
||||||
|
// while we iterate lines.
|
||||||
|
std::sort(ExpansionSubViews.begin(), ExpansionSubViews.end());
|
||||||
|
std::sort(InstantiationSubViews.begin(), InstantiationSubViews.end());
|
||||||
|
auto NextESV = ExpansionSubViews.begin();
|
||||||
|
auto EndESV = ExpansionSubViews.end();
|
||||||
|
auto NextISV = InstantiationSubViews.begin();
|
||||||
|
auto EndISV = InstantiationSubViews.end();
|
||||||
|
|
||||||
for (size_t I = 0, E = LineStats.size(); I < E; ++I) {
|
for (size_t I = 0, E = LineStats.size(); I < E; ++I) {
|
||||||
unsigned LineNo = I + LineOffset;
|
unsigned LineNo = I + LineOffset;
|
||||||
|
|
||||||
// Gather the child subviews that are visible on this line.
|
|
||||||
auto LineSubViews = gatherLineSubViews(CurrentChild, Children, LineNo);
|
|
||||||
|
|
||||||
renderIndent(OS, IndentLevel);
|
renderIndent(OS, IndentLevel);
|
||||||
if (Options.ShowLineStats)
|
if (Options.ShowLineStats)
|
||||||
renderLineCoverageColumn(OS, LineStats[I]);
|
renderLineCoverageColumn(OS, LineStats[I]);
|
||||||
@ -267,11 +243,10 @@ void SourceCoverageView::render(raw_ostream &OS, unsigned IndentLevel) {
|
|||||||
auto LineRanges = LineHighlightRanges;
|
auto LineRanges = LineHighlightRanges;
|
||||||
// Highlight the expansion range if there is an expansion subview on this
|
// Highlight the expansion range if there is an expansion subview on this
|
||||||
// line.
|
// line.
|
||||||
if (!LineSubViews.empty() && LineSubViews.front()->isExpansionSubView() &&
|
if (NextESV != EndESV && NextESV->getLine() == LineNo && Options.Colors) {
|
||||||
Options.Colors) {
|
insertExpansionHighlightRange(
|
||||||
insertHighlightRange(LineHighlightRanges,
|
LineHighlightRanges, NextESV->getLine(), NextESV->getStartCol(),
|
||||||
LineSubViews.front()->getExpansionHighlightRange(),
|
NextESV->getEndCol(), AdjustedLineHighlightRanges);
|
||||||
AdjustedLineHighlightRanges);
|
|
||||||
LineRanges = AdjustedLineHighlightRanges;
|
LineRanges = AdjustedLineHighlightRanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,40 +269,40 @@ void SourceCoverageView::render(raw_ostream &OS, unsigned IndentLevel) {
|
|||||||
renderRegionMarkers(OS, LineMarkers);
|
renderRegionMarkers(OS, LineMarkers);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show the line's expanded child subviews.
|
// Show the expansions and instantiations for this line.
|
||||||
bool FirstChildExpansion = true;
|
|
||||||
if (LineSubViews.empty())
|
|
||||||
continue;
|
|
||||||
unsigned NestedIndent = IndentLevel + 1;
|
unsigned NestedIndent = IndentLevel + 1;
|
||||||
renderViewDivider(NestedIndent, DividerWidth, OS);
|
bool RenderedSubView = false;
|
||||||
OS << "\n";
|
for (; NextESV != EndESV && NextESV->getLine() == LineNo; ++NextESV) {
|
||||||
for (const auto &Child : LineSubViews) {
|
renderViewDivider(NestedIndent, DividerWidth, OS);
|
||||||
// If this subview shows a function instantiation, render the function's
|
OS << "\n";
|
||||||
// name.
|
if (RenderedSubView) {
|
||||||
if (Child->isInstantiationSubView()) {
|
// Re-render the current line and highlight the expansion range for
|
||||||
renderIndent(OS, NestedIndent);
|
// this subview.
|
||||||
OS << ' ';
|
insertExpansionHighlightRange(
|
||||||
Options.colored_ostream(OS, raw_ostream::CYAN) << Child->FunctionName
|
LineHighlightRanges, NextESV->getLine(), NextESV->getStartCol(),
|
||||||
<< ":";
|
NextESV->getEndCol(), AdjustedLineHighlightRanges);
|
||||||
|
renderIndent(OS, IndentLevel);
|
||||||
|
OS.indent(CombinedColumnWidth + (IndentLevel == 0 ? 0 : 1));
|
||||||
|
renderLine(OS, Line, AdjustedLineHighlightRanges);
|
||||||
|
renderViewDivider(NestedIndent, DividerWidth, OS);
|
||||||
OS << "\n";
|
OS << "\n";
|
||||||
} else {
|
|
||||||
if (!FirstChildExpansion) {
|
|
||||||
// Re-render the current line and highlight the expansion range for
|
|
||||||
// this
|
|
||||||
// subview.
|
|
||||||
insertHighlightRange(LineHighlightRanges,
|
|
||||||
Child->getExpansionHighlightRange(),
|
|
||||||
AdjustedLineHighlightRanges);
|
|
||||||
renderIndent(OS, IndentLevel);
|
|
||||||
OS.indent(CombinedColumnWidth + (IndentLevel == 0 ? 0 : 1));
|
|
||||||
renderLine(OS, Line, AdjustedLineHighlightRanges);
|
|
||||||
renderViewDivider(NestedIndent, DividerWidth, OS);
|
|
||||||
OS << "\n";
|
|
||||||
} else
|
|
||||||
FirstChildExpansion = false;
|
|
||||||
}
|
}
|
||||||
// Render the child subview
|
// Render the child subview
|
||||||
Child->render(OS, NestedIndent);
|
NextESV->View->render(OS, NestedIndent);
|
||||||
|
RenderedSubView = true;
|
||||||
|
}
|
||||||
|
for (; NextISV != EndISV && NextISV->Line == LineNo; ++NextISV) {
|
||||||
|
renderViewDivider(NestedIndent, DividerWidth, OS);
|
||||||
|
OS << "\n";
|
||||||
|
renderIndent(OS, NestedIndent);
|
||||||
|
OS << ' ';
|
||||||
|
Options.colored_ostream(OS, raw_ostream::CYAN) << NextISV->FunctionName
|
||||||
|
<< ":";
|
||||||
|
OS << "\n";
|
||||||
|
NextISV->View->render(OS, NestedIndent);
|
||||||
|
RenderedSubView = true;
|
||||||
|
}
|
||||||
|
if (RenderedSubView) {
|
||||||
renderViewDivider(NestedIndent, DividerWidth, OS);
|
renderViewDivider(NestedIndent, DividerWidth, OS);
|
||||||
OS << "\n";
|
OS << "\n";
|
||||||
}
|
}
|
||||||
|
@ -22,12 +22,46 @@
|
|||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
|
class SourceCoverageView;
|
||||||
|
|
||||||
|
/// \brief A view that represents a macro or include expansion
|
||||||
|
struct ExpansionView {
|
||||||
|
coverage::CounterMappingRegion Region;
|
||||||
|
std::unique_ptr<SourceCoverageView> View;
|
||||||
|
|
||||||
|
ExpansionView(const coverage::CounterMappingRegion &Region,
|
||||||
|
std::unique_ptr<SourceCoverageView> View)
|
||||||
|
: Region(Region), View(std::move(View)) {}
|
||||||
|
|
||||||
|
unsigned getLine() const { return Region.LineStart; }
|
||||||
|
unsigned getStartCol() const { return Region.ColumnStart; }
|
||||||
|
unsigned getEndCol() const { return Region.ColumnEnd; }
|
||||||
|
|
||||||
|
friend bool operator<(const ExpansionView &LHS, const ExpansionView &RHS) {
|
||||||
|
return LHS.Region.startLoc() < RHS.Region.startLoc();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// \brief A view that represents a function instantiation
|
||||||
|
struct InstantiationView {
|
||||||
|
StringRef FunctionName;
|
||||||
|
unsigned Line;
|
||||||
|
std::unique_ptr<SourceCoverageView> View;
|
||||||
|
|
||||||
|
InstantiationView(StringRef FunctionName, unsigned Line,
|
||||||
|
std::unique_ptr<SourceCoverageView> View)
|
||||||
|
: FunctionName(FunctionName), Line(Line), View(std::move(View)) {}
|
||||||
|
|
||||||
|
friend bool operator<(const InstantiationView &LHS,
|
||||||
|
const InstantiationView &RHS) {
|
||||||
|
return LHS.Line < RHS.Line;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// \brief A code coverage view of a specific source file.
|
/// \brief A code coverage view of a specific source file.
|
||||||
/// It can have embedded coverage views.
|
/// It can have embedded coverage views.
|
||||||
class SourceCoverageView {
|
class SourceCoverageView {
|
||||||
public:
|
public:
|
||||||
enum SubViewKind { View, ExpansionView, InstantiationView };
|
|
||||||
|
|
||||||
/// \brief Coverage information for a single line.
|
/// \brief Coverage information for a single line.
|
||||||
struct LineCoverageInfo {
|
struct LineCoverageInfo {
|
||||||
uint64_t ExecutionCount;
|
uint64_t ExecutionCount;
|
||||||
@ -111,13 +145,11 @@ private:
|
|||||||
const MemoryBuffer &File;
|
const MemoryBuffer &File;
|
||||||
const CoverageViewOptions &Options;
|
const CoverageViewOptions &Options;
|
||||||
unsigned LineOffset;
|
unsigned LineOffset;
|
||||||
SubViewKind Kind;
|
std::vector<ExpansionView> ExpansionSubViews;
|
||||||
coverage::CounterMappingRegion ExpansionRegion;
|
std::vector<InstantiationView> InstantiationSubViews;
|
||||||
std::vector<std::unique_ptr<SourceCoverageView>> Children;
|
|
||||||
std::vector<LineCoverageInfo> LineStats;
|
std::vector<LineCoverageInfo> LineStats;
|
||||||
std::vector<HighlightRange> HighlightRanges;
|
std::vector<HighlightRange> HighlightRanges;
|
||||||
std::vector<RegionMarker> Markers;
|
std::vector<RegionMarker> Markers;
|
||||||
StringRef FunctionName;
|
|
||||||
|
|
||||||
/// \brief Initialize the visible source range for this view.
|
/// \brief Initialize the visible source range for this view.
|
||||||
void setUpVisibleRange(SourceCoverageDataManager &Data);
|
void setUpVisibleRange(SourceCoverageDataManager &Data);
|
||||||
@ -131,12 +163,6 @@ private:
|
|||||||
/// \brief Create the region markers using the coverage data.
|
/// \brief Create the region markers using the coverage data.
|
||||||
void createRegionMarkers(SourceCoverageDataManager &Data);
|
void createRegionMarkers(SourceCoverageDataManager &Data);
|
||||||
|
|
||||||
/// \brief Sort children by the starting location.
|
|
||||||
void sortChildren();
|
|
||||||
|
|
||||||
/// \brief Return a highlight range for the expansion region of this view.
|
|
||||||
HighlightRange getExpansionHighlightRange() const;
|
|
||||||
|
|
||||||
/// \brief Render a source line with highlighting.
|
/// \brief Render a source line with highlighting.
|
||||||
void renderLine(raw_ostream &OS, StringRef Line,
|
void renderLine(raw_ostream &OS, StringRef Line,
|
||||||
ArrayRef<HighlightRange> Ranges);
|
ArrayRef<HighlightRange> Ranges);
|
||||||
@ -160,34 +186,20 @@ private:
|
|||||||
public:
|
public:
|
||||||
SourceCoverageView(const MemoryBuffer &File,
|
SourceCoverageView(const MemoryBuffer &File,
|
||||||
const CoverageViewOptions &Options)
|
const CoverageViewOptions &Options)
|
||||||
: File(File), Options(Options), LineOffset(0), Kind(View),
|
: File(File), Options(Options), LineOffset(0) {}
|
||||||
ExpansionRegion(coverage::Counter(), 0, 0, 0, 0, 0) {}
|
|
||||||
|
|
||||||
SourceCoverageView(SourceCoverageView &Parent, StringRef FunctionName)
|
|
||||||
: File(Parent.File), Options(Parent.Options), LineOffset(0),
|
|
||||||
Kind(InstantiationView),
|
|
||||||
ExpansionRegion(coverage::Counter(), 0, 0, 0, 0, 0),
|
|
||||||
FunctionName(FunctionName) {}
|
|
||||||
|
|
||||||
SourceCoverageView(const MemoryBuffer &File,
|
|
||||||
const CoverageViewOptions &Options,
|
|
||||||
const coverage::CounterMappingRegion &ExpansionRegion)
|
|
||||||
: File(File), Options(Options), LineOffset(0), Kind(ExpansionView),
|
|
||||||
ExpansionRegion(ExpansionRegion) {}
|
|
||||||
|
|
||||||
const CoverageViewOptions &getOptions() const { return Options; }
|
const CoverageViewOptions &getOptions() const { return Options; }
|
||||||
|
|
||||||
bool isExpansionSubView() const { return Kind == ExpansionView; }
|
/// \brief Add an expansion subview to this view.
|
||||||
|
void addExpansion(const coverage::CounterMappingRegion &Region,
|
||||||
bool isInstantiationSubView() const { return Kind == InstantiationView; }
|
std::unique_ptr<SourceCoverageView> View) {
|
||||||
|
ExpansionSubViews.emplace_back(Region, std::move(View));
|
||||||
/// \brief Return the line number after which the subview expansion is shown.
|
|
||||||
unsigned getSubViewsExpansionLine() const {
|
|
||||||
return ExpansionRegion.LineStart;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void addChild(std::unique_ptr<SourceCoverageView> View) {
|
/// \brief Add a function instantiation subview to this view.
|
||||||
Children.push_back(std::move(View));
|
void addInstantiation(StringRef FunctionName, unsigned Line,
|
||||||
|
std::unique_ptr<SourceCoverageView> View) {
|
||||||
|
InstantiationSubViews.emplace_back(FunctionName, Line, std::move(View));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Print the code coverage information for a specific
|
/// \brief Print the code coverage information for a specific
|
||||||
|
Reference in New Issue
Block a user