From 97aba0bb2ffb7ab8cec43a300a9ad35ed89d2769 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Wed, 18 May 2016 12:53:59 +0000 Subject: [PATCH] [ASTMatcher] Add a node matcher for UnresolvedLookupExpr. Reviewers: alexfh, aaron.ballman Subscribers: aaron.ballman, klimek, cfe-commits Differential Revision: http://reviews.llvm.org/D20360 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@269916 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/LibASTMatchersReference.html | 15 +++++++++++++++ include/clang/ASTMatchers/ASTMatchers.h | 18 ++++++++++++++++++ lib/ASTMatchers/Dynamic/Registry.cpp | 1 + unittests/ASTMatchers/ASTMatchersNodeTest.cpp | 9 +++++++++ 4 files changed, 43 insertions(+) diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html index e7c0574068..27e934ccac 100644 --- a/docs/LibASTMatchersReference.html +++ b/docs/LibASTMatchersReference.html @@ -1275,6 +1275,21 @@ Example matches !a +Matcher<Stmt>unresolvedLookupExprMatcher<UnresolvedLookupExpr>... +
Matches reference to a name that can be looked up during parsing
+but could not be resolved to a specific declaration.
+
+Given
+  template<typename T>
+  T foo() { T a; return a; }
+  template<typename T>
+  void bar() {
+    foo<T>();
+  }
+unresolvedLookupExpr()
+  matches foo<T>() 
+ + Matcher<Stmt>userDefinedLiteralMatcher<UserDefinedLiteral>...
Matches user defined literal operator call.
 
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
index 20980731c9..7b1a7e77d5 100644
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -1086,6 +1086,24 @@ const internal::VariadicDynCastAllOfMatcher<
   Decl,
   UsingDirectiveDecl> usingDirectiveDecl;
 
+/// \brief Matches reference to a name that can be looked up during parsing
+/// but could not be resolved to a specific declaration.
+///
+/// Given
+/// \code
+///   template
+///   T foo() { T a; return a; }
+///   template
+///   void bar() {
+///     foo();
+///   }
+/// \endcode
+/// unresolvedLookupExpr()
+///   matches \code foo() \endcode
+const internal::VariadicDynCastAllOfMatcher<
+   Stmt,
+   UnresolvedLookupExpr> unresolvedLookupExpr;
+
 /// \brief Matches unresolved using value declarations.
 ///
 /// Given
diff --git a/lib/ASTMatchers/Dynamic/Registry.cpp b/lib/ASTMatchers/Dynamic/Registry.cpp
index 87d4292c6b..7f5e50c29a 100644
--- a/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -399,6 +399,7 @@ RegistryMaps::RegistryMaps() {
   REGISTER_MATCHER(unaryOperator);
   REGISTER_MATCHER(unaryTransformType);
   REGISTER_MATCHER(unless);
+  REGISTER_MATCHER(unresolvedLookupExpr);
   REGISTER_MATCHER(unresolvedUsingTypenameDecl);
   REGISTER_MATCHER(unresolvedUsingValueDecl);
   REGISTER_MATCHER(userDefinedLiteral);
diff --git a/unittests/ASTMatchers/ASTMatchersNodeTest.cpp b/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
index c6216d96da..8fd51eb9be 100644
--- a/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
+++ b/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
@@ -177,6 +177,15 @@ TEST(EnumConstant, Matches) {
   EXPECT_TRUE(notMatches("enum X {};", Matcher));
 }
 
+TEST(Matcher, UnresolvedLookupExpr) {
+  EXPECT_TRUE(matches("template"
+                      "T foo() { T a; return a; }"
+                      "template"
+                      "void bar() {"
+                      "  foo();"
+                      "}",
+                      unresolvedLookupExpr()));
+}
 
 TEST(Matcher, Call) {
   // FIXME: Do we want to overload Call() to directly take
-- 
2.40.0