blob: 7bb9550cd9198eee1cebaba28b58641357255167 [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
Samuel Benzaquend6b44aa2016-04-19 15:52:56 +0000711TEST(DeclarationMatcher, HasAncestorMemoization) {
712 // This triggers an hasAncestor with a TemplateArgument in the bound nodes.
713 // That node can't be memoized so we have to check for it before trying to put
714 // it on the cache.
715 DeclarationMatcher CannotMemoize = classTemplateSpecializationDecl(
716 hasAnyTemplateArgument(templateArgument().bind("targ")),
717 forEach(fieldDecl(hasAncestor(forStmt()))));
718
719 EXPECT_TRUE(notMatches("template <typename T> struct S;"
720 "template <> struct S<int>{ int i; int j; };",
721 CannotMemoize));
722}
723
Manuel Klimek3fe8a382014-08-25 11:23:50 +0000724TEST(DeclarationMatcher, HasAttr) {
725 EXPECT_TRUE(matches("struct __attribute__((warn_unused)) X {};",
726 decl(hasAttr(clang::attr::WarnUnused))));
727 EXPECT_FALSE(matches("struct X {};",
728 decl(hasAttr(clang::attr::WarnUnused))));
729}
730
Manuel Klimekd52a3b82014-08-05 09:45:53 +0000731TEST(DeclarationMatcher, MatchCudaDecl) {
732 EXPECT_TRUE(matchesWithCuda("__global__ void f() { }"
733 "void g() { f<<<1, 2>>>(); }",
Aaron Ballman512fb642015-09-17 13:30:52 +0000734 cudaKernelCallExpr()));
Manuel Klimekd52a3b82014-08-05 09:45:53 +0000735 EXPECT_TRUE(matchesWithCuda("__attribute__((device)) void f() {}",
Manuel Klimek3fe8a382014-08-25 11:23:50 +0000736 hasAttr(clang::attr::CUDADevice)));
Manuel Klimekd52a3b82014-08-05 09:45:53 +0000737 EXPECT_TRUE(notMatchesWithCuda("void f() {}",
Aaron Ballman512fb642015-09-17 13:30:52 +0000738 cudaKernelCallExpr()));
Manuel Klimekd52a3b82014-08-05 09:45:53 +0000739 EXPECT_FALSE(notMatchesWithCuda("__attribute__((global)) void f() {}",
Manuel Klimek3fe8a382014-08-25 11:23:50 +0000740 hasAttr(clang::attr::CUDAGlobal)));
Manuel Klimekd52a3b82014-08-05 09:45:53 +0000741}
742
Daniel Jasperd29d5fa2012-10-29 10:14:44 +0000743// Implements a run method that returns whether BoundNodes contains a
744// Decl bound to Id that can be dynamically cast to T.
745// Optionally checks that the check succeeded a specific number of times.
746template <typename T>
747class VerifyIdIsBoundTo : public BoundNodesCallback {
748public:
749 // Create an object that checks that a node of type \c T was bound to \c Id.
750 // Does not check for a certain number of matches.
751 explicit VerifyIdIsBoundTo(llvm::StringRef Id)
752 : Id(Id), ExpectedCount(-1), Count(0) {}
753
754 // Create an object that checks that a node of type \c T was bound to \c Id.
755 // Checks that there were exactly \c ExpectedCount matches.
756 VerifyIdIsBoundTo(llvm::StringRef Id, int ExpectedCount)
757 : Id(Id), ExpectedCount(ExpectedCount), Count(0) {}
758
759 // Create an object that checks that a node of type \c T was bound to \c Id.
760 // Checks that there was exactly one match with the name \c ExpectedName.
761 // Note that \c T must be a NamedDecl for this to work.
Manuel Klimekb64d6b72013-03-14 16:33:21 +0000762 VerifyIdIsBoundTo(llvm::StringRef Id, llvm::StringRef ExpectedName,
763 int ExpectedCount = 1)
764 : Id(Id), ExpectedCount(ExpectedCount), Count(0),
765 ExpectedName(ExpectedName) {}
Daniel Jasperd29d5fa2012-10-29 10:14:44 +0000766
Craig Toppera798a9d2014-03-02 09:32:10 +0000767 void onEndOfTranslationUnit() override {
Daniel Jasperd29d5fa2012-10-29 10:14:44 +0000768 if (ExpectedCount != -1)
769 EXPECT_EQ(ExpectedCount, Count);
770 if (!ExpectedName.empty())
771 EXPECT_EQ(ExpectedName, Name);
Peter Collingbourne2b9471302013-11-07 22:30:32 +0000772 Count = 0;
773 Name.clear();
774 }
775
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000776 ~VerifyIdIsBoundTo() override {
Peter Collingbourne2b9471302013-11-07 22:30:32 +0000777 EXPECT_EQ(0, Count);
778 EXPECT_EQ("", Name);
Daniel Jasperd29d5fa2012-10-29 10:14:44 +0000779 }
780
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000781 bool run(const BoundNodes *Nodes) override {
Peter Collingbourne093a7292013-11-06 00:27:07 +0000782 const BoundNodes::IDToNodeMap &M = Nodes->getMap();
Daniel Jasperd29d5fa2012-10-29 10:14:44 +0000783 if (Nodes->getNodeAs<T>(Id)) {
784 ++Count;
785 if (const NamedDecl *Named = Nodes->getNodeAs<NamedDecl>(Id)) {
786 Name = Named->getNameAsString();
787 } else if (const NestedNameSpecifier *NNS =
788 Nodes->getNodeAs<NestedNameSpecifier>(Id)) {
789 llvm::raw_string_ostream OS(Name);
790 NNS->print(OS, PrintingPolicy(LangOptions()));
791 }
Peter Collingbourne093a7292013-11-06 00:27:07 +0000792 BoundNodes::IDToNodeMap::const_iterator I = M.find(Id);
793 EXPECT_NE(M.end(), I);
794 if (I != M.end())
795 EXPECT_EQ(Nodes->getNodeAs<T>(Id), I->second.get<T>());
Daniel Jasperd29d5fa2012-10-29 10:14:44 +0000796 return true;
797 }
Craig Topper416fa342014-06-08 08:38:12 +0000798 EXPECT_TRUE(M.count(Id) == 0 ||
799 M.find(Id)->second.template get<T>() == nullptr);
Daniel Jasperd29d5fa2012-10-29 10:14:44 +0000800 return false;
801 }
802
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000803 bool run(const BoundNodes *Nodes, ASTContext *Context) override {
Daniel Jaspere9aa6872012-10-29 10:48:25 +0000804 return run(Nodes);
805 }
806
Daniel Jasperd29d5fa2012-10-29 10:14:44 +0000807private:
808 const std::string Id;
809 const int ExpectedCount;
810 int Count;
811 const std::string ExpectedName;
812 std::string Name;
813};
814
815TEST(HasDescendant, MatchesDescendantTypes) {
816 EXPECT_TRUE(matches("void f() { int i = 3; }",
817 decl(hasDescendant(loc(builtinType())))));
818 EXPECT_TRUE(matches("void f() { int i = 3; }",
819 stmt(hasDescendant(builtinType()))));
820
821 EXPECT_TRUE(matches("void f() { int i = 3; }",
822 stmt(hasDescendant(loc(builtinType())))));
823 EXPECT_TRUE(matches("void f() { int i = 3; }",
824 stmt(hasDescendant(qualType(builtinType())))));
825
826 EXPECT_TRUE(notMatches("void f() { float f = 2.0f; }",
827 stmt(hasDescendant(isInteger()))));
828
829 EXPECT_TRUE(matchAndVerifyResultTrue(
830 "void f() { int a; float c; int d; int e; }",
831 functionDecl(forEachDescendant(
832 varDecl(hasDescendant(isInteger())).bind("x"))),
833 new VerifyIdIsBoundTo<Decl>("x", 3)));
834}
835
836TEST(HasDescendant, MatchesDescendantsOfTypes) {
837 EXPECT_TRUE(matches("void f() { int*** i; }",
838 qualType(hasDescendant(builtinType()))));
839 EXPECT_TRUE(matches("void f() { int*** i; }",
840 qualType(hasDescendant(
841 pointerType(pointee(builtinType()))))));
842 EXPECT_TRUE(matches("void f() { int*** i; }",
David Blaikieb61d0872013-02-18 19:04:16 +0000843 typeLoc(hasDescendant(loc(builtinType())))));
Daniel Jasperd29d5fa2012-10-29 10:14:44 +0000844
845 EXPECT_TRUE(matchAndVerifyResultTrue(
846 "void f() { int*** i; }",
847 qualType(asString("int ***"), forEachDescendant(pointerType().bind("x"))),
848 new VerifyIdIsBoundTo<Type>("x", 2)));
849}
850
851TEST(Has, MatchesChildrenOfTypes) {
852 EXPECT_TRUE(matches("int i;",
853 varDecl(hasName("i"), has(isInteger()))));
854 EXPECT_TRUE(notMatches("int** i;",
855 varDecl(hasName("i"), has(isInteger()))));
856 EXPECT_TRUE(matchAndVerifyResultTrue(
857 "int (*f)(float, int);",
858 qualType(functionType(), forEach(qualType(isInteger()).bind("x"))),
859 new VerifyIdIsBoundTo<QualType>("x", 2)));
860}
861
862TEST(Has, MatchesChildTypes) {
863 EXPECT_TRUE(matches(
864 "int* i;",
865 varDecl(hasName("i"), hasType(qualType(has(builtinType()))))));
866 EXPECT_TRUE(notMatches(
867 "int* i;",
868 varDecl(hasName("i"), hasType(qualType(has(pointerType()))))));
869}
870
Samuel Benzaquenc640ef52014-10-28 13:33:58 +0000871TEST(ValueDecl, Matches) {
872 EXPECT_TRUE(matches("enum EnumType { EnumValue };",
873 valueDecl(hasType(asString("enum EnumType")))));
874 EXPECT_TRUE(matches("void FunctionDecl();",
875 valueDecl(hasType(asString("void (void)")))));
876}
877
Daniel Jasper1dad1832012-07-10 20:20:19 +0000878TEST(Enum, DoesNotMatchClasses) {
879 EXPECT_TRUE(notMatches("class X {};", enumDecl(hasName("X"))));
880}
881
882TEST(Enum, MatchesEnums) {
883 EXPECT_TRUE(matches("enum X {};", enumDecl(hasName("X"))));
884}
885
886TEST(EnumConstant, Matches) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000887 DeclarationMatcher Matcher = enumConstantDecl(hasName("A"));
Daniel Jasper1dad1832012-07-10 20:20:19 +0000888 EXPECT_TRUE(matches("enum X{ A };", Matcher));
889 EXPECT_TRUE(notMatches("enum X{ B };", Matcher));
890 EXPECT_TRUE(notMatches("enum X {};", Matcher));
891}
892
Manuel Klimek04616e42012-07-06 05:48:52 +0000893TEST(StatementMatcher, Has) {
894 StatementMatcher HasVariableI =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000895 expr(hasType(pointsTo(recordDecl(hasName("X")))),
896 has(declRefExpr(to(varDecl(hasName("i"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000897
898 EXPECT_TRUE(matches(
899 "class X; X *x(int); void c() { int i; x(i); }", HasVariableI));
900 EXPECT_TRUE(notMatches(
901 "class X; X *x(int); void c() { int i; x(42); }", HasVariableI));
902}
903
904TEST(StatementMatcher, HasDescendant) {
905 StatementMatcher HasDescendantVariableI =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000906 expr(hasType(pointsTo(recordDecl(hasName("X")))),
907 hasDescendant(declRefExpr(to(varDecl(hasName("i"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000908
909 EXPECT_TRUE(matches(
910 "class X; X *x(bool); bool b(int); void c() { int i; x(b(i)); }",
911 HasDescendantVariableI));
912 EXPECT_TRUE(notMatches(
913 "class X; X *x(bool); bool b(int); void c() { int i; x(b(42)); }",
914 HasDescendantVariableI));
915}
916
917TEST(TypeMatcher, MatchesClassType) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000918 TypeMatcher TypeA = hasDeclaration(recordDecl(hasName("A")));
Manuel Klimek04616e42012-07-06 05:48:52 +0000919
920 EXPECT_TRUE(matches("class A { public: A *a; };", TypeA));
921 EXPECT_TRUE(notMatches("class A {};", TypeA));
922
Aaron Ballman512fb642015-09-17 13:30:52 +0000923 TypeMatcher TypeDerivedFromA =
924 hasDeclaration(cxxRecordDecl(isDerivedFrom("A")));
Manuel Klimek04616e42012-07-06 05:48:52 +0000925
926 EXPECT_TRUE(matches("class A {}; class B : public A { public: B *b; };",
927 TypeDerivedFromA));
928 EXPECT_TRUE(notMatches("class A {};", TypeA));
929
930 TypeMatcher TypeAHasClassB = hasDeclaration(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000931 recordDecl(hasName("A"), has(recordDecl(hasName("B")))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000932
933 EXPECT_TRUE(
934 matches("class A { public: A *a; class B {}; };", TypeAHasClassB));
Aaron Ballmanc129c692015-09-04 18:34:48 +0000935
936 EXPECT_TRUE(matchesC("struct S {}; void f(void) { struct S s; }",
937 varDecl(hasType(namedDecl(hasName("S"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000938}
939
Aaron Ballmanb85be662015-09-11 11:51:24 +0000940TEST(TypeMatcher, MatchesDeclTypes) {
941 // TypedefType -> TypedefNameDecl
942 EXPECT_TRUE(matches("typedef int I; void f(I i);",
943 parmVarDecl(hasType(namedDecl(hasName("I"))))));
944 // ObjCObjectPointerType
945 EXPECT_TRUE(matchesObjC("@interface Foo @end void f(Foo *f);",
946 parmVarDecl(hasType(objcObjectPointerType()))));
947 // ObjCObjectPointerType -> ObjCInterfaceType -> ObjCInterfaceDecl
948 EXPECT_TRUE(matchesObjC(
949 "@interface Foo @end void f(Foo *f);",
950 parmVarDecl(hasType(pointsTo(objcInterfaceDecl(hasName("Foo")))))));
951 // TemplateTypeParmType
952 EXPECT_TRUE(matches("template <typename T> void f(T t);",
953 parmVarDecl(hasType(templateTypeParmType()))));
954 // TemplateTypeParmType -> TemplateTypeParmDecl
955 EXPECT_TRUE(matches("template <typename T> void f(T t);",
956 parmVarDecl(hasType(namedDecl(hasName("T"))))));
957 // InjectedClassNameType
958 EXPECT_TRUE(matches("template <typename T> struct S {"
959 " void f(S s);"
960 "};",
961 parmVarDecl(hasType(injectedClassNameType()))));
962 EXPECT_TRUE(notMatches("template <typename T> struct S {"
963 " void g(S<T> s);"
964 "};",
965 parmVarDecl(hasType(injectedClassNameType()))));
966 // InjectedClassNameType -> CXXRecordDecl
967 EXPECT_TRUE(matches("template <typename T> struct S {"
968 " void f(S s);"
969 "};",
970 parmVarDecl(hasType(namedDecl(hasName("S"))))));
971
972 static const char Using[] = "template <typename T>"
973 "struct Base {"
974 " typedef T Foo;"
975 "};"
976 ""
977 "template <typename T>"
978 "struct S : private Base<T> {"
979 " using typename Base<T>::Foo;"
980 " void f(Foo);"
981 "};";
982 // UnresolvedUsingTypenameDecl
983 EXPECT_TRUE(matches(Using, unresolvedUsingTypenameDecl(hasName("Foo"))));
984 // UnresolvedUsingTypenameType -> UnresolvedUsingTypenameDecl
985 EXPECT_TRUE(matches(Using, parmVarDecl(hasType(namedDecl(hasName("Foo"))))));
986}
987
Manuel Klimek04616e42012-07-06 05:48:52 +0000988TEST(Matcher, BindMatchedNodes) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000989 DeclarationMatcher ClassX = has(recordDecl(hasName("::X")).bind("x"));
Manuel Klimek04616e42012-07-06 05:48:52 +0000990
991 EXPECT_TRUE(matchAndVerifyResultTrue("class X {};",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +0000992 ClassX, new VerifyIdIsBoundTo<CXXRecordDecl>("x")));
Manuel Klimek04616e42012-07-06 05:48:52 +0000993
994 EXPECT_TRUE(matchAndVerifyResultFalse("class X {};",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +0000995 ClassX, new VerifyIdIsBoundTo<CXXRecordDecl>("other-id")));
Manuel Klimek04616e42012-07-06 05:48:52 +0000996
997 TypeMatcher TypeAHasClassB = hasDeclaration(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +0000998 recordDecl(hasName("A"), has(recordDecl(hasName("B")).bind("b"))));
Manuel Klimek04616e42012-07-06 05:48:52 +0000999
1000 EXPECT_TRUE(matchAndVerifyResultTrue("class A { public: A *a; class B {}; };",
1001 TypeAHasClassB,
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00001002 new VerifyIdIsBoundTo<Decl>("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +00001003
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001004 StatementMatcher MethodX =
Aaron Ballman512fb642015-09-17 13:30:52 +00001005 callExpr(callee(cxxMethodDecl(hasName("x")))).bind("x");
Manuel Klimek04616e42012-07-06 05:48:52 +00001006
1007 EXPECT_TRUE(matchAndVerifyResultTrue("class A { void x() { x(); } };",
1008 MethodX,
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00001009 new VerifyIdIsBoundTo<CXXMemberCallExpr>("x")));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001010}
1011
1012TEST(Matcher, BindTheSameNameInAlternatives) {
1013 StatementMatcher matcher = anyOf(
1014 binaryOperator(hasOperatorName("+"),
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001015 hasLHS(expr().bind("x")),
Daniel Jasper1dad1832012-07-10 20:20:19 +00001016 hasRHS(integerLiteral(equals(0)))),
1017 binaryOperator(hasOperatorName("+"),
1018 hasLHS(integerLiteral(equals(0))),
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001019 hasRHS(expr().bind("x"))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001020
1021 EXPECT_TRUE(matchAndVerifyResultTrue(
1022 // The first branch of the matcher binds x to 0 but then fails.
1023 // The second branch binds x to f() and succeeds.
1024 "int f() { return 0 + f(); }",
1025 matcher,
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00001026 new VerifyIdIsBoundTo<CallExpr>("x")));
Manuel Klimek04616e42012-07-06 05:48:52 +00001027}
1028
Manuel Klimekfdf98762012-08-30 19:41:06 +00001029TEST(Matcher, BindsIDForMemoizedResults) {
1030 // Using the same matcher in two match expressions will make memoization
1031 // kick in.
1032 DeclarationMatcher ClassX = recordDecl(hasName("X")).bind("x");
1033 EXPECT_TRUE(matchAndVerifyResultTrue(
1034 "class A { class B { class X {}; }; };",
1035 DeclarationMatcher(anyOf(
1036 recordDecl(hasName("A"), hasDescendant(ClassX)),
1037 recordDecl(hasName("B"), hasDescendant(ClassX)))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00001038 new VerifyIdIsBoundTo<Decl>("x", 2)));
Manuel Klimekfdf98762012-08-30 19:41:06 +00001039}
1040
Daniel Jasper856194d02012-12-03 15:43:25 +00001041TEST(HasDeclaration, HasDeclarationOfEnumType) {
1042 EXPECT_TRUE(matches("enum X {}; void y(X *x) { x; }",
1043 expr(hasType(pointsTo(
1044 qualType(hasDeclaration(enumDecl(hasName("X")))))))));
1045}
1046
Edwin Vaneed936452013-02-25 14:32:42 +00001047TEST(HasDeclaration, HasGetDeclTraitTest) {
1048 EXPECT_TRUE(internal::has_getDecl<TypedefType>::value);
1049 EXPECT_TRUE(internal::has_getDecl<RecordType>::value);
1050 EXPECT_FALSE(internal::has_getDecl<TemplateSpecializationType>::value);
1051}
1052
Edwin Vane2c197e02013-02-19 17:14:34 +00001053TEST(HasDeclaration, HasDeclarationOfTypeWithDecl) {
1054 EXPECT_TRUE(matches("typedef int X; X a;",
1055 varDecl(hasName("a"),
1056 hasType(typedefType(hasDeclaration(decl()))))));
1057
1058 // FIXME: Add tests for other types with getDecl() (e.g. RecordType)
1059}
1060
Edwin Vanef901b712013-02-25 14:49:29 +00001061TEST(HasDeclaration, HasDeclarationOfTemplateSpecializationType) {
1062 EXPECT_TRUE(matches("template <typename T> class A {}; A<int> a;",
1063 varDecl(hasType(templateSpecializationType(
1064 hasDeclaration(namedDecl(hasName("A"))))))));
1065}
1066
Manuel Klimek04616e42012-07-06 05:48:52 +00001067TEST(HasType, TakesQualTypeMatcherAndMatchesExpr) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001068 TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X")));
Manuel Klimek04616e42012-07-06 05:48:52 +00001069 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001070 matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001071 EXPECT_TRUE(
1072 notMatches("class X {}; void y(X *x) { x; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001073 expr(hasType(ClassX))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001074 EXPECT_TRUE(
1075 matches("class X {}; void y(X *x) { x; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001076 expr(hasType(pointsTo(ClassX)))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001077}
1078
1079TEST(HasType, TakesQualTypeMatcherAndMatchesValueDecl) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001080 TypeMatcher ClassX = hasDeclaration(recordDecl(hasName("X")));
Manuel Klimek04616e42012-07-06 05:48:52 +00001081 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001082 matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001083 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001084 notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001085 EXPECT_TRUE(
1086 matches("class X {}; void y() { X *x; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001087 varDecl(hasType(pointsTo(ClassX)))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001088}
1089
1090TEST(HasType, TakesDeclMatcherAndMatchesExpr) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001091 DeclarationMatcher ClassX = recordDecl(hasName("X"));
Manuel Klimek04616e42012-07-06 05:48:52 +00001092 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001093 matches("class X {}; void y(X &x) { x; }", expr(hasType(ClassX))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001094 EXPECT_TRUE(
1095 notMatches("class X {}; void y(X *x) { x; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001096 expr(hasType(ClassX))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001097}
1098
1099TEST(HasType, TakesDeclMatcherAndMatchesValueDecl) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001100 DeclarationMatcher ClassX = recordDecl(hasName("X"));
Manuel Klimek04616e42012-07-06 05:48:52 +00001101 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001102 matches("class X {}; void y() { X x; }", varDecl(hasType(ClassX))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001103 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001104 notMatches("class X {}; void y() { X *x; }", varDecl(hasType(ClassX))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001105}
1106
Aaron Ballman7e7b7b22016-02-01 14:11:47 +00001107TEST(HasType, MatchesTypedefDecl) {
1108 EXPECT_TRUE(matches("typedef int X;", typedefDecl(hasType(asString("int")))));
1109 EXPECT_TRUE(matches("typedef const int T;",
1110 typedefDecl(hasType(asString("const int")))));
1111 EXPECT_TRUE(notMatches("typedef const int T;",
1112 typedefDecl(hasType(asString("int")))));
1113 EXPECT_TRUE(matches("typedef int foo; typedef foo bar;",
1114 typedefDecl(hasType(asString("foo")), hasName("bar"))));
1115}
1116
Aaron Ballman66eb58a2016-04-14 16:05:45 +00001117TEST(HasType, MatchesTypedefNameDecl) {
1118 EXPECT_TRUE(matches("using X = int;", typedefNameDecl(hasType(asString("int")))));
1119 EXPECT_TRUE(matches("using T = const int;",
1120 typedefNameDecl(hasType(asString("const int")))));
1121 EXPECT_TRUE(notMatches("using T = const int;",
1122 typedefNameDecl(hasType(asString("int")))));
1123 EXPECT_TRUE(matches("using foo = int; using bar = foo;",
1124 typedefNameDecl(hasType(asString("foo")), hasName("bar"))));
1125}
1126
Manuel Klimekc16c6522013-06-20 13:08:29 +00001127TEST(HasTypeLoc, MatchesDeclaratorDecls) {
1128 EXPECT_TRUE(matches("int x;",
1129 varDecl(hasName("x"), hasTypeLoc(loc(asString("int"))))));
1130
1131 // Make sure we don't crash on implicit constructors.
1132 EXPECT_TRUE(notMatches("class X {}; X x;",
1133 declaratorDecl(hasTypeLoc(loc(asString("int"))))));
1134}
1135
Manuel Klimek04616e42012-07-06 05:48:52 +00001136TEST(Matcher, Call) {
1137 // FIXME: Do we want to overload Call() to directly take
Daniel Jasper1dad1832012-07-10 20:20:19 +00001138 // Matcher<Decl>, too?
Aaron Ballman512fb642015-09-17 13:30:52 +00001139 StatementMatcher MethodX =
1140 callExpr(hasDeclaration(cxxMethodDecl(hasName("x"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001141
1142 EXPECT_TRUE(matches("class Y { void x() { x(); } };", MethodX));
1143 EXPECT_TRUE(notMatches("class Y { void x() {} };", MethodX));
1144
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001145 StatementMatcher MethodOnY =
Aaron Ballman512fb642015-09-17 13:30:52 +00001146 cxxMemberCallExpr(on(hasType(recordDecl(hasName("Y")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001147
1148 EXPECT_TRUE(
1149 matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
1150 MethodOnY));
1151 EXPECT_TRUE(
1152 matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
1153 MethodOnY));
1154 EXPECT_TRUE(
1155 notMatches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
1156 MethodOnY));
1157 EXPECT_TRUE(
1158 notMatches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
1159 MethodOnY));
1160 EXPECT_TRUE(
1161 notMatches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
1162 MethodOnY));
1163
1164 StatementMatcher MethodOnYPointer =
Aaron Ballman512fb642015-09-17 13:30:52 +00001165 cxxMemberCallExpr(on(hasType(pointsTo(recordDecl(hasName("Y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001166
1167 EXPECT_TRUE(
1168 matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
1169 MethodOnYPointer));
1170 EXPECT_TRUE(
1171 matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
1172 MethodOnYPointer));
1173 EXPECT_TRUE(
1174 matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
1175 MethodOnYPointer));
1176 EXPECT_TRUE(
1177 notMatches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
1178 MethodOnYPointer));
1179 EXPECT_TRUE(
1180 notMatches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
1181 MethodOnYPointer));
1182}
1183
Daniel Jasper5901e472012-10-01 13:40:41 +00001184TEST(Matcher, Lambda) {
Richard Smith3d584b02014-02-06 21:49:08 +00001185 EXPECT_TRUE(matches("auto f = [] (int i) { return i; };",
Daniel Jasper5901e472012-10-01 13:40:41 +00001186 lambdaExpr()));
1187}
1188
1189TEST(Matcher, ForRange) {
Daniel Jasper6f595392012-10-01 15:05:34 +00001190 EXPECT_TRUE(matches("int as[] = { 1, 2, 3 };"
1191 "void f() { for (auto &a : as); }",
Aaron Ballman512fb642015-09-17 13:30:52 +00001192 cxxForRangeStmt()));
Daniel Jasper5901e472012-10-01 13:40:41 +00001193 EXPECT_TRUE(notMatches("void f() { for (int i; i<5; ++i); }",
Aaron Ballman512fb642015-09-17 13:30:52 +00001194 cxxForRangeStmt()));
Daniel Jasper5901e472012-10-01 13:40:41 +00001195}
1196
Alexander Kornienko9e41b5c2014-06-29 22:18:53 +00001197TEST(Matcher, SubstNonTypeTemplateParm) {
1198 EXPECT_FALSE(matches("template<int N>\n"
1199 "struct A { static const int n = 0; };\n"
1200 "struct B : public A<42> {};",
1201 substNonTypeTemplateParmExpr()));
1202 EXPECT_TRUE(matches("template<int N>\n"
1203 "struct A { static const int n = N; };\n"
1204 "struct B : public A<42> {};",
1205 substNonTypeTemplateParmExpr()));
1206}
1207
Aaron Ballman478a8eb2015-10-05 19:44:42 +00001208TEST(Matcher, NonTypeTemplateParmDecl) {
1209 EXPECT_TRUE(matches("template <int N> void f();",
1210 nonTypeTemplateParmDecl(hasName("N"))));
1211 EXPECT_TRUE(
1212 notMatches("template <typename T> void f();", nonTypeTemplateParmDecl()));
1213}
1214
Eric Fiselier3acf5fd2015-10-17 02:34:44 +00001215TEST(Matcher, templateTypeParmDecl) {
1216 EXPECT_TRUE(matches("template <typename T> void f();",
1217 templateTypeParmDecl(hasName("T"))));
1218 EXPECT_TRUE(
1219 notMatches("template <int N> void f();", templateTypeParmDecl()));
1220}
1221
Daniel Jasper5901e472012-10-01 13:40:41 +00001222TEST(Matcher, UserDefinedLiteral) {
1223 EXPECT_TRUE(matches("constexpr char operator \"\" _inc (const char i) {"
1224 " return i + 1;"
1225 "}"
1226 "char c = 'a'_inc;",
1227 userDefinedLiteral()));
1228}
1229
Daniel Jasper87c3d362012-09-20 14:12:57 +00001230TEST(Matcher, FlowControl) {
1231 EXPECT_TRUE(matches("void f() { while(true) { break; } }", breakStmt()));
1232 EXPECT_TRUE(matches("void f() { while(true) { continue; } }",
1233 continueStmt()));
1234 EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}", gotoStmt()));
Aaron Ballmana35b8fc2016-03-09 17:11:51 +00001235 EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}",
1236 labelStmt(
1237 hasDeclaration(
1238 labelDecl(hasName("FOO"))))));
1239 EXPECT_TRUE(matches("void f() { FOO: ; void *ptr = &&FOO; goto *ptr; }",
1240 addrLabelExpr()));
Daniel Jasper87c3d362012-09-20 14:12:57 +00001241 EXPECT_TRUE(matches("void f() { return; }", returnStmt()));
1242}
1243
Daniel Jasper1dad1832012-07-10 20:20:19 +00001244TEST(HasType, MatchesAsString) {
1245 EXPECT_TRUE(
1246 matches("class Y { public: void x(); }; void z() {Y* y; y->x(); }",
Aaron Ballman512fb642015-09-17 13:30:52 +00001247 cxxMemberCallExpr(on(hasType(asString("class Y *"))))));
1248 EXPECT_TRUE(
1249 matches("class X { void x(int x) {} };",
1250 cxxMethodDecl(hasParameter(0, hasType(asString("int"))))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001251 EXPECT_TRUE(matches("namespace ns { struct A {}; } struct B { ns::A a; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001252 fieldDecl(hasType(asString("ns::A")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001253 EXPECT_TRUE(matches("namespace { struct A {}; } struct B { A a; };",
David Blaikieabe1a392014-04-02 05:58:29 +00001254 fieldDecl(hasType(asString("struct (anonymous namespace)::A")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001255}
1256
Manuel Klimek04616e42012-07-06 05:48:52 +00001257TEST(Matcher, OverloadedOperatorCall) {
Aaron Ballman512fb642015-09-17 13:30:52 +00001258 StatementMatcher OpCall = cxxOperatorCallExpr();
Manuel Klimek04616e42012-07-06 05:48:52 +00001259 // Unary operator
1260 EXPECT_TRUE(matches("class Y { }; "
1261 "bool operator!(Y x) { return false; }; "
1262 "Y y; bool c = !y;", OpCall));
1263 // No match -- special operators like "new", "delete"
1264 // FIXME: operator new takes size_t, for which we need stddef.h, for which
1265 // we need to figure out include paths in the test.
1266 // EXPECT_TRUE(NotMatches("#include <stddef.h>\n"
1267 // "class Y { }; "
1268 // "void *operator new(size_t size) { return 0; } "
1269 // "Y *y = new Y;", OpCall));
1270 EXPECT_TRUE(notMatches("class Y { }; "
1271 "void operator delete(void *p) { } "
1272 "void a() {Y *y = new Y; delete y;}", OpCall));
1273 // Binary operator
1274 EXPECT_TRUE(matches("class Y { }; "
1275 "bool operator&&(Y x, Y y) { return true; }; "
1276 "Y a; Y b; bool c = a && b;",
1277 OpCall));
1278 // No match -- normal operator, not an overloaded one.
1279 EXPECT_TRUE(notMatches("bool x = true, y = true; bool t = x && y;", OpCall));
1280 EXPECT_TRUE(notMatches("int t = 5 << 2;", OpCall));
1281}
1282
1283TEST(Matcher, HasOperatorNameForOverloadedOperatorCall) {
1284 StatementMatcher OpCallAndAnd =
Aaron Ballman512fb642015-09-17 13:30:52 +00001285 cxxOperatorCallExpr(hasOverloadedOperatorName("&&"));
Manuel Klimek04616e42012-07-06 05:48:52 +00001286 EXPECT_TRUE(matches("class Y { }; "
1287 "bool operator&&(Y x, Y y) { return true; }; "
1288 "Y a; Y b; bool c = a && b;", OpCallAndAnd));
1289 StatementMatcher OpCallLessLess =
Aaron Ballman512fb642015-09-17 13:30:52 +00001290 cxxOperatorCallExpr(hasOverloadedOperatorName("<<"));
Manuel Klimek04616e42012-07-06 05:48:52 +00001291 EXPECT_TRUE(notMatches("class Y { }; "
1292 "bool operator&&(Y x, Y y) { return true; }; "
1293 "Y a; Y b; bool c = a && b;",
1294 OpCallLessLess));
Benjamin Kramer09514492014-07-14 14:05:02 +00001295 StatementMatcher OpStarCall =
Aaron Ballman512fb642015-09-17 13:30:52 +00001296 cxxOperatorCallExpr(hasOverloadedOperatorName("*"));
Benjamin Kramer09514492014-07-14 14:05:02 +00001297 EXPECT_TRUE(matches("class Y; int operator*(Y &); void f(Y &y) { *y; }",
1298 OpStarCall));
Edwin Vane0a4836e2013-03-06 17:02:57 +00001299 DeclarationMatcher ClassWithOpStar =
Aaron Ballman512fb642015-09-17 13:30:52 +00001300 cxxRecordDecl(hasMethod(hasOverloadedOperatorName("*")));
Edwin Vane0a4836e2013-03-06 17:02:57 +00001301 EXPECT_TRUE(matches("class Y { int operator*(); };",
1302 ClassWithOpStar));
1303 EXPECT_TRUE(notMatches("class Y { void myOperator(); };",
1304 ClassWithOpStar)) ;
Benjamin Kramer09514492014-07-14 14:05:02 +00001305 DeclarationMatcher AnyOpStar = functionDecl(hasOverloadedOperatorName("*"));
1306 EXPECT_TRUE(matches("class Y; int operator*(Y &);", AnyOpStar));
1307 EXPECT_TRUE(matches("class Y { int operator*(); };", AnyOpStar));
Manuel Klimek04616e42012-07-06 05:48:52 +00001308}
1309
Daniel Jasper0f9f0192012-11-15 03:29:05 +00001310TEST(Matcher, NestedOverloadedOperatorCalls) {
1311 EXPECT_TRUE(matchAndVerifyResultTrue(
Aaron Ballman512fb642015-09-17 13:30:52 +00001312 "class Y { }; "
1313 "Y& operator&&(Y& x, Y& y) { return x; }; "
1314 "Y a; Y b; Y c; Y d = a && b && c;",
1315 cxxOperatorCallExpr(hasOverloadedOperatorName("&&")).bind("x"),
1316 new VerifyIdIsBoundTo<CXXOperatorCallExpr>("x", 2)));
1317 EXPECT_TRUE(matches("class Y { }; "
1318 "Y& operator&&(Y& x, Y& y) { return x; }; "
1319 "Y a; Y b; Y c; Y d = a && b && c;",
1320 cxxOperatorCallExpr(hasParent(cxxOperatorCallExpr()))));
1321 EXPECT_TRUE(
1322 matches("class Y { }; "
1323 "Y& operator&&(Y& x, Y& y) { return x; }; "
1324 "Y a; Y b; Y c; Y d = a && b && c;",
1325 cxxOperatorCallExpr(hasDescendant(cxxOperatorCallExpr()))));
Daniel Jasper0f9f0192012-11-15 03:29:05 +00001326}
1327
Manuel Klimek04616e42012-07-06 05:48:52 +00001328TEST(Matcher, ThisPointerType) {
Manuel Klimek86f8bbc2012-07-24 13:37:29 +00001329 StatementMatcher MethodOnY =
Aaron Ballman512fb642015-09-17 13:30:52 +00001330 cxxMemberCallExpr(thisPointerType(recordDecl(hasName("Y"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001331
1332 EXPECT_TRUE(
1333 matches("class Y { public: void x(); }; void z() { Y y; y.x(); }",
1334 MethodOnY));
1335 EXPECT_TRUE(
1336 matches("class Y { public: void x(); }; void z(Y &y) { y.x(); }",
1337 MethodOnY));
1338 EXPECT_TRUE(
1339 matches("class Y { public: void x(); }; void z(Y *&y) { y->x(); }",
1340 MethodOnY));
1341 EXPECT_TRUE(
1342 matches("class Y { public: void x(); }; void z(Y y[]) { y->x(); }",
1343 MethodOnY));
1344 EXPECT_TRUE(
1345 matches("class Y { public: void x(); }; void z() { Y *y; y->x(); }",
1346 MethodOnY));
1347
1348 EXPECT_TRUE(matches(
1349 "class Y {"
1350 " public: virtual void x();"
1351 "};"
1352 "class X : public Y {"
1353 " public: virtual void x();"
1354 "};"
1355 "void z() { X *x; x->Y::x(); }", MethodOnY));
1356}
1357
1358TEST(Matcher, VariableUsage) {
1359 StatementMatcher Reference =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001360 declRefExpr(to(
1361 varDecl(hasInitializer(
Aaron Ballman512fb642015-09-17 13:30:52 +00001362 cxxMemberCallExpr(thisPointerType(recordDecl(hasName("Y"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001363
1364 EXPECT_TRUE(matches(
1365 "class Y {"
1366 " public:"
1367 " bool x() const;"
1368 "};"
1369 "void z(const Y &y) {"
1370 " bool b = y.x();"
1371 " if (b) {}"
1372 "}", Reference));
1373
1374 EXPECT_TRUE(notMatches(
1375 "class Y {"
1376 " public:"
1377 " bool x() const;"
1378 "};"
1379 "void z(const Y &y) {"
1380 " bool b = y.x();"
1381 "}", Reference));
1382}
1383
Samuel Benzaquenf56a2992014-06-05 18:22:14 +00001384TEST(Matcher, VarDecl_Storage) {
1385 auto M = varDecl(hasName("X"), hasLocalStorage());
1386 EXPECT_TRUE(matches("void f() { int X; }", M));
1387 EXPECT_TRUE(notMatches("int X;", M));
1388 EXPECT_TRUE(notMatches("void f() { static int X; }", M));
1389
1390 M = varDecl(hasName("X"), hasGlobalStorage());
1391 EXPECT_TRUE(notMatches("void f() { int X; }", M));
1392 EXPECT_TRUE(matches("int X;", M));
1393 EXPECT_TRUE(matches("void f() { static int X; }", M));
1394}
1395
Aaron Ballman8e7f00b2015-11-18 17:56:55 +00001396TEST(Matcher, VarDecl_StorageDuration) {
1397 std::string T =
Aaron Ballmanf08e1842015-11-18 18:37:29 +00001398 "void f() { int x; static int y; } int a;";
Aaron Ballman8e7f00b2015-11-18 17:56:55 +00001399
1400 EXPECT_TRUE(matches(T, varDecl(hasName("x"), hasAutomaticStorageDuration())));
1401 EXPECT_TRUE(
1402 notMatches(T, varDecl(hasName("y"), hasAutomaticStorageDuration())));
1403 EXPECT_TRUE(
Aaron Ballman8e7f00b2015-11-18 17:56:55 +00001404 notMatches(T, varDecl(hasName("a"), hasAutomaticStorageDuration())));
1405
1406 EXPECT_TRUE(matches(T, varDecl(hasName("y"), hasStaticStorageDuration())));
1407 EXPECT_TRUE(matches(T, varDecl(hasName("a"), hasStaticStorageDuration())));
1408 EXPECT_TRUE(notMatches(T, varDecl(hasName("x"), hasStaticStorageDuration())));
Aaron Ballman8e7f00b2015-11-18 17:56:55 +00001409
Aaron Ballmanf08e1842015-11-18 18:37:29 +00001410 // FIXME: It is really hard to test with thread_local itself because not all
1411 // targets support TLS, which causes this to be an error depending on what
1412 // platform the test is being run on. We do not have access to the TargetInfo
1413 // object to be able to test whether the platform supports TLS or not.
Aaron Ballman8e7f00b2015-11-18 17:56:55 +00001414 EXPECT_TRUE(notMatches(T, varDecl(hasName("x"), hasThreadStorageDuration())));
1415 EXPECT_TRUE(notMatches(T, varDecl(hasName("y"), hasThreadStorageDuration())));
1416 EXPECT_TRUE(notMatches(T, varDecl(hasName("a"), hasThreadStorageDuration())));
1417}
1418
Manuel Klimek61379422012-12-04 14:42:08 +00001419TEST(Matcher, FindsVarDeclInFunctionParameter) {
Daniel Jasper3cb72b42012-07-30 05:03:25 +00001420 EXPECT_TRUE(matches(
1421 "void f(int i) {}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001422 varDecl(hasName("i"))));
Daniel Jasper3cb72b42012-07-30 05:03:25 +00001423}
1424
Manuel Klimek04616e42012-07-06 05:48:52 +00001425TEST(Matcher, CalledVariable) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00001426 StatementMatcher CallOnVariableY =
Aaron Ballman512fb642015-09-17 13:30:52 +00001427 cxxMemberCallExpr(on(declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001428
1429 EXPECT_TRUE(matches(
1430 "class Y { public: void x() { Y y; y.x(); } };", CallOnVariableY));
1431 EXPECT_TRUE(matches(
1432 "class Y { public: void x() const { Y y; y.x(); } };", CallOnVariableY));
1433 EXPECT_TRUE(matches(
1434 "class Y { public: void x(); };"
1435 "class X : public Y { void z() { X y; y.x(); } };", CallOnVariableY));
1436 EXPECT_TRUE(matches(
1437 "class Y { public: void x(); };"
1438 "class X : public Y { void z() { X *y; y->x(); } };", CallOnVariableY));
1439 EXPECT_TRUE(notMatches(
1440 "class Y { public: void x(); };"
1441 "class X : public Y { void z() { unsigned long y; ((X*)y)->x(); } };",
1442 CallOnVariableY));
1443}
1444
Daniel Jasper1dad1832012-07-10 20:20:19 +00001445TEST(UnaryExprOrTypeTraitExpr, MatchesSizeOfAndAlignOf) {
1446 EXPECT_TRUE(matches("void x() { int a = sizeof(a); }",
1447 unaryExprOrTypeTraitExpr()));
1448 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }",
1449 alignOfExpr(anything())));
1450 // FIXME: Uncomment once alignof is enabled.
1451 // EXPECT_TRUE(matches("void x() { int a = alignof(a); }",
1452 // unaryExprOrTypeTraitExpr()));
1453 // EXPECT_TRUE(notMatches("void x() { int a = alignof(a); }",
1454 // sizeOfExpr()));
1455}
1456
1457TEST(UnaryExpressionOrTypeTraitExpression, MatchesCorrectType) {
1458 EXPECT_TRUE(matches("void x() { int a = sizeof(a); }", sizeOfExpr(
1459 hasArgumentOfType(asString("int")))));
1460 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
1461 hasArgumentOfType(asString("float")))));
1462 EXPECT_TRUE(matches(
1463 "struct A {}; void x() { A a; int b = sizeof(a); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001464 sizeOfExpr(hasArgumentOfType(hasDeclaration(recordDecl(hasName("A")))))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001465 EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001466 hasArgumentOfType(hasDeclaration(recordDecl(hasName("string")))))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001467}
1468
Manuel Klimek04616e42012-07-06 05:48:52 +00001469TEST(MemberExpression, DoesNotMatchClasses) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001470 EXPECT_TRUE(notMatches("class Y { void x() {} };", memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001471}
1472
1473TEST(MemberExpression, MatchesMemberFunctionCall) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001474 EXPECT_TRUE(matches("class Y { void x() { x(); } };", memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001475}
1476
1477TEST(MemberExpression, MatchesVariable) {
1478 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001479 matches("class Y { void x() { this->y; } int y; };", memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001480 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001481 matches("class Y { void x() { y; } int y; };", memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001482 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001483 matches("class Y { void x() { Y y; y.y; } int y; };", memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001484}
1485
1486TEST(MemberExpression, MatchesStaticVariable) {
1487 EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001488 memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001489 EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001490 memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001491 EXPECT_TRUE(notMatches("class Y { void x() { Y::y; } static int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001492 memberExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00001493}
1494
Daniel Jasper4e566c42012-07-12 08:50:38 +00001495TEST(IsInteger, MatchesIntegers) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001496 EXPECT_TRUE(matches("int i = 0;", varDecl(hasType(isInteger()))));
1497 EXPECT_TRUE(matches(
1498 "long long i = 0; void f(long long) { }; void g() {f(i);}",
1499 callExpr(hasArgument(0, declRefExpr(
1500 to(varDecl(hasType(isInteger()))))))));
Daniel Jasper4e566c42012-07-12 08:50:38 +00001501}
1502
1503TEST(IsInteger, ReportsNoFalsePositives) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001504 EXPECT_TRUE(notMatches("int *i;", varDecl(hasType(isInteger()))));
Daniel Jasper4e566c42012-07-12 08:50:38 +00001505 EXPECT_TRUE(notMatches("struct T {}; T t; void f(T *) { }; void g() {f(&t);}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001506 callExpr(hasArgument(0, declRefExpr(
1507 to(varDecl(hasType(isInteger()))))))));
Daniel Jasper4e566c42012-07-12 08:50:38 +00001508}
1509
Felix Bergercc9df3b2016-02-15 04:00:39 +00001510TEST(IsAnyPointer, MatchesPointers) {
1511 EXPECT_TRUE(matches("int* i = nullptr;", varDecl(hasType(isAnyPointer()))));
1512}
1513
Felix Berger40ef42a2016-03-06 15:27:59 +00001514TEST(IsAnyPointer, MatchesObjcPointer) {
1515 EXPECT_TRUE(matchesObjC("@interface Foo @end Foo *f;",
1516 varDecl(hasType(isAnyPointer()))));
1517}
1518
Felix Bergercc9df3b2016-02-15 04:00:39 +00001519TEST(IsAnyPointer, ReportsNoFalsePositives) {
1520 EXPECT_TRUE(notMatches("int i = 0;", varDecl(hasType(isAnyPointer()))));
1521}
1522
Gabor Horvath009c5d52015-12-15 08:35:45 +00001523TEST(IsAnyCharacter, MatchesCharacters) {
1524 EXPECT_TRUE(matches("char i = 0;", varDecl(hasType(isAnyCharacter()))));
1525}
1526
1527TEST(IsAnyCharacter, ReportsNoFalsePositives) {
1528 EXPECT_TRUE(notMatches("int i;", varDecl(hasType(isAnyCharacter()))));
1529}
1530
Manuel Klimek04616e42012-07-06 05:48:52 +00001531TEST(IsArrow, MatchesMemberVariablesViaArrow) {
1532 EXPECT_TRUE(matches("class Y { void x() { this->y; } int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001533 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001534 EXPECT_TRUE(matches("class Y { void x() { y; } int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001535 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001536 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001537 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001538}
1539
1540TEST(IsArrow, MatchesStaticMemberVariablesViaArrow) {
1541 EXPECT_TRUE(matches("class Y { void x() { this->y; } static int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001542 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001543 EXPECT_TRUE(notMatches("class Y { void x() { y; } static int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001544 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001545 EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } static int y; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001546 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001547}
1548
1549TEST(IsArrow, MatchesMemberCallsViaArrow) {
1550 EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001551 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001552 EXPECT_TRUE(matches("class Y { void x() { x(); } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001553 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001554 EXPECT_TRUE(notMatches("class Y { void x() { Y y; y.x(); } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001555 memberExpr(isArrow())));
Manuel Klimek04616e42012-07-06 05:48:52 +00001556}
1557
1558TEST(Callee, MatchesDeclarations) {
Aaron Ballman512fb642015-09-17 13:30:52 +00001559 StatementMatcher CallMethodX = callExpr(callee(cxxMethodDecl(hasName("x"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001560
1561 EXPECT_TRUE(matches("class Y { void x() { x(); } };", CallMethodX));
1562 EXPECT_TRUE(notMatches("class Y { void x() {} };", CallMethodX));
Samuel Benzaquen025f6b12015-04-20 20:58:50 +00001563
Aaron Ballman512fb642015-09-17 13:30:52 +00001564 CallMethodX = callExpr(callee(cxxConversionDecl()));
Samuel Benzaquen025f6b12015-04-20 20:58:50 +00001565 EXPECT_TRUE(
1566 matches("struct Y { operator int() const; }; int i = Y();", CallMethodX));
1567 EXPECT_TRUE(notMatches("struct Y { operator int() const; }; Y y = Y();",
1568 CallMethodX));
Manuel Klimek04616e42012-07-06 05:48:52 +00001569}
1570
Aaron Ballman6f6d0b62015-08-11 21:09:52 +00001571TEST(ConversionDeclaration, IsExplicit) {
1572 EXPECT_TRUE(matches("struct S { explicit operator int(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001573 cxxConversionDecl(isExplicit())));
Aaron Ballman6f6d0b62015-08-11 21:09:52 +00001574 EXPECT_TRUE(notMatches("struct S { operator int(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001575 cxxConversionDecl(isExplicit())));
Aaron Ballman6f6d0b62015-08-11 21:09:52 +00001576}
1577
Manuel Klimek04616e42012-07-06 05:48:52 +00001578TEST(Callee, MatchesMemberExpressions) {
1579 EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001580 callExpr(callee(memberExpr()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001581 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001582 notMatches("class Y { void x() { this->x(); } };", callExpr(callee(callExpr()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001583}
1584
1585TEST(Function, MatchesFunctionDeclarations) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001586 StatementMatcher CallFunctionF = callExpr(callee(functionDecl(hasName("f"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001587
1588 EXPECT_TRUE(matches("void f() { f(); }", CallFunctionF));
1589 EXPECT_TRUE(notMatches("void f() { }", CallFunctionF));
1590
NAKAMURA Takumi7d2da0b2014-02-16 10:16:09 +00001591 if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getOS() !=
1592 llvm::Triple::Win32) {
1593 // FIXME: Make this work for MSVC.
1594 // Dependent contexts, but a non-dependent call.
1595 EXPECT_TRUE(matches("void f(); template <int N> void g() { f(); }",
1596 CallFunctionF));
1597 EXPECT_TRUE(
1598 matches("void f(); template <int N> struct S { void g() { f(); } };",
1599 CallFunctionF));
1600 }
Manuel Klimek04616e42012-07-06 05:48:52 +00001601
1602 // Depedent calls don't match.
1603 EXPECT_TRUE(
1604 notMatches("void f(int); template <typename T> void g(T t) { f(t); }",
1605 CallFunctionF));
1606 EXPECT_TRUE(
1607 notMatches("void f(int);"
1608 "template <typename T> struct S { void g(T t) { f(t); } };",
1609 CallFunctionF));
Aaron Ballman3fd6c112015-10-05 14:41:27 +00001610
1611 EXPECT_TRUE(matches("void f(...);", functionDecl(isVariadic())));
1612 EXPECT_TRUE(notMatches("void f(int);", functionDecl(isVariadic())));
1613 EXPECT_TRUE(notMatches("template <typename... Ts> void f(Ts...);",
1614 functionDecl(isVariadic())));
1615 EXPECT_TRUE(notMatches("void f();", functionDecl(isVariadic())));
1616 EXPECT_TRUE(notMatchesC("void f();", functionDecl(isVariadic())));
Aaron Ballman7e7b7b22016-02-01 14:11:47 +00001617 EXPECT_TRUE(matches("void f(...);", functionDecl(parameterCountIs(0))));
1618 EXPECT_TRUE(matchesC("void f();", functionDecl(parameterCountIs(0))));
1619 EXPECT_TRUE(matches("void f(int, ...);", functionDecl(parameterCountIs(1))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001620}
1621
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00001622TEST(FunctionTemplate, MatchesFunctionTemplateDeclarations) {
1623 EXPECT_TRUE(
1624 matches("template <typename T> void f(T t) {}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001625 functionTemplateDecl(hasName("f"))));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00001626}
1627
1628TEST(FunctionTemplate, DoesNotMatchFunctionDeclarations) {
1629 EXPECT_TRUE(
1630 notMatches("void f(double d); void f(int t) {}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001631 functionTemplateDecl(hasName("f"))));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00001632}
1633
1634TEST(FunctionTemplate, DoesNotMatchFunctionTemplateSpecializations) {
1635 EXPECT_TRUE(
1636 notMatches("void g(); template <typename T> void f(T t) {}"
1637 "template <> void f(int t) { g(); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001638 functionTemplateDecl(hasName("f"),
1639 hasDescendant(declRefExpr(to(
1640 functionDecl(hasName("g"))))))));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00001641}
1642
Manuel Klimek04616e42012-07-06 05:48:52 +00001643TEST(Matcher, Argument) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00001644 StatementMatcher CallArgumentY = callExpr(
1645 hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001646
1647 EXPECT_TRUE(matches("void x(int) { int y; x(y); }", CallArgumentY));
1648 EXPECT_TRUE(
1649 matches("class X { void x(int) { int y; x(y); } };", CallArgumentY));
1650 EXPECT_TRUE(notMatches("void x(int) { int z; x(z); }", CallArgumentY));
1651
Daniel Jasper848cbe12012-09-18 13:09:13 +00001652 StatementMatcher WrongIndex = callExpr(
1653 hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001654 EXPECT_TRUE(notMatches("void x(int) { int y; x(y); }", WrongIndex));
1655}
1656
1657TEST(Matcher, AnyArgument) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00001658 StatementMatcher CallArgumentY = callExpr(
Gabor Horvath1b654f22016-03-30 11:22:14 +00001659 hasAnyArgument(
1660 ignoringParenImpCasts(declRefExpr(to(varDecl(hasName("y")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001661 EXPECT_TRUE(matches("void x(int, int) { int y; x(1, y); }", CallArgumentY));
1662 EXPECT_TRUE(matches("void x(int, int) { int y; x(y, 42); }", CallArgumentY));
1663 EXPECT_TRUE(notMatches("void x(int, int) { x(1, 2); }", CallArgumentY));
Gabor Horvath1b654f22016-03-30 11:22:14 +00001664
1665 StatementMatcher ImplicitCastedArgument = callExpr(
1666 hasAnyArgument(implicitCastExpr()));
1667 EXPECT_TRUE(matches("void x(long) { int y; x(y); }", ImplicitCastedArgument));
Manuel Klimek04616e42012-07-06 05:48:52 +00001668}
1669
Manuel Klimekce28f9e2016-01-18 11:20:09 +00001670TEST(ForEachArgumentWithParam, ReportsNoFalsePositives) {
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
1677 // IntParam does not match.
Aaron Ballmand7b18b92016-01-18 20:28:57 +00001678 EXPECT_TRUE(notMatches("void f(int* i) { int* y; f(y); }", CallExpr));
Manuel Klimekce28f9e2016-01-18 11:20:09 +00001679 // ArgumentY does not match.
Aaron Ballmand7b18b92016-01-18 20:28:57 +00001680 EXPECT_TRUE(notMatches("void f(int i) { int x; f(x); }", CallExpr));
Manuel Klimekce28f9e2016-01-18 11:20:09 +00001681}
1682
1683TEST(ForEachArgumentWithParam, MatchesCXXMemberCallExpr) {
1684 StatementMatcher ArgumentY =
1685 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1686 DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
1687 StatementMatcher CallExpr =
1688 callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
1689 EXPECT_TRUE(matchAndVerifyResultTrue(
1690 "struct S {"
1691 " const S& operator[](int i) { return *this; }"
1692 "};"
1693 "void f(S S1) {"
1694 " int y = 1;"
1695 " S1[y];"
1696 "}",
1697 CallExpr, new VerifyIdIsBoundTo<ParmVarDecl>("param", 1)));
Aaron Ballmand7b18b92016-01-18 20:28:57 +00001698
1699 StatementMatcher CallExpr2 =
1700 callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
1701 EXPECT_TRUE(matchAndVerifyResultTrue(
1702 "struct S {"
1703 " static void g(int i);"
1704 "};"
1705 "void f() {"
1706 " int y = 1;"
1707 " S::g(y);"
1708 "}",
1709 CallExpr2, new VerifyIdIsBoundTo<ParmVarDecl>("param", 1)));
Manuel Klimekce28f9e2016-01-18 11:20:09 +00001710}
1711
1712TEST(ForEachArgumentWithParam, MatchesCallExpr) {
1713 StatementMatcher ArgumentY =
1714 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1715 DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
1716 StatementMatcher CallExpr =
1717 callExpr(forEachArgumentWithParam(ArgumentY, IntParam));
1718
1719 EXPECT_TRUE(
1720 matchAndVerifyResultTrue("void f(int i) { int y; f(y); }", CallExpr,
1721 new VerifyIdIsBoundTo<ParmVarDecl>("param")));
1722 EXPECT_TRUE(
1723 matchAndVerifyResultTrue("void f(int i) { int y; f(y); }", CallExpr,
1724 new VerifyIdIsBoundTo<DeclRefExpr>("arg")));
1725
1726 EXPECT_TRUE(matchAndVerifyResultTrue(
1727 "void f(int i, int j) { int y; f(y, y); }", CallExpr,
1728 new VerifyIdIsBoundTo<ParmVarDecl>("param", 2)));
1729 EXPECT_TRUE(matchAndVerifyResultTrue(
1730 "void f(int i, int j) { int y; f(y, y); }", CallExpr,
1731 new VerifyIdIsBoundTo<DeclRefExpr>("arg", 2)));
1732}
1733
1734TEST(ForEachArgumentWithParam, MatchesConstructExpr) {
1735 StatementMatcher ArgumentY =
1736 declRefExpr(to(varDecl(hasName("y")))).bind("arg");
1737 DeclarationMatcher IntParam = parmVarDecl(hasType(isInteger())).bind("param");
1738 StatementMatcher ConstructExpr =
1739 cxxConstructExpr(forEachArgumentWithParam(ArgumentY, IntParam));
1740
1741 EXPECT_TRUE(matchAndVerifyResultTrue(
1742 "struct C {"
1743 " C(int i) {}"
1744 "};"
1745 "int y = 0;"
1746 "C Obj(y);",
1747 ConstructExpr, new VerifyIdIsBoundTo<ParmVarDecl>("param")));
1748}
1749
1750TEST(ForEachArgumentWithParam, HandlesBoundNodesForNonMatches) {
1751 EXPECT_TRUE(matchAndVerifyResultTrue(
1752 "void g(int i, int j) {"
1753 " int a;"
1754 " int b;"
1755 " int c;"
1756 " g(a, 0);"
1757 " g(a, b);"
1758 " g(0, b);"
1759 "}",
1760 functionDecl(
1761 forEachDescendant(varDecl().bind("v")),
1762 forEachDescendant(callExpr(forEachArgumentWithParam(
1763 declRefExpr(to(decl(equalsBoundNode("v")))), parmVarDecl())))),
1764 new VerifyIdIsBoundTo<VarDecl>("v", 4)));
1765}
1766
Manuel Klimek04616e42012-07-06 05:48:52 +00001767TEST(Matcher, ArgumentCount) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00001768 StatementMatcher Call1Arg = callExpr(argumentCountIs(1));
Manuel Klimek04616e42012-07-06 05:48:52 +00001769
1770 EXPECT_TRUE(matches("void x(int) { x(0); }", Call1Arg));
1771 EXPECT_TRUE(matches("class X { void x(int) { x(0); } };", Call1Arg));
1772 EXPECT_TRUE(notMatches("void x(int, int) { x(0, 0); }", Call1Arg));
1773}
1774
Daniel Jasper9f501292012-12-04 11:54:27 +00001775TEST(Matcher, ParameterCount) {
1776 DeclarationMatcher Function1Arg = functionDecl(parameterCountIs(1));
1777 EXPECT_TRUE(matches("void f(int i) {}", Function1Arg));
1778 EXPECT_TRUE(matches("class X { void f(int i) {} };", Function1Arg));
1779 EXPECT_TRUE(notMatches("void f() {}", Function1Arg));
1780 EXPECT_TRUE(notMatches("void f(int i, int j, int k) {}", Function1Arg));
Aaron Ballman7e7b7b22016-02-01 14:11:47 +00001781 EXPECT_TRUE(matches("void f(int i, ...) {};", Function1Arg));
Daniel Jasper9f501292012-12-04 11:54:27 +00001782}
1783
Manuel Klimek04616e42012-07-06 05:48:52 +00001784TEST(Matcher, References) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001785 DeclarationMatcher ReferenceClassX = varDecl(
1786 hasType(references(recordDecl(hasName("X")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001787 EXPECT_TRUE(matches("class X {}; void y(X y) { X &x = y; }",
1788 ReferenceClassX));
1789 EXPECT_TRUE(
1790 matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX));
Michael Hanc90d12d2013-09-11 15:53:29 +00001791 // The match here is on the implicit copy constructor code for
1792 // class X, not on code 'X x = y'.
Manuel Klimek04616e42012-07-06 05:48:52 +00001793 EXPECT_TRUE(
Michael Hanc90d12d2013-09-11 15:53:29 +00001794 matches("class X {}; void y(X y) { X x = y; }", ReferenceClassX));
1795 EXPECT_TRUE(
1796 notMatches("class X {}; extern X x;", ReferenceClassX));
Manuel Klimek04616e42012-07-06 05:48:52 +00001797 EXPECT_TRUE(
1798 notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX));
1799}
1800
Edwin Vane0a4836e2013-03-06 17:02:57 +00001801TEST(QualType, hasCanonicalType) {
1802 EXPECT_TRUE(notMatches("typedef int &int_ref;"
1803 "int a;"
1804 "int_ref b = a;",
1805 varDecl(hasType(qualType(referenceType())))));
1806 EXPECT_TRUE(
1807 matches("typedef int &int_ref;"
1808 "int a;"
1809 "int_ref b = a;",
1810 varDecl(hasType(qualType(hasCanonicalType(referenceType()))))));
1811}
1812
Edwin Vane119d3df2013-04-02 18:15:55 +00001813TEST(QualType, hasLocalQualifiers) {
1814 EXPECT_TRUE(notMatches("typedef const int const_int; const_int i = 1;",
1815 varDecl(hasType(hasLocalQualifiers()))));
1816 EXPECT_TRUE(matches("int *const j = nullptr;",
1817 varDecl(hasType(hasLocalQualifiers()))));
1818 EXPECT_TRUE(matches("int *volatile k;",
1819 varDecl(hasType(hasLocalQualifiers()))));
1820 EXPECT_TRUE(notMatches("int m;",
1821 varDecl(hasType(hasLocalQualifiers()))));
1822}
1823
Manuel Klimek04616e42012-07-06 05:48:52 +00001824TEST(HasParameter, CallsInnerMatcher) {
1825 EXPECT_TRUE(matches("class X { void x(int) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001826 cxxMethodDecl(hasParameter(0, varDecl()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001827 EXPECT_TRUE(notMatches("class X { void x(int) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001828 cxxMethodDecl(hasParameter(0, hasName("x")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001829}
1830
1831TEST(HasParameter, DoesNotMatchIfIndexOutOfBounds) {
1832 EXPECT_TRUE(notMatches("class X { void x(int) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001833 cxxMethodDecl(hasParameter(42, varDecl()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001834}
1835
1836TEST(HasType, MatchesParameterVariableTypesStrictly) {
Aaron Ballman512fb642015-09-17 13:30:52 +00001837 EXPECT_TRUE(matches(
1838 "class X { void x(X x) {} };",
1839 cxxMethodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
1840 EXPECT_TRUE(notMatches(
1841 "class X { void x(const X &x) {} };",
1842 cxxMethodDecl(hasParameter(0, hasType(recordDecl(hasName("X")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001843 EXPECT_TRUE(matches("class X { void x(const X *x) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001844 cxxMethodDecl(hasParameter(
1845 0, hasType(pointsTo(recordDecl(hasName("X"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001846 EXPECT_TRUE(matches("class X { void x(const X &x) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001847 cxxMethodDecl(hasParameter(
1848 0, hasType(references(recordDecl(hasName("X"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001849}
1850
1851TEST(HasAnyParameter, MatchesIndependentlyOfPosition) {
Aaron Ballman512fb642015-09-17 13:30:52 +00001852 EXPECT_TRUE(matches(
1853 "class Y {}; class X { void x(X x, Y y) {} };",
1854 cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
1855 EXPECT_TRUE(matches(
1856 "class Y {}; class X { void x(Y y, X x) {} };",
1857 cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001858}
1859
Daniel Jasper1dad1832012-07-10 20:20:19 +00001860TEST(Returns, MatchesReturnTypes) {
1861 EXPECT_TRUE(matches("class Y { int f() { return 1; } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001862 functionDecl(returns(asString("int")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001863 EXPECT_TRUE(notMatches("class Y { int f() { return 1; } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001864 functionDecl(returns(asString("float")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001865 EXPECT_TRUE(matches("class Y { Y getMe() { return *this; } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001866 functionDecl(returns(hasDeclaration(
1867 recordDecl(hasName("Y")))))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00001868}
1869
Daniel Jasperfaaffe32012-08-15 18:52:19 +00001870TEST(IsExternC, MatchesExternCFunctionDeclarations) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001871 EXPECT_TRUE(matches("extern \"C\" void f() {}", functionDecl(isExternC())));
1872 EXPECT_TRUE(matches("extern \"C\" { void f() {} }",
1873 functionDecl(isExternC())));
1874 EXPECT_TRUE(notMatches("void f() {}", functionDecl(isExternC())));
Daniel Jasperfaaffe32012-08-15 18:52:19 +00001875}
1876
Aaron Ballmaneb85b042016-01-18 20:37:44 +00001877TEST(IsDefaulted, MatchesDefaultedFunctionDeclarations) {
Aaron Ballman9e373df2016-01-18 20:47:02 +00001878 EXPECT_TRUE(notMatches("class A { ~A(); };",
1879 functionDecl(hasName("~A"), isDefaulted())));
Aaron Ballmaneb85b042016-01-18 20:37:44 +00001880 EXPECT_TRUE(matches("class B { ~B() = default; };",
Aaron Ballman9e373df2016-01-18 20:47:02 +00001881 functionDecl(hasName("~B"), isDefaulted())));
Aaron Ballmaneb85b042016-01-18 20:37:44 +00001882}
1883
Samuel Benzaquen8e7f9962014-08-15 14:20:59 +00001884TEST(IsDeleted, MatchesDeletedFunctionDeclarations) {
1885 EXPECT_TRUE(
1886 notMatches("void Func();", functionDecl(hasName("Func"), isDeleted())));
1887 EXPECT_TRUE(matches("void Func() = delete;",
1888 functionDecl(hasName("Func"), isDeleted())));
1889}
1890
Aaron Ballmana60bcda2015-12-02 15:23:59 +00001891TEST(IsNoThrow, MatchesNoThrowFunctionDeclarations) {
1892 EXPECT_TRUE(notMatches("void f();", functionDecl(isNoThrow())));
1893 EXPECT_TRUE(notMatches("void f() throw(int);", functionDecl(isNoThrow())));
1894 EXPECT_TRUE(
1895 notMatches("void f() noexcept(false);", functionDecl(isNoThrow())));
1896 EXPECT_TRUE(matches("void f() throw();", functionDecl(isNoThrow())));
1897 EXPECT_TRUE(matches("void f() noexcept;", functionDecl(isNoThrow())));
1898}
1899
Szabolcs Siposb37b0ed2015-05-22 11:35:50 +00001900TEST(isConstexpr, MatchesConstexprDeclarations) {
1901 EXPECT_TRUE(matches("constexpr int foo = 42;",
1902 varDecl(hasName("foo"), isConstexpr())));
1903 EXPECT_TRUE(matches("constexpr int bar();",
1904 functionDecl(hasName("bar"), isConstexpr())));
1905}
1906
Manuel Klimek04616e42012-07-06 05:48:52 +00001907TEST(HasAnyParameter, DoesntMatchIfInnerMatcherDoesntMatch) {
Aaron Ballman512fb642015-09-17 13:30:52 +00001908 EXPECT_TRUE(notMatches(
1909 "class Y {}; class X { void x(int) {} };",
1910 cxxMethodDecl(hasAnyParameter(hasType(recordDecl(hasName("X")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001911}
1912
1913TEST(HasAnyParameter, DoesNotMatchThisPointer) {
1914 EXPECT_TRUE(notMatches("class Y {}; class X { void x() {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001915 cxxMethodDecl(hasAnyParameter(
1916 hasType(pointsTo(recordDecl(hasName("X"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001917}
1918
Alp Toker8db6e7a2014-01-05 06:38:57 +00001919TEST(HasName, MatchesParameterVariableDeclarations) {
Manuel Klimek04616e42012-07-06 05:48:52 +00001920 EXPECT_TRUE(matches("class Y {}; class X { void x(int x) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001921 cxxMethodDecl(hasAnyParameter(hasName("x")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001922 EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00001923 cxxMethodDecl(hasAnyParameter(hasName("x")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00001924}
1925
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001926TEST(Matcher, MatchesClassTemplateSpecialization) {
1927 EXPECT_TRUE(matches("template<typename T> struct A {};"
1928 "template<> struct A<int> {};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001929 classTemplateSpecializationDecl()));
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001930 EXPECT_TRUE(matches("template<typename T> struct A {}; A<int> a;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001931 classTemplateSpecializationDecl()));
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001932 EXPECT_TRUE(notMatches("template<typename T> struct A {};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001933 classTemplateSpecializationDecl()));
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001934}
1935
Manuel Klimekc16c6522013-06-20 13:08:29 +00001936TEST(DeclaratorDecl, MatchesDeclaratorDecls) {
1937 EXPECT_TRUE(matches("int x;", declaratorDecl()));
1938 EXPECT_TRUE(notMatches("class A {};", declaratorDecl()));
1939}
1940
1941TEST(ParmVarDecl, MatchesParmVars) {
1942 EXPECT_TRUE(matches("void f(int x);", parmVarDecl()));
1943 EXPECT_TRUE(notMatches("void f();", parmVarDecl()));
1944}
1945
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001946TEST(Matcher, MatchesTypeTemplateArgument) {
1947 EXPECT_TRUE(matches(
1948 "template<typename T> struct B {};"
1949 "B<int> b;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001950 classTemplateSpecializationDecl(hasAnyTemplateArgument(refersToType(
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001951 asString("int"))))));
1952}
1953
1954TEST(Matcher, MatchesDeclarationReferenceTemplateArgument) {
1955 EXPECT_TRUE(matches(
1956 "struct B { int next; };"
1957 "template<int(B::*next_ptr)> struct A {};"
1958 "A<&B::next> a;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001959 classTemplateSpecializationDecl(hasAnyTemplateArgument(
1960 refersToDeclaration(fieldDecl(hasName("next")))))));
Daniel Jasper0c303372012-09-29 15:55:18 +00001961
1962 EXPECT_TRUE(notMatches(
1963 "template <typename T> struct A {};"
1964 "A<int> a;",
1965 classTemplateSpecializationDecl(hasAnyTemplateArgument(
1966 refersToDeclaration(decl())))));
Peter Collingbourne564597f2014-02-20 19:18:03 +00001967
1968 EXPECT_TRUE(matches(
1969 "struct B { int next; };"
1970 "template<int(B::*next_ptr)> struct A {};"
1971 "A<&B::next> a;",
1972 templateSpecializationType(hasAnyTemplateArgument(isExpr(
1973 hasDescendant(declRefExpr(to(fieldDecl(hasName("next"))))))))));
1974
1975 EXPECT_TRUE(notMatches(
1976 "template <typename T> struct A {};"
1977 "A<int> a;",
1978 templateSpecializationType(hasAnyTemplateArgument(
1979 refersToDeclaration(decl())))));
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001980}
1981
1982TEST(Matcher, MatchesSpecificArgument) {
1983 EXPECT_TRUE(matches(
1984 "template<typename T, typename U> class A {};"
1985 "A<bool, int> a;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001986 classTemplateSpecializationDecl(hasTemplateArgument(
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001987 1, refersToType(asString("int"))))));
1988 EXPECT_TRUE(notMatches(
1989 "template<typename T, typename U> class A {};"
1990 "A<int, bool> a;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00001991 classTemplateSpecializationDecl(hasTemplateArgument(
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00001992 1, refersToType(asString("int"))))));
Peter Collingbourne564597f2014-02-20 19:18:03 +00001993
1994 EXPECT_TRUE(matches(
1995 "template<typename T, typename U> class A {};"
1996 "A<bool, int> a;",
1997 templateSpecializationType(hasTemplateArgument(
1998 1, refersToType(asString("int"))))));
1999 EXPECT_TRUE(notMatches(
2000 "template<typename T, typename U> class A {};"
2001 "A<int, bool> a;",
2002 templateSpecializationType(hasTemplateArgument(
2003 1, refersToType(asString("int"))))));
Daniel Jasper8bd14aa2012-08-01 08:40:24 +00002004}
2005
Manuel Klimek7735e402014-10-09 13:06:22 +00002006TEST(TemplateArgument, Matches) {
2007 EXPECT_TRUE(matches("template<typename T> struct C {}; C<int> c;",
2008 classTemplateSpecializationDecl(
2009 hasAnyTemplateArgument(templateArgument()))));
2010 EXPECT_TRUE(matches(
2011 "template<typename T> struct C {}; C<int> c;",
2012 templateSpecializationType(hasAnyTemplateArgument(templateArgument()))));
2013}
2014
2015TEST(TemplateArgumentCountIs, Matches) {
2016 EXPECT_TRUE(
2017 matches("template<typename T> struct C {}; C<int> c;",
2018 classTemplateSpecializationDecl(templateArgumentCountIs(1))));
2019 EXPECT_TRUE(
2020 notMatches("template<typename T> struct C {}; C<int> c;",
2021 classTemplateSpecializationDecl(templateArgumentCountIs(2))));
2022
2023 EXPECT_TRUE(matches("template<typename T> struct C {}; C<int> c;",
2024 templateSpecializationType(templateArgumentCountIs(1))));
2025 EXPECT_TRUE(
2026 notMatches("template<typename T> struct C {}; C<int> c;",
2027 templateSpecializationType(templateArgumentCountIs(2))));
2028}
2029
2030TEST(IsIntegral, Matches) {
2031 EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
2032 classTemplateSpecializationDecl(
2033 hasAnyTemplateArgument(isIntegral()))));
2034 EXPECT_TRUE(notMatches("template<typename T> struct C {}; C<int> c;",
2035 classTemplateSpecializationDecl(hasAnyTemplateArgument(
2036 templateArgument(isIntegral())))));
2037}
2038
2039TEST(RefersToIntegralType, Matches) {
2040 EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
2041 classTemplateSpecializationDecl(
2042 hasAnyTemplateArgument(refersToIntegralType(
2043 asString("int"))))));
2044 EXPECT_TRUE(notMatches("template<unsigned T> struct C {}; C<42> c;",
2045 classTemplateSpecializationDecl(hasAnyTemplateArgument(
2046 refersToIntegralType(asString("int"))))));
2047}
2048
2049TEST(EqualsIntegralValue, Matches) {
2050 EXPECT_TRUE(matches("template<int T> struct C {}; C<42> c;",
2051 classTemplateSpecializationDecl(
2052 hasAnyTemplateArgument(equalsIntegralValue("42")))));
2053 EXPECT_TRUE(matches("template<int T> struct C {}; C<-42> c;",
2054 classTemplateSpecializationDecl(
2055 hasAnyTemplateArgument(equalsIntegralValue("-42")))));
2056 EXPECT_TRUE(matches("template<int T> struct C {}; C<-0042> c;",
2057 classTemplateSpecializationDecl(
2058 hasAnyTemplateArgument(equalsIntegralValue("-34")))));
2059 EXPECT_TRUE(notMatches("template<int T> struct C {}; C<42> c;",
2060 classTemplateSpecializationDecl(hasAnyTemplateArgument(
2061 equalsIntegralValue("0042")))));
2062}
2063
Daniel Jasper639522c2013-02-25 12:02:08 +00002064TEST(Matcher, MatchesAccessSpecDecls) {
2065 EXPECT_TRUE(matches("class C { public: int i; };", accessSpecDecl()));
2066 EXPECT_TRUE(
2067 matches("class C { public: int i; };", accessSpecDecl(isPublic())));
2068 EXPECT_TRUE(
2069 notMatches("class C { public: int i; };", accessSpecDecl(isProtected())));
2070 EXPECT_TRUE(
2071 notMatches("class C { public: int i; };", accessSpecDecl(isPrivate())));
2072
2073 EXPECT_TRUE(notMatches("class C { int i; };", accessSpecDecl()));
2074}
2075
Aaron Ballman41143bb2015-07-24 12:35:41 +00002076TEST(Matcher, MatchesFinal) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002077 EXPECT_TRUE(matches("class X final {};", cxxRecordDecl(isFinal())));
Aaron Ballman41143bb2015-07-24 12:35:41 +00002078 EXPECT_TRUE(matches("class X { virtual void f() final; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002079 cxxMethodDecl(isFinal())));
2080 EXPECT_TRUE(notMatches("class X {};", cxxRecordDecl(isFinal())));
2081 EXPECT_TRUE(
2082 notMatches("class X { virtual void f(); };", cxxMethodDecl(isFinal())));
Aaron Ballman41143bb2015-07-24 12:35:41 +00002083}
2084
Edwin Vane37ee1d72013-04-09 20:46:36 +00002085TEST(Matcher, MatchesVirtualMethod) {
2086 EXPECT_TRUE(matches("class X { virtual int f(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002087 cxxMethodDecl(isVirtual(), hasName("::X::f"))));
2088 EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isVirtual())));
Edwin Vane37ee1d72013-04-09 20:46:36 +00002089}
2090
Nico Webera415a1d2016-01-21 17:56:24 +00002091TEST(Matcher, MatchesVirtualAsWrittenMethod) {
2092 EXPECT_TRUE(matches("class A { virtual int f(); };"
2093 "class B : public A { int f(); };",
2094 cxxMethodDecl(isVirtualAsWritten(), hasName("::A::f"))));
2095 EXPECT_TRUE(
2096 notMatches("class A { virtual int f(); };"
2097 "class B : public A { int f(); };",
2098 cxxMethodDecl(isVirtualAsWritten(), hasName("::B::f"))));
2099}
2100
Dmitri Gribenko51c1b552014-02-24 09:27:46 +00002101TEST(Matcher, MatchesPureMethod) {
2102 EXPECT_TRUE(matches("class X { virtual int f() = 0; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002103 cxxMethodDecl(isPure(), hasName("::X::f"))));
2104 EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isPure())));
Dmitri Gribenko51c1b552014-02-24 09:27:46 +00002105}
2106
Angel Garcia Gomez4647ed72015-10-30 09:35:51 +00002107TEST(Matcher, MatchesCopyAssignmentOperator) {
2108 EXPECT_TRUE(matches("class X { X &operator=(X); };",
2109 cxxMethodDecl(isCopyAssignmentOperator())));
2110 EXPECT_TRUE(matches("class X { X &operator=(X &); };",
2111 cxxMethodDecl(isCopyAssignmentOperator())));
2112 EXPECT_TRUE(matches("class X { X &operator=(const X &); };",
2113 cxxMethodDecl(isCopyAssignmentOperator())));
2114 EXPECT_TRUE(matches("class X { X &operator=(volatile X &); };",
2115 cxxMethodDecl(isCopyAssignmentOperator())));
2116 EXPECT_TRUE(matches("class X { X &operator=(const volatile X &); };",
2117 cxxMethodDecl(isCopyAssignmentOperator())));
2118 EXPECT_TRUE(notMatches("class X { X &operator=(X &&); };",
2119 cxxMethodDecl(isCopyAssignmentOperator())));
2120}
2121
Aaron Ballman31bde872016-01-22 22:37:09 +00002122TEST(Matcher, MatchesMoveAssignmentOperator) {
2123 EXPECT_TRUE(notMatches("class X { X &operator=(X); };",
2124 cxxMethodDecl(isMoveAssignmentOperator())));
2125 EXPECT_TRUE(matches("class X { X &operator=(X &&); };",
2126 cxxMethodDecl(isMoveAssignmentOperator())));
2127 EXPECT_TRUE(matches("class X { X &operator=(const X &&); };",
2128 cxxMethodDecl(isMoveAssignmentOperator())));
2129 EXPECT_TRUE(matches("class X { X &operator=(volatile X &&); };",
2130 cxxMethodDecl(isMoveAssignmentOperator())));
2131 EXPECT_TRUE(matches("class X { X &operator=(const volatile X &&); };",
2132 cxxMethodDecl(isMoveAssignmentOperator())));
2133 EXPECT_TRUE(notMatches("class X { X &operator=(X &); };",
2134 cxxMethodDecl(isMoveAssignmentOperator())));
2135}
2136
Edwin Vanefc4f7dc2013-05-09 17:00:17 +00002137TEST(Matcher, MatchesConstMethod) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002138 EXPECT_TRUE(
2139 matches("struct A { void foo() const; };", cxxMethodDecl(isConst())));
2140 EXPECT_TRUE(
2141 notMatches("struct A { void foo(); };", cxxMethodDecl(isConst())));
Edwin Vanefc4f7dc2013-05-09 17:00:17 +00002142}
2143
Edwin Vane37ee1d72013-04-09 20:46:36 +00002144TEST(Matcher, MatchesOverridingMethod) {
2145 EXPECT_TRUE(matches("class X { virtual int f(); }; "
2146 "class Y : public X { int f(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002147 cxxMethodDecl(isOverride(), hasName("::Y::f"))));
Edwin Vane37ee1d72013-04-09 20:46:36 +00002148 EXPECT_TRUE(notMatches("class X { virtual int f(); }; "
Aaron Ballman512fb642015-09-17 13:30:52 +00002149 "class Y : public X { int f(); };",
2150 cxxMethodDecl(isOverride(), hasName("::X::f"))));
Edwin Vane37ee1d72013-04-09 20:46:36 +00002151 EXPECT_TRUE(notMatches("class X { int f(); }; "
2152 "class Y : public X { int f(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002153 cxxMethodDecl(isOverride())));
Edwin Vane37ee1d72013-04-09 20:46:36 +00002154 EXPECT_TRUE(notMatches("class X { int f(); int f(int); }; ",
Aaron Ballman512fb642015-09-17 13:30:52 +00002155 cxxMethodDecl(isOverride())));
Samuel Benzaquenbb5093f2015-03-06 16:24:47 +00002156 EXPECT_TRUE(
2157 matches("template <typename Base> struct Y : Base { void f() override;};",
Aaron Ballman512fb642015-09-17 13:30:52 +00002158 cxxMethodDecl(isOverride(), hasName("::Y::f"))));
Edwin Vane37ee1d72013-04-09 20:46:36 +00002159}
2160
Manuel Klimek04616e42012-07-06 05:48:52 +00002161TEST(Matcher, ConstructorCall) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002162 StatementMatcher Constructor = cxxConstructExpr();
Manuel Klimek04616e42012-07-06 05:48:52 +00002163
2164 EXPECT_TRUE(
2165 matches("class X { public: X(); }; void x() { X x; }", Constructor));
2166 EXPECT_TRUE(
2167 matches("class X { public: X(); }; void x() { X x = X(); }",
2168 Constructor));
2169 EXPECT_TRUE(
2170 matches("class X { public: X(int); }; void x() { X x = 0; }",
2171 Constructor));
2172 EXPECT_TRUE(matches("class X {}; void x(int) { X x; }", Constructor));
2173}
2174
2175TEST(Matcher, ConstructorArgument) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002176 StatementMatcher Constructor = cxxConstructExpr(
Daniel Jasper848cbe12012-09-18 13:09:13 +00002177 hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002178
2179 EXPECT_TRUE(
2180 matches("class X { public: X(int); }; void x() { int y; X x(y); }",
2181 Constructor));
2182 EXPECT_TRUE(
2183 matches("class X { public: X(int); }; void x() { int y; X x = X(y); }",
2184 Constructor));
2185 EXPECT_TRUE(
2186 matches("class X { public: X(int); }; void x() { int y; X x = y; }",
2187 Constructor));
2188 EXPECT_TRUE(
2189 notMatches("class X { public: X(int); }; void x() { int z; X x(z); }",
2190 Constructor));
2191
Aaron Ballman512fb642015-09-17 13:30:52 +00002192 StatementMatcher WrongIndex = cxxConstructExpr(
Daniel Jasper848cbe12012-09-18 13:09:13 +00002193 hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002194 EXPECT_TRUE(
2195 notMatches("class X { public: X(int); }; void x() { int y; X x(y); }",
2196 WrongIndex));
2197}
2198
2199TEST(Matcher, ConstructorArgumentCount) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002200 StatementMatcher Constructor1Arg = cxxConstructExpr(argumentCountIs(1));
Manuel Klimek04616e42012-07-06 05:48:52 +00002201
2202 EXPECT_TRUE(
2203 matches("class X { public: X(int); }; void x() { X x(0); }",
2204 Constructor1Arg));
2205 EXPECT_TRUE(
2206 matches("class X { public: X(int); }; void x() { X x = X(0); }",
2207 Constructor1Arg));
2208 EXPECT_TRUE(
2209 matches("class X { public: X(int); }; void x() { X x = 0; }",
2210 Constructor1Arg));
2211 EXPECT_TRUE(
2212 notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }",
2213 Constructor1Arg));
2214}
2215
Peter Collingbourne1fec3df2014-02-06 21:52:24 +00002216TEST(Matcher, ConstructorListInitialization) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002217 StatementMatcher ConstructorListInit =
2218 cxxConstructExpr(isListInitialization());
Peter Collingbourne1fec3df2014-02-06 21:52:24 +00002219
2220 EXPECT_TRUE(
2221 matches("class X { public: X(int); }; void x() { X x{0}; }",
2222 ConstructorListInit));
2223 EXPECT_FALSE(
2224 matches("class X { public: X(int); }; void x() { X x(0); }",
2225 ConstructorListInit));
2226}
2227
Manuel Klimek7fca93b2012-10-23 10:40:50 +00002228TEST(Matcher,ThisExpr) {
2229 EXPECT_TRUE(
Aaron Ballman512fb642015-09-17 13:30:52 +00002230 matches("struct X { int a; int f () { return a; } };", cxxThisExpr()));
Manuel Klimek7fca93b2012-10-23 10:40:50 +00002231 EXPECT_TRUE(
Aaron Ballman512fb642015-09-17 13:30:52 +00002232 notMatches("struct X { int f () { int a; return a; } };", cxxThisExpr()));
Manuel Klimek7fca93b2012-10-23 10:40:50 +00002233}
2234
Manuel Klimek04616e42012-07-06 05:48:52 +00002235TEST(Matcher, BindTemporaryExpression) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002236 StatementMatcher TempExpression = cxxBindTemporaryExpr();
Manuel Klimek04616e42012-07-06 05:48:52 +00002237
2238 std::string ClassString = "class string { public: string(); ~string(); }; ";
2239
2240 EXPECT_TRUE(
2241 matches(ClassString +
2242 "string GetStringByValue();"
2243 "void FunctionTakesString(string s);"
2244 "void run() { FunctionTakesString(GetStringByValue()); }",
2245 TempExpression));
2246
2247 EXPECT_TRUE(
2248 notMatches(ClassString +
2249 "string* GetStringPointer(); "
2250 "void FunctionTakesStringPtr(string* s);"
2251 "void run() {"
2252 " string* s = GetStringPointer();"
2253 " FunctionTakesStringPtr(GetStringPointer());"
2254 " FunctionTakesStringPtr(s);"
2255 "}",
2256 TempExpression));
2257
2258 EXPECT_TRUE(
2259 notMatches("class no_dtor {};"
2260 "no_dtor GetObjByValue();"
2261 "void ConsumeObj(no_dtor param);"
2262 "void run() { ConsumeObj(GetObjByValue()); }",
2263 TempExpression));
2264}
2265
Sam Panzer68a35af2012-08-24 22:04:44 +00002266TEST(MaterializeTemporaryExpr, MatchesTemporary) {
2267 std::string ClassString =
2268 "class string { public: string(); int length(); }; ";
2269
2270 EXPECT_TRUE(
2271 matches(ClassString +
2272 "string GetStringByValue();"
2273 "void FunctionTakesString(string s);"
2274 "void run() { FunctionTakesString(GetStringByValue()); }",
2275 materializeTemporaryExpr()));
2276
2277 EXPECT_TRUE(
2278 notMatches(ClassString +
2279 "string* GetStringPointer(); "
2280 "void FunctionTakesStringPtr(string* s);"
2281 "void run() {"
2282 " string* s = GetStringPointer();"
2283 " FunctionTakesStringPtr(GetStringPointer());"
2284 " FunctionTakesStringPtr(s);"
2285 "}",
2286 materializeTemporaryExpr()));
2287
2288 EXPECT_TRUE(
2289 notMatches(ClassString +
2290 "string GetStringByValue();"
2291 "void run() { int k = GetStringByValue().length(); }",
2292 materializeTemporaryExpr()));
2293
2294 EXPECT_TRUE(
2295 notMatches(ClassString +
2296 "string GetStringByValue();"
2297 "void run() { GetStringByValue(); }",
2298 materializeTemporaryExpr()));
2299}
2300
Manuel Klimek04616e42012-07-06 05:48:52 +00002301TEST(ConstructorDeclaration, SimpleCase) {
2302 EXPECT_TRUE(matches("class Foo { Foo(int i); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002303 cxxConstructorDecl(ofClass(hasName("Foo")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002304 EXPECT_TRUE(notMatches("class Foo { Foo(int i); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002305 cxxConstructorDecl(ofClass(hasName("Bar")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002306}
2307
2308TEST(ConstructorDeclaration, IsImplicit) {
2309 // This one doesn't match because the constructor is not added by the
2310 // compiler (it is not needed).
2311 EXPECT_TRUE(notMatches("class Foo { };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002312 cxxConstructorDecl(isImplicit())));
Manuel Klimek04616e42012-07-06 05:48:52 +00002313 // The compiler added the implicit default constructor.
2314 EXPECT_TRUE(matches("class Foo { }; Foo* f = new Foo();",
Aaron Ballman512fb642015-09-17 13:30:52 +00002315 cxxConstructorDecl(isImplicit())));
Manuel Klimek04616e42012-07-06 05:48:52 +00002316 EXPECT_TRUE(matches("class Foo { Foo(){} };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002317 cxxConstructorDecl(unless(isImplicit()))));
Joey Gouly0d9a2b22014-05-16 19:31:08 +00002318 // The compiler added an implicit assignment operator.
2319 EXPECT_TRUE(matches("struct A { int x; } a = {0}, b = a; void f() { a = b; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00002320 cxxMethodDecl(isImplicit(), hasName("operator="))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002321}
2322
Aaron Ballman6f6d0b62015-08-11 21:09:52 +00002323TEST(ConstructorDeclaration, IsExplicit) {
2324 EXPECT_TRUE(matches("struct S { explicit S(int); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002325 cxxConstructorDecl(isExplicit())));
Aaron Ballman6f6d0b62015-08-11 21:09:52 +00002326 EXPECT_TRUE(notMatches("struct S { S(int); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002327 cxxConstructorDecl(isExplicit())));
Aaron Ballman6f6d0b62015-08-11 21:09:52 +00002328}
2329
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002330TEST(ConstructorDeclaration, Kinds) {
2331 EXPECT_TRUE(matches("struct S { S(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002332 cxxConstructorDecl(isDefaultConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002333 EXPECT_TRUE(notMatches("struct S { S(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002334 cxxConstructorDecl(isCopyConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002335 EXPECT_TRUE(notMatches("struct S { S(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002336 cxxConstructorDecl(isMoveConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002337
2338 EXPECT_TRUE(notMatches("struct S { S(const S&); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002339 cxxConstructorDecl(isDefaultConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002340 EXPECT_TRUE(matches("struct S { S(const S&); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002341 cxxConstructorDecl(isCopyConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002342 EXPECT_TRUE(notMatches("struct S { S(const S&); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002343 cxxConstructorDecl(isMoveConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002344
2345 EXPECT_TRUE(notMatches("struct S { S(S&&); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002346 cxxConstructorDecl(isDefaultConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002347 EXPECT_TRUE(notMatches("struct S { S(S&&); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002348 cxxConstructorDecl(isCopyConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002349 EXPECT_TRUE(matches("struct S { S(S&&); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002350 cxxConstructorDecl(isMoveConstructor())));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002351}
2352
Alexander Kornienko7d20a5a2016-04-13 11:13:08 +00002353TEST(ConstructorDeclaration, IsUserProvided) {
2354 EXPECT_TRUE(notMatches("struct S { int X = 0; };",
2355 cxxConstructorDecl(isUserProvided())));
2356 EXPECT_TRUE(notMatches("struct S { S() = default; };",
2357 cxxConstructorDecl(isUserProvided())));
2358 EXPECT_TRUE(notMatches("struct S { S() = delete; };",
2359 cxxConstructorDecl(isUserProvided())));
2360 EXPECT_TRUE(
2361 matches("struct S { S(); };", cxxConstructorDecl(isUserProvided())));
2362 EXPECT_TRUE(matches("struct S { S(); }; S::S(){}",
2363 cxxConstructorDecl(isUserProvided())));
2364}
2365
2366TEST(ConstructorDeclaration, IsDelegatingConstructor) {
2367 EXPECT_TRUE(notMatches("struct S { S(); S(int); int X; };",
2368 cxxConstructorDecl(isDelegatingConstructor())));
2369 EXPECT_TRUE(notMatches("struct S { S(){} S(int X) : X(X) {} int X; };",
2370 cxxConstructorDecl(isDelegatingConstructor())));
2371 EXPECT_TRUE(matches(
2372 "struct S { S() : S(0) {} S(int X) : X(X) {} int X; };",
2373 cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(0))));
2374 EXPECT_TRUE(matches(
2375 "struct S { S(); S(int X); int X; }; S::S(int X) : S() {}",
2376 cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(1))));
2377}
2378
Daniel Jasper1dad1832012-07-10 20:20:19 +00002379TEST(DestructorDeclaration, MatchesVirtualDestructor) {
2380 EXPECT_TRUE(matches("class Foo { virtual ~Foo(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00002381 cxxDestructorDecl(ofClass(hasName("Foo")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00002382}
2383
2384TEST(DestructorDeclaration, DoesNotMatchImplicitDestructor) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002385 EXPECT_TRUE(notMatches("class Foo {};",
Aaron Ballman512fb642015-09-17 13:30:52 +00002386 cxxDestructorDecl(ofClass(hasName("Foo")))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00002387}
2388
Manuel Klimek04616e42012-07-06 05:48:52 +00002389TEST(HasAnyConstructorInitializer, SimpleCase) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002390 EXPECT_TRUE(
2391 notMatches("class Foo { Foo() { } };",
2392 cxxConstructorDecl(hasAnyConstructorInitializer(anything()))));
2393 EXPECT_TRUE(
2394 matches("class Foo {"
2395 " Foo() : foo_() { }"
2396 " int foo_;"
2397 "};",
2398 cxxConstructorDecl(hasAnyConstructorInitializer(anything()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002399}
2400
2401TEST(HasAnyConstructorInitializer, ForField) {
2402 static const char Code[] =
2403 "class Baz { };"
2404 "class Foo {"
2405 " Foo() : foo_() { }"
2406 " Baz foo_;"
2407 " Baz bar_;"
2408 "};";
Aaron Ballman512fb642015-09-17 13:30:52 +00002409 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002410 forField(hasType(recordDecl(hasName("Baz"))))))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002411 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00002412 forField(hasName("foo_"))))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002413 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002414 forField(hasType(recordDecl(hasName("Bar"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002415}
2416
2417TEST(HasAnyConstructorInitializer, WithInitializer) {
2418 static const char Code[] =
2419 "class Foo {"
2420 " Foo() : foo_(0) { }"
2421 " int foo_;"
2422 "};";
Aaron Ballman512fb642015-09-17 13:30:52 +00002423 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00002424 withInitializer(integerLiteral(equals(0)))))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002425 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00002426 withInitializer(integerLiteral(equals(1)))))));
2427}
2428
2429TEST(HasAnyConstructorInitializer, IsWritten) {
2430 static const char Code[] =
2431 "struct Bar { Bar(){} };"
2432 "class Foo {"
2433 " Foo() : foo_() { }"
2434 " Bar foo_;"
2435 " Bar bar_;"
2436 "};";
Aaron Ballman512fb642015-09-17 13:30:52 +00002437 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00002438 allOf(forField(hasName("foo_")), isWritten())))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002439 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00002440 allOf(forField(hasName("bar_")), isWritten())))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002441 EXPECT_TRUE(matches(Code, cxxConstructorDecl(hasAnyConstructorInitializer(
Manuel Klimek04616e42012-07-06 05:48:52 +00002442 allOf(forField(hasName("bar_")), unless(isWritten()))))));
2443}
2444
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002445TEST(HasAnyConstructorInitializer, IsBaseInitializer) {
2446 static const char Code[] =
2447 "struct B {};"
2448 "struct D : B {"
2449 " int I;"
2450 " D(int i) : I(i) {}"
2451 "};"
2452 "struct E : B {"
2453 " E() : B() {}"
2454 "};";
Aaron Ballman512fb642015-09-17 13:30:52 +00002455 EXPECT_TRUE(matches(Code, cxxConstructorDecl(allOf(
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002456 hasAnyConstructorInitializer(allOf(isBaseInitializer(), isWritten())),
2457 hasName("E")))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002458 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(allOf(
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002459 hasAnyConstructorInitializer(allOf(isBaseInitializer(), isWritten())),
2460 hasName("D")))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002461 EXPECT_TRUE(matches(Code, cxxConstructorDecl(allOf(
Aaron Ballmaned455d42015-08-11 20:42:00 +00002462 hasAnyConstructorInitializer(allOf(isMemberInitializer(), isWritten())),
2463 hasName("D")))));
Aaron Ballman512fb642015-09-17 13:30:52 +00002464 EXPECT_TRUE(notMatches(Code, cxxConstructorDecl(allOf(
Aaron Ballmaned455d42015-08-11 20:42:00 +00002465 hasAnyConstructorInitializer(allOf(isMemberInitializer(), isWritten())),
2466 hasName("E")))));
Aaron Ballman1ca258e2015-08-05 12:11:30 +00002467}
2468
Manuel Klimek04616e42012-07-06 05:48:52 +00002469TEST(Matcher, NewExpression) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002470 StatementMatcher New = cxxNewExpr();
Manuel Klimek04616e42012-07-06 05:48:52 +00002471
2472 EXPECT_TRUE(matches("class X { public: X(); }; void x() { new X; }", New));
2473 EXPECT_TRUE(
2474 matches("class X { public: X(); }; void x() { new X(); }", New));
2475 EXPECT_TRUE(
2476 matches("class X { public: X(int); }; void x() { new X(0); }", New));
2477 EXPECT_TRUE(matches("class X {}; void x(int) { new X; }", New));
2478}
2479
2480TEST(Matcher, NewExpressionArgument) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002481 StatementMatcher New = cxxConstructExpr(
Daniel Jasper848cbe12012-09-18 13:09:13 +00002482 hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002483
2484 EXPECT_TRUE(
2485 matches("class X { public: X(int); }; void x() { int y; new X(y); }",
2486 New));
2487 EXPECT_TRUE(
2488 matches("class X { public: X(int); }; void x() { int y; new X(y); }",
2489 New));
2490 EXPECT_TRUE(
2491 notMatches("class X { public: X(int); }; void x() { int z; new X(z); }",
2492 New));
2493
Aaron Ballman512fb642015-09-17 13:30:52 +00002494 StatementMatcher WrongIndex = cxxConstructExpr(
Daniel Jasper848cbe12012-09-18 13:09:13 +00002495 hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002496 EXPECT_TRUE(
2497 notMatches("class X { public: X(int); }; void x() { int y; new X(y); }",
2498 WrongIndex));
2499}
2500
2501TEST(Matcher, NewExpressionArgumentCount) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002502 StatementMatcher New = cxxConstructExpr(argumentCountIs(1));
Manuel Klimek04616e42012-07-06 05:48:52 +00002503
2504 EXPECT_TRUE(
2505 matches("class X { public: X(int); }; void x() { new X(0); }", New));
2506 EXPECT_TRUE(
2507 notMatches("class X { public: X(int, int); }; void x() { new X(0, 0); }",
2508 New));
2509}
2510
Daniel Jasper1dad1832012-07-10 20:20:19 +00002511TEST(Matcher, DeleteExpression) {
2512 EXPECT_TRUE(matches("struct A {}; void f(A* a) { delete a; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00002513 cxxDeleteExpr()));
Daniel Jasper1dad1832012-07-10 20:20:19 +00002514}
2515
Manuel Klimek04616e42012-07-06 05:48:52 +00002516TEST(Matcher, DefaultArgument) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002517 StatementMatcher Arg = cxxDefaultArgExpr();
Manuel Klimek04616e42012-07-06 05:48:52 +00002518
2519 EXPECT_TRUE(matches("void x(int, int = 0) { int y; x(y); }", Arg));
2520 EXPECT_TRUE(
2521 matches("class X { void x(int, int = 0) { int y; x(y); } };", Arg));
2522 EXPECT_TRUE(notMatches("void x(int, int = 0) { int y; x(y, 0); }", Arg));
2523}
2524
2525TEST(Matcher, StringLiterals) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00002526 StatementMatcher Literal = stringLiteral();
Manuel Klimek04616e42012-07-06 05:48:52 +00002527 EXPECT_TRUE(matches("const char *s = \"string\";", Literal));
2528 // wide string
2529 EXPECT_TRUE(matches("const wchar_t *s = L\"string\";", Literal));
2530 // with escaped characters
2531 EXPECT_TRUE(matches("const char *s = \"\x05five\";", Literal));
2532 // no matching -- though the data type is the same, there is no string literal
2533 EXPECT_TRUE(notMatches("const char s[1] = {'a'};", Literal));
2534}
2535
2536TEST(Matcher, CharacterLiterals) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00002537 StatementMatcher CharLiteral = characterLiteral();
Manuel Klimek04616e42012-07-06 05:48:52 +00002538 EXPECT_TRUE(matches("const char c = 'c';", CharLiteral));
2539 // wide character
2540 EXPECT_TRUE(matches("const char c = L'c';", CharLiteral));
2541 // wide character, Hex encoded, NOT MATCHED!
2542 EXPECT_TRUE(notMatches("const wchar_t c = 0x2126;", CharLiteral));
2543 EXPECT_TRUE(notMatches("const char c = 0x1;", CharLiteral));
2544}
2545
2546TEST(Matcher, IntegerLiterals) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00002547 StatementMatcher HasIntLiteral = integerLiteral();
Manuel Klimek04616e42012-07-06 05:48:52 +00002548 EXPECT_TRUE(matches("int i = 10;", HasIntLiteral));
2549 EXPECT_TRUE(matches("int i = 0x1AB;", HasIntLiteral));
2550 EXPECT_TRUE(matches("int i = 10L;", HasIntLiteral));
2551 EXPECT_TRUE(matches("int i = 10U;", HasIntLiteral));
2552
2553 // Non-matching cases (character literals, float and double)
2554 EXPECT_TRUE(notMatches("int i = L'a';",
2555 HasIntLiteral)); // this is actually a character
2556 // literal cast to int
2557 EXPECT_TRUE(notMatches("int i = 'a';", HasIntLiteral));
2558 EXPECT_TRUE(notMatches("int i = 1e10;", HasIntLiteral));
2559 EXPECT_TRUE(notMatches("int i = 10.0;", HasIntLiteral));
2560}
2561
Daniel Jasper91f1c8c2013-07-26 18:52:58 +00002562TEST(Matcher, FloatLiterals) {
2563 StatementMatcher HasFloatLiteral = floatLiteral();
2564 EXPECT_TRUE(matches("float i = 10.0;", HasFloatLiteral));
2565 EXPECT_TRUE(matches("float i = 10.0f;", HasFloatLiteral));
2566 EXPECT_TRUE(matches("double i = 10.0;", HasFloatLiteral));
2567 EXPECT_TRUE(matches("double i = 10.0L;", HasFloatLiteral));
2568 EXPECT_TRUE(matches("double i = 1e10;", HasFloatLiteral));
Daniel Jasperd1423812015-02-03 09:45:52 +00002569 EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0))));
2570 EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0f))));
2571 EXPECT_TRUE(
2572 matches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(5.0)))));
Daniel Jasper91f1c8c2013-07-26 18:52:58 +00002573
2574 EXPECT_TRUE(notMatches("float i = 10;", HasFloatLiteral));
Daniel Jasperd1423812015-02-03 09:45:52 +00002575 EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0))));
2576 EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0f))));
2577 EXPECT_TRUE(
2578 notMatches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(6.0)))));
Daniel Jasper91f1c8c2013-07-26 18:52:58 +00002579}
2580
Daniel Jasper5901e472012-10-01 13:40:41 +00002581TEST(Matcher, NullPtrLiteral) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002582 EXPECT_TRUE(matches("int* i = nullptr;", cxxNullPtrLiteralExpr()));
Daniel Jasper5901e472012-10-01 13:40:41 +00002583}
2584
Szabolcs Sipos1d068bb2015-05-07 14:24:22 +00002585TEST(Matcher, GNUNullExpr) {
2586 EXPECT_TRUE(matches("int* i = __null;", gnuNullExpr()));
2587}
2588
Aaron Ballmana35b8fc2016-03-09 17:11:51 +00002589TEST(Matcher, AtomicExpr) {
2590 EXPECT_TRUE(matches("void foo() { int *ptr; __atomic_load_n(ptr, 1); }",
2591 atomicExpr()));
2592}
2593
2594TEST(Matcher, Initializers) {
2595 const char *ToMatch = "void foo() { struct point { double x; double y; };"
2596 " struct point ptarray[10] = "
2597 " { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 }; }";
2598 EXPECT_TRUE(matchesConditionally(
2599 ToMatch,
2600 initListExpr(
2601 has(
2602 cxxConstructExpr(
2603 requiresZeroInitialization())),
2604 has(
2605 initListExpr(
2606 hasType(asString("struct point")),
2607 has(floatLiteral(equals(1.0))),
2608 has(implicitValueInitExpr(
2609 hasType(asString("double")))))),
2610 has(
2611 initListExpr(
2612 hasType(asString("struct point")),
2613 has(floatLiteral(equals(2.0))),
2614 has(floatLiteral(equals(1.0)))))
2615 ), true, "-std=gnu++98"));
2616
2617 EXPECT_TRUE(matchesC99(ToMatch,
2618 initListExpr(
2619 hasSyntacticForm(
2620 initListExpr(
2621 has(
2622 designatedInitExpr(
2623 designatorCountIs(2),
2624 has(floatLiteral(
2625 equals(1.0))),
2626 has(integerLiteral(
2627 equals(2))))),
2628 has(
2629 designatedInitExpr(
2630 designatorCountIs(2),
2631 has(floatLiteral(
2632 equals(2.0))),
2633 has(integerLiteral(
2634 equals(2))))),
2635 has(
2636 designatedInitExpr(
2637 designatorCountIs(2),
2638 has(floatLiteral(
2639 equals(1.0))),
2640 has(integerLiteral(
2641 equals(0)))))
2642 )))));
2643}
2644
2645TEST(Matcher, ParenListExpr) {
2646 EXPECT_TRUE(
Aaron Ballman2648d422016-03-09 18:07:17 +00002647 matches("template<typename T> class foo { void bar() { foo X(*this); } };"
2648 "template class foo<int>;",
2649 varDecl(hasInitializer(parenListExpr(has(unaryOperator()))))));
Aaron Ballmana35b8fc2016-03-09 17:11:51 +00002650}
2651
2652TEST(Matcher, StmtExpr) {
2653 EXPECT_TRUE(matches("void declToImport() { int C = ({int X=4; X;}); }",
2654 varDecl(hasInitializer(stmtExpr()))));
2655}
2656
2657TEST(Matcher, ImportPredefinedExpr) {
2658 // __func__ expands as StringLiteral("foo")
2659 EXPECT_TRUE(matches("void foo() { __func__; }",
2660 predefinedExpr(
2661 hasType(asString("const char [4]")),
2662 has(stringLiteral()))));
2663}
2664
Daniel Jasper87c3d362012-09-20 14:12:57 +00002665TEST(Matcher, AsmStatement) {
2666 EXPECT_TRUE(matches("void foo() { __asm(\"mov al, 2\"); }", asmStmt()));
2667}
2668
Manuel Klimek04616e42012-07-06 05:48:52 +00002669TEST(Matcher, Conditions) {
Aaron Ballman512fb642015-09-17 13:30:52 +00002670 StatementMatcher Condition =
2671 ifStmt(hasCondition(cxxBoolLiteral(equals(true))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002672
2673 EXPECT_TRUE(matches("void x() { if (true) {} }", Condition));
2674 EXPECT_TRUE(notMatches("void x() { if (false) {} }", Condition));
2675 EXPECT_TRUE(notMatches("void x() { bool a = true; if (a) {} }", Condition));
2676 EXPECT_TRUE(notMatches("void x() { if (true || false) {} }", Condition));
2677 EXPECT_TRUE(notMatches("void x() { if (1) {} }", Condition));
2678}
2679
Manuel Klimek909b5c942014-05-27 10:04:12 +00002680TEST(IfStmt, ChildTraversalMatchers) {
2681 EXPECT_TRUE(matches("void f() { if (false) true; else false; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00002682 ifStmt(hasThen(cxxBoolLiteral(equals(true))))));
Manuel Klimek909b5c942014-05-27 10:04:12 +00002683 EXPECT_TRUE(notMatches("void f() { if (false) false; else true; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00002684 ifStmt(hasThen(cxxBoolLiteral(equals(true))))));
Manuel Klimek909b5c942014-05-27 10:04:12 +00002685 EXPECT_TRUE(matches("void f() { if (false) false; else true; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00002686 ifStmt(hasElse(cxxBoolLiteral(equals(true))))));
Manuel Klimek909b5c942014-05-27 10:04:12 +00002687 EXPECT_TRUE(notMatches("void f() { if (false) true; else false; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00002688 ifStmt(hasElse(cxxBoolLiteral(equals(true))))));
Manuel Klimek909b5c942014-05-27 10:04:12 +00002689}
2690
Manuel Klimek04616e42012-07-06 05:48:52 +00002691TEST(MatchBinaryOperator, HasOperatorName) {
2692 StatementMatcher OperatorOr = binaryOperator(hasOperatorName("||"));
2693
2694 EXPECT_TRUE(matches("void x() { true || false; }", OperatorOr));
2695 EXPECT_TRUE(notMatches("void x() { true && false; }", OperatorOr));
2696}
2697
2698TEST(MatchBinaryOperator, HasLHSAndHasRHS) {
2699 StatementMatcher OperatorTrueFalse =
Aaron Ballman512fb642015-09-17 13:30:52 +00002700 binaryOperator(hasLHS(cxxBoolLiteral(equals(true))),
2701 hasRHS(cxxBoolLiteral(equals(false))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002702
2703 EXPECT_TRUE(matches("void x() { true || false; }", OperatorTrueFalse));
2704 EXPECT_TRUE(matches("void x() { true && false; }", OperatorTrueFalse));
2705 EXPECT_TRUE(notMatches("void x() { false || true; }", OperatorTrueFalse));
Alexander Kornienkoe39993e2015-11-02 22:23:21 +00002706
2707 StatementMatcher OperatorIntPointer = arraySubscriptExpr(
2708 hasLHS(hasType(isInteger())), hasRHS(hasType(pointsTo(qualType()))));
2709 EXPECT_TRUE(matches("void x() { 1[\"abc\"]; }", OperatorIntPointer));
2710 EXPECT_TRUE(notMatches("void x() { \"abc\"[1]; }", OperatorIntPointer));
Manuel Klimek04616e42012-07-06 05:48:52 +00002711}
2712
2713TEST(MatchBinaryOperator, HasEitherOperand) {
2714 StatementMatcher HasOperand =
Aaron Ballman512fb642015-09-17 13:30:52 +00002715 binaryOperator(hasEitherOperand(cxxBoolLiteral(equals(false))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002716
2717 EXPECT_TRUE(matches("void x() { true || false; }", HasOperand));
2718 EXPECT_TRUE(matches("void x() { false && true; }", HasOperand));
2719 EXPECT_TRUE(notMatches("void x() { true || true; }", HasOperand));
2720}
2721
2722TEST(Matcher, BinaryOperatorTypes) {
2723 // Integration test that verifies the AST provides all binary operators in
2724 // a way we expect.
2725 // FIXME: Operator ','
2726 EXPECT_TRUE(
2727 matches("void x() { 3, 4; }", binaryOperator(hasOperatorName(","))));
2728 EXPECT_TRUE(
2729 matches("bool b; bool c = (b = true);",
2730 binaryOperator(hasOperatorName("="))));
2731 EXPECT_TRUE(
2732 matches("bool b = 1 != 2;", binaryOperator(hasOperatorName("!="))));
2733 EXPECT_TRUE(
2734 matches("bool b = 1 == 2;", binaryOperator(hasOperatorName("=="))));
2735 EXPECT_TRUE(matches("bool b = 1 < 2;", binaryOperator(hasOperatorName("<"))));
2736 EXPECT_TRUE(
2737 matches("bool b = 1 <= 2;", binaryOperator(hasOperatorName("<="))));
2738 EXPECT_TRUE(
2739 matches("int i = 1 << 2;", binaryOperator(hasOperatorName("<<"))));
2740 EXPECT_TRUE(
2741 matches("int i = 1; int j = (i <<= 2);",
2742 binaryOperator(hasOperatorName("<<="))));
2743 EXPECT_TRUE(matches("bool b = 1 > 2;", binaryOperator(hasOperatorName(">"))));
2744 EXPECT_TRUE(
2745 matches("bool b = 1 >= 2;", binaryOperator(hasOperatorName(">="))));
2746 EXPECT_TRUE(
2747 matches("int i = 1 >> 2;", binaryOperator(hasOperatorName(">>"))));
2748 EXPECT_TRUE(
2749 matches("int i = 1; int j = (i >>= 2);",
2750 binaryOperator(hasOperatorName(">>="))));
2751 EXPECT_TRUE(
2752 matches("int i = 42 ^ 23;", binaryOperator(hasOperatorName("^"))));
2753 EXPECT_TRUE(
2754 matches("int i = 42; int j = (i ^= 42);",
2755 binaryOperator(hasOperatorName("^="))));
2756 EXPECT_TRUE(
2757 matches("int i = 42 % 23;", binaryOperator(hasOperatorName("%"))));
2758 EXPECT_TRUE(
2759 matches("int i = 42; int j = (i %= 42);",
2760 binaryOperator(hasOperatorName("%="))));
2761 EXPECT_TRUE(
2762 matches("bool b = 42 &23;", binaryOperator(hasOperatorName("&"))));
2763 EXPECT_TRUE(
2764 matches("bool b = true && false;",
2765 binaryOperator(hasOperatorName("&&"))));
2766 EXPECT_TRUE(
2767 matches("bool b = true; bool c = (b &= false);",
2768 binaryOperator(hasOperatorName("&="))));
2769 EXPECT_TRUE(
2770 matches("bool b = 42 | 23;", binaryOperator(hasOperatorName("|"))));
2771 EXPECT_TRUE(
2772 matches("bool b = true || false;",
2773 binaryOperator(hasOperatorName("||"))));
2774 EXPECT_TRUE(
2775 matches("bool b = true; bool c = (b |= false);",
2776 binaryOperator(hasOperatorName("|="))));
2777 EXPECT_TRUE(
2778 matches("int i = 42 *23;", binaryOperator(hasOperatorName("*"))));
2779 EXPECT_TRUE(
2780 matches("int i = 42; int j = (i *= 23);",
2781 binaryOperator(hasOperatorName("*="))));
2782 EXPECT_TRUE(
2783 matches("int i = 42 / 23;", binaryOperator(hasOperatorName("/"))));
2784 EXPECT_TRUE(
2785 matches("int i = 42; int j = (i /= 23);",
2786 binaryOperator(hasOperatorName("/="))));
2787 EXPECT_TRUE(
2788 matches("int i = 42 + 23;", binaryOperator(hasOperatorName("+"))));
2789 EXPECT_TRUE(
2790 matches("int i = 42; int j = (i += 23);",
2791 binaryOperator(hasOperatorName("+="))));
2792 EXPECT_TRUE(
2793 matches("int i = 42 - 23;", binaryOperator(hasOperatorName("-"))));
2794 EXPECT_TRUE(
2795 matches("int i = 42; int j = (i -= 23);",
2796 binaryOperator(hasOperatorName("-="))));
2797 EXPECT_TRUE(
2798 matches("struct A { void x() { void (A::*a)(); (this->*a)(); } };",
2799 binaryOperator(hasOperatorName("->*"))));
2800 EXPECT_TRUE(
2801 matches("struct A { void x() { void (A::*a)(); ((*this).*a)(); } };",
2802 binaryOperator(hasOperatorName(".*"))));
2803
2804 // Member expressions as operators are not supported in matches.
2805 EXPECT_TRUE(
2806 notMatches("struct A { void x(A *a) { a->x(this); } };",
2807 binaryOperator(hasOperatorName("->"))));
2808
2809 // Initializer assignments are not represented as operator equals.
2810 EXPECT_TRUE(
2811 notMatches("bool b = true;", binaryOperator(hasOperatorName("="))));
2812
2813 // Array indexing is not represented as operator.
2814 EXPECT_TRUE(notMatches("int a[42]; void x() { a[23]; }", unaryOperator()));
2815
2816 // Overloaded operators do not match at all.
2817 EXPECT_TRUE(notMatches(
2818 "struct A { bool operator&&(const A &a) const { return false; } };"
2819 "void x() { A a, b; a && b; }",
2820 binaryOperator()));
2821}
2822
2823TEST(MatchUnaryOperator, HasOperatorName) {
2824 StatementMatcher OperatorNot = unaryOperator(hasOperatorName("!"));
2825
2826 EXPECT_TRUE(matches("void x() { !true; } ", OperatorNot));
2827 EXPECT_TRUE(notMatches("void x() { true; } ", OperatorNot));
2828}
2829
2830TEST(MatchUnaryOperator, HasUnaryOperand) {
2831 StatementMatcher OperatorOnFalse =
Aaron Ballman512fb642015-09-17 13:30:52 +00002832 unaryOperator(hasUnaryOperand(cxxBoolLiteral(equals(false))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002833
2834 EXPECT_TRUE(matches("void x() { !false; }", OperatorOnFalse));
2835 EXPECT_TRUE(notMatches("void x() { !true; }", OperatorOnFalse));
2836}
2837
2838TEST(Matcher, UnaryOperatorTypes) {
2839 // Integration test that verifies the AST provides all unary operators in
2840 // a way we expect.
2841 EXPECT_TRUE(matches("bool b = !true;", unaryOperator(hasOperatorName("!"))));
2842 EXPECT_TRUE(
2843 matches("bool b; bool *p = &b;", unaryOperator(hasOperatorName("&"))));
2844 EXPECT_TRUE(matches("int i = ~ 1;", unaryOperator(hasOperatorName("~"))));
2845 EXPECT_TRUE(
2846 matches("bool *p; bool b = *p;", unaryOperator(hasOperatorName("*"))));
2847 EXPECT_TRUE(
2848 matches("int i; int j = +i;", unaryOperator(hasOperatorName("+"))));
2849 EXPECT_TRUE(
2850 matches("int i; int j = -i;", unaryOperator(hasOperatorName("-"))));
2851 EXPECT_TRUE(
2852 matches("int i; int j = ++i;", unaryOperator(hasOperatorName("++"))));
2853 EXPECT_TRUE(
2854 matches("int i; int j = i++;", unaryOperator(hasOperatorName("++"))));
2855 EXPECT_TRUE(
2856 matches("int i; int j = --i;", unaryOperator(hasOperatorName("--"))));
2857 EXPECT_TRUE(
2858 matches("int i; int j = i--;", unaryOperator(hasOperatorName("--"))));
2859
2860 // We don't match conversion operators.
2861 EXPECT_TRUE(notMatches("int i; double d = (double)i;", unaryOperator()));
2862
2863 // Function calls are not represented as operator.
2864 EXPECT_TRUE(notMatches("void f(); void x() { f(); }", unaryOperator()));
2865
2866 // Overloaded operators do not match at all.
2867 // FIXME: We probably want to add that.
2868 EXPECT_TRUE(notMatches(
2869 "struct A { bool operator!() const { return false; } };"
2870 "void x() { A a; !a; }", unaryOperator(hasOperatorName("!"))));
2871}
2872
2873TEST(Matcher, ConditionalOperator) {
2874 StatementMatcher Conditional = conditionalOperator(
Aaron Ballman512fb642015-09-17 13:30:52 +00002875 hasCondition(cxxBoolLiteral(equals(true))),
2876 hasTrueExpression(cxxBoolLiteral(equals(false))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002877
2878 EXPECT_TRUE(matches("void x() { true ? false : true; }", Conditional));
2879 EXPECT_TRUE(notMatches("void x() { false ? false : true; }", Conditional));
2880 EXPECT_TRUE(notMatches("void x() { true ? true : false; }", Conditional));
2881
2882 StatementMatcher ConditionalFalse = conditionalOperator(
Aaron Ballman512fb642015-09-17 13:30:52 +00002883 hasFalseExpression(cxxBoolLiteral(equals(false))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002884
2885 EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse));
2886 EXPECT_TRUE(
2887 notMatches("void x() { true ? false : true; }", ConditionalFalse));
Aaron Ballmana35b8fc2016-03-09 17:11:51 +00002888
2889 EXPECT_TRUE(matches("void x() { true ? true : false; }", ConditionalFalse));
2890 EXPECT_TRUE(
2891 notMatches("void x() { true ? false : true; }", ConditionalFalse));
2892}
2893
2894TEST(Matcher, BinaryConditionalOperator) {
2895 StatementMatcher AlwaysOne = binaryConditionalOperator(
2896 hasCondition(implicitCastExpr(
2897 has(
2898 opaqueValueExpr(
2899 hasSourceExpression((integerLiteral(equals(1)))))))),
2900 hasFalseExpression(integerLiteral(equals(0))));
2901
2902 EXPECT_TRUE(matches("void x() { 1 ?: 0; }", AlwaysOne));
2903
2904 StatementMatcher FourNotFive = binaryConditionalOperator(
2905 hasTrueExpression(opaqueValueExpr(
2906 hasSourceExpression((integerLiteral(equals(4)))))),
2907 hasFalseExpression(integerLiteral(equals(5))));
2908
2909 EXPECT_TRUE(matches("void x() { 4 ?: 5; }", FourNotFive));
Manuel Klimek04616e42012-07-06 05:48:52 +00002910}
2911
Daniel Jasper1dad1832012-07-10 20:20:19 +00002912TEST(ArraySubscriptMatchers, ArraySubscripts) {
2913 EXPECT_TRUE(matches("int i[2]; void f() { i[1] = 1; }",
2914 arraySubscriptExpr()));
2915 EXPECT_TRUE(notMatches("int i; void f() { i = 1; }",
2916 arraySubscriptExpr()));
2917}
2918
2919TEST(ArraySubscriptMatchers, ArrayIndex) {
2920 EXPECT_TRUE(matches(
2921 "int i[2]; void f() { i[1] = 1; }",
2922 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
2923 EXPECT_TRUE(matches(
2924 "int i[2]; void f() { 1[i] = 1; }",
2925 arraySubscriptExpr(hasIndex(integerLiteral(equals(1))))));
2926 EXPECT_TRUE(notMatches(
2927 "int i[2]; void f() { i[1] = 1; }",
2928 arraySubscriptExpr(hasIndex(integerLiteral(equals(0))))));
2929}
2930
2931TEST(ArraySubscriptMatchers, MatchesArrayBase) {
2932 EXPECT_TRUE(matches(
2933 "int i[2]; void f() { i[1] = 2; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002934 arraySubscriptExpr(hasBase(implicitCastExpr(
2935 hasSourceExpression(declRefExpr()))))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00002936}
2937
Manuel Klimek04616e42012-07-06 05:48:52 +00002938TEST(Matcher, HasNameSupportsNamespaces) {
2939 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002940 recordDecl(hasName("a::b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002941 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002942 recordDecl(hasName("::a::b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002943 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002944 recordDecl(hasName("b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002945 EXPECT_TRUE(matches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002946 recordDecl(hasName("C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002947 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002948 recordDecl(hasName("c::b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002949 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002950 recordDecl(hasName("a::c::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002951 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002952 recordDecl(hasName("a::b::A"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002953 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002954 recordDecl(hasName("::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002955 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002956 recordDecl(hasName("::b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002957 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002958 recordDecl(hasName("z::a::b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002959 EXPECT_TRUE(notMatches("namespace a { namespace b { class C; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002960 recordDecl(hasName("a+b::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002961 EXPECT_TRUE(notMatches("namespace a { namespace b { class AC; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002962 recordDecl(hasName("C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002963}
2964
2965TEST(Matcher, HasNameSupportsOuterClasses) {
2966 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002967 matches("class A { class B { class C; }; };",
2968 recordDecl(hasName("A::B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002969 EXPECT_TRUE(
2970 matches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002971 recordDecl(hasName("::A::B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002972 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002973 matches("class A { class B { class C; }; };",
2974 recordDecl(hasName("B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002975 EXPECT_TRUE(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002976 matches("class A { class B { class C; }; };",
2977 recordDecl(hasName("C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002978 EXPECT_TRUE(
2979 notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002980 recordDecl(hasName("c::B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002981 EXPECT_TRUE(
2982 notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002983 recordDecl(hasName("A::c::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002984 EXPECT_TRUE(
2985 notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002986 recordDecl(hasName("A::B::A"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002987 EXPECT_TRUE(
2988 notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002989 recordDecl(hasName("::C"))));
2990 EXPECT_TRUE(
2991 notMatches("class A { class B { class C; }; };",
2992 recordDecl(hasName("::B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002993 EXPECT_TRUE(notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002994 recordDecl(hasName("z::A::B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002995 EXPECT_TRUE(
2996 notMatches("class A { class B { class C; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00002997 recordDecl(hasName("A+B::C"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00002998}
2999
Samuel Benzaquen8e566f32016-02-05 18:29:24 +00003000TEST(Matcher, HasNameSupportsInlinedNamespaces) {
3001 std::string code = "namespace a { inline namespace b { class C; } }";
3002 EXPECT_TRUE(matches(code, recordDecl(hasName("a::b::C"))));
3003 EXPECT_TRUE(matches(code, recordDecl(hasName("a::C"))));
3004 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::b::C"))));
3005 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::C"))));
3006}
3007
3008TEST(Matcher, HasNameSupportsAnonymousNamespaces) {
3009 std::string code = "namespace a { namespace { class C; } }";
3010 EXPECT_TRUE(
3011 matches(code, recordDecl(hasName("a::(anonymous namespace)::C"))));
3012 EXPECT_TRUE(matches(code, recordDecl(hasName("a::C"))));
3013 EXPECT_TRUE(
3014 matches(code, recordDecl(hasName("::a::(anonymous namespace)::C"))));
3015 EXPECT_TRUE(matches(code, recordDecl(hasName("::a::C"))));
3016}
3017
3018TEST(Matcher, HasNameSupportsAnonymousOuterClasses) {
3019 EXPECT_TRUE(matches("class A { class { class C; } x; };",
3020 recordDecl(hasName("A::(anonymous class)::C"))));
3021 EXPECT_TRUE(matches("class A { class { class C; } x; };",
3022 recordDecl(hasName("::A::(anonymous class)::C"))));
3023 EXPECT_FALSE(matches("class A { class { class C; } x; };",
3024 recordDecl(hasName("::A::C"))));
3025 EXPECT_TRUE(matches("class A { struct { class C; } x; };",
3026 recordDecl(hasName("A::(anonymous struct)::C"))));
3027 EXPECT_TRUE(matches("class A { struct { class C; } x; };",
3028 recordDecl(hasName("::A::(anonymous struct)::C"))));
3029 EXPECT_FALSE(matches("class A { struct { class C; } x; };",
3030 recordDecl(hasName("::A::C"))));
3031}
3032
3033TEST(Matcher, HasNameSupportsFunctionScope) {
3034 std::string code =
3035 "namespace a { void F(int a) { struct S { int m; }; int i; } }";
3036 EXPECT_TRUE(matches(code, varDecl(hasName("i"))));
3037 EXPECT_FALSE(matches(code, varDecl(hasName("F()::i"))));
3038
3039 EXPECT_TRUE(matches(code, fieldDecl(hasName("m"))));
3040 EXPECT_TRUE(matches(code, fieldDecl(hasName("S::m"))));
3041 EXPECT_TRUE(matches(code, fieldDecl(hasName("F(int)::S::m"))));
3042 EXPECT_TRUE(matches(code, fieldDecl(hasName("a::F(int)::S::m"))));
3043 EXPECT_TRUE(matches(code, fieldDecl(hasName("::a::F(int)::S::m"))));
3044}
3045
Samuel Benzaquen922bef42016-02-22 21:13:02 +00003046TEST(Matcher, HasAnyName) {
3047 const std::string Code = "namespace a { namespace b { class C; } }";
3048
3049 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX", "a::b::C"))));
3050 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("a::b::C", "XX"))));
3051 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX::C", "a::b::C"))));
3052 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName("XX", "C"))));
3053
3054 EXPECT_TRUE(notMatches(Code, recordDecl(hasAnyName("::C", "::b::C"))));
3055 EXPECT_TRUE(
3056 matches(Code, recordDecl(hasAnyName("::C", "::b::C", "::a::b::C"))));
Samuel Benzaquenc1384c12016-03-25 16:29:30 +00003057
3058 std::vector<StringRef> Names = {"::C", "::b::C", "::a::b::C"};
3059 EXPECT_TRUE(matches(Code, recordDecl(hasAnyName(Names))));
Samuel Benzaquen922bef42016-02-22 21:13:02 +00003060}
3061
Manuel Klimek04616e42012-07-06 05:48:52 +00003062TEST(Matcher, IsDefinition) {
3063 DeclarationMatcher DefinitionOfClassA =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003064 recordDecl(hasName("A"), isDefinition());
Manuel Klimek04616e42012-07-06 05:48:52 +00003065 EXPECT_TRUE(matches("class A {};", DefinitionOfClassA));
3066 EXPECT_TRUE(notMatches("class A;", DefinitionOfClassA));
3067
3068 DeclarationMatcher DefinitionOfVariableA =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003069 varDecl(hasName("a"), isDefinition());
Manuel Klimek04616e42012-07-06 05:48:52 +00003070 EXPECT_TRUE(matches("int a;", DefinitionOfVariableA));
3071 EXPECT_TRUE(notMatches("extern int a;", DefinitionOfVariableA));
3072
3073 DeclarationMatcher DefinitionOfMethodA =
Aaron Ballman512fb642015-09-17 13:30:52 +00003074 cxxMethodDecl(hasName("a"), isDefinition());
Manuel Klimek04616e42012-07-06 05:48:52 +00003075 EXPECT_TRUE(matches("class A { void a() {} };", DefinitionOfMethodA));
3076 EXPECT_TRUE(notMatches("class A { void a(); };", DefinitionOfMethodA));
3077}
3078
3079TEST(Matcher, OfClass) {
Aaron Ballman512fb642015-09-17 13:30:52 +00003080 StatementMatcher Constructor = cxxConstructExpr(hasDeclaration(cxxMethodDecl(
Manuel Klimek04616e42012-07-06 05:48:52 +00003081 ofClass(hasName("X")))));
3082
3083 EXPECT_TRUE(
3084 matches("class X { public: X(); }; void x(int) { X x; }", Constructor));
3085 EXPECT_TRUE(
3086 matches("class X { public: X(); }; void x(int) { X x = X(); }",
3087 Constructor));
3088 EXPECT_TRUE(
3089 notMatches("class Y { public: Y(); }; void x(int) { Y y; }",
3090 Constructor));
3091}
3092
3093TEST(Matcher, VisitsTemplateInstantiations) {
3094 EXPECT_TRUE(matches(
3095 "class A { public: void x(); };"
3096 "template <typename T> class B { public: void y() { T t; t.x(); } };"
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003097 "void f() { B<A> b; b.y(); }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003098 callExpr(callee(cxxMethodDecl(hasName("x"))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003099
3100 EXPECT_TRUE(matches(
3101 "class A { public: void x(); };"
3102 "class C {"
3103 " public:"
3104 " template <typename T> class B { public: void y() { T t; t.x(); } };"
3105 "};"
3106 "void f() {"
3107 " C::B<A> b; b.y();"
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003108 "}",
Aaron Ballman512fb642015-09-17 13:30:52 +00003109 recordDecl(hasName("C"), hasDescendant(callExpr(
3110 callee(cxxMethodDecl(hasName("x"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003111}
3112
Daniel Jasper1dad1832012-07-10 20:20:19 +00003113TEST(Matcher, HandlesNullQualTypes) {
3114 // FIXME: Add a Type matcher so we can replace uses of this
3115 // variable with Type(True())
3116 const TypeMatcher AnyType = anything();
3117
3118 // We don't really care whether this matcher succeeds; we're testing that
3119 // it completes without crashing.
3120 EXPECT_TRUE(matches(
3121 "struct A { };"
3122 "template <typename T>"
3123 "void f(T t) {"
3124 " T local_t(t /* this becomes a null QualType in the AST */);"
3125 "}"
3126 "void g() {"
3127 " f(0);"
3128 "}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003129 expr(hasType(TypeMatcher(
Daniel Jasper1dad1832012-07-10 20:20:19 +00003130 anyOf(
3131 TypeMatcher(hasDeclaration(anything())),
3132 pointsTo(AnyType),
3133 references(AnyType)
3134 // Other QualType matchers should go here.
3135 ))))));
3136}
3137
Manuel Klimek04616e42012-07-06 05:48:52 +00003138// For testing AST_MATCHER_P().
Daniel Jasper1dad1832012-07-10 20:20:19 +00003139AST_MATCHER_P(Decl, just, internal::Matcher<Decl>, AMatcher) {
Manuel Klimek04616e42012-07-06 05:48:52 +00003140 // Make sure all special variables are used: node, match_finder,
3141 // bound_nodes_builder, and the parameter named 'AMatcher'.
3142 return AMatcher.matches(Node, Finder, Builder);
3143}
3144
3145TEST(AstMatcherPMacro, Works) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003146 DeclarationMatcher HasClassB = just(has(recordDecl(hasName("B")).bind("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003147
3148 EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003149 HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003150
3151 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003152 HasClassB, new VerifyIdIsBoundTo<Decl>("a")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003153
3154 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003155 HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003156}
3157
Benjamin Kramer57dd9bd2015-03-07 20:38:15 +00003158AST_POLYMORPHIC_MATCHER_P(polymorphicHas,
3159 AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt),
3160 internal::Matcher<Decl>, AMatcher) {
Manuel Klimek04616e42012-07-06 05:48:52 +00003161 return Finder->matchesChildOf(
Manuel Klimekeb958de2012-09-05 12:12:07 +00003162 Node, AMatcher, Builder,
Manuel Klimek04616e42012-07-06 05:48:52 +00003163 ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
3164 ASTMatchFinder::BK_First);
3165}
3166
3167TEST(AstPolymorphicMatcherPMacro, Works) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003168 DeclarationMatcher HasClassB =
3169 polymorphicHas(recordDecl(hasName("B")).bind("b"));
Manuel Klimek04616e42012-07-06 05:48:52 +00003170
3171 EXPECT_TRUE(matchAndVerifyResultTrue("class A { class B {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003172 HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003173
3174 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class B {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003175 HasClassB, new VerifyIdIsBoundTo<Decl>("a")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003176
3177 EXPECT_TRUE(matchAndVerifyResultFalse("class A { class C {}; };",
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003178 HasClassB, new VerifyIdIsBoundTo<Decl>("b")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003179
3180 StatementMatcher StatementHasClassB =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003181 polymorphicHas(recordDecl(hasName("B")));
Manuel Klimek04616e42012-07-06 05:48:52 +00003182
3183 EXPECT_TRUE(matches("void x() { class B {}; }", StatementHasClassB));
3184}
3185
3186TEST(For, FindsForLoops) {
3187 EXPECT_TRUE(matches("void f() { for(;;); }", forStmt()));
3188 EXPECT_TRUE(matches("void f() { if(true) for(;;); }", forStmt()));
Daniel Jasper6f595392012-10-01 15:05:34 +00003189 EXPECT_TRUE(notMatches("int as[] = { 1, 2, 3 };"
3190 "void f() { for (auto &a : as); }",
Daniel Jasper5901e472012-10-01 13:40:41 +00003191 forStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003192}
3193
Daniel Jasper4e566c42012-07-12 08:50:38 +00003194TEST(For, ForLoopInternals) {
3195 EXPECT_TRUE(matches("void f(){ int i; for (; i < 3 ; ); }",
3196 forStmt(hasCondition(anything()))));
3197 EXPECT_TRUE(matches("void f() { for (int i = 0; ;); }",
3198 forStmt(hasLoopInit(anything()))));
3199}
3200
Alexander Kornienko9b539e12014-02-05 16:35:08 +00003201TEST(For, ForRangeLoopInternals) {
3202 EXPECT_TRUE(matches("void f(){ int a[] {1, 2}; for (int i : a); }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003203 cxxForRangeStmt(hasLoopVariable(anything()))));
Manuel Klimek86510812014-05-23 17:49:03 +00003204 EXPECT_TRUE(matches(
3205 "void f(){ int a[] {1, 2}; for (int i : a); }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003206 cxxForRangeStmt(hasRangeInit(declRefExpr(to(varDecl(hasName("a"))))))));
Alexander Kornienko9b539e12014-02-05 16:35:08 +00003207}
3208
Daniel Jasper4e566c42012-07-12 08:50:38 +00003209TEST(For, NegativeForLoopInternals) {
3210 EXPECT_TRUE(notMatches("void f(){ for (int i = 0; ; ++i); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003211 forStmt(hasCondition(expr()))));
Daniel Jasper4e566c42012-07-12 08:50:38 +00003212 EXPECT_TRUE(notMatches("void f() {int i; for (; i < 4; ++i) {} }",
3213 forStmt(hasLoopInit(anything()))));
3214}
3215
Manuel Klimek04616e42012-07-06 05:48:52 +00003216TEST(For, ReportsNoFalsePositives) {
3217 EXPECT_TRUE(notMatches("void f() { ; }", forStmt()));
3218 EXPECT_TRUE(notMatches("void f() { if(true); }", forStmt()));
3219}
3220
3221TEST(CompoundStatement, HandlesSimpleCases) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003222 EXPECT_TRUE(notMatches("void f();", compoundStmt()));
3223 EXPECT_TRUE(matches("void f() {}", compoundStmt()));
3224 EXPECT_TRUE(matches("void f() {{}}", compoundStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003225}
3226
3227TEST(CompoundStatement, DoesNotMatchEmptyStruct) {
3228 // It's not a compound statement just because there's "{}" in the source
3229 // text. This is an AST search, not grep.
3230 EXPECT_TRUE(notMatches("namespace n { struct S {}; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003231 compoundStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003232 EXPECT_TRUE(matches("namespace n { struct S { void f() {{}} }; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003233 compoundStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003234}
3235
Daniel Jasper4e566c42012-07-12 08:50:38 +00003236TEST(HasBody, FindsBodyOfForWhileDoLoops) {
Manuel Klimek04616e42012-07-06 05:48:52 +00003237 EXPECT_TRUE(matches("void f() { for(;;) {} }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003238 forStmt(hasBody(compoundStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003239 EXPECT_TRUE(notMatches("void f() { for(;;); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003240 forStmt(hasBody(compoundStmt()))));
Daniel Jasper4e566c42012-07-12 08:50:38 +00003241 EXPECT_TRUE(matches("void f() { while(true) {} }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003242 whileStmt(hasBody(compoundStmt()))));
Daniel Jasper4e566c42012-07-12 08:50:38 +00003243 EXPECT_TRUE(matches("void f() { do {} while(true); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003244 doStmt(hasBody(compoundStmt()))));
Manuel Klimek2af0a912014-05-27 07:45:18 +00003245 EXPECT_TRUE(matches("void f() { int p[2]; for (auto x : p) {} }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003246 cxxForRangeStmt(hasBody(compoundStmt()))));
Aaron Ballman2b6963f2016-01-20 16:26:48 +00003247 EXPECT_TRUE(matches("void f() {}", functionDecl(hasBody(compoundStmt()))));
3248 EXPECT_TRUE(notMatches("void f();", functionDecl(hasBody(compoundStmt()))));
3249 EXPECT_TRUE(matches("void f(); void f() {}",
3250 functionDecl(hasBody(compoundStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003251}
3252
3253TEST(HasAnySubstatement, MatchesForTopLevelCompoundStatement) {
3254 // The simplest case: every compound statement is in a function
3255 // definition, and the function body itself must be a compound
3256 // statement.
3257 EXPECT_TRUE(matches("void f() { for (;;); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003258 compoundStmt(hasAnySubstatement(forStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003259}
3260
3261TEST(HasAnySubstatement, IsNotRecursive) {
3262 // It's really "has any immediate substatement".
3263 EXPECT_TRUE(notMatches("void f() { if (true) for (;;); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003264 compoundStmt(hasAnySubstatement(forStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003265}
3266
3267TEST(HasAnySubstatement, MatchesInNestedCompoundStatements) {
3268 EXPECT_TRUE(matches("void f() { if (true) { for (;;); } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003269 compoundStmt(hasAnySubstatement(forStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003270}
3271
3272TEST(HasAnySubstatement, FindsSubstatementBetweenOthers) {
3273 EXPECT_TRUE(matches("void f() { 1; 2; 3; for (;;); 4; 5; 6; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003274 compoundStmt(hasAnySubstatement(forStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003275}
3276
3277TEST(StatementCountIs, FindsNoStatementsInAnEmptyCompoundStatement) {
3278 EXPECT_TRUE(matches("void f() { }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003279 compoundStmt(statementCountIs(0))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003280 EXPECT_TRUE(notMatches("void f() {}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003281 compoundStmt(statementCountIs(1))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003282}
3283
3284TEST(StatementCountIs, AppearsToMatchOnlyOneCount) {
3285 EXPECT_TRUE(matches("void f() { 1; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003286 compoundStmt(statementCountIs(1))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003287 EXPECT_TRUE(notMatches("void f() { 1; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003288 compoundStmt(statementCountIs(0))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003289 EXPECT_TRUE(notMatches("void f() { 1; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003290 compoundStmt(statementCountIs(2))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003291}
3292
3293TEST(StatementCountIs, WorksWithMultipleStatements) {
3294 EXPECT_TRUE(matches("void f() { 1; 2; 3; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003295 compoundStmt(statementCountIs(3))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003296}
3297
3298TEST(StatementCountIs, WorksWithNestedCompoundStatements) {
3299 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003300 compoundStmt(statementCountIs(1))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003301 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003302 compoundStmt(statementCountIs(2))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003303 EXPECT_TRUE(notMatches("void f() { { 1; } { 1; 2; 3; 4; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003304 compoundStmt(statementCountIs(3))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003305 EXPECT_TRUE(matches("void f() { { 1; } { 1; 2; 3; 4; } }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003306 compoundStmt(statementCountIs(4))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003307}
3308
3309TEST(Member, WorksInSimplestCase) {
3310 EXPECT_TRUE(matches("struct { int first; } s; int i(s.first);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003311 memberExpr(member(hasName("first")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003312}
3313
3314TEST(Member, DoesNotMatchTheBaseExpression) {
3315 // Don't pick out the wrong part of the member expression, this should
3316 // be checking the member (name) only.
3317 EXPECT_TRUE(notMatches("struct { int i; } first; int i(first.i);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003318 memberExpr(member(hasName("first")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003319}
3320
3321TEST(Member, MatchesInMemberFunctionCall) {
3322 EXPECT_TRUE(matches("void f() {"
3323 " struct { void first() {}; } s;"
3324 " s.first();"
3325 "};",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003326 memberExpr(member(hasName("first")))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003327}
3328
Daniel Jasperb0c7b612012-10-23 15:46:39 +00003329TEST(Member, MatchesMember) {
3330 EXPECT_TRUE(matches(
3331 "struct A { int i; }; void f() { A a; a.i = 2; }",
3332 memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
3333 EXPECT_TRUE(notMatches(
3334 "struct A { float f; }; void f() { A a; a.f = 2.0f; }",
3335 memberExpr(hasDeclaration(fieldDecl(hasType(isInteger()))))));
3336}
3337
Daniel Jasper639522c2013-02-25 12:02:08 +00003338TEST(Member, UnderstandsAccess) {
3339 EXPECT_TRUE(matches(
3340 "struct A { int i; };", fieldDecl(isPublic(), hasName("i"))));
3341 EXPECT_TRUE(notMatches(
3342 "struct A { int i; };", fieldDecl(isProtected(), hasName("i"))));
3343 EXPECT_TRUE(notMatches(
3344 "struct A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
3345
3346 EXPECT_TRUE(notMatches(
3347 "class A { int i; };", fieldDecl(isPublic(), hasName("i"))));
3348 EXPECT_TRUE(notMatches(
3349 "class A { int i; };", fieldDecl(isProtected(), hasName("i"))));
3350 EXPECT_TRUE(matches(
3351 "class A { int i; };", fieldDecl(isPrivate(), hasName("i"))));
3352
3353 EXPECT_TRUE(notMatches(
3354 "class A { protected: int i; };", fieldDecl(isPublic(), hasName("i"))));
3355 EXPECT_TRUE(matches("class A { protected: int i; };",
3356 fieldDecl(isProtected(), hasName("i"))));
3357 EXPECT_TRUE(notMatches(
3358 "class A { protected: int i; };", fieldDecl(isPrivate(), hasName("i"))));
3359
3360 // Non-member decls have the AccessSpecifier AS_none and thus aren't matched.
3361 EXPECT_TRUE(notMatches("int i;", varDecl(isPublic(), hasName("i"))));
3362 EXPECT_TRUE(notMatches("int i;", varDecl(isProtected(), hasName("i"))));
3363 EXPECT_TRUE(notMatches("int i;", varDecl(isPrivate(), hasName("i"))));
3364}
3365
Dmitri Gribenko06963042012-08-18 00:29:27 +00003366TEST(Member, MatchesMemberAllocationFunction) {
Daniel Jasper5901e472012-10-01 13:40:41 +00003367 // Fails in C++11 mode
3368 EXPECT_TRUE(matchesConditionally(
3369 "namespace std { typedef typeof(sizeof(int)) size_t; }"
3370 "class X { void *operator new(std::size_t); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00003371 cxxMethodDecl(ofClass(hasName("X"))), true, "-std=gnu++98"));
Dmitri Gribenko06963042012-08-18 00:29:27 +00003372
3373 EXPECT_TRUE(matches("class X { void operator delete(void*); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00003374 cxxMethodDecl(ofClass(hasName("X")))));
Dmitri Gribenko06963042012-08-18 00:29:27 +00003375
Daniel Jasper5901e472012-10-01 13:40:41 +00003376 // Fails in C++11 mode
3377 EXPECT_TRUE(matchesConditionally(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003378 "namespace std { typedef typeof(sizeof(int)) size_t; }"
3379 "class X { void operator delete[](void*, std::size_t); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00003380 cxxMethodDecl(ofClass(hasName("X"))), true, "-std=gnu++98"));
Dmitri Gribenko06963042012-08-18 00:29:27 +00003381}
3382
Manuel Klimek04616e42012-07-06 05:48:52 +00003383TEST(HasObjectExpression, DoesNotMatchMember) {
3384 EXPECT_TRUE(notMatches(
3385 "class X {}; struct Z { X m; }; void f(Z z) { z.m; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003386 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003387}
3388
3389TEST(HasObjectExpression, MatchesBaseOfVariable) {
3390 EXPECT_TRUE(matches(
3391 "struct X { int m; }; void f(X x) { x.m; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003392 memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003393 EXPECT_TRUE(matches(
3394 "struct X { int m; }; void f(X* x) { x->m; }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003395 memberExpr(hasObjectExpression(
3396 hasType(pointsTo(recordDecl(hasName("X"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003397}
3398
3399TEST(HasObjectExpression,
3400 MatchesObjectExpressionOfImplicitlyFormedMemberExpression) {
3401 EXPECT_TRUE(matches(
3402 "class X {}; struct S { X m; void f() { this->m; } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003403 memberExpr(hasObjectExpression(
3404 hasType(pointsTo(recordDecl(hasName("S"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003405 EXPECT_TRUE(matches(
3406 "class X {}; struct S { X m; void f() { m; } };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003407 memberExpr(hasObjectExpression(
3408 hasType(pointsTo(recordDecl(hasName("S"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003409}
3410
3411TEST(Field, DoesNotMatchNonFieldMembers) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003412 EXPECT_TRUE(notMatches("class X { void m(); };", fieldDecl(hasName("m"))));
3413 EXPECT_TRUE(notMatches("class X { class m {}; };", fieldDecl(hasName("m"))));
3414 EXPECT_TRUE(notMatches("class X { enum { m }; };", fieldDecl(hasName("m"))));
3415 EXPECT_TRUE(notMatches("class X { enum m {}; };", fieldDecl(hasName("m"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003416}
3417
3418TEST(Field, MatchesField) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003419 EXPECT_TRUE(matches("class X { int m; };", fieldDecl(hasName("m"))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003420}
3421
Aaron Ballman6290fc92015-11-23 17:09:24 +00003422TEST(IsVolatileQualified, QualifiersMatch) {
3423 EXPECT_TRUE(matches("volatile int i = 42;",
3424 varDecl(hasType(isVolatileQualified()))));
3425 EXPECT_TRUE(notMatches("volatile int *i;",
3426 varDecl(hasType(isVolatileQualified()))));
3427 EXPECT_TRUE(matches("typedef volatile int v_int; v_int i = 42;",
3428 varDecl(hasType(isVolatileQualified()))));
3429}
3430
Manuel Klimek04616e42012-07-06 05:48:52 +00003431TEST(IsConstQualified, MatchesConstInt) {
3432 EXPECT_TRUE(matches("const int i = 42;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003433 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003434}
3435
3436TEST(IsConstQualified, MatchesConstPointer) {
3437 EXPECT_TRUE(matches("int i = 42; int* const p(&i);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003438 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003439}
3440
3441TEST(IsConstQualified, MatchesThroughTypedef) {
3442 EXPECT_TRUE(matches("typedef const int const_int; const_int i = 42;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003443 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003444 EXPECT_TRUE(matches("typedef int* int_ptr; const int_ptr p(0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003445 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003446}
3447
3448TEST(IsConstQualified, DoesNotMatchInappropriately) {
3449 EXPECT_TRUE(notMatches("typedef int nonconst_int; nonconst_int i = 42;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003450 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003451 EXPECT_TRUE(notMatches("int const* p;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003452 varDecl(hasType(isConstQualified()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003453}
3454
Sam Panzer80c13772012-08-16 16:58:10 +00003455TEST(CastExpression, MatchesExplicitCasts) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00003456 EXPECT_TRUE(matches("char *p = reinterpret_cast<char *>(&p);",castExpr()));
3457 EXPECT_TRUE(matches("void *p = (void *)(&p);", castExpr()));
3458 EXPECT_TRUE(matches("char q, *p = const_cast<char *>(&q);", castExpr()));
3459 EXPECT_TRUE(matches("char c = char(0);", castExpr()));
Sam Panzer80c13772012-08-16 16:58:10 +00003460}
3461TEST(CastExpression, MatchesImplicitCasts) {
3462 // This test creates an implicit cast from int to char.
Daniel Jasper848cbe12012-09-18 13:09:13 +00003463 EXPECT_TRUE(matches("char c = 0;", castExpr()));
Sam Panzer80c13772012-08-16 16:58:10 +00003464 // This test creates an implicit cast from lvalue to rvalue.
Daniel Jasper848cbe12012-09-18 13:09:13 +00003465 EXPECT_TRUE(matches("char c = 0, d = c;", castExpr()));
Sam Panzer80c13772012-08-16 16:58:10 +00003466}
3467
3468TEST(CastExpression, DoesNotMatchNonCasts) {
Daniel Jasper848cbe12012-09-18 13:09:13 +00003469 EXPECT_TRUE(notMatches("char c = '0';", castExpr()));
3470 EXPECT_TRUE(notMatches("char c, &q = c;", castExpr()));
3471 EXPECT_TRUE(notMatches("int i = (0);", castExpr()));
3472 EXPECT_TRUE(notMatches("int i = 0;", castExpr()));
Sam Panzer80c13772012-08-16 16:58:10 +00003473}
3474
Manuel Klimek04616e42012-07-06 05:48:52 +00003475TEST(ReinterpretCast, MatchesSimpleCase) {
3476 EXPECT_TRUE(matches("char* p = reinterpret_cast<char*>(&p);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003477 cxxReinterpretCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003478}
3479
3480TEST(ReinterpretCast, DoesNotMatchOtherCasts) {
Aaron Ballman512fb642015-09-17 13:30:52 +00003481 EXPECT_TRUE(notMatches("char* p = (char*)(&p);", cxxReinterpretCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003482 EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003483 cxxReinterpretCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003484 EXPECT_TRUE(notMatches("void* p = static_cast<void*>(&p);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003485 cxxReinterpretCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003486 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
3487 "B b;"
3488 "D* p = dynamic_cast<D*>(&b);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003489 cxxReinterpretCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003490}
3491
3492TEST(FunctionalCast, MatchesSimpleCase) {
Ismail Pazarbasi1121de32014-01-17 21:08:52 +00003493 std::string foo_class = "class Foo { public: Foo(const char*); };";
Manuel Klimek04616e42012-07-06 05:48:52 +00003494 EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello world\"); }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003495 cxxFunctionalCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003496}
3497
3498TEST(FunctionalCast, DoesNotMatchOtherCasts) {
Ismail Pazarbasi1121de32014-01-17 21:08:52 +00003499 std::string FooClass = "class Foo { public: Foo(const char*); };";
Manuel Klimek04616e42012-07-06 05:48:52 +00003500 EXPECT_TRUE(
3501 notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\"; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003502 cxxFunctionalCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003503 EXPECT_TRUE(
3504 notMatches(FooClass + "void r() { Foo f = \"hello world\"; }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003505 cxxFunctionalCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003506}
3507
3508TEST(DynamicCast, MatchesSimpleCase) {
3509 EXPECT_TRUE(matches("struct B { virtual ~B() {} }; struct D : B {};"
3510 "B b;"
3511 "D* p = dynamic_cast<D*>(&b);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003512 cxxDynamicCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003513}
3514
3515TEST(StaticCast, MatchesSimpleCase) {
3516 EXPECT_TRUE(matches("void* p(static_cast<void*>(&p));",
Aaron Ballman512fb642015-09-17 13:30:52 +00003517 cxxStaticCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003518}
3519
3520TEST(StaticCast, DoesNotMatchOtherCasts) {
Aaron Ballman512fb642015-09-17 13:30:52 +00003521 EXPECT_TRUE(notMatches("char* p = (char*)(&p);", cxxStaticCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003522 EXPECT_TRUE(notMatches("char q, *p = const_cast<char*>(&q);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003523 cxxStaticCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003524 EXPECT_TRUE(notMatches("void* p = reinterpret_cast<char*>(&p);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003525 cxxStaticCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003526 EXPECT_TRUE(notMatches("struct B { virtual ~B() {} }; struct D : B {};"
3527 "B b;"
3528 "D* p = dynamic_cast<D*>(&b);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003529 cxxStaticCastExpr()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003530}
3531
Daniel Jasper417f7762012-09-18 13:36:17 +00003532TEST(CStyleCast, MatchesSimpleCase) {
3533 EXPECT_TRUE(matches("int i = (int) 2.2f;", cStyleCastExpr()));
3534}
3535
3536TEST(CStyleCast, DoesNotMatchOtherCasts) {
3537 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);"
3538 "char q, *r = const_cast<char*>(&q);"
3539 "void* s = reinterpret_cast<char*>(&s);"
3540 "struct B { virtual ~B() {} }; struct D : B {};"
3541 "B b;"
3542 "D* t = dynamic_cast<D*>(&b);",
3543 cStyleCastExpr()));
3544}
3545
Manuel Klimek04616e42012-07-06 05:48:52 +00003546TEST(HasDestinationType, MatchesSimpleCase) {
3547 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
Aaron Ballman512fb642015-09-17 13:30:52 +00003548 cxxStaticCastExpr(hasDestinationType(
Daniel Jasper848cbe12012-09-18 13:09:13 +00003549 pointsTo(TypeMatcher(anything()))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003550}
3551
Sam Panzer80c13772012-08-16 16:58:10 +00003552TEST(HasImplicitDestinationType, MatchesSimpleCase) {
3553 // This test creates an implicit const cast.
3554 EXPECT_TRUE(matches("int x; const int i = x;",
Daniel Jasper848cbe12012-09-18 13:09:13 +00003555 implicitCastExpr(
3556 hasImplicitDestinationType(isInteger()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003557 // This test creates an implicit array-to-pointer cast.
3558 EXPECT_TRUE(matches("int arr[3]; int *p = arr;",
Daniel Jasper848cbe12012-09-18 13:09:13 +00003559 implicitCastExpr(hasImplicitDestinationType(
3560 pointsTo(TypeMatcher(anything()))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003561}
3562
3563TEST(HasImplicitDestinationType, DoesNotMatchIncorrectly) {
3564 // This test creates an implicit cast from int to char.
3565 EXPECT_TRUE(notMatches("char c = 0;",
Daniel Jasper848cbe12012-09-18 13:09:13 +00003566 implicitCastExpr(hasImplicitDestinationType(
3567 unless(anything())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003568 // This test creates an implicit array-to-pointer cast.
3569 EXPECT_TRUE(notMatches("int arr[3]; int *p = arr;",
Daniel Jasper848cbe12012-09-18 13:09:13 +00003570 implicitCastExpr(hasImplicitDestinationType(
3571 unless(anything())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003572}
3573
3574TEST(ImplicitCast, MatchesSimpleCase) {
3575 // This test creates an implicit const cast.
3576 EXPECT_TRUE(matches("int x = 0; const int y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003577 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003578 // This test creates an implicit cast from int to char.
3579 EXPECT_TRUE(matches("char c = 0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003580 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003581 // This test creates an implicit array-to-pointer cast.
3582 EXPECT_TRUE(matches("int arr[6]; int *p = arr;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003583 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003584}
3585
3586TEST(ImplicitCast, DoesNotMatchIncorrectly) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003587 // This test verifies that implicitCastExpr() matches exactly when implicit casts
Sam Panzer80c13772012-08-16 16:58:10 +00003588 // are present, and that it ignores explicit and paren casts.
3589
3590 // These two test cases have no casts.
3591 EXPECT_TRUE(notMatches("int x = 0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003592 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003593 EXPECT_TRUE(notMatches("int x = 0, &y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003594 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003595
3596 EXPECT_TRUE(notMatches("int x = 0; double d = (double) x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003597 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003598 EXPECT_TRUE(notMatches("const int *p; int *q = const_cast<int *>(p);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003599 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003600
3601 EXPECT_TRUE(notMatches("int x = (0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003602 varDecl(hasInitializer(implicitCastExpr()))));
Sam Panzer80c13772012-08-16 16:58:10 +00003603}
3604
3605TEST(IgnoringImpCasts, MatchesImpCasts) {
3606 // This test checks that ignoringImpCasts matches when implicit casts are
3607 // present and its inner matcher alone does not match.
3608 // Note that this test creates an implicit const cast.
3609 EXPECT_TRUE(matches("int x = 0; const int y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003610 varDecl(hasInitializer(ignoringImpCasts(
3611 declRefExpr(to(varDecl(hasName("x")))))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003612 // This test creates an implict cast from int to char.
3613 EXPECT_TRUE(matches("char x = 0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003614 varDecl(hasInitializer(ignoringImpCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003615 integerLiteral(equals(0)))))));
3616}
3617
3618TEST(IgnoringImpCasts, DoesNotMatchIncorrectly) {
3619 // These tests verify that ignoringImpCasts does not match if the inner
3620 // matcher does not match.
3621 // Note that the first test creates an implicit const cast.
3622 EXPECT_TRUE(notMatches("int x; const int y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003623 varDecl(hasInitializer(ignoringImpCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003624 unless(anything()))))));
3625 EXPECT_TRUE(notMatches("int x; int y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003626 varDecl(hasInitializer(ignoringImpCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003627 unless(anything()))))));
3628
3629 // These tests verify that ignoringImplictCasts does not look through explicit
3630 // casts or parentheses.
3631 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003632 varDecl(hasInitializer(ignoringImpCasts(
3633 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003634 EXPECT_TRUE(notMatches("int i = (0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003635 varDecl(hasInitializer(ignoringImpCasts(
3636 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003637 EXPECT_TRUE(notMatches("float i = (float)0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003638 varDecl(hasInitializer(ignoringImpCasts(
3639 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003640 EXPECT_TRUE(notMatches("float i = float(0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003641 varDecl(hasInitializer(ignoringImpCasts(
3642 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003643}
3644
3645TEST(IgnoringImpCasts, MatchesWithoutImpCasts) {
3646 // This test verifies that expressions that do not have implicit casts
3647 // still match the inner matcher.
3648 EXPECT_TRUE(matches("int x = 0; int &y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003649 varDecl(hasInitializer(ignoringImpCasts(
3650 declRefExpr(to(varDecl(hasName("x")))))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003651}
3652
3653TEST(IgnoringParenCasts, MatchesParenCasts) {
3654 // This test checks that ignoringParenCasts matches when parentheses and/or
3655 // casts are present and its inner matcher alone does not match.
3656 EXPECT_TRUE(matches("int x = (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("int x = (((((0)))));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003660 varDecl(hasInitializer(ignoringParenCasts(
3661 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003662
3663 // This test creates an implict cast from int to char in addition to the
3664 // parentheses.
3665 EXPECT_TRUE(matches("char x = (0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003666 varDecl(hasInitializer(ignoringParenCasts(
3667 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003668
3669 EXPECT_TRUE(matches("char x = (char)0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003670 varDecl(hasInitializer(ignoringParenCasts(
3671 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003672 EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003673 varDecl(hasInitializer(ignoringParenCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003674 integerLiteral(equals(0)))))));
3675}
3676
3677TEST(IgnoringParenCasts, MatchesWithoutParenCasts) {
3678 // This test verifies that expressions that do not have any casts still match.
3679 EXPECT_TRUE(matches("int x = 0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003680 varDecl(hasInitializer(ignoringParenCasts(
3681 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003682}
3683
3684TEST(IgnoringParenCasts, DoesNotMatchIncorrectly) {
3685 // These tests verify that ignoringImpCasts does not match if the inner
3686 // matcher does not match.
3687 EXPECT_TRUE(notMatches("int x = ((0));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003688 varDecl(hasInitializer(ignoringParenCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003689 unless(anything()))))));
3690
3691 // This test creates an implicit cast from int to char in addition to the
3692 // parentheses.
3693 EXPECT_TRUE(notMatches("char x = ((0));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003694 varDecl(hasInitializer(ignoringParenCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003695 unless(anything()))))));
3696
3697 EXPECT_TRUE(notMatches("char *x = static_cast<char *>((0));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003698 varDecl(hasInitializer(ignoringParenCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003699 unless(anything()))))));
3700}
3701
3702TEST(IgnoringParenAndImpCasts, MatchesParenImpCasts) {
3703 // This test checks that ignoringParenAndImpCasts matches when
3704 // parentheses and/or implicit casts are present and its inner matcher alone
3705 // does not match.
3706 // Note that this test creates an implicit const cast.
3707 EXPECT_TRUE(matches("int x = 0; const int y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003708 varDecl(hasInitializer(ignoringParenImpCasts(
3709 declRefExpr(to(varDecl(hasName("x")))))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003710 // This test creates an implicit cast from int to char.
3711 EXPECT_TRUE(matches("const char x = (0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003712 varDecl(hasInitializer(ignoringParenImpCasts(
3713 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003714}
3715
3716TEST(IgnoringParenAndImpCasts, MatchesWithoutParenImpCasts) {
3717 // This test verifies that expressions that do not have parentheses or
3718 // implicit casts still match.
3719 EXPECT_TRUE(matches("int x = 0; int &y = x;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003720 varDecl(hasInitializer(ignoringParenImpCasts(
3721 declRefExpr(to(varDecl(hasName("x")))))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003722 EXPECT_TRUE(matches("int x = 0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003723 varDecl(hasInitializer(ignoringParenImpCasts(
3724 integerLiteral(equals(0)))))));
Sam Panzer80c13772012-08-16 16:58:10 +00003725}
3726
3727TEST(IgnoringParenAndImpCasts, DoesNotMatchIncorrectly) {
3728 // These tests verify that ignoringParenImpCasts does not match if
3729 // the inner matcher does not match.
3730 // This test creates an implicit cast.
3731 EXPECT_TRUE(notMatches("char c = ((3));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003732 varDecl(hasInitializer(ignoringParenImpCasts(
Sam Panzer80c13772012-08-16 16:58:10 +00003733 unless(anything()))))));
3734 // These tests verify that ignoringParenAndImplictCasts does not look
3735 // through explicit casts.
3736 EXPECT_TRUE(notMatches("float y = (float(0));",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003737 varDecl(hasInitializer(ignoringParenImpCasts(
3738 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003739 EXPECT_TRUE(notMatches("float y = (float)0;",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003740 varDecl(hasInitializer(ignoringParenImpCasts(
3741 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003742 EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003743 varDecl(hasInitializer(ignoringParenImpCasts(
3744 integerLiteral())))));
Sam Panzer80c13772012-08-16 16:58:10 +00003745}
3746
Manuel Klimeke9235692012-07-25 10:02:02 +00003747TEST(HasSourceExpression, MatchesImplicitCasts) {
Manuel Klimek04616e42012-07-06 05:48:52 +00003748 EXPECT_TRUE(matches("class string {}; class URL { public: URL(string s); };"
3749 "void r() {string a_string; URL url = a_string; }",
Daniel Jasper848cbe12012-09-18 13:09:13 +00003750 implicitCastExpr(
Aaron Ballman512fb642015-09-17 13:30:52 +00003751 hasSourceExpression(cxxConstructExpr()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003752}
3753
Manuel Klimeke9235692012-07-25 10:02:02 +00003754TEST(HasSourceExpression, MatchesExplicitCasts) {
3755 EXPECT_TRUE(matches("float x = static_cast<float>(42);",
Daniel Jasper848cbe12012-09-18 13:09:13 +00003756 explicitCastExpr(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003757 hasSourceExpression(hasDescendant(
Daniel Jasper848cbe12012-09-18 13:09:13 +00003758 expr(integerLiteral()))))));
Manuel Klimeke9235692012-07-25 10:02:02 +00003759}
3760
Manuel Klimek04616e42012-07-06 05:48:52 +00003761TEST(Statement, DoesNotMatchDeclarations) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003762 EXPECT_TRUE(notMatches("class X {};", stmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003763}
3764
3765TEST(Statement, MatchesCompoundStatments) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003766 EXPECT_TRUE(matches("void x() {}", stmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003767}
3768
3769TEST(DeclarationStatement, DoesNotMatchCompoundStatements) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003770 EXPECT_TRUE(notMatches("void x() {}", declStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003771}
3772
3773TEST(DeclarationStatement, MatchesVariableDeclarationStatements) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003774 EXPECT_TRUE(matches("void x() { int a; }", declStmt()));
Manuel Klimek04616e42012-07-06 05:48:52 +00003775}
3776
Samuel Benzaquenf1066292014-04-02 13:12:14 +00003777TEST(ExprWithCleanups, MatchesExprWithCleanups) {
3778 EXPECT_TRUE(matches("struct Foo { ~Foo(); };"
3779 "const Foo f = Foo();",
3780 varDecl(hasInitializer(exprWithCleanups()))));
3781 EXPECT_FALSE(matches("struct Foo { };"
3782 "const Foo f = Foo();",
3783 varDecl(hasInitializer(exprWithCleanups()))));
3784}
3785
Daniel Jasper1dad1832012-07-10 20:20:19 +00003786TEST(InitListExpression, MatchesInitListExpression) {
3787 EXPECT_TRUE(matches("int a[] = { 1, 2 };",
3788 initListExpr(hasType(asString("int [2]")))));
3789 EXPECT_TRUE(matches("struct B { int x, y; }; B b = { 5, 6 };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003790 initListExpr(hasType(recordDecl(hasName("B"))))));
Daniel Jasper1d8ecbd2015-02-04 13:11:42 +00003791 EXPECT_TRUE(matches("struct S { S(void (*a)()); };"
3792 "void f();"
3793 "S s[1] = { &f };",
3794 declRefExpr(to(functionDecl(hasName("f"))))));
Daniel Jasper774e6b52015-02-04 14:29:47 +00003795 EXPECT_TRUE(
3796 matches("int i[1] = {42, [0] = 43};", integerLiteral(equals(42))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00003797}
3798
3799TEST(UsingDeclaration, MatchesUsingDeclarations) {
3800 EXPECT_TRUE(matches("namespace X { int x; } using X::x;",
3801 usingDecl()));
3802}
3803
3804TEST(UsingDeclaration, MatchesShadowUsingDelcarations) {
3805 EXPECT_TRUE(matches("namespace f { int a; } using f::a;",
3806 usingDecl(hasAnyUsingShadowDecl(hasName("a")))));
3807}
3808
3809TEST(UsingDeclaration, MatchesSpecificTarget) {
3810 EXPECT_TRUE(matches("namespace f { int a; void b(); } using f::b;",
3811 usingDecl(hasAnyUsingShadowDecl(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003812 hasTargetDecl(functionDecl())))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00003813 EXPECT_TRUE(notMatches("namespace f { int a; void b(); } using f::a;",
3814 usingDecl(hasAnyUsingShadowDecl(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003815 hasTargetDecl(functionDecl())))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00003816}
3817
3818TEST(UsingDeclaration, ThroughUsingDeclaration) {
3819 EXPECT_TRUE(matches(
3820 "namespace a { void f(); } using a::f; void g() { f(); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003821 declRefExpr(throughUsingDecl(anything()))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00003822 EXPECT_TRUE(notMatches(
3823 "namespace a { void f(); } using a::f; void g() { a::f(); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003824 declRefExpr(throughUsingDecl(anything()))));
Daniel Jasper1dad1832012-07-10 20:20:19 +00003825}
3826
Benjamin Kramer73ef2162014-07-16 14:14:51 +00003827TEST(UsingDirectiveDeclaration, MatchesUsingNamespace) {
3828 EXPECT_TRUE(matches("namespace X { int x; } using namespace X;",
3829 usingDirectiveDecl()));
3830 EXPECT_FALSE(
3831 matches("namespace X { int x; } using X::x;", usingDirectiveDecl()));
3832}
3833
Sam Panzerd624bfb2012-08-16 17:20:59 +00003834TEST(SingleDecl, IsSingleDecl) {
3835 StatementMatcher SingleDeclStmt =
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003836 declStmt(hasSingleDecl(varDecl(hasInitializer(anything()))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003837 EXPECT_TRUE(matches("void f() {int a = 4;}", SingleDeclStmt));
3838 EXPECT_TRUE(notMatches("void f() {int a;}", SingleDeclStmt));
3839 EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
3840 SingleDeclStmt));
3841}
3842
3843TEST(DeclStmt, ContainsDeclaration) {
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003844 DeclarationMatcher MatchesInit = varDecl(hasInitializer(anything()));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003845
3846 EXPECT_TRUE(matches("void f() {int a = 4;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003847 declStmt(containsDeclaration(0, MatchesInit))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003848 EXPECT_TRUE(matches("void f() {int a = 4, b = 3;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003849 declStmt(containsDeclaration(0, MatchesInit),
3850 containsDeclaration(1, MatchesInit))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003851 unsigned WrongIndex = 42;
3852 EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003853 declStmt(containsDeclaration(WrongIndex,
Sam Panzerd624bfb2012-08-16 17:20:59 +00003854 MatchesInit))));
3855}
3856
3857TEST(DeclCount, DeclCountIsCorrect) {
3858 EXPECT_TRUE(matches("void f() {int i,j;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003859 declStmt(declCountIs(2))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003860 EXPECT_TRUE(notMatches("void f() {int i,j; int k;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003861 declStmt(declCountIs(3))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003862 EXPECT_TRUE(notMatches("void f() {int i,j, k, l;}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003863 declStmt(declCountIs(3))));
Sam Panzerd624bfb2012-08-16 17:20:59 +00003864}
3865
Manuel Klimek04616e42012-07-06 05:48:52 +00003866TEST(While, MatchesWhileLoops) {
3867 EXPECT_TRUE(notMatches("void x() {}", whileStmt()));
3868 EXPECT_TRUE(matches("void x() { while(true); }", whileStmt()));
3869 EXPECT_TRUE(notMatches("void x() { do {} while(true); }", whileStmt()));
3870}
3871
3872TEST(Do, MatchesDoLoops) {
3873 EXPECT_TRUE(matches("void x() { do {} while(true); }", doStmt()));
3874 EXPECT_TRUE(matches("void x() { do ; while(false); }", doStmt()));
3875}
3876
3877TEST(Do, DoesNotMatchWhileLoops) {
3878 EXPECT_TRUE(notMatches("void x() { while(true) {} }", doStmt()));
3879}
3880
3881TEST(SwitchCase, MatchesCase) {
3882 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchCase()));
3883 EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchCase()));
3884 EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchCase()));
3885 EXPECT_TRUE(notMatches("void x() { switch(42) {} }", switchCase()));
3886}
3887
Daniel Jasper87c3d362012-09-20 14:12:57 +00003888TEST(SwitchCase, MatchesSwitch) {
3889 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }", switchStmt()));
3890 EXPECT_TRUE(matches("void x() { switch(42) { default:; } }", switchStmt()));
3891 EXPECT_TRUE(matches("void x() { switch(42) default:; }", switchStmt()));
3892 EXPECT_TRUE(notMatches("void x() {}", switchStmt()));
3893}
3894
Peter Collingbourne3154a102013-05-10 11:52:02 +00003895TEST(SwitchCase, MatchesEachCase) {
3896 EXPECT_TRUE(notMatches("void x() { switch(42); }",
3897 switchStmt(forEachSwitchCase(caseStmt()))));
3898 EXPECT_TRUE(matches("void x() { switch(42) case 42:; }",
3899 switchStmt(forEachSwitchCase(caseStmt()))));
3900 EXPECT_TRUE(matches("void x() { switch(42) { case 42:; } }",
3901 switchStmt(forEachSwitchCase(caseStmt()))));
3902 EXPECT_TRUE(notMatches(
3903 "void x() { if (1) switch(42) { case 42: switch (42) { default:; } } }",
3904 ifStmt(has(switchStmt(forEachSwitchCase(defaultStmt()))))));
3905 EXPECT_TRUE(matches("void x() { switch(42) { case 1+1: case 4:; } }",
3906 switchStmt(forEachSwitchCase(
3907 caseStmt(hasCaseConstant(integerLiteral()))))));
3908 EXPECT_TRUE(notMatches("void x() { switch(42) { case 1+1: case 2+2:; } }",
3909 switchStmt(forEachSwitchCase(
3910 caseStmt(hasCaseConstant(integerLiteral()))))));
3911 EXPECT_TRUE(notMatches("void x() { switch(42) { case 1 ... 2:; } }",
3912 switchStmt(forEachSwitchCase(
3913 caseStmt(hasCaseConstant(integerLiteral()))))));
3914 EXPECT_TRUE(matchAndVerifyResultTrue(
3915 "void x() { switch (42) { case 1: case 2: case 3: default:; } }",
3916 switchStmt(forEachSwitchCase(caseStmt().bind("x"))),
3917 new VerifyIdIsBoundTo<CaseStmt>("x", 3)));
3918}
3919
Manuel Klimekba46fc02013-07-19 11:50:54 +00003920TEST(ForEachConstructorInitializer, MatchesInitializers) {
3921 EXPECT_TRUE(matches(
3922 "struct X { X() : i(42), j(42) {} int i, j; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00003923 cxxConstructorDecl(forEachConstructorInitializer(cxxCtorInitializer()))));
Manuel Klimekba46fc02013-07-19 11:50:54 +00003924}
3925
Daniel Jasper87c3d362012-09-20 14:12:57 +00003926TEST(ExceptionHandling, SimpleCases) {
Aaron Ballman512fb642015-09-17 13:30:52 +00003927 EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", cxxCatchStmt()));
3928 EXPECT_TRUE(matches("void foo() try { } catch(int X) { }", cxxTryStmt()));
3929 EXPECT_TRUE(
3930 notMatches("void foo() try { } catch(int X) { }", cxxThrowExpr()));
Daniel Jasper87c3d362012-09-20 14:12:57 +00003931 EXPECT_TRUE(matches("void foo() try { throw; } catch(int X) { }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003932 cxxThrowExpr()));
Daniel Jasper87c3d362012-09-20 14:12:57 +00003933 EXPECT_TRUE(matches("void foo() try { throw 5;} catch(int X) { }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003934 cxxThrowExpr()));
Aaron Ballman9b869aa2015-07-02 12:53:22 +00003935 EXPECT_TRUE(matches("void foo() try { throw; } catch(...) { }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003936 cxxCatchStmt(isCatchAll())));
Aaron Ballman9b869aa2015-07-02 12:53:22 +00003937 EXPECT_TRUE(notMatches("void foo() try { throw; } catch(int) { }",
Aaron Ballman512fb642015-09-17 13:30:52 +00003938 cxxCatchStmt(isCatchAll())));
Aaron Ballman39918462015-07-15 17:11:21 +00003939 EXPECT_TRUE(matches("void foo() try {} catch(int X) { }",
3940 varDecl(isExceptionVariable())));
3941 EXPECT_TRUE(notMatches("void foo() try { int X; } catch (...) { }",
3942 varDecl(isExceptionVariable())));
Daniel Jasper87c3d362012-09-20 14:12:57 +00003943}
3944
Aaron Ballmane8295d72016-01-20 16:17:39 +00003945TEST(ParenExpression, SimpleCases) {
3946 EXPECT_TRUE(matches("int i = (3);", parenExpr()));
3947 EXPECT_TRUE(matches("int i = (3 + 7);", parenExpr()));
3948 EXPECT_TRUE(notMatches("int i = 3;", parenExpr()));
3949 EXPECT_TRUE(notMatches("int foo() { return 1; }; int a = foo();",
3950 parenExpr()));
3951}
3952
Manuel Klimek04616e42012-07-06 05:48:52 +00003953TEST(HasConditionVariableStatement, DoesNotMatchCondition) {
3954 EXPECT_TRUE(notMatches(
3955 "void x() { if(true) {} }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003956 ifStmt(hasConditionVariableStatement(declStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003957 EXPECT_TRUE(notMatches(
3958 "void x() { int x; if((x = 42)) {} }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003959 ifStmt(hasConditionVariableStatement(declStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003960}
3961
3962TEST(HasConditionVariableStatement, MatchesConditionVariables) {
3963 EXPECT_TRUE(matches(
3964 "void x() { if(int* a = 0) {} }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003965 ifStmt(hasConditionVariableStatement(declStmt()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00003966}
3967
3968TEST(ForEach, BindsOneNode) {
3969 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003970 recordDecl(hasName("C"), forEach(fieldDecl(hasName("x")).bind("x"))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003971 new VerifyIdIsBoundTo<FieldDecl>("x", 1)));
Manuel Klimek04616e42012-07-06 05:48:52 +00003972}
3973
3974TEST(ForEach, BindsMultipleNodes) {
3975 EXPECT_TRUE(matchAndVerifyResultTrue("class C { int x; int y; int z; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003976 recordDecl(hasName("C"), forEach(fieldDecl().bind("f"))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003977 new VerifyIdIsBoundTo<FieldDecl>("f", 3)));
Manuel Klimek04616e42012-07-06 05:48:52 +00003978}
3979
3980TEST(ForEach, BindsRecursiveCombinations) {
3981 EXPECT_TRUE(matchAndVerifyResultTrue(
3982 "class C { class D { int x; int y; }; class E { int y; int z; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003983 recordDecl(hasName("C"),
3984 forEach(recordDecl(forEach(fieldDecl().bind("f"))))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003985 new VerifyIdIsBoundTo<FieldDecl>("f", 4)));
Manuel Klimek04616e42012-07-06 05:48:52 +00003986}
3987
3988TEST(ForEachDescendant, BindsOneNode) {
3989 EXPECT_TRUE(matchAndVerifyResultTrue("class C { class D { int x; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00003990 recordDecl(hasName("C"),
3991 forEachDescendant(fieldDecl(hasName("x")).bind("x"))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00003992 new VerifyIdIsBoundTo<FieldDecl>("x", 1)));
Manuel Klimek04616e42012-07-06 05:48:52 +00003993}
3994
Daniel Jasper94a56852012-11-16 18:39:22 +00003995TEST(ForEachDescendant, NestedForEachDescendant) {
3996 DeclarationMatcher m = recordDecl(
3997 isDefinition(), decl().bind("x"), hasName("C"));
3998 EXPECT_TRUE(matchAndVerifyResultTrue(
3999 "class A { class B { class C {}; }; };",
4000 recordDecl(hasName("A"), anyOf(m, forEachDescendant(m))),
4001 new VerifyIdIsBoundTo<Decl>("x", "C")));
4002
Manuel Klimeka0c025f2013-06-19 15:42:45 +00004003 // Check that a partial match of 'm' that binds 'x' in the
4004 // first part of anyOf(m, anything()) will not overwrite the
4005 // binding created by the earlier binding in the hasDescendant.
4006 EXPECT_TRUE(matchAndVerifyResultTrue(
4007 "class A { class B { class C {}; }; };",
4008 recordDecl(hasName("A"), allOf(hasDescendant(m), anyOf(m, anything()))),
4009 new VerifyIdIsBoundTo<Decl>("x", "C")));
Daniel Jasper94a56852012-11-16 18:39:22 +00004010}
4011
Manuel Klimek04616e42012-07-06 05:48:52 +00004012TEST(ForEachDescendant, BindsMultipleNodes) {
4013 EXPECT_TRUE(matchAndVerifyResultTrue(
4014 "class C { class D { int x; int y; }; "
4015 " class E { class F { int y; int z; }; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004016 recordDecl(hasName("C"), forEachDescendant(fieldDecl().bind("f"))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00004017 new VerifyIdIsBoundTo<FieldDecl>("f", 4)));
Manuel Klimek04616e42012-07-06 05:48:52 +00004018}
4019
4020TEST(ForEachDescendant, BindsRecursiveCombinations) {
4021 EXPECT_TRUE(matchAndVerifyResultTrue(
4022 "class C { class D { "
4023 " class E { class F { class G { int y; int z; }; }; }; }; };",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004024 recordDecl(hasName("C"), forEachDescendant(recordDecl(
4025 forEachDescendant(fieldDecl().bind("f"))))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00004026 new VerifyIdIsBoundTo<FieldDecl>("f", 8)));
Manuel Klimek04616e42012-07-06 05:48:52 +00004027}
4028
Manuel Klimeka0c025f2013-06-19 15:42:45 +00004029TEST(ForEachDescendant, BindsCombinations) {
4030 EXPECT_TRUE(matchAndVerifyResultTrue(
4031 "void f() { if(true) {} if (true) {} while (true) {} if (true) {} while "
4032 "(true) {} }",
4033 compoundStmt(forEachDescendant(ifStmt().bind("if")),
4034 forEachDescendant(whileStmt().bind("while"))),
4035 new VerifyIdIsBoundTo<IfStmt>("if", 6)));
4036}
4037
4038TEST(Has, DoesNotDeleteBindings) {
4039 EXPECT_TRUE(matchAndVerifyResultTrue(
4040 "class X { int a; };", recordDecl(decl().bind("x"), has(fieldDecl())),
4041 new VerifyIdIsBoundTo<Decl>("x", 1)));
4042}
4043
4044TEST(LoopingMatchers, DoNotOverwritePreviousMatchResultOnFailure) {
4045 // Those matchers cover all the cases where an inner matcher is called
4046 // and there is not a 1:1 relationship between the match of the outer
4047 // matcher and the match of the inner matcher.
4048 // The pattern to look for is:
4049 // ... return InnerMatcher.matches(...); ...
4050 // In which case no special handling is needed.
4051 //
4052 // On the other hand, if there are multiple alternative matches
4053 // (for example forEach*) or matches might be discarded (for example has*)
4054 // the implementation must make sure that the discarded matches do not
4055 // affect the bindings.
4056 // When new such matchers are added, add a test here that:
4057 // - matches a simple node, and binds it as the first thing in the matcher:
4058 // recordDecl(decl().bind("x"), hasName("X")))
4059 // - uses the matcher under test afterwards in a way that not the first
4060 // alternative is matched; for anyOf, that means the first branch
4061 // would need to return false; for hasAncestor, it means that not
4062 // the direct parent matches the inner matcher.
4063
4064 EXPECT_TRUE(matchAndVerifyResultTrue(
4065 "class X { int y; };",
4066 recordDecl(
4067 recordDecl().bind("x"), hasName("::X"),
4068 anyOf(forEachDescendant(recordDecl(hasName("Y"))), anything())),
4069 new VerifyIdIsBoundTo<CXXRecordDecl>("x", 1)));
4070 EXPECT_TRUE(matchAndVerifyResultTrue(
4071 "class X {};", recordDecl(recordDecl().bind("x"), hasName("::X"),
4072 anyOf(unless(anything()), anything())),
4073 new VerifyIdIsBoundTo<CXXRecordDecl>("x", 1)));
4074 EXPECT_TRUE(matchAndVerifyResultTrue(
4075 "template<typename T1, typename T2> class X {}; X<float, int> x;",
4076 classTemplateSpecializationDecl(
4077 decl().bind("x"),
4078 hasAnyTemplateArgument(refersToType(asString("int")))),
4079 new VerifyIdIsBoundTo<Decl>("x", 1)));
4080 EXPECT_TRUE(matchAndVerifyResultTrue(
4081 "class X { void f(); void g(); };",
Aaron Ballman512fb642015-09-17 13:30:52 +00004082 cxxRecordDecl(decl().bind("x"), hasMethod(hasName("g"))),
Manuel Klimeka0c025f2013-06-19 15:42:45 +00004083 new VerifyIdIsBoundTo<Decl>("x", 1)));
4084 EXPECT_TRUE(matchAndVerifyResultTrue(
4085 "class X { X() : a(1), b(2) {} double a; int b; };",
4086 recordDecl(decl().bind("x"),
Aaron Ballman512fb642015-09-17 13:30:52 +00004087 has(cxxConstructorDecl(
Manuel Klimeka0c025f2013-06-19 15:42:45 +00004088 hasAnyConstructorInitializer(forField(hasName("b")))))),
4089 new VerifyIdIsBoundTo<Decl>("x", 1)));
4090 EXPECT_TRUE(matchAndVerifyResultTrue(
4091 "void x(int, int) { x(0, 42); }",
4092 callExpr(expr().bind("x"), hasAnyArgument(integerLiteral(equals(42)))),
4093 new VerifyIdIsBoundTo<Expr>("x", 1)));
4094 EXPECT_TRUE(matchAndVerifyResultTrue(
4095 "void x(int, int y) {}",
4096 functionDecl(decl().bind("x"), hasAnyParameter(hasName("y"))),
4097 new VerifyIdIsBoundTo<Decl>("x", 1)));
4098 EXPECT_TRUE(matchAndVerifyResultTrue(
4099 "void x() { return; if (true) {} }",
4100 functionDecl(decl().bind("x"),
4101 has(compoundStmt(hasAnySubstatement(ifStmt())))),
4102 new VerifyIdIsBoundTo<Decl>("x", 1)));
4103 EXPECT_TRUE(matchAndVerifyResultTrue(
4104 "namespace X { void b(int); void b(); }"
4105 "using X::b;",
4106 usingDecl(decl().bind("x"), hasAnyUsingShadowDecl(hasTargetDecl(
4107 functionDecl(parameterCountIs(1))))),
4108 new VerifyIdIsBoundTo<Decl>("x", 1)));
4109 EXPECT_TRUE(matchAndVerifyResultTrue(
4110 "class A{}; class B{}; class C : B, A {};",
Aaron Ballman512fb642015-09-17 13:30:52 +00004111 cxxRecordDecl(decl().bind("x"), isDerivedFrom("::A")),
Manuel Klimeka0c025f2013-06-19 15:42:45 +00004112 new VerifyIdIsBoundTo<Decl>("x", 1)));
4113 EXPECT_TRUE(matchAndVerifyResultTrue(
4114 "class A{}; typedef A B; typedef A C; typedef A D;"
4115 "class E : A {};",
Aaron Ballman512fb642015-09-17 13:30:52 +00004116 cxxRecordDecl(decl().bind("x"), isDerivedFrom("C")),
Manuel Klimeka0c025f2013-06-19 15:42:45 +00004117 new VerifyIdIsBoundTo<Decl>("x", 1)));
4118 EXPECT_TRUE(matchAndVerifyResultTrue(
4119 "class A { class B { void f() {} }; };",
4120 functionDecl(decl().bind("x"), hasAncestor(recordDecl(hasName("::A")))),
4121 new VerifyIdIsBoundTo<Decl>("x", 1)));
4122 EXPECT_TRUE(matchAndVerifyResultTrue(
4123 "template <typename T> struct A { struct B {"
4124 " void f() { if(true) {} }"
4125 "}; };"
4126 "void t() { A<int>::B b; b.f(); }",
4127 ifStmt(stmt().bind("x"), hasAncestor(recordDecl(hasName("::A")))),
4128 new VerifyIdIsBoundTo<Stmt>("x", 2)));
4129 EXPECT_TRUE(matchAndVerifyResultTrue(
4130 "class A {};",
4131 recordDecl(hasName("::A"), decl().bind("x"), unless(hasName("fooble"))),
4132 new VerifyIdIsBoundTo<Decl>("x", 1)));
Manuel Klimekba46fc02013-07-19 11:50:54 +00004133 EXPECT_TRUE(matchAndVerifyResultTrue(
4134 "class A { A() : s(), i(42) {} const char *s; int i; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00004135 cxxConstructorDecl(hasName("::A::A"), decl().bind("x"),
4136 forEachConstructorInitializer(forField(hasName("i")))),
Manuel Klimekba46fc02013-07-19 11:50:54 +00004137 new VerifyIdIsBoundTo<Decl>("x", 1)));
Manuel Klimeka0c025f2013-06-19 15:42:45 +00004138}
4139
Daniel Jasper33806cd2012-11-11 22:14:55 +00004140TEST(ForEachDescendant, BindsCorrectNodes) {
4141 EXPECT_TRUE(matchAndVerifyResultTrue(
4142 "class C { void f(); int i; };",
4143 recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
4144 new VerifyIdIsBoundTo<FieldDecl>("decl", 1)));
4145 EXPECT_TRUE(matchAndVerifyResultTrue(
4146 "class C { void f() {} int i; };",
4147 recordDecl(hasName("C"), forEachDescendant(decl().bind("decl"))),
4148 new VerifyIdIsBoundTo<FunctionDecl>("decl", 1)));
4149}
4150
Manuel Klimekabf43712013-02-04 10:59:20 +00004151TEST(FindAll, BindsNodeOnMatch) {
4152 EXPECT_TRUE(matchAndVerifyResultTrue(
4153 "class A {};",
4154 recordDecl(hasName("::A"), findAll(recordDecl(hasName("::A")).bind("v"))),
4155 new VerifyIdIsBoundTo<CXXRecordDecl>("v", 1)));
4156}
4157
4158TEST(FindAll, BindsDescendantNodeOnMatch) {
4159 EXPECT_TRUE(matchAndVerifyResultTrue(
4160 "class A { int a; int b; };",
4161 recordDecl(hasName("::A"), findAll(fieldDecl().bind("v"))),
4162 new VerifyIdIsBoundTo<FieldDecl>("v", 2)));
4163}
4164
4165TEST(FindAll, BindsNodeAndDescendantNodesOnOneMatch) {
4166 EXPECT_TRUE(matchAndVerifyResultTrue(
4167 "class A { int a; int b; };",
4168 recordDecl(hasName("::A"),
4169 findAll(decl(anyOf(recordDecl(hasName("::A")).bind("v"),
4170 fieldDecl().bind("v"))))),
4171 new VerifyIdIsBoundTo<Decl>("v", 3)));
4172
4173 EXPECT_TRUE(matchAndVerifyResultTrue(
4174 "class A { class B {}; class C {}; };",
4175 recordDecl(hasName("::A"), findAll(recordDecl(isDefinition()).bind("v"))),
4176 new VerifyIdIsBoundTo<CXXRecordDecl>("v", 3)));
4177}
4178
Manuel Klimek88b95872013-02-04 09:42:38 +00004179TEST(EachOf, TriggersForEachMatch) {
4180 EXPECT_TRUE(matchAndVerifyResultTrue(
4181 "class A { int a; int b; };",
4182 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
4183 has(fieldDecl(hasName("b")).bind("v")))),
4184 new VerifyIdIsBoundTo<FieldDecl>("v", 2)));
4185}
4186
4187TEST(EachOf, BehavesLikeAnyOfUnlessBothMatch) {
4188 EXPECT_TRUE(matchAndVerifyResultTrue(
4189 "class A { int a; int c; };",
4190 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
4191 has(fieldDecl(hasName("b")).bind("v")))),
4192 new VerifyIdIsBoundTo<FieldDecl>("v", 1)));
4193 EXPECT_TRUE(matchAndVerifyResultTrue(
4194 "class A { int c; int b; };",
4195 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
4196 has(fieldDecl(hasName("b")).bind("v")))),
4197 new VerifyIdIsBoundTo<FieldDecl>("v", 1)));
4198 EXPECT_TRUE(notMatches(
4199 "class A { int c; int d; };",
4200 recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")),
4201 has(fieldDecl(hasName("b")).bind("v"))))));
4202}
Manuel Klimek04616e42012-07-06 05:48:52 +00004203
4204TEST(IsTemplateInstantiation, MatchesImplicitClassTemplateInstantiation) {
4205 // Make sure that we can both match the class by name (::X) and by the type
4206 // the template was instantiated with (via a field).
4207
4208 EXPECT_TRUE(matches(
4209 "template <typename T> class X {}; class A {}; X<A> x;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004210 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
Manuel Klimek04616e42012-07-06 05:48:52 +00004211
4212 EXPECT_TRUE(matches(
4213 "template <typename T> class X { T t; }; class A {}; X<A> x;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004214 cxxRecordDecl(isTemplateInstantiation(), hasDescendant(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004215 fieldDecl(hasType(recordDecl(hasName("A"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00004216}
4217
4218TEST(IsTemplateInstantiation, MatchesImplicitFunctionTemplateInstantiation) {
4219 EXPECT_TRUE(matches(
4220 "template <typename T> void f(T t) {} class A {}; void g() { f(A()); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004221 functionDecl(hasParameter(0, hasType(recordDecl(hasName("A")))),
Manuel Klimek04616e42012-07-06 05:48:52 +00004222 isTemplateInstantiation())));
4223}
4224
4225TEST(IsTemplateInstantiation, MatchesExplicitClassTemplateInstantiation) {
4226 EXPECT_TRUE(matches(
4227 "template <typename T> class X { T t; }; class A {};"
4228 "template class X<A>;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004229 cxxRecordDecl(isTemplateInstantiation(), hasDescendant(
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004230 fieldDecl(hasType(recordDecl(hasName("A"))))))));
Manuel Klimek04616e42012-07-06 05:48:52 +00004231}
4232
4233TEST(IsTemplateInstantiation,
4234 MatchesInstantiationOfPartiallySpecializedClassTemplate) {
4235 EXPECT_TRUE(matches(
4236 "template <typename T> class X {};"
4237 "template <typename T> class X<T*> {}; class A {}; X<A*> x;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004238 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
Manuel Klimek04616e42012-07-06 05:48:52 +00004239}
4240
4241TEST(IsTemplateInstantiation,
4242 MatchesInstantiationOfClassTemplateNestedInNonTemplate) {
4243 EXPECT_TRUE(matches(
4244 "class A {};"
4245 "class X {"
4246 " template <typename U> class Y { U u; };"
4247 " Y<A> y;"
4248 "};",
Aaron Ballman512fb642015-09-17 13:30:52 +00004249 cxxRecordDecl(hasName("::X::Y"), isTemplateInstantiation())));
Manuel Klimek04616e42012-07-06 05:48:52 +00004250}
4251
4252TEST(IsTemplateInstantiation, DoesNotMatchInstantiationsInsideOfInstantiation) {
4253 // FIXME: Figure out whether this makes sense. It doesn't affect the
4254 // normal use case as long as the uppermost instantiation always is marked
4255 // as template instantiation, but it might be confusing as a predicate.
4256 EXPECT_TRUE(matches(
4257 "class A {};"
4258 "template <typename T> class X {"
4259 " template <typename U> class Y { U u; };"
4260 " Y<T> y;"
4261 "}; X<A> x;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004262 cxxRecordDecl(hasName("::X<A>::Y"), unless(isTemplateInstantiation()))));
Manuel Klimek04616e42012-07-06 05:48:52 +00004263}
4264
4265TEST(IsTemplateInstantiation, DoesNotMatchExplicitClassTemplateSpecialization) {
4266 EXPECT_TRUE(notMatches(
4267 "template <typename T> class X {}; class A {};"
4268 "template <> class X<A> {}; X<A> x;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004269 cxxRecordDecl(hasName("::X"), isTemplateInstantiation())));
Manuel Klimek04616e42012-07-06 05:48:52 +00004270}
4271
4272TEST(IsTemplateInstantiation, DoesNotMatchNonTemplate) {
4273 EXPECT_TRUE(notMatches(
4274 "class A {}; class Y { A a; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00004275 cxxRecordDecl(isTemplateInstantiation())));
Manuel Klimek04616e42012-07-06 05:48:52 +00004276}
4277
Benjamin Kramer7ab84762014-09-03 12:08:14 +00004278TEST(IsInstantiated, MatchesInstantiation) {
4279 EXPECT_TRUE(
4280 matches("template<typename T> class A { T i; }; class Y { A<int> a; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00004281 cxxRecordDecl(isInstantiated())));
Benjamin Kramer7ab84762014-09-03 12:08:14 +00004282}
4283
4284TEST(IsInstantiated, NotMatchesDefinition) {
4285 EXPECT_TRUE(notMatches("template<typename T> class A { T i; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00004286 cxxRecordDecl(isInstantiated())));
Benjamin Kramer7ab84762014-09-03 12:08:14 +00004287}
4288
4289TEST(IsInTemplateInstantiation, MatchesInstantiationStmt) {
4290 EXPECT_TRUE(matches("template<typename T> struct A { A() { T i; } };"
4291 "class Y { A<int> a; }; Y y;",
4292 declStmt(isInTemplateInstantiation())));
4293}
4294
4295TEST(IsInTemplateInstantiation, NotMatchesDefinitionStmt) {
4296 EXPECT_TRUE(notMatches("template<typename T> struct A { void x() { T i; } };",
4297 declStmt(isInTemplateInstantiation())));
4298}
4299
4300TEST(IsInstantiated, MatchesFunctionInstantiation) {
4301 EXPECT_TRUE(
4302 matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
4303 functionDecl(isInstantiated())));
4304}
4305
4306TEST(IsInstantiated, NotMatchesFunctionDefinition) {
4307 EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
4308 varDecl(isInstantiated())));
4309}
4310
4311TEST(IsInTemplateInstantiation, MatchesFunctionInstantiationStmt) {
4312 EXPECT_TRUE(
4313 matches("template<typename T> void A(T t) { T i; } void x() { A(0); }",
4314 declStmt(isInTemplateInstantiation())));
4315}
4316
4317TEST(IsInTemplateInstantiation, NotMatchesFunctionDefinitionStmt) {
4318 EXPECT_TRUE(notMatches("template<typename T> void A(T t) { T i; }",
4319 declStmt(isInTemplateInstantiation())));
4320}
4321
4322TEST(IsInTemplateInstantiation, Sharing) {
4323 auto Matcher = binaryOperator(unless(isInTemplateInstantiation()));
4324 // FIXME: Node sharing is an implementation detail, exposing it is ugly
4325 // and makes the matcher behave in non-obvious ways.
4326 EXPECT_TRUE(notMatches(
4327 "int j; template<typename T> void A(T t) { j += 42; } void x() { A(0); }",
4328 Matcher));
4329 EXPECT_TRUE(matches(
4330 "int j; template<typename T> void A(T t) { j += t; } void x() { A(0); }",
4331 Matcher));
4332}
4333
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004334TEST(IsExplicitTemplateSpecialization,
4335 DoesNotMatchPrimaryTemplate) {
4336 EXPECT_TRUE(notMatches(
4337 "template <typename T> class X {};",
Aaron Ballman512fb642015-09-17 13:30:52 +00004338 cxxRecordDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004339 EXPECT_TRUE(notMatches(
4340 "template <typename T> void f(T t);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004341 functionDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004342}
4343
4344TEST(IsExplicitTemplateSpecialization,
4345 DoesNotMatchExplicitTemplateInstantiations) {
4346 EXPECT_TRUE(notMatches(
4347 "template <typename T> class X {};"
4348 "template class X<int>; extern template class X<long>;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004349 cxxRecordDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004350 EXPECT_TRUE(notMatches(
4351 "template <typename T> void f(T t) {}"
4352 "template void f(int t); extern template void f(long t);",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004353 functionDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004354}
4355
4356TEST(IsExplicitTemplateSpecialization,
4357 DoesNotMatchImplicitTemplateInstantiations) {
4358 EXPECT_TRUE(notMatches(
4359 "template <typename T> class X {}; X<int> x;",
Aaron Ballman512fb642015-09-17 13:30:52 +00004360 cxxRecordDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004361 EXPECT_TRUE(notMatches(
4362 "template <typename T> void f(T t); void g() { f(10); }",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004363 functionDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004364}
4365
4366TEST(IsExplicitTemplateSpecialization,
4367 MatchesExplicitTemplateSpecializations) {
4368 EXPECT_TRUE(matches(
4369 "template <typename T> class X {};"
4370 "template<> class X<int> {};",
Aaron Ballman512fb642015-09-17 13:30:52 +00004371 cxxRecordDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004372 EXPECT_TRUE(matches(
4373 "template <typename T> void f(T t) {}"
4374 "template<> void f(int t) {}",
Daniel Jasperbd3d76d2012-08-24 05:12:34 +00004375 functionDecl(isExplicitTemplateSpecialization())));
Dmitri Gribenkod394c8a2012-08-17 18:42:47 +00004376}
4377
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004378TEST(HasAncenstor, MatchesDeclarationAncestors) {
4379 EXPECT_TRUE(matches(
4380 "class A { class B { class C {}; }; };",
4381 recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("A"))))));
4382}
4383
4384TEST(HasAncenstor, FailsIfNoAncestorMatches) {
4385 EXPECT_TRUE(notMatches(
4386 "class A { class B { class C {}; }; };",
4387 recordDecl(hasName("C"), hasAncestor(recordDecl(hasName("X"))))));
4388}
4389
4390TEST(HasAncestor, MatchesDeclarationsThatGetVisitedLater) {
4391 EXPECT_TRUE(matches(
4392 "class A { class B { void f() { C c; } class C {}; }; };",
4393 varDecl(hasName("c"), hasType(recordDecl(hasName("C"),
4394 hasAncestor(recordDecl(hasName("A"))))))));
4395}
4396
4397TEST(HasAncenstor, MatchesStatementAncestors) {
4398 EXPECT_TRUE(matches(
4399 "void f() { if (true) { while (false) { 42; } } }",
Daniel Jasper848cbe12012-09-18 13:09:13 +00004400 integerLiteral(equals(42), hasAncestor(ifStmt()))));
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004401}
4402
4403TEST(HasAncestor, DrillsThroughDifferentHierarchies) {
4404 EXPECT_TRUE(matches(
4405 "void f() { if (true) { int x = 42; } }",
Daniel Jasper848cbe12012-09-18 13:09:13 +00004406 integerLiteral(equals(42), hasAncestor(functionDecl(hasName("f"))))));
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004407}
4408
4409TEST(HasAncestor, BindsRecursiveCombinations) {
4410 EXPECT_TRUE(matchAndVerifyResultTrue(
4411 "class C { class D { class E { class F { int y; }; }; }; };",
4412 fieldDecl(hasAncestor(recordDecl(hasAncestor(recordDecl().bind("r"))))),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00004413 new VerifyIdIsBoundTo<CXXRecordDecl>("r", 1)));
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004414}
4415
4416TEST(HasAncestor, BindsCombinationsWithHasDescendant) {
4417 EXPECT_TRUE(matchAndVerifyResultTrue(
4418 "class C { class D { class E { class F { int y; }; }; }; };",
4419 fieldDecl(hasAncestor(
4420 decl(
4421 hasDescendant(recordDecl(isDefinition(),
4422 hasAncestor(recordDecl())))
4423 ).bind("d")
4424 )),
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00004425 new VerifyIdIsBoundTo<CXXRecordDecl>("d", "E")));
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004426}
4427
Manuel Klimekb64d6b72013-03-14 16:33:21 +00004428TEST(HasAncestor, MatchesClosestAncestor) {
4429 EXPECT_TRUE(matchAndVerifyResultTrue(
4430 "template <typename T> struct C {"
4431 " void f(int) {"
4432 " struct I { void g(T) { int x; } } i; i.g(42);"
4433 " }"
4434 "};"
4435 "template struct C<int>;",
4436 varDecl(hasName("x"),
4437 hasAncestor(functionDecl(hasParameter(
4438 0, varDecl(hasType(asString("int"))))).bind("f"))).bind("v"),
4439 new VerifyIdIsBoundTo<FunctionDecl>("f", "g", 2)));
4440}
4441
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004442TEST(HasAncestor, MatchesInTemplateInstantiations) {
4443 EXPECT_TRUE(matches(
4444 "template <typename T> struct A { struct B { struct C { T t; }; }; }; "
4445 "A<int>::B::C a;",
4446 fieldDecl(hasType(asString("int")),
4447 hasAncestor(recordDecl(hasName("A"))))));
4448}
4449
4450TEST(HasAncestor, MatchesInImplicitCode) {
4451 EXPECT_TRUE(matches(
4452 "struct X {}; struct A { A() {} X x; };",
Aaron Ballman512fb642015-09-17 13:30:52 +00004453 cxxConstructorDecl(
Manuel Klimek3ca12c52012-09-07 09:26:10 +00004454 hasAnyConstructorInitializer(withInitializer(expr(
4455 hasAncestor(recordDecl(hasName("A")))))))));
4456}
4457
Daniel Jasper632aea92012-10-22 16:26:51 +00004458TEST(HasParent, MatchesOnlyParent) {
4459 EXPECT_TRUE(matches(
4460 "void f() { if (true) { int x = 42; } }",
4461 compoundStmt(hasParent(ifStmt()))));
4462 EXPECT_TRUE(notMatches(
4463 "void f() { for (;;) { int x = 42; } }",
4464 compoundStmt(hasParent(ifStmt()))));
4465 EXPECT_TRUE(notMatches(
4466 "void f() { if (true) for (;;) { int x = 42; } }",
4467 compoundStmt(hasParent(ifStmt()))));
4468}
4469
Manuel Klimekc844a462012-12-06 14:42:48 +00004470TEST(HasAncestor, MatchesAllAncestors) {
4471 EXPECT_TRUE(matches(
4472 "template <typename T> struct C { static void f() { 42; } };"
4473 "void t() { C<int>::f(); }",
4474 integerLiteral(
4475 equals(42),
Aaron Ballman512fb642015-09-17 13:30:52 +00004476 allOf(
4477 hasAncestor(cxxRecordDecl(isTemplateInstantiation())),
4478 hasAncestor(cxxRecordDecl(unless(isTemplateInstantiation())))))));
Manuel Klimekc844a462012-12-06 14:42:48 +00004479}
4480
Nico Weberc4acee32016-01-22 15:11:54 +00004481TEST(HasAncestor, ImplicitArrayCopyCtorDeclRefExpr) {
4482 EXPECT_TRUE(matches("struct MyClass {\n"
4483 " int c[1];\n"
4484 " static MyClass Create() { return MyClass(); }\n"
4485 "};",
4486 declRefExpr(to(decl(hasAncestor(decl()))))));
4487}
4488
Nico Weber7b837f52016-01-28 19:25:00 +00004489TEST(HasAncestor, AnonymousUnionMemberExpr) {
4490 EXPECT_TRUE(matches("int F() {\n"
4491 " union { int i; };\n"
4492 " return i;\n"
4493 "}\n",
4494 memberExpr(member(hasAncestor(decl())))));
4495 EXPECT_TRUE(matches("void f() {\n"
4496 " struct {\n"
4497 " struct { int a; int b; };\n"
4498 " } s;\n"
4499 " s.a = 4;\n"
4500 "}\n",
4501 memberExpr(member(hasAncestor(decl())))));
4502 EXPECT_TRUE(matches("void f() {\n"
4503 " struct {\n"
4504 " struct { int a; int b; };\n"
4505 " } s;\n"
4506 " s.a = 4;\n"
4507 "}\n",
4508 declRefExpr(to(decl(hasAncestor(decl()))))));
4509}
4510
Nico Weberc0973372016-02-01 22:31:51 +00004511TEST(HasAncestor, NonParmDependentTemplateParmVarDeclRefExpr) {
4512 EXPECT_TRUE(matches("struct PartitionAllocator {\n"
4513 " template<typename T>\n"
4514 " static int quantizedSize(int count) {\n"
4515 " return count;\n"
4516 " }\n"
4517 " void f() { quantizedSize<int>(10); }\n"
4518 "};",
4519 declRefExpr(to(decl(hasAncestor(decl()))))));
4520}
4521
Nico Weber26911c72016-02-08 22:23:09 +00004522TEST(HasAncestor, AddressOfExplicitSpecializationFunction) {
4523 EXPECT_TRUE(matches("template <class T> void f();\n"
4524 "template <> void f<int>();\n"
4525 "void (*get_f())() { return f<int>; }\n",
4526 declRefExpr(to(decl(hasAncestor(decl()))))));
4527}
4528
Manuel Klimekc844a462012-12-06 14:42:48 +00004529TEST(HasParent, MatchesAllParents) {
4530 EXPECT_TRUE(matches(
4531 "template <typename T> struct C { static void f() { 42; } };"
4532 "void t() { C<int>::f(); }",
4533 integerLiteral(
4534 equals(42),
4535 hasParent(compoundStmt(hasParent(functionDecl(
Aaron Ballman512fb642015-09-17 13:30:52 +00004536 hasParent(cxxRecordDecl(isTemplateInstantiation())))))))));
4537 EXPECT_TRUE(
4538 matches("template <typename T> struct C { static void f() { 42; } };"
4539 "void t() { C<int>::f(); }",
4540 integerLiteral(
4541 equals(42),
4542 hasParent(compoundStmt(hasParent(functionDecl(hasParent(
4543 cxxRecordDecl(unless(isTemplateInstantiation()))))))))));
Manuel Klimekc844a462012-12-06 14:42:48 +00004544 EXPECT_TRUE(matches(
4545 "template <typename T> struct C { static void f() { 42; } };"
4546 "void t() { C<int>::f(); }",
4547 integerLiteral(equals(42),
Aaron Ballman512fb642015-09-17 13:30:52 +00004548 hasParent(compoundStmt(
4549 allOf(hasParent(functionDecl(hasParent(
4550 cxxRecordDecl(isTemplateInstantiation())))),
4551 hasParent(functionDecl(hasParent(cxxRecordDecl(
4552 unless(isTemplateInstantiation())))))))))));
Manuel Klimekb64d6b72013-03-14 16:33:21 +00004553 EXPECT_TRUE(
4554 notMatches("template <typename T> struct C { static void f() {} };"
4555 "void t() { C<int>::f(); }",
4556 compoundStmt(hasParent(recordDecl()))));
Manuel Klimekc844a462012-12-06 14:42:48 +00004557}
4558
Samuel Benzaquen3ca0a7b2014-06-13 13:31:40 +00004559TEST(HasParent, NoDuplicateParents) {
4560 class HasDuplicateParents : public BoundNodesCallback {
4561 public:
4562 bool run(const BoundNodes *Nodes) override { return false; }
4563 bool run(const BoundNodes *Nodes, ASTContext *Context) override {
4564 const Stmt *Node = Nodes->getNodeAs<Stmt>("node");
4565 std::set<const void *> Parents;
4566 for (const auto &Parent : Context->getParents(*Node)) {
4567 if (!Parents.insert(Parent.getMemoizationData()).second) {
4568 return true;
4569 }
4570 }
4571 return false;
4572 }
4573 };
4574 EXPECT_FALSE(matchAndVerifyResultTrue(
4575 "template <typename T> int Foo() { return 1 + 2; }\n"
4576 "int x = Foo<int>() + Foo<unsigned>();",
4577 stmt().bind("node"), new HasDuplicateParents()));
4578}
4579
Daniel Jasper516b02e2012-10-17 08:52:59 +00004580TEST(TypeMatching, MatchesTypes) {
4581 EXPECT_TRUE(matches("struct S {};", qualType().bind("loc")));
4582}
4583
Samuel Benzaquenbd3232a2015-12-22 20:06:40 +00004584TEST(TypeMatching, MatchesBool) {
4585 EXPECT_TRUE(matches("struct S { bool func(); };",
4586 cxxMethodDecl(returns(booleanType()))));
4587 EXPECT_TRUE(notMatches("struct S { void func(); };",
4588 cxxMethodDecl(returns(booleanType()))));
4589}
4590
Samuel Benzaquenb405c082014-12-15 15:09:22 +00004591TEST(TypeMatching, MatchesVoid) {
Aaron Ballman512fb642015-09-17 13:30:52 +00004592 EXPECT_TRUE(matches("struct S { void func(); };",
4593 cxxMethodDecl(returns(voidType()))));
Samuel Benzaquenb405c082014-12-15 15:09:22 +00004594}
4595
Aaron Ballmaneb7e5d92016-02-18 16:36:01 +00004596TEST(TypeMatching, MatchesRealFloats) {
4597 EXPECT_TRUE(matches("struct S { float func(); };",
4598 cxxMethodDecl(returns(realFloatingPointType()))));
4599 EXPECT_TRUE(notMatches("struct S { int func(); };",
4600 cxxMethodDecl(returns(realFloatingPointType()))));
4601 EXPECT_TRUE(matches("struct S { long double func(); };",
4602 cxxMethodDecl(returns(realFloatingPointType()))));
4603}
4604
Daniel Jasper516b02e2012-10-17 08:52:59 +00004605TEST(TypeMatching, MatchesArrayTypes) {
4606 EXPECT_TRUE(matches("int a[] = {2,3};", arrayType()));
4607 EXPECT_TRUE(matches("int a[42];", arrayType()));
4608 EXPECT_TRUE(matches("void f(int b) { int a[b]; }", arrayType()));
4609
4610 EXPECT_TRUE(notMatches("struct A {}; A a[7];",
4611 arrayType(hasElementType(builtinType()))));
4612
4613 EXPECT_TRUE(matches(
4614 "int const a[] = { 2, 3 };",
4615 qualType(arrayType(hasElementType(builtinType())))));
4616 EXPECT_TRUE(matches(
4617 "int const a[] = { 2, 3 };",
4618 qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
4619 EXPECT_TRUE(matches(
4620 "typedef const int T; T x[] = { 1, 2 };",
4621 qualType(isConstQualified(), arrayType())));
4622
4623 EXPECT_TRUE(notMatches(
4624 "int a[] = { 2, 3 };",
4625 qualType(isConstQualified(), arrayType(hasElementType(builtinType())))));
4626 EXPECT_TRUE(notMatches(
4627 "int a[] = { 2, 3 };",
4628 qualType(arrayType(hasElementType(isConstQualified(), builtinType())))));
4629 EXPECT_TRUE(notMatches(
4630 "int const a[] = { 2, 3 };",
4631 qualType(arrayType(hasElementType(builtinType())),
4632 unless(isConstQualified()))));
4633
4634 EXPECT_TRUE(matches("int a[2];",
4635 constantArrayType(hasElementType(builtinType()))));
4636 EXPECT_TRUE(matches("const int a = 0;", qualType(isInteger())));
4637}
4638
Matthias Gehre2cf7e802015-10-12 21:46:07 +00004639TEST(TypeMatching, DecayedType) {
4640 EXPECT_TRUE(matches("void f(int i[]);", valueDecl(hasType(decayedType(hasDecayedType(pointerType()))))));
4641 EXPECT_TRUE(notMatches("int i[7];", decayedType()));
4642}
4643
Daniel Jasper516b02e2012-10-17 08:52:59 +00004644TEST(TypeMatching, MatchesComplexTypes) {
4645 EXPECT_TRUE(matches("_Complex float f;", complexType()));
4646 EXPECT_TRUE(matches(
4647 "_Complex float f;",
4648 complexType(hasElementType(builtinType()))));
4649 EXPECT_TRUE(notMatches(
4650 "_Complex float f;",
4651 complexType(hasElementType(isInteger()))));
4652}
4653
4654TEST(TypeMatching, MatchesConstantArrayTypes) {
4655 EXPECT_TRUE(matches("int a[2];", constantArrayType()));
4656 EXPECT_TRUE(notMatches(
4657 "void f() { int a[] = { 2, 3 }; int b[a[0]]; }",
4658 constantArrayType(hasElementType(builtinType()))));
4659
4660 EXPECT_TRUE(matches("int a[42];", constantArrayType(hasSize(42))));
4661 EXPECT_TRUE(matches("int b[2*21];", constantArrayType(hasSize(42))));
4662 EXPECT_TRUE(notMatches("int c[41], d[43];", constantArrayType(hasSize(42))));
4663}
4664
4665TEST(TypeMatching, MatchesDependentSizedArrayTypes) {
4666 EXPECT_TRUE(matches(
4667 "template <typename T, int Size> class array { T data[Size]; };",
4668 dependentSizedArrayType()));
4669 EXPECT_TRUE(notMatches(
4670 "int a[42]; int b[] = { 2, 3 }; void f() { int c[b[0]]; }",
4671 dependentSizedArrayType()));
4672}
4673
4674TEST(TypeMatching, MatchesIncompleteArrayType) {
4675 EXPECT_TRUE(matches("int a[] = { 2, 3 };", incompleteArrayType()));
4676 EXPECT_TRUE(matches("void f(int a[]) {}", incompleteArrayType()));
4677
4678 EXPECT_TRUE(notMatches("int a[42]; void f() { int b[a[0]]; }",
4679 incompleteArrayType()));
4680}
4681
4682TEST(TypeMatching, MatchesVariableArrayType) {
4683 EXPECT_TRUE(matches("void f(int b) { int a[b]; }", variableArrayType()));
4684 EXPECT_TRUE(notMatches("int a[] = {2, 3}; int b[42];", variableArrayType()));
4685
4686 EXPECT_TRUE(matches(
4687 "void f(int b) { int a[b]; }",
4688 variableArrayType(hasSizeExpr(ignoringImpCasts(declRefExpr(to(
4689 varDecl(hasName("b")))))))));
4690}
4691
4692TEST(TypeMatching, MatchesAtomicTypes) {
David Majnemer197e2102014-03-05 06:32:38 +00004693 if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getOS() !=
4694 llvm::Triple::Win32) {
4695 // FIXME: Make this work for MSVC.
4696 EXPECT_TRUE(matches("_Atomic(int) i;", atomicType()));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004697
David Majnemer197e2102014-03-05 06:32:38 +00004698 EXPECT_TRUE(matches("_Atomic(int) i;",
4699 atomicType(hasValueType(isInteger()))));
4700 EXPECT_TRUE(notMatches("_Atomic(float) f;",
4701 atomicType(hasValueType(isInteger()))));
4702 }
Daniel Jasper516b02e2012-10-17 08:52:59 +00004703}
4704
4705TEST(TypeMatching, MatchesAutoTypes) {
4706 EXPECT_TRUE(matches("auto i = 2;", autoType()));
4707 EXPECT_TRUE(matches("int v[] = { 2, 3 }; void f() { for (int i : v) {} }",
4708 autoType()));
4709
Richard Smith061f1e22013-04-30 21:23:01 +00004710 // FIXME: Matching against the type-as-written can't work here, because the
4711 // type as written was not deduced.
4712 //EXPECT_TRUE(matches("auto a = 1;",
4713 // autoType(hasDeducedType(isInteger()))));
4714 //EXPECT_TRUE(notMatches("auto b = 2.0;",
4715 // autoType(hasDeducedType(isInteger()))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004716}
4717
Daniel Jasperd29d5fa2012-10-29 10:14:44 +00004718TEST(TypeMatching, MatchesFunctionTypes) {
4719 EXPECT_TRUE(matches("int (*f)(int);", functionType()));
4720 EXPECT_TRUE(matches("void f(int i) {}", functionType()));
4721}
4722
Aaron Ballman7e7b7b22016-02-01 14:11:47 +00004723TEST(TypeMatching, MatchesFunctionProtoTypes) {
4724 EXPECT_TRUE(matches("int (*f)(int);", functionProtoType()));
4725 EXPECT_TRUE(matches("void f(int i);", functionProtoType()));
4726 EXPECT_TRUE(matches("void f();", functionProtoType(parameterCountIs(0))));
4727 EXPECT_TRUE(notMatchesC("void f();", functionProtoType()));
4728 EXPECT_TRUE(
4729 matchesC("void f(void);", functionProtoType(parameterCountIs(0))));
4730}
4731
Edwin Vaneec074802013-04-01 18:33:34 +00004732TEST(TypeMatching, MatchesParenType) {
4733 EXPECT_TRUE(
4734 matches("int (*array)[4];", varDecl(hasType(pointsTo(parenType())))));
4735 EXPECT_TRUE(notMatches("int *array[4];", varDecl(hasType(parenType()))));
4736
4737 EXPECT_TRUE(matches(
4738 "int (*ptr_to_func)(int);",
4739 varDecl(hasType(pointsTo(parenType(innerType(functionType())))))));
4740 EXPECT_TRUE(notMatches(
4741 "int (*ptr_to_array)[4];",
4742 varDecl(hasType(pointsTo(parenType(innerType(functionType())))))));
4743}
4744
Daniel Jasper516b02e2012-10-17 08:52:59 +00004745TEST(TypeMatching, PointerTypes) {
Daniel Jasper7943eb52012-10-17 13:35:36 +00004746 // FIXME: Reactive when these tests can be more specific (not matching
4747 // implicit code on certain platforms), likely when we have hasDescendant for
4748 // Types/TypeLocs.
4749 //EXPECT_TRUE(matchAndVerifyResultTrue(
4750 // "int* a;",
4751 // pointerTypeLoc(pointeeLoc(typeLoc().bind("loc"))),
4752 // new VerifyIdIsBoundTo<TypeLoc>("loc", 1)));
4753 //EXPECT_TRUE(matchAndVerifyResultTrue(
4754 // "int* a;",
4755 // pointerTypeLoc().bind("loc"),
4756 // new VerifyIdIsBoundTo<TypeLoc>("loc", 1)));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004757 EXPECT_TRUE(matches(
4758 "int** a;",
David Blaikieb61d0872013-02-18 19:04:16 +00004759 loc(pointerType(pointee(qualType())))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004760 EXPECT_TRUE(matches(
4761 "int** a;",
4762 loc(pointerType(pointee(pointerType())))));
4763 EXPECT_TRUE(matches(
4764 "int* b; int* * const a = &b;",
4765 loc(qualType(isConstQualified(), pointerType()))));
4766
4767 std::string Fragment = "struct A { int i; }; int A::* ptr = &A::i;";
Daniel Jasper7943eb52012-10-17 13:35:36 +00004768 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4769 hasType(blockPointerType()))));
4770 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ptr"),
4771 hasType(memberPointerType()))));
4772 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4773 hasType(pointerType()))));
4774 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4775 hasType(referenceType()))));
Edwin Vane2a760d02013-03-07 15:44:40 +00004776 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4777 hasType(lValueReferenceType()))));
4778 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4779 hasType(rValueReferenceType()))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004780
Daniel Jasper7943eb52012-10-17 13:35:36 +00004781 Fragment = "int *ptr;";
4782 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4783 hasType(blockPointerType()))));
4784 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4785 hasType(memberPointerType()))));
4786 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ptr"),
4787 hasType(pointerType()))));
4788 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ptr"),
4789 hasType(referenceType()))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004790
Daniel Jasper7943eb52012-10-17 13:35:36 +00004791 Fragment = "int a; int &ref = a;";
4792 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4793 hasType(blockPointerType()))));
4794 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4795 hasType(memberPointerType()))));
4796 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4797 hasType(pointerType()))));
4798 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
4799 hasType(referenceType()))));
Edwin Vane2a760d02013-03-07 15:44:40 +00004800 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
4801 hasType(lValueReferenceType()))));
4802 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4803 hasType(rValueReferenceType()))));
4804
4805 Fragment = "int &&ref = 2;";
4806 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4807 hasType(blockPointerType()))));
4808 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4809 hasType(memberPointerType()))));
4810 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4811 hasType(pointerType()))));
4812 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
4813 hasType(referenceType()))));
4814 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("ref"),
4815 hasType(lValueReferenceType()))));
4816 EXPECT_TRUE(matches(Fragment, varDecl(hasName("ref"),
4817 hasType(rValueReferenceType()))));
4818}
4819
4820TEST(TypeMatching, AutoRefTypes) {
4821 std::string Fragment = "auto a = 1;"
4822 "auto b = a;"
4823 "auto &c = a;"
4824 "auto &&d = c;"
4825 "auto &&e = 2;";
4826 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("a"),
4827 hasType(referenceType()))));
4828 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("b"),
4829 hasType(referenceType()))));
4830 EXPECT_TRUE(matches(Fragment, varDecl(hasName("c"),
4831 hasType(referenceType()))));
4832 EXPECT_TRUE(matches(Fragment, varDecl(hasName("c"),
4833 hasType(lValueReferenceType()))));
4834 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("c"),
4835 hasType(rValueReferenceType()))));
4836 EXPECT_TRUE(matches(Fragment, varDecl(hasName("d"),
4837 hasType(referenceType()))));
4838 EXPECT_TRUE(matches(Fragment, varDecl(hasName("d"),
4839 hasType(lValueReferenceType()))));
4840 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("d"),
4841 hasType(rValueReferenceType()))));
4842 EXPECT_TRUE(matches(Fragment, varDecl(hasName("e"),
4843 hasType(referenceType()))));
4844 EXPECT_TRUE(notMatches(Fragment, varDecl(hasName("e"),
4845 hasType(lValueReferenceType()))));
4846 EXPECT_TRUE(matches(Fragment, varDecl(hasName("e"),
4847 hasType(rValueReferenceType()))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004848}
4849
4850TEST(TypeMatching, PointeeTypes) {
4851 EXPECT_TRUE(matches("int b; int &a = b;",
4852 referenceType(pointee(builtinType()))));
4853 EXPECT_TRUE(matches("int *a;", pointerType(pointee(builtinType()))));
4854
4855 EXPECT_TRUE(matches("int *a;",
David Blaikieb61d0872013-02-18 19:04:16 +00004856 loc(pointerType(pointee(builtinType())))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004857
4858 EXPECT_TRUE(matches(
4859 "int const *A;",
4860 pointerType(pointee(isConstQualified(), builtinType()))));
4861 EXPECT_TRUE(notMatches(
4862 "int *A;",
4863 pointerType(pointee(isConstQualified(), builtinType()))));
4864}
4865
4866TEST(TypeMatching, MatchesPointersToConstTypes) {
4867 EXPECT_TRUE(matches("int b; int * const a = &b;",
4868 loc(pointerType())));
4869 EXPECT_TRUE(matches("int b; int * const a = &b;",
David Blaikieb61d0872013-02-18 19:04:16 +00004870 loc(pointerType())));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004871 EXPECT_TRUE(matches(
4872 "int b; const int * a = &b;",
David Blaikieb61d0872013-02-18 19:04:16 +00004873 loc(pointerType(pointee(builtinType())))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004874 EXPECT_TRUE(matches(
4875 "int b; const int * a = &b;",
4876 pointerType(pointee(builtinType()))));
4877}
4878
4879TEST(TypeMatching, MatchesTypedefTypes) {
Daniel Jasper7943eb52012-10-17 13:35:36 +00004880 EXPECT_TRUE(matches("typedef int X; X a;", varDecl(hasName("a"),
4881 hasType(typedefType()))));
Daniel Jasper516b02e2012-10-17 08:52:59 +00004882}
4883
Edwin Vanef901b712013-02-25 14:49:29 +00004884TEST(TypeMatching, MatchesTemplateSpecializationType) {
Edwin Vaneb6eae142013-02-25 20:43:32 +00004885 EXPECT_TRUE(matches("template <typename T> class A{}; A<int> a;",
Edwin Vanef901b712013-02-25 14:49:29 +00004886 templateSpecializationType()));
4887}
4888
Edwin Vaneb6eae142013-02-25 20:43:32 +00004889TEST(TypeMatching, MatchesRecordType) {
4890 EXPECT_TRUE(matches("class C{}; C c;", recordType()));
Manuel Klimek59b0af62013-02-27 11:56:58 +00004891 EXPECT_TRUE(matches("struct S{}; S s;",
4892 recordType(hasDeclaration(recordDecl(hasName("S"))))));
4893 EXPECT_TRUE(notMatches("int i;",
4894 recordType(hasDeclaration(recordDecl(hasName("S"))))));
Edwin Vaneb6eae142013-02-25 20:43:32 +00004895}
4896
4897TEST(TypeMatching, MatchesElaboratedType) {
4898 EXPECT_TRUE(matches(
4899 "namespace N {"
4900 " namespace M {"
4901 " class D {};"
4902 " }"
4903 "}"
4904 "N::M::D d;", elaboratedType()));
4905 EXPECT_TRUE(matches("class C {} c;", elaboratedType()));
4906 EXPECT_TRUE(notMatches("class C {}; C c;", elaboratedType()));
4907}
4908
4909TEST(ElaboratedTypeNarrowing, hasQualifier) {
4910 EXPECT_TRUE(matches(
4911 "namespace N {"
4912 " namespace M {"
4913 " class D {};"
4914 " }"
4915 "}"
4916 "N::M::D d;",
4917 elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
4918 EXPECT_TRUE(notMatches(
4919 "namespace M {"
4920 " class D {};"
4921 "}"
4922 "M::D d;",
4923 elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
Edwin Vane6972f6d2013-03-04 17:51:00 +00004924 EXPECT_TRUE(notMatches(
4925 "struct D {"
4926 "} d;",
4927 elaboratedType(hasQualifier(nestedNameSpecifier()))));
Edwin Vaneb6eae142013-02-25 20:43:32 +00004928}
4929
4930TEST(ElaboratedTypeNarrowing, namesType) {
4931 EXPECT_TRUE(matches(
4932 "namespace N {"
4933 " namespace M {"
4934 " class D {};"
4935 " }"
4936 "}"
4937 "N::M::D d;",
4938 elaboratedType(elaboratedType(namesType(recordType(
4939 hasDeclaration(namedDecl(hasName("D")))))))));
4940 EXPECT_TRUE(notMatches(
4941 "namespace M {"
4942 " class D {};"
4943 "}"
4944 "M::D d;",
4945 elaboratedType(elaboratedType(namesType(typedefType())))));
4946}
4947
Samuel Benzaquenf8ec4542015-08-26 16:15:59 +00004948TEST(TypeMatching, MatchesSubstTemplateTypeParmType) {
4949 const std::string code = "template <typename T>"
4950 "int F() {"
4951 " return 1 + T();"
4952 "}"
4953 "int i = F<int>();";
4954 EXPECT_FALSE(matches(code, binaryOperator(hasLHS(
4955 expr(hasType(substTemplateTypeParmType()))))));
4956 EXPECT_TRUE(matches(code, binaryOperator(hasRHS(
4957 expr(hasType(substTemplateTypeParmType()))))));
4958}
4959
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00004960TEST(NNS, MatchesNestedNameSpecifiers) {
4961 EXPECT_TRUE(matches("namespace ns { struct A {}; } ns::A a;",
4962 nestedNameSpecifier()));
4963 EXPECT_TRUE(matches("template <typename T> class A { typename T::B b; };",
4964 nestedNameSpecifier()));
4965 EXPECT_TRUE(matches("struct A { void f(); }; void A::f() {}",
4966 nestedNameSpecifier()));
Daniel Jasperc8f472c2015-12-02 13:57:46 +00004967 EXPECT_TRUE(matches("namespace a { namespace b {} } namespace ab = a::b;",
4968 nestedNameSpecifier()));
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00004969
4970 EXPECT_TRUE(matches(
4971 "struct A { static void f() {} }; void g() { A::f(); }",
4972 nestedNameSpecifier()));
4973 EXPECT_TRUE(notMatches(
4974 "struct A { static void f() {} }; void g(A* a) { a->f(); }",
4975 nestedNameSpecifier()));
4976}
4977
Daniel Jasper87c3d362012-09-20 14:12:57 +00004978TEST(NullStatement, SimpleCases) {
4979 EXPECT_TRUE(matches("void f() {int i;;}", nullStmt()));
4980 EXPECT_TRUE(notMatches("void f() {int i;}", nullStmt()));
4981}
4982
Aaron Ballman11825f22015-08-18 19:55:20 +00004983TEST(NS, Anonymous) {
4984 EXPECT_TRUE(notMatches("namespace N {}", namespaceDecl(isAnonymous())));
4985 EXPECT_TRUE(matches("namespace {}", namespaceDecl(isAnonymous())));
4986}
4987
Aaron Ballman6c79f352015-08-28 19:39:21 +00004988TEST(NS, Alias) {
4989 EXPECT_TRUE(matches("namespace test {} namespace alias = ::test;",
4990 namespaceAliasDecl(hasName("alias"))));
4991}
4992
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00004993TEST(NNS, MatchesTypes) {
4994 NestedNameSpecifierMatcher Matcher = nestedNameSpecifier(
4995 specifiesType(hasDeclaration(recordDecl(hasName("A")))));
4996 EXPECT_TRUE(matches("struct A { struct B {}; }; A::B b;", Matcher));
4997 EXPECT_TRUE(matches("struct A { struct B { struct C {}; }; }; A::B::C c;",
4998 Matcher));
4999 EXPECT_TRUE(notMatches("namespace A { struct B {}; } A::B b;", Matcher));
5000}
5001
5002TEST(NNS, MatchesNamespaceDecls) {
5003 NestedNameSpecifierMatcher Matcher = nestedNameSpecifier(
5004 specifiesNamespace(hasName("ns")));
5005 EXPECT_TRUE(matches("namespace ns { struct A {}; } ns::A a;", Matcher));
5006 EXPECT_TRUE(notMatches("namespace xx { struct A {}; } xx::A a;", Matcher));
5007 EXPECT_TRUE(notMatches("struct ns { struct A {}; }; ns::A a;", Matcher));
5008}
5009
5010TEST(NNS, BindsNestedNameSpecifiers) {
5011 EXPECT_TRUE(matchAndVerifyResultTrue(
5012 "namespace ns { struct E { struct B {}; }; } ns::E::B b;",
5013 nestedNameSpecifier(specifiesType(asString("struct ns::E"))).bind("nns"),
5014 new VerifyIdIsBoundTo<NestedNameSpecifier>("nns", "ns::struct E::")));
5015}
5016
5017TEST(NNS, BindsNestedNameSpecifierLocs) {
5018 EXPECT_TRUE(matchAndVerifyResultTrue(
5019 "namespace ns { struct B {}; } ns::B b;",
5020 loc(nestedNameSpecifier()).bind("loc"),
5021 new VerifyIdIsBoundTo<NestedNameSpecifierLoc>("loc", 1)));
5022}
5023
5024TEST(NNS, MatchesNestedNameSpecifierPrefixes) {
5025 EXPECT_TRUE(matches(
5026 "struct A { struct B { struct C {}; }; }; A::B::C c;",
5027 nestedNameSpecifier(hasPrefix(specifiesType(asString("struct A"))))));
5028 EXPECT_TRUE(matches(
5029 "struct A { struct B { struct C {}; }; }; A::B::C c;",
Daniel Jasper516b02e2012-10-17 08:52:59 +00005030 nestedNameSpecifierLoc(hasPrefix(
5031 specifiesTypeLoc(loc(qualType(asString("struct A"))))))));
Daniel Jaspera6bc1f62012-09-13 13:11:25 +00005032}
5033
Daniel Jasper6fc34332012-10-30 15:42:00 +00005034TEST(NNS, DescendantsOfNestedNameSpecifiers) {
5035 std::string Fragment =
5036 "namespace a { struct A { struct B { struct C {}; }; }; };"
5037 "void f() { a::A::B::C c; }";
5038 EXPECT_TRUE(matches(
5039 Fragment,
5040 nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
5041 hasDescendant(nestedNameSpecifier(
5042 specifiesNamespace(hasName("a")))))));
5043 EXPECT_TRUE(notMatches(
5044 Fragment,
5045 nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
5046 has(nestedNameSpecifier(
5047 specifiesNamespace(hasName("a")))))));
5048 EXPECT_TRUE(matches(
5049 Fragment,
5050 nestedNameSpecifier(specifiesType(asString("struct a::A")),
5051 has(nestedNameSpecifier(
5052 specifiesNamespace(hasName("a")))))));
5053
5054 // Not really useful because a NestedNameSpecifier can af at most one child,
5055 // but to complete the interface.
5056 EXPECT_TRUE(matchAndVerifyResultTrue(
5057 Fragment,
5058 nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
5059 forEach(nestedNameSpecifier().bind("x"))),
5060 new VerifyIdIsBoundTo<NestedNameSpecifier>("x", 1)));
5061}
5062
5063TEST(NNS, NestedNameSpecifiersAsDescendants) {
5064 std::string Fragment =
5065 "namespace a { struct A { struct B { struct C {}; }; }; };"
5066 "void f() { a::A::B::C c; }";
5067 EXPECT_TRUE(matches(
5068 Fragment,
5069 decl(hasDescendant(nestedNameSpecifier(specifiesType(
5070 asString("struct a::A")))))));
5071 EXPECT_TRUE(matchAndVerifyResultTrue(
5072 Fragment,
5073 functionDecl(hasName("f"),
5074 forEachDescendant(nestedNameSpecifier().bind("x"))),
5075 // Nested names: a, a::A and a::A::B.
5076 new VerifyIdIsBoundTo<NestedNameSpecifier>("x", 3)));
5077}
5078
5079TEST(NNSLoc, DescendantsOfNestedNameSpecifierLocs) {
5080 std::string Fragment =
5081 "namespace a { struct A { struct B { struct C {}; }; }; };"
5082 "void f() { a::A::B::C c; }";
5083 EXPECT_TRUE(matches(
5084 Fragment,
5085 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
5086 hasDescendant(loc(nestedNameSpecifier(
5087 specifiesNamespace(hasName("a"))))))));
5088 EXPECT_TRUE(notMatches(
5089 Fragment,
5090 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
5091 has(loc(nestedNameSpecifier(
5092 specifiesNamespace(hasName("a"))))))));
5093 EXPECT_TRUE(matches(
5094 Fragment,
5095 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A"))),
5096 has(loc(nestedNameSpecifier(
5097 specifiesNamespace(hasName("a"))))))));
5098
5099 EXPECT_TRUE(matchAndVerifyResultTrue(
5100 Fragment,
5101 nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
5102 forEach(nestedNameSpecifierLoc().bind("x"))),
5103 new VerifyIdIsBoundTo<NestedNameSpecifierLoc>("x", 1)));
5104}
5105
5106TEST(NNSLoc, NestedNameSpecifierLocsAsDescendants) {
5107 std::string Fragment =
5108 "namespace a { struct A { struct B { struct C {}; }; }; };"
5109 "void f() { a::A::B::C c; }";
5110 EXPECT_TRUE(matches(
5111 Fragment,
5112 decl(hasDescendant(loc(nestedNameSpecifier(specifiesType(
5113 asString("struct a::A"))))))));
5114 EXPECT_TRUE(matchAndVerifyResultTrue(
5115 Fragment,
5116 functionDecl(hasName("f"),
5117 forEachDescendant(nestedNameSpecifierLoc().bind("x"))),
5118 // Nested names: a, a::A and a::A::B.
5119 new VerifyIdIsBoundTo<NestedNameSpecifierLoc>("x", 3)));
5120}
5121
Manuel Klimek191c0932013-02-01 13:41:35 +00005122template <typename T> class VerifyMatchOnNode : public BoundNodesCallback {
Manuel Klimekc2687452012-10-24 14:47:44 +00005123public:
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005124 VerifyMatchOnNode(StringRef Id, const internal::Matcher<T> &InnerMatcher,
5125 StringRef InnerId)
5126 : Id(Id), InnerMatcher(InnerMatcher), InnerId(InnerId) {
Daniel Jaspere9aa6872012-10-29 10:48:25 +00005127 }
5128
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005129 bool run(const BoundNodes *Nodes) override { return false; }
Manuel Klimek191c0932013-02-01 13:41:35 +00005130
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005131 bool run(const BoundNodes *Nodes, ASTContext *Context) override {
Manuel Klimekc2687452012-10-24 14:47:44 +00005132 const T *Node = Nodes->getNodeAs<T>(Id);
Benjamin Kramer76645582014-07-23 11:41:44 +00005133 return selectFirst<T>(InnerId, match(InnerMatcher, *Node, *Context)) !=
5134 nullptr;
Manuel Klimekc2687452012-10-24 14:47:44 +00005135 }
5136private:
5137 std::string Id;
5138 internal::Matcher<T> InnerMatcher;
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005139 std::string InnerId;
Manuel Klimekc2687452012-10-24 14:47:44 +00005140};
5141
5142TEST(MatchFinder, CanMatchDeclarationsRecursively) {
Manuel Klimek191c0932013-02-01 13:41:35 +00005143 EXPECT_TRUE(matchAndVerifyResultTrue(
5144 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5145 new VerifyMatchOnNode<clang::Decl>(
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005146 "X", decl(hasDescendant(recordDecl(hasName("X::Y")).bind("Y"))),
5147 "Y")));
Manuel Klimek191c0932013-02-01 13:41:35 +00005148 EXPECT_TRUE(matchAndVerifyResultFalse(
5149 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5150 new VerifyMatchOnNode<clang::Decl>(
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005151 "X", decl(hasDescendant(recordDecl(hasName("X::Z")).bind("Z"))),
5152 "Z")));
Manuel Klimekc2687452012-10-24 14:47:44 +00005153}
5154
5155TEST(MatchFinder, CanMatchStatementsRecursively) {
Manuel Klimek191c0932013-02-01 13:41:35 +00005156 EXPECT_TRUE(matchAndVerifyResultTrue(
5157 "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005158 new VerifyMatchOnNode<clang::Stmt>(
5159 "if", stmt(hasDescendant(forStmt().bind("for"))), "for")));
Manuel Klimek191c0932013-02-01 13:41:35 +00005160 EXPECT_TRUE(matchAndVerifyResultFalse(
5161 "void f() { if (1) { for (;;) { } } }", ifStmt().bind("if"),
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005162 new VerifyMatchOnNode<clang::Stmt>(
5163 "if", stmt(hasDescendant(declStmt().bind("decl"))), "decl")));
Manuel Klimek191c0932013-02-01 13:41:35 +00005164}
5165
5166TEST(MatchFinder, CanMatchSingleNodesRecursively) {
5167 EXPECT_TRUE(matchAndVerifyResultTrue(
5168 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5169 new VerifyMatchOnNode<clang::Decl>(
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005170 "X", recordDecl(has(recordDecl(hasName("X::Y")).bind("Y"))), "Y")));
Manuel Klimek191c0932013-02-01 13:41:35 +00005171 EXPECT_TRUE(matchAndVerifyResultFalse(
5172 "class X { class Y {}; };", recordDecl(hasName("::X")).bind("X"),
5173 new VerifyMatchOnNode<clang::Decl>(
Manuel Klimek2cff49e2013-02-06 10:33:21 +00005174 "X", recordDecl(has(recordDecl(hasName("X::Z")).bind("Z"))), "Z")));
Manuel Klimekc2687452012-10-24 14:47:44 +00005175}
5176
Manuel Klimekbee08572013-02-07 12:42:10 +00005177template <typename T>
5178class VerifyAncestorHasChildIsEqual : public BoundNodesCallback {
5179public:
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005180 bool run(const BoundNodes *Nodes) override { return false; }
Manuel Klimekbee08572013-02-07 12:42:10 +00005181
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005182 bool run(const BoundNodes *Nodes, ASTContext *Context) override {
Manuel Klimekbee08572013-02-07 12:42:10 +00005183 const T *Node = Nodes->getNodeAs<T>("");
5184 return verify(*Nodes, *Context, Node);
5185 }
5186
5187 bool verify(const BoundNodes &Nodes, ASTContext &Context, const Stmt *Node) {
Manuel Klimeka2c2a4f2014-05-27 12:31:10 +00005188 // Use the original typed pointer to verify we can pass pointers to subtypes
5189 // to equalsNode.
5190 const T *TypedNode = cast<T>(Node);
Benjamin Kramer76645582014-07-23 11:41:44 +00005191 return selectFirst<T>(
Manuel Klimeka2c2a4f2014-05-27 12:31:10 +00005192 "", match(stmt(hasParent(
5193 stmt(has(stmt(equalsNode(TypedNode)))).bind(""))),
Craig Topper416fa342014-06-08 08:38:12 +00005194 *Node, Context)) != nullptr;
Manuel Klimekbee08572013-02-07 12:42:10 +00005195 }
5196 bool verify(const BoundNodes &Nodes, ASTContext &Context, const Decl *Node) {
Manuel Klimeka2c2a4f2014-05-27 12:31:10 +00005197 // Use the original typed pointer to verify we can pass pointers to subtypes
5198 // to equalsNode.
5199 const T *TypedNode = cast<T>(Node);
Benjamin Kramer76645582014-07-23 11:41:44 +00005200 return selectFirst<T>(
Manuel Klimeka2c2a4f2014-05-27 12:31:10 +00005201 "", match(decl(hasParent(
5202 decl(has(decl(equalsNode(TypedNode)))).bind(""))),
Craig Topper416fa342014-06-08 08:38:12 +00005203 *Node, Context)) != nullptr;
Manuel Klimekbee08572013-02-07 12:42:10 +00005204 }
Angel Garcia Gomez4647ed72015-10-30 09:35:51 +00005205 bool verify(const BoundNodes &Nodes, ASTContext &Context, const Type *Node) {
5206 // Use the original typed pointer to verify we can pass pointers to subtypes
5207 // to equalsNode.
5208 const T *TypedNode = cast<T>(Node);
5209 const auto *Dec = Nodes.getNodeAs<FieldDecl>("decl");
5210 return selectFirst<T>(
5211 "", match(fieldDecl(hasParent(decl(has(fieldDecl(
5212 hasType(type(equalsNode(TypedNode)).bind(""))))))),
5213 *Dec, Context)) != nullptr;
5214 }
Manuel Klimekbee08572013-02-07 12:42:10 +00005215};
5216
5217TEST(IsEqualTo, MatchesNodesByIdentity) {
5218 EXPECT_TRUE(matchAndVerifyResultTrue(
5219 "class X { class Y {}; };", recordDecl(hasName("::X::Y")).bind(""),
Manuel Klimeka2c2a4f2014-05-27 12:31:10 +00005220 new VerifyAncestorHasChildIsEqual<CXXRecordDecl>()));
5221 EXPECT_TRUE(matchAndVerifyResultTrue(
5222 "void f() { if (true) if(true) {} }", ifStmt().bind(""),
5223 new VerifyAncestorHasChildIsEqual<IfStmt>()));
Angel Garcia Gomez4647ed72015-10-30 09:35:51 +00005224 EXPECT_TRUE(matchAndVerifyResultTrue(
5225 "class X { class Y {} y; };",
5226 fieldDecl(hasName("y"), hasType(type().bind(""))).bind("decl"),
5227 new VerifyAncestorHasChildIsEqual<Type>()));
Manuel Klimekbee08572013-02-07 12:42:10 +00005228}
5229
Samuel Benzaquen43dcf212014-10-22 20:31:05 +00005230TEST(MatchFinder, CheckProfiling) {
5231 MatchFinder::MatchFinderOptions Options;
5232 llvm::StringMap<llvm::TimeRecord> Records;
5233 Options.CheckProfiling.emplace(Records);
5234 MatchFinder Finder(std::move(Options));
5235
5236 struct NamedCallback : public MatchFinder::MatchCallback {
5237 void run(const MatchFinder::MatchResult &Result) override {}
5238 StringRef getID() const override { return "MyID"; }
5239 } Callback;
5240 Finder.addMatcher(decl(), &Callback);
5241 std::unique_ptr<FrontendActionFactory> Factory(
5242 newFrontendActionFactory(&Finder));
5243 ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), "int x;"));
5244
5245 EXPECT_EQ(1u, Records.size());
5246 EXPECT_EQ("MyID", Records.begin()->getKey());
5247}
5248
Manuel Klimekbd0e2b72012-11-02 01:31:03 +00005249class VerifyStartOfTranslationUnit : public MatchFinder::MatchCallback {
5250public:
5251 VerifyStartOfTranslationUnit() : Called(false) {}
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005252 void run(const MatchFinder::MatchResult &Result) override {
Manuel Klimekbd0e2b72012-11-02 01:31:03 +00005253 EXPECT_TRUE(Called);
5254 }
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005255 void onStartOfTranslationUnit() override { Called = true; }
Manuel Klimekbd0e2b72012-11-02 01:31:03 +00005256 bool Called;
5257};
5258
5259TEST(MatchFinder, InterceptsStartOfTranslationUnit) {
5260 MatchFinder Finder;
5261 VerifyStartOfTranslationUnit VerifyCallback;
5262 Finder.addMatcher(decl(), &VerifyCallback);
Ahmed Charlesb8984322014-03-07 20:03:18 +00005263 std::unique_ptr<FrontendActionFactory> Factory(
5264 newFrontendActionFactory(&Finder));
Manuel Klimekbd0e2b72012-11-02 01:31:03 +00005265 ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), "int x;"));
5266 EXPECT_TRUE(VerifyCallback.Called);
Peter Collingbournea2334162013-11-07 22:30:36 +00005267
5268 VerifyCallback.Called = false;
Ahmed Charlesb8984322014-03-07 20:03:18 +00005269 std::unique_ptr<ASTUnit> AST(tooling::buildASTFromCode("int x;"));
Peter Collingbournea2334162013-11-07 22:30:36 +00005270 ASSERT_TRUE(AST.get());
5271 Finder.matchAST(AST->getASTContext());
5272 EXPECT_TRUE(VerifyCallback.Called);
Manuel Klimekbd0e2b72012-11-02 01:31:03 +00005273}
5274
Peter Collingbourne6a55bb22013-05-28 19:21:51 +00005275class VerifyEndOfTranslationUnit : public MatchFinder::MatchCallback {
5276public:
5277 VerifyEndOfTranslationUnit() : Called(false) {}
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005278 void run(const MatchFinder::MatchResult &Result) override {
Peter Collingbourne6a55bb22013-05-28 19:21:51 +00005279 EXPECT_FALSE(Called);
5280 }
Alexander Kornienko34eb2072015-04-11 02:00:23 +00005281 void onEndOfTranslationUnit() override { Called = true; }
Peter Collingbourne6a55bb22013-05-28 19:21:51 +00005282 bool Called;
5283};
5284
5285TEST(MatchFinder, InterceptsEndOfTranslationUnit) {
5286 MatchFinder Finder;
5287 VerifyEndOfTranslationUnit VerifyCallback;
5288 Finder.addMatcher(decl(), &VerifyCallback);
Ahmed Charlesb8984322014-03-07 20:03:18 +00005289 std::unique_ptr<FrontendActionFactory> Factory(
5290 newFrontendActionFactory(&Finder));
Peter Collingbourne6a55bb22013-05-28 19:21:51 +00005291 ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), "int x;"));
5292 EXPECT_TRUE(VerifyCallback.Called);
Peter Collingbournea2334162013-11-07 22:30:36 +00005293
5294 VerifyCallback.Called = false;
Ahmed Charlesb8984322014-03-07 20:03:18 +00005295 std::unique_ptr<ASTUnit> AST(tooling::buildASTFromCode("int x;"));
Peter Collingbournea2334162013-11-07 22:30:36 +00005296 ASSERT_TRUE(AST.get());
5297 Finder.matchAST(AST->getASTContext());
5298 EXPECT_TRUE(VerifyCallback.Called);
Peter Collingbourne6a55bb22013-05-28 19:21:51 +00005299}
5300
Daniel Jasper739ae642016-02-03 14:29:55 +00005301TEST(Matcher, matchOverEntireASTContext) {
5302 std::unique_ptr<ASTUnit> AST =
5303 clang::tooling::buildASTFromCode("struct { int *foo; };");
5304 ASSERT_TRUE(AST.get());
5305 auto PT = selectFirst<PointerType>(
5306 "x", match(pointerType().bind("x"), AST->getASTContext()));
5307 EXPECT_NE(nullptr, PT);
5308}
5309
Manuel Klimekbbb75852013-06-20 14:06:32 +00005310TEST(EqualsBoundNodeMatcher, QualType) {
5311 EXPECT_TRUE(matches(
5312 "int i = 1;", varDecl(hasType(qualType().bind("type")),
5313 hasInitializer(ignoringParenImpCasts(
5314 hasType(qualType(equalsBoundNode("type"))))))));
5315 EXPECT_TRUE(notMatches("int i = 1.f;",
5316 varDecl(hasType(qualType().bind("type")),
5317 hasInitializer(ignoringParenImpCasts(hasType(
5318 qualType(equalsBoundNode("type"))))))));
5319}
5320
5321TEST(EqualsBoundNodeMatcher, NonMatchingTypes) {
5322 EXPECT_TRUE(notMatches(
5323 "int i = 1;", varDecl(namedDecl(hasName("i")).bind("name"),
5324 hasInitializer(ignoringParenImpCasts(
5325 hasType(qualType(equalsBoundNode("type"))))))));
5326}
5327
5328TEST(EqualsBoundNodeMatcher, Stmt) {
5329 EXPECT_TRUE(
5330 matches("void f() { if(true) {} }",
5331 stmt(allOf(ifStmt().bind("if"),
5332 hasParent(stmt(has(stmt(equalsBoundNode("if")))))))));
5333
5334 EXPECT_TRUE(notMatches(
5335 "void f() { if(true) { if (true) {} } }",
5336 stmt(allOf(ifStmt().bind("if"), has(stmt(equalsBoundNode("if")))))));
5337}
5338
5339TEST(EqualsBoundNodeMatcher, Decl) {
5340 EXPECT_TRUE(matches(
5341 "class X { class Y {}; };",
5342 decl(allOf(recordDecl(hasName("::X::Y")).bind("record"),
5343 hasParent(decl(has(decl(equalsBoundNode("record")))))))));
5344
5345 EXPECT_TRUE(notMatches("class X { class Y {}; };",
5346 decl(allOf(recordDecl(hasName("::X")).bind("record"),
5347 has(decl(equalsBoundNode("record")))))));
5348}
5349
5350TEST(EqualsBoundNodeMatcher, Type) {
5351 EXPECT_TRUE(matches(
5352 "class X { int a; int b; };",
5353 recordDecl(
5354 has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
5355 has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
5356
5357 EXPECT_TRUE(notMatches(
5358 "class X { int a; double b; };",
5359 recordDecl(
5360 has(fieldDecl(hasName("a"), hasType(type().bind("t")))),
5361 has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t"))))))));
5362}
5363
5364TEST(EqualsBoundNodeMatcher, UsingForEachDescendant) {
Manuel Klimekbbb75852013-06-20 14:06:32 +00005365 EXPECT_TRUE(matchAndVerifyResultTrue(
5366 "int f() {"
5367 " if (1) {"
5368 " int i = 9;"
5369 " }"
5370 " int j = 10;"
5371 " {"
5372 " float k = 9.0;"
5373 " }"
5374 " return 0;"
5375 "}",
5376 // Look for variable declarations within functions whose type is the same
5377 // as the function return type.
5378 functionDecl(returns(qualType().bind("type")),
5379 forEachDescendant(varDecl(hasType(
5380 qualType(equalsBoundNode("type")))).bind("decl"))),
5381 // Only i and j should match, not k.
5382 new VerifyIdIsBoundTo<VarDecl>("decl", 2)));
5383}
5384
5385TEST(EqualsBoundNodeMatcher, FiltersMatchedCombinations) {
5386 EXPECT_TRUE(matchAndVerifyResultTrue(
5387 "void f() {"
5388 " int x;"
5389 " double d;"
5390 " x = d + x - d + x;"
5391 "}",
5392 functionDecl(
5393 hasName("f"), forEachDescendant(varDecl().bind("d")),
5394 forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d")))))),
5395 new VerifyIdIsBoundTo<VarDecl>("d", 5)));
5396}
5397
Manuel Klimekce68f772014-03-25 14:39:26 +00005398TEST(EqualsBoundNodeMatcher, UnlessDescendantsOfAncestorsMatch) {
5399 EXPECT_TRUE(matchAndVerifyResultTrue(
5400 "struct StringRef { int size() const; const char* data() const; };"
5401 "void f(StringRef v) {"
5402 " v.data();"
5403 "}",
Aaron Ballman512fb642015-09-17 13:30:52 +00005404 cxxMemberCallExpr(
5405 callee(cxxMethodDecl(hasName("data"))),
5406 on(declRefExpr(to(
5407 varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),
5408 unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(
5409 callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
Manuel Klimekce68f772014-03-25 14:39:26 +00005410 on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
5411 .bind("data"),
5412 new VerifyIdIsBoundTo<Expr>("data", 1)));
5413
5414 EXPECT_FALSE(matches(
5415 "struct StringRef { int size() const; const char* data() const; };"
5416 "void f(StringRef v) {"
5417 " v.data();"
5418 " v.size();"
5419 "}",
Aaron Ballman512fb642015-09-17 13:30:52 +00005420 cxxMemberCallExpr(
5421 callee(cxxMethodDecl(hasName("data"))),
5422 on(declRefExpr(to(
5423 varDecl(hasType(recordDecl(hasName("StringRef")))).bind("var")))),
5424 unless(hasAncestor(stmt(hasDescendant(cxxMemberCallExpr(
5425 callee(cxxMethodDecl(anyOf(hasName("size"), hasName("length")))),
Manuel Klimekce68f772014-03-25 14:39:26 +00005426 on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
5427 .bind("data")));
5428}
5429
Aaron Ballman66eb58a2016-04-14 16:05:45 +00005430TEST(TypedefDeclMatcher, Match) {
Manuel Klimekd3aa1f42014-11-25 17:01:06 +00005431 EXPECT_TRUE(matches("typedef int typedefDeclTest;",
5432 typedefDecl(hasName("typedefDeclTest"))));
Aaron Ballman66eb58a2016-04-14 16:05:45 +00005433 EXPECT_TRUE(notMatches("using typedefDeclTest2 = int;",
5434 typedefDecl(hasName("typedefDeclTest2"))));
5435}
5436
5437TEST(TypeAliasDeclMatcher, Match) {
5438 EXPECT_TRUE(matches("using typeAliasTest2 = int;",
5439 typeAliasDecl(hasName("typeAliasTest2"))));
5440 EXPECT_TRUE(notMatches("typedef int typeAliasTest;",
5441 typeAliasDecl(hasName("typeAliasTest"))));
5442}
5443
5444TEST(TypedefNameDeclMatcher, Match) {
5445 EXPECT_TRUE(matches("typedef int typedefNameDeclTest1;",
5446 typedefNameDecl(hasName("typedefNameDeclTest1"))));
5447 EXPECT_TRUE(matches("using typedefNameDeclTest2 = int;",
5448 typedefNameDecl(hasName("typedefNameDeclTest2"))));
Manuel Klimekd3aa1f42014-11-25 17:01:06 +00005449}
5450
Aaron Ballman11825f22015-08-18 19:55:20 +00005451TEST(IsInlineMatcher, IsInline) {
5452 EXPECT_TRUE(matches("void g(); inline void f();",
5453 functionDecl(isInline(), hasName("f"))));
5454 EXPECT_TRUE(matches("namespace n { inline namespace m {} }",
5455 namespaceDecl(isInline(), hasName("m"))));
5456}
5457
Aaron Ballman7e7b7b22016-02-01 14:11:47 +00005458// FIXME: Figure out how to specify paths so the following tests pass on
5459// Windows.
Manuel Klimekd3aa1f42014-11-25 17:01:06 +00005460#ifndef LLVM_ON_WIN32
5461
5462TEST(Matcher, IsExpansionInMainFileMatcher) {
5463 EXPECT_TRUE(matches("class X {};",
5464 recordDecl(hasName("X"), isExpansionInMainFile())));
5465 EXPECT_TRUE(notMatches("", recordDecl(isExpansionInMainFile())));
5466 FileContentMappings M;
5467 M.push_back(std::make_pair("/other", "class X {};"));
5468 EXPECT_TRUE(matchesConditionally("#include <other>\n",
5469 recordDecl(isExpansionInMainFile()), false,
5470 "-isystem/", M));
5471}
5472
5473TEST(Matcher, IsExpansionInSystemHeader) {
5474 FileContentMappings M;
5475 M.push_back(std::make_pair("/other", "class X {};"));
5476 EXPECT_TRUE(matchesConditionally(
5477 "#include \"other\"\n", recordDecl(isExpansionInSystemHeader()), true,
5478 "-isystem/", M));
5479 EXPECT_TRUE(matchesConditionally("#include \"other\"\n",
5480 recordDecl(isExpansionInSystemHeader()),
5481 false, "-I/", M));
5482 EXPECT_TRUE(notMatches("class X {};",
5483 recordDecl(isExpansionInSystemHeader())));
5484 EXPECT_TRUE(notMatches("", recordDecl(isExpansionInSystemHeader())));
5485}
5486
5487TEST(Matcher, IsExpansionInFileMatching) {
5488 FileContentMappings M;
5489 M.push_back(std::make_pair("/foo", "class A {};"));
5490 M.push_back(std::make_pair("/bar", "class B {};"));
5491 EXPECT_TRUE(matchesConditionally(
5492 "#include <foo>\n"
5493 "#include <bar>\n"
5494 "class X {};",
5495 recordDecl(isExpansionInFileMatching("b.*"), hasName("B")), true,
5496 "-isystem/", M));
5497 EXPECT_TRUE(matchesConditionally(
5498 "#include <foo>\n"
5499 "#include <bar>\n"
5500 "class X {};",
5501 recordDecl(isExpansionInFileMatching("f.*"), hasName("X")), false,
5502 "-isystem/", M));
5503}
5504
5505#endif // LLVM_ON_WIN32
5506
Manuel Klimekbfa43572015-03-12 15:48:15 +00005507
5508TEST(ObjCMessageExprMatcher, SimpleExprs) {
5509 // don't find ObjCMessageExpr where none are present
5510 EXPECT_TRUE(notMatchesObjC("", objcMessageExpr(anything())));
5511
5512 std::string Objc1String =
5513 "@interface Str "
5514 " - (Str *)uppercaseString:(Str *)str;"
5515 "@end "
5516 "@interface foo "
5517 "- (void)meth:(Str *)text;"
5518 "@end "
5519 " "
5520 "@implementation foo "
5521 "- (void) meth:(Str *)text { "
5522 " [self contents];"
5523 " Str *up = [text uppercaseString];"
5524 "} "
5525 "@end ";
5526 EXPECT_TRUE(matchesObjC(
5527 Objc1String,
5528 objcMessageExpr(anything())));
5529 EXPECT_TRUE(matchesObjC(
5530 Objc1String,
5531 objcMessageExpr(hasSelector("contents"))));
5532 EXPECT_TRUE(matchesObjC(
5533 Objc1String,
5534 objcMessageExpr(matchesSelector("cont*"))));
5535 EXPECT_FALSE(matchesObjC(
5536 Objc1String,
5537 objcMessageExpr(matchesSelector("?cont*"))));
5538 EXPECT_TRUE(notMatchesObjC(
5539 Objc1String,
5540 objcMessageExpr(hasSelector("contents"), hasNullSelector())));
5541 EXPECT_TRUE(matchesObjC(
5542 Objc1String,
5543 objcMessageExpr(hasSelector("contents"), hasUnarySelector())));
5544 EXPECT_TRUE(matchesObjC(
5545 Objc1String,
Manuel Klimeke67a9d62015-09-08 10:11:26 +00005546 objcMessageExpr(hasSelector("contents"), numSelectorArgs(0))));
5547 EXPECT_TRUE(matchesObjC(
5548 Objc1String,
Manuel Klimekbfa43572015-03-12 15:48:15 +00005549 objcMessageExpr(matchesSelector("uppercase*"),
5550 argumentCountIs(0)
5551 )));
Manuel Klimekbfa43572015-03-12 15:48:15 +00005552}
5553
Aaron Ballman232e63d2016-02-16 21:02:23 +00005554TEST(NullPointerConstants, Basic) {
5555 EXPECT_TRUE(matches("#define NULL ((void *)0)\n"
5556 "void *v1 = NULL;", expr(nullPointerConstant())));
5557 EXPECT_TRUE(matches("void *v2 = nullptr;", expr(nullPointerConstant())));
5558 EXPECT_TRUE(matches("void *v3 = __null;", expr(nullPointerConstant())));
5559 EXPECT_TRUE(matches("char *cp = (char *)0;", expr(nullPointerConstant())));
5560 EXPECT_TRUE(matches("int *ip = 0;", expr(nullPointerConstant())));
Aaron Ballmancc928c82016-02-16 21:06:10 +00005561 EXPECT_TRUE(notMatches("int i = 0;", expr(nullPointerConstant())));
Aaron Ballman232e63d2016-02-16 21:02:23 +00005562}
5563
Alexander Kornienko976921d2016-03-22 11:03:03 +00005564TEST(StatementMatcher, HasReturnValue) {
5565 StatementMatcher RetVal = returnStmt(hasReturnValue(binaryOperator()));
5566 EXPECT_TRUE(matches("int F() { int a, b; return a + b; }", RetVal));
5567 EXPECT_FALSE(matches("int F() { int a; return a; }", RetVal));
Matthias Gehrec27d8d82016-04-12 05:43:18 +00005568 EXPECT_FALSE(matches("void F() { return; }", RetVal));
Alexander Kornienko976921d2016-03-22 11:03:03 +00005569}
5570
Manuel Klimek04616e42012-07-06 05:48:52 +00005571} // end namespace ast_matchers
5572} // end namespace clang