[clang][ASTMatchers] Add arrayTypeLoc ast matcher for ArrayTypeLoc (#168990)

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.
This commit is contained in:
Yu Hao 2025-12-01 07:21:17 -08:00 committed by GitHub
parent 73889c3571
commit 37858b087a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 48 additions and 0 deletions

View File

@ -2449,6 +2449,18 @@ templateName()
</pre></td></tr>
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>&gt;</td><td class="name" onclick="toggle('arrayTypeLoc0')"><a name="arrayTypeLoc0Anchor">arrayTypeLoc</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1ArrayTypeLoc.html">ArrayTypeLoc</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="arrayTypeLoc0"><pre>Matches `ArrayTypeLoc`s.
Given
int a[] = {1, 2};
int b[3];
void f() { int c[a[0]]; }
arrayTypeLoc()
matches "int a[]", "int b[3]" and "int c[a[0]]".
</pre></td></tr>
<tr><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>&gt;</td><td class="name" onclick="toggle('pointerTypeLoc0')"><a name="pointerTypeLoc0Anchor">pointerTypeLoc</a></td><td>Matcher&lt;<a href="https://clang.llvm.org/doxygen/classclang_1_1PointerTypeLoc.html">PointerTypeLoc</a>&gt;...</td></tr>
<tr><td colspan="4" class="doc" id="pointerTypeLoc0"><pre>Matches pointer `TypeLoc`s.

View File

@ -689,6 +689,7 @@ AST Matchers
- Fixed detection of explicit parameter lists in ``LambdaExpr``. (#GH168452)
- Added ``hasExplicitParameters`` for ``LambdaExpr`` as an output attribute to
AST JSON dumps.
- Add ``arrayTypeLoc`` matcher for matching ``ArrayTypeLoc``.
clang-format
------------

View File

@ -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

View File

@ -807,6 +807,7 @@ const internal::VariadicDynCastAllOfMatcher<TypeLoc, PointerTypeLoc>
pointerTypeLoc;
const internal::VariadicDynCastAllOfMatcher<TypeLoc, ReferenceTypeLoc>
referenceTypeLoc;
const internal::VariadicDynCastAllOfMatcher<TypeLoc, ArrayTypeLoc> arrayTypeLoc;
const internal::VariadicDynCastAllOfMatcher<TypeLoc,
TemplateSpecializationTypeLoc>
templateSpecializationTypeLoc;

View File

@ -138,6 +138,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(argumentCountAtLeast);
REGISTER_MATCHER(arraySubscriptExpr);
REGISTER_MATCHER(arrayType);
REGISTER_MATCHER(arrayTypeLoc);
REGISTER_MATCHER(asString);
REGISTER_MATCHER(asmStmt);
REGISTER_MATCHER(atomicExpr);

View File

@ -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()) {