1 /** 2 * Define basic types and type masks 3 * 4 * Compiler implementation of the 5 * $(LINK2 https://www.dlang.org, D programming language). 6 * 7 * Copyright: Copyright (C) 1983-1998 by Symantec 8 * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved 9 * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) 10 * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 11 * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/backend/ty.d, backend/_ty.d) 12 */ 13 14 module dmd.backend.ty; 15 16 // Online documentation: https://dlang.org/phobos/dmd_backend_ty.html 17 18 extern (C++): 19 @nogc: 20 nothrow: 21 @safe: 22 23 alias tym_t = uint; 24 25 /***************************************** 26 * Data types. 27 * (consists of basic type + modifier bits) 28 */ 29 30 // Basic types. 31 // casttab[][] in exp2.c depends on the order of this 32 // typromo[] in cpp.c depends on the order too 33 34 enum 35 { 36 TYbool = 0, 37 TYchar = 1, 38 TYschar = 2, // signed char 39 TYuchar = 3, // unsigned char 40 TYchar8 = 4, 41 TYchar16 = 5, 42 TYshort = 6, 43 TYwchar_t = 7, 44 TYushort = 8, // unsigned short 45 TYenum = 9, // enumeration value 46 TYint = 0xA, 47 TYuint = 0xB, // unsigned 48 TYlong = 0xC, 49 TYulong = 0xD, // unsigned long 50 TYdchar = 0xE, // 32 bit Unicode char 51 TYllong = 0xF, // 64 bit long 52 TYullong = 0x10, // 64 bit unsigned long 53 TYfloat = 0x11, // 32 bit real 54 TYdouble = 0x12, // 64 bit real 55 56 // long double is mapped to either of the following at runtime: 57 TYdouble_alias = 0x13, // 64 bit real (but distinct for overload purposes) 58 TYldouble = 0x14, // 80 bit real 59 60 // Add imaginary and complex types for D and C99 61 TYifloat = 0x15, 62 TYidouble = 0x16, 63 TYildouble = 0x17, 64 TYcfloat = 0x18, 65 TYcdouble = 0x19, 66 TYcldouble = 0x1A, 67 68 TYnullptr = 0x1C, 69 TYnptr = 0x1D, // data segment relative pointer 70 TYref = 0x24, // reference to another type 71 TYvoid = 0x25, 72 TYstruct = 0x26, // watch tyaggregate() 73 TYarray = 0x27, // watch tyaggregate() 74 TYnfunc = 0x28, // near C func 75 TYnpfunc = 0x2A, // near Cpp func 76 TYnsfunc = 0x2C, // near stdcall func 77 TYifunc = 0x2E, // interrupt func 78 TYptr = 0x33, // generic pointer type 79 TYmfunc = 0x37, // NT C++ member func 80 TYjfunc = 0x38, // LINK.d D function 81 TYhfunc = 0x39, // C function with hidden parameter 82 TYnref = 0x3A, // near reference 83 84 TYcent = 0x3C, // 128 bit signed integer 85 TYucent = 0x3D, // 128 bit unsigned integer 86 87 // Used for segmented architectures 88 TYsptr = 0x1E, // stack segment relative pointer 89 TYcptr = 0x1F, // code segment relative pointer 90 TYf16ptr = 0x20, // special OS/2 far16 pointer 91 TYfptr = 0x21, // far pointer (has segment and offset) 92 TYhptr = 0x22, // huge pointer (has segment and offset) 93 TYvptr = 0x23, // __handle pointer (has segment and offset) 94 TYffunc = 0x29, // far C func 95 TYfpfunc = 0x2B, // far Cpp func 96 TYfsfunc = 0x2D, // far stdcall func 97 TYf16func = 0x34, // _far16 _pascal function 98 TYnsysfunc = 0x35, // near __syscall func 99 TYfsysfunc = 0x36, // far __syscall func 100 TYfref = 0x3B, // far reference 101 102 // Used for C++ compiler 103 TYmemptr = 0x2F, // pointer to member 104 TYident = 0x30, // type-argument 105 TYtemplate = 0x31, // unexpanded class template 106 TYvtshape = 0x32, // virtual function table 107 108 // SIMD 16 byte vector types // D type 109 TYfloat4 = 0x3E, // float[4] 110 TYdouble2 = 0x3F, // double[2] 111 TYschar16 = 0x40, // byte[16] 112 TYuchar16 = 0x41, // ubyte[16] 113 TYshort8 = 0x42, // short[8] 114 TYushort8 = 0x43, // ushort[8] 115 TYlong4 = 0x44, // int[4] 116 TYulong4 = 0x45, // uint[4] 117 TYllong2 = 0x46, // long[2] 118 TYullong2 = 0x47, // ulong[2] 119 120 // SIMD 32 byte vector types // D type 121 TYfloat8 = 0x48, // float[8] 122 TYdouble4 = 0x49, // double[4] 123 TYschar32 = 0x4A, // byte[32] 124 TYuchar32 = 0x4B, // ubyte[32] 125 TYshort16 = 0x4C, // short[16] 126 TYushort16 = 0x4D, // ushort[16] 127 TYlong8 = 0x4E, // int[8] 128 TYulong8 = 0x4F, // uint[8] 129 TYllong4 = 0x50, // long[4] 130 TYullong4 = 0x51, // ulong[4] 131 132 // SIMD 64 byte vector types // D type 133 TYfloat16 = 0x52, // float[16] 134 TYdouble8 = 0x53, // double[8] 135 TYschar64 = 0x54, // byte[64] 136 TYuchar64 = 0x55, // ubyte[64] 137 TYshort32 = 0x56, // short[32] 138 TYushort32 = 0x57, // ushort[32] 139 TYlong16 = 0x58, // int[16] 140 TYulong16 = 0x59, // uint[16] 141 TYllong8 = 0x5A, // long[8] 142 TYullong8 = 0x5B, // ulong[8] 143 144 TYsharePtr = 0x5C, // pointer to shared data 145 TYimmutPtr = 0x5D, // pointer to immutable data 146 TYfgPtr = 0x5E, // GS: pointer (I32) FS: pointer (I64) 147 TYrestrictPtr = 0x5F, // restrict pointer 148 149 TYnoreturn = 0x60, // bottom type 150 151 TYMAX = 0x61, 152 } 153 154 alias TYerror = TYint; 155 156 extern __gshared int TYaarray; // D type 157 158 // These change depending on memory model 159 extern __gshared int TYdelegate, TYdarray; // D types 160 extern __gshared int TYptrdiff, TYsize, TYsize_t; 161 162 enum 163 { 164 mTYbasic = 0xFF, // bit mask for basic types 165 166 // Linkage type 167 mTYnear = 0x0800, 168 mTYfar = 0x1000, // seg:offset style pointer 169 mTYcs = 0x2000, // in code segment 170 mTYthread = 0x4000, 171 172 // Used for symbols going in the __thread_data section for TLS variables for Mach-O 64bit 173 mTYthreadData = 0x5000, 174 175 // Used in combination with SCcomdat to output symbols with weak linkage. 176 // Compared to a symbol with only SCcomdat, this allows the symbol to be put 177 // in any section in the object file. 178 mTYweakLinkage = 0x6000, 179 mTYLINK = 0x7800, // all linkage bits 180 181 mTYloadds = 0x08000, // 16 bit Windows LOADDS attribute 182 mTYexport = 0x10000, 183 mTYweak = 0x00000, 184 mTYimport = 0x20000, 185 mTYnaked = 0x40000, 186 mTYMOD = 0x78000, // all modifier bits 187 188 // Modifiers to basic types 189 190 mTYarrayhandle = 0x0, 191 mTYconst = 0x100, 192 mTYvolatile = 0x200, 193 mTYrestrict = 0, // BUG: add for C99 194 mTYmutable = 0, // need to add support 195 mTYunaligned = 0, // non-zero for PowerPC 196 197 mTYimmutable = 0x00080000, // immutable data 198 mTYshared = 0x00100000, // shared data 199 mTYnothrow = 0x00200000, // nothrow function 200 201 // SROA types 202 mTYxmmgpr = 0x00400000, // first slice in XMM register, the other in GPR 203 mTYgprxmm = 0x00800000, // first slice in GPR register, the other in XMM 204 205 mTYnoret = 0x01000000, // function has no return 206 mTYtransu = 0x01000000, // transparent union 207 mTYfar16 = 0x01000000, 208 mTYstdcall = 0x02000000, 209 mTYfastcall = 0x04000000, 210 mTYinterrupt = 0x08000000, 211 mTYcdecl = 0x10000000, 212 mTYpascal = 0x20000000, 213 mTYsyscall = 0x40000000, 214 mTYjava = 0x80000000, 215 216 mTYTFF = 0xFF000000, 217 } 218 219 pure 220 tym_t tybasic(tym_t ty) { return ty & mTYbasic; } 221 222 /* Flags in tytab[] array */ 223 extern __gshared uint[256] tytab; 224 enum 225 { 226 TYFLptr = 1, 227 TYFLreal = 2, 228 TYFLintegral = 4, 229 TYFLcomplex = 8, 230 TYFLimaginary = 0x10, 231 TYFLuns = 0x20, 232 TYFLmptr = 0x40, 233 TYFLfv = 0x80, // TYfptr || TYvptr 234 235 TYFLpascal = 0x200, // callee cleans up stack 236 TYFLrevparam = 0x400, // function parameters are reversed 237 TYFLnullptr = 0x800, 238 TYFLshort = 0x1000, 239 TYFLaggregate = 0x2000, 240 TYFLfunc = 0x4000, 241 TYFLref = 0x8000, 242 TYFLsimd = 0x20000, // SIMD vector type 243 TYFLfarfunc = 0x100, // __far functions (for segmented architectures) 244 TYFLxmmreg = 0x10000, // can be put in XMM register 245 } 246 247 /* Array to give the size in bytes of a type, -1 means error */ 248 extern __gshared byte[256] _tysize; 249 extern __gshared byte[256] _tyalignsize; 250 251 // Give size of type 252 @trusted 253 byte tysize(tym_t ty) { return _tysize[ty & 0xFF]; } 254 @trusted 255 byte tyalignsize(tym_t ty) { return _tyalignsize[ty & 0xFF]; } 256 257 258 /* Groupings of types */ 259 260 @trusted 261 uint tyintegral(tym_t ty) { return tytab[ty & 0xFF] & TYFLintegral; } 262 263 @trusted 264 uint tyarithmetic(tym_t ty) { return tytab[ty & 0xFF] & (TYFLintegral | TYFLreal | TYFLimaginary | TYFLcomplex); } 265 266 @trusted 267 uint tyaggregate(tym_t ty) { return tytab[ty & 0xFF] & TYFLaggregate; } 268 269 @trusted 270 uint tyscalar(tym_t ty) { return tytab[ty & 0xFF] & (TYFLintegral | TYFLreal | TYFLimaginary | TYFLcomplex | TYFLptr | TYFLmptr | TYFLnullptr | TYFLref); } 271 272 @trusted 273 uint tyfloating(tym_t ty) { return tytab[ty & 0xFF] & (TYFLreal | TYFLimaginary | TYFLcomplex); } 274 275 @trusted 276 uint tyimaginary(tym_t ty) { return tytab[ty & 0xFF] & TYFLimaginary; } 277 278 @trusted 279 uint tycomplex(tym_t ty) { return tytab[ty & 0xFF] & TYFLcomplex; } 280 281 @trusted 282 uint tyreal(tym_t ty) { return tytab[ty & 0xFF] & TYFLreal; } 283 284 // Fits into 64 bit register 285 @trusted 286 bool ty64reg(tym_t ty) { return tytab[ty & 0xFF] & (TYFLintegral | TYFLptr | TYFLref) && tysize(ty) <= _tysize[TYnptr]; } 287 288 // Can go in XMM floating point register 289 @trusted 290 uint tyxmmreg(tym_t ty) { return tytab[ty & 0xFF] & TYFLxmmreg; } 291 292 // Is a vector type 293 @trusted 294 bool tyvector(tym_t ty) { return tybasic(ty) >= TYfloat4 && tybasic(ty) <= TYullong4; } 295 296 /* Types that are chars or shorts */ 297 @trusted 298 uint tyshort(tym_t ty) { return tytab[ty & 0xFF] & TYFLshort; } 299 300 /* Detect TYlong or TYulong */ 301 @trusted 302 bool tylong(tym_t ty) { return tybasic(ty) == TYlong || tybasic(ty) == TYulong; } 303 304 /* Use to detect a pointer type */ 305 @trusted 306 uint typtr(tym_t ty) { return tytab[ty & 0xFF] & TYFLptr; } 307 308 /* Use to detect a reference type */ 309 @trusted 310 uint tyref(tym_t ty) { return tytab[ty & 0xFF] & TYFLref; } 311 312 /* Use to detect a pointer type or a member pointer */ 313 @trusted 314 uint tymptr(tym_t ty) { return tytab[ty & 0xFF] & (TYFLptr | TYFLmptr); } 315 316 // Use to detect a nullptr type or a member pointer 317 @trusted 318 uint tynullptr(tym_t ty) { return tytab[ty & 0xFF] & TYFLnullptr; } 319 320 /* Detect TYfptr or TYvptr */ 321 @trusted 322 uint tyfv(tym_t ty) { return tytab[ty & 0xFF] & TYFLfv; } 323 324 /* All data types that fit in exactly 8 bits */ 325 @trusted 326 bool tybyte(tym_t ty) { return tysize(ty) == 1; } 327 328 /* Types that fit into a single machine register */ 329 @trusted 330 bool tyreg(tym_t ty) { return tysize(ty) <= _tysize[TYnptr]; } 331 332 /* Detect function type */ 333 @trusted 334 uint tyfunc(tym_t ty) { return tytab[ty & 0xFF] & TYFLfunc; } 335 336 /* Detect function type where parameters are pushed left to right */ 337 @trusted 338 uint tyrevfunc(tym_t ty) { return tytab[ty & 0xFF] & TYFLrevparam; } 339 340 /* Detect uint types */ 341 @trusted 342 uint tyuns(tym_t ty) { return tytab[ty & 0xFF] & (TYFLuns | TYFLptr); } 343 344 /* Target dependent info */ 345 alias TYoffset = TYuint; // offset to an address 346 347 /* Detect cpp function type (callee cleans up stack) */ 348 @trusted 349 uint typfunc(tym_t ty) { return tytab[ty & 0xFF] & TYFLpascal; } 350 351 /* Array to convert a type to its unsigned equivalent */ 352 extern __gshared tym_t[256] tytouns; 353 @trusted 354 tym_t touns(tym_t ty) { return tytouns[ty & 0xFF]; } 355 356 /* Determine if TYffunc or TYfpfunc (a far function) */ 357 @trusted 358 uint tyfarfunc(tym_t ty) { return tytab[ty & 0xFF] & TYFLfarfunc; } 359 360 // Determine if parameter is a SIMD vector type 361 @trusted 362 uint tysimd(tym_t ty) { return tytab[ty & 0xFF] & TYFLsimd; } 363 364 /* Determine relaxed type */ 365 extern __gshared ubyte[TYMAX] _tyrelax; 366 @trusted 367 uint tyrelax(tym_t ty) { return _tyrelax[tybasic(ty)]; } 368 369 370 /* Determine functionally equivalent type */ 371 extern __gshared ubyte[TYMAX] tyequiv; 372 373 /* Give an ascii string for a type */ 374 extern (C) { extern __gshared const(char)*[TYMAX] tystring; } 375 376 /* Debugger value for type */ 377 extern __gshared ubyte[TYMAX] dttab; 378 extern __gshared ushort[TYMAX] dttab4; 379 380 381 @trusted 382 bool I16() { return _tysize[TYnptr] == 2; } 383 @trusted 384 bool I32() { return _tysize[TYnptr] == 4; } 385 @trusted 386 bool I64() { return _tysize[TYnptr] == 8; }