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