Don't store pointers into a std::vector (RawCommentList::Comments).  Although
currently we take address of std::vector's contents only after we finished
adding all comments (so no reallocation can happen), this will change in
future.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159845 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index b19d7ad..4dc0a44 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -440,7 +440,7 @@
 
 public:
   void addComment(const RawComment &RC) {
-    Comments.addComment(RC);
+    Comments.addComment(RC, BumpAlloc);
   }
 
   /// \brief Return the documentation comment attached to a given declaration.
diff --git a/include/clang/AST/RawCommentList.h b/include/clang/AST/RawCommentList.h
index 299502a..6ef213b 100644
--- a/include/clang/AST/RawCommentList.h
+++ b/include/clang/AST/RawCommentList.h
@@ -146,6 +146,10 @@
     return SM.isBeforeInTranslationUnit(LHS.getSourceRange().getBegin(),
                                         RHS.getSourceRange().getBegin());
   }
+
+  bool operator()(const RawComment *LHS, const RawComment *RHS) {
+    return operator()(*LHS, *RHS);
+  }
 };
 
 /// \brief This class represents all comments included in the translation unit,
@@ -155,19 +159,19 @@
   RawCommentList(SourceManager &SourceMgr) :
     SourceMgr(SourceMgr), OnlyWhitespaceSeen(true) { }
 
-  void addComment(const RawComment &RC);
+  void addComment(const RawComment &RC, llvm::BumpPtrAllocator &Allocator);
 
