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