yawanng updated this revision to Diff 109222.
yawanng added a comment.
Move tests to unitest and fix a bug.
https://reviews.llvm.org/D35743
Files:
lib/Format/TokenAnnotator.cpp
lib/Format/UnwrappedLineParser.cpp
lib/Format/UnwrappedLineParser.h
unittests/Format/FormatTest.cpp
Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -11085,6 +11085,41 @@
EXPECT_EQ("auto c = u8'a';", format("auto c = u8'a';"));
}
+TEST_F(FormatTest, StructuredBindingDeclaration) {
+ // structured-binding-declaration is a C++17 feature.
+ EXPECT_EQ("auto [x, y] = a;", format("auto[x, y] = a;"));
+ EXPECT_EQ("auto &[x, y] = a;", format("auto & [x, y] = a;"));
+ EXPECT_EQ("auto &&[x, y] = a;", format("auto && [x, y] = a;"));
+ EXPECT_EQ("auto &&[x, y] = a;", format("auto && [x, y] = a;"));
+ EXPECT_EQ("auto [x] = a;", format("auto[x] = a;"));
+ EXPECT_EQ("auto &[x] = a;", format("auto & [x] = a;"));
+ EXPECT_EQ("auto &&[x] = a;", format("auto && [x] = a;"));
+ EXPECT_EQ("const auto [x, y] = f();", format("const auto[x, y] = f();"));
+ EXPECT_EQ("const auto &[x, y] = f();", format("const auto & [x, y] = f();"));
+ EXPECT_EQ("const auto &&[x, y] = f();", format("const auto && [x, y] = f();"));
+ EXPECT_EQ("auto [x, y] = A{};", format("auto[x,y] = A{};"));
+ EXPECT_EQ("auto &[x, y] = A{};", format("auto & [x,y] = A{};"));
+ EXPECT_EQ("auto &&[x, y] = A{};", format("auto && [x,y] = A{};"));
+ EXPECT_EQ("for (const auto &&[a, b] : some_range) {\n"
+ "}",
+ format("for (const auto && [a, b] : some_range) {\n"
+ "}"));
+ EXPECT_EQ("for (const auto &[a, b] : some_range) {\n"
+ "}",
+ format("for (const auto & [a, b] : some_range) {\n"
+ "}"));
+ EXPECT_EQ("for (const auto [a, b] : some_range) {\n"
+ "}",
+ format("for (const auto[a, b] : some_range) {\n"
+ "}"));
+ EXPECT_EQ("auto [x, y](expr);", format("auto[x,y] (expr);"));
+ EXPECT_EQ("auto &[x, y](expr);", format("auto & [x,y] (expr);"));
+ EXPECT_EQ("auto &&[x, y](expr);", format("auto && [x,y] (expr);"));
+ EXPECT_EQ("auto [x, y]{expr};", format("auto[x,y] {expr};"));
+ EXPECT_EQ("auto &[x, y]{expr};", format("auto & [x,y] {expr};"));
+ EXPECT_EQ("auto &&[x, y]{expr};", format("auto && [x,y] {expr};"));
+}
+
} // end namespace
} // end namespace format
} // end namespace clang
Index: lib/Format/UnwrappedLineParser.h
===================================================================
--- lib/Format/UnwrappedLineParser.h
+++ lib/Format/UnwrappedLineParser.h
@@ -125,6 +125,7 @@
bool eof() const;
void nextToken();
const FormatToken *getPreviousToken();
+ const FormatToken *getPrePreviousToken();
void readToken();
// Decides which comment tokens should be added to the current line and which
Index: lib/Format/UnwrappedLineParser.cpp
===================================================================
--- lib/Format/UnwrappedLineParser.cpp
+++ lib/Format/UnwrappedLineParser.cpp
@@ -1211,9 +1211,12 @@
return false;
}
const FormatToken* Previous = getPreviousToken();
+ const FormatToken* PrePrevious = getPrePreviousToken();
if (Previous &&
(Previous->isOneOf(tok::identifier, tok::kw_operator, tok::kw_new,
- tok::kw_delete) ||
+ tok::kw_delete, tok::kw_auto) ||
+ (PrePrevious && Previous->isOneOf(tok::amp, tok::ampamp) &&
+ PrePrevious->is(tok::kw_auto)) ||
Previous->closesScope() || Previous->isSimpleTypeSpecifier())) {
nextToken();
return false;
@@ -2306,6 +2309,12 @@
return Line->Tokens.back().Tok;
}
+const FormatToken *UnwrappedLineParser::getPrePreviousToken() {
+ if (!Line || Line->Tokens.size() < 2)
+ return nullptr;
+ return std::prev(Line->Tokens.end(), 2)->Tok;
+}
+
void UnwrappedLineParser::distributeComments(
const SmallVectorImpl<FormatToken *> &Comments,
const FormatToken *NextTok) {
Index: lib/Format/TokenAnnotator.cpp
===================================================================
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -330,8 +330,15 @@
(Contexts.back().CanBeExpression || Contexts.back().IsExpression ||
Contexts.back().InTemplateArgument);
+ bool CppStructuredBindingDecl =
+ !CppArrayTemplates && Style.isCpp() && Parent &&
+ (Parent->is(tok::kw_auto) ||
+ (Parent->isOneOf(tok::amp, tok::ampamp) &&
+ Parent->getPreviousNonComment() &&
+ Parent->getPreviousNonComment()->is(tok::kw_auto)));
+
bool StartsObjCMethodExpr =
- !CppArrayTemplates && Style.isCpp() &&
+ !CppStructuredBindingDecl && !CppArrayTemplates && Style.isCpp() &&
Contexts.back().CanBeExpression && Left->isNot(TT_LambdaLSquare) &&
CurrentToken->isNot(tok::l_brace) &&
(!Parent ||
@@ -344,7 +351,9 @@
unsigned BindingIncrease = 1;
if (Left->is(TT_Unknown)) {
- if (StartsObjCMethodExpr) {
+ if (CppStructuredBindingDecl) {
+ Left->Type = TT_ArraySubscriptLSquare;
+ } else if (StartsObjCMethodExpr) {
Left->Type = TT_ObjCMethodExpr;
} else if (Style.Language == FormatStyle::LK_JavaScript && Parent &&
Contexts.back().ContextKind == tok::l_brace &&
@@ -2150,6 +2159,8 @@
bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
const FormatToken &Left,
const FormatToken &Right) {
+ if (Left.is(tok::kw_auto) && Right.is(TT_ArraySubscriptLSquare))
+ return true;
if (Left.is(tok::kw_return) && Right.isNot(tok::semi))
return true;
if (Style.ObjCSpaceAfterProperty && Line.Type == LT_ObjCProperty &&
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits