blob: bcdc10ab6c037688ce0a1c978da1fd877f955c40 [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({
Daniel Jasperbd3d76d2012-08-24 05:12:34 +000039 DeclarationMatcher IsDerivedFromEmpty = recordDecl(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;
47 EXPECT_TRUE(Finder.addDynamicMatcher(decl(), NULL));
48 EXPECT_TRUE(Finder.addDynamicMatcher(callExpr(), NULL));
49 EXPECT_TRUE(Finder.addDynamicMatcher(constantArrayType(hasSize(42)), NULL));
50
51 // Do not accept non-toplevel matchers.
52 EXPECT_FALSE(Finder.addDynamicMatcher(isArrow(), NULL));
53 EXPECT_FALSE(Finder.addDynamicMatcher(hasSize(2), NULL));
54 EXPECT_FALSE(Finder.addDynamicMatcher(hasName("x"), NULL));
55}
56
Manuel Klimeke9235692012-07-25 10:02:02 +000057TEST(Decl, MatchesDeclarations) {
58 EXPECT_TRUE(notMatches("", decl(usingDecl())));
59 EXPECT_TRUE(matches("namespace x { class X {}; } using x::X;",
60 decl(usingDecl())));
61}
62
Manuel Klimek04616e42012-07-06 05:48:52 +000063TEST(NameableDeclaration, MatchesVariousDecls) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +000064 DeclarationMatcher NamedX = namedDecl(hasName("X"));
Manuel Klimek04616e42012-07-06 05:48:52 +000065 EXPECT_TRUE(matches("typedef int X;", NamedX));
66 EXPECT_TRUE(matches("int X;", NamedX));
67 EXPECT_TRUE(matches("class foo { virtual void X(); };", NamedX));
68 EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", NamedX));
69 EXPECT_TRUE(matches("void foo() { int X; }", NamedX));
70 EXPECT_TRUE(matches("namespace X { }", NamedX));
Daniel Jasper1dad1832012-07-10 20:20:19 +000071 EXPECT_TRUE(matches("enum X { A, B, C };", NamedX));
Manuel Klimek04616e42012-07-06 05:48:52 +000072
73 EXPECT_TRUE(notMatches("#define X 1", NamedX));
74}
75
Daniel Jasper1dad1832012-07-10 20:20:19 +000076TEST(NameableDeclaration, REMatchesVariousDecls) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +000077 DeclarationMatcher NamedX = namedDecl(matchesName("::X"));
Daniel Jasper1dad1832012-07-10 20:20:19 +000078 EXPECT_TRUE(matches("typedef int Xa;", NamedX));
79 EXPECT_TRUE(matches("int Xb;", NamedX));
80 EXPECT_TRUE(matches("class foo { virtual void Xc(); };", NamedX));
81 EXPECT_TRUE(matches("void foo() try { } catch(int Xdef) { }", NamedX));
82 EXPECT_TRUE(matches("void foo() { int Xgh; }", NamedX));
83 EXPECT_TRUE(matches("namespace Xij { }", NamedX));
84 EXPECT_TRUE(matches("enum X { A, B, C };", NamedX));
85
86 EXPECT_TRUE(notMatches("#define Xkl 1", NamedX));
87
Daniel Jasperbd3d76d2012-08-24 05:12:34 +000088 DeclarationMatcher StartsWithNo = namedDecl(matchesName("::no"));
Daniel Jasper1dad1832012-07-10 20:20:19 +000089 EXPECT_TRUE(matches("int no_foo;", StartsWithNo));
90 EXPECT_TRUE(matches("class foo { virtual void nobody(); };", StartsWithNo));
91
Daniel Jasperbd3d76d2012-08-24 05:12:34 +000092 DeclarationMatcher Abc = namedDecl(matchesName("a.*b.*c"));
Daniel Jasper1dad1832012-07-10 20:20:19 +000093 EXPECT_TRUE(matches("int abc;", Abc));
94 EXPECT_TRUE(matches("int aFOObBARc;", Abc));
95 EXPECT_TRUE(notMatches("int cab;", Abc));
96 EXPECT_TRUE(matches("int cabc;", Abc));
Manuel Klimeke792efd2012-12-10 07:08:53 +000097
98 DeclarationMatcher StartsWithK = namedDecl(matchesName(":k[^:]*$"));
99 EXPECT_TRUE(matches("int k;", StartsWithK));
100 EXPECT_TRUE(matches("int kAbc;", StartsWithK));
101 EXPECT_TRUE(matches("namespace x { int kTest; }", StartsWithK));
102 EXPECT_TRUE(matches("class C { int k; };", StartsWithK));
103 EXPECT_TRUE(notMatches("class C { int ckc; };", StartsWithK));
Daniel Jasper1dad1832012-07-10 20:20:19 +0000104}
105
Manuel Klimek04616e42012-07-06 05:48:52 +0000106TEST(DeclarationMatcher, MatchClass) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000107 DeclarationMatcher ClassMatcher(recordDecl());
Saleem Abdulrasool377066a2014-03-27 22:50:18 +0000108 llvm::Triple Triple(llvm::sys::getDefaultTargetTriple());
109 if (Triple.getOS() != llvm::Triple::Win32 ||
110 Triple.getEnvironment() != llvm::Triple::MSVC)
NAKAMURA Takumi7d2da0b2014-02-16 10:16:09 +0000111 EXPECT_FALSE(matches("", ClassMatcher));
112 else
113 // Matches class type_info.
114 EXPECT_TRUE(matches("", ClassMatcher));
Manuel Klimek04616e42012-07-06 05:48:52 +0000115
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000116 DeclarationMatcher ClassX = recordDecl(recordDecl(hasName("X")));
Manuel Klimek04616e42012-07-06 05:48:52 +0000117 EXPECT_TRUE(matches("class X;", ClassX));
118 EXPECT_TRUE(matches("class X {};", ClassX));
119 EXPECT_TRUE(matches("template<class T> class X {};", ClassX));
120 EXPECT_TRUE(notMatches("", ClassX));
121}
122
123TEST(DeclarationMatcher, ClassIsDerived) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000124 DeclarationMatcher IsDerivedFromX = recordDecl(isDerivedFrom("X"));
Manuel Klimek04616e42012-07-06 05:48:52 +0000125
126 EXPECT_TRUE(matches("class X {}; class Y : public X {};", IsDerivedFromX));
Daniel Jasperf49d1e02012-09-07 12:48:17 +0000127 EXPECT_TRUE(notMatches("class X {};", IsDerivedFromX));
128 EXPECT_TRUE(notMatches("class X;", IsDerivedFromX));
Manuel Klimek04616e42012-07-06 05:48:52 +0000129 EXPECT_TRUE(notMatches("class Y;", IsDerivedFromX));
130 EXPECT_TRUE(notMatches("", IsDerivedFromX));
131
Daniel Jasperd6b82cb2012-09-12 21:14:15 +0000132 DeclarationMatcher IsAX = recordDecl(isSameOrDerivedFrom("X"));
Daniel Jasperf49d1e02012-09-07 12:48:17 +0000133
134 EXPECT_TRUE(matches("class X {}; class Y : public X {};", IsAX));
135 EXPECT_TRUE(matches("class X {};", IsAX));
136 EXPECT_TRUE(matches("class X;", IsAX));
137 EXPECT_TRUE(notMatches("class Y;", IsAX));
138 EXPECT_TRUE(notMatches("", IsAX));
139
Manuel Klimek04616e42012-07-06 05:48:52 +0000140 DeclarationMatcher ZIsDerivedFromX =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000141 recordDecl(hasName("Z"), isDerivedFrom("X"));
Manuel Klimek04616e42012-07-06 05:48:52 +0000142 EXPECT_TRUE(
143 matches("class X {}; class Y : public X {}; class Z : public Y {};",
144 ZIsDerivedFromX));
145 EXPECT_TRUE(
146 matches("class X {};"
147 "template<class T> class Y : public X {};"
148 "class Z : public Y<int> {};", ZIsDerivedFromX));
149 EXPECT_TRUE(matches("class X {}; template<class T> class Z : public X {};",
150 ZIsDerivedFromX));
151 EXPECT_TRUE(
152 matches("template<class T> class X {}; "
153 "template<class T> class Z : public X<T> {};",
154 ZIsDerivedFromX));
155 EXPECT_TRUE(
156 matches("template<class T, class U=T> class X {}; "
157 "template<class T> class Z : public X<T> {};",
158 ZIsDerivedFromX));
159 EXPECT_TRUE(
160 notMatches("template<class X> class A { class Z : public X {}; };",
161 ZIsDerivedFromX));
162 EXPECT_TRUE(
163 matches("template<class X> class A { public: class Z : public X {}; }; "
164 "class X{}; void y() { A<X>::Z z; }", ZIsDerivedFromX));
165 EXPECT_TRUE(
166 matches("template <class T> class X {}; "
167 "template<class Y> class A { class Z : public X<Y> {}; };",
168 ZIsDerivedFromX));
169 EXPECT_TRUE(
170 notMatches("template<template<class T> class X> class A { "
171 " class Z : public X<int> {}; };", ZIsDerivedFromX));
172 EXPECT_TRUE(
173 matches("template<template<class T> class X> class A { "
174 " public: class Z : public X<int> {}; }; "
175 "template<class T> class X {}; void y() { A<X>::Z z; }",
176 ZIsDerivedFromX));
177 EXPECT_TRUE(
178 notMatches("template<class X> class A { class Z : public X::D {}; };",
179 ZIsDerivedFromX));
180 EXPECT_TRUE(
181 matches("template<class X> class A { public: "
182 " class Z : public X::D {}; }; "
183 "class Y { public: class X {}; typedef X D; }; "
184 "void y() { A<Y>::Z z; }", ZIsDerivedFromX));
185 EXPECT_TRUE(
186 matches("class X {}; typedef X Y; class Z : public Y {};",
187 ZIsDerivedFromX));
188 EXPECT_TRUE(
189 matches("template<class T> class Y { typedef typename T::U X; "
190 " class Z : public X {}; };", ZIsDerivedFromX));
191 EXPECT_TRUE(matches("class X {}; class Z : public ::X {};",
192 ZIsDerivedFromX));
193 EXPECT_TRUE(
194 notMatches("template<class T> class X {}; "
195 "template<class T> class A { class Z : public X<T>::D {}; };",
196 ZIsDerivedFromX));
197 EXPECT_TRUE(
198 matches("template<class T> class X { public: typedef X<T> D; }; "
199 "template<class T> class A { public: "
200 " class Z : public X<T>::D {}; }; void y() { A<int>::Z z; }",
201 ZIsDerivedFromX));
202 EXPECT_TRUE(
203 notMatches("template<class X> class A { class Z : public X::D::E {}; };",
204 ZIsDerivedFromX));
205 EXPECT_TRUE(
206 matches("class X {}; typedef X V; typedef V W; class Z : public W {};",
207 ZIsDerivedFromX));
208 EXPECT_TRUE(
209 matches("class X {}; class Y : public X {}; "
210 "typedef Y V; typedef V W; class Z : public W {};",
211 ZIsDerivedFromX));
212 EXPECT_TRUE(
213 matches("template<class T, class U> class X {}; "
214 "template<class T> class A { class Z : public X<T, int> {}; };",
215 ZIsDerivedFromX));
216 EXPECT_TRUE(
217 notMatches("template<class X> class D { typedef X A; typedef A B; "
218 " typedef B C; class Z : public C {}; };",
219 ZIsDerivedFromX));
220 EXPECT_TRUE(
221 matches("class X {}; typedef X A; typedef A B; "
222 "class Z : public B {};", ZIsDerivedFromX));
223 EXPECT_TRUE(
224 matches("class X {}; typedef X A; typedef A B; typedef B C; "
225 "class Z : public C {};", ZIsDerivedFromX));
226 EXPECT_TRUE(
227 matches("class U {}; typedef U X; typedef X V; "
228 "class Z : public V {};", ZIsDerivedFromX));
229 EXPECT_TRUE(
230 matches("class Base {}; typedef Base X; "
231 "class Z : public Base {};", ZIsDerivedFromX));
232 EXPECT_TRUE(
233 matches("class Base {}; typedef Base Base2; typedef Base2 X; "
234 "class Z : public Base {};", ZIsDerivedFromX));
235 EXPECT_TRUE(
236 notMatches("class Base {}; class Base2 {}; typedef Base2 X; "
237 "class Z : public Base {};", ZIsDerivedFromX));
238 EXPECT_TRUE(
239 matches("class A {}; typedef A X; typedef A Y; "
240 "class Z : public Y {};", ZIsDerivedFromX));
241 EXPECT_TRUE(
242 notMatches("template <typename T> class Z;"
243 "template <> class Z<void> {};"
244 "template <typename T> class Z : public Z<void> {};",
245 IsDerivedFromX));
246 EXPECT_TRUE(
247 matches("template <typename T> class X;"
248 "template <> class X<void> {};"
249 "template <typename T> class X : public X<void> {};",
250 IsDerivedFromX));
251 EXPECT_TRUE(matches(
252 "class X {};"
253 "template <typename T> class Z;"
254 "template <> class Z<void> {};"
255 "template <typename T> class Z : public Z<void>, public X {};",
256 ZIsDerivedFromX));
Manuel Klimek5472a522012-12-04 13:40:29 +0000257 EXPECT_TRUE(
258 notMatches("template<int> struct X;"
259 "template<int i> struct X : public X<i-1> {};",
260 recordDecl(isDerivedFrom(recordDecl(hasName("Some"))))));
261 EXPECT_TRUE(matches(
262 "struct A {};"
263 "template<int> struct X;"
264 "template<int i> struct X : public X<i-1> {};"
265 "template<> struct X<0> : public A {};"
266 "struct B : public X<42> {};",
267 recordDecl(hasName("B"), isDerivedFrom(recordDecl(hasName("A"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000268
269 // FIXME: Once we have better matchers for template type matching,
270 // get rid of the Variable(...) matching and match the right template
271 // declarations directly.
272 const char *RecursiveTemplateOneParameter =
273 "class Base1 {}; class Base2 {};"
274 "template <typename T> class Z;"
275 "template <> class Z<void> : public Base1 {};"
276 "template <> class Z<int> : public Base2 {};"
277 "template <> class Z<float> : public Z<void> {};"
278 "template <> class Z<double> : public Z<int> {};"
279 "template <typename T> class Z : public Z<float>, public Z<double> {};"
280 "void f() { Z<float> z_float; Z<double> z_double; Z<char> z_char; }";
281 EXPECT_TRUE(matches(
282 RecursiveTemplateOneParameter,
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000283 varDecl(hasName("z_float"),
284 hasInitializer(hasType(recordDecl(isDerivedFrom("Base1")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000285 EXPECT_TRUE(notMatches(
286 RecursiveTemplateOneParameter,
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000287 varDecl(hasName("z_float"),
288 hasInitializer(hasType(recordDecl(isDerivedFrom("Base2")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000289 EXPECT_TRUE(matches(
290 RecursiveTemplateOneParameter,
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000291 varDecl(hasName("z_char"),
292 hasInitializer(hasType(recordDecl(isDerivedFrom("Base1"),
293 isDerivedFrom("Base2")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000294
295 const char *RecursiveTemplateTwoParameters =
296 "class Base1 {}; class Base2 {};"
297 "template <typename T1, typename T2> class Z;"
298 "template <typename T> class Z<void, T> : public Base1 {};"
299 "template <typename T> class Z<int, T> : public Base2 {};"
300 "template <typename T> class Z<float, T> : public Z<void, T> {};"
301 "template <typename T> class Z<double, T> : public Z<int, T> {};"
302 "template <typename T1, typename T2> class Z : "
303 " public Z<float, T2>, public Z<double, T2> {};"
304 "void f() { Z<float, void> z_float; Z<double, void> z_double; "
305 " Z<char, void> z_char; }";
306 EXPECT_TRUE(matches(
307 RecursiveTemplateTwoParameters,
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000308 varDecl(hasName("z_float"),
309 hasInitializer(hasType(recordDecl(isDerivedFrom("Base1")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000310 EXPECT_TRUE(notMatches(
311 RecursiveTemplateTwoParameters,
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000312 varDecl(hasName("z_float"),
313 hasInitializer(hasType(recordDecl(isDerivedFrom("Base2")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000314 EXPECT_TRUE(matches(
315 RecursiveTemplateTwoParameters,
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000316 varDecl(hasName("z_char"),
317 hasInitializer(hasType(recordDecl(isDerivedFrom("Base1"),
318 isDerivedFrom("Base2")))))));
Daniel Jasper2b3c7d42012-07-17 07:39:27 +0000319 EXPECT_TRUE(matches(
320 "namespace ns { class X {}; class Y : public X {}; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000321 recordDecl(isDerivedFrom("::ns::X"))));
Daniel Jasper2b3c7d42012-07-17 07:39:27 +0000322 EXPECT_TRUE(notMatches(
323 "class X {}; class Y : public X {};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000324 recordDecl(isDerivedFrom("::ns::X"))));
Daniel Jasper2b3c7d42012-07-17 07:39:27 +0000325
326 EXPECT_TRUE(matches(
327 "class X {}; class Y : public X {};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000328 recordDecl(isDerivedFrom(recordDecl(hasName("X")).bind("test")))));
Manuel Klimek1863e502013-08-02 21:24:09 +0000329
330 EXPECT_TRUE(matches(
331 "template<typename T> class X {};"
332 "template<typename T> using Z = X<T>;"
333 "template <typename T> class Y : Z<T> {};",
334 recordDecl(isDerivedFrom(namedDecl(hasName("X"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000335}
336
Edwin Vane0a4836e2013-03-06 17:02:57 +0000337TEST(DeclarationMatcher, hasMethod) {
338 EXPECT_TRUE(matches("class A { void func(); };",
339 recordDecl(hasMethod(hasName("func")))));
340 EXPECT_TRUE(notMatches("class A { void func(); };",
341 recordDecl(hasMethod(isPublic()))));
342}
343
Daniel Jasper83dafaf2012-09-18 14:17:42 +0000344TEST(DeclarationMatcher, ClassDerivedFromDependentTemplateSpecialization) {
345 EXPECT_TRUE(matches(
346 "template <typename T> struct A {"
347 " template <typename T2> struct F {};"
348 "};"
349 "template <typename T> struct B : A<T>::template F<T> {};"
350 "B<int> b;",
351 recordDecl(hasName("B"), isDerivedFrom(recordDecl()))));
352}
353
Edwin Vaneb6eae142013-02-25 20:43:32 +0000354TEST(DeclarationMatcher, hasDeclContext) {
355 EXPECT_TRUE(matches(
356 "namespace N {"
357 " namespace M {"
358 " class D {};"
359 " }"
360 "}",
Daniel Jasper9fcdc462013-04-08 16:44:05 +0000361 recordDecl(hasDeclContext(namespaceDecl(hasName("M"))))));
Edwin Vaneb6eae142013-02-25 20:43:32 +0000362 EXPECT_TRUE(notMatches(
363 "namespace N {"
364 " namespace M {"
365 " class D {};"
366 " }"
367 "}",
Daniel Jasper9fcdc462013-04-08 16:44:05 +0000368 recordDecl(hasDeclContext(namespaceDecl(hasName("N"))))));
369
370 EXPECT_TRUE(matches("namespace {"
371 " namespace M {"
372 " class D {};"
373 " }"
374 "}",
375 recordDecl(hasDeclContext(namespaceDecl(
376 hasName("M"), hasDeclContext(namespaceDecl()))))));
Edwin Vaneb6eae142013-02-25 20:43:32 +0000377}
378
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +0000379TEST(ClassTemplate, DoesNotMatchClass) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000380 DeclarationMatcher ClassX = classTemplateDecl(hasName("X"));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +0000381 EXPECT_TRUE(notMatches("class X;", ClassX));
382 EXPECT_TRUE(notMatches("class X {};", ClassX));
383}
384
385TEST(ClassTemplate, MatchesClassTemplate) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000386 DeclarationMatcher ClassX = classTemplateDecl(hasName("X"));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +0000387 EXPECT_TRUE(matches("template<typename T> class X {};", ClassX));
388 EXPECT_TRUE(matches("class Z { template<class T> class X {}; };", ClassX));
389}
390
391TEST(ClassTemplate, DoesNotMatchClassTemplateExplicitSpecialization) {
392 EXPECT_TRUE(notMatches("template<typename T> class X { };"
393 "template<> class X<int> { int a; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000394 classTemplateDecl(hasName("X"),
395 hasDescendant(fieldDecl(hasName("a"))))));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +0000396}
397
398TEST(ClassTemplate, DoesNotMatchClassTemplatePartialSpecialization) {
399 EXPECT_TRUE(notMatches("template<typename T, typename U> class X { };"
400 "template<typename T> class X<T, int> { int a; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000401 classTemplateDecl(hasName("X"),
402 hasDescendant(fieldDecl(hasName("a"))))));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +0000403}
404
Daniel Jasper4e566c42012-07-12 08:50:38 +0000405TEST(AllOf, AllOverloadsWork) {
406 const char Program[] =
Edwin Vanee9dd3602013-02-12 13:55:40 +0000407 "struct T { };"
408 "int f(int, T*, int, int);"
409 "void g(int x) { T t; f(x, &t, 3, 4); }";
Daniel Jasper4e566c42012-07-12 08:50:38 +0000410 EXPECT_TRUE(matches(Program,
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000411 callExpr(allOf(callee(functionDecl(hasName("f"))),
412 hasArgument(0, declRefExpr(to(varDecl())))))));
Daniel Jasper4e566c42012-07-12 08:50:38 +0000413 EXPECT_TRUE(matches(Program,
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000414 callExpr(allOf(callee(functionDecl(hasName("f"))),
415 hasArgument(0, declRefExpr(to(varDecl()))),
416 hasArgument(1, hasType(pointsTo(
417 recordDecl(hasName("T")))))))));
Edwin Vanee9dd3602013-02-12 13:55:40 +0000418 EXPECT_TRUE(matches(Program,
419 callExpr(allOf(callee(functionDecl(hasName("f"))),
420 hasArgument(0, declRefExpr(to(varDecl()))),
421 hasArgument(1, hasType(pointsTo(
422 recordDecl(hasName("T"))))),
423 hasArgument(2, integerLiteral(equals(3)))))));
424 EXPECT_TRUE(matches(Program,
425 callExpr(allOf(callee(functionDecl(hasName("f"))),
426 hasArgument(0, declRefExpr(to(varDecl()))),
427 hasArgument(1, hasType(pointsTo(
428 recordDecl(hasName("T"))))),
429 hasArgument(2, integerLiteral(equals(3))),
430 hasArgument(3, integerLiteral(equals(4)))))));
Daniel Jasper4e566c42012-07-12 08:50:38 +0000431}
432
Manuel Klimek04616e42012-07-06 05:48:52 +0000433TEST(DeclarationMatcher, MatchAnyOf) {
434 DeclarationMatcher YOrZDerivedFromX =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000435 recordDecl(anyOf(hasName("Y"), allOf(isDerivedFrom("X"), hasName("Z"))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000436 EXPECT_TRUE(
437 matches("class X {}; class Z : public X {};", YOrZDerivedFromX));
438 EXPECT_TRUE(matches("class Y {};", YOrZDerivedFromX));
439 EXPECT_TRUE(
440 notMatches("class X {}; class W : public X {};", YOrZDerivedFromX));
441 EXPECT_TRUE(notMatches("class Z {};", YOrZDerivedFromX));
442
Daniel Jasper84c763e2012-07-15 19:57:12 +0000443 DeclarationMatcher XOrYOrZOrU =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000444 recordDecl(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U")));
Daniel Jasper84c763e2012-07-15 19:57:12 +0000445 EXPECT_TRUE(matches("class X {};", XOrYOrZOrU));
446 EXPECT_TRUE(notMatches("class V {};", XOrYOrZOrU));
447
Manuel Klimek04616e42012-07-06 05:48:52 +0000448 DeclarationMatcher XOrYOrZOrUOrV =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000449 recordDecl(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U"),
450 hasName("V")));
Manuel Klimek04616e42012-07-06 05:48:52 +0000451 EXPECT_TRUE(matches("class X {};", XOrYOrZOrUOrV));
452 EXPECT_TRUE(matches("class Y {};", XOrYOrZOrUOrV));
453 EXPECT_TRUE(matches("class Z {};", XOrYOrZOrUOrV));
454 EXPECT_TRUE(matches("class U {};", XOrYOrZOrUOrV));
455 EXPECT_TRUE(matches("class V {};", XOrYOrZOrUOrV));
456 EXPECT_TRUE(notMatches("class A {};", XOrYOrZOrUOrV));
457}
458
459TEST(DeclarationMatcher, MatchHas) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000460 DeclarationMatcher HasClassX = recordDecl(has(recordDecl(hasName("X"))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000461 EXPECT_TRUE(matches("class Y { class X {}; };", HasClassX));
462 EXPECT_TRUE(matches("class X {};", HasClassX));
463
464 DeclarationMatcher YHasClassX =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000465 recordDecl(hasName("Y"), has(recordDecl(hasName("X"))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000466 EXPECT_TRUE(matches("class Y { class X {}; };", YHasClassX));
467 EXPECT_TRUE(notMatches("class X {};", YHasClassX));
468 EXPECT_TRUE(
469 notMatches("class Y { class Z { class X {}; }; };", YHasClassX));
470}
471
472TEST(DeclarationMatcher, MatchHasRecursiveAllOf) {
473 DeclarationMatcher Recursive =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000474 recordDecl(
475 has(recordDecl(
476 has(recordDecl(hasName("X"))),
477 has(recordDecl(hasName("Y"))),
Manuel Klimek04616e42012-07-06 05:48:52 +0000478 hasName("Z"))),
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000479 has(recordDecl(
480 has(recordDecl(hasName("A"))),
481 has(recordDecl(hasName("B"))),
Manuel Klimek04616e42012-07-06 05:48:52 +0000482 hasName("C"))),
483 hasName("F"));
484
485 EXPECT_TRUE(matches(
486 "class F {"
487 " class Z {"
488 " class X {};"
489 " class Y {};"
490 " };"
491 " class C {"
492 " class A {};"
493 " class B {};"
494 " };"
495 "};", Recursive));
496
497 EXPECT_TRUE(matches(
498 "class F {"
499 " class Z {"
500 " class A {};"
501 " class X {};"
502 " class Y {};"
503 " };"
504 " class C {"
505 " class X {};"
506 " class A {};"
507 " class B {};"
508 " };"
509 "};", Recursive));
510
511 EXPECT_TRUE(matches(
512 "class O1 {"
513 " class O2 {"
514 " class F {"
515 " class Z {"
516 " class A {};"
517 " class X {};"
518 " class Y {};"
519 " };"
520 " class C {"
521 " class X {};"
522 " class A {};"
523 " class B {};"
524 " };"
525 " };"
526 " };"
527 "};", Recursive));
528}
529
530TEST(DeclarationMatcher, MatchHasRecursiveAnyOf) {
531 DeclarationMatcher Recursive =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000532 recordDecl(
Manuel Klimek04616e42012-07-06 05:48:52 +0000533 anyOf(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000534 has(recordDecl(
Manuel Klimek04616e42012-07-06 05:48:52 +0000535 anyOf(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000536 has(recordDecl(
Manuel Klimek04616e42012-07-06 05:48:52 +0000537 hasName("X"))),
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000538 has(recordDecl(
Manuel Klimek04616e42012-07-06 05:48:52 +0000539 hasName("Y"))),
540 hasName("Z")))),
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000541 has(recordDecl(
Manuel Klimek04616e42012-07-06 05:48:52 +0000542 anyOf(
543 hasName("C"),
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000544 has(recordDecl(
Manuel Klimek04616e42012-07-06 05:48:52 +0000545 hasName("A"))),
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000546 has(recordDecl(
Manuel Klimek04616e42012-07-06 05:48:52 +0000547 hasName("B")))))),
548 hasName("F")));
549
550 EXPECT_TRUE(matches("class F {};", Recursive));
551 EXPECT_TRUE(matches("class Z {};", Recursive));
552 EXPECT_TRUE(matches("class C {};", Recursive));
553 EXPECT_TRUE(matches("class M { class N { class X {}; }; };", Recursive));
554 EXPECT_TRUE(matches("class M { class N { class B {}; }; };", Recursive));
555 EXPECT_TRUE(
556 matches("class O1 { class O2 {"
557 " class M { class N { class B {}; }; }; "
558 "}; };", Recursive));
559}
560
561TEST(DeclarationMatcher, MatchNot) {
562 DeclarationMatcher NotClassX =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000563 recordDecl(
Manuel Klimek04616e42012-07-06 05:48:52 +0000564 isDerivedFrom("Y"),
Manuel Klimek04616e42012-07-06 05:48:52 +0000565 unless(hasName("X")));
566 EXPECT_TRUE(notMatches("", NotClassX));
567 EXPECT_TRUE(notMatches("class Y {};", NotClassX));
568 EXPECT_TRUE(matches("class Y {}; class Z : public Y {};", NotClassX));
569 EXPECT_TRUE(notMatches("class Y {}; class X : public Y {};", NotClassX));
570 EXPECT_TRUE(
571 notMatches("class Y {}; class Z {}; class X : public Y {};",
572 NotClassX));
573
574 DeclarationMatcher ClassXHasNotClassY =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000575 recordDecl(
Manuel Klimek04616e42012-07-06 05:48:52 +0000576 hasName("X"),
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000577 has(recordDecl(hasName("Z"))),
Manuel Klimek04616e42012-07-06 05:48:52 +0000578 unless(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000579 has(recordDecl(hasName("Y")))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000580 EXPECT_TRUE(matches("class X { class Z {}; };", ClassXHasNotClassY));
581 EXPECT_TRUE(notMatches("class X { class Y {}; class Z {}; };",
582 ClassXHasNotClassY));
583}
584
585TEST(DeclarationMatcher, HasDescendant) {
586 DeclarationMatcher ZDescendantClassX =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000587 recordDecl(
588 hasDescendant(recordDecl(hasName("X"))),
Manuel Klimek04616e42012-07-06 05:48:52 +0000589 hasName("Z"));
590 EXPECT_TRUE(matches("class Z { class X {}; };", ZDescendantClassX));
591 EXPECT_TRUE(
592 matches("class Z { class Y { class X {}; }; };", ZDescendantClassX));
593 EXPECT_TRUE(
594 matches("class Z { class A { class Y { class X {}; }; }; };",
595 ZDescendantClassX));
596 EXPECT_TRUE(
597 matches("class Z { class A { class B { class Y { class X {}; }; }; }; };",
598 ZDescendantClassX));
599 EXPECT_TRUE(notMatches("class Z {};", ZDescendantClassX));
600
601 DeclarationMatcher ZDescendantClassXHasClassY =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000602 recordDecl(
603 hasDescendant(recordDecl(has(recordDecl(hasName("Y"))),
Manuel Klimek04616e42012-07-06 05:48:52 +0000604 hasName("X"))),
605 hasName("Z"));
606 EXPECT_TRUE(matches("class Z { class X { class Y {}; }; };",
607 ZDescendantClassXHasClassY));
608 EXPECT_TRUE(
609 matches("class Z { class A { class B { class X { class Y {}; }; }; }; };",
610 ZDescendantClassXHasClassY));
611 EXPECT_TRUE(notMatches(
612 "class Z {"
613 " class A {"
614 " class B {"
615 " class X {"
616 " class C {"
617 " class Y {};"
618 " };"
619 " };"
620 " }; "
621 " };"
622 "};", ZDescendantClassXHasClassY));
623
624 DeclarationMatcher ZDescendantClassXDescendantClassY =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000625 recordDecl(
626 hasDescendant(recordDecl(hasDescendant(recordDecl(hasName("Y"))),
627 hasName("X"))),
Manuel Klimek04616e42012-07-06 05:48:52 +0000628 hasName("Z"));
629 EXPECT_TRUE(
630 matches("class Z { class A { class X { class B { class Y {}; }; }; }; };",
631 ZDescendantClassXDescendantClassY));
632 EXPECT_TRUE(matches(
633 "class Z {"
634 " class A {"
635 " class X {"
636 " class B {"
637 " class Y {};"
638 " };"
639 " class Y {};"
640 " };"
641 " };"
642 "};", ZDescendantClassXDescendantClassY));
643}
644
Daniel Jasperd29d5fa2012-10-29 10:14:44 +0000645// Implements a run method that returns whether BoundNodes contains a
646// Decl bound to Id that can be dynamically cast to T.
647// Optionally checks that the check succeeded a specific number of times.
648template <typename T>
649class VerifyIdIsBoundTo : public BoundNodesCallback {
650public:
651 // Create an object that checks that a node of type \c T was bound to \c Id.
652 // Does not check for a certain number of matches.
653 explicit VerifyIdIsBoundTo(llvm::StringRef Id)
654 : Id(Id), ExpectedCount(-1), Count(0) {}
655
656 // Create an object that checks that a node of type \c T was bound to \c Id.
657 // Checks that there were exactly \c ExpectedCount matches.
658 VerifyIdIsBoundTo(llvm::StringRef Id, int ExpectedCount)
659 : Id(Id), ExpectedCount(ExpectedCount), Count(0) {}
660
661 // Create an object that checks that a node of type \c T was bound to \c Id.
662 // Checks that there was exactly one match with the name \c ExpectedName.
663 // Note that \c T must be a NamedDecl for this to work.
Manuel Klimekb64d6b72013-03-14 16:33:21 +0000664 VerifyIdIsBoundTo(llvm::StringRef Id, llvm::StringRef ExpectedName,
665 int ExpectedCount = 1)
666 : Id(Id), ExpectedCount(ExpectedCount), Count(0),
667 ExpectedName(ExpectedName) {}
Daniel Jasperd29d5fa2012-10-29 10:14:44 +0000668
Craig Toppera798a9d2014-03-02 09:32:10 +0000669 void onEndOfTranslationUnit() override {
Daniel Jasperd29d5fa2012-10-29 10:14:44 +0000670 if (ExpectedCount != -1)
671 EXPECT_EQ(ExpectedCount, Count);
672 if (!ExpectedName.empty())
673 EXPECT_EQ(ExpectedName, Name);
Peter Collingbourne2b9471302013-11-07 22:30:32 +0000674 Count = 0;
675 Name.clear();
676 }
677
678 ~VerifyIdIsBoundTo() {
679 EXPECT_EQ(0, Count);
680 EXPECT_EQ("", Name);
Daniel Jasperd29d5fa2012-10-29 10:14:44 +0000681 }
682
683 virtual bool run(const BoundNodes *Nodes) {
Peter Collingbourne093a7292013-11-06 00:27:07 +0000684 const BoundNodes::IDToNodeMap &M = Nodes->getMap();
Daniel Jasperd29d5fa2012-10-29 10:14:44 +0000685 if (Nodes->getNodeAs<T>(Id)) {
686 ++Count;
687 if (const NamedDecl *Named = Nodes->getNodeAs<NamedDecl>(Id)) {
688 Name = Named->getNameAsString();
689 } else if (const NestedNameSpecifier *NNS =
690 Nodes->getNodeAs<NestedNameSpecifier>(Id)) {
691 llvm::raw_string_ostream OS(Name);
692 NNS->print(OS, PrintingPolicy(LangOptions()));
693 }
Peter Collingbourne093a7292013-11-06 00:27:07 +0000694 BoundNodes::IDToNodeMap::const_iterator I = M.find(Id);
695 EXPECT_NE(M.end(), I);
696 if (I != M.end())
697 EXPECT_EQ(Nodes->getNodeAs<T>(Id), I->second.get<T>());
Daniel Jasperd29d5fa2012-10-29 10:14:44 +0000698 return true;
699 }
Peter Collingbourne093a7292013-11-06 00:27:07 +0000700 EXPECT_TRUE(M.count(Id) == 0 || M.find(Id)->second.template get<T>() == 0);
Daniel Jasperd29d5fa2012-10-29 10:14:44 +0000701 return false;
702 }
703
Daniel Jaspere9aa6872012-10-29 10:48:25 +0000704 virtual bool run(const BoundNodes *Nodes, ASTContext *Context) {
705 return run(Nodes);
706 }
707
Daniel Jasperd29d5fa2012-10-29 10:14:44 +0000708private:
709 const std::string Id;
710 const int ExpectedCount;
711 int Count;
712 const std::string ExpectedName;
713 std::string Name;
714};
715
716TEST(HasDescendant, MatchesDescendantTypes) {
717 EXPECT_TRUE(matches("void f() { int i = 3; }",
718 decl(hasDescendant(loc(builtinType())))));
719 EXPECT_TRUE(matches("void f() { int i = 3; }",
720 stmt(hasDescendant(builtinType()))));
721
722 EXPECT_TRUE(matches("void f() { int i = 3; }",
723 stmt(hasDescendant(loc(builtinType())))));
724 EXPECT_TRUE(matches("void f() { int i = 3; }",
725 stmt(hasDescendant(qualType(builtinType())))));
726
727 EXPECT_TRUE(notMatches("void f() { float f = 2.0f; }",
728 stmt(hasDescendant(isInteger()))));
729
730 EXPECT_TRUE(matchAndVerifyResultTrue(
731 "void f() { int a; float c; int d; int e; }",
732 functionDecl(forEachDescendant(
733 varDecl(hasDescendant(isInteger())).bind("x"))),
734 new VerifyIdIsBoundTo<Decl>("x", 3)));
735}
736
737TEST(HasDescendant, MatchesDescendantsOfTypes) {
738 EXPECT_TRUE(matches("void f() { int*** i; }",
739 qualType(hasDescendant(builtinType()))));
740 EXPECT_TRUE(matches("void f() { int*** i; }",
741 qualType(hasDescendant(
742 pointerType(pointee(builtinType()))))));
743 EXPECT_TRUE(matches("void f() { int*** i; }",
David Blaikieb61d0872013-02-18 19:04:16 +0000744 typeLoc(hasDescendant(loc(builtinType())))));
Daniel Jasperd29d5fa2012-10-29 10:14:44 +0000745
746 EXPECT_TRUE(matchAndVerifyResultTrue(
747 "void f() { int*** i; }",
748 qualType(asString("int ***"), forEachDescendant(pointerType().bind("x"))),
749 new VerifyIdIsBoundTo<Type>("x", 2)));
750}
751
752TEST(Has, MatchesChildrenOfTypes) {
753 EXPECT_TRUE(matches("int i;",
754 varDecl(hasName("i"), has(isInteger()))));
755 EXPECT_TRUE(notMatches("int** i;",
756 varDecl(hasName("i"), has(isInteger()))));
757 EXPECT_TRUE(matchAndVerifyResultTrue(
758 "int (*f)(float, int);",
759 qualType(functionType(), forEach(qualType(isInteger()).bind("x"))),
760 new VerifyIdIsBoundTo<QualType>("x", 2)));
761}
762
763TEST(Has, MatchesChildTypes) {
764 EXPECT_TRUE(matches(
765 "int* i;",
766 varDecl(hasName("i"), hasType(qualType(has(builtinType()))))));
767 EXPECT_TRUE(notMatches(
768 "int* i;",
769 varDecl(hasName("i"), hasType(qualType(has(pointerType()))))));
770}
771
Daniel Jasper1dad1832012-07-10 20:20:19 +0000772TEST(Enum, DoesNotMatchClasses) {
773 EXPECT_TRUE(notMatches("class X {};", enumDecl(hasName("X"))));
774}
775
776TEST(Enum, MatchesEnums) {
777 EXPECT_TRUE(matches("enum X {};", enumDecl(hasName("X"))));
778}
779
780TEST(EnumConstant, Matches) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000781 DeclarationMatcher Matcher = enumConstantDecl(hasName("A"));
Daniel Jasper1dad1832012-07-10 20:20:19 +0000782 EXPECT_TRUE(matches("enum X{ A };", Matcher));
783 EXPECT_TRUE(notMatches("enum X{ B };", Matcher));
784 EXPECT_TRUE(notMatches("enum X {};", Matcher));
785}
786
Manuel Klimek04616e42012-07-06 05:48:52 +0000787TEST(StatementMatcher, Has) {
788 StatementMatcher HasVariableI =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000789 expr(hasType(pointsTo(recordDecl(hasName("X")))),
790 has(declRefExpr(to(varDecl(hasName("i"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000791
792 EXPECT_TRUE(matches(
793 "class X; X *x(int); void c() { int i; x(i); }", HasVariableI));
794 EXPECT_TRUE(notMatches(
795 "class X; X *x(int); void c() { int i; x(42); }", HasVariableI));
796}
797
798TEST(StatementMatcher, HasDescendant) {
799 StatementMatcher HasDescendantVariableI =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000800 expr(hasType(pointsTo(recordDecl(hasName("X")))),
801 hasDescendant(declRefExpr(to(varDecl(hasName("i"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000802
803 EXPECT_TRUE(matches(
804 "class X; X *x(bool); bool b(int); void c() { int i; x(b(i)); }",
805 HasDescendantVariableI));
806 EXPECT_TRUE(notMatches(
807 "class X; X *x(bool); bool b(int); void c() { int i; x(b(42)); }",
808 HasDescendantVariableI));
809}
810
811TEST(TypeMatcher, MatchesClassType) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000812 TypeMatcher TypeA = hasDeclaration(recordDecl(hasName("A")));
Manuel Klimek04616e42012-07-06 05:48:52 +0000813
814 EXPECT_TRUE(matches("class A { public: A *a; };", TypeA));
815 EXPECT_TRUE(notMatches("class A {};", TypeA));
816
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000817 TypeMatcher TypeDerivedFromA = hasDeclaration(recordDecl(isDerivedFrom("A")));
Manuel Klimek04616e42012-07-06 05:48:52 +0000818
819 EXPECT_TRUE(matches("class A {}; class B : public A { public: B *b; };",
820 TypeDerivedFromA));
821 EXPECT_TRUE(notMatches("class A {};", TypeA));
822
823 TypeMatcher TypeAHasClassB = hasDeclaration(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000824 recordDecl(hasName("A"), has(recordDecl(hasName("B")))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000825
826 EXPECT_TRUE(
827 matches("class A { public: A *a; class B {}; };", TypeAHasClassB));
828}
829
Manuel Klimek04616e42012-07-06 05:48:52 +0000830TEST(Matcher, BindMatchedNodes) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000831 DeclarationMatcher ClassX = has(recordDecl(hasName("::X")).bind("x"));
Manuel Klimek04616e42012-07-06 05:48:52 +0000832
833 EXPECT_TRUE(matchAndVerifyResultTrue("class X {};",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +0000834 ClassX, new VerifyIdIsBoundTo<CXXRecordDecl>("x")));
Manuel Klimek04616e42012-07-06 05:48:52 +0000835
836 EXPECT_TRUE(matchAndVerifyResultFalse("class X {};",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +0000837 ClassX, new VerifyIdIsBoundTo<CXXRecordDecl>("other-id")));
Manuel Klimek04616e42012-07-06 05:48:52 +0000838
839 TypeMatcher TypeAHasClassB = hasDeclaration(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000840 recordDecl(hasName("A"), has(recordDecl(hasName("B")).bind("b"))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000841
842 EXPECT_TRUE(matchAndVerifyResultTrue("class A { public: A *a; class B {}; };",
843 TypeAHasClassB,
Daniel Jaspera6bc1f62012-09-13 13:11:25 +0000844 new VerifyIdIsBoundTo<Decl>("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +0000845
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000846 StatementMatcher MethodX =
847 callExpr(callee(methodDecl(hasName("x")))).bind("x");
Manuel Klimek04616e42012-07-06 05:48:52 +0000848
849 EXPECT_TRUE(matchAndVerifyResultTrue("class A { void x() { x(); } };",
850 MethodX,
Daniel Jaspera6bc1f62012-09-13 13:11:25 +0000851 new VerifyIdIsBoundTo<CXXMemberCallExpr>("x")));
Daniel Jasper1dad1832012-07-10 20:20:19 +0000852}
853
854TEST(Matcher, BindTheSameNameInAlternatives) {
855 StatementMatcher matcher = anyOf(
856 binaryOperator(hasOperatorName("+"),
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000857 hasLHS(expr().bind("x")),
Daniel Jasper1dad1832012-07-10 20:20:19 +0000858 hasRHS(integerLiteral(equals(0)))),
859 binaryOperator(hasOperatorName("+"),
860 hasLHS(integerLiteral(equals(0))),
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000861 hasRHS(expr().bind("x"))));
Daniel Jasper1dad1832012-07-10 20:20:19 +0000862
863 EXPECT_TRUE(matchAndVerifyResultTrue(
864 // The first branch of the matcher binds x to 0 but then fails.
865 // The second branch binds x to f() and succeeds.
866 "int f() { return 0 + f(); }",
867 matcher,
Daniel Jaspera6bc1f62012-09-13 13:11:25 +0000868 new VerifyIdIsBoundTo<CallExpr>("x")));
Manuel Klimek04616e42012-07-06 05:48:52 +0000869}
870
Manuel Klimekfdf98762012-08-30 19:41:06 +0000871TEST(Matcher, BindsIDForMemoizedResults) {
872 // Using the same matcher in two match expressions will make memoization
873 // kick in.
874 DeclarationMatcher ClassX = recordDecl(hasName("X")).bind("x");
875 EXPECT_TRUE(matchAndVerifyResultTrue(
876 "class A { class B { class X {}; }; };",
877 DeclarationMatcher(anyOf(
878 recordDecl(hasName("A"), hasDescendant(ClassX)),
879 recordDecl(hasName("B"), hasDescendant(ClassX)))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +0000880 new VerifyIdIsBoundTo<Decl>("x", 2)));
Manuel Klimekfdf98762012-08-30 19:41:06 +0000881}
882
Daniel Jasper856194d02012-12-03 15:43:25 +0000883TEST(HasDeclaration, HasDeclarationOfEnumType) {
884 EXPECT_TRUE(matches("enum X {}; void y(X *x) { x; }",
885 expr(hasType(pointsTo(
886 qualType(hasDeclaration(enumDecl(hasName("X")))))))));
887}
888
Edwin Vaneed936452013-02-25 14:32:42 +0000889TEST(HasDeclaration, HasGetDeclTraitTest) {
890 EXPECT_TRUE(internal::has_getDecl<TypedefType>::value);
891 EXPECT_TRUE(internal::has_getDecl<RecordType>::value);
892 EXPECT_FALSE(internal::has_getDecl<TemplateSpecializationType>::value);
893}
894
Edwin Vane2c197e02013-02-19 17:14:34 +0000895TEST(HasDeclaration, HasDeclarationOfTypeWithDecl) {
896 EXPECT_TRUE(matches("typedef int X; X a;",
897 varDecl(hasName("a"),
898 hasType(typedefType(hasDeclaration(decl()))))));
899
900 // FIXME: Add tests for other types with getDecl() (e.g. RecordType)
901}
902
Edwin Vanef901b712013-02-25 14:49:29 +0000903TEST(HasDeclaration, HasDeclarationOfTemplateSpecializationType) {
904 EXPECT_TRUE(matches("template <typename T> class A {}; A<int> a;",
905 varDecl(hasType(templateSpecializationType(
906 hasDeclaration(namedDecl(hasName("A"))))))));
907}
908
Manuel Klimek04616e42012-07-06 05:48:52 +0000909TEST(HasType, TakesQualTypeMatcherAndMatchesExpr) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000910 TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X")));
Manuel Klimek04616e42012-07-06 05:48:52 +0000911 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000912 matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000913 EXPECT_TRUE(
914 notMatches("class X {}; void y(X *x) { x; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000915 expr(hasType(ClassX))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000916 EXPECT_TRUE(
917 matches("class X {}; void y(X *x) { x; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000918 expr(hasType(pointsTo(ClassX)))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000919}
920
921TEST(HasType, TakesQualTypeMatcherAndMatchesValueDecl) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000922 TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X")));
Manuel Klimek04616e42012-07-06 05:48:52 +0000923 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000924 matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000925 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000926 notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000927 EXPECT_TRUE(
928 matches("class X {}; void y() { X *x; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000929 varDecl(hasType(pointsTo(ClassX)))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000930}
931
932TEST(HasType, TakesDeclMatcherAndMatchesExpr) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000933 DeclarationMatcher ClassX = recordDecl(hasName("X"));
Manuel Klimek04616e42012-07-06 05:48:52 +0000934 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000935 matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000936 EXPECT_TRUE(
937 notMatches("class X {}; void y(X *x) { x; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000938 expr(hasType(ClassX))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000939}
940
941TEST(HasType, TakesDeclMatcherAndMatchesValueDecl) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000942 DeclarationMatcher ClassX = recordDecl(hasName("X"));
Manuel Klimek04616e42012-07-06 05:48:52 +0000943 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000944 matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000945 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000946 notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000947}
948
Manuel Klimekc16c6522013-06-20 13:08:29 +0000949TEST(HasTypeLoc, MatchesDeclaratorDecls) {
950 EXPECT_TRUE(matches("int x;",
951 varDecl(hasName("x"), hasTypeLoc(loc(asString("int"))))));
952
953 // Make sure we don't crash on implicit constructors.
954 EXPECT_TRUE(notMatches("class X {}; X x;",
955 declaratorDecl(hasTypeLoc(loc(asString("int"))))));
956}
957
Manuel Klimek04616e42012-07-06 05:48:52 +0000958TEST(Matcher, Call) {
959 // FIXME: Do we want to overload Call() to directly take
Daniel Jasper1dad1832012-07-10 20:20:19 +0000960 // Matcher<Decl>, too?
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000961 StatementMatcher MethodX = callExpr(hasDeclaration(methodDecl(hasName("x"))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000962
963 EXPECT_TRUE(matches("class Y { void x() { x(); } };", MethodX));
964 EXPECT_TRUE(notMatches("class Y { void x() {} };", MethodX));
965
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000966 StatementMatcher MethodOnY =
967 memberCallExpr(on(hasType(recordDecl(hasName("Y")))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000968
969 EXPECT_TRUE(
970 matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
971 MethodOnY));
972 EXPECT_TRUE(
973 matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
974 MethodOnY));
975 EXPECT_TRUE(
976 notMatches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
977 MethodOnY));
978 EXPECT_TRUE(
979 notMatches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
980 MethodOnY));
981 EXPECT_TRUE(
982 notMatches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
983 MethodOnY));
984
985 StatementMatcher MethodOnYPointer =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000986 memberCallExpr(on(hasType(pointsTo(recordDecl(hasName("Y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000987
988 EXPECT_TRUE(
989 matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
990 MethodOnYPointer));
991 EXPECT_TRUE(
992 matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
993 MethodOnYPointer));
994 EXPECT_TRUE(
995 matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
996 MethodOnYPointer));
997 EXPECT_TRUE(
998 notMatches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
999 MethodOnYPointer));
1000 EXPECT_TRUE(
1001 notMatches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
1002 MethodOnYPointer));
1003}
1004
Daniel Jasper5901e472012-10-01 13:40:41 +00001005TEST(Matcher, Lambda) {
Richard Smith3d584b02014-02-06 21:49:08 +00001006 EXPECT_TRUE(matches("auto f = [] (int i) { return i; };",
Daniel Jasper5901e472012-10-01 13:40:41 +00001007 lambdaExpr()));
1008}
1009
1010TEST(Matcher, ForRange) {
Daniel Jasper6f595392012-10-01 15:05:34 +00001011 EXPECT_TRUE(matches("int as[] = { 1, 2, 3 };"
1012 "void f() { for (auto &a : as); }",
Daniel Jasper5901e472012-10-01 13:40:41 +00001013 forRangeStmt()));
1014 EXPECT_TRUE(notMatches("void f() { for (int i; i<5; ++i); }",
1015 forRangeStmt()));
1016}
1017
1018TEST(Matcher, UserDefinedLiteral) {
1019 EXPECT_TRUE(matches("constexpr char operator \"\" _inc (const char i) {"
1020 " return i + 1;"
1021 "}"
1022 "char c = 'a'_inc;",
1023 userDefinedLiteral()));
1024}
1025
Daniel Jasper87c3d362012-09-20 14:12:57 +00001026TEST(Matcher, FlowControl) {
1027 EXPECT_TRUE(matches("void f() { while(true) { break; } }", breakStmt()));
1028 EXPECT_TRUE(matches("void f() { while(true) { continue; } }",
1029 continueStmt()));
1030 EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}", gotoStmt()));
1031 EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}", labelStmt()));
1032 EXPECT_TRUE(matches("void f() { return; }", returnStmt()));
1033}
1034
Daniel Jasper1dad1832012-07-10 20:20:19 +00001035TEST(HasType, MatchesAsString) {
1036 EXPECT_TRUE(
1037 matches("class Y { public: void x(); }; void z() {Y* y; y->x(); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001038 memberCallExpr(on(hasType(asString("class Y *"))))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001039 EXPECT_TRUE(matches("class X { void x(int x) {} };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001040 methodDecl(hasParameter(0, hasType(asString("int"))))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001041 EXPECT_TRUE(matches("namespace ns { struct A {}; } struct B { ns::A a; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001042 fieldDecl(hasType(asString("ns::A")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001043 EXPECT_TRUE(matches("namespace { struct A {}; } struct B { A a; };",
David Blaikieabe1a392014-04-02 05:58:29 +00001044 fieldDecl(hasType(asString("struct (anonymous namespace)::A")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001045}
1046
Manuel Klimek04616e42012-07-06 05:48:52 +00001047TEST(Matcher, OverloadedOperatorCall) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001048 StatementMatcher OpCall = operatorCallExpr();
Manuel Klimek04616e42012-07-06 05:48:52 +00001049 // Unary operator
1050 EXPECT_TRUE(matches("class Y { }; "
1051 "bool operator!(Y x) { return false; }; "
1052 "Y y; bool c = !y;", OpCall));
1053 // No match -- special operators like "new", "delete"
1054 // FIXME: operator new takes size_t, for which we need stddef.h, for which
1055 // we need to figure out include paths in the test.
1056 // EXPECT_TRUE(NotMatches("#include <stddef.h>\n"
1057 // "class Y { }; "
1058 // "void *operator new(size_t size) { return 0; } "
1059 // "Y *y = new Y;", OpCall));
1060 EXPECT_TRUE(notMatches("class Y { }; "
1061 "void operator delete(void *p) { } "
1062 "void a() {Y *y = new Y; delete y;}", OpCall));
1063 // Binary operator
1064 EXPECT_TRUE(matches("class Y { }; "
1065 "bool operator&&(Y x, Y y) { return true; }; "
1066 "Y a; Y b; bool c = a && b;",
1067 OpCall));
1068 // No match -- normal operator, not an overloaded one.
1069 EXPECT_TRUE(notMatches("bool x = true, y = true; bool t = x && y;", OpCall));
1070 EXPECT_TRUE(notMatches("int t = 5 << 2;", OpCall));
1071}
1072
1073TEST(Matcher, HasOperatorNameForOverloadedOperatorCall) {
1074 StatementMatcher OpCallAndAnd =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001075 operatorCallExpr(hasOverloadedOperatorName("&&"));
Manuel Klimek04616e42012-07-06 05:48:52 +00001076 EXPECT_TRUE(matches("class Y { }; "
1077 "bool operator&&(Y x, Y y) { return true; }; "
1078 "Y a; Y b; bool c = a && b;", OpCallAndAnd));
1079 StatementMatcher OpCallLessLess =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001080 operatorCallExpr(hasOverloadedOperatorName("<<"));
Manuel Klimek04616e42012-07-06 05:48:52 +00001081 EXPECT_TRUE(notMatches("class Y { }; "
1082 "bool operator&&(Y x, Y y) { return true; }; "
1083 "Y a; Y b; bool c = a && b;",
1084 OpCallLessLess));
Edwin Vane0a4836e2013-03-06 17:02:57 +00001085 DeclarationMatcher ClassWithOpStar =
1086 recordDecl(hasMethod(hasOverloadedOperatorName("*")));
1087 EXPECT_TRUE(matches("class Y { int operator*(); };",
1088 ClassWithOpStar));
1089 EXPECT_TRUE(notMatches("class Y { void myOperator(); };",
1090 ClassWithOpStar)) ;
Manuel Klimek04616e42012-07-06 05:48:52 +00001091}
1092
Daniel Jasper0f9f0192012-11-15 03:29:05 +00001093TEST(Matcher, NestedOverloadedOperatorCalls) {
1094 EXPECT_TRUE(matchAndVerifyResultTrue(
1095 "class Y { }; "
1096 "Y& operator&&(Y& x, Y& y) { return x; }; "
1097 "Y a; Y b; Y c; Y d = a && b && c;",
1098 operatorCallExpr(hasOverloadedOperatorName("&&")).bind("x"),
1099 new VerifyIdIsBoundTo<CXXOperatorCallExpr>("x", 2)));
1100 EXPECT_TRUE(matches(
1101 "class Y { }; "
1102 "Y& operator&&(Y& x, Y& y) { return x; }; "
1103 "Y a; Y b; Y c; Y d = a && b && c;",
1104 operatorCallExpr(hasParent(operatorCallExpr()))));
1105 EXPECT_TRUE(matches(
1106 "class Y { }; "
1107 "Y& operator&&(Y& x, Y& y) { return x; }; "
1108 "Y a; Y b; Y c; Y d = a && b && c;",
1109 operatorCallExpr(hasDescendant(operatorCallExpr()))));
1110}
1111
Manuel Klimek04616e42012-07-06 05:48:52 +00001112TEST(Matcher, ThisPointerType) {
Manuel Klimek86f8bbc2012-07-24 13:37:29 +00001113 StatementMatcher MethodOnY =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001114 memberCallExpr(thisPointerType(recordDecl(hasName("Y"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001115
1116 EXPECT_TRUE(
1117 matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
1118 MethodOnY));
1119 EXPECT_TRUE(
1120 matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
1121 MethodOnY));
1122 EXPECT_TRUE(
1123 matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
1124 MethodOnY));
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
1132 EXPECT_TRUE(matches(
1133 "class Y {"
1134 " public: virtual void x();"
1135 "};"
1136 "class X : public Y {"
1137 " public: virtual void x();"
1138 "};"
1139 "void z() { X *x; x->Y::x(); }", MethodOnY));
1140}
1141
1142TEST(Matcher, VariableUsage) {
1143 StatementMatcher Reference =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001144 declRefExpr(to(
1145 varDecl(hasInitializer(
1146 memberCallExpr(thisPointerType(recordDecl(hasName("Y"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001147
1148 EXPECT_TRUE(matches(
1149 "class Y {"
1150 " public:"
1151 " bool x() const;"
1152 "};"
1153 "void z(const Y &y) {"
1154 " bool b = y.x();"
1155 " if (b) {}"
1156 "}", Reference));
1157
1158 EXPECT_TRUE(notMatches(
1159 "class Y {"
1160 " public:"
1161 " bool x() const;"
1162 "};"
1163 "void z(const Y &y) {"
1164 " bool b = y.x();"
1165 "}", Reference));
1166}
1167
Samuel Benzaquenf56a2992014-06-05 18:22:14 +00001168TEST(Matcher, VarDecl_Storage) {
1169 auto M = varDecl(hasName("X"), hasLocalStorage());
1170 EXPECT_TRUE(matches("void f() { int X; }", M));
1171 EXPECT_TRUE(notMatches("int X;", M));
1172 EXPECT_TRUE(notMatches("void f() { static int X; }", M));
1173
1174 M = varDecl(hasName("X"), hasGlobalStorage());
1175 EXPECT_TRUE(notMatches("void f() { int X; }", M));
1176 EXPECT_TRUE(matches("int X;", M));
1177 EXPECT_TRUE(matches("void f() { static int X; }", M));
1178}
1179
Manuel Klimek61379422012-12-04 14:42:08 +00001180TEST(Matcher, FindsVarDeclInFunctionParameter) {
Daniel Jasper3cb72b42012-07-30 05:03:25 +00001181 EXPECT_TRUE(matches(
1182 "void f(int i) {}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001183 varDecl(hasName("i"))));
Daniel Jasper3cb72b42012-07-30 05:03:25 +00001184}
1185
Manuel Klimek04616e42012-07-06 05:48:52 +00001186TEST(Matcher, CalledVariable) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00001187 StatementMatcher CallOnVariableY =
1188 memberCallExpr(on(declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001189
1190 EXPECT_TRUE(matches(
1191 "class Y { public: void x() { Y y; y.x(); } };", CallOnVariableY));
1192 EXPECT_TRUE(matches(
1193 "class Y { public: void x() const { Y y; y.x(); } };", CallOnVariableY));
1194 EXPECT_TRUE(matches(
1195 "class Y { public: void x(); };"
1196 "class X : public Y { void z() { X y; y.x(); } };", CallOnVariableY));
1197 EXPECT_TRUE(matches(
1198 "class Y { public: void x(); };"
1199 "class X : public Y { void z() { X *y; y->x(); } };", CallOnVariableY));
1200 EXPECT_TRUE(notMatches(
1201 "class Y { public: void x(); };"
1202 "class X : public Y { void z() { unsigned long y; ((X*)y)->x(); } };",
1203 CallOnVariableY));
1204}
1205
Daniel Jasper1dad1832012-07-10 20:20:19 +00001206TEST(UnaryExprOrTypeTraitExpr, MatchesSizeOfAndAlignOf) {
1207 EXPECT_TRUE(matches("void x() { int a = sizeof(a); }",
1208 unaryExprOrTypeTraitExpr()));
1209 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }",
1210 alignOfExpr(anything())));
1211 // FIXME: Uncomment once alignof is enabled.
1212 // EXPECT_TRUE(matches("void x() { int a = alignof(a); }",
1213 // unaryExprOrTypeTraitExpr()));
1214 // EXPECT_TRUE(notMatches("void x() { int a = alignof(a); }",
1215 // sizeOfExpr()));
1216}
1217
1218TEST(UnaryExpressionOrTypeTraitExpression, MatchesCorrectType) {
1219 EXPECT_TRUE(matches("void x() { int a = sizeof(a); }", sizeOfExpr(
1220 hasArgumentOfType(asString("int")))));
1221 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
1222 hasArgumentOfType(asString("float")))));
1223 EXPECT_TRUE(matches(
1224 "struct A {}; void x() { A a; int b = sizeof(a); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001225 sizeOfExpr(hasArgumentOfType(hasDeclaration(recordDecl(hasName("A")))))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001226 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001227 hasArgumentOfType(hasDeclaration(recordDecl(hasName("string")))))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001228}
1229
Manuel Klimek04616e42012-07-06 05:48:52 +00001230TEST(MemberExpression, DoesNotMatchClasses) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001231 EXPECT_TRUE(notMatches("class Y { void x() {} };", memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001232}
1233
1234TEST(MemberExpression, MatchesMemberFunctionCall) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001235 EXPECT_TRUE(matches("class Y { void x() { x(); } };", memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001236}
1237
1238TEST(MemberExpression, MatchesVariable) {
1239 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001240 matches("class Y { void x() { this->y; } int y; };", memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001241 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001242 matches("class Y { void x() { y; } int y; };", memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001243 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001244 matches("class Y { void x() { Y y; y.y; } int y; };", memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001245}
1246
1247TEST(MemberExpression, MatchesStaticVariable) {
1248 EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001249 memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001250 EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001251 memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001252 EXPECT_TRUE(notMatches("class Y { void x() { Y::y; } static int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001253 memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001254}
1255
Daniel Jasper4e566c42012-07-12 08:50:38 +00001256TEST(IsInteger, MatchesIntegers) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001257 EXPECT_TRUE(matches("int i = 0;", varDecl(hasType(isInteger()))));
1258 EXPECT_TRUE(matches(
1259 "long long i = 0; void f(long long) { }; void g() {f(i);}",
1260 callExpr(hasArgument(0, declRefExpr(
1261 to(varDecl(hasType(isInteger()))))))));
Daniel Jasper4e566c42012-07-12 08:50:38 +00001262}
1263
1264TEST(IsInteger, ReportsNoFalsePositives) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001265 EXPECT_TRUE(notMatches("int *i;", varDecl(hasType(isInteger()))));
Daniel Jasper4e566c42012-07-12 08:50:38 +00001266 EXPECT_TRUE(notMatches("struct T {}; T t; void f(T *) { }; void g() {f(&t);}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001267 callExpr(hasArgument(0, declRefExpr(
1268 to(varDecl(hasType(isInteger()))))))));
Daniel Jasper4e566c42012-07-12 08:50:38 +00001269}
1270
Manuel Klimek04616e42012-07-06 05:48:52 +00001271TEST(IsArrow, MatchesMemberVariablesViaArrow) {
1272 EXPECT_TRUE(matches("class Y { void x() { this->y; } int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001273 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001274 EXPECT_TRUE(matches("class Y { void x() { y; } int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001275 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001276 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001277 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001278}
1279
1280TEST(IsArrow, MatchesStaticMemberVariablesViaArrow) {
1281 EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001282 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001283 EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001284 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001285 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } static int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001286 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001287}
1288
1289TEST(IsArrow, MatchesMemberCallsViaArrow) {
1290 EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001291 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001292 EXPECT_TRUE(matches("class Y { void x() { x(); } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001293 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001294 EXPECT_TRUE(notMatches("class Y { void x() { Y y; y.x(); } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001295 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001296}
1297
1298TEST(Callee, MatchesDeclarations) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001299 StatementMatcher CallMethodX = callExpr(callee(methodDecl(hasName("x"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001300
1301 EXPECT_TRUE(matches("class Y { void x() { x(); } };", CallMethodX));
1302 EXPECT_TRUE(notMatches("class Y { void x() {} };", CallMethodX));
1303}
1304
1305TEST(Callee, MatchesMemberExpressions) {
1306 EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001307 callExpr(callee(memberExpr()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001308 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001309 notMatches("class Y { void x() { this->x(); } };", callExpr(callee(callExpr()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001310}
1311
1312TEST(Function, MatchesFunctionDeclarations) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001313 StatementMatcher CallFunctionF = callExpr(callee(functionDecl(hasName("f"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001314
1315 EXPECT_TRUE(matches("void f() { f(); }", CallFunctionF));
1316 EXPECT_TRUE(notMatches("void f() { }", CallFunctionF));
1317
NAKAMURA Takumi7d2da0b2014-02-16 10:16:09 +00001318 if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getOS() !=
1319 llvm::Triple::Win32) {
1320 // FIXME: Make this work for MSVC.
1321 // Dependent contexts, but a non-dependent call.
1322 EXPECT_TRUE(matches("void f(); template <int N> void g() { f(); }",
1323 CallFunctionF));
1324 EXPECT_TRUE(
1325 matches("void f(); template <int N> struct S { void g() { f(); } };",
1326 CallFunctionF));
1327 }
Manuel Klimek04616e42012-07-06 05:48:52 +00001328
1329 // Depedent calls don't match.
1330 EXPECT_TRUE(
1331 notMatches("void f(int); template <typename T> void g(T t) { f(t); }",
1332 CallFunctionF));
1333 EXPECT_TRUE(
1334 notMatches("void f(int);"
1335 "template <typename T> struct S { void g(T t) { f(t); } };",
1336 CallFunctionF));
1337}
1338
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00001339TEST(FunctionTemplate, MatchesFunctionTemplateDeclarations) {
1340 EXPECT_TRUE(
1341 matches("template <typename T> void f(T t) {}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001342 functionTemplateDecl(hasName("f"))));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00001343}
1344
1345TEST(FunctionTemplate, DoesNotMatchFunctionDeclarations) {
1346 EXPECT_TRUE(
1347 notMatches("void f(double d); void f(int t) {}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001348 functionTemplateDecl(hasName("f"))));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00001349}
1350
1351TEST(FunctionTemplate, DoesNotMatchFunctionTemplateSpecializations) {
1352 EXPECT_TRUE(
1353 notMatches("void g(); template <typename T> void f(T t) {}"
1354 "template <> void f(int t) { g(); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001355 functionTemplateDecl(hasName("f"),
1356 hasDescendant(declRefExpr(to(
1357 functionDecl(hasName("g"))))))));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00001358}
1359
Manuel Klimek04616e42012-07-06 05:48:52 +00001360TEST(Matcher, Argument) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00001361 StatementMatcher CallArgumentY = callExpr(
1362 hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001363
1364 EXPECT_TRUE(matches("void x(int) { int y; x(y); }", CallArgumentY));
1365 EXPECT_TRUE(
1366 matches("class X { void x(int) { int y; x(y); } };", CallArgumentY));
1367 EXPECT_TRUE(notMatches("void x(int) { int z; x(z); }", CallArgumentY));
1368
Daniel Jasper848cbe12012-09-18 13:09:13 +00001369 StatementMatcher WrongIndex = callExpr(
1370 hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001371 EXPECT_TRUE(notMatches("void x(int) { int y; x(y); }", WrongIndex));
1372}
1373
1374TEST(Matcher, AnyArgument) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00001375 StatementMatcher CallArgumentY = callExpr(
1376 hasAnyArgument(declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001377 EXPECT_TRUE(matches("void x(int, int) { int y; x(1, y); }", CallArgumentY));
1378 EXPECT_TRUE(matches("void x(int, int) { int y; x(y, 42); }", CallArgumentY));
1379 EXPECT_TRUE(notMatches("void x(int, int) { x(1, 2); }", CallArgumentY));
1380}
1381
1382TEST(Matcher, ArgumentCount) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00001383 StatementMatcher Call1Arg = callExpr(argumentCountIs(1));
Manuel Klimek04616e42012-07-06 05:48:52 +00001384
1385 EXPECT_TRUE(matches("void x(int) { x(0); }", Call1Arg));
1386 EXPECT_TRUE(matches("class X { void x(int) { x(0); } };", Call1Arg));
1387 EXPECT_TRUE(notMatches("void x(int, int) { x(0, 0); }", Call1Arg));
1388}
1389
Daniel Jasper9f501292012-12-04 11:54:27 +00001390TEST(Matcher, ParameterCount) {
1391 DeclarationMatcher Function1Arg = functionDecl(parameterCountIs(1));
1392 EXPECT_TRUE(matches("void f(int i) {}", Function1Arg));
1393 EXPECT_TRUE(matches("class X { void f(int i) {} };", Function1Arg));
1394 EXPECT_TRUE(notMatches("void f() {}", Function1Arg));
1395 EXPECT_TRUE(notMatches("void f(int i, int j, int k) {}", Function1Arg));
1396}
1397
Manuel Klimek04616e42012-07-06 05:48:52 +00001398TEST(Matcher, References) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001399 DeclarationMatcher ReferenceClassX = varDecl(
1400 hasType(references(recordDecl(hasName("X")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001401 EXPECT_TRUE(matches("class X {}; void y(X y) { X &x = y; }",
1402 ReferenceClassX));
1403 EXPECT_TRUE(
1404 matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX));
Michael Hanc90d12d2013-09-11 15:53:29 +00001405 // The match here is on the implicit copy constructor code for
1406 // class X, not on code 'X x = y'.
Manuel Klimek04616e42012-07-06 05:48:52 +00001407 EXPECT_TRUE(
Michael Hanc90d12d2013-09-11 15:53:29 +00001408 matches("class X {}; void y(X y) { X x = y; }", ReferenceClassX));
1409 EXPECT_TRUE(
1410 notMatches("class X {}; extern X x;", ReferenceClassX));
Manuel Klimek04616e42012-07-06 05:48:52 +00001411 EXPECT_TRUE(
1412 notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX));
1413}
1414
Edwin Vane0a4836e2013-03-06 17:02:57 +00001415TEST(QualType, hasCanonicalType) {
1416 EXPECT_TRUE(notMatches("typedef int &int_ref;"
1417 "int a;"
1418 "int_ref b = a;",
1419 varDecl(hasType(qualType(referenceType())))));
1420 EXPECT_TRUE(
1421 matches("typedef int &int_ref;"
1422 "int a;"
1423 "int_ref b = a;",
1424 varDecl(hasType(qualType(hasCanonicalType(referenceType()))))));
1425}
1426
Edwin Vane119d3df2013-04-02 18:15:55 +00001427TEST(QualType, hasLocalQualifiers) {
1428 EXPECT_TRUE(notMatches("typedef const int const_int; const_int i = 1;",
1429 varDecl(hasType(hasLocalQualifiers()))));
1430 EXPECT_TRUE(matches("int *const j = nullptr;",
1431 varDecl(hasType(hasLocalQualifiers()))));
1432 EXPECT_TRUE(matches("int *volatile k;",
1433 varDecl(hasType(hasLocalQualifiers()))));
1434 EXPECT_TRUE(notMatches("int m;",
1435 varDecl(hasType(hasLocalQualifiers()))));
1436}
1437
Manuel Klimek04616e42012-07-06 05:48:52 +00001438TEST(HasParameter, CallsInnerMatcher) {
1439 EXPECT_TRUE(matches("class X { void x(int) {} };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001440 methodDecl(hasParameter(0, varDecl()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001441 EXPECT_TRUE(notMatches("class X { void x(int) {} };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001442 methodDecl(hasParameter(0, hasName("x")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001443}
1444
1445TEST(HasParameter, DoesNotMatchIfIndexOutOfBounds) {
1446 EXPECT_TRUE(notMatches("class X { void x(int) {} };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001447 methodDecl(hasParameter(42, varDecl()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001448}
1449
1450TEST(HasType, MatchesParameterVariableTypesStrictly) {
1451 EXPECT_TRUE(matches("class X { void x(X x) {} };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001452 methodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001453 EXPECT_TRUE(notMatches("class X { void x(const X &x) {} };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001454 methodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001455 EXPECT_TRUE(matches("class X { void x(const X *x) {} };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001456 methodDecl(hasParameter(0,
1457 hasType(pointsTo(recordDecl(hasName("X"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001458 EXPECT_TRUE(matches("class X { void x(const X &x) {} };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001459 methodDecl(hasParameter(0,
1460 hasType(references(recordDecl(hasName("X"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001461}
1462
1463TEST(HasAnyParameter, MatchesIndependentlyOfPosition) {
1464 EXPECT_TRUE(matches("class Y {}; class X { void x(X x, Y y) {} };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001465 methodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001466 EXPECT_TRUE(matches("class Y {}; class X { void x(Y y, X x) {} };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001467 methodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001468}
1469
Daniel Jasper1dad1832012-07-10 20:20:19 +00001470TEST(Returns, MatchesReturnTypes) {
1471 EXPECT_TRUE(matches("class Y { int f() { return 1; } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001472 functionDecl(returns(asString("int")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001473 EXPECT_TRUE(notMatches("class Y { int f() { return 1; } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001474 functionDecl(returns(asString("float")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001475 EXPECT_TRUE(matches("class Y { Y getMe() { return *this; } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001476 functionDecl(returns(hasDeclaration(
1477 recordDecl(hasName("Y")))))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001478}
1479
Daniel Jasperfaaffe32012-08-15 18:52:19 +00001480TEST(IsExternC, MatchesExternCFunctionDeclarations) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001481 EXPECT_TRUE(matches("extern \"C\" void f() {}", functionDecl(isExternC())));
1482 EXPECT_TRUE(matches("extern \"C\" { void f() {} }",
1483 functionDecl(isExternC())));
1484 EXPECT_TRUE(notMatches("void f() {}", functionDecl(isExternC())));
Daniel Jasperfaaffe32012-08-15 18:52:19 +00001485}
1486
Manuel Klimek04616e42012-07-06 05:48:52 +00001487TEST(HasAnyParameter, DoesntMatchIfInnerMatcherDoesntMatch) {
1488 EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001489 methodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001490}
1491
1492TEST(HasAnyParameter, DoesNotMatchThisPointer) {
1493 EXPECT_TRUE(notMatches("class Y {}; class X { void x() {} };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001494 methodDecl(hasAnyParameter(hasType(pointsTo(
1495 recordDecl(hasName("X"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001496}
1497
Alp Toker8db6e7a2014-01-05 06:38:57 +00001498TEST(HasName, MatchesParameterVariableDeclarations) {
Manuel Klimek04616e42012-07-06 05:48:52 +00001499 EXPECT_TRUE(matches("class Y {}; class X { void x(int x) {} };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001500 methodDecl(hasAnyParameter(hasName("x")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001501 EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001502 methodDecl(hasAnyParameter(hasName("x")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001503}
1504
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001505TEST(Matcher, MatchesClassTemplateSpecialization) {
1506 EXPECT_TRUE(matches("template<typename T> struct A {};"
1507 "template<> struct A<int> {};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001508 classTemplateSpecializationDecl()));
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001509 EXPECT_TRUE(matches("template<typename T> struct A {}; A<int> a;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001510 classTemplateSpecializationDecl()));
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001511 EXPECT_TRUE(notMatches("template<typename T> struct A {};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001512 classTemplateSpecializationDecl()));
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001513}
1514
Manuel Klimekc16c6522013-06-20 13:08:29 +00001515TEST(DeclaratorDecl, MatchesDeclaratorDecls) {
1516 EXPECT_TRUE(matches("int x;", declaratorDecl()));
1517 EXPECT_TRUE(notMatches("class A {};", declaratorDecl()));
1518}
1519
1520TEST(ParmVarDecl, MatchesParmVars) {
1521 EXPECT_TRUE(matches("void f(int x);", parmVarDecl()));
1522 EXPECT_TRUE(notMatches("void f();", parmVarDecl()));
1523}
1524
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001525TEST(Matcher, MatchesTypeTemplateArgument) {
1526 EXPECT_TRUE(matches(
1527 "template<typename T> struct B {};"
1528 "B<int> b;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001529 classTemplateSpecializationDecl(hasAnyTemplateArgument(refersToType(
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001530 asString("int"))))));
1531}
1532
1533TEST(Matcher, MatchesDeclarationReferenceTemplateArgument) {
1534 EXPECT_TRUE(matches(
1535 "struct B { int next; };"
1536 "template<int(B::*next_ptr)> struct A {};"
1537 "A<&B::next> a;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001538 classTemplateSpecializationDecl(hasAnyTemplateArgument(
1539 refersToDeclaration(fieldDecl(hasName("next")))))));
Daniel Jasper0c303372012-09-29 15:55:18 +00001540
1541 EXPECT_TRUE(notMatches(
1542 "template <typename T> struct A {};"
1543 "A<int> a;",
1544 classTemplateSpecializationDecl(hasAnyTemplateArgument(
1545 refersToDeclaration(decl())))));
Peter Collingbourne564597f2014-02-20 19:18:03 +00001546
1547 EXPECT_TRUE(matches(
1548 "struct B { int next; };"
1549 "template<int(B::*next_ptr)> struct A {};"
1550 "A<&B::next> a;",
1551 templateSpecializationType(hasAnyTemplateArgument(isExpr(
1552 hasDescendant(declRefExpr(to(fieldDecl(hasName("next"))))))))));
1553
1554 EXPECT_TRUE(notMatches(
1555 "template <typename T> struct A {};"
1556 "A<int> a;",
1557 templateSpecializationType(hasAnyTemplateArgument(
1558 refersToDeclaration(decl())))));
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001559}
1560
1561TEST(Matcher, MatchesSpecificArgument) {
1562 EXPECT_TRUE(matches(
1563 "template<typename T, typename U> class A {};"
1564 "A<bool, int> a;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001565 classTemplateSpecializationDecl(hasTemplateArgument(
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001566 1, refersToType(asString("int"))))));
1567 EXPECT_TRUE(notMatches(
1568 "template<typename T, typename U> class A {};"
1569 "A<int, bool> a;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001570 classTemplateSpecializationDecl(hasTemplateArgument(
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001571 1, refersToType(asString("int"))))));
Peter Collingbourne564597f2014-02-20 19:18:03 +00001572
1573 EXPECT_TRUE(matches(
1574 "template<typename T, typename U> class A {};"
1575 "A<bool, int> a;",
1576 templateSpecializationType(hasTemplateArgument(
1577 1, refersToType(asString("int"))))));
1578 EXPECT_TRUE(notMatches(
1579 "template<typename T, typename U> class A {};"
1580 "A<int, bool> a;",
1581 templateSpecializationType(hasTemplateArgument(
1582 1, refersToType(asString("int"))))));
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001583}
1584
Daniel Jasper639522c2013-02-25 12:02:08 +00001585TEST(Matcher, MatchesAccessSpecDecls) {
1586 EXPECT_TRUE(matches("class C { public: int i; };", accessSpecDecl()));
1587 EXPECT_TRUE(
1588 matches("class C { public: int i; };", accessSpecDecl(isPublic())));
1589 EXPECT_TRUE(
1590 notMatches("class C { public: int i; };", accessSpecDecl(isProtected())));
1591 EXPECT_TRUE(
1592 notMatches("class C { public: int i; };", accessSpecDecl(isPrivate())));
1593
1594 EXPECT_TRUE(notMatches("class C { int i; };", accessSpecDecl()));
1595}
1596
Edwin Vane37ee1d72013-04-09 20:46:36 +00001597TEST(Matcher, MatchesVirtualMethod) {
1598 EXPECT_TRUE(matches("class X { virtual int f(); };",
1599 methodDecl(isVirtual(), hasName("::X::f"))));
1600 EXPECT_TRUE(notMatches("class X { int f(); };",
1601 methodDecl(isVirtual())));
1602}
1603
Dmitri Gribenko51c1b552014-02-24 09:27:46 +00001604TEST(Matcher, MatchesPureMethod) {
1605 EXPECT_TRUE(matches("class X { virtual int f() = 0; };",
1606 methodDecl(isPure(), hasName("::X::f"))));
1607 EXPECT_TRUE(notMatches("class X { int f(); };",
1608 methodDecl(isPure())));
1609}
1610
Edwin Vanefc4f7dc2013-05-09 17:00:17 +00001611TEST(Matcher, MatchesConstMethod) {
1612 EXPECT_TRUE(matches("struct A { void foo() const; };",
1613 methodDecl(isConst())));
1614 EXPECT_TRUE(notMatches("struct A { void foo(); };",
1615 methodDecl(isConst())));
1616}
1617
Edwin Vane37ee1d72013-04-09 20:46:36 +00001618TEST(Matcher, MatchesOverridingMethod) {
1619 EXPECT_TRUE(matches("class X { virtual int f(); }; "
1620 "class Y : public X { int f(); };",
1621 methodDecl(isOverride(), hasName("::Y::f"))));
1622 EXPECT_TRUE(notMatches("class X { virtual int f(); }; "
1623 "class Y : public X { int f(); };",
1624 methodDecl(isOverride(), hasName("::X::f"))));
1625 EXPECT_TRUE(notMatches("class X { int f(); }; "
1626 "class Y : public X { int f(); };",
1627 methodDecl(isOverride())));
1628 EXPECT_TRUE(notMatches("class X { int f(); int f(int); }; ",
1629 methodDecl(isOverride())));
1630}
1631
Manuel Klimek04616e42012-07-06 05:48:52 +00001632TEST(Matcher, ConstructorCall) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00001633 StatementMatcher Constructor = constructExpr();
Manuel Klimek04616e42012-07-06 05:48:52 +00001634
1635 EXPECT_TRUE(
1636 matches("class X { public: X(); }; void x() { X x; }", Constructor));
1637 EXPECT_TRUE(
1638 matches("class X { public: X(); }; void x() { X x = X(); }",
1639 Constructor));
1640 EXPECT_TRUE(
1641 matches("class X { public: X(int); }; void x() { X x = 0; }",
1642 Constructor));
1643 EXPECT_TRUE(matches("class X {}; void x(int) { X x; }", Constructor));
1644}
1645
1646TEST(Matcher, ConstructorArgument) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00001647 StatementMatcher Constructor = constructExpr(
1648 hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001649
1650 EXPECT_TRUE(
1651 matches("class X { public: X(int); }; void x() { int y; X x(y); }",
1652 Constructor));
1653 EXPECT_TRUE(
1654 matches("class X { public: X(int); }; void x() { int y; X x = X(y); }",
1655 Constructor));
1656 EXPECT_TRUE(
1657 matches("class X { public: X(int); }; void x() { int y; X x = y; }",
1658 Constructor));
1659 EXPECT_TRUE(
1660 notMatches("class X { public: X(int); }; void x() { int z; X x(z); }",
1661 Constructor));
1662
Daniel Jasper848cbe12012-09-18 13:09:13 +00001663 StatementMatcher WrongIndex = constructExpr(
1664 hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001665 EXPECT_TRUE(
1666 notMatches("class X { public: X(int); }; void x() { int y; X x(y); }",
1667 WrongIndex));
1668}
1669
1670TEST(Matcher, ConstructorArgumentCount) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00001671 StatementMatcher Constructor1Arg = constructExpr(argumentCountIs(1));
Manuel Klimek04616e42012-07-06 05:48:52 +00001672
1673 EXPECT_TRUE(
1674 matches("class X { public: X(int); }; void x() { X x(0); }",
1675 Constructor1Arg));
1676 EXPECT_TRUE(
1677 matches("class X { public: X(int); }; void x() { X x = X(0); }",
1678 Constructor1Arg));
1679 EXPECT_TRUE(
1680 matches("class X { public: X(int); }; void x() { X x = 0; }",
1681 Constructor1Arg));
1682 EXPECT_TRUE(
1683 notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }",
1684 Constructor1Arg));
1685}
1686
Peter Collingbourne1fec3df2014-02-06 21:52:24 +00001687TEST(Matcher, ConstructorListInitialization) {
1688 StatementMatcher ConstructorListInit = constructExpr(isListInitialization());
1689
1690 EXPECT_TRUE(
1691 matches("class X { public: X(int); }; void x() { X x{0}; }",
1692 ConstructorListInit));
1693 EXPECT_FALSE(
1694 matches("class X { public: X(int); }; void x() { X x(0); }",
1695 ConstructorListInit));
1696}
1697
Manuel Klimek7fca93b2012-10-23 10:40:50 +00001698TEST(Matcher,ThisExpr) {
1699 EXPECT_TRUE(
1700 matches("struct X { int a; int f () { return a; } };", thisExpr()));
1701 EXPECT_TRUE(
1702 notMatches("struct X { int f () { int a; return a; } };", thisExpr()));
1703}
1704
Manuel Klimek04616e42012-07-06 05:48:52 +00001705TEST(Matcher, BindTemporaryExpression) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00001706 StatementMatcher TempExpression = bindTemporaryExpr();
Manuel Klimek04616e42012-07-06 05:48:52 +00001707
1708 std::string ClassString = "class string { public: string(); ~string(); }; ";
1709
1710 EXPECT_TRUE(
1711 matches(ClassString +
1712 "string GetStringByValue();"
1713 "void FunctionTakesString(string s);"
1714 "void run() { FunctionTakesString(GetStringByValue()); }",
1715 TempExpression));
1716
1717 EXPECT_TRUE(
1718 notMatches(ClassString +
1719 "string* GetStringPointer(); "
1720 "void FunctionTakesStringPtr(string* s);"
1721 "void run() {"
1722 " string* s = GetStringPointer();"
1723 " FunctionTakesStringPtr(GetStringPointer());"
1724 " FunctionTakesStringPtr(s);"
1725 "}",
1726 TempExpression));
1727
1728 EXPECT_TRUE(
1729 notMatches("class no_dtor {};"
1730 "no_dtor GetObjByValue();"
1731 "void ConsumeObj(no_dtor param);"
1732 "void run() { ConsumeObj(GetObjByValue()); }",
1733 TempExpression));
1734}
1735
Sam Panzer68a35af2012-08-24 22:04:44 +00001736TEST(MaterializeTemporaryExpr, MatchesTemporary) {
1737 std::string ClassString =
1738 "class string { public: string(); int length(); }; ";
1739
1740 EXPECT_TRUE(
1741 matches(ClassString +
1742 "string GetStringByValue();"
1743 "void FunctionTakesString(string s);"
1744 "void run() { FunctionTakesString(GetStringByValue()); }",
1745 materializeTemporaryExpr()));
1746
1747 EXPECT_TRUE(
1748 notMatches(ClassString +
1749 "string* GetStringPointer(); "
1750 "void FunctionTakesStringPtr(string* s);"
1751 "void run() {"
1752 " string* s = GetStringPointer();"
1753 " FunctionTakesStringPtr(GetStringPointer());"
1754 " FunctionTakesStringPtr(s);"
1755 "}",
1756 materializeTemporaryExpr()));
1757
1758 EXPECT_TRUE(
1759 notMatches(ClassString +
1760 "string GetStringByValue();"
1761 "void run() { int k = GetStringByValue().length(); }",
1762 materializeTemporaryExpr()));
1763
1764 EXPECT_TRUE(
1765 notMatches(ClassString +
1766 "string GetStringByValue();"
1767 "void run() { GetStringByValue(); }",
1768 materializeTemporaryExpr()));
1769}
1770
Manuel Klimek04616e42012-07-06 05:48:52 +00001771TEST(ConstructorDeclaration, SimpleCase) {
1772 EXPECT_TRUE(matches("class Foo { Foo(int i); };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001773 constructorDecl(ofClass(hasName("Foo")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001774 EXPECT_TRUE(notMatches("class Foo { Foo(int i); };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001775 constructorDecl(ofClass(hasName("Bar")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001776}
1777
1778TEST(ConstructorDeclaration, IsImplicit) {
1779 // This one doesn't match because the constructor is not added by the
1780 // compiler (it is not needed).
1781 EXPECT_TRUE(notMatches("class Foo { };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001782 constructorDecl(isImplicit())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001783 // The compiler added the implicit default constructor.
1784 EXPECT_TRUE(matches("class Foo { }; Foo* f = new Foo();",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001785 constructorDecl(isImplicit())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001786 EXPECT_TRUE(matches("class Foo { Foo(){} };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001787 constructorDecl(unless(isImplicit()))));
Joey Gouly0d9a2b22014-05-16 19:31:08 +00001788 // The compiler added an implicit assignment operator.
1789 EXPECT_TRUE(matches("struct A { int x; } a = {0}, b = a; void f() { a = b; }",
1790 methodDecl(isImplicit(), hasName("operator="))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001791}
1792
Daniel Jasper1dad1832012-07-10 20:20:19 +00001793TEST(DestructorDeclaration, MatchesVirtualDestructor) {
1794 EXPECT_TRUE(matches("class Foo { virtual ~Foo(); };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001795 destructorDecl(ofClass(hasName("Foo")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001796}
1797
1798TEST(DestructorDeclaration, DoesNotMatchImplicitDestructor) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001799 EXPECT_TRUE(notMatches("class Foo {};",
1800 destructorDecl(ofClass(hasName("Foo")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001801}
1802
Manuel Klimek04616e42012-07-06 05:48:52 +00001803TEST(HasAnyConstructorInitializer, SimpleCase) {
1804 EXPECT_TRUE(notMatches(
1805 "class Foo { Foo() { } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001806 constructorDecl(hasAnyConstructorInitializer(anything()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001807 EXPECT_TRUE(matches(
1808 "class Foo {"
1809 " Foo() : foo_() { }"
1810 " int foo_;"
1811 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001812 constructorDecl(hasAnyConstructorInitializer(anything()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001813}
1814
1815TEST(HasAnyConstructorInitializer, ForField) {
1816 static const char Code[] =
1817 "class Baz { };"
1818 "class Foo {"
1819 " Foo() : foo_() { }"
1820 " Baz foo_;"
1821 " Baz bar_;"
1822 "};";
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001823 EXPECT_TRUE(matches(Code, constructorDecl(hasAnyConstructorInitializer(
1824 forField(hasType(recordDecl(hasName("Baz"))))))));
1825 EXPECT_TRUE(matches(Code, constructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00001826 forField(hasName("foo_"))))));
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001827 EXPECT_TRUE(notMatches(Code, constructorDecl(hasAnyConstructorInitializer(
1828 forField(hasType(recordDecl(hasName("Bar"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001829}
1830
1831TEST(HasAnyConstructorInitializer, WithInitializer) {
1832 static const char Code[] =
1833 "class Foo {"
1834 " Foo() : foo_(0) { }"
1835 " int foo_;"
1836 "};";
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001837 EXPECT_TRUE(matches(Code, constructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00001838 withInitializer(integerLiteral(equals(0)))))));
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001839 EXPECT_TRUE(notMatches(Code, constructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00001840 withInitializer(integerLiteral(equals(1)))))));
1841}
1842
1843TEST(HasAnyConstructorInitializer, IsWritten) {
1844 static const char Code[] =
1845 "struct Bar { Bar(){} };"
1846 "class Foo {"
1847 " Foo() : foo_() { }"
1848 " Bar foo_;"
1849 " Bar bar_;"
1850 "};";
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001851 EXPECT_TRUE(matches(Code, constructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00001852 allOf(forField(hasName("foo_")), isWritten())))));
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001853 EXPECT_TRUE(notMatches(Code, constructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00001854 allOf(forField(hasName("bar_")), isWritten())))));
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001855 EXPECT_TRUE(matches(Code, constructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00001856 allOf(forField(hasName("bar_")), unless(isWritten()))))));
1857}
1858
1859TEST(Matcher, NewExpression) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00001860 StatementMatcher New = newExpr();
Manuel Klimek04616e42012-07-06 05:48:52 +00001861
1862 EXPECT_TRUE(matches("class X { public: X(); }; void x() { new X; }", New));
1863 EXPECT_TRUE(
1864 matches("class X { public: X(); }; void x() { new X(); }", New));
1865 EXPECT_TRUE(
1866 matches("class X { public: X(int); }; void x() { new X(0); }", New));
1867 EXPECT_TRUE(matches("class X {}; void x(int) { new X; }", New));
1868}
1869
1870TEST(Matcher, NewExpressionArgument) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00001871 StatementMatcher New = constructExpr(
1872 hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001873
1874 EXPECT_TRUE(
1875 matches("class X { public: X(int); }; void x() { int y; new X(y); }",
1876 New));
1877 EXPECT_TRUE(
1878 matches("class X { public: X(int); }; void x() { int y; new X(y); }",
1879 New));
1880 EXPECT_TRUE(
1881 notMatches("class X { public: X(int); }; void x() { int z; new X(z); }",
1882 New));
1883
Daniel Jasper848cbe12012-09-18 13:09:13 +00001884 StatementMatcher WrongIndex = constructExpr(
1885 hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001886 EXPECT_TRUE(
1887 notMatches("class X { public: X(int); }; void x() { int y; new X(y); }",
1888 WrongIndex));
1889}
1890
1891TEST(Matcher, NewExpressionArgumentCount) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001892 StatementMatcher New = constructExpr(argumentCountIs(1));
Manuel Klimek04616e42012-07-06 05:48:52 +00001893
1894 EXPECT_TRUE(
1895 matches("class X { public: X(int); }; void x() { new X(0); }", New));
1896 EXPECT_TRUE(
1897 notMatches("class X { public: X(int, int); }; void x() { new X(0, 0); }",
1898 New));
1899}
1900
Daniel Jasper1dad1832012-07-10 20:20:19 +00001901TEST(Matcher, DeleteExpression) {
1902 EXPECT_TRUE(matches("struct A {}; void f(A* a) { delete a; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001903 deleteExpr()));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001904}
1905
Manuel Klimek04616e42012-07-06 05:48:52 +00001906TEST(Matcher, DefaultArgument) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001907 StatementMatcher Arg = defaultArgExpr();
Manuel Klimek04616e42012-07-06 05:48:52 +00001908
1909 EXPECT_TRUE(matches("void x(int, int = 0) { int y; x(y); }", Arg));
1910 EXPECT_TRUE(
1911 matches("class X { void x(int, int = 0) { int y; x(y); } };", Arg));
1912 EXPECT_TRUE(notMatches("void x(int, int = 0) { int y; x(y, 0); }", Arg));
1913}
1914
1915TEST(Matcher, StringLiterals) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00001916 StatementMatcher Literal = stringLiteral();
Manuel Klimek04616e42012-07-06 05:48:52 +00001917 EXPECT_TRUE(matches("const char *s = \"string\";", Literal));
1918 // wide string
1919 EXPECT_TRUE(matches("const wchar_t *s = L\"string\";", Literal));
1920 // with escaped characters
1921 EXPECT_TRUE(matches("const char *s = \"\x05five\";", Literal));
1922 // no matching -- though the data type is the same, there is no string literal
1923 EXPECT_TRUE(notMatches("const char s[1] = {'a'};", Literal));
1924}
1925
1926TEST(Matcher, CharacterLiterals) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00001927 StatementMatcher CharLiteral = characterLiteral();
Manuel Klimek04616e42012-07-06 05:48:52 +00001928 EXPECT_TRUE(matches("const char c = 'c';", CharLiteral));
1929 // wide character
1930 EXPECT_TRUE(matches("const char c = L'c';", CharLiteral));
1931 // wide character, Hex encoded, NOT MATCHED!
1932 EXPECT_TRUE(notMatches("const wchar_t c = 0x2126;", CharLiteral));
1933 EXPECT_TRUE(notMatches("const char c = 0x1;", CharLiteral));
1934}
1935
1936TEST(Matcher, IntegerLiterals) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00001937 StatementMatcher HasIntLiteral = integerLiteral();
Manuel Klimek04616e42012-07-06 05:48:52 +00001938 EXPECT_TRUE(matches("int i = 10;", HasIntLiteral));
1939 EXPECT_TRUE(matches("int i = 0x1AB;", HasIntLiteral));
1940 EXPECT_TRUE(matches("int i = 10L;", HasIntLiteral));
1941 EXPECT_TRUE(matches("int i = 10U;", HasIntLiteral));
1942
1943 // Non-matching cases (character literals, float and double)
1944 EXPECT_TRUE(notMatches("int i = L'a';",
1945 HasIntLiteral)); // this is actually a character
1946 // literal cast to int
1947 EXPECT_TRUE(notMatches("int i = 'a';", HasIntLiteral));
1948 EXPECT_TRUE(notMatches("int i = 1e10;", HasIntLiteral));
1949 EXPECT_TRUE(notMatches("int i = 10.0;", HasIntLiteral));
1950}
1951
Daniel Jasper91f1c8c2013-07-26 18:52:58 +00001952TEST(Matcher, FloatLiterals) {
1953 StatementMatcher HasFloatLiteral = floatLiteral();
1954 EXPECT_TRUE(matches("float i = 10.0;", HasFloatLiteral));
1955 EXPECT_TRUE(matches("float i = 10.0f;", HasFloatLiteral));
1956 EXPECT_TRUE(matches("double i = 10.0;", HasFloatLiteral));
1957 EXPECT_TRUE(matches("double i = 10.0L;", HasFloatLiteral));
1958 EXPECT_TRUE(matches("double i = 1e10;", HasFloatLiteral));
1959
1960 EXPECT_TRUE(notMatches("float i = 10;", HasFloatLiteral));
1961}
1962
Daniel Jasper5901e472012-10-01 13:40:41 +00001963TEST(Matcher, NullPtrLiteral) {
1964 EXPECT_TRUE(matches("int* i = nullptr;", nullPtrLiteralExpr()));
1965}
1966
Daniel Jasper87c3d362012-09-20 14:12:57 +00001967TEST(Matcher, AsmStatement) {
1968 EXPECT_TRUE(matches("void foo() { __asm(\"mov al, 2\"); }", asmStmt()));
1969}
1970
Manuel Klimek04616e42012-07-06 05:48:52 +00001971TEST(Matcher, Conditions) {
1972 StatementMatcher Condition = ifStmt(hasCondition(boolLiteral(equals(true))));
1973
1974 EXPECT_TRUE(matches("void x() { if (true) {} }", Condition));
1975 EXPECT_TRUE(notMatches("void x() { if (false) {} }", Condition));
1976 EXPECT_TRUE(notMatches("void x() { bool a = true; if (a) {} }", Condition));
1977 EXPECT_TRUE(notMatches("void x() { if (true || false) {} }", Condition));
1978 EXPECT_TRUE(notMatches("void x() { if (1) {} }", Condition));
1979}
1980
Manuel Klimek909b5c942014-05-27 10:04:12 +00001981TEST(IfStmt, ChildTraversalMatchers) {
1982 EXPECT_TRUE(matches("void f() { if (false) true; else false; }",
1983 ifStmt(hasThen(boolLiteral(equals(true))))));
1984 EXPECT_TRUE(notMatches("void f() { if (false) false; else true; }",
1985 ifStmt(hasThen(boolLiteral(equals(true))))));
1986 EXPECT_TRUE(matches("void f() { if (false) false; else true; }",
1987 ifStmt(hasElse(boolLiteral(equals(true))))));
1988 EXPECT_TRUE(notMatches("void f() { if (false) true; else false; }",
1989 ifStmt(hasElse(boolLiteral(equals(true))))));
1990}
1991
Manuel Klimek04616e42012-07-06 05:48:52 +00001992TEST(MatchBinaryOperator, HasOperatorName) {
1993 StatementMatcher OperatorOr = binaryOperator(hasOperatorName("||"));
1994
1995 EXPECT_TRUE(matches("void x() { true || false; }", OperatorOr));
1996 EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
1997}
1998
1999TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
2000 StatementMatcher OperatorTrueFalse =
2001 binaryOperator(hasLHS(boolLiteral(equals(true))),
2002 hasRHS(boolLiteral(equals(false))));
2003
2004 EXPECT_TRUE(matches("void x() { true || false; }", OperatorTrueFalse));
2005 EXPECT_TRUE(matches("void x() { true && false; }", OperatorTrueFalse));
2006 EXPECT_TRUE(notMatches("void x() { false || true; }", OperatorTrueFalse));
2007}
2008
2009TEST(MatchBinaryOperator, HasEitherOperand) {
2010 StatementMatcher HasOperand =
2011 binaryOperator(hasEitherOperand(boolLiteral(equals(false))));
2012
2013 EXPECT_TRUE(matches("void x() { true || false; }", HasOperand));
2014 EXPECT_TRUE(matches("void x() { false && true; }", HasOperand));
2015 EXPECT_TRUE(notMatches("void x() { true || true; }", HasOperand));
2016}
2017
2018TEST(Matcher, BinaryOperatorTypes) {
2019 // Integration test that verifies the AST provides all binary operators in
2020 // a way we expect.
2021 // FIXME: Operator ','
2022 EXPECT_TRUE(
2023 matches("void x() { 3, 4; }", binaryOperator(hasOperatorName(","))));
2024 EXPECT_TRUE(
2025 matches("bool b; bool c = (b = true);",
2026 binaryOperator(hasOperatorName("="))));
2027 EXPECT_TRUE(
2028 matches("bool b = 1 != 2;", binaryOperator(hasOperatorName("!="))));
2029 EXPECT_TRUE(
2030 matches("bool b = 1 == 2;", binaryOperator(hasOperatorName("=="))));
2031 EXPECT_TRUE(matches("bool b = 1 < 2;", binaryOperator(hasOperatorName("<"))));
2032 EXPECT_TRUE(
2033 matches("bool b = 1 <= 2;", binaryOperator(hasOperatorName("<="))));
2034 EXPECT_TRUE(
2035 matches("int i = 1 << 2;", binaryOperator(hasOperatorName("<<"))));
2036 EXPECT_TRUE(
2037 matches("int i = 1; int j = (i <<= 2);",
2038 binaryOperator(hasOperatorName("<<="))));
2039 EXPECT_TRUE(matches("bool b = 1 > 2;", binaryOperator(hasOperatorName(">"))));
2040 EXPECT_TRUE(
2041 matches("bool b = 1 >= 2;", binaryOperator(hasOperatorName(">="))));
2042 EXPECT_TRUE(
2043 matches("int i = 1 >> 2;", binaryOperator(hasOperatorName(">>"))));
2044 EXPECT_TRUE(
2045 matches("int i = 1; int j = (i >>= 2);",
2046 binaryOperator(hasOperatorName(">>="))));
2047 EXPECT_TRUE(
2048 matches("int i = 42 ^ 23;", binaryOperator(hasOperatorName("^"))));
2049 EXPECT_TRUE(
2050 matches("int i = 42; int j = (i ^= 42);",
2051 binaryOperator(hasOperatorName("^="))));
2052 EXPECT_TRUE(
2053 matches("int i = 42 % 23;", binaryOperator(hasOperatorName("%"))));
2054 EXPECT_TRUE(
2055 matches("int i = 42; int j = (i %= 42);",
2056 binaryOperator(hasOperatorName("%="))));
2057 EXPECT_TRUE(
2058 matches("bool b = 42 &23;", binaryOperator(hasOperatorName("&"))));
2059 EXPECT_TRUE(
2060 matches("bool b = true && false;",
2061 binaryOperator(hasOperatorName("&&"))));
2062 EXPECT_TRUE(
2063 matches("bool b = true; bool c = (b &= false);",
2064 binaryOperator(hasOperatorName("&="))));
2065 EXPECT_TRUE(
2066 matches("bool b = 42 | 23;", binaryOperator(hasOperatorName("|"))));
2067 EXPECT_TRUE(
2068 matches("bool b = true || false;",
2069 binaryOperator(hasOperatorName("||"))));
2070 EXPECT_TRUE(
2071 matches("bool b = true; bool c = (b |= false);",
2072 binaryOperator(hasOperatorName("|="))));
2073 EXPECT_TRUE(
2074 matches("int i = 42 *23;", binaryOperator(hasOperatorName("*"))));
2075 EXPECT_TRUE(
2076 matches("int i = 42; int j = (i *= 23);",
2077 binaryOperator(hasOperatorName("*="))));
2078 EXPECT_TRUE(
2079 matches("int i = 42 / 23;", binaryOperator(hasOperatorName("/"))));
2080 EXPECT_TRUE(
2081 matches("int i = 42; int j = (i /= 23);",
2082 binaryOperator(hasOperatorName("/="))));
2083 EXPECT_TRUE(
2084 matches("int i = 42 + 23;", binaryOperator(hasOperatorName("+"))));
2085 EXPECT_TRUE(
2086 matches("int i = 42; int j = (i += 23);",
2087 binaryOperator(hasOperatorName("+="))));
2088 EXPECT_TRUE(
2089 matches("int i = 42 - 23;", binaryOperator(hasOperatorName("-"))));
2090 EXPECT_TRUE(
2091 matches("int i = 42; int j = (i -= 23);",
2092 binaryOperator(hasOperatorName("-="))));
2093 EXPECT_TRUE(
2094 matches("struct A { void x() { void (A::*a)(); (this->*a)(); } };",
2095 binaryOperator(hasOperatorName("->*"))));
2096 EXPECT_TRUE(
2097 matches("struct A { void x() { void (A::*a)(); ((*this).*a)(); } };",
2098 binaryOperator(hasOperatorName(".*"))));
2099
2100 // Member expressions as operators are not supported in matches.
2101 EXPECT_TRUE(
2102 notMatches("struct A { void x(A *a) { a->x(this); } };",
2103 binaryOperator(hasOperatorName("->"))));
2104
2105 // Initializer assignments are not represented as operator equals.
2106 EXPECT_TRUE(
2107 notMatches("bool b = true;", binaryOperator(hasOperatorName("="))));
2108
2109 // Array indexing is not represented as operator.
2110 EXPECT_TRUE(notMatches("int a[42]; void x() { a[23]; }", unaryOperator()));
2111
2112 // Overloaded operators do not match at all.
2113 EXPECT_TRUE(notMatches(
2114 "struct A { bool operator&&(const A &a) const { return false; } };"
2115 "void x() { A a, b; a && b; }",
2116 binaryOperator()));
2117}
2118
2119TEST(MatchUnaryOperator, HasOperatorName) {
2120 StatementMatcher OperatorNot = unaryOperator(hasOperatorName("!"));
2121
2122 EXPECT_TRUE(matches("void x() { !true; } ", OperatorNot));
2123 EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
2124}
2125
2126TEST(MatchUnaryOperator, HasUnaryOperand) {
2127 StatementMatcher OperatorOnFalse =
2128 unaryOperator(hasUnaryOperand(boolLiteral(equals(false))));
2129
2130 EXPECT_TRUE(matches("void x() { !false; }", OperatorOnFalse));
2131 EXPECT_TRUE(notMatches("void x() { !true; }", OperatorOnFalse));
2132}
2133
2134TEST(Matcher, UnaryOperatorTypes) {
2135 // Integration test that verifies the AST provides all unary operators in
2136 // a way we expect.
2137 EXPECT_TRUE(matches("bool b = !true;", unaryOperator(hasOperatorName("!"))));
2138 EXPECT_TRUE(
2139 matches("bool b; bool *p = &b;", unaryOperator(hasOperatorName("&"))));
2140 EXPECT_TRUE(matches("int i = ~ 1;", unaryOperator(hasOperatorName("~"))));
2141 EXPECT_TRUE(
2142 matches("bool *p; bool b = *p;", unaryOperator(hasOperatorName("*"))));
2143 EXPECT_TRUE(
2144 matches("int i; int j = +i;", unaryOperator(hasOperatorName("+"))));
2145 EXPECT_TRUE(
2146 matches("int i; int j = -i;", unaryOperator(hasOperatorName("-"))));
2147 EXPECT_TRUE(
2148 matches("int i; int j = ++i;", unaryOperator(hasOperatorName("++"))));
2149 EXPECT_TRUE(
2150 matches("int i; int j = i++;", unaryOperator(hasOperatorName("++"))));
2151 EXPECT_TRUE(
2152 matches("int i; int j = --i;", unaryOperator(hasOperatorName("--"))));
2153 EXPECT_TRUE(
2154 matches("int i; int j = i--;", unaryOperator(hasOperatorName("--"))));
2155
2156 // We don't match conversion operators.
2157 EXPECT_TRUE(notMatches("int i; double d = (double)i;", unaryOperator()));
2158
2159 // Function calls are not represented as operator.
2160 EXPECT_TRUE(notMatches("void f(); void x() { f(); }", unaryOperator()));
2161
2162 // Overloaded operators do not match at all.
2163 // FIXME: We probably want to add that.
2164 EXPECT_TRUE(notMatches(
2165 "struct A { bool operator!() const { return false; } };"
2166 "void x() { A a; !a; }", unaryOperator(hasOperatorName("!"))));
2167}
2168
2169TEST(Matcher, ConditionalOperator) {
2170 StatementMatcher Conditional = conditionalOperator(
2171 hasCondition(boolLiteral(equals(true))),
2172 hasTrueExpression(boolLiteral(equals(false))));
2173
2174 EXPECT_TRUE(matches("void x() { true ? false : true; }", Conditional));
2175 EXPECT_TRUE(notMatches("void x() { false ? false : true; }", Conditional));
2176 EXPECT_TRUE(notMatches("void x() { true ? true : false; }", Conditional));
2177
2178 StatementMatcher ConditionalFalse = conditionalOperator(
2179 hasFalseExpression(boolLiteral(equals(false))));
2180
2181 EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse));
2182 EXPECT_TRUE(
2183 notMatches("void x() { true ? false : true; }", ConditionalFalse));
2184}
2185
Daniel Jasper1dad1832012-07-10 20:20:19 +00002186TEST(ArraySubscriptMatchers, ArraySubscripts) {
2187 EXPECT_TRUE(matches("int i[2]; void f() { i[1] = 1; }",
2188 arraySubscriptExpr()));
2189 EXPECT_TRUE(notMatches("int i; void f() { i = 1; }",
2190 arraySubscriptExpr()));
2191}
2192
2193TEST(ArraySubscriptMatchers, ArrayIndex) {
2194 EXPECT_TRUE(matches(
2195 "int i[2]; void f() { i[1] = 1; }",
2196 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
2197 EXPECT_TRUE(matches(
2198 "int i[2]; void f() { 1[i] = 1; }",
2199 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
2200 EXPECT_TRUE(notMatches(
2201 "int i[2]; void f() { i[1] = 1; }",
2202 arraySubscriptExpr(hasIndex(integerLiteral(equals(0))))));
2203}
2204
2205TEST(ArraySubscriptMatchers, MatchesArrayBase) {
2206 EXPECT_TRUE(matches(
2207 "int i[2]; void f() { i[1] = 2; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002208 arraySubscriptExpr(hasBase(implicitCastExpr(
2209 hasSourceExpression(declRefExpr()))))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00002210}
2211
Manuel Klimek04616e42012-07-06 05:48:52 +00002212TEST(Matcher, HasNameSupportsNamespaces) {
2213 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002214 recordDecl(hasName("a::b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002215 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002216 recordDecl(hasName("::a::b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002217 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002218 recordDecl(hasName("b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002219 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002220 recordDecl(hasName("C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002221 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002222 recordDecl(hasName("c::b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002223 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002224 recordDecl(hasName("a::c::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002225 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002226 recordDecl(hasName("a::b::A"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002227 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002228 recordDecl(hasName("::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002229 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002230 recordDecl(hasName("::b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002231 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002232 recordDecl(hasName("z::a::b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002233 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002234 recordDecl(hasName("a+b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002235 EXPECT_TRUE(notMatches("namespace a { namespace b { class AC; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002236 recordDecl(hasName("C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002237}
2238
2239TEST(Matcher, HasNameSupportsOuterClasses) {
2240 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002241 matches("class A { class B { class C; }; };",
2242 recordDecl(hasName("A::B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002243 EXPECT_TRUE(
2244 matches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002245 recordDecl(hasName("::A::B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002246 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002247 matches("class A { class B { class C; }; };",
2248 recordDecl(hasName("B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002249 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002250 matches("class A { class B { class C; }; };",
2251 recordDecl(hasName("C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002252 EXPECT_TRUE(
2253 notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002254 recordDecl(hasName("c::B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002255 EXPECT_TRUE(
2256 notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002257 recordDecl(hasName("A::c::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002258 EXPECT_TRUE(
2259 notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002260 recordDecl(hasName("A::B::A"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002261 EXPECT_TRUE(
2262 notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002263 recordDecl(hasName("::C"))));
2264 EXPECT_TRUE(
2265 notMatches("class A { class B { class C; }; };",
2266 recordDecl(hasName("::B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002267 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002268 recordDecl(hasName("z::A::B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002269 EXPECT_TRUE(
2270 notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002271 recordDecl(hasName("A+B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002272}
2273
2274TEST(Matcher, IsDefinition) {
2275 DeclarationMatcher DefinitionOfClassA =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002276 recordDecl(hasName("A"), isDefinition());
Manuel Klimek04616e42012-07-06 05:48:52 +00002277 EXPECT_TRUE(matches("class A {};", DefinitionOfClassA));
2278 EXPECT_TRUE(notMatches("class A;", DefinitionOfClassA));
2279
2280 DeclarationMatcher DefinitionOfVariableA =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002281 varDecl(hasName("a"), isDefinition());
Manuel Klimek04616e42012-07-06 05:48:52 +00002282 EXPECT_TRUE(matches("int a;", DefinitionOfVariableA));
2283 EXPECT_TRUE(notMatches("extern int a;", DefinitionOfVariableA));
2284
2285 DeclarationMatcher DefinitionOfMethodA =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002286 methodDecl(hasName("a"), isDefinition());
Manuel Klimek04616e42012-07-06 05:48:52 +00002287 EXPECT_TRUE(matches("class A { void a() {} };", DefinitionOfMethodA));
2288 EXPECT_TRUE(notMatches("class A { void a(); };", DefinitionOfMethodA));
2289}
2290
2291TEST(Matcher, OfClass) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002292 StatementMatcher Constructor = constructExpr(hasDeclaration(methodDecl(
Manuel Klimek04616e42012-07-06 05:48:52 +00002293 ofClass(hasName("X")))));
2294
2295 EXPECT_TRUE(
2296 matches("class X { public: X(); }; void x(int) { X x; }", Constructor));
2297 EXPECT_TRUE(
2298 matches("class X { public: X(); }; void x(int) { X x = X(); }",
2299 Constructor));
2300 EXPECT_TRUE(
2301 notMatches("class Y { public: Y(); }; void x(int) { Y y; }",
2302 Constructor));
2303}
2304
2305TEST(Matcher, VisitsTemplateInstantiations) {
2306 EXPECT_TRUE(matches(
2307 "class A { public: void x(); };"
2308 "template <typename T> class B { public: void y() { T t; t.x(); } };"
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002309 "void f() { B<A> b; b.y(); }",
2310 callExpr(callee(methodDecl(hasName("x"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002311
2312 EXPECT_TRUE(matches(
2313 "class A { public: void x(); };"
2314 "class C {"
2315 " public:"
2316 " template <typename T> class B { public: void y() { T t; t.x(); } };"
2317 "};"
2318 "void f() {"
2319 " C::B<A> b; b.y();"
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002320 "}",
2321 recordDecl(hasName("C"),
2322 hasDescendant(callExpr(callee(methodDecl(hasName("x"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002323}
2324
Daniel Jasper1dad1832012-07-10 20:20:19 +00002325TEST(Matcher, HandlesNullQualTypes) {
2326 // FIXME: Add a Type matcher so we can replace uses of this
2327 // variable with Type(True())
2328 const TypeMatcher AnyType = anything();
2329
2330 // We don't really care whether this matcher succeeds; we're testing that
2331 // it completes without crashing.
2332 EXPECT_TRUE(matches(
2333 "struct A { };"
2334 "template <typename T>"
2335 "void f(T t) {"
2336 " T local_t(t /* this becomes a null QualType in the AST */);"
2337 "}"
2338 "void g() {"
2339 " f(0);"
2340 "}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002341 expr(hasType(TypeMatcher(
Daniel Jasper1dad1832012-07-10 20:20:19 +00002342 anyOf(
2343 TypeMatcher(hasDeclaration(anything())),
2344 pointsTo(AnyType),
2345 references(AnyType)
2346 // Other QualType matchers should go here.
2347 ))))));
2348}
2349
Manuel Klimek04616e42012-07-06 05:48:52 +00002350// For testing AST_MATCHER_P().
Daniel Jasper1dad1832012-07-10 20:20:19 +00002351AST_MATCHER_P(Decl, just, internal::Matcher<Decl>, AMatcher) {
Manuel Klimek04616e42012-07-06 05:48:52 +00002352 // Make sure all special variables are used: node, match_finder,
2353 // bound_nodes_builder, and the parameter named 'AMatcher'.
2354 return AMatcher.matches(Node, Finder, Builder);
2355}
2356
2357TEST(AstMatcherPMacro, Works) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002358 DeclarationMatcher HasClassB = just(has(recordDecl(hasName("B")).bind("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +00002359
2360 EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00002361 HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +00002362
2363 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00002364 HasClassB, new VerifyIdIsBoundTo<Decl>("a")));
Manuel Klimek04616e42012-07-06 05:48:52 +00002365
2366 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00002367 HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +00002368}
2369
2370AST_POLYMORPHIC_MATCHER_P(
Samuel Benzaquenc6f2c9b2013-06-21 15:51:31 +00002371 polymorphicHas,
2372 AST_POLYMORPHIC_SUPPORTED_TYPES_2(Decl, Stmt),
2373 internal::Matcher<Decl>, AMatcher) {
Manuel Klimek04616e42012-07-06 05:48:52 +00002374 return Finder->matchesChildOf(
Manuel Klimekeb958de2012-09-05 12:12:07 +00002375 Node, AMatcher, Builder,
Manuel Klimek04616e42012-07-06 05:48:52 +00002376 ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
2377 ASTMatchFinder::BK_First);
2378}
2379
2380TEST(AstPolymorphicMatcherPMacro, Works) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002381 DeclarationMatcher HasClassB =
2382 polymorphicHas(recordDecl(hasName("B")).bind("b"));
Manuel Klimek04616e42012-07-06 05:48:52 +00002383
2384 EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00002385 HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +00002386
2387 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00002388 HasClassB, new VerifyIdIsBoundTo<Decl>("a")));
Manuel Klimek04616e42012-07-06 05:48:52 +00002389
2390 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00002391 HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +00002392
2393 StatementMatcher StatementHasClassB =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002394 polymorphicHas(recordDecl(hasName("B")));
Manuel Klimek04616e42012-07-06 05:48:52 +00002395
2396 EXPECT_TRUE(matches("void x() { class B {}; }", StatementHasClassB));
2397}
2398
2399TEST(For, FindsForLoops) {
2400 EXPECT_TRUE(matches("void f() { for(;;); }", forStmt()));
2401 EXPECT_TRUE(matches("void f() { if(true) for(;;); }", forStmt()));
Daniel Jasper6f595392012-10-01 15:05:34 +00002402 EXPECT_TRUE(notMatches("int as[] = { 1, 2, 3 };"
2403 "void f() { for (auto &a : as); }",
Daniel Jasper5901e472012-10-01 13:40:41 +00002404 forStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00002405}
2406
Daniel Jasper4e566c42012-07-12 08:50:38 +00002407TEST(For, ForLoopInternals) {
2408 EXPECT_TRUE(matches("void f(){ int i; for (; i < 3 ; ); }",
2409 forStmt(hasCondition(anything()))));
2410 EXPECT_TRUE(matches("void f() { for (int i = 0; ;); }",
2411 forStmt(hasLoopInit(anything()))));
2412}
2413
Alexander Kornienko9b539e12014-02-05 16:35:08 +00002414TEST(For, ForRangeLoopInternals) {
2415 EXPECT_TRUE(matches("void f(){ int a[] {1, 2}; for (int i : a); }",
2416 forRangeStmt(hasLoopVariable(anything()))));
Manuel Klimek86510812014-05-23 17:49:03 +00002417 EXPECT_TRUE(matches(
2418 "void f(){ int a[] {1, 2}; for (int i : a); }",
2419 forRangeStmt(hasRangeInit(declRefExpr(to(varDecl(hasName("a"))))))));
Alexander Kornienko9b539e12014-02-05 16:35:08 +00002420}
2421
Daniel Jasper4e566c42012-07-12 08:50:38 +00002422TEST(For, NegativeForLoopInternals) {
2423 EXPECT_TRUE(notMatches("void f(){ for (int i = 0; ; ++i); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002424 forStmt(hasCondition(expr()))));
Daniel Jasper4e566c42012-07-12 08:50:38 +00002425 EXPECT_TRUE(notMatches("void f() {int i; for (; i < 4; ++i) {} }",
2426 forStmt(hasLoopInit(anything()))));
2427}
2428
Manuel Klimek04616e42012-07-06 05:48:52 +00002429TEST(For, ReportsNoFalsePositives) {
2430 EXPECT_TRUE(notMatches("void f() { ; }", forStmt()));
2431 EXPECT_TRUE(notMatches("void f() { if(true); }", forStmt()));
2432}
2433
2434TEST(CompoundStatement, HandlesSimpleCases) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002435 EXPECT_TRUE(notMatches("void f();", compoundStmt()));
2436 EXPECT_TRUE(matches("void f() {}", compoundStmt()));
2437 EXPECT_TRUE(matches("void f() {{}}", compoundStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00002438}
2439
2440TEST(CompoundStatement, DoesNotMatchEmptyStruct) {
2441 // It's not a compound statement just because there's "{}" in the source
2442 // text. This is an AST search, not grep.
2443 EXPECT_TRUE(notMatches("namespace n { struct S {}; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002444 compoundStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00002445 EXPECT_TRUE(matches("namespace n { struct S { void f() {{}} }; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002446 compoundStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00002447}
2448
Daniel Jasper4e566c42012-07-12 08:50:38 +00002449TEST(HasBody, FindsBodyOfForWhileDoLoops) {
Manuel Klimek04616e42012-07-06 05:48:52 +00002450 EXPECT_TRUE(matches("void f() { for(;;) {} }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002451 forStmt(hasBody(compoundStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002452 EXPECT_TRUE(notMatches("void f() { for(;;); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002453 forStmt(hasBody(compoundStmt()))));
Daniel Jasper4e566c42012-07-12 08:50:38 +00002454 EXPECT_TRUE(matches("void f() { while(true) {} }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002455 whileStmt(hasBody(compoundStmt()))));
Daniel Jasper4e566c42012-07-12 08:50:38 +00002456 EXPECT_TRUE(matches("void f() { do {} while(true); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002457 doStmt(hasBody(compoundStmt()))));
Manuel Klimek2af0a912014-05-27 07:45:18 +00002458 EXPECT_TRUE(matches("void f() { int p[2]; for (auto x : p) {} }",
2459 forRangeStmt(hasBody(compoundStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002460}
2461
2462TEST(HasAnySubstatement, MatchesForTopLevelCompoundStatement) {
2463 // The simplest case: every compound statement is in a function
2464 // definition, and the function body itself must be a compound
2465 // statement.
2466 EXPECT_TRUE(matches("void f() { for (;;); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002467 compoundStmt(hasAnySubstatement(forStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002468}
2469
2470TEST(HasAnySubstatement, IsNotRecursive) {
2471 // It's really "has any immediate substatement".
2472 EXPECT_TRUE(notMatches("void f() { if (true) for (;;); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002473 compoundStmt(hasAnySubstatement(forStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002474}
2475
2476TEST(HasAnySubstatement, MatchesInNestedCompoundStatements) {
2477 EXPECT_TRUE(matches("void f() { if (true) { for (;;); } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002478 compoundStmt(hasAnySubstatement(forStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002479}
2480
2481TEST(HasAnySubstatement, FindsSubstatementBetweenOthers) {
2482 EXPECT_TRUE(matches("void f() { 1; 2; 3; for (;;); 4; 5; 6; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002483 compoundStmt(hasAnySubstatement(forStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002484}
2485
2486TEST(StatementCountIs, FindsNoStatementsInAnEmptyCompoundStatement) {
2487 EXPECT_TRUE(matches("void f() { }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002488 compoundStmt(statementCountIs(0))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002489 EXPECT_TRUE(notMatches("void f() {}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002490 compoundStmt(statementCountIs(1))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002491}
2492
2493TEST(StatementCountIs, AppearsToMatchOnlyOneCount) {
2494 EXPECT_TRUE(matches("void f() { 1; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002495 compoundStmt(statementCountIs(1))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002496 EXPECT_TRUE(notMatches("void f() { 1; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002497 compoundStmt(statementCountIs(0))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002498 EXPECT_TRUE(notMatches("void f() { 1; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002499 compoundStmt(statementCountIs(2))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002500}
2501
2502TEST(StatementCountIs, WorksWithMultipleStatements) {
2503 EXPECT_TRUE(matches("void f() { 1; 2; 3; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002504 compoundStmt(statementCountIs(3))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002505}
2506
2507TEST(StatementCountIs, WorksWithNestedCompoundStatements) {
2508 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002509 compoundStmt(statementCountIs(1))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002510 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002511 compoundStmt(statementCountIs(2))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002512 EXPECT_TRUE(notMatches("void f() { { 1; } { 1; 2; 3; 4; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002513 compoundStmt(statementCountIs(3))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002514 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002515 compoundStmt(statementCountIs(4))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002516}
2517
2518TEST(Member, WorksInSimplestCase) {
2519 EXPECT_TRUE(matches("struct { int first; } s; int i(s.first);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002520 memberExpr(member(hasName("first")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002521}
2522
2523TEST(Member, DoesNotMatchTheBaseExpression) {
2524 // Don't pick out the wrong part of the member expression, this should
2525 // be checking the member (name) only.
2526 EXPECT_TRUE(notMatches("struct { int i; } first; int i(first.i);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002527 memberExpr(member(hasName("first")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002528}
2529
2530TEST(Member, MatchesInMemberFunctionCall) {
2531 EXPECT_TRUE(matches("void f() {"
2532 " struct { void first() {}; } s;"
2533 " s.first();"
2534 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002535 memberExpr(member(hasName("first")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002536}
2537
Daniel Jasperb0c7b612012-10-23 15:46:39 +00002538TEST(Member, MatchesMember) {
2539 EXPECT_TRUE(matches(
2540 "struct A { int i; }; void f() { A a; a.i = 2; }",
2541 memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
2542 EXPECT_TRUE(notMatches(
2543 "struct A { float f; }; void f() { A a; a.f = 2.0f; }",
2544 memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
2545}
2546
Daniel Jasper639522c2013-02-25 12:02:08 +00002547TEST(Member, UnderstandsAccess) {
2548 EXPECT_TRUE(matches(
2549 "struct A { int i; };", fieldDecl(isPublic(), hasName("i"))));
2550 EXPECT_TRUE(notMatches(
2551 "struct A { int i; };", fieldDecl(isProtected(), hasName("i"))));
2552 EXPECT_TRUE(notMatches(
2553 "struct A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
2554
2555 EXPECT_TRUE(notMatches(
2556 "class A { int i; };", fieldDecl(isPublic(), hasName("i"))));
2557 EXPECT_TRUE(notMatches(
2558 "class A { int i; };", fieldDecl(isProtected(), hasName("i"))));
2559 EXPECT_TRUE(matches(
2560 "class A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
2561
2562 EXPECT_TRUE(notMatches(
2563 "class A { protected: int i; };", fieldDecl(isPublic(), hasName("i"))));
2564 EXPECT_TRUE(matches("class A { protected: int i; };",
2565 fieldDecl(isProtected(), hasName("i"))));
2566 EXPECT_TRUE(notMatches(
2567 "class A { protected: int i; };", fieldDecl(isPrivate(), hasName("i"))));
2568
2569 // Non-member decls have the AccessSpecifier AS_none and thus aren't matched.
2570 EXPECT_TRUE(notMatches("int i;", varDecl(isPublic(), hasName("i"))));
2571 EXPECT_TRUE(notMatches("int i;", varDecl(isProtected(), hasName("i"))));
2572 EXPECT_TRUE(notMatches("int i;", varDecl(isPrivate(), hasName("i"))));
2573}
2574
Dmitri Gribenko06963042012-08-18 00:29:27 +00002575TEST(Member, MatchesMemberAllocationFunction) {
Daniel Jasper5901e472012-10-01 13:40:41 +00002576 // Fails in C++11 mode
2577 EXPECT_TRUE(matchesConditionally(
2578 "namespace std { typedef typeof(sizeof(int)) size_t; }"
2579 "class X { void *operator new(std::size_t); };",
2580 methodDecl(ofClass(hasName("X"))), true, "-std=gnu++98"));
Dmitri Gribenko06963042012-08-18 00:29:27 +00002581
2582 EXPECT_TRUE(matches("class X { void operator delete(void*); };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002583 methodDecl(ofClass(hasName("X")))));
Dmitri Gribenko06963042012-08-18 00:29:27 +00002584
Daniel Jasper5901e472012-10-01 13:40:41 +00002585 // Fails in C++11 mode
2586 EXPECT_TRUE(matchesConditionally(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002587 "namespace std { typedef typeof(sizeof(int)) size_t; }"
2588 "class X { void operator delete[](void*, std::size_t); };",
Daniel Jasper5901e472012-10-01 13:40:41 +00002589 methodDecl(ofClass(hasName("X"))), true, "-std=gnu++98"));
Dmitri Gribenko06963042012-08-18 00:29:27 +00002590}
2591
Manuel Klimek04616e42012-07-06 05:48:52 +00002592TEST(HasObjectExpression, DoesNotMatchMember) {
2593 EXPECT_TRUE(notMatches(
2594 "class X {}; struct Z { X m; }; void f(Z z) { z.m; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002595 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002596}
2597
2598TEST(HasObjectExpression, MatchesBaseOfVariable) {
2599 EXPECT_TRUE(matches(
2600 "struct X { int m; }; void f(X x) { x.m; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002601 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002602 EXPECT_TRUE(matches(
2603 "struct X { int m; }; void f(X* x) { x->m; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002604 memberExpr(hasObjectExpression(
2605 hasType(pointsTo(recordDecl(hasName("X"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002606}
2607
2608TEST(HasObjectExpression,
2609 MatchesObjectExpressionOfImplicitlyFormedMemberExpression) {
2610 EXPECT_TRUE(matches(
2611 "class X {}; struct S { X m; void f() { this->m; } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002612 memberExpr(hasObjectExpression(
2613 hasType(pointsTo(recordDecl(hasName("S"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002614 EXPECT_TRUE(matches(
2615 "class X {}; struct S { X m; void f() { m; } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002616 memberExpr(hasObjectExpression(
2617 hasType(pointsTo(recordDecl(hasName("S"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002618}
2619
2620TEST(Field, DoesNotMatchNonFieldMembers) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002621 EXPECT_TRUE(notMatches("class X { void m(); };", fieldDecl(hasName("m"))));
2622 EXPECT_TRUE(notMatches("class X { class m {}; };", fieldDecl(hasName("m"))));
2623 EXPECT_TRUE(notMatches("class X { enum { m }; };", fieldDecl(hasName("m"))));
2624 EXPECT_TRUE(notMatches("class X { enum m {}; };", fieldDecl(hasName("m"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002625}
2626
2627TEST(Field, MatchesField) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002628 EXPECT_TRUE(matches("class X { int m; };", fieldDecl(hasName("m"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002629}
2630
2631TEST(IsConstQualified, MatchesConstInt) {
2632 EXPECT_TRUE(matches("const int i = 42;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002633 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002634}
2635
2636TEST(IsConstQualified, MatchesConstPointer) {
2637 EXPECT_TRUE(matches("int i = 42; int* const p(&i);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002638 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002639}
2640
2641TEST(IsConstQualified, MatchesThroughTypedef) {
2642 EXPECT_TRUE(matches("typedef const int const_int; const_int i = 42;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002643 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002644 EXPECT_TRUE(matches("typedef int* int_ptr; const int_ptr p(0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002645 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002646}
2647
2648TEST(IsConstQualified, DoesNotMatchInappropriately) {
2649 EXPECT_TRUE(notMatches("typedef int nonconst_int; nonconst_int i = 42;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002650 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002651 EXPECT_TRUE(notMatches("int const* p;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002652 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002653}
2654
Sam Panzer80c13772012-08-16 16:58:10 +00002655TEST(CastExpression, MatchesExplicitCasts) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00002656 EXPECT_TRUE(matches("char *p = reinterpret_cast<char *>(&p);",castExpr()));
2657 EXPECT_TRUE(matches("void *p = (void *)(&p);", castExpr()));
2658 EXPECT_TRUE(matches("char q, *p = const_cast<char *>(&q);", castExpr()));
2659 EXPECT_TRUE(matches("char c = char(0);", castExpr()));
Sam Panzer80c13772012-08-16 16:58:10 +00002660}
2661TEST(CastExpression, MatchesImplicitCasts) {
2662 // This test creates an implicit cast from int to char.
Daniel Jasper848cbe12012-09-18 13:09:13 +00002663 EXPECT_TRUE(matches("char c = 0;", castExpr()));
Sam Panzer80c13772012-08-16 16:58:10 +00002664 // This test creates an implicit cast from lvalue to rvalue.
Daniel Jasper848cbe12012-09-18 13:09:13 +00002665 EXPECT_TRUE(matches("char c = 0, d = c;", castExpr()));
Sam Panzer80c13772012-08-16 16:58:10 +00002666}
2667
2668TEST(CastExpression, DoesNotMatchNonCasts) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00002669 EXPECT_TRUE(notMatches("char c = '0';", castExpr()));
2670 EXPECT_TRUE(notMatches("char c, &q = c;", castExpr()));
2671 EXPECT_TRUE(notMatches("int i = (0);", castExpr()));
2672 EXPECT_TRUE(notMatches("int i = 0;", castExpr()));
Sam Panzer80c13772012-08-16 16:58:10 +00002673}
2674
Manuel Klimek04616e42012-07-06 05:48:52 +00002675TEST(ReinterpretCast, MatchesSimpleCase) {
2676 EXPECT_TRUE(matches("char* p = reinterpret_cast<char*>(&p);",
Daniel Jasper848cbe12012-09-18 13:09:13 +00002677 reinterpretCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00002678}
2679
2680TEST(ReinterpretCast, DoesNotMatchOtherCasts) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00002681 EXPECT_TRUE(notMatches("char* p = (char*)(&p);", reinterpretCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00002682 EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
Daniel Jasper848cbe12012-09-18 13:09:13 +00002683 reinterpretCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00002684 EXPECT_TRUE(notMatches("void* p = static_cast<void*>(&p);",
Daniel Jasper848cbe12012-09-18 13:09:13 +00002685 reinterpretCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00002686 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
2687 "B b;"
2688 "D* p = dynamic_cast<D*>(&b);",
Daniel Jasper848cbe12012-09-18 13:09:13 +00002689 reinterpretCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00002690}
2691
2692TEST(FunctionalCast, MatchesSimpleCase) {
Ismail Pazarbasi1121de32014-01-17 21:08:52 +00002693 std::string foo_class = "class Foo { public: Foo(const char*); };";
Manuel Klimek04616e42012-07-06 05:48:52 +00002694 EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello world\"); }",
Daniel Jasper848cbe12012-09-18 13:09:13 +00002695 functionalCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00002696}
2697
2698TEST(FunctionalCast, DoesNotMatchOtherCasts) {
Ismail Pazarbasi1121de32014-01-17 21:08:52 +00002699 std::string FooClass = "class Foo { public: Foo(const char*); };";
Manuel Klimek04616e42012-07-06 05:48:52 +00002700 EXPECT_TRUE(
2701 notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\"; }",
Daniel Jasper848cbe12012-09-18 13:09:13 +00002702 functionalCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00002703 EXPECT_TRUE(
2704 notMatches(FooClass + "void r() { Foo f = \"hello world\"; }",
Daniel Jasper848cbe12012-09-18 13:09:13 +00002705 functionalCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00002706}
2707
2708TEST(DynamicCast, MatchesSimpleCase) {
2709 EXPECT_TRUE(matches("struct B { virtual ~B() {} }; struct D : B {};"
2710 "B b;"
2711 "D* p = dynamic_cast<D*>(&b);",
Daniel Jasper848cbe12012-09-18 13:09:13 +00002712 dynamicCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00002713}
2714
2715TEST(StaticCast, MatchesSimpleCase) {
2716 EXPECT_TRUE(matches("void* p(static_cast<void*>(&p));",
Daniel Jasper848cbe12012-09-18 13:09:13 +00002717 staticCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00002718}
2719
2720TEST(StaticCast, DoesNotMatchOtherCasts) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00002721 EXPECT_TRUE(notMatches("char* p = (char*)(&p);", staticCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00002722 EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
Daniel Jasper848cbe12012-09-18 13:09:13 +00002723 staticCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00002724 EXPECT_TRUE(notMatches("void* p = reinterpret_cast<char*>(&p);",
Daniel Jasper848cbe12012-09-18 13:09:13 +00002725 staticCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00002726 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
2727 "B b;"
2728 "D* p = dynamic_cast<D*>(&b);",
Daniel Jasper848cbe12012-09-18 13:09:13 +00002729 staticCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00002730}
2731
Daniel Jasper417f7762012-09-18 13:36:17 +00002732TEST(CStyleCast, MatchesSimpleCase) {
2733 EXPECT_TRUE(matches("int i = (int) 2.2f;", cStyleCastExpr()));
2734}
2735
2736TEST(CStyleCast, DoesNotMatchOtherCasts) {
2737 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);"
2738 "char q, *r = const_cast<char*>(&q);"
2739 "void* s = reinterpret_cast<char*>(&s);"
2740 "struct B { virtual ~B() {} }; struct D : B {};"
2741 "B b;"
2742 "D* t = dynamic_cast<D*>(&b);",
2743 cStyleCastExpr()));
2744}
2745
Manuel Klimek04616e42012-07-06 05:48:52 +00002746TEST(HasDestinationType, MatchesSimpleCase) {
2747 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
Daniel Jasper848cbe12012-09-18 13:09:13 +00002748 staticCastExpr(hasDestinationType(
2749 pointsTo(TypeMatcher(anything()))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002750}
2751
Sam Panzer80c13772012-08-16 16:58:10 +00002752TEST(HasImplicitDestinationType, MatchesSimpleCase) {
2753 // This test creates an implicit const cast.
2754 EXPECT_TRUE(matches("int x; const int i = x;",
Daniel Jasper848cbe12012-09-18 13:09:13 +00002755 implicitCastExpr(
2756 hasImplicitDestinationType(isInteger()))));
Sam Panzer80c13772012-08-16 16:58:10 +00002757 // This test creates an implicit array-to-pointer cast.
2758 EXPECT_TRUE(matches("int arr[3]; int *p = arr;",
Daniel Jasper848cbe12012-09-18 13:09:13 +00002759 implicitCastExpr(hasImplicitDestinationType(
2760 pointsTo(TypeMatcher(anything()))))));
Sam Panzer80c13772012-08-16 16:58:10 +00002761}
2762
2763TEST(HasImplicitDestinationType, DoesNotMatchIncorrectly) {
2764 // This test creates an implicit cast from int to char.
2765 EXPECT_TRUE(notMatches("char c = 0;",
Daniel Jasper848cbe12012-09-18 13:09:13 +00002766 implicitCastExpr(hasImplicitDestinationType(
2767 unless(anything())))));
Sam Panzer80c13772012-08-16 16:58:10 +00002768 // This test creates an implicit array-to-pointer cast.
2769 EXPECT_TRUE(notMatches("int arr[3]; int *p = arr;",
Daniel Jasper848cbe12012-09-18 13:09:13 +00002770 implicitCastExpr(hasImplicitDestinationType(
2771 unless(anything())))));
Sam Panzer80c13772012-08-16 16:58:10 +00002772}
2773
2774TEST(ImplicitCast, MatchesSimpleCase) {
2775 // This test creates an implicit const cast.
2776 EXPECT_TRUE(matches("int x = 0; const int y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002777 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00002778 // This test creates an implicit cast from int to char.
2779 EXPECT_TRUE(matches("char c = 0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002780 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00002781 // This test creates an implicit array-to-pointer cast.
2782 EXPECT_TRUE(matches("int arr[6]; int *p = arr;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002783 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00002784}
2785
2786TEST(ImplicitCast, DoesNotMatchIncorrectly) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002787 // This test verifies that implicitCastExpr() matches exactly when implicit casts
Sam Panzer80c13772012-08-16 16:58:10 +00002788 // are present, and that it ignores explicit and paren casts.
2789
2790 // These two test cases have no casts.
2791 EXPECT_TRUE(notMatches("int x = 0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002792 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00002793 EXPECT_TRUE(notMatches("int x = 0, &y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002794 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00002795
2796 EXPECT_TRUE(notMatches("int x = 0; double d = (double) x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002797 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00002798 EXPECT_TRUE(notMatches("const int *p; int *q = const_cast<int *>(p);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002799 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00002800
2801 EXPECT_TRUE(notMatches("int x = (0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002802 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00002803}
2804
2805TEST(IgnoringImpCasts, MatchesImpCasts) {
2806 // This test checks that ignoringImpCasts matches when implicit casts are
2807 // present and its inner matcher alone does not match.
2808 // Note that this test creates an implicit const cast.
2809 EXPECT_TRUE(matches("int x = 0; const int y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002810 varDecl(hasInitializer(ignoringImpCasts(
2811 declRefExpr(to(varDecl(hasName("x")))))))));
Sam Panzer80c13772012-08-16 16:58:10 +00002812 // This test creates an implict cast from int to char.
2813 EXPECT_TRUE(matches("char x = 0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002814 varDecl(hasInitializer(ignoringImpCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00002815 integerLiteral(equals(0)))))));
2816}
2817
2818TEST(IgnoringImpCasts, DoesNotMatchIncorrectly) {
2819 // These tests verify that ignoringImpCasts does not match if the inner
2820 // matcher does not match.
2821 // Note that the first test creates an implicit const cast.
2822 EXPECT_TRUE(notMatches("int x; const int y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002823 varDecl(hasInitializer(ignoringImpCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00002824 unless(anything()))))));
2825 EXPECT_TRUE(notMatches("int x; int y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002826 varDecl(hasInitializer(ignoringImpCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00002827 unless(anything()))))));
2828
2829 // These tests verify that ignoringImplictCasts does not look through explicit
2830 // casts or parentheses.
2831 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002832 varDecl(hasInitializer(ignoringImpCasts(
2833 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00002834 EXPECT_TRUE(notMatches("int i = (0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002835 varDecl(hasInitializer(ignoringImpCasts(
2836 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00002837 EXPECT_TRUE(notMatches("float i = (float)0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002838 varDecl(hasInitializer(ignoringImpCasts(
2839 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00002840 EXPECT_TRUE(notMatches("float i = float(0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002841 varDecl(hasInitializer(ignoringImpCasts(
2842 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00002843}
2844
2845TEST(IgnoringImpCasts, MatchesWithoutImpCasts) {
2846 // This test verifies that expressions that do not have implicit casts
2847 // still match the inner matcher.
2848 EXPECT_TRUE(matches("int x = 0; int &y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002849 varDecl(hasInitializer(ignoringImpCasts(
2850 declRefExpr(to(varDecl(hasName("x")))))))));
Sam Panzer80c13772012-08-16 16:58:10 +00002851}
2852
2853TEST(IgnoringParenCasts, MatchesParenCasts) {
2854 // This test checks that ignoringParenCasts matches when parentheses and/or
2855 // casts are present and its inner matcher alone does not match.
2856 EXPECT_TRUE(matches("int x = (0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002857 varDecl(hasInitializer(ignoringParenCasts(
2858 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00002859 EXPECT_TRUE(matches("int x = (((((0)))));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002860 varDecl(hasInitializer(ignoringParenCasts(
2861 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00002862
2863 // This test creates an implict cast from int to char in addition to the
2864 // parentheses.
2865 EXPECT_TRUE(matches("char x = (0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002866 varDecl(hasInitializer(ignoringParenCasts(
2867 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00002868
2869 EXPECT_TRUE(matches("char x = (char)0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002870 varDecl(hasInitializer(ignoringParenCasts(
2871 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00002872 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002873 varDecl(hasInitializer(ignoringParenCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00002874 integerLiteral(equals(0)))))));
2875}
2876
2877TEST(IgnoringParenCasts, MatchesWithoutParenCasts) {
2878 // This test verifies that expressions that do not have any casts still match.
2879 EXPECT_TRUE(matches("int x = 0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002880 varDecl(hasInitializer(ignoringParenCasts(
2881 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00002882}
2883
2884TEST(IgnoringParenCasts, DoesNotMatchIncorrectly) {
2885 // These tests verify that ignoringImpCasts does not match if the inner
2886 // matcher does not match.
2887 EXPECT_TRUE(notMatches("int x = ((0));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002888 varDecl(hasInitializer(ignoringParenCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00002889 unless(anything()))))));
2890
2891 // This test creates an implicit cast from int to char in addition to the
2892 // parentheses.
2893 EXPECT_TRUE(notMatches("char x = ((0));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002894 varDecl(hasInitializer(ignoringParenCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00002895 unless(anything()))))));
2896
2897 EXPECT_TRUE(notMatches("char *x = static_cast<char *>((0));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002898 varDecl(hasInitializer(ignoringParenCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00002899 unless(anything()))))));
2900}
2901
2902TEST(IgnoringParenAndImpCasts, MatchesParenImpCasts) {
2903 // This test checks that ignoringParenAndImpCasts matches when
2904 // parentheses and/or implicit casts are present and its inner matcher alone
2905 // does not match.
2906 // Note that this test creates an implicit const cast.
2907 EXPECT_TRUE(matches("int x = 0; const int y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002908 varDecl(hasInitializer(ignoringParenImpCasts(
2909 declRefExpr(to(varDecl(hasName("x")))))))));
Sam Panzer80c13772012-08-16 16:58:10 +00002910 // This test creates an implicit cast from int to char.
2911 EXPECT_TRUE(matches("const char x = (0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002912 varDecl(hasInitializer(ignoringParenImpCasts(
2913 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00002914}
2915
2916TEST(IgnoringParenAndImpCasts, MatchesWithoutParenImpCasts) {
2917 // This test verifies that expressions that do not have parentheses or
2918 // implicit casts still match.
2919 EXPECT_TRUE(matches("int x = 0; int &y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002920 varDecl(hasInitializer(ignoringParenImpCasts(
2921 declRefExpr(to(varDecl(hasName("x")))))))));
Sam Panzer80c13772012-08-16 16:58:10 +00002922 EXPECT_TRUE(matches("int x = 0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002923 varDecl(hasInitializer(ignoringParenImpCasts(
2924 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00002925}
2926
2927TEST(IgnoringParenAndImpCasts, DoesNotMatchIncorrectly) {
2928 // These tests verify that ignoringParenImpCasts does not match if
2929 // the inner matcher does not match.
2930 // This test creates an implicit cast.
2931 EXPECT_TRUE(notMatches("char c = ((3));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002932 varDecl(hasInitializer(ignoringParenImpCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00002933 unless(anything()))))));
2934 // These tests verify that ignoringParenAndImplictCasts does not look
2935 // through explicit casts.
2936 EXPECT_TRUE(notMatches("float y = (float(0));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002937 varDecl(hasInitializer(ignoringParenImpCasts(
2938 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00002939 EXPECT_TRUE(notMatches("float y = (float)0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002940 varDecl(hasInitializer(ignoringParenImpCasts(
2941 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00002942 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002943 varDecl(hasInitializer(ignoringParenImpCasts(
2944 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00002945}
2946
Manuel Klimeke9235692012-07-25 10:02:02 +00002947TEST(HasSourceExpression, MatchesImplicitCasts) {
Manuel Klimek04616e42012-07-06 05:48:52 +00002948 EXPECT_TRUE(matches("class string {}; class URL { public: URL(string s); };"
2949 "void r() {string a_string; URL url = a_string; }",
Daniel Jasper848cbe12012-09-18 13:09:13 +00002950 implicitCastExpr(
2951 hasSourceExpression(constructExpr()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002952}
2953
Manuel Klimeke9235692012-07-25 10:02:02 +00002954TEST(HasSourceExpression, MatchesExplicitCasts) {
2955 EXPECT_TRUE(matches("float x = static_cast<float>(42);",
Daniel Jasper848cbe12012-09-18 13:09:13 +00002956 explicitCastExpr(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002957 hasSourceExpression(hasDescendant(
Daniel Jasper848cbe12012-09-18 13:09:13 +00002958 expr(integerLiteral()))))));
Manuel Klimeke9235692012-07-25 10:02:02 +00002959}
2960
Manuel Klimek04616e42012-07-06 05:48:52 +00002961TEST(Statement, DoesNotMatchDeclarations) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002962 EXPECT_TRUE(notMatches("class X {};", stmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00002963}
2964
2965TEST(Statement, MatchesCompoundStatments) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002966 EXPECT_TRUE(matches("void x() {}", stmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00002967}
2968
2969TEST(DeclarationStatement, DoesNotMatchCompoundStatements) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002970 EXPECT_TRUE(notMatches("void x() {}", declStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00002971}
2972
2973TEST(DeclarationStatement, MatchesVariableDeclarationStatements) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002974 EXPECT_TRUE(matches("void x() { int a; }", declStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00002975}
2976
Samuel Benzaquenf1066292014-04-02 13:12:14 +00002977TEST(ExprWithCleanups, MatchesExprWithCleanups) {
2978 EXPECT_TRUE(matches("struct Foo { ~Foo(); };"
2979 "const Foo f = Foo();",
2980 varDecl(hasInitializer(exprWithCleanups()))));
2981 EXPECT_FALSE(matches("struct Foo { };"
2982 "const Foo f = Foo();",
2983 varDecl(hasInitializer(exprWithCleanups()))));
2984}
2985
Daniel Jasper1dad1832012-07-10 20:20:19 +00002986TEST(InitListExpression, MatchesInitListExpression) {
2987 EXPECT_TRUE(matches("int a[] = { 1, 2 };",
2988 initListExpr(hasType(asString("int [2]")))));
2989 EXPECT_TRUE(matches("struct B { int x, y; }; B b = { 5, 6 };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002990 initListExpr(hasType(recordDecl(hasName("B"))))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00002991}
2992
2993TEST(UsingDeclaration, MatchesUsingDeclarations) {
2994 EXPECT_TRUE(matches("namespace X { int x; } using X::x;",
2995 usingDecl()));
2996}
2997
2998TEST(UsingDeclaration, MatchesShadowUsingDelcarations) {
2999 EXPECT_TRUE(matches("namespace f { int a; } using f::a;",
3000 usingDecl(hasAnyUsingShadowDecl(hasName("a")))));
3001}
3002
3003TEST(UsingDeclaration, MatchesSpecificTarget) {
3004 EXPECT_TRUE(matches("namespace f { int a; void b(); } using f::b;",
3005 usingDecl(hasAnyUsingShadowDecl(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003006 hasTargetDecl(functionDecl())))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00003007 EXPECT_TRUE(notMatches("namespace f { int a; void b(); } using f::a;",
3008 usingDecl(hasAnyUsingShadowDecl(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003009 hasTargetDecl(functionDecl())))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00003010}
3011
3012TEST(UsingDeclaration, ThroughUsingDeclaration) {
3013 EXPECT_TRUE(matches(
3014 "namespace a { void f(); } using a::f; void g() { f(); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003015 declRefExpr(throughUsingDecl(anything()))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00003016 EXPECT_TRUE(notMatches(
3017 "namespace a { void f(); } using a::f; void g() { a::f(); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003018 declRefExpr(throughUsingDecl(anything()))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00003019}
3020
Sam Panzerd624bfb2012-08-16 17:20:59 +00003021TEST(SingleDecl, IsSingleDecl) {
3022 StatementMatcher SingleDeclStmt =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003023 declStmt(hasSingleDecl(varDecl(hasInitializer(anything()))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003024 EXPECT_TRUE(matches("void f() {int a = 4;}", SingleDeclStmt));
3025 EXPECT_TRUE(notMatches("void f() {int a;}", SingleDeclStmt));
3026 EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
3027 SingleDeclStmt));
3028}
3029
3030TEST(DeclStmt, ContainsDeclaration) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003031 DeclarationMatcher MatchesInit = varDecl(hasInitializer(anything()));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003032
3033 EXPECT_TRUE(matches("void f() {int a = 4;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003034 declStmt(containsDeclaration(0, MatchesInit))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003035 EXPECT_TRUE(matches("void f() {int a = 4, b = 3;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003036 declStmt(containsDeclaration(0, MatchesInit),
3037 containsDeclaration(1, MatchesInit))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003038 unsigned WrongIndex = 42;
3039 EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003040 declStmt(containsDeclaration(WrongIndex,
Sam Panzerd624bfb2012-08-16 17:20:59 +00003041 MatchesInit))));
3042}
3043
3044TEST(DeclCount, DeclCountIsCorrect) {
3045 EXPECT_TRUE(matches("void f() {int i,j;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003046 declStmt(declCountIs(2))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003047 EXPECT_TRUE(notMatches("void f() {int i,j; int k;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003048 declStmt(declCountIs(3))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003049 EXPECT_TRUE(notMatches("void f() {int i,j, k, l;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003050 declStmt(declCountIs(3))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003051}
3052
Manuel Klimek04616e42012-07-06 05:48:52 +00003053TEST(While, MatchesWhileLoops) {
3054 EXPECT_TRUE(notMatches("void x() {}", whileStmt()));
3055 EXPECT_TRUE(matches("void x() { while(true); }", whileStmt()));
3056 EXPECT_TRUE(notMatches("void x() { do {} while(true); }", whileStmt()));
3057}
3058
3059TEST(Do, MatchesDoLoops) {
3060 EXPECT_TRUE(matches("void x() { do {} while(true); }", doStmt()));
3061 EXPECT_TRUE(matches("void x() { do ; while(false); }", doStmt()));
3062}
3063
3064TEST(Do, DoesNotMatchWhileLoops) {
3065 EXPECT_TRUE(notMatches("void x() { while(true) {} }", doStmt()));
3066}
3067
3068TEST(SwitchCase, MatchesCase) {
3069 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchCase()));
3070 EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchCase()));
3071 EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchCase()));
3072 EXPECT_TRUE(notMatches("void x() { switch(42) {} }", switchCase()));
3073}
3074
Daniel Jasper87c3d362012-09-20 14:12:57 +00003075TEST(SwitchCase, MatchesSwitch) {
3076 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchStmt()));
3077 EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchStmt()));
3078 EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchStmt()));
3079 EXPECT_TRUE(notMatches("void x() {}", switchStmt()));
3080}
3081
Peter Collingbourne3154a102013-05-10 11:52:02 +00003082TEST(SwitchCase, MatchesEachCase) {
3083 EXPECT_TRUE(notMatches("void x() { switch(42); }",
3084 switchStmt(forEachSwitchCase(caseStmt()))));
3085 EXPECT_TRUE(matches("void x() { switch(42) case 42:; }",
3086 switchStmt(forEachSwitchCase(caseStmt()))));
3087 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }",
3088 switchStmt(forEachSwitchCase(caseStmt()))));
3089 EXPECT_TRUE(notMatches(
3090 "void x() { if (1) switch(42) { case 42: switch (42) { default:; } } }",
3091 ifStmt(has(switchStmt(forEachSwitchCase(defaultStmt()))))));
3092 EXPECT_TRUE(matches("void x() { switch(42) { case 1+1: case 4:; } }",
3093 switchStmt(forEachSwitchCase(
3094 caseStmt(hasCaseConstant(integerLiteral()))))));
3095 EXPECT_TRUE(notMatches("void x() { switch(42) { case 1+1: case 2+2:; } }",
3096 switchStmt(forEachSwitchCase(
3097 caseStmt(hasCaseConstant(integerLiteral()))))));
3098 EXPECT_TRUE(notMatches("void x() { switch(42) { case 1 ... 2:; } }",
3099 switchStmt(forEachSwitchCase(
3100 caseStmt(hasCaseConstant(integerLiteral()))))));
3101 EXPECT_TRUE(matchAndVerifyResultTrue(
3102 "void x() { switch (42) { case 1: case 2: case 3: default:; } }",
3103 switchStmt(forEachSwitchCase(caseStmt().bind("x"))),
3104 new VerifyIdIsBoundTo<CaseStmt>("x", 3)));
3105}
3106
Manuel Klimekba46fc02013-07-19 11:50:54 +00003107TEST(ForEachConstructorInitializer, MatchesInitializers) {
3108 EXPECT_TRUE(matches(
3109 "struct X { X() : i(42), j(42) {} int i, j; };",
3110 constructorDecl(forEachConstructorInitializer(ctorInitializer()))));
3111}
3112
Daniel Jasper87c3d362012-09-20 14:12:57 +00003113TEST(ExceptionHandling, SimpleCases) {
3114 EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", catchStmt()));
3115 EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", tryStmt()));
3116 EXPECT_TRUE(notMatches("void foo() try { } catch(int X) { }", throwExpr()));
3117 EXPECT_TRUE(matches("void foo() try { throw; } catch(int X) { }",
3118 throwExpr()));
3119 EXPECT_TRUE(matches("void foo() try { throw 5;} catch(int X) { }",
3120 throwExpr()));
3121}
3122
Manuel Klimek04616e42012-07-06 05:48:52 +00003123TEST(HasConditionVariableStatement, DoesNotMatchCondition) {
3124 EXPECT_TRUE(notMatches(
3125 "void x() { if(true) {} }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003126 ifStmt(hasConditionVariableStatement(declStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003127 EXPECT_TRUE(notMatches(
3128 "void x() { int x; if((x = 42)) {} }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003129 ifStmt(hasConditionVariableStatement(declStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003130}
3131
3132TEST(HasConditionVariableStatement, MatchesConditionVariables) {
3133 EXPECT_TRUE(matches(
3134 "void x() { if(int* a = 0) {} }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003135 ifStmt(hasConditionVariableStatement(declStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003136}
3137
3138TEST(ForEach, BindsOneNode) {
3139 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003140 recordDecl(hasName("C"), forEach(fieldDecl(hasName("x")).bind("x"))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003141 new VerifyIdIsBoundTo<FieldDecl>("x", 1)));
Manuel Klimek04616e42012-07-06 05:48:52 +00003142}
3143
3144TEST(ForEach, BindsMultipleNodes) {
3145 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; int y; int z; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003146 recordDecl(hasName("C"), forEach(fieldDecl().bind("f"))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003147 new VerifyIdIsBoundTo<FieldDecl>("f", 3)));
Manuel Klimek04616e42012-07-06 05:48:52 +00003148}
3149
3150TEST(ForEach, BindsRecursiveCombinations) {
3151 EXPECT_TRUE(matchAndVerifyResultTrue(
3152 "class C { class D { int x; int y; }; class E { int y; int z; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003153 recordDecl(hasName("C"),
3154 forEach(recordDecl(forEach(fieldDecl().bind("f"))))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003155 new VerifyIdIsBoundTo<FieldDecl>("f", 4)));
Manuel Klimek04616e42012-07-06 05:48:52 +00003156}
3157
3158TEST(ForEachDescendant, BindsOneNode) {
3159 EXPECT_TRUE(matchAndVerifyResultTrue("class C { class D { int x; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003160 recordDecl(hasName("C"),
3161 forEachDescendant(fieldDecl(hasName("x")).bind("x"))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003162 new VerifyIdIsBoundTo<FieldDecl>("x", 1)));
Manuel Klimek04616e42012-07-06 05:48:52 +00003163}
3164
Daniel Jasper94a56852012-11-16 18:39:22 +00003165TEST(ForEachDescendant, NestedForEachDescendant) {
3166 DeclarationMatcher m = recordDecl(
3167 isDefinition(), decl().bind("x"), hasName("C"));
3168 EXPECT_TRUE(matchAndVerifyResultTrue(
3169 "class A { class B { class C {}; }; };",
3170 recordDecl(hasName("A"), anyOf(m, forEachDescendant(m))),
3171 new VerifyIdIsBoundTo<Decl>("x", "C")));
3172
Manuel Klimeka0c025f2013-06-19 15:42:45 +00003173 // Check that a partial match of 'm' that binds 'x' in the
3174 // first part of anyOf(m, anything()) will not overwrite the
3175 // binding created by the earlier binding in the hasDescendant.
3176 EXPECT_TRUE(matchAndVerifyResultTrue(
3177 "class A { class B { class C {}; }; };",
3178 recordDecl(hasName("A"), allOf(hasDescendant(m), anyOf(m, anything()))),
3179 new VerifyIdIsBoundTo<Decl>("x", "C")));
Daniel Jasper94a56852012-11-16 18:39:22 +00003180}
3181
Manuel Klimek04616e42012-07-06 05:48:52 +00003182TEST(ForEachDescendant, BindsMultipleNodes) {
3183 EXPECT_TRUE(matchAndVerifyResultTrue(
3184 "class C { class D { int x; int y; }; "
3185 " class E { class F { int y; int z; }; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003186 recordDecl(hasName("C"), forEachDescendant(fieldDecl().bind("f"))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003187 new VerifyIdIsBoundTo<FieldDecl>("f", 4)));
Manuel Klimek04616e42012-07-06 05:48:52 +00003188}
3189
3190TEST(ForEachDescendant, BindsRecursiveCombinations) {
3191 EXPECT_TRUE(matchAndVerifyResultTrue(
3192 "class C { class D { "
3193 " class E { class F { class G { int y; int z; }; }; }; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003194 recordDecl(hasName("C"), forEachDescendant(recordDecl(
3195 forEachDescendant(fieldDecl().bind("f"))))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003196 new VerifyIdIsBoundTo<FieldDecl>("f", 8)));
Manuel Klimek04616e42012-07-06 05:48:52 +00003197}
3198
Manuel Klimeka0c025f2013-06-19 15:42:45 +00003199TEST(ForEachDescendant, BindsCombinations) {
3200 EXPECT_TRUE(matchAndVerifyResultTrue(
3201 "void f() { if(true) {} if (true) {} while (true) {} if (true) {} while "
3202 "(true) {} }",
3203 compoundStmt(forEachDescendant(ifStmt().bind("if")),
3204 forEachDescendant(whileStmt().bind("while"))),
3205 new VerifyIdIsBoundTo<IfStmt>("if", 6)));
3206}
3207
3208TEST(Has, DoesNotDeleteBindings) {
3209 EXPECT_TRUE(matchAndVerifyResultTrue(
3210 "class X { int a; };", recordDecl(decl().bind("x"), has(fieldDecl())),
3211 new VerifyIdIsBoundTo<Decl>("x", 1)));
3212}
3213
3214TEST(LoopingMatchers, DoNotOverwritePreviousMatchResultOnFailure) {
3215 // Those matchers cover all the cases where an inner matcher is called
3216 // and there is not a 1:1 relationship between the match of the outer
3217 // matcher and the match of the inner matcher.
3218 // The pattern to look for is:
3219 // ... return InnerMatcher.matches(...); ...
3220 // In which case no special handling is needed.
3221 //
3222 // On the other hand, if there are multiple alternative matches
3223 // (for example forEach*) or matches might be discarded (for example has*)
3224 // the implementation must make sure that the discarded matches do not
3225 // affect the bindings.
3226 // When new such matchers are added, add a test here that:
3227 // - matches a simple node, and binds it as the first thing in the matcher:
3228 // recordDecl(decl().bind("x"), hasName("X")))
3229 // - uses the matcher under test afterwards in a way that not the first
3230 // alternative is matched; for anyOf, that means the first branch
3231 // would need to return false; for hasAncestor, it means that not
3232 // the direct parent matches the inner matcher.
3233
3234 EXPECT_TRUE(matchAndVerifyResultTrue(
3235 "class X { int y; };",
3236 recordDecl(
3237 recordDecl().bind("x"), hasName("::X"),
3238 anyOf(forEachDescendant(recordDecl(hasName("Y"))), anything())),
3239 new VerifyIdIsBoundTo<CXXRecordDecl>("x", 1)));
3240 EXPECT_TRUE(matchAndVerifyResultTrue(
3241 "class X {};", recordDecl(recordDecl().bind("x"), hasName("::X"),
3242 anyOf(unless(anything()), anything())),
3243 new VerifyIdIsBoundTo<CXXRecordDecl>("x", 1)));
3244 EXPECT_TRUE(matchAndVerifyResultTrue(
3245 "template<typename T1, typename T2> class X {}; X<float, int> x;",
3246 classTemplateSpecializationDecl(
3247 decl().bind("x"),
3248 hasAnyTemplateArgument(refersToType(asString("int")))),
3249 new VerifyIdIsBoundTo<Decl>("x", 1)));
3250 EXPECT_TRUE(matchAndVerifyResultTrue(
3251 "class X { void f(); void g(); };",
3252 recordDecl(decl().bind("x"), hasMethod(hasName("g"))),
3253 new VerifyIdIsBoundTo<Decl>("x", 1)));
3254 EXPECT_TRUE(matchAndVerifyResultTrue(
3255 "class X { X() : a(1), b(2) {} double a; int b; };",
3256 recordDecl(decl().bind("x"),
3257 has(constructorDecl(
3258 hasAnyConstructorInitializer(forField(hasName("b")))))),
3259 new VerifyIdIsBoundTo<Decl>("x", 1)));
3260 EXPECT_TRUE(matchAndVerifyResultTrue(
3261 "void x(int, int) { x(0, 42); }",
3262 callExpr(expr().bind("x"), hasAnyArgument(integerLiteral(equals(42)))),
3263 new VerifyIdIsBoundTo<Expr>("x", 1)));
3264 EXPECT_TRUE(matchAndVerifyResultTrue(
3265 "void x(int, int y) {}",
3266 functionDecl(decl().bind("x"), hasAnyParameter(hasName("y"))),
3267 new VerifyIdIsBoundTo<Decl>("x", 1)));
3268 EXPECT_TRUE(matchAndVerifyResultTrue(
3269 "void x() { return; if (true) {} }",
3270 functionDecl(decl().bind("x"),
3271 has(compoundStmt(hasAnySubstatement(ifStmt())))),
3272 new VerifyIdIsBoundTo<Decl>("x", 1)));
3273 EXPECT_TRUE(matchAndVerifyResultTrue(
3274 "namespace X { void b(int); void b(); }"
3275 "using X::b;",
3276 usingDecl(decl().bind("x"), hasAnyUsingShadowDecl(hasTargetDecl(
3277 functionDecl(parameterCountIs(1))))),
3278 new VerifyIdIsBoundTo<Decl>("x", 1)));
3279 EXPECT_TRUE(matchAndVerifyResultTrue(
3280 "class A{}; class B{}; class C : B, A {};",
3281 recordDecl(decl().bind("x"), isDerivedFrom("::A")),
3282 new VerifyIdIsBoundTo<Decl>("x", 1)));
3283 EXPECT_TRUE(matchAndVerifyResultTrue(
3284 "class A{}; typedef A B; typedef A C; typedef A D;"
3285 "class E : A {};",
3286 recordDecl(decl().bind("x"), isDerivedFrom("C")),
3287 new VerifyIdIsBoundTo<Decl>("x", 1)));
3288 EXPECT_TRUE(matchAndVerifyResultTrue(
3289 "class A { class B { void f() {} }; };",
3290 functionDecl(decl().bind("x"), hasAncestor(recordDecl(hasName("::A")))),
3291 new VerifyIdIsBoundTo<Decl>("x", 1)));
3292 EXPECT_TRUE(matchAndVerifyResultTrue(
3293 "template <typename T> struct A { struct B {"
3294 " void f() { if(true) {} }"
3295 "}; };"
3296 "void t() { A<int>::B b; b.f(); }",
3297 ifStmt(stmt().bind("x"), hasAncestor(recordDecl(hasName("::A")))),
3298 new VerifyIdIsBoundTo<Stmt>("x", 2)));
3299 EXPECT_TRUE(matchAndVerifyResultTrue(
3300 "class A {};",
3301 recordDecl(hasName("::A"), decl().bind("x"), unless(hasName("fooble"))),
3302 new VerifyIdIsBoundTo<Decl>("x", 1)));
Manuel Klimekba46fc02013-07-19 11:50:54 +00003303 EXPECT_TRUE(matchAndVerifyResultTrue(
3304 "class A { A() : s(), i(42) {} const char *s; int i; };",
3305 constructorDecl(hasName("::A::A"), decl().bind("x"),
3306 forEachConstructorInitializer(forField(hasName("i")))),
3307 new VerifyIdIsBoundTo<Decl>("x", 1)));
Manuel Klimeka0c025f2013-06-19 15:42:45 +00003308}
3309
Daniel Jasper33806cd2012-11-11 22:14:55 +00003310TEST(ForEachDescendant, BindsCorrectNodes) {
3311 EXPECT_TRUE(matchAndVerifyResultTrue(
3312 "class C { void f(); int i; };",
3313 recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
3314 new VerifyIdIsBoundTo<FieldDecl>("decl", 1)));
3315 EXPECT_TRUE(matchAndVerifyResultTrue(
3316 "class C { void f() {} int i; };",
3317 recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
3318 new VerifyIdIsBoundTo<FunctionDecl>("decl", 1)));
3319}
3320
Manuel Klimekabf43712013-02-04 10:59:20 +00003321TEST(FindAll, BindsNodeOnMatch) {
3322 EXPECT_TRUE(matchAndVerifyResultTrue(
3323 "class A {};",
3324 recordDecl(hasName("::A"), findAll(recordDecl(hasName("::A")).bind("v"))),
3325 new VerifyIdIsBoundTo<CXXRecordDecl>("v", 1)));
3326}
3327
3328TEST(FindAll, BindsDescendantNodeOnMatch) {
3329 EXPECT_TRUE(matchAndVerifyResultTrue(
3330 "class A { int a; int b; };",
3331 recordDecl(hasName("::A"), findAll(fieldDecl().bind("v"))),
3332 new VerifyIdIsBoundTo<FieldDecl>("v", 2)));
3333}
3334
3335TEST(FindAll, BindsNodeAndDescendantNodesOnOneMatch) {
3336 EXPECT_TRUE(matchAndVerifyResultTrue(
3337 "class A { int a; int b; };",
3338 recordDecl(hasName("::A"),
3339 findAll(decl(anyOf(recordDecl(hasName("::A")).bind("v"),
3340 fieldDecl().bind("v"))))),
3341 new VerifyIdIsBoundTo<Decl>("v", 3)));
3342
3343 EXPECT_TRUE(matchAndVerifyResultTrue(
3344 "class A { class B {}; class C {}; };",
3345 recordDecl(hasName("::A"), findAll(recordDecl(isDefinition()).bind("v"))),
3346 new VerifyIdIsBoundTo<CXXRecordDecl>("v", 3)));
3347}
3348
Manuel Klimek88b95872013-02-04 09:42:38 +00003349TEST(EachOf, TriggersForEachMatch) {
3350 EXPECT_TRUE(matchAndVerifyResultTrue(
3351 "class A { int a; int b; };",
3352 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
3353 has(fieldDecl(hasName("b")).bind("v")))),
3354 new VerifyIdIsBoundTo<FieldDecl>("v", 2)));
3355}
3356
3357TEST(EachOf, BehavesLikeAnyOfUnlessBothMatch) {
3358 EXPECT_TRUE(matchAndVerifyResultTrue(
3359 "class A { int a; int c; };",
3360 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
3361 has(fieldDecl(hasName("b")).bind("v")))),
3362 new VerifyIdIsBoundTo<FieldDecl>("v", 1)));
3363 EXPECT_TRUE(matchAndVerifyResultTrue(
3364 "class A { int c; int b; };",
3365 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
3366 has(fieldDecl(hasName("b")).bind("v")))),
3367 new VerifyIdIsBoundTo<FieldDecl>("v", 1)));
3368 EXPECT_TRUE(notMatches(
3369 "class A { int c; int d; };",
3370 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
3371 has(fieldDecl(hasName("b")).bind("v"))))));
3372}
Manuel Klimek04616e42012-07-06 05:48:52 +00003373
3374TEST(IsTemplateInstantiation, MatchesImplicitClassTemplateInstantiation) {
3375 // Make sure that we can both match the class by name (::X) and by the type
3376 // the template was instantiated with (via a field).
3377
3378 EXPECT_TRUE(matches(
3379 "template <typename T> class X {}; class A {}; X<A> x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003380 recordDecl(hasName("::X"), isTemplateInstantiation())));
Manuel Klimek04616e42012-07-06 05:48:52 +00003381
3382 EXPECT_TRUE(matches(
3383 "template <typename T> class X { T t; }; class A {}; X<A> x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003384 recordDecl(isTemplateInstantiation(), hasDescendant(
3385 fieldDecl(hasType(recordDecl(hasName("A"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003386}
3387
3388TEST(IsTemplateInstantiation, MatchesImplicitFunctionTemplateInstantiation) {
3389 EXPECT_TRUE(matches(
3390 "template <typename T> void f(T t) {} class A {}; void g() { f(A()); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003391 functionDecl(hasParameter(0, hasType(recordDecl(hasName("A")))),
Manuel Klimek04616e42012-07-06 05:48:52 +00003392 isTemplateInstantiation())));
3393}
3394
3395TEST(IsTemplateInstantiation, MatchesExplicitClassTemplateInstantiation) {
3396 EXPECT_TRUE(matches(
3397 "template <typename T> class X { T t; }; class A {};"
3398 "template class X<A>;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003399 recordDecl(isTemplateInstantiation(), hasDescendant(
3400 fieldDecl(hasType(recordDecl(hasName("A"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003401}
3402
3403TEST(IsTemplateInstantiation,
3404 MatchesInstantiationOfPartiallySpecializedClassTemplate) {
3405 EXPECT_TRUE(matches(
3406 "template <typename T> class X {};"
3407 "template <typename T> class X<T*> {}; class A {}; X<A*> x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003408 recordDecl(hasName("::X"), isTemplateInstantiation())));
Manuel Klimek04616e42012-07-06 05:48:52 +00003409}
3410
3411TEST(IsTemplateInstantiation,
3412 MatchesInstantiationOfClassTemplateNestedInNonTemplate) {
3413 EXPECT_TRUE(matches(
3414 "class A {};"
3415 "class X {"
3416 " template <typename U> class Y { U u; };"
3417 " Y<A> y;"
3418 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003419 recordDecl(hasName("::X::Y"), isTemplateInstantiation())));
Manuel Klimek04616e42012-07-06 05:48:52 +00003420}
3421
3422TEST(IsTemplateInstantiation, DoesNotMatchInstantiationsInsideOfInstantiation) {
3423 // FIXME: Figure out whether this makes sense. It doesn't affect the
3424 // normal use case as long as the uppermost instantiation always is marked
3425 // as template instantiation, but it might be confusing as a predicate.
3426 EXPECT_TRUE(matches(
3427 "class A {};"
3428 "template <typename T> class X {"
3429 " template <typename U> class Y { U u; };"
3430 " Y<T> y;"
3431 "}; X<A> x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003432 recordDecl(hasName("::X<A>::Y"), unless(isTemplateInstantiation()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003433}
3434
3435TEST(IsTemplateInstantiation, DoesNotMatchExplicitClassTemplateSpecialization) {
3436 EXPECT_TRUE(notMatches(
3437 "template <typename T> class X {}; class A {};"
3438 "template <> class X<A> {}; X<A> x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003439 recordDecl(hasName("::X"), isTemplateInstantiation())));
Manuel Klimek04616e42012-07-06 05:48:52 +00003440}
3441
3442TEST(IsTemplateInstantiation, DoesNotMatchNonTemplate) {
3443 EXPECT_TRUE(notMatches(
3444 "class A {}; class Y { A a; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003445 recordDecl(isTemplateInstantiation())));
Manuel Klimek04616e42012-07-06 05:48:52 +00003446}
3447
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00003448TEST(IsExplicitTemplateSpecialization,
3449 DoesNotMatchPrimaryTemplate) {
3450 EXPECT_TRUE(notMatches(
3451 "template <typename T> class X {};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003452 recordDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00003453 EXPECT_TRUE(notMatches(
3454 "template <typename T> void f(T t);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003455 functionDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00003456}
3457
3458TEST(IsExplicitTemplateSpecialization,
3459 DoesNotMatchExplicitTemplateInstantiations) {
3460 EXPECT_TRUE(notMatches(
3461 "template <typename T> class X {};"
3462 "template class X<int>; extern template class X<long>;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003463 recordDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00003464 EXPECT_TRUE(notMatches(
3465 "template <typename T> void f(T t) {}"
3466 "template void f(int t); extern template void f(long t);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003467 functionDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00003468}
3469
3470TEST(IsExplicitTemplateSpecialization,
3471 DoesNotMatchImplicitTemplateInstantiations) {
3472 EXPECT_TRUE(notMatches(
3473 "template <typename T> class X {}; X<int> x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003474 recordDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00003475 EXPECT_TRUE(notMatches(
3476 "template <typename T> void f(T t); void g() { f(10); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003477 functionDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00003478}
3479
3480TEST(IsExplicitTemplateSpecialization,
3481 MatchesExplicitTemplateSpecializations) {
3482 EXPECT_TRUE(matches(
3483 "template <typename T> class X {};"
3484 "template<> class X<int> {};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003485 recordDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00003486 EXPECT_TRUE(matches(
3487 "template <typename T> void f(T t) {}"
3488 "template<> void f(int t) {}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003489 functionDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00003490}
3491
Manuel Klimek3ca12c52012-09-07 09:26:10 +00003492TEST(HasAncenstor, MatchesDeclarationAncestors) {
3493 EXPECT_TRUE(matches(
3494 "class A { class B { class C {}; }; };",
3495 recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("A"))))));
3496}
3497
3498TEST(HasAncenstor, FailsIfNoAncestorMatches) {
3499 EXPECT_TRUE(notMatches(
3500 "class A { class B { class C {}; }; };",
3501 recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("X"))))));
3502}
3503
3504TEST(HasAncestor, MatchesDeclarationsThatGetVisitedLater) {
3505 EXPECT_TRUE(matches(
3506 "class A { class B { void f() { C c; } class C {}; }; };",
3507 varDecl(hasName("c"), hasType(recordDecl(hasName("C"),
3508 hasAncestor(recordDecl(hasName("A"))))))));
3509}
3510
3511TEST(HasAncenstor, MatchesStatementAncestors) {
3512 EXPECT_TRUE(matches(
3513 "void f() { if (true) { while (false) { 42; } } }",
Daniel Jasper848cbe12012-09-18 13:09:13 +00003514 integerLiteral(equals(42), hasAncestor(ifStmt()))));
Manuel Klimek3ca12c52012-09-07 09:26:10 +00003515}
3516
3517TEST(HasAncestor, DrillsThroughDifferentHierarchies) {
3518 EXPECT_TRUE(matches(
3519 "void f() { if (true) { int x = 42; } }",
Daniel Jasper848cbe12012-09-18 13:09:13 +00003520 integerLiteral(equals(42), hasAncestor(functionDecl(hasName("f"))))));
Manuel Klimek3ca12c52012-09-07 09:26:10 +00003521}
3522
3523TEST(HasAncestor, BindsRecursiveCombinations) {
3524 EXPECT_TRUE(matchAndVerifyResultTrue(
3525 "class C { class D { class E { class F { int y; }; }; }; };",
3526 fieldDecl(hasAncestor(recordDecl(hasAncestor(recordDecl().bind("r"))))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003527 new VerifyIdIsBoundTo<CXXRecordDecl>("r", 1)));
Manuel Klimek3ca12c52012-09-07 09:26:10 +00003528}
3529
3530TEST(HasAncestor, BindsCombinationsWithHasDescendant) {
3531 EXPECT_TRUE(matchAndVerifyResultTrue(
3532 "class C { class D { class E { class F { int y; }; }; }; };",
3533 fieldDecl(hasAncestor(
3534 decl(
3535 hasDescendant(recordDecl(isDefinition(),
3536 hasAncestor(recordDecl())))
3537 ).bind("d")
3538 )),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003539 new VerifyIdIsBoundTo<CXXRecordDecl>("d", "E")));
Manuel Klimek3ca12c52012-09-07 09:26:10 +00003540}
3541
Manuel Klimekb64d6b72013-03-14 16:33:21 +00003542TEST(HasAncestor, MatchesClosestAncestor) {
3543 EXPECT_TRUE(matchAndVerifyResultTrue(
3544 "template <typename T> struct C {"
3545 " void f(int) {"
3546 " struct I { void g(T) { int x; } } i; i.g(42);"
3547 " }"
3548 "};"
3549 "template struct C<int>;",
3550 varDecl(hasName("x"),
3551 hasAncestor(functionDecl(hasParameter(
3552 0, varDecl(hasType(asString("int"))))).bind("f"))).bind("v"),
3553 new VerifyIdIsBoundTo<FunctionDecl>("f", "g", 2)));
3554}
3555
Manuel Klimek3ca12c52012-09-07 09:26:10 +00003556TEST(HasAncestor, MatchesInTemplateInstantiations) {
3557 EXPECT_TRUE(matches(
3558 "template <typename T> struct A { struct B { struct C { T t; }; }; }; "
3559 "A<int>::B::C a;",
3560 fieldDecl(hasType(asString("int")),
3561 hasAncestor(recordDecl(hasName("A"))))));
3562}
3563
3564TEST(HasAncestor, MatchesInImplicitCode) {
3565 EXPECT_TRUE(matches(
3566 "struct X {}; struct A { A() {} X x; };",
3567 constructorDecl(
3568 hasAnyConstructorInitializer(withInitializer(expr(
3569 hasAncestor(recordDecl(hasName("A")))))))));
3570}
3571
Daniel Jasper632aea92012-10-22 16:26:51 +00003572TEST(HasParent, MatchesOnlyParent) {
3573 EXPECT_TRUE(matches(
3574 "void f() { if (true) { int x = 42; } }",
3575 compoundStmt(hasParent(ifStmt()))));
3576 EXPECT_TRUE(notMatches(
3577 "void f() { for (;;) { int x = 42; } }",
3578 compoundStmt(hasParent(ifStmt()))));
3579 EXPECT_TRUE(notMatches(
3580 "void f() { if (true) for (;;) { int x = 42; } }",
3581 compoundStmt(hasParent(ifStmt()))));
3582}
3583
Manuel Klimekc844a462012-12-06 14:42:48 +00003584TEST(HasAncestor, MatchesAllAncestors) {
3585 EXPECT_TRUE(matches(
3586 "template <typename T> struct C { static void f() { 42; } };"
3587 "void t() { C<int>::f(); }",
3588 integerLiteral(
3589 equals(42),
3590 allOf(hasAncestor(recordDecl(isTemplateInstantiation())),
3591 hasAncestor(recordDecl(unless(isTemplateInstantiation())))))));
3592}
3593
3594TEST(HasParent, MatchesAllParents) {
3595 EXPECT_TRUE(matches(
3596 "template <typename T> struct C { static void f() { 42; } };"
3597 "void t() { C<int>::f(); }",
3598 integerLiteral(
3599 equals(42),
3600 hasParent(compoundStmt(hasParent(functionDecl(
3601 hasParent(recordDecl(isTemplateInstantiation())))))))));
3602 EXPECT_TRUE(matches(
3603 "template <typename T> struct C { static void f() { 42; } };"
3604 "void t() { C<int>::f(); }",
3605 integerLiteral(
3606 equals(42),
3607 hasParent(compoundStmt(hasParent(functionDecl(
3608 hasParent(recordDecl(unless(isTemplateInstantiation()))))))))));
3609 EXPECT_TRUE(matches(
3610 "template <typename T> struct C { static void f() { 42; } };"
3611 "void t() { C<int>::f(); }",
3612 integerLiteral(equals(42),
3613 hasParent(compoundStmt(allOf(
3614 hasParent(functionDecl(
3615 hasParent(recordDecl(isTemplateInstantiation())))),
3616 hasParent(functionDecl(hasParent(recordDecl(
3617 unless(isTemplateInstantiation())))))))))));
Manuel Klimekb64d6b72013-03-14 16:33:21 +00003618 EXPECT_TRUE(
3619 notMatches("template <typename T> struct C { static void f() {} };"
3620 "void t() { C<int>::f(); }",
3621 compoundStmt(hasParent(recordDecl()))));
Manuel Klimekc844a462012-12-06 14:42:48 +00003622}
3623
Daniel Jasper516b02e2012-10-17 08:52:59 +00003624TEST(TypeMatching, MatchesTypes) {
3625 EXPECT_TRUE(matches("struct S {};", qualType().bind("loc")));
3626}
3627
3628TEST(TypeMatching, MatchesArrayTypes) {
3629 EXPECT_TRUE(matches("int a[] = {2,3};", arrayType()));
3630 EXPECT_TRUE(matches("int a[42];", arrayType()));
3631 EXPECT_TRUE(matches("void f(int b) { int a[b]; }", arrayType()));
3632
3633 EXPECT_TRUE(notMatches("struct A {}; A a[7];",
3634 arrayType(hasElementType(builtinType()))));
3635
3636 EXPECT_TRUE(matches(
3637 "int const a[] = { 2, 3 };",
3638 qualType(arrayType(hasElementType(builtinType())))));
3639 EXPECT_TRUE(matches(
3640 "int const a[] = { 2, 3 };",
3641 qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
3642 EXPECT_TRUE(matches(
3643 "typedef const int T; T x[] = { 1, 2 };",
3644 qualType(isConstQualified(), arrayType())));
3645
3646 EXPECT_TRUE(notMatches(
3647 "int a[] = { 2, 3 };",
3648 qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
3649 EXPECT_TRUE(notMatches(
3650 "int a[] = { 2, 3 };",
3651 qualType(arrayType(hasElementType(isConstQualified(), builtinType())))));
3652 EXPECT_TRUE(notMatches(
3653 "int const a[] = { 2, 3 };",
3654 qualType(arrayType(hasElementType(builtinType())),
3655 unless(isConstQualified()))));
3656
3657 EXPECT_TRUE(matches("int a[2];",
3658 constantArrayType(hasElementType(builtinType()))));
3659 EXPECT_TRUE(matches("const int a = 0;", qualType(isInteger())));
3660}
3661
3662TEST(TypeMatching, MatchesComplexTypes) {
3663 EXPECT_TRUE(matches("_Complex float f;", complexType()));
3664 EXPECT_TRUE(matches(
3665 "_Complex float f;",
3666 complexType(hasElementType(builtinType()))));
3667 EXPECT_TRUE(notMatches(
3668 "_Complex float f;",
3669 complexType(hasElementType(isInteger()))));
3670}
3671
3672TEST(TypeMatching, MatchesConstantArrayTypes) {
3673 EXPECT_TRUE(matches("int a[2];", constantArrayType()));
3674 EXPECT_TRUE(notMatches(
3675 "void f() { int a[] = { 2, 3 }; int b[a[0]]; }",
3676 constantArrayType(hasElementType(builtinType()))));
3677
3678 EXPECT_TRUE(matches("int a[42];", constantArrayType(hasSize(42))));
3679 EXPECT_TRUE(matches("int b[2*21];", constantArrayType(hasSize(42))));
3680 EXPECT_TRUE(notMatches("int c[41], d[43];", constantArrayType(hasSize(42))));
3681}
3682
3683TEST(TypeMatching, MatchesDependentSizedArrayTypes) {
3684 EXPECT_TRUE(matches(
3685 "template <typename T, int Size> class array { T data[Size]; };",
3686 dependentSizedArrayType()));
3687 EXPECT_TRUE(notMatches(
3688 "int a[42]; int b[] = { 2, 3 }; void f() { int c[b[0]]; }",
3689 dependentSizedArrayType()));
3690}
3691
3692TEST(TypeMatching, MatchesIncompleteArrayType) {
3693 EXPECT_TRUE(matches("int a[] = { 2, 3 };", incompleteArrayType()));
3694 EXPECT_TRUE(matches("void f(int a[]) {}", incompleteArrayType()));
3695
3696 EXPECT_TRUE(notMatches("int a[42]; void f() { int b[a[0]]; }",
3697 incompleteArrayType()));
3698}
3699
3700TEST(TypeMatching, MatchesVariableArrayType) {
3701 EXPECT_TRUE(matches("void f(int b) { int a[b]; }", variableArrayType()));
3702 EXPECT_TRUE(notMatches("int a[] = {2, 3}; int b[42];", variableArrayType()));
3703
3704 EXPECT_TRUE(matches(
3705 "void f(int b) { int a[b]; }",
3706 variableArrayType(hasSizeExpr(ignoringImpCasts(declRefExpr(to(
3707 varDecl(hasName("b")))))))));
3708}
3709
3710TEST(TypeMatching, MatchesAtomicTypes) {
David Majnemer197e2102014-03-05 06:32:38 +00003711 if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getOS() !=
3712 llvm::Triple::Win32) {
3713 // FIXME: Make this work for MSVC.
3714 EXPECT_TRUE(matches("_Atomic(int) i;", atomicType()));
Daniel Jasper516b02e2012-10-17 08:52:59 +00003715
David Majnemer197e2102014-03-05 06:32:38 +00003716 EXPECT_TRUE(matches("_Atomic(int) i;",
3717 atomicType(hasValueType(isInteger()))));
3718 EXPECT_TRUE(notMatches("_Atomic(float) f;",
3719 atomicType(hasValueType(isInteger()))));
3720 }
Daniel Jasper516b02e2012-10-17 08:52:59 +00003721}
3722
3723TEST(TypeMatching, MatchesAutoTypes) {
3724 EXPECT_TRUE(matches("auto i = 2;", autoType()));
3725 EXPECT_TRUE(matches("int v[] = { 2, 3 }; void f() { for (int i : v) {} }",
3726 autoType()));
3727
Richard Smith061f1e22013-04-30 21:23:01 +00003728 // FIXME: Matching against the type-as-written can't work here, because the
3729 // type as written was not deduced.
3730 //EXPECT_TRUE(matches("auto a = 1;",
3731 // autoType(hasDeducedType(isInteger()))));
3732 //EXPECT_TRUE(notMatches("auto b = 2.0;",
3733 // autoType(hasDeducedType(isInteger()))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00003734}
3735
Daniel Jasperd29d5fa2012-10-29 10:14:44 +00003736TEST(TypeMatching, MatchesFunctionTypes) {
3737 EXPECT_TRUE(matches("int (*f)(int);", functionType()));
3738 EXPECT_TRUE(matches("void f(int i) {}", functionType()));
3739}
3740
Edwin Vaneec074802013-04-01 18:33:34 +00003741TEST(TypeMatching, MatchesParenType) {
3742 EXPECT_TRUE(
3743 matches("int (*array)[4];", varDecl(hasType(pointsTo(parenType())))));
3744 EXPECT_TRUE(notMatches("int *array[4];", varDecl(hasType(parenType()))));
3745
3746 EXPECT_TRUE(matches(
3747 "int (*ptr_to_func)(int);",
3748 varDecl(hasType(pointsTo(parenType(innerType(functionType())))))));
3749 EXPECT_TRUE(notMatches(
3750 "int (*ptr_to_array)[4];",
3751 varDecl(hasType(pointsTo(parenType(innerType(functionType())))))));
3752}
3753
Daniel Jasper516b02e2012-10-17 08:52:59 +00003754TEST(TypeMatching, PointerTypes) {
Daniel Jasper7943eb52012-10-17 13:35:36 +00003755 // FIXME: Reactive when these tests can be more specific (not matching
3756 // implicit code on certain platforms), likely when we have hasDescendant for
3757 // Types/TypeLocs.
3758 //EXPECT_TRUE(matchAndVerifyResultTrue(
3759 // "int* a;",
3760 // pointerTypeLoc(pointeeLoc(typeLoc().bind("loc"))),
3761 // new VerifyIdIsBoundTo<TypeLoc>("loc", 1)));
3762 //EXPECT_TRUE(matchAndVerifyResultTrue(
3763 // "int* a;",
3764 // pointerTypeLoc().bind("loc"),
3765 // new VerifyIdIsBoundTo<TypeLoc>("loc", 1)));
Daniel Jasper516b02e2012-10-17 08:52:59 +00003766 EXPECT_TRUE(matches(
3767 "int** a;",
David Blaikieb61d0872013-02-18 19:04:16 +00003768 loc(pointerType(pointee(qualType())))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00003769 EXPECT_TRUE(matches(
3770 "int** a;",
3771 loc(pointerType(pointee(pointerType())))));
3772 EXPECT_TRUE(matches(
3773 "int* b; int* * const a = &b;",
3774 loc(qualType(isConstQualified(), pointerType()))));
3775
3776 std::string Fragment = "struct A { int i; }; int A::* ptr = &A::i;";
Daniel Jasper7943eb52012-10-17 13:35:36 +00003777 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
3778 hasType(blockPointerType()))));
3779 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ptr"),
3780 hasType(memberPointerType()))));
3781 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
3782 hasType(pointerType()))));
3783 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
3784 hasType(referenceType()))));
Edwin Vane2a760d02013-03-07 15:44:40 +00003785 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
3786 hasType(lValueReferenceType()))));
3787 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
3788 hasType(rValueReferenceType()))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00003789
Daniel Jasper7943eb52012-10-17 13:35:36 +00003790 Fragment = "int *ptr;";
3791 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
3792 hasType(blockPointerType()))));
3793 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
3794 hasType(memberPointerType()))));
3795 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ptr"),
3796 hasType(pointerType()))));
3797 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
3798 hasType(referenceType()))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00003799
Daniel Jasper7943eb52012-10-17 13:35:36 +00003800 Fragment = "int a; int &ref = a;";
3801 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
3802 hasType(blockPointerType()))));
3803 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
3804 hasType(memberPointerType()))));
3805 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
3806 hasType(pointerType()))));
3807 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
3808 hasType(referenceType()))));
Edwin Vane2a760d02013-03-07 15:44:40 +00003809 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
3810 hasType(lValueReferenceType()))));
3811 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
3812 hasType(rValueReferenceType()))));
3813
3814 Fragment = "int &&ref = 2;";
3815 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
3816 hasType(blockPointerType()))));
3817 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
3818 hasType(memberPointerType()))));
3819 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
3820 hasType(pointerType()))));
3821 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
3822 hasType(referenceType()))));
3823 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
3824 hasType(lValueReferenceType()))));
3825 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
3826 hasType(rValueReferenceType()))));
3827}
3828
3829TEST(TypeMatching, AutoRefTypes) {
3830 std::string Fragment = "auto a = 1;"
3831 "auto b = a;"
3832 "auto &c = a;"
3833 "auto &&d = c;"
3834 "auto &&e = 2;";
3835 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("a"),
3836 hasType(referenceType()))));
3837 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("b"),
3838 hasType(referenceType()))));
3839 EXPECT_TRUE(matches(Fragment, varDecl(hasName("c"),
3840 hasType(referenceType()))));
3841 EXPECT_TRUE(matches(Fragment, varDecl(hasName("c"),
3842 hasType(lValueReferenceType()))));
3843 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("c"),
3844 hasType(rValueReferenceType()))));
3845 EXPECT_TRUE(matches(Fragment, varDecl(hasName("d"),
3846 hasType(referenceType()))));
3847 EXPECT_TRUE(matches(Fragment, varDecl(hasName("d"),
3848 hasType(lValueReferenceType()))));
3849 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("d"),
3850 hasType(rValueReferenceType()))));
3851 EXPECT_TRUE(matches(Fragment, varDecl(hasName("e"),
3852 hasType(referenceType()))));
3853 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("e"),
3854 hasType(lValueReferenceType()))));
3855 EXPECT_TRUE(matches(Fragment, varDecl(hasName("e"),
3856 hasType(rValueReferenceType()))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00003857}
3858
3859TEST(TypeMatching, PointeeTypes) {
3860 EXPECT_TRUE(matches("int b; int &a = b;",
3861 referenceType(pointee(builtinType()))));
3862 EXPECT_TRUE(matches("int *a;", pointerType(pointee(builtinType()))));
3863
3864 EXPECT_TRUE(matches("int *a;",
David Blaikieb61d0872013-02-18 19:04:16 +00003865 loc(pointerType(pointee(builtinType())))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00003866
3867 EXPECT_TRUE(matches(
3868 "int const *A;",
3869 pointerType(pointee(isConstQualified(), builtinType()))));
3870 EXPECT_TRUE(notMatches(
3871 "int *A;",
3872 pointerType(pointee(isConstQualified(), builtinType()))));
3873}
3874
3875TEST(TypeMatching, MatchesPointersToConstTypes) {
3876 EXPECT_TRUE(matches("int b; int * const a = &b;",
3877 loc(pointerType())));
3878 EXPECT_TRUE(matches("int b; int * const a = &b;",
David Blaikieb61d0872013-02-18 19:04:16 +00003879 loc(pointerType())));
Daniel Jasper516b02e2012-10-17 08:52:59 +00003880 EXPECT_TRUE(matches(
3881 "int b; const int * a = &b;",
David Blaikieb61d0872013-02-18 19:04:16 +00003882 loc(pointerType(pointee(builtinType())))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00003883 EXPECT_TRUE(matches(
3884 "int b; const int * a = &b;",
3885 pointerType(pointee(builtinType()))));
3886}
3887
3888TEST(TypeMatching, MatchesTypedefTypes) {
Daniel Jasper7943eb52012-10-17 13:35:36 +00003889 EXPECT_TRUE(matches("typedef int X; X a;", varDecl(hasName("a"),
3890 hasType(typedefType()))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00003891}
3892
Edwin Vanef901b712013-02-25 14:49:29 +00003893TEST(TypeMatching, MatchesTemplateSpecializationType) {
Edwin Vaneb6eae142013-02-25 20:43:32 +00003894 EXPECT_TRUE(matches("template <typename T> class A{}; A<int> a;",
Edwin Vanef901b712013-02-25 14:49:29 +00003895 templateSpecializationType()));
3896}
3897
Edwin Vaneb6eae142013-02-25 20:43:32 +00003898TEST(TypeMatching, MatchesRecordType) {
3899 EXPECT_TRUE(matches("class C{}; C c;", recordType()));
Manuel Klimek59b0af62013-02-27 11:56:58 +00003900 EXPECT_TRUE(matches("struct S{}; S s;",
3901 recordType(hasDeclaration(recordDecl(hasName("S"))))));
3902 EXPECT_TRUE(notMatches("int i;",
3903 recordType(hasDeclaration(recordDecl(hasName("S"))))));
Edwin Vaneb6eae142013-02-25 20:43:32 +00003904}
3905
3906TEST(TypeMatching, MatchesElaboratedType) {
3907 EXPECT_TRUE(matches(
3908 "namespace N {"
3909 " namespace M {"
3910 " class D {};"
3911 " }"
3912 "}"
3913 "N::M::D d;", elaboratedType()));
3914 EXPECT_TRUE(matches("class C {} c;", elaboratedType()));
3915 EXPECT_TRUE(notMatches("class C {}; C c;", elaboratedType()));
3916}
3917
3918TEST(ElaboratedTypeNarrowing, hasQualifier) {
3919 EXPECT_TRUE(matches(
3920 "namespace N {"
3921 " namespace M {"
3922 " class D {};"
3923 " }"
3924 "}"
3925 "N::M::D d;",
3926 elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
3927 EXPECT_TRUE(notMatches(
3928 "namespace M {"
3929 " class D {};"
3930 "}"
3931 "M::D d;",
3932 elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
Edwin Vane6972f6d2013-03-04 17:51:00 +00003933 EXPECT_TRUE(notMatches(
3934 "struct D {"
3935 "} d;",
3936 elaboratedType(hasQualifier(nestedNameSpecifier()))));
Edwin Vaneb6eae142013-02-25 20:43:32 +00003937}
3938
3939TEST(ElaboratedTypeNarrowing, namesType) {
3940 EXPECT_TRUE(matches(
3941 "namespace N {"
3942 " namespace M {"
3943 " class D {};"
3944 " }"
3945 "}"
3946 "N::M::D d;",
3947 elaboratedType(elaboratedType(namesType(recordType(
3948 hasDeclaration(namedDecl(hasName("D")))))))));
3949 EXPECT_TRUE(notMatches(
3950 "namespace M {"
3951 " class D {};"
3952 "}"
3953 "M::D d;",
3954 elaboratedType(elaboratedType(namesType(typedefType())))));
3955}
3956
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003957TEST(NNS, MatchesNestedNameSpecifiers) {
3958 EXPECT_TRUE(matches("namespace ns { struct A {}; } ns::A a;",
3959 nestedNameSpecifier()));
3960 EXPECT_TRUE(matches("template <typename T> class A { typename T::B b; };",
3961 nestedNameSpecifier()));
3962 EXPECT_TRUE(matches("struct A { void f(); }; void A::f() {}",
3963 nestedNameSpecifier()));
3964
3965 EXPECT_TRUE(matches(
3966 "struct A { static void f() {} }; void g() { A::f(); }",
3967 nestedNameSpecifier()));
3968 EXPECT_TRUE(notMatches(
3969 "struct A { static void f() {} }; void g(A* a) { a->f(); }",
3970 nestedNameSpecifier()));
3971}
3972
Daniel Jasper87c3d362012-09-20 14:12:57 +00003973TEST(NullStatement, SimpleCases) {
3974 EXPECT_TRUE(matches("void f() {int i;;}", nullStmt()));
3975 EXPECT_TRUE(notMatches("void f() {int i;}", nullStmt()));
3976}
3977
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003978TEST(NNS, MatchesTypes) {
3979 NestedNameSpecifierMatcher Matcher = nestedNameSpecifier(
3980 specifiesType(hasDeclaration(recordDecl(hasName("A")))));
3981 EXPECT_TRUE(matches("struct A { struct B {}; }; A::B b;", Matcher));
3982 EXPECT_TRUE(matches("struct A { struct B { struct C {}; }; }; A::B::C c;",
3983 Matcher));
3984 EXPECT_TRUE(notMatches("namespace A { struct B {}; } A::B b;", Matcher));
3985}
3986
3987TEST(NNS, MatchesNamespaceDecls) {
3988 NestedNameSpecifierMatcher Matcher = nestedNameSpecifier(
3989 specifiesNamespace(hasName("ns")));
3990 EXPECT_TRUE(matches("namespace ns { struct A {}; } ns::A a;", Matcher));
3991 EXPECT_TRUE(notMatches("namespace xx { struct A {}; } xx::A a;", Matcher));
3992 EXPECT_TRUE(notMatches("struct ns { struct A {}; }; ns::A a;", Matcher));
3993}
3994
3995TEST(NNS, BindsNestedNameSpecifiers) {
3996 EXPECT_TRUE(matchAndVerifyResultTrue(
3997 "namespace ns { struct E { struct B {}; }; } ns::E::B b;",
3998 nestedNameSpecifier(specifiesType(asString("struct ns::E"))).bind("nns"),
3999 new VerifyIdIsBoundTo<NestedNameSpecifier>("nns", "ns::struct E::")));
4000}
4001
4002TEST(NNS, BindsNestedNameSpecifierLocs) {
4003 EXPECT_TRUE(matchAndVerifyResultTrue(
4004 "namespace ns { struct B {}; } ns::B b;",
4005 loc(nestedNameSpecifier()).bind("loc"),
4006 new VerifyIdIsBoundTo<NestedNameSpecifierLoc>("loc", 1)));
4007}
4008
4009TEST(NNS, MatchesNestedNameSpecifierPrefixes) {
4010 EXPECT_TRUE(matches(
4011 "struct A { struct B { struct C {}; }; }; A::B::C c;",
4012 nestedNameSpecifier(hasPrefix(specifiesType(asString("struct A"))))));
4013 EXPECT_TRUE(matches(
4014 "struct A { struct B { struct C {}; }; }; A::B::C c;",
Daniel Jasper516b02e2012-10-17 08:52:59 +00004015 nestedNameSpecifierLoc(hasPrefix(
4016 specifiesTypeLoc(loc(qualType(asString("struct A"))))))));
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00004017}
4018
Daniel Jasper6fc34332012-10-30 15:42:00 +00004019TEST(NNS, DescendantsOfNestedNameSpecifiers) {
4020 std::string Fragment =
4021 "namespace a { struct A { struct B { struct C {}; }; }; };"
4022 "void f() { a::A::B::C c; }";
4023 EXPECT_TRUE(matches(
4024 Fragment,
4025 nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
4026 hasDescendant(nestedNameSpecifier(
4027 specifiesNamespace(hasName("a")))))));
4028 EXPECT_TRUE(notMatches(
4029 Fragment,
4030 nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
4031 has(nestedNameSpecifier(
4032 specifiesNamespace(hasName("a")))))));
4033 EXPECT_TRUE(matches(
4034 Fragment,
4035 nestedNameSpecifier(specifiesType(asString("struct a::A")),
4036 has(nestedNameSpecifier(
4037 specifiesNamespace(hasName("a")))))));
4038
4039 // Not really useful because a NestedNameSpecifier can af at most one child,
4040 // but to complete the interface.
4041 EXPECT_TRUE(matchAndVerifyResultTrue(
4042 Fragment,
4043 nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
4044 forEach(nestedNameSpecifier().bind("x"))),
4045 new VerifyIdIsBoundTo<NestedNameSpecifier>("x", 1)));
4046}
4047
4048TEST(NNS, NestedNameSpecifiersAsDescendants) {
4049 std::string Fragment =
4050 "namespace a { struct A { struct B { struct C {}; }; }; };"
4051 "void f() { a::A::B::C c; }";
4052 EXPECT_TRUE(matches(
4053 Fragment,
4054 decl(hasDescendant(nestedNameSpecifier(specifiesType(
4055 asString("struct a::A")))))));
4056 EXPECT_TRUE(matchAndVerifyResultTrue(
4057 Fragment,
4058 functionDecl(hasName("f"),
4059 forEachDescendant(nestedNameSpecifier().bind("x"))),
4060 // Nested names: a, a::A and a::A::B.
4061 new VerifyIdIsBoundTo<NestedNameSpecifier>("x", 3)));
4062}
4063
4064TEST(NNSLoc, DescendantsOfNestedNameSpecifierLocs) {
4065 std::string Fragment =
4066 "namespace a { struct A { struct B { struct C {}; }; }; };"
4067 "void f() { a::A::B::C c; }";
4068 EXPECT_TRUE(matches(
4069 Fragment,
4070 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
4071 hasDescendant(loc(nestedNameSpecifier(
4072 specifiesNamespace(hasName("a"))))))));
4073 EXPECT_TRUE(notMatches(
4074 Fragment,
4075 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
4076 has(loc(nestedNameSpecifier(
4077 specifiesNamespace(hasName("a"))))))));
4078 EXPECT_TRUE(matches(
4079 Fragment,
4080 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A"))),
4081 has(loc(nestedNameSpecifier(
4082 specifiesNamespace(hasName("a"))))))));
4083
4084 EXPECT_TRUE(matchAndVerifyResultTrue(
4085 Fragment,
4086 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
4087 forEach(nestedNameSpecifierLoc().bind("x"))),
4088 new VerifyIdIsBoundTo<NestedNameSpecifierLoc>("x", 1)));
4089}
4090
4091TEST(NNSLoc, NestedNameSpecifierLocsAsDescendants) {
4092 std::string Fragment =
4093 "namespace a { struct A { struct B { struct C {}; }; }; };"
4094 "void f() { a::A::B::C c; }";
4095 EXPECT_TRUE(matches(
4096 Fragment,
4097 decl(hasDescendant(loc(nestedNameSpecifier(specifiesType(
4098 asString("struct a::A"))))))));
4099 EXPECT_TRUE(matchAndVerifyResultTrue(
4100 Fragment,
4101 functionDecl(hasName("f"),
4102 forEachDescendant(nestedNameSpecifierLoc().bind("x"))),
4103 // Nested names: a, a::A and a::A::B.
4104 new VerifyIdIsBoundTo<NestedNameSpecifierLoc>("x", 3)));
4105}
4106
Manuel Klimek191c0932013-02-01 13:41:35 +00004107template <typename T> class VerifyMatchOnNode : public BoundNodesCallback {
Manuel Klimekc2687452012-10-24 14:47:44 +00004108public:
Manuel Klimek2cff49e2013-02-06 10:33:21 +00004109 VerifyMatchOnNode(StringRef Id, const internal::Matcher<T> &InnerMatcher,
4110 StringRef InnerId)
4111 : Id(Id), InnerMatcher(InnerMatcher), InnerId(InnerId) {
Daniel Jaspere9aa6872012-10-29 10:48:25 +00004112 }
4113
Manuel Klimek191c0932013-02-01 13:41:35 +00004114 virtual bool run(const BoundNodes *Nodes) { return false; }
4115
Manuel Klimekc2687452012-10-24 14:47:44 +00004116 virtual bool run(const BoundNodes *Nodes, ASTContext *Context) {
4117 const T *Node = Nodes->getNodeAs<T>(Id);
Manuel Klimek2cff49e2013-02-06 10:33:21 +00004118 return selectFirst<const T>(InnerId,
4119 match(InnerMatcher, *Node, *Context)) != NULL;
Manuel Klimekc2687452012-10-24 14:47:44 +00004120 }
4121private:
4122 std::string Id;
4123 internal::Matcher<T> InnerMatcher;
Manuel Klimek2cff49e2013-02-06 10:33:21 +00004124 std::string InnerId;
Manuel Klimekc2687452012-10-24 14:47:44 +00004125};
4126
4127TEST(MatchFinder, CanMatchDeclarationsRecursively) {
Manuel Klimek191c0932013-02-01 13:41:35 +00004128 EXPECT_TRUE(matchAndVerifyResultTrue(
4129 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
4130 new VerifyMatchOnNode<clang::Decl>(
Manuel Klimek2cff49e2013-02-06 10:33:21 +00004131 "X", decl(hasDescendant(recordDecl(hasName("X::Y")).bind("Y"))),
4132 "Y")));
Manuel Klimek191c0932013-02-01 13:41:35 +00004133 EXPECT_TRUE(matchAndVerifyResultFalse(
4134 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
4135 new VerifyMatchOnNode<clang::Decl>(
Manuel Klimek2cff49e2013-02-06 10:33:21 +00004136 "X", decl(hasDescendant(recordDecl(hasName("X::Z")).bind("Z"))),
4137 "Z")));
Manuel Klimekc2687452012-10-24 14:47:44 +00004138}
4139
4140TEST(MatchFinder, CanMatchStatementsRecursively) {
Manuel Klimek191c0932013-02-01 13:41:35 +00004141 EXPECT_TRUE(matchAndVerifyResultTrue(
4142 "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
Manuel Klimek2cff49e2013-02-06 10:33:21 +00004143 new VerifyMatchOnNode<clang::Stmt>(
4144 "if", stmt(hasDescendant(forStmt().bind("for"))), "for")));
Manuel Klimek191c0932013-02-01 13:41:35 +00004145 EXPECT_TRUE(matchAndVerifyResultFalse(
4146 "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
Manuel Klimek2cff49e2013-02-06 10:33:21 +00004147 new VerifyMatchOnNode<clang::Stmt>(
4148 "if", stmt(hasDescendant(declStmt().bind("decl"))), "decl")));
Manuel Klimek191c0932013-02-01 13:41:35 +00004149}
4150
4151TEST(MatchFinder, CanMatchSingleNodesRecursively) {
4152 EXPECT_TRUE(matchAndVerifyResultTrue(
4153 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
4154 new VerifyMatchOnNode<clang::Decl>(
Manuel Klimek2cff49e2013-02-06 10:33:21 +00004155 "X", recordDecl(has(recordDecl(hasName("X::Y")).bind("Y"))), "Y")));
Manuel Klimek191c0932013-02-01 13:41:35 +00004156 EXPECT_TRUE(matchAndVerifyResultFalse(
4157 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
4158 new VerifyMatchOnNode<clang::Decl>(
Manuel Klimek2cff49e2013-02-06 10:33:21 +00004159 "X", recordDecl(has(recordDecl(hasName("X::Z")).bind("Z"))), "Z")));
Manuel Klimekc2687452012-10-24 14:47:44 +00004160}
4161
Manuel Klimekbee08572013-02-07 12:42:10 +00004162template <typename T>
4163class VerifyAncestorHasChildIsEqual : public BoundNodesCallback {
4164public:
4165 virtual bool run(const BoundNodes *Nodes) { return false; }
4166
4167 virtual bool run(const BoundNodes *Nodes, ASTContext *Context) {
4168 const T *Node = Nodes->getNodeAs<T>("");
4169 return verify(*Nodes, *Context, Node);
4170 }
4171
4172 bool verify(const BoundNodes &Nodes, ASTContext &Context, const Stmt *Node) {
Manuel Klimeka2c2a4f2014-05-27 12:31:10 +00004173 // Use the original typed pointer to verify we can pass pointers to subtypes
4174 // to equalsNode.
4175 const T *TypedNode = cast<T>(Node);
Manuel Klimekbee08572013-02-07 12:42:10 +00004176 return selectFirst<const T>(
Manuel Klimeka2c2a4f2014-05-27 12:31:10 +00004177 "", match(stmt(hasParent(
4178 stmt(has(stmt(equalsNode(TypedNode)))).bind(""))),
4179 *Node, Context)) != NULL;
Manuel Klimekbee08572013-02-07 12:42:10 +00004180 }
4181 bool verify(const BoundNodes &Nodes, ASTContext &Context, const Decl *Node) {
Manuel Klimeka2c2a4f2014-05-27 12:31:10 +00004182 // Use the original typed pointer to verify we can pass pointers to subtypes
4183 // to equalsNode.
4184 const T *TypedNode = cast<T>(Node);
Manuel Klimekbee08572013-02-07 12:42:10 +00004185 return selectFirst<const T>(
Manuel Klimeka2c2a4f2014-05-27 12:31:10 +00004186 "", match(decl(hasParent(
4187 decl(has(decl(equalsNode(TypedNode)))).bind(""))),
4188 *Node, Context)) != NULL;
Manuel Klimekbee08572013-02-07 12:42:10 +00004189 }
4190};
4191
4192TEST(IsEqualTo, MatchesNodesByIdentity) {
4193 EXPECT_TRUE(matchAndVerifyResultTrue(
4194 "class X { class Y {}; };", recordDecl(hasName("::X::Y")).bind(""),
Manuel Klimeka2c2a4f2014-05-27 12:31:10 +00004195 new VerifyAncestorHasChildIsEqual<CXXRecordDecl>()));
4196 EXPECT_TRUE(matchAndVerifyResultTrue(
4197 "void f() { if (true) if(true) {} }", ifStmt().bind(""),
4198 new VerifyAncestorHasChildIsEqual<IfStmt>()));
Manuel Klimekbee08572013-02-07 12:42:10 +00004199}
4200
Manuel Klimekbd0e2b72012-11-02 01:31:03 +00004201class VerifyStartOfTranslationUnit : public MatchFinder::MatchCallback {
4202public:
4203 VerifyStartOfTranslationUnit() : Called(false) {}
4204 virtual void run(const MatchFinder::MatchResult &Result) {
4205 EXPECT_TRUE(Called);
4206 }
4207 virtual void onStartOfTranslationUnit() {
4208 Called = true;
4209 }
4210 bool Called;
4211};
4212
4213TEST(MatchFinder, InterceptsStartOfTranslationUnit) {
4214 MatchFinder Finder;
4215 VerifyStartOfTranslationUnit VerifyCallback;
4216 Finder.addMatcher(decl(), &VerifyCallback);
Ahmed Charlesb8984322014-03-07 20:03:18 +00004217 std::unique_ptr<FrontendActionFactory> Factory(
4218 newFrontendActionFactory(&Finder));
Manuel Klimekbd0e2b72012-11-02 01:31:03 +00004219 ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), "int x;"));
4220 EXPECT_TRUE(VerifyCallback.Called);
Peter Collingbournea2334162013-11-07 22:30:36 +00004221
4222 VerifyCallback.Called = false;
Ahmed Charlesb8984322014-03-07 20:03:18 +00004223 std::unique_ptr<ASTUnit> AST(tooling::buildASTFromCode("int x;"));
Peter Collingbournea2334162013-11-07 22:30:36 +00004224 ASSERT_TRUE(AST.get());
4225 Finder.matchAST(AST->getASTContext());
4226 EXPECT_TRUE(VerifyCallback.Called);
Manuel Klimekbd0e2b72012-11-02 01:31:03 +00004227}
4228
Peter Collingbourne6a55bb22013-05-28 19:21:51 +00004229class VerifyEndOfTranslationUnit : public MatchFinder::MatchCallback {
4230public:
4231 VerifyEndOfTranslationUnit() : Called(false) {}
4232 virtual void run(const MatchFinder::MatchResult &Result) {
4233 EXPECT_FALSE(Called);
4234 }
4235 virtual void onEndOfTranslationUnit() {
4236 Called = true;
4237 }
4238 bool Called;
4239};
4240
4241TEST(MatchFinder, InterceptsEndOfTranslationUnit) {
4242 MatchFinder Finder;
4243 VerifyEndOfTranslationUnit VerifyCallback;
4244 Finder.addMatcher(decl(), &VerifyCallback);
Ahmed Charlesb8984322014-03-07 20:03:18 +00004245 std::unique_ptr<FrontendActionFactory> Factory(
4246 newFrontendActionFactory(&Finder));
Peter Collingbourne6a55bb22013-05-28 19:21:51 +00004247 ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), "int x;"));
4248 EXPECT_TRUE(VerifyCallback.Called);
Peter Collingbournea2334162013-11-07 22:30:36 +00004249
4250 VerifyCallback.Called = false;
Ahmed Charlesb8984322014-03-07 20:03:18 +00004251 std::unique_ptr<ASTUnit> AST(tooling::buildASTFromCode("int x;"));
Peter Collingbournea2334162013-11-07 22:30:36 +00004252 ASSERT_TRUE(AST.get());
4253 Finder.matchAST(AST->getASTContext());
4254 EXPECT_TRUE(VerifyCallback.Called);
Peter Collingbourne6a55bb22013-05-28 19:21:51 +00004255}
4256
Manuel Klimekbbb75852013-06-20 14:06:32 +00004257TEST(EqualsBoundNodeMatcher, QualType) {
4258 EXPECT_TRUE(matches(
4259 "int i = 1;", varDecl(hasType(qualType().bind("type")),
4260 hasInitializer(ignoringParenImpCasts(
4261 hasType(qualType(equalsBoundNode("type"))))))));
4262 EXPECT_TRUE(notMatches("int i = 1.f;",
4263 varDecl(hasType(qualType().bind("type")),
4264 hasInitializer(ignoringParenImpCasts(hasType(
4265 qualType(equalsBoundNode("type"))))))));
4266}
4267
4268TEST(EqualsBoundNodeMatcher, NonMatchingTypes) {
4269 EXPECT_TRUE(notMatches(
4270 "int i = 1;", varDecl(namedDecl(hasName("i")).bind("name"),
4271 hasInitializer(ignoringParenImpCasts(
4272 hasType(qualType(equalsBoundNode("type"))))))));
4273}
4274
4275TEST(EqualsBoundNodeMatcher, Stmt) {
4276 EXPECT_TRUE(
4277 matches("void f() { if(true) {} }",
4278 stmt(allOf(ifStmt().bind("if"),
4279 hasParent(stmt(has(stmt(equalsBoundNode("if")))))))));
4280
4281 EXPECT_TRUE(notMatches(
4282 "void f() { if(true) { if (true) {} } }",
4283 stmt(allOf(ifStmt().bind("if"), has(stmt(equalsBoundNode("if")))))));
4284}
4285
4286TEST(EqualsBoundNodeMatcher, Decl) {
4287 EXPECT_TRUE(matches(
4288 "class X { class Y {}; };",
4289 decl(allOf(recordDecl(hasName("::X::Y")).bind("record"),
4290 hasParent(decl(has(decl(equalsBoundNode("record")))))))));
4291
4292 EXPECT_TRUE(notMatches("class X { class Y {}; };",
4293 decl(allOf(recordDecl(hasName("::X")).bind("record"),
4294 has(decl(equalsBoundNode("record")))))));
4295}
4296
4297TEST(EqualsBoundNodeMatcher, Type) {
4298 EXPECT_TRUE(matches(
4299 "class X { int a; int b; };",
4300 recordDecl(
4301 has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
4302 has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
4303
4304 EXPECT_TRUE(notMatches(
4305 "class X { int a; double b; };",
4306 recordDecl(
4307 has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
4308 has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
4309}
4310
4311TEST(EqualsBoundNodeMatcher, UsingForEachDescendant) {
Manuel Klimekbbb75852013-06-20 14:06:32 +00004312 EXPECT_TRUE(matchAndVerifyResultTrue(
4313 "int f() {"
4314 " if (1) {"
4315 " int i = 9;"
4316 " }"
4317 " int j = 10;"
4318 " {"
4319 " float k = 9.0;"
4320 " }"
4321 " return 0;"
4322 "}",
4323 // Look for variable declarations within functions whose type is the same
4324 // as the function return type.
4325 functionDecl(returns(qualType().bind("type")),
4326 forEachDescendant(varDecl(hasType(
4327 qualType(equalsBoundNode("type")))).bind("decl"))),
4328 // Only i and j should match, not k.
4329 new VerifyIdIsBoundTo<VarDecl>("decl", 2)));
4330}
4331
4332TEST(EqualsBoundNodeMatcher, FiltersMatchedCombinations) {
4333 EXPECT_TRUE(matchAndVerifyResultTrue(
4334 "void f() {"
4335 " int x;"
4336 " double d;"
4337 " x = d + x - d + x;"
4338 "}",
4339 functionDecl(
4340 hasName("f"), forEachDescendant(varDecl().bind("d")),
4341 forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d")))))),
4342 new VerifyIdIsBoundTo<VarDecl>("d", 5)));
4343}
4344
Manuel Klimekce68f772014-03-25 14:39:26 +00004345TEST(EqualsBoundNodeMatcher, UnlessDescendantsOfAncestorsMatch) {
4346 EXPECT_TRUE(matchAndVerifyResultTrue(
4347 "struct StringRef { int size() const; const char* data() const; };"
4348 "void f(StringRef v) {"
4349 " v.data();"
4350 "}",
4351 memberCallExpr(
4352 callee(methodDecl(hasName("data"))),
4353 on(declRefExpr(to(varDecl(hasType(recordDecl(hasName("StringRef"))))
4354 .bind("var")))),
4355 unless(hasAncestor(stmt(hasDescendant(memberCallExpr(
4356 callee(methodDecl(anyOf(hasName("size"), hasName("length")))),
4357 on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
4358 .bind("data"),
4359 new VerifyIdIsBoundTo<Expr>("data", 1)));
4360
4361 EXPECT_FALSE(matches(
4362 "struct StringRef { int size() const; const char* data() const; };"
4363 "void f(StringRef v) {"
4364 " v.data();"
4365 " v.size();"
4366 "}",
4367 memberCallExpr(
4368 callee(methodDecl(hasName("data"))),
4369 on(declRefExpr(to(varDecl(hasType(recordDecl(hasName("StringRef"))))
4370 .bind("var")))),
4371 unless(hasAncestor(stmt(hasDescendant(memberCallExpr(
4372 callee(methodDecl(anyOf(hasName("size"), hasName("length")))),
4373 on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
4374 .bind("data")));
4375}
4376
Manuel Klimek04616e42012-07-06 05:48:52 +00004377} // end namespace ast_matchers
4378} // end namespace clang