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