1 #pragma once 2 3 /** 4 * This file provides portable macros for marking declarations 5 * as deprecated. You should generally use C10_DEPRECATED, 6 * except when marking 'using' declarations as deprecated, 7 * in which case you should use C10_DEFINE_DEPRECATED_USING 8 * (due to portability concerns). 9 */ 10 11 // Sample usage: 12 // 13 // C10_DEPRECATED void bad_func(); 14 // struct C10_DEPRECATED BadStruct { 15 // ... 16 // }; 17 18 // NB: __cplusplus doesn't work for MSVC, so for now MSVC always uses 19 // the "__declspec(deprecated)" implementation and not the C++14 20 // "[[deprecated]]" attribute. We tried enabling "[[deprecated]]" for C++14 on 21 // MSVC, but ran into issues with some older MSVC versions. 22 #if (defined(__cplusplus) && __cplusplus >= 201402L) 23 #define C10_DEPRECATED [[deprecated]] 24 #define C10_DEPRECATED_MESSAGE(message) [[deprecated(message)]] 25 #elif defined(__GNUC__) 26 #define C10_DEPRECATED __attribute__((deprecated)) 27 // TODO Is there some way to implement this? 28 #define C10_DEPRECATED_MESSAGE(message) __attribute__((deprecated)) 29 30 #elif defined(_MSC_VER) 31 #define C10_DEPRECATED __declspec(deprecated) 32 #define C10_DEPRECATED_MESSAGE(message) __declspec(deprecated(message)) 33 #else 34 #warning "You need to implement C10_DEPRECATED for this compiler" 35 #define C10_DEPRECATED 36 #endif 37 38 // Sample usage: 39 // 40 // C10_DEFINE_DEPRECATED_USING(BadType, int) 41 // 42 // which is the portable version of 43 // 44 // using BadType [[deprecated]] = int; 45 46 // technically [[deprecated]] syntax is from c++14 standard, but it works in 47 // many compilers. 48 #if defined(__has_cpp_attribute) 49 #if __has_cpp_attribute(deprecated) && !defined(__CUDACC__) 50 #define C10_DEFINE_DEPRECATED_USING(TypeName, TypeThingy) \ 51 using TypeName [[deprecated]] = TypeThingy; 52 #endif 53 #endif 54 55 #if defined(_MSC_VER) 56 #if defined(__CUDACC__) 57 // neither [[deprecated]] nor __declspec(deprecated) work on nvcc on Windows; 58 // you get the error: 59 // 60 // error: attribute does not apply to any entity 61 // 62 // So we just turn the macro off in this case. 63 #if defined(C10_DEFINE_DEPRECATED_USING) 64 #undef C10_DEFINE_DEPRECATED_USING 65 #endif 66 #define C10_DEFINE_DEPRECATED_USING(TypeName, TypeThingy) \ 67 using TypeName = TypeThingy; 68 #else 69 // [[deprecated]] does work in windows without nvcc, though msc doesn't support 70 // `__has_cpp_attribute` when c++14 is supported, otherwise 71 // __declspec(deprecated) is used as the alternative. 72 #ifndef C10_DEFINE_DEPRECATED_USING 73 #if defined(_MSVC_LANG) && _MSVC_LANG >= 201402L 74 #define C10_DEFINE_DEPRECATED_USING(TypeName, TypeThingy) \ 75 using TypeName [[deprecated]] = TypeThingy; 76 #else 77 #define C10_DEFINE_DEPRECATED_USING(TypeName, TypeThingy) \ 78 using TypeName = __declspec(deprecated) TypeThingy; 79 #endif 80 #endif 81 #endif 82 #endif 83 84 #if !defined(C10_DEFINE_DEPRECATED_USING) && defined(__GNUC__) 85 // nvcc has a bug where it doesn't understand __attribute__((deprecated)) 86 // declarations even when the host compiler supports it. We'll only use this gcc 87 // attribute when not cuda, and when using a GCC compiler that doesn't support 88 // the c++14 syntax we checked for above (available in __GNUC__ >= 5) 89 #if !defined(__CUDACC__) 90 #define C10_DEFINE_DEPRECATED_USING(TypeName, TypeThingy) \ 91 using TypeName __attribute__((deprecated)) = TypeThingy; 92 #else 93 // using cuda + gcc < 5, neither deprecated syntax is available so turning off. 94 #define C10_DEFINE_DEPRECATED_USING(TypeName, TypeThingy) \ 95 using TypeName = TypeThingy; 96 #endif 97 #endif 98 99 #if !defined(C10_DEFINE_DEPRECATED_USING) 100 #warning "You need to implement C10_DEFINE_DEPRECATED_USING for this compiler" 101 #define C10_DEFINE_DEPRECATED_USING 102 #endif 103