r312723 - [clang-format] Add support for C++17 structured bindings.
Marek Kurdej via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 7 07:28:32 PDT 2017
Author: mkurdej
Date: Thu Sep 7 07:28:32 2017
New Revision: 312723
URL: http://llvm.org/viewvc/llvm-project?rev=312723&view=rev
Log:
[clang-format] Add support for C++17 structured bindings.
Summary:
Before:
```
auto[a, b] = f();
```
After:
```
auto [a, b] = f();
```
or, if SpacesInSquareBrackets is true:
```
auto [ a, b ] = f();
```
Reviewers: djasper
Reviewed By: djasper
Subscribers: cfe-commits, klimek
Differential Revision: https://reviews.llvm.org/D37132
Modified:
cfe/trunk/lib/Format/FormatToken.h
cfe/trunk/lib/Format/TokenAnnotator.cpp
cfe/trunk/unittests/Format/FormatTest.cpp
Modified: cfe/trunk/lib/Format/FormatToken.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatToken.h?rev=312723&r1=312722&r2=312723&view=diff
==============================================================================
--- cfe/trunk/lib/Format/FormatToken.h (original)
+++ cfe/trunk/lib/Format/FormatToken.h Thu Sep 7 07:28:32 2017
@@ -84,6 +84,7 @@ namespace format {
TYPE(RegexLiteral) \
TYPE(SelectorName) \
TYPE(StartOfName) \
+ TYPE(StructuredBindingLSquare) \
TYPE(TemplateCloser) \
TYPE(TemplateOpener) \
TYPE(TemplateString) \
Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=312723&r1=312722&r2=312723&view=diff
==============================================================================
--- cfe/trunk/lib/Format/TokenAnnotator.cpp (original)
+++ cfe/trunk/lib/Format/TokenAnnotator.cpp Thu Sep 7 07:28:32 2017
@@ -310,6 +310,16 @@ private:
return false;
}
+ bool isCppStructuredBinding(const FormatToken *Tok) {
+ if (!Style.isCpp() || !Tok->is(tok::l_square))
+ return false;
+ do {
+ Tok = Tok->getPreviousNonComment();
+ } while (Tok && Tok->isOneOf(tok::kw_const, tok::kw_volatile, tok::amp,
+ tok::ampamp));
+ return Tok && Tok->is(tok::kw_auto);
+ }
+
bool parseSquare() {
if (!CurrentToken)
return false;
@@ -344,7 +354,9 @@ private:
unsigned BindingIncrease = 1;
if (Left->is(TT_Unknown)) {
- if (StartsObjCMethodExpr) {
+ if (isCppStructuredBinding(Left)) {
+ 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 &&
@@ -2261,17 +2273,20 @@ bool TokenAnnotator::spaceRequiredBetwee
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))
Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=312723&r1=312722&r2=312723&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Thu Sep 7 07:28:32 2017
@@ -11452,6 +11452,31 @@ TEST_F(FormatTest, DoNotFormatLikelyXml)
format(" <!-- >; -->", getGoogleStyle()));
}
+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
More information about the cfe-commits
mailing list