Skip to content

Conversation

@yuhaouy
Copy link
Contributor

@yuhaouy yuhaouy commented Nov 21, 2025

There's arrayType matcher for matching ArrayType, but no matcher for ArrayTypeLoc. This change complements it.

Note that there's already hasElementTypeLoc matcher, which was declared together with the hasElementType matcher.

@llvmbot llvmbot added the clang Clang issues not falling into any other category label Nov 21, 2025
@llvmbot
Copy link
Member

llvmbot commented Nov 21, 2025

@llvm/pr-subscribers-clang

Author: Yu Hao (yuhaouy)

Changes

There's arrayType matcher for matching ArrayType, but no matcher for ArrayTypeLoc. This change complements it.

Note that there's already hasElementTypeLoc matcher, which was declared together with the hasElementType matcher.


Full diff: https://github.com/llvm/llvm-project/pull/168990.diff

3 Files Affected:

  • (modified) clang/include/clang/ASTMatchers/ASTMatchers.h (+13)
  • (modified) clang/lib/ASTMatchers/ASTMatchersInternal.cpp (+2)
  • (modified) clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp (+20)
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index bca2d8425b3f5..e3ec26207d2bc 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -7003,6 +7003,19 @@ AST_MATCHER_P(ReferenceTypeLoc, hasReferentLoc, internal::Matcher<TypeLoc>,
   return ReferentMatcher.matches(Node.getPointeeLoc(), Finder, Builder);
 }
 
+/// Matches `ArrayTypeLoc`s.
+///
+/// Given
+/// \code
+///   int a[] = {1, 2};
+///   int b[3];
+///   void f() { int c[a[0]]; }
+/// \endcode
+/// arrayTypeLoc()
+///   matches "int a[]", "int b[3]" and "int c[a[0]]".
+extern const internal::VariadicDynCastAllOfMatcher<TypeLoc, ArrayTypeLoc>
+    arrayTypeLoc;
+
 /// Matches template specialization `TypeLoc`s.
 ///
 /// Given
diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
index 0874b3d0c45f5..13696a6fc71f2 100644
--- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -807,6 +807,8 @@ const internal::VariadicDynCastAllOfMatcher<TypeLoc, PointerTypeLoc>
     pointerTypeLoc;
 const internal::VariadicDynCastAllOfMatcher<TypeLoc, ReferenceTypeLoc>
     referenceTypeLoc;
+const internal::VariadicDynCastAllOfMatcher<TypeLoc, ArrayTypeLoc>
+    arrayTypeLoc;
 const internal::VariadicDynCastAllOfMatcher<TypeLoc,
                                             TemplateSpecializationTypeLoc>
     templateSpecializationTypeLoc;
diff --git a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
index 3fcb5582d3dd7..108b32e5d91b9 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
@@ -2353,6 +2353,26 @@ TEST_P(ASTMatchersTest, ReferenceTypeLocTest_BindsToAnyRvalueReferenceTypeLoc) {
   EXPECT_TRUE(matches("float&& r = 3.0;", matcher));
 }
 
+TEST_P(ASTMatchersTest, ArrayTypeLocTest_BindsToAnyArrayTypeLoc) {
+  auto matcher = varDecl(hasName("x"), hasTypeLoc(arrayTypeLoc()));
+  EXPECT_TRUE(matches("int x[3];", matcher));
+  EXPECT_TRUE(matches("float x[3];", matcher));
+  EXPECT_TRUE(matches("char x[3];", matcher));
+  EXPECT_TRUE(matches("void* x[3];", matcher));
+  EXPECT_TRUE(matches("const int x[3] = {1, 2, 3};", matcher));
+  EXPECT_TRUE(matches("int x[3][4];", matcher));
+  EXPECT_TRUE(matches("void foo(int x[]);", matcher));
+  EXPECT_TRUE(matches("int a[] = {1, 2}; void foo() {int x[a[0]];}", matcher));
+}
+
+TEST_P(ASTMatchersTest, ArrayTypeLocTest_DoesNotBindToNonArrayTypeLoc) {
+  auto matcher = varDecl(hasName("x"), hasTypeLoc(arrayTypeLoc()));
+  EXPECT_TRUE(notMatches("int x;", matcher));
+  EXPECT_TRUE(notMatches("float x;", matcher));
+  EXPECT_TRUE(notMatches("char x;", matcher));
+  EXPECT_TRUE(notMatches("void* x;", matcher));
+}
+
 TEST_P(ASTMatchersTest,
        TemplateSpecializationTypeLocTest_BindsToVarDeclTemplateSpecialization) {
   if (!GetParam().isCXX()) {

@github-actions
Copy link

github-actions bot commented Nov 21, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@github-actions
Copy link

github-actions bot commented Nov 21, 2025

🐧 Linux x64 Test Results

  • 111411 tests passed
  • 4434 tests skipped

@zwuis zwuis requested a review from AaronBallman November 21, 2025 05:20
return ReferentMatcher.matches(Node.getPointeeLoc(), Finder, Builder);
}

/// Matches `ArrayTypeLoc`s.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please be sure to run clang/docs/tools/dump_ast_matchers.py to regenerate the documentation for the new matcher.

You should also update clang/lib/ASTMatchers/Dynamic/Registry.cpp to add the dynamic matcher at the same time.

And finally, this should come with a release note in clang/docs/ReleaseNotes.rst.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Done.

@ymand ymand self-requested a review November 21, 2025 13:53
@yuhaouy yuhaouy changed the title [clang][transformer] Add arrayTypeLoc ast matcher for ArrayTypeLoc [clang][ASTMatchers] Add arrayTypeLoc ast matcher for ArrayTypeLoc Nov 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants