Index: cfe/trunk/docs/LibASTMatchersReference.html =================================================================== --- cfe/trunk/docs/LibASTMatchersReference.html +++ cfe/trunk/docs/LibASTMatchersReference.html @@ -1799,6 +1799,21 @@ +
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. +
Matches constructor and conversion declarations that are marked with the explicit keyword. @@ -1983,6 +1998,19 @@
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. +
Matches if the given method declaration is virtual. @@ -2538,7 +2566,7 @@
Matches NamedDecl nodes that have the specified name. Supports specifying enclosing namespaces or classes by prefixing the name @@ -2731,13 +2759,20 @@- Matcher<QualType> isAnyPointer - Matches QualType nodes that are of any pointer type. +@@ -3228,16 +3263,6 @@ 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".- Matcher<internal::Matcher<NamedDecl>> hasAnyName StringRef, ..., StringRef - - 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)) -Matcher<internal::Matcher<Stmt>> isInTemplateInstantiation Matches statements inside of a template instantiation. Index: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h @@ -3803,6 +3803,21 @@ return Node.size_overridden_methods() > 0 || Node.hasAttr(); } +/// \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 @@ 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. /// Index: cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp =================================================================== --- cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp +++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp @@ -2327,6 +2327,32 @@ 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")))));