diff options
| author | Samuel Benzaquen <sbenza@google.com> | 2013-07-24 14:48:01 +0000 |
|---|---|---|
| committer | Samuel Benzaquen <sbenza@google.com> | 2013-07-24 14:48:01 +0000 |
| commit | 7f8a5b140aaac95c73bb7b57875252f79dd14a4a (patch) | |
| tree | 57d4fcb634f65f64a1e0c7870701317c61896509 /clang/lib/ASTMatchers/Dynamic | |
| parent | e52a34c9938c77fb3567b8a4ab3f0272927c5ed3 (diff) | |
| download | bcm5719-llvm-7f8a5b140aaac95c73bb7b57875252f79dd14a4a.tar.gz bcm5719-llvm-7f8a5b140aaac95c73bb7b57875252f79dd14a4a.zip | |
Add support for Adaptative matchers on the dynamic registry.
Summary:
Add support for Adaptative matchers on the dynamic registry.
Each adaptative matcher is created with a function template. We instantiate the function N times, one for each possible From type and apply the techniques used on argument overloaded and polymorphic matchers to add them to the registry.
Reviewers: klimek
CC: cfe-commits, revane
Differential Revision: http://llvm-reviews.chandlerc.com/D1201
llvm-svn: 187044
Diffstat (limited to 'clang/lib/ASTMatchers/Dynamic')
| -rw-r--r-- | clang/lib/ASTMatchers/Dynamic/Registry.cpp | 73 |
1 files changed, 65 insertions, 8 deletions
diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp index 2daaa88af52..ac3241c466e 100644 --- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -109,6 +109,64 @@ class OverloadedMatcherCreateCallback : public MatcherCreateCallback { registerMatcher(#name, new OverloadedMatcherCreateCallback(Callbacks)); \ } while (0) +/// \brief Class that allows us to bind to the constructor of an +/// \c ArgumentAdaptingMatcher. +/// This class, together with \c collectAdaptativeMatcherOverloads below, help +/// us detect the Adapter class and create overload functions for the +/// appropriate To/From types. +/// We instantiate the \c createAdatingMatcher function for every type in +/// \c FromTypes. \c ToTypes is handled on the marshaller side by using the +/// \c ReturnTypes typedef in \c ArgumentAdaptingMatcher. +template <template <typename ToArg, typename FromArg> class ArgumentAdapterT, + typename FromTypes, typename ToTypes> +struct AdaptativeMatcherWrapper { + template <typename FromArg> + static ast_matchers::internal::ArgumentAdaptingMatcher< + ArgumentAdapterT, FromArg, FromTypes, ToTypes> + createAdatingMatcher( + const ast_matchers::internal::Matcher<FromArg> &InnerMatcher) { + return ast_matchers::internal::ArgumentAdaptingMatcher< + ArgumentAdapterT, FromArg, FromTypes, ToTypes>(InnerMatcher); + } + + static void collectOverloads(StringRef Name, + std::vector<MatcherCreateCallback *> &Out, + ast_matchers::internal::EmptyTypeList) {} + + template <typename FromTypeList> + static void collectOverloads(StringRef Name, + std::vector<MatcherCreateCallback *> &Out, + FromTypeList TypeList) { + Out.push_back(internal::makeMatcherAutoMarshall( + &createAdatingMatcher<typename FromTypeList::head>, Name)); + collectOverloads(Name, Out, typename FromTypeList::tail()); + } + + static void collectOverloads(StringRef Name, + std::vector<MatcherCreateCallback *> &Out) { + collectOverloads(Name, Out, FromTypes()); + } +}; + +template <template <typename ToArg, typename FromArg> class ArgumentAdapterT, + typename DummyArg, typename FromTypes, typename ToTypes> +void collectAdaptativeMatcherOverloads( + StringRef Name, + ast_matchers::internal::ArgumentAdaptingMatcher<ArgumentAdapterT, DummyArg, + FromTypes, ToTypes>( + *func)(const ast_matchers::internal::Matcher<DummyArg> &), + std::vector<MatcherCreateCallback *> &Out) { + AdaptativeMatcherWrapper<ArgumentAdapterT, FromTypes, + ToTypes>::collectOverloads(Name, Out); +} + +#define REGISTER_ADAPTATIVE(name) \ + do { \ + std::vector<MatcherCreateCallback *> Overloads; \ + collectAdaptativeMatcherOverloads(#name, &name<Decl>, Overloads); \ + registerMatcher(#name, new OverloadedMatcherCreateCallback(Overloads)); \ + } while (0) + /// \brief Generate a registry map with all the known matchers. RegistryMaps::RegistryMaps() { // TODO: Here is the list of the missing matchers, grouped by reason. @@ -123,14 +181,6 @@ RegistryMaps::RegistryMaps() { // allOf // findAll // - // Adaptative matcher (similar to polymorphic matcher): - // has - // forEach - // forEachDescendant - // hasDescendant - // hasParent - // hasAncestor - // // Other: // loc // equals @@ -146,6 +196,13 @@ RegistryMaps::RegistryMaps() { REGISTER_OVERLOADED_2(references); REGISTER_OVERLOADED_2(thisPointerType); + REGISTER_ADAPTATIVE(forEach); + REGISTER_ADAPTATIVE(forEachDescendant); + REGISTER_ADAPTATIVE(has); + REGISTER_ADAPTATIVE(hasAncestor); + REGISTER_ADAPTATIVE(hasDescendant); + REGISTER_ADAPTATIVE(hasParent); + REGISTER_MATCHER(accessSpecDecl); REGISTER_MATCHER(alignOfExpr); REGISTER_MATCHER(anything); |

