From 7dd29d4d3d1c2fdcb4917d4121c3352650f83d38 Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Fri, 6 Jul 2012 18:19:34 +0000 Subject: [PATCH] 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. llvm-svn: 159845 --- clang/include/clang/AST/ASTContext.h | 2 +- clang/include/clang/AST/RawCommentList.h | 12 ++++++++---- clang/lib/AST/ASTContext.cpp | 19 ++++++++++--------- clang/lib/AST/RawCommentList.cpp | 15 +++++++-------- clang/lib/Serialization/ASTReader.cpp | 7 ++++--- clang/lib/Serialization/ASTWriter.cpp | 14 +++++++------- 6 files changed, 37 insertions(+), 32 deletions(-) diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index b19d7ad42c92..4dc0a447bdf7 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -440,7 +440,7 @@ public: 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/clang/include/clang/AST/RawCommentList.h b/clang/include/clang/AST/RawCommentList.h index 299502acb6be..6ef213bdcb43 100644 --- a/clang/include/clang/AST/RawCommentList.h +++ b/clang/include/clang/AST/RawCommentList.h @@ -146,6 +146,10 @@ public: 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 @@ public: RawCommentList(SourceManager &SourceMgr) : SourceMgr(SourceMgr), OnlyWhitespaceSeen(true) { } - void addComment(const RawComment &RC); + void addComment(const RawComment &RC, llvm::BumpPtrAllocator &Allocator); - ArrayRef getComments() const { + ArrayRef getComments() const { return Comments; } private: SourceManager &SourceMgr; - std::vector Comments; + std::vector Comments; RawComment LastComment; bool OnlyWhitespaceSeen; - void addCommentsToFront(const std::vector &C) { + void addCommentsToFront(const std::vector &C) { size_t OldSize = Comments.size(); Comments.resize(C.size() + OldSize); std::copy_backward(Comments.begin(), Comments.begin() + OldSize, diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 99c5ff6d5673..12f1d4de039a 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -72,7 +72,7 @@ const RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const { if (isa(D)) return NULL; - ArrayRef RawComments = Comments.getComments(); + ArrayRef RawComments = Comments.getComments(); // If there are no comments anywhere, we won't find anything. if (RawComments.empty()) @@ -85,10 +85,11 @@ const RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const { return NULL; // Find the comment that occurs just after this declaration. - ArrayRef::iterator Comment + RawComment CommentAtDeclLoc(SourceMgr, SourceRange(DeclLoc)); + ArrayRef::iterator Comment = std::lower_bound(RawComments.begin(), RawComments.end(), - RawComment(SourceMgr, SourceRange(DeclLoc)), + &CommentAtDeclLoc, BeforeThanCompare(SourceMgr)); // Decompose the location for the declaration and find the beginning of the @@ -97,17 +98,17 @@ const RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const { // First check whether we have a trailing comment. if (Comment != RawComments.end() && - Comment->isDocumentation() && Comment->isTrailingComment() && + (*Comment)->isDocumentation() && (*Comment)->isTrailingComment() && !isa(D) && !isa(D)) { std::pair 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 @@ const RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const { --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 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 @@ const RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const { if (Text.find_first_of(",;{}#") != StringRef::npos) return NULL; - return &*Comment; + return *Comment; } const RawComment *ASTContext::getRawCommentForDecl(const Decl *D) const { diff --git a/clang/lib/AST/RawCommentList.cpp b/clang/lib/AST/RawCommentList.cpp index 791215103f0a..d67eb0822f2b 100644 --- a/clang/lib/AST/RawCommentList.cpp +++ b/clang/lib/AST/RawCommentList.cpp @@ -176,14 +176,15 @@ bool onlyWhitespaceBetweenComments(SourceManager &SM, } } // 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 @@ void RawCommentList::addComment(const RawComment &RC) { // 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 @@ void RawCommentList::addComment(const RawComment &RC) { 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/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 3d643f6b4396..46bd55e83e3e 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -6284,7 +6284,7 @@ void ASTReader::ClearSwitchCaseIDs() { } void ASTReader::ReadComments() { - std::vector Comments; + std::vector Comments; for (SmallVectorImpl >::iterator I = CommentsCursors.begin(), @@ -6325,8 +6325,9 @@ void ASTReader::ReadComments() { (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/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 8ab17374724c..566c8b77f5e7 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -2245,16 +2245,16 @@ void ASTWriter::WriteFileDeclIDsMap() { void ASTWriter::WriteComments() { Stream.EnterSubblock(COMMENTS_BLOCK_ID, 3); - ArrayRef RawComments = Context->Comments.getComments(); + ArrayRef RawComments = Context->Comments.getComments(); RecordData Record; - for (ArrayRef::iterator I = RawComments.begin(), - E = RawComments.end(); + for (ArrayRef::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();