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>hasDeclarationMatcher<Decl> InnerMatcher -
Matches a type if the declaration of the type matches the given
+Matcher<CXXConstructExpr>hasDeclarationMatcher<Decl>  InnerMatcher
+
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>
 
@@ -2130,12 +2134,16 @@ Example matches y in x(y)
-Matcher<CallExpr>hasDeclarationMatcher<Decl> InnerMatcher -
Matches a type if the declaration of the type matches the given
+Matcher<CallExpr>hasDeclarationMatcher<Decl>  InnerMatcher
+
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>
 
@@ -2523,12 +2531,16 @@ FIXME: Unit test this matcher
-Matcher<MemberExpr>hasDeclarationMatcher<Decl> InnerMatcher -
Matches a type if the declaration of the type matches the given
+Matcher<MemberExpr>hasDeclarationMatcher<Decl>  InnerMatcher
+
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>
 
@@ -2689,12 +2701,16 @@ Usable as: Matcher<QualType>hasDeclarationMatcher<Decl> InnerMatcher -
Matches a type if the declaration of the type matches the given
+Matcher<QualType>hasDeclarationMatcher<Decl>  InnerMatcher
+
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>
 
@@ -2785,9 +2801,16 @@ QualType-matcher matches.
-Matcher<TypedefType>hasDeclMatcher<TypedefNameDecl> InnerMatcher -
Matches TypedefTypes referring to a specific
-TypedefNameDecl.
+Matcher<TypedefType>hasDeclarationMatcher<Decl>  InnerMatcher
+
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>
 
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, 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) {