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