diff options
author | Martin Bohme <mboehme@google.com> | 2016-08-09 15:07:52 +0000 |
---|---|---|
committer | Martin Bohme <mboehme@google.com> | 2016-08-09 15:07:52 +0000 |
commit | e8aa1a2a0be336b5975327433851a7a807d420bf (patch) | |
tree | 7fbab59291298f3a80159dd97d3822d87032a3ee /include/clang/ASTMatchers | |
parent | ecf27f00beed659c1978fedb10d731204ea32781 (diff) |
[ASTMatchers] Add matchers canReferToDecl() and hasUnderlyingDecl()
Summary: Required for D22220
Reviewers: sbenza, klimek, aaron.ballman, alexfh
Subscribers: alexfh, klimek, cfe-commits
Differential Revision: https://reviews.llvm.org/D23004
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@278123 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/ASTMatchers')
-rw-r--r-- | include/clang/ASTMatchers/ASTMatchers.h | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index 2a5f047076..6f194e2a57 100644 --- a/include/clang/ASTMatchers/ASTMatchers.h +++ b/include/clang/ASTMatchers/ASTMatchers.h @@ -2468,6 +2468,25 @@ hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) { void(internal::HasDeclarationSupportedTypes)>(InnerMatcher); } +/// \brief Matches a \c NamedDecl whose underlying declaration matches the given +/// matcher. +/// +/// Given +/// \code +/// namespace N { template<class T> void f(T t); } +/// template <class T> void g() { using N::f; f(T()); } +/// \endcode +/// \c unresolvedLookupExpr(hasAnyDeclaration( +/// namedDecl(hasUnderlyingDecl(hasName("::N::f"))))) +/// matches the use of \c f in \c g() . +AST_MATCHER_P(NamedDecl, hasUnderlyingDecl, internal::Matcher<NamedDecl>, + InnerMatcher) { + const NamedDecl *UnderlyingDecl = Node.getUnderlyingDecl(); + + return UnderlyingDecl != nullptr && + InnerMatcher.matches(*UnderlyingDecl, Finder, Builder); +} + /// \brief Matches on the implicit object argument of a member call expression. /// /// Example matches y.x() @@ -2823,6 +2842,27 @@ AST_MATCHER_P(DeclRefExpr, throughUsingDecl, return false; } +/// \brief Matches an \c OverloadExpr if any of the declarations in the set of +/// overloads matches the given matcher. +/// +/// Given +/// \code +/// template <typename T> void foo(T); +/// template <typename T> void bar(T); +/// template <typename T> void baz(T t) { +/// foo(t); +/// bar(t); +/// } +/// \endcode +/// unresolvedLookupExpr(hasAnyDeclaration( +/// functionTemplateDecl(hasName("foo")))) +/// matches \c foo in \c foo(t); but not \c bar in \c bar(t); +AST_MATCHER_P(OverloadExpr, hasAnyDeclaration, internal::Matcher<Decl>, + InnerMatcher) { + return matchesFirstInPointerRange(InnerMatcher, Node.decls_begin(), + Node.decls_end(), Finder, Builder); +} + /// \brief Matches the Decl of a DeclStmt which has a single declaration. /// /// Given |