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