[clang] [clang-format] Fix bugs in annotating arrows and square brackets (PR #160973)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Sep 27 20:18:26 PDT 2025
https://github.com/owenca updated https://github.com/llvm/llvm-project/pull/160973
>From ec8aadf1ec05897667e1c9df60ac9845d45f955a Mon Sep 17 00:00:00 2001
From: Owen Pan <owenpiano at gmail.com>
Date: Fri, 26 Sep 2025 19:42:46 -0700
Subject: [PATCH 1/3] [clang-format] Fix bugs in annotating arrows and square
brackets
Fixes #160518
---
clang/lib/Format/TokenAnnotator.cpp | 5 ----
clang/lib/Format/UnwrappedLineParser.cpp | 25 ++++++++++---------
clang/unittests/Format/TokenAnnotatorTest.cpp | 16 +++++++++++-
3 files changed, 28 insertions(+), 18 deletions(-)
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 4bfb803ebedf7..94bfd4106c480 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -833,11 +833,6 @@ class AnnotatingParser {
if (Parent && Parent->is(TT_PointerOrReference))
Parent->overwriteFixedType(TT_BinaryOperator);
}
- // An arrow after an ObjC method expression is not a lambda arrow.
- if (CurrentToken->is(TT_ObjCMethodExpr) && CurrentToken->Next &&
- CurrentToken->Next->is(TT_LambdaArrow)) {
- CurrentToken->Next->overwriteFixedType(TT_Unknown);
- }
Left->MatchingParen = CurrentToken;
CurrentToken->MatchingParen = Left;
// FirstObjCSelectorName is set when a colon is found. This does
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index 2c9766c9b7bc0..38d0cb3dc0591 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -2268,7 +2268,7 @@ bool UnwrappedLineParser::tryToParseLambda() {
if (!tryToParseLambdaIntroducer())
return false;
- bool SeenArrow = false;
+ FormatToken *Arrow = nullptr;
bool InTemplateParameterList = false;
while (FormatTok->isNot(tok::l_brace)) {
@@ -2343,17 +2343,13 @@ bool UnwrappedLineParser::tryToParseLambda() {
case tok::ellipsis:
case tok::kw_true:
case tok::kw_false:
- if (SeenArrow || InTemplateParameterList) {
+ if (Arrow || InTemplateParameterList) {
nextToken();
break;
}
return true;
case tok::arrow:
- // This might or might not actually be a lambda arrow (this could be an
- // ObjC method invocation followed by a dereferencing arrow). We might
- // reset this back to TT_Unknown in TokenAnnotator.
- FormatTok->setFinalizedType(TT_LambdaArrow);
- SeenArrow = true;
+ Arrow = FormatTok;
nextToken();
break;
case tok::kw_requires: {
@@ -2375,6 +2371,9 @@ bool UnwrappedLineParser::tryToParseLambda() {
FormatTok->setFinalizedType(TT_LambdaLBrace);
LSquare.setFinalizedType(TT_LambdaLSquare);
+ if (Arrow)
+ Arrow->setFinalizedType(TT_LambdaArrow);
+
NestedLambdas.push_back(Line->SeenDecltypeAuto);
parseChildBlock();
assert(!NestedLambdas.empty());
@@ -2388,11 +2387,6 @@ bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
const FormatToken *LeftSquare = FormatTok;
nextToken();
if (Previous) {
- if (Previous->Tok.getIdentifierInfo() &&
- !Previous->isOneOf(tok::kw_return, tok::kw_co_await, tok::kw_co_yield,
- tok::kw_co_return)) {
- return false;
- }
if (Previous->closesScope()) {
// Not a potential C-style cast.
if (Previous->isNot(tok::r_paren))
@@ -2403,6 +2397,13 @@ bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
if (!BeforeRParen || !BeforeRParen->isOneOf(tok::greater, tok::r_paren))
return false;
}
+ if (Previous->is(tok::star))
+ Previous = Previous->Previous;
+ if (Previous && Previous->Tok.getIdentifierInfo() &&
+ !Previous->isOneOf(tok::kw_return, tok::kw_co_await, tok::kw_co_yield,
+ tok::kw_co_return)) {
+ return false;
+ }
}
if (LeftSquare->isCppStructuredBinding(IsCpp))
return false;
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp
index 4c43a963632a6..4a8f27f656f1d 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -2237,6 +2237,12 @@ TEST_F(TokenAnnotatorTest, UnderstandsLambdas) {
ASSERT_EQ(Tokens.size(), 21u) << Tokens;
EXPECT_TOKEN(Tokens[11], tok::l_square, TT_LambdaLSquare);
EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_LambdaLBrace);
+
+ Tokens = annotate("SomeFunction({[]() -> int *[] { return {}; }});");
+ ASSERT_EQ(Tokens.size(), 22u) << Tokens;
+ EXPECT_TOKEN(Tokens[3], tok::l_square, TT_LambdaLSquare);
+ EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_LambdaDefinitionLParen);
+ EXPECT_TOKEN(Tokens[10], tok::l_square, TT_ArraySubscriptLSquare);
}
TEST_F(TokenAnnotatorTest, UnderstandsFunctionAnnotations) {
@@ -4159,7 +4165,15 @@ TEST_F(TokenAnnotatorTest, LineCommentTrailingBackslash) {
EXPECT_TOKEN(Tokens[1], tok::comment, TT_LineComment);
}
-TEST_F(TokenAnnotatorTest, KeywordedFunctionLikeMacro) {
+TEST_F(TokenAnnotatorTest, ArrowAfterSubscript) {
+ auto Tokens =
+ annotate("return (getStructType()->getElements())[eIdx]->getName();");
+ ASSERT_EQ(Tokens.size(), 19u) << Tokens;
+ // Not TT_LambdaArrow.
+ EXPECT_TOKEN(Tokens[13], tok::arrow, TT_Unknown);
+}
+
+TEST_F(TokenAnnotatorTest, QtProperty) {
auto Style = getLLVMStyle();
Style.AllowBreakBeforeQtProperty = true;
>From 3499a530af07976e36f1110a4f75d5278d738d5e Mon Sep 17 00:00:00 2001
From: owenca <owenpiano at gmail.com>
Date: Sat, 27 Sep 2025 12:27:19 -0700
Subject: [PATCH 2/3] Update TokenAnnotatorTest.cpp
---
clang/unittests/Format/TokenAnnotatorTest.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp
index 4a8f27f656f1d..a5514d56f969b 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -4173,7 +4173,7 @@ TEST_F(TokenAnnotatorTest, ArrowAfterSubscript) {
EXPECT_TOKEN(Tokens[13], tok::arrow, TT_Unknown);
}
-TEST_F(TokenAnnotatorTest, QtProperty) {
+TEST_F(TokenAnnotatorTest, KeywordedFunctionLikeMacro) {
auto Style = getLLVMStyle();
Style.AllowBreakBeforeQtProperty = true;
>From f34b8f5913be811a2fba14292b6c1360ebdde1ae Mon Sep 17 00:00:00 2001
From: owenca <owenpiano at gmail.com>
Date: Sat, 27 Sep 2025 20:18:17 -0700
Subject: [PATCH 3/3] Update UnwrappedLineParser.cpp
---
clang/lib/Format/UnwrappedLineParser.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index 38d0cb3dc0591..6948b3de1e408 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -2396,9 +2396,9 @@ bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
// and `int (*)()`.
if (!BeforeRParen || !BeforeRParen->isOneOf(tok::greater, tok::r_paren))
return false;
+ } else if (Previous->is(tok::star)) {
+ Previous = Previous->getPreviousNonComment();
}
- if (Previous->is(tok::star))
- Previous = Previous->Previous;
if (Previous && Previous->Tok.getIdentifierInfo() &&
!Previous->isOneOf(tok::kw_return, tok::kw_co_await, tok::kw_co_yield,
tok::kw_co_return)) {
More information about the cfe-commits
mailing list