Index: cfe/trunk/docs/LibASTMatchersReference.html
===================================================================
--- cfe/trunk/docs/LibASTMatchersReference.html
+++ cfe/trunk/docs/LibASTMatchersReference.html
@@ -866,6 +866,17 @@
+
Matcher<Stmt> | cxxDependentScopeMemberExpr | Matcher<CXXDependentScopeMemberExpr>... |
+Matches member expressions where the actual member referenced could not be
+resolved because the base expression or the member name was dependent.
+
+Given
+ template <class T> void f() { T t; t.g(); }
+cxxDependentScopeMemberExpr()
+ matches t.g
+ |
+
+
Matcher<Stmt> | cxxDynamicCastExpr | Matcher<CXXDynamicCastExpr>... |
Matches a dynamic_cast expression.
@@ -1455,6 +1466,20 @@
matches foo<T>() |
+Matcher<Stmt> | unresolvedMemberExpr | Matcher<UnresolvedMemberExpr>... |
+Matches unresolved member expressions.
+
+Given
+ struct X {
+ template <class T> void f();
+ void g();
+ };
+ template <class T> void h() { X x; x.f<T>(); x.g(); }
+unresolvedMemberExpr()
+ matches x.f<T>
+ |
+
+
Matcher<Stmt> | userDefinedLiteral | Matcher<UserDefinedLiteral>... |
Matches user defined literal operator call.
@@ -1598,7 +1623,7 @@
short i = 1;
int j = 42;
decltype(i + j) result = i + j;
-decltypeType()
+decltypeType()
matches "decltype(i + j)"
|
Index: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
===================================================================
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
@@ -1141,6 +1141,34 @@
/// matches this->x, x, y.x, a, this->b
extern const internal::VariadicDynCastAllOfMatcher memberExpr;
+/// Matches unresolved member expressions.
+///
+/// Given
+/// \code
+/// struct X {
+/// template void f();
+/// void g();
+/// };
+/// template void h() { X x; x.f(); x.g(); }
+/// \endcode
+/// unresolvedMemberExpr()
+/// matches x.f
+extern const internal::VariadicDynCastAllOfMatcher
+ unresolvedMemberExpr;
+
+/// Matches member expressions where the actual member referenced could not be
+/// resolved because the base expression or the member name was dependent.
+///
+/// Given
+/// \code
+/// template void f() { T t; t.g(); }
+/// \endcode
+/// cxxDependentScopeMemberExpr()
+/// matches t.g
+extern const internal::VariadicDynCastAllOfMatcher
+ cxxDependentScopeMemberExpr;
+
/// Matches call expressions.
///
/// Example matches x.y() and y()
Index: cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
===================================================================
--- cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -610,6 +610,10 @@
const internal::VariadicAllOfMatcher stmt;
const internal::VariadicDynCastAllOfMatcher declStmt;
const internal::VariadicDynCastAllOfMatcher memberExpr;
+const internal::VariadicDynCastAllOfMatcher
+ unresolvedMemberExpr;
+const internal::VariadicDynCastAllOfMatcher
+ cxxDependentScopeMemberExpr;
const internal::VariadicDynCastAllOfMatcher callExpr;
const internal::VariadicDynCastAllOfMatcher lambdaExpr;
const internal::VariadicDynCastAllOfMatcher
Index: cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
===================================================================
--- cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
+++ cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -167,6 +167,7 @@
REGISTER_MATCHER(cxxCtorInitializer);
REGISTER_MATCHER(cxxDefaultArgExpr);
REGISTER_MATCHER(cxxDeleteExpr);
+ REGISTER_MATCHER(cxxDependentScopeMemberExpr);
REGISTER_MATCHER(cxxDestructorDecl);
REGISTER_MATCHER(cxxDynamicCastExpr);
REGISTER_MATCHER(cxxForRangeStmt);
@@ -475,6 +476,7 @@
REGISTER_MATCHER(unaryTransformType);
REGISTER_MATCHER(unless);
REGISTER_MATCHER(unresolvedLookupExpr);
+ REGISTER_MATCHER(unresolvedMemberExpr);
REGISTER_MATCHER(unresolvedUsingTypenameDecl);
REGISTER_MATCHER(unresolvedUsingValueDecl);
REGISTER_MATCHER(userDefinedLiteral);
Index: cfe/trunk/unittests/AST/ASTImporterTest.cpp
===================================================================
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp
@@ -814,9 +814,6 @@
functionTemplateDecl());
}
-const internal::VariadicDynCastAllOfMatcher
- cxxDependentScopeMemberExpr;
-
TEST_P(ImportExpr, ImportCXXDependentScopeMemberExpr) {
MatchVerifier Verifier;
testImport(
@@ -2364,9 +2361,6 @@
cxxRecordDecl(has(typedefDecl(has(dependentNameType())))))));
}
-const internal::VariadicDynCastAllOfMatcher
- unresolvedMemberExpr;
-
TEST_P(ImportExpr, UnresolvedMemberExpr) {
MatchVerifier Verifier;
testImport("struct S { template void mem(); };"
Index: cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
===================================================================
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
@@ -422,10 +422,17 @@
TEST(MemberExpression, DoesNotMatchClasses) {
EXPECT_TRUE(notMatches("class Y { void x() {} };", memberExpr()));
+ EXPECT_TRUE(notMatches("class Y { void x() {} };", unresolvedMemberExpr()));
+ EXPECT_TRUE(
+ notMatches("class Y { void x() {} };", cxxDependentScopeMemberExpr()));
}
TEST(MemberExpression, MatchesMemberFunctionCall) {
EXPECT_TRUE(matches("class Y { void x() { x(); } };", memberExpr()));
+ EXPECT_TRUE(matches("class Y { template void x() { x(); } };",
+ unresolvedMemberExpr()));
+ EXPECT_TRUE(matches("template void x() { T t; t.f(); }",
+ cxxDependentScopeMemberExpr()));
}
TEST(MemberExpression, MatchesVariable) {
@@ -435,6 +442,13 @@
matches("class Y { void x() { y; } int y; };", memberExpr()));
EXPECT_TRUE(
matches("class Y { void x() { Y y; y.y; } int y; };", memberExpr()));
+ EXPECT_TRUE(matches("template "
+ "class X : T { void f() { this->T::v; } };",
+ cxxDependentScopeMemberExpr()));
+ EXPECT_TRUE(matches("template class X : T { void f() { T::v; } };",
+ cxxDependentScopeMemberExpr()));
+ EXPECT_TRUE(matches("template void x() { T t; t.v; }",
+ cxxDependentScopeMemberExpr()));
}
TEST(MemberExpression, MatchesStaticVariable) {