Index: include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- include/clang/ASTMatchers/ASTMatchers.h +++ include/clang/ASTMatchers/ASTMatchers.h @@ -1990,8 +1990,8 @@ /// \code /// anyOf(hasName(a), hasName(b), hasName(c)) /// \endcode -const llvm::VariadicFunction<internal::Matcher<NamedDecl>, StringRef, - internal::hasAnyNameFunc> +const internal::VariadicFunction<internal::Matcher<NamedDecl>, StringRef, + internal::hasAnyNameFunc> hasAnyName = {}; /// \brief Matches NamedDecl nodes whose fully qualified names contain Index: include/clang/ASTMatchers/ASTMatchersInternal.h =================================================================== --- include/clang/ASTMatchers/ASTMatchersInternal.h +++ include/clang/ASTMatchers/ASTMatchersInternal.h @@ -46,8 +46,9 @@ #include "clang/AST/StmtCXX.h" #include "clang/AST/StmtObjC.h" #include "clang/AST/Type.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" -#include "llvm/ADT/VariadicFunction.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/ManagedStatic.h" #include <map> #include <string> @@ -60,6 +61,39 @@ namespace internal { +/// \brief Variadic function object. +/// +/// Most of the functions below that use VariadicFunction could be implemented +/// using plain C++11 variadic functions, but the function object allows us to +/// capture it on the dynamic matcher registry. +template <typename ResultT, typename ArgT, + ResultT (*Func)(ArrayRef<const ArgT *>)> +struct VariadicFunction { + ResultT operator()() const { return Func({}); } + + template <typename... ArgsT> + ResultT operator()(const ArgT &Arg1, const ArgsT &... Args) const { + return Execute(Arg1, static_cast<const ArgT &>(Args)...); + } + + // We also allow calls with an already created array, in case the caller + // already had it. + ResultT operator()(ArrayRef<ArgT> Args) const { + SmallVector<const ArgT*, 8> InnerArgs; + for (const ArgT &Arg : Args) + InnerArgs.push_back(&Arg); + return Func(InnerArgs); + } + +private: + // Trampoline function to allow for implicit conversions to take place + // before we make the array. + template <typename... ArgsT> ResultT Execute(const ArgsT &... Args) const { + const ArgT *const ArgsArray[] = {&Args...}; + return Func(ArgsArray); + } +}; + /// \brief Unifies obtaining the underlying type of a regular node through /// `getType` and a TypedefNameDecl node through `getUnderlyingType`. template <typename NodeType> @@ -1405,9 +1439,8 @@ /// casted to CXXRecordDecl and all given matchers match. template <typename SourceT, typename TargetT> class VariadicDynCastAllOfMatcher - : public llvm::VariadicFunction< - BindableMatcher<SourceT>, Matcher<TargetT>, - makeDynCastAllOfComposite<SourceT, TargetT> > { + : public VariadicFunction<BindableMatcher<SourceT>, Matcher<TargetT>, + makeDynCastAllOfComposite<SourceT, TargetT>> { public: VariadicDynCastAllOfMatcher() {} }; @@ -1423,9 +1456,9 @@ /// \c Matcher<NestedNameSpecifier>. /// The returned matcher matches if all given matchers match. template <typename T> -class VariadicAllOfMatcher : public llvm::VariadicFunction< - BindableMatcher<T>, Matcher<T>, - makeAllOfComposite<T> > { +class VariadicAllOfMatcher + : public VariadicFunction<BindableMatcher<T>, Matcher<T>, + makeAllOfComposite<T>> { public: VariadicAllOfMatcher() {} }; @@ -1546,8 +1579,8 @@ new MatcherImpl<OuterT>(InnerMatcher, Getter<OuterT>::value())); } - struct Func : public llvm::VariadicFunction<Self, Matcher<InnerTBase>, - &Self::create> { + struct Func + : public VariadicFunction<Self, Matcher<InnerTBase>, &Self::create> { Func() {} }; Index: lib/ASTMatchers/Dynamic/Marshallers.h =================================================================== --- lib/ASTMatchers/Dynamic/Marshallers.h +++ lib/ASTMatchers/Dynamic/Marshallers.h @@ -325,8 +325,9 @@ template <typename ResultT, typename ArgT, ResultT (*F)(ArrayRef<const ArgT *>)> - VariadicFuncMatcherDescriptor(llvm::VariadicFunction<ResultT, ArgT, F> Func, - StringRef MatcherName) + VariadicFuncMatcherDescriptor( + ast_matchers::internal::VariadicFunction<ResultT, ArgT, F> Func, + StringRef MatcherName) : Func(&variadicMatcherDescriptor<ResultT, ArgT, F>), MatcherName(MatcherName.str()), ArgsKind(ArgTypeTraits<ArgT>::getKind()) { @@ -655,9 +656,9 @@ /// \brief Variadic overload. template <typename ResultT, typename ArgT, ResultT (*Func)(ArrayRef<const ArgT *>)> -MatcherDescriptor * -makeMatcherAutoMarshall(llvm::VariadicFunction<ResultT, ArgT, Func> VarFunc, - StringRef MatcherName) { +MatcherDescriptor *makeMatcherAutoMarshall( + ast_matchers::internal::VariadicFunction<ResultT, ArgT, Func> VarFunc, + StringRef MatcherName) { return new VariadicFuncMatcherDescriptor(VarFunc, MatcherName); } Index: unittests/ASTMatchers/ASTMatchersTest.cpp =================================================================== --- unittests/ASTMatchers/ASTMatchersTest.cpp +++ unittests/ASTMatchers/ASTMatchersTest.cpp @@ -3000,6 +3000,9 @@ EXPECT_TRUE(notMatches(Code, recordDecl(hasAnyName("::C", "::b::C")))); EXPECT_TRUE( matches(Code, recordDecl(hasAnyName("::C", "::b::C", "::a::b::C")))); + + std::vector<StringRef> Names = {"::C", "::b::C", "::a::b::C"}; + EXPECT_TRUE(matches(Code, recordDecl(hasAnyName(Names)))); } TEST(Matcher, IsDefinition) {