IMP logo
IMP Reference Guide  develop.6100cc8943,2021/10/26
The Integrative Modeling Platform
compiler_macros.h
Go to the documentation of this file.
1 /**
2  * \file IMP/compiler_macros.h
3  * \brief Various compiler workarounds
4  *
5  * Copyright 2007-2021 IMP Inventors. All rights reserved.
6  */
7 
8 #ifndef IMPKERNEL_COMPILER_MACROS_H
9 #define IMPKERNEL_COMPILER_MACROS_H
10 
11 #include <boost/config.hpp>
12 #include <boost/version.hpp>
13 #if defined(BOOST_NO_CXX11_RANGE_BASED_FOR)
14 #include <boost/foreach.hpp>
15 #define IMP_FOREACH(v, r) BOOST_FOREACH(v, r)
16 #else
17 /** Use C++11 range-based for if available or BOOST_FOREACH if not. */
18 #define IMP_FOREACH(v, r) for (v : r)
19 #endif
20 
21 #define IMP_STRINGIFY(x) #x
22 
23 // recommended by http://gcc.gnu.org/gcc/Function-Names.html
24 #if defined(_MSC_VER)
25 #define IMP_CURRENT_FUNCTION __FUNCTION__
26 #define IMP_CURRENT_PRETTY_FUNCTION __FUNCTION__
27 #elif defined(__STDC_VERSION__) && __STDC_VERSION__ < 199901L
28 #define IMP_CURRENT_FUNCTION __FUNCTION__
29 #define IMP_CURRENT_PRETTY_FUNCTION __PRETTY_FUNCTION__
30 #else
31 #define IMP_CURRENT_FUNCTION __func__
32 #define IMP_CURRENT_PRETTY_FUNCTION __PRETTY_FUNCTION__
33 #endif
34 
35 #ifndef IMP_DOXYGEN
36 #ifdef __GNUC__
37 #define IMP_NO_SIDEEFFECTS __attribute__((pure))
38 #define IMP_UNUSED_FUNCTION __attribute__((unused))
39 #define IMP_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
40 #define IMP_RESTRICT __restrict__
41 
42 #else
43 #define IMP_NO_SIDEEFFECTS
44 #define IMP_UNUSED_FUNCTION
45 #define IMP_WARN_UNUSED_RESULT
46 #define IMP_RESTRICT
47 #endif
48 
49 #else
50 //! Use this to label a function with no side effects
51 /** \advancedmethod */
52 #define IMP_NO_SIDEEFFECTS
53 //! Use this to make the compiler (possibly) warn if the result is not used
54 /** \advancedmethod */
55 #define IMP_WARN_UNUSED_RESULT
56 //! Label a function that is never called
57 /** \advancedmethod */
58 #define IMP_UNUSED_FUNCTION
59 //! restrict means that a variable is not aliased with this function
60 #define IMP_RESTRICT
61 #endif
62 
63 #if defined(__clang__) && __clang_major__ >= 5
64 #define IMP_COMPILER_HAS_OVERRIDE 1
65 #elif !defined(__clang__) && defined(__GNUC__) && __cplusplus >= 201103L
66 // probably should be finer here
67 #define IMP_COMPILER_HAS_OVERRIDE 1
68 #else
69 #define IMP_COMPILER_HAS_OVERRIDE 0
70 #endif
71 
72 #ifdef IMP_DOXYGEN
73 //! Cause a compile error if this method does not override a parent method
74 /** This is helpful to catch accidental mismatches of call signatures between
75  the method and the parent method, which would cause the method to be
76  overloaded rather than overridden. Usually this macro should be used
77  whenever implementing a method that is declared virtual in the parent. */
78 #define IMP_OVERRIDE
79 #else
80 #if IMP_COMPILER_HAS_OVERRIDE
81 #define IMP_OVERRIDE override
82 #else
83 #define IMP_OVERRIDE
84 #endif
85 #endif
86 
87 #if defined(IMP_SWIG_WRAPPER)
88 #define IMP_COMPILER_HAS_FINAL 0
89 #elif defined(__clang__)
90 #define IMP_COMPILER_HAS_FINAL 1
91 #elif defined(__GNUC__) && __cplusplus >= 201103L
92 // probably should be finer here
93 #define IMP_COMPILER_HAS_FINAL 1
94 #else
95 #define IMP_COMPILER_HAS_FINAL 0
96 #endif
97 
98 #ifdef IMP_DOXYGEN
99 //! Have the compiler report an error if anything overrides this method
100 #define IMP_FINAL
101 #else
102 #if IMP_COMPILER_HAS_FINAL
103 #define IMP_FINAL final
104 #else
105 #define IMP_FINAL
106 #endif
107 #endif
108 
109 #if defined(__GNUC__) && __cplusplus >= 201103L
110 #define IMP_HAS_NOEXCEPT 1
111 #elif defined(__clang__) && defined(__has_feature)
112 #define IMP_HAS_NOEXCEPT __has_feature(cxx_noexcept)
113 #else
114 #define IMP_HAS_NOEXCEPT 0
115 #endif
116 
117 #if IMP_HAS_NOEXCEPT
118 #define IMP_NOEXCEPT noexcept
119 #define IMP_CXX11_DEFAULT_COPY_CONSTRUCTOR(Name) \
120  Name(const Name &) = default; \
121  Name &operator=(const Name &) = default
122 #else
123 // probably should be finer here
124 #define IMP_NOEXCEPT throw()
125 #define IMP_CXX11_DEFAULT_COPY_CONSTRUCTOR(Name)
126 #endif
127 
128 #if defined(__clang__) || defined(__GNUC__)
129 #define IMP_PRAGMA(x) _Pragma(IMP_STRINGIFY(x))
130 
131 #if defined(__clang__)
132 #define IMP_CLANG_PRAGMA(x) IMP_PRAGMA(clang x)
133 #define IMP_GCC_PRAGMA(x)
134 #define IMP_VC_PRAGMA(x)
135 #else
136 #define IMP_CLANG_PRAGMA(x)
137 #define IMP_GCC_PRAGMA(x) IMP_PRAGMA(GCC x)
138 #define IMP_VC_PRAGMA(x)
139 #endif
140 
141 #elif defined(_MSC_VER)
142 #define IMP_PRAGMA(x) __pragma(x)
143 #define IMP_CLANG_PRAGMA(x)
144 #define IMP_GCC_PRAGMA(x)
145 #define IMP_VC_PRAGMA(x) IMP_PRAGMA(x)
146 
147 #else
148 #define IMP_PRAGMA(x)
149 #define IMP_CLANG_PRAGMA(x)
150 #define IMP_GCC_PRAGMA(x)
151 #define IMP_VC_PRAGMA(x)
152 #endif
153 
154 #ifdef __clang__
155 
156 #define IMP_GCC_PUSH_POP(x)
157 
158 #define IMP_COMPILER_ENABLE_WARNINGS \
159  IMP_CLANG_PRAGMA(diagnostic push) \
160  IMP_CLANG_PRAGMA(diagnostic warning "-Wall") \
161  IMP_CLANG_PRAGMA(diagnostic warning "-Wextra") \
162  IMP_CLANG_PRAGMA(diagnostic warning "-Weverything") \
163  IMP_CLANG_PRAGMA(diagnostic ignored "-Wconversion") \
164  IMP_CLANG_PRAGMA(diagnostic ignored "-Wc++11-extensions") \
165  IMP_CLANG_PRAGMA(diagnostic ignored "-Wc++11-compat") \
166  IMP_CLANG_PRAGMA(diagnostic warning "-Wsign-compare") \
167  IMP_CLANG_PRAGMA(diagnostic ignored "-Wunused-member-function")
168 
169 #define IMP_HELPER_MACRO_PUSH_WARNINGS IMP_CLANG_PRAGMA(diagnostic push)
170 
171 #define IMP_HELPER_MACRO_POP_WARNINGS IMP_CLANG_PRAGMA(diagnostic pop)
172 
173 #define IMP_COMPILER_DISABLE_WARNINGS IMP_CLANG_PRAGMA(diagnostic pop)
174 
175 #elif defined(__GNUC__)
176 
177 /*ret+=["-Wno-deprecated",
178  "-Wstrict-aliasing=2",
179  -fno-operator-names",]*/
180 #if __GNUC__ > 4 || __GNUC_MINOR__ >= 6
181 #define IMP_GCC_PUSH_POP(x) IMP_PRAGMA(x)
182 #define IMP_GCC_CXX0X_COMPAT \
183  IMP_GCC_PRAGMA(diagnostic ignored \
184  "-Wc++0x-compat")
185 #ifdef IMP_SWIG_WRAPPER
186 #define IMP_GCC_PROTOTYPES
187 #else
188 #define IMP_GCC_PROTOTYPES \
189  IMP_GCC_PRAGMA(diagnostic warning "-Wmissing-declarations")
190 #endif
191 
192 #define IMP_HELPER_MACRO_PUSH_WARNINGS IMP_GCC_PRAGMA(diagnostic push)
193 
194 #define IMP_HELPER_MACRO_POP_WARNINGS IMP_GCC_PRAGMA(diagnostic pop)
195 
196 #else
197 #define IMP_GCC_PUSH_POP(x)
198 #define IMP_GCC_CXX0X_COMPAT
199 #define IMP_GCC_PROTOTYPES
200 #define IMP_HELPER_MACRO_PUSH_WARNINGS
201 #define IMP_HELPER_MACRO_POP_WARNINGS
202 #endif
203 
204 // Warn about missing IMP_OVERRIDE on virtual methods if gcc is new enough
205 #if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1)
206 #ifdef IMP_SWIG_WRAPPER
207 #define IMP_GCC_OVERRIDE
208 #else
209 #define IMP_GCC_OVERRIDE \
210  IMP_GCC_PRAGMA(diagnostic warning "-Wsuggest-override")
211 #endif
212 #else
213 #define IMP_GCC_OVERRIDE
214 #endif
215 
216 #define IMP_COMPILER_ENABLE_WARNINGS \
217  IMP_GCC_PUSH_POP(GCC diagnostic push) \
218  IMP_GCC_PRAGMA(diagnostic warning "-Wall") \
219  IMP_GCC_PRAGMA(diagnostic warning "-Wextra") \
220  IMP_GCC_PRAGMA(diagnostic warning "-Winit-self") \
221  IMP_GCC_PRAGMA(diagnostic warning "-Wcast-align") \
222  IMP_GCC_PRAGMA(diagnostic warning "-Woverloaded-virtual") \
223  IMP_GCC_PRAGMA(diagnostic warning "-Wdeprecated-declarations") \
224  IMP_GCC_PRAGMA(diagnostic warning "-Wundef") \
225  IMP_GCC_PROTOTYPES IMP_GCC_CXX0X_COMPAT IMP_GCC_OVERRIDE
226 
227 #define IMP_COMPILER_DISABLE_WARNINGS IMP_GCC_PUSH_POP(GCC diagnostic pop)
228 
229 #elif defined(_MSC_VER)
230 #define IMP_GCC_PUSH_POP(x)
231 
232 #define IMP_COMPILER_ENABLE_WARNINGS \
233  IMP_VC_PRAGMA(warning(push)) IMP_VC_PRAGMA(warning(disable : 4273)) \
234  IMP_VC_PRAGMA(warning(disable : 4244)) \
235  IMP_VC_PRAGMA(warning(disable : 4068)) \
236  IMP_VC_PRAGMA(warning(disable : 4297))
237 
238 #define IMP_COMPILER_DISABLE_WARNINGS IMP_VC_PRAGMA(warning(pop))
239 
240 #define IMP_HELPER_MACRO_PUSH_WARNINGS
241 #define IMP_HELPER_MACRO_POP_WARNINGS
242 
243 #else
244 #define IMP_COMPILER_ENABLE_WARNINGS
245 #define IMP_COMPILER_DISABLE_WARNINGS
246 #define IMP_HELPER_MACRO_PUSH_WARNINGS
247 #define IMP_HELPER_MACRO_POP_WARNINGS
248 #endif
249 
250 #if defined(__GNUC__) || defined(__clang__)
251 #define IMP_DEPRECATED_ATTRIBUTE __attribute__((deprecated))
252 #else
253 #define IMP_DEPRECATED_ATTRIBUTE
254 #endif
255 
256 // likely/unlikely macros provide manual optimization of branch
257 // prediction - particularly useful for rare cases in scoring
258 // functions, but use only if you know what you're doing cause
259 // profiler is better at this in 99.9% of times:
260 #if defined(__GNUC__)
261 #define IMP_LIKELY(x) __builtin_expect (!!(x), 1)
262 #define IMP_UNLIKELY(x) __builtin_expect (!!(x), 0)
263 #else // ifdef __GNUC__
264 #define IMP_LIKELY(x) x
265 #define IMP_UNLIKELY(x) x
266 #endif // ifdef __GNUC__
267 
268 #if defined(_MSC_VER)
269 //! platform independent C open() method
270 #define IMP_C_OPEN _open
271 #define IMP_C_CLOSE _close
272  //! platform independent C flag for open() method
273 #define IMP_C_OPEN_FLAG(x) _##x
274 #define IMP_C_OPEN_BINARY _O_BINARY
275 #else
276 //! platform independent C open() method
277 #define IMP_C_OPEN open
278 #define IMP_C_CLOSE close
279 //! platform independent C flag for open() method
280 #define IMP_C_OPEN_FLAG(x) x
281 #define IMP_C_OPEN_BINARY 0
282 #endif
283 
284 #endif /* IMPKERNEL_COMPILER_MACROS_H */