diff options
author | Samuel Benzaquen <sbenza@google.com> | 2013-08-16 16:19:42 +0000 |
---|---|---|
committer | Samuel Benzaquen <sbenza@google.com> | 2013-08-16 16:19:42 +0000 |
commit | bd7d887f186808d19e37d526ba543e0e2dc29397 (patch) | |
tree | 82fbac426f8aba0b777bb53defbd0c034d34e1c5 /clang/lib/ASTMatchers/Dynamic/Registry.cpp | |
parent | 8522270d7e2cb0c5417de0f58b20761cf9273f3d (diff) | |
download | bcm5719-llvm-bd7d887f186808d19e37d526ba543e0e2dc29397.tar.gz bcm5719-llvm-bd7d887f186808d19e37d526ba543e0e2dc29397.zip |
Refactor ArgumentAdaptativeMatcher matchers to remove the template from their declaration.
Summary:
Refactor ArgumentAdaptativeMatcher matchers to remove the template from their declaration.
This facilitates dynamic registration. Change the registry code to use the regular overload resolution mechanism for adaptative matchers.
Reviewers: klimek
CC: cfe-commits, revane
Differential Revision: http://llvm-reviews.chandlerc.com/D1402
llvm-svn: 188560
Diffstat (limited to 'clang/lib/ASTMatchers/Dynamic/Registry.cpp')
-rw-r--r-- | clang/lib/ASTMatchers/Dynamic/Registry.cpp | 116 |
1 files changed, 8 insertions, 108 deletions
diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp index 51d7bd856e6..55763b0efec 100644 --- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -48,48 +48,6 @@ void RegistryMaps::registerMatcher(StringRef MatcherName, Constructors[MatcherName] = Callback; } -/// \brief MatcherCreateCallback that wraps multiple "overloads" of the same -/// matcher. -/// -/// It will try every overload and generate appropriate errors for when none or -/// more than one overloads match the arguments. -class OverloadedMatcherCreateCallback : public MatcherCreateCallback { - public: - OverloadedMatcherCreateCallback(ArrayRef<MatcherCreateCallback *> Callbacks) - : Overloads(Callbacks) {} - - virtual ~OverloadedMatcherCreateCallback() { - for (size_t i = 0, e = Overloads.size(); i != e; ++i) - delete Overloads[i]; - } - - virtual VariantMatcher run(const SourceRange &NameRange, - ArrayRef<ParserValue> Args, - Diagnostics *Error) const { - std::vector<VariantMatcher> Constructed; - Diagnostics::OverloadContext Ctx(Error); - for (size_t i = 0, e = Overloads.size(); i != e; ++i) { - VariantMatcher SubMatcher = Overloads[i]->run(NameRange, Args, Error); - if (!SubMatcher.isNull()) { - Constructed.push_back(SubMatcher); - } - } - - if (Constructed.empty()) return VariantMatcher(); // No overload matched. - // We ignore the errors if any matcher succeeded. - Ctx.revertErrors(); - if (Constructed.size() > 1) { - // More than one constructed. It is ambiguous. - Error->addError(NameRange, Error->ET_RegistryAmbiguousOverload); - return VariantMatcher(); - } - return Constructed[0]; - } - - private: - std::vector<MatcherCreateCallback*> Overloads; -}; - #define REGISTER_MATCHER(name) \ registerMatcher(#name, internal::makeMatcherAutoMarshall( \ ::clang::ast_matchers::name, #name)); @@ -106,65 +64,8 @@ class OverloadedMatcherCreateCallback : public MatcherCreateCallback { internal::makeMatcherAutoMarshall(SPECIFIC_MATCHER_OVERLOAD(name, 1), \ #name) \ }; \ - 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)); \ + registerMatcher(#name, \ + new internal::OverloadedMatcherCreateCallback(Callbacks)); \ } while (0) /// \brief Generate a registry map with all the known matchers. @@ -196,13 +97,6 @@ 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); @@ -254,6 +148,8 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(expr); REGISTER_MATCHER(fieldDecl); REGISTER_MATCHER(floatLiteral); + REGISTER_MATCHER(forEach); + REGISTER_MATCHER(forEachDescendant); REGISTER_MATCHER(forField); REGISTER_MATCHER(forRangeStmt); REGISTER_MATCHER(forStmt); @@ -262,6 +158,8 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(functionType); REGISTER_MATCHER(functionalCastExpr); REGISTER_MATCHER(gotoStmt); + REGISTER_MATCHER(has); + REGISTER_MATCHER(hasAncestor); REGISTER_MATCHER(hasAnyArgument); REGISTER_MATCHER(hasAnyConstructorInitializer); REGISTER_MATCHER(hasAnyParameter); @@ -277,6 +175,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(hasConditionVariableStatement); REGISTER_MATCHER(hasDeclContext); REGISTER_MATCHER(hasDeducedType); + REGISTER_MATCHER(hasDescendant); REGISTER_MATCHER(hasDestinationType); REGISTER_MATCHER(hasEitherOperand); REGISTER_MATCHER(hasElementType); @@ -294,6 +193,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(hasOperatorName); REGISTER_MATCHER(hasOverloadedOperatorName); REGISTER_MATCHER(hasParameter); + REGISTER_MATCHER(hasParent); REGISTER_MATCHER(hasQualifier); REGISTER_MATCHER(hasRHS); REGISTER_MATCHER(hasSingleDecl); |