From d93c4f42bb3a79c9ec3eb2500ba13a07df93d034 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Sat, 7 Mar 2015 20:38:15 +0000 Subject: [PATCH] ASTMatchers: Make AST_POLYMORPHIC_SUPPORTED_TYPES a variadic macro C++11 finally allows us to use this C99 feature. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@231575 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/tools/dump_ast_matchers.py | 4 +- include/clang/ASTMatchers/ASTMatchers.h | 116 +++++++++--------- .../clang/ASTMatchers/ASTMatchersInternal.h | 2 +- include/clang/ASTMatchers/ASTMatchersMacros.h | 11 +- unittests/ASTMatchers/ASTMatchersTest.cpp | 7 +- 5 files changed, 68 insertions(+), 72 deletions(-) diff --git a/docs/tools/dump_ast_matchers.py b/docs/tools/dump_ast_matchers.py index 4ece46ae34..1e1fd3c9d6 100644 --- a/docs/tools/dump_ast_matchers.py +++ b/docs/tools/dump_ast_matchers.py @@ -163,7 +163,7 @@ def act_on_decl(declaration, comment, allowed_types): 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, allowed_types): 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* diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index 4501a42149..16d9e8dd52 100644 --- a/include/clang/ASTMatchers/ASTMatchers.h +++ b/include/clang/ASTMatchers/ASTMatchers.h @@ -181,8 +181,7 @@ const internal::VariadicDynCastAllOfMatcher typedefDecl; /// /// Usable as: Matcher, Matcher, Matcher 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(isExpansionInMainFile, /// /// Usable as: Matcher, Matcher, Matcher 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(isExpansionInSystemHeader, /// /// Usable as: Matcher, Matcher, Matcher 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 AST_POLYMORPHIC_MATCHER_P( hasAnyTemplateArgument, - AST_POLYMORPHIC_SUPPORTED_TYPES_2(ClassTemplateSpecializationDecl, - TemplateSpecializationType), + AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl, + TemplateSpecializationType), internal::Matcher, InnerMatcher) { ArrayRef List = internal::getTemplateSpecializationArgs(Node); @@ -556,8 +553,8 @@ AST_MATCHER_P(Expr, ignoringParenImpCasts, /// matches the specialization \c A AST_POLYMORPHIC_MATCHER_P2( hasTemplateArgument, - AST_POLYMORPHIC_SUPPORTED_TYPES_2(ClassTemplateSpecializationDecl, - TemplateSpecializationType), + AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl, + TemplateSpecializationType), unsigned, N, internal::Matcher, InnerMatcher) { ArrayRef List = internal::getTemplateSpecializationArgs(Node); @@ -577,8 +574,8 @@ AST_POLYMORPHIC_MATCHER_P2( /// matches C. 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, std::string, RegExp) { /// Usable as: Matcher, Matcher 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, internal::Matcher, InnerMatcher, /// 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, InnerMatcher, 0) { return InnerMatcher.matches(Node.getType(), Finder, Builder); } @@ -2079,9 +2075,10 @@ AST_POLYMORPHIC_MATCHER_P_OVERLOAD( /// \endcode /// /// Usable as: Matcher, Matcher -AST_POLYMORPHIC_MATCHER_P_OVERLOAD( - hasType, AST_POLYMORPHIC_SUPPORTED_TYPES_2(Expr, ValueDecl), - internal::Matcher, InnerMatcher, 1) { +AST_POLYMORPHIC_MATCHER_P_OVERLOAD(hasType, + AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, + ValueDecl), + internal::Matcher, 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(argumentCountIs, AST_POLYMORPHIC_SUPPORTED_TYPES_2( /// \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, InnerMatcher) { +AST_POLYMORPHIC_MATCHER_P2(hasArgument, + AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr, + CXXConstructExpr), + unsigned, N, internal::Matcher, InnerMatcher) { return (N < Node.getNumArgs() && InnerMatcher.matches( *Node.getArg(N)->IgnoreParenImpCasts(), Finder, Builder)); @@ -2474,8 +2472,9 @@ AST_MATCHER(CXXCtorInitializer, isWritten) { /// 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, 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, InnerMatcher) { +AST_POLYMORPHIC_MATCHER_P(hasCondition, + AST_POLYMORPHIC_SUPPORTED_TYPES(IfStmt, ForStmt, + WhileStmt, DoStmt, + ConditionalOperator), + internal::Matcher, 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::Matcher, InnerMatcher) { /// 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, hasBase, /// 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, 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, hasFalseExpression, /// \endcode /// /// Usable as: Matcher, Matcher, Matcher -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, hasTargetDecl, /// does not match, as X is an explicit template specialization. /// /// Usable as: Matcher, Matcher, Matcher -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, isInTemplateInstantiation) { /// matches the specialization A(). /// /// Usable as: Matcher, Matcher, Matcher -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, complexType); /// matches "int b[7]" /// /// Usable as: Matcher, Matcher -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 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 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 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, rValueReferenceType); /// /// Usable as: Matcher, Matcher, /// Matcher, Matcher -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. /// diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h index 86a31ea280..d96e3a9f7c 100644 --- a/include/clang/ASTMatchers/ASTMatchersInternal.h +++ b/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -887,7 +887,7 @@ typedef TypeList struct ExtractFunctionArgMeta; template struct ExtractFunctionArgMeta { typedef T type; diff --git a/include/clang/ASTMatchers/ASTMatchersMacros.h b/include/clang/ASTMatchers/ASTMatchersMacros.h index 7167dfb898..b25447f5b7 100644 --- a/include/clang/ASTMatchers/ASTMatchersMacros.h +++ b/include/clang/ASTMatchers/ASTMatchersMacros.h @@ -193,15 +193,8 @@ /// \c void(TypeList), 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) -#define AST_POLYMORPHIC_SUPPORTED_TYPES_2(t1, t2) \ - void(internal::TypeList) -#define AST_POLYMORPHIC_SUPPORTED_TYPES_3(t1, t2, t3) \ - void(internal::TypeList) -#define AST_POLYMORPHIC_SUPPORTED_TYPES_4(t1, t2, t3, t4) \ - void(internal::TypeList) -#define AST_POLYMORPHIC_SUPPORTED_TYPES_5(t1, t2, t3, t4, t5) \ - void(internal::TypeList) +#define AST_POLYMORPHIC_SUPPORTED_TYPES(...) \ + void(internal::TypeList<__VA_ARGS__>) /// \brief AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... } /// defines a single-parameter function named DefineMatcher() that is diff --git a/unittests/ASTMatchers/ASTMatchersTest.cpp b/unittests/ASTMatchers/ASTMatchersTest.cpp index dab22e33cd..d43e3f339b 100644 --- a/unittests/ASTMatchers/ASTMatchersTest.cpp +++ b/unittests/ASTMatchers/ASTMatchersTest.cpp @@ -2541,10 +2541,9 @@ TEST(AstMatcherPMacro, Works) { HasClassB, new VerifyIdIsBoundTo("b"))); } -AST_POLYMORPHIC_MATCHER_P( - polymorphicHas, - AST_POLYMORPHIC_SUPPORTED_TYPES_2(Decl, Stmt), - internal::Matcher, AMatcher) { +AST_POLYMORPHIC_MATCHER_P(polymorphicHas, + AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt), + internal::Matcher, AMatcher) { return Finder->matchesChildOf( Node, AMatcher, Builder, ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses, -- 2.40.0