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