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