blob: a34617935799a2968d556dbef3c0f7c5c6b98221 [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(
Gabor Horvath1b654f22016-03-30 11:22:14 +00001636 hasAnyArgument(
1637 ignoringParenImpCasts(declRefExpr(to(varDecl(hasName("y")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001638 EXPECT_TRUE(matches("void x(int, int) { int y; x(1, y); }", CallArgumentY));
1639 EXPECT_TRUE(matches("void x(int, int) { int y; x(y, 42); }", CallArgumentY));
1640 EXPECT_TRUE(notMatches("void x(int, int) { x(1, 2); }", CallArgumentY));
Gabor Horvath1b654f22016-03-30 11:22:14 +00001641
1642 StatementMatcher ImplicitCastedArgument = callExpr(
1643 hasAnyArgument(implicitCastExpr()));
1644 EXPECT_TRUE(matches("void x(long) { int y; x(y); }", ImplicitCastedArgument));
Manuel Klimek04616e42012-07-06 05:48:52 +00001645}
1646
Manuel Klimekce28f9e2016-01-18 11:20:09 +00001647TEST(ForEachArgumentWithParam, ReportsNoFalsePositives) {
1648 StatementMatcher ArgumentY =
1649 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1650 DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
1651 StatementMatcher CallExpr =
1652 callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
1653
1654 // IntParam does not match.
Aaron Ballmand7b18b92016-01-18 20:28:57 +00001655 EXPECT_TRUE(notMatches("void f(int* i) { int* y; f(y); }", CallExpr));
Manuel Klimekce28f9e2016-01-18 11:20:09 +00001656 // ArgumentY does not match.
Aaron Ballmand7b18b92016-01-18 20:28:57 +00001657 EXPECT_TRUE(notMatches("void f(int i) { int x; f(x); }", CallExpr));
Manuel Klimekce28f9e2016-01-18 11:20:09 +00001658}
1659
1660TEST(ForEachArgumentWithParam, MatchesCXXMemberCallExpr) {
1661 StatementMatcher ArgumentY =
1662 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1663 DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
1664 StatementMatcher CallExpr =
1665 callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
1666 EXPECT_TRUE(matchAndVerifyResultTrue(
1667 "struct S {"
1668 " const S& operator[](int i) { return *this; }"
1669 "};"
1670 "void f(S S1) {"
1671 " int y = 1;"
1672 " S1[y];"
1673 "}",
1674 CallExpr, new VerifyIdIsBoundTo<ParmVarDecl>("param", 1)));
Aaron Ballmand7b18b92016-01-18 20:28:57 +00001675
1676 StatementMatcher CallExpr2 =
1677 callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
1678 EXPECT_TRUE(matchAndVerifyResultTrue(
1679 "struct S {"
1680 " static void g(int i);"
1681 "};"
1682 "void f() {"
1683 " int y = 1;"
1684 " S::g(y);"
1685 "}",
1686 CallExpr2, new VerifyIdIsBoundTo<ParmVarDecl>("param", 1)));
Manuel Klimekce28f9e2016-01-18 11:20:09 +00001687}
1688
1689TEST(ForEachArgumentWithParam, MatchesCallExpr) {
1690 StatementMatcher ArgumentY =
1691 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1692 DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
1693 StatementMatcher CallExpr =
1694 callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
1695
1696 EXPECT_TRUE(
1697 matchAndVerifyResultTrue("void f(int i) { int y; f(y); }", CallExpr,
1698 new VerifyIdIsBoundTo<ParmVarDecl>("param")));
1699 EXPECT_TRUE(
1700 matchAndVerifyResultTrue("void f(int i) { int y; f(y); }", CallExpr,
1701 new VerifyIdIsBoundTo<DeclRefExpr>("arg")));
1702
1703 EXPECT_TRUE(matchAndVerifyResultTrue(
1704 "void f(int i, int j) { int y; f(y, y); }", CallExpr,
1705 new VerifyIdIsBoundTo<ParmVarDecl>("param", 2)));
1706 EXPECT_TRUE(matchAndVerifyResultTrue(
1707 "void f(int i, int j) { int y; f(y, y); }", CallExpr,
1708 new VerifyIdIsBoundTo<DeclRefExpr>("arg", 2)));
1709}
1710
1711TEST(ForEachArgumentWithParam, MatchesConstructExpr) {
1712 StatementMatcher ArgumentY =
1713 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1714 DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
1715 StatementMatcher ConstructExpr =
1716 cxxConstructExpr(forEachArgumentWithParam(ArgumentY, IntParam));
1717
1718 EXPECT_TRUE(matchAndVerifyResultTrue(
1719 "struct C {"
1720 " C(int i) {}"
1721 "};"
1722 "int y = 0;"
1723 "C Obj(y);",
1724 ConstructExpr, new VerifyIdIsBoundTo<ParmVarDecl>("param")));
1725}
1726
1727TEST(ForEachArgumentWithParam, HandlesBoundNodesForNonMatches) {
1728 EXPECT_TRUE(matchAndVerifyResultTrue(
1729 "void g(int i, int j) {"
1730 " int a;"
1731 " int b;"
1732 " int c;"
1733 " g(a, 0);"
1734 " g(a, b);"
1735 " g(0, b);"
1736 "}",
1737 functionDecl(
1738 forEachDescendant(varDecl().bind("v")),
1739 forEachDescendant(callExpr(forEachArgumentWithParam(
1740 declRefExpr(to(decl(equalsBoundNode("v")))), parmVarDecl())))),
1741 new VerifyIdIsBoundTo<VarDecl>("v", 4)));
1742}
1743
Manuel Klimek04616e42012-07-06 05:48:52 +00001744TEST(Matcher, ArgumentCount) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00001745 StatementMatcher Call1Arg = callExpr(argumentCountIs(1));
Manuel Klimek04616e42012-07-06 05:48:52 +00001746
1747 EXPECT_TRUE(matches("void x(int) { x(0); }", Call1Arg));
1748 EXPECT_TRUE(matches("class X { void x(int) { x(0); } };", Call1Arg));
1749 EXPECT_TRUE(notMatches("void x(int, int) { x(0, 0); }", Call1Arg));
1750}
1751
Daniel Jasper9f501292012-12-04 11:54:27 +00001752TEST(Matcher, ParameterCount) {
1753 DeclarationMatcher Function1Arg = functionDecl(parameterCountIs(1));
1754 EXPECT_TRUE(matches("void f(int i) {}", Function1Arg));
1755 EXPECT_TRUE(matches("class X { void f(int i) {} };", Function1Arg));
1756 EXPECT_TRUE(notMatches("void f() {}", Function1Arg));
1757 EXPECT_TRUE(notMatches("void f(int i, int j, int k) {}", Function1Arg));
Aaron Ballman7e7b7b22016-02-01 14:11:47 +00001758 EXPECT_TRUE(matches("void f(int i, ...) {};", Function1Arg));
Daniel Jasper9f501292012-12-04 11:54:27 +00001759}
1760
Manuel Klimek04616e42012-07-06 05:48:52 +00001761TEST(Matcher, References) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001762 DeclarationMatcher ReferenceClassX = varDecl(
1763 hasType(references(recordDecl(hasName("X")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001764 EXPECT_TRUE(matches("class X {}; void y(X y) { X &x = y; }",
1765 ReferenceClassX));
1766 EXPECT_TRUE(
1767 matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX));
Michael Hanc90d12d2013-09-11 15:53:29 +00001768 // The match here is on the implicit copy constructor code for
1769 // class X, not on code 'X x = y'.
Manuel Klimek04616e42012-07-06 05:48:52 +00001770 EXPECT_TRUE(
Michael Hanc90d12d2013-09-11 15:53:29 +00001771 matches("class X {}; void y(X y) { X x = y; }", ReferenceClassX));
1772 EXPECT_TRUE(
1773 notMatches("class X {}; extern X x;", ReferenceClassX));
Manuel Klimek04616e42012-07-06 05:48:52 +00001774 EXPECT_TRUE(
1775 notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX));
1776}
1777
Edwin Vane0a4836e2013-03-06 17:02:57 +00001778TEST(QualType, hasCanonicalType) {
1779 EXPECT_TRUE(notMatches("typedef int &int_ref;"
1780 "int a;"
1781 "int_ref b = a;",
1782 varDecl(hasType(qualType(referenceType())))));
1783 EXPECT_TRUE(
1784 matches("typedef int &int_ref;"
1785 "int a;"
1786 "int_ref b = a;",
1787 varDecl(hasType(qualType(hasCanonicalType(referenceType()))))));
1788}
1789
Edwin Vane119d3df2013-04-02 18:15:55 +00001790TEST(QualType, hasLocalQualifiers) {
1791 EXPECT_TRUE(notMatches("typedef const int const_int; const_int i = 1;",
1792 varDecl(hasType(hasLocalQualifiers()))));
1793 EXPECT_TRUE(matches("int *const j = nullptr;",
1794 varDecl(hasType(hasLocalQualifiers()))));
1795 EXPECT_TRUE(matches("int *volatile k;",
1796 varDecl(hasType(hasLocalQualifiers()))));
1797 EXPECT_TRUE(notMatches("int m;",
1798 varDecl(hasType(hasLocalQualifiers()))));
1799}
1800
Manuel Klimek04616e42012-07-06 05:48:52 +00001801TEST(HasParameter, CallsInnerMatcher) {
1802 EXPECT_TRUE(matches("class X { void x(int) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001803 cxxMethodDecl(hasParameter(0, varDecl()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001804 EXPECT_TRUE(notMatches("class X { void x(int) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001805 cxxMethodDecl(hasParameter(0, hasName("x")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001806}
1807
1808TEST(HasParameter, DoesNotMatchIfIndexOutOfBounds) {
1809 EXPECT_TRUE(notMatches("class X { void x(int) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001810 cxxMethodDecl(hasParameter(42, varDecl()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001811}
1812
1813TEST(HasType, MatchesParameterVariableTypesStrictly) {
Aaron Ballman512fb642015-09-17 13:30:52 +00001814 EXPECT_TRUE(matches(
1815 "class X { void x(X x) {} };",
1816 cxxMethodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
1817 EXPECT_TRUE(notMatches(
1818 "class X { void x(const X &x) {} };",
1819 cxxMethodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001820 EXPECT_TRUE(matches("class X { void x(const X *x) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001821 cxxMethodDecl(hasParameter(
1822 0, hasType(pointsTo(recordDecl(hasName("X"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001823 EXPECT_TRUE(matches("class X { void x(const X &x) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001824 cxxMethodDecl(hasParameter(
1825 0, hasType(references(recordDecl(hasName("X"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001826}
1827
1828TEST(HasAnyParameter, MatchesIndependentlyOfPosition) {
Aaron Ballman512fb642015-09-17 13:30:52 +00001829 EXPECT_TRUE(matches(
1830 "class Y {}; class X { void x(X x, Y y) {} };",
1831 cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
1832 EXPECT_TRUE(matches(
1833 "class Y {}; class X { void x(Y y, X x) {} };",
1834 cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001835}
1836
Daniel Jasper1dad1832012-07-10 20:20:19 +00001837TEST(Returns, MatchesReturnTypes) {
1838 EXPECT_TRUE(matches("class Y { int f() { return 1; } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001839 functionDecl(returns(asString("int")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001840 EXPECT_TRUE(notMatches("class Y { int f() { return 1; } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001841 functionDecl(returns(asString("float")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001842 EXPECT_TRUE(matches("class Y { Y getMe() { return *this; } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001843 functionDecl(returns(hasDeclaration(
1844 recordDecl(hasName("Y")))))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001845}
1846
Daniel Jasperfaaffe32012-08-15 18:52:19 +00001847TEST(IsExternC, MatchesExternCFunctionDeclarations) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001848 EXPECT_TRUE(matches("extern \"C\" void f() {}", functionDecl(isExternC())));
1849 EXPECT_TRUE(matches("extern \"C\" { void f() {} }",
1850 functionDecl(isExternC())));
1851 EXPECT_TRUE(notMatches("void f() {}", functionDecl(isExternC())));
Daniel Jasperfaaffe32012-08-15 18:52:19 +00001852}
1853
Aaron Ballmaneb85b042016-01-18 20:37:44 +00001854TEST(IsDefaulted, MatchesDefaultedFunctionDeclarations) {
Aaron Ballman9e373df2016-01-18 20:47:02 +00001855 EXPECT_TRUE(notMatches("class A { ~A(); };",
1856 functionDecl(hasName("~A"), isDefaulted())));
Aaron Ballmaneb85b042016-01-18 20:37:44 +00001857 EXPECT_TRUE(matches("class B { ~B() = default; };",
Aaron Ballman9e373df2016-01-18 20:47:02 +00001858 functionDecl(hasName("~B"), isDefaulted())));
Aaron Ballmaneb85b042016-01-18 20:37:44 +00001859}
1860
Samuel Benzaquen8e7f9962014-08-15 14:20:59 +00001861TEST(IsDeleted, MatchesDeletedFunctionDeclarations) {
1862 EXPECT_TRUE(
1863 notMatches("void Func();", functionDecl(hasName("Func"), isDeleted())));
1864 EXPECT_TRUE(matches("void Func() = delete;",
1865 functionDecl(hasName("Func"), isDeleted())));
1866}
1867
Aaron Ballmana60bcda2015-12-02 15:23:59 +00001868TEST(IsNoThrow, MatchesNoThrowFunctionDeclarations) {
1869 EXPECT_TRUE(notMatches("void f();", functionDecl(isNoThrow())));
1870 EXPECT_TRUE(notMatches("void f() throw(int);", functionDecl(isNoThrow())));
1871 EXPECT_TRUE(
1872 notMatches("void f() noexcept(false);", functionDecl(isNoThrow())));
1873 EXPECT_TRUE(matches("void f() throw();", functionDecl(isNoThrow())));
1874 EXPECT_TRUE(matches("void f() noexcept;", functionDecl(isNoThrow())));
1875}
1876
Szabolcs Siposb37b0ed2015-05-22 11:35:50 +00001877TEST(isConstexpr, MatchesConstexprDeclarations) {
1878 EXPECT_TRUE(matches("constexpr int foo = 42;",
1879 varDecl(hasName("foo"), isConstexpr())));
1880 EXPECT_TRUE(matches("constexpr int bar();",
1881 functionDecl(hasName("bar"), isConstexpr())));
1882}
1883
Manuel Klimek04616e42012-07-06 05:48:52 +00001884TEST(HasAnyParameter, DoesntMatchIfInnerMatcherDoesntMatch) {
Aaron Ballman512fb642015-09-17 13:30:52 +00001885 EXPECT_TRUE(notMatches(
1886 "class Y {}; class X { void x(int) {} };",
1887 cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001888}
1889
1890TEST(HasAnyParameter, DoesNotMatchThisPointer) {
1891 EXPECT_TRUE(notMatches("class Y {}; class X { void x() {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001892 cxxMethodDecl(hasAnyParameter(
1893 hasType(pointsTo(recordDecl(hasName("X"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001894}
1895
Alp Toker8db6e7a2014-01-05 06:38:57 +00001896TEST(HasName, MatchesParameterVariableDeclarations) {
Manuel Klimek04616e42012-07-06 05:48:52 +00001897 EXPECT_TRUE(matches("class Y {}; class X { void x(int x) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001898 cxxMethodDecl(hasAnyParameter(hasName("x")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001899 EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001900 cxxMethodDecl(hasAnyParameter(hasName("x")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001901}
1902
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001903TEST(Matcher, MatchesClassTemplateSpecialization) {
1904 EXPECT_TRUE(matches("template<typename T> struct A {};"
1905 "template<> struct A<int> {};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001906 classTemplateSpecializationDecl()));
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001907 EXPECT_TRUE(matches("template<typename T> struct A {}; A<int> a;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001908 classTemplateSpecializationDecl()));
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001909 EXPECT_TRUE(notMatches("template<typename T> struct A {};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001910 classTemplateSpecializationDecl()));
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001911}
1912
Manuel Klimekc16c6522013-06-20 13:08:29 +00001913TEST(DeclaratorDecl, MatchesDeclaratorDecls) {
1914 EXPECT_TRUE(matches("int x;", declaratorDecl()));
1915 EXPECT_TRUE(notMatches("class A {};", declaratorDecl()));
1916}
1917
1918TEST(ParmVarDecl, MatchesParmVars) {
1919 EXPECT_TRUE(matches("void f(int x);", parmVarDecl()));
1920 EXPECT_TRUE(notMatches("void f();", parmVarDecl()));
1921}
1922
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001923TEST(Matcher, MatchesTypeTemplateArgument) {
1924 EXPECT_TRUE(matches(
1925 "template<typename T> struct B {};"
1926 "B<int> b;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001927 classTemplateSpecializationDecl(hasAnyTemplateArgument(refersToType(
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001928 asString("int"))))));
1929}
1930
1931TEST(Matcher, MatchesDeclarationReferenceTemplateArgument) {
1932 EXPECT_TRUE(matches(
1933 "struct B { int next; };"
1934 "template<int(B::*next_ptr)> struct A {};"
1935 "A<&B::next> a;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001936 classTemplateSpecializationDecl(hasAnyTemplateArgument(
1937 refersToDeclaration(fieldDecl(hasName("next")))))));
Daniel Jasper0c303372012-09-29 15:55:18 +00001938
1939 EXPECT_TRUE(notMatches(
1940 "template <typename T> struct A {};"
1941 "A<int> a;",
1942 classTemplateSpecializationDecl(hasAnyTemplateArgument(
1943 refersToDeclaration(decl())))));
Peter Collingbourne564597f2014-02-20 19:18:03 +00001944
1945 EXPECT_TRUE(matches(
1946 "struct B { int next; };"
1947 "template<int(B::*next_ptr)> struct A {};"
1948 "A<&B::next> a;",
1949 templateSpecializationType(hasAnyTemplateArgument(isExpr(
1950 hasDescendant(declRefExpr(to(fieldDecl(hasName("next"))))))))));
1951
1952 EXPECT_TRUE(notMatches(
1953 "template <typename T> struct A {};"
1954 "A<int> a;",
1955 templateSpecializationType(hasAnyTemplateArgument(
1956 refersToDeclaration(decl())))));
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001957}
1958
1959TEST(Matcher, MatchesSpecificArgument) {
1960 EXPECT_TRUE(matches(
1961 "template<typename T, typename U> class A {};"
1962 "A<bool, int> a;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001963 classTemplateSpecializationDecl(hasTemplateArgument(
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001964 1, refersToType(asString("int"))))));
1965 EXPECT_TRUE(notMatches(
1966 "template<typename T, typename U> class A {};"
1967 "A<int, bool> a;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001968 classTemplateSpecializationDecl(hasTemplateArgument(
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001969 1, refersToType(asString("int"))))));
Peter Collingbourne564597f2014-02-20 19:18:03 +00001970
1971 EXPECT_TRUE(matches(
1972 "template<typename T, typename U> class A {};"
1973 "A<bool, int> a;",
1974 templateSpecializationType(hasTemplateArgument(
1975 1, refersToType(asString("int"))))));
1976 EXPECT_TRUE(notMatches(
1977 "template<typename T, typename U> class A {};"
1978 "A<int, bool> a;",
1979 templateSpecializationType(hasTemplateArgument(
1980 1, refersToType(asString("int"))))));
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001981}
1982
Manuel Klimek7735e402014-10-09 13:06:22 +00001983TEST(TemplateArgument, Matches) {
1984 EXPECT_TRUE(matches("template<typename T> struct C {}; C<int> c;",
1985 classTemplateSpecializationDecl(
1986 hasAnyTemplateArgument(templateArgument()))));
1987 EXPECT_TRUE(matches(
1988 "template<typename T> struct C {}; C<int> c;",
1989 templateSpecializationType(hasAnyTemplateArgument(templateArgument()))));
1990}
1991
1992TEST(TemplateArgumentCountIs, Matches) {
1993 EXPECT_TRUE(
1994 matches("template<typename T> struct C {}; C<int> c;",
1995 classTemplateSpecializationDecl(templateArgumentCountIs(1))));
1996 EXPECT_TRUE(
1997 notMatches("template<typename T> struct C {}; C<int> c;",
1998 classTemplateSpecializationDecl(templateArgumentCountIs(2))));
1999
2000 EXPECT_TRUE(matches("template<typename T> struct C {}; C<int> c;",
2001 templateSpecializationType(templateArgumentCountIs(1))));
2002 EXPECT_TRUE(
2003 notMatches("template<typename T> struct C {}; C<int> c;",
2004 templateSpecializationType(templateArgumentCountIs(2))));
2005}
2006
2007TEST(IsIntegral, Matches) {
2008 EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
2009 classTemplateSpecializationDecl(
2010 hasAnyTemplateArgument(isIntegral()))));
2011 EXPECT_TRUE(notMatches("template<typename T> struct C {}; C<int> c;",
2012 classTemplateSpecializationDecl(hasAnyTemplateArgument(
2013 templateArgument(isIntegral())))));
2014}
2015
2016TEST(RefersToIntegralType, Matches) {
2017 EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
2018 classTemplateSpecializationDecl(
2019 hasAnyTemplateArgument(refersToIntegralType(
2020 asString("int"))))));
2021 EXPECT_TRUE(notMatches("template<unsigned T> struct C {}; C<42> c;",
2022 classTemplateSpecializationDecl(hasAnyTemplateArgument(
2023 refersToIntegralType(asString("int"))))));
2024}
2025
2026TEST(EqualsIntegralValue, Matches) {
2027 EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
2028 classTemplateSpecializationDecl(
2029 hasAnyTemplateArgument(equalsIntegralValue("42")))));
2030 EXPECT_TRUE(matches("template<int T> struct C {}; C<-42> c;",
2031 classTemplateSpecializationDecl(
2032 hasAnyTemplateArgument(equalsIntegralValue("-42")))));
2033 EXPECT_TRUE(matches("template<int T> struct C {}; C<-0042> c;",
2034 classTemplateSpecializationDecl(
2035 hasAnyTemplateArgument(equalsIntegralValue("-34")))));
2036 EXPECT_TRUE(notMatches("template<int T> struct C {}; C<42> c;",
2037 classTemplateSpecializationDecl(hasAnyTemplateArgument(
2038 equalsIntegralValue("0042")))));
2039}
2040
Daniel Jasper639522c2013-02-25 12:02:08 +00002041TEST(Matcher, MatchesAccessSpecDecls) {
2042 EXPECT_TRUE(matches("class C { public: int i; };", accessSpecDecl()));
2043 EXPECT_TRUE(
2044 matches("class C { public: int i; };", accessSpecDecl(isPublic())));
2045 EXPECT_TRUE(
2046 notMatches("class C { public: int i; };", accessSpecDecl(isProtected())));
2047 EXPECT_TRUE(
2048 notMatches("class C { public: int i; };", accessSpecDecl(isPrivate())));
2049
2050 EXPECT_TRUE(notMatches("class C { int i; };", accessSpecDecl()));
2051}
2052
Aaron Ballman41143bb2015-07-24 12:35:41 +00002053TEST(Matcher, MatchesFinal) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002054 EXPECT_TRUE(matches("class X final {};", cxxRecordDecl(isFinal())));
Aaron Ballman41143bb2015-07-24 12:35:41 +00002055 EXPECT_TRUE(matches("class X { virtual void f() final; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002056 cxxMethodDecl(isFinal())));
2057 EXPECT_TRUE(notMatches("class X {};", cxxRecordDecl(isFinal())));
2058 EXPECT_TRUE(
2059 notMatches("class X { virtual void f(); };", cxxMethodDecl(isFinal())));
Aaron Ballman41143bb2015-07-24 12:35:41 +00002060}
2061
Edwin Vane37ee1d72013-04-09 20:46:36 +00002062TEST(Matcher, MatchesVirtualMethod) {
2063 EXPECT_TRUE(matches("class X { virtual int f(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002064 cxxMethodDecl(isVirtual(), hasName("::X::f"))));
2065 EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isVirtual())));
Edwin Vane37ee1d72013-04-09 20:46:36 +00002066}
2067
Nico Webera415a1d2016-01-21 17:56:24 +00002068TEST(Matcher, MatchesVirtualAsWrittenMethod) {
2069 EXPECT_TRUE(matches("class A { virtual int f(); };"
2070 "class B : public A { int f(); };",
2071 cxxMethodDecl(isVirtualAsWritten(), hasName("::A::f"))));
2072 EXPECT_TRUE(
2073 notMatches("class A { virtual int f(); };"
2074 "class B : public A { int f(); };",
2075 cxxMethodDecl(isVirtualAsWritten(), hasName("::B::f"))));
2076}
2077
Dmitri Gribenko51c1b552014-02-24 09:27:46 +00002078TEST(Matcher, MatchesPureMethod) {
2079 EXPECT_TRUE(matches("class X { virtual int f() = 0; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002080 cxxMethodDecl(isPure(), hasName("::X::f"))));
2081 EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isPure())));
Dmitri Gribenko51c1b552014-02-24 09:27:46 +00002082}
2083
Angel Garcia Gomez4647ed72015-10-30 09:35:51 +00002084TEST(Matcher, MatchesCopyAssignmentOperator) {
2085 EXPECT_TRUE(matches("class X { X &operator=(X); };",
2086 cxxMethodDecl(isCopyAssignmentOperator())));
2087 EXPECT_TRUE(matches("class X { X &operator=(X &); };",
2088 cxxMethodDecl(isCopyAssignmentOperator())));
2089 EXPECT_TRUE(matches("class X { X &operator=(const X &); };",
2090 cxxMethodDecl(isCopyAssignmentOperator())));
2091 EXPECT_TRUE(matches("class X { X &operator=(volatile X &); };",
2092 cxxMethodDecl(isCopyAssignmentOperator())));
2093 EXPECT_TRUE(matches("class X { X &operator=(const volatile X &); };",
2094 cxxMethodDecl(isCopyAssignmentOperator())));
2095 EXPECT_TRUE(notMatches("class X { X &operator=(X &&); };",
2096 cxxMethodDecl(isCopyAssignmentOperator())));
2097}
2098
Aaron Ballman31bde872016-01-22 22:37:09 +00002099TEST(Matcher, MatchesMoveAssignmentOperator) {
2100 EXPECT_TRUE(notMatches("class X { X &operator=(X); };",
2101 cxxMethodDecl(isMoveAssignmentOperator())));
2102 EXPECT_TRUE(matches("class X { X &operator=(X &&); };",
2103 cxxMethodDecl(isMoveAssignmentOperator())));
2104 EXPECT_TRUE(matches("class X { X &operator=(const X &&); };",
2105 cxxMethodDecl(isMoveAssignmentOperator())));
2106 EXPECT_TRUE(matches("class X { X &operator=(volatile X &&); };",
2107 cxxMethodDecl(isMoveAssignmentOperator())));
2108 EXPECT_TRUE(matches("class X { X &operator=(const volatile X &&); };",
2109 cxxMethodDecl(isMoveAssignmentOperator())));
2110 EXPECT_TRUE(notMatches("class X { X &operator=(X &); };",
2111 cxxMethodDecl(isMoveAssignmentOperator())));
2112}
2113
Edwin Vanefc4f7dc2013-05-09 17:00:17 +00002114TEST(Matcher, MatchesConstMethod) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002115 EXPECT_TRUE(
2116 matches("struct A { void foo() const; };", cxxMethodDecl(isConst())));
2117 EXPECT_TRUE(
2118 notMatches("struct A { void foo(); };", cxxMethodDecl(isConst())));
Edwin Vanefc4f7dc2013-05-09 17:00:17 +00002119}
2120
Edwin Vane37ee1d72013-04-09 20:46:36 +00002121TEST(Matcher, MatchesOverridingMethod) {
2122 EXPECT_TRUE(matches("class X { virtual int f(); }; "
2123 "class Y : public X { int f(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002124 cxxMethodDecl(isOverride(), hasName("::Y::f"))));
Edwin Vane37ee1d72013-04-09 20:46:36 +00002125 EXPECT_TRUE(notMatches("class X { virtual int f(); }; "
Aaron Ballman512fb642015-09-17 13:30:52 +00002126 "class Y : public X { int f(); };",
2127 cxxMethodDecl(isOverride(), hasName("::X::f"))));
Edwin Vane37ee1d72013-04-09 20:46:36 +00002128 EXPECT_TRUE(notMatches("class X { int f(); }; "
2129 "class Y : public X { int f(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002130 cxxMethodDecl(isOverride())));
Edwin Vane37ee1d72013-04-09 20:46:36 +00002131 EXPECT_TRUE(notMatches("class X { int f(); int f(int); }; ",
Aaron Ballman512fb642015-09-17 13:30:52 +00002132 cxxMethodDecl(isOverride())));
Samuel Benzaquenbb5093f2015-03-06 16:24:47 +00002133 EXPECT_TRUE(
2134 matches("template <typename Base> struct Y : Base { void f() override;};",
Aaron Ballman512fb642015-09-17 13:30:52 +00002135 cxxMethodDecl(isOverride(), hasName("::Y::f"))));
Edwin Vane37ee1d72013-04-09 20:46:36 +00002136}
2137
Manuel Klimek04616e42012-07-06 05:48:52 +00002138TEST(Matcher, ConstructorCall) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002139 StatementMatcher Constructor = cxxConstructExpr();
Manuel Klimek04616e42012-07-06 05:48:52 +00002140
2141 EXPECT_TRUE(
2142 matches("class X { public: X(); }; void x() { X x; }", Constructor));
2143 EXPECT_TRUE(
2144 matches("class X { public: X(); }; void x() { X x = X(); }",
2145 Constructor));
2146 EXPECT_TRUE(
2147 matches("class X { public: X(int); }; void x() { X x = 0; }",
2148 Constructor));
2149 EXPECT_TRUE(matches("class X {}; void x(int) { X x; }", Constructor));
2150}
2151
2152TEST(Matcher, ConstructorArgument) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002153 StatementMatcher Constructor = cxxConstructExpr(
Daniel Jasper848cbe12012-09-18 13:09:13 +00002154 hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002155
2156 EXPECT_TRUE(
2157 matches("class X { public: X(int); }; void x() { int y; X x(y); }",
2158 Constructor));
2159 EXPECT_TRUE(
2160 matches("class X { public: X(int); }; void x() { int y; X x = X(y); }",
2161 Constructor));
2162 EXPECT_TRUE(
2163 matches("class X { public: X(int); }; void x() { int y; X x = y; }",
2164 Constructor));
2165 EXPECT_TRUE(
2166 notMatches("class X { public: X(int); }; void x() { int z; X x(z); }",
2167 Constructor));
2168
Aaron Ballman512fb642015-09-17 13:30:52 +00002169 StatementMatcher WrongIndex = cxxConstructExpr(
Daniel Jasper848cbe12012-09-18 13:09:13 +00002170 hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002171 EXPECT_TRUE(
2172 notMatches("class X { public: X(int); }; void x() { int y; X x(y); }",
2173 WrongIndex));
2174}
2175
2176TEST(Matcher, ConstructorArgumentCount) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002177 StatementMatcher Constructor1Arg = cxxConstructExpr(argumentCountIs(1));
Manuel Klimek04616e42012-07-06 05:48:52 +00002178
2179 EXPECT_TRUE(
2180 matches("class X { public: X(int); }; void x() { X x(0); }",
2181 Constructor1Arg));
2182 EXPECT_TRUE(
2183 matches("class X { public: X(int); }; void x() { X x = X(0); }",
2184 Constructor1Arg));
2185 EXPECT_TRUE(
2186 matches("class X { public: X(int); }; void x() { X x = 0; }",
2187 Constructor1Arg));
2188 EXPECT_TRUE(
2189 notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }",
2190 Constructor1Arg));
2191}
2192
Peter Collingbourne1fec3df2014-02-06 21:52:24 +00002193TEST(Matcher, ConstructorListInitialization) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002194 StatementMatcher ConstructorListInit =
2195 cxxConstructExpr(isListInitialization());
Peter Collingbourne1fec3df2014-02-06 21:52:24 +00002196
2197 EXPECT_TRUE(
2198 matches("class X { public: X(int); }; void x() { X x{0}; }",
2199 ConstructorListInit));
2200 EXPECT_FALSE(
2201 matches("class X { public: X(int); }; void x() { X x(0); }",
2202 ConstructorListInit));
2203}
2204
Manuel Klimek7fca93b2012-10-23 10:40:50 +00002205TEST(Matcher,ThisExpr) {
2206 EXPECT_TRUE(
Aaron Ballman512fb642015-09-17 13:30:52 +00002207 matches("struct X { int a; int f () { return a; } };", cxxThisExpr()));
Manuel Klimek7fca93b2012-10-23 10:40:50 +00002208 EXPECT_TRUE(
Aaron Ballman512fb642015-09-17 13:30:52 +00002209 notMatches("struct X { int f () { int a; return a; } };", cxxThisExpr()));
Manuel Klimek7fca93b2012-10-23 10:40:50 +00002210}
2211
Manuel Klimek04616e42012-07-06 05:48:52 +00002212TEST(Matcher, BindTemporaryExpression) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002213 StatementMatcher TempExpression = cxxBindTemporaryExpr();
Manuel Klimek04616e42012-07-06 05:48:52 +00002214
2215 std::string ClassString = "class string { public: string(); ~string(); }; ";
2216
2217 EXPECT_TRUE(
2218 matches(ClassString +
2219 "string GetStringByValue();"
2220 "void FunctionTakesString(string s);"
2221 "void run() { FunctionTakesString(GetStringByValue()); }",
2222 TempExpression));
2223
2224 EXPECT_TRUE(
2225 notMatches(ClassString +
2226 "string* GetStringPointer(); "
2227 "void FunctionTakesStringPtr(string* s);"
2228 "void run() {"
2229 " string* s = GetStringPointer();"
2230 " FunctionTakesStringPtr(GetStringPointer());"
2231 " FunctionTakesStringPtr(s);"
2232 "}",
2233 TempExpression));
2234
2235 EXPECT_TRUE(
2236 notMatches("class no_dtor {};"
2237 "no_dtor GetObjByValue();"
2238 "void ConsumeObj(no_dtor param);"
2239 "void run() { ConsumeObj(GetObjByValue()); }",
2240 TempExpression));
2241}
2242
Sam Panzer68a35af2012-08-24 22:04:44 +00002243TEST(MaterializeTemporaryExpr, MatchesTemporary) {
2244 std::string ClassString =
2245 "class string { public: string(); int length(); }; ";
2246
2247 EXPECT_TRUE(
2248 matches(ClassString +
2249 "string GetStringByValue();"
2250 "void FunctionTakesString(string s);"
2251 "void run() { FunctionTakesString(GetStringByValue()); }",
2252 materializeTemporaryExpr()));
2253
2254 EXPECT_TRUE(
2255 notMatches(ClassString +
2256 "string* GetStringPointer(); "
2257 "void FunctionTakesStringPtr(string* s);"
2258 "void run() {"
2259 " string* s = GetStringPointer();"
2260 " FunctionTakesStringPtr(GetStringPointer());"
2261 " FunctionTakesStringPtr(s);"
2262 "}",
2263 materializeTemporaryExpr()));
2264
2265 EXPECT_TRUE(
2266 notMatches(ClassString +
2267 "string GetStringByValue();"
2268 "void run() { int k = GetStringByValue().length(); }",
2269 materializeTemporaryExpr()));
2270
2271 EXPECT_TRUE(
2272 notMatches(ClassString +
2273 "string GetStringByValue();"
2274 "void run() { GetStringByValue(); }",
2275 materializeTemporaryExpr()));
2276}
2277
Manuel Klimek04616e42012-07-06 05:48:52 +00002278TEST(ConstructorDeclaration, SimpleCase) {
2279 EXPECT_TRUE(matches("class Foo { Foo(int i); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002280 cxxConstructorDecl(ofClass(hasName("Foo")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002281 EXPECT_TRUE(notMatches("class Foo { Foo(int i); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002282 cxxConstructorDecl(ofClass(hasName("Bar")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002283}
2284
2285TEST(ConstructorDeclaration, IsImplicit) {
2286 // This one doesn't match because the constructor is not added by the
2287 // compiler (it is not needed).
2288 EXPECT_TRUE(notMatches("class Foo { };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002289 cxxConstructorDecl(isImplicit())));
Manuel Klimek04616e42012-07-06 05:48:52 +00002290 // The compiler added the implicit default constructor.
2291 EXPECT_TRUE(matches("class Foo { }; Foo* f = new Foo();",
Aaron Ballman512fb642015-09-17 13:30:52 +00002292 cxxConstructorDecl(isImplicit())));
Manuel Klimek04616e42012-07-06 05:48:52 +00002293 EXPECT_TRUE(matches("class Foo { Foo(){} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002294 cxxConstructorDecl(unless(isImplicit()))));
Joey Gouly0d9a2b22014-05-16 19:31:08 +00002295 // The compiler added an implicit assignment operator.
2296 EXPECT_TRUE(matches("struct A { int x; } a = {0}, b = a; void f() { a = b; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00002297 cxxMethodDecl(isImplicit(), hasName("operator="))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002298}
2299
Aaron Ballman6f6d0b62015-08-11 21:09:52 +00002300TEST(ConstructorDeclaration, IsExplicit) {
2301 EXPECT_TRUE(matches("struct S { explicit S(int); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002302 cxxConstructorDecl(isExplicit())));
Aaron Ballman6f6d0b62015-08-11 21:09:52 +00002303 EXPECT_TRUE(notMatches("struct S { S(int); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002304 cxxConstructorDecl(isExplicit())));
Aaron Ballman6f6d0b62015-08-11 21:09:52 +00002305}
2306
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002307TEST(ConstructorDeclaration, Kinds) {
2308 EXPECT_TRUE(matches("struct S { S(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002309 cxxConstructorDecl(isDefaultConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002310 EXPECT_TRUE(notMatches("struct S { S(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002311 cxxConstructorDecl(isCopyConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002312 EXPECT_TRUE(notMatches("struct S { S(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002313 cxxConstructorDecl(isMoveConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002314
2315 EXPECT_TRUE(notMatches("struct S { S(const S&); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002316 cxxConstructorDecl(isDefaultConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002317 EXPECT_TRUE(matches("struct S { S(const S&); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002318 cxxConstructorDecl(isCopyConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002319 EXPECT_TRUE(notMatches("struct S { S(const S&); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002320 cxxConstructorDecl(isMoveConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002321
2322 EXPECT_TRUE(notMatches("struct S { S(S&&); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002323 cxxConstructorDecl(isDefaultConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002324 EXPECT_TRUE(notMatches("struct S { S(S&&); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002325 cxxConstructorDecl(isCopyConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002326 EXPECT_TRUE(matches("struct S { S(S&&); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002327 cxxConstructorDecl(isMoveConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002328}
2329
Daniel Jasper1dad1832012-07-10 20:20:19 +00002330TEST(DestructorDeclaration, MatchesVirtualDestructor) {
2331 EXPECT_TRUE(matches("class Foo { virtual ~Foo(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002332 cxxDestructorDecl(ofClass(hasName("Foo")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00002333}
2334
2335TEST(DestructorDeclaration, DoesNotMatchImplicitDestructor) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002336 EXPECT_TRUE(notMatches("class Foo {};",
Aaron Ballman512fb642015-09-17 13:30:52 +00002337 cxxDestructorDecl(ofClass(hasName("Foo")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00002338}
2339
Manuel Klimek04616e42012-07-06 05:48:52 +00002340TEST(HasAnyConstructorInitializer, SimpleCase) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002341 EXPECT_TRUE(
2342 notMatches("class Foo { Foo() { } };",
2343 cxxConstructorDecl(hasAnyConstructorInitializer(anything()))));
2344 EXPECT_TRUE(
2345 matches("class Foo {"
2346 " Foo() : foo_() { }"
2347 " int foo_;"
2348 "};",
2349 cxxConstructorDecl(hasAnyConstructorInitializer(anything()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002350}
2351
2352TEST(HasAnyConstructorInitializer, ForField) {
2353 static const char Code[] =
2354 "class Baz { };"
2355 "class Foo {"
2356 " Foo() : foo_() { }"
2357 " Baz foo_;"
2358 " Baz bar_;"
2359 "};";
Aaron Ballman512fb642015-09-17 13:30:52 +00002360 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002361 forField(hasType(recordDecl(hasName("Baz"))))))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002362 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00002363 forField(hasName("foo_"))))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002364 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002365 forField(hasType(recordDecl(hasName("Bar"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002366}
2367
2368TEST(HasAnyConstructorInitializer, WithInitializer) {
2369 static const char Code[] =
2370 "class Foo {"
2371 " Foo() : foo_(0) { }"
2372 " int foo_;"
2373 "};";
Aaron Ballman512fb642015-09-17 13:30:52 +00002374 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00002375 withInitializer(integerLiteral(equals(0)))))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002376 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00002377 withInitializer(integerLiteral(equals(1)))))));
2378}
2379
2380TEST(HasAnyConstructorInitializer, IsWritten) {
2381 static const char Code[] =
2382 "struct Bar { Bar(){} };"
2383 "class Foo {"
2384 " Foo() : foo_() { }"
2385 " Bar foo_;"
2386 " Bar bar_;"
2387 "};";
Aaron Ballman512fb642015-09-17 13:30:52 +00002388 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00002389 allOf(forField(hasName("foo_")), isWritten())))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002390 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00002391 allOf(forField(hasName("bar_")), isWritten())))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002392 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00002393 allOf(forField(hasName("bar_")), unless(isWritten()))))));
2394}
2395
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002396TEST(HasAnyConstructorInitializer, IsBaseInitializer) {
2397 static const char Code[] =
2398 "struct B {};"
2399 "struct D : B {"
2400 " int I;"
2401 " D(int i) : I(i) {}"
2402 "};"
2403 "struct E : B {"
2404 " E() : B() {}"
2405 "};";
Aaron Ballman512fb642015-09-17 13:30:52 +00002406 EXPECT_TRUE(matches(Code, cxxConstructorDecl(allOf(
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002407 hasAnyConstructorInitializer(allOf(isBaseInitializer(), isWritten())),
2408 hasName("E")))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002409 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(allOf(
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002410 hasAnyConstructorInitializer(allOf(isBaseInitializer(), isWritten())),
2411 hasName("D")))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002412 EXPECT_TRUE(matches(Code, cxxConstructorDecl(allOf(
Aaron Ballmaned455d42015-08-11 20:42:00 +00002413 hasAnyConstructorInitializer(allOf(isMemberInitializer(), isWritten())),
2414 hasName("D")))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002415 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(allOf(
Aaron Ballmaned455d42015-08-11 20:42:00 +00002416 hasAnyConstructorInitializer(allOf(isMemberInitializer(), isWritten())),
2417 hasName("E")))));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002418}
2419
Manuel Klimek04616e42012-07-06 05:48:52 +00002420TEST(Matcher, NewExpression) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002421 StatementMatcher New = cxxNewExpr();
Manuel Klimek04616e42012-07-06 05:48:52 +00002422
2423 EXPECT_TRUE(matches("class X { public: X(); }; void x() { new X; }", New));
2424 EXPECT_TRUE(
2425 matches("class X { public: X(); }; void x() { new X(); }", New));
2426 EXPECT_TRUE(
2427 matches("class X { public: X(int); }; void x() { new X(0); }", New));
2428 EXPECT_TRUE(matches("class X {}; void x(int) { new X; }", New));
2429}
2430
2431TEST(Matcher, NewExpressionArgument) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002432 StatementMatcher New = cxxConstructExpr(
Daniel Jasper848cbe12012-09-18 13:09:13 +00002433 hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002434
2435 EXPECT_TRUE(
2436 matches("class X { public: X(int); }; void x() { int y; new X(y); }",
2437 New));
2438 EXPECT_TRUE(
2439 matches("class X { public: X(int); }; void x() { int y; new X(y); }",
2440 New));
2441 EXPECT_TRUE(
2442 notMatches("class X { public: X(int); }; void x() { int z; new X(z); }",
2443 New));
2444
Aaron Ballman512fb642015-09-17 13:30:52 +00002445 StatementMatcher WrongIndex = cxxConstructExpr(
Daniel Jasper848cbe12012-09-18 13:09:13 +00002446 hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002447 EXPECT_TRUE(
2448 notMatches("class X { public: X(int); }; void x() { int y; new X(y); }",
2449 WrongIndex));
2450}
2451
2452TEST(Matcher, NewExpressionArgumentCount) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002453 StatementMatcher New = cxxConstructExpr(argumentCountIs(1));
Manuel Klimek04616e42012-07-06 05:48:52 +00002454
2455 EXPECT_TRUE(
2456 matches("class X { public: X(int); }; void x() { new X(0); }", New));
2457 EXPECT_TRUE(
2458 notMatches("class X { public: X(int, int); }; void x() { new X(0, 0); }",
2459 New));
2460}
2461
Daniel Jasper1dad1832012-07-10 20:20:19 +00002462TEST(Matcher, DeleteExpression) {
2463 EXPECT_TRUE(matches("struct A {}; void f(A* a) { delete a; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00002464 cxxDeleteExpr()));
Daniel Jasper1dad1832012-07-10 20:20:19 +00002465}
2466
Manuel Klimek04616e42012-07-06 05:48:52 +00002467TEST(Matcher, DefaultArgument) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002468 StatementMatcher Arg = cxxDefaultArgExpr();
Manuel Klimek04616e42012-07-06 05:48:52 +00002469
2470 EXPECT_TRUE(matches("void x(int, int = 0) { int y; x(y); }", Arg));
2471 EXPECT_TRUE(
2472 matches("class X { void x(int, int = 0) { int y; x(y); } };", Arg));
2473 EXPECT_TRUE(notMatches("void x(int, int = 0) { int y; x(y, 0); }", Arg));
2474}
2475
2476TEST(Matcher, StringLiterals) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00002477 StatementMatcher Literal = stringLiteral();
Manuel Klimek04616e42012-07-06 05:48:52 +00002478 EXPECT_TRUE(matches("const char *s = \"string\";", Literal));
2479 // wide string
2480 EXPECT_TRUE(matches("const wchar_t *s = L\"string\";", Literal));
2481 // with escaped characters
2482 EXPECT_TRUE(matches("const char *s = \"\x05five\";", Literal));
2483 // no matching -- though the data type is the same, there is no string literal
2484 EXPECT_TRUE(notMatches("const char s[1] = {'a'};", Literal));
2485}
2486
2487TEST(Matcher, CharacterLiterals) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00002488 StatementMatcher CharLiteral = characterLiteral();
Manuel Klimek04616e42012-07-06 05:48:52 +00002489 EXPECT_TRUE(matches("const char c = 'c';", CharLiteral));
2490 // wide character
2491 EXPECT_TRUE(matches("const char c = L'c';", CharLiteral));
2492 // wide character, Hex encoded, NOT MATCHED!
2493 EXPECT_TRUE(notMatches("const wchar_t c = 0x2126;", CharLiteral));
2494 EXPECT_TRUE(notMatches("const char c = 0x1;", CharLiteral));
2495}
2496
2497TEST(Matcher, IntegerLiterals) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00002498 StatementMatcher HasIntLiteral = integerLiteral();
Manuel Klimek04616e42012-07-06 05:48:52 +00002499 EXPECT_TRUE(matches("int i = 10;", HasIntLiteral));
2500 EXPECT_TRUE(matches("int i = 0x1AB;", HasIntLiteral));
2501 EXPECT_TRUE(matches("int i = 10L;", HasIntLiteral));
2502 EXPECT_TRUE(matches("int i = 10U;", HasIntLiteral));
2503
2504 // Non-matching cases (character literals, float and double)
2505 EXPECT_TRUE(notMatches("int i = L'a';",
2506 HasIntLiteral)); // this is actually a character
2507 // literal cast to int
2508 EXPECT_TRUE(notMatches("int i = 'a';", HasIntLiteral));
2509 EXPECT_TRUE(notMatches("int i = 1e10;", HasIntLiteral));
2510 EXPECT_TRUE(notMatches("int i = 10.0;", HasIntLiteral));
2511}
2512
Daniel Jasper91f1c8c2013-07-26 18:52:58 +00002513TEST(Matcher, FloatLiterals) {
2514 StatementMatcher HasFloatLiteral = floatLiteral();
2515 EXPECT_TRUE(matches("float i = 10.0;", HasFloatLiteral));
2516 EXPECT_TRUE(matches("float i = 10.0f;", HasFloatLiteral));
2517 EXPECT_TRUE(matches("double i = 10.0;", HasFloatLiteral));
2518 EXPECT_TRUE(matches("double i = 10.0L;", HasFloatLiteral));
2519 EXPECT_TRUE(matches("double i = 1e10;", HasFloatLiteral));
Daniel Jasperd1423812015-02-03 09:45:52 +00002520 EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0))));
2521 EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0f))));
2522 EXPECT_TRUE(
2523 matches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(5.0)))));
Daniel Jasper91f1c8c2013-07-26 18:52:58 +00002524
2525 EXPECT_TRUE(notMatches("float i = 10;", HasFloatLiteral));
Daniel Jasperd1423812015-02-03 09:45:52 +00002526 EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0))));
2527 EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0f))));
2528 EXPECT_TRUE(
2529 notMatches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(6.0)))));
Daniel Jasper91f1c8c2013-07-26 18:52:58 +00002530}
2531
Daniel Jasper5901e472012-10-01 13:40:41 +00002532TEST(Matcher, NullPtrLiteral) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002533 EXPECT_TRUE(matches("int* i = nullptr;", cxxNullPtrLiteralExpr()));
Daniel Jasper5901e472012-10-01 13:40:41 +00002534}
2535
Szabolcs Sipos1d068bb2015-05-07 14:24:22 +00002536TEST(Matcher, GNUNullExpr) {
2537 EXPECT_TRUE(matches("int* i = __null;", gnuNullExpr()));
2538}
2539
Aaron Ballmana35b8fc2016-03-09 17:11:51 +00002540TEST(Matcher, AtomicExpr) {
2541 EXPECT_TRUE(matches("void foo() { int *ptr; __atomic_load_n(ptr, 1); }",
2542 atomicExpr()));
2543}
2544
2545TEST(Matcher, Initializers) {
2546 const char *ToMatch = "void foo() { struct point { double x; double y; };"
2547 " struct point ptarray[10] = "
2548 " { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 }; }";
2549 EXPECT_TRUE(matchesConditionally(
2550 ToMatch,
2551 initListExpr(
2552 has(
2553 cxxConstructExpr(
2554 requiresZeroInitialization())),
2555 has(
2556 initListExpr(
2557 hasType(asString("struct point")),
2558 has(floatLiteral(equals(1.0))),
2559 has(implicitValueInitExpr(
2560 hasType(asString("double")))))),
2561 has(
2562 initListExpr(
2563 hasType(asString("struct point")),
2564 has(floatLiteral(equals(2.0))),
2565 has(floatLiteral(equals(1.0)))))
2566 ), true, "-std=gnu++98"));
2567
2568 EXPECT_TRUE(matchesC99(ToMatch,
2569 initListExpr(
2570 hasSyntacticForm(
2571 initListExpr(
2572 has(
2573 designatedInitExpr(
2574 designatorCountIs(2),
2575 has(floatLiteral(
2576 equals(1.0))),
2577 has(integerLiteral(
2578 equals(2))))),
2579 has(
2580 designatedInitExpr(
2581 designatorCountIs(2),
2582 has(floatLiteral(
2583 equals(2.0))),
2584 has(integerLiteral(
2585 equals(2))))),
2586 has(
2587 designatedInitExpr(
2588 designatorCountIs(2),
2589 has(floatLiteral(
2590 equals(1.0))),
2591 has(integerLiteral(
2592 equals(0)))))
2593 )))));
2594}
2595
2596TEST(Matcher, ParenListExpr) {
2597 EXPECT_TRUE(
Aaron Ballman2648d422016-03-09 18:07:17 +00002598 matches("template<typename T> class foo { void bar() { foo X(*this); } };"
2599 "template class foo<int>;",
2600 varDecl(hasInitializer(parenListExpr(has(unaryOperator()))))));
Aaron Ballmana35b8fc2016-03-09 17:11:51 +00002601}
2602
2603TEST(Matcher, StmtExpr) {
2604 EXPECT_TRUE(matches("void declToImport() { int C = ({int X=4; X;}); }",
2605 varDecl(hasInitializer(stmtExpr()))));
2606}
2607
2608TEST(Matcher, ImportPredefinedExpr) {
2609 // __func__ expands as StringLiteral("foo")
2610 EXPECT_TRUE(matches("void foo() { __func__; }",
2611 predefinedExpr(
2612 hasType(asString("const char [4]")),
2613 has(stringLiteral()))));
2614}
2615
Daniel Jasper87c3d362012-09-20 14:12:57 +00002616TEST(Matcher, AsmStatement) {
2617 EXPECT_TRUE(matches("void foo() { __asm(\"mov al, 2\"); }", asmStmt()));
2618}
2619
Manuel Klimek04616e42012-07-06 05:48:52 +00002620TEST(Matcher, Conditions) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002621 StatementMatcher Condition =
2622 ifStmt(hasCondition(cxxBoolLiteral(equals(true))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002623
2624 EXPECT_TRUE(matches("void x() { if (true) {} }", Condition));
2625 EXPECT_TRUE(notMatches("void x() { if (false) {} }", Condition));
2626 EXPECT_TRUE(notMatches("void x() { bool a = true; if (a) {} }", Condition));
2627 EXPECT_TRUE(notMatches("void x() { if (true || false) {} }", Condition));
2628 EXPECT_TRUE(notMatches("void x() { if (1) {} }", Condition));
2629}
2630
Manuel Klimek909b5c942014-05-27 10:04:12 +00002631TEST(IfStmt, ChildTraversalMatchers) {
2632 EXPECT_TRUE(matches("void f() { if (false) true; else false; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00002633 ifStmt(hasThen(cxxBoolLiteral(equals(true))))));
Manuel Klimek909b5c942014-05-27 10:04:12 +00002634 EXPECT_TRUE(notMatches("void f() { if (false) false; else true; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00002635 ifStmt(hasThen(cxxBoolLiteral(equals(true))))));
Manuel Klimek909b5c942014-05-27 10:04:12 +00002636 EXPECT_TRUE(matches("void f() { if (false) false; else true; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00002637 ifStmt(hasElse(cxxBoolLiteral(equals(true))))));
Manuel Klimek909b5c942014-05-27 10:04:12 +00002638 EXPECT_TRUE(notMatches("void f() { if (false) true; else false; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00002639 ifStmt(hasElse(cxxBoolLiteral(equals(true))))));
Manuel Klimek909b5c942014-05-27 10:04:12 +00002640}
2641
Manuel Klimek04616e42012-07-06 05:48:52 +00002642TEST(MatchBinaryOperator, HasOperatorName) {
2643 StatementMatcher OperatorOr = binaryOperator(hasOperatorName("||"));
2644
2645 EXPECT_TRUE(matches("void x() { true || false; }", OperatorOr));
2646 EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
2647}
2648
2649TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
2650 StatementMatcher OperatorTrueFalse =
Aaron Ballman512fb642015-09-17 13:30:52 +00002651 binaryOperator(hasLHS(cxxBoolLiteral(equals(true))),
2652 hasRHS(cxxBoolLiteral(equals(false))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002653
2654 EXPECT_TRUE(matches("void x() { true || false; }", OperatorTrueFalse));
2655 EXPECT_TRUE(matches("void x() { true && false; }", OperatorTrueFalse));
2656 EXPECT_TRUE(notMatches("void x() { false || true; }", OperatorTrueFalse));
Alexander Kornienkoe39993e2015-11-02 22:23:21 +00002657
2658 StatementMatcher OperatorIntPointer = arraySubscriptExpr(
2659 hasLHS(hasType(isInteger())), hasRHS(hasType(pointsTo(qualType()))));
2660 EXPECT_TRUE(matches("void x() { 1[\"abc\"]; }", OperatorIntPointer));
2661 EXPECT_TRUE(notMatches("void x() { \"abc\"[1]; }", OperatorIntPointer));
Manuel Klimek04616e42012-07-06 05:48:52 +00002662}
2663
2664TEST(MatchBinaryOperator, HasEitherOperand) {
2665 StatementMatcher HasOperand =
Aaron Ballman512fb642015-09-17 13:30:52 +00002666 binaryOperator(hasEitherOperand(cxxBoolLiteral(equals(false))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002667
2668 EXPECT_TRUE(matches("void x() { true || false; }", HasOperand));
2669 EXPECT_TRUE(matches("void x() { false && true; }", HasOperand));
2670 EXPECT_TRUE(notMatches("void x() { true || true; }", HasOperand));
2671}
2672
2673TEST(Matcher, BinaryOperatorTypes) {
2674 // Integration test that verifies the AST provides all binary operators in
2675 // a way we expect.
2676 // FIXME: Operator ','
2677 EXPECT_TRUE(
2678 matches("void x() { 3, 4; }", binaryOperator(hasOperatorName(","))));
2679 EXPECT_TRUE(
2680 matches("bool b; bool c = (b = true);",
2681 binaryOperator(hasOperatorName("="))));
2682 EXPECT_TRUE(
2683 matches("bool b = 1 != 2;", binaryOperator(hasOperatorName("!="))));
2684 EXPECT_TRUE(
2685 matches("bool b = 1 == 2;", binaryOperator(hasOperatorName("=="))));
2686 EXPECT_TRUE(matches("bool b = 1 < 2;", binaryOperator(hasOperatorName("<"))));
2687 EXPECT_TRUE(
2688 matches("bool b = 1 <= 2;", binaryOperator(hasOperatorName("<="))));
2689 EXPECT_TRUE(
2690 matches("int i = 1 << 2;", binaryOperator(hasOperatorName("<<"))));
2691 EXPECT_TRUE(
2692 matches("int i = 1; int j = (i <<= 2);",
2693 binaryOperator(hasOperatorName("<<="))));
2694 EXPECT_TRUE(matches("bool b = 1 > 2;", binaryOperator(hasOperatorName(">"))));
2695 EXPECT_TRUE(
2696 matches("bool b = 1 >= 2;", binaryOperator(hasOperatorName(">="))));
2697 EXPECT_TRUE(
2698 matches("int i = 1 >> 2;", binaryOperator(hasOperatorName(">>"))));
2699 EXPECT_TRUE(
2700 matches("int i = 1; int j = (i >>= 2);",
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("int i = 42 % 23;", binaryOperator(hasOperatorName("%"))));
2709 EXPECT_TRUE(
2710 matches("int i = 42; int j = (i %= 42);",
2711 binaryOperator(hasOperatorName("%="))));
2712 EXPECT_TRUE(
2713 matches("bool b = 42 &23;", binaryOperator(hasOperatorName("&"))));
2714 EXPECT_TRUE(
2715 matches("bool b = true && false;",
2716 binaryOperator(hasOperatorName("&&"))));
2717 EXPECT_TRUE(
2718 matches("bool b = true; bool c = (b &= false);",
2719 binaryOperator(hasOperatorName("&="))));
2720 EXPECT_TRUE(
2721 matches("bool b = 42 | 23;", binaryOperator(hasOperatorName("|"))));
2722 EXPECT_TRUE(
2723 matches("bool b = true || false;",
2724 binaryOperator(hasOperatorName("||"))));
2725 EXPECT_TRUE(
2726 matches("bool b = true; bool c = (b |= false);",
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("int i = 42 - 23;", binaryOperator(hasOperatorName("-"))));
2745 EXPECT_TRUE(
2746 matches("int i = 42; int j = (i -= 23);",
2747 binaryOperator(hasOperatorName("-="))));
2748 EXPECT_TRUE(
2749 matches("struct A { void x() { void (A::*a)(); (this->*a)(); } };",
2750 binaryOperator(hasOperatorName("->*"))));
2751 EXPECT_TRUE(
2752 matches("struct A { void x() { void (A::*a)(); ((*this).*a)(); } };",
2753 binaryOperator(hasOperatorName(".*"))));
2754
2755 // Member expressions as operators are not supported in matches.
2756 EXPECT_TRUE(
2757 notMatches("struct A { void x(A *a) { a->x(this); } };",
2758 binaryOperator(hasOperatorName("->"))));
2759
2760 // Initializer assignments are not represented as operator equals.
2761 EXPECT_TRUE(
2762 notMatches("bool b = true;", binaryOperator(hasOperatorName("="))));
2763
2764 // Array indexing is not represented as operator.
2765 EXPECT_TRUE(notMatches("int a[42]; void x() { a[23]; }", unaryOperator()));
2766
2767 // Overloaded operators do not match at all.
2768 EXPECT_TRUE(notMatches(
2769 "struct A { bool operator&&(const A &a) const { return false; } };"
2770 "void x() { A a, b; a && b; }",
2771 binaryOperator()));
2772}
2773
2774TEST(MatchUnaryOperator, HasOperatorName) {
2775 StatementMatcher OperatorNot = unaryOperator(hasOperatorName("!"));
2776
2777 EXPECT_TRUE(matches("void x() { !true; } ", OperatorNot));
2778 EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
2779}
2780
2781TEST(MatchUnaryOperator, HasUnaryOperand) {
2782 StatementMatcher OperatorOnFalse =
Aaron Ballman512fb642015-09-17 13:30:52 +00002783 unaryOperator(hasUnaryOperand(cxxBoolLiteral(equals(false))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002784
2785 EXPECT_TRUE(matches("void x() { !false; }", OperatorOnFalse));
2786 EXPECT_TRUE(notMatches("void x() { !true; }", OperatorOnFalse));
2787}
2788
2789TEST(Matcher, UnaryOperatorTypes) {
2790 // Integration test that verifies the AST provides all unary operators in
2791 // a way we expect.
2792 EXPECT_TRUE(matches("bool b = !true;", unaryOperator(hasOperatorName("!"))));
2793 EXPECT_TRUE(
2794 matches("bool b; bool *p = &b;", unaryOperator(hasOperatorName("&"))));
2795 EXPECT_TRUE(matches("int i = ~ 1;", unaryOperator(hasOperatorName("~"))));
2796 EXPECT_TRUE(
2797 matches("bool *p; bool b = *p;", unaryOperator(hasOperatorName("*"))));
2798 EXPECT_TRUE(
2799 matches("int i; int j = +i;", unaryOperator(hasOperatorName("+"))));
2800 EXPECT_TRUE(
2801 matches("int i; int j = -i;", unaryOperator(hasOperatorName("-"))));
2802 EXPECT_TRUE(
2803 matches("int i; int j = ++i;", unaryOperator(hasOperatorName("++"))));
2804 EXPECT_TRUE(
2805 matches("int i; int j = i++;", unaryOperator(hasOperatorName("++"))));
2806 EXPECT_TRUE(
2807 matches("int i; int j = --i;", unaryOperator(hasOperatorName("--"))));
2808 EXPECT_TRUE(
2809 matches("int i; int j = i--;", unaryOperator(hasOperatorName("--"))));
2810
2811 // We don't match conversion operators.
2812 EXPECT_TRUE(notMatches("int i; double d = (double)i;", unaryOperator()));
2813
2814 // Function calls are not represented as operator.
2815 EXPECT_TRUE(notMatches("void f(); void x() { f(); }", unaryOperator()));
2816
2817 // Overloaded operators do not match at all.
2818 // FIXME: We probably want to add that.
2819 EXPECT_TRUE(notMatches(
2820 "struct A { bool operator!() const { return false; } };"
2821 "void x() { A a; !a; }", unaryOperator(hasOperatorName("!"))));
2822}
2823
2824TEST(Matcher, ConditionalOperator) {
2825 StatementMatcher Conditional = conditionalOperator(
Aaron Ballman512fb642015-09-17 13:30:52 +00002826 hasCondition(cxxBoolLiteral(equals(true))),
2827 hasTrueExpression(cxxBoolLiteral(equals(false))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002828
2829 EXPECT_TRUE(matches("void x() { true ? false : true; }", Conditional));
2830 EXPECT_TRUE(notMatches("void x() { false ? false : true; }", Conditional));
2831 EXPECT_TRUE(notMatches("void x() { true ? true : false; }", Conditional));
2832
2833 StatementMatcher ConditionalFalse = conditionalOperator(
Aaron Ballman512fb642015-09-17 13:30:52 +00002834 hasFalseExpression(cxxBoolLiteral(equals(false))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002835
2836 EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse));
2837 EXPECT_TRUE(
2838 notMatches("void x() { true ? false : true; }", ConditionalFalse));
Aaron Ballmana35b8fc2016-03-09 17:11:51 +00002839
2840 EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse));
2841 EXPECT_TRUE(
2842 notMatches("void x() { true ? false : true; }", ConditionalFalse));
2843}
2844
2845TEST(Matcher, BinaryConditionalOperator) {
2846 StatementMatcher AlwaysOne = binaryConditionalOperator(
2847 hasCondition(implicitCastExpr(
2848 has(
2849 opaqueValueExpr(
2850 hasSourceExpression((integerLiteral(equals(1)))))))),
2851 hasFalseExpression(integerLiteral(equals(0))));
2852
2853 EXPECT_TRUE(matches("void x() { 1 ?: 0; }", AlwaysOne));
2854
2855 StatementMatcher FourNotFive = binaryConditionalOperator(
2856 hasTrueExpression(opaqueValueExpr(
2857 hasSourceExpression((integerLiteral(equals(4)))))),
2858 hasFalseExpression(integerLiteral(equals(5))));
2859
2860 EXPECT_TRUE(matches("void x() { 4 ?: 5; }", FourNotFive));
Manuel Klimek04616e42012-07-06 05:48:52 +00002861}
2862
Daniel Jasper1dad1832012-07-10 20:20:19 +00002863TEST(ArraySubscriptMatchers, ArraySubscripts) {
2864 EXPECT_TRUE(matches("int i[2]; void f() { i[1] = 1; }",
2865 arraySubscriptExpr()));
2866 EXPECT_TRUE(notMatches("int i; void f() { i = 1; }",
2867 arraySubscriptExpr()));
2868}
2869
2870TEST(ArraySubscriptMatchers, ArrayIndex) {
2871 EXPECT_TRUE(matches(
2872 "int i[2]; void f() { i[1] = 1; }",
2873 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
2874 EXPECT_TRUE(matches(
2875 "int i[2]; void f() { 1[i] = 1; }",
2876 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
2877 EXPECT_TRUE(notMatches(
2878 "int i[2]; void f() { i[1] = 1; }",
2879 arraySubscriptExpr(hasIndex(integerLiteral(equals(0))))));
2880}
2881
2882TEST(ArraySubscriptMatchers, MatchesArrayBase) {
2883 EXPECT_TRUE(matches(
2884 "int i[2]; void f() { i[1] = 2; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002885 arraySubscriptExpr(hasBase(implicitCastExpr(
2886 hasSourceExpression(declRefExpr()))))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00002887}
2888
Manuel Klimek04616e42012-07-06 05:48:52 +00002889TEST(Matcher, HasNameSupportsNamespaces) {
2890 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002891 recordDecl(hasName("a::b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002892 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002893 recordDecl(hasName("::a::b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002894 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002895 recordDecl(hasName("b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002896 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002897 recordDecl(hasName("C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002898 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002899 recordDecl(hasName("c::b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002900 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002901 recordDecl(hasName("a::c::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002902 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002903 recordDecl(hasName("a::b::A"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002904 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002905 recordDecl(hasName("::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002906 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002907 recordDecl(hasName("::b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002908 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002909 recordDecl(hasName("z::a::b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002910 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002911 recordDecl(hasName("a+b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002912 EXPECT_TRUE(notMatches("namespace a { namespace b { class AC; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002913 recordDecl(hasName("C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002914}
2915
2916TEST(Matcher, HasNameSupportsOuterClasses) {
2917 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002918 matches("class A { class B { class C; }; };",
2919 recordDecl(hasName("A::B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002920 EXPECT_TRUE(
2921 matches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002922 recordDecl(hasName("::A::B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002923 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002924 matches("class A { class B { class C; }; };",
2925 recordDecl(hasName("B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002926 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002927 matches("class A { class B { class C; }; };",
2928 recordDecl(hasName("C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002929 EXPECT_TRUE(
2930 notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002931 recordDecl(hasName("c::B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002932 EXPECT_TRUE(
2933 notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002934 recordDecl(hasName("A::c::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002935 EXPECT_TRUE(
2936 notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002937 recordDecl(hasName("A::B::A"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002938 EXPECT_TRUE(
2939 notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002940 recordDecl(hasName("::C"))));
2941 EXPECT_TRUE(
2942 notMatches("class A { class B { class C; }; };",
2943 recordDecl(hasName("::B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002944 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002945 recordDecl(hasName("z::A::B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002946 EXPECT_TRUE(
2947 notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002948 recordDecl(hasName("A+B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002949}
2950
Samuel Benzaquen8e566f32016-02-05 18:29:24 +00002951TEST(Matcher, HasNameSupportsInlinedNamespaces) {
2952 std::string code = "namespace a { inline namespace b { class C; } }";
2953 EXPECT_TRUE(matches(code, recordDecl(hasName("a::b::C"))));
2954 EXPECT_TRUE(matches(code, recordDecl(hasName("a::C"))));
2955 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::b::C"))));
2956 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::C"))));
2957}
2958
2959TEST(Matcher, HasNameSupportsAnonymousNamespaces) {
2960 std::string code = "namespace a { namespace { class C; } }";
2961 EXPECT_TRUE(
2962 matches(code, recordDecl(hasName("a::(anonymous namespace)::C"))));
2963 EXPECT_TRUE(matches(code, recordDecl(hasName("a::C"))));
2964 EXPECT_TRUE(
2965 matches(code, recordDecl(hasName("::a::(anonymous namespace)::C"))));
2966 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::C"))));
2967}
2968
2969TEST(Matcher, HasNameSupportsAnonymousOuterClasses) {
2970 EXPECT_TRUE(matches("class A { class { class C; } x; };",
2971 recordDecl(hasName("A::(anonymous class)::C"))));
2972 EXPECT_TRUE(matches("class A { class { class C; } x; };",
2973 recordDecl(hasName("::A::(anonymous class)::C"))));
2974 EXPECT_FALSE(matches("class A { class { class C; } x; };",
2975 recordDecl(hasName("::A::C"))));
2976 EXPECT_TRUE(matches("class A { struct { class C; } x; };",
2977 recordDecl(hasName("A::(anonymous struct)::C"))));
2978 EXPECT_TRUE(matches("class A { struct { class C; } x; };",
2979 recordDecl(hasName("::A::(anonymous struct)::C"))));
2980 EXPECT_FALSE(matches("class A { struct { class C; } x; };",
2981 recordDecl(hasName("::A::C"))));
2982}
2983
2984TEST(Matcher, HasNameSupportsFunctionScope) {
2985 std::string code =
2986 "namespace a { void F(int a) { struct S { int m; }; int i; } }";
2987 EXPECT_TRUE(matches(code, varDecl(hasName("i"))));
2988 EXPECT_FALSE(matches(code, varDecl(hasName("F()::i"))));
2989
2990 EXPECT_TRUE(matches(code, fieldDecl(hasName("m"))));
2991 EXPECT_TRUE(matches(code, fieldDecl(hasName("S::m"))));
2992 EXPECT_TRUE(matches(code, fieldDecl(hasName("F(int)::S::m"))));
2993 EXPECT_TRUE(matches(code, fieldDecl(hasName("a::F(int)::S::m"))));
2994 EXPECT_TRUE(matches(code, fieldDecl(hasName("::a::F(int)::S::m"))));
2995}
2996
Samuel Benzaquen922bef42016-02-22 21:13:02 +00002997TEST(Matcher, HasAnyName) {
2998 const std::string Code = "namespace a { namespace b { class C; } }";
2999
3000 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX", "a::b::C"))));
3001 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("a::b::C", "XX"))));
3002 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX::C", "a::b::C"))));
3003 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX", "C"))));
3004
3005 EXPECT_TRUE(notMatches(Code, recordDecl(hasAnyName("::C", "::b::C"))));
3006 EXPECT_TRUE(
3007 matches(Code, recordDecl(hasAnyName("::C", "::b::C", "::a::b::C"))));
Samuel Benzaquenc1384c12016-03-25 16:29:30 +00003008
3009 std::vector<StringRef> Names = {"::C", "::b::C", "::a::b::C"};
3010 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName(Names))));
Samuel Benzaquen922bef42016-02-22 21:13:02 +00003011}
3012
Manuel Klimek04616e42012-07-06 05:48:52 +00003013TEST(Matcher, IsDefinition) {
3014 DeclarationMatcher DefinitionOfClassA =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003015 recordDecl(hasName("A"), isDefinition());
Manuel Klimek04616e42012-07-06 05:48:52 +00003016 EXPECT_TRUE(matches("class A {};", DefinitionOfClassA));
3017 EXPECT_TRUE(notMatches("class A;", DefinitionOfClassA));
3018
3019 DeclarationMatcher DefinitionOfVariableA =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003020 varDecl(hasName("a"), isDefinition());
Manuel Klimek04616e42012-07-06 05:48:52 +00003021 EXPECT_TRUE(matches("int a;", DefinitionOfVariableA));
3022 EXPECT_TRUE(notMatches("extern int a;", DefinitionOfVariableA));
3023
3024 DeclarationMatcher DefinitionOfMethodA =
Aaron Ballman512fb642015-09-17 13:30:52 +00003025 cxxMethodDecl(hasName("a"), isDefinition());
Manuel Klimek04616e42012-07-06 05:48:52 +00003026 EXPECT_TRUE(matches("class A { void a() {} };", DefinitionOfMethodA));
3027 EXPECT_TRUE(notMatches("class A { void a(); };", DefinitionOfMethodA));
3028}
3029
3030TEST(Matcher, OfClass) {
Aaron Ballman512fb642015-09-17 13:30:52 +00003031 StatementMatcher Constructor = cxxConstructExpr(hasDeclaration(cxxMethodDecl(
Manuel Klimek04616e42012-07-06 05:48:52 +00003032 ofClass(hasName("X")))));
3033
3034 EXPECT_TRUE(
3035 matches("class X { public: X(); }; void x(int) { X x; }", Constructor));
3036 EXPECT_TRUE(
3037 matches("class X { public: X(); }; void x(int) { X x = X(); }",
3038 Constructor));
3039 EXPECT_TRUE(
3040 notMatches("class Y { public: Y(); }; void x(int) { Y y; }",
3041 Constructor));
3042}
3043
3044TEST(Matcher, VisitsTemplateInstantiations) {
3045 EXPECT_TRUE(matches(
3046 "class A { public: void x(); };"
3047 "template <typename T> class B { public: void y() { T t; t.x(); } };"
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003048 "void f() { B<A> b; b.y(); }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003049 callExpr(callee(cxxMethodDecl(hasName("x"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003050
3051 EXPECT_TRUE(matches(
3052 "class A { public: void x(); };"
3053 "class C {"
3054 " public:"
3055 " template <typename T> class B { public: void y() { T t; t.x(); } };"
3056 "};"
3057 "void f() {"
3058 " C::B<A> b; b.y();"
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003059 "}",
Aaron Ballman512fb642015-09-17 13:30:52 +00003060 recordDecl(hasName("C"), hasDescendant(callExpr(
3061 callee(cxxMethodDecl(hasName("x"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003062}
3063
Daniel Jasper1dad1832012-07-10 20:20:19 +00003064TEST(Matcher, HandlesNullQualTypes) {
3065 // FIXME: Add a Type matcher so we can replace uses of this
3066 // variable with Type(True())
3067 const TypeMatcher AnyType = anything();
3068
3069 // We don't really care whether this matcher succeeds; we're testing that
3070 // it completes without crashing.
3071 EXPECT_TRUE(matches(
3072 "struct A { };"
3073 "template <typename T>"
3074 "void f(T t) {"
3075 " T local_t(t /* this becomes a null QualType in the AST */);"
3076 "}"
3077 "void g() {"
3078 " f(0);"
3079 "}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003080 expr(hasType(TypeMatcher(
Daniel Jasper1dad1832012-07-10 20:20:19 +00003081 anyOf(
3082 TypeMatcher(hasDeclaration(anything())),
3083 pointsTo(AnyType),
3084 references(AnyType)
3085 // Other QualType matchers should go here.
3086 ))))));
3087}
3088
Manuel Klimek04616e42012-07-06 05:48:52 +00003089// For testing AST_MATCHER_P().
Daniel Jasper1dad1832012-07-10 20:20:19 +00003090AST_MATCHER_P(Decl, just, internal::Matcher<Decl>, AMatcher) {
Manuel Klimek04616e42012-07-06 05:48:52 +00003091 // Make sure all special variables are used: node, match_finder,
3092 // bound_nodes_builder, and the parameter named 'AMatcher'.
3093 return AMatcher.matches(Node, Finder, Builder);
3094}
3095
3096TEST(AstMatcherPMacro, Works) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003097 DeclarationMatcher HasClassB = just(has(recordDecl(hasName("B")).bind("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003098
3099 EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003100 HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003101
3102 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003103 HasClassB, new VerifyIdIsBoundTo<Decl>("a")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003104
3105 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003106 HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003107}
3108
Benjamin Kramer57dd9bd2015-03-07 20:38:15 +00003109AST_POLYMORPHIC_MATCHER_P(polymorphicHas,
3110 AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt),
3111 internal::Matcher<Decl>, AMatcher) {
Manuel Klimek04616e42012-07-06 05:48:52 +00003112 return Finder->matchesChildOf(
Manuel Klimekeb958de2012-09-05 12:12:07 +00003113 Node, AMatcher, Builder,
Manuel Klimek04616e42012-07-06 05:48:52 +00003114 ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
3115 ASTMatchFinder::BK_First);
3116}
3117
3118TEST(AstPolymorphicMatcherPMacro, Works) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003119 DeclarationMatcher HasClassB =
3120 polymorphicHas(recordDecl(hasName("B")).bind("b"));
Manuel Klimek04616e42012-07-06 05:48:52 +00003121
3122 EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003123 HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003124
3125 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003126 HasClassB, new VerifyIdIsBoundTo<Decl>("a")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003127
3128 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003129 HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003130
3131 StatementMatcher StatementHasClassB =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003132 polymorphicHas(recordDecl(hasName("B")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003133
3134 EXPECT_TRUE(matches("void x() { class B {}; }", StatementHasClassB));
3135}
3136
3137TEST(For, FindsForLoops) {
3138 EXPECT_TRUE(matches("void f() { for(;;); }", forStmt()));
3139 EXPECT_TRUE(matches("void f() { if(true) for(;;); }", forStmt()));
Daniel Jasper6f595392012-10-01 15:05:34 +00003140 EXPECT_TRUE(notMatches("int as[] = { 1, 2, 3 };"
3141 "void f() { for (auto &a : as); }",
Daniel Jasper5901e472012-10-01 13:40:41 +00003142 forStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003143}
3144
Daniel Jasper4e566c42012-07-12 08:50:38 +00003145TEST(For, ForLoopInternals) {
3146 EXPECT_TRUE(matches("void f(){ int i; for (; i < 3 ; ); }",
3147 forStmt(hasCondition(anything()))));
3148 EXPECT_TRUE(matches("void f() { for (int i = 0; ;); }",
3149 forStmt(hasLoopInit(anything()))));
3150}
3151
Alexander Kornienko9b539e12014-02-05 16:35:08 +00003152TEST(For, ForRangeLoopInternals) {
3153 EXPECT_TRUE(matches("void f(){ int a[] {1, 2}; for (int i : a); }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003154 cxxForRangeStmt(hasLoopVariable(anything()))));
Manuel Klimek86510812014-05-23 17:49:03 +00003155 EXPECT_TRUE(matches(
3156 "void f(){ int a[] {1, 2}; for (int i : a); }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003157 cxxForRangeStmt(hasRangeInit(declRefExpr(to(varDecl(hasName("a"))))))));
Alexander Kornienko9b539e12014-02-05 16:35:08 +00003158}
3159
Daniel Jasper4e566c42012-07-12 08:50:38 +00003160TEST(For, NegativeForLoopInternals) {
3161 EXPECT_TRUE(notMatches("void f(){ for (int i = 0; ; ++i); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003162 forStmt(hasCondition(expr()))));
Daniel Jasper4e566c42012-07-12 08:50:38 +00003163 EXPECT_TRUE(notMatches("void f() {int i; for (; i < 4; ++i) {} }",
3164 forStmt(hasLoopInit(anything()))));
3165}
3166
Manuel Klimek04616e42012-07-06 05:48:52 +00003167TEST(For, ReportsNoFalsePositives) {
3168 EXPECT_TRUE(notMatches("void f() { ; }", forStmt()));
3169 EXPECT_TRUE(notMatches("void f() { if(true); }", forStmt()));
3170}
3171
3172TEST(CompoundStatement, HandlesSimpleCases) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003173 EXPECT_TRUE(notMatches("void f();", compoundStmt()));
3174 EXPECT_TRUE(matches("void f() {}", compoundStmt()));
3175 EXPECT_TRUE(matches("void f() {{}}", compoundStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003176}
3177
3178TEST(CompoundStatement, DoesNotMatchEmptyStruct) {
3179 // It's not a compound statement just because there's "{}" in the source
3180 // text. This is an AST search, not grep.
3181 EXPECT_TRUE(notMatches("namespace n { struct S {}; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003182 compoundStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003183 EXPECT_TRUE(matches("namespace n { struct S { void f() {{}} }; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003184 compoundStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003185}
3186
Daniel Jasper4e566c42012-07-12 08:50:38 +00003187TEST(HasBody, FindsBodyOfForWhileDoLoops) {
Manuel Klimek04616e42012-07-06 05:48:52 +00003188 EXPECT_TRUE(matches("void f() { for(;;) {} }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003189 forStmt(hasBody(compoundStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003190 EXPECT_TRUE(notMatches("void f() { for(;;); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003191 forStmt(hasBody(compoundStmt()))));
Daniel Jasper4e566c42012-07-12 08:50:38 +00003192 EXPECT_TRUE(matches("void f() { while(true) {} }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003193 whileStmt(hasBody(compoundStmt()))));
Daniel Jasper4e566c42012-07-12 08:50:38 +00003194 EXPECT_TRUE(matches("void f() { do {} while(true); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003195 doStmt(hasBody(compoundStmt()))));
Manuel Klimek2af0a912014-05-27 07:45:18 +00003196 EXPECT_TRUE(matches("void f() { int p[2]; for (auto x : p) {} }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003197 cxxForRangeStmt(hasBody(compoundStmt()))));
Aaron Ballman2b6963f2016-01-20 16:26:48 +00003198 EXPECT_TRUE(matches("void f() {}", functionDecl(hasBody(compoundStmt()))));
3199 EXPECT_TRUE(notMatches("void f();", functionDecl(hasBody(compoundStmt()))));
3200 EXPECT_TRUE(matches("void f(); void f() {}",
3201 functionDecl(hasBody(compoundStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003202}
3203
3204TEST(HasAnySubstatement, MatchesForTopLevelCompoundStatement) {
3205 // The simplest case: every compound statement is in a function
3206 // definition, and the function body itself must be a compound
3207 // statement.
3208 EXPECT_TRUE(matches("void f() { for (;;); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003209 compoundStmt(hasAnySubstatement(forStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003210}
3211
3212TEST(HasAnySubstatement, IsNotRecursive) {
3213 // It's really "has any immediate substatement".
3214 EXPECT_TRUE(notMatches("void f() { if (true) for (;;); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003215 compoundStmt(hasAnySubstatement(forStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003216}
3217
3218TEST(HasAnySubstatement, MatchesInNestedCompoundStatements) {
3219 EXPECT_TRUE(matches("void f() { if (true) { for (;;); } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003220 compoundStmt(hasAnySubstatement(forStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003221}
3222
3223TEST(HasAnySubstatement, FindsSubstatementBetweenOthers) {
3224 EXPECT_TRUE(matches("void f() { 1; 2; 3; for (;;); 4; 5; 6; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003225 compoundStmt(hasAnySubstatement(forStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003226}
3227
3228TEST(StatementCountIs, FindsNoStatementsInAnEmptyCompoundStatement) {
3229 EXPECT_TRUE(matches("void f() { }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003230 compoundStmt(statementCountIs(0))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003231 EXPECT_TRUE(notMatches("void f() {}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003232 compoundStmt(statementCountIs(1))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003233}
3234
3235TEST(StatementCountIs, AppearsToMatchOnlyOneCount) {
3236 EXPECT_TRUE(matches("void f() { 1; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003237 compoundStmt(statementCountIs(1))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003238 EXPECT_TRUE(notMatches("void f() { 1; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003239 compoundStmt(statementCountIs(0))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003240 EXPECT_TRUE(notMatches("void f() { 1; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003241 compoundStmt(statementCountIs(2))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003242}
3243
3244TEST(StatementCountIs, WorksWithMultipleStatements) {
3245 EXPECT_TRUE(matches("void f() { 1; 2; 3; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003246 compoundStmt(statementCountIs(3))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003247}
3248
3249TEST(StatementCountIs, WorksWithNestedCompoundStatements) {
3250 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003251 compoundStmt(statementCountIs(1))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003252 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003253 compoundStmt(statementCountIs(2))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003254 EXPECT_TRUE(notMatches("void f() { { 1; } { 1; 2; 3; 4; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003255 compoundStmt(statementCountIs(3))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003256 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003257 compoundStmt(statementCountIs(4))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003258}
3259
3260TEST(Member, WorksInSimplestCase) {
3261 EXPECT_TRUE(matches("struct { int first; } s; int i(s.first);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003262 memberExpr(member(hasName("first")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003263}
3264
3265TEST(Member, DoesNotMatchTheBaseExpression) {
3266 // Don't pick out the wrong part of the member expression, this should
3267 // be checking the member (name) only.
3268 EXPECT_TRUE(notMatches("struct { int i; } first; int i(first.i);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003269 memberExpr(member(hasName("first")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003270}
3271
3272TEST(Member, MatchesInMemberFunctionCall) {
3273 EXPECT_TRUE(matches("void f() {"
3274 " struct { void first() {}; } s;"
3275 " s.first();"
3276 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003277 memberExpr(member(hasName("first")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003278}
3279
Daniel Jasperb0c7b612012-10-23 15:46:39 +00003280TEST(Member, MatchesMember) {
3281 EXPECT_TRUE(matches(
3282 "struct A { int i; }; void f() { A a; a.i = 2; }",
3283 memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
3284 EXPECT_TRUE(notMatches(
3285 "struct A { float f; }; void f() { A a; a.f = 2.0f; }",
3286 memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
3287}
3288
Daniel Jasper639522c2013-02-25 12:02:08 +00003289TEST(Member, UnderstandsAccess) {
3290 EXPECT_TRUE(matches(
3291 "struct A { int i; };", fieldDecl(isPublic(), hasName("i"))));
3292 EXPECT_TRUE(notMatches(
3293 "struct A { int i; };", fieldDecl(isProtected(), hasName("i"))));
3294 EXPECT_TRUE(notMatches(
3295 "struct A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
3296
3297 EXPECT_TRUE(notMatches(
3298 "class A { int i; };", fieldDecl(isPublic(), hasName("i"))));
3299 EXPECT_TRUE(notMatches(
3300 "class A { int i; };", fieldDecl(isProtected(), hasName("i"))));
3301 EXPECT_TRUE(matches(
3302 "class A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
3303
3304 EXPECT_TRUE(notMatches(
3305 "class A { protected: int i; };", fieldDecl(isPublic(), hasName("i"))));
3306 EXPECT_TRUE(matches("class A { protected: int i; };",
3307 fieldDecl(isProtected(), hasName("i"))));
3308 EXPECT_TRUE(notMatches(
3309 "class A { protected: int i; };", fieldDecl(isPrivate(), hasName("i"))));
3310
3311 // Non-member decls have the AccessSpecifier AS_none and thus aren't matched.
3312 EXPECT_TRUE(notMatches("int i;", varDecl(isPublic(), hasName("i"))));
3313 EXPECT_TRUE(notMatches("int i;", varDecl(isProtected(), hasName("i"))));
3314 EXPECT_TRUE(notMatches("int i;", varDecl(isPrivate(), hasName("i"))));
3315}
3316
Dmitri Gribenko06963042012-08-18 00:29:27 +00003317TEST(Member, MatchesMemberAllocationFunction) {
Daniel Jasper5901e472012-10-01 13:40:41 +00003318 // Fails in C++11 mode
3319 EXPECT_TRUE(matchesConditionally(
3320 "namespace std { typedef typeof(sizeof(int)) size_t; }"
3321 "class X { void *operator new(std::size_t); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00003322 cxxMethodDecl(ofClass(hasName("X"))), true, "-std=gnu++98"));
Dmitri Gribenko06963042012-08-18 00:29:27 +00003323
3324 EXPECT_TRUE(matches("class X { void operator delete(void*); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00003325 cxxMethodDecl(ofClass(hasName("X")))));
Dmitri Gribenko06963042012-08-18 00:29:27 +00003326
Daniel Jasper5901e472012-10-01 13:40:41 +00003327 // Fails in C++11 mode
3328 EXPECT_TRUE(matchesConditionally(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003329 "namespace std { typedef typeof(sizeof(int)) size_t; }"
3330 "class X { void operator delete[](void*, std::size_t); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00003331 cxxMethodDecl(ofClass(hasName("X"))), true, "-std=gnu++98"));
Dmitri Gribenko06963042012-08-18 00:29:27 +00003332}
3333
Manuel Klimek04616e42012-07-06 05:48:52 +00003334TEST(HasObjectExpression, DoesNotMatchMember) {
3335 EXPECT_TRUE(notMatches(
3336 "class X {}; struct Z { X m; }; void f(Z z) { z.m; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003337 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003338}
3339
3340TEST(HasObjectExpression, MatchesBaseOfVariable) {
3341 EXPECT_TRUE(matches(
3342 "struct X { int m; }; void f(X x) { x.m; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003343 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003344 EXPECT_TRUE(matches(
3345 "struct X { int m; }; void f(X* x) { x->m; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003346 memberExpr(hasObjectExpression(
3347 hasType(pointsTo(recordDecl(hasName("X"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003348}
3349
3350TEST(HasObjectExpression,
3351 MatchesObjectExpressionOfImplicitlyFormedMemberExpression) {
3352 EXPECT_TRUE(matches(
3353 "class X {}; struct S { X m; void f() { this->m; } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003354 memberExpr(hasObjectExpression(
3355 hasType(pointsTo(recordDecl(hasName("S"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003356 EXPECT_TRUE(matches(
3357 "class X {}; struct S { X m; void f() { m; } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003358 memberExpr(hasObjectExpression(
3359 hasType(pointsTo(recordDecl(hasName("S"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003360}
3361
3362TEST(Field, DoesNotMatchNonFieldMembers) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003363 EXPECT_TRUE(notMatches("class X { void m(); };", fieldDecl(hasName("m"))));
3364 EXPECT_TRUE(notMatches("class X { class m {}; };", fieldDecl(hasName("m"))));
3365 EXPECT_TRUE(notMatches("class X { enum { m }; };", fieldDecl(hasName("m"))));
3366 EXPECT_TRUE(notMatches("class X { enum m {}; };", fieldDecl(hasName("m"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003367}
3368
3369TEST(Field, MatchesField) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003370 EXPECT_TRUE(matches("class X { int m; };", fieldDecl(hasName("m"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003371}
3372
Aaron Ballman6290fc92015-11-23 17:09:24 +00003373TEST(IsVolatileQualified, QualifiersMatch) {
3374 EXPECT_TRUE(matches("volatile int i = 42;",
3375 varDecl(hasType(isVolatileQualified()))));
3376 EXPECT_TRUE(notMatches("volatile int *i;",
3377 varDecl(hasType(isVolatileQualified()))));
3378 EXPECT_TRUE(matches("typedef volatile int v_int; v_int i = 42;",
3379 varDecl(hasType(isVolatileQualified()))));
3380}
3381
Manuel Klimek04616e42012-07-06 05:48:52 +00003382TEST(IsConstQualified, MatchesConstInt) {
3383 EXPECT_TRUE(matches("const int i = 42;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003384 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003385}
3386
3387TEST(IsConstQualified, MatchesConstPointer) {
3388 EXPECT_TRUE(matches("int i = 42; int* const p(&i);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003389 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003390}
3391
3392TEST(IsConstQualified, MatchesThroughTypedef) {
3393 EXPECT_TRUE(matches("typedef const int const_int; const_int i = 42;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003394 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003395 EXPECT_TRUE(matches("typedef int* int_ptr; const int_ptr p(0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003396 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003397}
3398
3399TEST(IsConstQualified, DoesNotMatchInappropriately) {
3400 EXPECT_TRUE(notMatches("typedef int nonconst_int; nonconst_int i = 42;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003401 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003402 EXPECT_TRUE(notMatches("int const* p;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003403 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003404}
3405
Sam Panzer80c13772012-08-16 16:58:10 +00003406TEST(CastExpression, MatchesExplicitCasts) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00003407 EXPECT_TRUE(matches("char *p = reinterpret_cast<char *>(&p);",castExpr()));
3408 EXPECT_TRUE(matches("void *p = (void *)(&p);", castExpr()));
3409 EXPECT_TRUE(matches("char q, *p = const_cast<char *>(&q);", castExpr()));
3410 EXPECT_TRUE(matches("char c = char(0);", castExpr()));
Sam Panzer80c13772012-08-16 16:58:10 +00003411}
3412TEST(CastExpression, MatchesImplicitCasts) {
3413 // This test creates an implicit cast from int to char.
Daniel Jasper848cbe12012-09-18 13:09:13 +00003414 EXPECT_TRUE(matches("char c = 0;", castExpr()));
Sam Panzer80c13772012-08-16 16:58:10 +00003415 // This test creates an implicit cast from lvalue to rvalue.
Daniel Jasper848cbe12012-09-18 13:09:13 +00003416 EXPECT_TRUE(matches("char c = 0, d = c;", castExpr()));
Sam Panzer80c13772012-08-16 16:58:10 +00003417}
3418
3419TEST(CastExpression, DoesNotMatchNonCasts) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00003420 EXPECT_TRUE(notMatches("char c = '0';", castExpr()));
3421 EXPECT_TRUE(notMatches("char c, &q = c;", castExpr()));
3422 EXPECT_TRUE(notMatches("int i = (0);", castExpr()));
3423 EXPECT_TRUE(notMatches("int i = 0;", castExpr()));
Sam Panzer80c13772012-08-16 16:58:10 +00003424}
3425
Manuel Klimek04616e42012-07-06 05:48:52 +00003426TEST(ReinterpretCast, MatchesSimpleCase) {
3427 EXPECT_TRUE(matches("char* p = reinterpret_cast<char*>(&p);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003428 cxxReinterpretCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003429}
3430
3431TEST(ReinterpretCast, DoesNotMatchOtherCasts) {
Aaron Ballman512fb642015-09-17 13:30:52 +00003432 EXPECT_TRUE(notMatches("char* p = (char*)(&p);", cxxReinterpretCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003433 EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003434 cxxReinterpretCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003435 EXPECT_TRUE(notMatches("void* p = static_cast<void*>(&p);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003436 cxxReinterpretCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003437 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
3438 "B b;"
3439 "D* p = dynamic_cast<D*>(&b);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003440 cxxReinterpretCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003441}
3442
3443TEST(FunctionalCast, MatchesSimpleCase) {
Ismail Pazarbasi1121de32014-01-17 21:08:52 +00003444 std::string foo_class = "class Foo { public: Foo(const char*); };";
Manuel Klimek04616e42012-07-06 05:48:52 +00003445 EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello world\"); }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003446 cxxFunctionalCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003447}
3448
3449TEST(FunctionalCast, DoesNotMatchOtherCasts) {
Ismail Pazarbasi1121de32014-01-17 21:08:52 +00003450 std::string FooClass = "class Foo { public: Foo(const char*); };";
Manuel Klimek04616e42012-07-06 05:48:52 +00003451 EXPECT_TRUE(
3452 notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\"; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003453 cxxFunctionalCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003454 EXPECT_TRUE(
3455 notMatches(FooClass + "void r() { Foo f = \"hello world\"; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003456 cxxFunctionalCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003457}
3458
3459TEST(DynamicCast, MatchesSimpleCase) {
3460 EXPECT_TRUE(matches("struct B { virtual ~B() {} }; struct D : B {};"
3461 "B b;"
3462 "D* p = dynamic_cast<D*>(&b);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003463 cxxDynamicCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003464}
3465
3466TEST(StaticCast, MatchesSimpleCase) {
3467 EXPECT_TRUE(matches("void* p(static_cast<void*>(&p));",
Aaron Ballman512fb642015-09-17 13:30:52 +00003468 cxxStaticCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003469}
3470
3471TEST(StaticCast, DoesNotMatchOtherCasts) {
Aaron Ballman512fb642015-09-17 13:30:52 +00003472 EXPECT_TRUE(notMatches("char* p = (char*)(&p);", cxxStaticCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003473 EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003474 cxxStaticCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003475 EXPECT_TRUE(notMatches("void* p = reinterpret_cast<char*>(&p);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003476 cxxStaticCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003477 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
3478 "B b;"
3479 "D* p = dynamic_cast<D*>(&b);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003480 cxxStaticCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003481}
3482
Daniel Jasper417f7762012-09-18 13:36:17 +00003483TEST(CStyleCast, MatchesSimpleCase) {
3484 EXPECT_TRUE(matches("int i = (int) 2.2f;", cStyleCastExpr()));
3485}
3486
3487TEST(CStyleCast, DoesNotMatchOtherCasts) {
3488 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);"
3489 "char q, *r = const_cast<char*>(&q);"
3490 "void* s = reinterpret_cast<char*>(&s);"
3491 "struct B { virtual ~B() {} }; struct D : B {};"
3492 "B b;"
3493 "D* t = dynamic_cast<D*>(&b);",
3494 cStyleCastExpr()));
3495}
3496
Manuel Klimek04616e42012-07-06 05:48:52 +00003497TEST(HasDestinationType, MatchesSimpleCase) {
3498 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003499 cxxStaticCastExpr(hasDestinationType(
Daniel Jasper848cbe12012-09-18 13:09:13 +00003500 pointsTo(TypeMatcher(anything()))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003501}
3502
Sam Panzer80c13772012-08-16 16:58:10 +00003503TEST(HasImplicitDestinationType, MatchesSimpleCase) {
3504 // This test creates an implicit const cast.
3505 EXPECT_TRUE(matches("int x; const int i = x;",
Daniel Jasper848cbe12012-09-18 13:09:13 +00003506 implicitCastExpr(
3507 hasImplicitDestinationType(isInteger()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003508 // This test creates an implicit array-to-pointer cast.
3509 EXPECT_TRUE(matches("int arr[3]; int *p = arr;",
Daniel Jasper848cbe12012-09-18 13:09:13 +00003510 implicitCastExpr(hasImplicitDestinationType(
3511 pointsTo(TypeMatcher(anything()))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003512}
3513
3514TEST(HasImplicitDestinationType, DoesNotMatchIncorrectly) {
3515 // This test creates an implicit cast from int to char.
3516 EXPECT_TRUE(notMatches("char c = 0;",
Daniel Jasper848cbe12012-09-18 13:09:13 +00003517 implicitCastExpr(hasImplicitDestinationType(
3518 unless(anything())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003519 // This test creates an implicit array-to-pointer cast.
3520 EXPECT_TRUE(notMatches("int arr[3]; int *p = arr;",
Daniel Jasper848cbe12012-09-18 13:09:13 +00003521 implicitCastExpr(hasImplicitDestinationType(
3522 unless(anything())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003523}
3524
3525TEST(ImplicitCast, MatchesSimpleCase) {
3526 // This test creates an implicit const cast.
3527 EXPECT_TRUE(matches("int x = 0; const int y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003528 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003529 // This test creates an implicit cast from int to char.
3530 EXPECT_TRUE(matches("char c = 0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003531 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003532 // This test creates an implicit array-to-pointer cast.
3533 EXPECT_TRUE(matches("int arr[6]; int *p = arr;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003534 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003535}
3536
3537TEST(ImplicitCast, DoesNotMatchIncorrectly) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003538 // This test verifies that implicitCastExpr() matches exactly when implicit casts
Sam Panzer80c13772012-08-16 16:58:10 +00003539 // are present, and that it ignores explicit and paren casts.
3540
3541 // These two test cases have no casts.
3542 EXPECT_TRUE(notMatches("int x = 0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003543 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003544 EXPECT_TRUE(notMatches("int x = 0, &y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003545 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003546
3547 EXPECT_TRUE(notMatches("int x = 0; double d = (double) x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003548 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003549 EXPECT_TRUE(notMatches("const int *p; int *q = const_cast<int *>(p);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003550 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003551
3552 EXPECT_TRUE(notMatches("int x = (0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003553 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003554}
3555
3556TEST(IgnoringImpCasts, MatchesImpCasts) {
3557 // This test checks that ignoringImpCasts matches when implicit casts are
3558 // present and its inner matcher alone does not match.
3559 // Note that this test creates an implicit const cast.
3560 EXPECT_TRUE(matches("int x = 0; const int y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003561 varDecl(hasInitializer(ignoringImpCasts(
3562 declRefExpr(to(varDecl(hasName("x")))))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003563 // This test creates an implict cast from int to char.
3564 EXPECT_TRUE(matches("char x = 0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003565 varDecl(hasInitializer(ignoringImpCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003566 integerLiteral(equals(0)))))));
3567}
3568
3569TEST(IgnoringImpCasts, DoesNotMatchIncorrectly) {
3570 // These tests verify that ignoringImpCasts does not match if the inner
3571 // matcher does not match.
3572 // Note that the first test creates an implicit const cast.
3573 EXPECT_TRUE(notMatches("int x; const int y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003574 varDecl(hasInitializer(ignoringImpCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003575 unless(anything()))))));
3576 EXPECT_TRUE(notMatches("int x; int y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003577 varDecl(hasInitializer(ignoringImpCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003578 unless(anything()))))));
3579
3580 // These tests verify that ignoringImplictCasts does not look through explicit
3581 // casts or parentheses.
3582 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003583 varDecl(hasInitializer(ignoringImpCasts(
3584 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003585 EXPECT_TRUE(notMatches("int i = (0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003586 varDecl(hasInitializer(ignoringImpCasts(
3587 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003588 EXPECT_TRUE(notMatches("float i = (float)0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003589 varDecl(hasInitializer(ignoringImpCasts(
3590 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003591 EXPECT_TRUE(notMatches("float i = float(0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003592 varDecl(hasInitializer(ignoringImpCasts(
3593 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003594}
3595
3596TEST(IgnoringImpCasts, MatchesWithoutImpCasts) {
3597 // This test verifies that expressions that do not have implicit casts
3598 // still match the inner matcher.
3599 EXPECT_TRUE(matches("int x = 0; int &y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003600 varDecl(hasInitializer(ignoringImpCasts(
3601 declRefExpr(to(varDecl(hasName("x")))))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003602}
3603
3604TEST(IgnoringParenCasts, MatchesParenCasts) {
3605 // This test checks that ignoringParenCasts matches when parentheses and/or
3606 // casts are present and its inner matcher alone does not match.
3607 EXPECT_TRUE(matches("int x = (0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003608 varDecl(hasInitializer(ignoringParenCasts(
3609 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003610 EXPECT_TRUE(matches("int x = (((((0)))));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003611 varDecl(hasInitializer(ignoringParenCasts(
3612 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003613
3614 // This test creates an implict cast from int to char in addition to the
3615 // parentheses.
3616 EXPECT_TRUE(matches("char x = (0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003617 varDecl(hasInitializer(ignoringParenCasts(
3618 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003619
3620 EXPECT_TRUE(matches("char x = (char)0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003621 varDecl(hasInitializer(ignoringParenCasts(
3622 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003623 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003624 varDecl(hasInitializer(ignoringParenCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003625 integerLiteral(equals(0)))))));
3626}
3627
3628TEST(IgnoringParenCasts, MatchesWithoutParenCasts) {
3629 // This test verifies that expressions that do not have any casts still match.
3630 EXPECT_TRUE(matches("int x = 0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003631 varDecl(hasInitializer(ignoringParenCasts(
3632 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003633}
3634
3635TEST(IgnoringParenCasts, DoesNotMatchIncorrectly) {
3636 // These tests verify that ignoringImpCasts does not match if the inner
3637 // matcher does not match.
3638 EXPECT_TRUE(notMatches("int x = ((0));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003639 varDecl(hasInitializer(ignoringParenCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003640 unless(anything()))))));
3641
3642 // This test creates an implicit cast from int to char in addition to the
3643 // parentheses.
3644 EXPECT_TRUE(notMatches("char x = ((0));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003645 varDecl(hasInitializer(ignoringParenCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003646 unless(anything()))))));
3647
3648 EXPECT_TRUE(notMatches("char *x = static_cast<char *>((0));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003649 varDecl(hasInitializer(ignoringParenCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003650 unless(anything()))))));
3651}
3652
3653TEST(IgnoringParenAndImpCasts, MatchesParenImpCasts) {
3654 // This test checks that ignoringParenAndImpCasts matches when
3655 // parentheses and/or implicit casts are present and its inner matcher alone
3656 // does not match.
3657 // Note that this test creates an implicit const cast.
3658 EXPECT_TRUE(matches("int x = 0; const int y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003659 varDecl(hasInitializer(ignoringParenImpCasts(
3660 declRefExpr(to(varDecl(hasName("x")))))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003661 // This test creates an implicit cast from int to char.
3662 EXPECT_TRUE(matches("const char x = (0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003663 varDecl(hasInitializer(ignoringParenImpCasts(
3664 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003665}
3666
3667TEST(IgnoringParenAndImpCasts, MatchesWithoutParenImpCasts) {
3668 // This test verifies that expressions that do not have parentheses or
3669 // implicit casts still match.
3670 EXPECT_TRUE(matches("int x = 0; int &y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003671 varDecl(hasInitializer(ignoringParenImpCasts(
3672 declRefExpr(to(varDecl(hasName("x")))))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003673 EXPECT_TRUE(matches("int x = 0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003674 varDecl(hasInitializer(ignoringParenImpCasts(
3675 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003676}
3677
3678TEST(IgnoringParenAndImpCasts, DoesNotMatchIncorrectly) {
3679 // These tests verify that ignoringParenImpCasts does not match if
3680 // the inner matcher does not match.
3681 // This test creates an implicit cast.
3682 EXPECT_TRUE(notMatches("char c = ((3));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003683 varDecl(hasInitializer(ignoringParenImpCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003684 unless(anything()))))));
3685 // These tests verify that ignoringParenAndImplictCasts does not look
3686 // through explicit casts.
3687 EXPECT_TRUE(notMatches("float y = (float(0));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003688 varDecl(hasInitializer(ignoringParenImpCasts(
3689 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003690 EXPECT_TRUE(notMatches("float y = (float)0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003691 varDecl(hasInitializer(ignoringParenImpCasts(
3692 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003693 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003694 varDecl(hasInitializer(ignoringParenImpCasts(
3695 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003696}
3697
Manuel Klimeke9235692012-07-25 10:02:02 +00003698TEST(HasSourceExpression, MatchesImplicitCasts) {
Manuel Klimek04616e42012-07-06 05:48:52 +00003699 EXPECT_TRUE(matches("class string {}; class URL { public: URL(string s); };"
3700 "void r() {string a_string; URL url = a_string; }",
Daniel Jasper848cbe12012-09-18 13:09:13 +00003701 implicitCastExpr(
Aaron Ballman512fb642015-09-17 13:30:52 +00003702 hasSourceExpression(cxxConstructExpr()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003703}
3704
Manuel Klimeke9235692012-07-25 10:02:02 +00003705TEST(HasSourceExpression, MatchesExplicitCasts) {
3706 EXPECT_TRUE(matches("float x = static_cast<float>(42);",
Daniel Jasper848cbe12012-09-18 13:09:13 +00003707 explicitCastExpr(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003708 hasSourceExpression(hasDescendant(
Daniel Jasper848cbe12012-09-18 13:09:13 +00003709 expr(integerLiteral()))))));
Manuel Klimeke9235692012-07-25 10:02:02 +00003710}
3711
Manuel Klimek04616e42012-07-06 05:48:52 +00003712TEST(Statement, DoesNotMatchDeclarations) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003713 EXPECT_TRUE(notMatches("class X {};", stmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003714}
3715
3716TEST(Statement, MatchesCompoundStatments) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003717 EXPECT_TRUE(matches("void x() {}", stmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003718}
3719
3720TEST(DeclarationStatement, DoesNotMatchCompoundStatements) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003721 EXPECT_TRUE(notMatches("void x() {}", declStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003722}
3723
3724TEST(DeclarationStatement, MatchesVariableDeclarationStatements) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003725 EXPECT_TRUE(matches("void x() { int a; }", declStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003726}
3727
Samuel Benzaquenf1066292014-04-02 13:12:14 +00003728TEST(ExprWithCleanups, MatchesExprWithCleanups) {
3729 EXPECT_TRUE(matches("struct Foo { ~Foo(); };"
3730 "const Foo f = Foo();",
3731 varDecl(hasInitializer(exprWithCleanups()))));
3732 EXPECT_FALSE(matches("struct Foo { };"
3733 "const Foo f = Foo();",
3734 varDecl(hasInitializer(exprWithCleanups()))));
3735}
3736
Daniel Jasper1dad1832012-07-10 20:20:19 +00003737TEST(InitListExpression, MatchesInitListExpression) {
3738 EXPECT_TRUE(matches("int a[] = { 1, 2 };",
3739 initListExpr(hasType(asString("int [2]")))));
3740 EXPECT_TRUE(matches("struct B { int x, y; }; B b = { 5, 6 };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003741 initListExpr(hasType(recordDecl(hasName("B"))))));
Daniel Jasper1d8ecbd2015-02-04 13:11:42 +00003742 EXPECT_TRUE(matches("struct S { S(void (*a)()); };"
3743 "void f();"
3744 "S s[1] = { &f };",
3745 declRefExpr(to(functionDecl(hasName("f"))))));
Daniel Jasper774e6b52015-02-04 14:29:47 +00003746 EXPECT_TRUE(
3747 matches("int i[1] = {42, [0] = 43};", integerLiteral(equals(42))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00003748}
3749
3750TEST(UsingDeclaration, MatchesUsingDeclarations) {
3751 EXPECT_TRUE(matches("namespace X { int x; } using X::x;",
3752 usingDecl()));
3753}
3754
3755TEST(UsingDeclaration, MatchesShadowUsingDelcarations) {
3756 EXPECT_TRUE(matches("namespace f { int a; } using f::a;",
3757 usingDecl(hasAnyUsingShadowDecl(hasName("a")))));
3758}
3759
3760TEST(UsingDeclaration, MatchesSpecificTarget) {
3761 EXPECT_TRUE(matches("namespace f { int a; void b(); } using f::b;",
3762 usingDecl(hasAnyUsingShadowDecl(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003763 hasTargetDecl(functionDecl())))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00003764 EXPECT_TRUE(notMatches("namespace f { int a; void b(); } using f::a;",
3765 usingDecl(hasAnyUsingShadowDecl(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003766 hasTargetDecl(functionDecl())))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00003767}
3768
3769TEST(UsingDeclaration, ThroughUsingDeclaration) {
3770 EXPECT_TRUE(matches(
3771 "namespace a { void f(); } using a::f; void g() { f(); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003772 declRefExpr(throughUsingDecl(anything()))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00003773 EXPECT_TRUE(notMatches(
3774 "namespace a { void f(); } using a::f; void g() { a::f(); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003775 declRefExpr(throughUsingDecl(anything()))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00003776}
3777
Benjamin Kramer73ef2162014-07-16 14:14:51 +00003778TEST(UsingDirectiveDeclaration, MatchesUsingNamespace) {
3779 EXPECT_TRUE(matches("namespace X { int x; } using namespace X;",
3780 usingDirectiveDecl()));
3781 EXPECT_FALSE(
3782 matches("namespace X { int x; } using X::x;", usingDirectiveDecl()));
3783}
3784
Sam Panzerd624bfb2012-08-16 17:20:59 +00003785TEST(SingleDecl, IsSingleDecl) {
3786 StatementMatcher SingleDeclStmt =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003787 declStmt(hasSingleDecl(varDecl(hasInitializer(anything()))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003788 EXPECT_TRUE(matches("void f() {int a = 4;}", SingleDeclStmt));
3789 EXPECT_TRUE(notMatches("void f() {int a;}", SingleDeclStmt));
3790 EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
3791 SingleDeclStmt));
3792}
3793
3794TEST(DeclStmt, ContainsDeclaration) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003795 DeclarationMatcher MatchesInit = varDecl(hasInitializer(anything()));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003796
3797 EXPECT_TRUE(matches("void f() {int a = 4;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003798 declStmt(containsDeclaration(0, MatchesInit))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003799 EXPECT_TRUE(matches("void f() {int a = 4, b = 3;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003800 declStmt(containsDeclaration(0, MatchesInit),
3801 containsDeclaration(1, MatchesInit))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003802 unsigned WrongIndex = 42;
3803 EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003804 declStmt(containsDeclaration(WrongIndex,
Sam Panzerd624bfb2012-08-16 17:20:59 +00003805 MatchesInit))));
3806}
3807
3808TEST(DeclCount, DeclCountIsCorrect) {
3809 EXPECT_TRUE(matches("void f() {int i,j;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003810 declStmt(declCountIs(2))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003811 EXPECT_TRUE(notMatches("void f() {int i,j; int k;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003812 declStmt(declCountIs(3))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003813 EXPECT_TRUE(notMatches("void f() {int i,j, k, l;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003814 declStmt(declCountIs(3))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003815}
3816
Manuel Klimek04616e42012-07-06 05:48:52 +00003817TEST(While, MatchesWhileLoops) {
3818 EXPECT_TRUE(notMatches("void x() {}", whileStmt()));
3819 EXPECT_TRUE(matches("void x() { while(true); }", whileStmt()));
3820 EXPECT_TRUE(notMatches("void x() { do {} while(true); }", whileStmt()));
3821}
3822
3823TEST(Do, MatchesDoLoops) {
3824 EXPECT_TRUE(matches("void x() { do {} while(true); }", doStmt()));
3825 EXPECT_TRUE(matches("void x() { do ; while(false); }", doStmt()));
3826}
3827
3828TEST(Do, DoesNotMatchWhileLoops) {
3829 EXPECT_TRUE(notMatches("void x() { while(true) {} }", doStmt()));
3830}
3831
3832TEST(SwitchCase, MatchesCase) {
3833 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchCase()));
3834 EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchCase()));
3835 EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchCase()));
3836 EXPECT_TRUE(notMatches("void x() { switch(42) {} }", switchCase()));
3837}
3838
Daniel Jasper87c3d362012-09-20 14:12:57 +00003839TEST(SwitchCase, MatchesSwitch) {
3840 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchStmt()));
3841 EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchStmt()));
3842 EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchStmt()));
3843 EXPECT_TRUE(notMatches("void x() {}", switchStmt()));
3844}
3845
Peter Collingbourne3154a102013-05-10 11:52:02 +00003846TEST(SwitchCase, MatchesEachCase) {
3847 EXPECT_TRUE(notMatches("void x() { switch(42); }",
3848 switchStmt(forEachSwitchCase(caseStmt()))));
3849 EXPECT_TRUE(matches("void x() { switch(42) case 42:; }",
3850 switchStmt(forEachSwitchCase(caseStmt()))));
3851 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }",
3852 switchStmt(forEachSwitchCase(caseStmt()))));
3853 EXPECT_TRUE(notMatches(
3854 "void x() { if (1) switch(42) { case 42: switch (42) { default:; } } }",
3855 ifStmt(has(switchStmt(forEachSwitchCase(defaultStmt()))))));
3856 EXPECT_TRUE(matches("void x() { switch(42) { case 1+1: case 4:; } }",
3857 switchStmt(forEachSwitchCase(
3858 caseStmt(hasCaseConstant(integerLiteral()))))));
3859 EXPECT_TRUE(notMatches("void x() { switch(42) { case 1+1: case 2+2:; } }",
3860 switchStmt(forEachSwitchCase(
3861 caseStmt(hasCaseConstant(integerLiteral()))))));
3862 EXPECT_TRUE(notMatches("void x() { switch(42) { case 1 ... 2:; } }",
3863 switchStmt(forEachSwitchCase(
3864 caseStmt(hasCaseConstant(integerLiteral()))))));
3865 EXPECT_TRUE(matchAndVerifyResultTrue(
3866 "void x() { switch (42) { case 1: case 2: case 3: default:; } }",
3867 switchStmt(forEachSwitchCase(caseStmt().bind("x"))),
3868 new VerifyIdIsBoundTo<CaseStmt>("x", 3)));
3869}
3870
Manuel Klimekba46fc02013-07-19 11:50:54 +00003871TEST(ForEachConstructorInitializer, MatchesInitializers) {
3872 EXPECT_TRUE(matches(
3873 "struct X { X() : i(42), j(42) {} int i, j; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00003874 cxxConstructorDecl(forEachConstructorInitializer(cxxCtorInitializer()))));
Manuel Klimekba46fc02013-07-19 11:50:54 +00003875}
3876
Daniel Jasper87c3d362012-09-20 14:12:57 +00003877TEST(ExceptionHandling, SimpleCases) {
Aaron Ballman512fb642015-09-17 13:30:52 +00003878 EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", cxxCatchStmt()));
3879 EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", cxxTryStmt()));
3880 EXPECT_TRUE(
3881 notMatches("void foo() try { } catch(int X) { }", cxxThrowExpr()));
Daniel Jasper87c3d362012-09-20 14:12:57 +00003882 EXPECT_TRUE(matches("void foo() try { throw; } catch(int X) { }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003883 cxxThrowExpr()));
Daniel Jasper87c3d362012-09-20 14:12:57 +00003884 EXPECT_TRUE(matches("void foo() try { throw 5;} catch(int X) { }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003885 cxxThrowExpr()));
Aaron Ballman9b869aa2015-07-02 12:53:22 +00003886 EXPECT_TRUE(matches("void foo() try { throw; } catch(...) { }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003887 cxxCatchStmt(isCatchAll())));
Aaron Ballman9b869aa2015-07-02 12:53:22 +00003888 EXPECT_TRUE(notMatches("void foo() try { throw; } catch(int) { }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003889 cxxCatchStmt(isCatchAll())));
Aaron Ballman39918462015-07-15 17:11:21 +00003890 EXPECT_TRUE(matches("void foo() try {} catch(int X) { }",
3891 varDecl(isExceptionVariable())));
3892 EXPECT_TRUE(notMatches("void foo() try { int X; } catch (...) { }",
3893 varDecl(isExceptionVariable())));
Daniel Jasper87c3d362012-09-20 14:12:57 +00003894}
3895
Aaron Ballmane8295d72016-01-20 16:17:39 +00003896TEST(ParenExpression, SimpleCases) {
3897 EXPECT_TRUE(matches("int i = (3);", parenExpr()));
3898 EXPECT_TRUE(matches("int i = (3 + 7);", parenExpr()));
3899 EXPECT_TRUE(notMatches("int i = 3;", parenExpr()));
3900 EXPECT_TRUE(notMatches("int foo() { return 1; }; int a = foo();",
3901 parenExpr()));
3902}
3903
Manuel Klimek04616e42012-07-06 05:48:52 +00003904TEST(HasConditionVariableStatement, DoesNotMatchCondition) {
3905 EXPECT_TRUE(notMatches(
3906 "void x() { if(true) {} }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003907 ifStmt(hasConditionVariableStatement(declStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003908 EXPECT_TRUE(notMatches(
3909 "void x() { int x; if((x = 42)) {} }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003910 ifStmt(hasConditionVariableStatement(declStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003911}
3912
3913TEST(HasConditionVariableStatement, MatchesConditionVariables) {
3914 EXPECT_TRUE(matches(
3915 "void x() { if(int* a = 0) {} }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003916 ifStmt(hasConditionVariableStatement(declStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003917}
3918
3919TEST(ForEach, BindsOneNode) {
3920 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003921 recordDecl(hasName("C"), forEach(fieldDecl(hasName("x")).bind("x"))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003922 new VerifyIdIsBoundTo<FieldDecl>("x", 1)));
Manuel Klimek04616e42012-07-06 05:48:52 +00003923}
3924
3925TEST(ForEach, BindsMultipleNodes) {
3926 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; int y; int z; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003927 recordDecl(hasName("C"), forEach(fieldDecl().bind("f"))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003928 new VerifyIdIsBoundTo<FieldDecl>("f", 3)));
Manuel Klimek04616e42012-07-06 05:48:52 +00003929}
3930
3931TEST(ForEach, BindsRecursiveCombinations) {
3932 EXPECT_TRUE(matchAndVerifyResultTrue(
3933 "class C { class D { int x; int y; }; class E { int y; int z; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003934 recordDecl(hasName("C"),
3935 forEach(recordDecl(forEach(fieldDecl().bind("f"))))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003936 new VerifyIdIsBoundTo<FieldDecl>("f", 4)));
Manuel Klimek04616e42012-07-06 05:48:52 +00003937}
3938
3939TEST(ForEachDescendant, BindsOneNode) {
3940 EXPECT_TRUE(matchAndVerifyResultTrue("class C { class D { int x; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003941 recordDecl(hasName("C"),
3942 forEachDescendant(fieldDecl(hasName("x")).bind("x"))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003943 new VerifyIdIsBoundTo<FieldDecl>("x", 1)));
Manuel Klimek04616e42012-07-06 05:48:52 +00003944}
3945
Daniel Jasper94a56852012-11-16 18:39:22 +00003946TEST(ForEachDescendant, NestedForEachDescendant) {
3947 DeclarationMatcher m = recordDecl(
3948 isDefinition(), decl().bind("x"), hasName("C"));
3949 EXPECT_TRUE(matchAndVerifyResultTrue(
3950 "class A { class B { class C {}; }; };",
3951 recordDecl(hasName("A"), anyOf(m, forEachDescendant(m))),
3952 new VerifyIdIsBoundTo<Decl>("x", "C")));
3953
Manuel Klimeka0c025f2013-06-19 15:42:45 +00003954 // Check that a partial match of 'm' that binds 'x' in the
3955 // first part of anyOf(m, anything()) will not overwrite the
3956 // binding created by the earlier binding in the hasDescendant.
3957 EXPECT_TRUE(matchAndVerifyResultTrue(
3958 "class A { class B { class C {}; }; };",
3959 recordDecl(hasName("A"), allOf(hasDescendant(m), anyOf(m, anything()))),
3960 new VerifyIdIsBoundTo<Decl>("x", "C")));
Daniel Jasper94a56852012-11-16 18:39:22 +00003961}
3962
Manuel Klimek04616e42012-07-06 05:48:52 +00003963TEST(ForEachDescendant, BindsMultipleNodes) {
3964 EXPECT_TRUE(matchAndVerifyResultTrue(
3965 "class C { class D { int x; int y; }; "
3966 " class E { class F { int y; int z; }; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003967 recordDecl(hasName("C"), forEachDescendant(fieldDecl().bind("f"))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003968 new VerifyIdIsBoundTo<FieldDecl>("f", 4)));
Manuel Klimek04616e42012-07-06 05:48:52 +00003969}
3970
3971TEST(ForEachDescendant, BindsRecursiveCombinations) {
3972 EXPECT_TRUE(matchAndVerifyResultTrue(
3973 "class C { class D { "
3974 " class E { class F { class G { int y; int z; }; }; }; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003975 recordDecl(hasName("C"), forEachDescendant(recordDecl(
3976 forEachDescendant(fieldDecl().bind("f"))))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003977 new VerifyIdIsBoundTo<FieldDecl>("f", 8)));
Manuel Klimek04616e42012-07-06 05:48:52 +00003978}
3979
Manuel Klimeka0c025f2013-06-19 15:42:45 +00003980TEST(ForEachDescendant, BindsCombinations) {
3981 EXPECT_TRUE(matchAndVerifyResultTrue(
3982 "void f() { if(true) {} if (true) {} while (true) {} if (true) {} while "
3983 "(true) {} }",
3984 compoundStmt(forEachDescendant(ifStmt().bind("if")),
3985 forEachDescendant(whileStmt().bind("while"))),
3986 new VerifyIdIsBoundTo<IfStmt>("if", 6)));
3987}
3988
3989TEST(Has, DoesNotDeleteBindings) {
3990 EXPECT_TRUE(matchAndVerifyResultTrue(
3991 "class X { int a; };", recordDecl(decl().bind("x"), has(fieldDecl())),
3992 new VerifyIdIsBoundTo<Decl>("x", 1)));
3993}
3994
3995TEST(LoopingMatchers, DoNotOverwritePreviousMatchResultOnFailure) {
3996 // Those matchers cover all the cases where an inner matcher is called
3997 // and there is not a 1:1 relationship between the match of the outer
3998 // matcher and the match of the inner matcher.
3999 // The pattern to look for is:
4000 // ... return InnerMatcher.matches(...); ...
4001 // In which case no special handling is needed.
4002 //
4003 // On the other hand, if there are multiple alternative matches
4004 // (for example forEach*) or matches might be discarded (for example has*)
4005 // the implementation must make sure that the discarded matches do not
4006 // affect the bindings.
4007 // When new such matchers are added, add a test here that:
4008 // - matches a simple node, and binds it as the first thing in the matcher:
4009 // recordDecl(decl().bind("x"), hasName("X")))
4010 // - uses the matcher under test afterwards in a way that not the first
4011 // alternative is matched; for anyOf, that means the first branch
4012 // would need to return false; for hasAncestor, it means that not
4013 // the direct parent matches the inner matcher.
4014
4015 EXPECT_TRUE(matchAndVerifyResultTrue(
4016 "class X { int y; };",
4017 recordDecl(
4018 recordDecl().bind("x"), hasName("::X"),
4019 anyOf(forEachDescendant(recordDecl(hasName("Y"))), anything())),
4020 new VerifyIdIsBoundTo<CXXRecordDecl>("x", 1)));
4021 EXPECT_TRUE(matchAndVerifyResultTrue(
4022 "class X {};", recordDecl(recordDecl().bind("x"), hasName("::X"),
4023 anyOf(unless(anything()), anything())),
4024 new VerifyIdIsBoundTo<CXXRecordDecl>("x", 1)));
4025 EXPECT_TRUE(matchAndVerifyResultTrue(
4026 "template<typename T1, typename T2> class X {}; X<float, int> x;",
4027 classTemplateSpecializationDecl(
4028 decl().bind("x"),
4029 hasAnyTemplateArgument(refersToType(asString("int")))),
4030 new VerifyIdIsBoundTo<Decl>("x", 1)));
4031 EXPECT_TRUE(matchAndVerifyResultTrue(
4032 "class X { void f(); void g(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00004033 cxxRecordDecl(decl().bind("x"), hasMethod(hasName("g"))),
Manuel Klimeka0c025f2013-06-19 15:42:45 +00004034 new VerifyIdIsBoundTo<Decl>("x", 1)));
4035 EXPECT_TRUE(matchAndVerifyResultTrue(
4036 "class X { X() : a(1), b(2) {} double a; int b; };",
4037 recordDecl(decl().bind("x"),
Aaron Ballman512fb642015-09-17 13:30:52 +00004038 has(cxxConstructorDecl(
Manuel Klimeka0c025f2013-06-19 15:42:45 +00004039 hasAnyConstructorInitializer(forField(hasName("b")))))),
4040 new VerifyIdIsBoundTo<Decl>("x", 1)));
4041 EXPECT_TRUE(matchAndVerifyResultTrue(
4042 "void x(int, int) { x(0, 42); }",
4043 callExpr(expr().bind("x"), hasAnyArgument(integerLiteral(equals(42)))),
4044 new VerifyIdIsBoundTo<Expr>("x", 1)));
4045 EXPECT_TRUE(matchAndVerifyResultTrue(
4046 "void x(int, int y) {}",
4047 functionDecl(decl().bind("x"), hasAnyParameter(hasName("y"))),
4048 new VerifyIdIsBoundTo<Decl>("x", 1)));
4049 EXPECT_TRUE(matchAndVerifyResultTrue(
4050 "void x() { return; if (true) {} }",
4051 functionDecl(decl().bind("x"),
4052 has(compoundStmt(hasAnySubstatement(ifStmt())))),
4053 new VerifyIdIsBoundTo<Decl>("x", 1)));
4054 EXPECT_TRUE(matchAndVerifyResultTrue(
4055 "namespace X { void b(int); void b(); }"
4056 "using X::b;",
4057 usingDecl(decl().bind("x"), hasAnyUsingShadowDecl(hasTargetDecl(
4058 functionDecl(parameterCountIs(1))))),
4059 new VerifyIdIsBoundTo<Decl>("x", 1)));
4060 EXPECT_TRUE(matchAndVerifyResultTrue(
4061 "class A{}; class B{}; class C : B, A {};",
Aaron Ballman512fb642015-09-17 13:30:52 +00004062 cxxRecordDecl(decl().bind("x"), isDerivedFrom("::A")),
Manuel Klimeka0c025f2013-06-19 15:42:45 +00004063 new VerifyIdIsBoundTo<Decl>("x", 1)));
4064 EXPECT_TRUE(matchAndVerifyResultTrue(
4065 "class A{}; typedef A B; typedef A C; typedef A D;"
4066 "class E : A {};",
Aaron Ballman512fb642015-09-17 13:30:52 +00004067 cxxRecordDecl(decl().bind("x"), isDerivedFrom("C")),
Manuel Klimeka0c025f2013-06-19 15:42:45 +00004068 new VerifyIdIsBoundTo<Decl>("x", 1)));
4069 EXPECT_TRUE(matchAndVerifyResultTrue(
4070 "class A { class B { void f() {} }; };",
4071 functionDecl(decl().bind("x"), hasAncestor(recordDecl(hasName("::A")))),
4072 new VerifyIdIsBoundTo<Decl>("x", 1)));
4073 EXPECT_TRUE(matchAndVerifyResultTrue(
4074 "template <typename T> struct A { struct B {"
4075 " void f() { if(true) {} }"
4076 "}; };"
4077 "void t() { A<int>::B b; b.f(); }",
4078 ifStmt(stmt().bind("x"), hasAncestor(recordDecl(hasName("::A")))),
4079 new VerifyIdIsBoundTo<Stmt>("x", 2)));
4080 EXPECT_TRUE(matchAndVerifyResultTrue(
4081 "class A {};",
4082 recordDecl(hasName("::A"), decl().bind("x"), unless(hasName("fooble"))),
4083 new VerifyIdIsBoundTo<Decl>("x", 1)));
Manuel Klimekba46fc02013-07-19 11:50:54 +00004084 EXPECT_TRUE(matchAndVerifyResultTrue(
4085 "class A { A() : s(), i(42) {} const char *s; int i; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00004086 cxxConstructorDecl(hasName("::A::A"), decl().bind("x"),
4087 forEachConstructorInitializer(forField(hasName("i")))),
Manuel Klimekba46fc02013-07-19 11:50:54 +00004088 new VerifyIdIsBoundTo<Decl>("x", 1)));
Manuel Klimeka0c025f2013-06-19 15:42:45 +00004089}
4090
Daniel Jasper33806cd2012-11-11 22:14:55 +00004091TEST(ForEachDescendant, BindsCorrectNodes) {
4092 EXPECT_TRUE(matchAndVerifyResultTrue(
4093 "class C { void f(); int i; };",
4094 recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
4095 new VerifyIdIsBoundTo<FieldDecl>("decl", 1)));
4096 EXPECT_TRUE(matchAndVerifyResultTrue(
4097 "class C { void f() {} int i; };",
4098 recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
4099 new VerifyIdIsBoundTo<FunctionDecl>("decl", 1)));
4100}
4101
Manuel Klimekabf43712013-02-04 10:59:20 +00004102TEST(FindAll, BindsNodeOnMatch) {
4103 EXPECT_TRUE(matchAndVerifyResultTrue(
4104 "class A {};",
4105 recordDecl(hasName("::A"), findAll(recordDecl(hasName("::A")).bind("v"))),
4106 new VerifyIdIsBoundTo<CXXRecordDecl>("v", 1)));
4107}
4108
4109TEST(FindAll, BindsDescendantNodeOnMatch) {
4110 EXPECT_TRUE(matchAndVerifyResultTrue(
4111 "class A { int a; int b; };",
4112 recordDecl(hasName("::A"), findAll(fieldDecl().bind("v"))),
4113 new VerifyIdIsBoundTo<FieldDecl>("v", 2)));
4114}
4115
4116TEST(FindAll, BindsNodeAndDescendantNodesOnOneMatch) {
4117 EXPECT_TRUE(matchAndVerifyResultTrue(
4118 "class A { int a; int b; };",
4119 recordDecl(hasName("::A"),
4120 findAll(decl(anyOf(recordDecl(hasName("::A")).bind("v"),
4121 fieldDecl().bind("v"))))),
4122 new VerifyIdIsBoundTo<Decl>("v", 3)));
4123
4124 EXPECT_TRUE(matchAndVerifyResultTrue(
4125 "class A { class B {}; class C {}; };",
4126 recordDecl(hasName("::A"), findAll(recordDecl(isDefinition()).bind("v"))),
4127 new VerifyIdIsBoundTo<CXXRecordDecl>("v", 3)));
4128}
4129
Manuel Klimek88b95872013-02-04 09:42:38 +00004130TEST(EachOf, TriggersForEachMatch) {
4131 EXPECT_TRUE(matchAndVerifyResultTrue(
4132 "class A { int a; int b; };",
4133 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
4134 has(fieldDecl(hasName("b")).bind("v")))),
4135 new VerifyIdIsBoundTo<FieldDecl>("v", 2)));
4136}
4137
4138TEST(EachOf, BehavesLikeAnyOfUnlessBothMatch) {
4139 EXPECT_TRUE(matchAndVerifyResultTrue(
4140 "class A { int a; int c; };",
4141 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
4142 has(fieldDecl(hasName("b")).bind("v")))),
4143 new VerifyIdIsBoundTo<FieldDecl>("v", 1)));
4144 EXPECT_TRUE(matchAndVerifyResultTrue(
4145 "class A { int c; int b; };",
4146 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
4147 has(fieldDecl(hasName("b")).bind("v")))),
4148 new VerifyIdIsBoundTo<FieldDecl>("v", 1)));
4149 EXPECT_TRUE(notMatches(
4150 "class A { int c; int d; };",
4151 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
4152 has(fieldDecl(hasName("b")).bind("v"))))));
4153}
Manuel Klimek04616e42012-07-06 05:48:52 +00004154
4155TEST(IsTemplateInstantiation, MatchesImplicitClassTemplateInstantiation) {
4156 // Make sure that we can both match the class by name (::X) and by the type
4157 // the template was instantiated with (via a field).
4158
4159 EXPECT_TRUE(matches(
4160 "template <typename T> class X {}; class A {}; X<A> x;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004161 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
Manuel Klimek04616e42012-07-06 05:48:52 +00004162
4163 EXPECT_TRUE(matches(
4164 "template <typename T> class X { T t; }; class A {}; X<A> x;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004165 cxxRecordDecl(isTemplateInstantiation(), hasDescendant(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004166 fieldDecl(hasType(recordDecl(hasName("A"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00004167}
4168
4169TEST(IsTemplateInstantiation, MatchesImplicitFunctionTemplateInstantiation) {
4170 EXPECT_TRUE(matches(
4171 "template <typename T> void f(T t) {} class A {}; void g() { f(A()); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004172 functionDecl(hasParameter(0, hasType(recordDecl(hasName("A")))),
Manuel Klimek04616e42012-07-06 05:48:52 +00004173 isTemplateInstantiation())));
4174}
4175
4176TEST(IsTemplateInstantiation, MatchesExplicitClassTemplateInstantiation) {
4177 EXPECT_TRUE(matches(
4178 "template <typename T> class X { T t; }; class A {};"
4179 "template class X<A>;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004180 cxxRecordDecl(isTemplateInstantiation(), hasDescendant(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004181 fieldDecl(hasType(recordDecl(hasName("A"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00004182}
4183
4184TEST(IsTemplateInstantiation,
4185 MatchesInstantiationOfPartiallySpecializedClassTemplate) {
4186 EXPECT_TRUE(matches(
4187 "template <typename T> class X {};"
4188 "template <typename T> class X<T*> {}; class A {}; X<A*> x;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004189 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
Manuel Klimek04616e42012-07-06 05:48:52 +00004190}
4191
4192TEST(IsTemplateInstantiation,
4193 MatchesInstantiationOfClassTemplateNestedInNonTemplate) {
4194 EXPECT_TRUE(matches(
4195 "class A {};"
4196 "class X {"
4197 " template <typename U> class Y { U u; };"
4198 " Y<A> y;"
4199 "};",
Aaron Ballman512fb642015-09-17 13:30:52 +00004200 cxxRecordDecl(hasName("::X::Y"), isTemplateInstantiation())));
Manuel Klimek04616e42012-07-06 05:48:52 +00004201}
4202
4203TEST(IsTemplateInstantiation, DoesNotMatchInstantiationsInsideOfInstantiation) {
4204 // FIXME: Figure out whether this makes sense. It doesn't affect the
4205 // normal use case as long as the uppermost instantiation always is marked
4206 // as template instantiation, but it might be confusing as a predicate.
4207 EXPECT_TRUE(matches(
4208 "class A {};"
4209 "template <typename T> class X {"
4210 " template <typename U> class Y { U u; };"
4211 " Y<T> y;"
4212 "}; X<A> x;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004213 cxxRecordDecl(hasName("::X<A>::Y"), unless(isTemplateInstantiation()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00004214}
4215
4216TEST(IsTemplateInstantiation, DoesNotMatchExplicitClassTemplateSpecialization) {
4217 EXPECT_TRUE(notMatches(
4218 "template <typename T> class X {}; class A {};"
4219 "template <> class X<A> {}; X<A> x;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004220 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
Manuel Klimek04616e42012-07-06 05:48:52 +00004221}
4222
4223TEST(IsTemplateInstantiation, DoesNotMatchNonTemplate) {
4224 EXPECT_TRUE(notMatches(
4225 "class A {}; class Y { A a; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00004226 cxxRecordDecl(isTemplateInstantiation())));
Manuel Klimek04616e42012-07-06 05:48:52 +00004227}
4228
Benjamin Kramer7ab84762014-09-03 12:08:14 +00004229TEST(IsInstantiated, MatchesInstantiation) {
4230 EXPECT_TRUE(
4231 matches("template<typename T> class A { T i; }; class Y { A<int> a; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00004232 cxxRecordDecl(isInstantiated())));
Benjamin Kramer7ab84762014-09-03 12:08:14 +00004233}
4234
4235TEST(IsInstantiated, NotMatchesDefinition) {
4236 EXPECT_TRUE(notMatches("template<typename T> class A { T i; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00004237 cxxRecordDecl(isInstantiated())));
Benjamin Kramer7ab84762014-09-03 12:08:14 +00004238}
4239
4240TEST(IsInTemplateInstantiation, MatchesInstantiationStmt) {
4241 EXPECT_TRUE(matches("template<typename T> struct A { A() { T i; } };"
4242 "class Y { A<int> a; }; Y y;",
4243 declStmt(isInTemplateInstantiation())));
4244}
4245
4246TEST(IsInTemplateInstantiation, NotMatchesDefinitionStmt) {
4247 EXPECT_TRUE(notMatches("template<typename T> struct A { void x() { T i; } };",
4248 declStmt(isInTemplateInstantiation())));
4249}
4250
4251TEST(IsInstantiated, MatchesFunctionInstantiation) {
4252 EXPECT_TRUE(
4253 matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
4254 functionDecl(isInstantiated())));
4255}
4256
4257TEST(IsInstantiated, NotMatchesFunctionDefinition) {
4258 EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
4259 varDecl(isInstantiated())));
4260}
4261
4262TEST(IsInTemplateInstantiation, MatchesFunctionInstantiationStmt) {
4263 EXPECT_TRUE(
4264 matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
4265 declStmt(isInTemplateInstantiation())));
4266}
4267
4268TEST(IsInTemplateInstantiation, NotMatchesFunctionDefinitionStmt) {
4269 EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
4270 declStmt(isInTemplateInstantiation())));
4271}
4272
4273TEST(IsInTemplateInstantiation, Sharing) {
4274 auto Matcher = binaryOperator(unless(isInTemplateInstantiation()));
4275 // FIXME: Node sharing is an implementation detail, exposing it is ugly
4276 // and makes the matcher behave in non-obvious ways.
4277 EXPECT_TRUE(notMatches(
4278 "int j; template<typename T> void A(T t) { j += 42; } void x() { A(0); }",
4279 Matcher));
4280 EXPECT_TRUE(matches(
4281 "int j; template<typename T> void A(T t) { j += t; } void x() { A(0); }",
4282 Matcher));
4283}
4284
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004285TEST(IsExplicitTemplateSpecialization,
4286 DoesNotMatchPrimaryTemplate) {
4287 EXPECT_TRUE(notMatches(
4288 "template <typename T> class X {};",
Aaron Ballman512fb642015-09-17 13:30:52 +00004289 cxxRecordDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004290 EXPECT_TRUE(notMatches(
4291 "template <typename T> void f(T t);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004292 functionDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004293}
4294
4295TEST(IsExplicitTemplateSpecialization,
4296 DoesNotMatchExplicitTemplateInstantiations) {
4297 EXPECT_TRUE(notMatches(
4298 "template <typename T> class X {};"
4299 "template class X<int>; extern template class X<long>;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004300 cxxRecordDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004301 EXPECT_TRUE(notMatches(
4302 "template <typename T> void f(T t) {}"
4303 "template void f(int t); extern template void f(long t);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004304 functionDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004305}
4306
4307TEST(IsExplicitTemplateSpecialization,
4308 DoesNotMatchImplicitTemplateInstantiations) {
4309 EXPECT_TRUE(notMatches(
4310 "template <typename T> class X {}; X<int> x;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004311 cxxRecordDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004312 EXPECT_TRUE(notMatches(
4313 "template <typename T> void f(T t); void g() { f(10); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004314 functionDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004315}
4316
4317TEST(IsExplicitTemplateSpecialization,
4318 MatchesExplicitTemplateSpecializations) {
4319 EXPECT_TRUE(matches(
4320 "template <typename T> class X {};"
4321 "template<> class X<int> {};",
Aaron Ballman512fb642015-09-17 13:30:52 +00004322 cxxRecordDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004323 EXPECT_TRUE(matches(
4324 "template <typename T> void f(T t) {}"
4325 "template<> void f(int t) {}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004326 functionDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004327}
4328
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004329TEST(HasAncenstor, MatchesDeclarationAncestors) {
4330 EXPECT_TRUE(matches(
4331 "class A { class B { class C {}; }; };",
4332 recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("A"))))));
4333}
4334
4335TEST(HasAncenstor, FailsIfNoAncestorMatches) {
4336 EXPECT_TRUE(notMatches(
4337 "class A { class B { class C {}; }; };",
4338 recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("X"))))));
4339}
4340
4341TEST(HasAncestor, MatchesDeclarationsThatGetVisitedLater) {
4342 EXPECT_TRUE(matches(
4343 "class A { class B { void f() { C c; } class C {}; }; };",
4344 varDecl(hasName("c"), hasType(recordDecl(hasName("C"),
4345 hasAncestor(recordDecl(hasName("A"))))))));
4346}
4347
4348TEST(HasAncenstor, MatchesStatementAncestors) {
4349 EXPECT_TRUE(matches(
4350 "void f() { if (true) { while (false) { 42; } } }",
Daniel Jasper848cbe12012-09-18 13:09:13 +00004351 integerLiteral(equals(42), hasAncestor(ifStmt()))));
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004352}
4353
4354TEST(HasAncestor, DrillsThroughDifferentHierarchies) {
4355 EXPECT_TRUE(matches(
4356 "void f() { if (true) { int x = 42; } }",
Daniel Jasper848cbe12012-09-18 13:09:13 +00004357 integerLiteral(equals(42), hasAncestor(functionDecl(hasName("f"))))));
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004358}
4359
4360TEST(HasAncestor, BindsRecursiveCombinations) {
4361 EXPECT_TRUE(matchAndVerifyResultTrue(
4362 "class C { class D { class E { class F { int y; }; }; }; };",
4363 fieldDecl(hasAncestor(recordDecl(hasAncestor(recordDecl().bind("r"))))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00004364 new VerifyIdIsBoundTo<CXXRecordDecl>("r", 1)));
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004365}
4366
4367TEST(HasAncestor, BindsCombinationsWithHasDescendant) {
4368 EXPECT_TRUE(matchAndVerifyResultTrue(
4369 "class C { class D { class E { class F { int y; }; }; }; };",
4370 fieldDecl(hasAncestor(
4371 decl(
4372 hasDescendant(recordDecl(isDefinition(),
4373 hasAncestor(recordDecl())))
4374 ).bind("d")
4375 )),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00004376 new VerifyIdIsBoundTo<CXXRecordDecl>("d", "E")));
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004377}
4378
Manuel Klimekb64d6b72013-03-14 16:33:21 +00004379TEST(HasAncestor, MatchesClosestAncestor) {
4380 EXPECT_TRUE(matchAndVerifyResultTrue(
4381 "template <typename T> struct C {"
4382 " void f(int) {"
4383 " struct I { void g(T) { int x; } } i; i.g(42);"
4384 " }"
4385 "};"
4386 "template struct C<int>;",
4387 varDecl(hasName("x"),
4388 hasAncestor(functionDecl(hasParameter(
4389 0, varDecl(hasType(asString("int"))))).bind("f"))).bind("v"),
4390 new VerifyIdIsBoundTo<FunctionDecl>("f", "g", 2)));
4391}
4392
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004393TEST(HasAncestor, MatchesInTemplateInstantiations) {
4394 EXPECT_TRUE(matches(
4395 "template <typename T> struct A { struct B { struct C { T t; }; }; }; "
4396 "A<int>::B::C a;",
4397 fieldDecl(hasType(asString("int")),
4398 hasAncestor(recordDecl(hasName("A"))))));
4399}
4400
4401TEST(HasAncestor, MatchesInImplicitCode) {
4402 EXPECT_TRUE(matches(
4403 "struct X {}; struct A { A() {} X x; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00004404 cxxConstructorDecl(
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004405 hasAnyConstructorInitializer(withInitializer(expr(
4406 hasAncestor(recordDecl(hasName("A")))))))));
4407}
4408
Daniel Jasper632aea92012-10-22 16:26:51 +00004409TEST(HasParent, MatchesOnlyParent) {
4410 EXPECT_TRUE(matches(
4411 "void f() { if (true) { int x = 42; } }",
4412 compoundStmt(hasParent(ifStmt()))));
4413 EXPECT_TRUE(notMatches(
4414 "void f() { for (;;) { int x = 42; } }",
4415 compoundStmt(hasParent(ifStmt()))));
4416 EXPECT_TRUE(notMatches(
4417 "void f() { if (true) for (;;) { int x = 42; } }",
4418 compoundStmt(hasParent(ifStmt()))));
4419}
4420
Manuel Klimekc844a462012-12-06 14:42:48 +00004421TEST(HasAncestor, MatchesAllAncestors) {
4422 EXPECT_TRUE(matches(
4423 "template <typename T> struct C { static void f() { 42; } };"
4424 "void t() { C<int>::f(); }",
4425 integerLiteral(
4426 equals(42),
Aaron Ballman512fb642015-09-17 13:30:52 +00004427 allOf(
4428 hasAncestor(cxxRecordDecl(isTemplateInstantiation())),
4429 hasAncestor(cxxRecordDecl(unless(isTemplateInstantiation())))))));
Manuel Klimekc844a462012-12-06 14:42:48 +00004430}
4431
Nico Weberc4acee32016-01-22 15:11:54 +00004432TEST(HasAncestor, ImplicitArrayCopyCtorDeclRefExpr) {
4433 EXPECT_TRUE(matches("struct MyClass {\n"
4434 " int c[1];\n"
4435 " static MyClass Create() { return MyClass(); }\n"
4436 "};",
4437 declRefExpr(to(decl(hasAncestor(decl()))))));
4438}
4439
Nico Weber7b837f52016-01-28 19:25:00 +00004440TEST(HasAncestor, AnonymousUnionMemberExpr) {
4441 EXPECT_TRUE(matches("int F() {\n"
4442 " union { int i; };\n"
4443 " return i;\n"
4444 "}\n",
4445 memberExpr(member(hasAncestor(decl())))));
4446 EXPECT_TRUE(matches("void f() {\n"
4447 " struct {\n"
4448 " struct { int a; int b; };\n"
4449 " } s;\n"
4450 " s.a = 4;\n"
4451 "}\n",
4452 memberExpr(member(hasAncestor(decl())))));
4453 EXPECT_TRUE(matches("void f() {\n"
4454 " struct {\n"
4455 " struct { int a; int b; };\n"
4456 " } s;\n"
4457 " s.a = 4;\n"
4458 "}\n",
4459 declRefExpr(to(decl(hasAncestor(decl()))))));
4460}
4461
Nico Weberc0973372016-02-01 22:31:51 +00004462TEST(HasAncestor, NonParmDependentTemplateParmVarDeclRefExpr) {
4463 EXPECT_TRUE(matches("struct PartitionAllocator {\n"
4464 " template<typename T>\n"
4465 " static int quantizedSize(int count) {\n"
4466 " return count;\n"
4467 " }\n"
4468 " void f() { quantizedSize<int>(10); }\n"
4469 "};",
4470 declRefExpr(to(decl(hasAncestor(decl()))))));
4471}
4472
Nico Weber26911c72016-02-08 22:23:09 +00004473TEST(HasAncestor, AddressOfExplicitSpecializationFunction) {
4474 EXPECT_TRUE(matches("template <class T> void f();\n"
4475 "template <> void f<int>();\n"
4476 "void (*get_f())() { return f<int>; }\n",
4477 declRefExpr(to(decl(hasAncestor(decl()))))));
4478}
4479
Manuel Klimekc844a462012-12-06 14:42:48 +00004480TEST(HasParent, MatchesAllParents) {
4481 EXPECT_TRUE(matches(
4482 "template <typename T> struct C { static void f() { 42; } };"
4483 "void t() { C<int>::f(); }",
4484 integerLiteral(
4485 equals(42),
4486 hasParent(compoundStmt(hasParent(functionDecl(
Aaron Ballman512fb642015-09-17 13:30:52 +00004487 hasParent(cxxRecordDecl(isTemplateInstantiation())))))))));
4488 EXPECT_TRUE(
4489 matches("template <typename T> struct C { static void f() { 42; } };"
4490 "void t() { C<int>::f(); }",
4491 integerLiteral(
4492 equals(42),
4493 hasParent(compoundStmt(hasParent(functionDecl(hasParent(
4494 cxxRecordDecl(unless(isTemplateInstantiation()))))))))));
Manuel Klimekc844a462012-12-06 14:42:48 +00004495 EXPECT_TRUE(matches(
4496 "template <typename T> struct C { static void f() { 42; } };"
4497 "void t() { C<int>::f(); }",
4498 integerLiteral(equals(42),
Aaron Ballman512fb642015-09-17 13:30:52 +00004499 hasParent(compoundStmt(
4500 allOf(hasParent(functionDecl(hasParent(
4501 cxxRecordDecl(isTemplateInstantiation())))),
4502 hasParent(functionDecl(hasParent(cxxRecordDecl(
4503 unless(isTemplateInstantiation())))))))))));
Manuel Klimekb64d6b72013-03-14 16:33:21 +00004504 EXPECT_TRUE(
4505 notMatches("template <typename T> struct C { static void f() {} };"
4506 "void t() { C<int>::f(); }",
4507 compoundStmt(hasParent(recordDecl()))));
Manuel Klimekc844a462012-12-06 14:42:48 +00004508}
4509
Samuel Benzaquen3ca0a7b2014-06-13 13:31:40 +00004510TEST(HasParent, NoDuplicateParents) {
4511 class HasDuplicateParents : public BoundNodesCallback {
4512 public:
4513 bool run(const BoundNodes *Nodes) override { return false; }
4514 bool run(const BoundNodes *Nodes, ASTContext *Context) override {
4515 const Stmt *Node = Nodes->getNodeAs<Stmt>("node");
4516 std::set<const void *> Parents;
4517 for (const auto &Parent : Context->getParents(*Node)) {
4518 if (!Parents.insert(Parent.getMemoizationData()).second) {
4519 return true;
4520 }
4521 }
4522 return false;
4523 }
4524 };
4525 EXPECT_FALSE(matchAndVerifyResultTrue(
4526 "template <typename T> int Foo() { return 1 + 2; }\n"
4527 "int x = Foo<int>() + Foo<unsigned>();",
4528 stmt().bind("node"), new HasDuplicateParents()));
4529}
4530
Daniel Jasper516b02e2012-10-17 08:52:59 +00004531TEST(TypeMatching, MatchesTypes) {
4532 EXPECT_TRUE(matches("struct S {};", qualType().bind("loc")));
4533}
4534
Samuel Benzaquenbd3232a2015-12-22 20:06:40 +00004535TEST(TypeMatching, MatchesBool) {
4536 EXPECT_TRUE(matches("struct S { bool func(); };",
4537 cxxMethodDecl(returns(booleanType()))));
4538 EXPECT_TRUE(notMatches("struct S { void func(); };",
4539 cxxMethodDecl(returns(booleanType()))));
4540}
4541
Samuel Benzaquenb405c082014-12-15 15:09:22 +00004542TEST(TypeMatching, MatchesVoid) {
Aaron Ballman512fb642015-09-17 13:30:52 +00004543 EXPECT_TRUE(matches("struct S { void func(); };",
4544 cxxMethodDecl(returns(voidType()))));
Samuel Benzaquenb405c082014-12-15 15:09:22 +00004545}
4546
Aaron Ballmaneb7e5d92016-02-18 16:36:01 +00004547TEST(TypeMatching, MatchesRealFloats) {
4548 EXPECT_TRUE(matches("struct S { float func(); };",
4549 cxxMethodDecl(returns(realFloatingPointType()))));
4550 EXPECT_TRUE(notMatches("struct S { int func(); };",
4551 cxxMethodDecl(returns(realFloatingPointType()))));
4552 EXPECT_TRUE(matches("struct S { long double func(); };",
4553 cxxMethodDecl(returns(realFloatingPointType()))));
4554}
4555
Daniel Jasper516b02e2012-10-17 08:52:59 +00004556TEST(TypeMatching, MatchesArrayTypes) {
4557 EXPECT_TRUE(matches("int a[] = {2,3};", arrayType()));
4558 EXPECT_TRUE(matches("int a[42];", arrayType()));
4559 EXPECT_TRUE(matches("void f(int b) { int a[b]; }", arrayType()));
4560
4561 EXPECT_TRUE(notMatches("struct A {}; A a[7];",
4562 arrayType(hasElementType(builtinType()))));
4563
4564 EXPECT_TRUE(matches(
4565 "int const a[] = { 2, 3 };",
4566 qualType(arrayType(hasElementType(builtinType())))));
4567 EXPECT_TRUE(matches(
4568 "int const a[] = { 2, 3 };",
4569 qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
4570 EXPECT_TRUE(matches(
4571 "typedef const int T; T x[] = { 1, 2 };",
4572 qualType(isConstQualified(), arrayType())));
4573
4574 EXPECT_TRUE(notMatches(
4575 "int a[] = { 2, 3 };",
4576 qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
4577 EXPECT_TRUE(notMatches(
4578 "int a[] = { 2, 3 };",
4579 qualType(arrayType(hasElementType(isConstQualified(), builtinType())))));
4580 EXPECT_TRUE(notMatches(
4581 "int const a[] = { 2, 3 };",
4582 qualType(arrayType(hasElementType(builtinType())),
4583 unless(isConstQualified()))));
4584
4585 EXPECT_TRUE(matches("int a[2];",
4586 constantArrayType(hasElementType(builtinType()))));
4587 EXPECT_TRUE(matches("const int a = 0;", qualType(isInteger())));
4588}
4589
Matthias Gehre2cf7e802015-10-12 21:46:07 +00004590TEST(TypeMatching, DecayedType) {
4591 EXPECT_TRUE(matches("void f(int i[]);", valueDecl(hasType(decayedType(hasDecayedType(pointerType()))))));
4592 EXPECT_TRUE(notMatches("int i[7];", decayedType()));
4593}
4594
Daniel Jasper516b02e2012-10-17 08:52:59 +00004595TEST(TypeMatching, MatchesComplexTypes) {
4596 EXPECT_TRUE(matches("_Complex float f;", complexType()));
4597 EXPECT_TRUE(matches(
4598 "_Complex float f;",
4599 complexType(hasElementType(builtinType()))));
4600 EXPECT_TRUE(notMatches(
4601 "_Complex float f;",
4602 complexType(hasElementType(isInteger()))));
4603}
4604
4605TEST(TypeMatching, MatchesConstantArrayTypes) {
4606 EXPECT_TRUE(matches("int a[2];", constantArrayType()));
4607 EXPECT_TRUE(notMatches(
4608 "void f() { int a[] = { 2, 3 }; int b[a[0]]; }",
4609 constantArrayType(hasElementType(builtinType()))));
4610
4611 EXPECT_TRUE(matches("int a[42];", constantArrayType(hasSize(42))));
4612 EXPECT_TRUE(matches("int b[2*21];", constantArrayType(hasSize(42))));
4613 EXPECT_TRUE(notMatches("int c[41], d[43];", constantArrayType(hasSize(42))));
4614}
4615
4616TEST(TypeMatching, MatchesDependentSizedArrayTypes) {
4617 EXPECT_TRUE(matches(
4618 "template <typename T, int Size> class array { T data[Size]; };",
4619 dependentSizedArrayType()));
4620 EXPECT_TRUE(notMatches(
4621 "int a[42]; int b[] = { 2, 3 }; void f() { int c[b[0]]; }",
4622 dependentSizedArrayType()));
4623}
4624
4625TEST(TypeMatching, MatchesIncompleteArrayType) {
4626 EXPECT_TRUE(matches("int a[] = { 2, 3 };", incompleteArrayType()));
4627 EXPECT_TRUE(matches("void f(int a[]) {}", incompleteArrayType()));
4628
4629 EXPECT_TRUE(notMatches("int a[42]; void f() { int b[a[0]]; }",
4630 incompleteArrayType()));
4631}
4632
4633TEST(TypeMatching, MatchesVariableArrayType) {
4634 EXPECT_TRUE(matches("void f(int b) { int a[b]; }", variableArrayType()));
4635 EXPECT_TRUE(notMatches("int a[] = {2, 3}; int b[42];", variableArrayType()));
4636
4637 EXPECT_TRUE(matches(
4638 "void f(int b) { int a[b]; }",
4639 variableArrayType(hasSizeExpr(ignoringImpCasts(declRefExpr(to(
4640 varDecl(hasName("b")))))))));
4641}
4642
4643TEST(TypeMatching, MatchesAtomicTypes) {
David Majnemer197e2102014-03-05 06:32:38 +00004644 if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getOS() !=
4645 llvm::Triple::Win32) {
4646 // FIXME: Make this work for MSVC.
4647 EXPECT_TRUE(matches("_Atomic(int) i;", atomicType()));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004648
David Majnemer197e2102014-03-05 06:32:38 +00004649 EXPECT_TRUE(matches("_Atomic(int) i;",
4650 atomicType(hasValueType(isInteger()))));
4651 EXPECT_TRUE(notMatches("_Atomic(float) f;",
4652 atomicType(hasValueType(isInteger()))));
4653 }
Daniel Jasper516b02e2012-10-17 08:52:59 +00004654}
4655
4656TEST(TypeMatching, MatchesAutoTypes) {
4657 EXPECT_TRUE(matches("auto i = 2;", autoType()));
4658 EXPECT_TRUE(matches("int v[] = { 2, 3 }; void f() { for (int i : v) {} }",
4659 autoType()));
4660
Richard Smith061f1e22013-04-30 21:23:01 +00004661 // FIXME: Matching against the type-as-written can't work here, because the
4662 // type as written was not deduced.
4663 //EXPECT_TRUE(matches("auto a = 1;",
4664 // autoType(hasDeducedType(isInteger()))));
4665 //EXPECT_TRUE(notMatches("auto b = 2.0;",
4666 // autoType(hasDeducedType(isInteger()))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004667}
4668
Daniel Jasperd29d5fa2012-10-29 10:14:44 +00004669TEST(TypeMatching, MatchesFunctionTypes) {
4670 EXPECT_TRUE(matches("int (*f)(int);", functionType()));
4671 EXPECT_TRUE(matches("void f(int i) {}", functionType()));
4672}
4673
Aaron Ballman7e7b7b22016-02-01 14:11:47 +00004674TEST(TypeMatching, MatchesFunctionProtoTypes) {
4675 EXPECT_TRUE(matches("int (*f)(int);", functionProtoType()));
4676 EXPECT_TRUE(matches("void f(int i);", functionProtoType()));
4677 EXPECT_TRUE(matches("void f();", functionProtoType(parameterCountIs(0))));
4678 EXPECT_TRUE(notMatchesC("void f();", functionProtoType()));
4679 EXPECT_TRUE(
4680 matchesC("void f(void);", functionProtoType(parameterCountIs(0))));
4681}
4682
Edwin Vaneec074802013-04-01 18:33:34 +00004683TEST(TypeMatching, MatchesParenType) {
4684 EXPECT_TRUE(
4685 matches("int (*array)[4];", varDecl(hasType(pointsTo(parenType())))));
4686 EXPECT_TRUE(notMatches("int *array[4];", varDecl(hasType(parenType()))));
4687
4688 EXPECT_TRUE(matches(
4689 "int (*ptr_to_func)(int);",
4690 varDecl(hasType(pointsTo(parenType(innerType(functionType())))))));
4691 EXPECT_TRUE(notMatches(
4692 "int (*ptr_to_array)[4];",
4693 varDecl(hasType(pointsTo(parenType(innerType(functionType())))))));
4694}
4695
Daniel Jasper516b02e2012-10-17 08:52:59 +00004696TEST(TypeMatching, PointerTypes) {
Daniel Jasper7943eb52012-10-17 13:35:36 +00004697 // FIXME: Reactive when these tests can be more specific (not matching
4698 // implicit code on certain platforms), likely when we have hasDescendant for
4699 // Types/TypeLocs.
4700 //EXPECT_TRUE(matchAndVerifyResultTrue(
4701 // "int* a;",
4702 // pointerTypeLoc(pointeeLoc(typeLoc().bind("loc"))),
4703 // new VerifyIdIsBoundTo<TypeLoc>("loc", 1)));
4704 //EXPECT_TRUE(matchAndVerifyResultTrue(
4705 // "int* a;",
4706 // pointerTypeLoc().bind("loc"),
4707 // new VerifyIdIsBoundTo<TypeLoc>("loc", 1)));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004708 EXPECT_TRUE(matches(
4709 "int** a;",
David Blaikieb61d0872013-02-18 19:04:16 +00004710 loc(pointerType(pointee(qualType())))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004711 EXPECT_TRUE(matches(
4712 "int** a;",
4713 loc(pointerType(pointee(pointerType())))));
4714 EXPECT_TRUE(matches(
4715 "int* b; int* * const a = &b;",
4716 loc(qualType(isConstQualified(), pointerType()))));
4717
4718 std::string Fragment = "struct A { int i; }; int A::* ptr = &A::i;";
Daniel Jasper7943eb52012-10-17 13:35:36 +00004719 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4720 hasType(blockPointerType()))));
4721 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ptr"),
4722 hasType(memberPointerType()))));
4723 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4724 hasType(pointerType()))));
4725 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4726 hasType(referenceType()))));
Edwin Vane2a760d02013-03-07 15:44:40 +00004727 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4728 hasType(lValueReferenceType()))));
4729 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4730 hasType(rValueReferenceType()))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004731
Daniel Jasper7943eb52012-10-17 13:35:36 +00004732 Fragment = "int *ptr;";
4733 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4734 hasType(blockPointerType()))));
4735 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4736 hasType(memberPointerType()))));
4737 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ptr"),
4738 hasType(pointerType()))));
4739 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4740 hasType(referenceType()))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004741
Daniel Jasper7943eb52012-10-17 13:35:36 +00004742 Fragment = "int a; int &ref = a;";
4743 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4744 hasType(blockPointerType()))));
4745 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4746 hasType(memberPointerType()))));
4747 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4748 hasType(pointerType()))));
4749 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
4750 hasType(referenceType()))));
Edwin Vane2a760d02013-03-07 15:44:40 +00004751 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
4752 hasType(lValueReferenceType()))));
4753 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4754 hasType(rValueReferenceType()))));
4755
4756 Fragment = "int &&ref = 2;";
4757 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4758 hasType(blockPointerType()))));
4759 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4760 hasType(memberPointerType()))));
4761 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4762 hasType(pointerType()))));
4763 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
4764 hasType(referenceType()))));
4765 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4766 hasType(lValueReferenceType()))));
4767 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
4768 hasType(rValueReferenceType()))));
4769}
4770
4771TEST(TypeMatching, AutoRefTypes) {
4772 std::string Fragment = "auto a = 1;"
4773 "auto b = a;"
4774 "auto &c = a;"
4775 "auto &&d = c;"
4776 "auto &&e = 2;";
4777 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("a"),
4778 hasType(referenceType()))));
4779 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("b"),
4780 hasType(referenceType()))));
4781 EXPECT_TRUE(matches(Fragment, varDecl(hasName("c"),
4782 hasType(referenceType()))));
4783 EXPECT_TRUE(matches(Fragment, varDecl(hasName("c"),
4784 hasType(lValueReferenceType()))));
4785 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("c"),
4786 hasType(rValueReferenceType()))));
4787 EXPECT_TRUE(matches(Fragment, varDecl(hasName("d"),
4788 hasType(referenceType()))));
4789 EXPECT_TRUE(matches(Fragment, varDecl(hasName("d"),
4790 hasType(lValueReferenceType()))));
4791 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("d"),
4792 hasType(rValueReferenceType()))));
4793 EXPECT_TRUE(matches(Fragment, varDecl(hasName("e"),
4794 hasType(referenceType()))));
4795 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("e"),
4796 hasType(lValueReferenceType()))));
4797 EXPECT_TRUE(matches(Fragment, varDecl(hasName("e"),
4798 hasType(rValueReferenceType()))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004799}
4800
4801TEST(TypeMatching, PointeeTypes) {
4802 EXPECT_TRUE(matches("int b; int &a = b;",
4803 referenceType(pointee(builtinType()))));
4804 EXPECT_TRUE(matches("int *a;", pointerType(pointee(builtinType()))));
4805
4806 EXPECT_TRUE(matches("int *a;",
David Blaikieb61d0872013-02-18 19:04:16 +00004807 loc(pointerType(pointee(builtinType())))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004808
4809 EXPECT_TRUE(matches(
4810 "int const *A;",
4811 pointerType(pointee(isConstQualified(), builtinType()))));
4812 EXPECT_TRUE(notMatches(
4813 "int *A;",
4814 pointerType(pointee(isConstQualified(), builtinType()))));
4815}
4816
4817TEST(TypeMatching, MatchesPointersToConstTypes) {
4818 EXPECT_TRUE(matches("int b; int * const a = &b;",
4819 loc(pointerType())));
4820 EXPECT_TRUE(matches("int b; int * const a = &b;",
David Blaikieb61d0872013-02-18 19:04:16 +00004821 loc(pointerType())));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004822 EXPECT_TRUE(matches(
4823 "int b; const int * a = &b;",
David Blaikieb61d0872013-02-18 19:04:16 +00004824 loc(pointerType(pointee(builtinType())))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004825 EXPECT_TRUE(matches(
4826 "int b; const int * a = &b;",
4827 pointerType(pointee(builtinType()))));
4828}
4829
4830TEST(TypeMatching, MatchesTypedefTypes) {
Daniel Jasper7943eb52012-10-17 13:35:36 +00004831 EXPECT_TRUE(matches("typedef int X; X a;", varDecl(hasName("a"),
4832 hasType(typedefType()))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004833}
4834
Edwin Vanef901b712013-02-25 14:49:29 +00004835TEST(TypeMatching, MatchesTemplateSpecializationType) {
Edwin Vaneb6eae142013-02-25 20:43:32 +00004836 EXPECT_TRUE(matches("template <typename T> class A{}; A<int> a;",
Edwin Vanef901b712013-02-25 14:49:29 +00004837 templateSpecializationType()));
4838}
4839
Edwin Vaneb6eae142013-02-25 20:43:32 +00004840TEST(TypeMatching, MatchesRecordType) {
4841 EXPECT_TRUE(matches("class C{}; C c;", recordType()));
Manuel Klimek59b0af62013-02-27 11:56:58 +00004842 EXPECT_TRUE(matches("struct S{}; S s;",
4843 recordType(hasDeclaration(recordDecl(hasName("S"))))));
4844 EXPECT_TRUE(notMatches("int i;",
4845 recordType(hasDeclaration(recordDecl(hasName("S"))))));
Edwin Vaneb6eae142013-02-25 20:43:32 +00004846}
4847
4848TEST(TypeMatching, MatchesElaboratedType) {
4849 EXPECT_TRUE(matches(
4850 "namespace N {"
4851 " namespace M {"
4852 " class D {};"
4853 " }"
4854 "}"
4855 "N::M::D d;", elaboratedType()));
4856 EXPECT_TRUE(matches("class C {} c;", elaboratedType()));
4857 EXPECT_TRUE(notMatches("class C {}; C c;", elaboratedType()));
4858}
4859
4860TEST(ElaboratedTypeNarrowing, hasQualifier) {
4861 EXPECT_TRUE(matches(
4862 "namespace N {"
4863 " namespace M {"
4864 " class D {};"
4865 " }"
4866 "}"
4867 "N::M::D d;",
4868 elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
4869 EXPECT_TRUE(notMatches(
4870 "namespace M {"
4871 " class D {};"
4872 "}"
4873 "M::D d;",
4874 elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
Edwin Vane6972f6d2013-03-04 17:51:00 +00004875 EXPECT_TRUE(notMatches(
4876 "struct D {"
4877 "} d;",
4878 elaboratedType(hasQualifier(nestedNameSpecifier()))));
Edwin Vaneb6eae142013-02-25 20:43:32 +00004879}
4880
4881TEST(ElaboratedTypeNarrowing, namesType) {
4882 EXPECT_TRUE(matches(
4883 "namespace N {"
4884 " namespace M {"
4885 " class D {};"
4886 " }"
4887 "}"
4888 "N::M::D d;",
4889 elaboratedType(elaboratedType(namesType(recordType(
4890 hasDeclaration(namedDecl(hasName("D")))))))));
4891 EXPECT_TRUE(notMatches(
4892 "namespace M {"
4893 " class D {};"
4894 "}"
4895 "M::D d;",
4896 elaboratedType(elaboratedType(namesType(typedefType())))));
4897}
4898
Samuel Benzaquenf8ec4542015-08-26 16:15:59 +00004899TEST(TypeMatching, MatchesSubstTemplateTypeParmType) {
4900 const std::string code = "template <typename T>"
4901 "int F() {"
4902 " return 1 + T();"
4903 "}"
4904 "int i = F<int>();";
4905 EXPECT_FALSE(matches(code, binaryOperator(hasLHS(
4906 expr(hasType(substTemplateTypeParmType()))))));
4907 EXPECT_TRUE(matches(code, binaryOperator(hasRHS(
4908 expr(hasType(substTemplateTypeParmType()))))));
4909}
4910
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00004911TEST(NNS, MatchesNestedNameSpecifiers) {
4912 EXPECT_TRUE(matches("namespace ns { struct A {}; } ns::A a;",
4913 nestedNameSpecifier()));
4914 EXPECT_TRUE(matches("template <typename T> class A { typename T::B b; };",
4915 nestedNameSpecifier()));
4916 EXPECT_TRUE(matches("struct A { void f(); }; void A::f() {}",
4917 nestedNameSpecifier()));
Daniel Jasperc8f472c2015-12-02 13:57:46 +00004918 EXPECT_TRUE(matches("namespace a { namespace b {} } namespace ab = a::b;",
4919 nestedNameSpecifier()));
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00004920
4921 EXPECT_TRUE(matches(
4922 "struct A { static void f() {} }; void g() { A::f(); }",
4923 nestedNameSpecifier()));
4924 EXPECT_TRUE(notMatches(
4925 "struct A { static void f() {} }; void g(A* a) { a->f(); }",
4926 nestedNameSpecifier()));
4927}
4928
Daniel Jasper87c3d362012-09-20 14:12:57 +00004929TEST(NullStatement, SimpleCases) {
4930 EXPECT_TRUE(matches("void f() {int i;;}", nullStmt()));
4931 EXPECT_TRUE(notMatches("void f() {int i;}", nullStmt()));
4932}
4933
Aaron Ballman11825f22015-08-18 19:55:20 +00004934TEST(NS, Anonymous) {
4935 EXPECT_TRUE(notMatches("namespace N {}", namespaceDecl(isAnonymous())));
4936 EXPECT_TRUE(matches("namespace {}", namespaceDecl(isAnonymous())));
4937}
4938
Aaron Ballman6c79f352015-08-28 19:39:21 +00004939TEST(NS, Alias) {
4940 EXPECT_TRUE(matches("namespace test {} namespace alias = ::test;",
4941 namespaceAliasDecl(hasName("alias"))));
4942}
4943
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00004944TEST(NNS, MatchesTypes) {
4945 NestedNameSpecifierMatcher Matcher = nestedNameSpecifier(
4946 specifiesType(hasDeclaration(recordDecl(hasName("A")))));
4947 EXPECT_TRUE(matches("struct A { struct B {}; }; A::B b;", Matcher));
4948 EXPECT_TRUE(matches("struct A { struct B { struct C {}; }; }; A::B::C c;",
4949 Matcher));
4950 EXPECT_TRUE(notMatches("namespace A { struct B {}; } A::B b;", Matcher));
4951}
4952
4953TEST(NNS, MatchesNamespaceDecls) {
4954 NestedNameSpecifierMatcher Matcher = nestedNameSpecifier(
4955 specifiesNamespace(hasName("ns")));
4956 EXPECT_TRUE(matches("namespace ns { struct A {}; } ns::A a;", Matcher));
4957 EXPECT_TRUE(notMatches("namespace xx { struct A {}; } xx::A a;", Matcher));
4958 EXPECT_TRUE(notMatches("struct ns { struct A {}; }; ns::A a;", Matcher));
4959}
4960
4961TEST(NNS, BindsNestedNameSpecifiers) {
4962 EXPECT_TRUE(matchAndVerifyResultTrue(
4963 "namespace ns { struct E { struct B {}; }; } ns::E::B b;",
4964 nestedNameSpecifier(specifiesType(asString("struct ns::E"))).bind("nns"),
4965 new VerifyIdIsBoundTo<NestedNameSpecifier>("nns", "ns::struct E::")));
4966}
4967
4968TEST(NNS, BindsNestedNameSpecifierLocs) {
4969 EXPECT_TRUE(matchAndVerifyResultTrue(
4970 "namespace ns { struct B {}; } ns::B b;",
4971 loc(nestedNameSpecifier()).bind("loc"),
4972 new VerifyIdIsBoundTo<NestedNameSpecifierLoc>("loc", 1)));
4973}
4974
4975TEST(NNS, MatchesNestedNameSpecifierPrefixes) {
4976 EXPECT_TRUE(matches(
4977 "struct A { struct B { struct C {}; }; }; A::B::C c;",
4978 nestedNameSpecifier(hasPrefix(specifiesType(asString("struct A"))))));
4979 EXPECT_TRUE(matches(
4980 "struct A { struct B { struct C {}; }; }; A::B::C c;",
Daniel Jasper516b02e2012-10-17 08:52:59 +00004981 nestedNameSpecifierLoc(hasPrefix(
4982 specifiesTypeLoc(loc(qualType(asString("struct A"))))))));
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00004983}
4984
Daniel Jasper6fc34332012-10-30 15:42:00 +00004985TEST(NNS, DescendantsOfNestedNameSpecifiers) {
4986 std::string Fragment =
4987 "namespace a { struct A { struct B { struct C {}; }; }; };"
4988 "void f() { a::A::B::C c; }";
4989 EXPECT_TRUE(matches(
4990 Fragment,
4991 nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
4992 hasDescendant(nestedNameSpecifier(
4993 specifiesNamespace(hasName("a")))))));
4994 EXPECT_TRUE(notMatches(
4995 Fragment,
4996 nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
4997 has(nestedNameSpecifier(
4998 specifiesNamespace(hasName("a")))))));
4999 EXPECT_TRUE(matches(
5000 Fragment,
5001 nestedNameSpecifier(specifiesType(asString("struct a::A")),
5002 has(nestedNameSpecifier(
5003 specifiesNamespace(hasName("a")))))));
5004
5005 // Not really useful because a NestedNameSpecifier can af at most one child,
5006 // but to complete the interface.
5007 EXPECT_TRUE(matchAndVerifyResultTrue(
5008 Fragment,
5009 nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
5010 forEach(nestedNameSpecifier().bind("x"))),
5011 new VerifyIdIsBoundTo<NestedNameSpecifier>("x", 1)));
5012}
5013
5014TEST(NNS, NestedNameSpecifiersAsDescendants) {
5015 std::string Fragment =
5016 "namespace a { struct A { struct B { struct C {}; }; }; };"
5017 "void f() { a::A::B::C c; }";
5018 EXPECT_TRUE(matches(
5019 Fragment,
5020 decl(hasDescendant(nestedNameSpecifier(specifiesType(
5021 asString("struct a::A")))))));
5022 EXPECT_TRUE(matchAndVerifyResultTrue(
5023 Fragment,
5024 functionDecl(hasName("f"),
5025 forEachDescendant(nestedNameSpecifier().bind("x"))),
5026 // Nested names: a, a::A and a::A::B.
5027 new VerifyIdIsBoundTo<NestedNameSpecifier>("x", 3)));
5028}
5029
5030TEST(NNSLoc, DescendantsOfNestedNameSpecifierLocs) {
5031 std::string Fragment =
5032 "namespace a { struct A { struct B { struct C {}; }; }; };"
5033 "void f() { a::A::B::C c; }";
5034 EXPECT_TRUE(matches(
5035 Fragment,
5036 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
5037 hasDescendant(loc(nestedNameSpecifier(
5038 specifiesNamespace(hasName("a"))))))));
5039 EXPECT_TRUE(notMatches(
5040 Fragment,
5041 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
5042 has(loc(nestedNameSpecifier(
5043 specifiesNamespace(hasName("a"))))))));
5044 EXPECT_TRUE(matches(
5045 Fragment,
5046 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A"))),
5047 has(loc(nestedNameSpecifier(
5048 specifiesNamespace(hasName("a"))))))));
5049
5050 EXPECT_TRUE(matchAndVerifyResultTrue(
5051 Fragment,
5052 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
5053 forEach(nestedNameSpecifierLoc().bind("x"))),
5054 new VerifyIdIsBoundTo<NestedNameSpecifierLoc>("x", 1)));
5055}
5056
5057TEST(NNSLoc, NestedNameSpecifierLocsAsDescendants) {
5058 std::string Fragment =
5059 "namespace a { struct A { struct B { struct C {}; }; }; };"
5060 "void f() { a::A::B::C c; }";
5061 EXPECT_TRUE(matches(
5062 Fragment,
5063 decl(hasDescendant(loc(nestedNameSpecifier(specifiesType(
5064 asString("struct a::A"))))))));
5065 EXPECT_TRUE(matchAndVerifyResultTrue(
5066 Fragment,
5067 functionDecl(hasName("f"),
5068 forEachDescendant(nestedNameSpecifierLoc().bind("x"))),
5069 // Nested names: a, a::A and a::A::B.
5070 new VerifyIdIsBoundTo<NestedNameSpecifierLoc>("x", 3)));
5071}
5072
Manuel Klimek191c0932013-02-01 13:41:35 +00005073template <typename T> class VerifyMatchOnNode : public BoundNodesCallback {
Manuel Klimekc2687452012-10-24 14:47:44 +00005074public:
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005075 VerifyMatchOnNode(StringRef Id, const internal::Matcher<T> &InnerMatcher,
5076 StringRef InnerId)
5077 : Id(Id), InnerMatcher(InnerMatcher), InnerId(InnerId) {
Daniel Jaspere9aa6872012-10-29 10:48:25 +00005078 }
5079
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005080 bool run(const BoundNodes *Nodes) override { return false; }
Manuel Klimek191c0932013-02-01 13:41:35 +00005081
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005082 bool run(const BoundNodes *Nodes, ASTContext *Context) override {
Manuel Klimekc2687452012-10-24 14:47:44 +00005083 const T *Node = Nodes->getNodeAs<T>(Id);
Benjamin Kramer76645582014-07-23 11:41:44 +00005084 return selectFirst<T>(InnerId, match(InnerMatcher, *Node, *Context)) !=
5085 nullptr;
Manuel Klimekc2687452012-10-24 14:47:44 +00005086 }
5087private:
5088 std::string Id;
5089 internal::Matcher<T> InnerMatcher;
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005090 std::string InnerId;
Manuel Klimekc2687452012-10-24 14:47:44 +00005091};
5092
5093TEST(MatchFinder, CanMatchDeclarationsRecursively) {
Manuel Klimek191c0932013-02-01 13:41:35 +00005094 EXPECT_TRUE(matchAndVerifyResultTrue(
5095 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5096 new VerifyMatchOnNode<clang::Decl>(
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005097 "X", decl(hasDescendant(recordDecl(hasName("X::Y")).bind("Y"))),
5098 "Y")));
Manuel Klimek191c0932013-02-01 13:41:35 +00005099 EXPECT_TRUE(matchAndVerifyResultFalse(
5100 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5101 new VerifyMatchOnNode<clang::Decl>(
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005102 "X", decl(hasDescendant(recordDecl(hasName("X::Z")).bind("Z"))),
5103 "Z")));
Manuel Klimekc2687452012-10-24 14:47:44 +00005104}
5105
5106TEST(MatchFinder, CanMatchStatementsRecursively) {
Manuel Klimek191c0932013-02-01 13:41:35 +00005107 EXPECT_TRUE(matchAndVerifyResultTrue(
5108 "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005109 new VerifyMatchOnNode<clang::Stmt>(
5110 "if", stmt(hasDescendant(forStmt().bind("for"))), "for")));
Manuel Klimek191c0932013-02-01 13:41:35 +00005111 EXPECT_TRUE(matchAndVerifyResultFalse(
5112 "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005113 new VerifyMatchOnNode<clang::Stmt>(
5114 "if", stmt(hasDescendant(declStmt().bind("decl"))), "decl")));
Manuel Klimek191c0932013-02-01 13:41:35 +00005115}
5116
5117TEST(MatchFinder, CanMatchSingleNodesRecursively) {
5118 EXPECT_TRUE(matchAndVerifyResultTrue(
5119 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5120 new VerifyMatchOnNode<clang::Decl>(
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005121 "X", recordDecl(has(recordDecl(hasName("X::Y")).bind("Y"))), "Y")));
Manuel Klimek191c0932013-02-01 13:41:35 +00005122 EXPECT_TRUE(matchAndVerifyResultFalse(
5123 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5124 new VerifyMatchOnNode<clang::Decl>(
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005125 "X", recordDecl(has(recordDecl(hasName("X::Z")).bind("Z"))), "Z")));
Manuel Klimekc2687452012-10-24 14:47:44 +00005126}
5127
Manuel Klimekbee08572013-02-07 12:42:10 +00005128template <typename T>
5129class VerifyAncestorHasChildIsEqual : public BoundNodesCallback {
5130public:
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005131 bool run(const BoundNodes *Nodes) override { return false; }
Manuel Klimekbee08572013-02-07 12:42:10 +00005132
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005133 bool run(const BoundNodes *Nodes, ASTContext *Context) override {
Manuel Klimekbee08572013-02-07 12:42:10 +00005134 const T *Node = Nodes->getNodeAs<T>("");
5135 return verify(*Nodes, *Context, Node);
5136 }
5137
5138 bool verify(const BoundNodes &Nodes, ASTContext &Context, const Stmt *Node) {
Manuel Klimeka2c2a4f2014-05-27 12:31:10 +00005139 // Use the original typed pointer to verify we can pass pointers to subtypes
5140 // to equalsNode.
5141 const T *TypedNode = cast<T>(Node);
Benjamin Kramer76645582014-07-23 11:41:44 +00005142 return selectFirst<T>(
Manuel Klimeka2c2a4f2014-05-27 12:31:10 +00005143 "", match(stmt(hasParent(
5144 stmt(has(stmt(equalsNode(TypedNode)))).bind(""))),
Craig Topper416fa342014-06-08 08:38:12 +00005145 *Node, Context)) != nullptr;
Manuel Klimekbee08572013-02-07 12:42:10 +00005146 }
5147 bool verify(const BoundNodes &Nodes, ASTContext &Context, const Decl *Node) {
Manuel Klimeka2c2a4f2014-05-27 12:31:10 +00005148 // Use the original typed pointer to verify we can pass pointers to subtypes
5149 // to equalsNode.
5150 const T *TypedNode = cast<T>(Node);
Benjamin Kramer76645582014-07-23 11:41:44 +00005151 return selectFirst<T>(
Manuel Klimeka2c2a4f2014-05-27 12:31:10 +00005152 "", match(decl(hasParent(
5153 decl(has(decl(equalsNode(TypedNode)))).bind(""))),
Craig Topper416fa342014-06-08 08:38:12 +00005154 *Node, Context)) != nullptr;
Manuel Klimekbee08572013-02-07 12:42:10 +00005155 }
Angel Garcia Gomez4647ed72015-10-30 09:35:51 +00005156 bool verify(const BoundNodes &Nodes, ASTContext &Context, const Type *Node) {
5157 // Use the original typed pointer to verify we can pass pointers to subtypes
5158 // to equalsNode.
5159 const T *TypedNode = cast<T>(Node);
5160 const auto *Dec = Nodes.getNodeAs<FieldDecl>("decl");
5161 return selectFirst<T>(
5162 "", match(fieldDecl(hasParent(decl(has(fieldDecl(
5163 hasType(type(equalsNode(TypedNode)).bind(""))))))),
5164 *Dec, Context)) != nullptr;
5165 }
Manuel Klimekbee08572013-02-07 12:42:10 +00005166};
5167
5168TEST(IsEqualTo, MatchesNodesByIdentity) {
5169 EXPECT_TRUE(matchAndVerifyResultTrue(
5170 "class X { class Y {}; };", recordDecl(hasName("::X::Y")).bind(""),
Manuel Klimeka2c2a4f2014-05-27 12:31:10 +00005171 new VerifyAncestorHasChildIsEqual<CXXRecordDecl>()));
5172 EXPECT_TRUE(matchAndVerifyResultTrue(
5173 "void f() { if (true) if(true) {} }", ifStmt().bind(""),
5174 new VerifyAncestorHasChildIsEqual<IfStmt>()));
Angel Garcia Gomez4647ed72015-10-30 09:35:51 +00005175 EXPECT_TRUE(matchAndVerifyResultTrue(
5176 "class X { class Y {} y; };",
5177 fieldDecl(hasName("y"), hasType(type().bind(""))).bind("decl"),
5178 new VerifyAncestorHasChildIsEqual<Type>()));
Manuel Klimekbee08572013-02-07 12:42:10 +00005179}
5180
Samuel Benzaquen43dcf212014-10-22 20:31:05 +00005181TEST(MatchFinder, CheckProfiling) {
5182 MatchFinder::MatchFinderOptions Options;
5183 llvm::StringMap<llvm::TimeRecord> Records;
5184 Options.CheckProfiling.emplace(Records);
5185 MatchFinder Finder(std::move(Options));
5186
5187 struct NamedCallback : public MatchFinder::MatchCallback {
5188 void run(const MatchFinder::MatchResult &Result) override {}
5189 StringRef getID() const override { return "MyID"; }
5190 } Callback;
5191 Finder.addMatcher(decl(), &Callback);
5192 std::unique_ptr<FrontendActionFactory> Factory(
5193 newFrontendActionFactory(&Finder));
5194 ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), "int x;"));
5195
5196 EXPECT_EQ(1u, Records.size());
5197 EXPECT_EQ("MyID", Records.begin()->getKey());
5198}
5199
Manuel Klimekbd0e2b72012-11-02 01:31:03 +00005200class VerifyStartOfTranslationUnit : public MatchFinder::MatchCallback {
5201public:
5202 VerifyStartOfTranslationUnit() : Called(false) {}
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005203 void run(const MatchFinder::MatchResult &Result) override {
Manuel Klimekbd0e2b72012-11-02 01:31:03 +00005204 EXPECT_TRUE(Called);
5205 }
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005206 void onStartOfTranslationUnit() override { Called = true; }
Manuel Klimekbd0e2b72012-11-02 01:31:03 +00005207 bool Called;
5208};
5209
5210TEST(MatchFinder, InterceptsStartOfTranslationUnit) {
5211 MatchFinder Finder;
5212 VerifyStartOfTranslationUnit VerifyCallback;
5213 Finder.addMatcher(decl(), &VerifyCallback);
Ahmed Charlesb8984322014-03-07 20:03:18 +00005214 std::unique_ptr<FrontendActionFactory> Factory(
5215 newFrontendActionFactory(&Finder));
Manuel Klimekbd0e2b72012-11-02 01:31:03 +00005216 ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), "int x;"));
5217 EXPECT_TRUE(VerifyCallback.Called);
Peter Collingbournea2334162013-11-07 22:30:36 +00005218
5219 VerifyCallback.Called = false;
Ahmed Charlesb8984322014-03-07 20:03:18 +00005220 std::unique_ptr<ASTUnit> AST(tooling::buildASTFromCode("int x;"));
Peter Collingbournea2334162013-11-07 22:30:36 +00005221 ASSERT_TRUE(AST.get());
5222 Finder.matchAST(AST->getASTContext());
5223 EXPECT_TRUE(VerifyCallback.Called);
Manuel Klimekbd0e2b72012-11-02 01:31:03 +00005224}
5225
Peter Collingbourne6a55bb22013-05-28 19:21:51 +00005226class VerifyEndOfTranslationUnit : public MatchFinder::MatchCallback {
5227public:
5228 VerifyEndOfTranslationUnit() : Called(false) {}
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005229 void run(const MatchFinder::MatchResult &Result) override {
Peter Collingbourne6a55bb22013-05-28 19:21:51 +00005230 EXPECT_FALSE(Called);
5231 }
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005232 void onEndOfTranslationUnit() override { Called = true; }
Peter Collingbourne6a55bb22013-05-28 19:21:51 +00005233 bool Called;
5234};
5235
5236TEST(MatchFinder, InterceptsEndOfTranslationUnit) {
5237 MatchFinder Finder;
5238 VerifyEndOfTranslationUnit VerifyCallback;
5239 Finder.addMatcher(decl(), &VerifyCallback);
Ahmed Charlesb8984322014-03-07 20:03:18 +00005240 std::unique_ptr<FrontendActionFactory> Factory(
5241 newFrontendActionFactory(&Finder));
Peter Collingbourne6a55bb22013-05-28 19:21:51 +00005242 ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), "int x;"));
5243 EXPECT_TRUE(VerifyCallback.Called);
Peter Collingbournea2334162013-11-07 22:30:36 +00005244
5245 VerifyCallback.Called = false;
Ahmed Charlesb8984322014-03-07 20:03:18 +00005246 std::unique_ptr<ASTUnit> AST(tooling::buildASTFromCode("int x;"));
Peter Collingbournea2334162013-11-07 22:30:36 +00005247 ASSERT_TRUE(AST.get());
5248 Finder.matchAST(AST->getASTContext());
5249 EXPECT_TRUE(VerifyCallback.Called);
Peter Collingbourne6a55bb22013-05-28 19:21:51 +00005250}
5251
Daniel Jasper739ae642016-02-03 14:29:55 +00005252TEST(Matcher, matchOverEntireASTContext) {
5253 std::unique_ptr<ASTUnit> AST =
5254 clang::tooling::buildASTFromCode("struct { int *foo; };");
5255 ASSERT_TRUE(AST.get());
5256 auto PT = selectFirst<PointerType>(
5257 "x", match(pointerType().bind("x"), AST->getASTContext()));
5258 EXPECT_NE(nullptr, PT);
5259}
5260
Manuel Klimekbbb75852013-06-20 14:06:32 +00005261TEST(EqualsBoundNodeMatcher, QualType) {
5262 EXPECT_TRUE(matches(
5263 "int i = 1;", varDecl(hasType(qualType().bind("type")),
5264 hasInitializer(ignoringParenImpCasts(
5265 hasType(qualType(equalsBoundNode("type"))))))));
5266 EXPECT_TRUE(notMatches("int i = 1.f;",
5267 varDecl(hasType(qualType().bind("type")),
5268 hasInitializer(ignoringParenImpCasts(hasType(
5269 qualType(equalsBoundNode("type"))))))));
5270}
5271
5272TEST(EqualsBoundNodeMatcher, NonMatchingTypes) {
5273 EXPECT_TRUE(notMatches(
5274 "int i = 1;", varDecl(namedDecl(hasName("i")).bind("name"),
5275 hasInitializer(ignoringParenImpCasts(
5276 hasType(qualType(equalsBoundNode("type"))))))));
5277}
5278
5279TEST(EqualsBoundNodeMatcher, Stmt) {
5280 EXPECT_TRUE(
5281 matches("void f() { if(true) {} }",
5282 stmt(allOf(ifStmt().bind("if"),
5283 hasParent(stmt(has(stmt(equalsBoundNode("if")))))))));
5284
5285 EXPECT_TRUE(notMatches(
5286 "void f() { if(true) { if (true) {} } }",
5287 stmt(allOf(ifStmt().bind("if"), has(stmt(equalsBoundNode("if")))))));
5288}
5289
5290TEST(EqualsBoundNodeMatcher, Decl) {
5291 EXPECT_TRUE(matches(
5292 "class X { class Y {}; };",
5293 decl(allOf(recordDecl(hasName("::X::Y")).bind("record"),
5294 hasParent(decl(has(decl(equalsBoundNode("record")))))))));
5295
5296 EXPECT_TRUE(notMatches("class X { class Y {}; };",
5297 decl(allOf(recordDecl(hasName("::X")).bind("record"),
5298 has(decl(equalsBoundNode("record")))))));
5299}
5300
5301TEST(EqualsBoundNodeMatcher, Type) {
5302 EXPECT_TRUE(matches(
5303 "class X { int a; int b; };",
5304 recordDecl(
5305 has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
5306 has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
5307
5308 EXPECT_TRUE(notMatches(
5309 "class X { int a; double b; };",
5310 recordDecl(
5311 has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
5312 has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
5313}
5314
5315TEST(EqualsBoundNodeMatcher, UsingForEachDescendant) {
Manuel Klimekbbb75852013-06-20 14:06:32 +00005316 EXPECT_TRUE(matchAndVerifyResultTrue(
5317 "int f() {"
5318 " if (1) {"
5319 " int i = 9;"
5320 " }"
5321 " int j = 10;"
5322 " {"
5323 " float k = 9.0;"
5324 " }"
5325 " return 0;"
5326 "}",
5327 // Look for variable declarations within functions whose type is the same
5328 // as the function return type.
5329 functionDecl(returns(qualType().bind("type")),
5330 forEachDescendant(varDecl(hasType(
5331 qualType(equalsBoundNode("type")))).bind("decl"))),
5332 // Only i and j should match, not k.
5333 new VerifyIdIsBoundTo<VarDecl>("decl", 2)));
5334}
5335
5336TEST(EqualsBoundNodeMatcher, FiltersMatchedCombinations) {
5337 EXPECT_TRUE(matchAndVerifyResultTrue(
5338 "void f() {"
5339 " int x;"
5340 " double d;"
5341 " x = d + x - d + x;"
5342 "}",
5343 functionDecl(
5344 hasName("f"), forEachDescendant(varDecl().bind("d")),
5345 forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d")))))),
5346 new VerifyIdIsBoundTo<VarDecl>("d", 5)));
5347}
5348
Manuel Klimekce68f772014-03-25 14:39:26 +00005349TEST(EqualsBoundNodeMatcher, UnlessDescendantsOfAncestorsMatch) {
5350 EXPECT_TRUE(matchAndVerifyResultTrue(
5351 "struct StringRef { int size() const; const char* data() const; };"
5352 "void f(StringRef v) {"
5353 " v.data();"
5354 "}",
Aaron Ballman512fb642015-09-17 13:30:52 +00005355 cxxMemberCallExpr(
5356 callee(cxxMethodDecl(hasName("data"))),
5357 on(declRefExpr(to(
5358 varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),
5359 unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(
5360 callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
Manuel Klimekce68f772014-03-25 14:39:26 +00005361 on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
5362 .bind("data"),
5363 new VerifyIdIsBoundTo<Expr>("data", 1)));
5364
5365 EXPECT_FALSE(matches(
5366 "struct StringRef { int size() const; const char* data() const; };"
5367 "void f(StringRef v) {"
5368 " v.data();"
5369 " v.size();"
5370 "}",
Aaron Ballman512fb642015-09-17 13:30:52 +00005371 cxxMemberCallExpr(
5372 callee(cxxMethodDecl(hasName("data"))),
5373 on(declRefExpr(to(
5374 varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),
5375 unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(
5376 callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
Manuel Klimekce68f772014-03-25 14:39:26 +00005377 on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
5378 .bind("data")));
5379}
5380
Manuel Klimekd3aa1f42014-11-25 17:01:06 +00005381TEST(TypeDefDeclMatcher, Match) {
5382 EXPECT_TRUE(matches("typedef int typedefDeclTest;",
5383 typedefDecl(hasName("typedefDeclTest"))));
5384}
5385
Aaron Ballman11825f22015-08-18 19:55:20 +00005386TEST(IsInlineMatcher, IsInline) {
5387 EXPECT_TRUE(matches("void g(); inline void f();",
5388 functionDecl(isInline(), hasName("f"))));
5389 EXPECT_TRUE(matches("namespace n { inline namespace m {} }",
5390 namespaceDecl(isInline(), hasName("m"))));
5391}
5392
Aaron Ballman7e7b7b22016-02-01 14:11:47 +00005393// FIXME: Figure out how to specify paths so the following tests pass on
5394// Windows.
Manuel Klimekd3aa1f42014-11-25 17:01:06 +00005395#ifndef LLVM_ON_WIN32
5396
5397TEST(Matcher, IsExpansionInMainFileMatcher) {
5398 EXPECT_TRUE(matches("class X {};",
5399 recordDecl(hasName("X"), isExpansionInMainFile())));
5400 EXPECT_TRUE(notMatches("", recordDecl(isExpansionInMainFile())));
5401 FileContentMappings M;
5402 M.push_back(std::make_pair("/other", "class X {};"));
5403 EXPECT_TRUE(matchesConditionally("#include <other>\n",
5404 recordDecl(isExpansionInMainFile()), false,
5405 "-isystem/", M));
5406}
5407
5408TEST(Matcher, IsExpansionInSystemHeader) {
5409 FileContentMappings M;
5410 M.push_back(std::make_pair("/other", "class X {};"));
5411 EXPECT_TRUE(matchesConditionally(
5412 "#include \"other\"\n", recordDecl(isExpansionInSystemHeader()), true,
5413 "-isystem/", M));
5414 EXPECT_TRUE(matchesConditionally("#include \"other\"\n",
5415 recordDecl(isExpansionInSystemHeader()),
5416 false, "-I/", M));
5417 EXPECT_TRUE(notMatches("class X {};",
5418 recordDecl(isExpansionInSystemHeader())));
5419 EXPECT_TRUE(notMatches("", recordDecl(isExpansionInSystemHeader())));
5420}
5421
5422TEST(Matcher, IsExpansionInFileMatching) {
5423 FileContentMappings M;
5424 M.push_back(std::make_pair("/foo", "class A {};"));
5425 M.push_back(std::make_pair("/bar", "class B {};"));
5426 EXPECT_TRUE(matchesConditionally(
5427 "#include <foo>\n"
5428 "#include <bar>\n"
5429 "class X {};",
5430 recordDecl(isExpansionInFileMatching("b.*"), hasName("B")), true,
5431 "-isystem/", M));
5432 EXPECT_TRUE(matchesConditionally(
5433 "#include <foo>\n"
5434 "#include <bar>\n"
5435 "class X {};",
5436 recordDecl(isExpansionInFileMatching("f.*"), hasName("X")), false,
5437 "-isystem/", M));
5438}
5439
5440#endif // LLVM_ON_WIN32
5441
Manuel Klimekbfa43572015-03-12 15:48:15 +00005442
5443TEST(ObjCMessageExprMatcher, SimpleExprs) {
5444 // don't find ObjCMessageExpr where none are present
5445 EXPECT_TRUE(notMatchesObjC("", objcMessageExpr(anything())));
5446
5447 std::string Objc1String =
5448 "@interface Str "
5449 " - (Str *)uppercaseString:(Str *)str;"
5450 "@end "
5451 "@interface foo "
5452 "- (void)meth:(Str *)text;"
5453 "@end "
5454 " "
5455 "@implementation foo "
5456 "- (void) meth:(Str *)text { "
5457 " [self contents];"
5458 " Str *up = [text uppercaseString];"
5459 "} "
5460 "@end ";
5461 EXPECT_TRUE(matchesObjC(
5462 Objc1String,
5463 objcMessageExpr(anything())));
5464 EXPECT_TRUE(matchesObjC(
5465 Objc1String,
5466 objcMessageExpr(hasSelector("contents"))));
5467 EXPECT_TRUE(matchesObjC(
5468 Objc1String,
5469 objcMessageExpr(matchesSelector("cont*"))));
5470 EXPECT_FALSE(matchesObjC(
5471 Objc1String,
5472 objcMessageExpr(matchesSelector("?cont*"))));
5473 EXPECT_TRUE(notMatchesObjC(
5474 Objc1String,
5475 objcMessageExpr(hasSelector("contents"), hasNullSelector())));
5476 EXPECT_TRUE(matchesObjC(
5477 Objc1String,
5478 objcMessageExpr(hasSelector("contents"), hasUnarySelector())));
5479 EXPECT_TRUE(matchesObjC(
5480 Objc1String,
Manuel Klimeke67a9d62015-09-08 10:11:26 +00005481 objcMessageExpr(hasSelector("contents"), numSelectorArgs(0))));
5482 EXPECT_TRUE(matchesObjC(
5483 Objc1String,
Manuel Klimekbfa43572015-03-12 15:48:15 +00005484 objcMessageExpr(matchesSelector("uppercase*"),
5485 argumentCountIs(0)
5486 )));
Manuel Klimekbfa43572015-03-12 15:48:15 +00005487}
5488
Aaron Ballman232e63d2016-02-16 21:02:23 +00005489TEST(NullPointerConstants, Basic) {
5490 EXPECT_TRUE(matches("#define NULL ((void *)0)\n"
5491 "void *v1 = NULL;", expr(nullPointerConstant())));
5492 EXPECT_TRUE(matches("void *v2 = nullptr;", expr(nullPointerConstant())));
5493 EXPECT_TRUE(matches("void *v3 = __null;", expr(nullPointerConstant())));
5494 EXPECT_TRUE(matches("char *cp = (char *)0;", expr(nullPointerConstant())));
5495 EXPECT_TRUE(matches("int *ip = 0;", expr(nullPointerConstant())));
Aaron Ballmancc928c82016-02-16 21:06:10 +00005496 EXPECT_TRUE(notMatches("int i = 0;", expr(nullPointerConstant())));
Aaron Ballman232e63d2016-02-16 21:02:23 +00005497}
5498
Alexander Kornienko976921d2016-03-22 11:03:03 +00005499TEST(StatementMatcher, HasReturnValue) {
5500 StatementMatcher RetVal = returnStmt(hasReturnValue(binaryOperator()));
5501 EXPECT_TRUE(matches("int F() { int a, b; return a + b; }", RetVal));
5502 EXPECT_FALSE(matches("int F() { int a; return a; }", RetVal));
5503}
5504
Manuel Klimek04616e42012-07-06 05:48:52 +00005505} // end namespace ast_matchers
5506} // end namespace clang