xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/misc/unused-using-decls.cpp (revision 04ca1b6bd938646874b6518067f03515d88c3b5b)
189a1d03eSRichard // RUN: %check_clang_tidy %s misc-unused-using-decls %t -- --fix-notes -- -fno-delayed-template-parsing -isystem %S/Inputs
289a1d03eSRichard 
389a1d03eSRichard // ----- Definitions -----
489a1d03eSRichard template <typename T> class vector {};
589a1d03eSRichard namespace n {
689a1d03eSRichard class A;
789a1d03eSRichard class B;
889a1d03eSRichard class C;
989a1d03eSRichard class D;
1089a1d03eSRichard class D { public: static int i; };
1189a1d03eSRichard template <typename T> class E {};
1289a1d03eSRichard template <typename T> class F {};
func()1389a1d03eSRichard class G { public: static void func() {} };
1489a1d03eSRichard class H { public: static int i; };
1589a1d03eSRichard class I {
1689a1d03eSRichard  public:
1789a1d03eSRichard   static int ii;
1889a1d03eSRichard };
1989a1d03eSRichard template <typename T> class J {};
2089a1d03eSRichard class G;
2189a1d03eSRichard class H;
2289a1d03eSRichard 
2389a1d03eSRichard template <typename T> class K {};
2489a1d03eSRichard template <template <typename> class S>
2589a1d03eSRichard class L {};
2689a1d03eSRichard 
2789a1d03eSRichard template <typename T> class M {};
2889a1d03eSRichard class N {};
2989a1d03eSRichard 
3089a1d03eSRichard template <int T> class P {};
3189a1d03eSRichard const int Constant = 0;
3289a1d03eSRichard 
3389a1d03eSRichard template <typename T> class Q {};
3489a1d03eSRichard 
3589a1d03eSRichard class Base {
3689a1d03eSRichard  public:
3789a1d03eSRichard   void f();
3889a1d03eSRichard };
3989a1d03eSRichard 
4089a1d03eSRichard D UsedInstance;
4189a1d03eSRichard D UnusedInstance;
4289a1d03eSRichard 
UsedFunc()4389a1d03eSRichard int UsedFunc() { return 1; }
UnusedFunc()4489a1d03eSRichard int UnusedFunc() { return 1; }
UsedTemplateFunc()4589a1d03eSRichard template <typename T> int UsedTemplateFunc() { return 1; }
UnusedTemplateFunc()4689a1d03eSRichard template <typename T> int UnusedTemplateFunc() { return 1; }
UsedInTemplateFunc()4789a1d03eSRichard template <typename T> int UsedInTemplateFunc() { return 1; }
4889a1d03eSRichard void OverloadFunc(int);
4989a1d03eSRichard void OverloadFunc(double);
FuncUsedByUsingDeclInMacro()5089a1d03eSRichard int FuncUsedByUsingDeclInMacro() { return 1; }
518003c1d6Sv1nh1shungry long double operator""_w(long double);
5289a1d03eSRichard 
5389a1d03eSRichard class ostream {
5489a1d03eSRichard public:
5589a1d03eSRichard   ostream &operator<<(ostream &(*PF)(ostream &));
5689a1d03eSRichard };
5789a1d03eSRichard extern ostream cout;
5889a1d03eSRichard ostream &endl(ostream &os);
5989a1d03eSRichard 
6089a1d03eSRichard enum Color1 { Green };
6189a1d03eSRichard 
6289a1d03eSRichard enum Color2 { Red };
6389a1d03eSRichard 
6489a1d03eSRichard enum Color3 { Yellow };
6589a1d03eSRichard 
6689a1d03eSRichard enum Color4 { Blue };
6789a1d03eSRichard 
6889a1d03eSRichard }  // namespace n
6989a1d03eSRichard 
7089a1d03eSRichard #include "unused-using-decls.h"
7189a1d03eSRichard namespace ns {
7289a1d03eSRichard template <typename T>
7389a1d03eSRichard class AA {
7489a1d03eSRichard   T t;
7589a1d03eSRichard };
7689a1d03eSRichard template <typename T>
ff()7789a1d03eSRichard T ff() { T t; return t; }
7889a1d03eSRichard } // namespace ns
7989a1d03eSRichard 
8089a1d03eSRichard // ----- Using declarations -----
8189a1d03eSRichard // eol-comments aren't removed (yet)
8289a1d03eSRichard using n::A; // A
8389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'A' is unused
8489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-2]]:10: note: remove the using
8589a1d03eSRichard // CHECK-FIXES: {{^}}// A
8689a1d03eSRichard using n::B;
8789a1d03eSRichard using n::C;
8889a1d03eSRichard using n::D;
8989a1d03eSRichard using n::E; // E
9089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'E' is unused
9189a1d03eSRichard // CHECK-FIXES: {{^}}// E
9289a1d03eSRichard using n::F;
9389a1d03eSRichard using n::G;
9489a1d03eSRichard using n::H;
9589a1d03eSRichard using n::I;
9689a1d03eSRichard int I::ii = 1;
9789a1d03eSRichard class Derived : public n::Base {
9889a1d03eSRichard  public:
9989a1d03eSRichard   using Base::f;
10089a1d03eSRichard };
10189a1d03eSRichard using n::UsedInstance;
10289a1d03eSRichard using n::UsedFunc;
10389a1d03eSRichard using n::UsedTemplateFunc;
10489a1d03eSRichard using n::UnusedInstance; // UnusedInstance
10589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'UnusedInstance' is unused
10689a1d03eSRichard // CHECK-FIXES: {{^}}// UnusedInstance
10789a1d03eSRichard using n::UnusedFunc; // UnusedFunc
10889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'UnusedFunc' is unused
10989a1d03eSRichard // CHECK-FIXES: {{^}}// UnusedFunc
1108003c1d6Sv1nh1shungry using n::operator""_w;
11189a1d03eSRichard using n::cout;
11289a1d03eSRichard using n::endl;
11389a1d03eSRichard 
11489a1d03eSRichard using n::UsedInTemplateFunc;
11589a1d03eSRichard using n::J;
Callee()11689a1d03eSRichard template <typename T> void Callee() {
11789a1d03eSRichard   J<T> j;
11889a1d03eSRichard   UsedInTemplateFunc<T>();
11989a1d03eSRichard }
12089a1d03eSRichard 
12189a1d03eSRichard using n::OverloadFunc; // OverloadFunc
12289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'OverloadFunc' is unused
12389a1d03eSRichard // CHECK-FIXES: {{^}}// OverloadFunc
12489a1d03eSRichard 
12589a1d03eSRichard #define DEFINE_INT(name)        \
12689a1d03eSRichard   namespace INT {               \
12789a1d03eSRichard   static const int _##name = 1; \
12889a1d03eSRichard   }                             \
12989a1d03eSRichard   using INT::_##name
13089a1d03eSRichard DEFINE_INT(test);
13189a1d03eSRichard #undef DEFIND_INT
13289a1d03eSRichard 
13389a1d03eSRichard #define USING_FUNC \
13489a1d03eSRichard   using n::FuncUsedByUsingDeclInMacro;
13589a1d03eSRichard USING_FUNC
13689a1d03eSRichard #undef USING_FUNC
13789a1d03eSRichard 
13889a1d03eSRichard namespace N1 {
13989a1d03eSRichard // n::G is used in namespace N2.
14089a1d03eSRichard // Currently, the check doesn't support multiple scopes. All the relevant
14189a1d03eSRichard // using-decls will be marked as used once we see an usage even the usage is in
14289a1d03eSRichard // other scope.
14389a1d03eSRichard using n::G;
14489a1d03eSRichard }
14589a1d03eSRichard 
14689a1d03eSRichard namespace N2 {
14789a1d03eSRichard using n::G;
14889a1d03eSRichard void f(G g);
14989a1d03eSRichard }
15089a1d03eSRichard 
IgnoreFunctionScope()15189a1d03eSRichard void IgnoreFunctionScope() {
15289a1d03eSRichard // Using-decls defined in function scope will be ignored.
15389a1d03eSRichard using n::H;
15489a1d03eSRichard }
15589a1d03eSRichard 
15689a1d03eSRichard using n::Color1;
15789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'Color1' is unused
15889a1d03eSRichard using n::Green;
15989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'Green' is unused
16089a1d03eSRichard using n::Color2;
16189a1d03eSRichard using n::Color3;
16289a1d03eSRichard using n::Blue;
16389a1d03eSRichard 
16489a1d03eSRichard using ns::AA;
16589a1d03eSRichard using ns::ff;
16689a1d03eSRichard 
16789a1d03eSRichard using n::K;
16889a1d03eSRichard 
16989a1d03eSRichard using n::N;
17089a1d03eSRichard 
17189a1d03eSRichard // FIXME: Currently non-type template arguments are not supported.
17289a1d03eSRichard using n::Constant;
17389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'Constant' is unused
17489a1d03eSRichard 
17589a1d03eSRichard using n::Q;
17689a1d03eSRichard 
17789a1d03eSRichard // ----- Usages -----
17889a1d03eSRichard void f(B b);
g()17989a1d03eSRichard void g() {
18089a1d03eSRichard   vector<C> data;
18189a1d03eSRichard   D::i = 1;
18289a1d03eSRichard   F<int> f;
18389a1d03eSRichard   void (*func)() = &G::func;
18489a1d03eSRichard   int *i = &H::i;
18589a1d03eSRichard   UsedInstance.i;
18689a1d03eSRichard   UsedFunc();
18789a1d03eSRichard   UsedTemplateFunc<int>();
1888003c1d6Sv1nh1shungry   1.5_w;
18989a1d03eSRichard   cout << endl;
19089a1d03eSRichard   Color2 color2;
19189a1d03eSRichard   int t1 = Color3::Yellow;
19289a1d03eSRichard   int t2 = Blue;
19389a1d03eSRichard 
19489a1d03eSRichard   MyClass a;
19589a1d03eSRichard   int t3 = 0;
19689a1d03eSRichard   a.func1<AA>(&t3);
19789a1d03eSRichard   a.func2<int, ff>(t3);
19889a1d03eSRichard 
19989a1d03eSRichard   n::L<K> l;
20089a1d03eSRichard }
20189a1d03eSRichard 
20289a1d03eSRichard template<class T>
h(n::M<T> * t)20389a1d03eSRichard void h(n::M<T>* t) {}
20489a1d03eSRichard // n::N is used the explicit template instantiation.
20589a1d03eSRichard template void h(n::M<N>* t);
20689a1d03eSRichard 
20789a1d03eSRichard // Test on Non-type template arguments.
20889a1d03eSRichard template <int T>
i(n::P<T> * t)20989a1d03eSRichard void i(n::P<T>* t) {}
21089a1d03eSRichard template void i(n::P<Constant>* t);
21189a1d03eSRichard 
21289a1d03eSRichard template <typename T, template <typename> class U> class Bar {};
21389a1d03eSRichard // We used to report Q unsued, because we only checked the first template
21489a1d03eSRichard // argument.
21589a1d03eSRichard Bar<int, Q> *bar;
216*04ca1b6bSCongcong Cai 
217*04ca1b6bSCongcong Cai namespace gh69714 {
218*04ca1b6bSCongcong Cai struct StructGH69714_1 {};
219*04ca1b6bSCongcong Cai struct StructGH69714_2 {};
220*04ca1b6bSCongcong Cai } // namespace gh69714
221*04ca1b6bSCongcong Cai using gh69714::StructGH69714_1;
222*04ca1b6bSCongcong Cai using gh69714::StructGH69714_2;
223*04ca1b6bSCongcong Cai struct StructGH69714_1 a;
224*04ca1b6bSCongcong Cai struct StructGH69714_2 *b;
225