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