source: mainline/abi/include/_bits/macros.h@ 9ddcb0b

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 9ddcb0b was 9ddcb0b, checked in by jzr <zarevucky.jiri@…>, 8 years ago

Add <_bits/…> headers.

  • Property mode set to 100644
File size: 14.4 KB
Line 
1/*
2 * Copyright (c) 2017 CZ.NIC, z.s.p.o.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/* Authors:
30 * Jiří Zárevúcky (jzr) <zarevucky.jiri@gmail.com>
31 */
32
33/** @addtogroup bits
34 * @{
35 */
36/** @file
37 * Basic macro definitions and redefinitions that support basic C types.
38 *
39 * Both GCC and clang define macros for fixed-size integer names
40 * (e.g. __INT32_TYPE__ for int32_t). However, while clang also provides
41 * definitions for formatting macros (PRId32 et al.), GCC does not.
42 * This poses a subtle problem for diagnostics -- when 'int' and 'long int'
43 * have the same width, it's not possible to detect which one is used to
44 * define 'int32_t', but using a formatting specifier for 'int' on 'long int'
45 * value, or vice versa, causes a compiler warning. Analogous problem occurs
46 * with 'long int' and 'long long int', if they are the same size.
47 *
48 * In the interest of compatibility, we ignore the compiler's opinion on
49 * fixed-size types, and redefine the macros consistently.
50 *
51 * However, we can't do the same for 'size_t', 'ptrdiff_t', 'wchar_t', 'wint_t',
52 * 'intmax_t' and 'uintmax_t', since their format specifiers and other
53 * properties are built into the language and their identity is therefore
54 * determined by the compiler.
55 *
56 * We use some macros if they are present, but provide our own fallbacks when
57 * they are not. There are several macros that have to be predefined either by
58 * the compiler itself, or supplied by the build system if necessary
59 * (e.g. using the '-imacros' compiler argument). This is basically a subset
60 * of the common denominator of GCC and clang predefined macros at this moment.
61 *
62 * These required macros include:
63 *
64 * __CHAR_BIT__
65 * __SIZEOF_SHORT__
66 * __SIZEOF_INT__
67 * __SIZEOF_LONG__
68 * __SIZEOF_LONG_LONG__
69 * __SIZEOF_POINTER__
70 *
71 * __SIZE_TYPE__
72 * __SIZE_MAX__
73 *
74 * __PTRDIFF_TYPE__
75 * __PTRDIFF_MAX__
76 *
77 * __WCHAR_TYPE__
78 * __WCHAR_MAX__
79 *
80 * __WINT_TYPE__
81 * __WINT_MAX__ or
82 * __WINT_WIDTH__ and __WINT_UNSIGNED__ when wint_t is unsigned
83 *
84 * __INTMAX_TYPE__
85 * __INTMAX_MAX__
86 * either __INTMAX_C_SUFFIX__ or __INTMAX_C
87 *
88 * __CHAR_UNSIGNED__ when char is unsigned
89 *
90 * After this header is processed, the following additional macros are
91 * guaranteed to be defined:
92 *
93 * TODO: List them all.
94 *
95 */
96
97// TODO: add sig_atomic_t for compatibility with C language standard
98
99#ifndef _BITS_MACROS_H_
100#define _BITS_MACROS_H_
101
102#if __CHAR_BIT__ != 8
103#error HelenOS expects char that is 8 bits wide.
104#endif
105
106#ifndef __SCHAR_MAX__
107#define __SCHAR_MAX__ 0x7f
108#endif
109
110#ifndef __SCHAR_MIN__
111#define __SCHAR_MIN__ (-__SCHAR_MAX__ - 1)
112#endif
113
114#ifndef __UCHAR_MAX__
115#define __UCHAR_MAX__ 0xff
116#endif
117
118#ifndef __CHAR_MIN__
119#ifdef __CHAR_UNSIGNED__
120#define __CHAR_MIN__ 0
121#else
122#define __CHAR_MIN__ __SCHAR_MIN__
123#endif
124#endif
125
126#ifndef __CHAR_MAX__
127#ifdef __CHAR_UNSIGNED__
128#define __CHAR_MAX__ __UCHAR_MAX__
129#else
130#define __CHAR_MAX__ __SCHAR_MAX__
131#endif
132#endif
133
134#undef __INT8_TYPE__
135#undef __INT8_C
136#undef __INT8_C_SUFFIX__
137#undef __INT8_MIN__
138#undef __INT8_MAX__
139
140#define __INT8_TYPE__ signed char
141#define __INT8_C(x) x
142#define __INT8_MIN__ __SCHAR_MIN__
143#define __INT8_MAX__ __SCHAR_MAX__
144
145#undef __UINT8_TYPE__
146#undef __UINT8_C
147#undef __UINT8_C_SUFFIX__
148#undef __UINT8_MIN__
149#undef __UINT8_MAX__
150
151#define __UINT8_TYPE__ unsigned char
152#define __UINT8_C(x) x
153#define __UINT8_MAX__ __UCHAR_MAX__
154
155#undef __PRId8__
156#undef __PRIi8__
157#undef __PRIu8__
158#undef __PRIo8__
159#undef __PRIx8__
160#undef __PRIX8__
161
162#define __PRId8__ "hhd"
163#define __PRIi8__ "hhi"
164#define __PRIu8__ "hhu"
165#define __PRIo8__ "hho"
166#define __PRIx8__ "hhx"
167#define __PRIX8__ "hhX"
168
169#undef __SCNd8__
170#undef __SCNi8__
171#undef __SCNu8__
172#undef __SCNo8__
173#undef __SCNx8__
174
175#define __SCNd8__ "hhd"
176#define __SCNi8__ "hhi"
177#define __SCNu8__ "hhu"
178#define __SCNo8__ "hho"
179#define __SCNx8__ "hhx"
180
181#if __SIZEOF_SHORT__ != 2
182#error HelenOS expects short that is 16 bits wide.
183#endif
184
185#ifndef __SHRT_MAX__
186#define __SHRT_MAX__ 0x7fff
187#endif
188
189#ifndef __SHRT_MIN__
190#define __SHRT_MIN__ (-__SHRT_MAX__ - 1)
191#endif
192
193#ifndef __USHRT_MAX__
194#define __USHRT_MAX__ 0xffff
195#endif
196
197#undef __INT16_TYPE__
198#undef __INT16_C
199#undef __INT16_C_SUFFIX__
200#undef __INT16_MIN__
201#undef __INT16_MAX__
202
203#define __INT16_TYPE__ short
204#define __INT16_C(x) x
205#define __INT16_MIN__ __SHRT_MIN__
206#define __INT16_MAX__ __SHRT_MAX__
207
208#undef __UINT16_TYPE__
209#undef __UINT16_C
210#undef __UINT16_C_SUFFIX__
211#undef __UINT16_MIN__
212#undef __UINT16_MAX__
213
214#define __UINT16_TYPE__ unsigned short
215#define __UINT16_C(x) x
216#define __UINT16_MAX__ __USHRT_MAX__
217
218#undef __PRId16__
219#undef __PRIi16__
220#undef __PRIu16__
221#undef __PRIo16__
222#undef __PRIx16__
223#undef __PRIX16__
224
225#define __PRId16__ "hd"
226#define __PRIi16__ "hi"
227#define __PRIu16__ "hu"
228#define __PRIo16__ "ho"
229#define __PRIx16__ "hx"
230#define __PRIX16__ "hX"
231
232#undef __SCNd16__
233#undef __SCNi16__
234#undef __SCNu16__
235#undef __SCNo16__
236#undef __SCNx16__
237
238#define __SCNd16__ "hd"
239#define __SCNi16__ "hi"
240#define __SCNu16__ "hu"
241#define __SCNo16__ "ho"
242#define __SCNx16__ "hx"
243
244#if __SIZEOF_INT__ != 4
245#error HelenOS expects int that is 32 bits wide.
246#endif
247
248#ifndef __INT_MAX__
249#define __INT_MAX__ 0x7fffffff
250#endif
251
252#ifndef __INT_MIN__
253#define __INT_MIN__ (-__INT_MAX__ - 1)
254#endif
255
256#ifndef __UINT_MAX__
257#define __UINT_MAX__ 0xffffffffU
258#endif
259
260#undef __INT32_TYPE__
261#undef __INT32_C
262#undef __INT32_C_SUFFIX__
263#undef __INT32_MIN__
264#undef __INT32_MAX__
265
266#define __INT32_TYPE__ int
267#define __INT32_C(x) x
268#define __INT32_MIN__ __INT_MIN__
269#define __INT32_MAX__ __INT_MAX__
270
271#undef __UINT32_TYPE__
272#undef __UINT32_C
273#undef __UINT32_C_SUFFIX__
274#undef __UINT32_MIN__
275#undef __UINT32_MAX__
276
277#define __UINT32_TYPE__ unsigned int
278#define __UINT32_C(x) x##U
279#define __UINT32_MAX__ __UINT_MAX__
280
281#undef __PRId32__
282#undef __PRIi32__
283#undef __PRIu32__
284#undef __PRIo32__
285#undef __PRIx32__
286#undef __PRIX32__
287
288#define __PRId32__ "d"
289#define __PRIi32__ "i"
290#define __PRIu32__ "u"
291#define __PRIo32__ "o"
292#define __PRIx32__ "x"
293#define __PRIX32__ "X"
294
295#undef __SCNd32__
296#undef __SCNi32__
297#undef __SCNu32__
298#undef __SCNo32__
299#undef __SCNx32__
300
301#define __SCNd32__ "d"
302#define __SCNi32__ "i"
303#define __SCNu32__ "u"
304#define __SCNo32__ "o"
305#define __SCNx32__ "x"
306
307#if __SIZEOF_LONG__ != __SIZEOF_POINTER__
308#error HelenOS expects long that has native width for the architecture.
309#endif
310
311#if __SIZEOF_POINTER__ < 4 || __SIZEOF_POINTER__ > 8
312#error HelenOS expects pointer width to be either 32 bits or 64 bits.
313#endif
314
315#ifndef __LONG_MAX__
316#if __SIZEOF_LONG__ == 4
317#define __LONG_MAX__ 0x7fffffffL
318#elif __SIZEOF_LONG__ == 8
319#define __LONG_MAX__ 0x7fffffffffffffffL
320#endif
321#endif
322
323#ifndef __LONG_MIN__
324#define __LONG_MIN__ (-__LONG_MAX__ - 1)
325#endif
326
327#ifndef __ULONG_MAX__
328#if __SIZEOF_LONG__ == 4
329#define __ULONG_MAX__ 0xffffffffUL
330#elif __SIZEOF_LONG__ == 8
331#define __ULONG_MAX__ 0xffffffffffffffffUL
332#endif
333#endif
334
335#undef __INTPTR_TYPE__
336#undef __INTPTR_C
337#undef __INTPTR_C_SUFFIX__
338#undef __INTPTR_MIN__
339#undef __INTPTR_MAX__
340#undef __UINTPTR_TYPE__
341#undef __UINTPTR_C
342#undef __UINTPTR_C_SUFFIX__
343#undef __UINTPTR_MIN__
344#undef __UINTPTR_MAX__
345#undef __PRIdPTR__
346#undef __PRIiPTR__
347#undef __PRIuPTR__
348#undef __PRIoPTR__
349#undef __PRIxPTR__
350#undef __PRIXPTR__
351#undef __SCNdPTR__
352#undef __SCNiPTR__
353#undef __SCNuPTR__
354#undef __SCNoPTR__
355#undef __SCNxPTR__
356
357#ifdef __intptr_is_long__
358
359#define __INTPTR_TYPE__ long
360#define __INTPTR_MIN__ __LONG_MIN__
361#define __INTPTR_MAX__ __LONG_MAX__
362#define __UINTPTR_TYPE__ unsigned long
363#define __UINTPTR_MAX__ __ULONG_MAX__
364
365#define __PRIdPTR__ "ld"
366#define __PRIiPTR__ "li"
367#define __PRIuPTR__ "lu"
368#define __PRIoPTR__ "lo"
369#define __PRIxPTR__ "lx"
370#define __PRIXPTR__ "lX"
371
372#define __SCNdPTR__ "ld"
373#define __SCNiPTR__ "li"
374#define __SCNuPTR__ "lu"
375#define __SCNoPTR__ "lo"
376#define __SCNxPTR__ "lx"
377
378#else
379
380// Original definition results in size_t and uintptr_t always having the same
381// type. We keep this definition for the time being, to avoid unnecessary noise.
382
383#define __INTPTR_TYPE__ __PTRDIFF_TYPE__
384#define __INTPTR_MIN__ __PTRDIFF_MIN__
385#define __INTPTR_MAX__ __PTRDIFF_MAX__
386#define __UINTPTR_TYPE__ __SIZE_TYPE__
387#define __UINTPTR_MAX__ __SIZE_MAX__
388
389#define __PRIdPTR__ "zd"
390#define __PRIiPTR__ "zi"
391#define __PRIuPTR__ "zu"
392#define __PRIoPTR__ "zo"
393#define __PRIxPTR__ "zx"
394#define __PRIXPTR__ "zX"
395
396#define __SCNdPTR__ "zd"
397#define __SCNiPTR__ "zi"
398#define __SCNuPTR__ "zu"
399#define __SCNoPTR__ "zo"
400#define __SCNxPTR__ "zx"
401
402#endif
403
404#if __SIZEOF_LONG_LONG__ != 8
405#error HelenOS expects long long that is 64 bits wide.
406#endif
407
408#ifndef __LLONG_MAX__
409#define __LLONG_MAX__ 0x7fffffffffffffffLL
410#endif
411
412#ifndef __LLONG_MIN__
413#define __LLONG_MIN__ (-__LLONG_MAX__ - 1)
414#endif
415
416#ifndef __ULLONG_MAX__
417#define __ULLONG_MAX__ 0xffffffffffffffffULL
418#endif
419
420#undef __INT64_TYPE__
421#undef __INT64_C
422#undef __INT64_C_SUFFIX__
423#undef __INT64_MIN__
424#undef __INT64_MAX__
425
426#define __INT64_TYPE__ long long
427#define __INT64_C(x) x##LL
428#define __INT64_MIN__ __LLONG_MIN__
429#define __INT64_MAX__ __LLONG_MAX__
430
431#undef __UINT64_TYPE__
432#undef __UINT64_C
433#undef __UINT64_C_SUFFIX__
434#undef __UINT64_MIN__
435#undef __UINT64_MAX__
436
437#define __UINT64_TYPE__ unsigned long long
438#define __UINT64_C(x) x##ULL
439#define __UINT64_MAX__ __ULLONG_MAX__
440
441#undef __PRId64__
442#undef __PRIi64__
443#undef __PRIu64__
444#undef __PRIo64__
445#undef __PRIx64__
446#undef __PRIX64__
447
448#define __PRId64__ "lld"
449#define __PRIi64__ "lli"
450#define __PRIu64__ "llu"
451#define __PRIo64__ "llo"
452#define __PRIx64__ "llx"
453#define __PRIX64__ "llX"
454
455#undef __SCNd64__
456#undef __SCNi64__
457#undef __SCNu64__
458#undef __SCNo64__
459#undef __SCNx64__
460
461#define __SCNd64__ "lld"
462#define __SCNi64__ "lli"
463#define __SCNu64__ "llu"
464#define __SCNo64__ "llo"
465#define __SCNx64__ "llx"
466
467#if !defined(__SIZE_TYPE__) || !defined(__SIZE_MAX__)
468#error HelenOS expects __SIZE_TYPE__ and __SIZE_MAX__ \
469 to be defined by the toolchain.
470#endif
471
472#if !defined(__PTRDIFF_TYPE__) || !defined(__PTRDIFF_MAX__)
473#error HelenOS expects __PTRDIFF_TYPE__ and __PTRDIFF_MAX__ \
474 to be defined by the toolchain.
475#endif
476
477#ifndef __PTRDIFF_MIN__
478#define __PTRDIFF_MIN__ (-__PTRDIFF_MAX__ - 1)
479#endif
480
481#if !defined(__WCHAR_TYPE__) || !defined(__WCHAR_MAX__)
482#error HelenOS expects __WCHAR_TYPE__ and __WCHAR_MAX__ \
483 to be defined by the toolchain.
484#endif
485
486#undef __WCHAR_SIGNED__
487#undef __WCHAR_UNSIGNED__
488
489#if __WCHAR_MAX__ == __INT32_MAX__
490#define __WCHAR_SIGNED__ 1
491#elif __WCHAR_MAX__ == __UINT32_MAX__
492#define __WCHAR_UNSIGNED__ 1
493#else
494#error HelenOS expects __WCHAR_TYPE__ to be 32 bits wide.
495#endif
496
497#ifndef __WCHAR_MIN__
498#ifdef __WCHAR_UNSIGNED__
499#define __WCHAR_MIN__ 0
500#else
501#define __WCHAR_MIN__ (-__WCHAR_MAX__ - 1)
502#endif
503#endif
504
505#if !defined(__WINT_TYPE__) || !defined(__WINT_WIDTH__)
506#error HelenOS expects __WINT_TYPE__ and __WINT_WIDTH__ \
507 to be defined by the toolchain.
508#endif
509
510#if __WINT_WIDTH__ != 32
511#error HelenOS expects __WINT_TYPE__ to be 32 bits wide.
512#endif
513
514#undef __WINT_SIGNED__
515#undef __WINT_UNSIGNED__
516
517#if __WINT_MAX__ == __INT32_MAX__
518#define __WINT_SIGNED__ 1
519#elif __WINT_MAX__ == __UINT32_MAX__
520#define __WINT_UNSIGNED__ 1
521#elif defined(__WINT_MAX__)
522#error Unrecognized value of __WINT_MAX__
523#endif
524
525#ifndef __WINT_MAX__
526#ifdef __WINT_UNSIGNED__
527#define __WINT_MAX__ 0xffffffffU
528#else
529#define __WINT_MAX__ 0x7fffffff
530#endif
531#endif
532
533#ifndef __WINT_MIN__
534#ifdef __WINT_UNSIGNED__
535#define __WINT_MIN__ 0
536#else
537#define __WINT_MIN__ (-__WINT_MAX__ - 1)
538#endif
539#endif
540
541#ifndef __WINT_EOF__
542#ifdef __WINT_UNSIGNED__
543#define __WINT_EOF__ __WINT_MAX__
544#else
545#define __WINT_EOF__ -1
546#endif
547#endif
548
549#if !defined(__INTMAX_TYPE__) || !defined(__INTMAX_MAX__)
550#error HelenOS expects __INTMAX_TYPE__ and __INTMAX_MAX__ \
551 to be defined by the toolchain.
552#endif
553
554#ifndef __INTMAX_MIN__
555#define __INTMAX_MIN__ (-__INTMAX_MAX__ - 1)
556#endif
557
558#ifndef __INTMAX_C
559#ifndef __INTMAX_C_SUFFIX__
560#error HelenOS expects __INTMAX_C or __INTMAX_C_SUFFIX__ \
561 to be defined by the toolchain.
562#endif
563#define __INTMAX_C__(x, y) x##y
564#define __INTMAX_C(x) __INTMAX_C__(x, __INTMAX_C_SUFFIX__)
565#endif
566
567#ifndef __UINTMAX_TYPE__
568#define __UINTMAX_TYPE__ unsigned __INTMAX_TYPE__
569#endif
570
571#ifndef __UINTMAX_C
572#ifdef __UINTMAX_C_SUFFIX__
573#define __UINTMAX_C__(x, y) x##y
574#define __UINTMAX_C(x) __UINTMAX_C__(x, __UINTMAX_C_SUFFIX__)
575#else
576#define __UINTMAX_C(x) __INTMAX_C(x##U)
577#endif
578#endif
579
580#ifndef __UINTMAX_MAX__
581#define ___UNSIGNED_INTMAX_MAX___(x) x##U
582#define __UINTMAX_MAX__ (2 * ___UNSIGNED_INTMAX_MAX___(__INTMAX_MAX__) + 1)
583#endif
584
585#undef __PRIdMAX__
586#undef __PRIiMAX__
587#undef __PRIuMAX__
588#undef __PRIoMAX__
589#undef __PRIxMAX__
590#undef __PRIXMAX__
591
592#define __PRIdMAX__ "jd"
593#define __PRIiMAX__ "ji"
594#define __PRIuMAX__ "ju"
595#define __PRIoMAX__ "jo"
596#define __PRIxMAX__ "jx"
597#define __PRIXMAX__ "jX"
598
599#undef __SCNdMAX__
600#undef __SCNiMAX__
601#undef __SCNuMAX__
602#undef __SCNoMAX__
603#undef __SCNxMAX__
604
605#define __SCNdMAX__ "jd"
606#define __SCNiMAX__ "ji"
607#define __SCNuMAX__ "ju"
608#define __SCNoMAX__ "jo"
609#define __SCNxMAX__ "jx"
610
611#ifndef __SIZEOF_FLOAT__
612#error HelenOS expects __SIZEOF_FLOAT__ to be defined.
613#endif
614
615#ifndef __SIZEOF_DOUBLE__
616#error HelenOS expects __SIZEOF_DOUBLE__ to be defined.
617#endif
618
619#ifndef __SIZEOF_LONG_DOUBLE__
620#error HelenOS expects __SIZEOF_LONG_DOUBLE__ to be defined.
621#endif
622
623#endif
624
625/** @}
626 */
Note: See TracBrowser for help on using the repository browser.