diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html index e7c05740689ef50f28e813ea14d2ab353b5101d0..27e934ccacc5b597d1a61b2af5e99df6c5257faa 100644 --- a/docs/LibASTMatchersReference.html +++ b/docs/LibASTMatchersReference.html @@ -1275,6 +1275,21 @@ Example matches !a </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('unresolvedLookupExpr0')"><a name="unresolvedLookupExpr0Anchor">unresolvedLookupExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnresolvedLookupExpr.html">UnresolvedLookupExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="unresolvedLookupExpr0"><pre>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>() </pre></td></tr> + + <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('userDefinedLiteral0')"><a name="userDefinedLiteral0Anchor">userDefinedLiteral</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UserDefinedLiteral.html">UserDefinedLiteral</a>>...</td></tr> <tr><td colspan="4" class="doc" id="userDefinedLiteral0"><pre>Matches user defined literal operator call. diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index 20980731c984ba9ddaec54b50dfb53d36950ec47..7b1a7e77d5a8ad14f7987f696a41bb7d34546f7e 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<typename T> +/// T foo() { T a; return a; } +/// template<typename T> +/// void bar() { +/// foo<T>(); +/// } +/// \endcode +/// unresolvedLookupExpr() +/// matches \code foo<T>() \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 87d4292c6bc9e249e2c55aa5653490427281dca3..7f5e50c29a40ee387b36a9ccc1b95b8596e9277f 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 c6216d96dad15b94883283366d556f1098b68975..8fd51eb9be7b983843703d164825bb743a990d81 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<typename T>" + "T foo() { T a; return a; }" + "template<typename T>" + "void bar() {" + " foo<T>();" + "}", + unresolvedLookupExpr())); +} TEST(Matcher, Call) { // FIXME: Do we want to overload Call() to directly take