[clang] [clang][ASTMatchers] Add `functionTypeLoc` matcher (PR #173668)
Victor Chernyakin via cfe-commits
cfe-commits at lists.llvm.org
Fri Dec 26 07:48:19 PST 2025
https://github.com/localspook updated https://github.com/llvm/llvm-project/pull/173668
>From a3728f150706887d244e8c32c38b9284b7d194f6 Mon Sep 17 00:00:00 2001
From: Victor Chernyakin <chernyakin.victor.j at outlook.com>
Date: Fri, 26 Dec 2025 08:25:57 -0700
Subject: [PATCH] [clang][ASTMatchers] Add `functionTypeLoc` matcher
---
clang/docs/LibASTMatchersReference.html | 12 +++++++++++
clang/docs/ReleaseNotes.rst | 1 +
clang/include/clang/ASTMatchers/ASTMatchers.h | 13 ++++++++++++
clang/lib/ASTMatchers/ASTMatchersInternal.cpp | 2 ++
clang/lib/ASTMatchers/Dynamic/Registry.cpp | 1 +
.../ASTMatchers/ASTMatchersNodeTest.cpp | 20 +++++++++++++++++++
6 files changed, 49 insertions(+)
diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html
index e34ac30b8f5a4..9f9d4223bb50a 100644
--- a/clang/docs/LibASTMatchersReference.html
+++ b/clang/docs/LibASTMatchersReference.html
@@ -2461,6 +2461,18 @@ <h2 id="decl-matchers">Node Matchers</h2>
</pre></td></tr>
+<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('functionTypeLoc0')"><a name="functionTypeLoc0Anchor">functionTypeLoc</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1FunctionTypeLoc.html">FunctionTypeLoc</a>>...</td></tr>
+<tr><td colspan="4" class="doc" id="functionTypeLoc0"><pre>Matches `FunctionTypeLoc`s.
+
+Given
+ void f(int);
+ using g = double (char, float);
+ char (*fn_ptr)();
+functionTypeLoc()
+ matches "void (int)", "double (char, float)", and "char ()".
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('pointerTypeLoc0')"><a name="pointerTypeLoc0Anchor">pointerTypeLoc</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1PointerTypeLoc.html">PointerTypeLoc</a>>...</td></tr>
<tr><td colspan="4" class="doc" id="pointerTypeLoc0"><pre>Matches pointer `TypeLoc`s.
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2319ff13f7864..050999cbb7c0d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -773,6 +773,7 @@ AST Matchers
- Added ``hasExplicitParameters`` for ``LambdaExpr`` as an output attribute to
AST JSON dumps.
- Add ``arrayTypeLoc`` matcher for matching ``ArrayTypeLoc``.
+- Add ``functionTypeLoc`` matcher for matching ``FunctionTypeLoc``.
clang-format
------------
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index e3ec26207d2bc..2347647ec7cc2 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -7016,6 +7016,19 @@ AST_MATCHER_P(ReferenceTypeLoc, hasReferentLoc, internal::Matcher<TypeLoc>,
extern const internal::VariadicDynCastAllOfMatcher<TypeLoc, ArrayTypeLoc>
arrayTypeLoc;
+/// Matches `FunctionTypeLoc`s.
+///
+/// Given
+/// \code
+/// void f(int);
+/// using g = double (char, float);
+/// char (*fn_ptr)();
+/// \endcode
+/// functionTypeLoc()
+/// matches "void (int)", "double (char, float)", and "char ()".
+extern const internal::VariadicDynCastAllOfMatcher<TypeLoc, FunctionTypeLoc>
+ functionTypeLoc;
+
/// Matches template specialization `TypeLoc`s.
///
/// Given
diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
index a556ffca96903..2c55c78d614b4 100644
--- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -808,6 +808,8 @@ const internal::VariadicDynCastAllOfMatcher<TypeLoc, PointerTypeLoc>
const internal::VariadicDynCastAllOfMatcher<TypeLoc, ReferenceTypeLoc>
referenceTypeLoc;
const internal::VariadicDynCastAllOfMatcher<TypeLoc, ArrayTypeLoc> arrayTypeLoc;
+const internal::VariadicDynCastAllOfMatcher<TypeLoc, FunctionTypeLoc>
+ functionTypeLoc;
const internal::VariadicDynCastAllOfMatcher<TypeLoc,
TemplateSpecializationTypeLoc>
templateSpecializationTypeLoc;
diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
index d1b19659905ca..906872b81f78b 100644
--- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -269,6 +269,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(functionProtoType);
REGISTER_MATCHER(functionTemplateDecl);
REGISTER_MATCHER(functionType);
+ REGISTER_MATCHER(functionTypeLoc);
REGISTER_MATCHER(genericSelectionExpr);
REGISTER_MATCHER(gnuNullExpr);
REGISTER_MATCHER(gotoStmt);
diff --git a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
index 108b32e5d91b9..ac3981590fd11 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
@@ -2373,6 +2373,26 @@ TEST_P(ASTMatchersTest, ArrayTypeLocTest_DoesNotBindToNonArrayTypeLoc) {
EXPECT_TRUE(notMatches("void* x;", matcher));
}
+TEST_P(ASTMatchersTest, FunctionTypeLocTest_BindsToAnyFunctionTypeLoc) {
+ auto matcher = functionTypeLoc();
+ EXPECT_TRUE(matches("void f();", matcher));
+ EXPECT_TRUE(matches("void f(void);", matcher));
+ EXPECT_TRUE(matches("void f(int);", matcher));
+ EXPECT_TRUE(matches("typedef double g(char, float);", matcher));
+ EXPECT_TRUE(matches("char (*fn_ptr)();", matcher));
+ if (!GetParam().isCXX11OrLater()) {
+ return;
+ }
+ EXPECT_TRUE(matches("auto f = (void (*)())0;", matcher));
+}
+
+TEST_P(ASTMatchersTest, FunctionTypeLocTest_DoesNotBindToNonFunctionTypeLoc) {
+ auto matcher = functionTypeLoc();
+ EXPECT_TRUE(notMatches("int x;", matcher));
+ EXPECT_TRUE(notMatches("void* x;", matcher));
+ EXPECT_TRUE(notMatches("int x[10];", matcher));
+}
+
TEST_P(ASTMatchersTest,
TemplateSpecializationTypeLocTest_BindsToVarDeclTemplateSpecialization) {
if (!GetParam().isCXX()) {
More information about the cfe-commits
mailing list