Change PathDiagnosticPieces to be reference counted (simplifying their management), and introduce 'PathPieces' as a common container for PathDiagnosticPieces.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150054 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
index 08b48e5..c1b120b 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
@@ -16,6 +16,7 @@
 
 #include "clang/Basic/SourceLocation.h"
 #include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/ADT/PointerUnion.h"
 #include <deque>
 #include <iterator>
@@ -44,12 +45,6 @@
 //===----------------------------------------------------------------------===//
 
 class PathDiagnostic;
-class PathDiagnosticPiece;
-
-class PathPieces : public std::deque<PathDiagnosticPiece *> {
-public:
-  ~PathPieces();  
-};
 
 class PathDiagnosticConsumer {
   virtual void anchor();
@@ -265,7 +260,7 @@
 // Path "pieces" for path-sensitive diagnostics.
 //===----------------------------------------------------------------------===//
 
-class PathDiagnosticPiece {
+class PathDiagnosticPiece : public llvm::RefCountedBaseVPTR {
 public:
   enum Kind { ControlFlow, Event, Macro, CallEnter, CallExit };
   enum DisplayHint { Above, Below };
@@ -328,6 +323,13 @@
   
   virtual void Profile(llvm::FoldingSetNodeID &ID) const;
 };
+  
+  
+class PathPieces :
+  public std::deque<llvm::IntrusiveRefCntPtr<PathDiagnosticPiece> > {
+public:
+  ~PathPieces();  
+};
 
 class PathDiagnosticSpotPiece : public PathDiagnosticPiece {
 private:
@@ -446,30 +448,22 @@
 };
 
 class PathDiagnosticMacroPiece : public PathDiagnosticSpotPiece {
-  std::vector<PathDiagnosticPiece*> SubPieces;
 public:
   PathDiagnosticMacroPiece(const PathDiagnosticLocation &pos)
     : PathDiagnosticSpotPiece(pos, "", Macro) {}
 
   ~PathDiagnosticMacroPiece();
 
+  PathPieces subPieces;
+  
   bool containsEvent() const;
 
-  void push_back(PathDiagnosticPiece *P) { SubPieces.push_back(P); }
-
-  typedef std::vector<PathDiagnosticPiece*>::iterator iterator;
-  iterator begin() { return SubPieces.begin(); }
-  iterator end() { return SubPieces.end(); }
-
   virtual void flattenLocations() {
     PathDiagnosticSpotPiece::flattenLocations();
-    for (iterator I=begin(), E=end(); I!=E; ++I) (*I)->flattenLocations();
+    for (PathPieces::iterator I = subPieces.begin(), 
+         E = subPieces.end(); I != E; ++I) (*I)->flattenLocations();
   }
 
-  typedef std::vector<PathDiagnosticPiece*>::const_iterator const_iterator;
-  const_iterator begin() const { return SubPieces.begin(); }
-  const_iterator end() const { return SubPieces.end(); }
-
   static inline bool classof(const PathDiagnosticPiece *P) {
     return P->getKind() == Macro;
   }
@@ -481,16 +475,14 @@
 ///  diagnostic.  It represents an ordered-collection of PathDiagnosticPieces,
 ///  each which represent the pieces of the path.
 class PathDiagnostic : public llvm::FoldingSetNode {
-  PathPieces path;
-  unsigned Size;
   std::string BugType;
   std::string Desc;
   std::string Category;
   std::deque<std::string> OtherDesc;
-
 public:
-  PathDiagnostic();
+  PathPieces path;
 
+  PathDiagnostic();
   PathDiagnostic(StringRef bugtype, StringRef desc,
                  StringRef category);
 
@@ -499,6 +491,7 @@
   StringRef getDescription() const { return Desc; }
   StringRef getBugType() const { return BugType; }
   StringRef getCategory() const { return Category; }
+  
 
   typedef std::deque<std::string>::const_iterator meta_iterator;
   meta_iterator meta_begin() const { return OtherDesc.begin(); }
@@ -506,106 +499,14 @@
   void addMeta(StringRef s) { OtherDesc.push_back(s); }
 
   PathDiagnosticLocation getLocation() const {
-    assert(Size > 0 && "getLocation() requires a non-empty PathDiagnostic.");
-    return rbegin()->getLocation();
+    assert(path.size() > 0 &&
+           "getLocation() requires a non-empty PathDiagnostic.");
+    return (*path.rbegin())->getLocation();
   }
 
-  void push_front(PathDiagnosticPiece *piece) {
-    assert(piece);
-    path.push_front(piece);
-    ++Size;
-  }
-
-  void push_back(PathDiagnosticPiece *piece) {
-    assert(piece);
-    path.push_back(piece);
-    ++Size;
-  }
-
-  PathDiagnosticPiece *back() {
-    return path.back();
-  }
-
-  const PathDiagnosticPiece *back() const {
-    return path.back();
-  }
-
-  unsigned size() const { return Size; }
-  bool empty() const { return Size == 0; }
-
-  void resetPath(bool deletePieces = true);
-
-  class iterator {
-  public:
-    typedef std::deque<PathDiagnosticPiece*>::iterator ImplTy;
-
-    typedef PathDiagnosticPiece              value_type;
-    typedef value_type&                      reference;
-    typedef value_type*                      pointer;
-    typedef ptrdiff_t                        difference_type;
-    typedef std::bidirectional_iterator_tag  iterator_category;
-
-  private:
-    ImplTy I;
-
-  public:
-    iterator(const ImplTy& i) : I(i) {}
-
-    bool operator==(const iterator &X) const { return I == X.I; }
-    bool operator!=(const iterator &X) const { return I != X.I; }
-
-    PathDiagnosticPiece& operator*() const { return **I; }
-    PathDiagnosticPiece *operator->() const { return *I; }
-
-    iterator &operator++() { ++I; return *this; }
-    iterator &operator--() { --I; return *this; }
-  };
-
-  class const_iterator {
-  public:
-    typedef std::deque<PathDiagnosticPiece*>::const_iterator ImplTy;
-
-    typedef const PathDiagnosticPiece        value_type;
-    typedef value_type&                      reference;
-    typedef value_type*                      pointer;
-    typedef ptrdiff_t                        difference_type;
-    typedef std::bidirectional_iterator_tag  iterator_category;
-
-  private:
-    ImplTy I;
-
-  public:
-    const_iterator(const ImplTy& i) : I(i) {}
-
-    bool operator==(const const_iterator &X) const { return I == X.I; }
-    bool operator!=(const const_iterator &X) const { return I != X.I; }
-
-    reference operator*() const { return **I; }
-    pointer operator->() const { return *I; }
-
-    const_iterator &operator++() { ++I; return *this; }
-    const_iterator &operator--() { --I; return *this; }
-  };
-
-  typedef std::reverse_iterator<iterator>       reverse_iterator;
-  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
-
-  // forward iterator creation methods.
-
-  iterator begin() { return path.begin(); }
-  iterator end() { return path.end(); }
-
-  const_iterator begin() const { return path.begin(); }
-  const_iterator end() const { return path.end(); }
-
-  // reverse iterator creation methods.
-  reverse_iterator rbegin()            { return reverse_iterator(end()); }
-  const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
-  reverse_iterator rend()              { return reverse_iterator(begin()); }
-  const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
-
   void flattenLocations() {
-    for (iterator I = begin(), E = end(); I != E; ++I) I->flattenLocations();
+    for (PathPieces::iterator I = path.begin(), E = path.end(); 
+         I != E; ++I) (*I)->flattenLocations();
   }
   
   void Profile(llvm::FoldingSetNodeID &ID) const;
diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp
index 8e5ea36..9399acf 100644
--- a/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -29,6 +29,7 @@
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include <queue>
 
 using namespace clang;
@@ -446,7 +447,7 @@
       PathDiagnosticLocation L =
         PathDiagnosticLocation::createBegin(S, BR.getSourceManager(),
                                                    Pred->getLocationContext());
-      PD.push_front(new PathDiagnosticEventPiece(L, os.str()));
+      PD.path.push_front(new PathDiagnosticEventPiece(L, os.str()));
     }
 
     return true;
@@ -558,8 +559,8 @@
 
           os << "Control jumps to line "
           << End.asLocation().getExpansionLineNumber();
-          PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
-                                                           os.str()));
+          PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+                                                                os.str()));
           break;
         }
 
