[llvm] r217940 - llvm-cov: Distinguish expansion/instantiation from SourceCoverageView

Justin Bogner mail at justinbogner.com
Tue Sep 16 22:33:20 PDT 2014


Author: bogner
Date: Wed Sep 17 00:33:20 2014
New Revision: 217940

URL: http://llvm.org/viewvc/llvm-project?rev=217940&view=rev
Log:
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.

Modified:
    llvm/trunk/tools/llvm-cov/CodeCoverage.cpp
    llvm/trunk/tools/llvm-cov/SourceCoverageView.cpp
    llvm/trunk/tools/llvm-cov/SourceCoverageView.h

Modified: llvm/trunk/tools/llvm-cov/CodeCoverage.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/CodeCoverage.cpp?rev=217940&r1=217939&r2=217940&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cov/CodeCoverage.cpp (original)
+++ llvm/trunk/tools/llvm-cov/CodeCoverage.cpp Wed Sep 17 00:33:20 2014
@@ -282,8 +282,8 @@ void CodeCoverageTool::createExpansionSu
       getSourceFile(Function.Filenames[ExpandedRegion.ExpandedFileID]);
   if (!SourceBuffer)
     return;
-  auto SubView = llvm::make_unique<SourceCoverageView>(
-      SourceBuffer.get(), Parent.getOptions(), ExpandedRegion);
+  auto SubView = llvm::make_unique<SourceCoverageView>(SourceBuffer.get(),
+                                                       Parent.getOptions());
   SourceCoverageDataManager RegionManager;
   for (const auto &CR : Function.CountedRegions) {
     if (CR.FileID == ExpandedRegion.ExpandedFileID)
@@ -291,7 +291,7 @@ void CodeCoverageTool::createExpansionSu
   }
   SubView->load(RegionManager);
   createExpansionSubViews(*SubView, ExpandedRegion.ExpandedFileID, Function);
-  Parent.addChild(std::move(SubView));
+  Parent.addExpansion(ExpandedRegion, std::move(SubView));
 }
 
 void CodeCoverageTool::createExpansionSubViews(
@@ -362,10 +362,18 @@ bool CodeCoverageTool::createSourceFileV
     if (InstantiationSet.second.size() < 2)
       continue;
     for (auto Function : InstantiationSet.second) {
-      auto SubView =
-          llvm::make_unique<SourceCoverageView>(View, Function->Name);
+      unsigned FileID = Function->CountedRegions.front().FileID;
+      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);
-      View.addChild(std::move(SubView));
+      View.addInstantiation(Function->Name, Line, std::move(SubView));
     }
   }
   return false;

Modified: llvm/trunk/tools/llvm-cov/SourceCoverageView.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/SourceCoverageView.cpp?rev=217940&r1=217939&r2=217940&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cov/SourceCoverageView.cpp (original)
+++ llvm/trunk/tools/llvm-cov/SourceCoverageView.cpp Wed Sep 17 00:33:20 2014
@@ -140,10 +140,12 @@ void SourceCoverageView::renderRegionMar
 
 /// \brief Insert a new highlighting range into the line's highlighting ranges
 /// Return line's new highlighting ranges in result.
