summaryrefslogtreecommitdiff
path: root/tests/stdalign.in.h
blob: 58fd245c6274d5df38afaaa4f58c3fe001e07889 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/* A substitute for ISO C11 <stdalign.h>.

   Copyright 2011-2022 Free Software Foundation, Inc.

   This file is free software: you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as
   published by the Free Software Foundation; either version 2.1 of the
   License, or (at your option) any later version.

   This file is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public License
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */

/* Written by Paul Eggert and Bruno Haible.  */

#ifndef _GL_STDALIGN_H
#define _GL_STDALIGN_H

/* ISO C11 <stdalign.h> for platforms that lack it.

   References:
   ISO C11 (latest free draft
   <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf>)
   sections 6.5.3.4, 6.7.5, 7.15.
   C++11 (latest free draft
   <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf>)
   section 18.10. */

/* alignof (TYPE), also known as _Alignof (TYPE), yields the alignment
   requirement of a structure member (i.e., slot or field) that is of
   type TYPE, as an integer constant expression.

   This differs from GCC's and clang's __alignof__ operator, which can
   yield a better-performing alignment for an object of that type.  For
   example, on x86 with GCC and on Linux/x86 with clang,
   __alignof__ (double) and __alignof__ (long long) are 8, whereas
   alignof (double) and alignof (long long) are 4 unless the option
   '-malign-double' is used.

   The result cannot be used as a value for an 'enum' constant, if you
   want to be portable to HP-UX 10.20 cc and AIX 3.2.5 xlc.  */

/* FreeBSD 9.1 <sys/cdefs.h>, included by <stddef.h> and lots of other
   standard headers, defines conflicting implementations of _Alignas
   and _Alignof that are no better than ours; override them.  */
#undef _Alignas
#undef _Alignof

/* GCC releases before GCC 4.9 had a bug in _Alignof.  See GCC bug 52023
   <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52023>.
   clang versions < 8.0.0 have the same bug.  */
#if (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112 \
     || (defined __GNUC__ && __GNUC__ < 4 + (__GNUC_MINOR__ < 9) \
         && !defined __clang__) \
     || (defined __clang__ && __clang_major__ < 8))
# ifdef __cplusplus
#  if (201103 <= __cplusplus || defined _MSC_VER)
#   define _Alignof(type) alignof (type)
#  else
   template <class __t> struct __alignof_helper { char __a; __t __b; };
#   define _Alignof(type) offsetof (__alignof_helper<type>, __b)
#   define _GL_STDALIGN_NEEDS_STDDEF 1
#  endif
# else
#  define _Alignof(type) offsetof (struct { char __a; type __b; }, __b)
#  define _GL_STDALIGN_NEEDS_STDDEF 1
# endif
#endif
#if ! (defined __cplusplus && (201103 <= __cplusplus || defined _MSC_VER))
# define alignof _Alignof
#endif
#define __alignof_is_defined 1

/* alignas (A), also known as _Alignas (A), aligns a variable or type
   to the alignment A, where A is an integer constant expression.  For
   example:

      int alignas (8) foo;
      struct s { int a; int alignas (8) bar; };

   aligns the address of FOO and the offset of BAR to be multiples of 8.

   A should be a power of two that is at least the type's alignment
   and at most the implementation's alignment limit.  This limit is
   2**28 on typical GNUish hosts, and 2**13 on MSVC.  To be portable
   to MSVC through at least version 10.0, A should be an integer
   constant, as MSVC does not support expressions such as 1 << 3.
   To be portable to Sun C 5.11, do not align auto variables to
   anything stricter than their default alignment.

   The following C11 requirements are not supported here:

     - If A is zero, alignas has no effect.
     - alignas can be used multiple times; the strictest one wins.
     - alignas (TYPE) is equivalent to alignas (alignof (TYPE)).

   */

#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112
# if defined __cplusplus && (201103 <= __cplusplus || defined _MSC_VER)
#  define _Alignas(a) alignas (a)
# elif (!defined __attribute__ \
        && ((defined __APPLE__ && defined __MACH__ \
             ? 4 < __GNUC__ + (1 <= __GNUC_MINOR__) \
             : __GNUC__ && !defined __ibmxl__) \
            || (4 <= __clang_major__) \
            || (__ia64 && (61200 <= __HP_cc || 61200 <= __HP_aCC)) \
            || __ICC || 0x590 <= __SUNPRO_C || 0x0600 <= __xlC__))
#  define _Alignas(a) __attribute__ ((__aligned__ (a)))
# elif 1300 <= _MSC_VER
#  define _Alignas(a) __declspec (align (a))
# endif
#endif
#if ((defined _Alignas \
      && !(defined __cplusplus && (201103 <= __cplusplus || defined _MSC_VER))) \
     || (defined __STDC_VERSION__ && 201112 <= __STDC_VERSION__))
# define alignas _Alignas
#endif
#if (defined alignas \
     || (defined __cplusplus && (201103 <= __cplusplus || defined _MSC_VER)))
# define __alignas_is_defined 1
#endif

/* Include <stddef.h> if needed for offsetof.  */
#if _GL_STDALIGN_NEEDS_STDDEF
# include <stddef.h>
#endif

#endif /* _GL_STDALIGN_H */