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