r334930 - [ASTMatchers] Add support for matching the type of a friend decl.

David L. Jones via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 18 02:23:08 PDT 2018


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"))));
 }




More information about the cfe-commits mailing list