diff options
-rw-r--r-- | clang/include/clang/ASTMatchers/ASTMatchers.h | 4 | ||||
-rw-r--r-- | clang/include/clang/ASTMatchers/ASTMatchersInternal.h | 51 | ||||
-rw-r--r-- | clang/lib/ASTMatchers/Dynamic/Marshallers.h | 11 | ||||
-rw-r--r-- | clang/unittests/ASTMatchers/ASTMatchersTest.cpp | 3 |
4 files changed, 53 insertions, 16 deletions
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 6835ea0871b..b727ff897bd 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -1990,8 +1990,8 @@ inline internal::Matcher<NamedDecl> hasName(const std::string &Name) { /// \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 diff --git a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h index f6b40867c65..185badb8dd2 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h +++ b/clang/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 @@ class BoundNodes; 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 @@ inline bool ValueEqualsMatcher<FloatingLiteral, llvm::APFloat>::matchesNode( /// 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 @@ public: /// \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 @@ public: 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() {} }; diff --git a/clang/lib/ASTMatchers/Dynamic/Marshallers.h b/clang/lib/ASTMatchers/Dynamic/Marshallers.h index 6bf887860bc..f28abb06f90 100644 --- a/clang/lib/ASTMatchers/Dynamic/Marshallers.h +++ b/clang/lib/ASTMatchers/Dynamic/Marshallers.h @@ -325,8 +325,9 @@ public: 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 @@ MatcherDescriptor *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1, ArgType2 /// \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); } diff --git a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp index 713ef5a84fe..fc983737f4a 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp @@ -3000,6 +3000,9 @@ TEST(Matcher, HasAnyName) { 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) { |