@@ -610,13 +611,13 @@
                 break;
               }
             }
-            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+            PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
                                                              os.str()));
           }
           else {
             os << "'Default' branch taken. ";
             const PathDiagnosticLocation &End = PDB.ExecutionContinues(os, N);
-            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+            PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
                                                              os.str()));
           }
 
@@ -628,7 +629,7 @@
           std::string sbuf;
           llvm::raw_string_ostream os(sbuf);
           PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
-          PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+          PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
                                                            os.str()));
           break;
         }
@@ -650,7 +651,7 @@
           if (const Stmt *S = End.asStmt())
             End = PDB.getEnclosingStmtLocation(S);
 
-          PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+          PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
                                                            os.str()));
           break;
         }
@@ -673,14 +674,14 @@
               PathDiagnosticLocation End(B->getLHS(), SMgr, LC);
               PathDiagnosticLocation Start =
                 PathDiagnosticLocation::createOperatorLoc(B, SMgr);
-              PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+              PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
                                                                os.str()));
             }
             else {
               os << "true";
               PathDiagnosticLocation Start(B->getLHS(), SMgr, LC);
               PathDiagnosticLocation End = PDB.ExecutionContinues(N);
-              PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+              PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
                                                                os.str()));
             }
           }
@@ -692,7 +693,7 @@
               os << "false";
               PathDiagnosticLocation Start(B->getLHS(), SMgr, LC);
               PathDiagnosticLocation End = PDB.ExecutionContinues(N);
