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
This commit is contained in:
parent
a98fde5d70
commit
7dd29d4d3d
|
@ -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.
|
||||
|
|
|
@ -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<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,
|
||||
|
|
|
@ -72,7 +72,7 @@ const RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
|
|||
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 @@ const RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
|
|||
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 @@ 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<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 @@ 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<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 @@ 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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -6284,7 +6284,7 @@ void ASTReader::ClearSwitchCaseIDs() {
|
|||
}
|
||||
|
||||
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 @@ 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2245,16 +2245,16 @@ void ASTWriter::WriteFileDeclIDsMap() {
|
|||
|
||||
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();
|
||||
|
|
Loading…
Reference in New Issue