r231575 - ASTMatchers: Make AST_POLYMORPHIC_SUPPORTED_TYPES a variadic macro

Benjamin Kramer benny.kra at googlemail.com
Sat Mar 7 12:38:16 PST 2015


Author: d0k
Date: Sat Mar  7 14:38:15 2015
New Revision: 231575

URL: http://llvm.org/viewvc/llvm-project?rev=231575&view=rev
Log:
ASTMatchers: Make AST_POLYMORPHIC_SUPPORTED_TYPES a variadic macro

C++11 finally allows us to use this C99 feature.

Modified:
    cfe/trunk/docs/tools/dump_ast_matchers.py
    cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
    cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h
    cfe/trunk/include/clang/ASTMatchers/ASTMatchersMacros.h
    cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp

Modified: cfe/trunk/docs/tools/dump_ast_matchers.py
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/tools/dump_ast_matchers.py?rev=231575&r1=231574&r2=231575&view=diff
==============================================================================
--- cfe/trunk/docs/tools/dump_ast_matchers.py (original)
+++ cfe/trunk/docs/tools/dump_ast_matchers.py Sat Mar  7 14:38:15 2015
@@ -163,7 +163,7 @@ def act_on_decl(declaration, comment, al
     m = re.match(""".*AST_TYPE(LOC)?_TRAVERSE_MATCHER\(
                        \s*([^\s,]+\s*),
                        \s*(?:[^\s,]+\s*),
-                       \s*AST_POLYMORPHIC_SUPPORTED_TYPES_([^(]*)\(([^)]*)\)
+                       \s*AST_POLYMORPHIC_SUPPORTED_TYPES\(([^)]*)\)
                      \)\s*;\s*$""", declaration, flags=re.X)
     if m:
       loc, name, n_results, results = m.groups()[0:4]
@@ -182,7 +182,7 @@ def act_on_decl(declaration, comment, al
 
     m = re.match(r"""^\s*AST_POLYMORPHIC_MATCHER(_P)?(.?)(?:_OVERLOAD)?\(
                           \s*([^\s,]+)\s*,
-                          \s*AST_POLYMORPHIC_SUPPORTED_TYPES_([^(]*)\(([^)]*)\)
+                          \s*AST_POLYMORPHIC_SUPPORTED_TYPES\(([^)]*)\)
                        (?:,\s*([^\s,]+)\s*
                           ,\s*([^\s,]+)\s*)?
                        (?:,\s*([^\s,]+)\s*

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=231575&r1=231574&r2=231575&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Sat Mar  7 14:38:15 2015
@@ -181,8 +181,7 @@ const internal::VariadicDynCastAllOfMatc
 ///
 /// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
 AST_POLYMORPHIC_MATCHER(isExpansionInMainFile,
-                        AST_POLYMORPHIC_SUPPORTED_TYPES_3(Decl, Stmt,
-                                                          TypeLoc)) {
+                        AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc)) {
   auto &SourceManager = Finder->getASTContext().getSourceManager();
   return SourceManager.isInMainFile(
       SourceManager.getExpansionLoc(Node.getLocStart()));
@@ -203,8 +202,7 @@ AST_POLYMORPHIC_MATCHER(isExpansionInMai
 ///
 /// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
 AST_POLYMORPHIC_MATCHER(isExpansionInSystemHeader,
-                        AST_POLYMORPHIC_SUPPORTED_TYPES_3(Decl, Stmt,
-                                                          TypeLoc)) {
+                        AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc)) {
   auto &SourceManager = Finder->getASTContext().getSourceManager();
   auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getLocStart());
   if (ExpansionLoc.isInvalid()) {
@@ -229,8 +227,7 @@ AST_POLYMORPHIC_MATCHER(isExpansionInSys
 ///
 /// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>
 AST_POLYMORPHIC_MATCHER_P(isExpansionInFileMatching,
-                          AST_POLYMORPHIC_SUPPORTED_TYPES_3(Decl, Stmt,
-                                                            TypeLoc),
+                          AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc),
                           std::string, RegExp) {
   auto &SourceManager = Finder->getASTContext().getSourceManager();
   auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getLocStart());
@@ -456,8 +453,8 @@ AST_MATCHER(Decl, isImplicit) {
 ///   matches the specialization \c A<int>
 AST_POLYMORPHIC_MATCHER_P(
     hasAnyTemplateArgument,
-    AST_POLYMORPHIC_SUPPORTED_TYPES_2(ClassTemplateSpecializationDecl,
-                                      TemplateSpecializationType),
+    AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
+                                    TemplateSpecializationType),
     internal::Matcher<TemplateArgument>, InnerMatcher) {
   ArrayRef<TemplateArgument> List =
       internal::getTemplateSpecializationArgs(Node);
@@ -556,8 +553,8 @@ AST_MATCHER_P(Expr, ignoringParenImpCast
 ///   matches the specialization \c A<bool, int>
 AST_POLYMORPHIC_MATCHER_P2(
     hasTemplateArgument,
-    AST_POLYMORPHIC_SUPPORTED_TYPES_2(ClassTemplateSpecializationDecl,
-                                      TemplateSpecializationType),
+    AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
+                                    TemplateSpecializationType),
     unsigned, N, internal::Matcher<TemplateArgument>, InnerMatcher) {
   ArrayRef<TemplateArgument> List =
       internal::getTemplateSpecializationArgs(Node);
@@ -577,8 +574,8 @@ AST_POLYMORPHIC_MATCHER_P2(
 ///   matches C<int>.
 AST_POLYMORPHIC_MATCHER_P(
     templateArgumentCountIs,
-    AST_POLYMORPHIC_SUPPORTED_TYPES_2(ClassTemplateSpecializationDecl,
-                                      TemplateSpecializationType),
+    AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
+                                    TemplateSpecializationType),
     unsigned, N) {
   return internal::getTemplateSpecializationArgs(Node).size() == N;
 }
@@ -1753,12 +1750,11 @@ AST_MATCHER_P(NamedDecl, matchesName, st
 /// Usable as: Matcher<CXXOperatorCallExpr>, Matcher<FunctionDecl>
 inline internal::PolymorphicMatcherWithParam1<
     internal::HasOverloadedOperatorNameMatcher, StringRef,
-    AST_POLYMORPHIC_SUPPORTED_TYPES_2(CXXOperatorCallExpr, FunctionDecl)>
+    AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)>
 hasOverloadedOperatorName(StringRef Name) {
   return internal::PolymorphicMatcherWithParam1<
       internal::HasOverloadedOperatorNameMatcher, StringRef,
-      AST_POLYMORPHIC_SUPPORTED_TYPES_2(CXXOperatorCallExpr, FunctionDecl)>(
-      Name);
+      AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)>(Name);
 }
 
 /// \brief Matches C++ classes that are directly or indirectly derived from
@@ -2057,7 +2053,7 @@ AST_MATCHER_P_OVERLOAD(CallExpr, callee,
 ///  void y(X &x) { x; X z; }
 /// \endcode
 AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
-    hasType, AST_POLYMORPHIC_SUPPORTED_TYPES_2(Expr, ValueDecl),
+    hasType, AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, ValueDecl),
     internal::Matcher<QualType>, InnerMatcher, 0) {
   return InnerMatcher.matches(Node.getType(), Finder, Builder);
 }
@@ -2079,9 +2075,10 @@ AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
 /// \endcode
 ///
 /// Usable as: Matcher<Expr>, Matcher<ValueDecl>
-AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
-    hasType, AST_POLYMORPHIC_SUPPORTED_TYPES_2(Expr, ValueDecl),
-    internal::Matcher<Decl>, InnerMatcher, 1) {
+AST_POLYMORPHIC_MATCHER_P_OVERLOAD(hasType,
+                                   AST_POLYMORPHIC_SUPPORTED_TYPES(Expr,
+                                                                   ValueDecl),
+                                   internal::Matcher<Decl>, InnerMatcher, 1) {
   return qualType(hasDeclaration(InnerMatcher))
       .matches(Node.getType(), Finder, Builder);
 }
@@ -2317,8 +2314,9 @@ AST_MATCHER(VarDecl, hasGlobalStorage) {
 ///   void f(int x, int y);
 ///   f(0, 0);
 /// \endcode
-AST_POLYMORPHIC_MATCHER_P(argumentCountIs, AST_POLYMORPHIC_SUPPORTED_TYPES_2(
-                                               CallExpr, CXXConstructExpr),
+AST_POLYMORPHIC_MATCHER_P(argumentCountIs,
+                          AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,
+                                                          CXXConstructExpr),
                           unsigned, N) {
   return Node.getNumArgs() == N;
 }
@@ -2331,10 +2329,10 @@ AST_POLYMORPHIC_MATCHER_P(argumentCountI
 /// \code
 ///   void x(int) { int y; x(y); }
 /// \endcode
-AST_POLYMORPHIC_MATCHER_P2(
-    hasArgument,
-    AST_POLYMORPHIC_SUPPORTED_TYPES_2(CallExpr, CXXConstructExpr),
-    unsigned, N, internal::Matcher<Expr>, InnerMatcher) {
+AST_POLYMORPHIC_MATCHER_P2(hasArgument,
+                           AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,
+                                                           CXXConstructExpr),
+                           unsigned, N, internal::Matcher<Expr>, InnerMatcher) {
   return (N < Node.getNumArgs() &&
           InnerMatcher.matches(
               *Node.getArg(N)->IgnoreParenImpCasts(), Finder, Builder));
@@ -2474,8 +2472,9 @@ AST_MATCHER(CXXCtorInitializer, isWritte
 /// the argument before applying the inner matcher. We'll want to remove
 /// this to allow for greater control by the user once \c ignoreImplicit()
 /// has been implemented.
-AST_POLYMORPHIC_MATCHER_P(hasAnyArgument, AST_POLYMORPHIC_SUPPORTED_TYPES_2(
-                                              CallExpr, CXXConstructExpr),
+AST_POLYMORPHIC_MATCHER_P(hasAnyArgument,
+                          AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,
+                                                          CXXConstructExpr),
                           internal::Matcher<Expr>, InnerMatcher) {
   for (const Expr *Arg : Node.arguments()) {
     BoundNodesTreeBuilder Result(*Builder);
@@ -2588,10 +2587,11 @@ AST_MATCHER(FunctionDecl, isDeleted) {
 /// \code
 ///   if (true) {}
 /// \endcode
-AST_POLYMORPHIC_MATCHER_P(
-    hasCondition, AST_POLYMORPHIC_SUPPORTED_TYPES_5(
-                      IfStmt, ForStmt, WhileStmt, DoStmt, ConditionalOperator),
-    internal::Matcher<Expr>, InnerMatcher) {
+AST_POLYMORPHIC_MATCHER_P(hasCondition,
+                          AST_POLYMORPHIC_SUPPORTED_TYPES(IfStmt, ForStmt,
+                                                          WhileStmt, DoStmt,
+                                                          ConditionalOperator),
+                          internal::Matcher<Expr>, InnerMatcher) {
   const Expr *const Condition = Node.getCond();
   return (Condition != nullptr &&
           InnerMatcher.matches(*Condition, Finder, Builder));
@@ -2642,8 +2642,9 @@ AST_MATCHER_P(IfStmt, hasElse, internal:
 ///     forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d"))))))
 /// will trigger a match for each combination of variable declaration
 /// and reference to that variable declaration within a compound statement.
-AST_POLYMORPHIC_MATCHER_P(equalsBoundNode, AST_POLYMORPHIC_SUPPORTED_TYPES_4(
-                                               Stmt, Decl, Type, QualType),
+AST_POLYMORPHIC_MATCHER_P(equalsBoundNode,
+                          AST_POLYMORPHIC_SUPPORTED_TYPES(Stmt, Decl, Type,
+                                                          QualType),
                           std::string, ID) {
   // FIXME: Figure out whether it makes sense to allow this
   // on any other node types.
@@ -2718,9 +2719,9 @@ AST_MATCHER_P(ArraySubscriptExpr, hasBas
 /// with compoundStmt()
 ///   matching '{}'
 AST_POLYMORPHIC_MATCHER_P(hasBody,
-                          AST_POLYMORPHIC_SUPPORTED_TYPES_4(DoStmt, ForStmt,
-                                                            WhileStmt,
-                                                            CXXForRangeStmt),
+                          AST_POLYMORPHIC_SUPPORTED_TYPES(DoStmt, ForStmt,
+                                                          WhileStmt,
+                                                          CXXForRangeStmt),
                           internal::Matcher<Stmt>, InnerMatcher) {
   const Stmt *const Statement = Node.getBody();
   return (Statement != nullptr &&
@@ -2782,8 +2783,9 @@ equals(const ValueT &Value) {
 /// \code
 ///   !(a || b)
 /// \endcode
-AST_POLYMORPHIC_MATCHER_P(hasOperatorName, AST_POLYMORPHIC_SUPPORTED_TYPES_2(
-                                               BinaryOperator, UnaryOperator),
+AST_POLYMORPHIC_MATCHER_P(hasOperatorName,
+                          AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator,
+                                                          UnaryOperator),
                           std::string, Name) {
   return Name == Node.getOpcodeStr(Node.getOpcode());
 }
@@ -2906,8 +2908,9 @@ AST_MATCHER_P(ConditionalOperator, hasFa
 /// \endcode
 ///
 /// Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>
-AST_POLYMORPHIC_MATCHER(isDefinition, AST_POLYMORPHIC_SUPPORTED_TYPES_3(
-                                          TagDecl, VarDecl, FunctionDecl)) {
+AST_POLYMORPHIC_MATCHER(isDefinition,
+                        AST_POLYMORPHIC_SUPPORTED_TYPES(TagDecl, VarDecl,
+                                                        FunctionDecl)) {
   return Node.isThisDeclarationADefinition();
 }
 
@@ -3154,9 +3157,9 @@ AST_MATCHER_P(UsingShadowDecl, hasTarget
 ///   does not match, as X<A> is an explicit template specialization.
 ///
 /// Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
-AST_POLYMORPHIC_MATCHER(
-    isTemplateInstantiation,
-    AST_POLYMORPHIC_SUPPORTED_TYPES_3(FunctionDecl, VarDecl, CXXRecordDecl)) {
+AST_POLYMORPHIC_MATCHER(isTemplateInstantiation,
+                        AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, VarDecl,
+                                                        CXXRecordDecl)) {
   return (Node.getTemplateSpecializationKind() == TSK_ImplicitInstantiation ||
           Node.getTemplateSpecializationKind() ==
           TSK_ExplicitInstantiationDefinition);
@@ -3211,9 +3214,9 @@ AST_MATCHER_FUNCTION(internal::Matcher<S
 ///   matches the specialization A<int>().
 ///
 /// Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
-AST_POLYMORPHIC_MATCHER(
-    isExplicitTemplateSpecialization,
-    AST_POLYMORPHIC_SUPPORTED_TYPES_3(FunctionDecl, VarDecl, CXXRecordDecl)) {
+AST_POLYMORPHIC_MATCHER(isExplicitTemplateSpecialization,
+                        AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, VarDecl,
+                                                        CXXRecordDecl)) {
   return (Node.getTemplateSpecializationKind() == TSK_ExplicitSpecialization);
 }
 
@@ -3286,9 +3289,9 @@ AST_TYPE_MATCHER(ComplexType, complexTyp
 ///   matches "int b[7]"
 ///
 /// Usable as: Matcher<ArrayType>, Matcher<ComplexType>
-AST_TYPELOC_TRAVERSE_MATCHER(
-    hasElementType, getElement,
-    AST_POLYMORPHIC_SUPPORTED_TYPES_2(ArrayType, ComplexType));
+AST_TYPELOC_TRAVERSE_MATCHER(hasElementType, getElement,
+                             AST_POLYMORPHIC_SUPPORTED_TYPES(ArrayType,
+                                                             ComplexType));
 
 /// \brief Matches C arrays with a specified constant size.
 ///
@@ -3397,7 +3400,7 @@ AST_TYPE_MATCHER(AtomicType, atomicType)
 ///
 /// Usable as: Matcher<AtomicType>
 AST_TYPELOC_TRAVERSE_MATCHER(hasValueType, getValue,
-                             AST_POLYMORPHIC_SUPPORTED_TYPES_1(AtomicType));
+                             AST_POLYMORPHIC_SUPPORTED_TYPES(AtomicType));
 
 /// \brief Matches types nodes representing C++11 auto types.
 ///
@@ -3426,7 +3429,7 @@ AST_TYPE_MATCHER(AutoType, autoType);
 ///
 /// Usable as: Matcher<AutoType>
 AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType,
-                          AST_POLYMORPHIC_SUPPORTED_TYPES_1(AutoType));
+                          AST_POLYMORPHIC_SUPPORTED_TYPES(AutoType));
 
 /// \brief Matches \c FunctionType nodes.
 ///
@@ -3464,7 +3467,7 @@ AST_TYPE_MATCHER(ParenType, parenType);
 ///
 /// Usable as: Matcher<ParenType>
 AST_TYPE_TRAVERSE_MATCHER(innerType, getInnerType,
-                          AST_POLYMORPHIC_SUPPORTED_TYPES_1(ParenType));
+                          AST_POLYMORPHIC_SUPPORTED_TYPES(ParenType));
 
 /// \brief Matches block pointer types, i.e. types syntactically represented as
 /// "void (^)(int)".
@@ -3558,10 +3561,11 @@ AST_TYPE_MATCHER(RValueReferenceType, rV
 ///
 /// Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>,
 ///   Matcher<PointerType>, Matcher<ReferenceType>
-AST_TYPELOC_TRAVERSE_MATCHER(
-    pointee, getPointee,
-    AST_POLYMORPHIC_SUPPORTED_TYPES_4(BlockPointerType, MemberPointerType,
-                                      PointerType, ReferenceType));
+AST_TYPELOC_TRAVERSE_MATCHER(pointee, getPointee,
+                             AST_POLYMORPHIC_SUPPORTED_TYPES(BlockPointerType,
+                                                             MemberPointerType,
+                                                             PointerType,
+                                                             ReferenceType));
 
 /// \brief Matches typedef types.
 ///

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h?rev=231575&r1=231574&r2=231575&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h Sat Mar  7 14:38:15 2015
@@ -887,7 +887,7 @@ typedef TypeList<Decl, Stmt, NestedNameS
 /// \brief Helper meta-function to extract the argument out of a function of
 ///   type void(Arg).
 ///
-/// See AST_POLYMORPHIC_SUPPORTED_TYPES_* for details.
+/// See AST_POLYMORPHIC_SUPPORTED_TYPES for details.
 template <class T> struct ExtractFunctionArgMeta;
 template <class T> struct ExtractFunctionArgMeta<void(T)> {
   typedef T type;

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchersMacros.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchersMacros.h?rev=231575&r1=231574&r2=231575&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchersMacros.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchersMacros.h Sat Mar  7 14:38:15 2015
@@ -193,15 +193,8 @@
 /// \c void(TypeList<Foo, Bar>), which works thanks to the parenthesis.
 /// The \c PolymorphicMatcherWithParam* classes will unpack the function type to
 /// extract the TypeList object.
-#define AST_POLYMORPHIC_SUPPORTED_TYPES_1(t1) void(internal::TypeList<t1>)
-#define AST_POLYMORPHIC_SUPPORTED_TYPES_2(t1, t2)                              \
-  void(internal::TypeList<t1, t2>)
-#define AST_POLYMORPHIC_SUPPORTED_TYPES_3(t1, t2, t3)                          \
-  void(internal::TypeList<t1, t2, t3>)
-#define AST_POLYMORPHIC_SUPPORTED_TYPES_4(t1, t2, t3, t4)                      \
-  void(internal::TypeList<t1, t2, t3, t4>)
-#define AST_POLYMORPHIC_SUPPORTED_TYPES_5(t1, t2, t3, t4, t5)                  \
-  void(internal::TypeList<t1, t2, t3, t4, t5>)
+#define AST_POLYMORPHIC_SUPPORTED_TYPES(...)                                   \
+  void(internal::TypeList<__VA_ARGS__>)
 
 /// \brief AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... }
 /// defines a single-parameter function named DefineMatcher() that is

Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp?rev=231575&r1=231574&r2=231575&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp Sat Mar  7 14:38:15 2015
@@ -2541,10 +2541,9 @@ TEST(AstMatcherPMacro, Works) {
       HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
 }
 
-AST_POLYMORPHIC_MATCHER_P(
-    polymorphicHas,
-    AST_POLYMORPHIC_SUPPORTED_TYPES_2(Decl, Stmt),
-    internal::Matcher<Decl>, AMatcher) {
+AST_POLYMORPHIC_MATCHER_P(polymorphicHas,
+                          AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt),
+                          internal::Matcher<Decl>, AMatcher) {
   return Finder->matchesChildOf(
       Node, AMatcher, Builder,
       ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,





More information about the cfe-commits mailing list