r286507 - [clang-format] Fix PR30527: Regression when clang-format insert spaces in [] when in template

Nico Weber via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 10 13:49:25 PST 2016


Author: nico
Date: Thu Nov 10 15:49:25 2016
New Revision: 286507

URL: http://llvm.org/viewvc/llvm-project?rev=286507&view=rev
Log:
[clang-format] Fix PR30527: Regression when clang-format insert spaces in [] when in template

Actual regression was introduced in r272668. This revision fixes JS script, but
also regress Cpp case. It manifests with spaces added when template is followed
with array. Bug 30527 mentions case of array as a nested template type
(foo<bar<baz>[]>). Fix is to detect such case and to prevent treating it as
array initialization, but as a subscript case. However, before r272668, this
case was treated simple because we were detecting it as a StartsObjCMethodExpr.
Same was true for other similar case - array of templates (foo<int>[]). This
patch tries to address two problems: 1) fixing regression 2) making sure both
cases (array as a nested type, array of templates) which were entering
StartsObjCMethodExpr branch are handled now appropriately.

https://reviews.llvm.org/D26163
Patch from Branko Kokanovic <branko at kokanovic.org>!

Modified:
    cfe/trunk/lib/Format/TokenAnnotator.cpp
    cfe/trunk/unittests/Format/FormatTest.cpp

Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=286507&r1=286506&r2=286507&view=diff
==============================================================================
--- cfe/trunk/lib/Format/TokenAnnotator.cpp (original)
+++ cfe/trunk/lib/Format/TokenAnnotator.cpp Thu Nov 10 15:49:25 2016
@@ -306,7 +306,17 @@ private:
     FormatToken *Left = CurrentToken->Previous;
     Left->ParentBracket = Contexts.back().ContextKind;
     FormatToken *Parent = Left->getPreviousNonComment();
-    bool StartsObjCMethodExpr =
+
+    // Cases where '>' is followed by '['.
+    // 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.Language == FormatStyle::LK_Cpp && Parent &&
+        Parent->is(TT_TemplateCloser) &&
+        (Contexts.back().CanBeExpression || Contexts.back().IsExpression ||
+         Contexts.back().InTemplateArgument);
+
+    bool StartsObjCMethodExpr = !CppArrayTemplates &&
         Style.Language == FormatStyle::LK_Cpp &&
         Contexts.back().CanBeExpression && Left->isNot(TT_LambdaLSquare) &&
         CurrentToken->isNot(tok::l_brace) &&
@@ -327,7 +337,7 @@ private:
                  Parent->isOneOf(tok::l_brace, tok::comma)) {
         Left->Type = TT_JsComputedPropertyName;
       } else if (Style.Language == FormatStyle::LK_Proto ||
-                 (Parent &&
+                 (!CppArrayTemplates && Parent &&
                   Parent->isOneOf(TT_BinaryOperator, TT_TemplateCloser, tok::at,
                                   tok::comma, tok::l_paren, tok::l_square,
                                   tok::question, tok::colon, tok::kw_return,

Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=286507&r1=286506&r2=286507&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Thu Nov 10 15:49:25 2016
@@ -11544,6 +11544,26 @@ TEST_F(FormatTest, FormatsTableGenCode)
   verifyFormat("include \"a.td\"\ninclude \"b.td\"", Style);
 }
 
+TEST_F(FormatTest, ArrayOfTemplates) {
+  EXPECT_EQ("auto a = new unique_ptr<int>[10];",
+            format("auto a = new unique_ptr<int > [ 10];"));
+
+  FormatStyle Spaces = getLLVMStyle();
+  Spaces.SpacesInSquareBrackets = true;
+  EXPECT_EQ("auto a = new unique_ptr<int>[ 10 ];",
+            format("auto a = new unique_ptr<int > [10];", Spaces));
+}
+
+TEST_F(FormatTest, ArrayAsTemplateType) {
+  EXPECT_EQ("auto a = unique_ptr<Foo<Bar>[10]>;",
+            format("auto a = unique_ptr < Foo < Bar>[ 10]> ;"));
+
+  FormatStyle Spaces = getLLVMStyle();
+  Spaces.SpacesInSquareBrackets = true;
+  EXPECT_EQ("auto a = unique_ptr<Foo<Bar>[ 10 ]>;",
+            format("auto a = unique_ptr < Foo < Bar>[10]> ;", Spaces));
+}
+
 // Since this test case uses UNIX-style file path. We disable it for MS
 // compiler.
 #if !defined(_MSC_VER) && !defined(__MINGW32__)




More information about the cfe-commits mailing list