Index: include/clang/ASTMatchers/ASTMatchersInternal.h =================================================================== --- include/clang/ASTMatchers/ASTMatchersInternal.h +++ include/clang/ASTMatchers/ASTMatchersInternal.h @@ -1577,6 +1577,7 @@ : public VariadicFunction, Matcher, makeAllOfComposite> { public: + using Type = T; VariadicAllOfMatcher() {} }; Index: lib/ASTMatchers/Dynamic/Registry.cpp =================================================================== --- lib/ASTMatchers/Dynamic/Registry.cpp +++ lib/ASTMatchers/Dynamic/Registry.cpp @@ -44,18 +44,54 @@ using ConstructorMap = llvm::StringMap>; +using NodeConstructorMap = + std::map>; + class RegistryMaps { public: RegistryMaps(); ~RegistryMaps(); const ConstructorMap &constructors() const { return Constructors; } + const NodeConstructorMap &nodeConstructors() const { + return NodeConstructors; + } + + void registerNodeMatcher(ast_type_traits::ASTNodeKind kind, + internal::MatcherDescriptor *Callback); private: void registerMatcher(StringRef MatcherName, std::unique_ptr Callback); + template + void registerIfNodeMatcher(MatcherType, + internal::MatcherDescriptor *Descriptor, + StringRef) {} + + template + void registerIfNodeMatcher( + ast_matchers::internal::VariadicAllOfMatcher VarFunc, + internal::MatcherDescriptor *Descriptor, StringRef MatcherName) { + auto NodeKind = ast_type_traits::ASTNodeKind::getFromNodeKind< + typename ast_matchers::internal::VariadicAllOfMatcher::Type>(); + if (!NodeKind.isNone()) + NodeConstructors[NodeKind] = std::make_pair(MatcherName, Descriptor); + } + + template + void registerIfNodeMatcher( + ast_matchers::internal::VariadicDynCastAllOfMatcher + VarFunc, + internal::MatcherDescriptor *Descriptor, StringRef MatcherName) { + auto NodeKind = ast_type_traits::ASTNodeKind::getFromNodeKind(); + if (!NodeKind.isNone()) + NodeConstructors[NodeKind] = std::make_pair(MatcherName, Descriptor); + } + ConstructorMap Constructors; + NodeConstructorMap NodeConstructors; }; } // namespace @@ -67,8 +103,13 @@ } #define REGISTER_MATCHER(name) \ - registerMatcher(#name, internal::makeMatcherAutoMarshall( \ - ::clang::ast_matchers::name, #name)); + { \ + auto Descriptor = \ + internal::makeMatcherAutoMarshall(::clang::ast_matchers::name, #name); \ + registerIfNodeMatcher(::clang::ast_matchers::name, Descriptor.get(), \ + #name); \ + registerMatcher(#name, std::move(Descriptor)); \ + } #define REGISTER_MATCHER_OVERLOAD(name) \ registerMatcher(#name, \