-              PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+              PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
                                                                os.str()));
             }
             else {
@@ -700,7 +701,7 @@
               PathDiagnosticLocation End(B->getLHS(), SMgr, LC);
               PathDiagnosticLocation Start =
                 PathDiagnosticLocation::createOperatorLoc(B, SMgr);
-              PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+              PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
                                                                os.str()));
             }
           }
@@ -719,7 +720,7 @@
             if (const Stmt *S = End.asStmt())
               End = PDB.getEnclosingStmtLocation(S);
 
-            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+            PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
                                                              os.str()));
           }
           else {
@@ -728,7 +729,7 @@
             if (const Stmt *S = End.asStmt())
               End = PDB.getEnclosingStmtLocation(S);
 
-            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+            PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
                               "Loop condition is false.  Exiting loop"));
           }
 
@@ -746,7 +747,7 @@
             if (const Stmt *S = End.asStmt())
               End = PDB.getEnclosingStmtLocation(S);
 
-            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+            PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
                                                              os.str()));
           }
           else {
@@ -754,7 +755,7 @@
             if (const Stmt *S = End.asStmt())
               End = PDB.getEnclosingStmtLocation(S);
 
-            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+            PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
                             "Loop condition is true.  Entering loop body"));
           }
 
@@ -768,10 +769,10 @@
             End = PDB.getEnclosingStmtLocation(S);
 
           if (*(Src->succ_begin()+1) == Dst)
-            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+            PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
                                                         "Taking false branch"));
           else
-            PD.push_front(new PathDiagnosticControlFlowPiece(Start, End,
+            PD.path.push_front(new PathDiagnosticControlFlowPiece(Start, End,
                                                          "Taking true branch"));
 
           break;
@@ -785,7 +786,7 @@
       for (BugReport::visitor_iterator I = R->visitor_begin(),
            E = R->visitor_end(); I!=E; ++I) {
         if (PathDiagnosticPiece *p = (*I)->VisitNode(N, NextNode, PDB, *R))
-          PD.push_front(p);
+          PD.path.push_front(p);
       }
     }
 
@@ -906,8 +907,8 @@
 
       // If the PathDiagnostic already has pieces, add the enclosing statement
       // of the first piece as a context as well.
-      if (!PD.empty()) {
-        PrevLoc = PD.begin()->getLocation();
+      if (!PD.path.empty()) {
+        PrevLoc = (*PD.path.begin())->getLocation();
 
         if (const Stmt *S = PrevLoc.asStmt())
           addExtendedContext(PDB.getEnclosingStmtLocation(S).asStmt());
@@ -1018,7 +1019,7 @@
       PrevLocClean.asLocation().getExpansionLoc())
     return;
 
-  PD.push_front(new PathDiagnosticControlFlowPiece(NewLocClean, PrevLocClean));
+  PD.path.push_front(new PathDiagnosticControlFlowPiece(NewLocClean, PrevLocClean));
   PrevLoc = NewLoc;
 }
 
@@ -1178,7 +1179,7 @@
                                         "Looping back to the head of the loop");
 
           EB.addEdge(p->getLocation(), true);
