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

Reply via email to