1 /*
2  *  Copyright 2008-2013 NVIDIA Corporation
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  */
16 
17 /*! \file compiler.h
18  *  \brief Compiler-specific configuration
19  */
20 
21 #pragma once
22 
23 // enumerate host compilers we know about
24 #define THRUST_HOST_COMPILER_UNKNOWN 0
25 #define THRUST_HOST_COMPILER_MSVC    1
26 #define THRUST_HOST_COMPILER_GCC     2
27 #define THRUST_HOST_COMPILER_CLANG   3
28 
29 // enumerate device compilers we know about
30 #define THRUST_DEVICE_COMPILER_UNKNOWN 0
31 #define THRUST_DEVICE_COMPILER_MSVC    1
32 #define THRUST_DEVICE_COMPILER_GCC     2
33 #define THRUST_DEVICE_COMPILER_NVCC    3
34 #define THRUST_DEVICE_COMPILER_CLANG   4
35 
36 // figure out which host compiler we're using
37 // XXX we should move the definition of THRUST_DEPRECATED out of this logic
38 #if   defined(_MSC_VER)
39 #define THRUST_HOST_COMPILER THRUST_HOST_COMPILER_MSVC
40 #elif defined(__clang__)
41 #define THRUST_HOST_COMPILER THRUST_HOST_COMPILER_CLANG
42 #define THRUST_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
43 #elif defined(__GNUC__)
44 #define THRUST_HOST_COMPILER THRUST_HOST_COMPILER_GCC
45 #define THRUST_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
46 #if (THRUST_GCC_VERSION >= 50000)
47 #define THRUST_MODERN_GCC
48 #else
49 #define THRUST_LEGACY_GCC
50 #endif
51 #else
52 #define THRUST_HOST_COMPILER THRUST_HOST_COMPILER_UNKNOWN
53 #endif // THRUST_HOST_COMPILER
54 
55 // figure out which device compiler we're using
56 #if defined(__CUDACC__)
57 #define THRUST_DEVICE_COMPILER THRUST_DEVICE_COMPILER_NVCC
58 #elif THRUST_HOST_COMPILER == THRUST_HOST_COMPILER_MSVC
59 #define THRUST_DEVICE_COMPILER THRUST_DEVICE_COMPILER_MSVC
60 #elif THRUST_HOST_COMPILER == THRUST_HOST_COMPILER_GCC
61 #define THRUST_DEVICE_COMPILER THRUST_DEVICE_COMPILER_GCC
62 #elif THRUST_HOST_COMPILER == THRUST_HOST_COMPILER_CLANG
63 // CUDA-capable clang should behave similar to NVCC.
64 #if defined(__CUDA__)
65 #define THRUST_DEVICE_COMPILER THRUST_DEVICE_COMPILER_NVCC
66 #else
67 #define THRUST_DEVICE_COMPILER THRUST_DEVICE_COMPILER_CLANG
68 #endif
69 #else
70 #define THRUST_DEVICE_COMPILER THRUST_DEVICE_COMPILER_UNKNOWN
71 #endif
72 
73 // is the device compiler capable of compiling omp?
74 #ifdef _OPENMP
75 #define THRUST_DEVICE_COMPILER_IS_OMP_CAPABLE THRUST_TRUE
76 #else
77 #define THRUST_DEVICE_COMPILER_IS_OMP_CAPABLE THRUST_FALSE
78 #endif // _OPENMP
79 
80 
81 #if (THRUST_HOST_COMPILER == THRUST_HOST_COMPILER_MSVC) && !defined(__CUDA_ARCH__)
82   #define THRUST_DISABLE_MSVC_WARNING_BEGIN(x)                                \
83     __pragma(warning(push))                                                   \
84     __pragma(warning(disable : x))                                            \
85     /**/
86   #define THRUST_DISABLE_MSVC_WARNING_END(x)                                  \
87     __pragma(warning(pop))                                                    \
88     /**/
89 #else
90   #define THRUST_DISABLE_MSVC_WARNING_BEGIN(x)
91   #define THRUST_DISABLE_MSVC_WARNING_END(x)
92 #endif
93 
94 #if (THRUST_HOST_COMPILER == THRUST_HOST_COMPILER_CLANG) && !defined(__CUDA_ARCH__)
95   #define THRUST_IGNORE_CLANG_WARNING_IMPL(x)                                 \
96     THRUST_PP_STRINGIZE(clang diagnostic ignored x)                           \
97     /**/
98   #define THRUST_IGNORE_CLANG_WARNING(x)                                      \
99     THRUST_IGNORE_CLANG_WARNING_IMPL(THRUST_PP_STRINGIZE(x))                  \
100     /**/
101 
102   #define THRUST_DISABLE_CLANG_WARNING_BEGIN(x)                               \
103     _Pragma("clang diagnostic push")                                          \
104     _Pragma(THRUST_IGNORE_CLANG_WARNING(x))                                   \
105     /**/
106   #define THRUST_DISABLE_CLANG_WARNING_END(x)                                 \
107     _Pragma("clang diagnostic pop")                                           \
108     /**/
109 #else
110   #define THRUST_DISABLE_CLANG_WARNING_BEGIN(x)
111   #define THRUST_DISABLE_CLANG_WARNING_END(x)
112 #endif
113 
114 #if (THRUST_HOST_COMPILER == THRUST_HOST_COMPILER_GCC) && !defined(__CUDA_ARCH__)
115   #define THRUST_IGNORE_GCC_WARNING_IMPL(x)                                   \
116     THRUST_PP_STRINGIZE(GCC diagnostic ignored x)                             \
117     /**/
118   #define THRUST_IGNORE_GCC_WARNING(x)                                        \
119     THRUST_IGNORE_GCC_WARNING_IMPL(THRUST_PP_STRINGIZE(x))                    \
120     /**/
121 
122   #define THRUST_DISABLE_GCC_WARNING_BEGIN(x)                                 \
123     _Pragma("GCC diagnostic push")                                            \
124     _Pragma(THRUST_IGNORE_GCC_WARNING(x))                                     \
125     /**/
126   #define THRUST_DISABLE_GCC_WARNING_END(x)                                   \
127     _Pragma("GCC diagnostic pop")                                             \
128     /**/
129 #else
130   #define THRUST_DISABLE_GCC_WARNING_BEGIN(x)
131   #define THRUST_DISABLE_GCC_WARNING_END(x)
132 #endif
133 
134 #define THRUST_DISABLE_MSVC_POSSIBLE_LOSS_OF_DATA_WARNING_BEGIN               \
135   THRUST_DISABLE_MSVC_WARNING_BEGIN(4244 4267)                                \
136   /**/
137 #define THRUST_DISABLE_MSVC_POSSIBLE_LOSS_OF_DATA_WARNING_END                 \
138   THRUST_DISABLE_MSVC_WARNING_END(4244 4267)                                  \
139   /**/
140 #define THRUST_DISABLE_MSVC_POSSIBLE_LOSS_OF_DATA_WARNING(x)                  \
141   THRUST_DISABLE_MSVC_POSSIBLE_LOSS_OF_DATA_WARNING_BEGIN                     \
142   x;                                                                          \
143   THRUST_DISABLE_MSVC_POSSIBLE_LOSS_OF_DATA_WARNING_END                       \
144   /**/
145 
146 #define THRUST_DISABLE_MSVC_FORCING_VALUE_TO_BOOL_WARNING_BEGIN               \
147   THRUST_DISABLE_MSVC_WARNING_BEGIN(4800)                                     \
148   /**/
149 #define THRUST_DISABLE_MSVC_FORCING_VALUE_TO_BOOL_WARNING_END                 \
150   THRUST_DISABLE_MSVC_WARNING_END(4800)                                       \
151   /**/
152 #define THRUST_DISABLE_MSVC_FORCING_VALUE_TO_BOOL_WARNING(x)                  \
153   THRUST_DISABLE_MSVC_FORCING_VALUE_TO_BOOL_WARNING_BEGIN                     \
154   x;                                                                          \
155   THRUST_DISABLE_MSVC_FORCING_VALUE_TO_BOOL_WARNING_END                       \
156   /**/
157 
158 #define THRUST_DISABLE_CLANG_SELF_ASSIGNMENT_WARNING_BEGIN                    \
159   THRUST_DISABLE_CLANG_WARNING_BEGIN(-Wself-assign)                           \
160   /**/
161 #define THRUST_DISABLE_CLANG_SELF_ASSIGNMENT_WARNING_END                      \
162   THRUST_DISABLE_CLANG_WARNING_END(-Wself-assign)                             \
163   /**/
164 #define THRUST_DISABLE_CLANG_SELF_ASSIGNMENT_WARNING(x)                       \
165   THRUST_DISABLE_CLANG_SELF_ASSIGNMENT_WARNING_BEGIN                          \
166   x;                                                                          \
167   THRUST_DISABLE_CLANG_SELF_ASSIGNMENT_WARNING_END                            \
168   /**/
169 
170 #define THRUST_DISABLE_CLANG_AND_GCC_INITIALIZER_REORDERING_WARNING_BEGIN     \
171   THRUST_DISABLE_CLANG_WARNING_BEGIN(-Wreorder)                               \
172   THRUST_DISABLE_GCC_WARNING_BEGIN(-Wreorder)                                 \
173   /**/
174 #define THRUST_DISABLE_CLANG_AND_GCC_INITIALIZER_REORDERING_WARNING_END       \
175   THRUST_DISABLE_CLANG_WARNING_END(-Wreorder)                                 \
176   THRUST_DISABLE_GCC_WARNING_END(-Wreorder)                                   \
177   /**/
178 #define THRUST_DISABLE_CLANG_AND_GCC_INITIALIZER_REORDERING_WARNING(x)        \
179   THRUST_DISABLE_CLANG_AND_GCC_INITIALIZER_REORDERING_WARNING_BEGIN           \
180   x;                                                                          \
181   THRUST_DISABLE_CLANG_AND_GCC_INITIALIZER_REORDERING_WARNING_END             \
182   /**/
183 
184 // TODO we should move the definition of THRUST_DEPRECATED out of this logic
185 #if   THRUST_HOST_COMPILER == THRUST_HOST_COMPILER_MSVC
186   #define THRUST_DEPRECATED __declspec(deprecated)
187 #elif THRUST_HOST_COMPILER == THRUST_HOST_COMPILER_CLANG
188   #define THRUST_DEPRECATED __attribute__((deprecated))
189 #elif THRUST_HOST_COMPILER == THRUST_HOST_COMPILER_GCC
190   #define THRUST_DEPRECATED __attribute__((deprecated))
191 #else
192   #define THRUST_DEPRECATED
193 #endif
194 
195