diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -6137,6 +6137,34 @@ +
Matches if the type location of a node matches the inner matcher. + +Examples: + int x; +declaratorDecl(hasTypeLoc(loc(asString("int")))) + matches int x + +auto x = int(3); +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) + matches int(3) + +struct Foo { Foo(int, int); }; +auto x = Foo(1, 2); +cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) + matches Foo(1, 2) + +Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, + Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, + Matcher<CXXNewExpr>, Matcher<CXXTemporaryObjectExpr>, + Matcher<CXXUnresolvedConstructExpr>, + Matcher<ClassTemplateSpecializationDecl>, Matcher<CompoundLiteralExpr>, + Matcher<DeclaratorDecl>, Matcher<ExplicitCastExpr>, + Matcher<ObjCPropertyDecl>, Matcher<TemplateArgumentLoc>, + Matcher<TypedefNameDecl> +
Narrows PointerType (and similar) matchers to those where the pointee matches a given matcher. @@ -6153,6 +6181,34 @@
Matches if the type location of a node matches the inner matcher. + +Examples: + int x; +declaratorDecl(hasTypeLoc(loc(asString("int")))) + matches int x + +auto x = int(3); +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) + matches int(3) + +struct Foo { Foo(int, int); }; +auto x = Foo(1, 2); +cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) + matches Foo(1, 2) + +Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, + Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, + Matcher<CXXNewExpr>, Matcher<CXXTemporaryObjectExpr>, + Matcher<CXXUnresolvedConstructExpr>, + Matcher<ClassTemplateSpecializationDecl>, Matcher<CompoundLiteralExpr>, + Matcher<DeclaratorDecl>, Matcher<ExplicitCastExpr>, + Matcher<ObjCPropertyDecl>, Matcher<TemplateArgumentLoc>, + Matcher<TypedefNameDecl> +
Overloaded to match the declaration of the expression's or value declaration's type. @@ -6353,6 +6409,34 @@
Matches if the type location of a node matches the inner matcher. + +Examples: + int x; +declaratorDecl(hasTypeLoc(loc(asString("int")))) + matches int x + +auto x = int(3); +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) + matches int(3) + +struct Foo { Foo(int, int); }; +auto x = Foo(1, 2); +cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) + matches Foo(1, 2) + +Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, + Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, + Matcher<CXXNewExpr>, Matcher<CXXTemporaryObjectExpr>, + Matcher<CXXUnresolvedConstructExpr>, + Matcher<ClassTemplateSpecializationDecl>, Matcher<CompoundLiteralExpr>, + Matcher<DeclaratorDecl>, Matcher<ExplicitCastExpr>, + Matcher<ObjCPropertyDecl>, Matcher<TemplateArgumentLoc>, + Matcher<TypedefNameDecl> +
Matches the initializer expression of a constructor initializer. @@ -6433,6 +6517,34 @@
Matches if the type location of a node matches the inner matcher. + +Examples: + int x; +declaratorDecl(hasTypeLoc(loc(asString("int")))) + matches int x + +auto x = int(3); +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) + matches int(3) + +struct Foo { Foo(int, int); }; +auto x = Foo(1, 2); +cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) + matches Foo(1, 2) + +Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, + Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, + Matcher<CXXNewExpr>, Matcher<CXXTemporaryObjectExpr>, + Matcher<CXXUnresolvedConstructExpr>, + Matcher<ClassTemplateSpecializationDecl>, Matcher<CompoundLiteralExpr>, + Matcher<DeclaratorDecl>, Matcher<ExplicitCastExpr>, + Matcher<ObjCPropertyDecl>, Matcher<TemplateArgumentLoc>, + Matcher<TypedefNameDecl> +
Matches on the implicit object argument of a member call expression. Unlike `on`, matches the argument directly without stripping away anything. @@ -6602,6 +6714,34 @@
Matches if the type location of a node matches the inner matcher. + +Examples: + int x; +declaratorDecl(hasTypeLoc(loc(asString("int")))) + matches int x + +auto x = int(3); +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) + matches int(3) + +struct Foo { Foo(int, int); }; +auto x = Foo(1, 2); +cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) + matches Foo(1, 2) + +Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, + Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, + Matcher<CXXNewExpr>, Matcher<CXXTemporaryObjectExpr>, + Matcher<CXXUnresolvedConstructExpr>, + Matcher<ClassTemplateSpecializationDecl>, Matcher<CompoundLiteralExpr>, + Matcher<DeclaratorDecl>, Matcher<ExplicitCastExpr>, + Matcher<ObjCPropertyDecl>, Matcher<TemplateArgumentLoc>, + Matcher<TypedefNameDecl> +
Matches if either the left hand side or the right hand side of a binary operator matches. @@ -6776,6 +6916,34 @@
Matches if the type location of a node matches the inner matcher. + +Examples: + int x; +declaratorDecl(hasTypeLoc(loc(asString("int")))) + matches int x + +auto x = int(3); +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) + matches int(3) + +struct Foo { Foo(int, int); }; +auto x = Foo(1, 2); +cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) + matches Foo(1, 2) + +Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, + Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, + Matcher<CXXNewExpr>, Matcher<CXXTemporaryObjectExpr>, + Matcher<CXXUnresolvedConstructExpr>, + Matcher<ClassTemplateSpecializationDecl>, Matcher<CompoundLiteralExpr>, + Matcher<DeclaratorDecl>, Matcher<ExplicitCastExpr>, + Matcher<ObjCPropertyDecl>, Matcher<TemplateArgumentLoc>, + Matcher<TypedefNameDecl> +
Matches any argument of a call expression or a constructor call expression, or an ObjC-message-send expression. @@ -6805,6 +6973,34 @@
Matches if the type location of a node matches the inner matcher. + +Examples: + int x; +declaratorDecl(hasTypeLoc(loc(asString("int")))) + matches int x + +auto x = int(3); +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) + matches int(3) + +struct Foo { Foo(int, int); }; +auto x = Foo(1, 2); +cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) + matches Foo(1, 2) + +Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, + Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, + Matcher<CXXNewExpr>, Matcher<CXXTemporaryObjectExpr>, + Matcher<CXXUnresolvedConstructExpr>, + Matcher<ClassTemplateSpecializationDecl>, Matcher<CompoundLiteralExpr>, + Matcher<DeclaratorDecl>, Matcher<ExplicitCastExpr>, + Matcher<ObjCPropertyDecl>, Matcher<TemplateArgumentLoc>, + Matcher<TypedefNameDecl> +
Matches if the call expression's callee's declaration matches the given matcher. @@ -7024,6 +7220,34 @@
Matches if the type location of a node matches the inner matcher. + +Examples: + int x; +declaratorDecl(hasTypeLoc(loc(asString("int")))) + matches int x + +auto x = int(3); +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) + matches int(3) + +struct Foo { Foo(int, int); }; +auto x = Foo(1, 2); +cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) + matches Foo(1, 2) + +Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, + Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, + Matcher<CXXNewExpr>, Matcher<CXXTemporaryObjectExpr>, + Matcher<CXXUnresolvedConstructExpr>, + Matcher<ClassTemplateSpecializationDecl>, Matcher<CompoundLiteralExpr>, + Matcher<DeclaratorDecl>, Matcher<ExplicitCastExpr>, + Matcher<ObjCPropertyDecl>, Matcher<TemplateArgumentLoc>, + Matcher<TypedefNameDecl> +
Matches arrays and C99 complex types that have a specific element type. @@ -7039,6 +7263,34 @@
Matches if the type location of a node matches the inner matcher. + +Examples: + int x; +declaratorDecl(hasTypeLoc(loc(asString("int")))) + matches int x + +auto x = int(3); +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) + matches int(3) + +struct Foo { Foo(int, int); }; +auto x = Foo(1, 2); +cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) + matches Foo(1, 2) + +Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, + Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, + Matcher<CXXNewExpr>, Matcher<CXXTemporaryObjectExpr>, + Matcher<CXXUnresolvedConstructExpr>, + Matcher<ClassTemplateSpecializationDecl>, Matcher<CompoundLiteralExpr>, + Matcher<DeclaratorDecl>, Matcher<ExplicitCastExpr>, + Matcher<ObjCPropertyDecl>, Matcher<TemplateArgumentLoc>, + Matcher<TypedefNameDecl> +
Matches compound statements where at least one substatement matches a given matcher. Also matches StmtExprs that have CompoundStmt as children. @@ -7148,14 +7400,31 @@
Matches if the type location of the declarator decl's type matches -the inner matcher. ++ Matcher<DeclaratorDecl> hasTypeLoc Matcher<TypeLoc> Inner @@ -7312,6 +7581,34 @@ Matches if the type location of a node matches the inner matcher. -Given +Examples: int x; declaratorDecl(hasTypeLoc(loc(asString("int")))) matches int x + +auto x = int(3); +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) + matches int(3) + +struct Foo { Foo(int, int); }; +auto x = Foo(1, 2); +cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) + matches Foo(1, 2) + +Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, + Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, + Matcher<CXXNewExpr>, Matcher<CXXTemporaryObjectExpr>, + Matcher<CXXUnresolvedConstructExpr>, + Matcher<ClassTemplateSpecializationDecl>, Matcher<CompoundLiteralExpr>, + Matcher<DeclaratorDecl>, Matcher<ExplicitCastExpr>, + Matcher<ObjCPropertyDecl>, Matcher<TemplateArgumentLoc>, + Matcher<TypedefNameDecl>
Matches if the type location of a node matches the inner matcher. + +Examples: + int x; +declaratorDecl(hasTypeLoc(loc(asString("int")))) + matches int x + +auto x = int(3); +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) + matches int(3) + +struct Foo { Foo(int, int); }; +auto x = Foo(1, 2); +cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) + matches Foo(1, 2) + +Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, + Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, + Matcher<CXXNewExpr>, Matcher<CXXTemporaryObjectExpr>, + Matcher<CXXUnresolvedConstructExpr>, + Matcher<ClassTemplateSpecializationDecl>, Matcher<CompoundLiteralExpr>, + Matcher<DeclaratorDecl>, Matcher<ExplicitCastExpr>, + Matcher<ObjCPropertyDecl>, Matcher<TemplateArgumentLoc>, + Matcher<TypedefNameDecl> +
Overloaded to match the declaration of the expression's or value declaration's type. @@ -8250,6 +8547,34 @@
Matches if the type location of a node matches the inner matcher. + +Examples: + int x; +declaratorDecl(hasTypeLoc(loc(asString("int")))) + matches int x + +auto x = int(3); +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) + matches int(3) + +struct Foo { Foo(int, int); }; +auto x = Foo(1, 2); +cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) + matches Foo(1, 2) + +Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, + Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, + Matcher<CXXNewExpr>, Matcher<CXXTemporaryObjectExpr>, + Matcher<CXXUnresolvedConstructExpr>, + Matcher<ClassTemplateSpecializationDecl>, Matcher<CompoundLiteralExpr>, + Matcher<DeclaratorDecl>, Matcher<ExplicitCastExpr>, + Matcher<ObjCPropertyDecl>, Matcher<TemplateArgumentLoc>, + Matcher<TypedefNameDecl> +
Matches if the cast's source expression or opaque value's source expression matches the given matcher. @@ -8601,6 +8926,34 @@
Matches if the type location of a node matches the inner matcher. + +Examples: + int x; +declaratorDecl(hasTypeLoc(loc(asString("int")))) + matches int x + +auto x = int(3); +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) + matches int(3) + +struct Foo { Foo(int, int); }; +auto x = Foo(1, 2); +cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) + matches Foo(1, 2) + +Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, + Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, + Matcher<CXXNewExpr>, Matcher<CXXTemporaryObjectExpr>, + Matcher<CXXUnresolvedConstructExpr>, + Matcher<ClassTemplateSpecializationDecl>, Matcher<CompoundLiteralExpr>, + Matcher<DeclaratorDecl>, Matcher<ExplicitCastExpr>, + Matcher<ObjCPropertyDecl>, Matcher<TemplateArgumentLoc>, + Matcher<TypedefNameDecl> +
Matches a sugar TemplateArgument that refers to a certain expression. @@ -8784,6 +9137,34 @@
Matches if the type location of a node matches the inner matcher. + +Examples: + int x; +declaratorDecl(hasTypeLoc(loc(asString("int")))) + matches int x + +auto x = int(3); +cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) + matches int(3) + +struct Foo { Foo(int, int); }; +auto x = Foo(1, 2); +cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) + matches Foo(1, 2) + +Usable as: Matcher<BlockDecl>, Matcher<CXXBaseSpecifier>, + Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>, + Matcher<CXXNewExpr>, Matcher<CXXTemporaryObjectExpr>, + Matcher<CXXUnresolvedConstructExpr>, + Matcher<ClassTemplateSpecializationDecl>, Matcher<CompoundLiteralExpr>, + Matcher<DeclaratorDecl>, Matcher<ExplicitCastExpr>, + Matcher<ObjCPropertyDecl>, Matcher<TemplateArgumentLoc>, + Matcher<TypedefNameDecl> +
Matches if the expression's or declaration's type matches a type matcher. diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -3896,20 +3896,51 @@ return false; } -/// Matches if the type location of the declarator decl's type matches -/// the inner matcher. +/// Matches if the type location of a node matches the inner matcher. /// -/// Given +/// Examples: /// \code /// int x; /// \endcode /// declaratorDecl(hasTypeLoc(loc(asString("int")))) /// matches int x -AST_MATCHER_P(DeclaratorDecl, hasTypeLoc, internal::Matcher, Inner) { - if (!Node.getTypeSourceInfo()) +/// +/// \code +/// auto x = int(3); +/// \code +/// cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int")))) +/// matches int(3) +/// +/// \code +/// struct Foo { Foo(int, int); }; +/// auto x = Foo(1, 2); +/// \code +/// cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo")))) +/// matches Foo(1, 2) +/// +/// Usable as: Matcher , Matcher , +/// Matcher , Matcher , +/// Matcher , Matcher , +/// Matcher , +/// Matcher , Matcher , +/// Matcher , Matcher , +/// Matcher , Matcher , +/// Matcher +AST_POLYMORPHIC_MATCHER_P( + hasTypeLoc, + AST_POLYMORPHIC_SUPPORTED_TYPES( + BlockDecl, CXXBaseSpecifier, CXXCtorInitializer, CXXFunctionalCastExpr, + CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr, + ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl, + ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, + TypedefNameDecl), + internal::Matcher , Inner) { + TypeSourceInfo *source = internal::GetTypeSourceInfo(Node); + if (source == nullptr) { // This happens for example for implicit destructors. return false; - return Inner.matches(Node.getTypeSourceInfo()->getTypeLoc(), Finder, Builder); + } + return Inner.matches(source->getTypeLoc(), Finder, Builder); } /// Matches if the matched type is represented by the given string. diff --git a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h --- a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h +++ b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -166,6 +166,35 @@ return Node.getType(); } +/// Unifies obtaining a `TypeSourceInfo` from different node types. +template , + T>::value> * = nullptr> +inline TypeSourceInfo *GetTypeSourceInfo(const T &Node) { + return Node.getTypeSourceInfo(); +} +template , T>::value> * = + nullptr> +inline TypeSourceInfo *GetTypeSourceInfo(const T &Node) { + return Node.getTypeInfoAsWritten(); +} +inline TypeSourceInfo *GetTypeSourceInfo(const BlockDecl &Node) { + return Node.getSignatureAsWritten(); +} +inline TypeSourceInfo *GetTypeSourceInfo(const CXXNewExpr &Node) { + return Node.getAllocatedTypeSourceInfo(); +} +inline TypeSourceInfo * +GetTypeSourceInfo(const ClassTemplateSpecializationDecl &Node) { + return Node.getTypeAsWritten(); +} + /// Unifies obtaining the FunctionProtoType pointer from both /// FunctionProtoType and FunctionDecl nodes.. inline const FunctionProtoType * diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp --- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -11,6 +11,7 @@ #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" #include "clang/Tooling/Tooling.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/Host.h" #include "gtest/gtest.h" @@ -375,15 +376,104 @@ typedefNameDecl(hasType(asString("foo")), hasName("bar")))); } -TEST(HasTypeLoc, MatchesDeclaratorDecls) { +TEST(HasTypeLoc, MatchesBlockDecl) { + EXPECT_TRUE(matchesConditionally( + "auto x = ^int (int a, int b) { return a + b; };", + blockDecl(hasTypeLoc(loc(asString("int (int, int)")))), true, + {"-fblocks"})); +} + +TEST(HasTypeLoc, MatchesCXXBaseSpecifierAndCtorInitializer) { + llvm::StringRef code = R"cpp( + class Foo {}; + class Bar : public Foo { + Bar() : Foo() {} + }; + )cpp"; + + EXPECT_TRUE(matches( + code, cxxRecordDecl(hasAnyBase(hasTypeLoc(loc(asString("class Foo"))))))); + EXPECT_TRUE(matches( + code, cxxCtorInitializer(hasTypeLoc(loc(asString("class Foo")))))); +} + +TEST(HasTypeLoc, MatchesCXXFunctionalCastExpr) { + EXPECT_TRUE(matches("auto x = int(3);", + cxxFunctionalCastExpr(hasTypeLoc(loc(asString("int")))))); +} + +TEST(HasTypeLoc, MatchesCXXNewExpr) { + EXPECT_TRUE(matches("auto* x = new int(3);", + cxxNewExpr(hasTypeLoc(loc(asString("int")))))); + EXPECT_TRUE(matches("class Foo{}; auto* x = new Foo();", + cxxNewExpr(hasTypeLoc(loc(asString("class Foo")))))); +} + +TEST(HasTypeLoc, MatchesCXXTemporaryObjectExpr) { + EXPECT_TRUE( + matches("struct Foo { Foo(int, int); }; auto x = Foo(1, 2);", + cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("struct Foo")))))); +} + +TEST(HasTypeLoc, MatchesCXXUnresolvedConstructExpr) { + EXPECT_TRUE( + matches("template T make() { return T(); }", + cxxUnresolvedConstructExpr(hasTypeLoc(loc(asString("T")))))); +} + +TEST(HasTypeLoc, MatchesClassTemplateSpecializationDecl) { + EXPECT_TRUE(matches( + "template class Foo; template <> class Foo {};", + classTemplateSpecializationDecl(hasTypeLoc(loc(asString("Foo ")))))); +} + +TEST(HasTypeLoc, MatchesCompoundLiteralExpr) { + EXPECT_TRUE( + matches("int* x = (int [2]) { 0, 1 };", + compoundLiteralExpr(hasTypeLoc(loc(asString("int [2]")))))); +} + +TEST(HasTypeLoc, MatchesDeclaratorDecl) { EXPECT_TRUE(matches("int x;", varDecl(hasName("x"), hasTypeLoc(loc(asString("int")))))); + EXPECT_TRUE(matches("int x(3);", + varDecl(hasName("x"), hasTypeLoc(loc(asString("int")))))); + EXPECT_TRUE( + matches("struct Foo { Foo(int, int); }; Foo x(1, 2);", + varDecl(hasName("x"), hasTypeLoc(loc(asString("struct Foo")))))); // Make sure we don't crash on implicit constructors. EXPECT_TRUE(notMatches("class X {}; X x;", declaratorDecl(hasTypeLoc(loc(asString("int")))))); } +TEST(HasTypeLoc, MatchesExplicitCastExpr) { + EXPECT_TRUE(matches("auto x = (int) 3;", + explicitCastExpr(hasTypeLoc(loc(asString("int")))))); + EXPECT_TRUE(matches("auto x = static_cast (3);", + explicitCastExpr(hasTypeLoc(loc(asString("int")))))); +} + +TEST(HasTypeLoc, MatchesObjCPropertyDecl) { + EXPECT_TRUE(matchesObjC(R"objc( + @interface Foo + @property int enabled; + @end + )objc", + objcPropertyDecl(hasTypeLoc(loc(asString("int")))))); +} + +TEST(HasTypeLoc, MatchesTemplateArgumentLoc) { + EXPECT_TRUE(matches("template class Foo {}; Foo x;", + templateArgumentLoc(hasTypeLoc(loc(asString("int")))))); +} + +TEST(HasTypeLoc, MatchesTypedefNameDecl) { + EXPECT_TRUE(matches("typedef int X;", + typedefNameDecl(hasTypeLoc(loc(asString("int")))))); + EXPECT_TRUE(matches("using X = int;", + typedefNameDecl(hasTypeLoc(loc(asString("int")))))); +} TEST(Callee, MatchesDeclarations) { StatementMatcher CallMethodX = callExpr(callee(cxxMethodDecl(hasName("x"))));