[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 llvm-svn: 334930
This commit is contained in:
parent
8f7adcd7fb
commit
82e08bd776
|
@ -2860,13 +2860,17 @@ AST_MATCHER_P_OVERLOAD(CallExpr, callee, internal::Matcher<Decl>, InnerMatcher,
|
|||
/// 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
|
||||
|
|
|
@ -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 Expr &Node) { return Node.getType(); }
|
|||
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..
|
||||
|
|
|
@ -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"))));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue