1 /**
2  * Compiler implementation of the
3  * $(LINK2 http://www.dlang.org, D programming language).
4  *
5  * Copyright:   Copyright (c) 1999-2016 by Digital Mars, All Rights Reserved
6  * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)
7  * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
8  * Source:      $(DMDSRC backend/_type.d)
9  */
10 
11 module ddmd.backend.type;
12 
13 import ddmd.backend.cdef;
14 import ddmd.backend.cc : block, Blockx, Classsym, Symbol;
15 import ddmd.backend.el : elem;
16 import ddmd.backend.ty;
17 
18 import tk.dlist;
19 
20 extern (C++):
21 @nogc:
22 nothrow:
23 
24 struct code;
25 
26 // type.h
27 
28 alias mangle_t = ubyte;
29 enum
30 {
31     mTYman_c      = 1,      // C mangling
32     mTYman_cpp    = 2,      // C++ mangling
33     mTYman_pas    = 3,      // Pascal mangling
34     mTYman_for    = 4,      // FORTRAN mangling
35     mTYman_sys    = 5,      // _syscall mangling
36     mTYman_std    = 6,      // _stdcall mangling
37     mTYman_d      = 7,      // D mangling
38 }
39 
40 /// Values for Tflags:
41 alias type_flags_t = ushort;
42 enum
43 {
44     TFprototype   = 1,      // if this function is prototyped
45     TFfixed       = 2,      // if prototype has a fixed # of parameters
46     TFgenerated   = 4,      // C: if we generated the prototype ourselves
47     TFdependent   = 4,      // CPP: template dependent type
48     TFforward     = 8,      // TYstruct: if forward reference of tag name
49     TFsizeunknown = 0x10,   // TYstruct,TYarray: if size of type is unknown
50                             // TYmptr: the Stag is TYident type
51     TFfuncret     = 0x20,   // C++,tyfunc(): overload based on function return value
52     TFfuncparam   = 0x20,   // TYarray: top level function parameter
53     TFhydrated    = 0x20,   // type data already hydrated
54     TFstatic      = 0x40,   // TYarray: static dimension
55     TFvla         = 0x80,   // TYarray: variable length array
56     TFemptyexc    = 0x100,  // tyfunc(): empty exception specification
57 }
58 
59 alias targ_size_t = ulong;
60 
61 struct PARAM;
62 alias type = TYPE;
63 
64 void type_incCount(type* t);
65 void type_setIdent(type* t, char* ident);
66 
67 type* type_pointer(type* tnext);
68 type* type_dyn_array(type* tnext);
69 extern extern (C) type* type_static_array(targ_size_t dim, type* tnext);
70 type* type_assoc_array(type* tkey, type* tvalue);
71 type* type_delegate(type* tnext);
72 extern extern (C) type* type_function(tym_t tyf, type** ptypes, size_t nparams, bool variadic, type* tret);
73 type* type_enum(const(char)* name, type* tbase);
74 type* type_struct_class(const(char)* name, uint alignsize, uint structsize,
75     type* arg1type, type* arg2type, bool isUnion, bool isClass, bool isPOD);
76 
77 void symbol_struct_addField(Symbol* s, const(char)* name, type* t, uint offset);
78 
79 // Return true if type is a struct, class or union
80 bool type_struct(type* t) { return tybasic(t.Tty) == TYstruct; }
81 
82 struct TYPE
83 {
84     debug ushort id;
85 
86     tym_t Tty;     /* mask (TYxxx)                         */
87     type_flags_t Tflags; // TFxxxxx
88 
89     mangle_t Tmangle; // name mangling
90 
91     uint Tcount; // # pointing to this type
92     TYPE* Tnext; // next in list
93                                 // TYenum: gives base type
94     union
95     {
96         targ_size_t Tdim;   // TYarray: # of elements in array
97         elem* Tel;          // TFvla: gives dimension (NULL if '*')
98         PARAM* Tparamtypes; // TYfunc, TYtemplate: types of function parameters
99         Classsym* Ttag;     // TYstruct,TYmemptr: tag symbol
100                             // TYenum,TYvtshape: tag symbol
101         char* Tident;       // TYident: identifier
102         type* Tkey;         // typtr: key type for associative arrays
103     }
104 
105     list_t Texcspec;        // tyfunc(): list of types of exception specification
106     Symbol *Ttypedef;       // if this type came from a typedef, this is
107                             // the typedef symbol
108 
109 
110     static uint sizeCheck();
111     unittest { assert(sizeCheck() == TYPE.sizeof); }
112 }
113 
114 // Workaround 2.066.x bug by resolving the TYMAX value before using it as dimension.
115 static if (__VERSION__ <= 2066)
116     private enum computeEnumValue = TYMAX;
117 
118 extern __gshared type*[TYMAX] tstypes;
119 extern __gshared type*[TYMAX] tsptr2types;
120 
121 //targ_size_t type_size(type *);
122 uint type_alignsize(type *);
123 uint type_paramsize(type *t);
124 type *type_alloc(tym_t);
125 type *type_alloc_template(Symbol *s);
126 type *type_allocn(tym_t,type *tn);
127 type *type_allocmemptr(Classsym *stag,type *tn);
128 type *type_fake(tym_t);
129 type *type_setty(type **,uint);
130 type *type_settype(type **pt, type *t);
131 type *type_setmangle(type **pt,mangle_t mangle);
132 type *type_setcv(type **pt,tym_t cv);
133 int type_embed(type *t,type *u);
134 int type_isvla(type *t);
135