blob: 7d5cba90862fb515cf58eec3aea0c9bff44f3ee1 [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
Aaron Ballman66eb58a2016-04-14 16:05:45 +00001104TEST(HasType, MatchesTypedefNameDecl) {
1105 EXPECT_TRUE(matches("using X = int;", typedefNameDecl(hasType(asString("int")))));
1106 EXPECT_TRUE(matches("using T = const int;",
1107 typedefNameDecl(hasType(asString("const int")))));
1108 EXPECT_TRUE(notMatches("using T = const int;",
1109 typedefNameDecl(hasType(asString("int")))));
1110 EXPECT_TRUE(matches("using foo = int; using bar = foo;",
1111 typedefNameDecl(hasType(asString("foo")), hasName("bar"))));
1112}
1113
Manuel Klimekc16c6522013-06-20 13:08:29 +00001114TEST(HasTypeLoc, MatchesDeclaratorDecls) {
1115 EXPECT_TRUE(matches("int x;",
1116 varDecl(hasName("x"), hasTypeLoc(loc(asString("int"))))));
1117
1118 // Make sure we don't crash on implicit constructors.
1119 EXPECT_TRUE(notMatches("class X {}; X x;",
1120 declaratorDecl(hasTypeLoc(loc(asString("int"))))));
1121}
1122
Manuel Klimek04616e42012-07-06 05:48:52 +00001123TEST(Matcher, Call) {
1124 // FIXME: Do we want to overload Call() to directly take
Daniel Jasper1dad1832012-07-10 20:20:19 +00001125 // Matcher<Decl>, too?
Aaron Ballman512fb642015-09-17 13:30:52 +00001126 StatementMatcher MethodX =
1127 callExpr(hasDeclaration(cxxMethodDecl(hasName("x"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001128
1129 EXPECT_TRUE(matches("class Y { void x() { x(); } };", MethodX));
1130 EXPECT_TRUE(notMatches("class Y { void x() {} };", MethodX));
1131
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001132 StatementMatcher MethodOnY =
Aaron Ballman512fb642015-09-17 13:30:52 +00001133 cxxMemberCallExpr(on(hasType(recordDecl(hasName("Y")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001134
1135 EXPECT_TRUE(
1136 matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
1137 MethodOnY));
1138 EXPECT_TRUE(
1139 matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
1140 MethodOnY));
1141 EXPECT_TRUE(
1142 notMatches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
1143 MethodOnY));
1144 EXPECT_TRUE(
1145 notMatches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
1146 MethodOnY));
1147 EXPECT_TRUE(
1148 notMatches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
1149 MethodOnY));
1150
1151 StatementMatcher MethodOnYPointer =
Aaron Ballman512fb642015-09-17 13:30:52 +00001152 cxxMemberCallExpr(on(hasType(pointsTo(recordDecl(hasName("Y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001153
1154 EXPECT_TRUE(
1155 matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
1156 MethodOnYPointer));
1157 EXPECT_TRUE(
1158 matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
1159 MethodOnYPointer));
1160 EXPECT_TRUE(
1161 matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
1162 MethodOnYPointer));
1163 EXPECT_TRUE(
1164 notMatches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
1165 MethodOnYPointer));
1166 EXPECT_TRUE(
1167 notMatches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
1168 MethodOnYPointer));
1169}
1170
Daniel Jasper5901e472012-10-01 13:40:41 +00001171TEST(Matcher, Lambda) {
Richard Smith3d584b02014-02-06 21:49:08 +00001172 EXPECT_TRUE(matches("auto f = [] (int i) { return i; };",
Daniel Jasper5901e472012-10-01 13:40:41 +00001173 lambdaExpr()));
1174}
1175
1176TEST(Matcher, ForRange) {
Daniel Jasper6f595392012-10-01 15:05:34 +00001177 EXPECT_TRUE(matches("int as[] = { 1, 2, 3 };"
1178 "void f() { for (auto &a : as); }",
Aaron Ballman512fb642015-09-17 13:30:52 +00001179 cxxForRangeStmt()));
Daniel Jasper5901e472012-10-01 13:40:41 +00001180 EXPECT_TRUE(notMatches("void f() { for (int i; i<5; ++i); }",
Aaron Ballman512fb642015-09-17 13:30:52 +00001181 cxxForRangeStmt()));
Daniel Jasper5901e472012-10-01 13:40:41 +00001182}
1183
Alexander Kornienko9e41b5c2014-06-29 22:18:53 +00001184TEST(Matcher, SubstNonTypeTemplateParm) {
1185 EXPECT_FALSE(matches("template<int N>\n"
1186 "struct A { static const int n = 0; };\n"
1187 "struct B : public A<42> {};",
1188 substNonTypeTemplateParmExpr()));
1189 EXPECT_TRUE(matches("template<int N>\n"
1190 "struct A { static const int n = N; };\n"
1191 "struct B : public A<42> {};",
1192 substNonTypeTemplateParmExpr()));
1193}
1194
Aaron Ballman478a8eb2015-10-05 19:44:42 +00001195TEST(Matcher, NonTypeTemplateParmDecl) {
1196 EXPECT_TRUE(matches("template <int N> void f();",
1197 nonTypeTemplateParmDecl(hasName("N"))));
1198 EXPECT_TRUE(
1199 notMatches("template <typename T> void f();", nonTypeTemplateParmDecl()));
1200}
1201
Eric Fiselier3acf5fd2015-10-17 02:34:44 +00001202TEST(Matcher, templateTypeParmDecl) {
1203 EXPECT_TRUE(matches("template <typename T> void f();",
1204 templateTypeParmDecl(hasName("T"))));
1205 EXPECT_TRUE(
1206 notMatches("template <int N> void f();", templateTypeParmDecl()));
1207}
1208
Daniel Jasper5901e472012-10-01 13:40:41 +00001209TEST(Matcher, UserDefinedLiteral) {
1210 EXPECT_TRUE(matches("constexpr char operator \"\" _inc (const char i) {"
1211 " return i + 1;"
1212 "}"
1213 "char c = 'a'_inc;",
1214 userDefinedLiteral()));
1215}
1216
Daniel Jasper87c3d362012-09-20 14:12:57 +00001217TEST(Matcher, FlowControl) {
1218 EXPECT_TRUE(matches("void f() { while(true) { break; } }", breakStmt()));
1219 EXPECT_TRUE(matches("void f() { while(true) { continue; } }",
1220 continueStmt()));
1221 EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}", gotoStmt()));
Aaron Ballmana35b8fc2016-03-09 17:11:51 +00001222 EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}",
1223 labelStmt(
1224 hasDeclaration(
1225 labelDecl(hasName("FOO"))))));
1226 EXPECT_TRUE(matches("void f() { FOO: ; void *ptr = &&FOO; goto *ptr; }",
1227 addrLabelExpr()));
Daniel Jasper87c3d362012-09-20 14:12:57 +00001228 EXPECT_TRUE(matches("void f() { return; }", returnStmt()));
1229}
1230
Daniel Jasper1dad1832012-07-10 20:20:19 +00001231TEST(HasType, MatchesAsString) {
1232 EXPECT_TRUE(
1233 matches("class Y { public: void x(); }; void z() {Y* y; y->x(); }",
Aaron Ballman512fb642015-09-17 13:30:52 +00001234 cxxMemberCallExpr(on(hasType(asString("class Y *"))))));
1235 EXPECT_TRUE(
1236 matches("class X { void x(int x) {} };",
1237 cxxMethodDecl(hasParameter(0, hasType(asString("int"))))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001238 EXPECT_TRUE(matches("namespace ns { struct A {}; } struct B { ns::A a; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001239 fieldDecl(hasType(asString("ns::A")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001240 EXPECT_TRUE(matches("namespace { struct A {}; } struct B { A a; };",
David Blaikieabe1a392014-04-02 05:58:29 +00001241 fieldDecl(hasType(asString("struct (anonymous namespace)::A")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001242}
1243
Manuel Klimek04616e42012-07-06 05:48:52 +00001244TEST(Matcher, OverloadedOperatorCall) {
Aaron Ballman512fb642015-09-17 13:30:52 +00001245 StatementMatcher OpCall = cxxOperatorCallExpr();
Manuel Klimek04616e42012-07-06 05:48:52 +00001246 // Unary operator
1247 EXPECT_TRUE(matches("class Y { }; "
1248 "bool operator!(Y x) { return false; }; "
1249 "Y y; bool c = !y;", OpCall));
1250 // No match -- special operators like "new", "delete"
1251 // FIXME: operator new takes size_t, for which we need stddef.h, for which
1252 // we need to figure out include paths in the test.
1253 // EXPECT_TRUE(NotMatches("#include <stddef.h>\n"
1254 // "class Y { }; "
1255 // "void *operator new(size_t size) { return 0; } "
1256 // "Y *y = new Y;", OpCall));
1257 EXPECT_TRUE(notMatches("class Y { }; "
1258 "void operator delete(void *p) { } "
1259 "void a() {Y *y = new Y; delete y;}", OpCall));
1260 // Binary operator
1261 EXPECT_TRUE(matches("class Y { }; "
1262 "bool operator&&(Y x, Y y) { return true; }; "
1263 "Y a; Y b; bool c = a && b;",
1264 OpCall));
1265 // No match -- normal operator, not an overloaded one.
1266 EXPECT_TRUE(notMatches("bool x = true, y = true; bool t = x && y;", OpCall));
1267 EXPECT_TRUE(notMatches("int t = 5 << 2;", OpCall));
1268}
1269
1270TEST(Matcher, HasOperatorNameForOverloadedOperatorCall) {
1271 StatementMatcher OpCallAndAnd =
Aaron Ballman512fb642015-09-17 13:30:52 +00001272 cxxOperatorCallExpr(hasOverloadedOperatorName("&&"));
Manuel Klimek04616e42012-07-06 05:48:52 +00001273 EXPECT_TRUE(matches("class Y { }; "
1274 "bool operator&&(Y x, Y y) { return true; }; "
1275 "Y a; Y b; bool c = a && b;", OpCallAndAnd));
1276 StatementMatcher OpCallLessLess =
Aaron Ballman512fb642015-09-17 13:30:52 +00001277 cxxOperatorCallExpr(hasOverloadedOperatorName("<<"));
Manuel Klimek04616e42012-07-06 05:48:52 +00001278 EXPECT_TRUE(notMatches("class Y { }; "
1279 "bool operator&&(Y x, Y y) { return true; }; "
1280 "Y a; Y b; bool c = a && b;",
1281 OpCallLessLess));
Benjamin Kramer09514492014-07-14 14:05:02 +00001282 StatementMatcher OpStarCall =
Aaron Ballman512fb642015-09-17 13:30:52 +00001283 cxxOperatorCallExpr(hasOverloadedOperatorName("*"));
Benjamin Kramer09514492014-07-14 14:05:02 +00001284 EXPECT_TRUE(matches("class Y; int operator*(Y &); void f(Y &y) { *y; }",
1285 OpStarCall));
Edwin Vane0a4836e2013-03-06 17:02:57 +00001286 DeclarationMatcher ClassWithOpStar =
Aaron Ballman512fb642015-09-17 13:30:52 +00001287 cxxRecordDecl(hasMethod(hasOverloadedOperatorName("*")));
Edwin Vane0a4836e2013-03-06 17:02:57 +00001288 EXPECT_TRUE(matches("class Y { int operator*(); };",
1289 ClassWithOpStar));
1290 EXPECT_TRUE(notMatches("class Y { void myOperator(); };",
1291 ClassWithOpStar)) ;
Benjamin Kramer09514492014-07-14 14:05:02 +00001292 DeclarationMatcher AnyOpStar = functionDecl(hasOverloadedOperatorName("*"));
1293 EXPECT_TRUE(matches("class Y; int operator*(Y &);", AnyOpStar));
1294 EXPECT_TRUE(matches("class Y { int operator*(); };", AnyOpStar));
Manuel Klimek04616e42012-07-06 05:48:52 +00001295}
1296
Daniel Jasper0f9f0192012-11-15 03:29:05 +00001297TEST(Matcher, NestedOverloadedOperatorCalls) {
1298 EXPECT_TRUE(matchAndVerifyResultTrue(
Aaron Ballman512fb642015-09-17 13:30:52 +00001299 "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(hasOverloadedOperatorName("&&")).bind("x"),
1303 new VerifyIdIsBoundTo<CXXOperatorCallExpr>("x", 2)));
1304 EXPECT_TRUE(matches("class Y { }; "
1305 "Y& operator&&(Y& x, Y& y) { return x; }; "
1306 "Y a; Y b; Y c; Y d = a && b && c;",
1307 cxxOperatorCallExpr(hasParent(cxxOperatorCallExpr()))));
1308 EXPECT_TRUE(
1309 matches("class Y { }; "
1310 "Y& operator&&(Y& x, Y& y) { return x; }; "
1311 "Y a; Y b; Y c; Y d = a && b && c;",
1312 cxxOperatorCallExpr(hasDescendant(cxxOperatorCallExpr()))));
Daniel Jasper0f9f0192012-11-15 03:29:05 +00001313}
1314
Manuel Klimek04616e42012-07-06 05:48:52 +00001315TEST(Matcher, ThisPointerType) {
Manuel Klimek86f8bbc2012-07-24 13:37:29 +00001316 StatementMatcher MethodOnY =
Aaron Ballman512fb642015-09-17 13:30:52 +00001317 cxxMemberCallExpr(thisPointerType(recordDecl(hasName("Y"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001318
1319 EXPECT_TRUE(
1320 matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
1321 MethodOnY));
1322 EXPECT_TRUE(
1323 matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
1324 MethodOnY));
1325 EXPECT_TRUE(
1326 matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
1327 MethodOnY));
1328 EXPECT_TRUE(
1329 matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
1330 MethodOnY));
1331 EXPECT_TRUE(
1332 matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
1333 MethodOnY));
1334
1335 EXPECT_TRUE(matches(
1336 "class Y {"
1337 " public: virtual void x();"
1338 "};"
1339 "class X : public Y {"
1340 " public: virtual void x();"
1341 "};"
1342 "void z() { X *x; x->Y::x(); }", MethodOnY));
1343}
1344
1345TEST(Matcher, VariableUsage) {
1346 StatementMatcher Reference =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001347 declRefExpr(to(
1348 varDecl(hasInitializer(
Aaron Ballman512fb642015-09-17 13:30:52 +00001349 cxxMemberCallExpr(thisPointerType(recordDecl(hasName("Y"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001350
1351 EXPECT_TRUE(matches(
1352 "class Y {"
1353 " public:"
1354 " bool x() const;"
1355 "};"
1356 "void z(const Y &y) {"
1357 " bool b = y.x();"
1358 " if (b) {}"
1359 "}", Reference));
1360
1361 EXPECT_TRUE(notMatches(
1362 "class Y {"
1363 " public:"
1364 " bool x() const;"
1365 "};"
1366 "void z(const Y &y) {"
1367 " bool b = y.x();"
1368 "}", Reference));
1369}
1370
Samuel Benzaquenf56a2992014-06-05 18:22:14 +00001371TEST(Matcher, VarDecl_Storage) {
1372 auto M = varDecl(hasName("X"), hasLocalStorage());
1373 EXPECT_TRUE(matches("void f() { int X; }", M));
1374 EXPECT_TRUE(notMatches("int X;", M));
1375 EXPECT_TRUE(notMatches("void f() { static int X; }", M));
1376
1377 M = varDecl(hasName("X"), hasGlobalStorage());
1378 EXPECT_TRUE(notMatches("void f() { int X; }", M));
1379 EXPECT_TRUE(matches("int X;", M));
1380 EXPECT_TRUE(matches("void f() { static int X; }", M));
1381}
1382
Aaron Ballman8e7f00b2015-11-18 17:56:55 +00001383TEST(Matcher, VarDecl_StorageDuration) {
1384 std::string T =
Aaron Ballmanf08e1842015-11-18 18:37:29 +00001385 "void f() { int x; static int y; } int a;";
Aaron Ballman8e7f00b2015-11-18 17:56:55 +00001386
1387 EXPECT_TRUE(matches(T, varDecl(hasName("x"), hasAutomaticStorageDuration())));
1388 EXPECT_TRUE(
1389 notMatches(T, varDecl(hasName("y"), hasAutomaticStorageDuration())));
1390 EXPECT_TRUE(
Aaron Ballman8e7f00b2015-11-18 17:56:55 +00001391 notMatches(T, varDecl(hasName("a"), hasAutomaticStorageDuration())));
1392
1393 EXPECT_TRUE(matches(T, varDecl(hasName("y"), hasStaticStorageDuration())));
1394 EXPECT_TRUE(matches(T, varDecl(hasName("a"), hasStaticStorageDuration())));
1395 EXPECT_TRUE(notMatches(T, varDecl(hasName("x"), hasStaticStorageDuration())));
Aaron Ballman8e7f00b2015-11-18 17:56:55 +00001396
Aaron Ballmanf08e1842015-11-18 18:37:29 +00001397 // FIXME: It is really hard to test with thread_local itself because not all
1398 // targets support TLS, which causes this to be an error depending on what
1399 // platform the test is being run on. We do not have access to the TargetInfo
1400 // object to be able to test whether the platform supports TLS or not.
Aaron Ballman8e7f00b2015-11-18 17:56:55 +00001401 EXPECT_TRUE(notMatches(T, varDecl(hasName("x"), hasThreadStorageDuration())));
1402 EXPECT_TRUE(notMatches(T, varDecl(hasName("y"), hasThreadStorageDuration())));
1403 EXPECT_TRUE(notMatches(T, varDecl(hasName("a"), hasThreadStorageDuration())));
1404}
1405
Manuel Klimek61379422012-12-04 14:42:08 +00001406TEST(Matcher, FindsVarDeclInFunctionParameter) {
Daniel Jasper3cb72b42012-07-30 05:03:25 +00001407 EXPECT_TRUE(matches(
1408 "void f(int i) {}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001409 varDecl(hasName("i"))));
Daniel Jasper3cb72b42012-07-30 05:03:25 +00001410}
1411
Manuel Klimek04616e42012-07-06 05:48:52 +00001412TEST(Matcher, CalledVariable) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00001413 StatementMatcher CallOnVariableY =
Aaron Ballman512fb642015-09-17 13:30:52 +00001414 cxxMemberCallExpr(on(declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001415
1416 EXPECT_TRUE(matches(
1417 "class Y { public: void x() { Y y; y.x(); } };", CallOnVariableY));
1418 EXPECT_TRUE(matches(
1419 "class Y { public: void x() const { Y y; y.x(); } };", CallOnVariableY));
1420 EXPECT_TRUE(matches(
1421 "class Y { public: void x(); };"
1422 "class X : public Y { void z() { X y; y.x(); } };", CallOnVariableY));
1423 EXPECT_TRUE(matches(
1424 "class Y { public: void x(); };"
1425 "class X : public Y { void z() { X *y; y->x(); } };", CallOnVariableY));
1426 EXPECT_TRUE(notMatches(
1427 "class Y { public: void x(); };"
1428 "class X : public Y { void z() { unsigned long y; ((X*)y)->x(); } };",
1429 CallOnVariableY));
1430}
1431
Daniel Jasper1dad1832012-07-10 20:20:19 +00001432TEST(UnaryExprOrTypeTraitExpr, MatchesSizeOfAndAlignOf) {
1433 EXPECT_TRUE(matches("void x() { int a = sizeof(a); }",
1434 unaryExprOrTypeTraitExpr()));
1435 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }",
1436 alignOfExpr(anything())));
1437 // FIXME: Uncomment once alignof is enabled.
1438 // EXPECT_TRUE(matches("void x() { int a = alignof(a); }",
1439 // unaryExprOrTypeTraitExpr()));
1440 // EXPECT_TRUE(notMatches("void x() { int a = alignof(a); }",
1441 // sizeOfExpr()));
1442}
1443
1444TEST(UnaryExpressionOrTypeTraitExpression, MatchesCorrectType) {
1445 EXPECT_TRUE(matches("void x() { int a = sizeof(a); }", sizeOfExpr(
1446 hasArgumentOfType(asString("int")))));
1447 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
1448 hasArgumentOfType(asString("float")))));
1449 EXPECT_TRUE(matches(
1450 "struct A {}; void x() { A a; int b = sizeof(a); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001451 sizeOfExpr(hasArgumentOfType(hasDeclaration(recordDecl(hasName("A")))))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001452 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001453 hasArgumentOfType(hasDeclaration(recordDecl(hasName("string")))))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001454}
1455
Manuel Klimek04616e42012-07-06 05:48:52 +00001456TEST(MemberExpression, DoesNotMatchClasses) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001457 EXPECT_TRUE(notMatches("class Y { void x() {} };", memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001458}
1459
1460TEST(MemberExpression, MatchesMemberFunctionCall) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001461 EXPECT_TRUE(matches("class Y { void x() { x(); } };", memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001462}
1463
1464TEST(MemberExpression, MatchesVariable) {
1465 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001466 matches("class Y { void x() { this->y; } int y; };", memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001467 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001468 matches("class Y { void x() { y; } int y; };", memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001469 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001470 matches("class Y { void x() { Y y; y.y; } int y; };", memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001471}
1472
1473TEST(MemberExpression, MatchesStaticVariable) {
1474 EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001475 memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001476 EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001477 memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001478 EXPECT_TRUE(notMatches("class Y { void x() { Y::y; } static int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001479 memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001480}
1481
Daniel Jasper4e566c42012-07-12 08:50:38 +00001482TEST(IsInteger, MatchesIntegers) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001483 EXPECT_TRUE(matches("int i = 0;", varDecl(hasType(isInteger()))));
1484 EXPECT_TRUE(matches(
1485 "long long i = 0; void f(long long) { }; void g() {f(i);}",
1486 callExpr(hasArgument(0, declRefExpr(
1487 to(varDecl(hasType(isInteger()))))))));
Daniel Jasper4e566c42012-07-12 08:50:38 +00001488}
1489
1490TEST(IsInteger, ReportsNoFalsePositives) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001491 EXPECT_TRUE(notMatches("int *i;", varDecl(hasType(isInteger()))));
Daniel Jasper4e566c42012-07-12 08:50:38 +00001492 EXPECT_TRUE(notMatches("struct T {}; T t; void f(T *) { }; void g() {f(&t);}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001493 callExpr(hasArgument(0, declRefExpr(
1494 to(varDecl(hasType(isInteger()))))))));
Daniel Jasper4e566c42012-07-12 08:50:38 +00001495}
1496
Felix Bergercc9df3b2016-02-15 04:00:39 +00001497TEST(IsAnyPointer, MatchesPointers) {
1498 EXPECT_TRUE(matches("int* i = nullptr;", varDecl(hasType(isAnyPointer()))));
1499}
1500
Felix Berger40ef42a2016-03-06 15:27:59 +00001501TEST(IsAnyPointer, MatchesObjcPointer) {
1502 EXPECT_TRUE(matchesObjC("@interface Foo @end Foo *f;",
1503 varDecl(hasType(isAnyPointer()))));
1504}
1505
Felix Bergercc9df3b2016-02-15 04:00:39 +00001506TEST(IsAnyPointer, ReportsNoFalsePositives) {
1507 EXPECT_TRUE(notMatches("int i = 0;", varDecl(hasType(isAnyPointer()))));
1508}
1509
Gabor Horvath009c5d52015-12-15 08:35:45 +00001510TEST(IsAnyCharacter, MatchesCharacters) {
1511 EXPECT_TRUE(matches("char i = 0;", varDecl(hasType(isAnyCharacter()))));
1512}
1513
1514TEST(IsAnyCharacter, ReportsNoFalsePositives) {
1515 EXPECT_TRUE(notMatches("int i;", varDecl(hasType(isAnyCharacter()))));
1516}
1517
Manuel Klimek04616e42012-07-06 05:48:52 +00001518TEST(IsArrow, MatchesMemberVariablesViaArrow) {
1519 EXPECT_TRUE(matches("class Y { void x() { this->y; } int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001520 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001521 EXPECT_TRUE(matches("class Y { void x() { y; } int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001522 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001523 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001524 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001525}
1526
1527TEST(IsArrow, MatchesStaticMemberVariablesViaArrow) {
1528 EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001529 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001530 EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001531 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001532 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } static int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001533 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001534}
1535
1536TEST(IsArrow, MatchesMemberCallsViaArrow) {
1537 EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001538 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001539 EXPECT_TRUE(matches("class Y { void x() { x(); } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001540 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001541 EXPECT_TRUE(notMatches("class Y { void x() { Y y; y.x(); } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001542 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001543}
1544
1545TEST(Callee, MatchesDeclarations) {
Aaron Ballman512fb642015-09-17 13:30:52 +00001546 StatementMatcher CallMethodX = callExpr(callee(cxxMethodDecl(hasName("x"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001547
1548 EXPECT_TRUE(matches("class Y { void x() { x(); } };", CallMethodX));
1549 EXPECT_TRUE(notMatches("class Y { void x() {} };", CallMethodX));
Samuel Benzaquen025f6b12015-04-20 20:58:50 +00001550
Aaron Ballman512fb642015-09-17 13:30:52 +00001551 CallMethodX = callExpr(callee(cxxConversionDecl()));
Samuel Benzaquen025f6b12015-04-20 20:58:50 +00001552 EXPECT_TRUE(
1553 matches("struct Y { operator int() const; }; int i = Y();", CallMethodX));
1554 EXPECT_TRUE(notMatches("struct Y { operator int() const; }; Y y = Y();",
1555 CallMethodX));
Manuel Klimek04616e42012-07-06 05:48:52 +00001556}
1557
Aaron Ballman6f6d0b62015-08-11 21:09:52 +00001558TEST(ConversionDeclaration, IsExplicit) {
1559 EXPECT_TRUE(matches("struct S { explicit operator int(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001560 cxxConversionDecl(isExplicit())));
Aaron Ballman6f6d0b62015-08-11 21:09:52 +00001561 EXPECT_TRUE(notMatches("struct S { operator int(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001562 cxxConversionDecl(isExplicit())));
Aaron Ballman6f6d0b62015-08-11 21:09:52 +00001563}
1564
Manuel Klimek04616e42012-07-06 05:48:52 +00001565TEST(Callee, MatchesMemberExpressions) {
1566 EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001567 callExpr(callee(memberExpr()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001568 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001569 notMatches("class Y { void x() { this->x(); } };", callExpr(callee(callExpr()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001570}
1571
1572TEST(Function, MatchesFunctionDeclarations) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001573 StatementMatcher CallFunctionF = callExpr(callee(functionDecl(hasName("f"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001574
1575 EXPECT_TRUE(matches("void f() { f(); }", CallFunctionF));
1576 EXPECT_TRUE(notMatches("void f() { }", CallFunctionF));
1577
NAKAMURA Takumi7d2da0b2014-02-16 10:16:09 +00001578 if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getOS() !=
1579 llvm::Triple::Win32) {
1580 // FIXME: Make this work for MSVC.
1581 // Dependent contexts, but a non-dependent call.
1582 EXPECT_TRUE(matches("void f(); template <int N> void g() { f(); }",
1583 CallFunctionF));
1584 EXPECT_TRUE(
1585 matches("void f(); template <int N> struct S { void g() { f(); } };",
1586 CallFunctionF));
1587 }
Manuel Klimek04616e42012-07-06 05:48:52 +00001588
1589 // Depedent calls don't match.
1590 EXPECT_TRUE(
1591 notMatches("void f(int); template <typename T> void g(T t) { f(t); }",
1592 CallFunctionF));
1593 EXPECT_TRUE(
1594 notMatches("void f(int);"
1595 "template <typename T> struct S { void g(T t) { f(t); } };",
1596 CallFunctionF));
Aaron Ballman3fd6c112015-10-05 14:41:27 +00001597
1598 EXPECT_TRUE(matches("void f(...);", functionDecl(isVariadic())));
1599 EXPECT_TRUE(notMatches("void f(int);", functionDecl(isVariadic())));
1600 EXPECT_TRUE(notMatches("template <typename... Ts> void f(Ts...);",
1601 functionDecl(isVariadic())));
1602 EXPECT_TRUE(notMatches("void f();", functionDecl(isVariadic())));
1603 EXPECT_TRUE(notMatchesC("void f();", functionDecl(isVariadic())));
Aaron Ballman7e7b7b22016-02-01 14:11:47 +00001604 EXPECT_TRUE(matches("void f(...);", functionDecl(parameterCountIs(0))));
1605 EXPECT_TRUE(matchesC("void f();", functionDecl(parameterCountIs(0))));
1606 EXPECT_TRUE(matches("void f(int, ...);", functionDecl(parameterCountIs(1))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001607}
1608
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00001609TEST(FunctionTemplate, MatchesFunctionTemplateDeclarations) {
1610 EXPECT_TRUE(
1611 matches("template <typename T> void f(T t) {}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001612 functionTemplateDecl(hasName("f"))));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00001613}
1614
1615TEST(FunctionTemplate, DoesNotMatchFunctionDeclarations) {
1616 EXPECT_TRUE(
1617 notMatches("void f(double d); void f(int t) {}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001618 functionTemplateDecl(hasName("f"))));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00001619}
1620
1621TEST(FunctionTemplate, DoesNotMatchFunctionTemplateSpecializations) {
1622 EXPECT_TRUE(
1623 notMatches("void g(); template <typename T> void f(T t) {}"
1624 "template <> void f(int t) { g(); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001625 functionTemplateDecl(hasName("f"),
1626 hasDescendant(declRefExpr(to(
1627 functionDecl(hasName("g"))))))));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00001628}
1629
Manuel Klimek04616e42012-07-06 05:48:52 +00001630TEST(Matcher, Argument) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00001631 StatementMatcher CallArgumentY = callExpr(
1632 hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001633
1634 EXPECT_TRUE(matches("void x(int) { int y; x(y); }", CallArgumentY));
1635 EXPECT_TRUE(
1636 matches("class X { void x(int) { int y; x(y); } };", CallArgumentY));
1637 EXPECT_TRUE(notMatches("void x(int) { int z; x(z); }", CallArgumentY));
1638
Daniel Jasper848cbe12012-09-18 13:09:13 +00001639 StatementMatcher WrongIndex = callExpr(
1640 hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001641 EXPECT_TRUE(notMatches("void x(int) { int y; x(y); }", WrongIndex));
1642}
1643
1644TEST(Matcher, AnyArgument) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00001645 StatementMatcher CallArgumentY = callExpr(
Gabor Horvath1b654f22016-03-30 11:22:14 +00001646 hasAnyArgument(
1647 ignoringParenImpCasts(declRefExpr(to(varDecl(hasName("y")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001648 EXPECT_TRUE(matches("void x(int, int) { int y; x(1, y); }", CallArgumentY));
1649 EXPECT_TRUE(matches("void x(int, int) { int y; x(y, 42); }", CallArgumentY));
1650 EXPECT_TRUE(notMatches("void x(int, int) { x(1, 2); }", CallArgumentY));
Gabor Horvath1b654f22016-03-30 11:22:14 +00001651
1652 StatementMatcher ImplicitCastedArgument = callExpr(
1653 hasAnyArgument(implicitCastExpr()));
1654 EXPECT_TRUE(matches("void x(long) { int y; x(y); }", ImplicitCastedArgument));
Manuel Klimek04616e42012-07-06 05:48:52 +00001655}
1656
Manuel Klimekce28f9e2016-01-18 11:20:09 +00001657TEST(ForEachArgumentWithParam, ReportsNoFalsePositives) {
1658 StatementMatcher ArgumentY =
1659 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1660 DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
1661 StatementMatcher CallExpr =
1662 callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
1663
1664 // IntParam does not match.
Aaron Ballmand7b18b92016-01-18 20:28:57 +00001665 EXPECT_TRUE(notMatches("void f(int* i) { int* y; f(y); }", CallExpr));
Manuel Klimekce28f9e2016-01-18 11:20:09 +00001666 // ArgumentY does not match.
Aaron Ballmand7b18b92016-01-18 20:28:57 +00001667 EXPECT_TRUE(notMatches("void f(int i) { int x; f(x); }", CallExpr));
Manuel Klimekce28f9e2016-01-18 11:20:09 +00001668}
1669
1670TEST(ForEachArgumentWithParam, MatchesCXXMemberCallExpr) {
1671 StatementMatcher ArgumentY =
1672 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1673 DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
1674 StatementMatcher CallExpr =
1675 callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
1676 EXPECT_TRUE(matchAndVerifyResultTrue(
1677 "struct S {"
1678 " const S& operator[](int i) { return *this; }"
1679 "};"
1680 "void f(S S1) {"
1681 " int y = 1;"
1682 " S1[y];"
1683 "}",
1684 CallExpr, new VerifyIdIsBoundTo<ParmVarDecl>("param", 1)));
Aaron Ballmand7b18b92016-01-18 20:28:57 +00001685
1686 StatementMatcher CallExpr2 =
1687 callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
1688 EXPECT_TRUE(matchAndVerifyResultTrue(
1689 "struct S {"
1690 " static void g(int i);"
1691 "};"
1692 "void f() {"
1693 " int y = 1;"
1694 " S::g(y);"
1695 "}",
1696 CallExpr2, new VerifyIdIsBoundTo<ParmVarDecl>("param", 1)));
Manuel Klimekce28f9e2016-01-18 11:20:09 +00001697}
1698
1699TEST(ForEachArgumentWithParam, MatchesCallExpr) {
1700 StatementMatcher ArgumentY =
1701 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1702 DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
1703 StatementMatcher CallExpr =
1704 callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
1705
1706 EXPECT_TRUE(
1707 matchAndVerifyResultTrue("void f(int i) { int y; f(y); }", CallExpr,
1708 new VerifyIdIsBoundTo<ParmVarDecl>("param")));
1709 EXPECT_TRUE(
1710 matchAndVerifyResultTrue("void f(int i) { int y; f(y); }", CallExpr,
1711 new VerifyIdIsBoundTo<DeclRefExpr>("arg")));
1712
1713 EXPECT_TRUE(matchAndVerifyResultTrue(
1714 "void f(int i, int j) { int y; f(y, y); }", CallExpr,
1715 new VerifyIdIsBoundTo<ParmVarDecl>("param", 2)));
1716 EXPECT_TRUE(matchAndVerifyResultTrue(
1717 "void f(int i, int j) { int y; f(y, y); }", CallExpr,
1718 new VerifyIdIsBoundTo<DeclRefExpr>("arg", 2)));
1719}
1720
1721TEST(ForEachArgumentWithParam, MatchesConstructExpr) {
1722 StatementMatcher ArgumentY =
1723 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1724 DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
1725 StatementMatcher ConstructExpr =
1726 cxxConstructExpr(forEachArgumentWithParam(ArgumentY, IntParam));
1727
1728 EXPECT_TRUE(matchAndVerifyResultTrue(
1729 "struct C {"
1730 " C(int i) {}"
1731 "};"
1732 "int y = 0;"
1733 "C Obj(y);",
1734 ConstructExpr, new VerifyIdIsBoundTo<ParmVarDecl>("param")));
1735}
1736
1737TEST(ForEachArgumentWithParam, HandlesBoundNodesForNonMatches) {
1738 EXPECT_TRUE(matchAndVerifyResultTrue(
1739 "void g(int i, int j) {"
1740 " int a;"
1741 " int b;"
1742 " int c;"
1743 " g(a, 0);"
1744 " g(a, b);"
1745 " g(0, b);"
1746 "}",
1747 functionDecl(
1748 forEachDescendant(varDecl().bind("v")),
1749 forEachDescendant(callExpr(forEachArgumentWithParam(
1750 declRefExpr(to(decl(equalsBoundNode("v")))), parmVarDecl())))),
1751 new VerifyIdIsBoundTo<VarDecl>("v", 4)));
1752}
1753
Manuel Klimek04616e42012-07-06 05:48:52 +00001754TEST(Matcher, ArgumentCount) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00001755 StatementMatcher Call1Arg = callExpr(argumentCountIs(1));
Manuel Klimek04616e42012-07-06 05:48:52 +00001756
1757 EXPECT_TRUE(matches("void x(int) { x(0); }", Call1Arg));
1758 EXPECT_TRUE(matches("class X { void x(int) { x(0); } };", Call1Arg));
1759 EXPECT_TRUE(notMatches("void x(int, int) { x(0, 0); }", Call1Arg));
1760}
1761
Daniel Jasper9f501292012-12-04 11:54:27 +00001762TEST(Matcher, ParameterCount) {
1763 DeclarationMatcher Function1Arg = functionDecl(parameterCountIs(1));
1764 EXPECT_TRUE(matches("void f(int i) {}", Function1Arg));
1765 EXPECT_TRUE(matches("class X { void f(int i) {} };", Function1Arg));
1766 EXPECT_TRUE(notMatches("void f() {}", Function1Arg));
1767 EXPECT_TRUE(notMatches("void f(int i, int j, int k) {}", Function1Arg));
Aaron Ballman7e7b7b22016-02-01 14:11:47 +00001768 EXPECT_TRUE(matches("void f(int i, ...) {};", Function1Arg));
Daniel Jasper9f501292012-12-04 11:54:27 +00001769}
1770
Manuel Klimek04616e42012-07-06 05:48:52 +00001771TEST(Matcher, References) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001772 DeclarationMatcher ReferenceClassX = varDecl(
1773 hasType(references(recordDecl(hasName("X")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001774 EXPECT_TRUE(matches("class X {}; void y(X y) { X &x = y; }",
1775 ReferenceClassX));
1776 EXPECT_TRUE(
1777 matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX));
Michael Hanc90d12d2013-09-11 15:53:29 +00001778 // The match here is on the implicit copy constructor code for
1779 // class X, not on code 'X x = y'.
Manuel Klimek04616e42012-07-06 05:48:52 +00001780 EXPECT_TRUE(
Michael Hanc90d12d2013-09-11 15:53:29 +00001781 matches("class X {}; void y(X y) { X x = y; }", ReferenceClassX));
1782 EXPECT_TRUE(
1783 notMatches("class X {}; extern X x;", ReferenceClassX));
Manuel Klimek04616e42012-07-06 05:48:52 +00001784 EXPECT_TRUE(
1785 notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX));
1786}
1787
Edwin Vane0a4836e2013-03-06 17:02:57 +00001788TEST(QualType, hasCanonicalType) {
1789 EXPECT_TRUE(notMatches("typedef int &int_ref;"
1790 "int a;"
1791 "int_ref b = a;",
1792 varDecl(hasType(qualType(referenceType())))));
1793 EXPECT_TRUE(
1794 matches("typedef int &int_ref;"
1795 "int a;"
1796 "int_ref b = a;",
1797 varDecl(hasType(qualType(hasCanonicalType(referenceType()))))));
1798}
1799
Edwin Vane119d3df2013-04-02 18:15:55 +00001800TEST(QualType, hasLocalQualifiers) {
1801 EXPECT_TRUE(notMatches("typedef const int const_int; const_int i = 1;",
1802 varDecl(hasType(hasLocalQualifiers()))));
1803 EXPECT_TRUE(matches("int *const j = nullptr;",
1804 varDecl(hasType(hasLocalQualifiers()))));
1805 EXPECT_TRUE(matches("int *volatile k;",
1806 varDecl(hasType(hasLocalQualifiers()))));
1807 EXPECT_TRUE(notMatches("int m;",
1808 varDecl(hasType(hasLocalQualifiers()))));
1809}
1810
Manuel Klimek04616e42012-07-06 05:48:52 +00001811TEST(HasParameter, CallsInnerMatcher) {
1812 EXPECT_TRUE(matches("class X { void x(int) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001813 cxxMethodDecl(hasParameter(0, varDecl()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001814 EXPECT_TRUE(notMatches("class X { void x(int) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001815 cxxMethodDecl(hasParameter(0, hasName("x")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001816}
1817
1818TEST(HasParameter, DoesNotMatchIfIndexOutOfBounds) {
1819 EXPECT_TRUE(notMatches("class X { void x(int) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001820 cxxMethodDecl(hasParameter(42, varDecl()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001821}
1822
1823TEST(HasType, MatchesParameterVariableTypesStrictly) {
Aaron Ballman512fb642015-09-17 13:30:52 +00001824 EXPECT_TRUE(matches(
1825 "class X { void x(X x) {} };",
1826 cxxMethodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
1827 EXPECT_TRUE(notMatches(
1828 "class X { void x(const X &x) {} };",
1829 cxxMethodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001830 EXPECT_TRUE(matches("class X { void x(const X *x) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001831 cxxMethodDecl(hasParameter(
1832 0, hasType(pointsTo(recordDecl(hasName("X"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001833 EXPECT_TRUE(matches("class X { void x(const X &x) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001834 cxxMethodDecl(hasParameter(
1835 0, hasType(references(recordDecl(hasName("X"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001836}
1837
1838TEST(HasAnyParameter, MatchesIndependentlyOfPosition) {
Aaron Ballman512fb642015-09-17 13:30:52 +00001839 EXPECT_TRUE(matches(
1840 "class Y {}; class X { void x(X x, Y y) {} };",
1841 cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
1842 EXPECT_TRUE(matches(
1843 "class Y {}; class X { void x(Y y, X x) {} };",
1844 cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001845}
1846
Daniel Jasper1dad1832012-07-10 20:20:19 +00001847TEST(Returns, MatchesReturnTypes) {
1848 EXPECT_TRUE(matches("class Y { int f() { return 1; } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001849 functionDecl(returns(asString("int")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001850 EXPECT_TRUE(notMatches("class Y { int f() { return 1; } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001851 functionDecl(returns(asString("float")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001852 EXPECT_TRUE(matches("class Y { Y getMe() { return *this; } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001853 functionDecl(returns(hasDeclaration(
1854 recordDecl(hasName("Y")))))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001855}
1856
Daniel Jasperfaaffe32012-08-15 18:52:19 +00001857TEST(IsExternC, MatchesExternCFunctionDeclarations) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001858 EXPECT_TRUE(matches("extern \"C\" void f() {}", functionDecl(isExternC())));
1859 EXPECT_TRUE(matches("extern \"C\" { void f() {} }",
1860 functionDecl(isExternC())));
1861 EXPECT_TRUE(notMatches("void f() {}", functionDecl(isExternC())));
Daniel Jasperfaaffe32012-08-15 18:52:19 +00001862}
1863
Aaron Ballmaneb85b042016-01-18 20:37:44 +00001864TEST(IsDefaulted, MatchesDefaultedFunctionDeclarations) {
Aaron Ballman9e373df2016-01-18 20:47:02 +00001865 EXPECT_TRUE(notMatches("class A { ~A(); };",
1866 functionDecl(hasName("~A"), isDefaulted())));
Aaron Ballmaneb85b042016-01-18 20:37:44 +00001867 EXPECT_TRUE(matches("class B { ~B() = default; };",
Aaron Ballman9e373df2016-01-18 20:47:02 +00001868 functionDecl(hasName("~B"), isDefaulted())));
Aaron Ballmaneb85b042016-01-18 20:37:44 +00001869}
1870
Samuel Benzaquen8e7f9962014-08-15 14:20:59 +00001871TEST(IsDeleted, MatchesDeletedFunctionDeclarations) {
1872 EXPECT_TRUE(
1873 notMatches("void Func();", functionDecl(hasName("Func"), isDeleted())));
1874 EXPECT_TRUE(matches("void Func() = delete;",
1875 functionDecl(hasName("Func"), isDeleted())));
1876}
1877
Aaron Ballmana60bcda2015-12-02 15:23:59 +00001878TEST(IsNoThrow, MatchesNoThrowFunctionDeclarations) {
1879 EXPECT_TRUE(notMatches("void f();", functionDecl(isNoThrow())));
1880 EXPECT_TRUE(notMatches("void f() throw(int);", functionDecl(isNoThrow())));
1881 EXPECT_TRUE(
1882 notMatches("void f() noexcept(false);", functionDecl(isNoThrow())));
1883 EXPECT_TRUE(matches("void f() throw();", functionDecl(isNoThrow())));
1884 EXPECT_TRUE(matches("void f() noexcept;", functionDecl(isNoThrow())));
1885}
1886
Szabolcs Siposb37b0ed2015-05-22 11:35:50 +00001887TEST(isConstexpr, MatchesConstexprDeclarations) {
1888 EXPECT_TRUE(matches("constexpr int foo = 42;",
1889 varDecl(hasName("foo"), isConstexpr())));
1890 EXPECT_TRUE(matches("constexpr int bar();",
1891 functionDecl(hasName("bar"), isConstexpr())));
1892}
1893
Manuel Klimek04616e42012-07-06 05:48:52 +00001894TEST(HasAnyParameter, DoesntMatchIfInnerMatcherDoesntMatch) {
Aaron Ballman512fb642015-09-17 13:30:52 +00001895 EXPECT_TRUE(notMatches(
1896 "class Y {}; class X { void x(int) {} };",
1897 cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001898}
1899
1900TEST(HasAnyParameter, DoesNotMatchThisPointer) {
1901 EXPECT_TRUE(notMatches("class Y {}; class X { void x() {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001902 cxxMethodDecl(hasAnyParameter(
1903 hasType(pointsTo(recordDecl(hasName("X"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001904}
1905
Alp Toker8db6e7a2014-01-05 06:38:57 +00001906TEST(HasName, MatchesParameterVariableDeclarations) {
Manuel Klimek04616e42012-07-06 05:48:52 +00001907 EXPECT_TRUE(matches("class Y {}; class X { void x(int x) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001908 cxxMethodDecl(hasAnyParameter(hasName("x")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001909 EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001910 cxxMethodDecl(hasAnyParameter(hasName("x")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001911}
1912
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001913TEST(Matcher, MatchesClassTemplateSpecialization) {
1914 EXPECT_TRUE(matches("template<typename T> struct A {};"
1915 "template<> struct A<int> {};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001916 classTemplateSpecializationDecl()));
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001917 EXPECT_TRUE(matches("template<typename T> struct A {}; A<int> a;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001918 classTemplateSpecializationDecl()));
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001919 EXPECT_TRUE(notMatches("template<typename T> struct A {};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001920 classTemplateSpecializationDecl()));
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001921}
1922
Manuel Klimekc16c6522013-06-20 13:08:29 +00001923TEST(DeclaratorDecl, MatchesDeclaratorDecls) {
1924 EXPECT_TRUE(matches("int x;", declaratorDecl()));
1925 EXPECT_TRUE(notMatches("class A {};", declaratorDecl()));
1926}
1927
1928TEST(ParmVarDecl, MatchesParmVars) {
1929 EXPECT_TRUE(matches("void f(int x);", parmVarDecl()));
1930 EXPECT_TRUE(notMatches("void f();", parmVarDecl()));
1931}
1932
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001933TEST(Matcher, MatchesTypeTemplateArgument) {
1934 EXPECT_TRUE(matches(
1935 "template<typename T> struct B {};"
1936 "B<int> b;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001937 classTemplateSpecializationDecl(hasAnyTemplateArgument(refersToType(
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001938 asString("int"))))));
1939}
1940
1941TEST(Matcher, MatchesDeclarationReferenceTemplateArgument) {
1942 EXPECT_TRUE(matches(
1943 "struct B { int next; };"
1944 "template<int(B::*next_ptr)> struct A {};"
1945 "A<&B::next> a;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001946 classTemplateSpecializationDecl(hasAnyTemplateArgument(
1947 refersToDeclaration(fieldDecl(hasName("next")))))));
Daniel Jasper0c303372012-09-29 15:55:18 +00001948
1949 EXPECT_TRUE(notMatches(
1950 "template <typename T> struct A {};"
1951 "A<int> a;",
1952 classTemplateSpecializationDecl(hasAnyTemplateArgument(
1953 refersToDeclaration(decl())))));
Peter Collingbourne564597f2014-02-20 19:18:03 +00001954
1955 EXPECT_TRUE(matches(
1956 "struct B { int next; };"
1957 "template<int(B::*next_ptr)> struct A {};"
1958 "A<&B::next> a;",
1959 templateSpecializationType(hasAnyTemplateArgument(isExpr(
1960 hasDescendant(declRefExpr(to(fieldDecl(hasName("next"))))))))));
1961
1962 EXPECT_TRUE(notMatches(
1963 "template <typename T> struct A {};"
1964 "A<int> a;",
1965 templateSpecializationType(hasAnyTemplateArgument(
1966 refersToDeclaration(decl())))));
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001967}
1968
1969TEST(Matcher, MatchesSpecificArgument) {
1970 EXPECT_TRUE(matches(
1971 "template<typename T, typename U> class A {};"
1972 "A<bool, int> a;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001973 classTemplateSpecializationDecl(hasTemplateArgument(
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001974 1, refersToType(asString("int"))))));
1975 EXPECT_TRUE(notMatches(
1976 "template<typename T, typename U> class A {};"
1977 "A<int, bool> a;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001978 classTemplateSpecializationDecl(hasTemplateArgument(
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001979 1, refersToType(asString("int"))))));
Peter Collingbourne564597f2014-02-20 19:18:03 +00001980
1981 EXPECT_TRUE(matches(
1982 "template<typename T, typename U> class A {};"
1983 "A<bool, int> a;",
1984 templateSpecializationType(hasTemplateArgument(
1985 1, refersToType(asString("int"))))));
1986 EXPECT_TRUE(notMatches(
1987 "template<typename T, typename U> class A {};"
1988 "A<int, bool> a;",
1989 templateSpecializationType(hasTemplateArgument(
1990 1, refersToType(asString("int"))))));
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001991}
1992
Manuel Klimek7735e402014-10-09 13:06:22 +00001993TEST(TemplateArgument, Matches) {
1994 EXPECT_TRUE(matches("template<typename T> struct C {}; C<int> c;",
1995 classTemplateSpecializationDecl(
1996 hasAnyTemplateArgument(templateArgument()))));
1997 EXPECT_TRUE(matches(
1998 "template<typename T> struct C {}; C<int> c;",
1999 templateSpecializationType(hasAnyTemplateArgument(templateArgument()))));
2000}
2001
2002TEST(TemplateArgumentCountIs, Matches) {
2003 EXPECT_TRUE(
2004 matches("template<typename T> struct C {}; C<int> c;",
2005 classTemplateSpecializationDecl(templateArgumentCountIs(1))));
2006 EXPECT_TRUE(
2007 notMatches("template<typename T> struct C {}; C<int> c;",
2008 classTemplateSpecializationDecl(templateArgumentCountIs(2))));
2009
2010 EXPECT_TRUE(matches("template<typename T> struct C {}; C<int> c;",
2011 templateSpecializationType(templateArgumentCountIs(1))));
2012 EXPECT_TRUE(
2013 notMatches("template<typename T> struct C {}; C<int> c;",
2014 templateSpecializationType(templateArgumentCountIs(2))));
2015}
2016
2017TEST(IsIntegral, Matches) {
2018 EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
2019 classTemplateSpecializationDecl(
2020 hasAnyTemplateArgument(isIntegral()))));
2021 EXPECT_TRUE(notMatches("template<typename T> struct C {}; C<int> c;",
2022 classTemplateSpecializationDecl(hasAnyTemplateArgument(
2023 templateArgument(isIntegral())))));
2024}
2025
2026TEST(RefersToIntegralType, Matches) {
2027 EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
2028 classTemplateSpecializationDecl(
2029 hasAnyTemplateArgument(refersToIntegralType(
2030 asString("int"))))));
2031 EXPECT_TRUE(notMatches("template<unsigned T> struct C {}; C<42> c;",
2032 classTemplateSpecializationDecl(hasAnyTemplateArgument(
2033 refersToIntegralType(asString("int"))))));
2034}
2035
2036TEST(EqualsIntegralValue, Matches) {
2037 EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
2038 classTemplateSpecializationDecl(
2039 hasAnyTemplateArgument(equalsIntegralValue("42")))));
2040 EXPECT_TRUE(matches("template<int T> struct C {}; C<-42> c;",
2041 classTemplateSpecializationDecl(
2042 hasAnyTemplateArgument(equalsIntegralValue("-42")))));
2043 EXPECT_TRUE(matches("template<int T> struct C {}; C<-0042> c;",
2044 classTemplateSpecializationDecl(
2045 hasAnyTemplateArgument(equalsIntegralValue("-34")))));
2046 EXPECT_TRUE(notMatches("template<int T> struct C {}; C<42> c;",
2047 classTemplateSpecializationDecl(hasAnyTemplateArgument(
2048 equalsIntegralValue("0042")))));
2049}
2050
Daniel Jasper639522c2013-02-25 12:02:08 +00002051TEST(Matcher, MatchesAccessSpecDecls) {
2052 EXPECT_TRUE(matches("class C { public: int i; };", accessSpecDecl()));
2053 EXPECT_TRUE(
2054 matches("class C { public: int i; };", accessSpecDecl(isPublic())));
2055 EXPECT_TRUE(
2056 notMatches("class C { public: int i; };", accessSpecDecl(isProtected())));
2057 EXPECT_TRUE(
2058 notMatches("class C { public: int i; };", accessSpecDecl(isPrivate())));
2059
2060 EXPECT_TRUE(notMatches("class C { int i; };", accessSpecDecl()));
2061}
2062
Aaron Ballman41143bb2015-07-24 12:35:41 +00002063TEST(Matcher, MatchesFinal) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002064 EXPECT_TRUE(matches("class X final {};", cxxRecordDecl(isFinal())));
Aaron Ballman41143bb2015-07-24 12:35:41 +00002065 EXPECT_TRUE(matches("class X { virtual void f() final; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002066 cxxMethodDecl(isFinal())));
2067 EXPECT_TRUE(notMatches("class X {};", cxxRecordDecl(isFinal())));
2068 EXPECT_TRUE(
2069 notMatches("class X { virtual void f(); };", cxxMethodDecl(isFinal())));
Aaron Ballman41143bb2015-07-24 12:35:41 +00002070}
2071
Edwin Vane37ee1d72013-04-09 20:46:36 +00002072TEST(Matcher, MatchesVirtualMethod) {
2073 EXPECT_TRUE(matches("class X { virtual int f(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002074 cxxMethodDecl(isVirtual(), hasName("::X::f"))));
2075 EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isVirtual())));
Edwin Vane37ee1d72013-04-09 20:46:36 +00002076}
2077
Nico Webera415a1d2016-01-21 17:56:24 +00002078TEST(Matcher, MatchesVirtualAsWrittenMethod) {
2079 EXPECT_TRUE(matches("class A { virtual int f(); };"
2080 "class B : public A { int f(); };",
2081 cxxMethodDecl(isVirtualAsWritten(), hasName("::A::f"))));
2082 EXPECT_TRUE(
2083 notMatches("class A { virtual int f(); };"
2084 "class B : public A { int f(); };",
2085 cxxMethodDecl(isVirtualAsWritten(), hasName("::B::f"))));
2086}
2087
Dmitri Gribenko51c1b552014-02-24 09:27:46 +00002088TEST(Matcher, MatchesPureMethod) {
2089 EXPECT_TRUE(matches("class X { virtual int f() = 0; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002090 cxxMethodDecl(isPure(), hasName("::X::f"))));
2091 EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isPure())));
Dmitri Gribenko51c1b552014-02-24 09:27:46 +00002092}
2093
Angel Garcia Gomez4647ed72015-10-30 09:35:51 +00002094TEST(Matcher, MatchesCopyAssignmentOperator) {
2095 EXPECT_TRUE(matches("class X { X &operator=(X); };",
2096 cxxMethodDecl(isCopyAssignmentOperator())));
2097 EXPECT_TRUE(matches("class X { X &operator=(X &); };",
2098 cxxMethodDecl(isCopyAssignmentOperator())));
2099 EXPECT_TRUE(matches("class X { X &operator=(const X &); };",
2100 cxxMethodDecl(isCopyAssignmentOperator())));
2101 EXPECT_TRUE(matches("class X { X &operator=(volatile X &); };",
2102 cxxMethodDecl(isCopyAssignmentOperator())));
2103 EXPECT_TRUE(matches("class X { X &operator=(const volatile X &); };",
2104 cxxMethodDecl(isCopyAssignmentOperator())));
2105 EXPECT_TRUE(notMatches("class X { X &operator=(X &&); };",
2106 cxxMethodDecl(isCopyAssignmentOperator())));
2107}
2108
Aaron Ballman31bde872016-01-22 22:37:09 +00002109TEST(Matcher, MatchesMoveAssignmentOperator) {
2110 EXPECT_TRUE(notMatches("class X { X &operator=(X); };",
2111 cxxMethodDecl(isMoveAssignmentOperator())));
2112 EXPECT_TRUE(matches("class X { X &operator=(X &&); };",
2113 cxxMethodDecl(isMoveAssignmentOperator())));
2114 EXPECT_TRUE(matches("class X { X &operator=(const X &&); };",
2115 cxxMethodDecl(isMoveAssignmentOperator())));
2116 EXPECT_TRUE(matches("class X { X &operator=(volatile X &&); };",
2117 cxxMethodDecl(isMoveAssignmentOperator())));
2118 EXPECT_TRUE(matches("class X { X &operator=(const volatile X &&); };",
2119 cxxMethodDecl(isMoveAssignmentOperator())));
2120 EXPECT_TRUE(notMatches("class X { X &operator=(X &); };",
2121 cxxMethodDecl(isMoveAssignmentOperator())));
2122}
2123
Edwin Vanefc4f7dc2013-05-09 17:00:17 +00002124TEST(Matcher, MatchesConstMethod) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002125 EXPECT_TRUE(
2126 matches("struct A { void foo() const; };", cxxMethodDecl(isConst())));
2127 EXPECT_TRUE(
2128 notMatches("struct A { void foo(); };", cxxMethodDecl(isConst())));
Edwin Vanefc4f7dc2013-05-09 17:00:17 +00002129}
2130
Edwin Vane37ee1d72013-04-09 20:46:36 +00002131TEST(Matcher, MatchesOverridingMethod) {
2132 EXPECT_TRUE(matches("class X { virtual int f(); }; "
2133 "class Y : public X { int f(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002134 cxxMethodDecl(isOverride(), hasName("::Y::f"))));
Edwin Vane37ee1d72013-04-09 20:46:36 +00002135 EXPECT_TRUE(notMatches("class X { virtual int f(); }; "
Aaron Ballman512fb642015-09-17 13:30:52 +00002136 "class Y : public X { int f(); };",
2137 cxxMethodDecl(isOverride(), hasName("::X::f"))));
Edwin Vane37ee1d72013-04-09 20:46:36 +00002138 EXPECT_TRUE(notMatches("class X { int f(); }; "
2139 "class Y : public X { int f(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002140 cxxMethodDecl(isOverride())));
Edwin Vane37ee1d72013-04-09 20:46:36 +00002141 EXPECT_TRUE(notMatches("class X { int f(); int f(int); }; ",
Aaron Ballman512fb642015-09-17 13:30:52 +00002142 cxxMethodDecl(isOverride())));
Samuel Benzaquenbb5093f2015-03-06 16:24:47 +00002143 EXPECT_TRUE(
2144 matches("template <typename Base> struct Y : Base { void f() override;};",
Aaron Ballman512fb642015-09-17 13:30:52 +00002145 cxxMethodDecl(isOverride(), hasName("::Y::f"))));
Edwin Vane37ee1d72013-04-09 20:46:36 +00002146}
2147
Manuel Klimek04616e42012-07-06 05:48:52 +00002148TEST(Matcher, ConstructorCall) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002149 StatementMatcher Constructor = cxxConstructExpr();
Manuel Klimek04616e42012-07-06 05:48:52 +00002150
2151 EXPECT_TRUE(
2152 matches("class X { public: X(); }; void x() { X x; }", Constructor));
2153 EXPECT_TRUE(
2154 matches("class X { public: X(); }; void x() { X x = X(); }",
2155 Constructor));
2156 EXPECT_TRUE(
2157 matches("class X { public: X(int); }; void x() { X x = 0; }",
2158 Constructor));
2159 EXPECT_TRUE(matches("class X {}; void x(int) { X x; }", Constructor));
2160}
2161
2162TEST(Matcher, ConstructorArgument) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002163 StatementMatcher Constructor = cxxConstructExpr(
Daniel Jasper848cbe12012-09-18 13:09:13 +00002164 hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002165
2166 EXPECT_TRUE(
2167 matches("class X { public: X(int); }; void x() { int y; X x(y); }",
2168 Constructor));
2169 EXPECT_TRUE(
2170 matches("class X { public: X(int); }; void x() { int y; X x = X(y); }",
2171 Constructor));
2172 EXPECT_TRUE(
2173 matches("class X { public: X(int); }; void x() { int y; X x = y; }",
2174 Constructor));
2175 EXPECT_TRUE(
2176 notMatches("class X { public: X(int); }; void x() { int z; X x(z); }",
2177 Constructor));
2178
Aaron Ballman512fb642015-09-17 13:30:52 +00002179 StatementMatcher WrongIndex = cxxConstructExpr(
Daniel Jasper848cbe12012-09-18 13:09:13 +00002180 hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002181 EXPECT_TRUE(
2182 notMatches("class X { public: X(int); }; void x() { int y; X x(y); }",
2183 WrongIndex));
2184}
2185
2186TEST(Matcher, ConstructorArgumentCount) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002187 StatementMatcher Constructor1Arg = cxxConstructExpr(argumentCountIs(1));
Manuel Klimek04616e42012-07-06 05:48:52 +00002188
2189 EXPECT_TRUE(
2190 matches("class X { public: X(int); }; void x() { X x(0); }",
2191 Constructor1Arg));
2192 EXPECT_TRUE(
2193 matches("class X { public: X(int); }; void x() { X x = X(0); }",
2194 Constructor1Arg));
2195 EXPECT_TRUE(
2196 matches("class X { public: X(int); }; void x() { X x = 0; }",
2197 Constructor1Arg));
2198 EXPECT_TRUE(
2199 notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }",
2200 Constructor1Arg));
2201}
2202
Peter Collingbourne1fec3df2014-02-06 21:52:24 +00002203TEST(Matcher, ConstructorListInitialization) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002204 StatementMatcher ConstructorListInit =
2205 cxxConstructExpr(isListInitialization());
Peter Collingbourne1fec3df2014-02-06 21:52:24 +00002206
2207 EXPECT_TRUE(
2208 matches("class X { public: X(int); }; void x() { X x{0}; }",
2209 ConstructorListInit));
2210 EXPECT_FALSE(
2211 matches("class X { public: X(int); }; void x() { X x(0); }",
2212 ConstructorListInit));
2213}
2214
Manuel Klimek7fca93b2012-10-23 10:40:50 +00002215TEST(Matcher,ThisExpr) {
2216 EXPECT_TRUE(
Aaron Ballman512fb642015-09-17 13:30:52 +00002217 matches("struct X { int a; int f () { return a; } };", cxxThisExpr()));
Manuel Klimek7fca93b2012-10-23 10:40:50 +00002218 EXPECT_TRUE(
Aaron Ballman512fb642015-09-17 13:30:52 +00002219 notMatches("struct X { int f () { int a; return a; } };", cxxThisExpr()));
Manuel Klimek7fca93b2012-10-23 10:40:50 +00002220}
2221
Manuel Klimek04616e42012-07-06 05:48:52 +00002222TEST(Matcher, BindTemporaryExpression) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002223 StatementMatcher TempExpression = cxxBindTemporaryExpr();
Manuel Klimek04616e42012-07-06 05:48:52 +00002224
2225 std::string ClassString = "class string { public: string(); ~string(); }; ";
2226
2227 EXPECT_TRUE(
2228 matches(ClassString +
2229 "string GetStringByValue();"
2230 "void FunctionTakesString(string s);"
2231 "void run() { FunctionTakesString(GetStringByValue()); }",
2232 TempExpression));
2233
2234 EXPECT_TRUE(
2235 notMatches(ClassString +
2236 "string* GetStringPointer(); "
2237 "void FunctionTakesStringPtr(string* s);"
2238 "void run() {"
2239 " string* s = GetStringPointer();"
2240 " FunctionTakesStringPtr(GetStringPointer());"
2241 " FunctionTakesStringPtr(s);"
2242 "}",
2243 TempExpression));
2244
2245 EXPECT_TRUE(
2246 notMatches("class no_dtor {};"
2247 "no_dtor GetObjByValue();"
2248 "void ConsumeObj(no_dtor param);"
2249 "void run() { ConsumeObj(GetObjByValue()); }",
2250 TempExpression));
2251}
2252
Sam Panzer68a35af2012-08-24 22:04:44 +00002253TEST(MaterializeTemporaryExpr, MatchesTemporary) {
2254 std::string ClassString =
2255 "class string { public: string(); int length(); }; ";
2256
2257 EXPECT_TRUE(
2258 matches(ClassString +
2259 "string GetStringByValue();"
2260 "void FunctionTakesString(string s);"
2261 "void run() { FunctionTakesString(GetStringByValue()); }",
2262 materializeTemporaryExpr()));
2263
2264 EXPECT_TRUE(
2265 notMatches(ClassString +
2266 "string* GetStringPointer(); "
2267 "void FunctionTakesStringPtr(string* s);"
2268 "void run() {"
2269 " string* s = GetStringPointer();"
2270 " FunctionTakesStringPtr(GetStringPointer());"
2271 " FunctionTakesStringPtr(s);"
2272 "}",
2273 materializeTemporaryExpr()));
2274
2275 EXPECT_TRUE(
2276 notMatches(ClassString +
2277 "string GetStringByValue();"
2278 "void run() { int k = GetStringByValue().length(); }",
2279 materializeTemporaryExpr()));
2280
2281 EXPECT_TRUE(
2282 notMatches(ClassString +
2283 "string GetStringByValue();"
2284 "void run() { GetStringByValue(); }",
2285 materializeTemporaryExpr()));
2286}
2287
Manuel Klimek04616e42012-07-06 05:48:52 +00002288TEST(ConstructorDeclaration, SimpleCase) {
2289 EXPECT_TRUE(matches("class Foo { Foo(int i); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002290 cxxConstructorDecl(ofClass(hasName("Foo")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002291 EXPECT_TRUE(notMatches("class Foo { Foo(int i); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002292 cxxConstructorDecl(ofClass(hasName("Bar")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002293}
2294
2295TEST(ConstructorDeclaration, IsImplicit) {
2296 // This one doesn't match because the constructor is not added by the
2297 // compiler (it is not needed).
2298 EXPECT_TRUE(notMatches("class Foo { };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002299 cxxConstructorDecl(isImplicit())));
Manuel Klimek04616e42012-07-06 05:48:52 +00002300 // The compiler added the implicit default constructor.
2301 EXPECT_TRUE(matches("class Foo { }; Foo* f = new Foo();",
Aaron Ballman512fb642015-09-17 13:30:52 +00002302 cxxConstructorDecl(isImplicit())));
Manuel Klimek04616e42012-07-06 05:48:52 +00002303 EXPECT_TRUE(matches("class Foo { Foo(){} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002304 cxxConstructorDecl(unless(isImplicit()))));
Joey Gouly0d9a2b22014-05-16 19:31:08 +00002305 // The compiler added an implicit assignment operator.
2306 EXPECT_TRUE(matches("struct A { int x; } a = {0}, b = a; void f() { a = b; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00002307 cxxMethodDecl(isImplicit(), hasName("operator="))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002308}
2309
Aaron Ballman6f6d0b62015-08-11 21:09:52 +00002310TEST(ConstructorDeclaration, IsExplicit) {
2311 EXPECT_TRUE(matches("struct S { explicit S(int); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002312 cxxConstructorDecl(isExplicit())));
Aaron Ballman6f6d0b62015-08-11 21:09:52 +00002313 EXPECT_TRUE(notMatches("struct S { S(int); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002314 cxxConstructorDecl(isExplicit())));
Aaron Ballman6f6d0b62015-08-11 21:09:52 +00002315}
2316
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002317TEST(ConstructorDeclaration, Kinds) {
2318 EXPECT_TRUE(matches("struct S { S(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002319 cxxConstructorDecl(isDefaultConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002320 EXPECT_TRUE(notMatches("struct S { S(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002321 cxxConstructorDecl(isCopyConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002322 EXPECT_TRUE(notMatches("struct S { S(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002323 cxxConstructorDecl(isMoveConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002324
2325 EXPECT_TRUE(notMatches("struct S { S(const S&); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002326 cxxConstructorDecl(isDefaultConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002327 EXPECT_TRUE(matches("struct S { S(const S&); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002328 cxxConstructorDecl(isCopyConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002329 EXPECT_TRUE(notMatches("struct S { S(const S&); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002330 cxxConstructorDecl(isMoveConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002331
2332 EXPECT_TRUE(notMatches("struct S { S(S&&); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002333 cxxConstructorDecl(isDefaultConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002334 EXPECT_TRUE(notMatches("struct S { S(S&&); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002335 cxxConstructorDecl(isCopyConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002336 EXPECT_TRUE(matches("struct S { S(S&&); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002337 cxxConstructorDecl(isMoveConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002338}
2339
Alexander Kornienko7d20a5a2016-04-13 11:13:08 +00002340TEST(ConstructorDeclaration, IsUserProvided) {
2341 EXPECT_TRUE(notMatches("struct S { int X = 0; };",
2342 cxxConstructorDecl(isUserProvided())));
2343 EXPECT_TRUE(notMatches("struct S { S() = default; };",
2344 cxxConstructorDecl(isUserProvided())));
2345 EXPECT_TRUE(notMatches("struct S { S() = delete; };",
2346 cxxConstructorDecl(isUserProvided())));
2347 EXPECT_TRUE(
2348 matches("struct S { S(); };", cxxConstructorDecl(isUserProvided())));
2349 EXPECT_TRUE(matches("struct S { S(); }; S::S(){}",
2350 cxxConstructorDecl(isUserProvided())));
2351}
2352
2353TEST(ConstructorDeclaration, IsDelegatingConstructor) {
2354 EXPECT_TRUE(notMatches("struct S { S(); S(int); int X; };",
2355 cxxConstructorDecl(isDelegatingConstructor())));
2356 EXPECT_TRUE(notMatches("struct S { S(){} S(int X) : X(X) {} int X; };",
2357 cxxConstructorDecl(isDelegatingConstructor())));
2358 EXPECT_TRUE(matches(
2359 "struct S { S() : S(0) {} S(int X) : X(X) {} int X; };",
2360 cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(0))));
2361 EXPECT_TRUE(matches(
2362 "struct S { S(); S(int X); int X; }; S::S(int X) : S() {}",
2363 cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(1))));
2364}
2365
Daniel Jasper1dad1832012-07-10 20:20:19 +00002366TEST(DestructorDeclaration, MatchesVirtualDestructor) {
2367 EXPECT_TRUE(matches("class Foo { virtual ~Foo(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002368 cxxDestructorDecl(ofClass(hasName("Foo")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00002369}
2370
2371TEST(DestructorDeclaration, DoesNotMatchImplicitDestructor) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002372 EXPECT_TRUE(notMatches("class Foo {};",
Aaron Ballman512fb642015-09-17 13:30:52 +00002373 cxxDestructorDecl(ofClass(hasName("Foo")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00002374}
2375
Manuel Klimek04616e42012-07-06 05:48:52 +00002376TEST(HasAnyConstructorInitializer, SimpleCase) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002377 EXPECT_TRUE(
2378 notMatches("class Foo { Foo() { } };",
2379 cxxConstructorDecl(hasAnyConstructorInitializer(anything()))));
2380 EXPECT_TRUE(
2381 matches("class Foo {"
2382 " Foo() : foo_() { }"
2383 " int foo_;"
2384 "};",
2385 cxxConstructorDecl(hasAnyConstructorInitializer(anything()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002386}
2387
2388TEST(HasAnyConstructorInitializer, ForField) {
2389 static const char Code[] =
2390 "class Baz { };"
2391 "class Foo {"
2392 " Foo() : foo_() { }"
2393 " Baz foo_;"
2394 " Baz bar_;"
2395 "};";
Aaron Ballman512fb642015-09-17 13:30:52 +00002396 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002397 forField(hasType(recordDecl(hasName("Baz"))))))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002398 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00002399 forField(hasName("foo_"))))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002400 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002401 forField(hasType(recordDecl(hasName("Bar"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002402}
2403
2404TEST(HasAnyConstructorInitializer, WithInitializer) {
2405 static const char Code[] =
2406 "class Foo {"
2407 " Foo() : foo_(0) { }"
2408 " int foo_;"
2409 "};";
Aaron Ballman512fb642015-09-17 13:30:52 +00002410 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00002411 withInitializer(integerLiteral(equals(0)))))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002412 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00002413 withInitializer(integerLiteral(equals(1)))))));
2414}
2415
2416TEST(HasAnyConstructorInitializer, IsWritten) {
2417 static const char Code[] =
2418 "struct Bar { Bar(){} };"
2419 "class Foo {"
2420 " Foo() : foo_() { }"
2421 " Bar foo_;"
2422 " Bar bar_;"
2423 "};";
Aaron Ballman512fb642015-09-17 13:30:52 +00002424 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00002425 allOf(forField(hasName("foo_")), isWritten())))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002426 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00002427 allOf(forField(hasName("bar_")), isWritten())))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002428 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00002429 allOf(forField(hasName("bar_")), unless(isWritten()))))));
2430}
2431
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002432TEST(HasAnyConstructorInitializer, IsBaseInitializer) {
2433 static const char Code[] =
2434 "struct B {};"
2435 "struct D : B {"
2436 " int I;"
2437 " D(int i) : I(i) {}"
2438 "};"
2439 "struct E : B {"
2440 " E() : B() {}"
2441 "};";
Aaron Ballman512fb642015-09-17 13:30:52 +00002442 EXPECT_TRUE(matches(Code, cxxConstructorDecl(allOf(
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002443 hasAnyConstructorInitializer(allOf(isBaseInitializer(), isWritten())),
2444 hasName("E")))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002445 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(allOf(
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002446 hasAnyConstructorInitializer(allOf(isBaseInitializer(), isWritten())),
2447 hasName("D")))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002448 EXPECT_TRUE(matches(Code, cxxConstructorDecl(allOf(
Aaron Ballmaned455d42015-08-11 20:42:00 +00002449 hasAnyConstructorInitializer(allOf(isMemberInitializer(), isWritten())),
2450 hasName("D")))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002451 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(allOf(
Aaron Ballmaned455d42015-08-11 20:42:00 +00002452 hasAnyConstructorInitializer(allOf(isMemberInitializer(), isWritten())),
2453 hasName("E")))));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002454}
2455
Manuel Klimek04616e42012-07-06 05:48:52 +00002456TEST(Matcher, NewExpression) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002457 StatementMatcher New = cxxNewExpr();
Manuel Klimek04616e42012-07-06 05:48:52 +00002458
2459 EXPECT_TRUE(matches("class X { public: X(); }; void x() { new X; }", New));
2460 EXPECT_TRUE(
2461 matches("class X { public: X(); }; void x() { new X(); }", New));
2462 EXPECT_TRUE(
2463 matches("class X { public: X(int); }; void x() { new X(0); }", New));
2464 EXPECT_TRUE(matches("class X {}; void x(int) { new X; }", New));
2465}
2466
2467TEST(Matcher, NewExpressionArgument) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002468 StatementMatcher New = cxxConstructExpr(
Daniel Jasper848cbe12012-09-18 13:09:13 +00002469 hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002470
2471 EXPECT_TRUE(
2472 matches("class X { public: X(int); }; void x() { int y; new X(y); }",
2473 New));
2474 EXPECT_TRUE(
2475 matches("class X { public: X(int); }; void x() { int y; new X(y); }",
2476 New));
2477 EXPECT_TRUE(
2478 notMatches("class X { public: X(int); }; void x() { int z; new X(z); }",
2479 New));
2480
Aaron Ballman512fb642015-09-17 13:30:52 +00002481 StatementMatcher WrongIndex = cxxConstructExpr(
Daniel Jasper848cbe12012-09-18 13:09:13 +00002482 hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002483 EXPECT_TRUE(
2484 notMatches("class X { public: X(int); }; void x() { int y; new X(y); }",
2485 WrongIndex));
2486}
2487
2488TEST(Matcher, NewExpressionArgumentCount) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002489 StatementMatcher New = cxxConstructExpr(argumentCountIs(1));
Manuel Klimek04616e42012-07-06 05:48:52 +00002490
2491 EXPECT_TRUE(
2492 matches("class X { public: X(int); }; void x() { new X(0); }", New));
2493 EXPECT_TRUE(
2494 notMatches("class X { public: X(int, int); }; void x() { new X(0, 0); }",
2495 New));
2496}
2497
Daniel Jasper1dad1832012-07-10 20:20:19 +00002498TEST(Matcher, DeleteExpression) {
2499 EXPECT_TRUE(matches("struct A {}; void f(A* a) { delete a; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00002500 cxxDeleteExpr()));
Daniel Jasper1dad1832012-07-10 20:20:19 +00002501}
2502
Manuel Klimek04616e42012-07-06 05:48:52 +00002503TEST(Matcher, DefaultArgument) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002504 StatementMatcher Arg = cxxDefaultArgExpr();
Manuel Klimek04616e42012-07-06 05:48:52 +00002505
2506 EXPECT_TRUE(matches("void x(int, int = 0) { int y; x(y); }", Arg));
2507 EXPECT_TRUE(
2508 matches("class X { void x(int, int = 0) { int y; x(y); } };", Arg));
2509 EXPECT_TRUE(notMatches("void x(int, int = 0) { int y; x(y, 0); }", Arg));
2510}
2511
2512TEST(Matcher, StringLiterals) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00002513 StatementMatcher Literal = stringLiteral();
Manuel Klimek04616e42012-07-06 05:48:52 +00002514 EXPECT_TRUE(matches("const char *s = \"string\";", Literal));
2515 // wide string
2516 EXPECT_TRUE(matches("const wchar_t *s = L\"string\";", Literal));
2517 // with escaped characters
2518 EXPECT_TRUE(matches("const char *s = \"\x05five\";", Literal));
2519 // no matching -- though the data type is the same, there is no string literal
2520 EXPECT_TRUE(notMatches("const char s[1] = {'a'};", Literal));
2521}
2522
2523TEST(Matcher, CharacterLiterals) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00002524 StatementMatcher CharLiteral = characterLiteral();
Manuel Klimek04616e42012-07-06 05:48:52 +00002525 EXPECT_TRUE(matches("const char c = 'c';", CharLiteral));
2526 // wide character
2527 EXPECT_TRUE(matches("const char c = L'c';", CharLiteral));
2528 // wide character, Hex encoded, NOT MATCHED!
2529 EXPECT_TRUE(notMatches("const wchar_t c = 0x2126;", CharLiteral));
2530 EXPECT_TRUE(notMatches("const char c = 0x1;", CharLiteral));
2531}
2532
2533TEST(Matcher, IntegerLiterals) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00002534 StatementMatcher HasIntLiteral = integerLiteral();
Manuel Klimek04616e42012-07-06 05:48:52 +00002535 EXPECT_TRUE(matches("int i = 10;", HasIntLiteral));
2536 EXPECT_TRUE(matches("int i = 0x1AB;", HasIntLiteral));
2537 EXPECT_TRUE(matches("int i = 10L;", HasIntLiteral));
2538 EXPECT_TRUE(matches("int i = 10U;", HasIntLiteral));
2539
2540 // Non-matching cases (character literals, float and double)
2541 EXPECT_TRUE(notMatches("int i = L'a';",
2542 HasIntLiteral)); // this is actually a character
2543 // literal cast to int
2544 EXPECT_TRUE(notMatches("int i = 'a';", HasIntLiteral));
2545 EXPECT_TRUE(notMatches("int i = 1e10;", HasIntLiteral));
2546 EXPECT_TRUE(notMatches("int i = 10.0;", HasIntLiteral));
2547}
2548
Daniel Jasper91f1c8c2013-07-26 18:52:58 +00002549TEST(Matcher, FloatLiterals) {
2550 StatementMatcher HasFloatLiteral = floatLiteral();
2551 EXPECT_TRUE(matches("float i = 10.0;", HasFloatLiteral));
2552 EXPECT_TRUE(matches("float i = 10.0f;", HasFloatLiteral));
2553 EXPECT_TRUE(matches("double i = 10.0;", HasFloatLiteral));
2554 EXPECT_TRUE(matches("double i = 10.0L;", HasFloatLiteral));
2555 EXPECT_TRUE(matches("double i = 1e10;", HasFloatLiteral));
Daniel Jasperd1423812015-02-03 09:45:52 +00002556 EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0))));
2557 EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0f))));
2558 EXPECT_TRUE(
2559 matches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(5.0)))));
Daniel Jasper91f1c8c2013-07-26 18:52:58 +00002560
2561 EXPECT_TRUE(notMatches("float i = 10;", HasFloatLiteral));
Daniel Jasperd1423812015-02-03 09:45:52 +00002562 EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0))));
2563 EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0f))));
2564 EXPECT_TRUE(
2565 notMatches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(6.0)))));
Daniel Jasper91f1c8c2013-07-26 18:52:58 +00002566}
2567
Daniel Jasper5901e472012-10-01 13:40:41 +00002568TEST(Matcher, NullPtrLiteral) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002569 EXPECT_TRUE(matches("int* i = nullptr;", cxxNullPtrLiteralExpr()));
Daniel Jasper5901e472012-10-01 13:40:41 +00002570}
2571
Szabolcs Sipos1d068bb2015-05-07 14:24:22 +00002572TEST(Matcher, GNUNullExpr) {
2573 EXPECT_TRUE(matches("int* i = __null;", gnuNullExpr()));
2574}
2575
Aaron Ballmana35b8fc2016-03-09 17:11:51 +00002576TEST(Matcher, AtomicExpr) {
2577 EXPECT_TRUE(matches("void foo() { int *ptr; __atomic_load_n(ptr, 1); }",
2578 atomicExpr()));
2579}
2580
2581TEST(Matcher, Initializers) {
2582 const char *ToMatch = "void foo() { struct point { double x; double y; };"
2583 " struct point ptarray[10] = "
2584 " { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 }; }";
2585 EXPECT_TRUE(matchesConditionally(
2586 ToMatch,
2587 initListExpr(
2588 has(
2589 cxxConstructExpr(
2590 requiresZeroInitialization())),
2591 has(
2592 initListExpr(
2593 hasType(asString("struct point")),
2594 has(floatLiteral(equals(1.0))),
2595 has(implicitValueInitExpr(
2596 hasType(asString("double")))))),
2597 has(
2598 initListExpr(
2599 hasType(asString("struct point")),
2600 has(floatLiteral(equals(2.0))),
2601 has(floatLiteral(equals(1.0)))))
2602 ), true, "-std=gnu++98"));
2603
2604 EXPECT_TRUE(matchesC99(ToMatch,
2605 initListExpr(
2606 hasSyntacticForm(
2607 initListExpr(
2608 has(
2609 designatedInitExpr(
2610 designatorCountIs(2),
2611 has(floatLiteral(
2612 equals(1.0))),
2613 has(integerLiteral(
2614 equals(2))))),
2615 has(
2616 designatedInitExpr(
2617 designatorCountIs(2),
2618 has(floatLiteral(
2619 equals(2.0))),
2620 has(integerLiteral(
2621 equals(2))))),
2622 has(
2623 designatedInitExpr(
2624 designatorCountIs(2),
2625 has(floatLiteral(
2626 equals(1.0))),
2627 has(integerLiteral(
2628 equals(0)))))
2629 )))));
2630}
2631
2632TEST(Matcher, ParenListExpr) {
2633 EXPECT_TRUE(
Aaron Ballman2648d422016-03-09 18:07:17 +00002634 matches("template<typename T> class foo { void bar() { foo X(*this); } };"
2635 "template class foo<int>;",
2636 varDecl(hasInitializer(parenListExpr(has(unaryOperator()))))));
Aaron Ballmana35b8fc2016-03-09 17:11:51 +00002637}
2638
2639TEST(Matcher, StmtExpr) {
2640 EXPECT_TRUE(matches("void declToImport() { int C = ({int X=4; X;}); }",
2641 varDecl(hasInitializer(stmtExpr()))));
2642}
2643
2644TEST(Matcher, ImportPredefinedExpr) {
2645 // __func__ expands as StringLiteral("foo")
2646 EXPECT_TRUE(matches("void foo() { __func__; }",
2647 predefinedExpr(
2648 hasType(asString("const char [4]")),
2649 has(stringLiteral()))));
2650}
2651
Daniel Jasper87c3d362012-09-20 14:12:57 +00002652TEST(Matcher, AsmStatement) {
2653 EXPECT_TRUE(matches("void foo() { __asm(\"mov al, 2\"); }", asmStmt()));
2654}
2655
Manuel Klimek04616e42012-07-06 05:48:52 +00002656TEST(Matcher, Conditions) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002657 StatementMatcher Condition =
2658 ifStmt(hasCondition(cxxBoolLiteral(equals(true))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002659
2660 EXPECT_TRUE(matches("void x() { if (true) {} }", Condition));
2661 EXPECT_TRUE(notMatches("void x() { if (false) {} }", Condition));
2662 EXPECT_TRUE(notMatches("void x() { bool a = true; if (a) {} }", Condition));
2663 EXPECT_TRUE(notMatches("void x() { if (true || false) {} }", Condition));
2664 EXPECT_TRUE(notMatches("void x() { if (1) {} }", Condition));
2665}
2666
Manuel Klimek909b5c942014-05-27 10:04:12 +00002667TEST(IfStmt, ChildTraversalMatchers) {
2668 EXPECT_TRUE(matches("void f() { if (false) true; else false; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00002669 ifStmt(hasThen(cxxBoolLiteral(equals(true))))));
Manuel Klimek909b5c942014-05-27 10:04:12 +00002670 EXPECT_TRUE(notMatches("void f() { if (false) false; else true; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00002671 ifStmt(hasThen(cxxBoolLiteral(equals(true))))));
Manuel Klimek909b5c942014-05-27 10:04:12 +00002672 EXPECT_TRUE(matches("void f() { if (false) false; else true; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00002673 ifStmt(hasElse(cxxBoolLiteral(equals(true))))));
Manuel Klimek909b5c942014-05-27 10:04:12 +00002674 EXPECT_TRUE(notMatches("void f() { if (false) true; else false; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00002675 ifStmt(hasElse(cxxBoolLiteral(equals(true))))));
Manuel Klimek909b5c942014-05-27 10:04:12 +00002676}
2677
Manuel Klimek04616e42012-07-06 05:48:52 +00002678TEST(MatchBinaryOperator, HasOperatorName) {
2679 StatementMatcher OperatorOr = binaryOperator(hasOperatorName("||"));
2680
2681 EXPECT_TRUE(matches("void x() { true || false; }", OperatorOr));
2682 EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
2683}
2684
2685TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
2686 StatementMatcher OperatorTrueFalse =
Aaron Ballman512fb642015-09-17 13:30:52 +00002687 binaryOperator(hasLHS(cxxBoolLiteral(equals(true))),
2688 hasRHS(cxxBoolLiteral(equals(false))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002689
2690 EXPECT_TRUE(matches("void x() { true || false; }", OperatorTrueFalse));
2691 EXPECT_TRUE(matches("void x() { true && false; }", OperatorTrueFalse));
2692 EXPECT_TRUE(notMatches("void x() { false || true; }", OperatorTrueFalse));
Alexander Kornienkoe39993e2015-11-02 22:23:21 +00002693
2694 StatementMatcher OperatorIntPointer = arraySubscriptExpr(
2695 hasLHS(hasType(isInteger())), hasRHS(hasType(pointsTo(qualType()))));
2696 EXPECT_TRUE(matches("void x() { 1[\"abc\"]; }", OperatorIntPointer));
2697 EXPECT_TRUE(notMatches("void x() { \"abc\"[1]; }", OperatorIntPointer));
Manuel Klimek04616e42012-07-06 05:48:52 +00002698}
2699
2700TEST(MatchBinaryOperator, HasEitherOperand) {
2701 StatementMatcher HasOperand =
Aaron Ballman512fb642015-09-17 13:30:52 +00002702 binaryOperator(hasEitherOperand(cxxBoolLiteral(equals(false))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002703
2704 EXPECT_TRUE(matches("void x() { true || false; }", HasOperand));
2705 EXPECT_TRUE(matches("void x() { false && true; }", HasOperand));
2706 EXPECT_TRUE(notMatches("void x() { true || true; }", HasOperand));
2707}
2708
2709TEST(Matcher, BinaryOperatorTypes) {
2710 // Integration test that verifies the AST provides all binary operators in
2711 // a way we expect.
2712 // FIXME: Operator ','
2713 EXPECT_TRUE(
2714 matches("void x() { 3, 4; }", binaryOperator(hasOperatorName(","))));
2715 EXPECT_TRUE(
2716 matches("bool b; bool c = (b = true);",
2717 binaryOperator(hasOperatorName("="))));
2718 EXPECT_TRUE(
2719 matches("bool b = 1 != 2;", binaryOperator(hasOperatorName("!="))));
2720 EXPECT_TRUE(
2721 matches("bool b = 1 == 2;", binaryOperator(hasOperatorName("=="))));
2722 EXPECT_TRUE(matches("bool b = 1 < 2;", binaryOperator(hasOperatorName("<"))));
2723 EXPECT_TRUE(
2724 matches("bool b = 1 <= 2;", binaryOperator(hasOperatorName("<="))));
2725 EXPECT_TRUE(
2726 matches("int i = 1 << 2;", binaryOperator(hasOperatorName("<<"))));
2727 EXPECT_TRUE(
2728 matches("int i = 1; int j = (i <<= 2);",
2729 binaryOperator(hasOperatorName("<<="))));
2730 EXPECT_TRUE(matches("bool b = 1 > 2;", binaryOperator(hasOperatorName(">"))));
2731 EXPECT_TRUE(
2732 matches("bool b = 1 >= 2;", binaryOperator(hasOperatorName(">="))));
2733 EXPECT_TRUE(
2734 matches("int i = 1 >> 2;", binaryOperator(hasOperatorName(">>"))));
2735 EXPECT_TRUE(
2736 matches("int i = 1; int j = (i >>= 2);",
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 ^= 42);",
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 %= 42);",
2747 binaryOperator(hasOperatorName("%="))));
2748 EXPECT_TRUE(
2749 matches("bool b = 42 &23;", binaryOperator(hasOperatorName("&"))));
2750 EXPECT_TRUE(
2751 matches("bool b = true && false;",
2752 binaryOperator(hasOperatorName("&&"))));
2753 EXPECT_TRUE(
2754 matches("bool b = true; bool c = (b &= false);",
2755 binaryOperator(hasOperatorName("&="))));
2756 EXPECT_TRUE(
2757 matches("bool b = 42 | 23;", binaryOperator(hasOperatorName("|"))));
2758 EXPECT_TRUE(
2759 matches("bool b = true || false;",
2760 binaryOperator(hasOperatorName("||"))));
2761 EXPECT_TRUE(
2762 matches("bool b = true; bool c = (b |= false);",
2763 binaryOperator(hasOperatorName("|="))));
2764 EXPECT_TRUE(
2765 matches("int i = 42 *23;", binaryOperator(hasOperatorName("*"))));
2766 EXPECT_TRUE(
2767 matches("int i = 42; int j = (i *= 23);",
2768 binaryOperator(hasOperatorName("*="))));
2769 EXPECT_TRUE(
2770 matches("int i = 42 / 23;", binaryOperator(hasOperatorName("/"))));
2771 EXPECT_TRUE(
2772 matches("int i = 42; int j = (i /= 23);",
2773 binaryOperator(hasOperatorName("/="))));
2774 EXPECT_TRUE(
2775 matches("int i = 42 + 23;", binaryOperator(hasOperatorName("+"))));
2776 EXPECT_TRUE(
2777 matches("int i = 42; int j = (i += 23);",
2778 binaryOperator(hasOperatorName("+="))));
2779 EXPECT_TRUE(
2780 matches("int i = 42 - 23;", binaryOperator(hasOperatorName("-"))));
2781 EXPECT_TRUE(
2782 matches("int i = 42; int j = (i -= 23);",
2783 binaryOperator(hasOperatorName("-="))));
2784 EXPECT_TRUE(
2785 matches("struct A { void x() { void (A::*a)(); (this->*a)(); } };",
2786 binaryOperator(hasOperatorName("->*"))));
2787 EXPECT_TRUE(
2788 matches("struct A { void x() { void (A::*a)(); ((*this).*a)(); } };",
2789 binaryOperator(hasOperatorName(".*"))));
2790
2791 // Member expressions as operators are not supported in matches.
2792 EXPECT_TRUE(
2793 notMatches("struct A { void x(A *a) { a->x(this); } };",
2794 binaryOperator(hasOperatorName("->"))));
2795
2796 // Initializer assignments are not represented as operator equals.
2797 EXPECT_TRUE(
2798 notMatches("bool b = true;", binaryOperator(hasOperatorName("="))));
2799
2800 // Array indexing is not represented as operator.
2801 EXPECT_TRUE(notMatches("int a[42]; void x() { a[23]; }", unaryOperator()));
2802
2803 // Overloaded operators do not match at all.
2804 EXPECT_TRUE(notMatches(
2805 "struct A { bool operator&&(const A &a) const { return false; } };"
2806 "void x() { A a, b; a && b; }",
2807 binaryOperator()));
2808}
2809
2810TEST(MatchUnaryOperator, HasOperatorName) {
2811 StatementMatcher OperatorNot = unaryOperator(hasOperatorName("!"));
2812
2813 EXPECT_TRUE(matches("void x() { !true; } ", OperatorNot));
2814 EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
2815}
2816
2817TEST(MatchUnaryOperator, HasUnaryOperand) {
2818 StatementMatcher OperatorOnFalse =
Aaron Ballman512fb642015-09-17 13:30:52 +00002819 unaryOperator(hasUnaryOperand(cxxBoolLiteral(equals(false))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002820
2821 EXPECT_TRUE(matches("void x() { !false; }", OperatorOnFalse));
2822 EXPECT_TRUE(notMatches("void x() { !true; }", OperatorOnFalse));
2823}
2824
2825TEST(Matcher, UnaryOperatorTypes) {
2826 // Integration test that verifies the AST provides all unary operators in
2827 // a way we expect.
2828 EXPECT_TRUE(matches("bool b = !true;", unaryOperator(hasOperatorName("!"))));
2829 EXPECT_TRUE(
2830 matches("bool b; bool *p = &b;", unaryOperator(hasOperatorName("&"))));
2831 EXPECT_TRUE(matches("int i = ~ 1;", unaryOperator(hasOperatorName("~"))));
2832 EXPECT_TRUE(
2833 matches("bool *p; bool b = *p;", unaryOperator(hasOperatorName("*"))));
2834 EXPECT_TRUE(
2835 matches("int i; int j = +i;", unaryOperator(hasOperatorName("+"))));
2836 EXPECT_TRUE(
2837 matches("int i; int j = -i;", unaryOperator(hasOperatorName("-"))));
2838 EXPECT_TRUE(
2839 matches("int i; int j = ++i;", unaryOperator(hasOperatorName("++"))));
2840 EXPECT_TRUE(
2841 matches("int i; int j = i++;", unaryOperator(hasOperatorName("++"))));
2842 EXPECT_TRUE(
2843 matches("int i; int j = --i;", unaryOperator(hasOperatorName("--"))));
2844 EXPECT_TRUE(
2845 matches("int i; int j = i--;", unaryOperator(hasOperatorName("--"))));
2846
2847 // We don't match conversion operators.
2848 EXPECT_TRUE(notMatches("int i; double d = (double)i;", unaryOperator()));
2849
2850 // Function calls are not represented as operator.
2851 EXPECT_TRUE(notMatches("void f(); void x() { f(); }", unaryOperator()));
2852
2853 // Overloaded operators do not match at all.
2854 // FIXME: We probably want to add that.
2855 EXPECT_TRUE(notMatches(
2856 "struct A { bool operator!() const { return false; } };"
2857 "void x() { A a; !a; }", unaryOperator(hasOperatorName("!"))));
2858}
2859
2860TEST(Matcher, ConditionalOperator) {
2861 StatementMatcher Conditional = conditionalOperator(
Aaron Ballman512fb642015-09-17 13:30:52 +00002862 hasCondition(cxxBoolLiteral(equals(true))),
2863 hasTrueExpression(cxxBoolLiteral(equals(false))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002864
2865 EXPECT_TRUE(matches("void x() { true ? false : true; }", Conditional));
2866 EXPECT_TRUE(notMatches("void x() { false ? false : true; }", Conditional));
2867 EXPECT_TRUE(notMatches("void x() { true ? true : false; }", Conditional));
2868
2869 StatementMatcher ConditionalFalse = conditionalOperator(
Aaron Ballman512fb642015-09-17 13:30:52 +00002870 hasFalseExpression(cxxBoolLiteral(equals(false))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002871
2872 EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse));
2873 EXPECT_TRUE(
2874 notMatches("void x() { true ? false : true; }", ConditionalFalse));
Aaron Ballmana35b8fc2016-03-09 17:11:51 +00002875
2876 EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse));
2877 EXPECT_TRUE(
2878 notMatches("void x() { true ? false : true; }", ConditionalFalse));
2879}
2880
2881TEST(Matcher, BinaryConditionalOperator) {
2882 StatementMatcher AlwaysOne = binaryConditionalOperator(
2883 hasCondition(implicitCastExpr(
2884 has(
2885 opaqueValueExpr(
2886 hasSourceExpression((integerLiteral(equals(1)))))))),
2887 hasFalseExpression(integerLiteral(equals(0))));
2888
2889 EXPECT_TRUE(matches("void x() { 1 ?: 0; }", AlwaysOne));
2890
2891 StatementMatcher FourNotFive = binaryConditionalOperator(
2892 hasTrueExpression(opaqueValueExpr(
2893 hasSourceExpression((integerLiteral(equals(4)))))),
2894 hasFalseExpression(integerLiteral(equals(5))));
2895
2896 EXPECT_TRUE(matches("void x() { 4 ?: 5; }", FourNotFive));
Manuel Klimek04616e42012-07-06 05:48:52 +00002897}
2898
Daniel Jasper1dad1832012-07-10 20:20:19 +00002899TEST(ArraySubscriptMatchers, ArraySubscripts) {
2900 EXPECT_TRUE(matches("int i[2]; void f() { i[1] = 1; }",
2901 arraySubscriptExpr()));
2902 EXPECT_TRUE(notMatches("int i; void f() { i = 1; }",
2903 arraySubscriptExpr()));
2904}
2905
2906TEST(ArraySubscriptMatchers, ArrayIndex) {
2907 EXPECT_TRUE(matches(
2908 "int i[2]; void f() { i[1] = 1; }",
2909 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
2910 EXPECT_TRUE(matches(
2911 "int i[2]; void f() { 1[i] = 1; }",
2912 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
2913 EXPECT_TRUE(notMatches(
2914 "int i[2]; void f() { i[1] = 1; }",
2915 arraySubscriptExpr(hasIndex(integerLiteral(equals(0))))));
2916}
2917
2918TEST(ArraySubscriptMatchers, MatchesArrayBase) {
2919 EXPECT_TRUE(matches(
2920 "int i[2]; void f() { i[1] = 2; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002921 arraySubscriptExpr(hasBase(implicitCastExpr(
2922 hasSourceExpression(declRefExpr()))))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00002923}
2924
Manuel Klimek04616e42012-07-06 05:48:52 +00002925TEST(Matcher, HasNameSupportsNamespaces) {
2926 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002927 recordDecl(hasName("a::b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002928 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002929 recordDecl(hasName("::a::b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002930 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002931 recordDecl(hasName("b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002932 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002933 recordDecl(hasName("C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002934 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002935 recordDecl(hasName("c::b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002936 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002937 recordDecl(hasName("a::c::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002938 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002939 recordDecl(hasName("a::b::A"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002940 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002941 recordDecl(hasName("::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002942 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002943 recordDecl(hasName("::b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002944 EXPECT_TRUE(notMatches("namespace a { namespace 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(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002947 recordDecl(hasName("a+b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002948 EXPECT_TRUE(notMatches("namespace a { namespace b { class AC; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002949 recordDecl(hasName("C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002950}
2951
2952TEST(Matcher, HasNameSupportsOuterClasses) {
2953 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002954 matches("class A { class B { class C; }; };",
2955 recordDecl(hasName("A::B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002956 EXPECT_TRUE(
2957 matches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002958 recordDecl(hasName("::A::B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002959 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002960 matches("class A { class B { class C; }; };",
2961 recordDecl(hasName("B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002962 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002963 matches("class A { class B { class C; }; };",
2964 recordDecl(hasName("C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002965 EXPECT_TRUE(
2966 notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002967 recordDecl(hasName("c::B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002968 EXPECT_TRUE(
2969 notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002970 recordDecl(hasName("A::c::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002971 EXPECT_TRUE(
2972 notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002973 recordDecl(hasName("A::B::A"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002974 EXPECT_TRUE(
2975 notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002976 recordDecl(hasName("::C"))));
2977 EXPECT_TRUE(
2978 notMatches("class A { class B { class C; }; };",
2979 recordDecl(hasName("::B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002980 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002981 recordDecl(hasName("z::A::B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002982 EXPECT_TRUE(
2983 notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002984 recordDecl(hasName("A+B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002985}
2986
Samuel Benzaquen8e566f32016-02-05 18:29:24 +00002987TEST(Matcher, HasNameSupportsInlinedNamespaces) {
2988 std::string code = "namespace a { inline namespace b { class C; } }";
2989 EXPECT_TRUE(matches(code, recordDecl(hasName("a::b::C"))));
2990 EXPECT_TRUE(matches(code, recordDecl(hasName("a::C"))));
2991 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::b::C"))));
2992 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::C"))));
2993}
2994
2995TEST(Matcher, HasNameSupportsAnonymousNamespaces) {
2996 std::string code = "namespace a { namespace { class C; } }";
2997 EXPECT_TRUE(
2998 matches(code, recordDecl(hasName("a::(anonymous namespace)::C"))));
2999 EXPECT_TRUE(matches(code, recordDecl(hasName("a::C"))));
3000 EXPECT_TRUE(
3001 matches(code, recordDecl(hasName("::a::(anonymous namespace)::C"))));
3002 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::C"))));
3003}
3004
3005TEST(Matcher, HasNameSupportsAnonymousOuterClasses) {
3006 EXPECT_TRUE(matches("class A { class { class C; } x; };",
3007 recordDecl(hasName("A::(anonymous class)::C"))));
3008 EXPECT_TRUE(matches("class A { class { class C; } x; };",
3009 recordDecl(hasName("::A::(anonymous class)::C"))));
3010 EXPECT_FALSE(matches("class A { class { class C; } x; };",
3011 recordDecl(hasName("::A::C"))));
3012 EXPECT_TRUE(matches("class A { struct { class C; } x; };",
3013 recordDecl(hasName("A::(anonymous struct)::C"))));
3014 EXPECT_TRUE(matches("class A { struct { class C; } x; };",
3015 recordDecl(hasName("::A::(anonymous struct)::C"))));
3016 EXPECT_FALSE(matches("class A { struct { class C; } x; };",
3017 recordDecl(hasName("::A::C"))));
3018}
3019
3020TEST(Matcher, HasNameSupportsFunctionScope) {
3021 std::string code =
3022 "namespace a { void F(int a) { struct S { int m; }; int i; } }";
3023 EXPECT_TRUE(matches(code, varDecl(hasName("i"))));
3024 EXPECT_FALSE(matches(code, varDecl(hasName("F()::i"))));
3025
3026 EXPECT_TRUE(matches(code, fieldDecl(hasName("m"))));
3027 EXPECT_TRUE(matches(code, fieldDecl(hasName("S::m"))));
3028 EXPECT_TRUE(matches(code, fieldDecl(hasName("F(int)::S::m"))));
3029 EXPECT_TRUE(matches(code, fieldDecl(hasName("a::F(int)::S::m"))));
3030 EXPECT_TRUE(matches(code, fieldDecl(hasName("::a::F(int)::S::m"))));
3031}
3032
Samuel Benzaquen922bef42016-02-22 21:13:02 +00003033TEST(Matcher, HasAnyName) {
3034 const std::string Code = "namespace a { namespace b { class C; } }";
3035
3036 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX", "a::b::C"))));
3037 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("a::b::C", "XX"))));
3038 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX::C", "a::b::C"))));
3039 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX", "C"))));
3040
3041 EXPECT_TRUE(notMatches(Code, recordDecl(hasAnyName("::C", "::b::C"))));
3042 EXPECT_TRUE(
3043 matches(Code, recordDecl(hasAnyName("::C", "::b::C", "::a::b::C"))));
Samuel Benzaquenc1384c12016-03-25 16:29:30 +00003044
3045 std::vector<StringRef> Names = {"::C", "::b::C", "::a::b::C"};
3046 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName(Names))));
Samuel Benzaquen922bef42016-02-22 21:13:02 +00003047}
3048
Manuel Klimek04616e42012-07-06 05:48:52 +00003049TEST(Matcher, IsDefinition) {
3050 DeclarationMatcher DefinitionOfClassA =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003051 recordDecl(hasName("A"), isDefinition());
Manuel Klimek04616e42012-07-06 05:48:52 +00003052 EXPECT_TRUE(matches("class A {};", DefinitionOfClassA));
3053 EXPECT_TRUE(notMatches("class A;", DefinitionOfClassA));
3054
3055 DeclarationMatcher DefinitionOfVariableA =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003056 varDecl(hasName("a"), isDefinition());
Manuel Klimek04616e42012-07-06 05:48:52 +00003057 EXPECT_TRUE(matches("int a;", DefinitionOfVariableA));
3058 EXPECT_TRUE(notMatches("extern int a;", DefinitionOfVariableA));
3059
3060 DeclarationMatcher DefinitionOfMethodA =
Aaron Ballman512fb642015-09-17 13:30:52 +00003061 cxxMethodDecl(hasName("a"), isDefinition());
Manuel Klimek04616e42012-07-06 05:48:52 +00003062 EXPECT_TRUE(matches("class A { void a() {} };", DefinitionOfMethodA));
3063 EXPECT_TRUE(notMatches("class A { void a(); };", DefinitionOfMethodA));
3064}
3065
3066TEST(Matcher, OfClass) {
Aaron Ballman512fb642015-09-17 13:30:52 +00003067 StatementMatcher Constructor = cxxConstructExpr(hasDeclaration(cxxMethodDecl(
Manuel Klimek04616e42012-07-06 05:48:52 +00003068 ofClass(hasName("X")))));
3069
3070 EXPECT_TRUE(
3071 matches("class X { public: X(); }; void x(int) { X x; }", Constructor));
3072 EXPECT_TRUE(
3073 matches("class X { public: X(); }; void x(int) { X x = X(); }",
3074 Constructor));
3075 EXPECT_TRUE(
3076 notMatches("class Y { public: Y(); }; void x(int) { Y y; }",
3077 Constructor));
3078}
3079
3080TEST(Matcher, VisitsTemplateInstantiations) {
3081 EXPECT_TRUE(matches(
3082 "class A { public: void x(); };"
3083 "template <typename T> class B { public: void y() { T t; t.x(); } };"
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003084 "void f() { B<A> b; b.y(); }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003085 callExpr(callee(cxxMethodDecl(hasName("x"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003086
3087 EXPECT_TRUE(matches(
3088 "class A { public: void x(); };"
3089 "class C {"
3090 " public:"
3091 " template <typename T> class B { public: void y() { T t; t.x(); } };"
3092 "};"
3093 "void f() {"
3094 " C::B<A> b; b.y();"
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003095 "}",
Aaron Ballman512fb642015-09-17 13:30:52 +00003096 recordDecl(hasName("C"), hasDescendant(callExpr(
3097 callee(cxxMethodDecl(hasName("x"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003098}
3099
Daniel Jasper1dad1832012-07-10 20:20:19 +00003100TEST(Matcher, HandlesNullQualTypes) {
3101 // FIXME: Add a Type matcher so we can replace uses of this
3102 // variable with Type(True())
3103 const TypeMatcher AnyType = anything();
3104
3105 // We don't really care whether this matcher succeeds; we're testing that
3106 // it completes without crashing.
3107 EXPECT_TRUE(matches(
3108 "struct A { };"
3109 "template <typename T>"
3110 "void f(T t) {"
3111 " T local_t(t /* this becomes a null QualType in the AST */);"
3112 "}"
3113 "void g() {"
3114 " f(0);"
3115 "}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003116 expr(hasType(TypeMatcher(
Daniel Jasper1dad1832012-07-10 20:20:19 +00003117 anyOf(
3118 TypeMatcher(hasDeclaration(anything())),
3119 pointsTo(AnyType),
3120 references(AnyType)
3121 // Other QualType matchers should go here.
3122 ))))));
3123}
3124
Manuel Klimek04616e42012-07-06 05:48:52 +00003125// For testing AST_MATCHER_P().
Daniel Jasper1dad1832012-07-10 20:20:19 +00003126AST_MATCHER_P(Decl, just, internal::Matcher<Decl>, AMatcher) {
Manuel Klimek04616e42012-07-06 05:48:52 +00003127 // Make sure all special variables are used: node, match_finder,
3128 // bound_nodes_builder, and the parameter named 'AMatcher'.
3129 return AMatcher.matches(Node, Finder, Builder);
3130}
3131
3132TEST(AstMatcherPMacro, Works) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003133 DeclarationMatcher HasClassB = just(has(recordDecl(hasName("B")).bind("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003134
3135 EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003136 HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003137
3138 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003139 HasClassB, new VerifyIdIsBoundTo<Decl>("a")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003140
3141 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003142 HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003143}
3144
Benjamin Kramer57dd9bd2015-03-07 20:38:15 +00003145AST_POLYMORPHIC_MATCHER_P(polymorphicHas,
3146 AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt),
3147 internal::Matcher<Decl>, AMatcher) {
Manuel Klimek04616e42012-07-06 05:48:52 +00003148 return Finder->matchesChildOf(
Manuel Klimekeb958de2012-09-05 12:12:07 +00003149 Node, AMatcher, Builder,
Manuel Klimek04616e42012-07-06 05:48:52 +00003150 ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
3151 ASTMatchFinder::BK_First);
3152}
3153
3154TEST(AstPolymorphicMatcherPMacro, Works) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003155 DeclarationMatcher HasClassB =
3156 polymorphicHas(recordDecl(hasName("B")).bind("b"));
Manuel Klimek04616e42012-07-06 05:48:52 +00003157
3158 EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003159 HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003160
3161 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003162 HasClassB, new VerifyIdIsBoundTo<Decl>("a")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003163
3164 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003165 HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003166
3167 StatementMatcher StatementHasClassB =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003168 polymorphicHas(recordDecl(hasName("B")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003169
3170 EXPECT_TRUE(matches("void x() { class B {}; }", StatementHasClassB));
3171}
3172
3173TEST(For, FindsForLoops) {
3174 EXPECT_TRUE(matches("void f() { for(;;); }", forStmt()));
3175 EXPECT_TRUE(matches("void f() { if(true) for(;;); }", forStmt()));
Daniel Jasper6f595392012-10-01 15:05:34 +00003176 EXPECT_TRUE(notMatches("int as[] = { 1, 2, 3 };"
3177 "void f() { for (auto &a : as); }",
Daniel Jasper5901e472012-10-01 13:40:41 +00003178 forStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003179}
3180
Daniel Jasper4e566c42012-07-12 08:50:38 +00003181TEST(For, ForLoopInternals) {
3182 EXPECT_TRUE(matches("void f(){ int i; for (; i < 3 ; ); }",
3183 forStmt(hasCondition(anything()))));
3184 EXPECT_TRUE(matches("void f() { for (int i = 0; ;); }",
3185 forStmt(hasLoopInit(anything()))));
3186}
3187
Alexander Kornienko9b539e12014-02-05 16:35:08 +00003188TEST(For, ForRangeLoopInternals) {
3189 EXPECT_TRUE(matches("void f(){ int a[] {1, 2}; for (int i : a); }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003190 cxxForRangeStmt(hasLoopVariable(anything()))));
Manuel Klimek86510812014-05-23 17:49:03 +00003191 EXPECT_TRUE(matches(
3192 "void f(){ int a[] {1, 2}; for (int i : a); }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003193 cxxForRangeStmt(hasRangeInit(declRefExpr(to(varDecl(hasName("a"))))))));
Alexander Kornienko9b539e12014-02-05 16:35:08 +00003194}
3195
Daniel Jasper4e566c42012-07-12 08:50:38 +00003196TEST(For, NegativeForLoopInternals) {
3197 EXPECT_TRUE(notMatches("void f(){ for (int i = 0; ; ++i); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003198 forStmt(hasCondition(expr()))));
Daniel Jasper4e566c42012-07-12 08:50:38 +00003199 EXPECT_TRUE(notMatches("void f() {int i; for (; i < 4; ++i) {} }",
3200 forStmt(hasLoopInit(anything()))));
3201}
3202
Manuel Klimek04616e42012-07-06 05:48:52 +00003203TEST(For, ReportsNoFalsePositives) {
3204 EXPECT_TRUE(notMatches("void f() { ; }", forStmt()));
3205 EXPECT_TRUE(notMatches("void f() { if(true); }", forStmt()));
3206}
3207
3208TEST(CompoundStatement, HandlesSimpleCases) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003209 EXPECT_TRUE(notMatches("void f();", compoundStmt()));
3210 EXPECT_TRUE(matches("void f() {}", compoundStmt()));
3211 EXPECT_TRUE(matches("void f() {{}}", compoundStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003212}
3213
3214TEST(CompoundStatement, DoesNotMatchEmptyStruct) {
3215 // It's not a compound statement just because there's "{}" in the source
3216 // text. This is an AST search, not grep.
3217 EXPECT_TRUE(notMatches("namespace n { struct S {}; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003218 compoundStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003219 EXPECT_TRUE(matches("namespace n { struct S { void f() {{}} }; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003220 compoundStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003221}
3222
Daniel Jasper4e566c42012-07-12 08:50:38 +00003223TEST(HasBody, FindsBodyOfForWhileDoLoops) {
Manuel Klimek04616e42012-07-06 05:48:52 +00003224 EXPECT_TRUE(matches("void f() { for(;;) {} }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003225 forStmt(hasBody(compoundStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003226 EXPECT_TRUE(notMatches("void f() { for(;;); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003227 forStmt(hasBody(compoundStmt()))));
Daniel Jasper4e566c42012-07-12 08:50:38 +00003228 EXPECT_TRUE(matches("void f() { while(true) {} }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003229 whileStmt(hasBody(compoundStmt()))));
Daniel Jasper4e566c42012-07-12 08:50:38 +00003230 EXPECT_TRUE(matches("void f() { do {} while(true); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003231 doStmt(hasBody(compoundStmt()))));
Manuel Klimek2af0a912014-05-27 07:45:18 +00003232 EXPECT_TRUE(matches("void f() { int p[2]; for (auto x : p) {} }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003233 cxxForRangeStmt(hasBody(compoundStmt()))));
Aaron Ballman2b6963f2016-01-20 16:26:48 +00003234 EXPECT_TRUE(matches("void f() {}", functionDecl(hasBody(compoundStmt()))));
3235 EXPECT_TRUE(notMatches("void f();", functionDecl(hasBody(compoundStmt()))));
3236 EXPECT_TRUE(matches("void f(); void f() {}",
3237 functionDecl(hasBody(compoundStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003238}
3239
3240TEST(HasAnySubstatement, MatchesForTopLevelCompoundStatement) {
3241 // The simplest case: every compound statement is in a function
3242 // definition, and the function body itself must be a compound
3243 // statement.
3244 EXPECT_TRUE(matches("void f() { for (;;); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003245 compoundStmt(hasAnySubstatement(forStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003246}
3247
3248TEST(HasAnySubstatement, IsNotRecursive) {
3249 // It's really "has any immediate substatement".
3250 EXPECT_TRUE(notMatches("void f() { if (true) for (;;); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003251 compoundStmt(hasAnySubstatement(forStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003252}
3253
3254TEST(HasAnySubstatement, MatchesInNestedCompoundStatements) {
3255 EXPECT_TRUE(matches("void f() { if (true) { for (;;); } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003256 compoundStmt(hasAnySubstatement(forStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003257}
3258
3259TEST(HasAnySubstatement, FindsSubstatementBetweenOthers) {
3260 EXPECT_TRUE(matches("void f() { 1; 2; 3; for (;;); 4; 5; 6; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003261 compoundStmt(hasAnySubstatement(forStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003262}
3263
3264TEST(StatementCountIs, FindsNoStatementsInAnEmptyCompoundStatement) {
3265 EXPECT_TRUE(matches("void f() { }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003266 compoundStmt(statementCountIs(0))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003267 EXPECT_TRUE(notMatches("void f() {}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003268 compoundStmt(statementCountIs(1))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003269}
3270
3271TEST(StatementCountIs, AppearsToMatchOnlyOneCount) {
3272 EXPECT_TRUE(matches("void f() { 1; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003273 compoundStmt(statementCountIs(1))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003274 EXPECT_TRUE(notMatches("void f() { 1; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003275 compoundStmt(statementCountIs(0))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003276 EXPECT_TRUE(notMatches("void f() { 1; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003277 compoundStmt(statementCountIs(2))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003278}
3279
3280TEST(StatementCountIs, WorksWithMultipleStatements) {
3281 EXPECT_TRUE(matches("void f() { 1; 2; 3; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003282 compoundStmt(statementCountIs(3))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003283}
3284
3285TEST(StatementCountIs, WorksWithNestedCompoundStatements) {
3286 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003287 compoundStmt(statementCountIs(1))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003288 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003289 compoundStmt(statementCountIs(2))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003290 EXPECT_TRUE(notMatches("void f() { { 1; } { 1; 2; 3; 4; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003291 compoundStmt(statementCountIs(3))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003292 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003293 compoundStmt(statementCountIs(4))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003294}
3295
3296TEST(Member, WorksInSimplestCase) {
3297 EXPECT_TRUE(matches("struct { int first; } s; int i(s.first);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003298 memberExpr(member(hasName("first")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003299}
3300
3301TEST(Member, DoesNotMatchTheBaseExpression) {
3302 // Don't pick out the wrong part of the member expression, this should
3303 // be checking the member (name) only.
3304 EXPECT_TRUE(notMatches("struct { int i; } first; int i(first.i);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003305 memberExpr(member(hasName("first")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003306}
3307
3308TEST(Member, MatchesInMemberFunctionCall) {
3309 EXPECT_TRUE(matches("void f() {"
3310 " struct { void first() {}; } s;"
3311 " s.first();"
3312 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003313 memberExpr(member(hasName("first")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003314}
3315
Daniel Jasperb0c7b612012-10-23 15:46:39 +00003316TEST(Member, MatchesMember) {
3317 EXPECT_TRUE(matches(
3318 "struct A { int i; }; void f() { A a; a.i = 2; }",
3319 memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
3320 EXPECT_TRUE(notMatches(
3321 "struct A { float f; }; void f() { A a; a.f = 2.0f; }",
3322 memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
3323}
3324
Daniel Jasper639522c2013-02-25 12:02:08 +00003325TEST(Member, UnderstandsAccess) {
3326 EXPECT_TRUE(matches(
3327 "struct A { int i; };", fieldDecl(isPublic(), hasName("i"))));
3328 EXPECT_TRUE(notMatches(
3329 "struct A { int i; };", fieldDecl(isProtected(), hasName("i"))));
3330 EXPECT_TRUE(notMatches(
3331 "struct A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
3332
3333 EXPECT_TRUE(notMatches(
3334 "class A { int i; };", fieldDecl(isPublic(), hasName("i"))));
3335 EXPECT_TRUE(notMatches(
3336 "class A { int i; };", fieldDecl(isProtected(), hasName("i"))));
3337 EXPECT_TRUE(matches(
3338 "class A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
3339
3340 EXPECT_TRUE(notMatches(
3341 "class A { protected: int i; };", fieldDecl(isPublic(), hasName("i"))));
3342 EXPECT_TRUE(matches("class A { protected: int i; };",
3343 fieldDecl(isProtected(), hasName("i"))));
3344 EXPECT_TRUE(notMatches(
3345 "class A { protected: int i; };", fieldDecl(isPrivate(), hasName("i"))));
3346
3347 // Non-member decls have the AccessSpecifier AS_none and thus aren't matched.
3348 EXPECT_TRUE(notMatches("int i;", varDecl(isPublic(), hasName("i"))));
3349 EXPECT_TRUE(notMatches("int i;", varDecl(isProtected(), hasName("i"))));
3350 EXPECT_TRUE(notMatches("int i;", varDecl(isPrivate(), hasName("i"))));
3351}
3352
Dmitri Gribenko06963042012-08-18 00:29:27 +00003353TEST(Member, MatchesMemberAllocationFunction) {
Daniel Jasper5901e472012-10-01 13:40:41 +00003354 // Fails in C++11 mode
3355 EXPECT_TRUE(matchesConditionally(
3356 "namespace std { typedef typeof(sizeof(int)) size_t; }"
3357 "class X { void *operator new(std::size_t); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00003358 cxxMethodDecl(ofClass(hasName("X"))), true, "-std=gnu++98"));
Dmitri Gribenko06963042012-08-18 00:29:27 +00003359
3360 EXPECT_TRUE(matches("class X { void operator delete(void*); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00003361 cxxMethodDecl(ofClass(hasName("X")))));
Dmitri Gribenko06963042012-08-18 00:29:27 +00003362
Daniel Jasper5901e472012-10-01 13:40:41 +00003363 // Fails in C++11 mode
3364 EXPECT_TRUE(matchesConditionally(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003365 "namespace std { typedef typeof(sizeof(int)) size_t; }"
3366 "class X { void operator delete[](void*, std::size_t); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00003367 cxxMethodDecl(ofClass(hasName("X"))), true, "-std=gnu++98"));
Dmitri Gribenko06963042012-08-18 00:29:27 +00003368}
3369
Manuel Klimek04616e42012-07-06 05:48:52 +00003370TEST(HasObjectExpression, DoesNotMatchMember) {
3371 EXPECT_TRUE(notMatches(
3372 "class X {}; struct Z { X m; }; void f(Z z) { z.m; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003373 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003374}
3375
3376TEST(HasObjectExpression, MatchesBaseOfVariable) {
3377 EXPECT_TRUE(matches(
3378 "struct X { int m; }; void f(X x) { x.m; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003379 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003380 EXPECT_TRUE(matches(
3381 "struct X { int m; }; void f(X* x) { x->m; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003382 memberExpr(hasObjectExpression(
3383 hasType(pointsTo(recordDecl(hasName("X"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003384}
3385
3386TEST(HasObjectExpression,
3387 MatchesObjectExpressionOfImplicitlyFormedMemberExpression) {
3388 EXPECT_TRUE(matches(
3389 "class X {}; struct S { X m; void f() { this->m; } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003390 memberExpr(hasObjectExpression(
3391 hasType(pointsTo(recordDecl(hasName("S"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003392 EXPECT_TRUE(matches(
3393 "class X {}; struct S { X m; void f() { m; } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003394 memberExpr(hasObjectExpression(
3395 hasType(pointsTo(recordDecl(hasName("S"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003396}
3397
3398TEST(Field, DoesNotMatchNonFieldMembers) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003399 EXPECT_TRUE(notMatches("class X { void m(); };", fieldDecl(hasName("m"))));
3400 EXPECT_TRUE(notMatches("class X { class m {}; };", fieldDecl(hasName("m"))));
3401 EXPECT_TRUE(notMatches("class X { enum { m }; };", fieldDecl(hasName("m"))));
3402 EXPECT_TRUE(notMatches("class X { enum m {}; };", fieldDecl(hasName("m"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003403}
3404
3405TEST(Field, MatchesField) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003406 EXPECT_TRUE(matches("class X { int m; };", fieldDecl(hasName("m"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003407}
3408
Aaron Ballman6290fc92015-11-23 17:09:24 +00003409TEST(IsVolatileQualified, QualifiersMatch) {
3410 EXPECT_TRUE(matches("volatile int i = 42;",
3411 varDecl(hasType(isVolatileQualified()))));
3412 EXPECT_TRUE(notMatches("volatile int *i;",
3413 varDecl(hasType(isVolatileQualified()))));
3414 EXPECT_TRUE(matches("typedef volatile int v_int; v_int i = 42;",
3415 varDecl(hasType(isVolatileQualified()))));
3416}
3417
Manuel Klimek04616e42012-07-06 05:48:52 +00003418TEST(IsConstQualified, MatchesConstInt) {
3419 EXPECT_TRUE(matches("const int i = 42;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003420 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003421}
3422
3423TEST(IsConstQualified, MatchesConstPointer) {
3424 EXPECT_TRUE(matches("int i = 42; int* const p(&i);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003425 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003426}
3427
3428TEST(IsConstQualified, MatchesThroughTypedef) {
3429 EXPECT_TRUE(matches("typedef const int const_int; const_int i = 42;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003430 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003431 EXPECT_TRUE(matches("typedef int* int_ptr; const int_ptr p(0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003432 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003433}
3434
3435TEST(IsConstQualified, DoesNotMatchInappropriately) {
3436 EXPECT_TRUE(notMatches("typedef int nonconst_int; nonconst_int i = 42;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003437 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003438 EXPECT_TRUE(notMatches("int const* p;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003439 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003440}
3441
Sam Panzer80c13772012-08-16 16:58:10 +00003442TEST(CastExpression, MatchesExplicitCasts) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00003443 EXPECT_TRUE(matches("char *p = reinterpret_cast<char *>(&p);",castExpr()));
3444 EXPECT_TRUE(matches("void *p = (void *)(&p);", castExpr()));
3445 EXPECT_TRUE(matches("char q, *p = const_cast<char *>(&q);", castExpr()));
3446 EXPECT_TRUE(matches("char c = char(0);", castExpr()));
Sam Panzer80c13772012-08-16 16:58:10 +00003447}
3448TEST(CastExpression, MatchesImplicitCasts) {
3449 // This test creates an implicit cast from int to char.
Daniel Jasper848cbe12012-09-18 13:09:13 +00003450 EXPECT_TRUE(matches("char c = 0;", castExpr()));
Sam Panzer80c13772012-08-16 16:58:10 +00003451 // This test creates an implicit cast from lvalue to rvalue.
Daniel Jasper848cbe12012-09-18 13:09:13 +00003452 EXPECT_TRUE(matches("char c = 0, d = c;", castExpr()));
Sam Panzer80c13772012-08-16 16:58:10 +00003453}
3454
3455TEST(CastExpression, DoesNotMatchNonCasts) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00003456 EXPECT_TRUE(notMatches("char c = '0';", castExpr()));
3457 EXPECT_TRUE(notMatches("char c, &q = c;", castExpr()));
3458 EXPECT_TRUE(notMatches("int i = (0);", castExpr()));
3459 EXPECT_TRUE(notMatches("int i = 0;", castExpr()));
Sam Panzer80c13772012-08-16 16:58:10 +00003460}
3461
Manuel Klimek04616e42012-07-06 05:48:52 +00003462TEST(ReinterpretCast, MatchesSimpleCase) {
3463 EXPECT_TRUE(matches("char* p = reinterpret_cast<char*>(&p);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003464 cxxReinterpretCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003465}
3466
3467TEST(ReinterpretCast, DoesNotMatchOtherCasts) {
Aaron Ballman512fb642015-09-17 13:30:52 +00003468 EXPECT_TRUE(notMatches("char* p = (char*)(&p);", cxxReinterpretCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003469 EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003470 cxxReinterpretCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003471 EXPECT_TRUE(notMatches("void* p = static_cast<void*>(&p);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003472 cxxReinterpretCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003473 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
3474 "B b;"
3475 "D* p = dynamic_cast<D*>(&b);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003476 cxxReinterpretCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003477}
3478
3479TEST(FunctionalCast, MatchesSimpleCase) {
Ismail Pazarbasi1121de32014-01-17 21:08:52 +00003480 std::string foo_class = "class Foo { public: Foo(const char*); };";
Manuel Klimek04616e42012-07-06 05:48:52 +00003481 EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello world\"); }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003482 cxxFunctionalCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003483}
3484
3485TEST(FunctionalCast, DoesNotMatchOtherCasts) {
Ismail Pazarbasi1121de32014-01-17 21:08:52 +00003486 std::string FooClass = "class Foo { public: Foo(const char*); };";
Manuel Klimek04616e42012-07-06 05:48:52 +00003487 EXPECT_TRUE(
3488 notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\"; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003489 cxxFunctionalCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003490 EXPECT_TRUE(
3491 notMatches(FooClass + "void r() { Foo f = \"hello world\"; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003492 cxxFunctionalCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003493}
3494
3495TEST(DynamicCast, MatchesSimpleCase) {
3496 EXPECT_TRUE(matches("struct B { virtual ~B() {} }; struct D : B {};"
3497 "B b;"
3498 "D* p = dynamic_cast<D*>(&b);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003499 cxxDynamicCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003500}
3501
3502TEST(StaticCast, MatchesSimpleCase) {
3503 EXPECT_TRUE(matches("void* p(static_cast<void*>(&p));",
Aaron Ballman512fb642015-09-17 13:30:52 +00003504 cxxStaticCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003505}
3506
3507TEST(StaticCast, DoesNotMatchOtherCasts) {
Aaron Ballman512fb642015-09-17 13:30:52 +00003508 EXPECT_TRUE(notMatches("char* p = (char*)(&p);", cxxStaticCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003509 EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003510 cxxStaticCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003511 EXPECT_TRUE(notMatches("void* p = reinterpret_cast<char*>(&p);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003512 cxxStaticCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003513 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
3514 "B b;"
3515 "D* p = dynamic_cast<D*>(&b);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003516 cxxStaticCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003517}
3518
Daniel Jasper417f7762012-09-18 13:36:17 +00003519TEST(CStyleCast, MatchesSimpleCase) {
3520 EXPECT_TRUE(matches("int i = (int) 2.2f;", cStyleCastExpr()));
3521}
3522
3523TEST(CStyleCast, DoesNotMatchOtherCasts) {
3524 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);"
3525 "char q, *r = const_cast<char*>(&q);"
3526 "void* s = reinterpret_cast<char*>(&s);"
3527 "struct B { virtual ~B() {} }; struct D : B {};"
3528 "B b;"
3529 "D* t = dynamic_cast<D*>(&b);",
3530 cStyleCastExpr()));
3531}
3532
Manuel Klimek04616e42012-07-06 05:48:52 +00003533TEST(HasDestinationType, MatchesSimpleCase) {
3534 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003535 cxxStaticCastExpr(hasDestinationType(
Daniel Jasper848cbe12012-09-18 13:09:13 +00003536 pointsTo(TypeMatcher(anything()))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003537}
3538
Sam Panzer80c13772012-08-16 16:58:10 +00003539TEST(HasImplicitDestinationType, MatchesSimpleCase) {
3540 // This test creates an implicit const cast.
3541 EXPECT_TRUE(matches("int x; const int i = x;",
Daniel Jasper848cbe12012-09-18 13:09:13 +00003542 implicitCastExpr(
3543 hasImplicitDestinationType(isInteger()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003544 // This test creates an implicit array-to-pointer cast.
3545 EXPECT_TRUE(matches("int arr[3]; int *p = arr;",
Daniel Jasper848cbe12012-09-18 13:09:13 +00003546 implicitCastExpr(hasImplicitDestinationType(
3547 pointsTo(TypeMatcher(anything()))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003548}
3549
3550TEST(HasImplicitDestinationType, DoesNotMatchIncorrectly) {
3551 // This test creates an implicit cast from int to char.
3552 EXPECT_TRUE(notMatches("char c = 0;",
Daniel Jasper848cbe12012-09-18 13:09:13 +00003553 implicitCastExpr(hasImplicitDestinationType(
3554 unless(anything())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003555 // This test creates an implicit array-to-pointer cast.
3556 EXPECT_TRUE(notMatches("int arr[3]; int *p = arr;",
Daniel Jasper848cbe12012-09-18 13:09:13 +00003557 implicitCastExpr(hasImplicitDestinationType(
3558 unless(anything())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003559}
3560
3561TEST(ImplicitCast, MatchesSimpleCase) {
3562 // This test creates an implicit const cast.
3563 EXPECT_TRUE(matches("int x = 0; const int y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003564 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003565 // This test creates an implicit cast from int to char.
3566 EXPECT_TRUE(matches("char c = 0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003567 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003568 // This test creates an implicit array-to-pointer cast.
3569 EXPECT_TRUE(matches("int arr[6]; int *p = arr;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003570 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003571}
3572
3573TEST(ImplicitCast, DoesNotMatchIncorrectly) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003574 // This test verifies that implicitCastExpr() matches exactly when implicit casts
Sam Panzer80c13772012-08-16 16:58:10 +00003575 // are present, and that it ignores explicit and paren casts.
3576
3577 // These two test cases have no casts.
3578 EXPECT_TRUE(notMatches("int x = 0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003579 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003580 EXPECT_TRUE(notMatches("int x = 0, &y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003581 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003582
3583 EXPECT_TRUE(notMatches("int x = 0; double d = (double) x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003584 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003585 EXPECT_TRUE(notMatches("const int *p; int *q = const_cast<int *>(p);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003586 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003587
3588 EXPECT_TRUE(notMatches("int x = (0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003589 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003590}
3591
3592TEST(IgnoringImpCasts, MatchesImpCasts) {
3593 // This test checks that ignoringImpCasts matches when implicit casts are
3594 // present and its inner matcher alone does not match.
3595 // Note that this test creates an implicit const cast.
3596 EXPECT_TRUE(matches("int x = 0; const int y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003597 varDecl(hasInitializer(ignoringImpCasts(
3598 declRefExpr(to(varDecl(hasName("x")))))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003599 // This test creates an implict cast from int to char.
3600 EXPECT_TRUE(matches("char x = 0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003601 varDecl(hasInitializer(ignoringImpCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003602 integerLiteral(equals(0)))))));
3603}
3604
3605TEST(IgnoringImpCasts, DoesNotMatchIncorrectly) {
3606 // These tests verify that ignoringImpCasts does not match if the inner
3607 // matcher does not match.
3608 // Note that the first test creates an implicit const cast.
3609 EXPECT_TRUE(notMatches("int x; const int y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003610 varDecl(hasInitializer(ignoringImpCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003611 unless(anything()))))));
3612 EXPECT_TRUE(notMatches("int x; int y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003613 varDecl(hasInitializer(ignoringImpCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003614 unless(anything()))))));
3615
3616 // These tests verify that ignoringImplictCasts does not look through explicit
3617 // casts or parentheses.
3618 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003619 varDecl(hasInitializer(ignoringImpCasts(
3620 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003621 EXPECT_TRUE(notMatches("int i = (0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003622 varDecl(hasInitializer(ignoringImpCasts(
3623 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003624 EXPECT_TRUE(notMatches("float i = (float)0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003625 varDecl(hasInitializer(ignoringImpCasts(
3626 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003627 EXPECT_TRUE(notMatches("float i = float(0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003628 varDecl(hasInitializer(ignoringImpCasts(
3629 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003630}
3631
3632TEST(IgnoringImpCasts, MatchesWithoutImpCasts) {
3633 // This test verifies that expressions that do not have implicit casts
3634 // still match the inner matcher.
3635 EXPECT_TRUE(matches("int x = 0; int &y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003636 varDecl(hasInitializer(ignoringImpCasts(
3637 declRefExpr(to(varDecl(hasName("x")))))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003638}
3639
3640TEST(IgnoringParenCasts, MatchesParenCasts) {
3641 // This test checks that ignoringParenCasts matches when parentheses and/or
3642 // casts are present and its inner matcher alone does not match.
3643 EXPECT_TRUE(matches("int x = (0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003644 varDecl(hasInitializer(ignoringParenCasts(
3645 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003646 EXPECT_TRUE(matches("int x = (((((0)))));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003647 varDecl(hasInitializer(ignoringParenCasts(
3648 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003649
3650 // This test creates an implict cast from int to char in addition to the
3651 // parentheses.
3652 EXPECT_TRUE(matches("char x = (0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003653 varDecl(hasInitializer(ignoringParenCasts(
3654 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003655
3656 EXPECT_TRUE(matches("char x = (char)0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003657 varDecl(hasInitializer(ignoringParenCasts(
3658 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003659 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003660 varDecl(hasInitializer(ignoringParenCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003661 integerLiteral(equals(0)))))));
3662}
3663
3664TEST(IgnoringParenCasts, MatchesWithoutParenCasts) {
3665 // This test verifies that expressions that do not have any casts still match.
3666 EXPECT_TRUE(matches("int x = 0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003667 varDecl(hasInitializer(ignoringParenCasts(
3668 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003669}
3670
3671TEST(IgnoringParenCasts, DoesNotMatchIncorrectly) {
3672 // These tests verify that ignoringImpCasts does not match if the inner
3673 // matcher does not match.
3674 EXPECT_TRUE(notMatches("int x = ((0));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003675 varDecl(hasInitializer(ignoringParenCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003676 unless(anything()))))));
3677
3678 // This test creates an implicit cast from int to char in addition to the
3679 // parentheses.
3680 EXPECT_TRUE(notMatches("char x = ((0));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003681 varDecl(hasInitializer(ignoringParenCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003682 unless(anything()))))));
3683
3684 EXPECT_TRUE(notMatches("char *x = static_cast<char *>((0));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003685 varDecl(hasInitializer(ignoringParenCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003686 unless(anything()))))));
3687}
3688
3689TEST(IgnoringParenAndImpCasts, MatchesParenImpCasts) {
3690 // This test checks that ignoringParenAndImpCasts matches when
3691 // parentheses and/or implicit casts are present and its inner matcher alone
3692 // does not match.
3693 // Note that this test creates an implicit const cast.
3694 EXPECT_TRUE(matches("int x = 0; const int y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003695 varDecl(hasInitializer(ignoringParenImpCasts(
3696 declRefExpr(to(varDecl(hasName("x")))))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003697 // This test creates an implicit cast from int to char.
3698 EXPECT_TRUE(matches("const char x = (0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003699 varDecl(hasInitializer(ignoringParenImpCasts(
3700 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003701}
3702
3703TEST(IgnoringParenAndImpCasts, MatchesWithoutParenImpCasts) {
3704 // This test verifies that expressions that do not have parentheses or
3705 // implicit casts still match.
3706 EXPECT_TRUE(matches("int x = 0; int &y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003707 varDecl(hasInitializer(ignoringParenImpCasts(
3708 declRefExpr(to(varDecl(hasName("x")))))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003709 EXPECT_TRUE(matches("int x = 0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003710 varDecl(hasInitializer(ignoringParenImpCasts(
3711 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003712}
3713
3714TEST(IgnoringParenAndImpCasts, DoesNotMatchIncorrectly) {
3715 // These tests verify that ignoringParenImpCasts does not match if
3716 // the inner matcher does not match.
3717 // This test creates an implicit cast.
3718 EXPECT_TRUE(notMatches("char c = ((3));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003719 varDecl(hasInitializer(ignoringParenImpCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003720 unless(anything()))))));
3721 // These tests verify that ignoringParenAndImplictCasts does not look
3722 // through explicit casts.
3723 EXPECT_TRUE(notMatches("float y = (float(0));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003724 varDecl(hasInitializer(ignoringParenImpCasts(
3725 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003726 EXPECT_TRUE(notMatches("float y = (float)0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003727 varDecl(hasInitializer(ignoringParenImpCasts(
3728 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003729 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003730 varDecl(hasInitializer(ignoringParenImpCasts(
3731 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003732}
3733
Manuel Klimeke9235692012-07-25 10:02:02 +00003734TEST(HasSourceExpression, MatchesImplicitCasts) {
Manuel Klimek04616e42012-07-06 05:48:52 +00003735 EXPECT_TRUE(matches("class string {}; class URL { public: URL(string s); };"
3736 "void r() {string a_string; URL url = a_string; }",
Daniel Jasper848cbe12012-09-18 13:09:13 +00003737 implicitCastExpr(
Aaron Ballman512fb642015-09-17 13:30:52 +00003738 hasSourceExpression(cxxConstructExpr()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003739}
3740
Manuel Klimeke9235692012-07-25 10:02:02 +00003741TEST(HasSourceExpression, MatchesExplicitCasts) {
3742 EXPECT_TRUE(matches("float x = static_cast<float>(42);",
Daniel Jasper848cbe12012-09-18 13:09:13 +00003743 explicitCastExpr(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003744 hasSourceExpression(hasDescendant(
Daniel Jasper848cbe12012-09-18 13:09:13 +00003745 expr(integerLiteral()))))));
Manuel Klimeke9235692012-07-25 10:02:02 +00003746}
3747
Manuel Klimek04616e42012-07-06 05:48:52 +00003748TEST(Statement, DoesNotMatchDeclarations) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003749 EXPECT_TRUE(notMatches("class X {};", stmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003750}
3751
3752TEST(Statement, MatchesCompoundStatments) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003753 EXPECT_TRUE(matches("void x() {}", stmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003754}
3755
3756TEST(DeclarationStatement, DoesNotMatchCompoundStatements) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003757 EXPECT_TRUE(notMatches("void x() {}", declStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003758}
3759
3760TEST(DeclarationStatement, MatchesVariableDeclarationStatements) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003761 EXPECT_TRUE(matches("void x() { int a; }", declStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003762}
3763
Samuel Benzaquenf1066292014-04-02 13:12:14 +00003764TEST(ExprWithCleanups, MatchesExprWithCleanups) {
3765 EXPECT_TRUE(matches("struct Foo { ~Foo(); };"
3766 "const Foo f = Foo();",
3767 varDecl(hasInitializer(exprWithCleanups()))));
3768 EXPECT_FALSE(matches("struct Foo { };"
3769 "const Foo f = Foo();",
3770 varDecl(hasInitializer(exprWithCleanups()))));
3771}
3772
Daniel Jasper1dad1832012-07-10 20:20:19 +00003773TEST(InitListExpression, MatchesInitListExpression) {
3774 EXPECT_TRUE(matches("int a[] = { 1, 2 };",
3775 initListExpr(hasType(asString("int [2]")))));
3776 EXPECT_TRUE(matches("struct B { int x, y; }; B b = { 5, 6 };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003777 initListExpr(hasType(recordDecl(hasName("B"))))));
Daniel Jasper1d8ecbd2015-02-04 13:11:42 +00003778 EXPECT_TRUE(matches("struct S { S(void (*a)()); };"
3779 "void f();"
3780 "S s[1] = { &f };",
3781 declRefExpr(to(functionDecl(hasName("f"))))));
Daniel Jasper774e6b52015-02-04 14:29:47 +00003782 EXPECT_TRUE(
3783 matches("int i[1] = {42, [0] = 43};", integerLiteral(equals(42))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00003784}
3785
3786TEST(UsingDeclaration, MatchesUsingDeclarations) {
3787 EXPECT_TRUE(matches("namespace X { int x; } using X::x;",
3788 usingDecl()));
3789}
3790
3791TEST(UsingDeclaration, MatchesShadowUsingDelcarations) {
3792 EXPECT_TRUE(matches("namespace f { int a; } using f::a;",
3793 usingDecl(hasAnyUsingShadowDecl(hasName("a")))));
3794}
3795
3796TEST(UsingDeclaration, MatchesSpecificTarget) {
3797 EXPECT_TRUE(matches("namespace f { int a; void b(); } using f::b;",
3798 usingDecl(hasAnyUsingShadowDecl(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003799 hasTargetDecl(functionDecl())))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00003800 EXPECT_TRUE(notMatches("namespace f { int a; void b(); } using f::a;",
3801 usingDecl(hasAnyUsingShadowDecl(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003802 hasTargetDecl(functionDecl())))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00003803}
3804
3805TEST(UsingDeclaration, ThroughUsingDeclaration) {
3806 EXPECT_TRUE(matches(
3807 "namespace a { void f(); } using a::f; void g() { f(); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003808 declRefExpr(throughUsingDecl(anything()))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00003809 EXPECT_TRUE(notMatches(
3810 "namespace a { void f(); } using a::f; void g() { a::f(); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003811 declRefExpr(throughUsingDecl(anything()))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00003812}
3813
Benjamin Kramer73ef2162014-07-16 14:14:51 +00003814TEST(UsingDirectiveDeclaration, MatchesUsingNamespace) {
3815 EXPECT_TRUE(matches("namespace X { int x; } using namespace X;",
3816 usingDirectiveDecl()));
3817 EXPECT_FALSE(
3818 matches("namespace X { int x; } using X::x;", usingDirectiveDecl()));
3819}
3820
Sam Panzerd624bfb2012-08-16 17:20:59 +00003821TEST(SingleDecl, IsSingleDecl) {
3822 StatementMatcher SingleDeclStmt =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003823 declStmt(hasSingleDecl(varDecl(hasInitializer(anything()))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003824 EXPECT_TRUE(matches("void f() {int a = 4;}", SingleDeclStmt));
3825 EXPECT_TRUE(notMatches("void f() {int a;}", SingleDeclStmt));
3826 EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
3827 SingleDeclStmt));
3828}
3829
3830TEST(DeclStmt, ContainsDeclaration) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003831 DeclarationMatcher MatchesInit = varDecl(hasInitializer(anything()));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003832
3833 EXPECT_TRUE(matches("void f() {int a = 4;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003834 declStmt(containsDeclaration(0, MatchesInit))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003835 EXPECT_TRUE(matches("void f() {int a = 4, b = 3;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003836 declStmt(containsDeclaration(0, MatchesInit),
3837 containsDeclaration(1, MatchesInit))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003838 unsigned WrongIndex = 42;
3839 EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003840 declStmt(containsDeclaration(WrongIndex,
Sam Panzerd624bfb2012-08-16 17:20:59 +00003841 MatchesInit))));
3842}
3843
3844TEST(DeclCount, DeclCountIsCorrect) {
3845 EXPECT_TRUE(matches("void f() {int i,j;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003846 declStmt(declCountIs(2))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003847 EXPECT_TRUE(notMatches("void f() {int i,j; int k;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003848 declStmt(declCountIs(3))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003849 EXPECT_TRUE(notMatches("void f() {int i,j, k, l;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003850 declStmt(declCountIs(3))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003851}
3852
Manuel Klimek04616e42012-07-06 05:48:52 +00003853TEST(While, MatchesWhileLoops) {
3854 EXPECT_TRUE(notMatches("void x() {}", whileStmt()));
3855 EXPECT_TRUE(matches("void x() { while(true); }", whileStmt()));
3856 EXPECT_TRUE(notMatches("void x() { do {} while(true); }", whileStmt()));
3857}
3858
3859TEST(Do, MatchesDoLoops) {
3860 EXPECT_TRUE(matches("void x() { do {} while(true); }", doStmt()));
3861 EXPECT_TRUE(matches("void x() { do ; while(false); }", doStmt()));
3862}
3863
3864TEST(Do, DoesNotMatchWhileLoops) {
3865 EXPECT_TRUE(notMatches("void x() { while(true) {} }", doStmt()));
3866}
3867
3868TEST(SwitchCase, MatchesCase) {
3869 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchCase()));
3870 EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchCase()));
3871 EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchCase()));
3872 EXPECT_TRUE(notMatches("void x() { switch(42) {} }", switchCase()));
3873}
3874
Daniel Jasper87c3d362012-09-20 14:12:57 +00003875TEST(SwitchCase, MatchesSwitch) {
3876 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchStmt()));
3877 EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchStmt()));
3878 EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchStmt()));
3879 EXPECT_TRUE(notMatches("void x() {}", switchStmt()));
3880}
3881
Peter Collingbourne3154a102013-05-10 11:52:02 +00003882TEST(SwitchCase, MatchesEachCase) {
3883 EXPECT_TRUE(notMatches("void x() { switch(42); }",
3884 switchStmt(forEachSwitchCase(caseStmt()))));
3885 EXPECT_TRUE(matches("void x() { switch(42) case 42:; }",
3886 switchStmt(forEachSwitchCase(caseStmt()))));
3887 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }",
3888 switchStmt(forEachSwitchCase(caseStmt()))));
3889 EXPECT_TRUE(notMatches(
3890 "void x() { if (1) switch(42) { case 42: switch (42) { default:; } } }",
3891 ifStmt(has(switchStmt(forEachSwitchCase(defaultStmt()))))));
3892 EXPECT_TRUE(matches("void x() { switch(42) { case 1+1: case 4:; } }",
3893 switchStmt(forEachSwitchCase(
3894 caseStmt(hasCaseConstant(integerLiteral()))))));
3895 EXPECT_TRUE(notMatches("void x() { switch(42) { case 1+1: case 2+2:; } }",
3896 switchStmt(forEachSwitchCase(
3897 caseStmt(hasCaseConstant(integerLiteral()))))));
3898 EXPECT_TRUE(notMatches("void x() { switch(42) { case 1 ... 2:; } }",
3899 switchStmt(forEachSwitchCase(
3900 caseStmt(hasCaseConstant(integerLiteral()))))));
3901 EXPECT_TRUE(matchAndVerifyResultTrue(
3902 "void x() { switch (42) { case 1: case 2: case 3: default:; } }",
3903 switchStmt(forEachSwitchCase(caseStmt().bind("x"))),
3904 new VerifyIdIsBoundTo<CaseStmt>("x", 3)));
3905}
3906
Manuel Klimekba46fc02013-07-19 11:50:54 +00003907TEST(ForEachConstructorInitializer, MatchesInitializers) {
3908 EXPECT_TRUE(matches(
3909 "struct X { X() : i(42), j(42) {} int i, j; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00003910 cxxConstructorDecl(forEachConstructorInitializer(cxxCtorInitializer()))));
Manuel Klimekba46fc02013-07-19 11:50:54 +00003911}
3912
Daniel Jasper87c3d362012-09-20 14:12:57 +00003913TEST(ExceptionHandling, SimpleCases) {
Aaron Ballman512fb642015-09-17 13:30:52 +00003914 EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", cxxCatchStmt()));
3915 EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", cxxTryStmt()));
3916 EXPECT_TRUE(
3917 notMatches("void foo() try { } catch(int X) { }", cxxThrowExpr()));
Daniel Jasper87c3d362012-09-20 14:12:57 +00003918 EXPECT_TRUE(matches("void foo() try { throw; } catch(int X) { }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003919 cxxThrowExpr()));
Daniel Jasper87c3d362012-09-20 14:12:57 +00003920 EXPECT_TRUE(matches("void foo() try { throw 5;} catch(int X) { }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003921 cxxThrowExpr()));
Aaron Ballman9b869aa2015-07-02 12:53:22 +00003922 EXPECT_TRUE(matches("void foo() try { throw; } catch(...) { }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003923 cxxCatchStmt(isCatchAll())));
Aaron Ballman9b869aa2015-07-02 12:53:22 +00003924 EXPECT_TRUE(notMatches("void foo() try { throw; } catch(int) { }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003925 cxxCatchStmt(isCatchAll())));
Aaron Ballman39918462015-07-15 17:11:21 +00003926 EXPECT_TRUE(matches("void foo() try {} catch(int X) { }",
3927 varDecl(isExceptionVariable())));
3928 EXPECT_TRUE(notMatches("void foo() try { int X; } catch (...) { }",
3929 varDecl(isExceptionVariable())));
Daniel Jasper87c3d362012-09-20 14:12:57 +00003930}
3931
Aaron Ballmane8295d72016-01-20 16:17:39 +00003932TEST(ParenExpression, SimpleCases) {
3933 EXPECT_TRUE(matches("int i = (3);", parenExpr()));
3934 EXPECT_TRUE(matches("int i = (3 + 7);", parenExpr()));
3935 EXPECT_TRUE(notMatches("int i = 3;", parenExpr()));
3936 EXPECT_TRUE(notMatches("int foo() { return 1; }; int a = foo();",
3937 parenExpr()));
3938}
3939
Manuel Klimek04616e42012-07-06 05:48:52 +00003940TEST(HasConditionVariableStatement, DoesNotMatchCondition) {
3941 EXPECT_TRUE(notMatches(
3942 "void x() { if(true) {} }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003943 ifStmt(hasConditionVariableStatement(declStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003944 EXPECT_TRUE(notMatches(
3945 "void x() { int x; if((x = 42)) {} }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003946 ifStmt(hasConditionVariableStatement(declStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003947}
3948
3949TEST(HasConditionVariableStatement, MatchesConditionVariables) {
3950 EXPECT_TRUE(matches(
3951 "void x() { if(int* a = 0) {} }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003952 ifStmt(hasConditionVariableStatement(declStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003953}
3954
3955TEST(ForEach, BindsOneNode) {
3956 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003957 recordDecl(hasName("C"), forEach(fieldDecl(hasName("x")).bind("x"))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003958 new VerifyIdIsBoundTo<FieldDecl>("x", 1)));
Manuel Klimek04616e42012-07-06 05:48:52 +00003959}
3960
3961TEST(ForEach, BindsMultipleNodes) {
3962 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; int y; int z; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003963 recordDecl(hasName("C"), forEach(fieldDecl().bind("f"))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003964 new VerifyIdIsBoundTo<FieldDecl>("f", 3)));
Manuel Klimek04616e42012-07-06 05:48:52 +00003965}
3966
3967TEST(ForEach, BindsRecursiveCombinations) {
3968 EXPECT_TRUE(matchAndVerifyResultTrue(
3969 "class C { class D { int x; int y; }; class E { int y; int z; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003970 recordDecl(hasName("C"),
3971 forEach(recordDecl(forEach(fieldDecl().bind("f"))))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003972 new VerifyIdIsBoundTo<FieldDecl>("f", 4)));
Manuel Klimek04616e42012-07-06 05:48:52 +00003973}
3974
3975TEST(ForEachDescendant, BindsOneNode) {
3976 EXPECT_TRUE(matchAndVerifyResultTrue("class C { class D { int x; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003977 recordDecl(hasName("C"),
3978 forEachDescendant(fieldDecl(hasName("x")).bind("x"))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003979 new VerifyIdIsBoundTo<FieldDecl>("x", 1)));
Manuel Klimek04616e42012-07-06 05:48:52 +00003980}
3981
Daniel Jasper94a56852012-11-16 18:39:22 +00003982TEST(ForEachDescendant, NestedForEachDescendant) {
3983 DeclarationMatcher m = recordDecl(
3984 isDefinition(), decl().bind("x"), hasName("C"));
3985 EXPECT_TRUE(matchAndVerifyResultTrue(
3986 "class A { class B { class C {}; }; };",
3987 recordDecl(hasName("A"), anyOf(m, forEachDescendant(m))),
3988 new VerifyIdIsBoundTo<Decl>("x", "C")));
3989
Manuel Klimeka0c025f2013-06-19 15:42:45 +00003990 // Check that a partial match of 'm' that binds 'x' in the
3991 // first part of anyOf(m, anything()) will not overwrite the
3992 // binding created by the earlier binding in the hasDescendant.
3993 EXPECT_TRUE(matchAndVerifyResultTrue(
3994 "class A { class B { class C {}; }; };",
3995 recordDecl(hasName("A"), allOf(hasDescendant(m), anyOf(m, anything()))),
3996 new VerifyIdIsBoundTo<Decl>("x", "C")));
Daniel Jasper94a56852012-11-16 18:39:22 +00003997}
3998
Manuel Klimek04616e42012-07-06 05:48:52 +00003999TEST(ForEachDescendant, BindsMultipleNodes) {
4000 EXPECT_TRUE(matchAndVerifyResultTrue(
4001 "class C { class D { int x; int y; }; "
4002 " class E { class F { int y; int z; }; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004003 recordDecl(hasName("C"), forEachDescendant(fieldDecl().bind("f"))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00004004 new VerifyIdIsBoundTo<FieldDecl>("f", 4)));
Manuel Klimek04616e42012-07-06 05:48:52 +00004005}
4006
4007TEST(ForEachDescendant, BindsRecursiveCombinations) {
4008 EXPECT_TRUE(matchAndVerifyResultTrue(
4009 "class C { class D { "
4010 " class E { class F { class G { int y; int z; }; }; }; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004011 recordDecl(hasName("C"), forEachDescendant(recordDecl(
4012 forEachDescendant(fieldDecl().bind("f"))))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00004013 new VerifyIdIsBoundTo<FieldDecl>("f", 8)));
Manuel Klimek04616e42012-07-06 05:48:52 +00004014}
4015
Manuel Klimeka0c025f2013-06-19 15:42:45 +00004016TEST(ForEachDescendant, BindsCombinations) {
4017 EXPECT_TRUE(matchAndVerifyResultTrue(
4018 "void f() { if(true) {} if (true) {} while (true) {} if (true) {} while "
4019 "(true) {} }",
4020 compoundStmt(forEachDescendant(ifStmt().bind("if")),
4021 forEachDescendant(whileStmt().bind("while"))),
4022 new VerifyIdIsBoundTo<IfStmt>("if", 6)));
4023}
4024
4025TEST(Has, DoesNotDeleteBindings) {
4026 EXPECT_TRUE(matchAndVerifyResultTrue(
4027 "class X { int a; };", recordDecl(decl().bind("x"), has(fieldDecl())),
4028 new VerifyIdIsBoundTo<Decl>("x", 1)));
4029}
4030
4031TEST(LoopingMatchers, DoNotOverwritePreviousMatchResultOnFailure) {
4032 // Those matchers cover all the cases where an inner matcher is called
4033 // and there is not a 1:1 relationship between the match of the outer
4034 // matcher and the match of the inner matcher.
4035 // The pattern to look for is:
4036 // ... return InnerMatcher.matches(...); ...
4037 // In which case no special handling is needed.
4038 //
4039 // On the other hand, if there are multiple alternative matches
4040 // (for example forEach*) or matches might be discarded (for example has*)
4041 // the implementation must make sure that the discarded matches do not
4042 // affect the bindings.
4043 // When new such matchers are added, add a test here that:
4044 // - matches a simple node, and binds it as the first thing in the matcher:
4045 // recordDecl(decl().bind("x"), hasName("X")))
4046 // - uses the matcher under test afterwards in a way that not the first
4047 // alternative is matched; for anyOf, that means the first branch
4048 // would need to return false; for hasAncestor, it means that not
4049 // the direct parent matches the inner matcher.
4050
4051 EXPECT_TRUE(matchAndVerifyResultTrue(
4052 "class X { int y; };",
4053 recordDecl(
4054 recordDecl().bind("x"), hasName("::X"),
4055 anyOf(forEachDescendant(recordDecl(hasName("Y"))), anything())),
4056 new VerifyIdIsBoundTo<CXXRecordDecl>("x", 1)));
4057 EXPECT_TRUE(matchAndVerifyResultTrue(
4058 "class X {};", recordDecl(recordDecl().bind("x"), hasName("::X"),
4059 anyOf(unless(anything()), anything())),
4060 new VerifyIdIsBoundTo<CXXRecordDecl>("x", 1)));
4061 EXPECT_TRUE(matchAndVerifyResultTrue(
4062 "template<typename T1, typename T2> class X {}; X<float, int> x;",
4063 classTemplateSpecializationDecl(
4064 decl().bind("x"),
4065 hasAnyTemplateArgument(refersToType(asString("int")))),
4066 new VerifyIdIsBoundTo<Decl>("x", 1)));
4067 EXPECT_TRUE(matchAndVerifyResultTrue(
4068 "class X { void f(); void g(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00004069 cxxRecordDecl(decl().bind("x"), hasMethod(hasName("g"))),
Manuel Klimeka0c025f2013-06-19 15:42:45 +00004070 new VerifyIdIsBoundTo<Decl>("x", 1)));
4071 EXPECT_TRUE(matchAndVerifyResultTrue(
4072 "class X { X() : a(1), b(2) {} double a; int b; };",
4073 recordDecl(decl().bind("x"),
Aaron Ballman512fb642015-09-17 13:30:52 +00004074 has(cxxConstructorDecl(
Manuel Klimeka0c025f2013-06-19 15:42:45 +00004075 hasAnyConstructorInitializer(forField(hasName("b")))))),
4076 new VerifyIdIsBoundTo<Decl>("x", 1)));
4077 EXPECT_TRUE(matchAndVerifyResultTrue(
4078 "void x(int, int) { x(0, 42); }",
4079 callExpr(expr().bind("x"), hasAnyArgument(integerLiteral(equals(42)))),
4080 new VerifyIdIsBoundTo<Expr>("x", 1)));
4081 EXPECT_TRUE(matchAndVerifyResultTrue(
4082 "void x(int, int y) {}",
4083 functionDecl(decl().bind("x"), hasAnyParameter(hasName("y"))),
4084 new VerifyIdIsBoundTo<Decl>("x", 1)));
4085 EXPECT_TRUE(matchAndVerifyResultTrue(
4086 "void x() { return; if (true) {} }",
4087 functionDecl(decl().bind("x"),
4088 has(compoundStmt(hasAnySubstatement(ifStmt())))),
4089 new VerifyIdIsBoundTo<Decl>("x", 1)));
4090 EXPECT_TRUE(matchAndVerifyResultTrue(
4091 "namespace X { void b(int); void b(); }"
4092 "using X::b;",
4093 usingDecl(decl().bind("x"), hasAnyUsingShadowDecl(hasTargetDecl(
4094 functionDecl(parameterCountIs(1))))),
4095 new VerifyIdIsBoundTo<Decl>("x", 1)));
4096 EXPECT_TRUE(matchAndVerifyResultTrue(
4097 "class A{}; class B{}; class C : B, A {};",
Aaron Ballman512fb642015-09-17 13:30:52 +00004098 cxxRecordDecl(decl().bind("x"), isDerivedFrom("::A")),
Manuel Klimeka0c025f2013-06-19 15:42:45 +00004099 new VerifyIdIsBoundTo<Decl>("x", 1)));
4100 EXPECT_TRUE(matchAndVerifyResultTrue(
4101 "class A{}; typedef A B; typedef A C; typedef A D;"
4102 "class E : A {};",
Aaron Ballman512fb642015-09-17 13:30:52 +00004103 cxxRecordDecl(decl().bind("x"), isDerivedFrom("C")),
Manuel Klimeka0c025f2013-06-19 15:42:45 +00004104 new VerifyIdIsBoundTo<Decl>("x", 1)));
4105 EXPECT_TRUE(matchAndVerifyResultTrue(
4106 "class A { class B { void f() {} }; };",
4107 functionDecl(decl().bind("x"), hasAncestor(recordDecl(hasName("::A")))),
4108 new VerifyIdIsBoundTo<Decl>("x", 1)));
4109 EXPECT_TRUE(matchAndVerifyResultTrue(
4110 "template <typename T> struct A { struct B {"
4111 " void f() { if(true) {} }"
4112 "}; };"
4113 "void t() { A<int>::B b; b.f(); }",
4114 ifStmt(stmt().bind("x"), hasAncestor(recordDecl(hasName("::A")))),
4115 new VerifyIdIsBoundTo<Stmt>("x", 2)));
4116 EXPECT_TRUE(matchAndVerifyResultTrue(
4117 "class A {};",
4118 recordDecl(hasName("::A"), decl().bind("x"), unless(hasName("fooble"))),
4119 new VerifyIdIsBoundTo<Decl>("x", 1)));
Manuel Klimekba46fc02013-07-19 11:50:54 +00004120 EXPECT_TRUE(matchAndVerifyResultTrue(
4121 "class A { A() : s(), i(42) {} const char *s; int i; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00004122 cxxConstructorDecl(hasName("::A::A"), decl().bind("x"),
4123 forEachConstructorInitializer(forField(hasName("i")))),
Manuel Klimekba46fc02013-07-19 11:50:54 +00004124 new VerifyIdIsBoundTo<Decl>("x", 1)));
Manuel Klimeka0c025f2013-06-19 15:42:45 +00004125}
4126
Daniel Jasper33806cd2012-11-11 22:14:55 +00004127TEST(ForEachDescendant, BindsCorrectNodes) {
4128 EXPECT_TRUE(matchAndVerifyResultTrue(
4129 "class C { void f(); int i; };",
4130 recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
4131 new VerifyIdIsBoundTo<FieldDecl>("decl", 1)));
4132 EXPECT_TRUE(matchAndVerifyResultTrue(
4133 "class C { void f() {} int i; };",
4134 recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
4135 new VerifyIdIsBoundTo<FunctionDecl>("decl", 1)));
4136}
4137
Manuel Klimekabf43712013-02-04 10:59:20 +00004138TEST(FindAll, BindsNodeOnMatch) {
4139 EXPECT_TRUE(matchAndVerifyResultTrue(
4140 "class A {};",
4141 recordDecl(hasName("::A"), findAll(recordDecl(hasName("::A")).bind("v"))),
4142 new VerifyIdIsBoundTo<CXXRecordDecl>("v", 1)));
4143}
4144
4145TEST(FindAll, BindsDescendantNodeOnMatch) {
4146 EXPECT_TRUE(matchAndVerifyResultTrue(
4147 "class A { int a; int b; };",
4148 recordDecl(hasName("::A"), findAll(fieldDecl().bind("v"))),
4149 new VerifyIdIsBoundTo<FieldDecl>("v", 2)));
4150}
4151
4152TEST(FindAll, BindsNodeAndDescendantNodesOnOneMatch) {
4153 EXPECT_TRUE(matchAndVerifyResultTrue(
4154 "class A { int a; int b; };",
4155 recordDecl(hasName("::A"),
4156 findAll(decl(anyOf(recordDecl(hasName("::A")).bind("v"),
4157 fieldDecl().bind("v"))))),
4158 new VerifyIdIsBoundTo<Decl>("v", 3)));
4159
4160 EXPECT_TRUE(matchAndVerifyResultTrue(
4161 "class A { class B {}; class C {}; };",
4162 recordDecl(hasName("::A"), findAll(recordDecl(isDefinition()).bind("v"))),
4163 new VerifyIdIsBoundTo<CXXRecordDecl>("v", 3)));
4164}
4165
Manuel Klimek88b95872013-02-04 09:42:38 +00004166TEST(EachOf, TriggersForEachMatch) {
4167 EXPECT_TRUE(matchAndVerifyResultTrue(
4168 "class A { int a; int b; };",
4169 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
4170 has(fieldDecl(hasName("b")).bind("v")))),
4171 new VerifyIdIsBoundTo<FieldDecl>("v", 2)));
4172}
4173
4174TEST(EachOf, BehavesLikeAnyOfUnlessBothMatch) {
4175 EXPECT_TRUE(matchAndVerifyResultTrue(
4176 "class A { int a; int c; };",
4177 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
4178 has(fieldDecl(hasName("b")).bind("v")))),
4179 new VerifyIdIsBoundTo<FieldDecl>("v", 1)));
4180 EXPECT_TRUE(matchAndVerifyResultTrue(
4181 "class A { int c; int b; };",
4182 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
4183 has(fieldDecl(hasName("b")).bind("v")))),
4184 new VerifyIdIsBoundTo<FieldDecl>("v", 1)));
4185 EXPECT_TRUE(notMatches(
4186 "class A { int c; int d; };",
4187 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
4188 has(fieldDecl(hasName("b")).bind("v"))))));
4189}
Manuel Klimek04616e42012-07-06 05:48:52 +00004190
4191TEST(IsTemplateInstantiation, MatchesImplicitClassTemplateInstantiation) {
4192 // Make sure that we can both match the class by name (::X) and by the type
4193 // the template was instantiated with (via a field).
4194
4195 EXPECT_TRUE(matches(
4196 "template <typename T> class X {}; class A {}; X<A> x;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004197 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
Manuel Klimek04616e42012-07-06 05:48:52 +00004198
4199 EXPECT_TRUE(matches(
4200 "template <typename T> class X { T t; }; class A {}; X<A> x;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004201 cxxRecordDecl(isTemplateInstantiation(), hasDescendant(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004202 fieldDecl(hasType(recordDecl(hasName("A"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00004203}
4204
4205TEST(IsTemplateInstantiation, MatchesImplicitFunctionTemplateInstantiation) {
4206 EXPECT_TRUE(matches(
4207 "template <typename T> void f(T t) {} class A {}; void g() { f(A()); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004208 functionDecl(hasParameter(0, hasType(recordDecl(hasName("A")))),
Manuel Klimek04616e42012-07-06 05:48:52 +00004209 isTemplateInstantiation())));
4210}
4211
4212TEST(IsTemplateInstantiation, MatchesExplicitClassTemplateInstantiation) {
4213 EXPECT_TRUE(matches(
4214 "template <typename T> class X { T t; }; class A {};"
4215 "template class X<A>;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004216 cxxRecordDecl(isTemplateInstantiation(), hasDescendant(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004217 fieldDecl(hasType(recordDecl(hasName("A"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00004218}
4219
4220TEST(IsTemplateInstantiation,
4221 MatchesInstantiationOfPartiallySpecializedClassTemplate) {
4222 EXPECT_TRUE(matches(
4223 "template <typename T> class X {};"
4224 "template <typename T> class X<T*> {}; class A {}; X<A*> x;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004225 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
Manuel Klimek04616e42012-07-06 05:48:52 +00004226}
4227
4228TEST(IsTemplateInstantiation,
4229 MatchesInstantiationOfClassTemplateNestedInNonTemplate) {
4230 EXPECT_TRUE(matches(
4231 "class A {};"
4232 "class X {"
4233 " template <typename U> class Y { U u; };"
4234 " Y<A> y;"
4235 "};",
Aaron Ballman512fb642015-09-17 13:30:52 +00004236 cxxRecordDecl(hasName("::X::Y"), isTemplateInstantiation())));
Manuel Klimek04616e42012-07-06 05:48:52 +00004237}
4238
4239TEST(IsTemplateInstantiation, DoesNotMatchInstantiationsInsideOfInstantiation) {
4240 // FIXME: Figure out whether this makes sense. It doesn't affect the
4241 // normal use case as long as the uppermost instantiation always is marked
4242 // as template instantiation, but it might be confusing as a predicate.
4243 EXPECT_TRUE(matches(
4244 "class A {};"
4245 "template <typename T> class X {"
4246 " template <typename U> class Y { U u; };"
4247 " Y<T> y;"
4248 "}; X<A> x;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004249 cxxRecordDecl(hasName("::X<A>::Y"), unless(isTemplateInstantiation()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00004250}
4251
4252TEST(IsTemplateInstantiation, DoesNotMatchExplicitClassTemplateSpecialization) {
4253 EXPECT_TRUE(notMatches(
4254 "template <typename T> class X {}; class A {};"
4255 "template <> class X<A> {}; X<A> x;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004256 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
Manuel Klimek04616e42012-07-06 05:48:52 +00004257}
4258
4259TEST(IsTemplateInstantiation, DoesNotMatchNonTemplate) {
4260 EXPECT_TRUE(notMatches(
4261 "class A {}; class Y { A a; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00004262 cxxRecordDecl(isTemplateInstantiation())));
Manuel Klimek04616e42012-07-06 05:48:52 +00004263}
4264
Benjamin Kramer7ab84762014-09-03 12:08:14 +00004265TEST(IsInstantiated, MatchesInstantiation) {
4266 EXPECT_TRUE(
4267 matches("template<typename T> class A { T i; }; class Y { A<int> a; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00004268 cxxRecordDecl(isInstantiated())));
Benjamin Kramer7ab84762014-09-03 12:08:14 +00004269}
4270
4271TEST(IsInstantiated, NotMatchesDefinition) {
4272 EXPECT_TRUE(notMatches("template<typename T> class A { T i; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00004273 cxxRecordDecl(isInstantiated())));
Benjamin Kramer7ab84762014-09-03 12:08:14 +00004274}
4275
4276TEST(IsInTemplateInstantiation, MatchesInstantiationStmt) {
4277 EXPECT_TRUE(matches("template<typename T> struct A { A() { T i; } };"
4278 "class Y { A<int> a; }; Y y;",
4279 declStmt(isInTemplateInstantiation())));
4280}
4281
4282TEST(IsInTemplateInstantiation, NotMatchesDefinitionStmt) {
4283 EXPECT_TRUE(notMatches("template<typename T> struct A { void x() { T i; } };",
4284 declStmt(isInTemplateInstantiation())));
4285}
4286
4287TEST(IsInstantiated, MatchesFunctionInstantiation) {
4288 EXPECT_TRUE(
4289 matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
4290 functionDecl(isInstantiated())));
4291}
4292
4293TEST(IsInstantiated, NotMatchesFunctionDefinition) {
4294 EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
4295 varDecl(isInstantiated())));
4296}
4297
4298TEST(IsInTemplateInstantiation, MatchesFunctionInstantiationStmt) {
4299 EXPECT_TRUE(
4300 matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
4301 declStmt(isInTemplateInstantiation())));
4302}
4303
4304TEST(IsInTemplateInstantiation, NotMatchesFunctionDefinitionStmt) {
4305 EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
4306 declStmt(isInTemplateInstantiation())));
4307}
4308
4309TEST(IsInTemplateInstantiation, Sharing) {
4310 auto Matcher = binaryOperator(unless(isInTemplateInstantiation()));
4311 // FIXME: Node sharing is an implementation detail, exposing it is ugly
4312 // and makes the matcher behave in non-obvious ways.
4313 EXPECT_TRUE(notMatches(
4314 "int j; template<typename T> void A(T t) { j += 42; } void x() { A(0); }",
4315 Matcher));
4316 EXPECT_TRUE(matches(
4317 "int j; template<typename T> void A(T t) { j += t; } void x() { A(0); }",
4318 Matcher));
4319}
4320
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004321TEST(IsExplicitTemplateSpecialization,
4322 DoesNotMatchPrimaryTemplate) {
4323 EXPECT_TRUE(notMatches(
4324 "template <typename T> class X {};",
Aaron Ballman512fb642015-09-17 13:30:52 +00004325 cxxRecordDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004326 EXPECT_TRUE(notMatches(
4327 "template <typename T> void f(T t);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004328 functionDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004329}
4330
4331TEST(IsExplicitTemplateSpecialization,
4332 DoesNotMatchExplicitTemplateInstantiations) {
4333 EXPECT_TRUE(notMatches(
4334 "template <typename T> class X {};"
4335 "template class X<int>; extern template class X<long>;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004336 cxxRecordDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004337 EXPECT_TRUE(notMatches(
4338 "template <typename T> void f(T t) {}"
4339 "template void f(int t); extern template void f(long t);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004340 functionDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004341}
4342
4343TEST(IsExplicitTemplateSpecialization,
4344 DoesNotMatchImplicitTemplateInstantiations) {
4345 EXPECT_TRUE(notMatches(
4346 "template <typename T> class X {}; X<int> x;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004347 cxxRecordDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004348 EXPECT_TRUE(notMatches(
4349 "template <typename T> void f(T t); void g() { f(10); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004350 functionDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004351}
4352
4353TEST(IsExplicitTemplateSpecialization,
4354 MatchesExplicitTemplateSpecializations) {
4355 EXPECT_TRUE(matches(
4356 "template <typename T> class X {};"
4357 "template<> class X<int> {};",
Aaron Ballman512fb642015-09-17 13:30:52 +00004358 cxxRecordDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004359 EXPECT_TRUE(matches(
4360 "template <typename T> void f(T t) {}"
4361 "template<> void f(int t) {}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004362 functionDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004363}
4364
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004365TEST(HasAncenstor, MatchesDeclarationAncestors) {
4366 EXPECT_TRUE(matches(
4367 "class A { class B { class C {}; }; };",
4368 recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("A"))))));
4369}
4370
4371TEST(HasAncenstor, FailsIfNoAncestorMatches) {
4372 EXPECT_TRUE(notMatches(
4373 "class A { class B { class C {}; }; };",
4374 recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("X"))))));
4375}
4376
4377TEST(HasAncestor, MatchesDeclarationsThatGetVisitedLater) {
4378 EXPECT_TRUE(matches(
4379 "class A { class B { void f() { C c; } class C {}; }; };",
4380 varDecl(hasName("c"), hasType(recordDecl(hasName("C"),
4381 hasAncestor(recordDecl(hasName("A"))))))));
4382}
4383
4384TEST(HasAncenstor, MatchesStatementAncestors) {
4385 EXPECT_TRUE(matches(
4386 "void f() { if (true) { while (false) { 42; } } }",
Daniel Jasper848cbe12012-09-18 13:09:13 +00004387 integerLiteral(equals(42), hasAncestor(ifStmt()))));
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004388}
4389
4390TEST(HasAncestor, DrillsThroughDifferentHierarchies) {
4391 EXPECT_TRUE(matches(
4392 "void f() { if (true) { int x = 42; } }",
Daniel Jasper848cbe12012-09-18 13:09:13 +00004393 integerLiteral(equals(42), hasAncestor(functionDecl(hasName("f"))))));
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004394}
4395
4396TEST(HasAncestor, BindsRecursiveCombinations) {
4397 EXPECT_TRUE(matchAndVerifyResultTrue(
4398 "class C { class D { class E { class F { int y; }; }; }; };",
4399 fieldDecl(hasAncestor(recordDecl(hasAncestor(recordDecl().bind("r"))))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00004400 new VerifyIdIsBoundTo<CXXRecordDecl>("r", 1)));
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004401}
4402
4403TEST(HasAncestor, BindsCombinationsWithHasDescendant) {
4404 EXPECT_TRUE(matchAndVerifyResultTrue(
4405 "class C { class D { class E { class F { int y; }; }; }; };",
4406 fieldDecl(hasAncestor(
4407 decl(
4408 hasDescendant(recordDecl(isDefinition(),
4409 hasAncestor(recordDecl())))
4410 ).bind("d")
4411 )),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00004412 new VerifyIdIsBoundTo<CXXRecordDecl>("d", "E")));
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004413}
4414
Manuel Klimekb64d6b72013-03-14 16:33:21 +00004415TEST(HasAncestor, MatchesClosestAncestor) {
4416 EXPECT_TRUE(matchAndVerifyResultTrue(
4417 "template <typename T> struct C {"
4418 " void f(int) {"
4419 " struct I { void g(T) { int x; } } i; i.g(42);"
4420 " }"
4421 "};"
4422 "template struct C<int>;",
4423 varDecl(hasName("x"),
4424 hasAncestor(functionDecl(hasParameter(
4425 0, varDecl(hasType(asString("int"))))).bind("f"))).bind("v"),
4426 new VerifyIdIsBoundTo<FunctionDecl>("f", "g", 2)));
4427}
4428
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004429TEST(HasAncestor, MatchesInTemplateInstantiations) {
4430 EXPECT_TRUE(matches(
4431 "template <typename T> struct A { struct B { struct C { T t; }; }; }; "
4432 "A<int>::B::C a;",
4433 fieldDecl(hasType(asString("int")),
4434 hasAncestor(recordDecl(hasName("A"))))));
4435}
4436
4437TEST(HasAncestor, MatchesInImplicitCode) {
4438 EXPECT_TRUE(matches(
4439 "struct X {}; struct A { A() {} X x; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00004440 cxxConstructorDecl(
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004441 hasAnyConstructorInitializer(withInitializer(expr(
4442 hasAncestor(recordDecl(hasName("A")))))))));
4443}
4444
Daniel Jasper632aea92012-10-22 16:26:51 +00004445TEST(HasParent, MatchesOnlyParent) {
4446 EXPECT_TRUE(matches(
4447 "void f() { if (true) { int x = 42; } }",
4448 compoundStmt(hasParent(ifStmt()))));
4449 EXPECT_TRUE(notMatches(
4450 "void f() { for (;;) { int x = 42; } }",
4451 compoundStmt(hasParent(ifStmt()))));
4452 EXPECT_TRUE(notMatches(
4453 "void f() { if (true) for (;;) { int x = 42; } }",
4454 compoundStmt(hasParent(ifStmt()))));
4455}
4456
Manuel Klimekc844a462012-12-06 14:42:48 +00004457TEST(HasAncestor, MatchesAllAncestors) {
4458 EXPECT_TRUE(matches(
4459 "template <typename T> struct C { static void f() { 42; } };"
4460 "void t() { C<int>::f(); }",
4461 integerLiteral(
4462 equals(42),
Aaron Ballman512fb642015-09-17 13:30:52 +00004463 allOf(
4464 hasAncestor(cxxRecordDecl(isTemplateInstantiation())),
4465 hasAncestor(cxxRecordDecl(unless(isTemplateInstantiation())))))));
Manuel Klimekc844a462012-12-06 14:42:48 +00004466}
4467
Nico Weberc4acee32016-01-22 15:11:54 +00004468TEST(HasAncestor, ImplicitArrayCopyCtorDeclRefExpr) {
4469 EXPECT_TRUE(matches("struct MyClass {\n"
4470 " int c[1];\n"
4471 " static MyClass Create() { return MyClass(); }\n"
4472 "};",
4473 declRefExpr(to(decl(hasAncestor(decl()))))));
4474}
4475
Nico Weber7b837f52016-01-28 19:25:00 +00004476TEST(HasAncestor, AnonymousUnionMemberExpr) {
4477 EXPECT_TRUE(matches("int F() {\n"
4478 " union { int i; };\n"
4479 " return i;\n"
4480 "}\n",
4481 memberExpr(member(hasAncestor(decl())))));
4482 EXPECT_TRUE(matches("void f() {\n"
4483 " struct {\n"
4484 " struct { int a; int b; };\n"
4485 " } s;\n"
4486 " s.a = 4;\n"
4487 "}\n",
4488 memberExpr(member(hasAncestor(decl())))));
4489 EXPECT_TRUE(matches("void f() {\n"
4490 " struct {\n"
4491 " struct { int a; int b; };\n"
4492 " } s;\n"
4493 " s.a = 4;\n"
4494 "}\n",
4495 declRefExpr(to(decl(hasAncestor(decl()))))));
4496}
4497
Nico Weberc0973372016-02-01 22:31:51 +00004498TEST(HasAncestor, NonParmDependentTemplateParmVarDeclRefExpr) {
4499 EXPECT_TRUE(matches("struct PartitionAllocator {\n"
4500 " template<typename T>\n"
4501 " static int quantizedSize(int count) {\n"
4502 " return count;\n"
4503 " }\n"
4504 " void f() { quantizedSize<int>(10); }\n"
4505 "};",
4506 declRefExpr(to(decl(hasAncestor(decl()))))));
4507}
4508
Nico Weber26911c72016-02-08 22:23:09 +00004509TEST(HasAncestor, AddressOfExplicitSpecializationFunction) {
4510 EXPECT_TRUE(matches("template <class T> void f();\n"
4511 "template <> void f<int>();\n"
4512 "void (*get_f())() { return f<int>; }\n",
4513 declRefExpr(to(decl(hasAncestor(decl()))))));
4514}
4515
Manuel Klimekc844a462012-12-06 14:42:48 +00004516TEST(HasParent, MatchesAllParents) {
4517 EXPECT_TRUE(matches(
4518 "template <typename T> struct C { static void f() { 42; } };"
4519 "void t() { C<int>::f(); }",
4520 integerLiteral(
4521 equals(42),
4522 hasParent(compoundStmt(hasParent(functionDecl(
Aaron Ballman512fb642015-09-17 13:30:52 +00004523 hasParent(cxxRecordDecl(isTemplateInstantiation())))))))));
4524 EXPECT_TRUE(
4525 matches("template <typename T> struct C { static void f() { 42; } };"
4526 "void t() { C<int>::f(); }",
4527 integerLiteral(
4528 equals(42),
4529 hasParent(compoundStmt(hasParent(functionDecl(hasParent(
4530 cxxRecordDecl(unless(isTemplateInstantiation()))))))))));
Manuel Klimekc844a462012-12-06 14:42:48 +00004531 EXPECT_TRUE(matches(
4532 "template <typename T> struct C { static void f() { 42; } };"
4533 "void t() { C<int>::f(); }",
4534 integerLiteral(equals(42),
Aaron Ballman512fb642015-09-17 13:30:52 +00004535 hasParent(compoundStmt(
4536 allOf(hasParent(functionDecl(hasParent(
4537 cxxRecordDecl(isTemplateInstantiation())))),
4538 hasParent(functionDecl(hasParent(cxxRecordDecl(
4539 unless(isTemplateInstantiation())))))))))));
Manuel Klimekb64d6b72013-03-14 16:33:21 +00004540 EXPECT_TRUE(
4541 notMatches("template <typename T> struct C { static void f() {} };"
4542 "void t() { C<int>::f(); }",
4543 compoundStmt(hasParent(recordDecl()))));
Manuel Klimekc844a462012-12-06 14:42:48 +00004544}
4545
Samuel Benzaquen3ca0a7b2014-06-13 13:31:40 +00004546TEST(HasParent, NoDuplicateParents) {
4547 class HasDuplicateParents : public BoundNodesCallback {
4548 public:
4549 bool run(const BoundNodes *Nodes) override { return false; }
4550 bool run(const BoundNodes *Nodes, ASTContext *Context) override {
4551 const Stmt *Node = Nodes->getNodeAs<Stmt>("node");
4552 std::set<const void *> Parents;
4553 for (const auto &Parent : Context->getParents(*Node)) {
4554 if (!Parents.insert(Parent.getMemoizationData()).second) {
4555 return true;
4556 }
4557 }
4558 return false;
4559 }
4560 };
4561 EXPECT_FALSE(matchAndVerifyResultTrue(
4562 "template <typename T> int Foo() { return 1 + 2; }\n"
4563 "int x = Foo<int>() + Foo<unsigned>();",
4564 stmt().bind("node"), new HasDuplicateParents()));
4565}
4566
Daniel Jasper516b02e2012-10-17 08:52:59 +00004567TEST(TypeMatching, MatchesTypes) {
4568 EXPECT_TRUE(matches("struct S {};", qualType().bind("loc")));
4569}
4570
Samuel Benzaquenbd3232a2015-12-22 20:06:40 +00004571TEST(TypeMatching, MatchesBool) {
4572 EXPECT_TRUE(matches("struct S { bool func(); };",
4573 cxxMethodDecl(returns(booleanType()))));
4574 EXPECT_TRUE(notMatches("struct S { void func(); };",
4575 cxxMethodDecl(returns(booleanType()))));
4576}
4577
Samuel Benzaquenb405c082014-12-15 15:09:22 +00004578TEST(TypeMatching, MatchesVoid) {
Aaron Ballman512fb642015-09-17 13:30:52 +00004579 EXPECT_TRUE(matches("struct S { void func(); };",
4580 cxxMethodDecl(returns(voidType()))));
Samuel Benzaquenb405c082014-12-15 15:09:22 +00004581}
4582
Aaron Ballmaneb7e5d92016-02-18 16:36:01 +00004583TEST(TypeMatching, MatchesRealFloats) {
4584 EXPECT_TRUE(matches("struct S { float func(); };",
4585 cxxMethodDecl(returns(realFloatingPointType()))));
4586 EXPECT_TRUE(notMatches("struct S { int func(); };",
4587 cxxMethodDecl(returns(realFloatingPointType()))));
4588 EXPECT_TRUE(matches("struct S { long double func(); };",
4589 cxxMethodDecl(returns(realFloatingPointType()))));
4590}
4591
Daniel Jasper516b02e2012-10-17 08:52:59 +00004592TEST(TypeMatching, MatchesArrayTypes) {
4593 EXPECT_TRUE(matches("int a[] = {2,3};", arrayType()));
4594 EXPECT_TRUE(matches("int a[42];", arrayType()));
4595 EXPECT_TRUE(matches("void f(int b) { int a[b]; }", arrayType()));
4596
4597 EXPECT_TRUE(notMatches("struct A {}; A a[7];",
4598 arrayType(hasElementType(builtinType()))));
4599
4600 EXPECT_TRUE(matches(
4601 "int const a[] = { 2, 3 };",
4602 qualType(arrayType(hasElementType(builtinType())))));
4603 EXPECT_TRUE(matches(
4604 "int const a[] = { 2, 3 };",
4605 qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
4606 EXPECT_TRUE(matches(
4607 "typedef const int T; T x[] = { 1, 2 };",
4608 qualType(isConstQualified(), arrayType())));
4609
4610 EXPECT_TRUE(notMatches(
4611 "int a[] = { 2, 3 };",
4612 qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
4613 EXPECT_TRUE(notMatches(
4614 "int a[] = { 2, 3 };",
4615 qualType(arrayType(hasElementType(isConstQualified(), builtinType())))));
4616 EXPECT_TRUE(notMatches(
4617 "int const a[] = { 2, 3 };",
4618 qualType(arrayType(hasElementType(builtinType())),
4619 unless(isConstQualified()))));
4620
4621 EXPECT_TRUE(matches("int a[2];",
4622 constantArrayType(hasElementType(builtinType()))));
4623 EXPECT_TRUE(matches("const int a = 0;", qualType(isInteger())));
4624}
4625
Matthias Gehre2cf7e802015-10-12 21:46:07 +00004626TEST(TypeMatching, DecayedType) {
4627 EXPECT_TRUE(matches("void f(int i[]);", valueDecl(hasType(decayedType(hasDecayedType(pointerType()))))));
4628 EXPECT_TRUE(notMatches("int i[7];", decayedType()));
4629}
4630
Daniel Jasper516b02e2012-10-17 08:52:59 +00004631TEST(TypeMatching, MatchesComplexTypes) {
4632 EXPECT_TRUE(matches("_Complex float f;", complexType()));
4633 EXPECT_TRUE(matches(
4634 "_Complex float f;",
4635 complexType(hasElementType(builtinType()))));
4636 EXPECT_TRUE(notMatches(
4637 "_Complex float f;",
4638 complexType(hasElementType(isInteger()))));
4639}
4640
4641TEST(TypeMatching, MatchesConstantArrayTypes) {
4642 EXPECT_TRUE(matches("int a[2];", constantArrayType()));
4643 EXPECT_TRUE(notMatches(
4644 "void f() { int a[] = { 2, 3 }; int b[a[0]]; }",
4645 constantArrayType(hasElementType(builtinType()))));
4646
4647 EXPECT_TRUE(matches("int a[42];", constantArrayType(hasSize(42))));
4648 EXPECT_TRUE(matches("int b[2*21];", constantArrayType(hasSize(42))));
4649 EXPECT_TRUE(notMatches("int c[41], d[43];", constantArrayType(hasSize(42))));
4650}
4651
4652TEST(TypeMatching, MatchesDependentSizedArrayTypes) {
4653 EXPECT_TRUE(matches(
4654 "template <typename T, int Size> class array { T data[Size]; };",
4655 dependentSizedArrayType()));
4656 EXPECT_TRUE(notMatches(
4657 "int a[42]; int b[] = { 2, 3 }; void f() { int c[b[0]]; }",
4658 dependentSizedArrayType()));
4659}
4660
4661TEST(TypeMatching, MatchesIncompleteArrayType) {
4662 EXPECT_TRUE(matches("int a[] = { 2, 3 };", incompleteArrayType()));
4663 EXPECT_TRUE(matches("void f(int a[]) {}", incompleteArrayType()));
4664
4665 EXPECT_TRUE(notMatches("int a[42]; void f() { int b[a[0]]; }",
4666 incompleteArrayType()));
4667}
4668
4669TEST(TypeMatching, MatchesVariableArrayType) {
4670 EXPECT_TRUE(matches("void f(int b) { int a[b]; }", variableArrayType()));
4671 EXPECT_TRUE(notMatches("int a[] = {2, 3}; int b[42];", variableArrayType()));
4672
4673 EXPECT_TRUE(matches(
4674 "void f(int b) { int a[b]; }",
4675 variableArrayType(hasSizeExpr(ignoringImpCasts(declRefExpr(to(
4676 varDecl(hasName("b")))))))));
4677}
4678
4679TEST(TypeMatching, MatchesAtomicTypes) {
David Majnemer197e2102014-03-05 06:32:38 +00004680 if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getOS() !=
4681 llvm::Triple::Win32) {
4682 // FIXME: Make this work for MSVC.
4683 EXPECT_TRUE(matches("_Atomic(int) i;", atomicType()));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004684
David Majnemer197e2102014-03-05 06:32:38 +00004685 EXPECT_TRUE(matches("_Atomic(int) i;",
4686 atomicType(hasValueType(isInteger()))));
4687 EXPECT_TRUE(notMatches("_Atomic(float) f;",
4688 atomicType(hasValueType(isInteger()))));
4689 }
Daniel Jasper516b02e2012-10-17 08:52:59 +00004690}
4691
4692TEST(TypeMatching, MatchesAutoTypes) {
4693 EXPECT_TRUE(matches("auto i = 2;", autoType()));
4694 EXPECT_TRUE(matches("int v[] = { 2, 3 }; void f() { for (int i : v) {} }",
4695 autoType()));
4696
Richard Smith061f1e22013-04-30 21:23:01 +00004697 // FIXME: Matching against the type-as-written can't work here, because the
4698 // type as written was not deduced.
4699 //EXPECT_TRUE(matches("auto a = 1;",
4700 // autoType(hasDeducedType(isInteger()))));
4701 //EXPECT_TRUE(notMatches("auto b = 2.0;",
4702 // autoType(hasDeducedType(isInteger()))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004703}
4704
Daniel Jasperd29d5fa2012-10-29 10:14:44 +00004705TEST(TypeMatching, MatchesFunctionTypes) {
4706 EXPECT_TRUE(matches("int (*f)(int);", functionType()));
4707 EXPECT_TRUE(matches("void f(int i) {}", functionType()));
4708}
4709
Aaron Ballman7e7b7b22016-02-01 14:11:47 +00004710TEST(TypeMatching, MatchesFunctionProtoTypes) {
4711 EXPECT_TRUE(matches("int (*f)(int);", functionProtoType()));
4712 EXPECT_TRUE(matches("void f(int i);", functionProtoType()));
4713 EXPECT_TRUE(matches("void f();", functionProtoType(parameterCountIs(0))));
4714 EXPECT_TRUE(notMatchesC("void f();", functionProtoType()));
4715 EXPECT_TRUE(
4716 matchesC("void f(void);", functionProtoType(parameterCountIs(0))));
4717}
4718
Edwin Vaneec074802013-04-01 18:33:34 +00004719TEST(TypeMatching, MatchesParenType) {
4720 EXPECT_TRUE(
4721 matches("int (*array)[4];", varDecl(hasType(pointsTo(parenType())))));
4722 EXPECT_TRUE(notMatches("int *array[4];", varDecl(hasType(parenType()))));
4723
4724 EXPECT_TRUE(matches(
4725 "int (*ptr_to_func)(int);",
4726 varDecl(hasType(pointsTo(parenType(innerType(functionType())))))));
4727 EXPECT_TRUE(notMatches(
4728 "int (*ptr_to_array)[4];",
4729 varDecl(hasType(pointsTo(parenType(innerType(functionType())))))));
4730}
4731
Daniel Jasper516b02e2012-10-17 08:52:59 +00004732TEST(TypeMatching, PointerTypes) {
Daniel Jasper7943eb52012-10-17 13:35:36 +00004733 // FIXME: Reactive when these tests can be more specific (not matching
4734 // implicit code on certain platforms), likely when we have hasDescendant for
4735 // Types/TypeLocs.
4736 //EXPECT_TRUE(matchAndVerifyResultTrue(
4737 // "int* a;",
4738 // pointerTypeLoc(pointeeLoc(typeLoc().bind("loc"))),
4739 // new VerifyIdIsBoundTo<TypeLoc>("loc", 1)));
4740 //EXPECT_TRUE(matchAndVerifyResultTrue(
4741 // "int* a;",
4742 // pointerTypeLoc().bind("loc"),
4743 // new VerifyIdIsBoundTo<TypeLoc>("loc", 1)));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004744 EXPECT_TRUE(matches(
4745 "int** a;",
David Blaikieb61d0872013-02-18 19:04:16 +00004746 loc(pointerType(pointee(qualType())))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004747 EXPECT_TRUE(matches(
4748 "int** a;",
4749 loc(pointerType(pointee(pointerType())))));
4750 EXPECT_TRUE(matches(
4751 "int* b; int* * const a = &b;",
4752 loc(qualType(isConstQualified(), pointerType()))));
4753
4754 std::string Fragment = "struct A { int i; }; int A::* ptr = &A::i;";
Daniel Jasper7943eb52012-10-17 13:35:36 +00004755 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4756 hasType(blockPointerType()))));
4757 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ptr"),
4758 hasType(memberPointerType()))));
4759 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4760 hasType(pointerType()))));
4761 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4762 hasType(referenceType()))));
Edwin Vane2a760d02013-03-07 15:44:40 +00004763 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4764 hasType(lValueReferenceType()))));
4765 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4766 hasType(rValueReferenceType()))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004767
Daniel Jasper7943eb52012-10-17 13:35:36 +00004768 Fragment = "int *ptr;";
4769 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4770 hasType(blockPointerType()))));
4771 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4772 hasType(memberPointerType()))));
4773 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ptr"),
4774 hasType(pointerType()))));
4775 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4776 hasType(referenceType()))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004777
Daniel Jasper7943eb52012-10-17 13:35:36 +00004778 Fragment = "int a; int &ref = a;";
4779 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4780 hasType(blockPointerType()))));
4781 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4782 hasType(memberPointerType()))));
4783 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4784 hasType(pointerType()))));
4785 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
4786 hasType(referenceType()))));
Edwin Vane2a760d02013-03-07 15:44:40 +00004787 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
4788 hasType(lValueReferenceType()))));
4789 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4790 hasType(rValueReferenceType()))));
4791
4792 Fragment = "int &&ref = 2;";
4793 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4794 hasType(blockPointerType()))));
4795 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4796 hasType(memberPointerType()))));
4797 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4798 hasType(pointerType()))));
4799 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
4800 hasType(referenceType()))));
4801 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4802 hasType(lValueReferenceType()))));
4803 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
4804 hasType(rValueReferenceType()))));
4805}
4806
4807TEST(TypeMatching, AutoRefTypes) {
4808 std::string Fragment = "auto a = 1;"
4809 "auto b = a;"
4810 "auto &c = a;"
4811 "auto &&d = c;"
4812 "auto &&e = 2;";
4813 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("a"),
4814 hasType(referenceType()))));
4815 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("b"),
4816 hasType(referenceType()))));
4817 EXPECT_TRUE(matches(Fragment, varDecl(hasName("c"),
4818 hasType(referenceType()))));
4819 EXPECT_TRUE(matches(Fragment, varDecl(hasName("c"),
4820 hasType(lValueReferenceType()))));
4821 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("c"),
4822 hasType(rValueReferenceType()))));
4823 EXPECT_TRUE(matches(Fragment, varDecl(hasName("d"),
4824 hasType(referenceType()))));
4825 EXPECT_TRUE(matches(Fragment, varDecl(hasName("d"),
4826 hasType(lValueReferenceType()))));
4827 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("d"),
4828 hasType(rValueReferenceType()))));
4829 EXPECT_TRUE(matches(Fragment, varDecl(hasName("e"),
4830 hasType(referenceType()))));
4831 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("e"),
4832 hasType(lValueReferenceType()))));
4833 EXPECT_TRUE(matches(Fragment, varDecl(hasName("e"),
4834 hasType(rValueReferenceType()))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004835}
4836
4837TEST(TypeMatching, PointeeTypes) {
4838 EXPECT_TRUE(matches("int b; int &a = b;",
4839 referenceType(pointee(builtinType()))));
4840 EXPECT_TRUE(matches("int *a;", pointerType(pointee(builtinType()))));
4841
4842 EXPECT_TRUE(matches("int *a;",
David Blaikieb61d0872013-02-18 19:04:16 +00004843 loc(pointerType(pointee(builtinType())))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004844
4845 EXPECT_TRUE(matches(
4846 "int const *A;",
4847 pointerType(pointee(isConstQualified(), builtinType()))));
4848 EXPECT_TRUE(notMatches(
4849 "int *A;",
4850 pointerType(pointee(isConstQualified(), builtinType()))));
4851}
4852
4853TEST(TypeMatching, MatchesPointersToConstTypes) {
4854 EXPECT_TRUE(matches("int b; int * const a = &b;",
4855 loc(pointerType())));
4856 EXPECT_TRUE(matches("int b; int * const a = &b;",
David Blaikieb61d0872013-02-18 19:04:16 +00004857 loc(pointerType())));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004858 EXPECT_TRUE(matches(
4859 "int b; const int * a = &b;",
David Blaikieb61d0872013-02-18 19:04:16 +00004860 loc(pointerType(pointee(builtinType())))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004861 EXPECT_TRUE(matches(
4862 "int b; const int * a = &b;",
4863 pointerType(pointee(builtinType()))));
4864}
4865
4866TEST(TypeMatching, MatchesTypedefTypes) {
Daniel Jasper7943eb52012-10-17 13:35:36 +00004867 EXPECT_TRUE(matches("typedef int X; X a;", varDecl(hasName("a"),
4868 hasType(typedefType()))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004869}
4870
Edwin Vanef901b712013-02-25 14:49:29 +00004871TEST(TypeMatching, MatchesTemplateSpecializationType) {
Edwin Vaneb6eae142013-02-25 20:43:32 +00004872 EXPECT_TRUE(matches("template <typename T> class A{}; A<int> a;",
Edwin Vanef901b712013-02-25 14:49:29 +00004873 templateSpecializationType()));
4874}
4875
Edwin Vaneb6eae142013-02-25 20:43:32 +00004876TEST(TypeMatching, MatchesRecordType) {
4877 EXPECT_TRUE(matches("class C{}; C c;", recordType()));
Manuel Klimek59b0af62013-02-27 11:56:58 +00004878 EXPECT_TRUE(matches("struct S{}; S s;",
4879 recordType(hasDeclaration(recordDecl(hasName("S"))))));
4880 EXPECT_TRUE(notMatches("int i;",
4881 recordType(hasDeclaration(recordDecl(hasName("S"))))));
Edwin Vaneb6eae142013-02-25 20:43:32 +00004882}
4883
4884TEST(TypeMatching, MatchesElaboratedType) {
4885 EXPECT_TRUE(matches(
4886 "namespace N {"
4887 " namespace M {"
4888 " class D {};"
4889 " }"
4890 "}"
4891 "N::M::D d;", elaboratedType()));
4892 EXPECT_TRUE(matches("class C {} c;", elaboratedType()));
4893 EXPECT_TRUE(notMatches("class C {}; C c;", elaboratedType()));
4894}
4895
4896TEST(ElaboratedTypeNarrowing, hasQualifier) {
4897 EXPECT_TRUE(matches(
4898 "namespace N {"
4899 " namespace M {"
4900 " class D {};"
4901 " }"
4902 "}"
4903 "N::M::D d;",
4904 elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
4905 EXPECT_TRUE(notMatches(
4906 "namespace M {"
4907 " class D {};"
4908 "}"
4909 "M::D d;",
4910 elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
Edwin Vane6972f6d2013-03-04 17:51:00 +00004911 EXPECT_TRUE(notMatches(
4912 "struct D {"
4913 "} d;",
4914 elaboratedType(hasQualifier(nestedNameSpecifier()))));
Edwin Vaneb6eae142013-02-25 20:43:32 +00004915}
4916
4917TEST(ElaboratedTypeNarrowing, namesType) {
4918 EXPECT_TRUE(matches(
4919 "namespace N {"
4920 " namespace M {"
4921 " class D {};"
4922 " }"
4923 "}"
4924 "N::M::D d;",
4925 elaboratedType(elaboratedType(namesType(recordType(
4926 hasDeclaration(namedDecl(hasName("D")))))))));
4927 EXPECT_TRUE(notMatches(
4928 "namespace M {"
4929 " class D {};"
4930 "}"
4931 "M::D d;",
4932 elaboratedType(elaboratedType(namesType(typedefType())))));
4933}
4934
Samuel Benzaquenf8ec4542015-08-26 16:15:59 +00004935TEST(TypeMatching, MatchesSubstTemplateTypeParmType) {
4936 const std::string code = "template <typename T>"
4937 "int F() {"
4938 " return 1 + T();"
4939 "}"
4940 "int i = F<int>();";
4941 EXPECT_FALSE(matches(code, binaryOperator(hasLHS(
4942 expr(hasType(substTemplateTypeParmType()))))));
4943 EXPECT_TRUE(matches(code, binaryOperator(hasRHS(
4944 expr(hasType(substTemplateTypeParmType()))))));
4945}
4946
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00004947TEST(NNS, MatchesNestedNameSpecifiers) {
4948 EXPECT_TRUE(matches("namespace ns { struct A {}; } ns::A a;",
4949 nestedNameSpecifier()));
4950 EXPECT_TRUE(matches("template <typename T> class A { typename T::B b; };",
4951 nestedNameSpecifier()));
4952 EXPECT_TRUE(matches("struct A { void f(); }; void A::f() {}",
4953 nestedNameSpecifier()));
Daniel Jasperc8f472c2015-12-02 13:57:46 +00004954 EXPECT_TRUE(matches("namespace a { namespace b {} } namespace ab = a::b;",
4955 nestedNameSpecifier()));
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00004956
4957 EXPECT_TRUE(matches(
4958 "struct A { static void f() {} }; void g() { A::f(); }",
4959 nestedNameSpecifier()));
4960 EXPECT_TRUE(notMatches(
4961 "struct A { static void f() {} }; void g(A* a) { a->f(); }",
4962 nestedNameSpecifier()));
4963}
4964
Daniel Jasper87c3d362012-09-20 14:12:57 +00004965TEST(NullStatement, SimpleCases) {
4966 EXPECT_TRUE(matches("void f() {int i;;}", nullStmt()));
4967 EXPECT_TRUE(notMatches("void f() {int i;}", nullStmt()));
4968}
4969
Aaron Ballman11825f22015-08-18 19:55:20 +00004970TEST(NS, Anonymous) {
4971 EXPECT_TRUE(notMatches("namespace N {}", namespaceDecl(isAnonymous())));
4972 EXPECT_TRUE(matches("namespace {}", namespaceDecl(isAnonymous())));
4973}
4974
Aaron Ballman6c79f352015-08-28 19:39:21 +00004975TEST(NS, Alias) {
4976 EXPECT_TRUE(matches("namespace test {} namespace alias = ::test;",
4977 namespaceAliasDecl(hasName("alias"))));
4978}
4979
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00004980TEST(NNS, MatchesTypes) {
4981 NestedNameSpecifierMatcher Matcher = nestedNameSpecifier(
4982 specifiesType(hasDeclaration(recordDecl(hasName("A")))));
4983 EXPECT_TRUE(matches("struct A { struct B {}; }; A::B b;", Matcher));
4984 EXPECT_TRUE(matches("struct A { struct B { struct C {}; }; }; A::B::C c;",
4985 Matcher));
4986 EXPECT_TRUE(notMatches("namespace A { struct B {}; } A::B b;", Matcher));
4987}
4988
4989TEST(NNS, MatchesNamespaceDecls) {
4990 NestedNameSpecifierMatcher Matcher = nestedNameSpecifier(
4991 specifiesNamespace(hasName("ns")));
4992 EXPECT_TRUE(matches("namespace ns { struct A {}; } ns::A a;", Matcher));
4993 EXPECT_TRUE(notMatches("namespace xx { struct A {}; } xx::A a;", Matcher));
4994 EXPECT_TRUE(notMatches("struct ns { struct A {}; }; ns::A a;", Matcher));
4995}
4996
4997TEST(NNS, BindsNestedNameSpecifiers) {
4998 EXPECT_TRUE(matchAndVerifyResultTrue(
4999 "namespace ns { struct E { struct B {}; }; } ns::E::B b;",
5000 nestedNameSpecifier(specifiesType(asString("struct ns::E"))).bind("nns"),
5001 new VerifyIdIsBoundTo<NestedNameSpecifier>("nns", "ns::struct E::")));
5002}
5003
5004TEST(NNS, BindsNestedNameSpecifierLocs) {
5005 EXPECT_TRUE(matchAndVerifyResultTrue(
5006 "namespace ns { struct B {}; } ns::B b;",
5007 loc(nestedNameSpecifier()).bind("loc"),
5008 new VerifyIdIsBoundTo<NestedNameSpecifierLoc>("loc", 1)));
5009}
5010
5011TEST(NNS, MatchesNestedNameSpecifierPrefixes) {
5012 EXPECT_TRUE(matches(
5013 "struct A { struct B { struct C {}; }; }; A::B::C c;",
5014 nestedNameSpecifier(hasPrefix(specifiesType(asString("struct A"))))));
5015 EXPECT_TRUE(matches(
5016 "struct A { struct B { struct C {}; }; }; A::B::C c;",
Daniel Jasper516b02e2012-10-17 08:52:59 +00005017 nestedNameSpecifierLoc(hasPrefix(
5018 specifiesTypeLoc(loc(qualType(asString("struct A"))))))));
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00005019}
5020
Daniel Jasper6fc34332012-10-30 15:42:00 +00005021TEST(NNS, DescendantsOfNestedNameSpecifiers) {
5022 std::string Fragment =
5023 "namespace a { struct A { struct B { struct C {}; }; }; };"
5024 "void f() { a::A::B::C c; }";
5025 EXPECT_TRUE(matches(
5026 Fragment,
5027 nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
5028 hasDescendant(nestedNameSpecifier(
5029 specifiesNamespace(hasName("a")))))));
5030 EXPECT_TRUE(notMatches(
5031 Fragment,
5032 nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
5033 has(nestedNameSpecifier(
5034 specifiesNamespace(hasName("a")))))));
5035 EXPECT_TRUE(matches(
5036 Fragment,
5037 nestedNameSpecifier(specifiesType(asString("struct a::A")),
5038 has(nestedNameSpecifier(
5039 specifiesNamespace(hasName("a")))))));
5040
5041 // Not really useful because a NestedNameSpecifier can af at most one child,
5042 // but to complete the interface.
5043 EXPECT_TRUE(matchAndVerifyResultTrue(
5044 Fragment,
5045 nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
5046 forEach(nestedNameSpecifier().bind("x"))),
5047 new VerifyIdIsBoundTo<NestedNameSpecifier>("x", 1)));
5048}
5049
5050TEST(NNS, NestedNameSpecifiersAsDescendants) {
5051 std::string Fragment =
5052 "namespace a { struct A { struct B { struct C {}; }; }; };"
5053 "void f() { a::A::B::C c; }";
5054 EXPECT_TRUE(matches(
5055 Fragment,
5056 decl(hasDescendant(nestedNameSpecifier(specifiesType(
5057 asString("struct a::A")))))));
5058 EXPECT_TRUE(matchAndVerifyResultTrue(
5059 Fragment,
5060 functionDecl(hasName("f"),
5061 forEachDescendant(nestedNameSpecifier().bind("x"))),
5062 // Nested names: a, a::A and a::A::B.
5063 new VerifyIdIsBoundTo<NestedNameSpecifier>("x", 3)));
5064}
5065
5066TEST(NNSLoc, DescendantsOfNestedNameSpecifierLocs) {
5067 std::string Fragment =
5068 "namespace a { struct A { struct B { struct C {}; }; }; };"
5069 "void f() { a::A::B::C c; }";
5070 EXPECT_TRUE(matches(
5071 Fragment,
5072 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
5073 hasDescendant(loc(nestedNameSpecifier(
5074 specifiesNamespace(hasName("a"))))))));
5075 EXPECT_TRUE(notMatches(
5076 Fragment,
5077 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
5078 has(loc(nestedNameSpecifier(
5079 specifiesNamespace(hasName("a"))))))));
5080 EXPECT_TRUE(matches(
5081 Fragment,
5082 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A"))),
5083 has(loc(nestedNameSpecifier(
5084 specifiesNamespace(hasName("a"))))))));
5085
5086 EXPECT_TRUE(matchAndVerifyResultTrue(
5087 Fragment,
5088 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
5089 forEach(nestedNameSpecifierLoc().bind("x"))),
5090 new VerifyIdIsBoundTo<NestedNameSpecifierLoc>("x", 1)));
5091}
5092
5093TEST(NNSLoc, NestedNameSpecifierLocsAsDescendants) {
5094 std::string Fragment =
5095 "namespace a { struct A { struct B { struct C {}; }; }; };"
5096 "void f() { a::A::B::C c; }";
5097 EXPECT_TRUE(matches(
5098 Fragment,
5099 decl(hasDescendant(loc(nestedNameSpecifier(specifiesType(
5100 asString("struct a::A"))))))));
5101 EXPECT_TRUE(matchAndVerifyResultTrue(
5102 Fragment,
5103 functionDecl(hasName("f"),
5104 forEachDescendant(nestedNameSpecifierLoc().bind("x"))),
5105 // Nested names: a, a::A and a::A::B.
5106 new VerifyIdIsBoundTo<NestedNameSpecifierLoc>("x", 3)));
5107}
5108
Manuel Klimek191c0932013-02-01 13:41:35 +00005109template <typename T> class VerifyMatchOnNode : public BoundNodesCallback {
Manuel Klimekc2687452012-10-24 14:47:44 +00005110public:
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005111 VerifyMatchOnNode(StringRef Id, const internal::Matcher<T> &InnerMatcher,
5112 StringRef InnerId)
5113 : Id(Id), InnerMatcher(InnerMatcher), InnerId(InnerId) {
Daniel Jaspere9aa6872012-10-29 10:48:25 +00005114 }
5115
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005116 bool run(const BoundNodes *Nodes) override { return false; }
Manuel Klimek191c0932013-02-01 13:41:35 +00005117
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005118 bool run(const BoundNodes *Nodes, ASTContext *Context) override {
Manuel Klimekc2687452012-10-24 14:47:44 +00005119 const T *Node = Nodes->getNodeAs<T>(Id);
Benjamin Kramer76645582014-07-23 11:41:44 +00005120 return selectFirst<T>(InnerId, match(InnerMatcher, *Node, *Context)) !=
5121 nullptr;
Manuel Klimekc2687452012-10-24 14:47:44 +00005122 }
5123private:
5124 std::string Id;
5125 internal::Matcher<T> InnerMatcher;
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005126 std::string InnerId;
Manuel Klimekc2687452012-10-24 14:47:44 +00005127};
5128
5129TEST(MatchFinder, CanMatchDeclarationsRecursively) {
Manuel Klimek191c0932013-02-01 13:41:35 +00005130 EXPECT_TRUE(matchAndVerifyResultTrue(
5131 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5132 new VerifyMatchOnNode<clang::Decl>(
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005133 "X", decl(hasDescendant(recordDecl(hasName("X::Y")).bind("Y"))),
5134 "Y")));
Manuel Klimek191c0932013-02-01 13:41:35 +00005135 EXPECT_TRUE(matchAndVerifyResultFalse(
5136 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5137 new VerifyMatchOnNode<clang::Decl>(
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005138 "X", decl(hasDescendant(recordDecl(hasName("X::Z")).bind("Z"))),
5139 "Z")));
Manuel Klimekc2687452012-10-24 14:47:44 +00005140}
5141
5142TEST(MatchFinder, CanMatchStatementsRecursively) {
Manuel Klimek191c0932013-02-01 13:41:35 +00005143 EXPECT_TRUE(matchAndVerifyResultTrue(
5144 "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005145 new VerifyMatchOnNode<clang::Stmt>(
5146 "if", stmt(hasDescendant(forStmt().bind("for"))), "for")));
Manuel Klimek191c0932013-02-01 13:41:35 +00005147 EXPECT_TRUE(matchAndVerifyResultFalse(
5148 "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005149 new VerifyMatchOnNode<clang::Stmt>(
5150 "if", stmt(hasDescendant(declStmt().bind("decl"))), "decl")));
Manuel Klimek191c0932013-02-01 13:41:35 +00005151}
5152
5153TEST(MatchFinder, CanMatchSingleNodesRecursively) {
5154 EXPECT_TRUE(matchAndVerifyResultTrue(
5155 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5156 new VerifyMatchOnNode<clang::Decl>(
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005157 "X", recordDecl(has(recordDecl(hasName("X::Y")).bind("Y"))), "Y")));
Manuel Klimek191c0932013-02-01 13:41:35 +00005158 EXPECT_TRUE(matchAndVerifyResultFalse(
5159 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5160 new VerifyMatchOnNode<clang::Decl>(
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005161 "X", recordDecl(has(recordDecl(hasName("X::Z")).bind("Z"))), "Z")));
Manuel Klimekc2687452012-10-24 14:47:44 +00005162}
5163
Manuel Klimekbee08572013-02-07 12:42:10 +00005164template <typename T>
5165class VerifyAncestorHasChildIsEqual : public BoundNodesCallback {
5166public:
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005167 bool run(const BoundNodes *Nodes) override { return false; }
Manuel Klimekbee08572013-02-07 12:42:10 +00005168
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005169 bool run(const BoundNodes *Nodes, ASTContext *Context) override {
Manuel Klimekbee08572013-02-07 12:42:10 +00005170 const T *Node = Nodes->getNodeAs<T>("");
5171 return verify(*Nodes, *Context, Node);
5172 }
5173
5174 bool verify(const BoundNodes &Nodes, ASTContext &Context, const Stmt *Node) {
Manuel Klimeka2c2a4f2014-05-27 12:31:10 +00005175 // Use the original typed pointer to verify we can pass pointers to subtypes
5176 // to equalsNode.
5177 const T *TypedNode = cast<T>(Node);
Benjamin Kramer76645582014-07-23 11:41:44 +00005178 return selectFirst<T>(
Manuel Klimeka2c2a4f2014-05-27 12:31:10 +00005179 "", match(stmt(hasParent(
5180 stmt(has(stmt(equalsNode(TypedNode)))).bind(""))),
Craig Topper416fa342014-06-08 08:38:12 +00005181 *Node, Context)) != nullptr;
Manuel Klimekbee08572013-02-07 12:42:10 +00005182 }
5183 bool verify(const BoundNodes &Nodes, ASTContext &Context, const Decl *Node) {
Manuel Klimeka2c2a4f2014-05-27 12:31:10 +00005184 // Use the original typed pointer to verify we can pass pointers to subtypes
5185 // to equalsNode.
5186 const T *TypedNode = cast<T>(Node);
Benjamin Kramer76645582014-07-23 11:41:44 +00005187 return selectFirst<T>(
Manuel Klimeka2c2a4f2014-05-27 12:31:10 +00005188 "", match(decl(hasParent(
5189 decl(has(decl(equalsNode(TypedNode)))).bind(""))),
Craig Topper416fa342014-06-08 08:38:12 +00005190 *Node, Context)) != nullptr;
Manuel Klimekbee08572013-02-07 12:42:10 +00005191 }
Angel Garcia Gomez4647ed72015-10-30 09:35:51 +00005192 bool verify(const BoundNodes &Nodes, ASTContext &Context, const Type *Node) {
5193 // Use the original typed pointer to verify we can pass pointers to subtypes
5194 // to equalsNode.
5195 const T *TypedNode = cast<T>(Node);
5196 const auto *Dec = Nodes.getNodeAs<FieldDecl>("decl");
5197 return selectFirst<T>(
5198 "", match(fieldDecl(hasParent(decl(has(fieldDecl(
5199 hasType(type(equalsNode(TypedNode)).bind(""))))))),
5200 *Dec, Context)) != nullptr;
5201 }
Manuel Klimekbee08572013-02-07 12:42:10 +00005202};
5203
5204TEST(IsEqualTo, MatchesNodesByIdentity) {
5205 EXPECT_TRUE(matchAndVerifyResultTrue(
5206 "class X { class Y {}; };", recordDecl(hasName("::X::Y")).bind(""),
Manuel Klimeka2c2a4f2014-05-27 12:31:10 +00005207 new VerifyAncestorHasChildIsEqual<CXXRecordDecl>()));
5208 EXPECT_TRUE(matchAndVerifyResultTrue(
5209 "void f() { if (true) if(true) {} }", ifStmt().bind(""),
5210 new VerifyAncestorHasChildIsEqual<IfStmt>()));
Angel Garcia Gomez4647ed72015-10-30 09:35:51 +00005211 EXPECT_TRUE(matchAndVerifyResultTrue(
5212 "class X { class Y {} y; };",
5213 fieldDecl(hasName("y"), hasType(type().bind(""))).bind("decl"),
5214 new VerifyAncestorHasChildIsEqual<Type>()));
Manuel Klimekbee08572013-02-07 12:42:10 +00005215}
5216
Samuel Benzaquen43dcf212014-10-22 20:31:05 +00005217TEST(MatchFinder, CheckProfiling) {
5218 MatchFinder::MatchFinderOptions Options;
5219 llvm::StringMap<llvm::TimeRecord> Records;
5220 Options.CheckProfiling.emplace(Records);
5221 MatchFinder Finder(std::move(Options));
5222
5223 struct NamedCallback : public MatchFinder::MatchCallback {
5224 void run(const MatchFinder::MatchResult &Result) override {}
5225 StringRef getID() const override { return "MyID"; }
5226 } Callback;
5227 Finder.addMatcher(decl(), &Callback);
5228 std::unique_ptr<FrontendActionFactory> Factory(
5229 newFrontendActionFactory(&Finder));
5230 ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), "int x;"));
5231
5232 EXPECT_EQ(1u, Records.size());
5233 EXPECT_EQ("MyID", Records.begin()->getKey());
5234}
5235
Manuel Klimekbd0e2b72012-11-02 01:31:03 +00005236class VerifyStartOfTranslationUnit : public MatchFinder::MatchCallback {
5237public:
5238 VerifyStartOfTranslationUnit() : Called(false) {}
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005239 void run(const MatchFinder::MatchResult &Result) override {
Manuel Klimekbd0e2b72012-11-02 01:31:03 +00005240 EXPECT_TRUE(Called);
5241 }
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005242 void onStartOfTranslationUnit() override { Called = true; }
Manuel Klimekbd0e2b72012-11-02 01:31:03 +00005243 bool Called;
5244};
5245
5246TEST(MatchFinder, InterceptsStartOfTranslationUnit) {
5247 MatchFinder Finder;
5248 VerifyStartOfTranslationUnit VerifyCallback;
5249 Finder.addMatcher(decl(), &VerifyCallback);
Ahmed Charlesb8984322014-03-07 20:03:18 +00005250 std::unique_ptr<FrontendActionFactory> Factory(
5251 newFrontendActionFactory(&Finder));
Manuel Klimekbd0e2b72012-11-02 01:31:03 +00005252 ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), "int x;"));
5253 EXPECT_TRUE(VerifyCallback.Called);
Peter Collingbournea2334162013-11-07 22:30:36 +00005254
5255 VerifyCallback.Called = false;
Ahmed Charlesb8984322014-03-07 20:03:18 +00005256 std::unique_ptr<ASTUnit> AST(tooling::buildASTFromCode("int x;"));
Peter Collingbournea2334162013-11-07 22:30:36 +00005257 ASSERT_TRUE(AST.get());
5258 Finder.matchAST(AST->getASTContext());
5259 EXPECT_TRUE(VerifyCallback.Called);
Manuel Klimekbd0e2b72012-11-02 01:31:03 +00005260}
5261
Peter Collingbourne6a55bb22013-05-28 19:21:51 +00005262class VerifyEndOfTranslationUnit : public MatchFinder::MatchCallback {
5263public:
5264 VerifyEndOfTranslationUnit() : Called(false) {}
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005265 void run(const MatchFinder::MatchResult &Result) override {
Peter Collingbourne6a55bb22013-05-28 19:21:51 +00005266 EXPECT_FALSE(Called);
5267 }
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005268 void onEndOfTranslationUnit() override { Called = true; }
Peter Collingbourne6a55bb22013-05-28 19:21:51 +00005269 bool Called;
5270};
5271
5272TEST(MatchFinder, InterceptsEndOfTranslationUnit) {
5273 MatchFinder Finder;
5274 VerifyEndOfTranslationUnit VerifyCallback;
5275 Finder.addMatcher(decl(), &VerifyCallback);
Ahmed Charlesb8984322014-03-07 20:03:18 +00005276 std::unique_ptr<FrontendActionFactory> Factory(
5277 newFrontendActionFactory(&Finder));
Peter Collingbourne6a55bb22013-05-28 19:21:51 +00005278 ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), "int x;"));
5279 EXPECT_TRUE(VerifyCallback.Called);
Peter Collingbournea2334162013-11-07 22:30:36 +00005280
5281 VerifyCallback.Called = false;
Ahmed Charlesb8984322014-03-07 20:03:18 +00005282 std::unique_ptr<ASTUnit> AST(tooling::buildASTFromCode("int x;"));
Peter Collingbournea2334162013-11-07 22:30:36 +00005283 ASSERT_TRUE(AST.get());
5284 Finder.matchAST(AST->getASTContext());
5285 EXPECT_TRUE(VerifyCallback.Called);
Peter Collingbourne6a55bb22013-05-28 19:21:51 +00005286}
5287
Daniel Jasper739ae642016-02-03 14:29:55 +00005288TEST(Matcher, matchOverEntireASTContext) {
5289 std::unique_ptr<ASTUnit> AST =
5290 clang::tooling::buildASTFromCode("struct { int *foo; };");
5291 ASSERT_TRUE(AST.get());
5292 auto PT = selectFirst<PointerType>(
5293 "x", match(pointerType().bind("x"), AST->getASTContext()));
5294 EXPECT_NE(nullptr, PT);
5295}
5296
Manuel Klimekbbb75852013-06-20 14:06:32 +00005297TEST(EqualsBoundNodeMatcher, QualType) {
5298 EXPECT_TRUE(matches(
5299 "int i = 1;", varDecl(hasType(qualType().bind("type")),
5300 hasInitializer(ignoringParenImpCasts(
5301 hasType(qualType(equalsBoundNode("type"))))))));
5302 EXPECT_TRUE(notMatches("int i = 1.f;",
5303 varDecl(hasType(qualType().bind("type")),
5304 hasInitializer(ignoringParenImpCasts(hasType(
5305 qualType(equalsBoundNode("type"))))))));
5306}
5307
5308TEST(EqualsBoundNodeMatcher, NonMatchingTypes) {
5309 EXPECT_TRUE(notMatches(
5310 "int i = 1;", varDecl(namedDecl(hasName("i")).bind("name"),
5311 hasInitializer(ignoringParenImpCasts(
5312 hasType(qualType(equalsBoundNode("type"))))))));
5313}
5314
5315TEST(EqualsBoundNodeMatcher, Stmt) {
5316 EXPECT_TRUE(
5317 matches("void f() { if(true) {} }",
5318 stmt(allOf(ifStmt().bind("if"),
5319 hasParent(stmt(has(stmt(equalsBoundNode("if")))))))));
5320
5321 EXPECT_TRUE(notMatches(
5322 "void f() { if(true) { if (true) {} } }",
5323 stmt(allOf(ifStmt().bind("if"), has(stmt(equalsBoundNode("if")))))));
5324}
5325
5326TEST(EqualsBoundNodeMatcher, Decl) {
5327 EXPECT_TRUE(matches(
5328 "class X { class Y {}; };",
5329 decl(allOf(recordDecl(hasName("::X::Y")).bind("record"),
5330 hasParent(decl(has(decl(equalsBoundNode("record")))))))));
5331
5332 EXPECT_TRUE(notMatches("class X { class Y {}; };",
5333 decl(allOf(recordDecl(hasName("::X")).bind("record"),
5334 has(decl(equalsBoundNode("record")))))));
5335}
5336
5337TEST(EqualsBoundNodeMatcher, Type) {
5338 EXPECT_TRUE(matches(
5339 "class X { int a; int b; };",
5340 recordDecl(
5341 has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
5342 has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
5343
5344 EXPECT_TRUE(notMatches(
5345 "class X { int a; double b; };",
5346 recordDecl(
5347 has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
5348 has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
5349}
5350
5351TEST(EqualsBoundNodeMatcher, UsingForEachDescendant) {
Manuel Klimekbbb75852013-06-20 14:06:32 +00005352 EXPECT_TRUE(matchAndVerifyResultTrue(
5353 "int f() {"
5354 " if (1) {"
5355 " int i = 9;"
5356 " }"
5357 " int j = 10;"
5358 " {"
5359 " float k = 9.0;"
5360 " }"
5361 " return 0;"
5362 "}",
5363 // Look for variable declarations within functions whose type is the same
5364 // as the function return type.
5365 functionDecl(returns(qualType().bind("type")),
5366 forEachDescendant(varDecl(hasType(
5367 qualType(equalsBoundNode("type")))).bind("decl"))),
5368 // Only i and j should match, not k.
5369 new VerifyIdIsBoundTo<VarDecl>("decl", 2)));
5370}
5371
5372TEST(EqualsBoundNodeMatcher, FiltersMatchedCombinations) {
5373 EXPECT_TRUE(matchAndVerifyResultTrue(
5374 "void f() {"
5375 " int x;"
5376 " double d;"
5377 " x = d + x - d + x;"
5378 "}",
5379 functionDecl(
5380 hasName("f"), forEachDescendant(varDecl().bind("d")),
5381 forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d")))))),
5382 new VerifyIdIsBoundTo<VarDecl>("d", 5)));
5383}
5384
Manuel Klimekce68f772014-03-25 14:39:26 +00005385TEST(EqualsBoundNodeMatcher, UnlessDescendantsOfAncestorsMatch) {
5386 EXPECT_TRUE(matchAndVerifyResultTrue(
5387 "struct StringRef { int size() const; const char* data() const; };"
5388 "void f(StringRef v) {"
5389 " v.data();"
5390 "}",
Aaron Ballman512fb642015-09-17 13:30:52 +00005391 cxxMemberCallExpr(
5392 callee(cxxMethodDecl(hasName("data"))),
5393 on(declRefExpr(to(
5394 varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),
5395 unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(
5396 callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
Manuel Klimekce68f772014-03-25 14:39:26 +00005397 on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
5398 .bind("data"),
5399 new VerifyIdIsBoundTo<Expr>("data", 1)));
5400
5401 EXPECT_FALSE(matches(
5402 "struct StringRef { int size() const; const char* data() const; };"
5403 "void f(StringRef v) {"
5404 " v.data();"
5405 " v.size();"
5406 "}",
Aaron Ballman512fb642015-09-17 13:30:52 +00005407 cxxMemberCallExpr(
5408 callee(cxxMethodDecl(hasName("data"))),
5409 on(declRefExpr(to(
5410 varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),
5411 unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(
5412 callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
Manuel Klimekce68f772014-03-25 14:39:26 +00005413 on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
5414 .bind("data")));
5415}
5416
Aaron Ballman66eb58a2016-04-14 16:05:45 +00005417TEST(TypedefDeclMatcher, Match) {
Manuel Klimekd3aa1f42014-11-25 17:01:06 +00005418 EXPECT_TRUE(matches("typedef int typedefDeclTest;",
5419 typedefDecl(hasName("typedefDeclTest"))));
Aaron Ballman66eb58a2016-04-14 16:05:45 +00005420 EXPECT_TRUE(notMatches("using typedefDeclTest2 = int;",
5421 typedefDecl(hasName("typedefDeclTest2"))));
5422}
5423
5424TEST(TypeAliasDeclMatcher, Match) {
5425 EXPECT_TRUE(matches("using typeAliasTest2 = int;",
5426 typeAliasDecl(hasName("typeAliasTest2"))));
5427 EXPECT_TRUE(notMatches("typedef int typeAliasTest;",
5428 typeAliasDecl(hasName("typeAliasTest"))));
5429}
5430
5431TEST(TypedefNameDeclMatcher, Match) {
5432 EXPECT_TRUE(matches("typedef int typedefNameDeclTest1;",
5433 typedefNameDecl(hasName("typedefNameDeclTest1"))));
5434 EXPECT_TRUE(matches("using typedefNameDeclTest2 = int;",
5435 typedefNameDecl(hasName("typedefNameDeclTest2"))));
Manuel Klimekd3aa1f42014-11-25 17:01:06 +00005436}
5437
Aaron Ballman11825f22015-08-18 19:55:20 +00005438TEST(IsInlineMatcher, IsInline) {
5439 EXPECT_TRUE(matches("void g(); inline void f();",
5440 functionDecl(isInline(), hasName("f"))));
5441 EXPECT_TRUE(matches("namespace n { inline namespace m {} }",
5442 namespaceDecl(isInline(), hasName("m"))));
5443}
5444
Aaron Ballman7e7b7b22016-02-01 14:11:47 +00005445// FIXME: Figure out how to specify paths so the following tests pass on
5446// Windows.
Manuel Klimekd3aa1f42014-11-25 17:01:06 +00005447#ifndef LLVM_ON_WIN32
5448
5449TEST(Matcher, IsExpansionInMainFileMatcher) {
5450 EXPECT_TRUE(matches("class X {};",
5451 recordDecl(hasName("X"), isExpansionInMainFile())));
5452 EXPECT_TRUE(notMatches("", recordDecl(isExpansionInMainFile())));
5453 FileContentMappings M;
5454 M.push_back(std::make_pair("/other", "class X {};"));
5455 EXPECT_TRUE(matchesConditionally("#include <other>\n",
5456 recordDecl(isExpansionInMainFile()), false,
5457 "-isystem/", M));
5458}
5459
5460TEST(Matcher, IsExpansionInSystemHeader) {
5461 FileContentMappings M;
5462 M.push_back(std::make_pair("/other", "class X {};"));
5463 EXPECT_TRUE(matchesConditionally(
5464 "#include \"other\"\n", recordDecl(isExpansionInSystemHeader()), true,
5465 "-isystem/", M));
5466 EXPECT_TRUE(matchesConditionally("#include \"other\"\n",
5467 recordDecl(isExpansionInSystemHeader()),
5468 false, "-I/", M));
5469 EXPECT_TRUE(notMatches("class X {};",
5470 recordDecl(isExpansionInSystemHeader())));
5471 EXPECT_TRUE(notMatches("", recordDecl(isExpansionInSystemHeader())));
5472}
5473
5474TEST(Matcher, IsExpansionInFileMatching) {
5475 FileContentMappings M;
5476 M.push_back(std::make_pair("/foo", "class A {};"));
5477 M.push_back(std::make_pair("/bar", "class B {};"));
5478 EXPECT_TRUE(matchesConditionally(
5479 "#include <foo>\n"
5480 "#include <bar>\n"
5481 "class X {};",
5482 recordDecl(isExpansionInFileMatching("b.*"), hasName("B")), true,
5483 "-isystem/", M));
5484 EXPECT_TRUE(matchesConditionally(
5485 "#include <foo>\n"
5486 "#include <bar>\n"
5487 "class X {};",
5488 recordDecl(isExpansionInFileMatching("f.*"), hasName("X")), false,
5489 "-isystem/", M));
5490}
5491
5492#endif // LLVM_ON_WIN32
5493
Manuel Klimekbfa43572015-03-12 15:48:15 +00005494
5495TEST(ObjCMessageExprMatcher, SimpleExprs) {
5496 // don't find ObjCMessageExpr where none are present
5497 EXPECT_TRUE(notMatchesObjC("", objcMessageExpr(anything())));
5498
5499 std::string Objc1String =
5500 "@interface Str "
5501 " - (Str *)uppercaseString:(Str *)str;"
5502 "@end "
5503 "@interface foo "
5504 "- (void)meth:(Str *)text;"
5505 "@end "
5506 " "
5507 "@implementation foo "
5508 "- (void) meth:(Str *)text { "
5509 " [self contents];"
5510 " Str *up = [text uppercaseString];"
5511 "} "
5512 "@end ";
5513 EXPECT_TRUE(matchesObjC(
5514 Objc1String,
5515 objcMessageExpr(anything())));
5516 EXPECT_TRUE(matchesObjC(
5517 Objc1String,
5518 objcMessageExpr(hasSelector("contents"))));
5519 EXPECT_TRUE(matchesObjC(
5520 Objc1String,
5521 objcMessageExpr(matchesSelector("cont*"))));
5522 EXPECT_FALSE(matchesObjC(
5523 Objc1String,
5524 objcMessageExpr(matchesSelector("?cont*"))));
5525 EXPECT_TRUE(notMatchesObjC(
5526 Objc1String,
5527 objcMessageExpr(hasSelector("contents"), hasNullSelector())));
5528 EXPECT_TRUE(matchesObjC(
5529 Objc1String,
5530 objcMessageExpr(hasSelector("contents"), hasUnarySelector())));
5531 EXPECT_TRUE(matchesObjC(
5532 Objc1String,
Manuel Klimeke67a9d62015-09-08 10:11:26 +00005533 objcMessageExpr(hasSelector("contents"), numSelectorArgs(0))));
5534 EXPECT_TRUE(matchesObjC(
5535 Objc1String,
Manuel Klimekbfa43572015-03-12 15:48:15 +00005536 objcMessageExpr(matchesSelector("uppercase*"),
5537 argumentCountIs(0)
5538 )));
Manuel Klimekbfa43572015-03-12 15:48:15 +00005539}
5540
Aaron Ballman232e63d2016-02-16 21:02:23 +00005541TEST(NullPointerConstants, Basic) {
5542 EXPECT_TRUE(matches("#define NULL ((void *)0)\n"
5543 "void *v1 = NULL;", expr(nullPointerConstant())));
5544 EXPECT_TRUE(matches("void *v2 = nullptr;", expr(nullPointerConstant())));
5545 EXPECT_TRUE(matches("void *v3 = __null;", expr(nullPointerConstant())));
5546 EXPECT_TRUE(matches("char *cp = (char *)0;", expr(nullPointerConstant())));
5547 EXPECT_TRUE(matches("int *ip = 0;", expr(nullPointerConstant())));
Aaron Ballmancc928c82016-02-16 21:06:10 +00005548 EXPECT_TRUE(notMatches("int i = 0;", expr(nullPointerConstant())));
Aaron Ballman232e63d2016-02-16 21:02:23 +00005549}
5550
Alexander Kornienko976921d2016-03-22 11:03:03 +00005551TEST(StatementMatcher, HasReturnValue) {
5552 StatementMatcher RetVal = returnStmt(hasReturnValue(binaryOperator()));
5553 EXPECT_TRUE(matches("int F() { int a, b; return a + b; }", RetVal));
5554 EXPECT_FALSE(matches("int F() { int a; return a; }", RetVal));
Matthias Gehrec27d8d82016-04-12 05:43:18 +00005555 EXPECT_FALSE(matches("void F() { return; }", RetVal));
Alexander Kornienko976921d2016-03-22 11:03:03 +00005556}
5557
Manuel Klimek04616e42012-07-06 05:48:52 +00005558} // end namespace ast_matchers
5559} // end namespace clang