xref: /llvm-project/clang-tools-extra/unittests/clang-tidy/AddConstTest.cpp (revision 1b0fcf1e42e05611ec37aa7956988ae6317ad116)
1 #include "../clang-tidy/utils/FixItHintUtils.h"
2 #include "ClangTidyDiagnosticConsumer.h"
3 #include "ClangTidyTest.h"
4 #include "clang/ASTMatchers/ASTMatchFinder.h"
5 #include "clang/ASTMatchers/ASTMatchers.h"
6 #include "clang/Tooling/Tooling.h"
7 #include "gtest/gtest.h"
8 #include <optional>
9 
10 namespace clang {
11 namespace tidy {
12 
13 namespace {
14 using namespace clang::ast_matchers;
15 using namespace utils::fixit;
16 
17 template <QualifierTarget CT, QualifierPolicy CP>
18 class ConstTransform : public ClangTidyCheck {
19 public:
20   ConstTransform(StringRef CheckName, ClangTidyContext *Context)
21       : ClangTidyCheck(CheckName, Context) {}
22 
23   void registerMatchers(MatchFinder *Finder) override {
24     Finder->addMatcher(varDecl(hasName("target")).bind("var"), this);
25   }
26 
27   void check(const MatchFinder::MatchResult &Result) override {
28     const auto *D = Result.Nodes.getNodeAs<VarDecl>("var");
29     using utils::fixit::addQualifierToVarDecl;
30     std::optional<FixItHint> Fix =
31         addQualifierToVarDecl(*D, *Result.Context, Qualifiers::Const, CT, CP);
32     auto Diag = diag(D->getBeginLoc(), "doing const transformation");
33     if (Fix)
34       Diag << *Fix;
35   }
36 };
37 } // namespace
38 
39 namespace test {
40 using PointeeLTransform =
41     ConstTransform<QualifierTarget::Pointee, QualifierPolicy::Left>;
42 using PointeeRTransform =
43     ConstTransform<QualifierTarget::Pointee, QualifierPolicy::Right>;
44 
45 using ValueLTransform =
46     ConstTransform<QualifierTarget::Value, QualifierPolicy::Left>;
47 using ValueRTransform =
48     ConstTransform<QualifierTarget::Value, QualifierPolicy::Right>;
49 
50 // ----------------------------------------------------------------------------
51 // Test Value-like types. Everything with indirection is done later.
52 // ----------------------------------------------------------------------------
53 
54 TEST(Values, Builtin) {
55   StringRef Snippet = "int target = 0;";
56 
57   EXPECT_EQ("const int target = 0;", runCheckOnCode<ValueLTransform>(Snippet));
58   EXPECT_EQ("const int target = 0;",
59             runCheckOnCode<PointeeLTransform>(Snippet));
60 
61   EXPECT_EQ("int const target = 0;", runCheckOnCode<ValueRTransform>(Snippet));
62   EXPECT_EQ("int const target = 0;",
63             runCheckOnCode<PointeeRTransform>(Snippet));
64 }
65 TEST(Values, TypedefBuiltin) {
66   StringRef T = "typedef int MyInt;";
67   StringRef S = "MyInt target = 0;";
68   auto Cat = [&T](StringRef S) { return (T + S).str(); };
69 
70   EXPECT_EQ(Cat("const MyInt target = 0;"),
71             runCheckOnCode<ValueLTransform>(Cat(S)));
72   EXPECT_EQ(Cat("const MyInt target = 0;"),
73             runCheckOnCode<PointeeLTransform>(Cat(S)));
74 
75   EXPECT_EQ(Cat("MyInt const target = 0;"),
76             runCheckOnCode<ValueRTransform>(Cat(S)));
77   EXPECT_EQ(Cat("MyInt const target = 0;"),
78             runCheckOnCode<PointeeRTransform>(Cat(S)));
79 }
80 TEST(Values, TypedefBuiltinPointer) {
81   StringRef T = "typedef int* MyInt;";
82   StringRef S = "MyInt target = nullptr;";
83   auto Cat = [&T](StringRef S) { return (T + S).str(); };
84 
85   EXPECT_EQ(Cat("const MyInt target = nullptr;"),
86             runCheckOnCode<ValueLTransform>(Cat(S)));
87   EXPECT_EQ(Cat("const MyInt target = nullptr;"),
88             runCheckOnCode<PointeeLTransform>(Cat(S)));
89 
90   EXPECT_EQ(Cat("MyInt const target = nullptr;"),
91             runCheckOnCode<ValueRTransform>(Cat(S)));
92   EXPECT_EQ(Cat("MyInt const target = nullptr;"),
93             runCheckOnCode<PointeeRTransform>(Cat(S)));
94 }
95 TEST(Values, UsingBuiltin) {
96   StringRef T = "using MyInt = int;";
97   StringRef S = "MyInt target = 0;";
98   auto Cat = [&T](StringRef S) { return (T + S).str(); };
99 
100   EXPECT_EQ(Cat("const MyInt target = 0;"),
101             runCheckOnCode<ValueLTransform>(Cat(S)));
102   EXPECT_EQ(Cat("const MyInt target = 0;"),
103             runCheckOnCode<PointeeLTransform>(Cat(S)));
104 
105   EXPECT_EQ(Cat("MyInt const target = 0;"),
106             runCheckOnCode<ValueRTransform>(Cat(S)));
107   EXPECT_EQ(Cat("MyInt const target = 0;"),
108             runCheckOnCode<PointeeRTransform>(Cat(S)));
109 }
110 TEST(Values, UsingBuiltinPointer) {
111   StringRef T = "using MyInt = int*;";
112   StringRef S = "MyInt target = nullptr;";
113   auto Cat = [&T](StringRef S) { return (T + S).str(); };
114 
115   EXPECT_EQ(Cat("const MyInt target = nullptr;"),
116             runCheckOnCode<ValueLTransform>(Cat(S)));
117   EXPECT_EQ(Cat("const MyInt target = nullptr;"),
118             runCheckOnCode<PointeeLTransform>(Cat(S)));
119 
120   EXPECT_EQ(Cat("MyInt const target = nullptr;"),
121             runCheckOnCode<ValueRTransform>(Cat(S)));
122   EXPECT_EQ(Cat("MyInt const target = nullptr;"),
123             runCheckOnCode<PointeeRTransform>(Cat(S)));
124 }
125 TEST(Values, AutoValue) {
126   StringRef T = "int f() { return 42; }\n";
127   StringRef S = "auto target = f();";
128   auto Cat = [&T](StringRef S) { return (T + S).str(); };
129 
130   EXPECT_EQ(Cat("const auto target = f();"),
131             runCheckOnCode<ValueLTransform>(Cat(S)));
132   EXPECT_EQ(Cat("const auto target = f();"),
133             runCheckOnCode<PointeeLTransform>(Cat(S)));
134 
135   EXPECT_EQ(Cat("auto const target = f();"),
136             runCheckOnCode<ValueRTransform>(Cat(S)));
137   EXPECT_EQ(Cat("auto const target = f();"),
138             runCheckOnCode<PointeeRTransform>(Cat(S)));
139 }
140 TEST(Values, AutoPointer) {
141   StringRef T = "int* f() { return nullptr; }\n";
142   StringRef S = "auto target = f();";
143   auto Cat = [&T](StringRef S) { return (T + S).str(); };
144 
145   EXPECT_EQ(Cat("const auto target = f();"),
146             runCheckOnCode<ValueLTransform>(Cat(S)));
147   EXPECT_EQ(Cat("const auto target = f();"),
148             runCheckOnCode<PointeeLTransform>(Cat(S)));
149 
150   EXPECT_EQ(Cat("auto const target = f();"),
151             runCheckOnCode<ValueRTransform>(Cat(S)));
152   EXPECT_EQ(Cat("auto const target = f();"),
153             runCheckOnCode<PointeeRTransform>(Cat(S)));
154 }
155 TEST(Values, AutoReference) {
156   StringRef T = "static int global = 42; int& f() { return global; }\n";
157   StringRef S = "auto target = f();";
158   auto Cat = [&T](StringRef S) { return (T + S).str(); };
159 
160   EXPECT_EQ(Cat("const auto target = f();"),
161             runCheckOnCode<ValueLTransform>(Cat(S)));
162   EXPECT_EQ(Cat("const auto target = f();"),
163             runCheckOnCode<PointeeLTransform>(Cat(S)));
164 
165   EXPECT_EQ(Cat("auto const target = f();"),
166             runCheckOnCode<ValueRTransform>(Cat(S)));
167   EXPECT_EQ(Cat("auto const target = f();"),
168             runCheckOnCode<PointeeRTransform>(Cat(S)));
169 }
170 TEST(Values, DeclTypeValue) {
171   StringRef T = "int f() { return 42; }\n";
172   StringRef S = "decltype(f()) target = f();";
173   auto Cat = [&T](StringRef S) { return (T + S).str(); };
174 
175   EXPECT_EQ(Cat("const decltype(f()) target = f();"),
176             runCheckOnCode<ValueLTransform>(Cat(S)));
177   EXPECT_EQ(Cat("const decltype(f()) target = f();"),
178             runCheckOnCode<PointeeLTransform>(Cat(S)));
179 
180   EXPECT_EQ(Cat("decltype(f()) const target = f();"),
181             runCheckOnCode<ValueRTransform>(Cat(S)));
182   EXPECT_EQ(Cat("decltype(f()) const target = f();"),
183             runCheckOnCode<PointeeRTransform>(Cat(S)));
184 }
185 TEST(Values, DeclTypePointer) {
186   // The pointer itself will be changed to 'const'. There is no
187   // way to make the pointee 'const' with this syntax.
188   StringRef T = "int* f() { return nullptr; }\n";
189   StringRef S = "decltype(f()) target = f();";
190   auto Cat = [&T](StringRef S) { return (T + S).str(); };
191 
192   EXPECT_EQ(Cat("const decltype(f()) target = f();"),
193             runCheckOnCode<ValueLTransform>(Cat(S)));
194   EXPECT_EQ(Cat("const decltype(f()) target = f();"),
195             runCheckOnCode<PointeeLTransform>(Cat(S)));
196 
197   EXPECT_EQ(Cat("decltype(f()) const target = f();"),
198             runCheckOnCode<ValueRTransform>(Cat(S)));
199   EXPECT_EQ(Cat("decltype(f()) const target = f();"),
200             runCheckOnCode<PointeeRTransform>(Cat(S)));
201 }
202 TEST(Values, DeclTypeReference) {
203   // Same as pointer, but the reference itself will be marked 'const'.
204   // This has no effect and will result in a warning afterwards. The
205   // transformation itself is still correct.
206   StringRef T = "static int global = 42; int& f() { return global; }\n";
207   StringRef S = "decltype(f()) target = f();";
208   auto Cat = [&T](StringRef S) { return (T + S).str(); };
209 
210   EXPECT_EQ(Cat("const decltype(f()) target = f();"),
211             runCheckOnCode<ValueLTransform>(Cat(S)));
212   EXPECT_EQ(Cat("const decltype(f()) target = f();"),
213             runCheckOnCode<PointeeLTransform>(Cat(S)));
214 
215   EXPECT_EQ(Cat("decltype(f()) const target = f();"),
216             runCheckOnCode<ValueRTransform>(Cat(S)));
217   EXPECT_EQ(Cat("decltype(f()) const target = f();"),
218             runCheckOnCode<PointeeRTransform>(Cat(S)));
219 }
220 TEST(Values, Parens) {
221   StringRef Snippet = "int ((target)) = 0;";
222 
223   EXPECT_EQ("const int ((target)) = 0;",
224             runCheckOnCode<ValueLTransform>(Snippet));
225   EXPECT_EQ("const int ((target)) = 0;",
226             runCheckOnCode<PointeeLTransform>(Snippet));
227 
228   EXPECT_EQ("int const ((target)) = 0;",
229             runCheckOnCode<ValueRTransform>(Snippet));
230   EXPECT_EQ("int const ((target)) = 0;",
231             runCheckOnCode<PointeeRTransform>(Snippet));
232 }
233 
234 // ----------------------------------------------------------------------------
235 // Test builtin-arrays
236 // ----------------------------------------------------------------------------
237 
238 TEST(Arrays, Builtin) {
239   StringRef Snippet = "int target[][1] = {{1}, {2}, {3}};";
240 
241   EXPECT_EQ("const int target[][1] = {{1}, {2}, {3}};",
242             runCheckOnCode<PointeeLTransform>(Snippet));
243   EXPECT_EQ("const int target[][1] = {{1}, {2}, {3}};",
244             runCheckOnCode<ValueLTransform>(Snippet));
245 
246   EXPECT_EQ("int const target[][1] = {{1}, {2}, {3}};",
247             runCheckOnCode<PointeeRTransform>(Snippet));
248   EXPECT_EQ("int const target[][1] = {{1}, {2}, {3}};",
249             runCheckOnCode<ValueRTransform>(Snippet));
250 }
251 TEST(Arrays, BuiltinParens) {
252   StringRef Snippet = "int ((target))[][1] = {{1}, {2}, {3}};";
253 
254   EXPECT_EQ("const int ((target))[][1] = {{1}, {2}, {3}};",
255             runCheckOnCode<PointeeLTransform>(Snippet));
256   EXPECT_EQ("const int ((target))[][1] = {{1}, {2}, {3}};",
257             runCheckOnCode<ValueLTransform>(Snippet));
258 
259   EXPECT_EQ("int const ((target))[][1] = {{1}, {2}, {3}};",
260             runCheckOnCode<PointeeRTransform>(Snippet));
261   EXPECT_EQ("int const ((target))[][1] = {{1}, {2}, {3}};",
262             runCheckOnCode<ValueRTransform>(Snippet));
263 }
264 TEST(Arrays, Pointers) {
265   StringRef Snippet = "int x; int* target[] = {&x, &x, &x};";
266 
267   EXPECT_EQ("int x; const int* target[] = {&x, &x, &x};",
268             runCheckOnCode<PointeeLTransform>(Snippet));
269   EXPECT_EQ("int x; int const* target[] = {&x, &x, &x};",
270             runCheckOnCode<PointeeRTransform>(Snippet));
271 
272   EXPECT_EQ("int x; int* const target[] = {&x, &x, &x};",
273             runCheckOnCode<ValueLTransform>(Snippet));
274   EXPECT_EQ("int x; int* const target[] = {&x, &x, &x};",
275             runCheckOnCode<ValueRTransform>(Snippet));
276 }
277 TEST(Arrays, PointerPointers) {
278   StringRef Snippet = "int* x = nullptr; int** target[] = {&x, &x, &x};";
279 
280   EXPECT_EQ("int* x = nullptr; int* const* target[] = {&x, &x, &x};",
281             runCheckOnCode<PointeeLTransform>(Snippet));
282   EXPECT_EQ("int* x = nullptr; int** const target[] = {&x, &x, &x};",
283             runCheckOnCode<ValueLTransform>(Snippet));
284 
285   EXPECT_EQ("int* x = nullptr; int* const* target[] = {&x, &x, &x};",
286             runCheckOnCode<PointeeRTransform>(Snippet));
287   EXPECT_EQ("int* x = nullptr; int** const target[] = {&x, &x, &x};",
288             runCheckOnCode<ValueRTransform>(Snippet));
289 }
290 TEST(Arrays, PointersParens) {
291   StringRef Snippet = "int x; int* (target)[] = {&x, &x, &x};";
292 
293   EXPECT_EQ("int x; const int* (target)[] = {&x, &x, &x};",
294             runCheckOnCode<PointeeLTransform>(Snippet));
295   EXPECT_EQ("int x; int const* (target)[] = {&x, &x, &x};",
296             runCheckOnCode<PointeeRTransform>(Snippet));
297 
298   EXPECT_EQ("int x; int* const (target)[] = {&x, &x, &x};",
299             runCheckOnCode<ValueLTransform>(Snippet));
300   EXPECT_EQ("int x; int* const (target)[] = {&x, &x, &x};",
301             runCheckOnCode<ValueRTransform>(Snippet));
302 }
303 
304 // ----------------------------------------------------------------------------
305 // Test reference types. This does not include pointers and arrays.
306 // ----------------------------------------------------------------------------
307 
308 TEST(Reference, LValueBuiltin) {
309   StringRef Snippet = "int x = 42; int& target = x;";
310 
311   EXPECT_EQ("int x = 42; const int& target = x;",
312             runCheckOnCode<ValueLTransform>(Snippet));
313   EXPECT_EQ("int x = 42; const int& target = x;",
314             runCheckOnCode<PointeeLTransform>(Snippet));
315 
316   EXPECT_EQ("int x = 42; int const& target = x;",
317             runCheckOnCode<ValueRTransform>(Snippet));
318   EXPECT_EQ("int x = 42; int const& target = x;",
319             runCheckOnCode<PointeeRTransform>(Snippet));
320 }
321 TEST(Reference, RValueBuiltin) {
322   StringRef Snippet = "int&& target = 42;";
323   EXPECT_EQ("const int&& target = 42;",
324             runCheckOnCode<ValueLTransform>(Snippet));
325   EXPECT_EQ("const int&& target = 42;",
326             runCheckOnCode<PointeeLTransform>(Snippet));
327 
328   EXPECT_EQ("int const&& target = 42;",
329             runCheckOnCode<ValueRTransform>(Snippet));
330   EXPECT_EQ("int const&& target = 42;",
331             runCheckOnCode<PointeeRTransform>(Snippet));
332 }
333 TEST(Reference, LValueToPointer) {
334   StringRef Snippet = "int* p; int *& target = p;";
335   EXPECT_EQ("int* p; int * const& target = p;",
336             runCheckOnCode<ValueLTransform>(Snippet));
337   EXPECT_EQ("int* p; int * const& target = p;",
338             runCheckOnCode<PointeeLTransform>(Snippet));
339 
340   EXPECT_EQ("int* p; int * const& target = p;",
341             runCheckOnCode<ValueRTransform>(Snippet));
342   EXPECT_EQ("int* p; int * const& target = p;",
343             runCheckOnCode<PointeeRTransform>(Snippet));
344 }
345 TEST(Reference, LValueParens) {
346   StringRef Snippet = "int x = 42; int ((& target)) = x;";
347 
348   EXPECT_EQ("int x = 42; const int ((& target)) = x;",
349             runCheckOnCode<ValueLTransform>(Snippet));
350   EXPECT_EQ("int x = 42; const int ((& target)) = x;",
351             runCheckOnCode<PointeeLTransform>(Snippet));
352 
353   EXPECT_EQ("int x = 42; int  const((& target)) = x;",
354             runCheckOnCode<ValueRTransform>(Snippet));
355   EXPECT_EQ("int x = 42; int  const((& target)) = x;",
356             runCheckOnCode<PointeeRTransform>(Snippet));
357 }
358 TEST(Reference, ToArray) {
359   StringRef ArraySnippet = "int a[4] = {1, 2, 3, 4};";
360   StringRef Snippet = "int (&target)[4] = a;";
361   auto Cat = [&ArraySnippet](StringRef S) { return (ArraySnippet + S).str(); };
362 
363   EXPECT_EQ(Cat("const int (&target)[4] = a;"),
364             runCheckOnCode<ValueLTransform>(Cat(Snippet)));
365   EXPECT_EQ(Cat("const int (&target)[4] = a;"),
366             runCheckOnCode<PointeeLTransform>(Cat(Snippet)));
367 
368   EXPECT_EQ(Cat("int  const(&target)[4] = a;"),
369             runCheckOnCode<ValueRTransform>(Cat(Snippet)));
370   EXPECT_EQ(Cat("int  const(&target)[4] = a;"),
371             runCheckOnCode<PointeeRTransform>(Cat(Snippet)));
372 }
373 TEST(Reference, Auto) {
374   StringRef T = "static int global = 42; int& f() { return global; }\n";
375   StringRef S = "auto& target = f();";
376   auto Cat = [&T](StringRef S) { return (T + S).str(); };
377 
378   EXPECT_EQ(Cat("const auto& target = f();"),
379             runCheckOnCode<ValueLTransform>(Cat(S)));
380   EXPECT_EQ(Cat("auto const& target = f();"),
381             runCheckOnCode<ValueRTransform>(Cat(S)));
382 
383   EXPECT_EQ(Cat("const auto& target = f();"),
384             runCheckOnCode<PointeeLTransform>(Cat(S)));
385   EXPECT_EQ(Cat("auto const& target = f();"),
386             runCheckOnCode<PointeeRTransform>(Cat(S)));
387 }
388 
389 // ----------------------------------------------------------------------------
390 // Test pointers types.
391 // ----------------------------------------------------------------------------
392 
393 TEST(Pointers, SingleBuiltin) {
394   StringRef Snippet = "int* target = nullptr;";
395 
396   EXPECT_EQ("int* const target = nullptr;",
397             runCheckOnCode<ValueLTransform>(Snippet));
398   EXPECT_EQ("int* const target = nullptr;",
399             runCheckOnCode<ValueRTransform>(Snippet));
400 
401   EXPECT_EQ("const int* target = nullptr;",
402             runCheckOnCode<PointeeLTransform>(Snippet));
403   EXPECT_EQ("int const* target = nullptr;",
404             runCheckOnCode<PointeeRTransform>(Snippet));
405 }
406 TEST(Pointers, MultiBuiltin) {
407   StringRef Snippet = "int** target = nullptr;";
408 
409   EXPECT_EQ("int** const target = nullptr;",
410             runCheckOnCode<ValueLTransform>(Snippet));
411   EXPECT_EQ("int** const target = nullptr;",
412             runCheckOnCode<ValueRTransform>(Snippet));
413 
414   EXPECT_EQ("int* const* target = nullptr;",
415             runCheckOnCode<PointeeLTransform>(Snippet));
416   EXPECT_EQ("int* const* target = nullptr;",
417             runCheckOnCode<PointeeRTransform>(Snippet));
418 }
419 TEST(Pointers, ToArray) {
420   StringRef ArraySnippet = "int a[4] = {1, 2, 3, 4};";
421   StringRef Snippet = "int (*target)[4] = &a;";
422   auto Cat = [&ArraySnippet](StringRef S) { return (ArraySnippet + S).str(); };
423 
424   EXPECT_EQ(Cat("int (*const target)[4] = &a;"),
425             runCheckOnCode<ValueLTransform>(Cat(Snippet)));
426   EXPECT_EQ(Cat("const int (*target)[4] = &a;"),
427             runCheckOnCode<PointeeLTransform>(Cat(Snippet)));
428 
429   EXPECT_EQ(Cat("int (*const target)[4] = &a;"),
430             runCheckOnCode<ValueRTransform>(Cat(Snippet)));
431   EXPECT_EQ(Cat("int  const(*target)[4] = &a;"),
432             runCheckOnCode<PointeeRTransform>(Cat(Snippet)));
433 }
434 TEST(Pointers, Parens) {
435   StringRef Snippet = "int ((**target)) = nullptr;";
436 
437   EXPECT_EQ("int ((**const target)) = nullptr;",
438             runCheckOnCode<ValueLTransform>(Snippet));
439   EXPECT_EQ("int ((**const target)) = nullptr;",
440             runCheckOnCode<ValueRTransform>(Snippet));
441 
442   EXPECT_EQ("int ((* const*target)) = nullptr;",
443             runCheckOnCode<PointeeLTransform>(Snippet));
444   EXPECT_EQ("int ((* const*target)) = nullptr;",
445             runCheckOnCode<PointeeRTransform>(Snippet));
446 }
447 TEST(Pointers, Auto) {
448   StringRef T = "int* f() { return nullptr; }\n";
449   StringRef S = "auto* target = f();";
450   auto Cat = [&T](StringRef S) { return (T + S).str(); };
451 
452   EXPECT_EQ(Cat("auto* const target = f();"),
453             runCheckOnCode<ValueLTransform>(Cat(S)));
454   EXPECT_EQ(Cat("auto* const target = f();"),
455             runCheckOnCode<ValueRTransform>(Cat(S)));
456 
457   EXPECT_EQ(Cat("const auto* target = f();"),
458             runCheckOnCode<PointeeLTransform>(Cat(S)));
459   EXPECT_EQ(Cat("auto const* target = f();"),
460             runCheckOnCode<PointeeRTransform>(Cat(S)));
461 }
462 TEST(Pointers, AutoParens) {
463   StringRef T = "int* f() { return nullptr; }\n";
464   StringRef S = "auto (((* target))) = f();";
465   auto Cat = [&T](StringRef S) { return (T + S).str(); };
466 
467   EXPECT_EQ(Cat("auto (((* const target))) = f();"),
468             runCheckOnCode<ValueLTransform>(Cat(S)));
469   EXPECT_EQ(Cat("auto (((* const target))) = f();"),
470             runCheckOnCode<ValueRTransform>(Cat(S)));
471 
472   EXPECT_EQ(Cat("const auto (((* target))) = f();"),
473             runCheckOnCode<PointeeLTransform>(Cat(S)));
474   EXPECT_EQ(Cat("auto  const(((* target))) = f();"),
475             runCheckOnCode<PointeeRTransform>(Cat(S)));
476 }
477 TEST(Pointers, FunctionPointer) {
478   StringRef S = "int (*target)(float, int, double) = nullptr;";
479 
480   EXPECT_EQ("int (*const target)(float, int, double) = nullptr;",
481             runCheckOnCode<ValueLTransform>(S));
482   EXPECT_EQ("int (*const target)(float, int, double) = nullptr;",
483             runCheckOnCode<ValueRTransform>(S));
484 
485   EXPECT_EQ("int (*const target)(float, int, double) = nullptr;",
486             runCheckOnCode<PointeeLTransform>(S));
487   EXPECT_EQ("int (*const target)(float, int, double) = nullptr;",
488             runCheckOnCode<PointeeRTransform>(S));
489 
490   S = "int (((*target)))(float, int, double) = nullptr;";
491   EXPECT_EQ("int (((*const target)))(float, int, double) = nullptr;",
492             runCheckOnCode<PointeeRTransform>(S));
493 }
494 TEST(Pointers, MemberFunctionPointer) {
495   StringRef T = "struct A { int f() { return 1; } };";
496   StringRef S = "int (A::*target)() = &A::f;";
497   auto Cat = [&T](StringRef S) { return (T + S).str(); };
498 
499   EXPECT_EQ(Cat("int (A::*const target)() = &A::f;"),
500             runCheckOnCode<ValueLTransform>(Cat(S)));
501   EXPECT_EQ(Cat("int (A::*const target)() = &A::f;"),
502             runCheckOnCode<ValueRTransform>(Cat(S)));
503 
504   EXPECT_EQ(Cat("int (A::*const target)() = &A::f;"),
505             runCheckOnCode<PointeeLTransform>(Cat(S)));
506   EXPECT_EQ(Cat("int (A::*const target)() = &A::f;"),
507             runCheckOnCode<PointeeRTransform>(Cat(S)));
508 
509   S = "int (A::*((target)))() = &A::f;";
510   EXPECT_EQ(Cat("int (A::*const ((target)))() = &A::f;"),
511             runCheckOnCode<ValueLTransform>(Cat(S)));
512 }
513 TEST(Pointers, MemberDataPointer) {
514   StringRef T = "struct A { int member = 0; };";
515   StringRef S = "int A::*target = &A::member;";
516   auto Cat = [&T](StringRef S) { return (T + S).str(); };
517 
518   EXPECT_EQ(Cat("int A::*const target = &A::member;"),
519             runCheckOnCode<ValueLTransform>(Cat(S)));
520   EXPECT_EQ(Cat("int A::*const target = &A::member;"),
521             runCheckOnCode<ValueRTransform>(Cat(S)));
522 
523   EXPECT_EQ(Cat("int A::*const target = &A::member;"),
524             runCheckOnCode<PointeeLTransform>(Cat(S)));
525   EXPECT_EQ(Cat("int A::*const target = &A::member;"),
526             runCheckOnCode<PointeeRTransform>(Cat(S)));
527 
528   S = "int A::*((target)) = &A::member;";
529   EXPECT_EQ(Cat("int A::*const ((target)) = &A::member;"),
530             runCheckOnCode<PointeeRTransform>(Cat(S)));
531 }
532 
533 // ----------------------------------------------------------------------------
534 // Test TagTypes (struct, class, unions, enums)
535 // ----------------------------------------------------------------------------
536 
537 TEST(TagTypes, Struct) {
538   StringRef T = "struct Foo { int data; int method(); };\n";
539   StringRef S = "struct Foo target{0};";
540   auto Cat = [&T](StringRef S) { return (T + S).str(); };
541 
542   EXPECT_EQ(Cat("const struct Foo target{0};"),
543             runCheckOnCode<ValueLTransform>(Cat(S)));
544   EXPECT_EQ(Cat("const struct Foo target{0};"),
545             runCheckOnCode<PointeeLTransform>(Cat(S)));
546 
547   EXPECT_EQ(Cat("struct Foo const target{0};"),
548             runCheckOnCode<ValueRTransform>(Cat(S)));
549   EXPECT_EQ(Cat("struct Foo const target{0};"),
550             runCheckOnCode<PointeeRTransform>(Cat(S)));
551 
552   S = "Foo target{0};";
553   EXPECT_EQ(Cat("const Foo target{0};"),
554             runCheckOnCode<ValueLTransform>(Cat(S)));
555   EXPECT_EQ(Cat("const Foo target{0};"),
556             runCheckOnCode<PointeeLTransform>(Cat(S)));
557 
558   EXPECT_EQ(Cat("Foo const target{0};"),
559             runCheckOnCode<ValueRTransform>(Cat(S)));
560   EXPECT_EQ(Cat("Foo const target{0};"),
561             runCheckOnCode<PointeeRTransform>(Cat(S)));
562 
563   S = "Foo (target){0};";
564   EXPECT_EQ(Cat("const Foo (target){0};"),
565             runCheckOnCode<ValueLTransform>(Cat(S)));
566   EXPECT_EQ(Cat("const Foo (target){0};"),
567             runCheckOnCode<PointeeLTransform>(Cat(S)));
568 
569   EXPECT_EQ(Cat("Foo const (target){0};"),
570             runCheckOnCode<ValueRTransform>(Cat(S)));
571   EXPECT_EQ(Cat("Foo const (target){0};"),
572             runCheckOnCode<PointeeRTransform>(Cat(S)));
573 
574   S = "struct S { int i; } target = { 0 };";
575   EXPECT_EQ("const struct S { int i; } target = { 0 };",
576             runCheckOnCode<ValueLTransform>(S));
577   EXPECT_EQ("const struct S { int i; } target = { 0 };",
578             runCheckOnCode<PointeeLTransform>(S));
579 
580   EXPECT_EQ("struct S { int i; } const target = { 0 };",
581             runCheckOnCode<PointeeRTransform>(S));
582   EXPECT_EQ("struct S { int i; } const target = { 0 };",
583             runCheckOnCode<PointeeRTransform>(S));
584 
585   S = "struct { int i; } target = { 0 };";
586   EXPECT_EQ("const struct { int i; } target = { 0 };",
587             runCheckOnCode<ValueLTransform>(S));
588   EXPECT_EQ("const struct { int i; } target = { 0 };",
589             runCheckOnCode<PointeeLTransform>(S));
590 
591   EXPECT_EQ("struct { int i; } const target = { 0 };",
592             runCheckOnCode<PointeeRTransform>(S));
593   EXPECT_EQ("struct { int i; } const target = { 0 };",
594             runCheckOnCode<PointeeRTransform>(S));
595 }
596 TEST(TagTypes, Class) {
597   StringRef T = "class Foo { int data; int method(); };\n";
598   StringRef S = "class Foo target;";
599   auto Cat = [&T](StringRef S) { return (T + S).str(); };
600 
601   EXPECT_EQ(Cat("const class Foo target;"),
602             runCheckOnCode<ValueLTransform>(Cat(S)));
603   EXPECT_EQ(Cat("const class Foo target;"),
604             runCheckOnCode<PointeeLTransform>(Cat(S)));
605 
606   EXPECT_EQ(Cat("class Foo const target;"),
607             runCheckOnCode<ValueRTransform>(Cat(S)));
608   EXPECT_EQ(Cat("class Foo const target;"),
609             runCheckOnCode<PointeeRTransform>(Cat(S)));
610 
611   S = "Foo target;";
612   EXPECT_EQ(Cat("const Foo target;"), runCheckOnCode<ValueLTransform>(Cat(S)));
613   EXPECT_EQ(Cat("const Foo target;"),
614             runCheckOnCode<PointeeLTransform>(Cat(S)));
615 
616   EXPECT_EQ(Cat("Foo const target;"), runCheckOnCode<ValueRTransform>(Cat(S)));
617   EXPECT_EQ(Cat("Foo const target;"),
618             runCheckOnCode<PointeeRTransform>(Cat(S)));
619 
620   S = "Foo (target);";
621   EXPECT_EQ(Cat("const Foo (target);"),
622             runCheckOnCode<ValueLTransform>(Cat(S)));
623   EXPECT_EQ(Cat("const Foo (target);"),
624             runCheckOnCode<PointeeLTransform>(Cat(S)));
625 
626   EXPECT_EQ(Cat("Foo const (target);"),
627             runCheckOnCode<ValueRTransform>(Cat(S)));
628   EXPECT_EQ(Cat("Foo const (target);"),
629             runCheckOnCode<PointeeRTransform>(Cat(S)));
630 }
631 TEST(TagTypes, Enum) {
632   StringRef T = "enum Foo { N_ONE, N_TWO, N_THREE };\n";
633   StringRef S = "enum Foo target;";
634   auto Cat = [&T](StringRef S) { return (T + S).str(); };
635 
636   EXPECT_EQ(Cat("const enum Foo target;"),
637             runCheckOnCode<ValueLTransform>(Cat(S)));
638   EXPECT_EQ(Cat("const enum Foo target;"),
639             runCheckOnCode<PointeeLTransform>(Cat(S)));
640 
641   EXPECT_EQ(Cat("enum Foo const target;"),
642             runCheckOnCode<ValueRTransform>(Cat(S)));
643   EXPECT_EQ(Cat("enum Foo const target;"),
644             runCheckOnCode<PointeeRTransform>(Cat(S)));
645 
646   S = "Foo target;";
647   EXPECT_EQ(Cat("const Foo target;"), runCheckOnCode<ValueLTransform>(Cat(S)));
648   EXPECT_EQ(Cat("const Foo target;"),
649             runCheckOnCode<PointeeLTransform>(Cat(S)));
650 
651   EXPECT_EQ(Cat("Foo const target;"), runCheckOnCode<ValueRTransform>(Cat(S)));
652   EXPECT_EQ(Cat("Foo const target;"),
653             runCheckOnCode<PointeeRTransform>(Cat(S)));
654 
655   S = "Foo (target);";
656   EXPECT_EQ(Cat("const Foo (target);"),
657             runCheckOnCode<ValueLTransform>(Cat(S)));
658   EXPECT_EQ(Cat("const Foo (target);"),
659             runCheckOnCode<PointeeLTransform>(Cat(S)));
660 
661   EXPECT_EQ(Cat("Foo const (target);"),
662             runCheckOnCode<ValueRTransform>(Cat(S)));
663   EXPECT_EQ(Cat("Foo const (target);"),
664             runCheckOnCode<PointeeRTransform>(Cat(S)));
665 }
666 TEST(TagTypes, Union) {
667   StringRef T = "union Foo { int yay; float nej; };\n";
668   StringRef S = "union Foo target;";
669   auto Cat = [&T](StringRef S) { return (T + S).str(); };
670 
671   EXPECT_EQ(Cat("const union Foo target;"),
672             runCheckOnCode<ValueLTransform>(Cat(S)));
673   EXPECT_EQ(Cat("const union Foo target;"),
674             runCheckOnCode<PointeeLTransform>(Cat(S)));
675 
676   EXPECT_EQ(Cat("union Foo const target;"),
677             runCheckOnCode<ValueRTransform>(Cat(S)));
678   EXPECT_EQ(Cat("union Foo const target;"),
679             runCheckOnCode<PointeeRTransform>(Cat(S)));
680 
681   S = "Foo target;";
682   EXPECT_EQ(Cat("const Foo target;"), runCheckOnCode<ValueLTransform>(Cat(S)));
683   EXPECT_EQ(Cat("const Foo target;"),
684             runCheckOnCode<PointeeLTransform>(Cat(S)));
685 
686   EXPECT_EQ(Cat("Foo const target;"), runCheckOnCode<ValueRTransform>(Cat(S)));
687   EXPECT_EQ(Cat("Foo const target;"),
688             runCheckOnCode<PointeeRTransform>(Cat(S)));
689 
690   S = "Foo (target);";
691   EXPECT_EQ(Cat("const Foo (target);"),
692             runCheckOnCode<ValueLTransform>(Cat(S)));
693   EXPECT_EQ(Cat("const Foo (target);"),
694             runCheckOnCode<PointeeLTransform>(Cat(S)));
695 
696   EXPECT_EQ(Cat("Foo const (target);"),
697             runCheckOnCode<ValueRTransform>(Cat(S)));
698   EXPECT_EQ(Cat("Foo const (target);"),
699             runCheckOnCode<PointeeRTransform>(Cat(S)));
700 }
701 
702 // ----------------------------------------------------------------------------
703 // Test Macro expansions.
704 // ----------------------------------------------------------------------------
705 
706 TEST(Macro, AllInMacro) {
707   StringRef T = "#define DEFINE_VARIABLE int target = 42\n";
708   StringRef S = "DEFINE_VARIABLE;";
709   auto Cat = [&T](StringRef S) { return (T + S).str(); };
710 
711   EXPECT_EQ(Cat("DEFINE_VARIABLE;"), runCheckOnCode<ValueLTransform>(Cat(S)));
712   EXPECT_EQ(Cat("DEFINE_VARIABLE;"), runCheckOnCode<ValueRTransform>(Cat(S)));
713 
714   EXPECT_EQ(Cat("DEFINE_VARIABLE;"), runCheckOnCode<PointeeLTransform>(Cat(S)));
715   EXPECT_EQ(Cat("DEFINE_VARIABLE;"), runCheckOnCode<PointeeRTransform>(Cat(S)));
716 }
717 TEST(Macro, MacroParameter) {
718   StringRef T = "#define DEFINE_VARIABLE(X) int X = 42\n";
719   StringRef S = "DEFINE_VARIABLE(target);";
720   auto Cat = [&T](StringRef S) { return (T + S).str(); };
721 
722   EXPECT_EQ(Cat("DEFINE_VARIABLE(target);"),
723             runCheckOnCode<ValueLTransform>(Cat(S)));
724   EXPECT_EQ(Cat("DEFINE_VARIABLE(target);"),
725             runCheckOnCode<ValueRTransform>(Cat(S)));
726 
727   EXPECT_EQ(Cat("DEFINE_VARIABLE(target);"),
728             runCheckOnCode<PointeeLTransform>(Cat(S)));
729   EXPECT_EQ(Cat("DEFINE_VARIABLE(target);"),
730             runCheckOnCode<PointeeRTransform>(Cat(S)));
731 }
732 TEST(Macro, MacroTypeValue) {
733   StringRef T = "#define BAD_TYPEDEF int\n";
734   StringRef S = "BAD_TYPEDEF target = 42;";
735   auto Cat = [&T](StringRef S) { return (T + S).str(); };
736 
737   EXPECT_EQ(Cat("BAD_TYPEDEF target = 42;"),
738             runCheckOnCode<ValueLTransform>(Cat(S)));
739   EXPECT_EQ(Cat("BAD_TYPEDEF target = 42;"),
740             runCheckOnCode<PointeeLTransform>(Cat(S)));
741 
742   EXPECT_EQ(Cat("BAD_TYPEDEF const target = 42;"),
743             runCheckOnCode<PointeeRTransform>(Cat(S)));
744   EXPECT_EQ(Cat("BAD_TYPEDEF const target = 42;"),
745             runCheckOnCode<ValueRTransform>(Cat(S)));
746 }
747 TEST(Macro, MacroTypePointer) {
748   StringRef T = "#define BAD_TYPEDEF int *\n";
749   StringRef S = "BAD_TYPEDEF target = nullptr;";
750   auto Cat = [&T](StringRef S) { return (T + S).str(); };
751 
752   EXPECT_EQ(Cat("BAD_TYPEDEF const target = nullptr;"),
753             runCheckOnCode<ValueLTransform>(Cat(S)));
754   EXPECT_EQ(Cat("BAD_TYPEDEF const target = nullptr;"),
755             runCheckOnCode<ValueRTransform>(Cat(S)));
756 
757   // FIXME: Failing even all parts seem to bail-out in for isMacroID()
758   // The macro itself is changed here and below which is not intended.
759   EXPECT_NE(Cat("BAD_TYPEDEF target = nullptr;"),
760             runCheckOnCode<PointeeRTransform>(Cat(S)));
761   EXPECT_EQ(Cat("BAD_TYPEDEF target = nullptr;"),
762             runCheckOnCode<PointeeLTransform>(Cat(S)));
763 }
764 TEST(Macro, MacroTypeReference) {
765   StringRef T = "static int g = 42;\n#define BAD_TYPEDEF int&\n";
766   StringRef S = "BAD_TYPEDEF target = g;";
767   auto Cat = [&T](StringRef S) { return (T + S).str(); };
768 
769   EXPECT_EQ(Cat("BAD_TYPEDEF target = g;"),
770             runCheckOnCode<ValueLTransform>(Cat(S)));
771   // FIXME: Failing even all parts seem to bail-out in for isMacroID()
772   EXPECT_NE(Cat("BAD_TYPEDEF target = g;"),
773             runCheckOnCode<ValueRTransform>(Cat(S)));
774 
775   EXPECT_EQ(Cat("BAD_TYPEDEF target = g;"),
776             runCheckOnCode<PointeeLTransform>(Cat(S)));
777   // FIXME: Failing even all parts seem to bail-out in for isMacroID()
778   EXPECT_NE(Cat("BAD_TYPEDEF target = g;"),
779             runCheckOnCode<PointeeRTransform>(Cat(S)));
780 }
781 // This failed in LLVM.
782 TEST(Macro, Variable) {
783   StringRef M = "#define DEBUG(X) do { if (1) { X; } } while (0)\n";
784   StringRef F = "void foo() ";
785   StringRef V = "{ DEBUG(int target = 42;); }";
786 
787   auto Cat = [&](StringRef S) { return (M + F + V).str(); };
788 
789   EXPECT_EQ(Cat("{ DEBUG(const int target = 42;); }"),
790             runCheckOnCode<ValueLTransform>(Cat(V)));
791   EXPECT_EQ(Cat("{ DEBUG(int const target = 42;); }"),
792             runCheckOnCode<ValueRTransform>(Cat(V)));
793 }
794 TEST(Macro, RangeLoop) {
795   StringRef M = "#define DEBUG(X) do { if (1) { X; }} while (false)\n";
796   StringRef F = "void foo() { char array[] = {'a', 'b', 'c'}; ";
797   StringRef V = "DEBUG( for(auto& target: array) 10 + target; );";
798   StringRef E = "}";
799 
800   auto Cat = [&](StringRef S) { return (M + F + V + E).str(); };
801 
802   EXPECT_EQ(Cat("DEBUG( for(const auto& target: array); );"),
803             runCheckOnCode<ValueLTransform>(Cat(V)));
804   EXPECT_EQ(Cat("DEBUG( for(auto const& target: array); );"),
805             runCheckOnCode<ValueRTransform>(Cat(V)));
806 }
807 
808 // ----------------------------------------------------------------------------
809 // Test template code.
810 // ----------------------------------------------------------------------------
811 
812 TEST(Template, TemplateVariable) {
813   StringRef T = "template <typename T> T target = 3.1415;";
814 
815   EXPECT_EQ("template <typename T> const T target = 3.1415;",
816             runCheckOnCode<ValueLTransform>(T));
817   EXPECT_EQ("template <typename T> T const target = 3.1415;",
818             runCheckOnCode<ValueRTransform>(T));
819 
820   EXPECT_EQ("template <typename T> const T target = 3.1415;",
821             runCheckOnCode<PointeeLTransform>(T));
822   EXPECT_EQ("template <typename T> T const target = 3.1415;",
823             runCheckOnCode<PointeeRTransform>(T));
824 }
825 TEST(Template, FunctionValue) {
826   StringRef T = "template <typename T> void f(T v) \n";
827   StringRef S = "{ T target = v; }";
828   auto Cat = [&T](StringRef S) { return (T + S).str(); };
829 
830   EXPECT_EQ(Cat("{ const T target = v; }"),
831             runCheckOnCode<ValueLTransform>(Cat(S)));
832   EXPECT_EQ(Cat("{ T const target = v; }"),
833             runCheckOnCode<ValueRTransform>(Cat(S)));
834 
835   EXPECT_EQ(Cat("{ const T target = v; }"),
836             runCheckOnCode<PointeeLTransform>(Cat(S)));
837   EXPECT_EQ(Cat("{ T const target = v; }"),
838             runCheckOnCode<PointeeRTransform>(Cat(S)));
839 }
840 TEST(Template, FunctionPointer) {
841   StringRef T = "template <typename T> void f(T* v) \n";
842   StringRef S = "{ T* target = v; }";
843   auto Cat = [&T](StringRef S) { return (T + S).str(); };
844 
845   EXPECT_EQ(Cat("{ T* const target = v; }"),
846             runCheckOnCode<ValueLTransform>(Cat(S)));
847   EXPECT_EQ(Cat("{ T* const target = v; }"),
848             runCheckOnCode<ValueRTransform>(Cat(S)));
849 
850   EXPECT_EQ(Cat("{ const T* target = v; }"),
851             runCheckOnCode<PointeeLTransform>(Cat(S)));
852   EXPECT_EQ(Cat("{ T const* target = v; }"),
853             runCheckOnCode<PointeeRTransform>(Cat(S)));
854 }
855 TEST(Template, FunctionReference) {
856   StringRef T = "template <typename T> void f(T& v) \n";
857   StringRef S = "{ T& target = v; }";
858   auto Cat = [&T](StringRef S) { return (T + S).str(); };
859 
860   EXPECT_EQ(Cat("{ const T& target = v; }"),
861             runCheckOnCode<ValueLTransform>(Cat(S)));
862   EXPECT_EQ(Cat("{ T const& target = v; }"),
863             runCheckOnCode<ValueRTransform>(Cat(S)));
864 
865   EXPECT_EQ(Cat("{ const T& target = v; }"),
866             runCheckOnCode<PointeeLTransform>(Cat(S)));
867   EXPECT_EQ(Cat("{ T const& target = v; }"),
868             runCheckOnCode<PointeeRTransform>(Cat(S)));
869 }
870 TEST(Template, MultiInstantiationsFunction) {
871   StringRef T = "template <typename T> void f(T v) \n";
872   StringRef S = "{ T target = v; }";
873   StringRef InstantStart = "void calls() {\n";
874   StringRef InstValue = "f<int>(42);\n";
875   StringRef InstConstValue = "f<const int>(42);\n";
876   StringRef InstPointer = "f<int*>(nullptr);\n";
877   StringRef InstPointerConst = "f<int* const>(nullptr);\n";
878   StringRef InstConstPointer = "f<const int*>(nullptr);\n";
879   StringRef InstConstPointerConst = "f<const int* const>(nullptr);\n";
880   StringRef InstRef = "int i = 42;\nf<int&>(i);\n";
881   StringRef InstConstRef = "f<const int&>(i);\n";
882   StringRef InstantEnd = "}";
883   auto Cat = [&](StringRef Target) {
884     return (T + Target + InstantStart + InstValue + InstConstValue +
885             InstPointer + InstPointerConst + InstConstPointer +
886             InstConstPointerConst + InstRef + InstConstRef + InstantEnd)
887         .str();
888   };
889 
890   EXPECT_EQ(Cat("{ const T target = v; }"),
891             runCheckOnCode<ValueLTransform>(Cat(S)));
892   EXPECT_EQ(Cat("{ T const target = v; }"),
893             runCheckOnCode<ValueRTransform>(Cat(S)));
894 
895   EXPECT_EQ(Cat("{ const T target = v; }"),
896             runCheckOnCode<PointeeLTransform>(Cat(S)));
897   EXPECT_EQ(Cat("{ T const target = v; }"),
898             runCheckOnCode<PointeeRTransform>(Cat(S)));
899 }
900 
901 TEST(Template, StructValue) {
902   StringRef T = "template <typename T> struct S { void f(T& v) \n";
903   StringRef S = "{ T target = v; }";
904   StringRef End = "\n};";
905   auto Cat = [&T, &End](StringRef S) { return (T + S + End).str(); };
906 
907   EXPECT_EQ(Cat("{ const T target = v; }"),
908             runCheckOnCode<ValueLTransform>(Cat(S)));
909   EXPECT_EQ(Cat("{ T const target = v; }"),
910             runCheckOnCode<ValueRTransform>(Cat(S)));
911 
912   EXPECT_EQ(Cat("{ const T target = v; }"),
913             runCheckOnCode<PointeeLTransform>(Cat(S)));
914   EXPECT_EQ(Cat("{ T const target = v; }"),
915             runCheckOnCode<PointeeRTransform>(Cat(S)));
916 }
917 TEST(Template, StructPointer) {
918   StringRef T = "template <typename T> struct S { void f(T* v) \n";
919   StringRef S = "{ T* target = v; }";
920   StringRef End = "\n};";
921   auto Cat = [&T, &End](StringRef S) { return (T + S + End).str(); };
922 
923   EXPECT_EQ(Cat("{ T* const target = v; }"),
924             runCheckOnCode<ValueLTransform>(Cat(S)));
925   EXPECT_EQ(Cat("{ T* const target = v; }"),
926             runCheckOnCode<ValueRTransform>(Cat(S)));
927 
928   EXPECT_EQ(Cat("{ const T* target = v; }"),
929             runCheckOnCode<PointeeLTransform>(Cat(S)));
930   EXPECT_EQ(Cat("{ T const* target = v; }"),
931             runCheckOnCode<PointeeRTransform>(Cat(S)));
932 }
933 TEST(Template, StructReference) {
934   StringRef T = "template <typename T> struct S { void f(T& v) \n";
935   StringRef S = "{ T& target = v; }";
936   StringRef End = "\n};";
937   auto Cat = [&T, &End](StringRef S) { return (T + S + End).str(); };
938 
939   EXPECT_EQ(Cat("{ const T& target = v; }"),
940             runCheckOnCode<ValueLTransform>(Cat(S)));
941   EXPECT_EQ(Cat("{ T const& target = v; }"),
942             runCheckOnCode<ValueRTransform>(Cat(S)));
943 
944   EXPECT_EQ(Cat("{ const T& target = v; }"),
945             runCheckOnCode<PointeeLTransform>(Cat(S)));
946   EXPECT_EQ(Cat("{ T const& target = v; }"),
947             runCheckOnCode<PointeeRTransform>(Cat(S)));
948 }
949 TEST(Template, DependentReturnFunction) {
950   StringRef TS = "template <typename T> struct TS { using value_type = T; };";
951   StringRef T = "template <typename T> void foo() ";
952   StringRef S = "{ typename T::value_type target; }";
953   auto Cat = [&TS, &T](StringRef S) { return (TS + T + S).str(); };
954 
955   EXPECT_EQ(Cat("{ const typename T::value_type target; }"),
956             runCheckOnCode<ValueLTransform>(Cat(S)));
957   EXPECT_EQ(Cat("{ typename T::value_type const target; }"),
958             runCheckOnCode<ValueRTransform>(Cat(S)));
959 
960   EXPECT_EQ(Cat("{ const typename T::value_type target; }"),
961             runCheckOnCode<PointeeLTransform>(Cat(S)));
962   EXPECT_EQ(Cat("{ typename T::value_type const target; }"),
963             runCheckOnCode<PointeeRTransform>(Cat(S)));
964 }
965 TEST(Template, DependentReturnPointerFunction) {
966   StringRef TS = "template <typename T> struct TS { using value_type = T; };";
967   StringRef T = "template <typename T> void foo() ";
968   StringRef S = "{ typename T::value_type *target; }";
969   auto Cat = [&TS, &T](StringRef S) { return (TS + T + S).str(); };
970 
971   EXPECT_EQ(Cat("{ typename T::value_type *const target; }"),
972             runCheckOnCode<ValueLTransform>(Cat(S)));
973   EXPECT_EQ(Cat("{ typename T::value_type *const target; }"),
974             runCheckOnCode<ValueRTransform>(Cat(S)));
975 
976   EXPECT_EQ(Cat("{ const typename T::value_type *target; }"),
977             runCheckOnCode<PointeeLTransform>(Cat(S)));
978   EXPECT_EQ(Cat("{ typename T::value_type  const*target; }"),
979             runCheckOnCode<PointeeRTransform>(Cat(S)));
980 }
981 TEST(Template, DependentReturnReferenceFunction) {
982   StringRef TS = "template <typename T> struct TS { using value_type = T; };";
983   StringRef T = "template <typename T> void foo(T& f) ";
984   StringRef S = "{ typename T::value_type &target = f; }";
985   auto Cat = [&TS, &T](StringRef S) { return (TS + T + S).str(); };
986 
987   EXPECT_EQ(Cat("{ const typename T::value_type &target = f; }"),
988             runCheckOnCode<ValueLTransform>(Cat(S)));
989   EXPECT_EQ(Cat("{ typename T::value_type  const&target = f; }"),
990             runCheckOnCode<ValueRTransform>(Cat(S)));
991 
992   EXPECT_EQ(Cat("{ const typename T::value_type &target = f; }"),
993             runCheckOnCode<PointeeLTransform>(Cat(S)));
994   EXPECT_EQ(Cat("{ typename T::value_type  const&target = f; }"),
995             runCheckOnCode<PointeeRTransform>(Cat(S)));
996 }
997 TEST(Template, VectorLikeType) {
998   StringRef TS = "template <typename T> struct TS { TS(const T&) {} }; ";
999   StringRef T = "void foo() ";
1000   StringRef S = "{ TS<int> target(42); }";
1001   auto Cat = [&TS, &T](StringRef S) { return (TS + T + S).str(); };
1002 
1003   EXPECT_EQ(Cat("{ const TS<int> target(42); }"),
1004             runCheckOnCode<ValueLTransform>(Cat(S)));
1005   EXPECT_EQ(Cat("{ TS<int> const target(42); }"),
1006             runCheckOnCode<ValueRTransform>(Cat(S)));
1007 
1008   EXPECT_EQ(Cat("{ const TS<int> target(42); }"),
1009             runCheckOnCode<PointeeLTransform>(Cat(S)));
1010   EXPECT_EQ(Cat("{ TS<int> const target(42); }"),
1011             runCheckOnCode<PointeeRTransform>(Cat(S)));
1012 }
1013 TEST(Template, SpecializedTemplate) {
1014   StringRef TS = "template <typename T = int> struct TS { TS(const T&) {} }; ";
1015   StringRef TS2 = "template <> struct TS<double> { TS(const double&) {} }; ";
1016   StringRef T = "void foo() ";
1017   StringRef S = "{ TS<double> target(42.42); }";
1018   auto Cat = [&](StringRef S) { return (TS + TS2 + T + S).str(); };
1019 
1020   EXPECT_EQ(Cat("{ const TS<double> target(42.42); }"),
1021             runCheckOnCode<ValueLTransform>(Cat(S)));
1022   EXPECT_EQ(Cat("{ TS<double> const target(42.42); }"),
1023             runCheckOnCode<ValueRTransform>(Cat(S)));
1024 
1025   EXPECT_EQ(Cat("{ const TS<double> target(42.42); }"),
1026             runCheckOnCode<PointeeLTransform>(Cat(S)));
1027   EXPECT_EQ(Cat("{ TS<double> const target(42.42); }"),
1028             runCheckOnCode<PointeeRTransform>(Cat(S)));
1029 }
1030 
1031 // -----------------------------------------------------------------------------
1032 // ObjC Pointers
1033 // -----------------------------------------------------------------------------
1034 
1035 TEST(ObjC, SimplePointers) {
1036   StringRef S = "int * target = 0;";
1037   EXPECT_EQ(runCheckOnCode<PointeeLTransform>(S, nullptr, "input.m"),
1038             "const int * target = 0;");
1039   EXPECT_EQ(runCheckOnCode<PointeeRTransform>(S, nullptr, "input.m"),
1040             "int  const* target = 0;");
1041   EXPECT_EQ(runCheckOnCode<ValueLTransform>(S, nullptr, "input.m"),
1042             "int * const target = 0;");
1043   EXPECT_EQ(runCheckOnCode<ValueRTransform>(S, nullptr, "input.m"),
1044             "int * const target = 0;");
1045 }
1046 TEST(ObjC, ClassPointer) {
1047   StringRef TB = "@class Object;\nint main() {\n";
1048   StringRef S = "Object *target;";
1049   StringRef TE = "\n}";
1050   auto Cat = [&](StringRef S) { return (TB + S + TE).str(); };
1051 
1052   // FIXME: Not done properly for some reason.
1053   EXPECT_NE(runCheckOnCode<PointeeLTransform>(Cat(S), nullptr, "input.m"),
1054             Cat("const Object *target;"));
1055   EXPECT_NE(runCheckOnCode<PointeeRTransform>(Cat(S), nullptr, "input.m"),
1056             Cat("Object  const*target;"));
1057   EXPECT_NE(runCheckOnCode<ValueLTransform>(Cat(S), nullptr, "input.m"),
1058             Cat("Object *const target;"));
1059   EXPECT_NE(runCheckOnCode<ValueRTransform>(Cat(S), nullptr, "input.m"),
1060             Cat("Object *const target;"));
1061 }
1062 TEST(ObjC, InterfacePointer) {
1063   StringRef TB = "@interface I\n";
1064   StringRef S = "- (void) foo: (int *) target;";
1065   StringRef TE = "\n@end";
1066   auto Cat = [&](StringRef S) { return (TB + S + TE).str(); };
1067 
1068   EXPECT_EQ(runCheckOnCode<PointeeLTransform>(Cat(S), nullptr, "input.m"),
1069             Cat("- (void) foo: (const int *) target;"));
1070   EXPECT_EQ(runCheckOnCode<PointeeRTransform>(Cat(S), nullptr, "input.m"),
1071             Cat("- (void) foo: (int  const*) target;"));
1072   // FIXME: These transformations are incorrect. ObjC seems to need
1073   // RParenSkipping which is not implemented.
1074   EXPECT_NE(runCheckOnCode<ValueLTransform>(Cat(S), nullptr, "input.m"),
1075             Cat("- (void) foo: (int * const) target;"));
1076   EXPECT_NE(runCheckOnCode<ValueRTransform>(Cat(S), nullptr, "input.m"),
1077             Cat("- (void) foo: (int * const) target;"));
1078 }
1079 
1080 } // namespace test
1081 } // namespace tidy
1082 } // namespace clang
1083