Author: dlj Date: Mon Jun 18 02:23:08 2018 New Revision: 334930 URL: http://llvm.org/viewvc/llvm-project?rev=334930&view=rev Log: [ASTMatchers] Add support for matching the type of a friend decl.
This allows matchers like: friendDecl(hasType(cxxRecordDecl(...))) friendDecl(hasType(asString(...))) It seems that hasType is probably the most reasonable narrowing matcher to overload, since it is already used to narrow to other declaration kinds. Differential Revision: https://reviews.llvm.org/D48242 Reviewers: klimek, aaron.ballman Subscribers: cfe-commits Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=334930&r1=334929&r2=334930&view=diff ============================================================================== --- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original) +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Mon Jun 18 02:23:08 2018 @@ -2860,13 +2860,17 @@ AST_MATCHER_P_OVERLOAD(CallExpr, callee, /// Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X"))))) /// and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X"))))) /// and U (matcher = typedefDecl(hasType(asString("int"))) +/// and friend class X (matcher = friendDecl(hasType("X")) /// \code /// class X {}; /// void y(X &x) { x; X z; } /// typedef int U; +/// class Y { friend class X; }; /// \endcode AST_POLYMORPHIC_MATCHER_P_OVERLOAD( - hasType, AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, TypedefNameDecl, ValueDecl), + hasType, + AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, FriendDecl, TypedefNameDecl, + ValueDecl), internal::Matcher<QualType>, InnerMatcher, 0) { QualType QT = internal::getUnderlyingType(Node); if (!QT.isNull()) @@ -2885,18 +2889,21 @@ AST_POLYMORPHIC_MATCHER_P_OVERLOAD( /// /// Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X"))))) /// and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X"))))) +/// and friend class X (matcher = friendDecl(hasType("X")) /// \code /// class X {}; /// void y(X &x) { x; X z; } +/// class Y { friend class X; }; /// \endcode /// /// Usable as: Matcher<Expr>, Matcher<ValueDecl> -AST_POLYMORPHIC_MATCHER_P_OVERLOAD(hasType, - AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, - ValueDecl), - internal::Matcher<Decl>, InnerMatcher, 1) { - return qualType(hasDeclaration(InnerMatcher)) - .matches(Node.getType(), Finder, Builder); +AST_POLYMORPHIC_MATCHER_P_OVERLOAD( + hasType, AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, FriendDecl, ValueDecl), + internal::Matcher<Decl>, InnerMatcher, 1) { + QualType QT = internal::getUnderlyingType(Node); + if (!QT.isNull()) + return qualType(hasDeclaration(InnerMatcher)).matches(QT, Finder, Builder); + return false; } /// Matches if the type location of the declarator decl's type matches Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h?rev=334930&r1=334929&r2=334930&view=diff ============================================================================== --- cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h (original) +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h Mon Jun 18 02:23:08 2018 @@ -38,6 +38,7 @@ #include "clang/AST/ASTTypeTraits.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclFriend.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" @@ -120,10 +121,14 @@ inline QualType getUnderlyingType(const inline QualType getUnderlyingType(const ValueDecl &Node) { return Node.getType(); } - inline QualType getUnderlyingType(const TypedefNameDecl &Node) { return Node.getUnderlyingType(); } +inline QualType getUnderlyingType(const FriendDecl &Node) { + if (const TypeSourceInfo *TSI = Node.getFriendType()) + return TSI->getType(); + return QualType(); +} /// Unifies obtaining the FunctionProtoType pointer from both /// FunctionProtoType and FunctionDecl nodes.. Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp?rev=334930&r1=334929&r2=334930&view=diff ============================================================================== --- cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp (original) +++ cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp Mon Jun 18 02:23:08 2018 @@ -160,6 +160,16 @@ TEST(ValueDecl, Matches) { valueDecl(hasType(asString("void (void)"))))); } +TEST(FriendDecl, Matches) { + EXPECT_TRUE(matches("class Y { friend class X; };", + friendDecl(hasType(asString("class X"))))); + EXPECT_TRUE(matches("class Y { friend class X; };", + friendDecl(hasType(recordDecl(hasName("X")))))); + + EXPECT_TRUE(matches("class Y { friend void f(); };", + functionDecl(hasName("f"), hasParent(friendDecl())))); +} + TEST(Enum, DoesNotMatchClasses) { EXPECT_TRUE(notMatches("class X {};", enumDecl(hasName("X")))); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits