Skip to content

Commit 41e817a

Browse files
owencadyung
authored andcommitted
release/21.x: [clang-format] Fix bugs in annotating arrows and square brackets (llvm#160973)
Backport 4edda3d
1 parent 559d966 commit 41e817a

File tree

3 files changed

+27
-17
lines changed

3 files changed

+27
-17
lines changed

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -829,11 +829,6 @@ class AnnotatingParser {
829829
if (Parent && Parent->is(TT_PointerOrReference))
830830
Parent->overwriteFixedType(TT_BinaryOperator);
831831
}
832-
// An arrow after an ObjC method expression is not a lambda arrow.
833-
if (CurrentToken->is(TT_ObjCMethodExpr) && CurrentToken->Next &&
834-
CurrentToken->Next->is(TT_LambdaArrow)) {
835-
CurrentToken->Next->overwriteFixedType(TT_Unknown);
836-
}
837832
Left->MatchingParen = CurrentToken;
838833
CurrentToken->MatchingParen = Left;
839834
// FirstObjCSelectorName is set when a colon is found. This does

clang/lib/Format/UnwrappedLineParser.cpp

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2266,7 +2266,7 @@ bool UnwrappedLineParser::tryToParseLambda() {
22662266
if (!tryToParseLambdaIntroducer())
22672267
return false;
22682268

2269-
bool SeenArrow = false;
2269+
FormatToken *Arrow = nullptr;
22702270
bool InTemplateParameterList = false;
22712271

22722272
while (FormatTok->isNot(tok::l_brace)) {
@@ -2341,17 +2341,13 @@ bool UnwrappedLineParser::tryToParseLambda() {
23412341
case tok::ellipsis:
23422342
case tok::kw_true:
23432343
case tok::kw_false:
2344-
if (SeenArrow || InTemplateParameterList) {
2344+
if (Arrow || InTemplateParameterList) {
23452345
nextToken();
23462346
break;
23472347
}
23482348
return true;
23492349
case tok::arrow:
2350-
// This might or might not actually be a lambda arrow (this could be an
2351-
// ObjC method invocation followed by a dereferencing arrow). We might
2352-
// reset this back to TT_Unknown in TokenAnnotator.
2353-
FormatTok->setFinalizedType(TT_LambdaArrow);
2354-
SeenArrow = true;
2350+
Arrow = FormatTok;
23552351
nextToken();
23562352
break;
23572353
case tok::kw_requires: {
@@ -2373,6 +2369,9 @@ bool UnwrappedLineParser::tryToParseLambda() {
23732369
FormatTok->setFinalizedType(TT_LambdaLBrace);
23742370
LSquare.setFinalizedType(TT_LambdaLSquare);
23752371

2372+
if (Arrow)
2373+
Arrow->setFinalizedType(TT_LambdaArrow);
2374+
23762375
NestedLambdas.push_back(Line->SeenDecltypeAuto);
23772376
parseChildBlock();
23782377
assert(!NestedLambdas.empty());
@@ -2386,11 +2385,6 @@ bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
23862385
const FormatToken *LeftSquare = FormatTok;
23872386
nextToken();
23882387
if (Previous) {
2389-
if (Previous->Tok.getIdentifierInfo() &&
2390-
!Previous->isOneOf(tok::kw_return, tok::kw_co_await, tok::kw_co_yield,
2391-
tok::kw_co_return)) {
2392-
return false;
2393-
}
23942388
if (Previous->closesScope()) {
23952389
// Not a potential C-style cast.
23962390
if (Previous->isNot(tok::r_paren))
@@ -2400,6 +2394,13 @@ bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
24002394
// and `int (*)()`.
24012395
if (!BeforeRParen || !BeforeRParen->isOneOf(tok::greater, tok::r_paren))
24022396
return false;
2397+
} else if (Previous->is(tok::star)) {
2398+
Previous = Previous->getPreviousNonComment();
2399+
}
2400+
if (Previous && Previous->Tok.getIdentifierInfo() &&
2401+
!Previous->isOneOf(tok::kw_return, tok::kw_co_await, tok::kw_co_yield,
2402+
tok::kw_co_return)) {
2403+
return false;
24032404
}
24042405
}
24052406
if (LeftSquare->isCppStructuredBinding(IsCpp))

clang/unittests/Format/TokenAnnotatorTest.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2229,6 +2229,12 @@ TEST_F(TokenAnnotatorTest, UnderstandsLambdas) {
22292229
ASSERT_EQ(Tokens.size(), 21u) << Tokens;
22302230
EXPECT_TOKEN(Tokens[11], tok::l_square, TT_LambdaLSquare);
22312231
EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_LambdaLBrace);
2232+
2233+
Tokens = annotate("SomeFunction({[]() -> int *[] { return {}; }});");
2234+
ASSERT_EQ(Tokens.size(), 22u) << Tokens;
2235+
EXPECT_TOKEN(Tokens[3], tok::l_square, TT_LambdaLSquare);
2236+
EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_LambdaDefinitionLParen);
2237+
EXPECT_TOKEN(Tokens[10], tok::l_square, TT_ArraySubscriptLSquare);
22322238
}
22332239

22342240
TEST_F(TokenAnnotatorTest, UnderstandsFunctionAnnotations) {
@@ -4151,6 +4157,14 @@ TEST_F(TokenAnnotatorTest, LineCommentTrailingBackslash) {
41514157
EXPECT_TOKEN(Tokens[1], tok::comment, TT_LineComment);
41524158
}
41534159

4160+
TEST_F(TokenAnnotatorTest, ArrowAfterSubscript) {
4161+
auto Tokens =
4162+
annotate("return (getStructType()->getElements())[eIdx]->getName();");
4163+
ASSERT_EQ(Tokens.size(), 19u) << Tokens;
4164+
// Not TT_LambdaArrow.
4165+
EXPECT_TOKEN(Tokens[13], tok::arrow, TT_Unknown);
4166+
}
4167+
41544168
} // namespace
41554169
} // namespace format
41564170
} // namespace clang

0 commit comments

Comments
 (0)