[clang-tidy][modernize-use-starts-ends-with] Fix operator rewriting false negative...
[llvm-project.git] / clang-tools-extra / unittests / clang-tidy / AddConstTest.cpp
blobd8c76049e393f986596390f843f933cea0ea4d23
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>
10 namespace clang {
11 namespace tidy {
13 namespace {
14 using namespace clang::ast_matchers;
15 using namespace utils::fixit;
17 template <QualifierTarget CT, QualifierPolicy CP>
18 class ConstTransform : public ClangTidyCheck {
19 public:
20 ConstTransform(StringRef CheckName, ClangTidyContext *Context)
21 : ClangTidyCheck(CheckName, Context) {}
23 void registerMatchers(MatchFinder *Finder) override {
24 Finder->addMatcher(varDecl(hasName("target")).bind("var"), this);
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;
37 } // namespace
39 namespace test {
40 using PointeeLTransform =
41 ConstTransform<QualifierTarget::Pointee, QualifierPolicy::Left>;
42 using PointeeRTransform =
43 ConstTransform<QualifierTarget::Pointee, QualifierPolicy::Right>;
45 using ValueLTransform =
46 ConstTransform<QualifierTarget::Value, QualifierPolicy::Left>;
47 using ValueRTransform =
48 ConstTransform<QualifierTarget::Value, QualifierPolicy::Right>;
50 // ----------------------------------------------------------------------------
51 // Test Value-like types. Everything with indirection is done later.
52 // ----------------------------------------------------------------------------
54 TEST(Values, Builtin) {
55 StringRef Snippet = "int target = 0;";
57 EXPECT_EQ("const int target = 0;", runCheckOnCode<ValueLTransform>(Snippet));
58 EXPECT_EQ("const int target = 0;",
59 runCheckOnCode<PointeeLTransform>(Snippet));
61 EXPECT_EQ("int const target = 0;", runCheckOnCode<ValueRTransform>(Snippet));
62 EXPECT_EQ("int const target = 0;",
63 runCheckOnCode<PointeeRTransform>(Snippet));
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(); };
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)));
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)));
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(); };
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)));
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)));
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(); };
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)));
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)));
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(); };
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)));
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)));
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(); };
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)));
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)));
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(); };
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)));
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)));
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(); };
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)));
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)));
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(); };
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)));
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)));
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(); };
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)));
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)));
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(); };
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)));
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)));
220 TEST(Values, Parens) {
221 StringRef Snippet = "int ((target)) = 0;";
223 EXPECT_EQ("const int ((target)) = 0;",
224 runCheckOnCode<ValueLTransform>(Snippet));
225 EXPECT_EQ("const int ((target)) = 0;",
226 runCheckOnCode<PointeeLTransform>(Snippet));
228 EXPECT_EQ("int const ((target)) = 0;",
229 runCheckOnCode<ValueRTransform>(Snippet));
230 EXPECT_EQ("int const ((target)) = 0;",
231 runCheckOnCode<PointeeRTransform>(Snippet));
234 // ----------------------------------------------------------------------------
235 // Test builtin-arrays
236 // ----------------------------------------------------------------------------
238 TEST(Arrays, Builtin) {
239 StringRef Snippet = "int target[][1] = {{1}, {2}, {3}};";
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));
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));
251 TEST(Arrays, BuiltinParens) {
252 StringRef Snippet = "int ((target))[][1] = {{1}, {2}, {3}};";
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));
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));
264 TEST(Arrays, Pointers) {
265 StringRef Snippet = "int x; int* target[] = {&x, &x, &x};";
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));
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));
277 TEST(Arrays, PointerPointers) {
278 StringRef Snippet = "int* x = nullptr; int** target[] = {&x, &x, &x};";
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));
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));
290 TEST(Arrays, PointersParens) {
291 StringRef Snippet = "int x; int* (target)[] = {&x, &x, &x};";
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));
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));
304 // ----------------------------------------------------------------------------
305 // Test reference types. This does not include pointers and arrays.
306 // ----------------------------------------------------------------------------
308 TEST(Reference, LValueBuiltin) {
309 StringRef Snippet = "int x = 42; int& target = x;";
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));
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));
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));
328 EXPECT_EQ("int const&& target = 42;",
329 runCheckOnCode<ValueRTransform>(Snippet));
330 EXPECT_EQ("int const&& target = 42;",
331 runCheckOnCode<PointeeRTransform>(Snippet));
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));
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));
345 TEST(Reference, LValueParens) {
346 StringRef Snippet = "int x = 42; int ((& target)) = x;";
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));
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));
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(); };
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)));
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)));
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(); };
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)));
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)));
389 // ----------------------------------------------------------------------------
390 // Test pointers types.
391 // ----------------------------------------------------------------------------
393 TEST(Pointers, SingleBuiltin) {
394 StringRef Snippet = "int* target = nullptr;";
396 EXPECT_EQ("int* const target = nullptr;",
397 runCheckOnCode<ValueLTransform>(Snippet));
398 EXPECT_EQ("int* const target = nullptr;",
399 runCheckOnCode<ValueRTransform>(Snippet));
401 EXPECT_EQ("const int* target = nullptr;",
402 runCheckOnCode<PointeeLTransform>(Snippet));
403 EXPECT_EQ("int const* target = nullptr;",
404 runCheckOnCode<PointeeRTransform>(Snippet));
406 TEST(Pointers, MultiBuiltin) {
407 StringRef Snippet = "int** target = nullptr;";
409 EXPECT_EQ("int** const target = nullptr;",
410 runCheckOnCode<ValueLTransform>(Snippet));
411 EXPECT_EQ("int** const target = nullptr;",
412 runCheckOnCode<ValueRTransform>(Snippet));
414 EXPECT_EQ("int* const* target = nullptr;",
415 runCheckOnCode<PointeeLTransform>(Snippet));
416 EXPECT_EQ("int* const* target = nullptr;",
417 runCheckOnCode<PointeeRTransform>(Snippet));
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(); };
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)));
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)));
434 TEST(Pointers, Parens) {
435 StringRef Snippet = "int ((**target)) = nullptr;";
437 EXPECT_EQ("int ((**const target)) = nullptr;",
438 runCheckOnCode<ValueLTransform>(Snippet));
439 EXPECT_EQ("int ((**const target)) = nullptr;",
440 runCheckOnCode<ValueRTransform>(Snippet));
442 EXPECT_EQ("int ((* const*target)) = nullptr;",
443 runCheckOnCode<PointeeLTransform>(Snippet));
444 EXPECT_EQ("int ((* const*target)) = nullptr;",
445 runCheckOnCode<PointeeRTransform>(Snippet));
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(); };
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)));
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)));
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(); };
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)));
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)));
477 TEST(Pointers, FunctionPointer) {
478 StringRef S = "int (*target)(float, int, double) = nullptr;";
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));
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));
490 S = "int (((*target)))(float, int, double) = nullptr;";
491 EXPECT_EQ("int (((*const target)))(float, int, double) = nullptr;",
492 runCheckOnCode<PointeeRTransform>(S));
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(); };
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)));
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)));
509 S = "int (A::*((target)))() = &A::f;";
510 EXPECT_EQ(Cat("int (A::*const ((target)))() = &A::f;"),
511 runCheckOnCode<ValueLTransform>(Cat(S)));
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(); };
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)));
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)));
528 S = "int A::*((target)) = &A::member;";
529 EXPECT_EQ(Cat("int A::*const ((target)) = &A::member;"),
530 runCheckOnCode<PointeeRTransform>(Cat(S)));
533 // ----------------------------------------------------------------------------
534 // Test TagTypes (struct, class, unions, enums)
535 // ----------------------------------------------------------------------------
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(); };
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)));
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)));
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)));
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)));
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)));
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)));
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));
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));
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));
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));
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(); };
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)));
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)));
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)));
616 EXPECT_EQ(Cat("Foo const target;"), runCheckOnCode<ValueRTransform>(Cat(S)));
617 EXPECT_EQ(Cat("Foo const target;"),
618 runCheckOnCode<PointeeRTransform>(Cat(S)));
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)));
626 EXPECT_EQ(Cat("Foo const (target);"),
627 runCheckOnCode<ValueRTransform>(Cat(S)));
628 EXPECT_EQ(Cat("Foo const (target);"),
629 runCheckOnCode<PointeeRTransform>(Cat(S)));
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(); };
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)));
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)));
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)));
651 EXPECT_EQ(Cat("Foo const target;"), runCheckOnCode<ValueRTransform>(Cat(S)));
652 EXPECT_EQ(Cat("Foo const target;"),
653 runCheckOnCode<PointeeRTransform>(Cat(S)));
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)));
661 EXPECT_EQ(Cat("Foo const (target);"),
662 runCheckOnCode<ValueRTransform>(Cat(S)));
663 EXPECT_EQ(Cat("Foo const (target);"),
664 runCheckOnCode<PointeeRTransform>(Cat(S)));
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(); };
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)));
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)));
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)));
686 EXPECT_EQ(Cat("Foo const target;"), runCheckOnCode<ValueRTransform>(Cat(S)));
687 EXPECT_EQ(Cat("Foo const target;"),
688 runCheckOnCode<PointeeRTransform>(Cat(S)));
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)));
696 EXPECT_EQ(Cat("Foo const (target);"),
697 runCheckOnCode<ValueRTransform>(Cat(S)));
698 EXPECT_EQ(Cat("Foo const (target);"),
699 runCheckOnCode<PointeeRTransform>(Cat(S)));
702 // ----------------------------------------------------------------------------
703 // Test Macro expansions.
704 // ----------------------------------------------------------------------------
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(); };
711 EXPECT_EQ(Cat("DEFINE_VARIABLE;"), runCheckOnCode<ValueLTransform>(Cat(S)));
712 EXPECT_EQ(Cat("DEFINE_VARIABLE;"), runCheckOnCode<ValueRTransform>(Cat(S)));
714 EXPECT_EQ(Cat("DEFINE_VARIABLE;"), runCheckOnCode<PointeeLTransform>(Cat(S)));
715 EXPECT_EQ(Cat("DEFINE_VARIABLE;"), runCheckOnCode<PointeeRTransform>(Cat(S)));
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(); };
722 EXPECT_EQ(Cat("DEFINE_VARIABLE(target);"),
723 runCheckOnCode<ValueLTransform>(Cat(S)));
724 EXPECT_EQ(Cat("DEFINE_VARIABLE(target);"),
725 runCheckOnCode<ValueRTransform>(Cat(S)));
727 EXPECT_EQ(Cat("DEFINE_VARIABLE(target);"),
728 runCheckOnCode<PointeeLTransform>(Cat(S)));
729 EXPECT_EQ(Cat("DEFINE_VARIABLE(target);"),
730 runCheckOnCode<PointeeRTransform>(Cat(S)));
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(); };
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)));
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)));
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(); };
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)));
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)));
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(); };
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)));
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)));
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;); }";
787 auto Cat = [&](StringRef S) { return (M + F + V).str(); };
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)));
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 = "}";
800 auto Cat = [&](StringRef S) { return (M + F + V + E).str(); };
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)));
808 // ----------------------------------------------------------------------------
809 // Test template code.
810 // ----------------------------------------------------------------------------
812 TEST(Template, TemplateVariable) {
813 StringRef T = "template <typename T> T target = 3.1415;";
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));
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));
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(); };
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)));
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)));
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(); };
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)));
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)));
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(); };
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)));
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)));
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();
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)));
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)));
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(); };
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)));
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)));
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(); };
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)));
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)));
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(); };
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)));
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)));
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(); };
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)));
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)));
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(); };
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)));
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)));
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(); };
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)));
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)));
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(); };
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)));
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)));
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(); };
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)));
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)));
1031 // -----------------------------------------------------------------------------
1032 // ObjC Pointers
1033 // -----------------------------------------------------------------------------
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;");
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(); };
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;"));
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(); };
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;"));
1080 } // namespace test
1081 } // namespace tidy
1082 } // namespace clang