1 /** 2 * Compiler implementation of the 3 * $(LINK2 http://www.dlang.org, D programming language). 4 * 5 * Copyright: Copyright (C) 1985-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/type.d, backend/_type.d) 10 */ 11 12 module dmd.backend.type; 13 14 // Online documentation: https://dlang.org/phobos/dmd_backend_type.html 15 16 import dmd.backend.cdef; 17 import dmd.backend.cc : block, Blockx, Classsym, Symbol, param_t; 18 import dmd.backend.code; 19 import dmd.backend.dlist; 20 import dmd.backend.el : elem; 21 import dmd.backend.ty; 22 23 extern (C++): 24 @nogc: 25 nothrow: 26 27 // type.h 28 29 alias mangle_t = ubyte; 30 enum 31 { 32 mTYman_c = 1, // C mangling 33 mTYman_cpp = 2, // C++ mangling 34 mTYman_pas = 3, // Pascal mangling 35 mTYman_for = 4, // FORTRAN mangling 36 mTYman_sys = 5, // _syscall mangling 37 mTYman_std = 6, // _stdcall mangling 38 mTYman_d = 7, // D mangling 39 } 40 41 /// Values for Tflags: 42 alias type_flags_t = ushort; 43 enum 44 { 45 TFprototype = 1, // if this function is prototyped 46 TFfixed = 2, // if prototype has a fixed # of parameters 47 TFgenerated = 4, // C: if we generated the prototype ourselves 48 TFdependent = 4, // CPP: template dependent type 49 TFforward = 8, // TYstruct: if forward reference of tag name 50 TFsizeunknown = 0x10, // TYstruct,TYarray: if size of type is unknown 51 // TYmptr: the Stag is TYident type 52 TFfuncret = 0x20, // C++,tyfunc(): overload based on function return value 53 TFfuncparam = 0x20, // TYarray: top level function parameter 54 TFhydrated = 0x20, // type data already hydrated 55 TFstatic = 0x40, // TYarray: static dimension 56 TFvla = 0x80, // TYarray: variable length array 57 TFemptyexc = 0x100, // tyfunc(): empty exception specification 58 } 59 60 alias type = TYPE; 61 62 void type_incCount(type* t); 63 void type_setIdent(type* t, char* ident); 64 65 void symbol_struct_addField(Symbol* s, const(char)* name, type* t, uint offset); 66 67 // Return true if type is a struct, class or union 68 bool type_struct(const type* t) { return tybasic(t.Tty) == TYstruct; } 69 70 struct TYPE 71 { 72 debug ushort id; 73 enum IDtype = 0x1234; 74 75 tym_t Tty; /* mask (TYxxx) */ 76 type_flags_t Tflags; // TFxxxxx 77 78 mangle_t Tmangle; // name mangling 79 80 uint Tcount; // # pointing to this type 81 char* Tident; // TYident: identifier; TYdarray, TYaarray: pretty name for debug info 82 TYPE* Tnext; // next in list 83 // TYenum: gives base type 84 union 85 { 86 targ_size_t Tdim; // TYarray: # of elements in array 87 elem* Tel; // TFvla: gives dimension (NULL if '*') 88 param_t* Tparamtypes; // TYfunc, TYtemplate: types of function parameters 89 Classsym* Ttag; // TYstruct,TYmemptr: tag symbol 90 // TYenum,TYvtshape: tag symbol 91 type* Talternate; // C++: typtr: type of parameter before converting 92 type* Tkey; // typtr: key type for associative arrays 93 } 94 95 list_t Texcspec; // tyfunc(): list of types of exception specification 96 Symbol *Ttypedef; // if this type came from a typedef, this is 97 // the typedef symbol 98 } 99 100 struct typetemp_t 101 { 102 TYPE Ttype; 103 104 /* Tsym should really be part of a derived class, as we only 105 allocate room for it if TYtemplate 106 */ 107 Symbol *Tsym; // primary class template symbol 108 } 109 110 void type_debug(const type* t) 111 { 112 debug assert(t.id == t.IDtype); 113 } 114 115 // Return name mangling of type 116 mangle_t type_mangle(const type *t) { return t.Tmangle; } 117 118 // Return true if function type has a variable number of arguments 119 bool variadic(const type *t) { return (t.Tflags & (TFprototype | TFfixed)) == TFprototype; } 120 121 extern __gshared type*[TYMAX] tstypes; 122 extern __gshared type*[TYMAX] tsptr2types; 123 124 extern __gshared 125 { 126 type* tslogical; 127 type* chartype; 128 type* tsclib; 129 type* tsdlib; 130 type* tspvoid; 131 type* tspcvoid; 132 type* tsptrdiff; 133 type* tssize; 134 type* tstrace; 135 } 136 137 /* Functions */ 138 void type_print(const type* t); 139 void type_free(type *); 140 void type_init(); 141 void type_term(); 142 type *type_copy(type *); 143 elem *type_vla_fix(type **pt); 144 type *type_setdim(type **,targ_size_t); 145 type *type_setdependent(type *t); 146 int type_isdependent(type *t); 147 void type_hydrate(type **); 148 void type_dehydrate(type **); 149 150 version (SCPP) 151 targ_size_t type_size(type *); 152 version (HTOD) 153 targ_size_t type_size(type *); 154 155 targ_size_t type_size(const type *); 156 uint type_alignsize(type *); 157 bool type_zeroSize(type *t, tym_t tyf); 158 uint type_parameterSize(type *t, tym_t tyf); 159 uint type_paramsize(type *t); 160 type *type_alloc(tym_t); 161 type *type_alloc_template(Symbol *s); 162 type *type_allocn(tym_t,type *tn); 163 type *type_allocmemptr(Classsym *stag,type *tn); 164 type *type_fake(tym_t); 165 type *type_setty(type **,uint); 166 type *type_settype(type **pt, type *t); 167 type *type_setmangle(type **pt,mangle_t mangle); 168 type *type_setcv(type **pt,tym_t cv); 169 int type_embed(type *t,type *u); 170 int type_isvla(type *t); 171 172 param_t *param_calloc(); 173 param_t *param_append_type(param_t **,type *); 174 void param_free_l(param_t *); 175 void param_free(param_t **); 176 Symbol *param_search(const(char)* name, param_t **pp); 177 void param_hydrate(param_t **); 178 void param_dehydrate(param_t **); 179 int typematch(type *t1, type *t2, int relax); 180 181 type *type_pointer(type *tnext); 182 type *type_dyn_array(type *tnext); 183 extern (C) type *type_static_array(targ_size_t dim, type *tnext); 184 type *type_assoc_array(type *tkey, type *tvalue); 185 type *type_delegate(type *tnext); 186 extern (C) type *type_function(tym_t tyf, type*[] ptypes, bool variadic, type *tret); 187 type *type_enum(const(char) *name, type *tbase); 188 type *type_struct_class(const(char)* name, uint alignsize, uint structsize, 189 type *arg1type, type *arg2type, bool isUnion, bool isClass, bool isPOD, bool is0size);