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()1389a1d03eSRichardclass 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()4389a1d03eSRichardint UsedFunc() { return 1; } UnusedFunc()4489a1d03eSRichardint UnusedFunc() { return 1; } UsedTemplateFunc()4589a1d03eSRichardtemplate <typename T> int UsedTemplateFunc() { return 1; } UnusedTemplateFunc()4689a1d03eSRichardtemplate <typename T> int UnusedTemplateFunc() { return 1; } UsedInTemplateFunc()4789a1d03eSRichardtemplate <typename T> int UsedInTemplateFunc() { return 1; } 4889a1d03eSRichard void OverloadFunc(int); 4989a1d03eSRichard void OverloadFunc(double); FuncUsedByUsingDeclInMacro()5089a1d03eSRichardint 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()7789a1d03eSRichardT 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()11689a1d03eSRichardtemplate <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()15189a1d03eSRichardvoid 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()17989a1d03eSRichardvoid 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)20389a1d03eSRichardvoid 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)20989a1d03eSRichardvoid 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