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