diff options
author | Alexander Kornienko <alexfh@google.com> | 2016-04-13 11:13:08 +0000 |
---|---|---|
committer | Alexander Kornienko <alexfh@google.com> | 2016-04-13 11:13:08 +0000 |
commit | 7d20a5afdbe77bccea3d854de2b6d86ee8fc8c8c (patch) | |
tree | 49989857a9ea5dbd5ed8cbb43a5a0e15f029772a | |
parent | 074edd7c1e5f1df4a538a1efe19f4753f367c96e (diff) | |
download | bcm5719-llvm-7d20a5afdbe77bccea3d854de2b6d86ee8fc8c8c.tar.gz bcm5719-llvm-7d20a5afdbe77bccea3d854de2b6d86ee8fc8c8c.zip |
Add AST Matchers for CXXConstructorDecl::isDelegatingConstructor and CXXMethodDecl::isUserProvided.
Summary: Added two AST matchers: isDelegatingConstructor for CXXConstructorDecl::IsDelegatingConstructor; and isUserProvided corresponding to CXXMethodDecl::isUserProvided.
Reviewers: aaron.ballman, alexfh
Subscribers: klimek, cfe-commits
Patch by Michael Miller!
Differential Revision: http://reviews.llvm.org/D19038
llvm-svn: 266189
-rw-r--r-- | clang/docs/LibASTMatchersReference.html | 51 | ||||
-rw-r--r-- | clang/include/clang/ASTMatchers/ASTMatchers.h | 32 | ||||
-rw-r--r-- | clang/unittests/ASTMatchers/ASTMatchersTest.cpp | 26 |
3 files changed, 96 insertions, 13 deletions
diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html index aaddb5b840b..f31d9490cc5 100644 --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -1799,6 +1799,21 @@ cxxConstructorDecl(isDefaultConstructor()) will match #1, but not #2 or #3. </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructorDecl.html">CXXConstructorDecl</a>></td><td class="name" onclick="toggle('isDelegatingConstructor0')"><a name="isDelegatingConstructor0Anchor">isDelegatingConstructor</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isDelegatingConstructor0"><pre>Matches constructors that delegate to another constructor. + +Given + struct S { + S(); #1 + S(int) {} #2 + S(S &&) : S() {} #3 + }; + S::S() : S(0) {} #4 +cxxConstructorDecl(isDelegatingConstructor()) will match #3 and #4, but not +#1 or #2. +</pre></td></tr> + + <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructorDecl.html">CXXConstructorDecl</a>></td><td class="name" onclick="toggle('isExplicit0')"><a name="isExplicit0Anchor">isExplicit</a></td><td></td></tr> <tr><td colspan="4" class="doc" id="isExplicit0"><pre>Matches constructor and conversion declarations that are marked with the explicit keyword. @@ -1983,6 +1998,19 @@ Given </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>></td><td class="name" onclick="toggle('isUserProvided0')"><a name="isUserProvided0Anchor">isUserProvided</a></td><td></td></tr> +<tr><td colspan="4" class="doc" id="isUserProvided0"><pre>Matches method declarations that are user-provided. + +Given + struct S { + S(); #1 + S(const S &) = default; #2 + S(S &&) = delete; #3 + }; +cxxConstructorDecl(isUserProvided()) will match #1, but not #2 or #3. +</pre></td></tr> + + <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>></td><td class="name" onclick="toggle('isVirtual0')"><a name="isVirtual0Anchor">isVirtual</a></td><td></td></tr> <tr><td colspan="4" class="doc" id="isVirtual0"><pre>Matches if the given method declaration is virtual. @@ -2538,7 +2566,7 @@ memberExpr(isArrow()) </pre></td></tr> -<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1NamedDecl.html">NamedDecl</a>></td><td class="name" onclick="toggle('hasName0')"><a name="hasName0Anchor">hasName</a></td><td>std::string Name</td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1NamedDecl.html">NamedDecl</a>></td><td class="name" onclick="toggle('hasName0')"><a name="hasName0Anchor">hasName</a></td><td>std::string Name</td></tr> <tr><td colspan="4" class="doc" id="hasName0"><pre>Matches NamedDecl nodes that have the specified name. Supports specifying enclosing namespaces or classes by prefixing the name @@ -2731,13 +2759,20 @@ matches "a(char)", "b(wchar_t)", but not "c(double)". <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>></td><td class="name" onclick="toggle('isAnyPointer0')"><a name="isAnyPointer0Anchor">isAnyPointer</a></td><td></td></tr> -<tr><td colspan="4" class="doc" id="isAnyPointer0"><pre>Matches QualType nodes that are of any pointer type. +<tr><td colspan="4" class="doc" id="isAnyPointer0"><pre>Matches QualType nodes that are of any pointer type; this includes +the Objective-C object pointer type, which is different despite being +syntactically similar. Given int *i = nullptr; + + @interface Foo + @end + Foo *f; + int j; varDecl(hasType(isAnyPointer())) - matches "int *i", but not "int j". + matches "int *i" and "Foo *f", but not "int j". </pre></td></tr> @@ -3228,16 +3263,6 @@ expr(nullPointerConstant()) </pre></td></tr> -<tr><td>Matcher<internal::Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1NamedDecl.html">NamedDecl</a>>></td><td class="name" onclick="toggle('hasAnyName0')"><a name="hasAnyName0Anchor">hasAnyName</a></td><td>StringRef, ..., StringRef</td></tr> -<tr><td colspan="4" class="doc" id="hasAnyName0"><pre>Matches NamedDecl nodes that have any of the specified names. - -This matcher is only provided as a performance optimization of hasName. - hasAnyName(a, b, c) - is equivalent but faster than - anyOf(hasName(a), hasName(b), hasName(c)) -</pre></td></tr> - - <tr><td>Matcher<internal::Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>>></td><td class="name" onclick="toggle('isInTemplateInstantiation0')"><a name="isInTemplateInstantiation0Anchor">isInTemplateInstantiation</a></td><td></td></tr> <tr><td colspan="4" class="doc" id="isInTemplateInstantiation0"><pre>Matches statements inside of a template instantiation. diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 9a89cd1e381..2a734f14fb1 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -3803,6 +3803,21 @@ AST_MATCHER(CXXMethodDecl, isOverride) { return Node.size_overridden_methods() > 0 || Node.hasAttr<OverrideAttr>(); } +/// \brief Matches method declarations that are user-provided. +/// +/// Given +/// \code +/// struct S { +/// S(); // #1 +/// S(const S &) = default; // #2 +/// S(S &&) = delete; // #3 +/// }; +/// \endcode +/// cxxConstructorDecl(isUserProvided()) will match #1, but not #2 or #3. +AST_MATCHER(CXXMethodDecl, isUserProvided) { + return Node.isUserProvided(); +} + /// \brief Matches member expressions that are called with '->' as opposed /// to '.'. /// @@ -4911,6 +4926,23 @@ AST_MATCHER(CXXConstructorDecl, isDefaultConstructor) { return Node.isDefaultConstructor(); } +/// \brief Matches constructors that delegate to another constructor. +/// +/// Given +/// \code +/// struct S { +/// S(); // #1 +/// S(int) {} // #2 +/// S(S &&) : S() {} // #3 +/// }; +/// S::S() : S(0) {} // #4 +/// \endcode +/// cxxConstructorDecl(isDelegatingConstructor()) will match #3 and #4, but not +/// #1 or #2. +AST_MATCHER(CXXConstructorDecl, isDelegatingConstructor) { + return Node.isDelegatingConstructor(); +} + /// \brief Matches constructor and conversion declarations that are marked with /// the explicit keyword. /// diff --git a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp index e4b6bb17033..df818ba9422 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp @@ -2327,6 +2327,32 @@ TEST(ConstructorDeclaration, Kinds) { cxxConstructorDecl(isMoveConstructor()))); } +TEST(ConstructorDeclaration, IsUserProvided) { + EXPECT_TRUE(notMatches("struct S { int X = 0; };", + cxxConstructorDecl(isUserProvided()))); + EXPECT_TRUE(notMatches("struct S { S() = default; };", + cxxConstructorDecl(isUserProvided()))); + EXPECT_TRUE(notMatches("struct S { S() = delete; };", + cxxConstructorDecl(isUserProvided()))); + EXPECT_TRUE( + matches("struct S { S(); };", cxxConstructorDecl(isUserProvided()))); + EXPECT_TRUE(matches("struct S { S(); }; S::S(){}", + cxxConstructorDecl(isUserProvided()))); +} + +TEST(ConstructorDeclaration, IsDelegatingConstructor) { + EXPECT_TRUE(notMatches("struct S { S(); S(int); int X; };", + cxxConstructorDecl(isDelegatingConstructor()))); + EXPECT_TRUE(notMatches("struct S { S(){} S(int X) : X(X) {} int X; };", + cxxConstructorDecl(isDelegatingConstructor()))); + EXPECT_TRUE(matches( + "struct S { S() : S(0) {} S(int X) : X(X) {} int X; };", + cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(0)))); + EXPECT_TRUE(matches( + "struct S { S(); S(int X); int X; }; S::S(int X) : S() {}", + cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(1)))); +} + TEST(DestructorDeclaration, MatchesVirtualDestructor) { EXPECT_TRUE(matches("class Foo { virtual ~Foo(); };", cxxDestructorDecl(ofClass(hasName("Foo"))))); |