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