-static void insertHighlightRange(
+static void insertExpansionHighlightRange(
     ArrayRef<SourceCoverageView::HighlightRange> Ranges,
-    SourceCoverageView::HighlightRange RangeToInsert,
+    unsigned Line, unsigned StartCol, unsigned EndCol,
     SmallVectorImpl<SourceCoverageView::HighlightRange> &Result) {
+  auto RangeToInsert = SourceCoverageView::HighlightRange(
+      Line, StartCol, EndCol, SourceCoverageView::HighlightRange::Expanded);
   Result.clear();
   size_t I = 0;
   auto E = Ranges.size();
@@ -189,22 +191,6 @@ static void insertHighlightRange(
     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>
 ArrayRef<T> gatherLineItems(size_t &CurrentIdx, const std::vector<T> &Items,
                             unsigned LineNo) {
@@ -215,24 +201,8 @@ ArrayRef<T> gatherLineItems(size_t &Curr
   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) {
-  // Make sure that the children are in sorted order.
-  sortChildren();
-
   SmallVector<HighlightRange, 8> AdjustedLineHighlightRanges;
-  size_t CurrentChild = 0;
   size_t CurrentHighlightRange = 0;
   size_t CurrentRegionMarker = 0;
 
@@ -249,12 +219,18 @@ void SourceCoverageView::render(raw_ostr
   // subviews.
   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) {
     unsigned LineNo = I + LineOffset;
 
-    // Gather the child subviews that are visible on this line.
-    auto LineSubViews = gatherLineSubViews(CurrentChild, Children, LineNo);
-
     renderIndent(OS, IndentLevel);
     if (Options.ShowLineStats)
       renderLineCoverageColumn(OS, LineStats[I]);
@@ -267,11 +243,10 @@ void SourceCoverageView::render(raw_ostr
     auto LineRanges = LineHighlightRanges;
     // Highlight the expansion range if there is an expansion subview on this
     // line.
-    if (!LineSubViews.empty() && LineSubViews.front()->isExpansionSubView() &&
-        Options.Colors) {
-      insertHighlightRange(LineHighlightRanges,
-                           LineSubViews.front()->getExpansionHighlightRange(),
-                           AdjustedLineHighlightRanges);
+    if (NextESV != EndESV && NextESV->getLine() == LineNo && Options.Colors) {
+      insertExpansionHighlightRange(
+          LineHighlightRanges, NextESV->getLine(), NextESV->getStartCol(),
+          NextESV->getEndCol(), AdjustedLineHighlightRanges);
       LineRanges = AdjustedLineHighlightRanges;
     }
 
@@ -294,40 +269,40 @@ void SourceCoverageView::render(raw_ostr
       renderRegionMarkers(OS, LineMarkers);
     }
 
-    // Show the line's expanded child subviews.
-    bool FirstChildExpansion = true;
-    if (LineSubViews.empty())
-      continue;
+    // Show the expansions and instantiations for this line.
     unsigned NestedIndent = IndentLevel + 1;
-    renderViewDivider(NestedIndent, DividerWidth, OS);
-    OS << "\n";
-    for (const auto &Child : LineSubViews) {
-      // If this subview shows a function instantiation, render the function's
-      // name.
-      if (Child->isInstantiationSubView()) {
-        renderIndent(OS, NestedIndent);
-        OS << ' ';
-        Options.colored_ostream(OS, raw_ostream::CYAN) << Child->FunctionName
-                                                       << ":";
+    bool RenderedSubView = false;
+    for (; NextESV != EndESV && NextESV->getLine() == LineNo; ++NextESV) {
+      renderViewDivider(NestedIndent, DividerWidth, OS);
+      OS << "\n";
+      if (RenderedSubView) {
+        // Re-render the current line and highlight the expansion range for
+        // this subview.
+        insertExpansionHighlightRange(
+            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";
-      } 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
-      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);
       OS << "\n";
     }

Modified: llvm/trunk/tools/llvm-cov/SourceCoverageView.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/SourceCoverageView.h?rev=217940&r1=217939&r2=217940&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cov/SourceCoverageView.h (original)
+++ llvm/trunk/tools/llvm-cov/SourceCoverageView.h Wed Sep 17 00:33:20 2014
@@ -22,12 +22,46 @@
 
 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.
 /// It can have embedded coverage views.
 class SourceCoverageView {
 public:
-  enum SubViewKind { View, ExpansionView, InstantiationView };
-
   /// \brief Coverage information for a single line.
   struct LineCoverageInfo {
     uint64_t ExecutionCount;
@@ -111,13 +145,11 @@ private:
   const MemoryBuffer &File;
   const CoverageViewOptions &Options;
   unsigned LineOffset;
-  SubViewKind Kind;
-  coverage::CounterMappingRegion ExpansionRegion;
-  std::vector<std::unique_ptr<SourceCoverageView>> Children;
+  std::vector<ExpansionView> ExpansionSubViews;
+  std::vector<InstantiationView> InstantiationSubViews;
   std::vector<LineCoverageInfo> LineStats;
   std::vector<HighlightRange> HighlightRanges;
   std::vector<RegionMarker> Markers;
-  StringRef FunctionName;
 
   /// \brief Initialize the visible source range for this view.
   void setUpVisibleRange(SourceCoverageDataManager &Data);
@@ -131,12 +163,6 @@ private:
   /// \brief Create the region markers using the coverage 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.
   void renderLine(raw_ostream &OS, StringRef Line,
                   ArrayRef<HighlightRange> Ranges);
@@ -160,34 +186,20 @@ private:
 public:
   SourceCoverageView(const MemoryBuffer &File,
                      const CoverageViewOptions &Options)
-      : File(File), Options(Options), LineOffset(0), Kind(View),
-        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) {}
+      : File(File), Options(Options), LineOffset(0) {}
 
   const CoverageViewOptions &getOptions() const { return Options; }
 
-  bool isExpansionSubView() const { return Kind == ExpansionView; }
-
-  bool isInstantiationSubView() const { return Kind == InstantiationView; }
-
-  /// \brief Return the line number after which the subview expansion is shown.
-  unsigned getSubViewsExpansionLine() const {
-    return ExpansionRegion.LineStart;
+  /// \brief Add an expansion subview to this view.
+  void addExpansion(const coverage::CounterMappingRegion &Region,
+                    std::unique_ptr<SourceCoverageView> View) {
+    ExpansionSubViews.emplace_back(Region, std::move(View));
   }
 
-  void addChild(std::unique_ptr<SourceCoverageView> View) {
-    Children.push_back(std::move(View));
+  /// \brief Add a function instantiation subview to this 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





More information about the llvm-commits mailing list