Fix clang-format's detection of structured bindings.
Correctly determine when [ is part of a structured binding instead of a
lambda.
To be able to reuse the implementation already available, this patch also:
- sets the Previous link of FormatTokens in the UnwrappedLineParser
- moves the isCppStructuredBinding function into FormatToken
Before:
auto const const &&[x, y] { A *i };
After:
auto const const && [x, y]{A * i};
Fixing formatting of the type of the structured binding is still missing.
llvm-svn: 313742
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index 8722d80..1e6a6aa 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -356,7 +356,7 @@
// definitions, too.
unsigned StoredPosition = Tokens->getPosition();
FormatToken *Tok = FormatTok;
- const FormatToken *PrevTok = getPreviousToken();
+ const FormatToken *PrevTok = Tok->Previous;
// Keep a stack of positions of lbrace tokens. We will
// update information about whether an lbrace starts a
// braced init list or a different block during the loop.
@@ -1100,7 +1100,7 @@
break;
}
do {
- const FormatToken *Previous = getPreviousToken();
+ const FormatToken *Previous = FormatTok->Previous;
switch (FormatTok->Tok.getKind()) {
case tok::at:
nextToken();
@@ -1356,10 +1356,11 @@
}
bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
- const FormatToken* Previous = getPreviousToken();
+ const FormatToken* Previous = FormatTok->Previous;
if (Previous &&
(Previous->isOneOf(tok::identifier, tok::kw_operator, tok::kw_new,
tok::kw_delete) ||
+ FormatTok->isCppStructuredBinding(Style) ||
Previous->closesScope() || Previous->isSimpleTypeSpecifier())) {
nextToken();
return false;
@@ -2232,6 +2233,8 @@
std::make_move_iterator(PreprocessorDirectives.end()));
PreprocessorDirectives.clear();
}
+ // Disconnect the current token from the last token on the previous line.
+ FormatTok->Previous = nullptr;
}
bool UnwrappedLineParser::eof() const { return FormatTok->Tok.is(tok::eof); }
@@ -2378,18 +2381,12 @@
return;
flushComments(isOnNewLine(*FormatTok));
pushToken(FormatTok);
+ FormatToken* Previous = FormatTok;
if (Style.Language != FormatStyle::LK_JavaScript)
readToken(LevelDifference);
else
readTokenWithJavaScriptASI();
-}
-
-const FormatToken *UnwrappedLineParser::getPreviousToken() {
- // FIXME: This is a dirty way to access the previous token. Find a better
- // solution.
- if (!Line || Line->Tokens.empty())
- return nullptr;
- return Line->Tokens.back().Tok;
+ FormatTok->Previous = Previous;
}
void UnwrappedLineParser::distributeComments(