189a1d03eSRichard // RUN: %check_clang_tidy %s misc-definitions-in-headers %t -- --fix-notes 289a1d03eSRichard 389a1d03eSRichard int f() { 489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f' defined in a header file; function definitions in header files can lead to ODR violations [misc-definitions-in-headers] 5*50320ec9SJulian Schmidt // CHECK-MESSAGES: :[[@LINE-2]]:5: note: mark the definition as 'inline' 689a1d03eSRichard // CHECK-FIXES: inline int f() { 789a1d03eSRichard return 1; 889a1d03eSRichard } 989a1d03eSRichard 1089a1d03eSRichard class CA { 1189a1d03eSRichard void f1() {} // OK: inline class member function definition. 1289a1d03eSRichard void f2(); 1389a1d03eSRichard template<typename T> 1489a1d03eSRichard T f3() { 1589a1d03eSRichard T a = 1; 1689a1d03eSRichard return a; 1789a1d03eSRichard } 1889a1d03eSRichard template<typename T> 1989a1d03eSRichard struct CAA { 2089a1d03eSRichard struct CAB { 2189a1d03eSRichard void f4(); 2289a1d03eSRichard }; 2389a1d03eSRichard }; 2489a1d03eSRichard }; 2589a1d03eSRichard 2689a1d03eSRichard void CA::f2() { } 2789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: function 'f2' defined in a header file; 2889a1d03eSRichard // CHECK-FIXES: inline void CA::f2() { 2989a1d03eSRichard 3089a1d03eSRichard template <> 3189a1d03eSRichard int CA::f3() { 3289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: full function template specialization 'f3<int>' defined in a header file; 3389a1d03eSRichard // CHECK-FIXES: inline int CA::f3() { 3489a1d03eSRichard int a = 1; 3589a1d03eSRichard return a; 3689a1d03eSRichard } 3789a1d03eSRichard 3889a1d03eSRichard template <typename T> 3989a1d03eSRichard void CA::CAA<T>::CAB::f4() { 4089a1d03eSRichard // OK: member function definition of a nested template class in a class. 4189a1d03eSRichard } 4289a1d03eSRichard 4389a1d03eSRichard template <typename T> 4489a1d03eSRichard struct CB { 4589a1d03eSRichard void f1(); 4689a1d03eSRichard struct CCA { 4789a1d03eSRichard void f2(T a); 4889a1d03eSRichard }; 4989a1d03eSRichard struct CCB; // OK: forward declaration. 5089a1d03eSRichard static int a; // OK: class static data member declaration. 5189a1d03eSRichard }; 5289a1d03eSRichard 5389a1d03eSRichard template <typename T> 5489a1d03eSRichard void CB<T>::f1() { // OK: Member function definition of a class template. 5589a1d03eSRichard } 5689a1d03eSRichard 5789a1d03eSRichard template <typename T> 5889a1d03eSRichard void CB<T>::CCA::f2(T a) { 5989a1d03eSRichard // OK: member function definition of a nested class in a class template. 6089a1d03eSRichard } 6189a1d03eSRichard 6289a1d03eSRichard template <typename T> 6389a1d03eSRichard struct CB<T>::CCB { 6489a1d03eSRichard void f3(); 6589a1d03eSRichard }; 6689a1d03eSRichard 6789a1d03eSRichard template <typename T> 6889a1d03eSRichard void CB<T>::CCB::f3() { 6989a1d03eSRichard // OK: member function definition of a nested class in a class template. 7089a1d03eSRichard } 7189a1d03eSRichard 7289a1d03eSRichard template <typename T> 7389a1d03eSRichard int CB<T>::a = 2; // OK: static data member definition of a class template. 7489a1d03eSRichard 7589a1d03eSRichard template class CB<int>; // OK: explicitly instantiated static data member of a class template. 7689a1d03eSRichard inline int callCB() { 7789a1d03eSRichard CB<double> cb; // OK: implicitly instantiated static data member of a class template. 7889a1d03eSRichard return cb.a; 7989a1d03eSRichard } 8089a1d03eSRichard 8189a1d03eSRichard template <typename T> 8289a1d03eSRichard T tf() { // OK: template function definition. 8389a1d03eSRichard T a; 8489a1d03eSRichard return a; 8589a1d03eSRichard } 8689a1d03eSRichard 8789a1d03eSRichard 8889a1d03eSRichard namespace NA { 8989a1d03eSRichard int f() { return 1; } 9089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: function 'f' defined in a header file; 9189a1d03eSRichard // CHECK-FIXES: inline int f() { return 1; } 9289a1d03eSRichard } 9389a1d03eSRichard 9489a1d03eSRichard template <typename T> 9589a1d03eSRichard T f3() { 9689a1d03eSRichard T a = 1; 9789a1d03eSRichard return a; 9889a1d03eSRichard } 9989a1d03eSRichard 10089a1d03eSRichard template <> 10189a1d03eSRichard int f3() { 10289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: full function template specialization 'f3<int>' defined in a header file; 10389a1d03eSRichard // CHECK-FIXES: inline int f3() { 10489a1d03eSRichard int a = 1; 10589a1d03eSRichard return a; 10689a1d03eSRichard } 10789a1d03eSRichard 10889a1d03eSRichard int f5(); // OK: function declaration. 10989a1d03eSRichard inline int f6() { return 1; } // OK: inline function definition. 11089a1d03eSRichard namespace { 1112469bd98SCarlos Galvez int f7() { return 1; } // OK: each TU defines the function in a unique namespace. 11289a1d03eSRichard } 11389a1d03eSRichard 11489a1d03eSRichard int f8() = delete; // OK: the function being marked delete is not callable. 11589a1d03eSRichard 11689a1d03eSRichard template <typename T> 11789a1d03eSRichard int f9(T t) { return 1; } 11889a1d03eSRichard 11989a1d03eSRichard inline void callF9() { f9(1); } // OK: implicitly instantiated function. 12089a1d03eSRichard template int f9(double); // OK: explicitly instantiated function. 12189a1d03eSRichard 12289a1d03eSRichard int a = 1; 12389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: variable 'a' defined in a header file; variable definitions in header files can lead to ODR violations [misc-definitions-in-headers] 12489a1d03eSRichard CA a1; 12589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: variable 'a1' defined in a header file; 12689a1d03eSRichard 12789a1d03eSRichard namespace NB { 12889a1d03eSRichard int b = 1; 12989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: variable 'b' defined in a header file; 13089a1d03eSRichard const int c = 1; // OK: internal linkage variable definition. 13189a1d03eSRichard } 13289a1d03eSRichard 13389a1d03eSRichard class CC { 13489a1d03eSRichard static int d; // OK: class static data member declaration. 13589a1d03eSRichard }; 13689a1d03eSRichard 13789a1d03eSRichard int CC::d = 1; 13889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: variable 'd' defined in a header file; 13989a1d03eSRichard 14089a1d03eSRichard const char* ca = "foo"; 14189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: variable 'ca' defined in a header file; 14289a1d03eSRichard 14389a1d03eSRichard namespace { 1442469bd98SCarlos Galvez int e = 2; // OK: each TU defines the variable in a unique namespace. 14589a1d03eSRichard } 14689a1d03eSRichard 14789a1d03eSRichard const char* const g = "foo"; // OK: internal linkage variable definition. 14889a1d03eSRichard static int h = 1; // OK: internal linkage variable definition. 14989a1d03eSRichard const int i = 1; // OK: internal linkage variable definition. 15089a1d03eSRichard extern int j; // OK: internal linkage variable definition. 15189a1d03eSRichard 15289a1d03eSRichard template <typename T, typename U> 15389a1d03eSRichard struct CD { 15489a1d03eSRichard int f(); 15589a1d03eSRichard }; 15689a1d03eSRichard 15789a1d03eSRichard template <typename T> 15889a1d03eSRichard struct CD<T, int> { 15989a1d03eSRichard int f(); 16089a1d03eSRichard }; 16189a1d03eSRichard 16289a1d03eSRichard template <> 16389a1d03eSRichard struct CD<int, int> { 16489a1d03eSRichard int f(); 16589a1d03eSRichard }; 16689a1d03eSRichard 16789a1d03eSRichard int CD<int, int>::f() { 16889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: function 'f' defined in a header file; 16989a1d03eSRichard // CHECK-FIXES: inline int CD<int, int>::f() { 17089a1d03eSRichard return 0; 17189a1d03eSRichard } 17289a1d03eSRichard 17389a1d03eSRichard template <typename T> 17489a1d03eSRichard int CD<T, int>::f() { // OK: partial template specialization. 17589a1d03eSRichard return 0; 17689a1d03eSRichard } 17789a1d03eSRichard 17889a1d03eSRichard constexpr int k = 1; // OK: constexpr variable has internal linkage. 17989a1d03eSRichard 18089a1d03eSRichard constexpr int f10() { return 0; } // OK: constexpr function definition. 18189a1d03eSRichard 18289a1d03eSRichard const int f11() { return 0; } 18389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: function 'f11' defined in a header file; 18489a1d03eSRichard // CHECK-FIXES: inline const int f11() { return 0; } 18589a1d03eSRichard 18689a1d03eSRichard template <typename T> 18789a1d03eSRichard const T f12(); 18889a1d03eSRichard 18989a1d03eSRichard template <> 19089a1d03eSRichard const int f12() { return 0; } 19189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: full function template specialization 'f12<int>' defined in a header file; 19289a1d03eSRichard // CHECK-FIXES: inline const int f12() { return 0; } 19389a1d03eSRichard 19489a1d03eSRichard template <typename T1, typename T2> 19589a1d03eSRichard constexpr bool f13 = false; 19689a1d03eSRichard 19789a1d03eSRichard template <typename T> 19889a1d03eSRichard constexpr bool f13<T, int> = true; // OK: template partial specialization 19989a1d03eSRichard 20089a1d03eSRichard template <> 20189a1d03eSRichard constexpr bool f13<void, int> = false; 20289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: variable 'f13<void, int>' defined in a header file; 20389a1d03eSRichard 20489a1d03eSRichard int main() {} 20589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'main' defined in a header file; 20689a1d03eSRichard // CHECK-FIXES: {{^}}int main() { 207