Skip to content

Commit c28e268

Browse files
authored
[clang-format] Correctly annotate pointer/reference in if statement (#109370)
Fixes #60146.
1 parent 4fd14b9 commit c28e268

File tree

2 files changed

+27
-21
lines changed

2 files changed

+27
-21
lines changed

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ class AnnotatingParser {
300300
return false;
301301
}
302302

303-
bool parseParens(bool LookForDecls = false) {
303+
bool parseParens(bool IsIf = false) {
304304
if (!CurrentToken)
305305
return false;
306306
assert(CurrentToken->Previous && "Unknown previous token");
@@ -468,24 +468,6 @@ class AnnotatingParser {
468468
OpeningParen.Previous && OpeningParen.Previous->is(tok::kw_for);
469469
FormatToken *PossibleObjCForInToken = nullptr;
470470
while (CurrentToken) {
471-
// LookForDecls is set when "if (" has been seen. Check for
472-
// 'identifier' '*' 'identifier' followed by not '=' -- this
473-
// '*' has to be a binary operator but determineStarAmpUsage() will
474-
// categorize it as an unary operator, so set the right type here.
475-
if (LookForDecls && CurrentToken->Next) {
476-
FormatToken *Prev = CurrentToken->getPreviousNonComment();
477-
if (Prev) {
478-
FormatToken *PrevPrev = Prev->getPreviousNonComment();
479-
FormatToken *Next = CurrentToken->Next;
480-
if (PrevPrev && PrevPrev->is(tok::identifier) &&
481-
PrevPrev->isNot(TT_TypeName) && Prev->isPointerOrReference() &&
482-
CurrentToken->is(tok::identifier) && Next->isNot(tok::equal)) {
483-
Prev->setType(TT_BinaryOperator);
484-
LookForDecls = false;
485-
}
486-
}
487-
}
488-
489471
if (CurrentToken->Previous->is(TT_PointerOrReference) &&
490472
CurrentToken->Previous->Previous->isOneOf(tok::l_paren,
491473
tok::coloncolon)) {
@@ -581,6 +563,15 @@ class AnnotatingParser {
581563
PossibleObjCForInToken = nullptr;
582564
}
583565
}
566+
if (IsIf && CurrentToken->is(tok::semi)) {
567+
for (auto *Tok = OpeningParen.Next;
568+
Tok != CurrentToken &&
569+
!Tok->isOneOf(tok::equal, tok::l_paren, tok::l_brace);
570+
Tok = Tok->Next) {
571+
if (Tok->isPointerOrReference())
572+
Tok->setFinalizedType(TT_PointerOrReference);
573+
}
574+
}
584575
if (MightBeObjCForRangeLoop && CurrentToken->is(Keywords.kw_in)) {
585576
PossibleObjCForInToken = CurrentToken;
586577
PossibleObjCForInToken->setType(TT_ObjCForIn);
@@ -1307,7 +1298,7 @@ class AnnotatingParser {
13071298
// Multi-line string itself is a single annotated token.
13081299
if (Tok->is(TT_TableGenMultiLineString))
13091300
return true;
1310-
switch (Tok->Tok.getKind()) {
1301+
switch (bool IsIf = false; Tok->Tok.getKind()) {
13111302
case tok::plus:
13121303
case tok::minus:
13131304
if (!Tok->Previous && Line.MustBeDeclaration)
@@ -1467,11 +1458,12 @@ class AnnotatingParser {
14671458
CurrentToken->isOneOf(tok::kw_constexpr, tok::identifier)) {
14681459
next();
14691460
}
1461+
IsIf = true;
14701462
[[fallthrough]];
14711463
case tok::kw_while:
14721464
if (CurrentToken && CurrentToken->is(tok::l_paren)) {
14731465
next();
1474-
if (!parseParens(/*LookForDecls=*/true))
1466+
if (!parseParens(IsIf))
14751467
return false;
14761468
}
14771469
break;

clang/unittests/Format/TokenAnnotatorTest.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,20 @@ TEST_F(TokenAnnotatorTest, UnderstandsUsesOfStarAndAmp) {
294294
EXPECT_TOKEN(Tokens[7], tok::ampamp, TT_BinaryOperator);
295295
EXPECT_TOKEN(Tokens[10], tok::greater, TT_BinaryOperator);
296296

297+
Tokens = annotate("if (Foo *foo; bar)");
298+
ASSERT_EQ(Tokens.size(), 9u) << Tokens;
299+
EXPECT_TOKEN(Tokens[3], tok::star, TT_PointerOrReference);
300+
301+
Tokens = annotate("if (Foo **foo(); bar)");
302+
ASSERT_EQ(Tokens.size(), 12u) << Tokens;
303+
EXPECT_TOKEN(Tokens[3], tok::star, TT_PointerOrReference);
304+
EXPECT_TOKEN(Tokens[4], tok::star, TT_PointerOrReference);
305+
306+
Tokens = annotate("if (Foo *&foo{a}; bar)");
307+
ASSERT_EQ(Tokens.size(), 13u) << Tokens;
308+
EXPECT_TOKEN(Tokens[3], tok::star, TT_PointerOrReference);
309+
EXPECT_TOKEN(Tokens[4], tok::amp, TT_PointerOrReference);
310+
297311
FormatStyle Style = getLLVMStyle();
298312
Style.TypeNames.push_back("MYI");
299313
Tokens = annotate("if (MYI *p{nullptr})", Style);

0 commit comments

Comments
 (0)