summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/RawCommentList.cpp
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2013-09-28 15:06:27 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2013-09-28 15:06:27 +0000
commit20c28bebf95fbc9bb5829d9224cea032c3903fe2 (patch)
tree7f738d77636c4524e67d573b6f0788933473b661 /clang/lib/AST/RawCommentList.cpp
parentb027bd212b7faa541d8baaea45e2289d7250bb6d (diff)
Refactor comment merging.
- We scan for whitespace between comments anyways, remember any newlines seen along the way. - Use this newline number to decide whether two comments are adjacent. - Since the newline check is now free remove the caching and unused code. - Remove unnecessary boolean state from the comment list. - No behavioral change. llvm-svn: 191614
Diffstat (limited to 'clang/lib/AST/RawCommentList.cpp')
-rw-r--r--clang/lib/AST/RawCommentList.cpp106
1 files changed, 45 insertions, 61 deletions
diff --git a/clang/lib/AST/RawCommentList.cpp b/clang/lib/AST/RawCommentList.cpp
index 92b96dc8e5a1..1fa7cea1d498 100644
--- a/clang/lib/AST/RawCommentList.cpp
+++ b/clang/lib/AST/RawCommentList.cpp
@@ -68,8 +68,7 @@ RawComment::RawComment(const SourceManager &SourceMgr, SourceRange SR,
bool Merged, bool ParseAllComments) :
Range(SR), RawTextValid(false), BriefTextValid(false),
IsAttached(false), IsAlmostTrailingComment(false),
- ParseAllComments(ParseAllComments),
- BeginLineValid(false), EndLineValid(false) {
+ ParseAllComments(ParseAllComments) {
// Extract raw comment text, if possible.
if (SR.getBegin() == SR.getEnd() || getRawText(SourceMgr).empty()) {
Kind = RCK_Invalid;
@@ -90,26 +89,6 @@ RawComment::RawComment(const SourceManager &SourceMgr, SourceRange SR,
}
}
-unsigned RawComment::getBeginLine(const SourceManager &SM) const {
- if (BeginLineValid)
- return BeginLine;
-
- std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Range.getBegin());
- BeginLine = SM.getLineNumber(LocInfo.first, LocInfo.second);
- BeginLineValid = true;
- return BeginLine;
-}
-
-unsigned RawComment::getEndLine(const SourceManager &SM) const {
- if (EndLineValid)
- return EndLine;
-
- std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Range.getEnd());
- EndLine = SM.getLineNumber(LocInfo.first, LocInfo.second);
- EndLineValid = true;
- return EndLine;
-}
-
StringRef RawComment::getRawTextSlow(const SourceManager &SourceMgr) const {
FileID BeginFileID;
FileID EndFileID;
@@ -184,13 +163,9 @@ comments::FullComment *RawComment::parse(const ASTContext &Context,
return P.parseFullComment();
}
-namespace {
-bool containsOnlyWhitespace(StringRef Str) {
- return Str.find_first_not_of(" \t\f\v\r\n") == StringRef::npos;
-}
-
-bool onlyWhitespaceBetween(SourceManager &SM,
- SourceLocation Loc1, SourceLocation Loc2) {
+static bool onlyWhitespaceBetween(SourceManager &SM,
+ SourceLocation Loc1, SourceLocation Loc2,
+ unsigned MaxNewlinesAllowed) {
std::pair<FileID, unsigned> Loc1Info = SM.getDecomposedLoc(Loc1);
std::pair<FileID, unsigned> Loc2Info = SM.getDecomposedLoc(Loc2);
@@ -203,10 +178,38 @@ bool onlyWhitespaceBetween(SourceManager &SM,
if (Invalid)
return false;
- StringRef Text(Buffer + Loc1Info.second, Loc2Info.second - Loc1Info.second);
- return containsOnlyWhitespace(Text);
+ unsigned NumNewlines = 0;
+ assert(Loc1Info.second <= Loc2Info.second && "Loc1 after Loc2!");
+ // Look for non-whitespace characters and remember any newlines seen.
+ for (unsigned I = Loc1Info.second; I != Loc2Info.second; ++I) {
+ switch (Buffer[I]) {
+ default:
+ return false;
+ case ' ':
+ case '\t':
+ case '\f':
+ case '\v':
+ break;
+ case '\r':
+ case '\n':
+ ++NumNewlines;
+
+ // Check if we have found more than the maximum allowed number of
+ // newlines.
+ if (NumNewlines > MaxNewlinesAllowed)
+ return false;
+
+ // Collapse \r\n and \n\r into a single newline.
+ if (I + 1 != Loc2Info.second &&
+ (Buffer[I + 1] == '\n' || Buffer[I + 1] == '\r') &&
+ Buffer[I] != Buffer[I + 1])
+ ++I;
+ break;
+ }
+ }
+
+ return true;
}
-} // unnamed namespace
void RawCommentList::addComment(const RawComment &RC,
llvm::BumpPtrAllocator &Allocator) {
@@ -215,23 +218,13 @@ void RawCommentList::addComment(const RawComment &RC,
// Check if the comments are not in source order.
while (!Comments.empty() &&
- !SourceMgr.isBeforeInTranslationUnit(
- Comments.back()->getSourceRange().getBegin(),
- RC.getSourceRange().getBegin())) {
+ !SourceMgr.isBeforeInTranslationUnit(Comments.back()->getLocStart(),
+ RC.getLocStart())) {
// If they are, just pop a few last comments that don't fit.
// This happens if an \#include directive contains comments.
Comments.pop_back();
}
- if (OnlyWhitespaceSeen) {
- if (!onlyWhitespaceBetween(SourceMgr,
- PrevCommentEndLoc,
- RC.getSourceRange().getBegin()))
- OnlyWhitespaceSeen = false;
- }
-
- PrevCommentEndLoc = RC.getSourceRange().getEnd();
-
// Ordinary comments are not interesting for us.
if (RC.isOrdinary())
return;
@@ -240,7 +233,6 @@ void RawCommentList::addComment(const RawComment &RC,
// anything to merge it with).
if (Comments.empty()) {
Comments.push_back(new (Allocator) RawComment(RC));
- OnlyWhitespaceSeen = true;
return;
}
@@ -250,21 +242,13 @@ void RawCommentList::addComment(const RawComment &RC,
// Merge comments only if there is only whitespace between them.
// Can't merge trailing and non-trailing comments.
// Merge comments if they are on same or consecutive lines.
- bool Merged = false;
- if (OnlyWhitespaceSeen &&
- (C1.isTrailingComment() == C2.isTrailingComment())) {
- unsigned C1EndLine = C1.getEndLine(SourceMgr);
- unsigned C2BeginLine = C2.getBeginLine(SourceMgr);
- if (C1EndLine + 1 == C2BeginLine || C1EndLine == C2BeginLine) {
- SourceRange MergedRange(C1.getSourceRange().getBegin(),
- C2.getSourceRange().getEnd());
- *Comments.back() = RawComment(SourceMgr, MergedRange, true,
- RC.isParseAllComments());
- Merged = true;
- }
- }
- if (!Merged)
+ if (C1.isTrailingComment() == C2.isTrailingComment() &&
+ onlyWhitespaceBetween(SourceMgr, C1.getLocEnd(), C2.getLocStart(),
+ /*MaxNewlinesAllowed=*/1)) {
+ SourceRange MergedRange(C1.getLocStart(), C2.getLocEnd());
+ *Comments.back() = RawComment(SourceMgr, MergedRange, true,
+ RC.isParseAllComments());
+ } else {
Comments.push_back(new (Allocator) RawComment(RC));
-
- OnlyWhitespaceSeen = true;
+ }
}