From: Edwin Vane Date: Thu, 7 Mar 2013 15:44:40 +0000 (+0000) Subject: Adding lvalue and rvalue reference type matchers X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f4b48042724d2253d0426cadcb93e24eeb47e264;p=clang Adding lvalue and rvalue reference type matchers Updated docs and tests. Reviewers: klimek, gribozavr git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176630 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html index a32f1a4afb..5bee8ccea4 100644 --- a/docs/LibASTMatchersReference.html +++ b/docs/LibASTMatchersReference.html @@ -973,6 +973,23 @@ incompleteArrayType() +Matcher<TypeLoc>lvalueReferenceTypeLocMatcher<LValueReferenceTypeLoc>... +
Matches lvalue reference types.
+
+Given:
+  int *a;
+  int &b = *a;
+  int &&c = 1;
+  auto &d = b;
+  auto &&e = c;
+  auto &&f = 2;
+  int g = 5;
+
+lvalueReferenceType() matches the types of b, d, and e. e is
+matched since the type is deduced as int& by reference collapsing rules.
+
+ + Matcher<TypeLoc>memberPointerTypeLocMatcher<MemberPointerTypeLoc>...
Matches member pointer types.
 Given
@@ -1011,14 +1028,35 @@ and s.
 
 
 Matcher<TypeLoc>referenceTypeLocMatcher<ReferenceTypeLoc>...
-
Matches reference types.
+
Matches both lvalue and rvalue reference types.
 
 Given
   int *a;
   int &b = *a;
-  int c = 5;
-pointerType()
-  matches "int &b"
+  int &&c = 1;
+  auto &d = b;
+  auto &&e = c;
+  auto &&f = 2;
+  int g = 5;
+
+referenceType() matches the types of b, c, d, e, and f.
+
+ + +Matcher<TypeLoc>rvalueReferenceTypeLocMatcher<RValueReferenceTypeLoc>... +
Matches rvalue reference types.
+
+Given:
+  int *a;
+  int &b = *a;
+  int &&c = 1;
+  auto &d = b;
+  auto &&e = c;
+  auto &&f = 2;
+  int g = 5;
+
+lvalueReferenceType() matches the types of c and f. e is not
+matched as it is deduced to int& by reference collapsing rules.
 
@@ -1202,6 +1240,23 @@ incompleteArrayType()
+Matcher<Type>lvalueReferenceTypeMatcher<LValueReferenceType>... +
Matches lvalue reference types.
+
+Given:
+  int *a;
+  int &b = *a;
+  int &&c = 1;
+  auto &d = b;
+  auto &&e = c;
+  auto &&f = 2;
+  int g = 5;
+
+lvalueReferenceType() matches the types of b, d, and e. e is
+matched since the type is deduced as int& by reference collapsing rules.
+
+ + Matcher<Type>memberPointerTypeMatcher<MemberPointerType>...
Matches member pointer types.
 Given
@@ -1240,14 +1295,35 @@ and s.
 
 
 Matcher<Type>referenceTypeMatcher<ReferenceType>...
-
Matches reference types.
+
Matches both lvalue and rvalue reference types.
 
 Given
   int *a;
   int &b = *a;
