1*89a1d03eSRichard // RUN: %check_clang_tidy %s bugprone-forward-declaration-namespace %t 2*89a1d03eSRichard 3*89a1d03eSRichard namespace { 4*89a1d03eSRichard // This is a declaration in a wrong namespace. 5*89a1d03eSRichard class T_A; 6*89a1d03eSRichard // CHECK-NOTES: :[[@LINE-1]]:7: warning: declaration 'T_A' is never referenced, but a declaration with the same name found in another namespace 'na' [bugprone-forward-declaration-namespace] 7*89a1d03eSRichard // CHECK-NOTES: note: a declaration of 'T_A' is found here 8*89a1d03eSRichard // CHECK-NOTES: :[[@LINE-3]]:7: warning: no definition found for 'T_A', but a definition with the same name 'T_A' found in another namespace '(global)' [bugprone-forward-declaration-namespace] 9*89a1d03eSRichard // CHECK-NOTES: note: a definition of 'T_A' is found here 10*89a1d03eSRichard } 11*89a1d03eSRichard 12*89a1d03eSRichard namespace na { 13*89a1d03eSRichard // This is a declaration in a wrong namespace. 14*89a1d03eSRichard class T_A; 15*89a1d03eSRichard // CHECK-NOTES: :[[@LINE-1]]:7: warning: declaration 'T_A' is never referenced, but a declaration with the same name found in another namespace '(anonymous)' 16*89a1d03eSRichard // CHECK-NOTES: note: a declaration of 'T_A' is found here 17*89a1d03eSRichard // CHECK-NOTES: :[[@LINE-3]]:7: warning: no definition found for 'T_A', but a definition with the same name 'T_A' found in another namespace '(global)' 18*89a1d03eSRichard // CHECK-NOTES: note: a definition of 'T_A' is found here 19*89a1d03eSRichard } 20*89a1d03eSRichard 21*89a1d03eSRichard class T_A; 22*89a1d03eSRichard 23*89a1d03eSRichard class T_A { 24*89a1d03eSRichard int x; 25*89a1d03eSRichard }; 26*89a1d03eSRichard 27*89a1d03eSRichard class NESTED; 28*89a1d03eSRichard // CHECK-NOTES: :[[@LINE-1]]:7: warning: no definition found for 'NESTED', but a definition with the same name 'NESTED' found in another namespace '(anonymous namespace)::nq::(anonymous)' 29*89a1d03eSRichard // CHECK-NOTES: note: a definition of 'NESTED' is found here 30*89a1d03eSRichard 31*89a1d03eSRichard namespace { 32*89a1d03eSRichard namespace nq { 33*89a1d03eSRichard namespace { 34*89a1d03eSRichard class NESTED {}; 35*89a1d03eSRichard } 36*89a1d03eSRichard } 37*89a1d03eSRichard } 38*89a1d03eSRichard 39*89a1d03eSRichard namespace na { 40*89a1d03eSRichard class T_B; 41*89a1d03eSRichard // CHECK-NOTES: :[[@LINE-1]]:7: warning: declaration 'T_B' is never referenced, but a declaration with the same name found in another namespace 'nb' 42*89a1d03eSRichard // CHECK-NOTES: note: a declaration of 'T_B' is found here 43*89a1d03eSRichard // CHECK-NOTES: :[[@LINE-3]]:7: warning: no definition found for 'T_B', but a definition with the same name 'T_B' found in another namespace 'nb' 44*89a1d03eSRichard // CHECK-NOTES: note: a definition of 'T_B' is found here 45*89a1d03eSRichard } 46*89a1d03eSRichard 47*89a1d03eSRichard namespace nb { 48*89a1d03eSRichard class T_B; 49*89a1d03eSRichard } 50*89a1d03eSRichard 51*89a1d03eSRichard namespace nb { 52*89a1d03eSRichard class T_B { 53*89a1d03eSRichard int x; 54*89a1d03eSRichard }; 55*89a1d03eSRichard } 56*89a1d03eSRichard 57*89a1d03eSRichard namespace na { 58*89a1d03eSRichard class T_B; 59*89a1d03eSRichard // CHECK-NOTES: :[[@LINE-1]]:7: warning: declaration 'T_B' is never referenced, but a declaration with the same name found in another namespace 'nb' 60*89a1d03eSRichard // CHECK-NOTES: note: a declaration of 'T_B' is found here 61*89a1d03eSRichard // CHECK-NOTES: :[[@LINE-3]]:7: warning: no definition found for 'T_B', but a definition with the same name 'T_B' found in another namespace 'nb' 62*89a1d03eSRichard // CHECK-NOTES: note: a definition of 'T_B' is found here 63*89a1d03eSRichard } 64*89a1d03eSRichard 65*89a1d03eSRichard // A simple forward declaration. Although it is never used, but no declaration 66*89a1d03eSRichard // with the same name is found in other namespace. 67*89a1d03eSRichard class OUTSIDER; 68*89a1d03eSRichard 69*89a1d03eSRichard namespace na { 70*89a1d03eSRichard // This class is referenced declaration, we don't generate warning. 71*89a1d03eSRichard class OUTSIDER_1; 72*89a1d03eSRichard } 73*89a1d03eSRichard 74*89a1d03eSRichard void f(na::OUTSIDER_1); 75*89a1d03eSRichard 76*89a1d03eSRichard namespace nc { 77*89a1d03eSRichard // This class is referenced as friend in OOP. 78*89a1d03eSRichard class OUTSIDER_1; 79*89a1d03eSRichard 80*89a1d03eSRichard class OOP { 81*89a1d03eSRichard friend struct OUTSIDER_1; 82*89a1d03eSRichard }; 83*89a1d03eSRichard } 84*89a1d03eSRichard 85*89a1d03eSRichard namespace nd { 86*89a1d03eSRichard class OUTSIDER_1; 87*89a1d03eSRichard void f(OUTSIDER_1 *); 88*89a1d03eSRichard } 89*89a1d03eSRichard 90*89a1d03eSRichard namespace nb { 91*89a1d03eSRichard class OUTSIDER_1; 92*89a1d03eSRichard // CHECK-NOTES: :[[@LINE-1]]:7: warning: declaration 'OUTSIDER_1' is never referenced, but a declaration with the same name found in another namespace 'na' 93*89a1d03eSRichard // CHECK-NOTES: note: a declaration of 'OUTSIDER_1' is found here 94*89a1d03eSRichard } 95*89a1d03eSRichard 96*89a1d03eSRichard 97*89a1d03eSRichard namespace na { 98*89a1d03eSRichard template<typename T> 99*89a1d03eSRichard class T_C; 100*89a1d03eSRichard } 101*89a1d03eSRichard 102*89a1d03eSRichard namespace nb { 103*89a1d03eSRichard // FIXME: this is an error, but we don't consider template class declaration 104*89a1d03eSRichard // now. 105*89a1d03eSRichard template<typename T> 106*89a1d03eSRichard class T_C; 107*89a1d03eSRichard } 108*89a1d03eSRichard 109*89a1d03eSRichard namespace na { 110*89a1d03eSRichard template<typename T> 111*89a1d03eSRichard class T_C { 112*89a1d03eSRichard int x; 113*89a1d03eSRichard }; 114*89a1d03eSRichard } 115*89a1d03eSRichard 116*89a1d03eSRichard namespace na { 117*89a1d03eSRichard 118*89a1d03eSRichard template <typename T> 119*89a1d03eSRichard class T_TEMP { 120*89a1d03eSRichard template <typename _Tp1> 121*89a1d03eSRichard struct rebind { typedef T_TEMP<_Tp1> other; }; 122*89a1d03eSRichard }; 123*89a1d03eSRichard 124*89a1d03eSRichard // We ignore class template specialization. 125*89a1d03eSRichard template class T_TEMP<char>; 126*89a1d03eSRichard } 127*89a1d03eSRichard 128*89a1d03eSRichard namespace nb { 129*89a1d03eSRichard 130*89a1d03eSRichard template <typename T> 131*89a1d03eSRichard class T_TEMP_1 { 132*89a1d03eSRichard template <typename _Tp1> 133*89a1d03eSRichard struct rebind { typedef T_TEMP_1<_Tp1> other; }; 134*89a1d03eSRichard }; 135*89a1d03eSRichard 136*89a1d03eSRichard // We ignore class template specialization. 137*89a1d03eSRichard extern template class T_TEMP_1<char>; 138*89a1d03eSRichard } 139*89a1d03eSRichard 140*89a1d03eSRichard namespace nd { 141*89a1d03eSRichard class D; 142*89a1d03eSRichard // CHECK-NOTES: :[[@LINE-1]]:7: warning: declaration 'D' is never referenced, but a declaration with the same name found in another namespace 'nd::ne' 143*89a1d03eSRichard // CHECK-NOTES: note: a declaration of 'D' is found here 144*89a1d03eSRichard } 145*89a1d03eSRichard 146*89a1d03eSRichard namespace nd { 147*89a1d03eSRichard namespace ne { 148*89a1d03eSRichard class D; 149*89a1d03eSRichard } 150*89a1d03eSRichard } 151*89a1d03eSRichard 152*89a1d03eSRichard int f(nd::ne::D &d); 153*89a1d03eSRichard 154*89a1d03eSRichard 155*89a1d03eSRichard // This should be ignored by the check. 156*89a1d03eSRichard template <typename... Args> 157*89a1d03eSRichard class Observer { 158*89a1d03eSRichard class Impl; 159*89a1d03eSRichard }; 160*89a1d03eSRichard 161*89a1d03eSRichard template <typename... Args> 162*89a1d03eSRichard class Observer<Args...>::Impl { 163*89a1d03eSRichard }; 164