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-2021 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     TYnoreturn          = 0x60, // bottom type
147 
148     TYMAX               = 0x61,
149 }
150 
151 alias TYerror = TYint;
152 
153 extern __gshared int TYaarray;                            // D type
154 
155 // These change depending on memory model
156 extern __gshared int TYdelegate, TYdarray;                // D types
157 extern __gshared int TYptrdiff, TYsize, TYsize_t;
158 
159 enum
160 {
161     mTYbasic        = 0xFF,          // bit mask for basic types
162 
163    // Linkage type
164     mTYnear         = 0x0800,
165     mTYfar          = 0x1000,        // seg:offset style pointer
166     mTYcs           = 0x2000,        // in code segment
167     mTYthread       = 0x4000,
168 
169     // Used for symbols going in the __thread_data section for TLS variables for Mach-O 64bit
170     mTYthreadData   = 0x5000,
171 
172     // Used in combination with SCcomdat to output symbols with weak linkage.
173     // Compared to a symbol with only SCcomdat, this allows the symbol to be put
174     // in any section in the object file.
175     mTYweakLinkage  = 0x6000,
176     mTYLINK         = 0x7800,        // all linkage bits
177 
178     mTYloadds       = 0x08000,       // 16 bit Windows LOADDS attribute
179     mTYexport       = 0x10000,
180     mTYweak         = 0x00000,
181     mTYimport       = 0x20000,
182     mTYnaked        = 0x40000,
183     mTYMOD          = 0x78000,       // all modifier bits
184 
185     // Modifiers to basic types
186 
187     mTYarrayhandle  = 0x0,
188     mTYconst        = 0x100,
189     mTYvolatile     = 0x200,
190     mTYrestrict     = 0,             // BUG: add for C99
191     mTYmutable      = 0,             // need to add support
192     mTYunaligned    = 0,             // non-zero for PowerPC
193 
194     mTYimmutable    = 0x00080000,    // immutable data
195     mTYshared       = 0x00100000,    // shared data
196     mTYnothrow      = 0x00200000,    // nothrow function
197 
198     // SROA types
199     mTYxmmgpr       = 0x00400000,    // first slice in XMM register, the other in GPR
200     mTYgprxmm       = 0x00800000,    // first slice in GPR register, the other in XMM
201 
202     mTYnoret        = 0x01000000,    // function has no return
203     mTYtransu       = 0x01000000,    // transparent union
204     mTYfar16        = 0x01000000,
205     mTYstdcall      = 0x02000000,
206     mTYfastcall     = 0x04000000,
207     mTYinterrupt    = 0x08000000,
208     mTYcdecl        = 0x10000000,
209     mTYpascal       = 0x20000000,
210     mTYsyscall      = 0x40000000,
211     mTYjava         = 0x80000000,
212 
213     mTYTFF          = 0xFF000000,
214 }
215 
216 pure
217 tym_t tybasic(tym_t ty) { return ty & mTYbasic; }
218 
219 /* Flags in tytab[] array       */
220 extern __gshared uint[256] tytab;
221 enum
222 {
223     TYFLptr         = 1,
224     TYFLreal        = 2,
225     TYFLintegral    = 4,
226     TYFLcomplex     = 8,
227     TYFLimaginary   = 0x10,
228     TYFLuns         = 0x20,
229     TYFLmptr        = 0x40,
230     TYFLfv          = 0x80,       // TYfptr || TYvptr
231 
232     TYFLpascal      = 0x200,      // callee cleans up stack
233     TYFLrevparam    = 0x400,      // function parameters are reversed
234     TYFLnullptr     = 0x800,
235     TYFLshort       = 0x1000,
236     TYFLaggregate   = 0x2000,
237     TYFLfunc        = 0x4000,
238     TYFLref         = 0x8000,
239     TYFLsimd        = 0x20000,    // SIMD vector type
240     TYFLfarfunc     = 0x100,      // __far functions (for segmented architectures)
241     TYFLxmmreg      = 0x10000,    // can be put in XMM register
242 }
243 
244 /* Array to give the size in bytes of a type, -1 means error    */
245 extern __gshared byte[256] _tysize;
246 extern __gshared byte[256] _tyalignsize;
247 
248 // Give size of type
249 byte tysize(tym_t ty)      { return _tysize[ty & 0xFF]; }
250 byte tyalignsize(tym_t ty) { return _tyalignsize[ty & 0xFF]; }
251 
252 
253 /* Groupings of types   */
254 
255 uint tyintegral(tym_t ty) { return tytab[ty & 0xFF] & TYFLintegral; }
256 
257 uint tyarithmetic(tym_t ty) { return tytab[ty & 0xFF] & (TYFLintegral | TYFLreal | TYFLimaginary | TYFLcomplex); }
258 
259 uint tyaggregate(tym_t ty) { return tytab[ty & 0xFF] & TYFLaggregate; }
260 
261 uint tyscalar(tym_t ty) { return tytab[ty & 0xFF] & (TYFLintegral | TYFLreal | TYFLimaginary | TYFLcomplex | TYFLptr | TYFLmptr | TYFLnullptr | TYFLref); }
262 
263 uint tyfloating(tym_t ty) { return tytab[ty & 0xFF] & (TYFLreal | TYFLimaginary | TYFLcomplex); }
264 
265 uint tyimaginary(tym_t ty) { return tytab[ty & 0xFF] & TYFLimaginary; }
266 
267 uint tycomplex(tym_t ty) { return tytab[ty & 0xFF] & TYFLcomplex; }
268 
269 uint tyreal(tym_t ty) { return tytab[ty & 0xFF] & TYFLreal; }
270 
271 // Fits into 64 bit register
272 bool ty64reg(tym_t ty) { return tytab[ty & 0xFF] & (TYFLintegral | TYFLptr | TYFLref) && tysize(ty) <= _tysize[TYnptr]; }
273 
274 // Can go in XMM floating point register
275 uint tyxmmreg(tym_t ty) { return tytab[ty & 0xFF] & TYFLxmmreg; }
276 
277 // Is a vector type
278 bool tyvector(tym_t ty) { return tybasic(ty) >= TYfloat4 && tybasic(ty) <= TYullong4; }
279 
280 /* Types that are chars or shorts       */
281 uint tyshort(tym_t ty) { return tytab[ty & 0xFF] & TYFLshort; }
282 
283 /* Detect TYlong or TYulong     */
284 bool tylong(tym_t ty) { return tybasic(ty) == TYlong || tybasic(ty) == TYulong; }
285 
286 /* Use to detect a pointer type */
287 uint typtr(tym_t ty) { return tytab[ty & 0xFF] & TYFLptr; }
288 
289 /* Use to detect a reference type */
290 uint tyref(tym_t ty) { return tytab[ty & 0xFF] & TYFLref; }
291 
292 /* Use to detect a pointer type or a member pointer     */
293 uint tymptr(tym_t ty) { return tytab[ty & 0xFF] & (TYFLptr | TYFLmptr); }
294 
295 // Use to detect a nullptr type or a member pointer
296 uint tynullptr(tym_t ty) { return tytab[ty & 0xFF] & TYFLnullptr; }
297 
298 /* Detect TYfptr or TYvptr      */
299 uint tyfv(tym_t ty) { return tytab[ty & 0xFF] & TYFLfv; }
300 
301 /* All data types that fit in exactly 8 bits    */
302 bool tybyte(tym_t ty) { return tysize(ty) == 1; }
303 
304 /* Types that fit into a single machine register        */
305 bool tyreg(tym_t ty) { return tysize(ty) <= _tysize[TYnptr]; }
306 
307 /* Detect function type */
308 uint tyfunc(tym_t ty) { return tytab[ty & 0xFF] & TYFLfunc; }
309 
310 /* Detect function type where parameters are pushed left to right    */
311 uint tyrevfunc(tym_t ty) { return tytab[ty & 0xFF] & TYFLrevparam; }
312 
313 /* Detect uint types */
314 uint tyuns(tym_t ty) { return tytab[ty & 0xFF] & (TYFLuns | TYFLptr); }
315 
316 /* Target dependent info        */
317 alias TYoffset = TYuint;         // offset to an address
318 
319 /* Detect cpp function type (callee cleans up stack)    */
320 uint typfunc(tym_t ty) { return tytab[ty & 0xFF] & TYFLpascal; }
321 
322 /* Array to convert a type to its unsigned equivalent   */
323 extern __gshared tym_t[256] tytouns;
324 tym_t touns(tym_t ty) { return tytouns[ty & 0xFF]; }
325 
326 /* Determine if TYffunc or TYfpfunc (a far function) */
327 uint tyfarfunc(tym_t ty) { return tytab[ty & 0xFF] & TYFLfarfunc; }
328 
329 // Determine if parameter is a SIMD vector type
330 uint tysimd(tym_t ty) { return tytab[ty & 0xFF] & TYFLsimd; }
331 
332 /* Determine relaxed type       */
333 extern __gshared ubyte[TYMAX] _tyrelax;
334 uint tyrelax(tym_t ty) { return _tyrelax[tybasic(ty)]; }
335 
336 
337 /* Determine functionally equivalent type       */
338 extern __gshared ubyte[TYMAX] tyequiv;
339 
340 /* Give an ascii string for a type      */
341 extern (C) { extern __gshared const(char)*[TYMAX] tystring; }
342 
343 /* Debugger value for type      */
344 extern __gshared ubyte[TYMAX] dttab;
345 extern __gshared ushort[TYMAX] dttab4;
346 
347 
348 bool I16() { return _tysize[TYnptr] == 2; }
349 bool I32() { return _tysize[TYnptr] == 4; }
350 bool I64() { return _tysize[TYnptr] == 8; }
351