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     // SROA types
192     mTYxmmgpr       = 0x00400000,    // first slice in XMM register, the other in GPR
193     mTYgprxmm       = 0x00800000,    // first slice in GPR register, the other in XMM
194 
195     // Used only by C/C++ compiler
196 //#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_DRAGONFLYBSD || TARGET_SOLARIS
197     mTYnoret        = 0x01000000,    // function has no return
198     mTYtransu       = 0x01000000,    // transparent union
199 //#else
200     mTYfar16        = 0x01000000,
201 //#endif
202     mTYstdcall      = 0x02000000,
203     mTYfastcall     = 0x04000000,
204     mTYinterrupt    = 0x08000000,
205     mTYcdecl        = 0x10000000,
206     mTYpascal       = 0x20000000,
207     mTYsyscall      = 0x40000000,
208     mTYjava         = 0x80000000,
209 
210 //#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_DRAGONFLYBSD || TARGET_SOLARIS
211 //    mTYTFF          = 0xFE000000,
212 //#else
213     mTYTFF          = 0xFF000000,
214 //#endif
215 }
216 
217 pure
218 tym_t tybasic(tym_t ty) { return ty & mTYbasic; }
219 
220 /* Flags in tytab[] array       */
221 extern __gshared uint[256] tytab;
222 enum
223 {
224     TYFLptr         = 1,
225     TYFLreal        = 2,
226     TYFLintegral    = 4,
227     TYFLcomplex     = 8,
228     TYFLimaginary   = 0x10,
229     TYFLuns         = 0x20,
230     TYFLmptr        = 0x40,
231     TYFLfv          = 0x80,       // TYfptr || TYvptr
232 
233     TYFLpascal      = 0x200,      // callee cleans up stack
234     TYFLrevparam    = 0x400,      // function parameters are reversed
235     TYFLnullptr     = 0x800,
236     TYFLshort       = 0x1000,
237     TYFLaggregate   = 0x2000,
238     TYFLfunc        = 0x4000,
239     TYFLref         = 0x8000,
240     TYFLsimd        = 0x20000,    // SIMD vector type
241     TYFLfarfunc     = 0x100,      // __far functions (for segmented architectures)
242     TYFLxmmreg      = 0x10000,    // can be put in XMM register
243 }
244 
245 /* Array to give the size in bytes of a type, -1 means error    */
246 extern __gshared byte[256] _tysize;
247 extern __gshared byte[256] _tyalignsize;
248 
249 // Give size of type
250 byte tysize(tym_t ty)      { return _tysize[ty & 0xFF]; }
251 byte tyalignsize(tym_t ty) { return _tyalignsize[ty & 0xFF]; }
252 
253 
254 /* Groupings of types   */
255 
256 uint tyintegral(tym_t ty) { return tytab[ty & 0xFF] & TYFLintegral; }
257 
258 uint tyarithmetic(tym_t ty) { return tytab[ty & 0xFF] & (TYFLintegral | TYFLreal | TYFLimaginary | TYFLcomplex); }
259 
260 uint tyaggregate(tym_t ty) { return tytab[ty & 0xFF] & TYFLaggregate; }
261 
262 uint tyscalar(tym_t ty) { return tytab[ty & 0xFF] & (TYFLintegral | TYFLreal | TYFLimaginary | TYFLcomplex | TYFLptr | TYFLmptr | TYFLnullptr | TYFLref); }
263 
264 uint tyfloating(tym_t ty) { return tytab[ty & 0xFF] & (TYFLreal | TYFLimaginary | TYFLcomplex); }
265 
266 uint tyimaginary(tym_t ty) { return tytab[ty & 0xFF] & TYFLimaginary; }
267 
268 uint tycomplex(tym_t ty) { return tytab[ty & 0xFF] & TYFLcomplex; }
269 
270 uint tyreal(tym_t ty) { return tytab[ty & 0xFF] & TYFLreal; }
271 
272 // Fits into 64 bit register
273 bool ty64reg(tym_t ty) { return tytab[ty & 0xFF] & (TYFLintegral | TYFLptr | TYFLref) && tysize(ty) <= _tysize[TYnptr]; }
274 
275 // Can go in XMM floating point register
276 uint tyxmmreg(tym_t ty) { return tytab[ty & 0xFF] & TYFLxmmreg; }
277 
278 // Is a vector type
279 bool tyvector(tym_t ty) { return tybasic(ty) >= TYfloat4 && tybasic(ty) <= TYullong4; }
280 
281 /* Types that are chars or shorts       */
282 uint tyshort(tym_t ty) { return tytab[ty & 0xFF] & TYFLshort; }
283 
284 /* Detect TYlong or TYulong     */
285 bool tylong(tym_t ty) { return tybasic(ty) == TYlong || tybasic(ty) == TYulong; }
286 
287 /* Use to detect a pointer type */
288 uint typtr(tym_t ty) { return tytab[ty & 0xFF] & TYFLptr; }
289 
290 /* Use to detect a reference type */
291 uint tyref(tym_t ty) { return tytab[ty & 0xFF] & TYFLref; }
292 
293 /* Use to detect a pointer type or a member pointer     */
294 uint tymptr(tym_t ty) { return tytab[ty & 0xFF] & (TYFLptr | TYFLmptr); }
295 
296 // Use to detect a nullptr type or a member pointer
297 uint tynullptr(tym_t ty) { return tytab[ty & 0xFF] & TYFLnullptr; }
298 
299 /* Detect TYfptr or TYvptr      */
300 uint tyfv(tym_t ty) { return tytab[ty & 0xFF] & TYFLfv; }
301 
302 /* All data types that fit in exactly 8 bits    */
303 bool tybyte(tym_t ty) { return tysize(ty) == 1; }
304 
305 /* Types that fit into a single machine register        */
306 bool tyreg(tym_t ty) { return tysize(ty) <= _tysize[TYnptr]; }
307 
308 /* Detect function type */
309 uint tyfunc(tym_t ty) { return tytab[ty & 0xFF] & TYFLfunc; }
310 
311 /* Detect function type where parameters are pushed left to right    */
312 uint tyrevfunc(tym_t ty) { return tytab[ty & 0xFF] & TYFLrevparam; }
313 
314 /* Detect uint types */
315 uint tyuns(tym_t ty) { return tytab[ty & 0xFF] & (TYFLuns | TYFLptr); }
316 
317 /* Target dependent info        */
318 alias TYoffset = TYuint;         // offset to an address
319 
320 /* Detect cpp function type (callee cleans up stack)    */
321 uint typfunc(tym_t ty) { return tytab[ty & 0xFF] & TYFLpascal; }
322 
323 /* Array to convert a type to its unsigned equivalent   */
324 extern __gshared tym_t[256] tytouns;
325 tym_t touns(tym_t ty) { return tytouns[ty & 0xFF]; }
326 
327 /* Determine if TYffunc or TYfpfunc (a far function) */
328 uint tyfarfunc(tym_t ty) { return tytab[ty & 0xFF] & TYFLfarfunc; }
329 
330 // Determine if parameter is a SIMD vector type
331 uint tysimd(tym_t ty) { return tytab[ty & 0xFF] & TYFLsimd; }
332 
333 /* Determine relaxed type       */
334 extern __gshared ubyte[TYMAX] _tyrelax;
335 uint tyrelax(tym_t ty) { return _tyrelax[tybasic(ty)]; }
336 
337 
338 /* Determine functionally equivalent type       */
339 extern __gshared ubyte[TYMAX] tyequiv;
340 
341 /* Give an ascii string for a type      */
342 extern (C) { extern __gshared const(char)*[TYMAX] tystring; }
343 
344 /* Debugger value for type      */
345 extern __gshared ubyte[TYMAX] dttab;
346 extern __gshared ushort[TYMAX] dttab4;
347 
348 
349 bool I16() { return _tysize[TYnptr] == 2; }
350 bool I32() { return _tysize[TYnptr] == 4; }
351 bool I64() { return _tysize[TYnptr] == 8; }
352