diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html index 930b922cdd175a1998a0d083760b33f91eed604f..4f85395c0ac2808b39afeba62527c244d0cc499f 100644 --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -1979,12 +1979,16 @@ Usable as: Matcher<CXXConstructExpr>
Matches a type if the declaration of the type matches the given ++ Matcher<CXXConstructExpr> hasDeclaration Matcher<Decl> InnerMatcher @@ -2130,12 +2134,16 @@ Example matches y in x(y) Matches a type if the declaration of the type matches the given matcher. +In addition to being usable as Matcher<TypedefType>, also usable as +Matcher<T> for any T supporting the getDecl() member function. e.g. various +subtypes of clang::Type. + Usable as: Matcher<QualType>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, - Matcher<MemberExpr> + Matcher<MemberExpr>, Matcher<TypedefType>
Matches a type if the declaration of the type matches the given ++ Matcher<CallExpr> hasDeclaration Matcher<Decl> InnerMatcher @@ -2523,12 +2531,16 @@ FIXME: Unit test this matcher Matches a type if the declaration of the type matches the given matcher. +In addition to being usable as Matcher<TypedefType>, also usable as +Matcher<T> for any T supporting the getDecl() member function. e.g. various +subtypes of clang::Type. + Usable as: Matcher<QualType>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, - Matcher<MemberExpr> + Matcher<MemberExpr>, Matcher<TypedefType>
Matches a type if the declaration of the type matches the given ++ Matcher<MemberExpr> hasDeclaration Matcher<Decl> InnerMatcher @@ -2689,12 +2701,16 @@ Usable as: Matcher<QualType> Matches a type if the declaration of the type matches the given matcher. +In addition to being usable as Matcher<TypedefType>, also usable as +Matcher<T> for any T supporting the getDecl() member function. e.g. various +subtypes of clang::Type. + Usable as: Matcher<QualType>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, - Matcher<MemberExpr> + Matcher<MemberExpr>, Matcher<TypedefType>
Matches a type if the declaration of the type matches the given ++ Matcher<QualType> hasDeclaration Matcher<Decl> InnerMatcher @@ -2785,9 +2801,16 @@ QualType-matcher matches. Matches a type if the declaration of the type matches the given matcher. +In addition to being usable as Matcher<TypedefType>, also usable as +Matcher<T> for any T supporting the getDecl() member function. e.g. various +subtypes of clang::Type. + Usable as: Matcher<QualType>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, - Matcher<MemberExpr> + Matcher<MemberExpr>, Matcher<TypedefType>
Matches TypedefTypes referring to a specific -TypedefNameDecl. ++ Matcher<TypedefType> hasDeclaration Matcher<Decl> InnerMatcher diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index fe2c14f58bf701db7c106da6587df6ffe673a741..de9919aaf0da2df994300d3198df75a50b9197d2 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -1561,8 +1561,12 @@ unless(const M &InnerMatcher) { /// \brief Matches a type if the declaration of the type matches the given /// matcher. /// +/// In addition to being usable as Matcher Matches a type if the declaration of the type matches the given +matcher. + +In addition to being usable as Matcher<TypedefType>, also usable as +Matcher<T> for any T supporting the getDecl() member function. e.g. various +subtypes of clang::Type. + +Usable as: Matcher<QualType>, Matcher<CallExpr>, Matcher<CXXConstructExpr>, + Matcher<MemberExpr>, Matcher<TypedefType>, also usable as +/// Matcher for any T supporting the getDecl() member function. e.g. various +/// subtypes of clang::Type. +/// /// Usable as: Matcher , Matcher , Matcher , -/// Matcher +/// Matcher , Matcher inline internal::PolymorphicMatcherWithParam1< internal::HasDeclarationMatcher, internal::Matcher > hasDeclaration(const internal::Matcher &InnerMatcher) { @@ -2846,13 +2850,6 @@ AST_TYPELOC_TRAVERSE_MATCHER(pointee, getPointee); /// matches "typedef int X" AST_TYPE_MATCHER(TypedefType, typedefType); -/// \brief Matches \c TypedefTypes referring to a specific -/// \c TypedefNameDecl. -AST_MATCHER_P(TypedefType, hasDecl, - internal::Matcher , InnerMatcher) { - return InnerMatcher.matches(*Node.getDecl(), Finder, Builder); -} - /// \brief Matches nested name specifiers. /// /// Given diff --git a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h index b41a74ce8378150f27393f435bc7b84b55aa1784..cc4edacf42d8538e39b90ba74e5d4500d6c7a0fa 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h +++ b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -353,6 +353,18 @@ inline Matcher makeMatcher(MatcherInterface *Implementation) { return Matcher (Implementation); } +/// \brief Metafunction to determine if type T has a member called getDecl. +template struct has_getDecl { + typedef char yes[1]; + typedef char no[2]; + + template + static yes &test(char[sizeof(&TestType::getDecl)]); + template static no &test(...); + + static bool const value = sizeof(test (0)) == sizeof(yes); +}; + /// \brief Matches declarations for QualType and CallExpr. /// /// Type argument DeclMatcherT is required by PolymorphicMatcherWithParam1 but @@ -373,6 +385,15 @@ public: } private: + /// \brief If getDecl exists as a member of U, returns whether the inner + /// matcher matches Node.getDecl(). + template + bool matchesSpecialized( + const U &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder, + typename llvm::enable_if , int>::type = 0) const { + return matchesDecl(Node.getDecl(), Finder, Builder); + } + /// \brief Extracts the CXXRecordDecl or EnumDecl of a QualType and returns /// whether the inner matcher matches on it. bool matchesSpecialized(const QualType &Node, ASTMatchFinder *Finder, diff --git a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp index 608e7479a6b166e6b5f3a2d38807a347d7f92b2d..8e4f3e93274820d6c6c8c6382b01d79ded5e532d 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp @@ -818,6 +818,14 @@ TEST(HasDeclaration, HasDeclarationOfEnumType) { qualType(hasDeclaration(enumDecl(hasName("X"))))))))); } +TEST(HasDeclaration, HasDeclarationOfTypeWithDecl) { + EXPECT_TRUE(matches("typedef int X; X a;", + varDecl(hasName("a"), + hasType(typedefType(hasDeclaration(decl())))))); + + // FIXME: Add tests for other types with getDecl() (e.g. RecordType) +} + TEST(HasType, TakesQualTypeMatcherAndMatchesExpr) { TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X"))); EXPECT_TRUE( @@ -3350,10 +3358,6 @@ TEST(TypeMatching, MatchesPointersToConstTypes) { TEST(TypeMatching, MatchesTypedefTypes) { EXPECT_TRUE(matches("typedef int X; X a;", varDecl(hasName("a"), hasType(typedefType())))); - - EXPECT_TRUE(matches("typedef int X; X a;", - varDecl(hasName("a"), - hasType(typedefType(hasDecl(decl())))))); } TEST(NNS, MatchesNestedNameSpecifiers) {