// RUN: %check_clang_tidy %s llvmlibc-inline-function-decl %t #ifndef LLVM_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_LLVMLIBC_INLINEFUNCTIONDECL_H #define LLVM_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_LLVMLIBC_INLINEFUNCTIONDECL_H #define LIBC_INLINE inline namespace __llvm_libc { LIBC_INLINE int addi(int a, int b) { return a + b; } LIBC_INLINE constexpr long addl(long a, long b) { return a + b; } constexpr long long addll(long long a, long long b) { // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: 'addll' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] // CHECK-FIXES: LIBC_INLINE constexpr long long addll(long long a, long long b) { return a + b; } inline unsigned long addul(unsigned long a, unsigned long b) { // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: 'addul' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] // CHECK-FIXES: LIBC_INLINE inline unsigned long addul(unsigned long a, unsigned long b) { return a + b; } class MyClass { int A; public: MyClass() : A(123) {} // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'MyClass' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] // CHECK-FIXES: LIBC_INLINE MyClass() : A(123) {} LIBC_INLINE MyClass(int V) : A(V) {} constexpr operator int() const { return A; } // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'operator int' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] // CHECK-FIXES: LIBC_INLINE constexpr operator int() const { return A; } LIBC_INLINE bool operator==(const MyClass &RHS) { return RHS.A == A; } static int getVal(const MyClass &V) { // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'getVal' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] // CHECK-FIXES: LIBC_INLINE static int getVal(const MyClass &V) { return V.A; } LIBC_INLINE static void setVal(MyClass &V, int A) { V.A = A; } constexpr static int addInt(MyClass &V, int A) { // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'addInt' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] // CHECK-FIXES: LIBC_INLINE constexpr static int addInt(MyClass &V, int A) { return V.A += A; } static LIBC_INLINE int mulInt(MyClass &V, int A) { // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'mulInt' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] return V.A *= A; } }; LIBC_INLINE void lambda() { // CHECK-MESSAGES-NOT: :[[@LINE+4]]:3: warning: '__invoke' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] // CHECK-MESSAGES-NOT: :[[@LINE+3]]:3: warning: 'operator void (*)()' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] // CHECK-MESSAGES-NOT: :[[@LINE+2]]:3: warning: '~(lambda at [[FILENAME:.+]])' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] // CHECK-MESSAGES-NOT: :[[@LINE+1]]:6: warning: 'operator()' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] [](){}; } namespace issue_62746 { void goodSimpleFunction(); void badSimpleFunction(); void badSimpleFunctionWrongLocation(); LIBC_INLINE void goodSimpleFunction() {} inline void badSimpleFunction() {} // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: 'badSimpleFunction' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] // CHECK-FIXES: LIBC_INLINE inline void badSimpleFunction() {} void LIBC_INLINE badSimpleFunctionWrongLocation() {} // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: 'badSimpleFunctionWrongLocation' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] template void goodTemplateFunction(); template void badTemplateFunction(); template void badTemplateFunctionWrongLocation(); template LIBC_INLINE void goodTemplateFunction() {} template inline void badTemplateFunction() {} // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'badTemplateFunction' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] // CHECK-FIXES: template LIBC_INLINE inline void badTemplateFunction() {} template void LIBC_INLINE badTemplateFunctionWrongLocation() {} // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'badTemplateFunctionWrongLocation' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] template void goodVariadicFunction(); template void badVariadicFunction(); template void badVariadicFunctionWrongLocation(); template LIBC_INLINE void goodVariadicFunction() {} template inline void badVariadicFunction() {} // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: 'badVariadicFunction' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] // CHECK-FIXES: template LIBC_INLINE inline void badVariadicFunction() {} template void LIBC_INLINE badVariadicFunctionWrongLocation() {} // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: 'badVariadicFunctionWrongLocation' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] // CHECK-FIXES: template LIBC_INLINE void LIBC_INLINE badVariadicFunctionWrongLocation() {} struct NoTemplate { void goodNoTemplate(); void badNoTemplate(); void badNoTemplateWrongLocation(); template void goodNestedTemplate(); template void badNestedTemplate(); template void badNestedTemplateWrongLocation(); template void goodVariadicTemplate(); template void badVariadicTemplate(); template void badVariadicTemplateWrongLocation(); }; LIBC_INLINE void NoTemplate::goodNoTemplate() {} inline void NoTemplate::badNoTemplate() {} // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: 'badNoTemplate' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] // CHECK-FIXES: LIBC_INLINE inline void NoTemplate::badNoTemplate() {} void LIBC_INLINE NoTemplate::badNoTemplateWrongLocation() {} // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: 'badNoTemplateWrongLocation' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] // CHECK-FIXES: LIBC_INLINE void LIBC_INLINE NoTemplate::badNoTemplateWrongLocation() {} template LIBC_INLINE void NoTemplate::goodNestedTemplate() {} template inline void NoTemplate::badNestedTemplate() {} // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'badNestedTemplate' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] // CHECK-FIXES: template LIBC_INLINE inline void NoTemplate::badNestedTemplate() {} template void LIBC_INLINE NoTemplate::badNestedTemplateWrongLocation() {} // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'badNestedTemplateWrongLocation' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] // CHECK-FIXES: template LIBC_INLINE void LIBC_INLINE NoTemplate::badNestedTemplateWrongLocation() {} template LIBC_INLINE void NoTemplate::goodVariadicTemplate() {} template void inline NoTemplate::badVariadicTemplate() {} // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: 'badVariadicTemplate' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] // CHECK-FIXES: template LIBC_INLINE void inline NoTemplate::badVariadicTemplate() {} template void LIBC_INLINE NoTemplate::badVariadicTemplateWrongLocation() {} // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: 'badVariadicTemplateWrongLocation' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] template struct SimpleTemplate { void goodSimpleTemplate(); void badSimpleTemplate(); void badSimpleTemplateWrongLocation(); template void goodNestedTemplate(); template void badNestedTemplate(); template void badNestedTemplateWrongLocation(); template void goodNestedVariadicTemplate(); template void badNestedVariadicTemplate(); template void badNestedVariadicTemplateWrongLocation(); }; template LIBC_INLINE void SimpleTemplate::goodSimpleTemplate() {} template inline void SimpleTemplate::badSimpleTemplate() {} // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'badSimpleTemplate' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] // CHECK-FIXES: template LIBC_INLINE inline void SimpleTemplate::badSimpleTemplate() {} template void LIBC_INLINE SimpleTemplate::badSimpleTemplateWrongLocation() {} // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'badSimpleTemplateWrongLocation' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] template template LIBC_INLINE void SimpleTemplate::goodNestedTemplate() {} template template inline void SimpleTemplate::badNestedTemplate() {} // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: 'badNestedTemplate' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] // CHECK-FIXES: template template LIBC_INLINE inline void SimpleTemplate::badNestedTemplate() {} template template void LIBC_INLINE SimpleTemplate::badNestedTemplateWrongLocation() {} // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: 'badNestedTemplateWrongLocation' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] template template LIBC_INLINE void SimpleTemplate::goodNestedVariadicTemplate() {} template template inline void SimpleTemplate::badNestedVariadicTemplate() {} // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: 'badNestedVariadicTemplate' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] // CHECK-FIXES: template template LIBC_INLINE inline void SimpleTemplate::badNestedVariadicTemplate() {} template template void LIBC_INLINE SimpleTemplate::badNestedVariadicTemplateWrongLocation() {} // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: 'badNestedVariadicTemplateWrongLocation' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] template struct VariadicTemplate { void goodVariadicTemplate(); void badVariadicTemplate(); void badVariadicTemplateWrongLocation(); template void goodNestedTemplate(); template void badNestedTemplate(); template void badNestedTemplateWrongLocation(); template void goodNestedVariadicTemplate(); template void badNestedVariadicTemplate(); template void badNestedVariadicTemplateWrongLocation(); }; template LIBC_INLINE void VariadicTemplate::goodVariadicTemplate() {} template inline void VariadicTemplate::badVariadicTemplate() {} // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: 'badVariadicTemplate' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] // CHECK-FIXES: template LIBC_INLINE inline void VariadicTemplate::badVariadicTemplate() {} template void LIBC_INLINE VariadicTemplate::badVariadicTemplateWrongLocation() {} // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: 'badVariadicTemplateWrongLocation' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] template template LIBC_INLINE void VariadicTemplate::goodNestedTemplate() {} template template inline void VariadicTemplate::badNestedTemplate() {} // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: 'badNestedTemplate' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] // CHECK-FIXES: template template LIBC_INLINE inline void VariadicTemplate::badNestedTemplate() {} template template void LIBC_INLINE VariadicTemplate::badNestedTemplateWrongLocation() {} // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: 'badNestedTemplateWrongLocation' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] template template LIBC_INLINE void VariadicTemplate::goodNestedVariadicTemplate() {} template template inline void VariadicTemplate::badNestedVariadicTemplate() {} // CHECK-MESSAGES: :[[@LINE-1]]:53: warning: 'badNestedVariadicTemplate' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] // CHECK-FIXES: template template LIBC_INLINE inline void VariadicTemplate::badNestedVariadicTemplate() {} template template void LIBC_INLINE VariadicTemplate::badNestedVariadicTemplateWrongLocation() {} // CHECK-MESSAGES: :[[@LINE-1]]:53: warning: 'badNestedVariadicTemplateWrongLocation' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] template void goodWeirdFormatting(); template void badWeirdFormatting(); template LIBC_INLINE void goodWeirdFormatting() {} template void LIBC_INLINE badWeirdFormatting() {} // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: 'badWeirdFormatting' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] template struct HasMemberAndTemplate { char Data[NumberOfBits]; void explicitFunction() {} // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'explicitFunction' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] // CHECK-FIXES: LIBC_INLINE void explicitFunction() {} }; static auto instanceOfStruct = HasMemberAndTemplate<16>(); struct HasMemberAndExplicitDefault { int TrivialMember; HasMemberAndExplicitDefault() = default; // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'HasMemberAndExplicitDefault' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration [llvmlibc-inline-function-decl] // CHECK-FIXES: LIBC_INLINE HasMemberAndExplicitDefault() = default; ~HasMemberAndExplicitDefault() = delete; }; } // namespace issue_62746 } // namespace __llvm_libc #endif // LLVM_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_CHECKERS_LLVMLIBC_INLINEFUNCTIONDECL_H