Redone following a simpler approach of splitting up << into < and <, and 
remerging only if not <<<. The formatting of kernel launch parameters then 
follows that of template instantiation, The previous approach could also have 
resulted in unmatched braces.


http://reviews.llvm.org/D6800

Files:
  lib/Format/Format.cpp
  lib/Format/TokenAnnotator.cpp
  unittests/Format/FormatTest.cpp

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
Index: lib/Format/Format.cpp
===================================================================
--- lib/Format/Format.cpp
+++ lib/Format/Format.cpp
@@ -600,10 +600,10 @@
   FormatTokenLexer(SourceManager &SourceMgr, FileID ID, FormatStyle &Style,
                    encoding::Encoding Encoding)
       : FormatTok(nullptr), IsFirstToken(true), GreaterStashed(false),
-        Column(0), TrailingWhitespace(0), SourceMgr(SourceMgr), ID(ID),
-        Style(Style), IdentTable(getFormattingLangOpts(Style)),
-        Keywords(IdentTable), Encoding(Encoding), FirstInLineIndex(0),
-        FormattingDisabled(false) {
+        LessStashed(false), Column(0), TrailingWhitespace(0),
+        SourceMgr(SourceMgr), ID(ID), Style(Style),
+        IdentTable(getFormattingLangOpts(Style)), Keywords(IdentTable),
+        Encoding(Encoding), FirstInLineIndex(0), FormattingDisabled(false) {
     Lex.reset(new Lexer(ID, SourceMgr.getBuffer(ID), SourceMgr,
                         getFormattingLangOpts(Style)));
     Lex->SetKeepWhitespaceMode(true);
@@ -633,6 +633,8 @@
       return;
     if (tryMergeConflictMarkers())
       return;
+    if (tryMergeLessLess())
+      return;
 
     if (Style.Language == FormatStyle::LK_JavaScript) {
       if (tryMergeJSRegexLiteral())
@@ -658,6 +660,30 @@
     }
   }
 
+  bool tryMergeLessLess() {
+    // Merge X,less,less,Y into X,lessless,Y unless X or Y is less.
+    if (Tokens.size() < 4)
+        return false;
+    SmallVectorImpl<FormatToken *>::const_iterator First = Tokens.end() - 4;
+    if (First[3]->is(tok::less) ||
+        First[2]->isNot(tok::less) ||
+        First[1]->isNot(tok::less) ||
+        First[0]->is(tok::less))
+      return false;
+
+    // Check for whitespace between less and less
+    if (First[2]->WhitespaceRange.getBegin() !=
+        First[2]->WhitespaceRange.getEnd())
+        return false;
+
+    // Merge X,less,less,Y into X,lessless,Y
+    First[1]->Tok.setKind(tok::lessless);
+    First[1]->TokenText = "<<";
+    First[1]->ColumnWidth += 1;
+    Tokens.erase(Tokens.end() - 2);
+    return true;
+  }
+
   bool tryMergeTokens(ArrayRef<tok::TokenKind> Kinds) {
     if (Tokens.size() < Kinds.size())
       return false;
@@ -842,22 +868,32 @@
     return false;
   }
 
+  FormatToken *getStashedToken() {
+    // Create a synthesized second '>' or '<' token.
+    Token Tok = FormatTok->Tok;
+    StringRef TokenText = FormatTok->TokenText;
+
+    unsigned OriginalColumn = FormatTok->OriginalColumn;
+    FormatTok = new (Allocator.Allocate()) FormatToken;
+    FormatTok->Tok = Tok;
+    SourceLocation TokLocation =
+        FormatTok->Tok.getLocation().getLocWithOffset(1);
+    FormatTok->WhitespaceRange =
+        SourceRange(TokLocation, TokLocation);
+    FormatTok->TokenText = TokenText;
+    FormatTok->ColumnWidth = 1;
+    FormatTok->OriginalColumn = OriginalColumn;
+    return FormatTok;
+  }
+
   FormatToken *getNextToken() {
     if (GreaterStashed) {
-      // Create a synthesized second '>' token.
-      Token Greater = FormatTok->Tok;
-      unsigned OriginalColumn = FormatTok->OriginalColumn;
-      FormatTok = new (Allocator.Allocate()) FormatToken;
-      FormatTok->Tok = Greater;
-      SourceLocation GreaterLocation =
-          FormatTok->Tok.getLocation().getLocWithOffset(1);
-      FormatTok->WhitespaceRange =
-          SourceRange(GreaterLocation, GreaterLocation);
-      FormatTok->TokenText = ">";
-      FormatTok->ColumnWidth = 1;
-      FormatTok->OriginalColumn = OriginalColumn;
       GreaterStashed = false;
-      return FormatTok;
+      return getStashedToken();
+    }
+    if (LessStashed) {
+      LessStashed = false;
+      return getStashedToken();
     }
 
     FormatTok = new (Allocator.Allocate()) FormatToken;
@@ -952,6 +988,10 @@
       FormatTok->Tok.setKind(tok::greater);
       FormatTok->TokenText = FormatTok->TokenText.substr(0, 1);
       GreaterStashed = true;
+    } else if (FormatTok->Tok.is(tok::lessless)) {
+      FormatTok->Tok.setKind(tok::less);
+      FormatTok->TokenText = FormatTok->TokenText.substr(0, 1);
+      LessStashed = true;
     }
 
     // Now FormatTok is the next non-whitespace token.
@@ -988,7 +1028,7 @@
 
   FormatToken *FormatTok;
   bool IsFirstToken;
-  bool GreaterStashed;
+  bool GreaterStashed, LessStashed;
   unsigned Column;
   unsigned TrailingWhitespace;
   std::unique_ptr<Lexer> Lex;
Index: lib/Format/TokenAnnotator.cpp
===================================================================
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -2039,6 +2039,9 @@
     return true;
   if (Right.is(tok::kw_typename) && Left.isNot(tok::kw_const))
     return true;
+  if ((Left.is(TT_TemplateOpener) && Right.is(TT_TemplateOpener)) ||
+      (Left.is(TT_TemplateCloser) && Right.is(TT_TemplateCloser)))
+      return false;
   if (Left.isBinaryOperator() && !Left.isOneOf(tok::arrowstar, tok::lessless) &&
       Style.BreakBeforeBinaryOperators != FormatStyle::BOS_All &&
       (Style.BreakBeforeBinaryOperators == FormatStyle::BOS_None ||
Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -9735,6 +9735,20 @@
   verifyFormat("A<A<int>>();", Spaces);
 }
 
+TEST_F(FormatTest, TripleAngleBrackets) {
+  verifyFormat("f<<<1, 1>>>();");
+  verifyFormat("f<<<1, 1, 1, s>>>();");
+  verifyFormat("f<<<a, b, c, d>>>();");
+  EXPECT_EQ("f<<<1, 1>>>();",
+            format("f <<< 1, 1 >>> ();"));
+  verifyFormat("f<param><<<1, 1>>>();");
+  verifyFormat("f<1><<<1, 1>>>();");
+  EXPECT_EQ("f<param><<<1, 1>>>();",
+            format("f< param > <<< 1, 1 >>> ();"));
+  verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+               "aaaaaaaaaaa<<<\n    1, 1>>>();");
+}
+
 TEST_F(FormatTest, HandleUnbalancedImplicitBracesAcrossPPBranches) {
   std::string code = "#if A\n"
                      "#if B\n"
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to