xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/modernize/use-using.cpp (revision f77152d9a44b49ee38b15085034bbfe22b4b3992)
1 // RUN: %check_clang_tidy %s modernize-use-using %t -- -- -fno-delayed-template-parsing -I %S/Inputs/use-using/
2 
3 typedef int Type;
4 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' [modernize-use-using]
5 // CHECK-FIXES: using Type = int;
6 
7 typedef long LL;
8 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
9 // CHECK-FIXES: using LL = long;
10 
11 typedef int Bla;
12 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
13 // CHECK-FIXES: using Bla = int;
14 
15 typedef Bla Bla2;
16 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
17 // CHECK-FIXES: using Bla2 = Bla;
18 
19 typedef void (*type)(int, int);
20 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
21 // CHECK-FIXES: using type = void (*)(int, int);
22 
23 typedef void (*type2)();
24 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
25 // CHECK-FIXES: using type2 = void (*)();
26 
27 class Class {
28   typedef long long Type;
29   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef'
30   // CHECK-FIXES: using Type = long long;
31 };
32 
33 typedef void (Class::*MyPtrType)(Bla) const;
34 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
35 // CHECK-FIXES: using MyPtrType = void (Class::*)(Bla)[[ATTR:( __attribute__\(\(thiscall\)\))?]] const;
36 
37 class Iterable {
38 public:
39   class Iterator {};
40 };
41 
42 template <typename T>
43 class Test {
44   typedef typename T::iterator Iter;
45   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef'
46   // CHECK-FIXES: using Iter = typename T::iterator;
47 };
48 
49 using balba = long long;
50 
51 union A {};
52 
53 typedef void (A::*PtrType)(int, int) const;
54 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
55 // CHECK-FIXES: using PtrType = void (A::*)(int, int)[[ATTR]] const;
56 
57 typedef Class some_class;
58 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
59 // CHECK-FIXES: using some_class = Class;
60 
61 typedef Class Cclass;
62 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
63 // CHECK-FIXES: using Cclass = Class;
64 
65 typedef Cclass cclass2;
66 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
67 // CHECK-FIXES: using cclass2 = Cclass;
68 
69 class cclass {};
70 
71 typedef void (cclass::*MyPtrType3)(Bla);
72 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
73 // CHECK-FIXES: using MyPtrType3 = void (cclass::*)(Bla)[[ATTR]];
74 
75 using my_class = int;
76 
77 typedef Test<my_class *> another;
78 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
79 // CHECK-FIXES: using another = Test<my_class *>;
80 
81 typedef int* PInt;
82 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
83 // CHECK-FIXES: using PInt = int*;
84 
85 typedef int bla1, bla2, bla3;
86 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
87 // CHECK-MESSAGES: :[[@LINE-2]]:17: warning: use 'using' instead of 'typedef'
88 // CHECK-MESSAGES: :[[@LINE-3]]:23: warning: use 'using' instead of 'typedef'
89 // CHECK-FIXES: using bla1 = int;
90 // CHECK-FIXES-NEXT: using bla2 = int;
91 // CHECK-FIXES-NEXT: using bla3 = int;
92 
93 #define CODE typedef int INT
94 
95 CODE;
96 // CHECK-FIXES: #define CODE typedef int INT
97 // CHECK-FIXES: CODE;
98 
99 struct Foo;
100 #define Bar Baz
101 typedef Foo Bar;
102 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
103 // CHECK-FIXES: #define Bar Baz
104 // CHECK-FIXES: using Baz = Foo;
105 
106 #define TYPEDEF typedef
107 TYPEDEF Foo Bak;
108 // CHECK-FIXES: #define TYPEDEF typedef
109 // CHECK-FIXES: TYPEDEF Foo Bak;
110 
111 #define FOO Foo
112 typedef FOO Bam;
113 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
114 // CHECK-FIXES: #define FOO Foo
115 // CHECK-FIXES: using Bam = FOO;
116 
117 typedef struct Foo Bap;
118 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
119 // CHECK-FIXES: using Bap = struct Foo;
120 
121 struct Foo typedef Bap2;
122 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
123 // CHECK-FIXES: using Bap2 = struct Foo;
124 
125 Foo typedef Bap3;
126 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
127 // CHECK-FIXES: using Bap3 = Foo;
128 
129 typedef struct Unknown Baq;
130 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
131 // CHECK-FIXES: using Baq = struct Unknown;
132 
133 struct Unknown2 typedef Baw;
134 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
135 // CHECK-FIXES: using Baw = struct Unknown2;
136 
137 int typedef Bax;
138 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
139 // CHECK-FIXES: using Bax = int;
140 
141 typedef struct Q1 { int a; } S1;
142 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
143 // CHECK-FIXES: using S1 = struct Q1 { int a; };
144 typedef struct { int b; } S2;
145 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
146 // CHECK-FIXES: using S2 = struct { int b; };
147 struct Q2 { int c; } typedef S3;
148 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
149 // CHECK-FIXES: using S3 = struct Q2 { int c; };
150 struct { int d; } typedef S4;
151 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
152 // CHECK-FIXES: using S4 = struct { int d; };
153 
154 namespace my_space {
155   class my_cclass {};
156   typedef my_cclass FuncType;
157 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef'
158 // CHECK-FIXES: using FuncType = my_cclass;
159 }
160 
161 #define lol 4
162 typedef unsigned Map[lol];
163 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
164 // CHECK-FIXES: typedef unsigned Map[lol];
165 
166 typedef void (*fun_type)();
167 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
168 // CHECK-FIXES: using fun_type = void (*)();
169 
170 namespace template_instantiations {
171 template <typename T>
172 class C {
173  protected:
174   typedef C<T> super;
175   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef'
176   // CHECK-FIXES: using super = C<T>;
177   virtual void f();
178 
179 public:
180   virtual ~C();
181 };
182 
183 class D : public C<D> {
184   void f() override { super::f(); }
185 };
186 class E : public C<E> {
187   void f() override { super::f(); }
188 };
189 }
190 
191 template <typename T1, typename T2>
192 class TwoArgTemplate {
193   typedef TwoArgTemplate<T1, T2> self;
194   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef'
195   // CHECK-FIXES: using self = TwoArgTemplate<T1, T2>;
196 };
197 
198 template <bool B, typename T>
199 struct S {};
200 
201 typedef S<(0 > 0), int> S_t, *S_p;
202 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
203 // CHECK-MESSAGES: :[[@LINE-2]]:28: warning: use 'using' instead of 'typedef'
204 // CHECK-FIXES: using S_t = S<(0 > 0), int>;
205 // CHECK-FIXES-NEXT: using S_p = S_t*;
206 
207 typedef S<(0 < 0), int> S2_t, *S2_p;
208 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
209 // CHECK-MESSAGES: :[[@LINE-2]]:29: warning: use 'using' instead of 'typedef'
210 // CHECK-FIXES: using S2_t = S<(0 < 0), int>;
211 // CHECK-FIXES-NEXT: using S2_p = S2_t*;
212 
213 typedef S<(0 > 0 && (3 > 1) && (1 < 1)), int> S3_t;
214 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
215 // CHECK-FIXES: using S3_t = S<(0 > 0 && (3 > 1) && (1 < 1)), int>;
216 
217 template <bool B>
218 struct Q {};
219 
220 constexpr bool b[1] = {true};
221 
222 typedef Q<b[0 < 0]> Q_t, *Q_p;
223 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
224 // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: use 'using' instead of 'typedef'
225 // CHECK-FIXES: using Q_t = Q<b[0 < 0]>;
226 // CHECK-FIXES-NEXT: using Q_p = Q_t*;
227 
228 typedef Q<b[0 < 0]> Q2_t;
229 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
230 // CHECK-FIXES: using Q2_t = Q<b[0 < 0]>;
231 
232 struct T {
233   constexpr T(bool) {}
234 
235   static constexpr bool b = true;
236 };
237 
238 typedef Q<T{0 < 0}.b> Q3_t, *Q3_p;
239 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
240 // CHECK-MESSAGES: :[[@LINE-2]]:27: warning: use 'using' instead of 'typedef'
241 // CHECK-FIXES: using Q3_t = Q<T{0 < 0}.b>;
242 // CHECK-FIXES-NEXT: using Q3_p = Q3_t*;
243 
244 typedef Q<T{0 < 0}.b> Q3_t;
245 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
246 // CHECK-FIXES: using Q3_t = Q<T{0 < 0}.b>;
247 
248 typedef TwoArgTemplate<TwoArgTemplate<int, Q<T{0 < 0}.b> >, S<(0 < 0), Q<b[0 < 0]> > > Nested_t;
249 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
250 // CHECK-FIXES: using Nested_t = TwoArgTemplate<TwoArgTemplate<int, Q<T{0 < 0}.b> >, S<(0 < 0), Q<b[0 < 0]> > >;
251 
252 template <typename a>
253 class TemplateKeyword {
254   typedef typename a::template b<> d;
255   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef'
256   // CHECK-FIXES: using d = typename a::template b<>;
257 
258   typedef typename a::template b<>::c d2;
259   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef'
260   // CHECK-FIXES: using d2 = typename a::template b<>::c;
261 };
262 
263 template <typename... Args>
264 class Variadic {};
265 
266 typedef Variadic<Variadic<int, bool, Q<T{0 < 0}.b> >, S<(0 < 0), Variadic<Q<b[0 < 0]> > > > Variadic_t;
267 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
268 // CHECK-FIXES: using Variadic_t = Variadic<Variadic<int, bool, Q<T{0 < 0}.b> >, S<(0 < 0), Variadic<Q<b[0 < 0]> > > >
269 
270 typedef Variadic<Variadic<int, bool, Q<T{0 < 0}.b> >, S<(0 < 0), Variadic<Q<b[0 < 0]> > > > Variadic_t, *Variadic_p;
271 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
272 // CHECK-MESSAGES: :[[@LINE-2]]:103: warning: use 'using' instead of 'typedef'
273 // CHECK-FIXES: using Variadic_t = Variadic<Variadic<int, bool, Q<T{0 < 0}.b> >, S<(0 < 0), Variadic<Q<b[0 < 0]> > > >;
274 // CHECK-FIXES-NEXT: using Variadic_p = Variadic_t*;
275 
276 typedef struct { int a; } R_t, *R_p;
277 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
278 // CHECK-MESSAGES: :[[@LINE-2]]:30: warning: use 'using' instead of 'typedef'
279 // CHECK-FIXES: using R_t = struct { int a; };
280 // CHECK-FIXES-NEXT: using R_p = R_t*;
281 
282 typedef enum { ea1, eb1 } EnumT1;
283 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
284 // CHECK-FIXES: using EnumT1 = enum { ea1, eb1 };
285 
286 #include "modernize-use-using.h"
287 
288 typedef enum { ea2, eb2 } EnumT2_CheckTypedefImpactFromAnotherFile;
289 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
290 // CHECK-FIXES: using EnumT2_CheckTypedefImpactFromAnotherFile = enum { ea2, eb2 };
291 
292 template <int A>
293 struct InjectedClassName {
294   typedef InjectedClassName b;
295   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef'
296   // CHECK-FIXES: using b = InjectedClassName;
297 };
298 
299 template <int>
300 struct InjectedClassNameWithUnnamedArgument {
301   typedef InjectedClassNameWithUnnamedArgument b;
302   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef'
303   // CHECK-FIXES: using b = InjectedClassNameWithUnnamedArgument;
304 };
305 
306 typedef struct { int a; union { int b; }; } PR50990;
307 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
308 // CHECK-FIXES: using PR50990 = struct { int a; union { int b; }; };
309 
310 typedef struct { struct { int a; struct { struct { int b; } c; int d; } e; } f; int g; } PR50990_nested;
311 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
312 // CHECK-FIXES: using PR50990_nested = struct { struct { int a; struct { struct { int b; } c; int d; } e; } f; int g; };
313 
314 typedef struct { struct { int a; } b; union { int c; float d; struct { int e; }; }; struct { double f; } g; } PR50990_siblings;
315 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
316 // CHECK-FIXES: using PR50990_siblings = struct { struct { int a; } b; union { int c; float d; struct { int e; }; }; struct { double f; } g; };
317 
318 typedef void (*ISSUE_65055_1)(int);
319 typedef bool (*ISSUE_65055_2)(int);
320 // CHECK-MESSAGES: :[[@LINE-2]]:1: warning: use 'using' instead of 'typedef'
321 // CHECK-MESSAGES: :[[@LINE-2]]:1: warning: use 'using' instead of 'typedef'
322 // CHECK-FIXES: {{^}}using ISSUE_65055_1 = void (*)(int);{{$}}
323 // CHECK-FIXES: {{^}}using ISSUE_65055_2 = bool (*)(int);{{$}}
324 
325 typedef class ISSUE_67529_1 *ISSUE_67529;
326 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
327 // CHECK-FIXES: using ISSUE_67529 = class ISSUE_67529_1 *;
328 
329 // Some Header
330 extern "C" {
331 
332 typedef int InExternC;
333 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' [modernize-use-using]
334 // CHECK-FIXES: using InExternC = int;
335 
336 }
337 
338 extern "C++" {
339 
340 typedef int InExternCPP;
341 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' [modernize-use-using]
342 // CHECK-FIXES: using InExternCPP = int;
343 
344 }
345 
346 namespace ISSUE_72179
347 {
348   void foo()
349   {
350     typedef int a;
351     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'using' instead of 'typedef' [modernize-use-using]
352     // CHECK-FIXES: using a = int;
353 
354   }
355 
356   void foo2()
357   {
358     typedef struct { int a; union { int b; }; } c;
359     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'using' instead of 'typedef' [modernize-use-using]
360     // CHECK-FIXES: using c = struct { int a; union { int b; }; };
361   }
362 
363   template <typename T>
364   void foo3()
365   {
366     typedef T b;
367     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'using' instead of 'typedef' [modernize-use-using]
368     // CHECK-FIXES: using b = T;
369   }
370 
371   template <typename T>
372   class MyClass
373   {
374     void foo()
375     {
376       typedef MyClass c;
377       // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use 'using' instead of 'typedef' [modernize-use-using]
378       // CHECK-FIXES: using c = MyClass;
379     }
380   };
381 
382   const auto foo4 = [](int a){typedef int d;};
383   // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: use 'using' instead of 'typedef' [modernize-use-using]
384   // CHECK-FIXES: const auto foo4 = [](int a){using d = int;};
385 }
386 
387 
388 typedef int* int_ptr, *int_ptr_ptr;
389 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' [modernize-use-using]
390 // CHECK-MESSAGES: :[[@LINE-2]]:21: warning: use 'using' instead of 'typedef' [modernize-use-using]
391 // CHECK-FIXES: using int_ptr = int*;
392 // CHECK-FIXES-NEXT: using int_ptr_ptr = int_ptr*;
393 
394 #ifndef SpecialMode
395 #define SomeMacro(x) x
396 #else
397 #define SomeMacro(x) SpecialType
398 #endif
399 
400 class SomeMacro(GH33760) { };
401 
402 typedef void(SomeMacro(GH33760)::* FunctionType)(float, int);
403 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' [modernize-use-using]
404 // CHECK-FIXES: using FunctionType = void(SomeMacro(GH33760)::* )(float, int);
405 
406 #define CDECL __attribute((cdecl))
407 
408 // GH37846 & GH41685
409 typedef void (CDECL *GH37846)(int);
410 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' [modernize-use-using]
411 // CHECK-FIXES: using GH37846 = void (CDECL *)(int);
412 
413 typedef void (__attribute((cdecl)) *GH41685)(int);
414 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' [modernize-use-using]
415 // CHECK-FIXES: using GH41685 = void (__attribute((cdecl)) *)(int);
416 
417 namespace GH83568 {
418   typedef int(*name)(int arg1, int arg2);
419 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef' [modernize-use-using]
420 // CHECK-FIXES: using name = int(*)(int arg1, int arg2);
421 }
422 
423 #ifdef FOO
424 #define GH95716 float
425 #else
426 #define GH95716 double
427 #endif
428 
429 typedef GH95716 foo;
430 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef' [modernize-use-using]
431 // CHECK-FIXES: using foo = GH95716;
432 
433 namespace GH97009 {
434   typedef double PointType[3];
435 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef' [modernize-use-using]
436   typedef bool (*Function)(PointType, PointType);
437 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef' [modernize-use-using]
438 // CHECK-FIXES: using Function = bool (*)(PointType, PointType);
439 }
440