curdeius updated this revision to Diff 113077.
curdeius added a comment.

Fix line endings again.


https://reviews.llvm.org/D37132

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

Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -11217,6 +11217,31 @@
   EXPECT_EQ("auto c = u8'a';", format("auto c = u8'a';"));
 }
 
+TEST_F(FormatTest, StructuredBindings) {
+  // Structured bindings is a C++17 feature.
+  // all modes, including C++11, C++14 and C++17
+  verifyFormat("auto [a, b] = f();");
+  EXPECT_EQ("auto [a, b] = f();", format("auto[a, b] = f();"));
+  EXPECT_EQ("const auto [a, b] = f();", format("const   auto[a, b] = f();"));
+  EXPECT_EQ("auto const [a, b] = f();", format("auto  const[a, b] = f();"));
+  EXPECT_EQ("auto const volatile [a, b] = f();",
+            format("auto  const   volatile[a, b] = f();"));
+  EXPECT_EQ("auto [a, b, c] = f();", format("auto   [  a  ,  b,c   ] = f();"));
+  EXPECT_EQ("auto & [a, b, c] = f();",
+            format("auto   &[  a  ,  b,c   ] = f();"));
+  EXPECT_EQ("auto && [a, b, c] = f();",
+            format("auto   &&[  a  ,  b,c   ] = f();"));
+  EXPECT_EQ("auto const & [a, b] = f();", format("auto  const&[a, b] = f();"));
+  EXPECT_EQ("auto const volatile && [a, b] = f();",
+            format("auto  const  volatile  &&[a, b] = f();"));
+  EXPECT_EQ("auto && [a, b] = f();", format("auto  &&[a, b] = f();"));
+
+  format::FormatStyle Spaces = format::getLLVMStyle();
+  Spaces.SpacesInSquareBrackets = true;
+  verifyFormat("auto [ a, b ] = f();", Spaces);
+  verifyFormat("auto && [ a, b ] = f();", Spaces);
+}
+
 } // end namespace
 } // end namespace format
 } // end namespace clang
Index: lib/Format/TokenAnnotator.cpp
===================================================================
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -47,7 +47,7 @@
     if (NonTemplateLess.count(CurrentToken->Previous))
       return false;
 
-    const FormatToken& Previous = *CurrentToken->Previous;
+    const FormatToken &Previous = *CurrentToken->Previous;
     if (Previous.Previous) {
       if (Previous.Previous->Tok.isLiteral())
         return false;
@@ -152,11 +152,11 @@
       // export type X = (...);
       Contexts.back().IsExpression = false;
     } else if (Left->Previous &&
-        (Left->Previous->isOneOf(tok::kw_static_assert, tok::kw_decltype,
-                                 tok::kw_if, tok::kw_while, tok::l_paren,
-                                 tok::comma) ||
-         Left->Previous->endsSequence(tok::kw_constexpr, tok::kw_if) ||
-         Left->Previous->is(TT_BinaryOperator))) {
+               (Left->Previous->isOneOf(tok::kw_static_assert, tok::kw_decltype,
+                                        tok::kw_if, tok::kw_while, tok::l_paren,
+                                        tok::comma) ||
+                Left->Previous->endsSequence(tok::kw_constexpr, tok::kw_if) ||
+                Left->Previous->is(TT_BinaryOperator))) {
       // static_assert, if and while usually contain expressions.
       Contexts.back().IsExpression = true;
     } else if (Style.Language == FormatStyle::LK_JavaScript && Left->Previous &&
@@ -325,8 +325,7 @@
     // In C++, this can happen either in array of templates (foo<int>[10])
     // or when array is a nested template type (unique_ptr<type1<type2>[]>).
     bool CppArrayTemplates =
-        Style.isCpp() && Parent &&
-        Parent->is(TT_TemplateCloser) &&
+        Style.isCpp() && Parent && Parent->is(TT_TemplateCloser) &&
         (Contexts.back().CanBeExpression || Contexts.back().IsExpression ||
          Contexts.back().InTemplateArgument);
 
@@ -342,9 +341,22 @@
          getBinOpPrecedence(Parent->Tok.getKind(), true, true) > prec::Unknown);
     bool ColonFound = false;
 
