From c1384c138c0000368ea6751fc7b6ac164cae849b Mon Sep 17 00:00:00 2001 From: Samuel Benzaquen Date: Fri, 25 Mar 2016 16:29:30 +0000 Subject: [PATCH] [ASTMatchers] Add own version of VariadicFunction. Summary: llvm::VariadicFunction is only being used by ASTMatchers. Having our own copy here allows us to remove the other one from llvm/ADT. Also, we can extend the API to meet our needs without modifying the common implementation. Reviewers: alexfh Subscribers: klimek, cfe-commits Differential Revision: http://reviews.llvm.org/D18275 llvm-svn: 264417 --- clang/include/clang/ASTMatchers/ASTMatchers.h | 4 +- .../clang/ASTMatchers/ASTMatchersInternal.h | 51 ++++++++++++++++++---- clang/lib/ASTMatchers/Dynamic/Marshallers.h | 11 ++--- 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 6835ea0..b727ff8 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -1990,8 +1990,8 @@ inline internal::Matcher hasName(const std::string &Name) { /// \code /// anyOf(hasName(a), hasName(b), hasName(c)) /// \endcode -const llvm::VariadicFunction, StringRef, - internal::hasAnyNameFunc> +const internal::VariadicFunction, 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 f6b4086..185badb 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 #include @@ -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 )> +struct VariadicFunction { + ResultT operator()() const { return Func({}); } + + template + ResultT operator()(const ArgT &Arg1, const ArgsT &... Args) const { + return Execute(Arg1, static_cast(Args)...); + } + + // We also allow calls with an already created array, in case the caller + // already had it. + ResultT operator()(ArrayRef Args) const { + SmallVector 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 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 @@ -1405,9 +1439,8 @@ inline bool ValueEqualsMatcher::matchesNode( /// casted to CXXRecordDecl and all given matchers match. template class VariadicDynCastAllOfMatcher - : public llvm::VariadicFunction< - BindableMatcher, Matcher, - makeDynCastAllOfComposite > { + : public VariadicFunction, Matcher, + makeDynCastAllOfComposite> { public: VariadicDynCastAllOfMatcher() {} }; @@ -1423,9 +1456,9 @@ public: /// \c Matcher. /// The returned matcher matches if all given matchers match. template -class VariadicAllOfMatcher : public llvm::VariadicFunction< - BindableMatcher, Matcher, - makeAllOfComposite > { +class VariadicAllOfMatcher + : public VariadicFunction, Matcher, + makeAllOfComposite> { public: VariadicAllOfMatcher() {} }; @@ -1546,8 +1579,8 @@ public: new MatcherImpl(InnerMatcher, Getter::value())); } - struct Func : public llvm::VariadicFunction, - &Self::create> { + struct Func + : public VariadicFunction, &Self::create> { Func() {} }; diff --git a/clang/lib/ASTMatchers/Dynamic/Marshallers.h b/clang/lib/ASTMatchers/Dynamic/Marshallers.h index 6bf8878..f28abb0 100644 --- a/clang/lib/ASTMatchers/Dynamic/Marshallers.h +++ b/clang/lib/ASTMatchers/Dynamic/Marshallers.h @@ -325,8 +325,9 @@ public: template )> - VariadicFuncMatcherDescriptor(llvm::VariadicFunction Func, - StringRef MatcherName) + VariadicFuncMatcherDescriptor( + ast_matchers::internal::VariadicFunction Func, + StringRef MatcherName) : Func(&variadicMatcherDescriptor), MatcherName(MatcherName.str()), ArgsKind(ArgTypeTraits::getKind()) { @@ -655,9 +656,9 @@ MatcherDescriptor *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1, ArgType2 /// \brief Variadic overload. template )> -MatcherDescriptor * -makeMatcherAutoMarshall(llvm::VariadicFunction VarFunc, - StringRef MatcherName) { +MatcherDescriptor *makeMatcherAutoMarshall( + ast_matchers::internal::VariadicFunction VarFunc, + StringRef MatcherName) { return new VariadicFuncMatcherDescriptor(VarFunc, MatcherName); } diff --git a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp index 713ef5a..fc98373 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 Names = {"::C", "::b::C", "::a::b::C"}; + EXPECT_TRUE(matches(Code, recordDecl(hasAnyName(Names)))); } TEST(Matcher, IsDefinition) { -- 2.7.4