diff options
author | Edwin Vane <edwin.vane@intel.com> | 2013-03-07 15:44:40 +0000 |
---|---|---|
committer | Edwin Vane <edwin.vane@intel.com> | 2013-03-07 15:44:40 +0000 |
commit | f4b48042724d2253d0426cadcb93e24eeb47e264 (patch) | |
tree | f7f95641de29ea524bd213e3cd647737bb47e3b1 | |
parent | f3ddf639697d9be7f0429f3672a32c9fbac3653d (diff) |
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
-rw-r--r-- | docs/LibASTMatchersReference.html | 92 | ||||
-rw-r--r-- | include/clang/ASTMatchers/ASTMatchers.h | 46 | ||||
-rw-r--r-- | unittests/ASTMatchers/ASTMatchersTest.cpp | 52 |
3 files changed, 178 insertions, 12 deletions
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() </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('lvalueReferenceTypeLoc0')"><a name="lvalueReferenceTypeLoc0Anchor">lvalueReferenceTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1LValueReferenceTypeLoc.html">LValueReferenceTypeLoc</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="lvalueReferenceTypeLoc0"><pre>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. +</pre></td></tr> + + <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('memberPointerTypeLoc0')"><a name="memberPointerTypeLoc0Anchor">memberPointerTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberPointerTypeLoc.html">MemberPointerTypeLoc</a>>...</td></tr> <tr><td colspan="4" class="doc" id="memberPointerTypeLoc0"><pre>Matches member pointer types. Given @@ -1011,14 +1028,35 @@ and s. <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('referenceTypeLoc0')"><a name="referenceTypeLoc0Anchor">referenceTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ReferenceTypeLoc.html">ReferenceTypeLoc</a>>...</td></tr> -<tr><td colspan="4" class="doc" id="referenceTypeLoc0"><pre>Matches reference types. +<tr><td colspan="4" class="doc" id="referenceTypeLoc0"><pre>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. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('rvalueReferenceTypeLoc0')"><a name="rvalueReferenceTypeLoc0Anchor">rvalueReferenceTypeLoc</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1RValueReferenceTypeLoc.html">RValueReferenceTypeLoc</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="rvalueReferenceTypeLoc0"><pre>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. </pre></td></tr> @@ -1202,6 +1240,23 @@ incompleteArrayType() </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('lvalueReferenceType0')"><a name="lvalueReferenceType0Anchor">lvalueReferenceType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1LValueReferenceType.html">LValueReferenceType</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="lvalueReferenceType0"><pre>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. +</pre></td></tr> + + <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('memberPointerType0')"><a name="memberPointerType0Anchor">memberPointerType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberPointerType.html">MemberPointerType</a>>...</td></tr> <tr><td colspan="4" class="doc" id="memberPointerType0"><pre>Matches member pointer types. Given @@ -1240,14 +1295,35 @@ and s. <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('referenceType0')"><a name="referenceType0Anchor">referenceType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ReferenceType.html">ReferenceType</a>>...</td></tr> -<tr><td colspan="4" class="doc" id="referenceType0"><pre>Matches reference types. +<tr><td colspan="4" class="doc" id="referenceType0"><pre>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. +</pre></td></tr> + + +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('rvalueReferenceType0')"><a name="rvalueReferenceType0Anchor">rvalueReferenceType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1RValueReferenceType.html">RValueReferenceType</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="rvalueReferenceType0"><pre>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. </pre></td></tr> 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) { |