summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/ASTMatchers/ASTMatchers.h4
-rw-r--r--clang/include/clang/ASTMatchers/ASTMatchersInternal.h51
-rw-r--r--clang/lib/ASTMatchers/Dynamic/Marshallers.h11
-rw-r--r--clang/unittests/ASTMatchers/ASTMatchersTest.cpp3
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) {
OpenPOWER on IntegriCloud