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