From 72b56ed6b46e790b75f9a5524e389dd595f625b5 Mon Sep 17 00:00:00 2001 From: Shuai Wang Date: Sun, 12 Aug 2018 17:34:36 +0000 Subject: [PATCH] [ASTMatchers] Add matchers unresolvedMemberExpr, cxxDependentScopeMemberExpr Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D50606 llvm-svn: 339522 --- clang/docs/LibASTMatchersReference.html | 27 +++++++++++++++++- clang/include/clang/ASTMatchers/ASTMatchers.h | 28 +++++++++++++++++++ clang/lib/ASTMatchers/ASTMatchersInternal.cpp | 4 +++ clang/lib/ASTMatchers/Dynamic/Registry.cpp | 2 ++ clang/unittests/AST/ASTImporterTest.cpp | 6 ---- .../ASTMatchers/ASTMatchersNodeTest.cpp | 14 ++++++++++ 6 files changed, 74 insertions(+), 7 deletions(-) diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html index cf32a5ce4a0f..2f05a648a678 100644 --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -866,6 +866,17 @@ cxxDeleteExpr() +Matcher<Stmt>cxxDependentScopeMemberExprMatcher<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>cxxDynamicCastExprMatcher<CXXDynamicCastExpr>...
Matches a dynamic_cast expression.
 
@@ -1455,6 +1466,20 @@ unresolvedLookupExpr()
   matches foo<T>() 
+Matcher<Stmt>unresolvedMemberExprMatcher<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>userDefinedLiteralMatcher<UserDefinedLiteral>...
Matches user defined literal operator call.
 
@@ -1598,7 +1623,7 @@ Given:
   short i = 1;
   int j = 42;
   decltype(i + j) result = i + j;
-decltypeType() 
+decltypeType()
   matches "decltype(i + j)"
 
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 2552ff2795f4..51d99d50ba7b 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -1141,6 +1141,34 @@ extern const internal::VariadicDynCastAllOfMatcher declStmt; /// 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() diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp index 97b0ab8fd313..186289cd40ab 100644 --- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp +++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp @@ -610,6 +610,10 @@ const internal::VariadicDynCastAllOfMatcher friendDecl; 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 diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp index 4d2d76f6a75b..4cf70f94c784 100644 --- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -167,6 +167,7 @@ RegistryMaps::RegistryMaps() { 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 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(unaryTransformType); REGISTER_MATCHER(unless); REGISTER_MATCHER(unresolvedLookupExpr); + REGISTER_MATCHER(unresolvedMemberExpr); REGISTER_MATCHER(unresolvedUsingTypenameDecl); REGISTER_MATCHER(unresolvedUsingValueDecl); REGISTER_MATCHER(userDefinedLiteral); diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp index 70edd150467c..7d61e98be1a7 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -814,9 +814,6 @@ TEST_P(ImportDecl, ImportFunctionTemplateDecl) { functionTemplateDecl()); } -const internal::VariadicDynCastAllOfMatcher - cxxDependentScopeMemberExpr; - TEST_P(ImportExpr, ImportCXXDependentScopeMemberExpr) { MatchVerifier Verifier; testImport( @@ -2364,9 +2361,6 @@ TEST_P(ImportExpr, DependentNameType) { cxxRecordDecl(has(typedefDecl(has(dependentNameType()))))))); } -const internal::VariadicDynCastAllOfMatcher - unresolvedMemberExpr; - TEST_P(ImportExpr, UnresolvedMemberExpr) { MatchVerifier Verifier; testImport("struct S { template void mem(); };" diff --git a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp index e521940983b2..8860170bae64 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp @@ -422,10 +422,17 @@ TEST(UnaryExprOrTypeTraitExpr, MatchesSizeOfAndAlignOf) { 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 @@ TEST(MemberExpression, MatchesVariable) { 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) {