Insert a space at the start of a line comment in case it starts with an alphanumeric character.

Summary:
"//Test" becomes "// Test". This change is aimed to improve code
readability and conformance to certain coding styles. If a comment starts with a
non-alphanumeric character, the space isn't added, e.g. "//-*-c++-*-" stays
unchanged.

Reviewers: klimek

Reviewed By: klimek

CC: cfe-commits

Differential Revision: http://llvm-reviews.chandlerc.com/D949

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@183750 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Format/BreakableToken.cpp b/lib/Format/BreakableToken.cpp
index 94b4322..d915aef 100644
--- a/lib/Format/BreakableToken.cpp
+++ b/lib/Format/BreakableToken.cpp
@@ -16,6 +16,7 @@
 #define DEBUG_TYPE "format-token-breaker"
 
 #include "BreakableToken.h"
+#include "clang/Basic/CharInfo.h"
 #include "clang/Format/Format.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/Debug.h"
@@ -118,15 +119,6 @@
          encoding::getCodePointCount(Line.substr(Offset, Length), Encoding);
 }
 
-void BreakableSingleLineToken::insertBreak(unsigned LineIndex,
-                                           unsigned TailOffset, Split Split,
-                                           bool InPPDirective,
-                                           WhitespaceManager &Whitespaces) {
-  Whitespaces.breakToken(Tok, Prefix.size() + TailOffset + Split.first,
-                         Split.second, Postfix, Prefix, InPPDirective,
-                         StartColumn);
-}
-
 BreakableSingleLineToken::BreakableSingleLineToken(const FormatToken &Tok,
                                                    unsigned StartColumn,
                                                    StringRef Prefix,
@@ -151,6 +143,15 @@
                         Encoding);
 }
 
+void BreakableStringLiteral::insertBreak(unsigned LineIndex,
+                                         unsigned TailOffset, Split Split,
+                                         bool InPPDirective,
+                                         WhitespaceManager &Whitespaces) {
+  Whitespaces.replaceWhitespaceInToken(
+      Tok, Prefix.size() + TailOffset + Split.first, Split.second, Postfix,
+      Prefix, InPPDirective, 1, StartColumn);
+}
+
 static StringRef getLineCommentPrefix(StringRef Comment) {
   const char *KnownPrefixes[] = { "/// ", "///", "// ", "//" };
   for (size_t i = 0, e = llvm::array_lengthof(KnownPrefixes); i != e; ++i)
@@ -164,7 +165,16 @@
                                            encoding::Encoding Encoding)
     : BreakableSingleLineToken(Token, StartColumn,
                                getLineCommentPrefix(Token.TokenText), "",
-                               Encoding) {}
+                               Encoding) {
+  OriginalPrefix = Prefix;
+  if (Token.TokenText.size() > Prefix.size() &&
+      isAlphanumeric(Token.TokenText[Prefix.size()])) {
+    if (Prefix == "//")
+      Prefix = "// ";
+    else if (Prefix == "///")
+      Prefix = "/// ";
+  }
+}
 
 BreakableToken::Split
 BreakableLineComment::getSplit(unsigned LineIndex, unsigned TailOffset,
@@ -173,6 +183,24 @@
                          ColumnLimit, Encoding);
 }
 
+void BreakableLineComment::insertBreak(unsigned LineIndex, unsigned TailOffset,
+                                       Split Split, bool InPPDirective,
+                                       WhitespaceManager &Whitespaces) {
+  Whitespaces.replaceWhitespaceInToken(
+      Tok, OriginalPrefix.size() + TailOffset + Split.first, Split.second,
+      Postfix, Prefix, InPPDirective, 1, StartColumn);
+}
+
+void
+BreakableLineComment::replaceWhitespaceBefore(unsigned LineIndex,
+                                              unsigned InPPDirective,
+                                              WhitespaceManager &Whitespaces) {
+  if (OriginalPrefix != Prefix) {
+    Whitespaces.replaceWhitespaceInToken(Tok, OriginalPrefix.size(), 0, "", "",
+                                         false, 0, 1);
+  }
+}
+
 BreakableBlockComment::BreakableBlockComment(
     const FormatStyle &Style, const FormatToken &Token, unsigned StartColumn,
     unsigned OriginalStartColumn, bool FirstInLine, encoding::Encoding Encoding)
@@ -299,8 +327,9 @@
       Text.data() - Tok.TokenText.data() + Split.first;
   unsigned CharsToRemove = Split.second;
   assert(IndentAtLineBreak >= Decoration.size());
-  Whitespaces.breakToken(Tok, BreakOffsetInToken, CharsToRemove, "", Prefix,
-                         InPPDirective, IndentAtLineBreak - Decoration.size());
+  Whitespaces.replaceWhitespaceInToken(Tok, BreakOffsetInToken, CharsToRemove,
+                                       "", Prefix, InPPDirective, 1,
+                                       IndentAtLineBreak - Decoration.size());
 }
 
 void
@@ -331,9 +360,9 @@
       Lines[LineIndex].data() - Tok.TokenText.data() -
       LeadingWhitespace[LineIndex];
   assert(StartOfLineColumn[LineIndex] >= Prefix.size());
-  Whitespaces.breakToken(
+  Whitespaces.replaceWhitespaceInToken(
       Tok, WhitespaceOffsetInToken, LeadingWhitespace[LineIndex], "", Prefix,
-      InPPDirective, StartOfLineColumn[LineIndex] - Prefix.size());
+      InPPDirective, 1, StartOfLineColumn[LineIndex] - Prefix.size());
 }
 
 unsigned