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