1 /**
2 * Compiler implementation of the
3 * $(LINK2 http://www.dlang.org, D programming language).
4 *
5 * Copyright: Copyright (C) 1983-1998 by Symantec
6 * Copyright (C) 1999-2020 by The D Language Foundation, All Rights Reserved
7 * Authors: $(LINK2 http://www.digitalmars.com, Walter Bright)
8 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
9 * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/backend/ty.d, backend/_ty.d)
10 */
11
12 module dmd.backend.ty;
13
14 // Online documentation: https://dlang.org/phobos/dmd_backend_ty.html
15
16 extern (C++):
17 @nogc:
18 nothrow:
19
20 alias tym_t = uint;
21
22 /*****************************************
23 * Data types.
24 * (consists of basic type + modifier bits)
25 */
26
27 // Basic types.
28 // casttab[][] in exp2.c depends on the order of this
29 // typromo[] in cpp.c depends on the order too
30
31 enum
32 {
33 TYbool = 0,
34 TYchar = 1,
35 TYschar = 2, // signed char
36 TYuchar = 3, // unsigned char
37 TYchar8 = 4,
38 TYchar16 = 5,
39 TYshort = 6,
40 TYwchar_t = 7,
41 TYushort = 8, // unsigned short
42 TYenum = 9, // enumeration value
43 TYint = 0xA,
44 TYuint = 0xB, // unsigned
45 TYlong = 0xC,
46 TYulong = 0xD, // unsigned long
47 TYdchar = 0xE, // 32 bit Unicode char
48 TYllong = 0xF, // 64 bit long
49 TYullong = 0x10, // 64 bit unsigned long
50 TYfloat = 0x11, // 32 bit real
51 TYdouble = 0x12, // 64 bit real
52
53 // long double is mapped to either of the following at runtime:
54 TYdouble_alias = 0x13, // 64 bit real (but distinct for overload purposes)
55 TYldouble = 0x14, // 80 bit real
56
57 // Add imaginary and complex types for D and C99
58 TYifloat = 0x15,
59 TYidouble = 0x16,
60 TYildouble = 0x17,
61 TYcfloat = 0x18,
62 TYcdouble = 0x19,
63 TYcldouble = 0x1A,
64
65 TYnullptr = 0x1C,
66 TYnptr = 0x1D, // data segment relative pointer
67 TYref = 0x24, // reference to another type
68 TYvoid = 0x25,
69 TYstruct = 0x26, // watch tyaggregate()
70 TYarray = 0x27, // watch tyaggregate()
71 TYnfunc = 0x28, // near C func
72 TYnpfunc = 0x2A, // near Cpp func
73 TYnsfunc = 0x2C, // near stdcall func
74 TYifunc = 0x2E, // interrupt func
75 TYptr = 0x33, // generic pointer type
76 TYmfunc = 0x37, // NT C++ member func
77 TYjfunc = 0x38, // LINK.d D function
78 TYhfunc = 0x39, // C function with hidden parameter
79 TYnref = 0x3A, // near reference
80
81 TYcent = 0x3C, // 128 bit signed integer
82 TYucent = 0x3D, // 128 bit unsigned integer
83
84 // Used for segmented architectures
85 TYsptr = 0x1E, // stack segment relative pointer
86 TYcptr = 0x1F, // code segment relative pointer
87 TYf16ptr = 0x20, // special OS/2 far16 pointer
88 TYfptr = 0x21, // far pointer (has segment and offset)
89 TYhptr = 0x22, // huge pointer (has segment and offset)
90 TYvptr = 0x23, // __handle pointer (has segment and offset)
91 TYffunc = 0x29, // far C func
92 TYfpfunc = 0x2B, // far Cpp func
93 TYfsfunc = 0x2D, // far stdcall func
94 TYf16func = 0x34, // _far16 _pascal function
95 TYnsysfunc = 0x35, // near __syscall func
96 TYfsysfunc = 0x36, // far __syscall func
97 TYfref = 0x3B, // far reference
98
99 // Used for C++ compiler
100 TYmemptr = 0x2F, // pointer to member
101 TYident = 0x30, // type-argument
102 TYtemplate = 0x31, // unexpanded class template
103 TYvtshape = 0x32, // virtual function table
104
105 // SIMD 16 byte vector types // D type
106 TYfloat4 = 0x3E, // float[4]
107 TYdouble2 = 0x3F, // double[2]
108 TYschar16 = 0x40, // byte[16]
109 TYuchar16 = 0x41, // ubyte[16]
110 TYshort8 = 0x42, // short[8]
111 TYushort8 = 0x43, // ushort[8]
112 TYlong4 = 0x44, // int[4]
113 TYulong4 = 0x45, // uint[4]
114 TYllong2 = 0x46, // long[2]
115 TYullong2 = 0x47, // ulong[2]
116
117 // SIMD 32 byte vector types // D type
118 TYfloat8 = 0x48, // float[8]
119 TYdouble4 = 0x49, // double[4]
120 TYschar32 = 0x4A, // byte[32]
121 TYuchar32 = 0x4B, // ubyte[32]
122 TYshort16 = 0x4C, // short[16]
123 TYushort16 = 0x4D, // ushort[16]
124 TYlong8 = 0x4E, // int[8]
125 TYulong8 = 0x4F, // uint[8]
126 TYllong4 = 0x50, // long[4]
127 TYullong4 = 0x51, // ulong[4]
128
129 // SIMD 64 byte vector types // D type
130 TYfloat16 = 0x52, // float[16]
131 TYdouble8 = 0x53, // double[8]
132 TYschar64 = 0x54, // byte[64]
133 TYuchar64 = 0x55, // ubyte[64]
134 TYshort32 = 0x56, // short[32]
135 TYushort32 = 0x57, // ushort[32]
136 TYlong16 = 0x58, // int[16]
137 TYulong16 = 0x59, // uint[16]
138 TYllong8 = 0x5A, // long[8]
139 TYullong8 = 0x5B, // ulong[8]
140
141 TYsharePtr = 0x5C, // pointer to shared data
142 TYimmutPtr = 0x5D, // pointer to immutable data
143 TYfgPtr = 0x5E, // GS: pointer (I32) FS: pointer (I64)
144 TYrestrictPtr = 0x5F, // restrict pointer
145
146 TYMAX = 0x60,
147 }
148
149 alias TYerror = TYint;
150
151 extern __gshared int TYaarray; // D type
152
153 // These change depending on memory model
154 extern __gshared int TYdelegate, TYdarray; // D types
155 extern __gshared int TYptrdiff, TYsize, TYsize_t;
156
157 enum
158 {
159 mTYbasic = 0xFF, // bit mask for basic types
160
161 // Linkage type
162 mTYnear = 0x0800,
163 mTYfar = 0x1000, // seg:offset style pointer
164 mTYcs = 0x2000, // in code segment
165 mTYthread = 0x4000,
166
167 // Used for symbols going in the __thread_data section for TLS variables for Mach-O 64bit
168 mTYthreadData = 0x5000,
169 mTYLINK = 0x7800, // all linkage bits
170
171 mTYloadds = 0x08000, // 16 bit Windows LOADDS attribute
172 mTYexport = 0x10000,
173 mTYweak = 0x00000,
174 mTYimport = 0x20000,
175 mTYnaked = 0x40000,
176 mTYMOD = 0x78000, // all modifier bits
177
178 // Modifiers to basic types
179
180 mTYarrayhandle = 0x0,
181 mTYconst = 0x100,
182 mTYvolatile = 0x200,
183 mTYrestrict = 0, // BUG: add for C99
184 mTYmutable = 0, // need to add support
185 mTYunaligned = 0, // non-zero for PowerPC
186
187 mTYimmutable = 0x00080000, // immutable data
188 mTYshared = 0x00100000, // shared data
189 mTYnothrow = 0x00200000, // nothrow function
190
191 // Used only by C/C++ compiler
192 //#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_DRAGONFLYBSD || TARGET_SOLARIS
193 mTYnoret = 0x01000000, // function has no return
194 mTYtransu = 0x01000000, // transparent union
195 //#else
196 mTYfar16 = 0x01000000,
197 //#endif
198 mTYstdcall = 0x02000000,
199 mTYfastcall = 0x04000000,
200 mTYinterrupt = 0x08000000,
201 mTYcdecl = 0x10000000,
202 mTYpascal = 0x20000000,
203 mTYsyscall = 0x40000000,
204 mTYjava = 0x80000000,
205
206 //#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_DRAGONFLYBSD || TARGET_SOLARIS
207 // mTYTFF = 0xFE000000,
208 //#else
209 mTYTFF = 0xFF000000,
210 //#endif
211 }
212
213 pure
214 tym_t tybasic(tym_t ty) { return ty & mTYbasic; }
215
216 /* Flags in tytab[] array */
217 extern __gshared uint[256] tytab;
218 enum
219 {
220 TYFLptr = 1,
221 TYFLreal = 2,
222 TYFLintegral = 4,
223 TYFLcomplex = 8,
224 TYFLimaginary = 0x10,
225 TYFLuns = 0x20,
226 TYFLmptr = 0x40,
227 TYFLfv = 0x80, // TYfptr || TYvptr
228
229 TYFLpascal = 0x200, // callee cleans up stack
230 TYFLrevparam = 0x400, // function parameters are reversed
231 TYFLnullptr = 0x800,
232 TYFLshort = 0x1000,
233 TYFLaggregate = 0x2000,
234 TYFLfunc = 0x4000,
235 TYFLref = 0x8000,
236 TYFLsimd = 0x20000, // SIMD vector type
237 TYFLfarfunc = 0x100, // __far functions (for segmented architectures)
238 TYFLxmmreg = 0x10000, // can be put in XMM register
239 }
240
241 /* Array to give the size in bytes of a type, -1 means error */
242 extern __gshared byte[256] _tysize;
243 extern __gshared byte[256] _tyalignsize;
244
245 // Give size of type
246 byte tysize(tym_t ty) { return _tysize[ty & 0xFF]; }
247 byte tyalignsize(tym_t ty) { return _tyalignsize[ty & 0xFF]; }
248
249
250 /* Groupings of types */
251
252 uint tyintegral(tym_t ty) { return tytab[ty & 0xFF] & TYFLintegral; }
253
254 uint tyarithmetic(tym_t ty) { return tytab[ty & 0xFF] & (TYFLintegral | TYFLreal | TYFLimaginary | TYFLcomplex); }
255
256 uint tyaggregate(tym_t ty) { return tytab[ty & 0xFF] & TYFLaggregate; }
257
258 uint tyscalar(tym_t ty) { return tytab[ty & 0xFF] & (TYFLintegral | TYFLreal | TYFLimaginary | TYFLcomplex | TYFLptr | TYFLmptr | TYFLnullptr | TYFLref); }
259
260 uint tyfloating(tym_t ty) { return tytab[ty & 0xFF] & (TYFLreal | TYFLimaginary | TYFLcomplex); }
261
262 uint tyimaginary(tym_t ty) { return tytab[ty & 0xFF] & TYFLimaginary; }
263
264 uint tycomplex(tym_t ty) { return tytab[ty & 0xFF] & TYFLcomplex; }
265
266 uint tyreal(tym_t ty) { return tytab[ty & 0xFF] & TYFLreal; }
267
268 // Fits into 64 bit register
269 bool ty64reg(tym_t ty) { return tytab[ty & 0xFF] & (TYFLintegral | TYFLptr | TYFLref) && tysize(ty) <= _tysize[TYnptr]; }
270
271 // Can go in XMM floating point register
272 uint tyxmmreg(tym_t ty) { return tytab[ty & 0xFF] & TYFLxmmreg; }
273
274 // Is a vector type
275 bool tyvector(tym_t ty) { return tybasic(ty) >= TYfloat4 && tybasic(ty) <= TYullong4; }
276
277 /* Types that are chars or shorts */
278 uint tyshort(tym_t ty) { return tytab[ty & 0xFF] & TYFLshort; }
279
280 /* Detect TYlong or TYulong */
281 bool tylong(tym_t ty) { return tybasic(ty) == TYlong || tybasic(ty) == TYulong; }
282
283 /* Use to detect a pointer type */
284 uint typtr(tym_t ty) { return tytab[ty & 0xFF] & TYFLptr; }
285
286 /* Use to detect a reference type */
287 uint tyref(tym_t ty) { return tytab[ty & 0xFF] & TYFLref; }
288
289 /* Use to detect a pointer type or a member pointer */
290 uint tymptr(tym_t ty) { return tytab[ty & 0xFF] & (TYFLptr | TYFLmptr); }
291
292 // Use to detect a nullptr type or a member pointer
293 uint tynullptr(tym_t ty) { return tytab[ty & 0xFF] & TYFLnullptr; }
294
295 /* Detect TYfptr or TYvptr */
296 uint tyfv(tym_t ty) { return tytab[ty & 0xFF] & TYFLfv; }
297
298 /* All data types that fit in exactly 8 bits */
299 bool tybyte(tym_t ty) { return tysize(ty) == 1; }
300
301 /* Types that fit into a single machine register */
302 bool tyreg(tym_t ty) { return tysize(ty) <= _tysize[TYnptr]; }
303
304 /* Detect function type */
305 uint tyfunc(tym_t ty) { return tytab[ty & 0xFF] & TYFLfunc; }
306
307 /* Detect function type where parameters are pushed left to right */
308 uint tyrevfunc(tym_t ty) { return tytab[ty & 0xFF] & TYFLrevparam; }
309
310 /* Detect uint types */
311 uint tyuns(tym_t ty) { return tytab[ty & 0xFF] & (TYFLuns | TYFLptr); }
312
313 /* Target dependent info */
314 alias TYoffset = TYuint; // offset to an address
315
316 /* Detect cpp function type (callee cleans up stack) */
317 uint typfunc(tym_t ty) { return tytab[ty & 0xFF] & TYFLpascal; }
318
319 /* Array to convert a type to its unsigned equivalent */
320 extern __gshared tym_t[256] tytouns;
321 tym_t touns(tym_t ty) { return tytouns[ty & 0xFF]; }
322
323 /* Determine if TYffunc or TYfpfunc (a far function) */
324 uint tyfarfunc(tym_t ty) { return tytab[ty & 0xFF] & TYFLfarfunc; }
325
326 // Determine if parameter is a SIMD vector type
327 uint tysimd(tym_t ty) { return tytab[ty & 0xFF] & TYFLsimd; }
328
329 /* Determine relaxed type */
330 extern __gshared ubyte[TYMAX] _tyrelax;
331 uint tyrelax(tym_t ty) { return _tyrelax[tybasic(ty)]; }
332
333
334 /* Determine functionally equivalent type */
335 extern __gshared ubyte[TYMAX] tyequiv;
336
337 /* Give an ascii string for a type */
338 extern (C) { extern __gshared const(char)*[TYMAX] tystring; }
339
340 /* Debugger value for type */
341 extern __gshared ubyte[TYMAX] dttab;
342 extern __gshared ushort[TYMAX] dttab4;
343
344
345 bool I16() { return _tysize[TYnptr] == 2; }
346 bool I32() { return _tysize[TYnptr] == 4; }
347 bool I64() { return _tysize[TYnptr] == 8; }
348