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