+    FormatToken *PreviousNoneOfConstVolatileReference = Parent;
+    while (PreviousNoneOfConstVolatileReference &&
+           PreviousNoneOfConstVolatileReference->isOneOf(
+               tok::kw_const, tok::kw_volatile, tok::amp, tok::ampamp))
+      PreviousNoneOfConstVolatileReference =
+          PreviousNoneOfConstVolatileReference->getPreviousNonComment();
+
+    bool CppStructuredBindings =
+        Style.isCpp() && PreviousNoneOfConstVolatileReference &&
+        PreviousNoneOfConstVolatileReference->is(tok::kw_auto);
+
     unsigned BindingIncrease = 1;
     if (Left->is(TT_Unknown)) {
-      if (StartsObjCMethodExpr) {
+      if (CppStructuredBindings) {
+        Left->Type = TT_StructuredBindingLSquare;
+      } else if (StartsObjCMethodExpr) {
         Left->Type = TT_ObjCMethodExpr;
       } else if (Style.Language == FormatStyle::LK_JavaScript && Parent &&
                  Contexts.back().ContextKind == tok::l_brace &&
@@ -605,7 +617,8 @@
       break;
     case tok::kw_if:
     case tok::kw_while:
-      if (Tok->is(tok::kw_if) && CurrentToken && CurrentToken->is(tok::kw_constexpr))
+      if (Tok->is(tok::kw_if) && CurrentToken &&
+          CurrentToken->is(tok::kw_constexpr))
         next();
       if (CurrentToken && CurrentToken->is(tok::l_paren)) {
         next();
@@ -631,8 +644,7 @@
       // marks the first l_paren as a OverloadedOperatorLParen. Here, we make
       // the first two parens OverloadedOperators and the second l_paren an
       // OverloadedOperatorLParen.
-      if (Tok->Previous &&
-          Tok->Previous->is(tok::r_paren) &&
+      if (Tok->Previous && Tok->Previous->is(tok::r_paren) &&
           Tok->Previous->MatchingParen &&
           Tok->Previous->MatchingParen->is(TT_OverloadedOperatorLParen)) {
         Tok->Previous->Type = TT_OverloadedOperator;
@@ -655,7 +667,7 @@
       break;
     case tok::l_brace:
       if (Style.Language == FormatStyle::LK_TextProto) {
-        FormatToken *Previous =Tok->getPreviousNonComment();
+        FormatToken *Previous = Tok->getPreviousNonComment();
         if (Previous && Previous->Type != TT_DictLiteral)
           Previous->Type = TT_SelectorName;
       }
@@ -752,8 +764,8 @@
 
   void parseIncludeDirective() {
     if (CurrentToken && CurrentToken->is(tok::less)) {
-     next();
-     while (CurrentToken) {
+      next();
+      while (CurrentToken) {
         // Mark tokens up to the trailing line comments as implicit string
         // literals.
         if (CurrentToken->isNot(tok::comment) &&
@@ -793,9 +805,9 @@
   void parseHasInclude() {
     if (!CurrentToken || !CurrentToken->is(tok::l_paren))
       return;
-    next();  // '('
+    next(); // '('
     parseIncludeDirective();
-    next();  // ')'
+    next(); // ')'
   }
 
   LineType parsePreprocessorDirective() {
@@ -854,7 +866,7 @@
       if (Tok->is(tok::l_paren))
         parseParens();
       else if (Tok->isOneOf(Keywords.kw___has_include,
-                       Keywords.kw___has_include_next))
+                            Keywords.kw___has_include_next))
         parseHasInclude();
     }
     return Type;
@@ -945,11 +957,12 @@
     // FIXME: Closure-library specific stuff should not be hard-coded but be
     // configurable.
     return Tok.TokenText == "goog" && Tok.Next && Tok.Next->is(tok::period) &&
-           Tok.Next->Next && (Tok.Next->Next->TokenText == "module" ||
-                              Tok.Next->Next->TokenText == "provide" ||
-                              Tok.Next->Next->TokenText == "require" ||
-                              Tok.Next->Next->TokenText == "setTestOnly" ||
-                              Tok.Next->Next->TokenText == "forwardDeclare") &&
+           Tok.Next->Next &&
+           (Tok.Next->Next->TokenText == "module" ||
+            Tok.Next->Next->TokenText == "provide" ||
+            Tok.Next->Next->TokenText == "require" ||
+            Tok.Next->Next->TokenText == "setTestOnly" ||
+            Tok.Next->Next->TokenText == "forwardDeclare") &&
            Tok.Next->Next->Next && Tok.Next->Next->Next->is(tok::l_paren);
   }
 
@@ -1066,8 +1079,7 @@
                Current.Previous->is(TT_CtorInitializerColon)) {
       Contexts.back().IsExpression = true;
       Contexts.back().InCtorInitializer = true;
-    } else if (Current.Previous &&
-               Current.Previous->is(TT_InheritanceColon)) {
+    } else if (Current.Previous && Current.Previous->is(TT_InheritanceColon)) {
       Contexts.back().InInheritanceList = true;
     } else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) {
       for (FormatToken *Previous = Current.Previous;
@@ -1125,10 +1137,10 @@
                Current.NestingLevel == 0) {
       Current.Type = TT_TrailingReturnArrow;
     } else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) {
-      Current.Type =
-          determineStarAmpUsage(Current, Contexts.back().CanBeExpression &&
-                                             Contexts.back().IsExpression,
-                                Contexts.back().InTemplateArgument);
+      Current.Type = determineStarAmpUsage(Current,
+                                           Contexts.back().CanBeExpression &&
+                                               Contexts.back().IsExpression,
+                                           Contexts.back().InTemplateArgument);
     } else if (Current.isOneOf(tok::minus, tok::plus, tok::caret)) {
       Current.Type = determinePlusMinusCaretUsage(Current);
       if (Current.is(TT_UnaryOperator) && Current.is(tok::caret))
@@ -1736,7 +1748,7 @@
 
 static unsigned maxNestingDepth(const AnnotatedLine &Line) {
   unsigned Result = 0;
-  for (const auto* Tok = Line.First; Tok != nullptr; Tok = Tok->Next)
+  for (const auto *Tok = Line.First; Tok != nullptr; Tok = Tok->Next)
     Result = std::max(Result, Tok->NestingLevel);
   return Result;
 }
@@ -1778,7 +1790,7 @@
 // function declaration.
 static bool isFunctionDeclarationName(const FormatToken &Current,
                                       const AnnotatedLine &Line) {
-  auto skipOperatorName = [](const FormatToken* Next) -> const FormatToken* {
+  auto skipOperatorName = [](const FormatToken *Next) -> const FormatToken * {
     for (; Next; Next = Next->Next) {
       if (Next->is(TT_OverloadedOperatorLParen))
         return Next;
@@ -1786,8 +1798,8 @@
         continue;
       if (Next->isOneOf(tok::kw_new, tok::kw_delete)) {
         // For 'new[]' and 'delete[]'.
-        if (Next->Next && Next->Next->is(tok::l_square) &&
-            Next->Next->Next && Next->Next->Next->is(tok::r_square))
+        if (Next->Next && Next->Next->is(tok::l_square) && Next->Next->Next &&
+            Next->Next->Next->is(tok::r_square))
           Next = Next->Next->Next;
         continue;
       }
@@ -2066,7 +2078,8 @@
   if (Left.is(tok::comment))
     return 1000;
 
-  if (Left.isOneOf(TT_RangeBasedForLoopColon, TT_InheritanceColon, TT_CtorInitializerColon))
+  if (Left.isOneOf(TT_RangeBasedForLoopColon, TT_InheritanceColon,
+                   TT_CtorInitializerColon))
     return 2;
 
   if (Right.isMemberAccess()) {
@@ -2124,8 +2137,8 @@
       Style.AlignAfterOpenBracket != FormatStyle::BAS_DontAlign)
     return 100;
   if (Left.is(tok::l_paren) && Left.Previous &&
-      (Left.Previous->isOneOf(tok::kw_if, tok::kw_for)
-       || Left.Previous->endsSequence(tok::kw_constexpr, tok::kw_if)))
+      (Left.Previous->isOneOf(tok::kw_if, tok::kw_for) ||
+       Left.Previous->endsSequence(tok::kw_constexpr, tok::kw_if)))
     return 1000;
   if (Left.is(tok::equal) && InFunctionDecl)
     return 110;
@@ -2195,8 +2208,8 @@
                : Style.SpacesInParentheses;
   if (Right.isOneOf(tok::semi, tok::comma))
     return false;
-  if (Right.is(tok::less) &&
-      Line.Type == LT_ObjCDecl && Style.ObjCSpaceBeforeProtocolList)
+  if (Right.is(tok::less) && Line.Type == LT_ObjCDecl &&
+      Style.ObjCSpaceBeforeProtocolList)
     return true;
   if (Right.is(tok::less) && Left.is(tok::kw_template))
     return Style.SpaceAfterTemplateKeyword;
@@ -2256,17 +2269,20 @@
   if (Left.is(tok::l_square))
     return (Left.is(TT_ArrayInitializerLSquare) &&
             Style.SpacesInContainerLiterals && Right.isNot(tok::r_square)) ||
-           (Left.is(TT_ArraySubscriptLSquare) && Style.SpacesInSquareBrackets &&
-            Right.isNot(tok::r_square));
+           (Left.isOneOf(TT_ArraySubscriptLSquare,
+                         TT_StructuredBindingLSquare) &&
+            Style.SpacesInSquareBrackets && Right.isNot(tok::r_square));
   if (Right.is(tok::r_square))
     return Right.MatchingParen &&
            ((Style.SpacesInContainerLiterals &&
              Right.MatchingParen->is(TT_ArrayInitializerLSquare)) ||
             (Style.SpacesInSquareBrackets &&
-             Right.MatchingParen->is(TT_ArraySubscriptLSquare)));
+             Right.MatchingParen->isOneOf(TT_ArraySubscriptLSquare,
+                                          TT_StructuredBindingLSquare)));
   if (Right.is(tok::l_square) &&
       !Right.isOneOf(TT_ObjCMethodExpr, TT_LambdaLSquare,
-                     TT_DesignatedInitializerLSquare) &&
+                     TT_DesignatedInitializerLSquare,
+                     TT_StructuredBindingLSquare) &&
       !Left.isOneOf(tok::numeric_constant, TT_DictLiteral))
     return false;
   if (Left.is(tok::l_brace) && Right.is(tok::r_brace))
@@ -2342,8 +2358,8 @@
     if (Left.is(TT_JsFatArrow))
       return true;
     // for await ( ...
-    if (Right.is(tok::l_paren) && Left.is(Keywords.kw_await) &&
-        Left.Previous && Left.Previous->is(tok::kw_for))
+    if (Right.is(tok::l_paren) && Left.is(Keywords.kw_await) && Left.Previous &&
+        Left.Previous->is(tok::kw_for))
       return true;
     if (Left.is(Keywords.kw_async) && Right.is(tok::l_paren) &&
         Right.MatchingParen) {
@@ -2500,7 +2516,8 @@
     return (Left.is(TT_TemplateOpener) &&
             Style.Standard == FormatStyle::LS_Cpp03) ||
            !(Left.isOneOf(tok::l_paren, tok::r_paren, tok::l_square,
-                          tok::kw___super, TT_TemplateCloser, TT_TemplateOpener));
+                          tok::kw___super, TT_TemplateCloser,
+                          TT_TemplateOpener));
   if ((Left.is(TT_TemplateOpener)) != (Right.is(TT_TemplateCloser)))
     return Style.SpacesInAngles;
   if ((Right.is(TT_BinaryOperator) && !Left.is(tok::l_paren)) ||
@@ -2625,9 +2642,8 @@
       !Style.ConstructorInitializerAllOnOneLineOrOnePerLine)
     return true;
   // Break only if we have multiple inheritance.
-  if (Style.BreakBeforeInheritanceComma &&
-      Right.is(TT_InheritanceComma))
-   return true;
+  if (Style.BreakBeforeInheritanceComma && Right.is(TT_InheritanceComma))
+    return true;
   if (Right.is(tok::string_literal) && Right.TokenText.startswith("R\""))
     // Raw string literals are special wrt. line breaks. The author has made a
     // deliberate choice and might have aligned the contents of the string
@@ -2634,10 +2650,8 @@
     // literal accordingly. Thus, we try keep existing line breaks.
     return Right.NewlinesBefore > 0;
   if ((Right.Previous->is(tok::l_brace) ||
-       (Right.Previous->is(tok::less) &&
-        Right.Previous->Previous &&
-        Right.Previous->Previous->is(tok::equal))
-        ) &&
+       (Right.Previous->is(tok::less) && Right.Previous->Previous &&
+        Right.Previous->Previous->is(tok::equal))) &&
       Right.NestingLevel == 1 && Style.Language == FormatStyle::LK_Proto) {
     // Don't put enums or option definitions onto single lines in protocol
     // buffers.
@@ -2740,8 +2754,7 @@
     // list.
     return Left.BlockKind == BK_BracedInit ||
            (Left.is(TT_CtorInitializerColon) &&
-            Style.BreakConstructorInitializers ==
-                FormatStyle::BCIS_AfterColon);
+            Style.BreakConstructorInitializers == FormatStyle::BCIS_AfterColon);
   if (Left.is(tok::question) && Right.is(tok::colon))
     return false;
   if (Right.is(TT_ConditionalExpr) || Right.is(tok::question))
@@ -2866,10 +2879,9 @@
                  << " T=" << getTokenTypeName(Tok->Type)
                  << " S=" << Tok->SpacesRequiredBefore
                  << " B=" << Tok->BlockParameterCount
-                 << " BK=" << Tok->BlockKind
-                 << " P=" << Tok->SplitPenalty << " Name=" << Tok->Tok.getName()
-                 << " L=" << Tok->TotalLength << " PPK=" << Tok->PackingKind
-                 << " FakeLParens=";
+                 << " BK=" << Tok->BlockKind << " P=" << Tok->SplitPenalty
+                 << " Name=" << Tok->Tok.getName() << " L=" << Tok->TotalLength
+                 << " PPK=" << Tok->PackingKind << " FakeLParens=";
     for (unsigned i = 0, e = Tok->FakeLParens.size(); i != e; ++i)
       llvm::errs() << Tok->FakeLParens[i] << "/";
     llvm::errs() << " FakeRParens=" << Tok->FakeRParens;
Index: lib/Format/FormatToken.h
===================================================================
--- lib/Format/FormatToken.h
+++ lib/Format/FormatToken.h
@@ -84,6 +84,7 @@
   TYPE(RegexLiteral) \
   TYPE(SelectorName) \
   TYPE(StartOfName) \
+  TYPE(StructuredBindingLSquare) \
   TYPE(TemplateCloser) \
   TYPE(TemplateOpener) \
   TYPE(TemplateString) \
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to