1 #ifndef MY_COMPILER_INCLUDED
2 #define MY_COMPILER_INCLUDED
3 
4 // Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License, version 2.0, as
8 // published by the Free Software Foundation.
9 //
10 // This program is also distributed with certain software (including
11 // but not limited to OpenSSL) that is licensed under separate terms,
12 // as designated in a particular file or component or in included license
13 // documentation. The authors of MySQL hereby grant you an
14 // additional permission to link the program and your derivative works
15 // with the separately licensed software that they have included with
16 // MySQL.
17 //
18 // Without limiting anything contained in the foregoing, this file,
19 // which is part of MySQL Server, is also subject to the
20 // Universal FOSS Exception, version 1.0, a copy of which can be found at
21 // http://oss.oracle.com/licenses/universal-foss-exception.
22 //
23 // This program is distributed in the hope that it will be useful, but
24 // WITHOUT ANY WARRANTY; without even the implied warranty of
25 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
26 // See the GNU General Public License, version 2.0, for more details.
27 //
28 // You should have received a copy of the GNU General Public License
29 // along with this program; if not, write to the Free Software Foundation, Inc.,
30 // 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31 
32 /**
33   @file include/my_compiler.h
34   Header for compiler-dependent features.
35 
36   Intended to contain a set of reusable wrappers for preprocessor
37   macros, attributes, pragmas, and any other features that are
38   specific to a target compiler.
39 */
40 
41 #ifndef MYSQL_ABI_CHECK
42 #include <assert.h>
43 #include <stddef.h> /* size_t */
44 #endif
45 
46 #include "my_config.h"
47 
48 /*
49   The macros below are borrowed from include/linux/compiler.h in the
50   Linux kernel. Use them to indicate the likelyhood of the truthfulness
51   of a condition. This serves two purposes - newer versions of gcc will be
52   able to optimize for branch predication, which could yield siginficant
53   performance gains in frequently executed sections of the code, and the
54   other reason to use them is for documentation
55 */
56 #ifdef HAVE_BUILTIN_EXPECT
57 
58 // likely/unlikely are likely to clash with other symbols, do not #define
59 #if defined(__cplusplus)
likely(bool expr)60 inline bool likely(bool expr) { return __builtin_expect(expr, true); }
unlikely(bool expr)61 inline bool unlikely(bool expr) { return __builtin_expect(expr, false); }
62 #else
63 #define likely(x) __builtin_expect((x), 1)
64 #define unlikely(x) __builtin_expect((x), 0)
65 #endif
66 
67 #else /* HAVE_BUILTIN_EXPECT */
68 
69 #if defined(__cplusplus)
likely(bool expr)70 inline bool likely(bool expr) { return expr; }
unlikely(bool expr)71 inline bool unlikely(bool expr) { return expr; }
72 #else
73 #define likely(x) (x)
74 #define unlikely(x) (x)
75 #endif
76 
77 #endif /* HAVE_BUILTIN_EXPECT */
78 
79 /* Comunicate to the compiler the unreachability of the code. */
80 #ifdef HAVE_BUILTIN_UNREACHABLE
81 #define MY_ASSERT_UNREACHABLE() __builtin_unreachable()
82 #else
83 #define MY_ASSERT_UNREACHABLE() \
84   do {                          \
85     assert(0);                  \
86   } while (0)
87 #endif
88 
89 #if defined __GNUC__ || defined __SUNPRO_C || defined __SUNPRO_CC
90 /* Specifies the minimum alignment of a type. */
91 #define MY_ALIGNOF(type) __alignof__(type)
92 /* Determine the alignment requirement of a type. */
93 #define MY_ALIGNED(n) __attribute__((__aligned__((n))))
94 /* Microsoft Visual C++ */
95 #elif defined _MSC_VER
96 #define MY_ALIGNOF(type) __alignof(type)
97 #define MY_ALIGNED(n) __declspec(align(n))
98 #else /* Make sure they are defined for other compilers. */
99 #define MY_ALIGNOF(type)
100 #define MY_ALIGNED(size)
101 #endif
102 
103 /* Visual Studio requires '__inline' for C code */
104 #if !defined(__cplusplus) && defined(_MSC_VER)
105 #define inline __inline
106 #endif
107 
108 /* Provide __func__ macro definition for Visual Studio. */
109 #if defined(_MSC_VER)
110 #define __func__ __FUNCTION__
111 #endif
112 
113 /**
114   C++ Type Traits
115 */
116 #ifdef __cplusplus
117 
118 /**
119   Opaque storage with a particular alignment.
120   Partial specialization used due to MSVC++.
121 */
122 template <size_t alignment>
123 struct my_alignment_imp;
124 
125 template <>
126 struct MY_ALIGNED(1) my_alignment_imp<1> {};
127 template <>
128 struct MY_ALIGNED(2) my_alignment_imp<2> {};
129 template <>
130 struct MY_ALIGNED(4) my_alignment_imp<4> {};
131 template <>
132 struct MY_ALIGNED(8) my_alignment_imp<8> {};
133 template <>
134 struct MY_ALIGNED(16) my_alignment_imp<16> {};
135 
136 /**
137   A POD type with a given size and alignment.
138 
139   @remark If the compiler does not support a alignment attribute
140           (MY_ALIGN macro), the default alignment of a double is
141           used instead.
142 
143   @tparam size        The minimum size.
144   @tparam alignment   The desired alignment: 1, 2, 4, 8 or 16.
145 */
146 template <size_t size, size_t alignment>
147 struct my_aligned_storage {
148   union {
149     char data[size];
150     my_alignment_imp<alignment> align;
151   };
152 };
153 
154 #endif /* __cplusplus */
155 
156 /*
157   Disable MY_ATTRIBUTE for Sun Studio and Visual Studio.
158   Note that Sun Studio supports some __attribute__ variants,
159   but not format or unused which we use quite a lot.
160 */
161 #ifndef MY_ATTRIBUTE
162 #if defined(__GNUC__) || defined(__clang__)
163 #define MY_ATTRIBUTE(A) __attribute__(A)
164 #else
165 #define MY_ATTRIBUTE(A)
166 #endif
167 #endif
168 
169 #if defined(_MSC_VER)
170 #define ALWAYS_INLINE __forceinline
171 #else
172 #define ALWAYS_INLINE __attribute__((always_inline)) inline
173 #endif
174 
175 #ifndef __has_attribute
176 #define __has_attribute(x) 0
177 #endif
178 
179 #ifndef SUPPRESS_UBSAN
180 #if __has_attribute(no_sanitize_undefined)
181 #define SUPPRESS_UBSAN MY_ATTRIBUTE((no_sanitize_undefined))
182 #else
183 #define SUPPRESS_UBSAN
184 #endif
185 #endif /* SUPPRESS_UBSAN */
186 
187 #ifdef _WIN32
188 #define STDCALL __stdcall
189 #else
190 #define STDCALL
191 #endif
192 
193 #endif /* MY_COMPILER_INCLUDED */
194