xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/misc/unused-using-decls.cpp (revision 04ca1b6bd938646874b6518067f03515d88c3b5b)
1 // RUN: %check_clang_tidy %s misc-unused-using-decls %t -- --fix-notes -- -fno-delayed-template-parsing -isystem %S/Inputs
2 
3 // ----- Definitions -----
4 template <typename T> class vector {};
5 namespace n {
6 class A;
7 class B;
8 class C;
9 class D;
10 class D { public: static int i; };
11 template <typename T> class E {};
12 template <typename T> class F {};
func()13 class G { public: static void func() {} };
14 class H { public: static int i; };
15 class I {
16  public:
17   static int ii;
18 };
19 template <typename T> class J {};
20 class G;
21 class H;
22 
23 template <typename T> class K {};
24 template <template <typename> class S>
25 class L {};
26 
27 template <typename T> class M {};
28 class N {};
29 
30 template <int T> class P {};
31 const int Constant = 0;
32 
33 template <typename T> class Q {};
34 
35 class Base {
36  public:
37   void f();
38 };
39 
40 D UsedInstance;
41 D UnusedInstance;
42 
UsedFunc()43 int UsedFunc() { return 1; }
UnusedFunc()44 int UnusedFunc() { return 1; }
UsedTemplateFunc()45 template <typename T> int UsedTemplateFunc() { return 1; }
UnusedTemplateFunc()46 template <typename T> int UnusedTemplateFunc() { return 1; }
UsedInTemplateFunc()47 template <typename T> int UsedInTemplateFunc() { return 1; }
48 void OverloadFunc(int);
49 void OverloadFunc(double);
FuncUsedByUsingDeclInMacro()50 int FuncUsedByUsingDeclInMacro() { return 1; }
51 long double operator""_w(long double);
52 
53 class ostream {
54 public:
55   ostream &operator<<(ostream &(*PF)(ostream &));
56 };
57 extern ostream cout;
58 ostream &endl(ostream &os);
59 
60 enum Color1 { Green };
61 
62 enum Color2 { Red };
63 
64 enum Color3 { Yellow };
65 
66 enum Color4 { Blue };
67 
68 }  // namespace n
69 
70 #include "unused-using-decls.h"
71 namespace ns {
72 template <typename T>
73 class AA {
74   T t;
75 };
76 template <typename T>
ff()77 T ff() { T t; return t; }
78 } // namespace ns
79 
80 // ----- Using declarations -----
81 // eol-comments aren't removed (yet)
82 using n::A; // A
83 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'A' is unused
84 // CHECK-MESSAGES: :[[@LINE-2]]:10: note: remove the using
85 // CHECK-FIXES: {{^}}// A
86 using n::B;
87 using n::C;
88 using n::D;
89 using n::E; // E
90 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'E' is unused
91 // CHECK-FIXES: {{^}}// E
92 using n::F;
93 using n::G;
94 using n::H;
95 using n::I;
96 int I::ii = 1;
97 class Derived : public n::Base {
98  public:
99   using Base::f;
100 };
101 using n::UsedInstance;
102 using n::UsedFunc;
103 using n::UsedTemplateFunc;
104 using n::UnusedInstance; // UnusedInstance
105 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'UnusedInstance' is unused
106 // CHECK-FIXES: {{^}}// UnusedInstance
107 using n::UnusedFunc; // UnusedFunc
108 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'UnusedFunc' is unused
109 // CHECK-FIXES: {{^}}// UnusedFunc
110 using n::operator""_w;
111 using n::cout;
112 using n::endl;
113 
114 using n::UsedInTemplateFunc;
115 using n::J;
Callee()116 template <typename T> void Callee() {
117   J<T> j;
118   UsedInTemplateFunc<T>();
119 }
120 
121 using n::OverloadFunc; // OverloadFunc
122 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'OverloadFunc' is unused
123 // CHECK-FIXES: {{^}}// OverloadFunc
124 
125 #define DEFINE_INT(name)        \
126   namespace INT {               \
127   static const int _##name = 1; \
128   }                             \
129   using INT::_##name
130 DEFINE_INT(test);
131 #undef DEFIND_INT
132 
133 #define USING_FUNC \
134   using n::FuncUsedByUsingDeclInMacro;
135 USING_FUNC
136 #undef USING_FUNC
137 
138 namespace N1 {
139 // n::G is used in namespace N2.
140 // Currently, the check doesn't support multiple scopes. All the relevant
141 // using-decls will be marked as used once we see an usage even the usage is in
142 // other scope.
143 using n::G;
144 }
145 
146 namespace N2 {
147 using n::G;
148 void f(G g);
149 }
150 
IgnoreFunctionScope()151 void IgnoreFunctionScope() {
152 // Using-decls defined in function scope will be ignored.
153 using n::H;
154 }
155 
156 using n::Color1;
157 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'Color1' is unused
158 using n::Green;
159 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'Green' is unused
160 using n::Color2;
161 using n::Color3;
162 using n::Blue;
163 
164 using ns::AA;
165 using ns::ff;
166 
167 using n::K;
168 
169 using n::N;
170 
171 // FIXME: Currently non-type template arguments are not supported.
172 using n::Constant;
173 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'Constant' is unused
174 
175 using n::Q;
176 
177 // ----- Usages -----
178 void f(B b);
g()179 void g() {
180   vector<C> data;
181   D::i = 1;
182   F<int> f;
183   void (*func)() = &G::func;
184   int *i = &H::i;
185   UsedInstance.i;
186   UsedFunc();
187   UsedTemplateFunc<int>();
188   1.5_w;
189   cout << endl;
190   Color2 color2;
191   int t1 = Color3::Yellow;
192   int t2 = Blue;
193 
194   MyClass a;
195   int t3 = 0;
196   a.func1<AA>(&t3);
197   a.func2<int, ff>(t3);
198 
199   n::L<K> l;
200 }
201 
202 template<class T>
h(n::M<T> * t)203 void h(n::M<T>* t) {}
204 // n::N is used the explicit template instantiation.
205 template void h(n::M<N>* t);
206 
207 // Test on Non-type template arguments.
208 template <int T>
i(n::P<T> * t)209 void i(n::P<T>* t) {}
210 template void i(n::P<Constant>* t);
211 
212 template <typename T, template <typename> class U> class Bar {};
213 // We used to report Q unsued, because we only checked the first template
214 // argument.
215 Bar<int, Q> *bar;
216 
217 namespace gh69714 {
218 struct StructGH69714_1 {};
219 struct StructGH69714_2 {};
220 } // namespace gh69714
221 using gh69714::StructGH69714_1;
222 using gh69714::StructGH69714_2;
223 struct StructGH69714_1 a;
224 struct StructGH69714_2 *b;
225