-  ArrayRef<RawComment> getComments() const {
+  ArrayRef<RawComment *> getComments() const {
     return Comments;
   }
 
 private:
   SourceManager &SourceMgr;
-  std::vector<RawComment> Comments;
+  std::vector<RawComment *> Comments;
   RawComment LastComment;
   bool OnlyWhitespaceSeen;
 
-  void addCommentsToFront(const std::vector<RawComment> &C) {
+  void addCommentsToFront(const std::vector<RawComment *> &C) {
     size_t OldSize = Comments.size();
     Comments.resize(C.size() + OldSize);
     std::copy_backward(Comments.begin(), Comments.begin() + OldSize,
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 99c5ff6..12f1d4d 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -72,7 +72,7 @@
   if (isa<ParmVarDecl>(D))
     return NULL;
 
-  ArrayRef<RawComment> RawComments = Comments.getComments();
+  ArrayRef<RawComment *> RawComments = Comments.getComments();
 
   // If there are no comments anywhere, we won't find anything.
   if (RawComments.empty())
@@ -85,10 +85,11 @@
     return NULL;
 
   // Find the comment that occurs just after this declaration.
-  ArrayRef<RawComment>::iterator Comment
+  RawComment CommentAtDeclLoc(SourceMgr, SourceRange(DeclLoc));
+  ArrayRef<RawComment *>::iterator Comment
       = std::lower_bound(RawComments.begin(),
                          RawComments.end(),
-                         RawComment(SourceMgr, SourceRange(DeclLoc)),
+                         &CommentAtDeclLoc,
                          BeforeThanCompare<RawComment>(SourceMgr));
 
   // Decompose the location for the declaration and find the beginning of the
@@ -97,17 +98,17 @@
 
   // First check whether we have a trailing comment.
   if (Comment != RawComments.end() &&
-      Comment->isDocumentation() && Comment->isTrailingComment() &&
+      (*Comment)->isDocumentation() && (*Comment)->isTrailingComment() &&
       !isa<TagDecl>(D) && !isa<NamespaceDecl>(D)) {
     std::pair<FileID, unsigned> CommentBeginDecomp
-      = SourceMgr.getDecomposedLoc(Comment->getSourceRange().getBegin());
+      = SourceMgr.getDecomposedLoc((*Comment)->getSourceRange().getBegin());
     // Check that Doxygen trailing comment comes after the declaration, starts
     // on the same line and in the same file as the declaration.
     if (DeclLocDecomp.first == CommentBeginDecomp.first &&
         SourceMgr.getLineNumber(DeclLocDecomp.first, DeclLocDecomp.second)
           == SourceMgr.getLineNumber(CommentBeginDecomp.first,
                                      CommentBeginDecomp.second)) {
-      return &*Comment;
+      return *Comment;
     }
   }
 
@@ -118,12 +119,12 @@
   --Comment;
 
   // Check that we actually have a non-member Doxygen comment.
-  if (!Comment->isDocumentation() || Comment->isTrailingComment())
+  if (!(*Comment)->isDocumentation() || (*Comment)->isTrailingComment())
     return NULL;
 
   // Decompose the end of the comment.
   std::pair<FileID, unsigned> CommentEndDecomp
-    = SourceMgr.getDecomposedLoc(Comment->getSourceRange().getEnd());
+    = SourceMgr.getDecomposedLoc((*Comment)->getSourceRange().getEnd());
 
   // If the comment and the declaration aren't in the same file, then they
   // aren't related.
@@ -146,7 +147,7 @@
   if (Text.find_first_of(",;{}#") != StringRef::npos)
     return NULL;
 
-  return &*Comment;
+  return *Comment;
 }
 
 const RawComment *ASTContext::getRawCommentForDecl(const Decl *D) const {
diff --git a/lib/AST/RawCommentList.cpp b/lib/AST/RawCommentList.cpp
index 7912151..d67eb08 100644
--- a/lib/AST/RawCommentList.cpp
+++ b/lib/AST/RawCommentList.cpp
@@ -176,14 +176,15 @@
 }
 } // unnamed namespace
 
-void RawCommentList::addComment(const RawComment &RC) {
+void RawCommentList::addComment(const RawComment &RC,
+                                llvm::BumpPtrAllocator &Allocator) {
   if (RC.isInvalid())
     return;
 
   // Check if the comments are not in source order.
   while (!Comments.empty() &&
          !SourceMgr.isBeforeInTranslationUnit(
-              Comments.back().getSourceRange().getBegin(),
+              Comments.back()->getSourceRange().getBegin(),
               RC.getSourceRange().getBegin())) {
     // If they are, just pop a few last comments that don't fit.
     // This happens if an \#include directive contains comments.
@@ -204,12 +205,12 @@
   // If this is the first Doxygen comment, save it (because there isn't
   // anything to merge it with).
   if (Comments.empty()) {
-    Comments.push_back(RC);
+    Comments.push_back(new (Allocator) RawComment(RC));
     OnlyWhitespaceSeen = true;
     return;
   }
 
-  const RawComment &C1 = Comments.back();
+  const RawComment &C1 = *Comments.back();
   const RawComment &C2 = RC;
 
   // Merge comments only if there is only whitespace between them.
@@ -221,11 +222,9 @@
        C1.getEndLine(SourceMgr) + 1 >= C2.getBeginLine(SourceMgr))) {
     SourceRange MergedRange(C1.getSourceRange().getBegin(),
                             C2.getSourceRange().getEnd());
-    RawComment Merged(SourceMgr, MergedRange, true);
-    Comments.pop_back();
-    Comments.push_back(Merged);
+    *Comments.back() = RawComment(SourceMgr, MergedRange, true);
   } else
-    Comments.push_back(RC);
+    Comments.push_back(new (Allocator) RawComment(RC));
 
   OnlyWhitespaceSeen = true;
 }
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 3d643f6..46bd55e 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -6284,7 +6284,7 @@
 }
 
 void ASTReader::ReadComments() {
-  std::vector<RawComment> Comments;
+  std::vector<RawComment *> Comments;
   for (SmallVectorImpl<std::pair<llvm::BitstreamCursor,
                                  serialization::ModuleFile *> >::iterator
        I = CommentsCursors.begin(),
@@ -6325,8 +6325,9 @@
             (RawComment::CommentKind) Record[Idx++];
         bool IsTrailingComment = Record[Idx++];
         bool IsAlmostTrailingComment = Record[Idx++];
-        Comments.push_back(RawComment(SR, Kind, IsTrailingComment,
-                                      IsAlmostTrailingComment));
+        Comments.push_back(new (Context) RawComment(SR, Kind,
+                                                    IsTrailingComment,
+                                                    IsAlmostTrailingComment));
         break;
       }
       }
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 8ab1737..566c8b7 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -2245,16 +2245,16 @@
 
 void ASTWriter::WriteComments() {
   Stream.EnterSubblock(COMMENTS_BLOCK_ID, 3);
-  ArrayRef<RawComment> RawComments = Context->Comments.getComments();
+  ArrayRef<RawComment *> RawComments = Context->Comments.getComments();
   RecordData Record;
-  for (ArrayRef<RawComment>::iterator I = RawComments.begin(),
-                                      E = RawComments.end();
+  for (ArrayRef<RawComment *>::iterator I = RawComments.begin(),
+                                        E = RawComments.end();
        I != E; ++I) {
     Record.clear();
-    AddSourceRange(I->getSourceRange(), Record);
-    Record.push_back(I->getKind());
-    Record.push_back(I->isTrailingComment());
-    Record.push_back(I->isAlmostTrailingComment());
+    AddSourceRange((*I)->getSourceRange(), Record);
+    Record.push_back((*I)->getKind());
+    Record.push_back((*I)->isTrailingComment());
+    Record.push_back((*I)->isAlmostTrailingComment());
     Stream.EmitRecord(COMMENTS_RAW_COMMENT, Record);
   }
   Stream.ExitBlock();