1// RUN: %check_clang_tidy %s readability-convert-member-functions-to-static %t
2
3class DoNotMakeEmptyStatic {
4 void emptyMethod() {}
5 void empty_method_out_of_line();
6};
7
8void DoNotMakeEmptyStatic::empty_method_out_of_line() {}
9
10class A {
11 int field;
12 const int const_field;
13 static int static_field;
14
15 void no_use() {
16 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: method 'no_use' can be made static
17 // CHECK-FIXES: {{^}} static void no_use() {
18 int i = 1;
19 }
20
21 int read_field() {
22 return field;
23 }
24
25 void write_field() {
26 field = 1;
27 }
28
29 int call_non_const_member() { return read_field(); }
30
31 int call_static_member() {
32 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: method 'call_static_member' can be made static
33 // CHECK-FIXES: {{^}} static int call_static_member() {
34 already_static();
35 return 0;
36 }
37
38 int read_static() {
39 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: method 'read_static' can be made static
40 // CHECK-FIXES: {{^}} static int read_static() {
41 return static_field;
42 }
43 void write_static() {
44 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: method 'write_static' can be made static
45 // CHECK-FIXES: {{^}} static void write_static() {
46 static_field = 1;
47 }
48
49 void static_nested() {
50 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: method 'static_nested' can be made static
51 // CHECK-FIXES: {{^}} static void static_nested() {
52 struct Nested {
53 int Foo;
54 int getFoo() { return Foo; }
55 };
56 }
57
58 void write_nested() {
59 struct Nested {
60 int Foo;
61 int getFoo() { return Foo; }
62 };
63 // Ensure we still detect usages of `this` once we leave the nested class definition.
64 field = 1;
65 }
66
67 static int already_static() { return static_field; }
68
69 int already_const() const { return field; }
70
71 int already_const_convert_to_static() const {
72 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: method 'already_const_convert_to_static' can be made static
73 // CHECK-FIXES: {{^}} static int already_const_convert_to_static() {
74 return static_field;
75 }
76
77 static int out_of_line_already_static();
78
79 void out_of_line_call_static();
80 // CHECK-FIXES: {{^}} static void out_of_line_call_static();
81 int out_of_line_const_to_static() const;
82 // CHECK-FIXES: {{^}} static int out_of_line_const_to_static() ;
83};
84
85int A::out_of_line_already_static() { return 0; }
86
87void A::out_of_line_call_static() {
88 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: method 'out_of_line_call_static' can be made static
89 // CHECK-FIXES: {{^}}void A::out_of_line_call_static() {
90 already_static();
91}
92
93int A::out_of_line_const_to_static() const {
94 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: method 'out_of_line_const_to_static' can be made static
95 // CHECK-FIXES: {{^}}int A::out_of_line_const_to_static() {
96 return 0;
97}
98
99struct KeepVirtual {
100 virtual int f() { return 0; }
101 virtual int h() const { return 0; }
102};
103
104struct KeepVirtualDerived : public KeepVirtual {
105 int f() { return 0; }
106 int h() const override { return 0; }
107};
108
109// Don't add 'static' to special member functions and operators.
110struct KeepSpecial {
111 KeepSpecial() { int L = 0; }
112 ~KeepSpecial() { int L = 0; }
113 int operator+() { return 0; }
114 operator int() { return 0; }
115};
116
117void KeepLambdas() {
118 using FT = int (*)();
119 auto F = static_cast<FT>([]() { return 0; });
120 auto F2 = []() { return 0; };
121}
122
123template <class Base>
124struct KeepWithTemplateBase : public Base {
125 int i;
126 // We cannot make these methods static because they might need to override
127 // a function from Base.
128 int static_f() { return 0; }
129};
130
131template <class T>
132struct KeepTemplateClass {
133 int i;
134 // We cannot make these methods static because a specialization
135 // might use *this differently.
136 int static_f() { return 0; }
137};
138
139struct KeepTemplateMethod {
140 int i;
141 // We cannot make these methods static because a specialization
142 // might use *this differently.
143 template <class T>
144 static int static_f() { return 0; }
145};
146
147void instantiate() {
148 struct S {};
149 KeepWithTemplateBase<S> I1;
150 I1.static_f();
151
152 KeepTemplateClass<int> I2;
153 I2.static_f();
154
155 KeepTemplateMethod I3;
156 I3.static_f<int>();
157}
158
159struct Trailing {
160 auto g() const -> int {
161 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: method 'g' can be made static
162 // CHECK-FIXES: {{^}} static auto g() -> int {
163 return 0;
164 }
165
166 void vol() volatile {
167 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: method 'vol' can be made static
168 return;
169 }
170
171 void ref() const & {
172 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: method 'ref' can be made static
173 return;
174 }
175 void refref() const && {
176 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: method 'refref' can be made static
177 return;
178 }
179
180 void restr() __restrict {
181 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: method 'restr' can be made static
182 return;
183 }
184};
185
186struct UnevaluatedContext {
187 void f() { sizeof(this); }
188
189 void noex() noexcept(noexcept(this));
190};
191
192struct LambdaCapturesThis {
193 int Field;
194
195 int explicitCapture() {
196 return [this]() { return Field; }();
197 }
198
199 int implicitCapture() {
200 return [&]() { return Field; }();
201 }
202};
203
204struct NoFixitInMacro {
205#define CONST const
206 int no_use_macro_const() CONST {
207 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: method 'no_use_macro_const' can be made static
208 return 0;
209 }
210
211#define ADD_CONST(F) F const
212 int ADD_CONST(no_use_macro2()) {
213 return 0;
214 }
215
216#define FUN no_use_macro()
217 int i;
218 int FUN {
219 return i;
220 }
221
222#define T(FunctionName, Keyword) \
223 Keyword int FunctionName() { return 0; }
224#define EMPTY
225 T(A, EMPTY)
226 T(B, static)
227
228#define T2(FunctionName) \
229 int FunctionName() { return 0; }
230 T2(A2)
231
232#define VOLATILE volatile
233 void volatileMacro() VOLATILE {
234 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: method 'volatileMacro' can be made static
235 return;
236 }
237};
238

source code of clang-tools-extra/test/clang-tidy/checkers/readability/convert-member-functions-to-static.cpp