blob: fc983737f4acdaa5fe7f44ed2f65e1348d9ace9f [file] [log] [blame]
Manuel Klimek04616e42012-07-06 05:48:52 +00001//===- unittest/Tooling/ASTMatchersTest.cpp - AST matcher unit tests ------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "ASTMatchersTest.h"
Benjamin Kramere5015e52012-12-01 17:22:05 +000011#include "clang/AST/PrettyPrinter.h"
Manuel Klimek04616e42012-07-06 05:48:52 +000012#include "clang/ASTMatchers/ASTMatchFinder.h"
Chandler Carruth320d9662012-12-04 09:45:34 +000013#include "clang/ASTMatchers/ASTMatchers.h"
Manuel Klimek04616e42012-07-06 05:48:52 +000014#include "clang/Tooling/Tooling.h"
NAKAMURA Takumi7d2da0b2014-02-16 10:16:09 +000015#include "llvm/ADT/Triple.h"
16#include "llvm/Support/Host.h"
Manuel Klimek04616e42012-07-06 05:48:52 +000017#include "gtest/gtest.h"
18
19namespace clang {
20namespace ast_matchers {
21
Benjamin Kramer60d7f5a2012-07-10 17:30:44 +000022#if GTEST_HAS_DEATH_TEST
Manuel Klimek04616e42012-07-06 05:48:52 +000023TEST(HasNameDeathTest, DiesOnEmptyName) {
24 ASSERT_DEBUG_DEATH({
Daniel Jasperbd3d76d2012-08-24 05:12:34 +000025 DeclarationMatcher HasEmptyName = recordDecl(hasName(""));
Manuel Klimek04616e42012-07-06 05:48:52 +000026 EXPECT_TRUE(notMatches("class X {};", HasEmptyName));
27 }, "");
28}
29
Daniel Jasper1dad1832012-07-10 20:20:19 +000030TEST(HasNameDeathTest, DiesOnEmptyPattern) {
31 ASSERT_DEBUG_DEATH({
Daniel Jasperbd3d76d2012-08-24 05:12:34 +000032 DeclarationMatcher HasEmptyName = recordDecl(matchesName(""));
Daniel Jasper1dad1832012-07-10 20:20:19 +000033 EXPECT_TRUE(notMatches("class X {};", HasEmptyName));
34 }, "");
35}
36
Manuel Klimek04616e42012-07-06 05:48:52 +000037TEST(IsDerivedFromDeathTest, DiesOnEmptyBaseName) {
38 ASSERT_DEBUG_DEATH({
Aaron Ballman512fb642015-09-17 13:30:52 +000039 DeclarationMatcher IsDerivedFromEmpty = cxxRecordDecl(isDerivedFrom(""));
Manuel Klimek04616e42012-07-06 05:48:52 +000040 EXPECT_TRUE(notMatches("class X {};", IsDerivedFromEmpty));
41 }, "");
42}
Benjamin Kramer60d7f5a2012-07-10 17:30:44 +000043#endif
Manuel Klimek04616e42012-07-06 05:48:52 +000044
Peter Collingbourne2b9471302013-11-07 22:30:32 +000045TEST(Finder, DynamicOnlyAcceptsSomeMatchers) {
46 MatchFinder Finder;
Craig Topper416fa342014-06-08 08:38:12 +000047 EXPECT_TRUE(Finder.addDynamicMatcher(decl(), nullptr));
48 EXPECT_TRUE(Finder.addDynamicMatcher(callExpr(), nullptr));
49 EXPECT_TRUE(Finder.addDynamicMatcher(constantArrayType(hasSize(42)),
50 nullptr));
Peter Collingbourne2b9471302013-11-07 22:30:32 +000051
52 // Do not accept non-toplevel matchers.
Craig Topper416fa342014-06-08 08:38:12 +000053 EXPECT_FALSE(Finder.addDynamicMatcher(isArrow(), nullptr));
54 EXPECT_FALSE(Finder.addDynamicMatcher(hasSize(2), nullptr));
55 EXPECT_FALSE(Finder.addDynamicMatcher(hasName("x"), nullptr));
Peter Collingbourne2b9471302013-11-07 22:30:32 +000056}
57
Manuel Klimeke9235692012-07-25 10:02:02 +000058TEST(Decl, MatchesDeclarations) {
59 EXPECT_TRUE(notMatches("", decl(usingDecl())));
60 EXPECT_TRUE(matches("namespace x { class X {}; } using x::X;",
61 decl(usingDecl())));
62}
63
Manuel Klimek04616e42012-07-06 05:48:52 +000064TEST(NameableDeclaration, MatchesVariousDecls) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +000065 DeclarationMatcher NamedX = namedDecl(hasName("X"));
Manuel Klimek04616e42012-07-06 05:48:52 +000066 EXPECT_TRUE(matches("typedef int X;", NamedX));
67 EXPECT_TRUE(matches("int X;", NamedX));
68 EXPECT_TRUE(matches("class foo { virtual void X(); };", NamedX));
69 EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", NamedX));
70 EXPECT_TRUE(matches("void foo() { int X; }", NamedX));
71 EXPECT_TRUE(matches("namespace X { }", NamedX));
Daniel Jasper1dad1832012-07-10 20:20:19 +000072 EXPECT_TRUE(matches("enum X { A, B, C };", NamedX));
Manuel Klimek04616e42012-07-06 05:48:52 +000073
74 EXPECT_TRUE(notMatches("#define X 1", NamedX));
75}
76
Daniel Jasper1dad1832012-07-10 20:20:19 +000077TEST(NameableDeclaration, REMatchesVariousDecls) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +000078 DeclarationMatcher NamedX = namedDecl(matchesName("::X"));
Daniel Jasper1dad1832012-07-10 20:20:19 +000079 EXPECT_TRUE(matches("typedef int Xa;", NamedX));
80 EXPECT_TRUE(matches("int Xb;", NamedX));
81 EXPECT_TRUE(matches("class foo { virtual void Xc(); };", NamedX));
82 EXPECT_TRUE(matches("void foo() try { } catch(int Xdef) { }", NamedX));
83 EXPECT_TRUE(matches("void foo() { int Xgh; }", NamedX));
84 EXPECT_TRUE(matches("namespace Xij { }", NamedX));
85 EXPECT_TRUE(matches("enum X { A, B, C };", NamedX));
86
87 EXPECT_TRUE(notMatches("#define Xkl 1", NamedX));
88
Daniel Jasperbd3d76d2012-08-24 05:12:34 +000089 DeclarationMatcher StartsWithNo = namedDecl(matchesName("::no"));
Daniel Jasper1dad1832012-07-10 20:20:19 +000090 EXPECT_TRUE(matches("int no_foo;", StartsWithNo));
91 EXPECT_TRUE(matches("class foo { virtual void nobody(); };", StartsWithNo));
92
Daniel Jasperbd3d76d2012-08-24 05:12:34 +000093 DeclarationMatcher Abc = namedDecl(matchesName("a.*b.*c"));
Daniel Jasper1dad1832012-07-10 20:20:19 +000094 EXPECT_TRUE(matches("int abc;", Abc));
95 EXPECT_TRUE(matches("int aFOObBARc;", Abc));
96 EXPECT_TRUE(notMatches("int cab;", Abc));
97 EXPECT_TRUE(matches("int cabc;", Abc));
Manuel Klimeke792efd2012-12-10 07:08:53 +000098
99 DeclarationMatcher StartsWithK = namedDecl(matchesName(":k[^:]*$"));
100 EXPECT_TRUE(matches("int k;", StartsWithK));
101 EXPECT_TRUE(matches("int kAbc;", StartsWithK));
102 EXPECT_TRUE(matches("namespace x { int kTest; }", StartsWithK));
103 EXPECT_TRUE(matches("class C { int k; };", StartsWithK));
104 EXPECT_TRUE(notMatches("class C { int ckc; };", StartsWithK));
Daniel Jasper1dad1832012-07-10 20:20:19 +0000105}
106
Manuel Klimek04616e42012-07-06 05:48:52 +0000107TEST(DeclarationMatcher, MatchClass) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000108 DeclarationMatcher ClassMatcher(recordDecl());
Saleem Abdulrasool377066a2014-03-27 22:50:18 +0000109 llvm::Triple Triple(llvm::sys::getDefaultTargetTriple());
110 if (Triple.getOS() != llvm::Triple::Win32 ||
111 Triple.getEnvironment() != llvm::Triple::MSVC)
NAKAMURA Takumi7d2da0b2014-02-16 10:16:09 +0000112 EXPECT_FALSE(matches("", ClassMatcher));
113 else
114 // Matches class type_info.
115 EXPECT_TRUE(matches("", ClassMatcher));
Manuel Klimek04616e42012-07-06 05:48:52 +0000116
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000117 DeclarationMatcher ClassX = recordDecl(recordDecl(hasName("X")));
Manuel Klimek04616e42012-07-06 05:48:52 +0000118 EXPECT_TRUE(matches("class X;", ClassX));
119 EXPECT_TRUE(matches("class X {};", ClassX));
120 EXPECT_TRUE(matches("template<class T> class X {};", ClassX));
121 EXPECT_TRUE(notMatches("", ClassX));
122}
123
124TEST(DeclarationMatcher, ClassIsDerived) {
Aaron Ballman512fb642015-09-17 13:30:52 +0000125 DeclarationMatcher IsDerivedFromX = cxxRecordDecl(isDerivedFrom("X"));
Manuel Klimek04616e42012-07-06 05:48:52 +0000126
127 EXPECT_TRUE(matches("class X {}; class Y : public X {};", IsDerivedFromX));
Daniel Jasperf49d1e02012-09-07 12:48:17 +0000128 EXPECT_TRUE(notMatches("class X {};", IsDerivedFromX));
129 EXPECT_TRUE(notMatches("class X;", IsDerivedFromX));
Manuel Klimek04616e42012-07-06 05:48:52 +0000130 EXPECT_TRUE(notMatches("class Y;", IsDerivedFromX));
131 EXPECT_TRUE(notMatches("", IsDerivedFromX));
132
Aaron Ballman512fb642015-09-17 13:30:52 +0000133 DeclarationMatcher IsAX = cxxRecordDecl(isSameOrDerivedFrom("X"));
Daniel Jasperf49d1e02012-09-07 12:48:17 +0000134
135 EXPECT_TRUE(matches("class X {}; class Y : public X {};", IsAX));
136 EXPECT_TRUE(matches("class X {};", IsAX));
137 EXPECT_TRUE(matches("class X;", IsAX));
138 EXPECT_TRUE(notMatches("class Y;", IsAX));
139 EXPECT_TRUE(notMatches("", IsAX));
140
Manuel Klimek04616e42012-07-06 05:48:52 +0000141 DeclarationMatcher ZIsDerivedFromX =
Aaron Ballman512fb642015-09-17 13:30:52 +0000142 cxxRecordDecl(hasName("Z"), isDerivedFrom("X"));
Manuel Klimek04616e42012-07-06 05:48:52 +0000143 EXPECT_TRUE(
144 matches("class X {}; class Y : public X {}; class Z : public Y {};",
145 ZIsDerivedFromX));
146 EXPECT_TRUE(
147 matches("class X {};"
148 "template<class T> class Y : public X {};"
149 "class Z : public Y<int> {};", ZIsDerivedFromX));
150 EXPECT_TRUE(matches("class X {}; template<class T> class Z : public X {};",
151 ZIsDerivedFromX));
152 EXPECT_TRUE(
153 matches("template<class T> class X {}; "
154 "template<class T> class Z : public X<T> {};",
155 ZIsDerivedFromX));
156 EXPECT_TRUE(
157 matches("template<class T, class U=T> class X {}; "
158 "template<class T> class Z : public X<T> {};",
159 ZIsDerivedFromX));
160 EXPECT_TRUE(
161 notMatches("template<class X> class A { class Z : public X {}; };",
162 ZIsDerivedFromX));
163 EXPECT_TRUE(
164 matches("template<class X> class A { public: class Z : public X {}; }; "
165 "class X{}; void y() { A<X>::Z z; }", ZIsDerivedFromX));
166 EXPECT_TRUE(
167 matches("template <class T> class X {}; "
168 "template<class Y> class A { class Z : public X<Y> {}; };",
169 ZIsDerivedFromX));
170 EXPECT_TRUE(
171 notMatches("template<template<class T> class X> class A { "
172 " class Z : public X<int> {}; };", ZIsDerivedFromX));
173 EXPECT_TRUE(
174 matches("template<template<class T> class X> class A { "
175 " public: class Z : public X<int> {}; }; "
176 "template<class T> class X {}; void y() { A<X>::Z z; }",
177 ZIsDerivedFromX));
178 EXPECT_TRUE(
179 notMatches("template<class X> class A { class Z : public X::D {}; };",
180 ZIsDerivedFromX));
181 EXPECT_TRUE(
182 matches("template<class X> class A { public: "
183 " class Z : public X::D {}; }; "
184 "class Y { public: class X {}; typedef X D; }; "
185 "void y() { A<Y>::Z z; }", ZIsDerivedFromX));
186 EXPECT_TRUE(
187 matches("class X {}; typedef X Y; class Z : public Y {};",
188 ZIsDerivedFromX));
189 EXPECT_TRUE(
190 matches("template<class T> class Y { typedef typename T::U X; "
191 " class Z : public X {}; };", ZIsDerivedFromX));
192 EXPECT_TRUE(matches("class X {}; class Z : public ::X {};",
193 ZIsDerivedFromX));
194 EXPECT_TRUE(
195 notMatches("template<class T> class X {}; "
196 "template<class T> class A { class Z : public X<T>::D {}; };",
197 ZIsDerivedFromX));
198 EXPECT_TRUE(
199 matches("template<class T> class X { public: typedef X<T> D; }; "
200 "template<class T> class A { public: "
201 " class Z : public X<T>::D {}; }; void y() { A<int>::Z z; }",
202 ZIsDerivedFromX));
203 EXPECT_TRUE(
204 notMatches("template<class X> class A { class Z : public X::D::E {}; };",
205 ZIsDerivedFromX));
206 EXPECT_TRUE(
207 matches("class X {}; typedef X V; typedef V W; class Z : public W {};",
208 ZIsDerivedFromX));
209 EXPECT_TRUE(
210 matches("class X {}; class Y : public X {}; "
211 "typedef Y V; typedef V W; class Z : public W {};",
212 ZIsDerivedFromX));
213 EXPECT_TRUE(
214 matches("template<class T, class U> class X {}; "
215 "template<class T> class A { class Z : public X<T, int> {}; };",
216 ZIsDerivedFromX));
217 EXPECT_TRUE(
218 notMatches("template<class X> class D { typedef X A; typedef A B; "
219 " typedef B C; class Z : public C {}; };",
220 ZIsDerivedFromX));
221 EXPECT_TRUE(
222 matches("class X {}; typedef X A; typedef A B; "
223 "class Z : public B {};", ZIsDerivedFromX));
224 EXPECT_TRUE(
225 matches("class X {}; typedef X A; typedef A B; typedef B C; "
226 "class Z : public C {};", ZIsDerivedFromX));
227 EXPECT_TRUE(
228 matches("class U {}; typedef U X; typedef X V; "
229 "class Z : public V {};", ZIsDerivedFromX));
230 EXPECT_TRUE(
231 matches("class Base {}; typedef Base X; "
232 "class Z : public Base {};", ZIsDerivedFromX));
233 EXPECT_TRUE(
234 matches("class Base {}; typedef Base Base2; typedef Base2 X; "
235 "class Z : public Base {};", ZIsDerivedFromX));
236 EXPECT_TRUE(
237 notMatches("class Base {}; class Base2 {}; typedef Base2 X; "
238 "class Z : public Base {};", ZIsDerivedFromX));
239 EXPECT_TRUE(
240 matches("class A {}; typedef A X; typedef A Y; "
241 "class Z : public Y {};", ZIsDerivedFromX));
242 EXPECT_TRUE(
243 notMatches("template <typename T> class Z;"
244 "template <> class Z<void> {};"
245 "template <typename T> class Z : public Z<void> {};",
246 IsDerivedFromX));
247 EXPECT_TRUE(
248 matches("template <typename T> class X;"
249 "template <> class X<void> {};"
250 "template <typename T> class X : public X<void> {};",
251 IsDerivedFromX));
252 EXPECT_TRUE(matches(
253 "class X {};"
254 "template <typename T> class Z;"
255 "template <> class Z<void> {};"
256 "template <typename T> class Z : public Z<void>, public X {};",
257 ZIsDerivedFromX));
Manuel Klimek5472a522012-12-04 13:40:29 +0000258 EXPECT_TRUE(
259 notMatches("template<int> struct X;"
260 "template<int i> struct X : public X<i-1> {};",
Aaron Ballman512fb642015-09-17 13:30:52 +0000261 cxxRecordDecl(isDerivedFrom(recordDecl(hasName("Some"))))));
Manuel Klimek5472a522012-12-04 13:40:29 +0000262 EXPECT_TRUE(matches(
263 "struct A {};"
264 "template<int> struct X;"
265 "template<int i> struct X : public X<i-1> {};"
266 "template<> struct X<0> : public A {};"
267 "struct B : public X<42> {};",
Aaron Ballman512fb642015-09-17 13:30:52 +0000268 cxxRecordDecl(hasName("B"), isDerivedFrom(recordDecl(hasName("A"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000269
270 // FIXME: Once we have better matchers for template type matching,
271 // get rid of the Variable(...) matching and match the right template
272 // declarations directly.
273 const char *RecursiveTemplateOneParameter =
274 "class Base1 {}; class Base2 {};"
275 "template <typename T> class Z;"
276 "template <> class Z<void> : public Base1 {};"
277 "template <> class Z<int> : public Base2 {};"
278 "template <> class Z<float> : public Z<void> {};"
279 "template <> class Z<double> : public Z<int> {};"
280 "template <typename T> class Z : public Z<float>, public Z<double> {};"
281 "void f() { Z<float> z_float; Z<double> z_double; Z<char> z_char; }";
282 EXPECT_TRUE(matches(
283 RecursiveTemplateOneParameter,
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000284 varDecl(hasName("z_float"),
Aaron Ballman512fb642015-09-17 13:30:52 +0000285 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000286 EXPECT_TRUE(notMatches(
287 RecursiveTemplateOneParameter,
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000288 varDecl(hasName("z_float"),
Aaron Ballman512fb642015-09-17 13:30:52 +0000289 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base2")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000290 EXPECT_TRUE(matches(
291 RecursiveTemplateOneParameter,
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000292 varDecl(hasName("z_char"),
Aaron Ballman512fb642015-09-17 13:30:52 +0000293 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1"),
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000294 isDerivedFrom("Base2")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000295
296 const char *RecursiveTemplateTwoParameters =
297 "class Base1 {}; class Base2 {};"
298 "template <typename T1, typename T2> class Z;"
299 "template <typename T> class Z<void, T> : public Base1 {};"
300 "template <typename T> class Z<int, T> : public Base2 {};"
301 "template <typename T> class Z<float, T> : public Z<void, T> {};"
302 "template <typename T> class Z<double, T> : public Z<int, T> {};"
303 "template <typename T1, typename T2> class Z : "
304 " public Z<float, T2>, public Z<double, T2> {};"
305 "void f() { Z<float, void> z_float; Z<double, void> z_double; "
306 " Z<char, void> z_char; }";
307 EXPECT_TRUE(matches(
308 RecursiveTemplateTwoParameters,
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000309 varDecl(hasName("z_float"),
Aaron Ballman512fb642015-09-17 13:30:52 +0000310 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000311 EXPECT_TRUE(notMatches(
312 RecursiveTemplateTwoParameters,
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000313 varDecl(hasName("z_float"),
Aaron Ballman512fb642015-09-17 13:30:52 +0000314 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base2")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000315 EXPECT_TRUE(matches(
316 RecursiveTemplateTwoParameters,
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000317 varDecl(hasName("z_char"),
Aaron Ballman512fb642015-09-17 13:30:52 +0000318 hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1"),
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000319 isDerivedFrom("Base2")))))));
Daniel Jasper2b3c7d42012-07-17 07:39:27 +0000320 EXPECT_TRUE(matches(
321 "namespace ns { class X {}; class Y : public X {}; }",
Aaron Ballman512fb642015-09-17 13:30:52 +0000322 cxxRecordDecl(isDerivedFrom("::ns::X"))));
Daniel Jasper2b3c7d42012-07-17 07:39:27 +0000323 EXPECT_TRUE(notMatches(
324 "class X {}; class Y : public X {};",
Aaron Ballman512fb642015-09-17 13:30:52 +0000325 cxxRecordDecl(isDerivedFrom("::ns::X"))));
Daniel Jasper2b3c7d42012-07-17 07:39:27 +0000326
327 EXPECT_TRUE(matches(
328 "class X {}; class Y : public X {};",
Aaron Ballman512fb642015-09-17 13:30:52 +0000329 cxxRecordDecl(isDerivedFrom(recordDecl(hasName("X")).bind("test")))));
Manuel Klimek1863e502013-08-02 21:24:09 +0000330
331 EXPECT_TRUE(matches(
332 "template<typename T> class X {};"
333 "template<typename T> using Z = X<T>;"
334 "template <typename T> class Y : Z<T> {};",
Aaron Ballman512fb642015-09-17 13:30:52 +0000335 cxxRecordDecl(isDerivedFrom(namedDecl(hasName("X"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000336}
337
Edwin Vane0a4836e2013-03-06 17:02:57 +0000338TEST(DeclarationMatcher, hasMethod) {
339 EXPECT_TRUE(matches("class A { void func(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +0000340 cxxRecordDecl(hasMethod(hasName("func")))));
Edwin Vane0a4836e2013-03-06 17:02:57 +0000341 EXPECT_TRUE(notMatches("class A { void func(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +0000342 cxxRecordDecl(hasMethod(isPublic()))));
Edwin Vane0a4836e2013-03-06 17:02:57 +0000343}
344
Daniel Jasper83dafaf2012-09-18 14:17:42 +0000345TEST(DeclarationMatcher, ClassDerivedFromDependentTemplateSpecialization) {
346 EXPECT_TRUE(matches(
347 "template <typename T> struct A {"
348 " template <typename T2> struct F {};"
349 "};"
350 "template <typename T> struct B : A<T>::template F<T> {};"
351 "B<int> b;",
Aaron Ballman512fb642015-09-17 13:30:52 +0000352 cxxRecordDecl(hasName("B"), isDerivedFrom(recordDecl()))));
Daniel Jasper83dafaf2012-09-18 14:17:42 +0000353}
354
Edwin Vaneb6eae142013-02-25 20:43:32 +0000355TEST(DeclarationMatcher, hasDeclContext) {
356 EXPECT_TRUE(matches(
357 "namespace N {"
358 " namespace M {"
359 " class D {};"
360 " }"
361 "}",
Daniel Jasper9fcdc462013-04-08 16:44:05 +0000362 recordDecl(hasDeclContext(namespaceDecl(hasName("M"))))));
Edwin Vaneb6eae142013-02-25 20:43:32 +0000363 EXPECT_TRUE(notMatches(
364 "namespace N {"
365 " namespace M {"
366 " class D {};"
367 " }"
368 "}",
Daniel Jasper9fcdc462013-04-08 16:44:05 +0000369 recordDecl(hasDeclContext(namespaceDecl(hasName("N"))))));
370
371 EXPECT_TRUE(matches("namespace {"
372 " namespace M {"
373 " class D {};"
374 " }"
375 "}",
376 recordDecl(hasDeclContext(namespaceDecl(
377 hasName("M"), hasDeclContext(namespaceDecl()))))));
Samuel Benzaquend93fcc12014-10-27 20:58:44 +0000378
379 EXPECT_TRUE(matches("class D{};", decl(hasDeclContext(decl()))));
Edwin Vaneb6eae142013-02-25 20:43:32 +0000380}
381
Samuel Benzaquenef621f42015-02-10 14:46:45 +0000382TEST(DeclarationMatcher, translationUnitDecl) {
383 const std::string Code = "int MyVar1;\n"
384 "namespace NameSpace {\n"
385 "int MyVar2;\n"
386 "} // namespace NameSpace\n";
387 EXPECT_TRUE(matches(
388 Code, varDecl(hasName("MyVar1"), hasDeclContext(translationUnitDecl()))));
389 EXPECT_FALSE(matches(
390 Code, varDecl(hasName("MyVar2"), hasDeclContext(translationUnitDecl()))));
391 EXPECT_TRUE(matches(
392 Code,
393 varDecl(hasName("MyVar2"),
394 hasDeclContext(decl(hasDeclContext(translationUnitDecl()))))));
395}
396
Manuel Klimek94ad0bf2014-09-04 08:51:06 +0000397TEST(DeclarationMatcher, LinkageSpecification) {
398 EXPECT_TRUE(matches("extern \"C\" { void foo() {}; }", linkageSpecDecl()));
399 EXPECT_TRUE(notMatches("void foo() {};", linkageSpecDecl()));
400}
401
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +0000402TEST(ClassTemplate, DoesNotMatchClass) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000403 DeclarationMatcher ClassX = classTemplateDecl(hasName("X"));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +0000404 EXPECT_TRUE(notMatches("class X;", ClassX));
405 EXPECT_TRUE(notMatches("class X {};", ClassX));
406}
407
408TEST(ClassTemplate, MatchesClassTemplate) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000409 DeclarationMatcher ClassX = classTemplateDecl(hasName("X"));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +0000410 EXPECT_TRUE(matches("template<typename T> class X {};", ClassX));
411 EXPECT_TRUE(matches("class Z { template<class T> class X {}; };", ClassX));
412}
413
414TEST(ClassTemplate, DoesNotMatchClassTemplateExplicitSpecialization) {
415 EXPECT_TRUE(notMatches("template<typename T> class X { };"
416 "template<> class X<int> { int a; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000417 classTemplateDecl(hasName("X"),
418 hasDescendant(fieldDecl(hasName("a"))))));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +0000419}
420
421TEST(ClassTemplate, DoesNotMatchClassTemplatePartialSpecialization) {
422 EXPECT_TRUE(notMatches("template<typename T, typename U> class X { };"
423 "template<typename T> class X<T, int> { int a; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000424 classTemplateDecl(hasName("X"),
425 hasDescendant(fieldDecl(hasName("a"))))));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +0000426}
427
Daniel Jasper4e566c42012-07-12 08:50:38 +0000428TEST(AllOf, AllOverloadsWork) {
429 const char Program[] =
Edwin Vanee9dd3602013-02-12 13:55:40 +0000430 "struct T { };"
431 "int f(int, T*, int, int);"
432 "void g(int x) { T t; f(x, &t, 3, 4); }";
Daniel Jasper4e566c42012-07-12 08:50:38 +0000433 EXPECT_TRUE(matches(Program,
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000434 callExpr(allOf(callee(functionDecl(hasName("f"))),
435 hasArgument(0, declRefExpr(to(varDecl())))))));
Daniel Jasper4e566c42012-07-12 08:50:38 +0000436 EXPECT_TRUE(matches(Program,
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000437 callExpr(allOf(callee(functionDecl(hasName("f"))),
438 hasArgument(0, declRefExpr(to(varDecl()))),
439 hasArgument(1, hasType(pointsTo(
440 recordDecl(hasName("T")))))))));
Edwin Vanee9dd3602013-02-12 13:55:40 +0000441 EXPECT_TRUE(matches(Program,
442 callExpr(allOf(callee(functionDecl(hasName("f"))),
443 hasArgument(0, declRefExpr(to(varDecl()))),
444 hasArgument(1, hasType(pointsTo(
445 recordDecl(hasName("T"))))),
446 hasArgument(2, integerLiteral(equals(3)))))));
447 EXPECT_TRUE(matches(Program,
448 callExpr(allOf(callee(functionDecl(hasName("f"))),
449 hasArgument(0, declRefExpr(to(varDecl()))),
450 hasArgument(1, hasType(pointsTo(
451 recordDecl(hasName("T"))))),
452 hasArgument(2, integerLiteral(equals(3))),
453 hasArgument(3, integerLiteral(equals(4)))))));
Daniel Jasper4e566c42012-07-12 08:50:38 +0000454}
455
Samuel Benzaquenb063f5c2015-07-17 16:05:27 +0000456TEST(ConstructVariadic, MismatchedTypes_Regression) {
457 EXPECT_TRUE(
458 matches("const int a = 0;",
459 internal::DynTypedMatcher::constructVariadic(
460 internal::DynTypedMatcher::VO_AnyOf,
461 ast_type_traits::ASTNodeKind::getFromNodeKind<QualType>(),
462 {isConstQualified(), arrayType()})
463 .convertTo<QualType>()));
464}
465
Manuel Klimek04616e42012-07-06 05:48:52 +0000466TEST(DeclarationMatcher, MatchAnyOf) {
Aaron Ballman512fb642015-09-17 13:30:52 +0000467 DeclarationMatcher YOrZDerivedFromX = cxxRecordDecl(
468 anyOf(hasName("Y"), allOf(isDerivedFrom("X"), hasName("Z"))));
469 EXPECT_TRUE(matches("class X {}; class Z : public X {};", YOrZDerivedFromX));
Manuel Klimek04616e42012-07-06 05:48:52 +0000470 EXPECT_TRUE(matches("class Y {};", YOrZDerivedFromX));
471 EXPECT_TRUE(
472 notMatches("class X {}; class W : public X {};", YOrZDerivedFromX));
473 EXPECT_TRUE(notMatches("class Z {};", YOrZDerivedFromX));
474
Daniel Jasper84c763e2012-07-15 19:57:12 +0000475 DeclarationMatcher XOrYOrZOrU =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000476 recordDecl(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U")));
Daniel Jasper84c763e2012-07-15 19:57:12 +0000477 EXPECT_TRUE(matches("class X {};", XOrYOrZOrU));
478 EXPECT_TRUE(notMatches("class V {};", XOrYOrZOrU));
479
Manuel Klimek04616e42012-07-06 05:48:52 +0000480 DeclarationMatcher XOrYOrZOrUOrV =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000481 recordDecl(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U"),
482 hasName("V")));
Manuel Klimek04616e42012-07-06 05:48:52 +0000483 EXPECT_TRUE(matches("class X {};", XOrYOrZOrUOrV));
484 EXPECT_TRUE(matches("class Y {};", XOrYOrZOrUOrV));
485 EXPECT_TRUE(matches("class Z {};", XOrYOrZOrUOrV));
486 EXPECT_TRUE(matches("class U {};", XOrYOrZOrUOrV));
487 EXPECT_TRUE(matches("class V {};", XOrYOrZOrUOrV));
488 EXPECT_TRUE(notMatches("class A {};", XOrYOrZOrUOrV));
Samuel Benzaquena1170022014-10-06 13:14:30 +0000489
490 StatementMatcher MixedTypes = stmt(anyOf(ifStmt(), binaryOperator()));
491 EXPECT_TRUE(matches("int F() { return 1 + 2; }", MixedTypes));
492 EXPECT_TRUE(matches("int F() { if (true) return 1; }", MixedTypes));
493 EXPECT_TRUE(notMatches("int F() { return 1; }", MixedTypes));
Aaron Ballman8f4699a2015-07-02 14:02:41 +0000494
495 EXPECT_TRUE(
496 matches("void f() try { } catch (int) { } catch (...) { }",
Aaron Ballman512fb642015-09-17 13:30:52 +0000497 cxxCatchStmt(anyOf(hasDescendant(varDecl()), isCatchAll()))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000498}
499
500TEST(DeclarationMatcher, MatchHas) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000501 DeclarationMatcher HasClassX = recordDecl(has(recordDecl(hasName("X"))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000502 EXPECT_TRUE(matches("class Y { class X {}; };", HasClassX));
503 EXPECT_TRUE(matches("class X {};", HasClassX));
504
505 DeclarationMatcher YHasClassX =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000506 recordDecl(hasName("Y"), has(recordDecl(hasName("X"))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000507 EXPECT_TRUE(matches("class Y { class X {}; };", YHasClassX));
508 EXPECT_TRUE(notMatches("class X {};", YHasClassX));
509 EXPECT_TRUE(
510 notMatches("class Y { class Z { class X {}; }; };", YHasClassX));
511}
512
513TEST(DeclarationMatcher, MatchHasRecursiveAllOf) {
514 DeclarationMatcher Recursive =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000515 recordDecl(
516 has(recordDecl(
517 has(recordDecl(hasName("X"))),
518 has(recordDecl(hasName("Y"))),
Manuel Klimek04616e42012-07-06 05:48:52 +0000519 hasName("Z"))),
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000520 has(recordDecl(
521 has(recordDecl(hasName("A"))),
522 has(recordDecl(hasName("B"))),
Manuel Klimek04616e42012-07-06 05:48:52 +0000523 hasName("C"))),
524 hasName("F"));
525
526 EXPECT_TRUE(matches(
527 "class F {"
528 " class Z {"
529 " class X {};"
530 " class Y {};"
531 " };"
532 " class C {"
533 " class A {};"
534 " class B {};"
535 " };"
536 "};", Recursive));
537
538 EXPECT_TRUE(matches(
539 "class F {"
540 " class Z {"
541 " class A {};"
542 " class X {};"
543 " class Y {};"
544 " };"
545 " class C {"
546 " class X {};"
547 " class A {};"
548 " class B {};"
549 " };"
550 "};", Recursive));
551
552 EXPECT_TRUE(matches(
553 "class O1 {"
554 " class O2 {"
555 " class F {"
556 " class Z {"
557 " class A {};"
558 " class X {};"
559 " class Y {};"
560 " };"
561 " class C {"
562 " class X {};"
563 " class A {};"
564 " class B {};"
565 " };"
566 " };"
567 " };"
568 "};", Recursive));
569}
570
571TEST(DeclarationMatcher, MatchHasRecursiveAnyOf) {
572 DeclarationMatcher Recursive =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000573 recordDecl(
Manuel Klimek04616e42012-07-06 05:48:52 +0000574 anyOf(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000575 has(recordDecl(
Manuel Klimek04616e42012-07-06 05:48:52 +0000576 anyOf(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000577 has(recordDecl(
Manuel Klimek04616e42012-07-06 05:48:52 +0000578 hasName("X"))),
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000579 has(recordDecl(
Manuel Klimek04616e42012-07-06 05:48:52 +0000580 hasName("Y"))),
581 hasName("Z")))),
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000582 has(recordDecl(
Manuel Klimek04616e42012-07-06 05:48:52 +0000583 anyOf(
584 hasName("C"),
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000585 has(recordDecl(
Manuel Klimek04616e42012-07-06 05:48:52 +0000586 hasName("A"))),
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000587 has(recordDecl(
Manuel Klimek04616e42012-07-06 05:48:52 +0000588 hasName("B")))))),
589 hasName("F")));
590
591 EXPECT_TRUE(matches("class F {};", Recursive));
592 EXPECT_TRUE(matches("class Z {};", Recursive));
593 EXPECT_TRUE(matches("class C {};", Recursive));
594 EXPECT_TRUE(matches("class M { class N { class X {}; }; };", Recursive));
595 EXPECT_TRUE(matches("class M { class N { class B {}; }; };", Recursive));
596 EXPECT_TRUE(
597 matches("class O1 { class O2 {"
598 " class M { class N { class B {}; }; }; "
599 "}; };", Recursive));
600}
601
602TEST(DeclarationMatcher, MatchNot) {
603 DeclarationMatcher NotClassX =
Aaron Ballman512fb642015-09-17 13:30:52 +0000604 cxxRecordDecl(
Manuel Klimek04616e42012-07-06 05:48:52 +0000605 isDerivedFrom("Y"),
Manuel Klimek04616e42012-07-06 05:48:52 +0000606 unless(hasName("X")));
607 EXPECT_TRUE(notMatches("", NotClassX));
608 EXPECT_TRUE(notMatches("class Y {};", NotClassX));
609 EXPECT_TRUE(matches("class Y {}; class Z : public Y {};", NotClassX));
610 EXPECT_TRUE(notMatches("class Y {}; class X : public Y {};", NotClassX));
611 EXPECT_TRUE(
612 notMatches("class Y {}; class Z {}; class X : public Y {};",
613 NotClassX));
614
615 DeclarationMatcher ClassXHasNotClassY =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000616 recordDecl(
Manuel Klimek04616e42012-07-06 05:48:52 +0000617 hasName("X"),
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000618 has(recordDecl(hasName("Z"))),
Manuel Klimek04616e42012-07-06 05:48:52 +0000619 unless(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000620 has(recordDecl(hasName("Y")))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000621 EXPECT_TRUE(matches("class X { class Z {}; };", ClassXHasNotClassY));
622 EXPECT_TRUE(notMatches("class X { class Y {}; class Z {}; };",
623 ClassXHasNotClassY));
Samuel Benzaquen20099602014-10-13 17:38:12 +0000624
625 DeclarationMatcher NamedNotRecord =
626 namedDecl(hasName("Foo"), unless(recordDecl()));
627 EXPECT_TRUE(matches("void Foo(){}", NamedNotRecord));
628 EXPECT_TRUE(notMatches("struct Foo {};", NamedNotRecord));
Manuel Klimek04616e42012-07-06 05:48:52 +0000629}
630
631TEST(DeclarationMatcher, HasDescendant) {
632 DeclarationMatcher ZDescendantClassX =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000633 recordDecl(
634 hasDescendant(recordDecl(hasName("X"))),
Manuel Klimek04616e42012-07-06 05:48:52 +0000635 hasName("Z"));
636 EXPECT_TRUE(matches("class Z { class X {}; };", ZDescendantClassX));
637 EXPECT_TRUE(
638 matches("class Z { class Y { class X {}; }; };", ZDescendantClassX));
639 EXPECT_TRUE(
640 matches("class Z { class A { class Y { class X {}; }; }; };",
641 ZDescendantClassX));
642 EXPECT_TRUE(
643 matches("class Z { class A { class B { class Y { class X {}; }; }; }; };",
644 ZDescendantClassX));
645 EXPECT_TRUE(notMatches("class Z {};", ZDescendantClassX));
646
647 DeclarationMatcher ZDescendantClassXHasClassY =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000648 recordDecl(
649 hasDescendant(recordDecl(has(recordDecl(hasName("Y"))),
Manuel Klimek04616e42012-07-06 05:48:52 +0000650 hasName("X"))),
651 hasName("Z"));
652 EXPECT_TRUE(matches("class Z { class X { class Y {}; }; };",
653 ZDescendantClassXHasClassY));
654 EXPECT_TRUE(
655 matches("class Z { class A { class B { class X { class Y {}; }; }; }; };",
656 ZDescendantClassXHasClassY));
657 EXPECT_TRUE(notMatches(
658 "class Z {"
659 " class A {"
660 " class B {"
661 " class X {"
662 " class C {"
663 " class Y {};"
664 " };"
665 " };"
666 " }; "
667 " };"
668 "};", ZDescendantClassXHasClassY));
669
670 DeclarationMatcher ZDescendantClassXDescendantClassY =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000671 recordDecl(
672 hasDescendant(recordDecl(hasDescendant(recordDecl(hasName("Y"))),
673 hasName("X"))),
Manuel Klimek04616e42012-07-06 05:48:52 +0000674 hasName("Z"));
675 EXPECT_TRUE(
676 matches("class Z { class A { class X { class B { class Y {}; }; }; }; };",
677 ZDescendantClassXDescendantClassY));
678 EXPECT_TRUE(matches(
679 "class Z {"
680 " class A {"
681 " class X {"
682 " class B {"
683 " class Y {};"
684 " };"
685 " class Y {};"
686 " };"
687 " };"
688 "};", ZDescendantClassXDescendantClassY));
689}
690
Daniel Jasper3dfa09b2014-07-23 13:17:47 +0000691TEST(DeclarationMatcher, HasDescendantMemoization) {
692 DeclarationMatcher CannotMemoize =
693 decl(hasDescendant(typeLoc().bind("x")), has(decl()));
694 EXPECT_TRUE(matches("void f() { int i; }", CannotMemoize));
695}
696
Samuel Benzaquenf28d9972014-10-01 15:08:07 +0000697TEST(DeclarationMatcher, HasDescendantMemoizationUsesRestrictKind) {
698 auto Name = hasName("i");
699 auto VD = internal::Matcher<VarDecl>(Name).dynCastTo<Decl>();
700 auto RD = internal::Matcher<RecordDecl>(Name).dynCastTo<Decl>();
701 // Matching VD first should not make a cache hit for RD.
702 EXPECT_TRUE(notMatches("void f() { int i; }",
703 decl(hasDescendant(VD), hasDescendant(RD))));
704 EXPECT_TRUE(notMatches("void f() { int i; }",
705 decl(hasDescendant(RD), hasDescendant(VD))));
706 // Not matching RD first should not make a cache hit for VD either.
707 EXPECT_TRUE(matches("void f() { int i; }",
708 decl(anyOf(hasDescendant(RD), hasDescendant(VD)))));
709}
710
Manuel Klimek3fe8a382014-08-25 11:23:50 +0000711TEST(DeclarationMatcher, HasAttr) {
712 EXPECT_TRUE(matches("struct __attribute__((warn_unused)) X {};",
713 decl(hasAttr(clang::attr::WarnUnused))));
714 EXPECT_FALSE(matches("struct X {};",
715 decl(hasAttr(clang::attr::WarnUnused))));
716}
717
Manuel Klimekd52a3b82014-08-05 09:45:53 +0000718TEST(DeclarationMatcher, MatchCudaDecl) {
719 EXPECT_TRUE(matchesWithCuda("__global__ void f() { }"
720 "void g() { f<<<1, 2>>>(); }",
Aaron Ballman512fb642015-09-17 13:30:52 +0000721 cudaKernelCallExpr()));
Manuel Klimekd52a3b82014-08-05 09:45:53 +0000722 EXPECT_TRUE(matchesWithCuda("__attribute__((device)) void f() {}",
Manuel Klimek3fe8a382014-08-25 11:23:50 +0000723 hasAttr(clang::attr::CUDADevice)));
Manuel Klimekd52a3b82014-08-05 09:45:53 +0000724 EXPECT_TRUE(notMatchesWithCuda("void f() {}",
Aaron Ballman512fb642015-09-17 13:30:52 +0000725 cudaKernelCallExpr()));
Manuel Klimekd52a3b82014-08-05 09:45:53 +0000726 EXPECT_FALSE(notMatchesWithCuda("__attribute__((global)) void f() {}",
Manuel Klimek3fe8a382014-08-25 11:23:50 +0000727 hasAttr(clang::attr::CUDAGlobal)));
Manuel Klimekd52a3b82014-08-05 09:45:53 +0000728}
729
Daniel Jasperd29d5fa2012-10-29 10:14:44 +0000730// Implements a run method that returns whether BoundNodes contains a
731// Decl bound to Id that can be dynamically cast to T.
732// Optionally checks that the check succeeded a specific number of times.
733template <typename T>
734class VerifyIdIsBoundTo : public BoundNodesCallback {
735public:
736 // Create an object that checks that a node of type \c T was bound to \c Id.
737 // Does not check for a certain number of matches.
738 explicit VerifyIdIsBoundTo(llvm::StringRef Id)
739 : Id(Id), ExpectedCount(-1), Count(0) {}
740
741 // Create an object that checks that a node of type \c T was bound to \c Id.
742 // Checks that there were exactly \c ExpectedCount matches.
743 VerifyIdIsBoundTo(llvm::StringRef Id, int ExpectedCount)
744 : Id(Id), ExpectedCount(ExpectedCount), Count(0) {}
745
746 // Create an object that checks that a node of type \c T was bound to \c Id.
747 // Checks that there was exactly one match with the name \c ExpectedName.
748 // Note that \c T must be a NamedDecl for this to work.
Manuel Klimekb64d6b72013-03-14 16:33:21 +0000749 VerifyIdIsBoundTo(llvm::StringRef Id, llvm::StringRef ExpectedName,
750 int ExpectedCount = 1)
751 : Id(Id), ExpectedCount(ExpectedCount), Count(0),
752 ExpectedName(ExpectedName) {}
Daniel Jasperd29d5fa2012-10-29 10:14:44 +0000753
Craig Toppera798a9d2014-03-02 09:32:10 +0000754 void onEndOfTranslationUnit() override {
Daniel Jasperd29d5fa2012-10-29 10:14:44 +0000755 if (ExpectedCount != -1)
756 EXPECT_EQ(ExpectedCount, Count);
757 if (!ExpectedName.empty())
758 EXPECT_EQ(ExpectedName, Name);
Peter Collingbourne2b9471302013-11-07 22:30:32 +0000759 Count = 0;
760 Name.clear();
761 }
762
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000763 ~VerifyIdIsBoundTo() override {
Peter Collingbourne2b9471302013-11-07 22:30:32 +0000764 EXPECT_EQ(0, Count);
765 EXPECT_EQ("", Name);
Daniel Jasperd29d5fa2012-10-29 10:14:44 +0000766 }
767
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000768 bool run(const BoundNodes *Nodes) override {
Peter Collingbourne093a7292013-11-06 00:27:07 +0000769 const BoundNodes::IDToNodeMap &M = Nodes->getMap();
Daniel Jasperd29d5fa2012-10-29 10:14:44 +0000770 if (Nodes->getNodeAs<T>(Id)) {
771 ++Count;
772 if (const NamedDecl *Named = Nodes->getNodeAs<NamedDecl>(Id)) {
773 Name = Named->getNameAsString();
774 } else if (const NestedNameSpecifier *NNS =
775 Nodes->getNodeAs<NestedNameSpecifier>(Id)) {
776 llvm::raw_string_ostream OS(Name);
777 NNS->print(OS, PrintingPolicy(LangOptions()));
778 }
Peter Collingbourne093a7292013-11-06 00:27:07 +0000779 BoundNodes::IDToNodeMap::const_iterator I = M.find(Id);
780 EXPECT_NE(M.end(), I);
781 if (I != M.end())
782 EXPECT_EQ(Nodes->getNodeAs<T>(Id), I->second.get<T>());
Daniel Jasperd29d5fa2012-10-29 10:14:44 +0000783 return true;
784 }
Craig Topper416fa342014-06-08 08:38:12 +0000785 EXPECT_TRUE(M.count(Id) == 0 ||
786 M.find(Id)->second.template get<T>() == nullptr);
Daniel Jasperd29d5fa2012-10-29 10:14:44 +0000787 return false;
788 }
789
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000790 bool run(const BoundNodes *Nodes, ASTContext *Context) override {
Daniel Jaspere9aa6872012-10-29 10:48:25 +0000791 return run(Nodes);
792 }
793
Daniel Jasperd29d5fa2012-10-29 10:14:44 +0000794private:
795 const std::string Id;
796 const int ExpectedCount;
797 int Count;
798 const std::string ExpectedName;
799 std::string Name;
800};
801
802TEST(HasDescendant, MatchesDescendantTypes) {
803 EXPECT_TRUE(matches("void f() { int i = 3; }",
804 decl(hasDescendant(loc(builtinType())))));
805 EXPECT_TRUE(matches("void f() { int i = 3; }",
806 stmt(hasDescendant(builtinType()))));
807
808 EXPECT_TRUE(matches("void f() { int i = 3; }",
809 stmt(hasDescendant(loc(builtinType())))));
810 EXPECT_TRUE(matches("void f() { int i = 3; }",
811 stmt(hasDescendant(qualType(builtinType())))));
812
813 EXPECT_TRUE(notMatches("void f() { float f = 2.0f; }",
814 stmt(hasDescendant(isInteger()))));
815
816 EXPECT_TRUE(matchAndVerifyResultTrue(
817 "void f() { int a; float c; int d; int e; }",
818 functionDecl(forEachDescendant(
819 varDecl(hasDescendant(isInteger())).bind("x"))),
820 new VerifyIdIsBoundTo<Decl>("x", 3)));
821}
822
823TEST(HasDescendant, MatchesDescendantsOfTypes) {
824 EXPECT_TRUE(matches("void f() { int*** i; }",
825 qualType(hasDescendant(builtinType()))));
826 EXPECT_TRUE(matches("void f() { int*** i; }",
827 qualType(hasDescendant(
828 pointerType(pointee(builtinType()))))));
829 EXPECT_TRUE(matches("void f() { int*** i; }",
David Blaikieb61d0872013-02-18 19:04:16 +0000830 typeLoc(hasDescendant(loc(builtinType())))));
Daniel Jasperd29d5fa2012-10-29 10:14:44 +0000831
832 EXPECT_TRUE(matchAndVerifyResultTrue(
833 "void f() { int*** i; }",
834 qualType(asString("int ***"), forEachDescendant(pointerType().bind("x"))),
835 new VerifyIdIsBoundTo<Type>("x", 2)));
836}
837
838TEST(Has, MatchesChildrenOfTypes) {
839 EXPECT_TRUE(matches("int i;",
840 varDecl(hasName("i"), has(isInteger()))));
841 EXPECT_TRUE(notMatches("int** i;",
842 varDecl(hasName("i"), has(isInteger()))));
843 EXPECT_TRUE(matchAndVerifyResultTrue(
844 "int (*f)(float, int);",
845 qualType(functionType(), forEach(qualType(isInteger()).bind("x"))),
846 new VerifyIdIsBoundTo<QualType>("x", 2)));
847}
848
849TEST(Has, MatchesChildTypes) {
850 EXPECT_TRUE(matches(
851 "int* i;",
852 varDecl(hasName("i"), hasType(qualType(has(builtinType()))))));
853 EXPECT_TRUE(notMatches(
854 "int* i;",
855 varDecl(hasName("i"), hasType(qualType(has(pointerType()))))));
856}
857
Samuel Benzaquenc640ef52014-10-28 13:33:58 +0000858TEST(ValueDecl, Matches) {
859 EXPECT_TRUE(matches("enum EnumType { EnumValue };",
860 valueDecl(hasType(asString("enum EnumType")))));
861 EXPECT_TRUE(matches("void FunctionDecl();",
862 valueDecl(hasType(asString("void (void)")))));
863}
864
Daniel Jasper1dad1832012-07-10 20:20:19 +0000865TEST(Enum, DoesNotMatchClasses) {
866 EXPECT_TRUE(notMatches("class X {};", enumDecl(hasName("X"))));
867}
868
869TEST(Enum, MatchesEnums) {
870 EXPECT_TRUE(matches("enum X {};", enumDecl(hasName("X"))));
871}
872
873TEST(EnumConstant, Matches) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000874 DeclarationMatcher Matcher = enumConstantDecl(hasName("A"));
Daniel Jasper1dad1832012-07-10 20:20:19 +0000875 EXPECT_TRUE(matches("enum X{ A };", Matcher));
876 EXPECT_TRUE(notMatches("enum X{ B };", Matcher));
877 EXPECT_TRUE(notMatches("enum X {};", Matcher));
878}
879
Manuel Klimek04616e42012-07-06 05:48:52 +0000880TEST(StatementMatcher, Has) {
881 StatementMatcher HasVariableI =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000882 expr(hasType(pointsTo(recordDecl(hasName("X")))),
883 has(declRefExpr(to(varDecl(hasName("i"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000884
885 EXPECT_TRUE(matches(
886 "class X; X *x(int); void c() { int i; x(i); }", HasVariableI));
887 EXPECT_TRUE(notMatches(
888 "class X; X *x(int); void c() { int i; x(42); }", HasVariableI));
889}
890
891TEST(StatementMatcher, HasDescendant) {
892 StatementMatcher HasDescendantVariableI =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000893 expr(hasType(pointsTo(recordDecl(hasName("X")))),
894 hasDescendant(declRefExpr(to(varDecl(hasName("i"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000895
896 EXPECT_TRUE(matches(
897 "class X; X *x(bool); bool b(int); void c() { int i; x(b(i)); }",
898 HasDescendantVariableI));
899 EXPECT_TRUE(notMatches(
900 "class X; X *x(bool); bool b(int); void c() { int i; x(b(42)); }",
901 HasDescendantVariableI));
902}
903
904TEST(TypeMatcher, MatchesClassType) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000905 TypeMatcher TypeA = hasDeclaration(recordDecl(hasName("A")));
Manuel Klimek04616e42012-07-06 05:48:52 +0000906
907 EXPECT_TRUE(matches("class A { public: A *a; };", TypeA));
908 EXPECT_TRUE(notMatches("class A {};", TypeA));
909
Aaron Ballman512fb642015-09-17 13:30:52 +0000910 TypeMatcher TypeDerivedFromA =
911 hasDeclaration(cxxRecordDecl(isDerivedFrom("A")));
Manuel Klimek04616e42012-07-06 05:48:52 +0000912
913 EXPECT_TRUE(matches("class A {}; class B : public A { public: B *b; };",
914 TypeDerivedFromA));
915 EXPECT_TRUE(notMatches("class A {};", TypeA));
916
917 TypeMatcher TypeAHasClassB = hasDeclaration(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000918 recordDecl(hasName("A"), has(recordDecl(hasName("B")))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000919
920 EXPECT_TRUE(
921 matches("class A { public: A *a; class B {}; };", TypeAHasClassB));
Aaron Ballmanc129c692015-09-04 18:34:48 +0000922
923 EXPECT_TRUE(matchesC("struct S {}; void f(void) { struct S s; }",
924 varDecl(hasType(namedDecl(hasName("S"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000925}
926
Aaron Ballmanb85be662015-09-11 11:51:24 +0000927TEST(TypeMatcher, MatchesDeclTypes) {
928 // TypedefType -> TypedefNameDecl
929 EXPECT_TRUE(matches("typedef int I; void f(I i);",
930 parmVarDecl(hasType(namedDecl(hasName("I"))))));
931 // ObjCObjectPointerType
932 EXPECT_TRUE(matchesObjC("@interface Foo @end void f(Foo *f);",
933 parmVarDecl(hasType(objcObjectPointerType()))));
934 // ObjCObjectPointerType -> ObjCInterfaceType -> ObjCInterfaceDecl
935 EXPECT_TRUE(matchesObjC(
936 "@interface Foo @end void f(Foo *f);",
937 parmVarDecl(hasType(pointsTo(objcInterfaceDecl(hasName("Foo")))))));
938 // TemplateTypeParmType
939 EXPECT_TRUE(matches("template <typename T> void f(T t);",
940 parmVarDecl(hasType(templateTypeParmType()))));
941 // TemplateTypeParmType -> TemplateTypeParmDecl
942 EXPECT_TRUE(matches("template <typename T> void f(T t);",
943 parmVarDecl(hasType(namedDecl(hasName("T"))))));
944 // InjectedClassNameType
945 EXPECT_TRUE(matches("template <typename T> struct S {"
946 " void f(S s);"
947 "};",
948 parmVarDecl(hasType(injectedClassNameType()))));
949 EXPECT_TRUE(notMatches("template <typename T> struct S {"
950 " void g(S<T> s);"
951 "};",
952 parmVarDecl(hasType(injectedClassNameType()))));
953 // InjectedClassNameType -> CXXRecordDecl
954 EXPECT_TRUE(matches("template <typename T> struct S {"
955 " void f(S s);"
956 "};",
957 parmVarDecl(hasType(namedDecl(hasName("S"))))));
958
959 static const char Using[] = "template <typename T>"
960 "struct Base {"
961 " typedef T Foo;"
962 "};"
963 ""
964 "template <typename T>"
965 "struct S : private Base<T> {"
966 " using typename Base<T>::Foo;"
967 " void f(Foo);"
968 "};";
969 // UnresolvedUsingTypenameDecl
970 EXPECT_TRUE(matches(Using, unresolvedUsingTypenameDecl(hasName("Foo"))));
971 // UnresolvedUsingTypenameType -> UnresolvedUsingTypenameDecl
972 EXPECT_TRUE(matches(Using, parmVarDecl(hasType(namedDecl(hasName("Foo"))))));
973}
974
Manuel Klimek04616e42012-07-06 05:48:52 +0000975TEST(Matcher, BindMatchedNodes) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000976 DeclarationMatcher ClassX = has(recordDecl(hasName("::X")).bind("x"));
Manuel Klimek04616e42012-07-06 05:48:52 +0000977
978 EXPECT_TRUE(matchAndVerifyResultTrue("class X {};",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +0000979 ClassX, new VerifyIdIsBoundTo<CXXRecordDecl>("x")));
Manuel Klimek04616e42012-07-06 05:48:52 +0000980
981 EXPECT_TRUE(matchAndVerifyResultFalse("class X {};",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +0000982 ClassX, new VerifyIdIsBoundTo<CXXRecordDecl>("other-id")));
Manuel Klimek04616e42012-07-06 05:48:52 +0000983
984 TypeMatcher TypeAHasClassB = hasDeclaration(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000985 recordDecl(hasName("A"), has(recordDecl(hasName("B")).bind("b"))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000986
987 EXPECT_TRUE(matchAndVerifyResultTrue("class A { public: A *a; class B {}; };",
988 TypeAHasClassB,
Daniel Jaspera6bc1f62012-09-13 13:11:25 +0000989 new VerifyIdIsBoundTo<Decl>("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +0000990
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000991 StatementMatcher MethodX =
Aaron Ballman512fb642015-09-17 13:30:52 +0000992 callExpr(callee(cxxMethodDecl(hasName("x")))).bind("x");
Manuel Klimek04616e42012-07-06 05:48:52 +0000993
994 EXPECT_TRUE(matchAndVerifyResultTrue("class A { void x() { x(); } };",
995 MethodX,
Daniel Jaspera6bc1f62012-09-13 13:11:25 +0000996 new VerifyIdIsBoundTo<CXXMemberCallExpr>("x")));
Daniel Jasper1dad1832012-07-10 20:20:19 +0000997}
998
999TEST(Matcher, BindTheSameNameInAlternatives) {
1000 StatementMatcher matcher = anyOf(
1001 binaryOperator(hasOperatorName("+"),
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001002 hasLHS(expr().bind("x")),
Daniel Jasper1dad1832012-07-10 20:20:19 +00001003 hasRHS(integerLiteral(equals(0)))),
1004 binaryOperator(hasOperatorName("+"),
1005 hasLHS(integerLiteral(equals(0))),
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001006 hasRHS(expr().bind("x"))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001007
1008 EXPECT_TRUE(matchAndVerifyResultTrue(
1009 // The first branch of the matcher binds x to 0 but then fails.
1010 // The second branch binds x to f() and succeeds.
1011 "int f() { return 0 + f(); }",
1012 matcher,
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00001013 new VerifyIdIsBoundTo<CallExpr>("x")));
Manuel Klimek04616e42012-07-06 05:48:52 +00001014}
1015
Manuel Klimekfdf98762012-08-30 19:41:06 +00001016TEST(Matcher, BindsIDForMemoizedResults) {
1017 // Using the same matcher in two match expressions will make memoization
1018 // kick in.
1019 DeclarationMatcher ClassX = recordDecl(hasName("X")).bind("x");
1020 EXPECT_TRUE(matchAndVerifyResultTrue(
1021 "class A { class B { class X {}; }; };",
1022 DeclarationMatcher(anyOf(
1023 recordDecl(hasName("A"), hasDescendant(ClassX)),
1024 recordDecl(hasName("B"), hasDescendant(ClassX)))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00001025 new VerifyIdIsBoundTo<Decl>("x", 2)));
Manuel Klimekfdf98762012-08-30 19:41:06 +00001026}
1027
Daniel Jasper856194d02012-12-03 15:43:25 +00001028TEST(HasDeclaration, HasDeclarationOfEnumType) {
1029 EXPECT_TRUE(matches("enum X {}; void y(X *x) { x; }",
1030 expr(hasType(pointsTo(
1031 qualType(hasDeclaration(enumDecl(hasName("X")))))))));
1032}
1033
Edwin Vaneed936452013-02-25 14:32:42 +00001034TEST(HasDeclaration, HasGetDeclTraitTest) {
1035 EXPECT_TRUE(internal::has_getDecl<TypedefType>::value);
1036 EXPECT_TRUE(internal::has_getDecl<RecordType>::value);
1037 EXPECT_FALSE(internal::has_getDecl<TemplateSpecializationType>::value);
1038}
1039
Edwin Vane2c197e02013-02-19 17:14:34 +00001040TEST(HasDeclaration, HasDeclarationOfTypeWithDecl) {
1041 EXPECT_TRUE(matches("typedef int X; X a;",
1042 varDecl(hasName("a"),
1043 hasType(typedefType(hasDeclaration(decl()))))));
1044
1045 // FIXME: Add tests for other types with getDecl() (e.g. RecordType)
1046}
1047
Edwin Vanef901b712013-02-25 14:49:29 +00001048TEST(HasDeclaration, HasDeclarationOfTemplateSpecializationType) {
1049 EXPECT_TRUE(matches("template <typename T> class A {}; A<int> a;",
1050 varDecl(hasType(templateSpecializationType(
1051 hasDeclaration(namedDecl(hasName("A"))))))));
1052}
1053
Manuel Klimek04616e42012-07-06 05:48:52 +00001054TEST(HasType, TakesQualTypeMatcherAndMatchesExpr) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001055 TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X")));
Manuel Klimek04616e42012-07-06 05:48:52 +00001056 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001057 matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001058 EXPECT_TRUE(
1059 notMatches("class X {}; void y(X *x) { x; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001060 expr(hasType(ClassX))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001061 EXPECT_TRUE(
1062 matches("class X {}; void y(X *x) { x; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001063 expr(hasType(pointsTo(ClassX)))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001064}
1065
1066TEST(HasType, TakesQualTypeMatcherAndMatchesValueDecl) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001067 TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X")));
Manuel Klimek04616e42012-07-06 05:48:52 +00001068 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001069 matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001070 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001071 notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001072 EXPECT_TRUE(
1073 matches("class X {}; void y() { X *x; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001074 varDecl(hasType(pointsTo(ClassX)))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001075}
1076
1077TEST(HasType, TakesDeclMatcherAndMatchesExpr) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001078 DeclarationMatcher ClassX = recordDecl(hasName("X"));
Manuel Klimek04616e42012-07-06 05:48:52 +00001079 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001080 matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001081 EXPECT_TRUE(
1082 notMatches("class X {}; void y(X *x) { x; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001083 expr(hasType(ClassX))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001084}
1085
1086TEST(HasType, TakesDeclMatcherAndMatchesValueDecl) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001087 DeclarationMatcher ClassX = recordDecl(hasName("X"));
Manuel Klimek04616e42012-07-06 05:48:52 +00001088 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001089 matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001090 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001091 notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001092}
1093
Aaron Ballman7e7b7b22016-02-01 14:11:47 +00001094TEST(HasType, MatchesTypedefDecl) {
1095 EXPECT_TRUE(matches("typedef int X;", typedefDecl(hasType(asString("int")))));
1096 EXPECT_TRUE(matches("typedef const int T;",
1097 typedefDecl(hasType(asString("const int")))));
1098 EXPECT_TRUE(notMatches("typedef const int T;",
1099 typedefDecl(hasType(asString("int")))));
1100 EXPECT_TRUE(matches("typedef int foo; typedef foo bar;",
1101 typedefDecl(hasType(asString("foo")), hasName("bar"))));
1102}
1103
Manuel Klimekc16c6522013-06-20 13:08:29 +00001104TEST(HasTypeLoc, MatchesDeclaratorDecls) {
1105 EXPECT_TRUE(matches("int x;",
1106 varDecl(hasName("x"), hasTypeLoc(loc(asString("int"))))));
1107
1108 // Make sure we don't crash on implicit constructors.
1109 EXPECT_TRUE(notMatches("class X {}; X x;",
1110 declaratorDecl(hasTypeLoc(loc(asString("int"))))));
1111}
1112
Manuel Klimek04616e42012-07-06 05:48:52 +00001113TEST(Matcher, Call) {
1114 // FIXME: Do we want to overload Call() to directly take
Daniel Jasper1dad1832012-07-10 20:20:19 +00001115 // Matcher<Decl>, too?
Aaron Ballman512fb642015-09-17 13:30:52 +00001116 StatementMatcher MethodX =
1117 callExpr(hasDeclaration(cxxMethodDecl(hasName("x"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001118
1119 EXPECT_TRUE(matches("class Y { void x() { x(); } };", MethodX));
1120 EXPECT_TRUE(notMatches("class Y { void x() {} };", MethodX));
1121
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001122 StatementMatcher MethodOnY =
Aaron Ballman512fb642015-09-17 13:30:52 +00001123 cxxMemberCallExpr(on(hasType(recordDecl(hasName("Y")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001124
1125 EXPECT_TRUE(
1126 matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
1127 MethodOnY));
1128 EXPECT_TRUE(
1129 matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
1130 MethodOnY));
1131 EXPECT_TRUE(
1132 notMatches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
1133 MethodOnY));
1134 EXPECT_TRUE(
1135 notMatches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
1136 MethodOnY));
1137 EXPECT_TRUE(
1138 notMatches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
1139 MethodOnY));
1140
1141 StatementMatcher MethodOnYPointer =
Aaron Ballman512fb642015-09-17 13:30:52 +00001142 cxxMemberCallExpr(on(hasType(pointsTo(recordDecl(hasName("Y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001143
1144 EXPECT_TRUE(
1145 matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
1146 MethodOnYPointer));
1147 EXPECT_TRUE(
1148 matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
1149 MethodOnYPointer));
1150 EXPECT_TRUE(
1151 matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
1152 MethodOnYPointer));
1153 EXPECT_TRUE(
1154 notMatches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
1155 MethodOnYPointer));
1156 EXPECT_TRUE(
1157 notMatches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
1158 MethodOnYPointer));
1159}
1160
Daniel Jasper5901e472012-10-01 13:40:41 +00001161TEST(Matcher, Lambda) {
Richard Smith3d584b02014-02-06 21:49:08 +00001162 EXPECT_TRUE(matches("auto f = [] (int i) { return i; };",
Daniel Jasper5901e472012-10-01 13:40:41 +00001163 lambdaExpr()));
1164}
1165
1166TEST(Matcher, ForRange) {
Daniel Jasper6f595392012-10-01 15:05:34 +00001167 EXPECT_TRUE(matches("int as[] = { 1, 2, 3 };"
1168 "void f() { for (auto &a : as); }",
Aaron Ballman512fb642015-09-17 13:30:52 +00001169 cxxForRangeStmt()));
Daniel Jasper5901e472012-10-01 13:40:41 +00001170 EXPECT_TRUE(notMatches("void f() { for (int i; i<5; ++i); }",
Aaron Ballman512fb642015-09-17 13:30:52 +00001171 cxxForRangeStmt()));
Daniel Jasper5901e472012-10-01 13:40:41 +00001172}
1173
Alexander Kornienko9e41b5c2014-06-29 22:18:53 +00001174TEST(Matcher, SubstNonTypeTemplateParm) {
1175 EXPECT_FALSE(matches("template<int N>\n"
1176 "struct A { static const int n = 0; };\n"
1177 "struct B : public A<42> {};",
1178 substNonTypeTemplateParmExpr()));
1179 EXPECT_TRUE(matches("template<int N>\n"
1180 "struct A { static const int n = N; };\n"
1181 "struct B : public A<42> {};",
1182 substNonTypeTemplateParmExpr()));
1183}
1184
Aaron Ballman478a8eb2015-10-05 19:44:42 +00001185TEST(Matcher, NonTypeTemplateParmDecl) {
1186 EXPECT_TRUE(matches("template <int N> void f();",
1187 nonTypeTemplateParmDecl(hasName("N"))));
1188 EXPECT_TRUE(
1189 notMatches("template <typename T> void f();", nonTypeTemplateParmDecl()));
1190}
1191
Eric Fiselier3acf5fd2015-10-17 02:34:44 +00001192TEST(Matcher, templateTypeParmDecl) {
1193 EXPECT_TRUE(matches("template <typename T> void f();",
1194 templateTypeParmDecl(hasName("T"))));
1195 EXPECT_TRUE(
1196 notMatches("template <int N> void f();", templateTypeParmDecl()));
1197}
1198
Daniel Jasper5901e472012-10-01 13:40:41 +00001199TEST(Matcher, UserDefinedLiteral) {
1200 EXPECT_TRUE(matches("constexpr char operator \"\" _inc (const char i) {"
1201 " return i + 1;"
1202 "}"
1203 "char c = 'a'_inc;",
1204 userDefinedLiteral()));
1205}
1206
Daniel Jasper87c3d362012-09-20 14:12:57 +00001207TEST(Matcher, FlowControl) {
1208 EXPECT_TRUE(matches("void f() { while(true) { break; } }", breakStmt()));
1209 EXPECT_TRUE(matches("void f() { while(true) { continue; } }",
1210 continueStmt()));
1211 EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}", gotoStmt()));
Aaron Ballmana35b8fc2016-03-09 17:11:51 +00001212 EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}",
1213 labelStmt(
1214 hasDeclaration(
1215 labelDecl(hasName("FOO"))))));
1216 EXPECT_TRUE(matches("void f() { FOO: ; void *ptr = &&FOO; goto *ptr; }",
1217 addrLabelExpr()));
Daniel Jasper87c3d362012-09-20 14:12:57 +00001218 EXPECT_TRUE(matches("void f() { return; }", returnStmt()));
1219}
1220
Daniel Jasper1dad1832012-07-10 20:20:19 +00001221TEST(HasType, MatchesAsString) {
1222 EXPECT_TRUE(
1223 matches("class Y { public: void x(); }; void z() {Y* y; y->x(); }",
Aaron Ballman512fb642015-09-17 13:30:52 +00001224 cxxMemberCallExpr(on(hasType(asString("class Y *"))))));
1225 EXPECT_TRUE(
1226 matches("class X { void x(int x) {} };",
1227 cxxMethodDecl(hasParameter(0, hasType(asString("int"))))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001228 EXPECT_TRUE(matches("namespace ns { struct A {}; } struct B { ns::A a; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001229 fieldDecl(hasType(asString("ns::A")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001230 EXPECT_TRUE(matches("namespace { struct A {}; } struct B { A a; };",
David Blaikieabe1a392014-04-02 05:58:29 +00001231 fieldDecl(hasType(asString("struct (anonymous namespace)::A")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001232}
1233
Manuel Klimek04616e42012-07-06 05:48:52 +00001234TEST(Matcher, OverloadedOperatorCall) {
Aaron Ballman512fb642015-09-17 13:30:52 +00001235 StatementMatcher OpCall = cxxOperatorCallExpr();
Manuel Klimek04616e42012-07-06 05:48:52 +00001236 // Unary operator
1237 EXPECT_TRUE(matches("class Y { }; "
1238 "bool operator!(Y x) { return false; }; "
1239 "Y y; bool c = !y;", OpCall));
1240 // No match -- special operators like "new", "delete"
1241 // FIXME: operator new takes size_t, for which we need stddef.h, for which
1242 // we need to figure out include paths in the test.
1243 // EXPECT_TRUE(NotMatches("#include <stddef.h>\n"
1244 // "class Y { }; "
1245 // "void *operator new(size_t size) { return 0; } "
1246 // "Y *y = new Y;", OpCall));
1247 EXPECT_TRUE(notMatches("class Y { }; "
1248 "void operator delete(void *p) { } "
1249 "void a() {Y *y = new Y; delete y;}", OpCall));
1250 // Binary operator
1251 EXPECT_TRUE(matches("class Y { }; "
1252 "bool operator&&(Y x, Y y) { return true; }; "
1253 "Y a; Y b; bool c = a && b;",
1254 OpCall));
1255 // No match -- normal operator, not an overloaded one.
1256 EXPECT_TRUE(notMatches("bool x = true, y = true; bool t = x && y;", OpCall));
1257 EXPECT_TRUE(notMatches("int t = 5 << 2;", OpCall));
1258}
1259
1260TEST(Matcher, HasOperatorNameForOverloadedOperatorCall) {
1261 StatementMatcher OpCallAndAnd =
Aaron Ballman512fb642015-09-17 13:30:52 +00001262 cxxOperatorCallExpr(hasOverloadedOperatorName("&&"));
Manuel Klimek04616e42012-07-06 05:48:52 +00001263 EXPECT_TRUE(matches("class Y { }; "
1264 "bool operator&&(Y x, Y y) { return true; }; "
1265 "Y a; Y b; bool c = a && b;", OpCallAndAnd));
1266 StatementMatcher OpCallLessLess =
Aaron Ballman512fb642015-09-17 13:30:52 +00001267 cxxOperatorCallExpr(hasOverloadedOperatorName("<<"));
Manuel Klimek04616e42012-07-06 05:48:52 +00001268 EXPECT_TRUE(notMatches("class Y { }; "
1269 "bool operator&&(Y x, Y y) { return true; }; "
1270 "Y a; Y b; bool c = a && b;",
1271 OpCallLessLess));
Benjamin Kramer09514492014-07-14 14:05:02 +00001272 StatementMatcher OpStarCall =
Aaron Ballman512fb642015-09-17 13:30:52 +00001273 cxxOperatorCallExpr(hasOverloadedOperatorName("*"));
Benjamin Kramer09514492014-07-14 14:05:02 +00001274 EXPECT_TRUE(matches("class Y; int operator*(Y &); void f(Y &y) { *y; }",
1275 OpStarCall));
Edwin Vane0a4836e2013-03-06 17:02:57 +00001276 DeclarationMatcher ClassWithOpStar =
Aaron Ballman512fb642015-09-17 13:30:52 +00001277 cxxRecordDecl(hasMethod(hasOverloadedOperatorName("*")));
Edwin Vane0a4836e2013-03-06 17:02:57 +00001278 EXPECT_TRUE(matches("class Y { int operator*(); };",
1279 ClassWithOpStar));
1280 EXPECT_TRUE(notMatches("class Y { void myOperator(); };",
1281 ClassWithOpStar)) ;
Benjamin Kramer09514492014-07-14 14:05:02 +00001282 DeclarationMatcher AnyOpStar = functionDecl(hasOverloadedOperatorName("*"));
1283 EXPECT_TRUE(matches("class Y; int operator*(Y &);", AnyOpStar));
1284 EXPECT_TRUE(matches("class Y { int operator*(); };", AnyOpStar));
Manuel Klimek04616e42012-07-06 05:48:52 +00001285}
1286
Daniel Jasper0f9f0192012-11-15 03:29:05 +00001287TEST(Matcher, NestedOverloadedOperatorCalls) {
1288 EXPECT_TRUE(matchAndVerifyResultTrue(
Aaron Ballman512fb642015-09-17 13:30:52 +00001289 "class Y { }; "
1290 "Y& operator&&(Y& x, Y& y) { return x; }; "
1291 "Y a; Y b; Y c; Y d = a && b && c;",
1292 cxxOperatorCallExpr(hasOverloadedOperatorName("&&")).bind("x"),
1293 new VerifyIdIsBoundTo<CXXOperatorCallExpr>("x", 2)));
1294 EXPECT_TRUE(matches("class Y { }; "
1295 "Y& operator&&(Y& x, Y& y) { return x; }; "
1296 "Y a; Y b; Y c; Y d = a && b && c;",
1297 cxxOperatorCallExpr(hasParent(cxxOperatorCallExpr()))));
1298 EXPECT_TRUE(
1299 matches("class Y { }; "
1300 "Y& operator&&(Y& x, Y& y) { return x; }; "
1301 "Y a; Y b; Y c; Y d = a && b && c;",
1302 cxxOperatorCallExpr(hasDescendant(cxxOperatorCallExpr()))));
Daniel Jasper0f9f0192012-11-15 03:29:05 +00001303}
1304
Manuel Klimek04616e42012-07-06 05:48:52 +00001305TEST(Matcher, ThisPointerType) {
Manuel Klimek86f8bbc2012-07-24 13:37:29 +00001306 StatementMatcher MethodOnY =
Aaron Ballman512fb642015-09-17 13:30:52 +00001307 cxxMemberCallExpr(thisPointerType(recordDecl(hasName("Y"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001308
1309 EXPECT_TRUE(
1310 matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
1311 MethodOnY));
1312 EXPECT_TRUE(
1313 matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
1314 MethodOnY));
1315 EXPECT_TRUE(
1316 matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
1317 MethodOnY));
1318 EXPECT_TRUE(
1319 matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
1320 MethodOnY));
1321 EXPECT_TRUE(
1322 matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
1323 MethodOnY));
1324
1325 EXPECT_TRUE(matches(
1326 "class Y {"
1327 " public: virtual void x();"
1328 "};"
1329 "class X : public Y {"
1330 " public: virtual void x();"
1331 "};"
1332 "void z() { X *x; x->Y::x(); }", MethodOnY));
1333}
1334
1335TEST(Matcher, VariableUsage) {
1336 StatementMatcher Reference =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001337 declRefExpr(to(
1338 varDecl(hasInitializer(
Aaron Ballman512fb642015-09-17 13:30:52 +00001339 cxxMemberCallExpr(thisPointerType(recordDecl(hasName("Y"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001340
1341 EXPECT_TRUE(matches(
1342 "class Y {"
1343 " public:"
1344 " bool x() const;"
1345 "};"
1346 "void z(const Y &y) {"
1347 " bool b = y.x();"
1348 " if (b) {}"
1349 "}", Reference));
1350
1351 EXPECT_TRUE(notMatches(
1352 "class Y {"
1353 " public:"
1354 " bool x() const;"
1355 "};"
1356 "void z(const Y &y) {"
1357 " bool b = y.x();"
1358 "}", Reference));
1359}
1360
Samuel Benzaquenf56a2992014-06-05 18:22:14 +00001361TEST(Matcher, VarDecl_Storage) {
1362 auto M = varDecl(hasName("X"), hasLocalStorage());
1363 EXPECT_TRUE(matches("void f() { int X; }", M));
1364 EXPECT_TRUE(notMatches("int X;", M));
1365 EXPECT_TRUE(notMatches("void f() { static int X; }", M));
1366
1367 M = varDecl(hasName("X"), hasGlobalStorage());
1368 EXPECT_TRUE(notMatches("void f() { int X; }", M));
1369 EXPECT_TRUE(matches("int X;", M));
1370 EXPECT_TRUE(matches("void f() { static int X; }", M));
1371}
1372
Aaron Ballman8e7f00b2015-11-18 17:56:55 +00001373TEST(Matcher, VarDecl_StorageDuration) {
1374 std::string T =
Aaron Ballmanf08e1842015-11-18 18:37:29 +00001375 "void f() { int x; static int y; } int a;";
Aaron Ballman8e7f00b2015-11-18 17:56:55 +00001376
1377 EXPECT_TRUE(matches(T, varDecl(hasName("x"), hasAutomaticStorageDuration())));
1378 EXPECT_TRUE(
1379 notMatches(T, varDecl(hasName("y"), hasAutomaticStorageDuration())));
1380 EXPECT_TRUE(
Aaron Ballman8e7f00b2015-11-18 17:56:55 +00001381 notMatches(T, varDecl(hasName("a"), hasAutomaticStorageDuration())));
1382
1383 EXPECT_TRUE(matches(T, varDecl(hasName("y"), hasStaticStorageDuration())));
1384 EXPECT_TRUE(matches(T, varDecl(hasName("a"), hasStaticStorageDuration())));
1385 EXPECT_TRUE(notMatches(T, varDecl(hasName("x"), hasStaticStorageDuration())));
Aaron Ballman8e7f00b2015-11-18 17:56:55 +00001386
Aaron Ballmanf08e1842015-11-18 18:37:29 +00001387 // FIXME: It is really hard to test with thread_local itself because not all
1388 // targets support TLS, which causes this to be an error depending on what
1389 // platform the test is being run on. We do not have access to the TargetInfo
1390 // object to be able to test whether the platform supports TLS or not.
Aaron Ballman8e7f00b2015-11-18 17:56:55 +00001391 EXPECT_TRUE(notMatches(T, varDecl(hasName("x"), hasThreadStorageDuration())));
1392 EXPECT_TRUE(notMatches(T, varDecl(hasName("y"), hasThreadStorageDuration())));
1393 EXPECT_TRUE(notMatches(T, varDecl(hasName("a"), hasThreadStorageDuration())));
1394}
1395
Manuel Klimek61379422012-12-04 14:42:08 +00001396TEST(Matcher, FindsVarDeclInFunctionParameter) {
Daniel Jasper3cb72b42012-07-30 05:03:25 +00001397 EXPECT_TRUE(matches(
1398 "void f(int i) {}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001399 varDecl(hasName("i"))));
Daniel Jasper3cb72b42012-07-30 05:03:25 +00001400}
1401
Manuel Klimek04616e42012-07-06 05:48:52 +00001402TEST(Matcher, CalledVariable) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00001403 StatementMatcher CallOnVariableY =
Aaron Ballman512fb642015-09-17 13:30:52 +00001404 cxxMemberCallExpr(on(declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001405
1406 EXPECT_TRUE(matches(
1407 "class Y { public: void x() { Y y; y.x(); } };", CallOnVariableY));
1408 EXPECT_TRUE(matches(
1409 "class Y { public: void x() const { Y y; y.x(); } };", CallOnVariableY));
1410 EXPECT_TRUE(matches(
1411 "class Y { public: void x(); };"
1412 "class X : public Y { void z() { X y; y.x(); } };", CallOnVariableY));
1413 EXPECT_TRUE(matches(
1414 "class Y { public: void x(); };"
1415 "class X : public Y { void z() { X *y; y->x(); } };", CallOnVariableY));
1416 EXPECT_TRUE(notMatches(
1417 "class Y { public: void x(); };"
1418 "class X : public Y { void z() { unsigned long y; ((X*)y)->x(); } };",
1419 CallOnVariableY));
1420}
1421
Daniel Jasper1dad1832012-07-10 20:20:19 +00001422TEST(UnaryExprOrTypeTraitExpr, MatchesSizeOfAndAlignOf) {
1423 EXPECT_TRUE(matches("void x() { int a = sizeof(a); }",
1424 unaryExprOrTypeTraitExpr()));
1425 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }",
1426 alignOfExpr(anything())));
1427 // FIXME: Uncomment once alignof is enabled.
1428 // EXPECT_TRUE(matches("void x() { int a = alignof(a); }",
1429 // unaryExprOrTypeTraitExpr()));
1430 // EXPECT_TRUE(notMatches("void x() { int a = alignof(a); }",
1431 // sizeOfExpr()));
1432}
1433
1434TEST(UnaryExpressionOrTypeTraitExpression, MatchesCorrectType) {
1435 EXPECT_TRUE(matches("void x() { int a = sizeof(a); }", sizeOfExpr(
1436 hasArgumentOfType(asString("int")))));
1437 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
1438 hasArgumentOfType(asString("float")))));
1439 EXPECT_TRUE(matches(
1440 "struct A {}; void x() { A a; int b = sizeof(a); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001441 sizeOfExpr(hasArgumentOfType(hasDeclaration(recordDecl(hasName("A")))))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001442 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001443 hasArgumentOfType(hasDeclaration(recordDecl(hasName("string")))))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001444}
1445
Manuel Klimek04616e42012-07-06 05:48:52 +00001446TEST(MemberExpression, DoesNotMatchClasses) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001447 EXPECT_TRUE(notMatches("class Y { void x() {} };", memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001448}
1449
1450TEST(MemberExpression, MatchesMemberFunctionCall) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001451 EXPECT_TRUE(matches("class Y { void x() { x(); } };", memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001452}
1453
1454TEST(MemberExpression, MatchesVariable) {
1455 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001456 matches("class Y { void x() { this->y; } int y; };", memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001457 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001458 matches("class Y { void x() { y; } int y; };", memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001459 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001460 matches("class Y { void x() { Y y; y.y; } int y; };", memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001461}
1462
1463TEST(MemberExpression, MatchesStaticVariable) {
1464 EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001465 memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001466 EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001467 memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001468 EXPECT_TRUE(notMatches("class Y { void x() { Y::y; } static int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001469 memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001470}
1471
Daniel Jasper4e566c42012-07-12 08:50:38 +00001472TEST(IsInteger, MatchesIntegers) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001473 EXPECT_TRUE(matches("int i = 0;", varDecl(hasType(isInteger()))));
1474 EXPECT_TRUE(matches(
1475 "long long i = 0; void f(long long) { }; void g() {f(i);}",
1476 callExpr(hasArgument(0, declRefExpr(
1477 to(varDecl(hasType(isInteger()))))))));
Daniel Jasper4e566c42012-07-12 08:50:38 +00001478}
1479
1480TEST(IsInteger, ReportsNoFalsePositives) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001481 EXPECT_TRUE(notMatches("int *i;", varDecl(hasType(isInteger()))));
Daniel Jasper4e566c42012-07-12 08:50:38 +00001482 EXPECT_TRUE(notMatches("struct T {}; T t; void f(T *) { }; void g() {f(&t);}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001483 callExpr(hasArgument(0, declRefExpr(
1484 to(varDecl(hasType(isInteger()))))))));
Daniel Jasper4e566c42012-07-12 08:50:38 +00001485}
1486
Felix Bergercc9df3b2016-02-15 04:00:39 +00001487TEST(IsAnyPointer, MatchesPointers) {
1488 EXPECT_TRUE(matches("int* i = nullptr;", varDecl(hasType(isAnyPointer()))));
1489}
1490
Felix Berger40ef42a2016-03-06 15:27:59 +00001491TEST(IsAnyPointer, MatchesObjcPointer) {
1492 EXPECT_TRUE(matchesObjC("@interface Foo @end Foo *f;",
1493 varDecl(hasType(isAnyPointer()))));
1494}
1495
Felix Bergercc9df3b2016-02-15 04:00:39 +00001496TEST(IsAnyPointer, ReportsNoFalsePositives) {
1497 EXPECT_TRUE(notMatches("int i = 0;", varDecl(hasType(isAnyPointer()))));
1498}
1499
Gabor Horvath009c5d52015-12-15 08:35:45 +00001500TEST(IsAnyCharacter, MatchesCharacters) {
1501 EXPECT_TRUE(matches("char i = 0;", varDecl(hasType(isAnyCharacter()))));
1502}
1503
1504TEST(IsAnyCharacter, ReportsNoFalsePositives) {
1505 EXPECT_TRUE(notMatches("int i;", varDecl(hasType(isAnyCharacter()))));
1506}
1507
Manuel Klimek04616e42012-07-06 05:48:52 +00001508TEST(IsArrow, MatchesMemberVariablesViaArrow) {
1509 EXPECT_TRUE(matches("class Y { void x() { this->y; } int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001510 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001511 EXPECT_TRUE(matches("class Y { void x() { y; } int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001512 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001513 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001514 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001515}
1516
1517TEST(IsArrow, MatchesStaticMemberVariablesViaArrow) {
1518 EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001519 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001520 EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001521 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001522 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } static int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001523 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001524}
1525
1526TEST(IsArrow, MatchesMemberCallsViaArrow) {
1527 EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001528 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001529 EXPECT_TRUE(matches("class Y { void x() { x(); } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001530 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001531 EXPECT_TRUE(notMatches("class Y { void x() { Y y; y.x(); } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001532 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001533}
1534
1535TEST(Callee, MatchesDeclarations) {
Aaron Ballman512fb642015-09-17 13:30:52 +00001536 StatementMatcher CallMethodX = callExpr(callee(cxxMethodDecl(hasName("x"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001537
1538 EXPECT_TRUE(matches("class Y { void x() { x(); } };", CallMethodX));
1539 EXPECT_TRUE(notMatches("class Y { void x() {} };", CallMethodX));
Samuel Benzaquen025f6b12015-04-20 20:58:50 +00001540
Aaron Ballman512fb642015-09-17 13:30:52 +00001541 CallMethodX = callExpr(callee(cxxConversionDecl()));
Samuel Benzaquen025f6b12015-04-20 20:58:50 +00001542 EXPECT_TRUE(
1543 matches("struct Y { operator int() const; }; int i = Y();", CallMethodX));
1544 EXPECT_TRUE(notMatches("struct Y { operator int() const; }; Y y = Y();",
1545 CallMethodX));
Manuel Klimek04616e42012-07-06 05:48:52 +00001546}
1547
Aaron Ballman6f6d0b62015-08-11 21:09:52 +00001548TEST(ConversionDeclaration, IsExplicit) {
1549 EXPECT_TRUE(matches("struct S { explicit operator int(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001550 cxxConversionDecl(isExplicit())));
Aaron Ballman6f6d0b62015-08-11 21:09:52 +00001551 EXPECT_TRUE(notMatches("struct S { operator int(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001552 cxxConversionDecl(isExplicit())));
Aaron Ballman6f6d0b62015-08-11 21:09:52 +00001553}
1554
Manuel Klimek04616e42012-07-06 05:48:52 +00001555TEST(Callee, MatchesMemberExpressions) {
1556 EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001557 callExpr(callee(memberExpr()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001558 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001559 notMatches("class Y { void x() { this->x(); } };", callExpr(callee(callExpr()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001560}
1561
1562TEST(Function, MatchesFunctionDeclarations) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001563 StatementMatcher CallFunctionF = callExpr(callee(functionDecl(hasName("f"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001564
1565 EXPECT_TRUE(matches("void f() { f(); }", CallFunctionF));
1566 EXPECT_TRUE(notMatches("void f() { }", CallFunctionF));
1567
NAKAMURA Takumi7d2da0b2014-02-16 10:16:09 +00001568 if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getOS() !=
1569 llvm::Triple::Win32) {
1570 // FIXME: Make this work for MSVC.
1571 // Dependent contexts, but a non-dependent call.
1572 EXPECT_TRUE(matches("void f(); template <int N> void g() { f(); }",
1573 CallFunctionF));
1574 EXPECT_TRUE(
1575 matches("void f(); template <int N> struct S { void g() { f(); } };",
1576 CallFunctionF));
1577 }
Manuel Klimek04616e42012-07-06 05:48:52 +00001578
1579 // Depedent calls don't match.
1580 EXPECT_TRUE(
1581 notMatches("void f(int); template <typename T> void g(T t) { f(t); }",
1582 CallFunctionF));
1583 EXPECT_TRUE(
1584 notMatches("void f(int);"
1585 "template <typename T> struct S { void g(T t) { f(t); } };",
1586 CallFunctionF));
Aaron Ballman3fd6c112015-10-05 14:41:27 +00001587
1588 EXPECT_TRUE(matches("void f(...);", functionDecl(isVariadic())));
1589 EXPECT_TRUE(notMatches("void f(int);", functionDecl(isVariadic())));
1590 EXPECT_TRUE(notMatches("template <typename... Ts> void f(Ts...);",
1591 functionDecl(isVariadic())));
1592 EXPECT_TRUE(notMatches("void f();", functionDecl(isVariadic())));
1593 EXPECT_TRUE(notMatchesC("void f();", functionDecl(isVariadic())));
Aaron Ballman7e7b7b22016-02-01 14:11:47 +00001594 EXPECT_TRUE(matches("void f(...);", functionDecl(parameterCountIs(0))));
1595 EXPECT_TRUE(matchesC("void f();", functionDecl(parameterCountIs(0))));
1596 EXPECT_TRUE(matches("void f(int, ...);", functionDecl(parameterCountIs(1))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001597}
1598
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00001599TEST(FunctionTemplate, MatchesFunctionTemplateDeclarations) {
1600 EXPECT_TRUE(
1601 matches("template <typename T> void f(T t) {}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001602 functionTemplateDecl(hasName("f"))));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00001603}
1604
1605TEST(FunctionTemplate, DoesNotMatchFunctionDeclarations) {
1606 EXPECT_TRUE(
1607 notMatches("void f(double d); void f(int t) {}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001608 functionTemplateDecl(hasName("f"))));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00001609}
1610
1611TEST(FunctionTemplate, DoesNotMatchFunctionTemplateSpecializations) {
1612 EXPECT_TRUE(
1613 notMatches("void g(); template <typename T> void f(T t) {}"
1614 "template <> void f(int t) { g(); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001615 functionTemplateDecl(hasName("f"),
1616 hasDescendant(declRefExpr(to(
1617 functionDecl(hasName("g"))))))));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00001618}
1619
Manuel Klimek04616e42012-07-06 05:48:52 +00001620TEST(Matcher, Argument) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00001621 StatementMatcher CallArgumentY = callExpr(
1622 hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001623
1624 EXPECT_TRUE(matches("void x(int) { int y; x(y); }", CallArgumentY));
1625 EXPECT_TRUE(
1626 matches("class X { void x(int) { int y; x(y); } };", CallArgumentY));
1627 EXPECT_TRUE(notMatches("void x(int) { int z; x(z); }", CallArgumentY));
1628
Daniel Jasper848cbe12012-09-18 13:09:13 +00001629 StatementMatcher WrongIndex = callExpr(
1630 hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001631 EXPECT_TRUE(notMatches("void x(int) { int y; x(y); }", WrongIndex));
1632}
1633
1634TEST(Matcher, AnyArgument) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00001635 StatementMatcher CallArgumentY = callExpr(
1636 hasAnyArgument(declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001637 EXPECT_TRUE(matches("void x(int, int) { int y; x(1, y); }", CallArgumentY));
1638 EXPECT_TRUE(matches("void x(int, int) { int y; x(y, 42); }", CallArgumentY));
1639 EXPECT_TRUE(notMatches("void x(int, int) { x(1, 2); }", CallArgumentY));
1640}
1641
Manuel Klimekce28f9e2016-01-18 11:20:09 +00001642TEST(ForEachArgumentWithParam, ReportsNoFalsePositives) {
1643 StatementMatcher ArgumentY =
1644 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1645 DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
1646 StatementMatcher CallExpr =
1647 callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
1648
1649 // IntParam does not match.
Aaron Ballmand7b18b92016-01-18 20:28:57 +00001650 EXPECT_TRUE(notMatches("void f(int* i) { int* y; f(y); }", CallExpr));
Manuel Klimekce28f9e2016-01-18 11:20:09 +00001651 // ArgumentY does not match.
Aaron Ballmand7b18b92016-01-18 20:28:57 +00001652 EXPECT_TRUE(notMatches("void f(int i) { int x; f(x); }", CallExpr));
Manuel Klimekce28f9e2016-01-18 11:20:09 +00001653}
1654
1655TEST(ForEachArgumentWithParam, MatchesCXXMemberCallExpr) {
1656 StatementMatcher ArgumentY =
1657 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1658 DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
1659 StatementMatcher CallExpr =
1660 callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
1661 EXPECT_TRUE(matchAndVerifyResultTrue(
1662 "struct S {"
1663 " const S& operator[](int i) { return *this; }"
1664 "};"
1665 "void f(S S1) {"
1666 " int y = 1;"
1667 " S1[y];"
1668 "}",
1669 CallExpr, new VerifyIdIsBoundTo<ParmVarDecl>("param", 1)));
Aaron Ballmand7b18b92016-01-18 20:28:57 +00001670
1671 StatementMatcher CallExpr2 =
1672 callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
1673 EXPECT_TRUE(matchAndVerifyResultTrue(
1674 "struct S {"
1675 " static void g(int i);"
1676 "};"
1677 "void f() {"
1678 " int y = 1;"
1679 " S::g(y);"
1680 "}",
1681 CallExpr2, new VerifyIdIsBoundTo<ParmVarDecl>("param", 1)));
Manuel Klimekce28f9e2016-01-18 11:20:09 +00001682}
1683
1684TEST(ForEachArgumentWithParam, MatchesCallExpr) {
1685 StatementMatcher ArgumentY =
1686 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1687 DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
1688 StatementMatcher CallExpr =
1689 callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
1690
1691 EXPECT_TRUE(
1692 matchAndVerifyResultTrue("void f(int i) { int y; f(y); }", CallExpr,
1693 new VerifyIdIsBoundTo<ParmVarDecl>("param")));
1694 EXPECT_TRUE(
1695 matchAndVerifyResultTrue("void f(int i) { int y; f(y); }", CallExpr,
1696 new VerifyIdIsBoundTo<DeclRefExpr>("arg")));
1697
1698 EXPECT_TRUE(matchAndVerifyResultTrue(
1699 "void f(int i, int j) { int y; f(y, y); }", CallExpr,
1700 new VerifyIdIsBoundTo<ParmVarDecl>("param", 2)));
1701 EXPECT_TRUE(matchAndVerifyResultTrue(
1702 "void f(int i, int j) { int y; f(y, y); }", CallExpr,
1703 new VerifyIdIsBoundTo<DeclRefExpr>("arg", 2)));
1704}
1705
1706TEST(ForEachArgumentWithParam, MatchesConstructExpr) {
1707 StatementMatcher ArgumentY =
1708 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1709 DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
1710 StatementMatcher ConstructExpr =
1711 cxxConstructExpr(forEachArgumentWithParam(ArgumentY, IntParam));
1712
1713 EXPECT_TRUE(matchAndVerifyResultTrue(
1714 "struct C {"
1715 " C(int i) {}"
1716 "};"
1717 "int y = 0;"
1718 "C Obj(y);",
1719 ConstructExpr, new VerifyIdIsBoundTo<ParmVarDecl>("param")));
1720}
1721
1722TEST(ForEachArgumentWithParam, HandlesBoundNodesForNonMatches) {
1723 EXPECT_TRUE(matchAndVerifyResultTrue(
1724 "void g(int i, int j) {"
1725 " int a;"
1726 " int b;"
1727 " int c;"
1728 " g(a, 0);"
1729 " g(a, b);"
1730 " g(0, b);"
1731 "}",
1732 functionDecl(
1733 forEachDescendant(varDecl().bind("v")),
1734 forEachDescendant(callExpr(forEachArgumentWithParam(
1735 declRefExpr(to(decl(equalsBoundNode("v")))), parmVarDecl())))),
1736 new VerifyIdIsBoundTo<VarDecl>("v", 4)));
1737}
1738
Manuel Klimek04616e42012-07-06 05:48:52 +00001739TEST(Matcher, ArgumentCount) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00001740 StatementMatcher Call1Arg = callExpr(argumentCountIs(1));
Manuel Klimek04616e42012-07-06 05:48:52 +00001741
1742 EXPECT_TRUE(matches("void x(int) { x(0); }", Call1Arg));
1743 EXPECT_TRUE(matches("class X { void x(int) { x(0); } };", Call1Arg));
1744 EXPECT_TRUE(notMatches("void x(int, int) { x(0, 0); }", Call1Arg));
1745}
1746
Daniel Jasper9f501292012-12-04 11:54:27 +00001747TEST(Matcher, ParameterCount) {
1748 DeclarationMatcher Function1Arg = functionDecl(parameterCountIs(1));
1749 EXPECT_TRUE(matches("void f(int i) {}", Function1Arg));
1750 EXPECT_TRUE(matches("class X { void f(int i) {} };", Function1Arg));
1751 EXPECT_TRUE(notMatches("void f() {}", Function1Arg));
1752 EXPECT_TRUE(notMatches("void f(int i, int j, int k) {}", Function1Arg));
Aaron Ballman7e7b7b22016-02-01 14:11:47 +00001753 EXPECT_TRUE(matches("void f(int i, ...) {};", Function1Arg));
Daniel Jasper9f501292012-12-04 11:54:27 +00001754}
1755
Manuel Klimek04616e42012-07-06 05:48:52 +00001756TEST(Matcher, References) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001757 DeclarationMatcher ReferenceClassX = varDecl(
1758 hasType(references(recordDecl(hasName("X")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001759 EXPECT_TRUE(matches("class X {}; void y(X y) { X &x = y; }",
1760 ReferenceClassX));
1761 EXPECT_TRUE(
1762 matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX));
Michael Hanc90d12d2013-09-11 15:53:29 +00001763 // The match here is on the implicit copy constructor code for
1764 // class X, not on code 'X x = y'.
Manuel Klimek04616e42012-07-06 05:48:52 +00001765 EXPECT_TRUE(
Michael Hanc90d12d2013-09-11 15:53:29 +00001766 matches("class X {}; void y(X y) { X x = y; }", ReferenceClassX));
1767 EXPECT_TRUE(
1768 notMatches("class X {}; extern X x;", ReferenceClassX));
Manuel Klimek04616e42012-07-06 05:48:52 +00001769 EXPECT_TRUE(
1770 notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX));
1771}
1772
Edwin Vane0a4836e2013-03-06 17:02:57 +00001773TEST(QualType, hasCanonicalType) {
1774 EXPECT_TRUE(notMatches("typedef int &int_ref;"
1775 "int a;"
1776 "int_ref b = a;",
1777 varDecl(hasType(qualType(referenceType())))));
1778 EXPECT_TRUE(
1779 matches("typedef int &int_ref;"
1780 "int a;"
1781 "int_ref b = a;",
1782 varDecl(hasType(qualType(hasCanonicalType(referenceType()))))));
1783}
1784
Edwin Vane119d3df2013-04-02 18:15:55 +00001785TEST(QualType, hasLocalQualifiers) {
1786 EXPECT_TRUE(notMatches("typedef const int const_int; const_int i = 1;",
1787 varDecl(hasType(hasLocalQualifiers()))));
1788 EXPECT_TRUE(matches("int *const j = nullptr;",
1789 varDecl(hasType(hasLocalQualifiers()))));
1790 EXPECT_TRUE(matches("int *volatile k;",
1791 varDecl(hasType(hasLocalQualifiers()))));
1792 EXPECT_TRUE(notMatches("int m;",
1793 varDecl(hasType(hasLocalQualifiers()))));
1794}
1795
Manuel Klimek04616e42012-07-06 05:48:52 +00001796TEST(HasParameter, CallsInnerMatcher) {
1797 EXPECT_TRUE(matches("class X { void x(int) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001798 cxxMethodDecl(hasParameter(0, varDecl()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001799 EXPECT_TRUE(notMatches("class X { void x(int) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001800 cxxMethodDecl(hasParameter(0, hasName("x")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001801}
1802
1803TEST(HasParameter, DoesNotMatchIfIndexOutOfBounds) {
1804 EXPECT_TRUE(notMatches("class X { void x(int) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001805 cxxMethodDecl(hasParameter(42, varDecl()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001806}
1807
1808TEST(HasType, MatchesParameterVariableTypesStrictly) {
Aaron Ballman512fb642015-09-17 13:30:52 +00001809 EXPECT_TRUE(matches(
1810 "class X { void x(X x) {} };",
1811 cxxMethodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
1812 EXPECT_TRUE(notMatches(
1813 "class X { void x(const X &x) {} };",
1814 cxxMethodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001815 EXPECT_TRUE(matches("class X { void x(const X *x) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001816 cxxMethodDecl(hasParameter(
1817 0, hasType(pointsTo(recordDecl(hasName("X"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001818 EXPECT_TRUE(matches("class X { void x(const X &x) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001819 cxxMethodDecl(hasParameter(
1820 0, hasType(references(recordDecl(hasName("X"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001821}
1822
1823TEST(HasAnyParameter, MatchesIndependentlyOfPosition) {
Aaron Ballman512fb642015-09-17 13:30:52 +00001824 EXPECT_TRUE(matches(
1825 "class Y {}; class X { void x(X x, Y y) {} };",
1826 cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
1827 EXPECT_TRUE(matches(
1828 "class Y {}; class X { void x(Y y, X x) {} };",
1829 cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001830}
1831
Daniel Jasper1dad1832012-07-10 20:20:19 +00001832TEST(Returns, MatchesReturnTypes) {
1833 EXPECT_TRUE(matches("class Y { int f() { return 1; } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001834 functionDecl(returns(asString("int")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001835 EXPECT_TRUE(notMatches("class Y { int f() { return 1; } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001836 functionDecl(returns(asString("float")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001837 EXPECT_TRUE(matches("class Y { Y getMe() { return *this; } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001838 functionDecl(returns(hasDeclaration(
1839 recordDecl(hasName("Y")))))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001840}
1841
Daniel Jasperfaaffe32012-08-15 18:52:19 +00001842TEST(IsExternC, MatchesExternCFunctionDeclarations) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001843 EXPECT_TRUE(matches("extern \"C\" void f() {}", functionDecl(isExternC())));
1844 EXPECT_TRUE(matches("extern \"C\" { void f() {} }",
1845 functionDecl(isExternC())));
1846 EXPECT_TRUE(notMatches("void f() {}", functionDecl(isExternC())));
Daniel Jasperfaaffe32012-08-15 18:52:19 +00001847}
1848
Aaron Ballmaneb85b042016-01-18 20:37:44 +00001849TEST(IsDefaulted, MatchesDefaultedFunctionDeclarations) {
Aaron Ballman9e373df2016-01-18 20:47:02 +00001850 EXPECT_TRUE(notMatches("class A { ~A(); };",
1851 functionDecl(hasName("~A"), isDefaulted())));
Aaron Ballmaneb85b042016-01-18 20:37:44 +00001852 EXPECT_TRUE(matches("class B { ~B() = default; };",
Aaron Ballman9e373df2016-01-18 20:47:02 +00001853 functionDecl(hasName("~B"), isDefaulted())));
Aaron Ballmaneb85b042016-01-18 20:37:44 +00001854}
1855
Samuel Benzaquen8e7f9962014-08-15 14:20:59 +00001856TEST(IsDeleted, MatchesDeletedFunctionDeclarations) {
1857 EXPECT_TRUE(
1858 notMatches("void Func();", functionDecl(hasName("Func"), isDeleted())));
1859 EXPECT_TRUE(matches("void Func() = delete;",
1860 functionDecl(hasName("Func"), isDeleted())));
1861}
1862
Aaron Ballmana60bcda2015-12-02 15:23:59 +00001863TEST(IsNoThrow, MatchesNoThrowFunctionDeclarations) {
1864 EXPECT_TRUE(notMatches("void f();", functionDecl(isNoThrow())));
1865 EXPECT_TRUE(notMatches("void f() throw(int);", functionDecl(isNoThrow())));
1866 EXPECT_TRUE(
1867 notMatches("void f() noexcept(false);", functionDecl(isNoThrow())));
1868 EXPECT_TRUE(matches("void f() throw();", functionDecl(isNoThrow())));
1869 EXPECT_TRUE(matches("void f() noexcept;", functionDecl(isNoThrow())));
1870}
1871
Szabolcs Siposb37b0ed2015-05-22 11:35:50 +00001872TEST(isConstexpr, MatchesConstexprDeclarations) {
1873 EXPECT_TRUE(matches("constexpr int foo = 42;",
1874 varDecl(hasName("foo"), isConstexpr())));
1875 EXPECT_TRUE(matches("constexpr int bar();",
1876 functionDecl(hasName("bar"), isConstexpr())));
1877}
1878
Manuel Klimek04616e42012-07-06 05:48:52 +00001879TEST(HasAnyParameter, DoesntMatchIfInnerMatcherDoesntMatch) {
Aaron Ballman512fb642015-09-17 13:30:52 +00001880 EXPECT_TRUE(notMatches(
1881 "class Y {}; class X { void x(int) {} };",
1882 cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001883}
1884
1885TEST(HasAnyParameter, DoesNotMatchThisPointer) {
1886 EXPECT_TRUE(notMatches("class Y {}; class X { void x() {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001887 cxxMethodDecl(hasAnyParameter(
1888 hasType(pointsTo(recordDecl(hasName("X"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001889}
1890
Alp Toker8db6e7a2014-01-05 06:38:57 +00001891TEST(HasName, MatchesParameterVariableDeclarations) {
Manuel Klimek04616e42012-07-06 05:48:52 +00001892 EXPECT_TRUE(matches("class Y {}; class X { void x(int x) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001893 cxxMethodDecl(hasAnyParameter(hasName("x")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001894 EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001895 cxxMethodDecl(hasAnyParameter(hasName("x")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001896}
1897
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001898TEST(Matcher, MatchesClassTemplateSpecialization) {
1899 EXPECT_TRUE(matches("template<typename T> struct A {};"
1900 "template<> struct A<int> {};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001901 classTemplateSpecializationDecl()));
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001902 EXPECT_TRUE(matches("template<typename T> struct A {}; A<int> a;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001903 classTemplateSpecializationDecl()));
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001904 EXPECT_TRUE(notMatches("template<typename T> struct A {};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001905 classTemplateSpecializationDecl()));
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001906}
1907
Manuel Klimekc16c6522013-06-20 13:08:29 +00001908TEST(DeclaratorDecl, MatchesDeclaratorDecls) {
1909 EXPECT_TRUE(matches("int x;", declaratorDecl()));
1910 EXPECT_TRUE(notMatches("class A {};", declaratorDecl()));
1911}
1912
1913TEST(ParmVarDecl, MatchesParmVars) {
1914 EXPECT_TRUE(matches("void f(int x);", parmVarDecl()));
1915 EXPECT_TRUE(notMatches("void f();", parmVarDecl()));
1916}
1917
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001918TEST(Matcher, MatchesTypeTemplateArgument) {
1919 EXPECT_TRUE(matches(
1920 "template<typename T> struct B {};"
1921 "B<int> b;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001922 classTemplateSpecializationDecl(hasAnyTemplateArgument(refersToType(
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001923 asString("int"))))));
1924}
1925
1926TEST(Matcher, MatchesDeclarationReferenceTemplateArgument) {
1927 EXPECT_TRUE(matches(
1928 "struct B { int next; };"
1929 "template<int(B::*next_ptr)> struct A {};"
1930 "A<&B::next> a;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001931 classTemplateSpecializationDecl(hasAnyTemplateArgument(
1932 refersToDeclaration(fieldDecl(hasName("next")))))));
Daniel Jasper0c303372012-09-29 15:55:18 +00001933
1934 EXPECT_TRUE(notMatches(
1935 "template <typename T> struct A {};"
1936 "A<int> a;",
1937 classTemplateSpecializationDecl(hasAnyTemplateArgument(
1938 refersToDeclaration(decl())))));
Peter Collingbourne564597f2014-02-20 19:18:03 +00001939
1940 EXPECT_TRUE(matches(
1941 "struct B { int next; };"
1942 "template<int(B::*next_ptr)> struct A {};"
1943 "A<&B::next> a;",
1944 templateSpecializationType(hasAnyTemplateArgument(isExpr(
1945 hasDescendant(declRefExpr(to(fieldDecl(hasName("next"))))))))));
1946
1947 EXPECT_TRUE(notMatches(
1948 "template <typename T> struct A {};"
1949 "A<int> a;",
1950 templateSpecializationType(hasAnyTemplateArgument(
1951 refersToDeclaration(decl())))));
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001952}
1953
1954TEST(Matcher, MatchesSpecificArgument) {
1955 EXPECT_TRUE(matches(
1956 "template<typename T, typename U> class A {};"
1957 "A<bool, int> a;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001958 classTemplateSpecializationDecl(hasTemplateArgument(
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001959 1, refersToType(asString("int"))))));
1960 EXPECT_TRUE(notMatches(
1961 "template<typename T, typename U> class A {};"
1962 "A<int, bool> a;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001963 classTemplateSpecializationDecl(hasTemplateArgument(
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001964 1, refersToType(asString("int"))))));
Peter Collingbourne564597f2014-02-20 19:18:03 +00001965
1966 EXPECT_TRUE(matches(
1967 "template<typename T, typename U> class A {};"
1968 "A<bool, int> a;",
1969 templateSpecializationType(hasTemplateArgument(
1970 1, refersToType(asString("int"))))));
1971 EXPECT_TRUE(notMatches(
1972 "template<typename T, typename U> class A {};"
1973 "A<int, bool> a;",
1974 templateSpecializationType(hasTemplateArgument(
1975 1, refersToType(asString("int"))))));
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001976}
1977
Manuel Klimek7735e402014-10-09 13:06:22 +00001978TEST(TemplateArgument, Matches) {
1979 EXPECT_TRUE(matches("template<typename T> struct C {}; C<int> c;",
1980 classTemplateSpecializationDecl(
1981 hasAnyTemplateArgument(templateArgument()))));
1982 EXPECT_TRUE(matches(
1983 "template<typename T> struct C {}; C<int> c;",
1984 templateSpecializationType(hasAnyTemplateArgument(templateArgument()))));
1985}
1986
1987TEST(TemplateArgumentCountIs, Matches) {
1988 EXPECT_TRUE(
1989 matches("template<typename T> struct C {}; C<int> c;",
1990 classTemplateSpecializationDecl(templateArgumentCountIs(1))));
1991 EXPECT_TRUE(
1992 notMatches("template<typename T> struct C {}; C<int> c;",
1993 classTemplateSpecializationDecl(templateArgumentCountIs(2))));
1994
1995 EXPECT_TRUE(matches("template<typename T> struct C {}; C<int> c;",
1996 templateSpecializationType(templateArgumentCountIs(1))));
1997 EXPECT_TRUE(
1998 notMatches("template<typename T> struct C {}; C<int> c;",
1999 templateSpecializationType(templateArgumentCountIs(2))));
2000}
2001
2002TEST(IsIntegral, Matches) {
2003 EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
2004 classTemplateSpecializationDecl(
2005 hasAnyTemplateArgument(isIntegral()))));
2006 EXPECT_TRUE(notMatches("template<typename T> struct C {}; C<int> c;",
2007 classTemplateSpecializationDecl(hasAnyTemplateArgument(
2008 templateArgument(isIntegral())))));
2009}
2010
2011TEST(RefersToIntegralType, Matches) {
2012 EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
2013 classTemplateSpecializationDecl(
2014 hasAnyTemplateArgument(refersToIntegralType(
2015 asString("int"))))));
2016 EXPECT_TRUE(notMatches("template<unsigned T> struct C {}; C<42> c;",
2017 classTemplateSpecializationDecl(hasAnyTemplateArgument(
2018 refersToIntegralType(asString("int"))))));
2019}
2020
2021TEST(EqualsIntegralValue, Matches) {
2022 EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
2023 classTemplateSpecializationDecl(
2024 hasAnyTemplateArgument(equalsIntegralValue("42")))));
2025 EXPECT_TRUE(matches("template<int T> struct C {}; C<-42> c;",
2026 classTemplateSpecializationDecl(
2027 hasAnyTemplateArgument(equalsIntegralValue("-42")))));
2028 EXPECT_TRUE(matches("template<int T> struct C {}; C<-0042> c;",
2029 classTemplateSpecializationDecl(
2030 hasAnyTemplateArgument(equalsIntegralValue("-34")))));
2031 EXPECT_TRUE(notMatches("template<int T> struct C {}; C<42> c;",
2032 classTemplateSpecializationDecl(hasAnyTemplateArgument(
2033 equalsIntegralValue("0042")))));
2034}
2035
Daniel Jasper639522c2013-02-25 12:02:08 +00002036TEST(Matcher, MatchesAccessSpecDecls) {
2037 EXPECT_TRUE(matches("class C { public: int i; };", accessSpecDecl()));
2038 EXPECT_TRUE(
2039 matches("class C { public: int i; };", accessSpecDecl(isPublic())));
2040 EXPECT_TRUE(
2041 notMatches("class C { public: int i; };", accessSpecDecl(isProtected())));
2042 EXPECT_TRUE(
2043 notMatches("class C { public: int i; };", accessSpecDecl(isPrivate())));
2044
2045 EXPECT_TRUE(notMatches("class C { int i; };", accessSpecDecl()));
2046}
2047
Aaron Ballman41143bb2015-07-24 12:35:41 +00002048TEST(Matcher, MatchesFinal) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002049 EXPECT_TRUE(matches("class X final {};", cxxRecordDecl(isFinal())));
Aaron Ballman41143bb2015-07-24 12:35:41 +00002050 EXPECT_TRUE(matches("class X { virtual void f() final; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002051 cxxMethodDecl(isFinal())));
2052 EXPECT_TRUE(notMatches("class X {};", cxxRecordDecl(isFinal())));
2053 EXPECT_TRUE(
2054 notMatches("class X { virtual void f(); };", cxxMethodDecl(isFinal())));
Aaron Ballman41143bb2015-07-24 12:35:41 +00002055}
2056
Edwin Vane37ee1d72013-04-09 20:46:36 +00002057TEST(Matcher, MatchesVirtualMethod) {
2058 EXPECT_TRUE(matches("class X { virtual int f(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002059 cxxMethodDecl(isVirtual(), hasName("::X::f"))));
2060 EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isVirtual())));
Edwin Vane37ee1d72013-04-09 20:46:36 +00002061}
2062
Nico Webera415a1d2016-01-21 17:56:24 +00002063TEST(Matcher, MatchesVirtualAsWrittenMethod) {
2064 EXPECT_TRUE(matches("class A { virtual int f(); };"
2065 "class B : public A { int f(); };",
2066 cxxMethodDecl(isVirtualAsWritten(), hasName("::A::f"))));
2067 EXPECT_TRUE(
2068 notMatches("class A { virtual int f(); };"
2069 "class B : public A { int f(); };",
2070 cxxMethodDecl(isVirtualAsWritten(), hasName("::B::f"))));
2071}
2072
Dmitri Gribenko51c1b552014-02-24 09:27:46 +00002073TEST(Matcher, MatchesPureMethod) {
2074 EXPECT_TRUE(matches("class X { virtual int f() = 0; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002075 cxxMethodDecl(isPure(), hasName("::X::f"))));
2076 EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isPure())));
Dmitri Gribenko51c1b552014-02-24 09:27:46 +00002077}
2078
Angel Garcia Gomez4647ed72015-10-30 09:35:51 +00002079TEST(Matcher, MatchesCopyAssignmentOperator) {
2080 EXPECT_TRUE(matches("class X { X &operator=(X); };",
2081 cxxMethodDecl(isCopyAssignmentOperator())));
2082 EXPECT_TRUE(matches("class X { X &operator=(X &); };",
2083 cxxMethodDecl(isCopyAssignmentOperator())));
2084 EXPECT_TRUE(matches("class X { X &operator=(const X &); };",
2085 cxxMethodDecl(isCopyAssignmentOperator())));
2086 EXPECT_TRUE(matches("class X { X &operator=(volatile X &); };",
2087 cxxMethodDecl(isCopyAssignmentOperator())));
2088 EXPECT_TRUE(matches("class X { X &operator=(const volatile X &); };",
2089 cxxMethodDecl(isCopyAssignmentOperator())));
2090 EXPECT_TRUE(notMatches("class X { X &operator=(X &&); };",
2091 cxxMethodDecl(isCopyAssignmentOperator())));
2092}
2093
Aaron Ballman31bde872016-01-22 22:37:09 +00002094TEST(Matcher, MatchesMoveAssignmentOperator) {
2095 EXPECT_TRUE(notMatches("class X { X &operator=(X); };",
2096 cxxMethodDecl(isMoveAssignmentOperator())));
2097 EXPECT_TRUE(matches("class X { X &operator=(X &&); };",
2098 cxxMethodDecl(isMoveAssignmentOperator())));
2099 EXPECT_TRUE(matches("class X { X &operator=(const X &&); };",
2100 cxxMethodDecl(isMoveAssignmentOperator())));
2101 EXPECT_TRUE(matches("class X { X &operator=(volatile X &&); };",
2102 cxxMethodDecl(isMoveAssignmentOperator())));
2103 EXPECT_TRUE(matches("class X { X &operator=(const volatile X &&); };",
2104 cxxMethodDecl(isMoveAssignmentOperator())));
2105 EXPECT_TRUE(notMatches("class X { X &operator=(X &); };",
2106 cxxMethodDecl(isMoveAssignmentOperator())));
2107}
2108
Edwin Vanefc4f7dc2013-05-09 17:00:17 +00002109TEST(Matcher, MatchesConstMethod) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002110 EXPECT_TRUE(
2111 matches("struct A { void foo() const; };", cxxMethodDecl(isConst())));
2112 EXPECT_TRUE(
2113 notMatches("struct A { void foo(); };", cxxMethodDecl(isConst())));
Edwin Vanefc4f7dc2013-05-09 17:00:17 +00002114}
2115
Edwin Vane37ee1d72013-04-09 20:46:36 +00002116TEST(Matcher, MatchesOverridingMethod) {
2117 EXPECT_TRUE(matches("class X { virtual int f(); }; "
2118 "class Y : public X { int f(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002119 cxxMethodDecl(isOverride(), hasName("::Y::f"))));
Edwin Vane37ee1d72013-04-09 20:46:36 +00002120 EXPECT_TRUE(notMatches("class X { virtual int f(); }; "
Aaron Ballman512fb642015-09-17 13:30:52 +00002121 "class Y : public X { int f(); };",
2122 cxxMethodDecl(isOverride(), hasName("::X::f"))));
Edwin Vane37ee1d72013-04-09 20:46:36 +00002123 EXPECT_TRUE(notMatches("class X { int f(); }; "
2124 "class Y : public X { int f(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002125 cxxMethodDecl(isOverride())));
Edwin Vane37ee1d72013-04-09 20:46:36 +00002126 EXPECT_TRUE(notMatches("class X { int f(); int f(int); }; ",
Aaron Ballman512fb642015-09-17 13:30:52 +00002127 cxxMethodDecl(isOverride())));
Samuel Benzaquenbb5093f2015-03-06 16:24:47 +00002128 EXPECT_TRUE(
2129 matches("template <typename Base> struct Y : Base { void f() override;};",
Aaron Ballman512fb642015-09-17 13:30:52 +00002130 cxxMethodDecl(isOverride(), hasName("::Y::f"))));
Edwin Vane37ee1d72013-04-09 20:46:36 +00002131}
2132
Manuel Klimek04616e42012-07-06 05:48:52 +00002133TEST(Matcher, ConstructorCall) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002134 StatementMatcher Constructor = cxxConstructExpr();
Manuel Klimek04616e42012-07-06 05:48:52 +00002135
2136 EXPECT_TRUE(
2137 matches("class X { public: X(); }; void x() { X x; }", Constructor));
2138 EXPECT_TRUE(
2139 matches("class X { public: X(); }; void x() { X x = X(); }",
2140 Constructor));
2141 EXPECT_TRUE(
2142 matches("class X { public: X(int); }; void x() { X x = 0; }",
2143 Constructor));
2144 EXPECT_TRUE(matches("class X {}; void x(int) { X x; }", Constructor));
2145}
2146
2147TEST(Matcher, ConstructorArgument) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002148 StatementMatcher Constructor = cxxConstructExpr(
Daniel Jasper848cbe12012-09-18 13:09:13 +00002149 hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002150
2151 EXPECT_TRUE(
2152 matches("class X { public: X(int); }; void x() { int y; X x(y); }",
2153 Constructor));
2154 EXPECT_TRUE(
2155 matches("class X { public: X(int); }; void x() { int y; X x = X(y); }",
2156 Constructor));
2157 EXPECT_TRUE(
2158 matches("class X { public: X(int); }; void x() { int y; X x = y; }",
2159 Constructor));
2160 EXPECT_TRUE(
2161 notMatches("class X { public: X(int); }; void x() { int z; X x(z); }",
2162 Constructor));
2163
Aaron Ballman512fb642015-09-17 13:30:52 +00002164 StatementMatcher WrongIndex = cxxConstructExpr(
Daniel Jasper848cbe12012-09-18 13:09:13 +00002165 hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002166 EXPECT_TRUE(
2167 notMatches("class X { public: X(int); }; void x() { int y; X x(y); }",
2168 WrongIndex));
2169}
2170
2171TEST(Matcher, ConstructorArgumentCount) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002172 StatementMatcher Constructor1Arg = cxxConstructExpr(argumentCountIs(1));
Manuel Klimek04616e42012-07-06 05:48:52 +00002173
2174 EXPECT_TRUE(
2175 matches("class X { public: X(int); }; void x() { X x(0); }",
2176 Constructor1Arg));
2177 EXPECT_TRUE(
2178 matches("class X { public: X(int); }; void x() { X x = X(0); }",
2179 Constructor1Arg));
2180 EXPECT_TRUE(
2181 matches("class X { public: X(int); }; void x() { X x = 0; }",
2182 Constructor1Arg));
2183 EXPECT_TRUE(
2184 notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }",
2185 Constructor1Arg));
2186}
2187
Peter Collingbourne1fec3df2014-02-06 21:52:24 +00002188TEST(Matcher, ConstructorListInitialization) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002189 StatementMatcher ConstructorListInit =
2190 cxxConstructExpr(isListInitialization());
Peter Collingbourne1fec3df2014-02-06 21:52:24 +00002191
2192 EXPECT_TRUE(
2193 matches("class X { public: X(int); }; void x() { X x{0}; }",
2194 ConstructorListInit));
2195 EXPECT_FALSE(
2196 matches("class X { public: X(int); }; void x() { X x(0); }",
2197 ConstructorListInit));
2198}
2199
Manuel Klimek7fca93b2012-10-23 10:40:50 +00002200TEST(Matcher,ThisExpr) {
2201 EXPECT_TRUE(
Aaron Ballman512fb642015-09-17 13:30:52 +00002202 matches("struct X { int a; int f () { return a; } };", cxxThisExpr()));
Manuel Klimek7fca93b2012-10-23 10:40:50 +00002203 EXPECT_TRUE(
Aaron Ballman512fb642015-09-17 13:30:52 +00002204 notMatches("struct X { int f () { int a; return a; } };", cxxThisExpr()));
Manuel Klimek7fca93b2012-10-23 10:40:50 +00002205}
2206
Manuel Klimek04616e42012-07-06 05:48:52 +00002207TEST(Matcher, BindTemporaryExpression) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002208 StatementMatcher TempExpression = cxxBindTemporaryExpr();
Manuel Klimek04616e42012-07-06 05:48:52 +00002209
2210 std::string ClassString = "class string { public: string(); ~string(); }; ";
2211
2212 EXPECT_TRUE(
2213 matches(ClassString +
2214 "string GetStringByValue();"
2215 "void FunctionTakesString(string s);"
2216 "void run() { FunctionTakesString(GetStringByValue()); }",
2217 TempExpression));
2218
2219 EXPECT_TRUE(
2220 notMatches(ClassString +
2221 "string* GetStringPointer(); "
2222 "void FunctionTakesStringPtr(string* s);"
2223 "void run() {"
2224 " string* s = GetStringPointer();"
2225 " FunctionTakesStringPtr(GetStringPointer());"
2226 " FunctionTakesStringPtr(s);"
2227 "}",
2228 TempExpression));
2229
2230 EXPECT_TRUE(
2231 notMatches("class no_dtor {};"
2232 "no_dtor GetObjByValue();"
2233 "void ConsumeObj(no_dtor param);"
2234 "void run() { ConsumeObj(GetObjByValue()); }",
2235 TempExpression));
2236}
2237
Sam Panzer68a35af2012-08-24 22:04:44 +00002238TEST(MaterializeTemporaryExpr, MatchesTemporary) {
2239 std::string ClassString =
2240 "class string { public: string(); int length(); }; ";
2241
2242 EXPECT_TRUE(
2243 matches(ClassString +
2244 "string GetStringByValue();"
2245 "void FunctionTakesString(string s);"
2246 "void run() { FunctionTakesString(GetStringByValue()); }",
2247 materializeTemporaryExpr()));
2248
2249 EXPECT_TRUE(
2250 notMatches(ClassString +
2251 "string* GetStringPointer(); "
2252 "void FunctionTakesStringPtr(string* s);"
2253 "void run() {"
2254 " string* s = GetStringPointer();"
2255 " FunctionTakesStringPtr(GetStringPointer());"
2256 " FunctionTakesStringPtr(s);"
2257 "}",
2258 materializeTemporaryExpr()));
2259
2260 EXPECT_TRUE(
2261 notMatches(ClassString +
2262 "string GetStringByValue();"
2263 "void run() { int k = GetStringByValue().length(); }",
2264 materializeTemporaryExpr()));
2265
2266 EXPECT_TRUE(
2267 notMatches(ClassString +
2268 "string GetStringByValue();"
2269 "void run() { GetStringByValue(); }",
2270 materializeTemporaryExpr()));
2271}
2272
Manuel Klimek04616e42012-07-06 05:48:52 +00002273TEST(ConstructorDeclaration, SimpleCase) {
2274 EXPECT_TRUE(matches("class Foo { Foo(int i); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002275 cxxConstructorDecl(ofClass(hasName("Foo")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002276 EXPECT_TRUE(notMatches("class Foo { Foo(int i); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002277 cxxConstructorDecl(ofClass(hasName("Bar")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002278}
2279
2280TEST(ConstructorDeclaration, IsImplicit) {
2281 // This one doesn't match because the constructor is not added by the
2282 // compiler (it is not needed).
2283 EXPECT_TRUE(notMatches("class Foo { };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002284 cxxConstructorDecl(isImplicit())));
Manuel Klimek04616e42012-07-06 05:48:52 +00002285 // The compiler added the implicit default constructor.
2286 EXPECT_TRUE(matches("class Foo { }; Foo* f = new Foo();",
Aaron Ballman512fb642015-09-17 13:30:52 +00002287 cxxConstructorDecl(isImplicit())));
Manuel Klimek04616e42012-07-06 05:48:52 +00002288 EXPECT_TRUE(matches("class Foo { Foo(){} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002289 cxxConstructorDecl(unless(isImplicit()))));
Joey Gouly0d9a2b22014-05-16 19:31:08 +00002290 // The compiler added an implicit assignment operator.
2291 EXPECT_TRUE(matches("struct A { int x; } a = {0}, b = a; void f() { a = b; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00002292 cxxMethodDecl(isImplicit(), hasName("operator="))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002293}
2294
Aaron Ballman6f6d0b62015-08-11 21:09:52 +00002295TEST(ConstructorDeclaration, IsExplicit) {
2296 EXPECT_TRUE(matches("struct S { explicit S(int); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002297 cxxConstructorDecl(isExplicit())));
Aaron Ballman6f6d0b62015-08-11 21:09:52 +00002298 EXPECT_TRUE(notMatches("struct S { S(int); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002299 cxxConstructorDecl(isExplicit())));
Aaron Ballman6f6d0b62015-08-11 21:09:52 +00002300}
2301
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002302TEST(ConstructorDeclaration, Kinds) {
2303 EXPECT_TRUE(matches("struct S { S(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002304 cxxConstructorDecl(isDefaultConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002305 EXPECT_TRUE(notMatches("struct S { S(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002306 cxxConstructorDecl(isCopyConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002307 EXPECT_TRUE(notMatches("struct S { S(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002308 cxxConstructorDecl(isMoveConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002309
2310 EXPECT_TRUE(notMatches("struct S { S(const S&); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002311 cxxConstructorDecl(isDefaultConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002312 EXPECT_TRUE(matches("struct S { S(const S&); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002313 cxxConstructorDecl(isCopyConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002314 EXPECT_TRUE(notMatches("struct S { S(const S&); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002315 cxxConstructorDecl(isMoveConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002316
2317 EXPECT_TRUE(notMatches("struct S { S(S&&); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002318 cxxConstructorDecl(isDefaultConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002319 EXPECT_TRUE(notMatches("struct S { S(S&&); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002320 cxxConstructorDecl(isCopyConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002321 EXPECT_TRUE(matches("struct S { S(S&&); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002322 cxxConstructorDecl(isMoveConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002323}
2324
Daniel Jasper1dad1832012-07-10 20:20:19 +00002325TEST(DestructorDeclaration, MatchesVirtualDestructor) {
2326 EXPECT_TRUE(matches("class Foo { virtual ~Foo(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002327 cxxDestructorDecl(ofClass(hasName("Foo")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00002328}
2329
2330TEST(DestructorDeclaration, DoesNotMatchImplicitDestructor) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002331 EXPECT_TRUE(notMatches("class Foo {};",
Aaron Ballman512fb642015-09-17 13:30:52 +00002332 cxxDestructorDecl(ofClass(hasName("Foo")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00002333}
2334
Manuel Klimek04616e42012-07-06 05:48:52 +00002335TEST(HasAnyConstructorInitializer, SimpleCase) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002336 EXPECT_TRUE(
2337 notMatches("class Foo { Foo() { } };",
2338 cxxConstructorDecl(hasAnyConstructorInitializer(anything()))));
2339 EXPECT_TRUE(
2340 matches("class Foo {"
2341 " Foo() : foo_() { }"
2342 " int foo_;"
2343 "};",
2344 cxxConstructorDecl(hasAnyConstructorInitializer(anything()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002345}
2346
2347TEST(HasAnyConstructorInitializer, ForField) {
2348 static const char Code[] =
2349 "class Baz { };"
2350 "class Foo {"
2351 " Foo() : foo_() { }"
2352 " Baz foo_;"
2353 " Baz bar_;"
2354 "};";
Aaron Ballman512fb642015-09-17 13:30:52 +00002355 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002356 forField(hasType(recordDecl(hasName("Baz"))))))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002357 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00002358 forField(hasName("foo_"))))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002359 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002360 forField(hasType(recordDecl(hasName("Bar"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002361}
2362
2363TEST(HasAnyConstructorInitializer, WithInitializer) {
2364 static const char Code[] =
2365 "class Foo {"
2366 " Foo() : foo_(0) { }"
2367 " int foo_;"
2368 "};";
Aaron Ballman512fb642015-09-17 13:30:52 +00002369 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00002370 withInitializer(integerLiteral(equals(0)))))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002371 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00002372 withInitializer(integerLiteral(equals(1)))))));
2373}
2374
2375TEST(HasAnyConstructorInitializer, IsWritten) {
2376 static const char Code[] =
2377 "struct Bar { Bar(){} };"
2378 "class Foo {"
2379 " Foo() : foo_() { }"
2380 " Bar foo_;"
2381 " Bar bar_;"
2382 "};";
Aaron Ballman512fb642015-09-17 13:30:52 +00002383 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00002384 allOf(forField(hasName("foo_")), isWritten())))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002385 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00002386 allOf(forField(hasName("bar_")), isWritten())))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002387 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00002388 allOf(forField(hasName("bar_")), unless(isWritten()))))));
2389}
2390
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002391TEST(HasAnyConstructorInitializer, IsBaseInitializer) {
2392 static const char Code[] =
2393 "struct B {};"
2394 "struct D : B {"
2395 " int I;"
2396 " D(int i) : I(i) {}"
2397 "};"
2398 "struct E : B {"
2399 " E() : B() {}"
2400 "};";
Aaron Ballman512fb642015-09-17 13:30:52 +00002401 EXPECT_TRUE(matches(Code, cxxConstructorDecl(allOf(
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002402 hasAnyConstructorInitializer(allOf(isBaseInitializer(), isWritten())),
2403 hasName("E")))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002404 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(allOf(
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002405 hasAnyConstructorInitializer(allOf(isBaseInitializer(), isWritten())),
2406 hasName("D")))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002407 EXPECT_TRUE(matches(Code, cxxConstructorDecl(allOf(
Aaron Ballmaned455d42015-08-11 20:42:00 +00002408 hasAnyConstructorInitializer(allOf(isMemberInitializer(), isWritten())),
2409 hasName("D")))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002410 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(allOf(
Aaron Ballmaned455d42015-08-11 20:42:00 +00002411 hasAnyConstructorInitializer(allOf(isMemberInitializer(), isWritten())),
2412 hasName("E")))));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002413}
2414
Manuel Klimek04616e42012-07-06 05:48:52 +00002415TEST(Matcher, NewExpression) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002416 StatementMatcher New = cxxNewExpr();
Manuel Klimek04616e42012-07-06 05:48:52 +00002417
2418 EXPECT_TRUE(matches("class X { public: X(); }; void x() { new X; }", New));
2419 EXPECT_TRUE(
2420 matches("class X { public: X(); }; void x() { new X(); }", New));
2421 EXPECT_TRUE(
2422 matches("class X { public: X(int); }; void x() { new X(0); }", New));
2423 EXPECT_TRUE(matches("class X {}; void x(int) { new X; }", New));
2424}
2425
2426TEST(Matcher, NewExpressionArgument) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002427 StatementMatcher New = cxxConstructExpr(
Daniel Jasper848cbe12012-09-18 13:09:13 +00002428 hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002429
2430 EXPECT_TRUE(
2431 matches("class X { public: X(int); }; void x() { int y; new X(y); }",
2432 New));
2433 EXPECT_TRUE(
2434 matches("class X { public: X(int); }; void x() { int y; new X(y); }",
2435 New));
2436 EXPECT_TRUE(
2437 notMatches("class X { public: X(int); }; void x() { int z; new X(z); }",
2438 New));
2439
Aaron Ballman512fb642015-09-17 13:30:52 +00002440 StatementMatcher WrongIndex = cxxConstructExpr(
Daniel Jasper848cbe12012-09-18 13:09:13 +00002441 hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002442 EXPECT_TRUE(
2443 notMatches("class X { public: X(int); }; void x() { int y; new X(y); }",
2444 WrongIndex));
2445}
2446
2447TEST(Matcher, NewExpressionArgumentCount) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002448 StatementMatcher New = cxxConstructExpr(argumentCountIs(1));
Manuel Klimek04616e42012-07-06 05:48:52 +00002449
2450 EXPECT_TRUE(
2451 matches("class X { public: X(int); }; void x() { new X(0); }", New));
2452 EXPECT_TRUE(
2453 notMatches("class X { public: X(int, int); }; void x() { new X(0, 0); }",
2454 New));
2455}
2456
Daniel Jasper1dad1832012-07-10 20:20:19 +00002457TEST(Matcher, DeleteExpression) {
2458 EXPECT_TRUE(matches("struct A {}; void f(A* a) { delete a; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00002459 cxxDeleteExpr()));
Daniel Jasper1dad1832012-07-10 20:20:19 +00002460}
2461
Manuel Klimek04616e42012-07-06 05:48:52 +00002462TEST(Matcher, DefaultArgument) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002463 StatementMatcher Arg = cxxDefaultArgExpr();
Manuel Klimek04616e42012-07-06 05:48:52 +00002464
2465 EXPECT_TRUE(matches("void x(int, int = 0) { int y; x(y); }", Arg));
2466 EXPECT_TRUE(
2467 matches("class X { void x(int, int = 0) { int y; x(y); } };", Arg));
2468 EXPECT_TRUE(notMatches("void x(int, int = 0) { int y; x(y, 0); }", Arg));
2469}
2470
2471TEST(Matcher, StringLiterals) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00002472 StatementMatcher Literal = stringLiteral();
Manuel Klimek04616e42012-07-06 05:48:52 +00002473 EXPECT_TRUE(matches("const char *s = \"string\";", Literal));
2474 // wide string
2475 EXPECT_TRUE(matches("const wchar_t *s = L\"string\";", Literal));
2476 // with escaped characters
2477 EXPECT_TRUE(matches("const char *s = \"\x05five\";", Literal));
2478 // no matching -- though the data type is the same, there is no string literal
2479 EXPECT_TRUE(notMatches("const char s[1] = {'a'};", Literal));
2480}
2481
2482TEST(Matcher, CharacterLiterals) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00002483 StatementMatcher CharLiteral = characterLiteral();
Manuel Klimek04616e42012-07-06 05:48:52 +00002484 EXPECT_TRUE(matches("const char c = 'c';", CharLiteral));
2485 // wide character
2486 EXPECT_TRUE(matches("const char c = L'c';", CharLiteral));
2487 // wide character, Hex encoded, NOT MATCHED!
2488 EXPECT_TRUE(notMatches("const wchar_t c = 0x2126;", CharLiteral));
2489 EXPECT_TRUE(notMatches("const char c = 0x1;", CharLiteral));
2490}
2491
2492TEST(Matcher, IntegerLiterals) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00002493 StatementMatcher HasIntLiteral = integerLiteral();
Manuel Klimek04616e42012-07-06 05:48:52 +00002494 EXPECT_TRUE(matches("int i = 10;", HasIntLiteral));
2495 EXPECT_TRUE(matches("int i = 0x1AB;", HasIntLiteral));
2496 EXPECT_TRUE(matches("int i = 10L;", HasIntLiteral));
2497 EXPECT_TRUE(matches("int i = 10U;", HasIntLiteral));
2498
2499 // Non-matching cases (character literals, float and double)
2500 EXPECT_TRUE(notMatches("int i = L'a';",
2501 HasIntLiteral)); // this is actually a character
2502 // literal cast to int
2503 EXPECT_TRUE(notMatches("int i = 'a';", HasIntLiteral));
2504 EXPECT_TRUE(notMatches("int i = 1e10;", HasIntLiteral));
2505 EXPECT_TRUE(notMatches("int i = 10.0;", HasIntLiteral));
2506}
2507
Daniel Jasper91f1c8c2013-07-26 18:52:58 +00002508TEST(Matcher, FloatLiterals) {
2509 StatementMatcher HasFloatLiteral = floatLiteral();
2510 EXPECT_TRUE(matches("float i = 10.0;", HasFloatLiteral));
2511 EXPECT_TRUE(matches("float i = 10.0f;", HasFloatLiteral));
2512 EXPECT_TRUE(matches("double i = 10.0;", HasFloatLiteral));
2513 EXPECT_TRUE(matches("double i = 10.0L;", HasFloatLiteral));
2514 EXPECT_TRUE(matches("double i = 1e10;", HasFloatLiteral));
Daniel Jasperd1423812015-02-03 09:45:52 +00002515 EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0))));
2516 EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0f))));
2517 EXPECT_TRUE(
2518 matches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(5.0)))));
Daniel Jasper91f1c8c2013-07-26 18:52:58 +00002519
2520 EXPECT_TRUE(notMatches("float i = 10;", HasFloatLiteral));
Daniel Jasperd1423812015-02-03 09:45:52 +00002521 EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0))));
2522 EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0f))));
2523 EXPECT_TRUE(
2524 notMatches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(6.0)))));
Daniel Jasper91f1c8c2013-07-26 18:52:58 +00002525}
2526
Daniel Jasper5901e472012-10-01 13:40:41 +00002527TEST(Matcher, NullPtrLiteral) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002528 EXPECT_TRUE(matches("int* i = nullptr;", cxxNullPtrLiteralExpr()));
Daniel Jasper5901e472012-10-01 13:40:41 +00002529}
2530
Szabolcs Sipos1d068bb2015-05-07 14:24:22 +00002531TEST(Matcher, GNUNullExpr) {
2532 EXPECT_TRUE(matches("int* i = __null;", gnuNullExpr()));
2533}
2534
Aaron Ballmana35b8fc2016-03-09 17:11:51 +00002535TEST(Matcher, AtomicExpr) {
2536 EXPECT_TRUE(matches("void foo() { int *ptr; __atomic_load_n(ptr, 1); }",
2537 atomicExpr()));
2538}
2539
2540TEST(Matcher, Initializers) {
2541 const char *ToMatch = "void foo() { struct point { double x; double y; };"
2542 " struct point ptarray[10] = "
2543 " { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 }; }";
2544 EXPECT_TRUE(matchesConditionally(
2545 ToMatch,
2546 initListExpr(
2547 has(
2548 cxxConstructExpr(
2549 requiresZeroInitialization())),
2550 has(
2551 initListExpr(
2552 hasType(asString("struct point")),
2553 has(floatLiteral(equals(1.0))),
2554 has(implicitValueInitExpr(
2555 hasType(asString("double")))))),
2556 has(
2557 initListExpr(
2558 hasType(asString("struct point")),
2559 has(floatLiteral(equals(2.0))),
2560 has(floatLiteral(equals(1.0)))))
2561 ), true, "-std=gnu++98"));
2562
2563 EXPECT_TRUE(matchesC99(ToMatch,
2564 initListExpr(
2565 hasSyntacticForm(
2566 initListExpr(
2567 has(
2568 designatedInitExpr(
2569 designatorCountIs(2),
2570 has(floatLiteral(
2571 equals(1.0))),
2572 has(integerLiteral(
2573 equals(2))))),
2574 has(
2575 designatedInitExpr(
2576 designatorCountIs(2),
2577 has(floatLiteral(
2578 equals(2.0))),
2579 has(integerLiteral(
2580 equals(2))))),
2581 has(
2582 designatedInitExpr(
2583 designatorCountIs(2),
2584 has(floatLiteral(
2585 equals(1.0))),
2586 has(integerLiteral(
2587 equals(0)))))
2588 )))));
2589}
2590
2591TEST(Matcher, ParenListExpr) {
2592 EXPECT_TRUE(
Aaron Ballman2648d422016-03-09 18:07:17 +00002593 matches("template<typename T> class foo { void bar() { foo X(*this); } };"
2594 "template class foo<int>;",
2595 varDecl(hasInitializer(parenListExpr(has(unaryOperator()))))));
Aaron Ballmana35b8fc2016-03-09 17:11:51 +00002596}
2597
2598TEST(Matcher, StmtExpr) {
2599 EXPECT_TRUE(matches("void declToImport() { int C = ({int X=4; X;}); }",
2600 varDecl(hasInitializer(stmtExpr()))));
2601}
2602
2603TEST(Matcher, ImportPredefinedExpr) {
2604 // __func__ expands as StringLiteral("foo")
2605 EXPECT_TRUE(matches("void foo() { __func__; }",
2606 predefinedExpr(
2607 hasType(asString("const char [4]")),
2608 has(stringLiteral()))));
2609}
2610
Daniel Jasper87c3d362012-09-20 14:12:57 +00002611TEST(Matcher, AsmStatement) {
2612 EXPECT_TRUE(matches("void foo() { __asm(\"mov al, 2\"); }", asmStmt()));
2613}
2614
Manuel Klimek04616e42012-07-06 05:48:52 +00002615TEST(Matcher, Conditions) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002616 StatementMatcher Condition =
2617 ifStmt(hasCondition(cxxBoolLiteral(equals(true))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002618
2619 EXPECT_TRUE(matches("void x() { if (true) {} }", Condition));
2620 EXPECT_TRUE(notMatches("void x() { if (false) {} }", Condition));
2621 EXPECT_TRUE(notMatches("void x() { bool a = true; if (a) {} }", Condition));
2622 EXPECT_TRUE(notMatches("void x() { if (true || false) {} }", Condition));
2623 EXPECT_TRUE(notMatches("void x() { if (1) {} }", Condition));
2624}
2625
Manuel Klimek909b5c942014-05-27 10:04:12 +00002626TEST(IfStmt, ChildTraversalMatchers) {
2627 EXPECT_TRUE(matches("void f() { if (false) true; else false; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00002628 ifStmt(hasThen(cxxBoolLiteral(equals(true))))));
Manuel Klimek909b5c942014-05-27 10:04:12 +00002629 EXPECT_TRUE(notMatches("void f() { if (false) false; else true; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00002630 ifStmt(hasThen(cxxBoolLiteral(equals(true))))));
Manuel Klimek909b5c942014-05-27 10:04:12 +00002631 EXPECT_TRUE(matches("void f() { if (false) false; else true; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00002632 ifStmt(hasElse(cxxBoolLiteral(equals(true))))));
Manuel Klimek909b5c942014-05-27 10:04:12 +00002633 EXPECT_TRUE(notMatches("void f() { if (false) true; else false; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00002634 ifStmt(hasElse(cxxBoolLiteral(equals(true))))));
Manuel Klimek909b5c942014-05-27 10:04:12 +00002635}
2636
Manuel Klimek04616e42012-07-06 05:48:52 +00002637TEST(MatchBinaryOperator, HasOperatorName) {
2638 StatementMatcher OperatorOr = binaryOperator(hasOperatorName("||"));
2639
2640 EXPECT_TRUE(matches("void x() { true || false; }", OperatorOr));
2641 EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
2642}
2643
2644TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
2645 StatementMatcher OperatorTrueFalse =
Aaron Ballman512fb642015-09-17 13:30:52 +00002646 binaryOperator(hasLHS(cxxBoolLiteral(equals(true))),
2647 hasRHS(cxxBoolLiteral(equals(false))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002648
2649 EXPECT_TRUE(matches("void x() { true || false; }", OperatorTrueFalse));
2650 EXPECT_TRUE(matches("void x() { true && false; }", OperatorTrueFalse));
2651 EXPECT_TRUE(notMatches("void x() { false || true; }", OperatorTrueFalse));
Alexander Kornienkoe39993e2015-11-02 22:23:21 +00002652
2653 StatementMatcher OperatorIntPointer = arraySubscriptExpr(
2654 hasLHS(hasType(isInteger())), hasRHS(hasType(pointsTo(qualType()))));
2655 EXPECT_TRUE(matches("void x() { 1[\"abc\"]; }", OperatorIntPointer));
2656 EXPECT_TRUE(notMatches("void x() { \"abc\"[1]; }", OperatorIntPointer));
Manuel Klimek04616e42012-07-06 05:48:52 +00002657}
2658
2659TEST(MatchBinaryOperator, HasEitherOperand) {
2660 StatementMatcher HasOperand =
Aaron Ballman512fb642015-09-17 13:30:52 +00002661 binaryOperator(hasEitherOperand(cxxBoolLiteral(equals(false))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002662
2663 EXPECT_TRUE(matches("void x() { true || false; }", HasOperand));
2664 EXPECT_TRUE(matches("void x() { false && true; }", HasOperand));
2665 EXPECT_TRUE(notMatches("void x() { true || true; }", HasOperand));
2666}
2667
2668TEST(Matcher, BinaryOperatorTypes) {
2669 // Integration test that verifies the AST provides all binary operators in
2670 // a way we expect.
2671 // FIXME: Operator ','
2672 EXPECT_TRUE(
2673 matches("void x() { 3, 4; }", binaryOperator(hasOperatorName(","))));
2674 EXPECT_TRUE(
2675 matches("bool b; bool c = (b = true);",
2676 binaryOperator(hasOperatorName("="))));
2677 EXPECT_TRUE(
2678 matches("bool b = 1 != 2;", binaryOperator(hasOperatorName("!="))));
2679 EXPECT_TRUE(
2680 matches("bool b = 1 == 2;", binaryOperator(hasOperatorName("=="))));
2681 EXPECT_TRUE(matches("bool b = 1 < 2;", binaryOperator(hasOperatorName("<"))));
2682 EXPECT_TRUE(
2683 matches("bool b = 1 <= 2;", binaryOperator(hasOperatorName("<="))));
2684 EXPECT_TRUE(
2685 matches("int i = 1 << 2;", binaryOperator(hasOperatorName("<<"))));
2686 EXPECT_TRUE(
2687 matches("int i = 1; int j = (i <<= 2);",
2688 binaryOperator(hasOperatorName("<<="))));
2689 EXPECT_TRUE(matches("bool b = 1 > 2;", binaryOperator(hasOperatorName(">"))));
2690 EXPECT_TRUE(
2691 matches("bool b = 1 >= 2;", binaryOperator(hasOperatorName(">="))));
2692 EXPECT_TRUE(
2693 matches("int i = 1 >> 2;", binaryOperator(hasOperatorName(">>"))));
2694 EXPECT_TRUE(
2695 matches("int i = 1; int j = (i >>= 2);",
2696 binaryOperator(hasOperatorName(">>="))));
2697 EXPECT_TRUE(
2698 matches("int i = 42 ^ 23;", binaryOperator(hasOperatorName("^"))));
2699 EXPECT_TRUE(
2700 matches("int i = 42; int j = (i ^= 42);",
2701 binaryOperator(hasOperatorName("^="))));
2702 EXPECT_TRUE(
2703 matches("int i = 42 % 23;", binaryOperator(hasOperatorName("%"))));
2704 EXPECT_TRUE(
2705 matches("int i = 42; int j = (i %= 42);",
2706 binaryOperator(hasOperatorName("%="))));
2707 EXPECT_TRUE(
2708 matches("bool b = 42 &23;", binaryOperator(hasOperatorName("&"))));
2709 EXPECT_TRUE(
2710 matches("bool b = true && false;",
2711 binaryOperator(hasOperatorName("&&"))));
2712 EXPECT_TRUE(
2713 matches("bool b = true; bool c = (b &= false);",
2714 binaryOperator(hasOperatorName("&="))));
2715 EXPECT_TRUE(
2716 matches("bool b = 42 | 23;", binaryOperator(hasOperatorName("|"))));
2717 EXPECT_TRUE(
2718 matches("bool b = true || false;",
2719 binaryOperator(hasOperatorName("||"))));
2720 EXPECT_TRUE(
2721 matches("bool b = true; bool c = (b |= false);",
2722 binaryOperator(hasOperatorName("|="))));
2723 EXPECT_TRUE(
2724 matches("int i = 42 *23;", binaryOperator(hasOperatorName("*"))));
2725 EXPECT_TRUE(
2726 matches("int i = 42; int j = (i *= 23);",
2727 binaryOperator(hasOperatorName("*="))));
2728 EXPECT_TRUE(
2729 matches("int i = 42 / 23;", binaryOperator(hasOperatorName("/"))));
2730 EXPECT_TRUE(
2731 matches("int i = 42; int j = (i /= 23);",
2732 binaryOperator(hasOperatorName("/="))));
2733 EXPECT_TRUE(
2734 matches("int i = 42 + 23;", binaryOperator(hasOperatorName("+"))));
2735 EXPECT_TRUE(
2736 matches("int i = 42; int j = (i += 23);",
2737 binaryOperator(hasOperatorName("+="))));
2738 EXPECT_TRUE(
2739 matches("int i = 42 - 23;", binaryOperator(hasOperatorName("-"))));
2740 EXPECT_TRUE(
2741 matches("int i = 42; int j = (i -= 23);",
2742 binaryOperator(hasOperatorName("-="))));
2743 EXPECT_TRUE(
2744 matches("struct A { void x() { void (A::*a)(); (this->*a)(); } };",
2745 binaryOperator(hasOperatorName("->*"))));
2746 EXPECT_TRUE(
2747 matches("struct A { void x() { void (A::*a)(); ((*this).*a)(); } };",
2748 binaryOperator(hasOperatorName(".*"))));
2749
2750 // Member expressions as operators are not supported in matches.
2751 EXPECT_TRUE(
2752 notMatches("struct A { void x(A *a) { a->x(this); } };",
2753 binaryOperator(hasOperatorName("->"))));
2754
2755 // Initializer assignments are not represented as operator equals.
2756 EXPECT_TRUE(
2757 notMatches("bool b = true;", binaryOperator(hasOperatorName("="))));
2758
2759 // Array indexing is not represented as operator.
2760 EXPECT_TRUE(notMatches("int a[42]; void x() { a[23]; }", unaryOperator()));
2761
2762 // Overloaded operators do not match at all.
2763 EXPECT_TRUE(notMatches(
2764 "struct A { bool operator&&(const A &a) const { return false; } };"
2765 "void x() { A a, b; a && b; }",
2766 binaryOperator()));
2767}
2768
2769TEST(MatchUnaryOperator, HasOperatorName) {
2770 StatementMatcher OperatorNot = unaryOperator(hasOperatorName("!"));
2771
2772 EXPECT_TRUE(matches("void x() { !true; } ", OperatorNot));
2773 EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
2774}
2775
2776TEST(MatchUnaryOperator, HasUnaryOperand) {
2777 StatementMatcher OperatorOnFalse =
Aaron Ballman512fb642015-09-17 13:30:52 +00002778 unaryOperator(hasUnaryOperand(cxxBoolLiteral(equals(false))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002779
2780 EXPECT_TRUE(matches("void x() { !false; }", OperatorOnFalse));
2781 EXPECT_TRUE(notMatches("void x() { !true; }", OperatorOnFalse));
2782}
2783
2784TEST(Matcher, UnaryOperatorTypes) {
2785 // Integration test that verifies the AST provides all unary operators in
2786 // a way we expect.
2787 EXPECT_TRUE(matches("bool b = !true;", unaryOperator(hasOperatorName("!"))));
2788 EXPECT_TRUE(
2789 matches("bool b; bool *p = &b;", unaryOperator(hasOperatorName("&"))));
2790 EXPECT_TRUE(matches("int i = ~ 1;", unaryOperator(hasOperatorName("~"))));
2791 EXPECT_TRUE(
2792 matches("bool *p; bool b = *p;", unaryOperator(hasOperatorName("*"))));
2793 EXPECT_TRUE(
2794 matches("int i; int j = +i;", unaryOperator(hasOperatorName("+"))));
2795 EXPECT_TRUE(
2796 matches("int i; int j = -i;", unaryOperator(hasOperatorName("-"))));
2797 EXPECT_TRUE(
2798 matches("int i; int j = ++i;", unaryOperator(hasOperatorName("++"))));
2799 EXPECT_TRUE(
2800 matches("int i; int j = i++;", unaryOperator(hasOperatorName("++"))));
2801 EXPECT_TRUE(
2802 matches("int i; int j = --i;", unaryOperator(hasOperatorName("--"))));
2803 EXPECT_TRUE(
2804 matches("int i; int j = i--;", unaryOperator(hasOperatorName("--"))));
2805
2806 // We don't match conversion operators.
2807 EXPECT_TRUE(notMatches("int i; double d = (double)i;", unaryOperator()));
2808
2809 // Function calls are not represented as operator.
2810 EXPECT_TRUE(notMatches("void f(); void x() { f(); }", unaryOperator()));
2811
2812 // Overloaded operators do not match at all.
2813 // FIXME: We probably want to add that.
2814 EXPECT_TRUE(notMatches(
2815 "struct A { bool operator!() const { return false; } };"
2816 "void x() { A a; !a; }", unaryOperator(hasOperatorName("!"))));
2817}
2818
2819TEST(Matcher, ConditionalOperator) {
2820 StatementMatcher Conditional = conditionalOperator(
Aaron Ballman512fb642015-09-17 13:30:52 +00002821 hasCondition(cxxBoolLiteral(equals(true))),
2822 hasTrueExpression(cxxBoolLiteral(equals(false))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002823
2824 EXPECT_TRUE(matches("void x() { true ? false : true; }", Conditional));
2825 EXPECT_TRUE(notMatches("void x() { false ? false : true; }", Conditional));
2826 EXPECT_TRUE(notMatches("void x() { true ? true : false; }", Conditional));
2827
2828 StatementMatcher ConditionalFalse = conditionalOperator(
Aaron Ballman512fb642015-09-17 13:30:52 +00002829 hasFalseExpression(cxxBoolLiteral(equals(false))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002830
2831 EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse));
2832 EXPECT_TRUE(
2833 notMatches("void x() { true ? false : true; }", ConditionalFalse));
Aaron Ballmana35b8fc2016-03-09 17:11:51 +00002834
2835 EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse));
2836 EXPECT_TRUE(
2837 notMatches("void x() { true ? false : true; }", ConditionalFalse));
2838}
2839
2840TEST(Matcher, BinaryConditionalOperator) {
2841 StatementMatcher AlwaysOne = binaryConditionalOperator(
2842 hasCondition(implicitCastExpr(
2843 has(
2844 opaqueValueExpr(
2845 hasSourceExpression((integerLiteral(equals(1)))))))),
2846 hasFalseExpression(integerLiteral(equals(0))));
2847
2848 EXPECT_TRUE(matches("void x() { 1 ?: 0; }", AlwaysOne));
2849
2850 StatementMatcher FourNotFive = binaryConditionalOperator(
2851 hasTrueExpression(opaqueValueExpr(
2852 hasSourceExpression((integerLiteral(equals(4)))))),
2853 hasFalseExpression(integerLiteral(equals(5))));
2854
2855 EXPECT_TRUE(matches("void x() { 4 ?: 5; }", FourNotFive));
Manuel Klimek04616e42012-07-06 05:48:52 +00002856}
2857
Daniel Jasper1dad1832012-07-10 20:20:19 +00002858TEST(ArraySubscriptMatchers, ArraySubscripts) {
2859 EXPECT_TRUE(matches("int i[2]; void f() { i[1] = 1; }",
2860 arraySubscriptExpr()));
2861 EXPECT_TRUE(notMatches("int i; void f() { i = 1; }",
2862 arraySubscriptExpr()));
2863}
2864
2865TEST(ArraySubscriptMatchers, ArrayIndex) {
2866 EXPECT_TRUE(matches(
2867 "int i[2]; void f() { i[1] = 1; }",
2868 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
2869 EXPECT_TRUE(matches(
2870 "int i[2]; void f() { 1[i] = 1; }",
2871 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
2872 EXPECT_TRUE(notMatches(
2873 "int i[2]; void f() { i[1] = 1; }",
2874 arraySubscriptExpr(hasIndex(integerLiteral(equals(0))))));
2875}
2876
2877TEST(ArraySubscriptMatchers, MatchesArrayBase) {
2878 EXPECT_TRUE(matches(
2879 "int i[2]; void f() { i[1] = 2; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002880 arraySubscriptExpr(hasBase(implicitCastExpr(
2881 hasSourceExpression(declRefExpr()))))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00002882}
2883
Manuel Klimek04616e42012-07-06 05:48:52 +00002884TEST(Matcher, HasNameSupportsNamespaces) {
2885 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002886 recordDecl(hasName("a::b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002887 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002888 recordDecl(hasName("::a::b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002889 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002890 recordDecl(hasName("b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002891 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002892 recordDecl(hasName("C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002893 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002894 recordDecl(hasName("c::b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002895 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002896 recordDecl(hasName("a::c::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002897 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002898 recordDecl(hasName("a::b::A"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002899 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002900 recordDecl(hasName("::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002901 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002902 recordDecl(hasName("::b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002903 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002904 recordDecl(hasName("z::a::b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002905 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002906 recordDecl(hasName("a+b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002907 EXPECT_TRUE(notMatches("namespace a { namespace b { class AC; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002908 recordDecl(hasName("C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002909}
2910
2911TEST(Matcher, HasNameSupportsOuterClasses) {
2912 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002913 matches("class A { class B { class C; }; };",
2914 recordDecl(hasName("A::B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002915 EXPECT_TRUE(
2916 matches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002917 recordDecl(hasName("::A::B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002918 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002919 matches("class A { class B { class C; }; };",
2920 recordDecl(hasName("B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002921 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002922 matches("class A { class B { class C; }; };",
2923 recordDecl(hasName("C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002924 EXPECT_TRUE(
2925 notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002926 recordDecl(hasName("c::B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002927 EXPECT_TRUE(
2928 notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002929 recordDecl(hasName("A::c::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002930 EXPECT_TRUE(
2931 notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002932 recordDecl(hasName("A::B::A"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002933 EXPECT_TRUE(
2934 notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002935 recordDecl(hasName("::C"))));
2936 EXPECT_TRUE(
2937 notMatches("class A { class B { class C; }; };",
2938 recordDecl(hasName("::B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002939 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002940 recordDecl(hasName("z::A::B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002941 EXPECT_TRUE(
2942 notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002943 recordDecl(hasName("A+B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002944}
2945
Samuel Benzaquen8e566f32016-02-05 18:29:24 +00002946TEST(Matcher, HasNameSupportsInlinedNamespaces) {
2947 std::string code = "namespace a { inline namespace b { class C; } }";
2948 EXPECT_TRUE(matches(code, recordDecl(hasName("a::b::C"))));
2949 EXPECT_TRUE(matches(code, recordDecl(hasName("a::C"))));
2950 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::b::C"))));
2951 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::C"))));
2952}
2953
2954TEST(Matcher, HasNameSupportsAnonymousNamespaces) {
2955 std::string code = "namespace a { namespace { class C; } }";
2956 EXPECT_TRUE(
2957 matches(code, recordDecl(hasName("a::(anonymous namespace)::C"))));
2958 EXPECT_TRUE(matches(code, recordDecl(hasName("a::C"))));
2959 EXPECT_TRUE(
2960 matches(code, recordDecl(hasName("::a::(anonymous namespace)::C"))));
2961 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::C"))));
2962}
2963
2964TEST(Matcher, HasNameSupportsAnonymousOuterClasses) {
2965 EXPECT_TRUE(matches("class A { class { class C; } x; };",
2966 recordDecl(hasName("A::(anonymous class)::C"))));
2967 EXPECT_TRUE(matches("class A { class { class C; } x; };",
2968 recordDecl(hasName("::A::(anonymous class)::C"))));
2969 EXPECT_FALSE(matches("class A { class { class C; } x; };",
2970 recordDecl(hasName("::A::C"))));
2971 EXPECT_TRUE(matches("class A { struct { class C; } x; };",
2972 recordDecl(hasName("A::(anonymous struct)::C"))));
2973 EXPECT_TRUE(matches("class A { struct { class C; } x; };",
2974 recordDecl(hasName("::A::(anonymous struct)::C"))));
2975 EXPECT_FALSE(matches("class A { struct { class C; } x; };",
2976 recordDecl(hasName("::A::C"))));
2977}
2978
2979TEST(Matcher, HasNameSupportsFunctionScope) {
2980 std::string code =
2981 "namespace a { void F(int a) { struct S { int m; }; int i; } }";
2982 EXPECT_TRUE(matches(code, varDecl(hasName("i"))));
2983 EXPECT_FALSE(matches(code, varDecl(hasName("F()::i"))));
2984
2985 EXPECT_TRUE(matches(code, fieldDecl(hasName("m"))));
2986 EXPECT_TRUE(matches(code, fieldDecl(hasName("S::m"))));
2987 EXPECT_TRUE(matches(code, fieldDecl(hasName("F(int)::S::m"))));
2988 EXPECT_TRUE(matches(code, fieldDecl(hasName("a::F(int)::S::m"))));
2989 EXPECT_TRUE(matches(code, fieldDecl(hasName("::a::F(int)::S::m"))));
2990}
2991
Samuel Benzaquen922bef42016-02-22 21:13:02 +00002992TEST(Matcher, HasAnyName) {
2993 const std::string Code = "namespace a { namespace b { class C; } }";
2994
2995 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX", "a::b::C"))));
2996 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("a::b::C", "XX"))));
2997 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX::C", "a::b::C"))));
2998 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX", "C"))));
2999
3000 EXPECT_TRUE(notMatches(Code, recordDecl(hasAnyName("::C", "::b::C"))));
3001 EXPECT_TRUE(
3002 matches(Code, recordDecl(hasAnyName("::C", "::b::C", "::a::b::C"))));
Samuel Benzaquenc1384c12016-03-25 16:29:30 +00003003
3004 std::vector<StringRef> Names = {"::C", "::b::C", "::a::b::C"};
3005 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName(Names))));
Samuel Benzaquen922bef42016-02-22 21:13:02 +00003006}
3007
Manuel Klimek04616e42012-07-06 05:48:52 +00003008TEST(Matcher, IsDefinition) {
3009 DeclarationMatcher DefinitionOfClassA =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003010 recordDecl(hasName("A"), isDefinition());
Manuel Klimek04616e42012-07-06 05:48:52 +00003011 EXPECT_TRUE(matches("class A {};", DefinitionOfClassA));
3012 EXPECT_TRUE(notMatches("class A;", DefinitionOfClassA));
3013
3014 DeclarationMatcher DefinitionOfVariableA =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003015 varDecl(hasName("a"), isDefinition());
Manuel Klimek04616e42012-07-06 05:48:52 +00003016 EXPECT_TRUE(matches("int a;", DefinitionOfVariableA));
3017 EXPECT_TRUE(notMatches("extern int a;", DefinitionOfVariableA));
3018
3019 DeclarationMatcher DefinitionOfMethodA =
Aaron Ballman512fb642015-09-17 13:30:52 +00003020 cxxMethodDecl(hasName("a"), isDefinition());
Manuel Klimek04616e42012-07-06 05:48:52 +00003021 EXPECT_TRUE(matches("class A { void a() {} };", DefinitionOfMethodA));
3022 EXPECT_TRUE(notMatches("class A { void a(); };", DefinitionOfMethodA));
3023}
3024
3025TEST(Matcher, OfClass) {
Aaron Ballman512fb642015-09-17 13:30:52 +00003026 StatementMatcher Constructor = cxxConstructExpr(hasDeclaration(cxxMethodDecl(
Manuel Klimek04616e42012-07-06 05:48:52 +00003027 ofClass(hasName("X")))));
3028
3029 EXPECT_TRUE(
3030 matches("class X { public: X(); }; void x(int) { X x; }", Constructor));
3031 EXPECT_TRUE(
3032 matches("class X { public: X(); }; void x(int) { X x = X(); }",
3033 Constructor));
3034 EXPECT_TRUE(
3035 notMatches("class Y { public: Y(); }; void x(int) { Y y; }",
3036 Constructor));
3037}
3038
3039TEST(Matcher, VisitsTemplateInstantiations) {
3040 EXPECT_TRUE(matches(
3041 "class A { public: void x(); };"
3042 "template <typename T> class B { public: void y() { T t; t.x(); } };"
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003043 "void f() { B<A> b; b.y(); }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003044 callExpr(callee(cxxMethodDecl(hasName("x"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003045
3046 EXPECT_TRUE(matches(
3047 "class A { public: void x(); };"
3048 "class C {"
3049 " public:"
3050 " template <typename T> class B { public: void y() { T t; t.x(); } };"
3051 "};"
3052 "void f() {"
3053 " C::B<A> b; b.y();"
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003054 "}",
Aaron Ballman512fb642015-09-17 13:30:52 +00003055 recordDecl(hasName("C"), hasDescendant(callExpr(
3056 callee(cxxMethodDecl(hasName("x"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003057}
3058
Daniel Jasper1dad1832012-07-10 20:20:19 +00003059TEST(Matcher, HandlesNullQualTypes) {
3060 // FIXME: Add a Type matcher so we can replace uses of this
3061 // variable with Type(True())
3062 const TypeMatcher AnyType = anything();
3063
3064 // We don't really care whether this matcher succeeds; we're testing that
3065 // it completes without crashing.
3066 EXPECT_TRUE(matches(
3067 "struct A { };"
3068 "template <typename T>"
3069 "void f(T t) {"
3070 " T local_t(t /* this becomes a null QualType in the AST */);"
3071 "}"
3072 "void g() {"
3073 " f(0);"
3074 "}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003075 expr(hasType(TypeMatcher(
Daniel Jasper1dad1832012-07-10 20:20:19 +00003076 anyOf(
3077 TypeMatcher(hasDeclaration(anything())),
3078 pointsTo(AnyType),
3079 references(AnyType)
3080 // Other QualType matchers should go here.
3081 ))))));
3082}
3083
Manuel Klimek04616e42012-07-06 05:48:52 +00003084// For testing AST_MATCHER_P().
Daniel Jasper1dad1832012-07-10 20:20:19 +00003085AST_MATCHER_P(Decl, just, internal::Matcher<Decl>, AMatcher) {
Manuel Klimek04616e42012-07-06 05:48:52 +00003086 // Make sure all special variables are used: node, match_finder,
3087 // bound_nodes_builder, and the parameter named 'AMatcher'.
3088 return AMatcher.matches(Node, Finder, Builder);
3089}
3090
3091TEST(AstMatcherPMacro, Works) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003092 DeclarationMatcher HasClassB = just(has(recordDecl(hasName("B")).bind("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003093
3094 EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003095 HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003096
3097 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003098 HasClassB, new VerifyIdIsBoundTo<Decl>("a")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003099
3100 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003101 HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003102}
3103
Benjamin Kramer57dd9bd2015-03-07 20:38:15 +00003104AST_POLYMORPHIC_MATCHER_P(polymorphicHas,
3105 AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt),
3106 internal::Matcher<Decl>, AMatcher) {
Manuel Klimek04616e42012-07-06 05:48:52 +00003107 return Finder->matchesChildOf(
Manuel Klimekeb958de2012-09-05 12:12:07 +00003108 Node, AMatcher, Builder,
Manuel Klimek04616e42012-07-06 05:48:52 +00003109 ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
3110 ASTMatchFinder::BK_First);
3111}
3112
3113TEST(AstPolymorphicMatcherPMacro, Works) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003114 DeclarationMatcher HasClassB =
3115 polymorphicHas(recordDecl(hasName("B")).bind("b"));
Manuel Klimek04616e42012-07-06 05:48:52 +00003116
3117 EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003118 HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003119
3120 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003121 HasClassB, new VerifyIdIsBoundTo<Decl>("a")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003122
3123 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003124 HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003125
3126 StatementMatcher StatementHasClassB =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003127 polymorphicHas(recordDecl(hasName("B")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003128
3129 EXPECT_TRUE(matches("void x() { class B {}; }", StatementHasClassB));
3130}
3131
3132TEST(For, FindsForLoops) {
3133 EXPECT_TRUE(matches("void f() { for(;;); }", forStmt()));
3134 EXPECT_TRUE(matches("void f() { if(true) for(;;); }", forStmt()));
Daniel Jasper6f595392012-10-01 15:05:34 +00003135 EXPECT_TRUE(notMatches("int as[] = { 1, 2, 3 };"
3136 "void f() { for (auto &a : as); }",
Daniel Jasper5901e472012-10-01 13:40:41 +00003137 forStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003138}
3139
Daniel Jasper4e566c42012-07-12 08:50:38 +00003140TEST(For, ForLoopInternals) {
3141 EXPECT_TRUE(matches("void f(){ int i; for (; i < 3 ; ); }",
3142 forStmt(hasCondition(anything()))));
3143 EXPECT_TRUE(matches("void f() { for (int i = 0; ;); }",
3144 forStmt(hasLoopInit(anything()))));
3145}
3146
Alexander Kornienko9b539e12014-02-05 16:35:08 +00003147TEST(For, ForRangeLoopInternals) {
3148 EXPECT_TRUE(matches("void f(){ int a[] {1, 2}; for (int i : a); }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003149 cxxForRangeStmt(hasLoopVariable(anything()))));
Manuel Klimek86510812014-05-23 17:49:03 +00003150 EXPECT_TRUE(matches(
3151 "void f(){ int a[] {1, 2}; for (int i : a); }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003152 cxxForRangeStmt(hasRangeInit(declRefExpr(to(varDecl(hasName("a"))))))));
Alexander Kornienko9b539e12014-02-05 16:35:08 +00003153}
3154
Daniel Jasper4e566c42012-07-12 08:50:38 +00003155TEST(For, NegativeForLoopInternals) {
3156 EXPECT_TRUE(notMatches("void f(){ for (int i = 0; ; ++i); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003157 forStmt(hasCondition(expr()))));
Daniel Jasper4e566c42012-07-12 08:50:38 +00003158 EXPECT_TRUE(notMatches("void f() {int i; for (; i < 4; ++i) {} }",
3159 forStmt(hasLoopInit(anything()))));
3160}
3161
Manuel Klimek04616e42012-07-06 05:48:52 +00003162TEST(For, ReportsNoFalsePositives) {
3163 EXPECT_TRUE(notMatches("void f() { ; }", forStmt()));
3164 EXPECT_TRUE(notMatches("void f() { if(true); }", forStmt()));
3165}
3166
3167TEST(CompoundStatement, HandlesSimpleCases) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003168 EXPECT_TRUE(notMatches("void f();", compoundStmt()));
3169 EXPECT_TRUE(matches("void f() {}", compoundStmt()));
3170 EXPECT_TRUE(matches("void f() {{}}", compoundStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003171}
3172
3173TEST(CompoundStatement, DoesNotMatchEmptyStruct) {
3174 // It's not a compound statement just because there's "{}" in the source
3175 // text. This is an AST search, not grep.
3176 EXPECT_TRUE(notMatches("namespace n { struct S {}; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003177 compoundStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003178 EXPECT_TRUE(matches("namespace n { struct S { void f() {{}} }; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003179 compoundStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003180}
3181
Daniel Jasper4e566c42012-07-12 08:50:38 +00003182TEST(HasBody, FindsBodyOfForWhileDoLoops) {
Manuel Klimek04616e42012-07-06 05:48:52 +00003183 EXPECT_TRUE(matches("void f() { for(;;) {} }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003184 forStmt(hasBody(compoundStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003185 EXPECT_TRUE(notMatches("void f() { for(;;); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003186 forStmt(hasBody(compoundStmt()))));
Daniel Jasper4e566c42012-07-12 08:50:38 +00003187 EXPECT_TRUE(matches("void f() { while(true) {} }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003188 whileStmt(hasBody(compoundStmt()))));
Daniel Jasper4e566c42012-07-12 08:50:38 +00003189 EXPECT_TRUE(matches("void f() { do {} while(true); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003190 doStmt(hasBody(compoundStmt()))));
Manuel Klimek2af0a912014-05-27 07:45:18 +00003191 EXPECT_TRUE(matches("void f() { int p[2]; for (auto x : p) {} }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003192 cxxForRangeStmt(hasBody(compoundStmt()))));
Aaron Ballman2b6963f2016-01-20 16:26:48 +00003193 EXPECT_TRUE(matches("void f() {}", functionDecl(hasBody(compoundStmt()))));
3194 EXPECT_TRUE(notMatches("void f();", functionDecl(hasBody(compoundStmt()))));
3195 EXPECT_TRUE(matches("void f(); void f() {}",
3196 functionDecl(hasBody(compoundStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003197}
3198
3199TEST(HasAnySubstatement, MatchesForTopLevelCompoundStatement) {
3200 // The simplest case: every compound statement is in a function
3201 // definition, and the function body itself must be a compound
3202 // statement.
3203 EXPECT_TRUE(matches("void f() { for (;;); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003204 compoundStmt(hasAnySubstatement(forStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003205}
3206
3207TEST(HasAnySubstatement, IsNotRecursive) {
3208 // It's really "has any immediate substatement".
3209 EXPECT_TRUE(notMatches("void f() { if (true) for (;;); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003210 compoundStmt(hasAnySubstatement(forStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003211}
3212
3213TEST(HasAnySubstatement, MatchesInNestedCompoundStatements) {
3214 EXPECT_TRUE(matches("void f() { if (true) { for (;;); } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003215 compoundStmt(hasAnySubstatement(forStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003216}
3217
3218TEST(HasAnySubstatement, FindsSubstatementBetweenOthers) {
3219 EXPECT_TRUE(matches("void f() { 1; 2; 3; for (;;); 4; 5; 6; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003220 compoundStmt(hasAnySubstatement(forStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003221}
3222
3223TEST(StatementCountIs, FindsNoStatementsInAnEmptyCompoundStatement) {
3224 EXPECT_TRUE(matches("void f() { }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003225 compoundStmt(statementCountIs(0))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003226 EXPECT_TRUE(notMatches("void f() {}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003227 compoundStmt(statementCountIs(1))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003228}
3229
3230TEST(StatementCountIs, AppearsToMatchOnlyOneCount) {
3231 EXPECT_TRUE(matches("void f() { 1; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003232 compoundStmt(statementCountIs(1))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003233 EXPECT_TRUE(notMatches("void f() { 1; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003234 compoundStmt(statementCountIs(0))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003235 EXPECT_TRUE(notMatches("void f() { 1; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003236 compoundStmt(statementCountIs(2))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003237}
3238
3239TEST(StatementCountIs, WorksWithMultipleStatements) {
3240 EXPECT_TRUE(matches("void f() { 1; 2; 3; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003241 compoundStmt(statementCountIs(3))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003242}
3243
3244TEST(StatementCountIs, WorksWithNestedCompoundStatements) {
3245 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003246 compoundStmt(statementCountIs(1))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003247 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003248 compoundStmt(statementCountIs(2))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003249 EXPECT_TRUE(notMatches("void f() { { 1; } { 1; 2; 3; 4; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003250 compoundStmt(statementCountIs(3))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003251 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003252 compoundStmt(statementCountIs(4))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003253}
3254
3255TEST(Member, WorksInSimplestCase) {
3256 EXPECT_TRUE(matches("struct { int first; } s; int i(s.first);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003257 memberExpr(member(hasName("first")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003258}
3259
3260TEST(Member, DoesNotMatchTheBaseExpression) {
3261 // Don't pick out the wrong part of the member expression, this should
3262 // be checking the member (name) only.
3263 EXPECT_TRUE(notMatches("struct { int i; } first; int i(first.i);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003264 memberExpr(member(hasName("first")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003265}
3266
3267TEST(Member, MatchesInMemberFunctionCall) {
3268 EXPECT_TRUE(matches("void f() {"
3269 " struct { void first() {}; } s;"
3270 " s.first();"
3271 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003272 memberExpr(member(hasName("first")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003273}
3274
Daniel Jasperb0c7b612012-10-23 15:46:39 +00003275TEST(Member, MatchesMember) {
3276 EXPECT_TRUE(matches(
3277 "struct A { int i; }; void f() { A a; a.i = 2; }",
3278 memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
3279 EXPECT_TRUE(notMatches(
3280 "struct A { float f; }; void f() { A a; a.f = 2.0f; }",
3281 memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
3282}
3283
Daniel Jasper639522c2013-02-25 12:02:08 +00003284TEST(Member, UnderstandsAccess) {
3285 EXPECT_TRUE(matches(
3286 "struct A { int i; };", fieldDecl(isPublic(), hasName("i"))));
3287 EXPECT_TRUE(notMatches(
3288 "struct A { int i; };", fieldDecl(isProtected(), hasName("i"))));
3289 EXPECT_TRUE(notMatches(
3290 "struct A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
3291
3292 EXPECT_TRUE(notMatches(
3293 "class A { int i; };", fieldDecl(isPublic(), hasName("i"))));
3294 EXPECT_TRUE(notMatches(
3295 "class A { int i; };", fieldDecl(isProtected(), hasName("i"))));
3296 EXPECT_TRUE(matches(
3297 "class A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
3298
3299 EXPECT_TRUE(notMatches(
3300 "class A { protected: int i; };", fieldDecl(isPublic(), hasName("i"))));
3301 EXPECT_TRUE(matches("class A { protected: int i; };",
3302 fieldDecl(isProtected(), hasName("i"))));
3303 EXPECT_TRUE(notMatches(
3304 "class A { protected: int i; };", fieldDecl(isPrivate(), hasName("i"))));
3305
3306 // Non-member decls have the AccessSpecifier AS_none and thus aren't matched.
3307 EXPECT_TRUE(notMatches("int i;", varDecl(isPublic(), hasName("i"))));
3308 EXPECT_TRUE(notMatches("int i;", varDecl(isProtected(), hasName("i"))));
3309 EXPECT_TRUE(notMatches("int i;", varDecl(isPrivate(), hasName("i"))));
3310}
3311
Dmitri Gribenko06963042012-08-18 00:29:27 +00003312TEST(Member, MatchesMemberAllocationFunction) {
Daniel Jasper5901e472012-10-01 13:40:41 +00003313 // Fails in C++11 mode
3314 EXPECT_TRUE(matchesConditionally(
3315 "namespace std { typedef typeof(sizeof(int)) size_t; }"
3316 "class X { void *operator new(std::size_t); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00003317 cxxMethodDecl(ofClass(hasName("X"))), true, "-std=gnu++98"));
Dmitri Gribenko06963042012-08-18 00:29:27 +00003318
3319 EXPECT_TRUE(matches("class X { void operator delete(void*); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00003320 cxxMethodDecl(ofClass(hasName("X")))));
Dmitri Gribenko06963042012-08-18 00:29:27 +00003321
Daniel Jasper5901e472012-10-01 13:40:41 +00003322 // Fails in C++11 mode
3323 EXPECT_TRUE(matchesConditionally(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003324 "namespace std { typedef typeof(sizeof(int)) size_t; }"
3325 "class X { void operator delete[](void*, std::size_t); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00003326 cxxMethodDecl(ofClass(hasName("X"))), true, "-std=gnu++98"));
Dmitri Gribenko06963042012-08-18 00:29:27 +00003327}
3328
Manuel Klimek04616e42012-07-06 05:48:52 +00003329TEST(HasObjectExpression, DoesNotMatchMember) {
3330 EXPECT_TRUE(notMatches(
3331 "class X {}; struct Z { X m; }; void f(Z z) { z.m; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003332 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003333}
3334
3335TEST(HasObjectExpression, MatchesBaseOfVariable) {
3336 EXPECT_TRUE(matches(
3337 "struct X { int m; }; void f(X x) { x.m; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003338 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003339 EXPECT_TRUE(matches(
3340 "struct X { int m; }; void f(X* x) { x->m; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003341 memberExpr(hasObjectExpression(
3342 hasType(pointsTo(recordDecl(hasName("X"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003343}
3344
3345TEST(HasObjectExpression,
3346 MatchesObjectExpressionOfImplicitlyFormedMemberExpression) {
3347 EXPECT_TRUE(matches(
3348 "class X {}; struct S { X m; void f() { this->m; } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003349 memberExpr(hasObjectExpression(
3350 hasType(pointsTo(recordDecl(hasName("S"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003351 EXPECT_TRUE(matches(
3352 "class X {}; struct S { X m; void f() { m; } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003353 memberExpr(hasObjectExpression(
3354 hasType(pointsTo(recordDecl(hasName("S"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003355}
3356
3357TEST(Field, DoesNotMatchNonFieldMembers) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003358 EXPECT_TRUE(notMatches("class X { void m(); };", fieldDecl(hasName("m"))));
3359 EXPECT_TRUE(notMatches("class X { class m {}; };", fieldDecl(hasName("m"))));
3360 EXPECT_TRUE(notMatches("class X { enum { m }; };", fieldDecl(hasName("m"))));
3361 EXPECT_TRUE(notMatches("class X { enum m {}; };", fieldDecl(hasName("m"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003362}
3363
3364TEST(Field, MatchesField) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003365 EXPECT_TRUE(matches("class X { int m; };", fieldDecl(hasName("m"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003366}
3367
Aaron Ballman6290fc92015-11-23 17:09:24 +00003368TEST(IsVolatileQualified, QualifiersMatch) {
3369 EXPECT_TRUE(matches("volatile int i = 42;",
3370 varDecl(hasType(isVolatileQualified()))));
3371 EXPECT_TRUE(notMatches("volatile int *i;",
3372 varDecl(hasType(isVolatileQualified()))));
3373 EXPECT_TRUE(matches("typedef volatile int v_int; v_int i = 42;",
3374 varDecl(hasType(isVolatileQualified()))));
3375}
3376
Manuel Klimek04616e42012-07-06 05:48:52 +00003377TEST(IsConstQualified, MatchesConstInt) {
3378 EXPECT_TRUE(matches("const int i = 42;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003379 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003380}
3381
3382TEST(IsConstQualified, MatchesConstPointer) {
3383 EXPECT_TRUE(matches("int i = 42; int* const p(&i);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003384 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003385}
3386
3387TEST(IsConstQualified, MatchesThroughTypedef) {
3388 EXPECT_TRUE(matches("typedef const int const_int; const_int i = 42;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003389 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003390 EXPECT_TRUE(matches("typedef int* int_ptr; const int_ptr p(0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003391 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003392}
3393
3394TEST(IsConstQualified, DoesNotMatchInappropriately) {
3395 EXPECT_TRUE(notMatches("typedef int nonconst_int; nonconst_int i = 42;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003396 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003397 EXPECT_TRUE(notMatches("int const* p;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003398 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003399}
3400
Sam Panzer80c13772012-08-16 16:58:10 +00003401TEST(CastExpression, MatchesExplicitCasts) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00003402 EXPECT_TRUE(matches("char *p = reinterpret_cast<char *>(&p);",castExpr()));
3403 EXPECT_TRUE(matches("void *p = (void *)(&p);", castExpr()));
3404 EXPECT_TRUE(matches("char q, *p = const_cast<char *>(&q);", castExpr()));
3405 EXPECT_TRUE(matches("char c = char(0);", castExpr()));
Sam Panzer80c13772012-08-16 16:58:10 +00003406}
3407TEST(CastExpression, MatchesImplicitCasts) {
3408 // This test creates an implicit cast from int to char.
Daniel Jasper848cbe12012-09-18 13:09:13 +00003409 EXPECT_TRUE(matches("char c = 0;", castExpr()));
Sam Panzer80c13772012-08-16 16:58:10 +00003410 // This test creates an implicit cast from lvalue to rvalue.
Daniel Jasper848cbe12012-09-18 13:09:13 +00003411 EXPECT_TRUE(matches("char c = 0, d = c;", castExpr()));
Sam Panzer80c13772012-08-16 16:58:10 +00003412}
3413
3414TEST(CastExpression, DoesNotMatchNonCasts) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00003415 EXPECT_TRUE(notMatches("char c = '0';", castExpr()));
3416 EXPECT_TRUE(notMatches("char c, &q = c;", castExpr()));
3417 EXPECT_TRUE(notMatches("int i = (0);", castExpr()));
3418 EXPECT_TRUE(notMatches("int i = 0;", castExpr()));
Sam Panzer80c13772012-08-16 16:58:10 +00003419}
3420
Manuel Klimek04616e42012-07-06 05:48:52 +00003421TEST(ReinterpretCast, MatchesSimpleCase) {
3422 EXPECT_TRUE(matches("char* p = reinterpret_cast<char*>(&p);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003423 cxxReinterpretCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003424}
3425
3426TEST(ReinterpretCast, DoesNotMatchOtherCasts) {
Aaron Ballman512fb642015-09-17 13:30:52 +00003427 EXPECT_TRUE(notMatches("char* p = (char*)(&p);", cxxReinterpretCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003428 EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003429 cxxReinterpretCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003430 EXPECT_TRUE(notMatches("void* p = static_cast<void*>(&p);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003431 cxxReinterpretCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003432 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
3433 "B b;"
3434 "D* p = dynamic_cast<D*>(&b);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003435 cxxReinterpretCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003436}
3437
3438TEST(FunctionalCast, MatchesSimpleCase) {
Ismail Pazarbasi1121de32014-01-17 21:08:52 +00003439 std::string foo_class = "class Foo { public: Foo(const char*); };";
Manuel Klimek04616e42012-07-06 05:48:52 +00003440 EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello world\"); }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003441 cxxFunctionalCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003442}
3443
3444TEST(FunctionalCast, DoesNotMatchOtherCasts) {
Ismail Pazarbasi1121de32014-01-17 21:08:52 +00003445 std::string FooClass = "class Foo { public: Foo(const char*); };";
Manuel Klimek04616e42012-07-06 05:48:52 +00003446 EXPECT_TRUE(
3447 notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\"; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003448 cxxFunctionalCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003449 EXPECT_TRUE(
3450 notMatches(FooClass + "void r() { Foo f = \"hello world\"; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003451 cxxFunctionalCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003452}
3453
3454TEST(DynamicCast, MatchesSimpleCase) {
3455 EXPECT_TRUE(matches("struct B { virtual ~B() {} }; struct D : B {};"
3456 "B b;"
3457 "D* p = dynamic_cast<D*>(&b);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003458 cxxDynamicCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003459}
3460
3461TEST(StaticCast, MatchesSimpleCase) {
3462 EXPECT_TRUE(matches("void* p(static_cast<void*>(&p));",
Aaron Ballman512fb642015-09-17 13:30:52 +00003463 cxxStaticCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003464}
3465
3466TEST(StaticCast, DoesNotMatchOtherCasts) {
Aaron Ballman512fb642015-09-17 13:30:52 +00003467 EXPECT_TRUE(notMatches("char* p = (char*)(&p);", cxxStaticCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003468 EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003469 cxxStaticCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003470 EXPECT_TRUE(notMatches("void* p = reinterpret_cast<char*>(&p);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003471 cxxStaticCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003472 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
3473 "B b;"
3474 "D* p = dynamic_cast<D*>(&b);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003475 cxxStaticCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003476}
3477
Daniel Jasper417f7762012-09-18 13:36:17 +00003478TEST(CStyleCast, MatchesSimpleCase) {
3479 EXPECT_TRUE(matches("int i = (int) 2.2f;", cStyleCastExpr()));
3480}
3481
3482TEST(CStyleCast, DoesNotMatchOtherCasts) {
3483 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);"
3484 "char q, *r = const_cast<char*>(&q);"
3485 "void* s = reinterpret_cast<char*>(&s);"
3486 "struct B { virtual ~B() {} }; struct D : B {};"
3487 "B b;"
3488 "D* t = dynamic_cast<D*>(&b);",
3489 cStyleCastExpr()));
3490}
3491
Manuel Klimek04616e42012-07-06 05:48:52 +00003492TEST(HasDestinationType, MatchesSimpleCase) {
3493 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003494 cxxStaticCastExpr(hasDestinationType(
Daniel Jasper848cbe12012-09-18 13:09:13 +00003495 pointsTo(TypeMatcher(anything()))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003496}
3497
Sam Panzer80c13772012-08-16 16:58:10 +00003498TEST(HasImplicitDestinationType, MatchesSimpleCase) {
3499 // This test creates an implicit const cast.
3500 EXPECT_TRUE(matches("int x; const int i = x;",
Daniel Jasper848cbe12012-09-18 13:09:13 +00003501 implicitCastExpr(
3502 hasImplicitDestinationType(isInteger()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003503 // This test creates an implicit array-to-pointer cast.
3504 EXPECT_TRUE(matches("int arr[3]; int *p = arr;",
Daniel Jasper848cbe12012-09-18 13:09:13 +00003505 implicitCastExpr(hasImplicitDestinationType(
3506 pointsTo(TypeMatcher(anything()))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003507}
3508
3509TEST(HasImplicitDestinationType, DoesNotMatchIncorrectly) {
3510 // This test creates an implicit cast from int to char.
3511 EXPECT_TRUE(notMatches("char c = 0;",
Daniel Jasper848cbe12012-09-18 13:09:13 +00003512 implicitCastExpr(hasImplicitDestinationType(
3513 unless(anything())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003514 // This test creates an implicit array-to-pointer cast.
3515 EXPECT_TRUE(notMatches("int arr[3]; int *p = arr;",
Daniel Jasper848cbe12012-09-18 13:09:13 +00003516 implicitCastExpr(hasImplicitDestinationType(
3517 unless(anything())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003518}
3519
3520TEST(ImplicitCast, MatchesSimpleCase) {
3521 // This test creates an implicit const cast.
3522 EXPECT_TRUE(matches("int x = 0; const int y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003523 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003524 // This test creates an implicit cast from int to char.
3525 EXPECT_TRUE(matches("char c = 0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003526 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003527 // This test creates an implicit array-to-pointer cast.
3528 EXPECT_TRUE(matches("int arr[6]; int *p = arr;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003529 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003530}
3531
3532TEST(ImplicitCast, DoesNotMatchIncorrectly) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003533 // This test verifies that implicitCastExpr() matches exactly when implicit casts
Sam Panzer80c13772012-08-16 16:58:10 +00003534 // are present, and that it ignores explicit and paren casts.
3535
3536 // These two test cases have no casts.
3537 EXPECT_TRUE(notMatches("int x = 0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003538 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003539 EXPECT_TRUE(notMatches("int x = 0, &y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003540 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003541
3542 EXPECT_TRUE(notMatches("int x = 0; double d = (double) x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003543 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003544 EXPECT_TRUE(notMatches("const int *p; int *q = const_cast<int *>(p);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003545 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003546
3547 EXPECT_TRUE(notMatches("int x = (0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003548 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003549}
3550
3551TEST(IgnoringImpCasts, MatchesImpCasts) {
3552 // This test checks that ignoringImpCasts matches when implicit casts are
3553 // present and its inner matcher alone does not match.
3554 // Note that this test creates an implicit const cast.
3555 EXPECT_TRUE(matches("int x = 0; const int y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003556 varDecl(hasInitializer(ignoringImpCasts(
3557 declRefExpr(to(varDecl(hasName("x")))))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003558 // This test creates an implict cast from int to char.
3559 EXPECT_TRUE(matches("char x = 0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003560 varDecl(hasInitializer(ignoringImpCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003561 integerLiteral(equals(0)))))));
3562}
3563
3564TEST(IgnoringImpCasts, DoesNotMatchIncorrectly) {
3565 // These tests verify that ignoringImpCasts does not match if the inner
3566 // matcher does not match.
3567 // Note that the first test creates an implicit const cast.
3568 EXPECT_TRUE(notMatches("int x; const int y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003569 varDecl(hasInitializer(ignoringImpCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003570 unless(anything()))))));
3571 EXPECT_TRUE(notMatches("int x; int y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003572 varDecl(hasInitializer(ignoringImpCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003573 unless(anything()))))));
3574
3575 // These tests verify that ignoringImplictCasts does not look through explicit
3576 // casts or parentheses.
3577 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003578 varDecl(hasInitializer(ignoringImpCasts(
3579 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003580 EXPECT_TRUE(notMatches("int i = (0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003581 varDecl(hasInitializer(ignoringImpCasts(
3582 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003583 EXPECT_TRUE(notMatches("float i = (float)0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003584 varDecl(hasInitializer(ignoringImpCasts(
3585 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003586 EXPECT_TRUE(notMatches("float i = float(0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003587 varDecl(hasInitializer(ignoringImpCasts(
3588 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003589}
3590
3591TEST(IgnoringImpCasts, MatchesWithoutImpCasts) {
3592 // This test verifies that expressions that do not have implicit casts
3593 // still match the inner matcher.
3594 EXPECT_TRUE(matches("int x = 0; int &y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003595 varDecl(hasInitializer(ignoringImpCasts(
3596 declRefExpr(to(varDecl(hasName("x")))))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003597}
3598
3599TEST(IgnoringParenCasts, MatchesParenCasts) {
3600 // This test checks that ignoringParenCasts matches when parentheses and/or
3601 // casts are present and its inner matcher alone does not match.
3602 EXPECT_TRUE(matches("int x = (0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003603 varDecl(hasInitializer(ignoringParenCasts(
3604 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003605 EXPECT_TRUE(matches("int x = (((((0)))));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003606 varDecl(hasInitializer(ignoringParenCasts(
3607 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003608
3609 // This test creates an implict cast from int to char in addition to the
3610 // parentheses.
3611 EXPECT_TRUE(matches("char x = (0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003612 varDecl(hasInitializer(ignoringParenCasts(
3613 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003614
3615 EXPECT_TRUE(matches("char x = (char)0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003616 varDecl(hasInitializer(ignoringParenCasts(
3617 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003618 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003619 varDecl(hasInitializer(ignoringParenCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003620 integerLiteral(equals(0)))))));
3621}
3622
3623TEST(IgnoringParenCasts, MatchesWithoutParenCasts) {
3624 // This test verifies that expressions that do not have any casts still match.
3625 EXPECT_TRUE(matches("int x = 0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003626 varDecl(hasInitializer(ignoringParenCasts(
3627 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003628}
3629
3630TEST(IgnoringParenCasts, DoesNotMatchIncorrectly) {
3631 // These tests verify that ignoringImpCasts does not match if the inner
3632 // matcher does not match.
3633 EXPECT_TRUE(notMatches("int x = ((0));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003634 varDecl(hasInitializer(ignoringParenCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003635 unless(anything()))))));
3636
3637 // This test creates an implicit cast from int to char in addition to the
3638 // parentheses.
3639 EXPECT_TRUE(notMatches("char x = ((0));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003640 varDecl(hasInitializer(ignoringParenCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003641 unless(anything()))))));
3642
3643 EXPECT_TRUE(notMatches("char *x = static_cast<char *>((0));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003644 varDecl(hasInitializer(ignoringParenCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003645 unless(anything()))))));
3646}
3647
3648TEST(IgnoringParenAndImpCasts, MatchesParenImpCasts) {
3649 // This test checks that ignoringParenAndImpCasts matches when
3650 // parentheses and/or implicit casts are present and its inner matcher alone
3651 // does not match.
3652 // Note that this test creates an implicit const cast.
3653 EXPECT_TRUE(matches("int x = 0; const int y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003654 varDecl(hasInitializer(ignoringParenImpCasts(
3655 declRefExpr(to(varDecl(hasName("x")))))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003656 // This test creates an implicit cast from int to char.
3657 EXPECT_TRUE(matches("const char x = (0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003658 varDecl(hasInitializer(ignoringParenImpCasts(
3659 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003660}
3661
3662TEST(IgnoringParenAndImpCasts, MatchesWithoutParenImpCasts) {
3663 // This test verifies that expressions that do not have parentheses or
3664 // implicit casts still match.
3665 EXPECT_TRUE(matches("int x = 0; int &y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003666 varDecl(hasInitializer(ignoringParenImpCasts(
3667 declRefExpr(to(varDecl(hasName("x")))))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003668 EXPECT_TRUE(matches("int x = 0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003669 varDecl(hasInitializer(ignoringParenImpCasts(
3670 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003671}
3672
3673TEST(IgnoringParenAndImpCasts, DoesNotMatchIncorrectly) {
3674 // These tests verify that ignoringParenImpCasts does not match if
3675 // the inner matcher does not match.
3676 // This test creates an implicit cast.
3677 EXPECT_TRUE(notMatches("char c = ((3));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003678 varDecl(hasInitializer(ignoringParenImpCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003679 unless(anything()))))));
3680 // These tests verify that ignoringParenAndImplictCasts does not look
3681 // through explicit casts.
3682 EXPECT_TRUE(notMatches("float y = (float(0));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003683 varDecl(hasInitializer(ignoringParenImpCasts(
3684 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003685 EXPECT_TRUE(notMatches("float y = (float)0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003686 varDecl(hasInitializer(ignoringParenImpCasts(
3687 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003688 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003689 varDecl(hasInitializer(ignoringParenImpCasts(
3690 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003691}
3692
Manuel Klimeke9235692012-07-25 10:02:02 +00003693TEST(HasSourceExpression, MatchesImplicitCasts) {
Manuel Klimek04616e42012-07-06 05:48:52 +00003694 EXPECT_TRUE(matches("class string {}; class URL { public: URL(string s); };"
3695 "void r() {string a_string; URL url = a_string; }",
Daniel Jasper848cbe12012-09-18 13:09:13 +00003696 implicitCastExpr(
Aaron Ballman512fb642015-09-17 13:30:52 +00003697 hasSourceExpression(cxxConstructExpr()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003698}
3699
Manuel Klimeke9235692012-07-25 10:02:02 +00003700TEST(HasSourceExpression, MatchesExplicitCasts) {
3701 EXPECT_TRUE(matches("float x = static_cast<float>(42);",
Daniel Jasper848cbe12012-09-18 13:09:13 +00003702 explicitCastExpr(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003703 hasSourceExpression(hasDescendant(
Daniel Jasper848cbe12012-09-18 13:09:13 +00003704 expr(integerLiteral()))))));
Manuel Klimeke9235692012-07-25 10:02:02 +00003705}
3706
Manuel Klimek04616e42012-07-06 05:48:52 +00003707TEST(Statement, DoesNotMatchDeclarations) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003708 EXPECT_TRUE(notMatches("class X {};", stmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003709}
3710
3711TEST(Statement, MatchesCompoundStatments) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003712 EXPECT_TRUE(matches("void x() {}", stmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003713}
3714
3715TEST(DeclarationStatement, DoesNotMatchCompoundStatements) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003716 EXPECT_TRUE(notMatches("void x() {}", declStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003717}
3718
3719TEST(DeclarationStatement, MatchesVariableDeclarationStatements) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003720 EXPECT_TRUE(matches("void x() { int a; }", declStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003721}
3722
Samuel Benzaquenf1066292014-04-02 13:12:14 +00003723TEST(ExprWithCleanups, MatchesExprWithCleanups) {
3724 EXPECT_TRUE(matches("struct Foo { ~Foo(); };"
3725 "const Foo f = Foo();",
3726 varDecl(hasInitializer(exprWithCleanups()))));
3727 EXPECT_FALSE(matches("struct Foo { };"
3728 "const Foo f = Foo();",
3729 varDecl(hasInitializer(exprWithCleanups()))));
3730}
3731
Daniel Jasper1dad1832012-07-10 20:20:19 +00003732TEST(InitListExpression, MatchesInitListExpression) {
3733 EXPECT_TRUE(matches("int a[] = { 1, 2 };",
3734 initListExpr(hasType(asString("int [2]")))));
3735 EXPECT_TRUE(matches("struct B { int x, y; }; B b = { 5, 6 };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003736 initListExpr(hasType(recordDecl(hasName("B"))))));
Daniel Jasper1d8ecbd2015-02-04 13:11:42 +00003737 EXPECT_TRUE(matches("struct S { S(void (*a)()); };"
3738 "void f();"
3739 "S s[1] = { &f };",
3740 declRefExpr(to(functionDecl(hasName("f"))))));
Daniel Jasper774e6b52015-02-04 14:29:47 +00003741 EXPECT_TRUE(
3742 matches("int i[1] = {42, [0] = 43};", integerLiteral(equals(42))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00003743}
3744
3745TEST(UsingDeclaration, MatchesUsingDeclarations) {
3746 EXPECT_TRUE(matches("namespace X { int x; } using X::x;",
3747 usingDecl()));
3748}
3749
3750TEST(UsingDeclaration, MatchesShadowUsingDelcarations) {
3751 EXPECT_TRUE(matches("namespace f { int a; } using f::a;",
3752 usingDecl(hasAnyUsingShadowDecl(hasName("a")))));
3753}
3754
3755TEST(UsingDeclaration, MatchesSpecificTarget) {
3756 EXPECT_TRUE(matches("namespace f { int a; void b(); } using f::b;",
3757 usingDecl(hasAnyUsingShadowDecl(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003758 hasTargetDecl(functionDecl())))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00003759 EXPECT_TRUE(notMatches("namespace f { int a; void b(); } using f::a;",
3760 usingDecl(hasAnyUsingShadowDecl(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003761 hasTargetDecl(functionDecl())))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00003762}
3763
3764TEST(UsingDeclaration, ThroughUsingDeclaration) {
3765 EXPECT_TRUE(matches(
3766 "namespace a { void f(); } using a::f; void g() { f(); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003767 declRefExpr(throughUsingDecl(anything()))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00003768 EXPECT_TRUE(notMatches(
3769 "namespace a { void f(); } using a::f; void g() { a::f(); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003770 declRefExpr(throughUsingDecl(anything()))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00003771}
3772
Benjamin Kramer73ef2162014-07-16 14:14:51 +00003773TEST(UsingDirectiveDeclaration, MatchesUsingNamespace) {
3774 EXPECT_TRUE(matches("namespace X { int x; } using namespace X;",
3775 usingDirectiveDecl()));
3776 EXPECT_FALSE(
3777 matches("namespace X { int x; } using X::x;", usingDirectiveDecl()));
3778}
3779
Sam Panzerd624bfb2012-08-16 17:20:59 +00003780TEST(SingleDecl, IsSingleDecl) {
3781 StatementMatcher SingleDeclStmt =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003782 declStmt(hasSingleDecl(varDecl(hasInitializer(anything()))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003783 EXPECT_TRUE(matches("void f() {int a = 4;}", SingleDeclStmt));
3784 EXPECT_TRUE(notMatches("void f() {int a;}", SingleDeclStmt));
3785 EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
3786 SingleDeclStmt));
3787}
3788
3789TEST(DeclStmt, ContainsDeclaration) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003790 DeclarationMatcher MatchesInit = varDecl(hasInitializer(anything()));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003791
3792 EXPECT_TRUE(matches("void f() {int a = 4;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003793 declStmt(containsDeclaration(0, MatchesInit))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003794 EXPECT_TRUE(matches("void f() {int a = 4, b = 3;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003795 declStmt(containsDeclaration(0, MatchesInit),
3796 containsDeclaration(1, MatchesInit))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003797 unsigned WrongIndex = 42;
3798 EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003799 declStmt(containsDeclaration(WrongIndex,
Sam Panzerd624bfb2012-08-16 17:20:59 +00003800 MatchesInit))));
3801}
3802
3803TEST(DeclCount, DeclCountIsCorrect) {
3804 EXPECT_TRUE(matches("void f() {int i,j;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003805 declStmt(declCountIs(2))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003806 EXPECT_TRUE(notMatches("void f() {int i,j; int k;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003807 declStmt(declCountIs(3))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003808 EXPECT_TRUE(notMatches("void f() {int i,j, k, l;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003809 declStmt(declCountIs(3))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003810}
3811
Manuel Klimek04616e42012-07-06 05:48:52 +00003812TEST(While, MatchesWhileLoops) {
3813 EXPECT_TRUE(notMatches("void x() {}", whileStmt()));
3814 EXPECT_TRUE(matches("void x() { while(true); }", whileStmt()));
3815 EXPECT_TRUE(notMatches("void x() { do {} while(true); }", whileStmt()));
3816}
3817
3818TEST(Do, MatchesDoLoops) {
3819 EXPECT_TRUE(matches("void x() { do {} while(true); }", doStmt()));
3820 EXPECT_TRUE(matches("void x() { do ; while(false); }", doStmt()));
3821}
3822
3823TEST(Do, DoesNotMatchWhileLoops) {
3824 EXPECT_TRUE(notMatches("void x() { while(true) {} }", doStmt()));
3825}
3826
3827TEST(SwitchCase, MatchesCase) {
3828 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchCase()));
3829 EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchCase()));
3830 EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchCase()));
3831 EXPECT_TRUE(notMatches("void x() { switch(42) {} }", switchCase()));
3832}
3833
Daniel Jasper87c3d362012-09-20 14:12:57 +00003834TEST(SwitchCase, MatchesSwitch) {
3835 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchStmt()));
3836 EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchStmt()));
3837 EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchStmt()));
3838 EXPECT_TRUE(notMatches("void x() {}", switchStmt()));
3839}
3840
Peter Collingbourne3154a102013-05-10 11:52:02 +00003841TEST(SwitchCase, MatchesEachCase) {
3842 EXPECT_TRUE(notMatches("void x() { switch(42); }",
3843 switchStmt(forEachSwitchCase(caseStmt()))));
3844 EXPECT_TRUE(matches("void x() { switch(42) case 42:; }",
3845 switchStmt(forEachSwitchCase(caseStmt()))));
3846 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }",
3847 switchStmt(forEachSwitchCase(caseStmt()))));
3848 EXPECT_TRUE(notMatches(
3849 "void x() { if (1) switch(42) { case 42: switch (42) { default:; } } }",
3850 ifStmt(has(switchStmt(forEachSwitchCase(defaultStmt()))))));
3851 EXPECT_TRUE(matches("void x() { switch(42) { case 1+1: case 4:; } }",
3852 switchStmt(forEachSwitchCase(
3853 caseStmt(hasCaseConstant(integerLiteral()))))));
3854 EXPECT_TRUE(notMatches("void x() { switch(42) { case 1+1: case 2+2:; } }",
3855 switchStmt(forEachSwitchCase(
3856 caseStmt(hasCaseConstant(integerLiteral()))))));
3857 EXPECT_TRUE(notMatches("void x() { switch(42) { case 1 ... 2:; } }",
3858 switchStmt(forEachSwitchCase(
3859 caseStmt(hasCaseConstant(integerLiteral()))))));
3860 EXPECT_TRUE(matchAndVerifyResultTrue(
3861 "void x() { switch (42) { case 1: case 2: case 3: default:; } }",
3862 switchStmt(forEachSwitchCase(caseStmt().bind("x"))),
3863 new VerifyIdIsBoundTo<CaseStmt>("x", 3)));
3864}
3865
Manuel Klimekba46fc02013-07-19 11:50:54 +00003866TEST(ForEachConstructorInitializer, MatchesInitializers) {
3867 EXPECT_TRUE(matches(
3868 "struct X { X() : i(42), j(42) {} int i, j; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00003869 cxxConstructorDecl(forEachConstructorInitializer(cxxCtorInitializer()))));
Manuel Klimekba46fc02013-07-19 11:50:54 +00003870}
3871
Daniel Jasper87c3d362012-09-20 14:12:57 +00003872TEST(ExceptionHandling, SimpleCases) {
Aaron Ballman512fb642015-09-17 13:30:52 +00003873 EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", cxxCatchStmt()));
3874 EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", cxxTryStmt()));
3875 EXPECT_TRUE(
3876 notMatches("void foo() try { } catch(int X) { }", cxxThrowExpr()));
Daniel Jasper87c3d362012-09-20 14:12:57 +00003877 EXPECT_TRUE(matches("void foo() try { throw; } catch(int X) { }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003878 cxxThrowExpr()));
Daniel Jasper87c3d362012-09-20 14:12:57 +00003879 EXPECT_TRUE(matches("void foo() try { throw 5;} catch(int X) { }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003880 cxxThrowExpr()));
Aaron Ballman9b869aa2015-07-02 12:53:22 +00003881 EXPECT_TRUE(matches("void foo() try { throw; } catch(...) { }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003882 cxxCatchStmt(isCatchAll())));
Aaron Ballman9b869aa2015-07-02 12:53:22 +00003883 EXPECT_TRUE(notMatches("void foo() try { throw; } catch(int) { }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003884 cxxCatchStmt(isCatchAll())));
Aaron Ballman39918462015-07-15 17:11:21 +00003885 EXPECT_TRUE(matches("void foo() try {} catch(int X) { }",
3886 varDecl(isExceptionVariable())));
3887 EXPECT_TRUE(notMatches("void foo() try { int X; } catch (...) { }",
3888 varDecl(isExceptionVariable())));
Daniel Jasper87c3d362012-09-20 14:12:57 +00003889}
3890
Aaron Ballmane8295d72016-01-20 16:17:39 +00003891TEST(ParenExpression, SimpleCases) {
3892 EXPECT_TRUE(matches("int i = (3);", parenExpr()));
3893 EXPECT_TRUE(matches("int i = (3 + 7);", parenExpr()));
3894 EXPECT_TRUE(notMatches("int i = 3;", parenExpr()));
3895 EXPECT_TRUE(notMatches("int foo() { return 1; }; int a = foo();",
3896 parenExpr()));
3897}
3898
Manuel Klimek04616e42012-07-06 05:48:52 +00003899TEST(HasConditionVariableStatement, DoesNotMatchCondition) {
3900 EXPECT_TRUE(notMatches(
3901 "void x() { if(true) {} }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003902 ifStmt(hasConditionVariableStatement(declStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003903 EXPECT_TRUE(notMatches(
3904 "void x() { int x; if((x = 42)) {} }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003905 ifStmt(hasConditionVariableStatement(declStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003906}
3907
3908TEST(HasConditionVariableStatement, MatchesConditionVariables) {
3909 EXPECT_TRUE(matches(
3910 "void x() { if(int* a = 0) {} }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003911 ifStmt(hasConditionVariableStatement(declStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003912}
3913
3914TEST(ForEach, BindsOneNode) {
3915 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003916 recordDecl(hasName("C"), forEach(fieldDecl(hasName("x")).bind("x"))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003917 new VerifyIdIsBoundTo<FieldDecl>("x", 1)));
Manuel Klimek04616e42012-07-06 05:48:52 +00003918}
3919
3920TEST(ForEach, BindsMultipleNodes) {
3921 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; int y; int z; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003922 recordDecl(hasName("C"), forEach(fieldDecl().bind("f"))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003923 new VerifyIdIsBoundTo<FieldDecl>("f", 3)));
Manuel Klimek04616e42012-07-06 05:48:52 +00003924}
3925
3926TEST(ForEach, BindsRecursiveCombinations) {
3927 EXPECT_TRUE(matchAndVerifyResultTrue(
3928 "class C { class D { int x; int y; }; class E { int y; int z; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003929 recordDecl(hasName("C"),
3930 forEach(recordDecl(forEach(fieldDecl().bind("f"))))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003931 new VerifyIdIsBoundTo<FieldDecl>("f", 4)));
Manuel Klimek04616e42012-07-06 05:48:52 +00003932}
3933
3934TEST(ForEachDescendant, BindsOneNode) {
3935 EXPECT_TRUE(matchAndVerifyResultTrue("class C { class D { int x; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003936 recordDecl(hasName("C"),
3937 forEachDescendant(fieldDecl(hasName("x")).bind("x"))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003938 new VerifyIdIsBoundTo<FieldDecl>("x", 1)));
Manuel Klimek04616e42012-07-06 05:48:52 +00003939}
3940
Daniel Jasper94a56852012-11-16 18:39:22 +00003941TEST(ForEachDescendant, NestedForEachDescendant) {
3942 DeclarationMatcher m = recordDecl(
3943 isDefinition(), decl().bind("x"), hasName("C"));
3944 EXPECT_TRUE(matchAndVerifyResultTrue(
3945 "class A { class B { class C {}; }; };",
3946 recordDecl(hasName("A"), anyOf(m, forEachDescendant(m))),
3947 new VerifyIdIsBoundTo<Decl>("x", "C")));
3948
Manuel Klimeka0c025f2013-06-19 15:42:45 +00003949 // Check that a partial match of 'm' that binds 'x' in the
3950 // first part of anyOf(m, anything()) will not overwrite the
3951 // binding created by the earlier binding in the hasDescendant.
3952 EXPECT_TRUE(matchAndVerifyResultTrue(
3953 "class A { class B { class C {}; }; };",
3954 recordDecl(hasName("A"), allOf(hasDescendant(m), anyOf(m, anything()))),
3955 new VerifyIdIsBoundTo<Decl>("x", "C")));
Daniel Jasper94a56852012-11-16 18:39:22 +00003956}
3957
Manuel Klimek04616e42012-07-06 05:48:52 +00003958TEST(ForEachDescendant, BindsMultipleNodes) {
3959 EXPECT_TRUE(matchAndVerifyResultTrue(
3960 "class C { class D { int x; int y; }; "
3961 " class E { class F { int y; int z; }; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003962 recordDecl(hasName("C"), forEachDescendant(fieldDecl().bind("f"))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003963 new VerifyIdIsBoundTo<FieldDecl>("f", 4)));
Manuel Klimek04616e42012-07-06 05:48:52 +00003964}
3965
3966TEST(ForEachDescendant, BindsRecursiveCombinations) {
3967 EXPECT_TRUE(matchAndVerifyResultTrue(
3968 "class C { class D { "
3969 " class E { class F { class G { int y; int z; }; }; }; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003970 recordDecl(hasName("C"), forEachDescendant(recordDecl(
3971 forEachDescendant(fieldDecl().bind("f"))))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003972 new VerifyIdIsBoundTo<FieldDecl>("f", 8)));
Manuel Klimek04616e42012-07-06 05:48:52 +00003973}
3974
Manuel Klimeka0c025f2013-06-19 15:42:45 +00003975TEST(ForEachDescendant, BindsCombinations) {
3976 EXPECT_TRUE(matchAndVerifyResultTrue(
3977 "void f() { if(true) {} if (true) {} while (true) {} if (true) {} while "
3978 "(true) {} }",
3979 compoundStmt(forEachDescendant(ifStmt().bind("if")),
3980 forEachDescendant(whileStmt().bind("while"))),
3981 new VerifyIdIsBoundTo<IfStmt>("if", 6)));
3982}
3983
3984TEST(Has, DoesNotDeleteBindings) {
3985 EXPECT_TRUE(matchAndVerifyResultTrue(
3986 "class X { int a; };", recordDecl(decl().bind("x"), has(fieldDecl())),
3987 new VerifyIdIsBoundTo<Decl>("x", 1)));
3988}
3989
3990TEST(LoopingMatchers, DoNotOverwritePreviousMatchResultOnFailure) {
3991 // Those matchers cover all the cases where an inner matcher is called
3992 // and there is not a 1:1 relationship between the match of the outer
3993 // matcher and the match of the inner matcher.
3994 // The pattern to look for is:
3995 // ... return InnerMatcher.matches(...); ...
3996 // In which case no special handling is needed.
3997 //
3998 // On the other hand, if there are multiple alternative matches
3999 // (for example forEach*) or matches might be discarded (for example has*)
4000 // the implementation must make sure that the discarded matches do not
4001 // affect the bindings.
4002 // When new such matchers are added, add a test here that:
4003 // - matches a simple node, and binds it as the first thing in the matcher:
4004 // recordDecl(decl().bind("x"), hasName("X")))
4005 // - uses the matcher under test afterwards in a way that not the first
4006 // alternative is matched; for anyOf, that means the first branch
4007 // would need to return false; for hasAncestor, it means that not
4008 // the direct parent matches the inner matcher.
4009
4010 EXPECT_TRUE(matchAndVerifyResultTrue(
4011 "class X { int y; };",
4012 recordDecl(
4013 recordDecl().bind("x"), hasName("::X"),
4014 anyOf(forEachDescendant(recordDecl(hasName("Y"))), anything())),
4015 new VerifyIdIsBoundTo<CXXRecordDecl>("x", 1)));
4016 EXPECT_TRUE(matchAndVerifyResultTrue(
4017 "class X {};", recordDecl(recordDecl().bind("x"), hasName("::X"),
4018 anyOf(unless(anything()), anything())),
4019 new VerifyIdIsBoundTo<CXXRecordDecl>("x", 1)));
4020 EXPECT_TRUE(matchAndVerifyResultTrue(
4021 "template<typename T1, typename T2> class X {}; X<float, int> x;",
4022 classTemplateSpecializationDecl(
4023 decl().bind("x"),
4024 hasAnyTemplateArgument(refersToType(asString("int")))),
4025 new VerifyIdIsBoundTo<Decl>("x", 1)));
4026 EXPECT_TRUE(matchAndVerifyResultTrue(
4027 "class X { void f(); void g(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00004028 cxxRecordDecl(decl().bind("x"), hasMethod(hasName("g"))),
Manuel Klimeka0c025f2013-06-19 15:42:45 +00004029 new VerifyIdIsBoundTo<Decl>("x", 1)));
4030 EXPECT_TRUE(matchAndVerifyResultTrue(
4031 "class X { X() : a(1), b(2) {} double a; int b; };",
4032 recordDecl(decl().bind("x"),
Aaron Ballman512fb642015-09-17 13:30:52 +00004033 has(cxxConstructorDecl(
Manuel Klimeka0c025f2013-06-19 15:42:45 +00004034 hasAnyConstructorInitializer(forField(hasName("b")))))),
4035 new VerifyIdIsBoundTo<Decl>("x", 1)));
4036 EXPECT_TRUE(matchAndVerifyResultTrue(
4037 "void x(int, int) { x(0, 42); }",
4038 callExpr(expr().bind("x"), hasAnyArgument(integerLiteral(equals(42)))),
4039 new VerifyIdIsBoundTo<Expr>("x", 1)));
4040 EXPECT_TRUE(matchAndVerifyResultTrue(
4041 "void x(int, int y) {}",
4042 functionDecl(decl().bind("x"), hasAnyParameter(hasName("y"))),
4043 new VerifyIdIsBoundTo<Decl>("x", 1)));
4044 EXPECT_TRUE(matchAndVerifyResultTrue(
4045 "void x() { return; if (true) {} }",
4046 functionDecl(decl().bind("x"),
4047 has(compoundStmt(hasAnySubstatement(ifStmt())))),
4048 new VerifyIdIsBoundTo<Decl>("x", 1)));
4049 EXPECT_TRUE(matchAndVerifyResultTrue(
4050 "namespace X { void b(int); void b(); }"
4051 "using X::b;",
4052 usingDecl(decl().bind("x"), hasAnyUsingShadowDecl(hasTargetDecl(
4053 functionDecl(parameterCountIs(1))))),
4054 new VerifyIdIsBoundTo<Decl>("x", 1)));
4055 EXPECT_TRUE(matchAndVerifyResultTrue(
4056 "class A{}; class B{}; class C : B, A {};",
Aaron Ballman512fb642015-09-17 13:30:52 +00004057 cxxRecordDecl(decl().bind("x"), isDerivedFrom("::A")),
Manuel Klimeka0c025f2013-06-19 15:42:45 +00004058 new VerifyIdIsBoundTo<Decl>("x", 1)));
4059 EXPECT_TRUE(matchAndVerifyResultTrue(
4060 "class A{}; typedef A B; typedef A C; typedef A D;"
4061 "class E : A {};",
Aaron Ballman512fb642015-09-17 13:30:52 +00004062 cxxRecordDecl(decl().bind("x"), isDerivedFrom("C")),
Manuel Klimeka0c025f2013-06-19 15:42:45 +00004063 new VerifyIdIsBoundTo<Decl>("x", 1)));
4064 EXPECT_TRUE(matchAndVerifyResultTrue(
4065 "class A { class B { void f() {} }; };",
4066 functionDecl(decl().bind("x"), hasAncestor(recordDecl(hasName("::A")))),
4067 new VerifyIdIsBoundTo<Decl>("x", 1)));
4068 EXPECT_TRUE(matchAndVerifyResultTrue(
4069 "template <typename T> struct A { struct B {"
4070 " void f() { if(true) {} }"
4071 "}; };"
4072 "void t() { A<int>::B b; b.f(); }",
4073 ifStmt(stmt().bind("x"), hasAncestor(recordDecl(hasName("::A")))),
4074 new VerifyIdIsBoundTo<Stmt>("x", 2)));
4075 EXPECT_TRUE(matchAndVerifyResultTrue(
4076 "class A {};",
4077 recordDecl(hasName("::A"), decl().bind("x"), unless(hasName("fooble"))),
4078 new VerifyIdIsBoundTo<Decl>("x", 1)));
Manuel Klimekba46fc02013-07-19 11:50:54 +00004079 EXPECT_TRUE(matchAndVerifyResultTrue(
4080 "class A { A() : s(), i(42) {} const char *s; int i; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00004081 cxxConstructorDecl(hasName("::A::A"), decl().bind("x"),
4082 forEachConstructorInitializer(forField(hasName("i")))),
Manuel Klimekba46fc02013-07-19 11:50:54 +00004083 new VerifyIdIsBoundTo<Decl>("x", 1)));
Manuel Klimeka0c025f2013-06-19 15:42:45 +00004084}
4085
Daniel Jasper33806cd2012-11-11 22:14:55 +00004086TEST(ForEachDescendant, BindsCorrectNodes) {
4087 EXPECT_TRUE(matchAndVerifyResultTrue(
4088 "class C { void f(); int i; };",
4089 recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
4090 new VerifyIdIsBoundTo<FieldDecl>("decl", 1)));
4091 EXPECT_TRUE(matchAndVerifyResultTrue(
4092 "class C { void f() {} int i; };",
4093 recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
4094 new VerifyIdIsBoundTo<FunctionDecl>("decl", 1)));
4095}
4096
Manuel Klimekabf43712013-02-04 10:59:20 +00004097TEST(FindAll, BindsNodeOnMatch) {
4098 EXPECT_TRUE(matchAndVerifyResultTrue(
4099 "class A {};",
4100 recordDecl(hasName("::A"), findAll(recordDecl(hasName("::A")).bind("v"))),
4101 new VerifyIdIsBoundTo<CXXRecordDecl>("v", 1)));
4102}
4103
4104TEST(FindAll, BindsDescendantNodeOnMatch) {
4105 EXPECT_TRUE(matchAndVerifyResultTrue(
4106 "class A { int a; int b; };",
4107 recordDecl(hasName("::A"), findAll(fieldDecl().bind("v"))),
4108 new VerifyIdIsBoundTo<FieldDecl>("v", 2)));
4109}
4110
4111TEST(FindAll, BindsNodeAndDescendantNodesOnOneMatch) {
4112 EXPECT_TRUE(matchAndVerifyResultTrue(
4113 "class A { int a; int b; };",
4114 recordDecl(hasName("::A"),
4115 findAll(decl(anyOf(recordDecl(hasName("::A")).bind("v"),
4116 fieldDecl().bind("v"))))),
4117 new VerifyIdIsBoundTo<Decl>("v", 3)));
4118
4119 EXPECT_TRUE(matchAndVerifyResultTrue(
4120 "class A { class B {}; class C {}; };",
4121 recordDecl(hasName("::A"), findAll(recordDecl(isDefinition()).bind("v"))),
4122 new VerifyIdIsBoundTo<CXXRecordDecl>("v", 3)));
4123}
4124
Manuel Klimek88b95872013-02-04 09:42:38 +00004125TEST(EachOf, TriggersForEachMatch) {
4126 EXPECT_TRUE(matchAndVerifyResultTrue(
4127 "class A { int a; int b; };",
4128 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
4129 has(fieldDecl(hasName("b")).bind("v")))),
4130 new VerifyIdIsBoundTo<FieldDecl>("v", 2)));
4131}
4132
4133TEST(EachOf, BehavesLikeAnyOfUnlessBothMatch) {
4134 EXPECT_TRUE(matchAndVerifyResultTrue(
4135 "class A { int a; int c; };",
4136 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
4137 has(fieldDecl(hasName("b")).bind("v")))),
4138 new VerifyIdIsBoundTo<FieldDecl>("v", 1)));
4139 EXPECT_TRUE(matchAndVerifyResultTrue(
4140 "class A { int c; int b; };",
4141 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
4142 has(fieldDecl(hasName("b")).bind("v")))),
4143 new VerifyIdIsBoundTo<FieldDecl>("v", 1)));
4144 EXPECT_TRUE(notMatches(
4145 "class A { int c; int d; };",
4146 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
4147 has(fieldDecl(hasName("b")).bind("v"))))));
4148}
Manuel Klimek04616e42012-07-06 05:48:52 +00004149
4150TEST(IsTemplateInstantiation, MatchesImplicitClassTemplateInstantiation) {
4151 // Make sure that we can both match the class by name (::X) and by the type
4152 // the template was instantiated with (via a field).
4153
4154 EXPECT_TRUE(matches(
4155 "template <typename T> class X {}; class A {}; X<A> x;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004156 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
Manuel Klimek04616e42012-07-06 05:48:52 +00004157
4158 EXPECT_TRUE(matches(
4159 "template <typename T> class X { T t; }; class A {}; X<A> x;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004160 cxxRecordDecl(isTemplateInstantiation(), hasDescendant(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004161 fieldDecl(hasType(recordDecl(hasName("A"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00004162}
4163
4164TEST(IsTemplateInstantiation, MatchesImplicitFunctionTemplateInstantiation) {
4165 EXPECT_TRUE(matches(
4166 "template <typename T> void f(T t) {} class A {}; void g() { f(A()); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004167 functionDecl(hasParameter(0, hasType(recordDecl(hasName("A")))),
Manuel Klimek04616e42012-07-06 05:48:52 +00004168 isTemplateInstantiation())));
4169}
4170
4171TEST(IsTemplateInstantiation, MatchesExplicitClassTemplateInstantiation) {
4172 EXPECT_TRUE(matches(
4173 "template <typename T> class X { T t; }; class A {};"
4174 "template class X<A>;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004175 cxxRecordDecl(isTemplateInstantiation(), hasDescendant(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004176 fieldDecl(hasType(recordDecl(hasName("A"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00004177}
4178
4179TEST(IsTemplateInstantiation,
4180 MatchesInstantiationOfPartiallySpecializedClassTemplate) {
4181 EXPECT_TRUE(matches(
4182 "template <typename T> class X {};"
4183 "template <typename T> class X<T*> {}; class A {}; X<A*> x;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004184 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
Manuel Klimek04616e42012-07-06 05:48:52 +00004185}
4186
4187TEST(IsTemplateInstantiation,
4188 MatchesInstantiationOfClassTemplateNestedInNonTemplate) {
4189 EXPECT_TRUE(matches(
4190 "class A {};"
4191 "class X {"
4192 " template <typename U> class Y { U u; };"
4193 " Y<A> y;"
4194 "};",
Aaron Ballman512fb642015-09-17 13:30:52 +00004195 cxxRecordDecl(hasName("::X::Y"), isTemplateInstantiation())));
Manuel Klimek04616e42012-07-06 05:48:52 +00004196}
4197
4198TEST(IsTemplateInstantiation, DoesNotMatchInstantiationsInsideOfInstantiation) {
4199 // FIXME: Figure out whether this makes sense. It doesn't affect the
4200 // normal use case as long as the uppermost instantiation always is marked
4201 // as template instantiation, but it might be confusing as a predicate.
4202 EXPECT_TRUE(matches(
4203 "class A {};"
4204 "template <typename T> class X {"
4205 " template <typename U> class Y { U u; };"
4206 " Y<T> y;"
4207 "}; X<A> x;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004208 cxxRecordDecl(hasName("::X<A>::Y"), unless(isTemplateInstantiation()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00004209}
4210
4211TEST(IsTemplateInstantiation, DoesNotMatchExplicitClassTemplateSpecialization) {
4212 EXPECT_TRUE(notMatches(
4213 "template <typename T> class X {}; class A {};"
4214 "template <> class X<A> {}; X<A> x;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004215 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
Manuel Klimek04616e42012-07-06 05:48:52 +00004216}
4217
4218TEST(IsTemplateInstantiation, DoesNotMatchNonTemplate) {
4219 EXPECT_TRUE(notMatches(
4220 "class A {}; class Y { A a; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00004221 cxxRecordDecl(isTemplateInstantiation())));
Manuel Klimek04616e42012-07-06 05:48:52 +00004222}
4223
Benjamin Kramer7ab84762014-09-03 12:08:14 +00004224TEST(IsInstantiated, MatchesInstantiation) {
4225 EXPECT_TRUE(
4226 matches("template<typename T> class A { T i; }; class Y { A<int> a; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00004227 cxxRecordDecl(isInstantiated())));
Benjamin Kramer7ab84762014-09-03 12:08:14 +00004228}
4229
4230TEST(IsInstantiated, NotMatchesDefinition) {
4231 EXPECT_TRUE(notMatches("template<typename T> class A { T i; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00004232 cxxRecordDecl(isInstantiated())));
Benjamin Kramer7ab84762014-09-03 12:08:14 +00004233}
4234
4235TEST(IsInTemplateInstantiation, MatchesInstantiationStmt) {
4236 EXPECT_TRUE(matches("template<typename T> struct A { A() { T i; } };"
4237 "class Y { A<int> a; }; Y y;",
4238 declStmt(isInTemplateInstantiation())));
4239}
4240
4241TEST(IsInTemplateInstantiation, NotMatchesDefinitionStmt) {
4242 EXPECT_TRUE(notMatches("template<typename T> struct A { void x() { T i; } };",
4243 declStmt(isInTemplateInstantiation())));
4244}
4245
4246TEST(IsInstantiated, MatchesFunctionInstantiation) {
4247 EXPECT_TRUE(
4248 matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
4249 functionDecl(isInstantiated())));
4250}
4251
4252TEST(IsInstantiated, NotMatchesFunctionDefinition) {
4253 EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
4254 varDecl(isInstantiated())));
4255}
4256
4257TEST(IsInTemplateInstantiation, MatchesFunctionInstantiationStmt) {
4258 EXPECT_TRUE(
4259 matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
4260 declStmt(isInTemplateInstantiation())));
4261}
4262
4263TEST(IsInTemplateInstantiation, NotMatchesFunctionDefinitionStmt) {
4264 EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
4265 declStmt(isInTemplateInstantiation())));
4266}
4267
4268TEST(IsInTemplateInstantiation, Sharing) {
4269 auto Matcher = binaryOperator(unless(isInTemplateInstantiation()));
4270 // FIXME: Node sharing is an implementation detail, exposing it is ugly
4271 // and makes the matcher behave in non-obvious ways.
4272 EXPECT_TRUE(notMatches(
4273 "int j; template<typename T> void A(T t) { j += 42; } void x() { A(0); }",
4274 Matcher));
4275 EXPECT_TRUE(matches(
4276 "int j; template<typename T> void A(T t) { j += t; } void x() { A(0); }",
4277 Matcher));
4278}
4279
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004280TEST(IsExplicitTemplateSpecialization,
4281 DoesNotMatchPrimaryTemplate) {
4282 EXPECT_TRUE(notMatches(
4283 "template <typename T> class X {};",
Aaron Ballman512fb642015-09-17 13:30:52 +00004284 cxxRecordDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004285 EXPECT_TRUE(notMatches(
4286 "template <typename T> void f(T t);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004287 functionDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004288}
4289
4290TEST(IsExplicitTemplateSpecialization,
4291 DoesNotMatchExplicitTemplateInstantiations) {
4292 EXPECT_TRUE(notMatches(
4293 "template <typename T> class X {};"
4294 "template class X<int>; extern template class X<long>;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004295 cxxRecordDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004296 EXPECT_TRUE(notMatches(
4297 "template <typename T> void f(T t) {}"
4298 "template void f(int t); extern template void f(long t);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004299 functionDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004300}
4301
4302TEST(IsExplicitTemplateSpecialization,
4303 DoesNotMatchImplicitTemplateInstantiations) {
4304 EXPECT_TRUE(notMatches(
4305 "template <typename T> class X {}; X<int> x;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004306 cxxRecordDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004307 EXPECT_TRUE(notMatches(
4308 "template <typename T> void f(T t); void g() { f(10); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004309 functionDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004310}
4311
4312TEST(IsExplicitTemplateSpecialization,
4313 MatchesExplicitTemplateSpecializations) {
4314 EXPECT_TRUE(matches(
4315 "template <typename T> class X {};"
4316 "template<> class X<int> {};",
Aaron Ballman512fb642015-09-17 13:30:52 +00004317 cxxRecordDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004318 EXPECT_TRUE(matches(
4319 "template <typename T> void f(T t) {}"
4320 "template<> void f(int t) {}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004321 functionDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004322}
4323
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004324TEST(HasAncenstor, MatchesDeclarationAncestors) {
4325 EXPECT_TRUE(matches(
4326 "class A { class B { class C {}; }; };",
4327 recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("A"))))));
4328}
4329
4330TEST(HasAncenstor, FailsIfNoAncestorMatches) {
4331 EXPECT_TRUE(notMatches(
4332 "class A { class B { class C {}; }; };",
4333 recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("X"))))));
4334}
4335
4336TEST(HasAncestor, MatchesDeclarationsThatGetVisitedLater) {
4337 EXPECT_TRUE(matches(
4338 "class A { class B { void f() { C c; } class C {}; }; };",
4339 varDecl(hasName("c"), hasType(recordDecl(hasName("C"),
4340 hasAncestor(recordDecl(hasName("A"))))))));
4341}
4342
4343TEST(HasAncenstor, MatchesStatementAncestors) {
4344 EXPECT_TRUE(matches(
4345 "void f() { if (true) { while (false) { 42; } } }",
Daniel Jasper848cbe12012-09-18 13:09:13 +00004346 integerLiteral(equals(42), hasAncestor(ifStmt()))));
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004347}
4348
4349TEST(HasAncestor, DrillsThroughDifferentHierarchies) {
4350 EXPECT_TRUE(matches(
4351 "void f() { if (true) { int x = 42; } }",
Daniel Jasper848cbe12012-09-18 13:09:13 +00004352 integerLiteral(equals(42), hasAncestor(functionDecl(hasName("f"))))));
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004353}
4354
4355TEST(HasAncestor, BindsRecursiveCombinations) {
4356 EXPECT_TRUE(matchAndVerifyResultTrue(
4357 "class C { class D { class E { class F { int y; }; }; }; };",
4358 fieldDecl(hasAncestor(recordDecl(hasAncestor(recordDecl().bind("r"))))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00004359 new VerifyIdIsBoundTo<CXXRecordDecl>("r", 1)));
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004360}
4361
4362TEST(HasAncestor, BindsCombinationsWithHasDescendant) {
4363 EXPECT_TRUE(matchAndVerifyResultTrue(
4364 "class C { class D { class E { class F { int y; }; }; }; };",
4365 fieldDecl(hasAncestor(
4366 decl(
4367 hasDescendant(recordDecl(isDefinition(),
4368 hasAncestor(recordDecl())))
4369 ).bind("d")
4370 )),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00004371 new VerifyIdIsBoundTo<CXXRecordDecl>("d", "E")));
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004372}
4373
Manuel Klimekb64d6b72013-03-14 16:33:21 +00004374TEST(HasAncestor, MatchesClosestAncestor) {
4375 EXPECT_TRUE(matchAndVerifyResultTrue(
4376 "template <typename T> struct C {"
4377 " void f(int) {"
4378 " struct I { void g(T) { int x; } } i; i.g(42);"
4379 " }"
4380 "};"
4381 "template struct C<int>;",
4382 varDecl(hasName("x"),
4383 hasAncestor(functionDecl(hasParameter(
4384 0, varDecl(hasType(asString("int"))))).bind("f"))).bind("v"),
4385 new VerifyIdIsBoundTo<FunctionDecl>("f", "g", 2)));
4386}
4387
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004388TEST(HasAncestor, MatchesInTemplateInstantiations) {
4389 EXPECT_TRUE(matches(
4390 "template <typename T> struct A { struct B { struct C { T t; }; }; }; "
4391 "A<int>::B::C a;",
4392 fieldDecl(hasType(asString("int")),
4393 hasAncestor(recordDecl(hasName("A"))))));
4394}
4395
4396TEST(HasAncestor, MatchesInImplicitCode) {
4397 EXPECT_TRUE(matches(
4398 "struct X {}; struct A { A() {} X x; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00004399 cxxConstructorDecl(
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004400 hasAnyConstructorInitializer(withInitializer(expr(
4401 hasAncestor(recordDecl(hasName("A")))))))));
4402}
4403
Daniel Jasper632aea92012-10-22 16:26:51 +00004404TEST(HasParent, MatchesOnlyParent) {
4405 EXPECT_TRUE(matches(
4406 "void f() { if (true) { int x = 42; } }",
4407 compoundStmt(hasParent(ifStmt()))));
4408 EXPECT_TRUE(notMatches(
4409 "void f() { for (;;) { int x = 42; } }",
4410 compoundStmt(hasParent(ifStmt()))));
4411 EXPECT_TRUE(notMatches(
4412 "void f() { if (true) for (;;) { int x = 42; } }",
4413 compoundStmt(hasParent(ifStmt()))));
4414}
4415
Manuel Klimekc844a462012-12-06 14:42:48 +00004416TEST(HasAncestor, MatchesAllAncestors) {
4417 EXPECT_TRUE(matches(
4418 "template <typename T> struct C { static void f() { 42; } };"
4419 "void t() { C<int>::f(); }",
4420 integerLiteral(
4421 equals(42),
Aaron Ballman512fb642015-09-17 13:30:52 +00004422 allOf(
4423 hasAncestor(cxxRecordDecl(isTemplateInstantiation())),
4424 hasAncestor(cxxRecordDecl(unless(isTemplateInstantiation())))))));
Manuel Klimekc844a462012-12-06 14:42:48 +00004425}
4426
Nico Weberc4acee32016-01-22 15:11:54 +00004427TEST(HasAncestor, ImplicitArrayCopyCtorDeclRefExpr) {
4428 EXPECT_TRUE(matches("struct MyClass {\n"
4429 " int c[1];\n"
4430 " static MyClass Create() { return MyClass(); }\n"
4431 "};",
4432 declRefExpr(to(decl(hasAncestor(decl()))))));
4433}
4434
Nico Weber7b837f52016-01-28 19:25:00 +00004435TEST(HasAncestor, AnonymousUnionMemberExpr) {
4436 EXPECT_TRUE(matches("int F() {\n"
4437 " union { int i; };\n"
4438 " return i;\n"
4439 "}\n",
4440 memberExpr(member(hasAncestor(decl())))));
4441 EXPECT_TRUE(matches("void f() {\n"
4442 " struct {\n"
4443 " struct { int a; int b; };\n"
4444 " } s;\n"
4445 " s.a = 4;\n"
4446 "}\n",
4447 memberExpr(member(hasAncestor(decl())))));
4448 EXPECT_TRUE(matches("void f() {\n"
4449 " struct {\n"
4450 " struct { int a; int b; };\n"
4451 " } s;\n"
4452 " s.a = 4;\n"
4453 "}\n",
4454 declRefExpr(to(decl(hasAncestor(decl()))))));
4455}
4456
Nico Weberc0973372016-02-01 22:31:51 +00004457TEST(HasAncestor, NonParmDependentTemplateParmVarDeclRefExpr) {
4458 EXPECT_TRUE(matches("struct PartitionAllocator {\n"
4459 " template<typename T>\n"
4460 " static int quantizedSize(int count) {\n"
4461 " return count;\n"
4462 " }\n"
4463 " void f() { quantizedSize<int>(10); }\n"
4464 "};",
4465 declRefExpr(to(decl(hasAncestor(decl()))))));
4466}
4467
Nico Weber26911c72016-02-08 22:23:09 +00004468TEST(HasAncestor, AddressOfExplicitSpecializationFunction) {
4469 EXPECT_TRUE(matches("template <class T> void f();\n"
4470 "template <> void f<int>();\n"
4471 "void (*get_f())() { return f<int>; }\n",
4472 declRefExpr(to(decl(hasAncestor(decl()))))));
4473}
4474
Manuel Klimekc844a462012-12-06 14:42:48 +00004475TEST(HasParent, MatchesAllParents) {
4476 EXPECT_TRUE(matches(
4477 "template <typename T> struct C { static void f() { 42; } };"
4478 "void t() { C<int>::f(); }",
4479 integerLiteral(
4480 equals(42),
4481 hasParent(compoundStmt(hasParent(functionDecl(
Aaron Ballman512fb642015-09-17 13:30:52 +00004482 hasParent(cxxRecordDecl(isTemplateInstantiation())))))))));
4483 EXPECT_TRUE(
4484 matches("template <typename T> struct C { static void f() { 42; } };"
4485 "void t() { C<int>::f(); }",
4486 integerLiteral(
4487 equals(42),
4488 hasParent(compoundStmt(hasParent(functionDecl(hasParent(
4489 cxxRecordDecl(unless(isTemplateInstantiation()))))))))));
Manuel Klimekc844a462012-12-06 14:42:48 +00004490 EXPECT_TRUE(matches(
4491 "template <typename T> struct C { static void f() { 42; } };"
4492 "void t() { C<int>::f(); }",
4493 integerLiteral(equals(42),
Aaron Ballman512fb642015-09-17 13:30:52 +00004494 hasParent(compoundStmt(
4495 allOf(hasParent(functionDecl(hasParent(
4496 cxxRecordDecl(isTemplateInstantiation())))),
4497 hasParent(functionDecl(hasParent(cxxRecordDecl(
4498 unless(isTemplateInstantiation())))))))))));
Manuel Klimekb64d6b72013-03-14 16:33:21 +00004499 EXPECT_TRUE(
4500 notMatches("template <typename T> struct C { static void f() {} };"
4501 "void t() { C<int>::f(); }",
4502 compoundStmt(hasParent(recordDecl()))));
Manuel Klimekc844a462012-12-06 14:42:48 +00004503}
4504
Samuel Benzaquen3ca0a7b2014-06-13 13:31:40 +00004505TEST(HasParent, NoDuplicateParents) {
4506 class HasDuplicateParents : public BoundNodesCallback {
4507 public:
4508 bool run(const BoundNodes *Nodes) override { return false; }
4509 bool run(const BoundNodes *Nodes, ASTContext *Context) override {
4510 const Stmt *Node = Nodes->getNodeAs<Stmt>("node");
4511 std::set<const void *> Parents;
4512 for (const auto &Parent : Context->getParents(*Node)) {
4513 if (!Parents.insert(Parent.getMemoizationData()).second) {
4514 return true;
4515 }
4516 }
4517 return false;
4518 }
4519 };
4520 EXPECT_FALSE(matchAndVerifyResultTrue(
4521 "template <typename T> int Foo() { return 1 + 2; }\n"
4522 "int x = Foo<int>() + Foo<unsigned>();",
4523 stmt().bind("node"), new HasDuplicateParents()));
4524}
4525
Daniel Jasper516b02e2012-10-17 08:52:59 +00004526TEST(TypeMatching, MatchesTypes) {
4527 EXPECT_TRUE(matches("struct S {};", qualType().bind("loc")));
4528}
4529
Samuel Benzaquenbd3232a2015-12-22 20:06:40 +00004530TEST(TypeMatching, MatchesBool) {
4531 EXPECT_TRUE(matches("struct S { bool func(); };",
4532 cxxMethodDecl(returns(booleanType()))));
4533 EXPECT_TRUE(notMatches("struct S { void func(); };",
4534 cxxMethodDecl(returns(booleanType()))));
4535}
4536
Samuel Benzaquenb405c082014-12-15 15:09:22 +00004537TEST(TypeMatching, MatchesVoid) {
Aaron Ballman512fb642015-09-17 13:30:52 +00004538 EXPECT_TRUE(matches("struct S { void func(); };",
4539 cxxMethodDecl(returns(voidType()))));
Samuel Benzaquenb405c082014-12-15 15:09:22 +00004540}
4541
Aaron Ballmaneb7e5d92016-02-18 16:36:01 +00004542TEST(TypeMatching, MatchesRealFloats) {
4543 EXPECT_TRUE(matches("struct S { float func(); };",
4544 cxxMethodDecl(returns(realFloatingPointType()))));
4545 EXPECT_TRUE(notMatches("struct S { int func(); };",
4546 cxxMethodDecl(returns(realFloatingPointType()))));
4547 EXPECT_TRUE(matches("struct S { long double func(); };",
4548 cxxMethodDecl(returns(realFloatingPointType()))));
4549}
4550
Daniel Jasper516b02e2012-10-17 08:52:59 +00004551TEST(TypeMatching, MatchesArrayTypes) {
4552 EXPECT_TRUE(matches("int a[] = {2,3};", arrayType()));
4553 EXPECT_TRUE(matches("int a[42];", arrayType()));
4554 EXPECT_TRUE(matches("void f(int b) { int a[b]; }", arrayType()));
4555
4556 EXPECT_TRUE(notMatches("struct A {}; A a[7];",
4557 arrayType(hasElementType(builtinType()))));
4558
4559 EXPECT_TRUE(matches(
4560 "int const a[] = { 2, 3 };",
4561 qualType(arrayType(hasElementType(builtinType())))));
4562 EXPECT_TRUE(matches(
4563 "int const a[] = { 2, 3 };",
4564 qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
4565 EXPECT_TRUE(matches(
4566 "typedef const int T; T x[] = { 1, 2 };",
4567 qualType(isConstQualified(), arrayType())));
4568
4569 EXPECT_TRUE(notMatches(
4570 "int a[] = { 2, 3 };",
4571 qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
4572 EXPECT_TRUE(notMatches(
4573 "int a[] = { 2, 3 };",
4574 qualType(arrayType(hasElementType(isConstQualified(), builtinType())))));
4575 EXPECT_TRUE(notMatches(
4576 "int const a[] = { 2, 3 };",
4577 qualType(arrayType(hasElementType(builtinType())),
4578 unless(isConstQualified()))));
4579
4580 EXPECT_TRUE(matches("int a[2];",
4581 constantArrayType(hasElementType(builtinType()))));
4582 EXPECT_TRUE(matches("const int a = 0;", qualType(isInteger())));
4583}
4584
Matthias Gehre2cf7e802015-10-12 21:46:07 +00004585TEST(TypeMatching, DecayedType) {
4586 EXPECT_TRUE(matches("void f(int i[]);", valueDecl(hasType(decayedType(hasDecayedType(pointerType()))))));
4587 EXPECT_TRUE(notMatches("int i[7];", decayedType()));
4588}
4589
Daniel Jasper516b02e2012-10-17 08:52:59 +00004590TEST(TypeMatching, MatchesComplexTypes) {
4591 EXPECT_TRUE(matches("_Complex float f;", complexType()));
4592 EXPECT_TRUE(matches(
4593 "_Complex float f;",
4594 complexType(hasElementType(builtinType()))));
4595 EXPECT_TRUE(notMatches(
4596 "_Complex float f;",
4597 complexType(hasElementType(isInteger()))));
4598}
4599
4600TEST(TypeMatching, MatchesConstantArrayTypes) {
4601 EXPECT_TRUE(matches("int a[2];", constantArrayType()));
4602 EXPECT_TRUE(notMatches(
4603 "void f() { int a[] = { 2, 3 }; int b[a[0]]; }",
4604 constantArrayType(hasElementType(builtinType()))));
4605
4606 EXPECT_TRUE(matches("int a[42];", constantArrayType(hasSize(42))));
4607 EXPECT_TRUE(matches("int b[2*21];", constantArrayType(hasSize(42))));
4608 EXPECT_TRUE(notMatches("int c[41], d[43];", constantArrayType(hasSize(42))));
4609}
4610
4611TEST(TypeMatching, MatchesDependentSizedArrayTypes) {
4612 EXPECT_TRUE(matches(
4613 "template <typename T, int Size> class array { T data[Size]; };",
4614 dependentSizedArrayType()));
4615 EXPECT_TRUE(notMatches(
4616 "int a[42]; int b[] = { 2, 3 }; void f() { int c[b[0]]; }",
4617 dependentSizedArrayType()));
4618}
4619
4620TEST(TypeMatching, MatchesIncompleteArrayType) {
4621 EXPECT_TRUE(matches("int a[] = { 2, 3 };", incompleteArrayType()));
4622 EXPECT_TRUE(matches("void f(int a[]) {}", incompleteArrayType()));
4623
4624 EXPECT_TRUE(notMatches("int a[42]; void f() { int b[a[0]]; }",
4625 incompleteArrayType()));
4626}
4627
4628TEST(TypeMatching, MatchesVariableArrayType) {
4629 EXPECT_TRUE(matches("void f(int b) { int a[b]; }", variableArrayType()));
4630 EXPECT_TRUE(notMatches("int a[] = {2, 3}; int b[42];", variableArrayType()));
4631
4632 EXPECT_TRUE(matches(
4633 "void f(int b) { int a[b]; }",
4634 variableArrayType(hasSizeExpr(ignoringImpCasts(declRefExpr(to(
4635 varDecl(hasName("b")))))))));
4636}
4637
4638TEST(TypeMatching, MatchesAtomicTypes) {
David Majnemer197e2102014-03-05 06:32:38 +00004639 if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getOS() !=
4640 llvm::Triple::Win32) {
4641 // FIXME: Make this work for MSVC.
4642 EXPECT_TRUE(matches("_Atomic(int) i;", atomicType()));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004643
David Majnemer197e2102014-03-05 06:32:38 +00004644 EXPECT_TRUE(matches("_Atomic(int) i;",
4645 atomicType(hasValueType(isInteger()))));
4646 EXPECT_TRUE(notMatches("_Atomic(float) f;",
4647 atomicType(hasValueType(isInteger()))));
4648 }
Daniel Jasper516b02e2012-10-17 08:52:59 +00004649}
4650
4651TEST(TypeMatching, MatchesAutoTypes) {
4652 EXPECT_TRUE(matches("auto i = 2;", autoType()));
4653 EXPECT_TRUE(matches("int v[] = { 2, 3 }; void f() { for (int i : v) {} }",
4654 autoType()));
4655
Richard Smith061f1e22013-04-30 21:23:01 +00004656 // FIXME: Matching against the type-as-written can't work here, because the
4657 // type as written was not deduced.
4658 //EXPECT_TRUE(matches("auto a = 1;",
4659 // autoType(hasDeducedType(isInteger()))));
4660 //EXPECT_TRUE(notMatches("auto b = 2.0;",
4661 // autoType(hasDeducedType(isInteger()))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004662}
4663
Daniel Jasperd29d5fa2012-10-29 10:14:44 +00004664TEST(TypeMatching, MatchesFunctionTypes) {
4665 EXPECT_TRUE(matches("int (*f)(int);", functionType()));
4666 EXPECT_TRUE(matches("void f(int i) {}", functionType()));
4667}
4668
Aaron Ballman7e7b7b22016-02-01 14:11:47 +00004669TEST(TypeMatching, MatchesFunctionProtoTypes) {
4670 EXPECT_TRUE(matches("int (*f)(int);", functionProtoType()));
4671 EXPECT_TRUE(matches("void f(int i);", functionProtoType()));
4672 EXPECT_TRUE(matches("void f();", functionProtoType(parameterCountIs(0))));
4673 EXPECT_TRUE(notMatchesC("void f();", functionProtoType()));
4674 EXPECT_TRUE(
4675 matchesC("void f(void);", functionProtoType(parameterCountIs(0))));
4676}
4677
Edwin Vaneec074802013-04-01 18:33:34 +00004678TEST(TypeMatching, MatchesParenType) {
4679 EXPECT_TRUE(
4680 matches("int (*array)[4];", varDecl(hasType(pointsTo(parenType())))));
4681 EXPECT_TRUE(notMatches("int *array[4];", varDecl(hasType(parenType()))));
4682
4683 EXPECT_TRUE(matches(
4684 "int (*ptr_to_func)(int);",
4685 varDecl(hasType(pointsTo(parenType(innerType(functionType())))))));
4686 EXPECT_TRUE(notMatches(
4687 "int (*ptr_to_array)[4];",
4688 varDecl(hasType(pointsTo(parenType(innerType(functionType())))))));
4689}
4690
Daniel Jasper516b02e2012-10-17 08:52:59 +00004691TEST(TypeMatching, PointerTypes) {
Daniel Jasper7943eb52012-10-17 13:35:36 +00004692 // FIXME: Reactive when these tests can be more specific (not matching
4693 // implicit code on certain platforms), likely when we have hasDescendant for
4694 // Types/TypeLocs.
4695 //EXPECT_TRUE(matchAndVerifyResultTrue(
4696 // "int* a;",
4697 // pointerTypeLoc(pointeeLoc(typeLoc().bind("loc"))),
4698 // new VerifyIdIsBoundTo<TypeLoc>("loc", 1)));
4699 //EXPECT_TRUE(matchAndVerifyResultTrue(
4700 // "int* a;",
4701 // pointerTypeLoc().bind("loc"),
4702 // new VerifyIdIsBoundTo<TypeLoc>("loc", 1)));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004703 EXPECT_TRUE(matches(
4704 "int** a;",
David Blaikieb61d0872013-02-18 19:04:16 +00004705 loc(pointerType(pointee(qualType())))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004706 EXPECT_TRUE(matches(
4707 "int** a;",
4708 loc(pointerType(pointee(pointerType())))));
4709 EXPECT_TRUE(matches(
4710 "int* b; int* * const a = &b;",
4711 loc(qualType(isConstQualified(), pointerType()))));
4712
4713 std::string Fragment = "struct A { int i; }; int A::* ptr = &A::i;";
Daniel Jasper7943eb52012-10-17 13:35:36 +00004714 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4715 hasType(blockPointerType()))));
4716 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ptr"),
4717 hasType(memberPointerType()))));
4718 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4719 hasType(pointerType()))));
4720 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4721 hasType(referenceType()))));
Edwin Vane2a760d02013-03-07 15:44:40 +00004722 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4723 hasType(lValueReferenceType()))));
4724 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4725 hasType(rValueReferenceType()))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004726
Daniel Jasper7943eb52012-10-17 13:35:36 +00004727 Fragment = "int *ptr;";
4728 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4729 hasType(blockPointerType()))));
4730 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4731 hasType(memberPointerType()))));
4732 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ptr"),
4733 hasType(pointerType()))));
4734 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4735 hasType(referenceType()))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004736
Daniel Jasper7943eb52012-10-17 13:35:36 +00004737 Fragment = "int a; int &ref = a;";
4738 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4739 hasType(blockPointerType()))));
4740 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4741 hasType(memberPointerType()))));
4742 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4743 hasType(pointerType()))));
4744 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
4745 hasType(referenceType()))));
Edwin Vane2a760d02013-03-07 15:44:40 +00004746 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
4747 hasType(lValueReferenceType()))));
4748 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4749 hasType(rValueReferenceType()))));
4750
4751 Fragment = "int &&ref = 2;";
4752 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4753 hasType(blockPointerType()))));
4754 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4755 hasType(memberPointerType()))));
4756 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4757 hasType(pointerType()))));
4758 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
4759 hasType(referenceType()))));
4760 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4761 hasType(lValueReferenceType()))));
4762 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
4763 hasType(rValueReferenceType()))));
4764}
4765
4766TEST(TypeMatching, AutoRefTypes) {
4767 std::string Fragment = "auto a = 1;"
4768 "auto b = a;"
4769 "auto &c = a;"
4770 "auto &&d = c;"
4771 "auto &&e = 2;";
4772 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("a"),
4773 hasType(referenceType()))));
4774 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("b"),
4775 hasType(referenceType()))));
4776 EXPECT_TRUE(matches(Fragment, varDecl(hasName("c"),
4777 hasType(referenceType()))));
4778 EXPECT_TRUE(matches(Fragment, varDecl(hasName("c"),
4779 hasType(lValueReferenceType()))));
4780 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("c"),
4781 hasType(rValueReferenceType()))));
4782 EXPECT_TRUE(matches(Fragment, varDecl(hasName("d"),
4783 hasType(referenceType()))));
4784 EXPECT_TRUE(matches(Fragment, varDecl(hasName("d"),
4785 hasType(lValueReferenceType()))));
4786 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("d"),
4787 hasType(rValueReferenceType()))));
4788 EXPECT_TRUE(matches(Fragment, varDecl(hasName("e"),
4789 hasType(referenceType()))));
4790 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("e"),
4791 hasType(lValueReferenceType()))));
4792 EXPECT_TRUE(matches(Fragment, varDecl(hasName("e"),
4793 hasType(rValueReferenceType()))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004794}
4795
4796TEST(TypeMatching, PointeeTypes) {
4797 EXPECT_TRUE(matches("int b; int &a = b;",
4798 referenceType(pointee(builtinType()))));
4799 EXPECT_TRUE(matches("int *a;", pointerType(pointee(builtinType()))));
4800
4801 EXPECT_TRUE(matches("int *a;",
David Blaikieb61d0872013-02-18 19:04:16 +00004802 loc(pointerType(pointee(builtinType())))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004803
4804 EXPECT_TRUE(matches(
4805 "int const *A;",
4806 pointerType(pointee(isConstQualified(), builtinType()))));
4807 EXPECT_TRUE(notMatches(
4808 "int *A;",
4809 pointerType(pointee(isConstQualified(), builtinType()))));
4810}
4811
4812TEST(TypeMatching, MatchesPointersToConstTypes) {
4813 EXPECT_TRUE(matches("int b; int * const a = &b;",
4814 loc(pointerType())));
4815 EXPECT_TRUE(matches("int b; int * const a = &b;",
David Blaikieb61d0872013-02-18 19:04:16 +00004816 loc(pointerType())));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004817 EXPECT_TRUE(matches(
4818 "int b; const int * a = &b;",
David Blaikieb61d0872013-02-18 19:04:16 +00004819 loc(pointerType(pointee(builtinType())))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004820 EXPECT_TRUE(matches(
4821 "int b; const int * a = &b;",
4822 pointerType(pointee(builtinType()))));
4823}
4824
4825TEST(TypeMatching, MatchesTypedefTypes) {
Daniel Jasper7943eb52012-10-17 13:35:36 +00004826 EXPECT_TRUE(matches("typedef int X; X a;", varDecl(hasName("a"),
4827 hasType(typedefType()))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004828}
4829
Edwin Vanef901b712013-02-25 14:49:29 +00004830TEST(TypeMatching, MatchesTemplateSpecializationType) {
Edwin Vaneb6eae142013-02-25 20:43:32 +00004831 EXPECT_TRUE(matches("template <typename T> class A{}; A<int> a;",
Edwin Vanef901b712013-02-25 14:49:29 +00004832 templateSpecializationType()));
4833}
4834
Edwin Vaneb6eae142013-02-25 20:43:32 +00004835TEST(TypeMatching, MatchesRecordType) {
4836 EXPECT_TRUE(matches("class C{}; C c;", recordType()));
Manuel Klimek59b0af62013-02-27 11:56:58 +00004837 EXPECT_TRUE(matches("struct S{}; S s;",
4838 recordType(hasDeclaration(recordDecl(hasName("S"))))));
4839 EXPECT_TRUE(notMatches("int i;",
4840 recordType(hasDeclaration(recordDecl(hasName("S"))))));
Edwin Vaneb6eae142013-02-25 20:43:32 +00004841}
4842
4843TEST(TypeMatching, MatchesElaboratedType) {
4844 EXPECT_TRUE(matches(
4845 "namespace N {"
4846 " namespace M {"
4847 " class D {};"
4848 " }"
4849 "}"
4850 "N::M::D d;", elaboratedType()));
4851 EXPECT_TRUE(matches("class C {} c;", elaboratedType()));
4852 EXPECT_TRUE(notMatches("class C {}; C c;", elaboratedType()));
4853}
4854
4855TEST(ElaboratedTypeNarrowing, hasQualifier) {
4856 EXPECT_TRUE(matches(
4857 "namespace N {"
4858 " namespace M {"
4859 " class D {};"
4860 " }"
4861 "}"
4862 "N::M::D d;",
4863 elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
4864 EXPECT_TRUE(notMatches(
4865 "namespace M {"
4866 " class D {};"
4867 "}"
4868 "M::D d;",
4869 elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
Edwin Vane6972f6d2013-03-04 17:51:00 +00004870 EXPECT_TRUE(notMatches(
4871 "struct D {"
4872 "} d;",
4873 elaboratedType(hasQualifier(nestedNameSpecifier()))));
Edwin Vaneb6eae142013-02-25 20:43:32 +00004874}
4875
4876TEST(ElaboratedTypeNarrowing, namesType) {
4877 EXPECT_TRUE(matches(
4878 "namespace N {"
4879 " namespace M {"
4880 " class D {};"
4881 " }"
4882 "}"
4883 "N::M::D d;",
4884 elaboratedType(elaboratedType(namesType(recordType(
4885 hasDeclaration(namedDecl(hasName("D")))))))));
4886 EXPECT_TRUE(notMatches(
4887 "namespace M {"
4888 " class D {};"
4889 "}"
4890 "M::D d;",
4891 elaboratedType(elaboratedType(namesType(typedefType())))));
4892}
4893
Samuel Benzaquenf8ec4542015-08-26 16:15:59 +00004894TEST(TypeMatching, MatchesSubstTemplateTypeParmType) {
4895 const std::string code = "template <typename T>"
4896 "int F() {"
4897 " return 1 + T();"
4898 "}"
4899 "int i = F<int>();";
4900 EXPECT_FALSE(matches(code, binaryOperator(hasLHS(
4901 expr(hasType(substTemplateTypeParmType()))))));
4902 EXPECT_TRUE(matches(code, binaryOperator(hasRHS(
4903 expr(hasType(substTemplateTypeParmType()))))));
4904}
4905
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00004906TEST(NNS, MatchesNestedNameSpecifiers) {
4907 EXPECT_TRUE(matches("namespace ns { struct A {}; } ns::A a;",
4908 nestedNameSpecifier()));
4909 EXPECT_TRUE(matches("template <typename T> class A { typename T::B b; };",
4910 nestedNameSpecifier()));
4911 EXPECT_TRUE(matches("struct A { void f(); }; void A::f() {}",
4912 nestedNameSpecifier()));
Daniel Jasperc8f472c2015-12-02 13:57:46 +00004913 EXPECT_TRUE(matches("namespace a { namespace b {} } namespace ab = a::b;",
4914 nestedNameSpecifier()));
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00004915
4916 EXPECT_TRUE(matches(
4917 "struct A { static void f() {} }; void g() { A::f(); }",
4918 nestedNameSpecifier()));
4919 EXPECT_TRUE(notMatches(
4920 "struct A { static void f() {} }; void g(A* a) { a->f(); }",
4921 nestedNameSpecifier()));
4922}
4923
Daniel Jasper87c3d362012-09-20 14:12:57 +00004924TEST(NullStatement, SimpleCases) {
4925 EXPECT_TRUE(matches("void f() {int i;;}", nullStmt()));
4926 EXPECT_TRUE(notMatches("void f() {int i;}", nullStmt()));
4927}
4928
Aaron Ballman11825f22015-08-18 19:55:20 +00004929TEST(NS, Anonymous) {
4930 EXPECT_TRUE(notMatches("namespace N {}", namespaceDecl(isAnonymous())));
4931 EXPECT_TRUE(matches("namespace {}", namespaceDecl(isAnonymous())));
4932}
4933
Aaron Ballman6c79f352015-08-28 19:39:21 +00004934TEST(NS, Alias) {
4935 EXPECT_TRUE(matches("namespace test {} namespace alias = ::test;",
4936 namespaceAliasDecl(hasName("alias"))));
4937}
4938
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00004939TEST(NNS, MatchesTypes) {
4940 NestedNameSpecifierMatcher Matcher = nestedNameSpecifier(
4941 specifiesType(hasDeclaration(recordDecl(hasName("A")))));
4942 EXPECT_TRUE(matches("struct A { struct B {}; }; A::B b;", Matcher));
4943 EXPECT_TRUE(matches("struct A { struct B { struct C {}; }; }; A::B::C c;",
4944 Matcher));
4945 EXPECT_TRUE(notMatches("namespace A { struct B {}; } A::B b;", Matcher));
4946}
4947
4948TEST(NNS, MatchesNamespaceDecls) {
4949 NestedNameSpecifierMatcher Matcher = nestedNameSpecifier(
4950 specifiesNamespace(hasName("ns")));
4951 EXPECT_TRUE(matches("namespace ns { struct A {}; } ns::A a;", Matcher));
4952 EXPECT_TRUE(notMatches("namespace xx { struct A {}; } xx::A a;", Matcher));
4953 EXPECT_TRUE(notMatches("struct ns { struct A {}; }; ns::A a;", Matcher));
4954}
4955
4956TEST(NNS, BindsNestedNameSpecifiers) {
4957 EXPECT_TRUE(matchAndVerifyResultTrue(
4958 "namespace ns { struct E { struct B {}; }; } ns::E::B b;",
4959 nestedNameSpecifier(specifiesType(asString("struct ns::E"))).bind("nns"),
4960 new VerifyIdIsBoundTo<NestedNameSpecifier>("nns", "ns::struct E::")));
4961}
4962
4963TEST(NNS, BindsNestedNameSpecifierLocs) {
4964 EXPECT_TRUE(matchAndVerifyResultTrue(
4965 "namespace ns { struct B {}; } ns::B b;",
4966 loc(nestedNameSpecifier()).bind("loc"),
4967 new VerifyIdIsBoundTo<NestedNameSpecifierLoc>("loc", 1)));
4968}
4969
4970TEST(NNS, MatchesNestedNameSpecifierPrefixes) {
4971 EXPECT_TRUE(matches(
4972 "struct A { struct B { struct C {}; }; }; A::B::C c;",
4973 nestedNameSpecifier(hasPrefix(specifiesType(asString("struct A"))))));
4974 EXPECT_TRUE(matches(
4975 "struct A { struct B { struct C {}; }; }; A::B::C c;",
Daniel Jasper516b02e2012-10-17 08:52:59 +00004976 nestedNameSpecifierLoc(hasPrefix(
4977 specifiesTypeLoc(loc(qualType(asString("struct A"))))))));
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00004978}
4979
Daniel Jasper6fc34332012-10-30 15:42:00 +00004980TEST(NNS, DescendantsOfNestedNameSpecifiers) {
4981 std::string Fragment =
4982 "namespace a { struct A { struct B { struct C {}; }; }; };"
4983 "void f() { a::A::B::C c; }";
4984 EXPECT_TRUE(matches(
4985 Fragment,
4986 nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
4987 hasDescendant(nestedNameSpecifier(
4988 specifiesNamespace(hasName("a")))))));
4989 EXPECT_TRUE(notMatches(
4990 Fragment,
4991 nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
4992 has(nestedNameSpecifier(
4993 specifiesNamespace(hasName("a")))))));
4994 EXPECT_TRUE(matches(
4995 Fragment,
4996 nestedNameSpecifier(specifiesType(asString("struct a::A")),
4997 has(nestedNameSpecifier(
4998 specifiesNamespace(hasName("a")))))));
4999
5000 // Not really useful because a NestedNameSpecifier can af at most one child,
5001 // but to complete the interface.
5002 EXPECT_TRUE(matchAndVerifyResultTrue(
5003 Fragment,
5004 nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
5005 forEach(nestedNameSpecifier().bind("x"))),
5006 new VerifyIdIsBoundTo<NestedNameSpecifier>("x", 1)));
5007}
5008
5009TEST(NNS, NestedNameSpecifiersAsDescendants) {
5010 std::string Fragment =
5011 "namespace a { struct A { struct B { struct C {}; }; }; };"
5012 "void f() { a::A::B::C c; }";
5013 EXPECT_TRUE(matches(
5014 Fragment,
5015 decl(hasDescendant(nestedNameSpecifier(specifiesType(
5016 asString("struct a::A")))))));
5017 EXPECT_TRUE(matchAndVerifyResultTrue(
5018 Fragment,
5019 functionDecl(hasName("f"),
5020 forEachDescendant(nestedNameSpecifier().bind("x"))),
5021 // Nested names: a, a::A and a::A::B.
5022 new VerifyIdIsBoundTo<NestedNameSpecifier>("x", 3)));
5023}
5024
5025TEST(NNSLoc, DescendantsOfNestedNameSpecifierLocs) {
5026 std::string Fragment =
5027 "namespace a { struct A { struct B { struct C {}; }; }; };"
5028 "void f() { a::A::B::C c; }";
5029 EXPECT_TRUE(matches(
5030 Fragment,
5031 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
5032 hasDescendant(loc(nestedNameSpecifier(
5033 specifiesNamespace(hasName("a"))))))));
5034 EXPECT_TRUE(notMatches(
5035 Fragment,
5036 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
5037 has(loc(nestedNameSpecifier(
5038 specifiesNamespace(hasName("a"))))))));
5039 EXPECT_TRUE(matches(
5040 Fragment,
5041 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A"))),
5042 has(loc(nestedNameSpecifier(
5043 specifiesNamespace(hasName("a"))))))));
5044
5045 EXPECT_TRUE(matchAndVerifyResultTrue(
5046 Fragment,
5047 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
5048 forEach(nestedNameSpecifierLoc().bind("x"))),
5049 new VerifyIdIsBoundTo<NestedNameSpecifierLoc>("x", 1)));
5050}
5051
5052TEST(NNSLoc, NestedNameSpecifierLocsAsDescendants) {
5053 std::string Fragment =
5054 "namespace a { struct A { struct B { struct C {}; }; }; };"
5055 "void f() { a::A::B::C c; }";
5056 EXPECT_TRUE(matches(
5057 Fragment,
5058 decl(hasDescendant(loc(nestedNameSpecifier(specifiesType(
5059 asString("struct a::A"))))))));
5060 EXPECT_TRUE(matchAndVerifyResultTrue(
5061 Fragment,
5062 functionDecl(hasName("f"),
5063 forEachDescendant(nestedNameSpecifierLoc().bind("x"))),
5064 // Nested names: a, a::A and a::A::B.
5065 new VerifyIdIsBoundTo<NestedNameSpecifierLoc>("x", 3)));
5066}
5067
Manuel Klimek191c0932013-02-01 13:41:35 +00005068template <typename T> class VerifyMatchOnNode : public BoundNodesCallback {
Manuel Klimekc2687452012-10-24 14:47:44 +00005069public:
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005070 VerifyMatchOnNode(StringRef Id, const internal::Matcher<T> &InnerMatcher,
5071 StringRef InnerId)
5072 : Id(Id), InnerMatcher(InnerMatcher), InnerId(InnerId) {
Daniel Jaspere9aa6872012-10-29 10:48:25 +00005073 }
5074
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005075 bool run(const BoundNodes *Nodes) override { return false; }
Manuel Klimek191c0932013-02-01 13:41:35 +00005076
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005077 bool run(const BoundNodes *Nodes, ASTContext *Context) override {
Manuel Klimekc2687452012-10-24 14:47:44 +00005078 const T *Node = Nodes->getNodeAs<T>(Id);
Benjamin Kramer76645582014-07-23 11:41:44 +00005079 return selectFirst<T>(InnerId, match(InnerMatcher, *Node, *Context)) !=
5080 nullptr;
Manuel Klimekc2687452012-10-24 14:47:44 +00005081 }
5082private:
5083 std::string Id;
5084 internal::Matcher<T> InnerMatcher;
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005085 std::string InnerId;
Manuel Klimekc2687452012-10-24 14:47:44 +00005086};
5087
5088TEST(MatchFinder, CanMatchDeclarationsRecursively) {
Manuel Klimek191c0932013-02-01 13:41:35 +00005089 EXPECT_TRUE(matchAndVerifyResultTrue(
5090 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5091 new VerifyMatchOnNode<clang::Decl>(
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005092 "X", decl(hasDescendant(recordDecl(hasName("X::Y")).bind("Y"))),
5093 "Y")));
Manuel Klimek191c0932013-02-01 13:41:35 +00005094 EXPECT_TRUE(matchAndVerifyResultFalse(
5095 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5096 new VerifyMatchOnNode<clang::Decl>(
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005097 "X", decl(hasDescendant(recordDecl(hasName("X::Z")).bind("Z"))),
5098 "Z")));
Manuel Klimekc2687452012-10-24 14:47:44 +00005099}
5100
5101TEST(MatchFinder, CanMatchStatementsRecursively) {
Manuel Klimek191c0932013-02-01 13:41:35 +00005102 EXPECT_TRUE(matchAndVerifyResultTrue(
5103 "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005104 new VerifyMatchOnNode<clang::Stmt>(
5105 "if", stmt(hasDescendant(forStmt().bind("for"))), "for")));
Manuel Klimek191c0932013-02-01 13:41:35 +00005106 EXPECT_TRUE(matchAndVerifyResultFalse(
5107 "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005108 new VerifyMatchOnNode<clang::Stmt>(
5109 "if", stmt(hasDescendant(declStmt().bind("decl"))), "decl")));
Manuel Klimek191c0932013-02-01 13:41:35 +00005110}
5111
5112TEST(MatchFinder, CanMatchSingleNodesRecursively) {
5113 EXPECT_TRUE(matchAndVerifyResultTrue(
5114 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5115 new VerifyMatchOnNode<clang::Decl>(
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005116 "X", recordDecl(has(recordDecl(hasName("X::Y")).bind("Y"))), "Y")));
Manuel Klimek191c0932013-02-01 13:41:35 +00005117 EXPECT_TRUE(matchAndVerifyResultFalse(
5118 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5119 new VerifyMatchOnNode<clang::Decl>(
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005120 "X", recordDecl(has(recordDecl(hasName("X::Z")).bind("Z"))), "Z")));
Manuel Klimekc2687452012-10-24 14:47:44 +00005121}
5122
Manuel Klimekbee08572013-02-07 12:42:10 +00005123template <typename T>
5124class VerifyAncestorHasChildIsEqual : public BoundNodesCallback {
5125public:
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005126 bool run(const BoundNodes *Nodes) override { return false; }
Manuel Klimekbee08572013-02-07 12:42:10 +00005127
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005128 bool run(const BoundNodes *Nodes, ASTContext *Context) override {
Manuel Klimekbee08572013-02-07 12:42:10 +00005129 const T *Node = Nodes->getNodeAs<T>("");
5130 return verify(*Nodes, *Context, Node);
5131 }
5132
5133 bool verify(const BoundNodes &Nodes, ASTContext &Context, const Stmt *Node) {
Manuel Klimeka2c2a4f2014-05-27 12:31:10 +00005134 // Use the original typed pointer to verify we can pass pointers to subtypes
5135 // to equalsNode.
5136 const T *TypedNode = cast<T>(Node);
Benjamin Kramer76645582014-07-23 11:41:44 +00005137 return selectFirst<T>(
Manuel Klimeka2c2a4f2014-05-27 12:31:10 +00005138 "", match(stmt(hasParent(
5139 stmt(has(stmt(equalsNode(TypedNode)))).bind(""))),
Craig Topper416fa342014-06-08 08:38:12 +00005140 *Node, Context)) != nullptr;
Manuel Klimekbee08572013-02-07 12:42:10 +00005141 }
5142 bool verify(const BoundNodes &Nodes, ASTContext &Context, const Decl *Node) {
Manuel Klimeka2c2a4f2014-05-27 12:31:10 +00005143 // Use the original typed pointer to verify we can pass pointers to subtypes
5144 // to equalsNode.
5145 const T *TypedNode = cast<T>(Node);
Benjamin Kramer76645582014-07-23 11:41:44 +00005146 return selectFirst<T>(
Manuel Klimeka2c2a4f2014-05-27 12:31:10 +00005147 "", match(decl(hasParent(
5148 decl(has(decl(equalsNode(TypedNode)))).bind(""))),
Craig Topper416fa342014-06-08 08:38:12 +00005149 *Node, Context)) != nullptr;
Manuel Klimekbee08572013-02-07 12:42:10 +00005150 }
Angel Garcia Gomez4647ed72015-10-30 09:35:51 +00005151 bool verify(const BoundNodes &Nodes, ASTContext &Context, const Type *Node) {
5152 // Use the original typed pointer to verify we can pass pointers to subtypes
5153 // to equalsNode.
5154 const T *TypedNode = cast<T>(Node);
5155 const auto *Dec = Nodes.getNodeAs<FieldDecl>("decl");
5156 return selectFirst<T>(
5157 "", match(fieldDecl(hasParent(decl(has(fieldDecl(
5158 hasType(type(equalsNode(TypedNode)).bind(""))))))),
5159 *Dec, Context)) != nullptr;
5160 }
Manuel Klimekbee08572013-02-07 12:42:10 +00005161};
5162
5163TEST(IsEqualTo, MatchesNodesByIdentity) {
5164 EXPECT_TRUE(matchAndVerifyResultTrue(
5165 "class X { class Y {}; };", recordDecl(hasName("::X::Y")).bind(""),
Manuel Klimeka2c2a4f2014-05-27 12:31:10 +00005166 new VerifyAncestorHasChildIsEqual<CXXRecordDecl>()));
5167 EXPECT_TRUE(matchAndVerifyResultTrue(
5168 "void f() { if (true) if(true) {} }", ifStmt().bind(""),
5169 new VerifyAncestorHasChildIsEqual<IfStmt>()));
Angel Garcia Gomez4647ed72015-10-30 09:35:51 +00005170 EXPECT_TRUE(matchAndVerifyResultTrue(
5171 "class X { class Y {} y; };",
5172 fieldDecl(hasName("y"), hasType(type().bind(""))).bind("decl"),
5173 new VerifyAncestorHasChildIsEqual<Type>()));
Manuel Klimekbee08572013-02-07 12:42:10 +00005174}
5175
Samuel Benzaquen43dcf212014-10-22 20:31:05 +00005176TEST(MatchFinder, CheckProfiling) {
5177 MatchFinder::MatchFinderOptions Options;
5178 llvm::StringMap<llvm::TimeRecord> Records;
5179 Options.CheckProfiling.emplace(Records);
5180 MatchFinder Finder(std::move(Options));
5181
5182 struct NamedCallback : public MatchFinder::MatchCallback {
5183 void run(const MatchFinder::MatchResult &Result) override {}
5184 StringRef getID() const override { return "MyID"; }
5185 } Callback;
5186 Finder.addMatcher(decl(), &Callback);
5187 std::unique_ptr<FrontendActionFactory> Factory(
5188 newFrontendActionFactory(&Finder));
5189 ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), "int x;"));
5190
5191 EXPECT_EQ(1u, Records.size());
5192 EXPECT_EQ("MyID", Records.begin()->getKey());
5193}
5194
Manuel Klimekbd0e2b72012-11-02 01:31:03 +00005195class VerifyStartOfTranslationUnit : public MatchFinder::MatchCallback {
5196public:
5197 VerifyStartOfTranslationUnit() : Called(false) {}
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005198 void run(const MatchFinder::MatchResult &Result) override {
Manuel Klimekbd0e2b72012-11-02 01:31:03 +00005199 EXPECT_TRUE(Called);
5200 }
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005201 void onStartOfTranslationUnit() override { Called = true; }
Manuel Klimekbd0e2b72012-11-02 01:31:03 +00005202 bool Called;
5203};
5204
5205TEST(MatchFinder, InterceptsStartOfTranslationUnit) {
5206 MatchFinder Finder;
5207 VerifyStartOfTranslationUnit VerifyCallback;
5208 Finder.addMatcher(decl(), &VerifyCallback);
Ahmed Charlesb8984322014-03-07 20:03:18 +00005209 std::unique_ptr<FrontendActionFactory> Factory(
5210 newFrontendActionFactory(&Finder));
Manuel Klimekbd0e2b72012-11-02 01:31:03 +00005211 ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), "int x;"));
5212 EXPECT_TRUE(VerifyCallback.Called);
Peter Collingbournea2334162013-11-07 22:30:36 +00005213
5214 VerifyCallback.Called = false;
Ahmed Charlesb8984322014-03-07 20:03:18 +00005215 std::unique_ptr<ASTUnit> AST(tooling::buildASTFromCode("int x;"));
Peter Collingbournea2334162013-11-07 22:30:36 +00005216 ASSERT_TRUE(AST.get());
5217 Finder.matchAST(AST->getASTContext());
5218 EXPECT_TRUE(VerifyCallback.Called);
Manuel Klimekbd0e2b72012-11-02 01:31:03 +00005219}
5220
Peter Collingbourne6a55bb22013-05-28 19:21:51 +00005221class VerifyEndOfTranslationUnit : public MatchFinder::MatchCallback {
5222public:
5223 VerifyEndOfTranslationUnit() : Called(false) {}
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005224 void run(const MatchFinder::MatchResult &Result) override {
Peter Collingbourne6a55bb22013-05-28 19:21:51 +00005225 EXPECT_FALSE(Called);
5226 }
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005227 void onEndOfTranslationUnit() override { Called = true; }
Peter Collingbourne6a55bb22013-05-28 19:21:51 +00005228 bool Called;
5229};
5230
5231TEST(MatchFinder, InterceptsEndOfTranslationUnit) {
5232 MatchFinder Finder;
5233 VerifyEndOfTranslationUnit VerifyCallback;
5234 Finder.addMatcher(decl(), &VerifyCallback);
Ahmed Charlesb8984322014-03-07 20:03:18 +00005235 std::unique_ptr<FrontendActionFactory> Factory(
5236 newFrontendActionFactory(&Finder));
Peter Collingbourne6a55bb22013-05-28 19:21:51 +00005237 ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), "int x;"));
5238 EXPECT_TRUE(VerifyCallback.Called);
Peter Collingbournea2334162013-11-07 22:30:36 +00005239
5240 VerifyCallback.Called = false;
Ahmed Charlesb8984322014-03-07 20:03:18 +00005241 std::unique_ptr<ASTUnit> AST(tooling::buildASTFromCode("int x;"));
Peter Collingbournea2334162013-11-07 22:30:36 +00005242 ASSERT_TRUE(AST.get());
5243 Finder.matchAST(AST->getASTContext());
5244 EXPECT_TRUE(VerifyCallback.Called);
Peter Collingbourne6a55bb22013-05-28 19:21:51 +00005245}
5246
Daniel Jasper739ae642016-02-03 14:29:55 +00005247TEST(Matcher, matchOverEntireASTContext) {
5248 std::unique_ptr<ASTUnit> AST =
5249 clang::tooling::buildASTFromCode("struct { int *foo; };");
5250 ASSERT_TRUE(AST.get());
5251 auto PT = selectFirst<PointerType>(
5252 "x", match(pointerType().bind("x"), AST->getASTContext()));
5253 EXPECT_NE(nullptr, PT);
5254}
5255
Manuel Klimekbbb75852013-06-20 14:06:32 +00005256TEST(EqualsBoundNodeMatcher, QualType) {
5257 EXPECT_TRUE(matches(
5258 "int i = 1;", varDecl(hasType(qualType().bind("type")),
5259 hasInitializer(ignoringParenImpCasts(
5260 hasType(qualType(equalsBoundNode("type"))))))));
5261 EXPECT_TRUE(notMatches("int i = 1.f;",
5262 varDecl(hasType(qualType().bind("type")),
5263 hasInitializer(ignoringParenImpCasts(hasType(
5264 qualType(equalsBoundNode("type"))))))));
5265}
5266
5267TEST(EqualsBoundNodeMatcher, NonMatchingTypes) {
5268 EXPECT_TRUE(notMatches(
5269 "int i = 1;", varDecl(namedDecl(hasName("i")).bind("name"),
5270 hasInitializer(ignoringParenImpCasts(
5271 hasType(qualType(equalsBoundNode("type"))))))));
5272}
5273
5274TEST(EqualsBoundNodeMatcher, Stmt) {
5275 EXPECT_TRUE(
5276 matches("void f() { if(true) {} }",
5277 stmt(allOf(ifStmt().bind("if"),
5278 hasParent(stmt(has(stmt(equalsBoundNode("if")))))))));
5279
5280 EXPECT_TRUE(notMatches(
5281 "void f() { if(true) { if (true) {} } }",
5282 stmt(allOf(ifStmt().bind("if"), has(stmt(equalsBoundNode("if")))))));
5283}
5284
5285TEST(EqualsBoundNodeMatcher, Decl) {
5286 EXPECT_TRUE(matches(
5287 "class X { class Y {}; };",
5288 decl(allOf(recordDecl(hasName("::X::Y")).bind("record"),
5289 hasParent(decl(has(decl(equalsBoundNode("record")))))))));
5290
5291 EXPECT_TRUE(notMatches("class X { class Y {}; };",
5292 decl(allOf(recordDecl(hasName("::X")).bind("record"),
5293 has(decl(equalsBoundNode("record")))))));
5294}
5295
5296TEST(EqualsBoundNodeMatcher, Type) {
5297 EXPECT_TRUE(matches(
5298 "class X { int a; int b; };",
5299 recordDecl(
5300 has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
5301 has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
5302
5303 EXPECT_TRUE(notMatches(
5304 "class X { int a; double b; };",
5305 recordDecl(
5306 has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
5307 has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
5308}
5309
5310TEST(EqualsBoundNodeMatcher, UsingForEachDescendant) {
Manuel Klimekbbb75852013-06-20 14:06:32 +00005311 EXPECT_TRUE(matchAndVerifyResultTrue(
5312 "int f() {"
5313 " if (1) {"
5314 " int i = 9;"
5315 " }"
5316 " int j = 10;"
5317 " {"
5318 " float k = 9.0;"
5319 " }"
5320 " return 0;"
5321 "}",
5322 // Look for variable declarations within functions whose type is the same
5323 // as the function return type.
5324 functionDecl(returns(qualType().bind("type")),
5325 forEachDescendant(varDecl(hasType(
5326 qualType(equalsBoundNode("type")))).bind("decl"))),
5327 // Only i and j should match, not k.
5328 new VerifyIdIsBoundTo<VarDecl>("decl", 2)));
5329}
5330
5331TEST(EqualsBoundNodeMatcher, FiltersMatchedCombinations) {
5332 EXPECT_TRUE(matchAndVerifyResultTrue(
5333 "void f() {"
5334 " int x;"
5335 " double d;"
5336 " x = d + x - d + x;"
5337 "}",
5338 functionDecl(
5339 hasName("f"), forEachDescendant(varDecl().bind("d")),
5340 forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d")))))),
5341 new VerifyIdIsBoundTo<VarDecl>("d", 5)));
5342}
5343
Manuel Klimekce68f772014-03-25 14:39:26 +00005344TEST(EqualsBoundNodeMatcher, UnlessDescendantsOfAncestorsMatch) {
5345 EXPECT_TRUE(matchAndVerifyResultTrue(
5346 "struct StringRef { int size() const; const char* data() const; };"
5347 "void f(StringRef v) {"
5348 " v.data();"
5349 "}",
Aaron Ballman512fb642015-09-17 13:30:52 +00005350 cxxMemberCallExpr(
5351 callee(cxxMethodDecl(hasName("data"))),
5352 on(declRefExpr(to(
5353 varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),
5354 unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(
5355 callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
Manuel Klimekce68f772014-03-25 14:39:26 +00005356 on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
5357 .bind("data"),
5358 new VerifyIdIsBoundTo<Expr>("data", 1)));
5359
5360 EXPECT_FALSE(matches(
5361 "struct StringRef { int size() const; const char* data() const; };"
5362 "void f(StringRef v) {"
5363 " v.data();"
5364 " v.size();"
5365 "}",
Aaron Ballman512fb642015-09-17 13:30:52 +00005366 cxxMemberCallExpr(
5367 callee(cxxMethodDecl(hasName("data"))),
5368 on(declRefExpr(to(
5369 varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),
5370 unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(
5371 callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
Manuel Klimekce68f772014-03-25 14:39:26 +00005372 on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
5373 .bind("data")));
5374}
5375
Manuel Klimekd3aa1f42014-11-25 17:01:06 +00005376TEST(TypeDefDeclMatcher, Match) {
5377 EXPECT_TRUE(matches("typedef int typedefDeclTest;",
5378 typedefDecl(hasName("typedefDeclTest"))));
5379}
5380
Aaron Ballman11825f22015-08-18 19:55:20 +00005381TEST(IsInlineMatcher, IsInline) {
5382 EXPECT_TRUE(matches("void g(); inline void f();",
5383 functionDecl(isInline(), hasName("f"))));
5384 EXPECT_TRUE(matches("namespace n { inline namespace m {} }",
5385 namespaceDecl(isInline(), hasName("m"))));
5386}
5387
Aaron Ballman7e7b7b22016-02-01 14:11:47 +00005388// FIXME: Figure out how to specify paths so the following tests pass on
5389// Windows.
Manuel Klimekd3aa1f42014-11-25 17:01:06 +00005390#ifndef LLVM_ON_WIN32
5391
5392TEST(Matcher, IsExpansionInMainFileMatcher) {
5393 EXPECT_TRUE(matches("class X {};",
5394 recordDecl(hasName("X"), isExpansionInMainFile())));
5395 EXPECT_TRUE(notMatches("", recordDecl(isExpansionInMainFile())));
5396 FileContentMappings M;
5397 M.push_back(std::make_pair("/other", "class X {};"));
5398 EXPECT_TRUE(matchesConditionally("#include <other>\n",
5399 recordDecl(isExpansionInMainFile()), false,
5400 "-isystem/", M));
5401}
5402
5403TEST(Matcher, IsExpansionInSystemHeader) {
5404 FileContentMappings M;
5405 M.push_back(std::make_pair("/other", "class X {};"));
5406 EXPECT_TRUE(matchesConditionally(
5407 "#include \"other\"\n", recordDecl(isExpansionInSystemHeader()), true,
5408 "-isystem/", M));
5409 EXPECT_TRUE(matchesConditionally("#include \"other\"\n",
5410 recordDecl(isExpansionInSystemHeader()),
5411 false, "-I/", M));
5412 EXPECT_TRUE(notMatches("class X {};",
5413 recordDecl(isExpansionInSystemHeader())));
5414 EXPECT_TRUE(notMatches("", recordDecl(isExpansionInSystemHeader())));
5415}
5416
5417TEST(Matcher, IsExpansionInFileMatching) {
5418 FileContentMappings M;
5419 M.push_back(std::make_pair("/foo", "class A {};"));
5420 M.push_back(std::make_pair("/bar", "class B {};"));
5421 EXPECT_TRUE(matchesConditionally(
5422 "#include <foo>\n"
5423 "#include <bar>\n"
5424 "class X {};",
5425 recordDecl(isExpansionInFileMatching("b.*"), hasName("B")), true,
5426 "-isystem/", M));
5427 EXPECT_TRUE(matchesConditionally(
5428 "#include <foo>\n"
5429 "#include <bar>\n"
5430 "class X {};",
5431 recordDecl(isExpansionInFileMatching("f.*"), hasName("X")), false,
5432 "-isystem/", M));
5433}
5434
5435#endif // LLVM_ON_WIN32
5436
Manuel Klimekbfa43572015-03-12 15:48:15 +00005437
5438TEST(ObjCMessageExprMatcher, SimpleExprs) {
5439 // don't find ObjCMessageExpr where none are present
5440 EXPECT_TRUE(notMatchesObjC("", objcMessageExpr(anything())));
5441
5442 std::string Objc1String =
5443 "@interface Str "
5444 " - (Str *)uppercaseString:(Str *)str;"
5445 "@end "
5446 "@interface foo "
5447 "- (void)meth:(Str *)text;"
5448 "@end "
5449 " "
5450 "@implementation foo "
5451 "- (void) meth:(Str *)text { "
5452 " [self contents];"
5453 " Str *up = [text uppercaseString];"
5454 "} "
5455 "@end ";
5456 EXPECT_TRUE(matchesObjC(
5457 Objc1String,
5458 objcMessageExpr(anything())));
5459 EXPECT_TRUE(matchesObjC(
5460 Objc1String,
5461 objcMessageExpr(hasSelector("contents"))));
5462 EXPECT_TRUE(matchesObjC(
5463 Objc1String,
5464 objcMessageExpr(matchesSelector("cont*"))));
5465 EXPECT_FALSE(matchesObjC(
5466 Objc1String,
5467 objcMessageExpr(matchesSelector("?cont*"))));
5468 EXPECT_TRUE(notMatchesObjC(
5469 Objc1String,
5470 objcMessageExpr(hasSelector("contents"), hasNullSelector())));
5471 EXPECT_TRUE(matchesObjC(
5472 Objc1String,
5473 objcMessageExpr(hasSelector("contents"), hasUnarySelector())));
5474 EXPECT_TRUE(matchesObjC(
5475 Objc1String,
Manuel Klimeke67a9d62015-09-08 10:11:26 +00005476 objcMessageExpr(hasSelector("contents"), numSelectorArgs(0))));
5477 EXPECT_TRUE(matchesObjC(
5478 Objc1String,
Manuel Klimekbfa43572015-03-12 15:48:15 +00005479 objcMessageExpr(matchesSelector("uppercase*"),
5480 argumentCountIs(0)
5481 )));
Manuel Klimekbfa43572015-03-12 15:48:15 +00005482}
5483
Aaron Ballman232e63d2016-02-16 21:02:23 +00005484TEST(NullPointerConstants, Basic) {
5485 EXPECT_TRUE(matches("#define NULL ((void *)0)\n"
5486 "void *v1 = NULL;", expr(nullPointerConstant())));
5487 EXPECT_TRUE(matches("void *v2 = nullptr;", expr(nullPointerConstant())));
5488 EXPECT_TRUE(matches("void *v3 = __null;", expr(nullPointerConstant())));
5489 EXPECT_TRUE(matches("char *cp = (char *)0;", expr(nullPointerConstant())));
5490 EXPECT_TRUE(matches("int *ip = 0;", expr(nullPointerConstant())));
Aaron Ballmancc928c82016-02-16 21:06:10 +00005491 EXPECT_TRUE(notMatches("int i = 0;", expr(nullPointerConstant())));
Aaron Ballman232e63d2016-02-16 21:02:23 +00005492}
5493
Alexander Kornienko976921d2016-03-22 11:03:03 +00005494TEST(StatementMatcher, HasReturnValue) {
5495 StatementMatcher RetVal = returnStmt(hasReturnValue(binaryOperator()));
5496 EXPECT_TRUE(matches("int F() { int a, b; return a + b; }", RetVal));
5497 EXPECT_FALSE(matches("int F() { int a; return a; }", RetVal));
5498}
5499
Manuel Klimek04616e42012-07-06 05:48:52 +00005500} // end namespace ast_matchers
5501} // end namespace clang