-          PD.push_front(p);
+          PD.path.push_front(p);
 
           if (CS) {
             PathDiagnosticLocation BL =
@@ -1220,7 +1221,7 @@
       if (PathDiagnosticPiece *p = (*I)->VisitNode(N, NextNode, PDB, *R)) {
         const PathDiagnosticLocation &Loc = p->getLocation();
         EB.addEdge(Loc, true);
-        PD.push_front(p);
+        PD.path.push_front(p);
         if (const Stmt *S = Loc.asStmt())
           EB.addExtendedContext(PDB.getEnclosingStmtLocation(S).asStmt());
       }
@@ -1549,18 +1550,18 @@
 /// CompactPathDiagnostic - This function postprocesses a PathDiagnostic object
 ///  and collapses PathDiagosticPieces that are expanded by macros.
 static void CompactPathDiagnostic(PathDiagnostic &PD, const SourceManager& SM) {
-  typedef std::vector<std::pair<PathDiagnosticMacroPiece*, SourceLocation> >
+  typedef std::vector<std::pair<llvm::IntrusiveRefCntPtr<PathDiagnosticMacroPiece>, SourceLocation> >
           MacroStackTy;
 
-  typedef std::vector<PathDiagnosticPiece*>
+  typedef std::vector<llvm::IntrusiveRefCntPtr<PathDiagnosticPiece> >
           PiecesTy;
 
   MacroStackTy MacroStack;
   PiecesTy Pieces;
 
-  for (PathDiagnostic::iterator I = PD.begin(), E = PD.end(); I!=E; ++I) {
+  for (PathPieces::iterator I = PD.path.begin(), E = PD.path.end(); I!=E; ++I) {
     // Get the location of the PathDiagnosticPiece.
-    const FullSourceLoc Loc = I->getLocation().asLocation();
+    const FullSourceLoc Loc = (*I)->getLocation().asLocation();
 
     // Determine the instantiation location, which is the location we group
     // related PathDiagnosticPieces.
@@ -1570,7 +1571,7 @@
 
     if (Loc.isFileID()) {
       MacroStack.clear();
-      Pieces.push_back(&*I);
+      Pieces.push_back(*I);
       continue;
     }
 
@@ -1578,13 +1579,13 @@
 
     // Is the PathDiagnosticPiece within the same macro group?
     if (!MacroStack.empty() && InstantiationLoc == MacroStack.back().second) {
-      MacroStack.back().first->push_back(&*I);
+      MacroStack.back().first->subPieces.push_back(*I);
       continue;
     }
 
     // We aren't in the same group.  Are we descending into a new macro
     // or are part of an old one?
-    PathDiagnosticMacroPiece *MacroGroup = 0;
+    llvm::IntrusiveRefCntPtr<PathDiagnosticMacroPiece> MacroGroup;
 
     SourceLocation ParentInstantiationLoc = InstantiationLoc.isMacroID() ?
                                           SM.getExpansionLoc(Loc) :
@@ -1609,10 +1610,10 @@
       // Create a new macro group and add it to the stack.
       PathDiagnosticMacroPiece *NewGroup =
         new PathDiagnosticMacroPiece(
-          PathDiagnosticLocation::createSingleLocation(I->getLocation()));
+          PathDiagnosticLocation::createSingleLocation((*I)->getLocation()));
 
       if (MacroGroup)
-        MacroGroup->push_back(NewGroup);
+        MacroGroup->subPieces.push_back(NewGroup);
       else {
         assert(InstantiationLoc.isFileID());
         Pieces.push_back(NewGroup);
@@ -1623,11 +1624,11 @@
     }
 
     // Finally, add the PathDiagnosticPiece to the group.
-    MacroGroup->push_back(&*I);
+    MacroGroup->subPieces.push_back(*I);
   }
 
   // Now take the pieces and construct a new PathDiagnostic.
-  PD.resetPath(false);
+  PD.path.clear();
 
   for (PiecesTy::iterator I=Pieces.begin(), E=Pieces.end(); I!=E; ++I) {
     if (PathDiagnosticMacroPiece *MP=dyn_cast<PathDiagnosticMacroPiece>(*I))
@@ -1636,7 +1637,7 @@
         continue;
       }
 
-    PD.push_back(*I);
+    PD.path.push_back(*I);
   }
 }
 
