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) 2000-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/el.d, backend/el.d) 10 */ 11 12 module dmd.backend.el; 13 14 // Online documentation: https://dlang.org/phobos/dmd_backend_el.html 15 16 import dmd.backend.cdef; 17 import dmd.backend.cc; 18 import dmd.backend.global; 19 import dmd.backend.oper; 20 import dmd.backend.type; 21 22 import dmd.backend.cc : Symbol; 23 24 import dmd.backend.dlist; 25 26 extern (C++): 27 @nogc: 28 nothrow: 29 30 /* Routines to handle elems. */ 31 32 alias eflags_t = ubyte; 33 enum 34 { 35 EFLAGS_variadic = 1, // variadic function call 36 } 37 38 alias pef_flags_t = uint; 39 enum 40 { 41 PEFnotlvalue = 1, // although elem may look like 42 // an lvalue, it isn't 43 PEFtemplate_id = 0x10, // symbol is a template-id 44 PEFparentheses = 0x20, // expression was within () 45 PEFaddrmem = 0x40, // address of member 46 PEFdependent = 0x80, // value-dependent 47 PEFmember = 0x100, // was a class member access 48 } 49 50 alias nflags_t = ubyte; 51 enum 52 { 53 NFLli = 1, // loop invariant 54 NFLnogoal = 2, // evaluate elem for side effects only 55 NFLassign = 8, // unambiguous assignment elem 56 NFLaecp = 0x10, // AE or CP or VBE expression 57 NFLdelcse = 0x40, // this is not the generating CSE 58 NFLtouns = 0x80, // relational operator was changed from signed to unsigned 59 } 60 61 /****************************************** 62 * Elems: 63 * Elems are the basic tree element. They can be either 64 * terminal elems (leaves), unary elems (left subtree exists) 65 * or binary elems (left and right subtrees exist). 66 */ 67 68 struct elem 69 { 70 debug ushort id; 71 enum IDelem = 0x4C45; // 'EL' 72 73 version (OSX) // workaround https://issues.dlang.org/show_bug.cgi?id=16466 74 align(16) eve EV; // variants for each type of elem 75 else 76 eve EV; // variants for each type of elem 77 78 ubyte Eoper; // operator (OPxxxx) 79 ubyte Ecount; // # of parents of this elem - 1, 80 // always 0 until CSE elimination is done 81 eflags_t Eflags; 82 83 union 84 { 85 // PARSER 86 struct 87 { 88 version (SCPP) 89 Symbol* Emember; // if PEFmember, this is the member 90 version (HTOD) 91 Symbol* Emember; // if PEFmember, this is the member 92 pef_flags_t PEFflags; 93 } 94 95 // OPTIMIZER 96 struct 97 { 98 tym_t Ety; // data type (TYxxxx) 99 uint Eexp; // index into expnod[] 100 uint Edef; // index into expdef[] 101 102 // These flags are all temporary markers, used once and then 103 // thrown away. 104 nflags_t Nflags; // NFLxxx 105 106 // MARS 107 ubyte Ejty; // original Mars type 108 } 109 110 // CODGEN 111 struct 112 { 113 // Ety2: Must be in same position as Ety! 114 tym_t Ety2; // data type (TYxxxx) 115 ubyte Ecomsub; // number of remaining references to 116 // this common subexp (used to determine 117 // first, intermediate, and last references 118 // to a CSE) 119 } 120 } 121 122 type *ET; // pointer to type of elem if TYstruct | TYarray 123 Srcpos Esrcpos; // source file position 124 } 125 126 void elem_debug(const elem* e) 127 { 128 debug assert(e.id == e.IDelem); 129 } 130 131 version (MARS) 132 tym_t typemask(const elem* e) { return e.Ety; } 133 else 134 tym_t typemask(const elem* e) { return PARSER ? e.ET.Tty : e.Ety; } 135 136 FL el_fl(const elem* e) { return cast(FL)e.EV.Vsym.Sfl; } 137 138 //#define Eoffset EV.sp.Voffset 139 //#define Esymnum EV.sp.Vsymnum 140 141 inout(elem)* list_elem(inout list_t list) { return cast(inout(elem)*)list_ptr(list); } 142 143 void list_setelem(list_t list, void* ptr) { list.ptr = cast(elem *)ptr; } 144 145 //#define cnst(e) ((e)->Eoper == OPconst) /* Determine if elem is a constant */ 146 //#define E1 EV.eop.Eleft /* left child */ 147 //#define E2 EV.eop.Eright /* right child */ 148 //#define Erd EV.sp.spu.Erd // reaching definition 149 150 void el_init(); 151 void el_reset(); 152 void el_term(); 153 elem *el_calloc(); 154 void el_free(elem *); 155 elem *el_combine(elem *,elem *); 156 elem *el_param(elem *,elem *); 157 elem *el_params(elem *, ...); 158 elem *el_params(void **args, int length); 159 elem *el_combines(void **args, int length); 160 int el_nparams(const elem *e); 161 void el_paramArray(elem ***parray, elem *e); 162 elem *el_pair(tym_t, elem *, elem *); 163 void el_copy(elem *, const elem *); 164 elem *el_alloctmp(tym_t); 165 elem *el_selecte1(elem *); 166 elem *el_selecte2(elem *); 167 elem *el_copytree(elem *); 168 void el_replace_sym(elem *e,const Symbol *s1,Symbol *s2); 169 elem *el_scancommas(elem *); 170 int el_countCommas(const(elem)*); 171 bool el_sideeffect(const elem *); 172 int el_depends(const(elem)* ea, const elem *eb); 173 targ_llong el_tolongt(elem *); 174 targ_llong el_tolong(elem *); 175 bool el_allbits(const elem*, int); 176 bool el_signx32(const elem *); 177 targ_ldouble el_toldouble(elem *); 178 void el_toconst(elem *); 179 elem *el_same(elem **); 180 elem *el_copytotmp(elem **); 181 bool el_match(const elem *, const elem *); 182 bool el_match2(const elem *, const elem *); 183 bool el_match3(const elem *, const elem *); 184 bool el_match4(const elem *, const elem *); 185 bool el_match5(const elem *, const elem *); 186 int el_appears(const(elem)* e, const Symbol *s); 187 Symbol *el_basesym(elem *e); 188 bool el_anydef(const elem *ed, const(elem)* e); 189 elem* el_bint(OPER, type*,elem*, elem*); 190 elem* el_unat(OPER, type*, elem*); 191 elem* el_bin(OPER, tym_t, elem*, elem*); 192 elem* el_una(OPER, tym_t, elem*); 193 extern(C) elem *el_longt(type *,targ_llong); 194 elem *el_settype(elem *,type *); 195 elem *el_typesize(type *); 196 elem *el_ptr_offset(Symbol *s,targ_size_t offset); 197 void el_replacesym(elem *,const Symbol *,Symbol *); 198 elem *el_nelems(type *); 199 200 extern (C) elem *el_long(tym_t,targ_llong); 201 202 bool ERTOL(const elem *); 203 bool el_returns(const(elem) *); 204 //elem *el_dctor(elem *e,void *decl); 205 //elem *el_ddtor(elem *e,void *decl); 206 elem *el_ctor_dtor(elem *ec, elem *ed, elem **pedtor); 207 elem *el_ctor(elem *ector,elem *e,Symbol *sdtor); 208 elem *el_dtor(elem *edtor,elem *e); 209 elem *el_zero(type *t); 210 elem *el_const(tym_t, eve *); 211 elem *el_test(tym_t, eve *); 212 elem ** el_parent(elem *,elem **); 213 214 //#ifdef DEBUG 215 //void el_check(const(elem)*); 216 //#else 217 //#define el_check(e) ((void)0) 218 //#endif 219 220 elem *el_convfloat(elem *); 221 elem *el_convstring(elem *); 222 elem *el_convert(elem *e); 223 bool el_isdependent(elem *); 224 uint el_alignsize(elem *); 225 226 size_t el_opN(const elem *e, OPER op); 227 void el_opArray(elem ***parray, elem *e, OPER op); 228 void el_opFree(elem *e, OPER op); 229 extern (C) elem *el_opCombine(elem **args, size_t length, OPER op, tym_t ty); 230 231 void elem_print(const elem *, int nestlevel = 0); 232 void elem_print_const(const elem *); 233 void el_hydrate(elem **); 234 void el_dehydrate(elem **); 235 236 // elpicpie.d 237 elem *el_var(Symbol *); 238 elem *el_ptr(Symbol *); 239