https://github.com/Nikunj-Pokharel created https://github.com/llvm/llvm-project/pull/235319
Fixes #225876 When PointerAlignment: Left is set, clang-format can incorrectly format the & operator when the right-hand side is a qualified function call. For example, a & b; is formatted correctly, but a & c::d(); gets formatted as a& c::d();. This happens because the ampersand is not recognized as a binary operator in this case. This patch updates determineStarAmpUsage() to handle qualified function calls on the right-hand side and adds a regression test to cover the issue. >From e4252f80f68075f087a56b807cfb24d0beeb1718 Mon Sep 17 00:00:00 2001 From: Xen00n <[email protected]> Date: Sat, 24 Oct 2026 19:50:49 +0530 Subject: [PATCH] [clang-format] Fix ampersand formatting with qualified calls --- clang/lib/Format/TokenAnnotator.cpp | 17 +++++++++++++---- clang/unittests/Format/FormatTest.cpp | 12 ++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index c6a87980264a4c..5fb8ed297b1d2d 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -3169,10 +3169,19 @@ class AnnotatingParser { if (Tok.is(tok::amp) && PrevToken->Tok.isAnyIdentifier() && IsChainedOperatorAmpOrMember(PrevToken->getPreviousNonComment()) && NextToken && NextToken->Tok.isAnyIdentifier()) { - if (auto NextNext = NextToken->getNextNonComment(); - NextNext && - (IsChainedOperatorAmpOrMember(NextNext) || NextNext->is(tok::semi))) { - return TT_BinaryOperator; + if (auto NextNext = NextToken->getNextNonComment(); NextNext) { + if (IsChainedOperatorAmpOrMember(NextNext) || NextNext->is(tok::semi)) + return TT_BinaryOperator; + + // A qualified function call on the RHS indicates a binary expression. + if (NextNext->is(tok::coloncolon)) { + const auto *QualifiedName = NextNext->getNextNonComment(); + if (QualifiedName && QualifiedName->is(tok::identifier)) { + const auto *AfterName = QualifiedName->getNextNonComment(); + if (AfterName && AfterName->is(tok::l_paren)) + return TT_BinaryOperator; + } + } } } diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 156a2eff27a712..4b3e188330bd22 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -11966,6 +11966,18 @@ TEST_F(FormatTest, UnderstandsBinaryOperators) { verifyFormat("auto s = sizeof...(Ts) - 1;"); } +TEST_F(FormatTest, AmpersandWithQualifiedCall) { + FormatStyle Style = getLLVMStyle(); + Style.PointerAlignment = FormatStyle::PAS_Left; + Style.DerivePointerAlignment = false; + + verifyFormat("void f() {\n" + " a & b;\n" + " a & c::d();\n" + "}", + Style); +} + TEST_F(FormatTest, UnderstandsPointersToMembers) { verifyFormat("int A::*x;"); verifyFormat("int (S::*func)(void *);"); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
