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 @nogc:
26 nothrow:
27 @safe:
28 
29 // type.h
30 
31 alias mangle_t = ubyte;
32 enum
33 {
34     mTYman_c      = 1,      // C mangling
35     mTYman_cpp    = 2,      // C++ mangling
36     mTYman_pas    = 3,      // Pascal mangling
37     mTYman_for    = 4,      // FORTRAN mangling
38     mTYman_sys    = 5,      // _syscall mangling
39     mTYman_std    = 6,      // _stdcall mangling
40     mTYman_d      = 7,      // D mangling
41 }
42 
43 /// Values for Tflags:
44 alias type_flags_t = ushort;
45 enum
46 {
47     TFprototype   = 1,      // if this function is prototyped
48     TFfixed       = 2,      // if prototype has a fixed # of parameters
49     TFgenerated   = 4,      // C: if we generated the prototype ourselves
50     TFdependent   = 4,      // CPP: template dependent type
51     TFforward     = 8,      // TYstruct: if forward reference of tag name
52     TFsizeunknown = 0x10,   // TYstruct,TYarray: if size of type is unknown
53                             // TYmptr: the Stag is TYident type
54     TFfuncret     = 0x20,   // C++,tyfunc(): overload based on function return value
55     TFfuncparam   = 0x20,   // TYarray: top level function parameter
56     TFhydrated    = 0x20,   // type data already hydrated
57     TFstatic      = 0x40,   // TYarray: static dimension
58     TFvla         = 0x80,   // TYarray: variable length array
59     TFemptyexc    = 0x100,  // tyfunc(): empty exception specification
60 }
61 
62 alias type = TYPE;
63 
64 public import dmd.backend.symbol : symbol_struct_addField, symbol_struct_addBitField, symbol_struct_hasBitFields, symbol_struct_addBaseClass;
65 
66 // Return true if type is a struct, class or union
67 bool type_struct(const type* t) { return tybasic(t.Tty) == TYstruct; }
68 
69 struct TYPE
70 {
71     debug ushort id;
72     enum IDtype = 0x1234;
73 
74     tym_t Tty;     /* mask (TYxxx)                         */
75     type_flags_t Tflags; // TFxxxxx
76 
77     mangle_t Tmangle; // name mangling
78 
79     uint Tcount; // # pointing to this type
80     char* Tident; // TYident: identifier; TYdarray, TYaarray: pretty name for debug info
81     TYPE* Tnext; // next in list
82                                 // TYenum: gives base type
83     union
84     {
85         targ_size_t Tdim;   // TYarray: # of elements in array
86         elem* Tel;          // TFvla: gives dimension (NULL if '*')
87         param_t* Tparamtypes; // TYfunc, TYtemplate: types of function parameters
88         Classsym* Ttag;     // TYstruct,TYmemptr: tag symbol
89                             // TYenum,TYvtshape: tag symbol
90         type* Talternate;   // C++: typtr: type of parameter before converting
91         type* Tkey;         // typtr: key type for associative arrays
92     }
93 
94     list_t Texcspec;        // tyfunc(): list of types of exception specification
95     Symbol *Ttypedef;       // if this type came from a typedef, this is
96                             // the typedef symbol
97 }
98 
99 struct typetemp_t
100 {
101     TYPE Ttype;
102 
103     /* Tsym should really be part of a derived class, as we only
104         allocate room for it if TYtemplate
105      */
106     Symbol *Tsym;               // primary class template symbol
107 }
108 
109 void type_debug(const type* t)
110 {
111     debug assert(t.id == t.IDtype);
112 }
113 
114 // Return name mangling of type
115 mangle_t type_mangle(const type *t) { return t.Tmangle; }
116 
117 // Return true if function type has a variable number of arguments
118 bool variadic(const type *t) { return (t.Tflags & (TFprototype | TFfixed)) == TFprototype; }
119 
120 public import dmd.backend.var : chartype;
121 
122 public import dmd.backend.dtype : type_print, type_free, type_init, type_term, type_copy,
123     type_setdim, type_setdependent, type_isdependent, type_size, type_alignsize, type_zeroSize,
124     type_parameterSize, type_paramsize, type_alloc, type_allocn, type_fake, type_setty,
125     type_settype, type_setmangle, type_setcv, type_embed, type_isvla, param_calloc,
126     param_append_type, param_free_l, param_free, param_search, typematch, type_pointer,
127     type_dyn_array, type_static_array, type_assoc_array, type_delegate, type_function,
128     type_enum, type_struct_class, tstypes, tsptr2types, tslogical, tsclib, tsdlib,
129     tspvoid, tspcvoid, tsptrdiff, tssize, tstrace;