Index: include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- include/clang/ASTMatchers/ASTMatchers.h +++ include/clang/ASTMatchers/ASTMatchers.h @@ -76,6 +76,9 @@ const T *getStmtAs(StringRef ID) const { return getNodeAs(StmtBindings, ID); } + QualType *getType(StringRef ID) const { + + } /// @} private: @@ -130,6 +133,14 @@ return internal::PolymorphicMatcherWithParam0(); } +/// \brief Matches types. +/// +/// Examples matches TODO +/// \code +/// TODO +/// \endcode +const internal::VariadicNodeMatcher type; + /// \brief Matches declarations. /// /// Examples matches \c X, \c C, and the friend declaration inside \c C; Index: include/clang/ASTMatchers/ASTMatchersInternal.h =================================================================== --- include/clang/ASTMatchers/ASTMatchersInternal.h +++ include/clang/ASTMatchers/ASTMatchersInternal.h @@ -598,9 +598,12 @@ template class BindableMatcher : public Matcher { public: - BindableMatcher(MatcherInterface *Implementation) + explicit BindableMatcher(MatcherInterface *Implementation) : Matcher(Implementation) {} + explicit BindableMatcher(const Matcher &Other) + : Matcher(Other) {} + /// \brief Returns a matcher that will bind the matched node on a match. /// /// The returned matcher is equivalent to this matcher, but will @@ -733,6 +736,21 @@ const Matcher InnertMatcher2; }; +template +BindableMatcher makeAllOfComposite( + ArrayRef *> Matchers) { + if (Matchers.empty()) { + return BindableMatcher(new TrueMatcher); + } + Matcher Combined = *Matchers.back(); + for (int i = Matchers.size() - 2; i >= 0; --i) { + Combined = makeMatcher( + new AllOfMatcher, Matcher >( + *Matchers[i], Combined)); + } + return BindableMatcher(Combined); +} + /// \brief Creates a Matcher that matches if /// T is dyn_cast'able into InnerT and all inner matchers match. /// @@ -742,17 +760,8 @@ template BindableMatcher makeDynCastAllOfComposite( ArrayRef *> InnerMatchers) { - if (InnerMatchers.empty()) { - Matcher InnerMatcher = makeMatcher(new TrueMatcher); - return BindableMatcher(new DynCastMatcher(InnerMatcher)); - } - Matcher InnerMatcher = *InnerMatchers.back(); - for (int i = InnerMatchers.size() - 2; i >= 0; --i) { - InnerMatcher = makeMatcher( - new AllOfMatcher, Matcher >( - *InnerMatchers[i], InnerMatcher)); - } - return BindableMatcher(new DynCastMatcher(InnerMatcher)); + return BindableMatcher(new DynCastMatcher( + makeAllOfComposite(InnerMatchers))); } /// \brief Matches nodes of type T that have at least one descendant node of @@ -894,6 +903,15 @@ VariadicDynCastAllOfMatcher() {} }; +template +class VariadicNodeMatcher + : public llvm::VariadicFunction< + BindableMatcher, Matcher, + makeAllOfComposite > { +public: + VariadicNodeMatcher() {} +}; + } // end namespace internal } // end namespace ast_matchers } // end namespace clang Index: unittests/ASTMatchers/ASTMatchersTest.cpp =================================================================== --- unittests/ASTMatchers/ASTMatchersTest.cpp +++ unittests/ASTMatchers/ASTMatchersTest.cpp @@ -45,6 +45,11 @@ decl(usingDecl()))); } +TEST(Type, MatchesTypes) { + EXPECT_TRUE(notMatches("", type(asString("x")).bind("x"))); + EXPECT_TRUE(matches("typedef int x; x y;", type(asString("x")))); +} + TEST(NameableDeclaration, MatchesVariousDecls) { DeclarationMatcher NamedX = nameableDeclaration(hasName("X")); EXPECT_TRUE(matches("typedef int X;", NamedX));