summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2016-11-10 21:49:25 +0000
committerNico Weber <nicolasweber@gmx.de>2016-11-10 21:49:25 +0000
commitb2673a1e48077f6c016269f5f4f2e8ae311b1244 (patch)
tree88d768b332c5f32cb1cbda19c8897590690e329a
parent0d546534d3e7ecc85afc75dabc3b5b3831298afb (diff)
downloadbcm5719-llvm-b2673a1e48077f6c016269f5f4f2e8ae311b1244.tar.gz
bcm5719-llvm-b2673a1e48077f6c016269f5f4f2e8ae311b1244.zip
[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@kokanovic.org>! llvm-svn: 286507
-rw-r--r--clang/lib/Format/TokenAnnotator.cpp14
-rw-r--r--clang/unittests/Format/FormatTest.cpp20
2 files changed, 32 insertions, 2 deletions
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 893e5fa65d4..d64daa66875 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -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,
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index f526d458437..0056436e537 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -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__)
OpenPOWER on IntegriCloud