From 2a760d02f718751c76db2ed3058f3624ac6ed0d4 Mon Sep 17 00:00:00 2001 From: Edwin Vane Date: Thu, 7 Mar 2013 15:44:40 +0000 Subject: [PATCH] Adding lvalue and rvalue reference type matchers Updated docs and tests. Reviewers: klimek, gribozavr llvm-svn: 176630 --- clang/docs/LibASTMatchersReference.html | 92 ++++++++++++++++++++++--- clang/include/clang/ASTMatchers/ASTMatchers.h | 46 +++++++++++-- clang/unittests/ASTMatchers/ASTMatchersTest.cpp | 52 ++++++++++++++ 3 files changed, 178 insertions(+), 12 deletions(-) diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html index a32f1a4..5bee8cc 100644 --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/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/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index c5ebd3c..f48e8a5 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/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/clang/unittests/ASTMatchers/ASTMatchersTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp index 318d09c..32f846d 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp +++ b/clang/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) { -- 2.7.4