@@ -1692,7 +1693,7 @@
   if (!LastPiece)
     LastPiece = BugReporterVisitor::getDefaultEndPath(PDB, N, *R);
   if (LastPiece)
-    PD.push_back(LastPiece);
+    PD.path.push_back(LastPiece);
   else
     return;
 
@@ -1951,13 +1952,13 @@
   if (!PD)
     return;
 
-  if (D->empty()) {
+  if (D->path.empty()) {
     PathDiagnosticPiece *piece = new PathDiagnosticEventPiece(
                                  exampleReport->getLocation(getSourceManager()),
                                  exampleReport->getDescription());
 
     for ( ; Beg != End; ++Beg) piece->addRange(*Beg);
-    D->push_back(piece);
+    D->path.push_back(piece);
   }
 
   PD->HandlePathDiagnostic(D.take());
diff --git a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
index 2b3dcdc..e39d32d 100644
--- a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
@@ -119,12 +119,13 @@
   if (noDir)
     return;
 
-  const SourceManager &SMgr = D.begin()->getLocation().getManager();
+  const SourceManager &SMgr = (*D.path.begin())->getLocation().getManager();
   FileID FID;
 
   // Verify that the entire path is from the same FileID.
-  for (PathDiagnostic::const_iterator I = D.begin(), E = D.end(); I != E; ++I) {
-    FullSourceLoc L = I->getLocation().asLocation().getExpansionLoc();
+  for (PathPieces::const_iterator I = D.path.begin(), E = D.path.end();
+       I != E; ++I) {
+    FullSourceLoc L = (*I)->getLocation().asLocation().getExpansionLoc();
 
     if (FID.isInvalid()) {
       FID = SMgr.getFileID(L);
@@ -132,16 +133,13 @@
       return; // FIXME: Emit a warning?
 
     // Check the source ranges.
-    for (PathDiagnosticPiece::range_iterator RI=I->ranges_begin(),
-                                             RE=I->ranges_end(); RI!=RE; ++RI) {
-
+    for (PathDiagnosticPiece::range_iterator RI = (*I)->ranges_begin(),
+                                             RE = (*I)->ranges_end();
+                                             RI != RE; ++RI) {
       SourceLocation L = SMgr.getExpansionLoc(RI->getBegin());
-
       if (!L.isFileID() || SMgr.getFileID(L) != FID)
         return; // FIXME: Emit a warning?
-
       L = SMgr.getExpansionLoc(RI->getEnd());
-
       if (!L.isFileID() || SMgr.getFileID(L) != FID)
         return; // FIXME: Emit a warning?
     }
@@ -154,12 +152,12 @@
   Rewriter R(const_cast<SourceManager&>(SMgr), PP.getLangOptions());
 
   // Process the path.
-  unsigned n = D.size();
+  unsigned n = D.path.size();
   unsigned max = n;
 
-  for (PathDiagnostic::const_reverse_iterator I=D.rbegin(), E=D.rend();
-        I!=E; ++I, --n)
-    HandlePiece(R, FID, *I, n, max);
+  for (PathPieces::const_reverse_iterator I = D.path.rbegin(), E=D.path.rend();
+        I != E; ++I, --n)
+    HandlePiece(R, FID, **I, n, max);
 
   // Add line numbers, header, footer, etc.
 
@@ -202,9 +200,9 @@
       << html::EscapeText(Entry->getName())
       << "</td></tr>\n<tr><td class=\"rowname\">Location:</td><td>"
          "<a href=\"#EndPath\">line "
-      << (*D.rbegin()).getLocation().asLocation().getExpansionLineNumber()
+      << (*D.path.rbegin())->getLocation().asLocation().getExpansionLineNumber()
       << ", column "
-      << (*D.rbegin()).getLocation().asLocation().getExpansionColumnNumber()
+      << (*D.path.rbegin())->getLocation().asLocation().getExpansionColumnNumber()
       << "</a></td></tr>\n"
          "<tr><td class=\"rowname\">Description:</td><td>"
       << D.getDescription() << "</td></tr>\n";
@@ -242,10 +240,10 @@
     os << "\n<!-- BUGFILE " << DirName << Entry->getName() << " -->\n";
 
     os << "\n<!-- BUGLINE "
-       << D.back()->getLocation().asLocation().getExpansionLineNumber()
+       << D.path.back()->getLocation().asLocation().getExpansionLineNumber()
        << " -->\n";
 
-    os << "\n<!-- BUGPATHLENGTH " << D.size() << " -->\n";
+    os << "\n<!-- BUGPATHLENGTH " << D.path.size() << " -->\n";
 
     // Mark the end of the tags.
     os << "\n<!-- BUGMETAEND -->\n";
@@ -501,7 +499,7 @@
                                             const PathDiagnosticMacroPiece& P,
                                             unsigned num) {
 
-  for (PathDiagnosticMacroPiece::const_iterator I=P.begin(), E=P.end();
+  for (PathPieces::const_iterator I = P.subPieces.begin(), E=P.subPieces.end();
         I!=E; ++I) {
 
     if (const PathDiagnosticMacroPiece *MP =
diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
index bdf2e16..5ded6bc 100644
--- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -24,15 +24,14 @@
 using namespace ento;
 
 bool PathDiagnosticMacroPiece::containsEvent() const {
-  for (const_iterator I = begin(), E = end(); I!=E; ++I) {
+  for (PathPieces::const_iterator I = subPieces.begin(), E = subPieces.end();
+       I!=E; ++I) {
     if (isa<PathDiagnosticEventPiece>(*I))
       return true;
-
     if (PathDiagnosticMacroPiece *MP = dyn_cast<PathDiagnosticMacroPiece>(*I))
       if (MP->containsEvent())
         return true;
   }
-
   return false;
 }
 
@@ -55,34 +54,14 @@
 PathDiagnosticCallEnterPiece::~PathDiagnosticCallEnterPiece() {}
 PathDiagnosticCallExitPiece::~PathDiagnosticCallExitPiece() {}
 PathDiagnosticControlFlowPiece::~PathDiagnosticControlFlowPiece() {}
-
-PathDiagnosticMacroPiece::~PathDiagnosticMacroPiece() {
-  for (iterator I = begin(), E = end(); I != E; ++I) delete *I;
-}
-
-PathDiagnostic::PathDiagnostic() : Size(0) {}
-
-PathPieces::~PathPieces() {
-  for (iterator I = begin(), E = end(); I != E; ++I) delete *I;
-}
-
+PathDiagnosticMacroPiece::~PathDiagnosticMacroPiece() {}
+PathDiagnostic::PathDiagnostic() {}
+PathPieces::~PathPieces() {}
 PathDiagnostic::~PathDiagnostic() {}
 
-void PathDiagnostic::resetPath(bool deletePieces) {
-  Size = 0;
-
-  if (deletePieces)
-    for (iterator I=begin(), E=end(); I!=E; ++I)
-      delete &*I;
-
-  path.clear();
-}
-
-
 PathDiagnostic::PathDiagnostic(StringRef bugtype, StringRef desc,
                                StringRef category)
-  : Size(0),
-    BugType(StripTrailingDots(bugtype)),
+  : BugType(StripTrailingDots(bugtype)),
     Desc(StripTrailingDots(desc)),
     Category(StripTrailingDots(category)) {}
 
@@ -100,7 +79,7 @@
   if (!D)
     return;
   
-  if (D->empty()) {
+  if (D->path.empty()) {
     delete D;
     return;
   }
@@ -117,9 +96,9 @@
 
   if (PathDiagnostic *orig = Diags.FindNodeOrInsertPos(profile, InsertPos)) {
     // Keep the PathDiagnostic with the shorter path.
-    if (orig->size() <= D->size()) {
+    if (orig->path.size() <= D->path.size()) {
       bool shouldKeepOriginal = true;
-      if (orig->size() == D->size()) {
+      if (orig->path.size() == D->path.size()) {
         // Here we break ties in a fairly arbitrary, but deterministic, way.
         llvm::FoldingSetNodeID fullProfile, fullProfileOrig;
         D->FullProfile(fullProfile);
@@ -476,12 +455,13 @@
 
 void PathDiagnosticMacroPiece::Profile(llvm::FoldingSetNodeID &ID) const {
   PathDiagnosticSpotPiece::Profile(ID);
-  for (const_iterator I = begin(), E = end(); I != E; ++I)
+  for (PathPieces::const_iterator I = subPieces.begin(), E = subPieces.end();
+       I != E; ++I)
     ID.Add(**I);
 }
 
 void PathDiagnostic::Profile(llvm::FoldingSetNodeID &ID) const {
-  if (Size)
+  if (!path.empty())
     getLocation().Profile(ID);
   ID.AddString(BugType);
   ID.AddString(Desc);
@@ -490,8 +470,8 @@
 
 void PathDiagnostic::FullProfile(llvm::FoldingSetNodeID &ID) const {
   Profile(ID);
-  for (const_iterator I = begin(), E = end(); I != E; ++I)
-    ID.Add(*I);
+  for (PathPieces::const_iterator I = path.begin(), E = path.end(); I != E; ++I)
+    ID.Add(**I);
   for (meta_iterator I = meta_begin(), E = meta_end(); I != E; ++I)
     ID.AddString(*I);
 }
diff --git a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
index 89b44c1..93bd467 100644
--- a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
@@ -246,7 +246,7 @@
                         const LangOptions &LangOpts,
                         unsigned indent) {
 
-  for (PathDiagnosticMacroPiece::const_iterator I=P.begin(), E=P.end();
+  for (PathPieces::const_iterator I = P.subPieces.begin(), E=P.subPieces.end();
        I!=E; ++I) {
 
     switch ((*I)->getKind()) {
@@ -298,18 +298,19 @@
   const SourceManager* SM = 0;
 
   if (!Diags.empty())
-    SM = &(*Diags.begin())->begin()->getLocation().getManager();
+    SM = &(*(*Diags.begin())->path.begin())->getLocation().getManager();
 
   for (std::vector<const PathDiagnostic*>::iterator DI = Diags.begin(),
        DE = Diags.end(); DI != DE; ++DI) {
 
     const PathDiagnostic *D = *DI;
 
-    for (PathDiagnostic::const_iterator I=D->begin(), E=D->end(); I!=E; ++I) {
-      AddFID(FM, Fids, SM, I->getLocation().asLocation());
+    for (PathPieces::const_iterator I = D->path.begin(), E = D->path.end();
+         I!=E; ++I) {
+      AddFID(FM, Fids, SM, (*I)->getLocation().asLocation());
 
-      for (PathDiagnosticPiece::range_iterator RI=I->ranges_begin(),
-           RE=I->ranges_end(); RI!=RE; ++RI) {
+      for (PathDiagnosticPiece::range_iterator RI = (*I)->ranges_begin(),
+           RE= (*I)->ranges_end(); RI != RE; ++RI) {
         AddFID(FM, Fids, SM, RI->getBegin());
         AddFID(FM, Fids, SM, RI->getEnd());
       }
@@ -357,8 +358,9 @@
 
     o << "   <array>\n";
 
-    for (PathDiagnostic::const_iterator I=D->begin(), E=D->end(); I != E; ++I)
-      ReportDiag(o, *I, FM, *SM, LangOpts);
+    for (PathPieces::const_iterator I = D->path.begin(), E = D->path.end(); 
+         I != E; ++I)
+      ReportDiag(o, **I, FM, *SM, LangOpts);
 
     o << "   </array>\n";
 
diff --git a/lib/StaticAnalyzer/Core/TextPathDiagnostics.cpp b/lib/StaticAnalyzer/Core/TextPathDiagnostics.cpp
index 0c6b228..fe912df 100644
--- a/lib/StaticAnalyzer/Core/TextPathDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/TextPathDiagnostics.cpp
@@ -58,11 +58,12 @@
   for (std::vector<const PathDiagnostic *>::iterator it = Diags.begin(),
        et = Diags.end(); it != et; ++it) {
     const PathDiagnostic *D = *it;
-    for (PathDiagnostic::const_iterator I=D->begin(), E=D->end(); I != E; ++I) {
+    for (PathPieces::const_iterator I = D->path.begin(), E = D->path.end(); 
+         I != E; ++I) {
       unsigned diagID =
         Diag.getDiagnosticIDs()->getCustomDiagID(DiagnosticIDs::Note,
-                                                 I->getString());
-      Diag.Report(I->getLocation().asLocation(), diagID);
+                                                 (*I)->getString());
+      Diag.Report((*I)->getLocation().asLocation(), diagID);
     }
   }
 }