[clang] [clang-format] Improve function pointer CastRParen detection. (PR #126019)

via cfe-commits cfe-commits at lists.llvm.org
Wed Feb 5 23:45:31 PST 2025


https://github.com/rmarker updated https://github.com/llvm/llvm-project/pull/126019

>From 7a9726372f24c7bc42c18b78e989dff3b48bc910 Mon Sep 17 00:00:00 2001
From: rmarker <rmarker at outlook.com>
Date: Thu, 6 Feb 2025 17:54:25 +1030
Subject: [PATCH 1/2] Improve function pointer cast detection.

---
 clang/lib/Format/TokenAnnotator.cpp           | 17 +++++++++++++++--
 clang/unittests/Format/TokenAnnotatorTest.cpp |  5 +++++
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index f25332e3a5f4e1a..fc84f29dd04389b 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -2915,14 +2915,27 @@ class AnnotatingParser {
     if (Prev->is(tok::r_paren)) {
       if (Prev->is(TT_CastRParen))
         return false;
+
+      // Check for the second pair of parentheses.
       Prev = Prev->MatchingParen;
       if (!Prev)
         return false;
+
+      // Now check for the first pair of parentheses.
       Prev = Prev->Previous;
       if (!Prev || Prev->isNot(tok::r_paren))
         return false;
-      Prev = Prev->MatchingParen;
-      return Prev && Prev->is(TT_FunctionTypeLParen);
+      const auto* PrevMatchingParen = Prev->MatchingParen;
+      if (!PrevMatchingParen)
+        return false;
+
+      // We can quickly tell it is a function pointer type if the paren is the
+      // right type.
+      if (PrevMatchingParen->isNot(TT_Unknown))
+        return PrevMatchingParen->is(TT_FunctionTypeLParen);
+
+      // Otherwise check for the trailing * in the parentheses.
+      return Prev->Previous && Prev->Previous->is(tok::star);
     }
 
     // Search for unexpected tokens.
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp
index 1b09c4570345622..5dcb9b94a5bb2f5 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -874,6 +874,11 @@ TEST_F(TokenAnnotatorTest, UnderstandsCasts) {
   EXPECT_TOKEN(Tokens[14], tok::r_paren, TT_CastRParen);
   EXPECT_TOKEN(Tokens[15], tok::amp, TT_UnaryOperator);
 
+  Tokens = annotate("func((foo(bar::*)(void))&a);");
+  ASSERT_EQ(Tokens.size(), 18u) << Tokens;
+  EXPECT_TOKEN(Tokens[12], tok::r_paren, TT_CastRParen);
+  EXPECT_TOKEN(Tokens[13], tok::amp, TT_UnaryOperator);
+
   auto Style = getLLVMStyle();
   Style.TypeNames.push_back("Foo");
   Tokens = annotate("#define FOO(bar) foo((Foo)&bar)", Style);

>From b5b5ca2a2bc89d28608709edb5c3bcd514ed82d1 Mon Sep 17 00:00:00 2001
From: rmarker <rmarker at outlook.com>
Date: Thu, 6 Feb 2025 18:12:59 +1030
Subject: [PATCH 2/2] Fix formatting.

---
 clang/lib/Format/TokenAnnotator.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index fc84f29dd04389b..fccf37bed27c737 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -2925,7 +2925,7 @@ class AnnotatingParser {
       Prev = Prev->Previous;
       if (!Prev || Prev->isNot(tok::r_paren))
         return false;
-      const auto* PrevMatchingParen = Prev->MatchingParen;
+      const auto *PrevMatchingParen = Prev->MatchingParen;
       if (!PrevMatchingParen)
         return false;
 



More information about the cfe-commits mailing list