-  int c = 5;
-pointerType()
-  matches "int &b"
+  int &&c = 1;
+  auto &d = b;
+  auto &&e = c;
+  auto &&f = 2;
+  int g = 5;
+
+referenceType() matches the types of b, c, d, e, and f.
+
+ + +Matcher<Type>rvalueReferenceTypeMatcher<RValueReferenceType>... +
Matches rvalue reference types.
+
+Given:
+  int *a;
+  int &b = *a;
+  int &&c = 1;
+  auto &d = b;
+  auto &&e = c;
+  auto &&f = 2;
+  int g = 5;
+
+lvalueReferenceType() matches the types of c and f. e is not
+matched as it is deduced to int& by reference collapsing rules.
 
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index c5ebd3c450..f48e8a53ef 100644 --- a/include/clang/ASTMatchers/ASTMatchers.h +++ b/include/clang/ASTMatchers/ASTMatchers.h @@ -2922,18 +2922,56 @@ AST_TYPE_MATCHER(MemberPointerType, memberPointerType); /// matches "int *a" AST_TYPE_MATCHER(PointerType, pointerType); -/// \brief Matches reference types. +/// \brief Matches both lvalue and rvalue reference types. /// /// Given /// \code /// int *a; /// int &b = *a; -/// int c = 5; +/// int &&c = 1; +/// auto &d = b; +/// auto &&e = c; +/// auto &&f = 2; +/// int g = 5; /// \endcode -/// pointerType() -/// matches "int &b" +/// +/// \c referenceType() matches the types of \c b, \c c, \c d, \c e, and \c f. AST_TYPE_MATCHER(ReferenceType, referenceType); +/// \brief Matches lvalue reference types. +/// +/// Given: +/// \code +/// int *a; +/// int &b = *a; +/// int &&c = 1; +/// auto &d = b; +/// auto &&e = c; +/// auto &&f = 2; +/// int g = 5; +/// \endcode +/// +/// \c lValueReferenceType() matches the types of \c b, \c d, and \c e. \c e is +/// matched since the type is deduced as int& by reference collapsing rules. +AST_TYPE_MATCHER(LValueReferenceType, lValueReferenceType); + +/// \brief Matches rvalue reference types. +/// +/// Given: +/// \code +/// int *a; +/// int &b = *a; +/// int &&c = 1; +/// auto &d = b; +/// auto &&e = c; +/// auto &&f = 2; +/// int g = 5; +/// \endcode +/// +/// \c rValueReferenceType() matches the types of \c c and \c f. \c e is not +/// matched as it is deduced to int& by reference collapsing rules. +AST_TYPE_MATCHER(RValueReferenceType, rValueReferenceType); + /// \brief Narrows PointerType (and similar) matchers to those where the /// \c pointee matches a given matcher. /// diff --git a/unittests/ASTMatchers/ASTMatchersTest.cpp b/unittests/ASTMatchers/ASTMatchersTest.cpp index 318d09c9bf..32f846d925 100644 --- a/unittests/ASTMatchers/ASTMatchersTest.cpp +++ b/unittests/ASTMatchers/ASTMatchersTest.cpp @@ -3398,6 +3398,10 @@ TEST(TypeMatching, PointerTypes) { hasType(pointerType())))); EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"), hasType(referenceType())))); + EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"), + hasType(lValueReferenceType())))); + EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"), + hasType(rValueReferenceType())))); Fragment = "int *ptr;"; EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"), @@ -3418,6 +3422,54 @@ TEST(TypeMatching, PointerTypes) { hasType(pointerType())))); EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"), hasType(referenceType())))); + EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"), + hasType(lValueReferenceType())))); + EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"), + hasType(rValueReferenceType())))); + + Fragment = "int &&ref = 2;"; + EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"), + hasType(blockPointerType())))); + EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"), + hasType(memberPointerType())))); + EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"), + hasType(pointerType())))); + EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"), + hasType(referenceType())))); + EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"), + hasType(lValueReferenceType())))); + EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"), + hasType(rValueReferenceType())))); +} + +TEST(TypeMatching, AutoRefTypes) { + std::string Fragment = "auto a = 1;" + "auto b = a;" + "auto &c = a;" + "auto &&d = c;" + "auto &&e = 2;"; + EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("a"), + hasType(referenceType())))); + EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("b"), + hasType(referenceType())))); + EXPECT_TRUE(matches(Fragment, varDecl(hasName("c"), + hasType(referenceType())))); + EXPECT_TRUE(matches(Fragment, varDecl(hasName("c"), + hasType(lValueReferenceType())))); + EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("c"), + hasType(rValueReferenceType())))); + EXPECT_TRUE(matches(Fragment, varDecl(hasName("d"), + hasType(referenceType())))); + EXPECT_TRUE(matches(Fragment, varDecl(hasName("d"), + hasType(lValueReferenceType())))); + EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("d"), + hasType(rValueReferenceType())))); + EXPECT_TRUE(matches(Fragment, varDecl(hasName("e"), + hasType(referenceType())))); + EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("e"), + hasType(lValueReferenceType())))); + EXPECT_TRUE(matches(Fragment, varDecl(hasName("e"), + hasType(rValueReferenceType())))); } TEST(TypeMatching, PointeeTypes) {