1 /***
2  * D compatible types that correspond to various basic types in associated
3  * C and C++ compilers.
4  *
5  * Copyright: Copyright Sean Kelly 2005 - 2009.
6  * License: Distributed under the
7  *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
8  *    (See accompanying file LICENSE)
9  * Authors:   Sean Kelly
10  * Source:    $(DRUNTIMESRC core/stdc/_config.d)
11  * Standards: ISO/IEC 9899:1999 (E)
12  */
13 
14 /* NOTE: This file has been patched from the original DMD distribution to
15  * work with the GDC compiler.
16  */
17 module core.stdc.config;
18 
version(StdDdoc)19 version (StdDdoc)
20 {
21     private
22     {
23         version (Posix)
24             enum isPosix = true;
25         else
26             enum isPosix = false;
27         static if (isPosix && (void*).sizeof > int.sizeof)
28         {
29             alias ddoc_long = long;
30             alias ddoc_ulong = ulong;
31         }
32         else
33         {
34             alias ddoc_long = int;
35             alias ddoc_ulong = uint;
36         }
37         struct ddoc_complex(T) { T re; T im; };
38     }
39 
40     /***
41      * Used for a signed integer type that corresponds in size to the associated
42      * C compiler's `long` type.
43      */
44     alias c_long = ddoc_long;
45 
46     /***
47      * Used for an unsigned integer type that corresponds in size to the associated
48      * C compiler's `unsigned long` type.
49      */
50     alias c_ulong = ddoc_ulong;
51 
52     /***
53      * Used for a signed integer type that corresponds in size and mangling to the associated
54      * C++ compiler's `long` type.
55      */
56     alias cpp_long = c_long;
57 
58     /***
59      * Used for an unsigned integer type that corresponds in size and mangling to the associated
60      * C++ compiler's `unsigned long` type.
61      */
62     alias cpp_ulong = c_ulong;
63 
64     /***
65      * Used for a signed integer type that corresponds in size and mangling to the associated
66      * C++ compiler's `long long` type.
67      */
68     alias cpp_longlong = long;
69 
70     /***
71      * Used for an unsigned integer type that corresponds in size and mangling to the associated
72      * C++ compiler's `unsigned long long` type.
73      */
74     alias cpp_ulonglong = ulong;
75 
76     /***
77      * Used for a floating point type that corresponds in size and mangling to the associated
78      * C++ compiler's `long double` type.
79      */
80     alias c_long_double = real;
81 
82     /***
83      * Used for an unsigned integer type that corresponds in size and mangling to the associated
84      * C++ compiler's `size_t` type.
85      */
86     alias cpp_size_t = size_t;
87 
88     /***
89      * Used for a signed integer type that corresponds in size and mangling to the associated
90      * C++ compiler's `ptrdiff_t` type.
91      */
92     alias cpp_ptrdiff_t = ptrdiff_t;
93 
94     /***
95      * Used for a complex floating point type that corresponds in size and ABI to the associated
96      * C compiler's `_Complex float` type.
97      */
98     alias c_complex_float = ddoc_complex!float;
99 
100     /***
101      * Used for a complex floating point type that corresponds in size and ABI to the associated
102      * C compiler's `_Complex double` type.
103      */
104     alias c_complex_double = ddoc_complex!double;
105 
106     /***
107      * Used for a complex floating point type that corresponds in size and ABI to the associated
108      * C compiler's `_Complex long double` type.
109      */
110     alias c_complex_real = ddoc_complex!real;
111 }
112 else
113 {
114 
115 version (OSX)
116     version = Darwin;
117 else version (iOS)
118     version = Darwin;
119 else version (TVOS)
120     version = Darwin;
121 else version (WatchOS)
122     version = Darwin;
123 
version(GNU)124 version (GNU)
125 {
126     import gcc.builtins;
127 
128     alias __builtin_clong  c_long;
129     alias __builtin_culong c_ulong;
130 
131     enum __c_long  : __builtin_clong;
132     enum __c_ulong : __builtin_culong;
133 
134     alias __c_long  cpp_long;
135     alias __c_ulong cpp_ulong;
136 
137     enum __c_longlong  : __builtin_clonglong;
138     enum __c_ulonglong : __builtin_culonglong;
139 
140     alias __c_longlong  cpp_longlong;
141     alias __c_ulonglong cpp_ulonglong;
142 }
version(Windows)143 else version (Windows)
144 {
145     enum __c_long  : int;
146     enum __c_ulong : uint;
147 
148     alias int   c_long;
149     alias uint  c_ulong;
150 
151     alias __c_long   cpp_long;
152     alias __c_ulong  cpp_ulong;
153 
154     alias long  cpp_longlong;
155     alias ulong cpp_ulonglong;
156 }
version(Posix)157 else version (Posix)
158 {
159   static if ( (void*).sizeof > int.sizeof )
160   {
161     enum __c_longlong  : long;
162     enum __c_ulonglong : ulong;
163 
164     alias long  c_long;
165     alias ulong c_ulong;
166 
167     alias long   cpp_long;
168     alias ulong  cpp_ulong;
169 
170     alias __c_longlong  cpp_longlong;
171     alias __c_ulonglong cpp_ulonglong;
172   }
173   else
174   {
175     enum __c_long  : int;
176     enum __c_ulong : uint;
177 
178     alias int   c_long;
179     alias uint  c_ulong;
180 
181     alias __c_long   cpp_long;
182     alias __c_ulong  cpp_ulong;
183 
184     alias long  cpp_longlong;
185     alias ulong cpp_ulonglong;
186   }
187 }
188 
189 version (GNU)
190     alias c_long_double = real;
191 else version (LDC)
192     alias c_long_double = real; // 64-bit real for MSVC targets
version(SDC)193 else version (SDC)
194 {
195     version (X86)
196         alias c_long_double = real;
197     else version (X86_64)
198         alias c_long_double = real;
199 }
version(CRuntime_Microsoft)200 else version (CRuntime_Microsoft)
201 {
202     /* long double is 64 bits, not 80 bits, but is mangled differently
203      * than double. To distinguish double from long double, create a wrapper to represent
204      * long double, then recognize that wrapper specially in the compiler
205      * to generate the correct name mangling and correct function call/return
206      * ABI conformance.
207      */
208     enum __c_long_double : double;
209 
210     alias __c_long_double c_long_double;
211 }
version(DigitalMars)212 else version (DigitalMars)
213 {
214     version (X86)
215     {
216         alias real c_long_double;
217     }
218     else version (X86_64)
219     {
220         version (linux)
221             alias real c_long_double;
222         else version (FreeBSD)
223             alias real c_long_double;
224         else version (OpenBSD)
225             alias real c_long_double;
226         else version (NetBSD)
227             alias real c_long_double;
228         else version (DragonFlyBSD)
229             alias real c_long_double;
230         else version (Solaris)
231             alias real c_long_double;
232         else version (Darwin)
233             alias real c_long_double;
234     }
235 }
236 
237 static assert(is(c_long_double), "c_long_double needs to be declared for this platform/architecture.");
238 
version(Darwin)239 version (Darwin)
240 {
241     alias cpp_size_t = cpp_ulong;
242     version (D_LP64)
243         alias cpp_ptrdiff_t = cpp_long;
244     else
245         alias cpp_ptrdiff_t = ptrdiff_t;
246 }
247 else
248 {
249     alias cpp_size_t = size_t;
250     alias cpp_ptrdiff_t = ptrdiff_t;
251 }
252 
253 // ABI layout of native complex types.
_Complex(T)254 private struct _Complex(T)
255 {
256     T re;
257     T im;
258 }
259 
260 enum __c_complex_float  : _Complex!float;
261 enum __c_complex_double : _Complex!double;
262 enum __c_complex_real   : _Complex!c_long_double;
263 
264 alias c_complex_float = __c_complex_float;
265 alias c_complex_double = __c_complex_double;
266 alias c_complex_real = __c_complex_real;
267 }
268