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