diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html index 3ee44cfe11d..8afb1639e54 100644 --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -987,6 +987,21 @@ pointerType() +Matcher<TypeLoc>templateSpecializationTypeLocMatcher<TemplateSpecializationTypeLoc>... +
Matches template specialization types.
+
+Given
+  template <typename T>
+  class C { };
+
+  template class C<int>;  A
+  C<char> var;            B
+
+templateSpecializationType() matches the type of the explicit
+instantiation in A and the type of the variable declaration in B.
+
+ + Matcher<TypeLoc>typeLocMatcher<TypeLoc>...
Matches TypeLocs in the clang AST.
 
@@ -1166,6 +1181,21 @@ pointerType() +Matcher<Type>templateSpecializationTypeMatcher<TemplateSpecializationType>... +
Matches template specialization types.
+
+Given
+  template <typename T>
+  class C { };
+
+  template class C<int>;  A
+  C<char> var;            B
+
+templateSpecializationType() matches the type of the explicit
+instantiation in A and the type of the variable declaration in B.
+
+ + Matcher<Type>typeMatcher<Type>...
Matches Types in the clang AST.
 
@@ -2034,8 +2064,8 @@ 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
@@ -2043,7 +2073,8 @@ Matcher<T> for any T supporting the getDecl() member function. e.g. variou
 subtypes of clang::Type.
 
 Usable as: Matcher<QualType>, Matcher<CallExpr>, Matcher<CXXConstructExpr>,
-  Matcher<MemberExpr>, Matcher<TypedefType>
+  Matcher<MemberExpr>, Matcher<TypedefType>,
+  Matcher<TemplateSpecializationType>
 
@@ -2189,8 +2220,8 @@ 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
@@ -2198,7 +2229,8 @@ Matcher<T> for any T supporting the getDecl() member function. e.g. variou
 subtypes of clang::Type.
 
 Usable as: Matcher<QualType>, Matcher<CallExpr>, Matcher<CXXConstructExpr>,
-  Matcher<MemberExpr>, Matcher<TypedefType>
+  Matcher<MemberExpr>, Matcher<TypedefType>,
+  Matcher<TemplateSpecializationType>
 
@@ -2586,8 +2618,8 @@ 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
@@ -2595,7 +2627,8 @@ Matcher<T> for any T supporting the getDecl() member function. e.g. variou
 subtypes of clang::Type.
 
 Usable as: Matcher<QualType>, Matcher<CallExpr>, Matcher<CXXConstructExpr>,
-  Matcher<MemberExpr>, Matcher<TypedefType>
+  Matcher<MemberExpr>, Matcher<TypedefType>,
+  Matcher<TemplateSpecializationType>
 
@@ -2756,8 +2789,8 @@ 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
@@ -2765,7 +2798,8 @@ Matcher<T> for any T supporting the getDecl() member function. e.g. variou
 subtypes of clang::Type.
 
 Usable as: Matcher<QualType>, Matcher<CallExpr>, Matcher<CXXConstructExpr>,
-  Matcher<MemberExpr>, Matcher<TypedefType>
+  Matcher<MemberExpr>, Matcher<TypedefType>,
+  Matcher<TemplateSpecializationType>
 
@@ -2850,13 +2884,7 @@ classTemplateSpecializationDecl(hasAnyTemplateArgument(
-Matcher<TypeLoc>locMatcher<QualType> InnerMatcher -
Matches TypeLocs for which the given inner
-QualType-matcher matches.
-
- - -Matcher<TypedefType>hasDeclarationMatcher<Decl> InnerMatcher +Matcher<TemplateSpecializationType>hasDeclarationMatcher<Decl> InnerMatcher
Matches a type if the declaration of the type matches the given
 matcher.
 
@@ -2865,7 +2893,28 @@ Matcher<T> for any T supporting the getDecl() member function. e.g. variou
 subtypes of clang::Type.
 
 Usable as: Matcher<QualType>, Matcher<CallExpr>, Matcher<CXXConstructExpr>,
-  Matcher<MemberExpr>, Matcher<TypedefType>
+  Matcher<MemberExpr>, Matcher<TypedefType>,
+  Matcher<TemplateSpecializationType>
+
+ + +Matcher<TypeLoc>locMatcher<QualType> InnerMatcher +
Matches TypeLocs for which the given inner
+QualType-matcher matches.
+
+ + +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>,
+  Matcher<TemplateSpecializationType>
 
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 443c628519a..bee7c214355 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -1629,7 +1629,8 @@ unless(const M &InnerMatcher) { /// subtypes of clang::Type. /// /// Usable as: Matcher, Matcher, Matcher, -/// Matcher, Matcher +/// Matcher, Matcher, +/// Matcher inline internal::PolymorphicMatcherWithParam1< internal::HasDeclarationMatcher, internal::Matcher > hasDeclaration(const internal::Matcher &InnerMatcher) { @@ -2913,6 +2914,21 @@ AST_TYPELOC_TRAVERSE_MATCHER(pointee, getPointee); /// matches "typedef int X" AST_TYPE_MATCHER(TypedefType, typedefType); +/// \brief Matches template specialization types. +/// +/// Given +/// \code +/// template +/// class C { }; +/// +/// template class C; // A +/// C var; // B +/// \code +/// +/// \c templateSpecializationType() matches the type of the explicit +/// instantiation in \c A and the type of the variable declaration in \c B. +AST_TYPE_MATCHER(TemplateSpecializationType, templateSpecializationType); + /// \brief Matches nested name specifiers. /// /// Given diff --git a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h index ac85f501072..1119a72a425 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h +++ b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -411,6 +411,15 @@ private: return matchesDecl(Node->getAsCXXRecordDecl(), Finder, Builder); } + /// \brief Gets the TemplateDecl from a TemplateSpecializationType + /// and returns whether the inner matches on it. + bool matchesSpecialized(const TemplateSpecializationType &Node, + ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) const { + return matchesDecl(Node.getTemplateName().getAsTemplateDecl(), + Finder, Builder); + } + /// \brief Extracts the Decl of the callee of a CallExpr and returns whether /// the inner matcher matches on it. bool matchesSpecialized(const CallExpr &Node, ASTMatchFinder *Finder, diff --git a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp index a759df9070f..6eb552aa564 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp @@ -832,6 +832,12 @@ TEST(HasDeclaration, HasDeclarationOfTypeWithDecl) { // FIXME: Add tests for other types with getDecl() (e.g. RecordType) } +TEST(HasDeclaration, HasDeclarationOfTemplateSpecializationType) { + EXPECT_TRUE(matches("template class A {}; A a;", + varDecl(hasType(templateSpecializationType( + hasDeclaration(namedDecl(hasName("A")))))))); +} + TEST(HasType, TakesQualTypeMatcherAndMatchesExpr) { TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X"))); EXPECT_TRUE( @@ -3406,6 +3412,11 @@ TEST(TypeMatching, MatchesTypedefTypes) { hasType(typedefType())))); } +TEST(TypeMatching, MatchesTemplateSpecializationType) { + EXPECT_TRUE(matches("template class A{}; Aa;", + templateSpecializationType())); +} + TEST(NNS, MatchesNestedNameSpecifiers) { EXPECT_TRUE(matches("namespace ns { struct A {}; } ns::A a;", nestedNameSpecifier()));