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