1 // RUN: %check_clang_tidy %s llvmlibc-inline-function-decl %t
2
3 #ifndef LLVM_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_LLVMLIBC_INLINEFUNCTIONDECL_H
4 #define LLVM_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_LLVMLIBC_INLINEFUNCTIONDECL_H
5
6 #define LIBC_INLINE inline
7
8 namespace __llvm_libc {
9
addi(int a,int b)10 LIBC_INLINE int addi(int a, int b) {
11 return a + b;
12 }
13
addl(long a,long b)14 LIBC_INLINE constexpr long addl(long a, long b) {
15 return a + b;
16 }
17
addll(long long a,long long b)18 constexpr long long addll(long long a, long long b) {
19 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: 'addll' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
20 // CHECK-FIXES: LIBC_INLINE constexpr long long addll(long long a, long long b) {
21 return a + b;
22 }
23
addul(unsigned long a,unsigned long b)24 inline unsigned long addul(unsigned long a, unsigned long b) {
25 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: 'addul' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
26 // CHECK-FIXES: LIBC_INLINE inline unsigned long addul(unsigned long a, unsigned long b) {
27 return a + b;
28 }
29
30 class MyClass {
31 int A;
32 public:
MyClass()33 MyClass() : A(123) {}
34 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'MyClass' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
35 // CHECK-FIXES: LIBC_INLINE MyClass() : A(123) {}
36
MyClass(int V)37 LIBC_INLINE MyClass(int V) : A(V) {}
38
operator int() const39 constexpr operator int() const { return A; }
40 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'operator int' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
41 // CHECK-FIXES: LIBC_INLINE constexpr operator int() const { return A; }
42
operator ==(const MyClass & RHS)43 LIBC_INLINE bool operator==(const MyClass &RHS) {
44 return RHS.A == A;
45 }
46
getVal(const MyClass & V)47 static int getVal(const MyClass &V) {
48 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'getVal' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
49 // CHECK-FIXES: LIBC_INLINE static int getVal(const MyClass &V) {
50 return V.A;
51 }
52
setVal(MyClass & V,int A)53 LIBC_INLINE static void setVal(MyClass &V, int A) {
54 V.A = A;
55 }
56
addInt(MyClass & V,int A)57 constexpr static int addInt(MyClass &V, int A) {
58 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'addInt' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
59 // CHECK-FIXES: LIBC_INLINE constexpr static int addInt(MyClass &V, int A) {
60 return V.A += A;
61 }
62
mulInt(MyClass & V,int A)63 static LIBC_INLINE int mulInt(MyClass &V, int A) {
64 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'mulInt' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
65 return V.A *= A;
66 }
67 };
68
lambda()69 LIBC_INLINE void lambda() {
70 // CHECK-MESSAGES-NOT: :[[@LINE+4]]:3: warning: '__invoke' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
71 // CHECK-MESSAGES-NOT: :[[@LINE+3]]:3: warning: 'operator void (*)()' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
72 // CHECK-MESSAGES-NOT: :[[@LINE+2]]:3: warning: '~(lambda at [[FILENAME:.+]])' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
73 // CHECK-MESSAGES-NOT: :[[@LINE+1]]:6: warning: 'operator()' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
74 [](){};
75 }
76
77 namespace issue_62746 {
78
79 void goodSimpleFunction();
80 void badSimpleFunction();
81 void badSimpleFunctionWrongLocation();
82
goodSimpleFunction()83 LIBC_INLINE void goodSimpleFunction() {}
84
badSimpleFunction()85 inline void badSimpleFunction() {}
86 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: 'badSimpleFunction' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
87 // CHECK-FIXES: LIBC_INLINE inline void badSimpleFunction() {}
88
badSimpleFunctionWrongLocation()89 void LIBC_INLINE badSimpleFunctionWrongLocation() {}
90 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: 'badSimpleFunctionWrongLocation' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
91
92 template <typename T>
93 void goodTemplateFunction();
94 template <typename T>
95 void badTemplateFunction();
96 template <typename T>
97 void badTemplateFunctionWrongLocation();
98
goodTemplateFunction()99 template <typename T> LIBC_INLINE void goodTemplateFunction() {}
100
badTemplateFunction()101 template <typename T> inline void badTemplateFunction() {}
102 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'badTemplateFunction' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
103 // CHECK-FIXES: template <typename T> LIBC_INLINE inline void badTemplateFunction() {}
104
badTemplateFunctionWrongLocation()105 template <typename T> void LIBC_INLINE badTemplateFunctionWrongLocation() {}
106 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'badTemplateFunctionWrongLocation' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
107
108 template <typename... Ts>
109 void goodVariadicFunction();
110 template <typename... Ts>
111 void badVariadicFunction();
112 template <typename... Ts>
113 void badVariadicFunctionWrongLocation();
114
goodVariadicFunction()115 template <typename... Ts> LIBC_INLINE void goodVariadicFunction() {}
116
badVariadicFunction()117 template <typename... Ts> inline void badVariadicFunction() {}
118 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: 'badVariadicFunction' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
119 // CHECK-FIXES: template <typename... Ts> LIBC_INLINE inline void badVariadicFunction() {}
120
badVariadicFunctionWrongLocation()121 template <typename... Ts> void LIBC_INLINE badVariadicFunctionWrongLocation() {}
122 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: 'badVariadicFunctionWrongLocation' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
123 // CHECK-FIXES: template <typename... Ts> LIBC_INLINE void LIBC_INLINE badVariadicFunctionWrongLocation() {}
124
125 struct NoTemplate {
126 void goodNoTemplate();
127 void badNoTemplate();
128 void badNoTemplateWrongLocation();
129
130 template <typename T>
131 void goodNestedTemplate();
132 template <typename T>
133 void badNestedTemplate();
134 template <typename T>
135 void badNestedTemplateWrongLocation();
136
137 template <typename... Ts>
138 void goodVariadicTemplate();
139 template <typename... Ts>
140 void badVariadicTemplate();
141 template <typename... Ts>
142 void badVariadicTemplateWrongLocation();
143
144 };
145
goodNoTemplate()146 LIBC_INLINE void NoTemplate::goodNoTemplate() {}
147
badNoTemplate()148 inline void NoTemplate::badNoTemplate() {}
149 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: 'badNoTemplate' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
150 // CHECK-FIXES: LIBC_INLINE inline void NoTemplate::badNoTemplate() {}
151
badNoTemplateWrongLocation()152 void LIBC_INLINE NoTemplate::badNoTemplateWrongLocation() {}
153 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: 'badNoTemplateWrongLocation' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
154 // CHECK-FIXES: LIBC_INLINE void LIBC_INLINE NoTemplate::badNoTemplateWrongLocation() {}
155
goodNestedTemplate()156 template <typename T> LIBC_INLINE void NoTemplate::goodNestedTemplate() {}
157
badNestedTemplate()158 template <typename T> inline void NoTemplate::badNestedTemplate() {}
159 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'badNestedTemplate' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
160 // CHECK-FIXES: template <typename T> LIBC_INLINE inline void NoTemplate::badNestedTemplate() {}
161
badNestedTemplateWrongLocation()162 template <typename T> void LIBC_INLINE NoTemplate::badNestedTemplateWrongLocation() {}
163 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'badNestedTemplateWrongLocation' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
164 // CHECK-FIXES: template <typename T> LIBC_INLINE void LIBC_INLINE NoTemplate::badNestedTemplateWrongLocation() {}
165
goodVariadicTemplate()166 template <typename... Ts> LIBC_INLINE void NoTemplate::goodVariadicTemplate() {}
167
badVariadicTemplate()168 template <typename... Ts> void inline NoTemplate::badVariadicTemplate() {}
169 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: 'badVariadicTemplate' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
170 // CHECK-FIXES: template <typename... Ts> LIBC_INLINE void inline NoTemplate::badVariadicTemplate() {}
171
badVariadicTemplateWrongLocation()172 template <typename... Ts> void LIBC_INLINE NoTemplate::badVariadicTemplateWrongLocation() {}
173 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: 'badVariadicTemplateWrongLocation' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
174
175 template <typename T>
176 struct SimpleTemplate {
177 void goodSimpleTemplate();
178 void badSimpleTemplate();
179 void badSimpleTemplateWrongLocation();
180
181 template <typename U>
182 void goodNestedTemplate();
183 template <typename U>
184 void badNestedTemplate();
185 template <typename U>
186 void badNestedTemplateWrongLocation();
187
188 template <typename... Ts>
189 void goodNestedVariadicTemplate();
190 template <typename... Ts>
191 void badNestedVariadicTemplate();
192 template <typename... Ts>
193 void badNestedVariadicTemplateWrongLocation();
194 };
195
goodSimpleTemplate()196 template <typename T> LIBC_INLINE void SimpleTemplate<T>::goodSimpleTemplate() {}
197
badSimpleTemplate()198 template <typename T> inline void SimpleTemplate<T>::badSimpleTemplate() {}
199 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'badSimpleTemplate' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
200 // CHECK-FIXES: template <typename T> LIBC_INLINE inline void SimpleTemplate<T>::badSimpleTemplate() {}
201
badSimpleTemplateWrongLocation()202 template <typename T> void LIBC_INLINE SimpleTemplate<T>::badSimpleTemplateWrongLocation() {}
203 // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'badSimpleTemplateWrongLocation' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
204
goodNestedTemplate()205 template <typename T> template <typename U> LIBC_INLINE void SimpleTemplate<T>::goodNestedTemplate() {}
206
badNestedTemplate()207 template <typename T> template <typename U> inline void SimpleTemplate<T>::badNestedTemplate() {}
208 // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: 'badNestedTemplate' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
209 // CHECK-FIXES: template <typename T> template <typename U> LIBC_INLINE inline void SimpleTemplate<T>::badNestedTemplate() {}
210
badNestedTemplateWrongLocation()211 template <typename T> template <typename U> void LIBC_INLINE SimpleTemplate<T>::badNestedTemplateWrongLocation() {}
212 // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: 'badNestedTemplateWrongLocation' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
213
goodNestedVariadicTemplate()214 template <typename T> template <typename... Ts> LIBC_INLINE void SimpleTemplate<T>::goodNestedVariadicTemplate() {}
215
badNestedVariadicTemplate()216 template <typename T> template <typename... Ts> inline void SimpleTemplate<T>::badNestedVariadicTemplate() {}
217 // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: 'badNestedVariadicTemplate' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
218 // CHECK-FIXES: template <typename T> template <typename... Ts> LIBC_INLINE inline void SimpleTemplate<T>::badNestedVariadicTemplate() {}
219
badNestedVariadicTemplateWrongLocation()220 template <typename T> template <typename... Ts> void LIBC_INLINE SimpleTemplate<T>::badNestedVariadicTemplateWrongLocation() {}
221 // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: 'badNestedVariadicTemplateWrongLocation' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
222
223 template <typename... Ts>
224 struct VariadicTemplate {
225 void goodVariadicTemplate();
226 void badVariadicTemplate();
227 void badVariadicTemplateWrongLocation();
228
229 template <typename U>
230 void goodNestedTemplate();
231 template <typename U>
232 void badNestedTemplate();
233 template <typename U>
234 void badNestedTemplateWrongLocation();
235
236 template <typename... Us>
237 void goodNestedVariadicTemplate();
238 template <typename... Us>
239 void badNestedVariadicTemplate();
240 template <typename... Us>
241 void badNestedVariadicTemplateWrongLocation();
242 };
243
goodVariadicTemplate()244 template <typename... Ts> LIBC_INLINE void VariadicTemplate<Ts...>::goodVariadicTemplate() {}
245
badVariadicTemplate()246 template <typename... Ts> inline void VariadicTemplate<Ts...>::badVariadicTemplate() {}
247 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: 'badVariadicTemplate' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
248 // CHECK-FIXES: template <typename... Ts> LIBC_INLINE inline void VariadicTemplate<Ts...>::badVariadicTemplate() {}
249
badVariadicTemplateWrongLocation()250 template <typename... Ts> void LIBC_INLINE VariadicTemplate<Ts...>::badVariadicTemplateWrongLocation() {}
251 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: 'badVariadicTemplateWrongLocation' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
252
goodNestedTemplate()253 template <typename... Ts> template <typename U> LIBC_INLINE void VariadicTemplate<Ts...>::goodNestedTemplate() {}
254
badNestedTemplate()255 template <typename... Ts> template <typename U> inline void VariadicTemplate<Ts...>::badNestedTemplate() {}
256 // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: 'badNestedTemplate' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
257 // CHECK-FIXES: template <typename... Ts> template <typename U> LIBC_INLINE inline void VariadicTemplate<Ts...>::badNestedTemplate() {}
258
badNestedTemplateWrongLocation()259 template <typename... Ts> template <typename U> void LIBC_INLINE VariadicTemplate<Ts...>::badNestedTemplateWrongLocation() {}
260 // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: 'badNestedTemplateWrongLocation' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
261
goodNestedVariadicTemplate()262 template <typename... Ts> template <typename... Us> LIBC_INLINE void VariadicTemplate<Ts...>::goodNestedVariadicTemplate() {}
263
badNestedVariadicTemplate()264 template <typename... Ts> template <typename... Us> inline void VariadicTemplate<Ts...>::badNestedVariadicTemplate() {}
265 // CHECK-MESSAGES: :[[@LINE-1]]:53: warning: 'badNestedVariadicTemplate' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
266 // CHECK-FIXES: template <typename... Ts> template <typename... Us> LIBC_INLINE inline void VariadicTemplate<Ts...>::badNestedVariadicTemplate() {}
267
badNestedVariadicTemplateWrongLocation()268 template <typename... Ts> template <typename... Us> void LIBC_INLINE VariadicTemplate<Ts...>::badNestedVariadicTemplateWrongLocation() {}
269 // CHECK-MESSAGES: :[[@LINE-1]]:53: warning: 'badNestedVariadicTemplateWrongLocation' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
270
271 template <typename T>
272 void goodWeirdFormatting();
273 template <typename T>
274 void badWeirdFormatting();
275
goodWeirdFormatting()276 template <typename T>LIBC_INLINE void goodWeirdFormatting() {}
277
badWeirdFormatting()278 template <typename T>void LIBC_INLINE badWeirdFormatting() {}
279 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: 'badWeirdFormatting' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
280
281
282 template <unsigned int NumberOfBits> struct HasMemberAndTemplate {
283 char Data[NumberOfBits];
284
explicitFunction__llvm_libc::issue_62746::HasMemberAndTemplate285 void explicitFunction() {}
286 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'explicitFunction' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
287 // CHECK-FIXES: LIBC_INLINE void explicitFunction() {}
288 };
289
290 static auto instanceOfStruct = HasMemberAndTemplate<16>();
291
292 struct HasMemberAndExplicitDefault {
293 int TrivialMember;
294
295 HasMemberAndExplicitDefault() = default;
296 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'HasMemberAndExplicitDefault' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl]
297 // CHECK-FIXES: LIBC_INLINE HasMemberAndExplicitDefault() = default;
298
299 ~HasMemberAndExplicitDefault() = delete;
300 };
301
302
303 } // namespace issue_62746
304
305 } // namespace __llvm_libc
306
307 #endif // LLVM_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_LLVMLIBC_INLINEFUNCTIONDECL_H
308