diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -2648,6 +2648,18 @@ +
Matches qualified types when the qualifier is applied via a macro. + +Given + #define CDECL __attribute__((cdecl)) + typedef void (CDECL *X)(); + typedef void (__attribute__((cdecl)) *Y)(); +macroQualifiedType() + matches the type of the typedef declaration of X but not Y. +
Matches member pointer types. Given diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -249,6 +249,7 @@ ------------ - Add ``convertVectorExpr``. - Add ``dependentSizedExtVectorType``. +- Add ``macroQualifiedType``. clang-format ------------ diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -7258,6 +7258,18 @@ /// matches "typedef int X" extern const AstTypeMatchertypedefType; +/// Matches qualified types when the qualifier is applied via a macro. +/// +/// Given +/// \code +/// #define CDECL __attribute__((cdecl)) +/// typedef void (CDECL *X)(); +/// typedef void (__attribute__((cdecl)) *Y)(); +/// \endcode +/// macroQualifiedType() +/// matches the type of the typedef declaration of \c X but not \c Y. +extern const AstTypeMatcher macroQualifiedType; + /// Matches enum types. /// /// Given diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp --- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp +++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp @@ -1058,6 +1058,7 @@ const AstTypeMatcher functionProtoType; const AstTypeMatcher parenType; const AstTypeMatcher blockPointerType; +const AstTypeMatcher macroQualifiedType; const AstTypeMatcher memberPointerType; const AstTypeMatcher pointerType; const AstTypeMatcher objcObjectPointerType; diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp --- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -485,6 +485,7 @@ REGISTER_MATCHER(lambdaCapture); REGISTER_MATCHER(lambdaExpr); REGISTER_MATCHER(linkageSpecDecl); + REGISTER_MATCHER(macroQualifiedType); REGISTER_MATCHER(materializeTemporaryExpr); REGISTER_MATCHER(member); REGISTER_MATCHER(memberExpr); diff --git a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp --- a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp @@ -1838,6 +1838,20 @@ namesType(typedefType())))))); } +TEST_P(ASTMatchersTest, MacroQualifiedType) { + EXPECT_TRUE(matches( + R"( + #define CDECL __attribute__((cdecl)) + typedef void (CDECL *X)(); + )", + typedefDecl(hasType(pointerType(pointee(macroQualifiedType())))))); + EXPECT_TRUE(notMatches( + R"( + typedef void (__attribute__((cdecl)) *Y)(); + )", + typedefDecl(hasType(pointerType(pointee(macroQualifiedType())))))); +} + TEST_P(ASTMatchersTest, TemplateSpecializationType) { if (!GetParam().isCXX()) { return;