From 952eddef9aff85b1e92626e89baaf7a360e2ac85 Mon Sep 17 00:00:00 2001
From: dim <dim@FreeBSD.org>
Date: Sun, 22 Dec 2013 00:07:40 +0000
Subject: Vendor import of clang release_34 branch r197841 (effectively, 3.4
 RC3): https://llvm.org/svn/llvm-project/cfe/branches/release_34@197841

---
 lib/AST/RawCommentList.cpp | 106 +++++++++++++++++++--------------------------
 1 file changed, 45 insertions(+), 61 deletions(-)

(limited to 'lib/AST/RawCommentList.cpp')

diff --git a/lib/AST/RawCommentList.cpp b/lib/AST/RawCommentList.cpp
index 92b96dc..1fa7cea 100644
--- a/lib/AST/RawCommentList.cpp
+++ b/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;
+  }
 }
-- 
cgit v1.1