1 /** 2 * Expression trees (intermediate representation) 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) 2000-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/el.d, backend/el.d) 12 */ 13 14 module dmd.backend.el; 15 16 // Online documentation: https://dlang.org/phobos/dmd_backend_el.html 17 18 import dmd.backend.cdef; 19 import dmd.backend.cc; 20 import dmd.backend.global; 21 import dmd.backend.oper; 22 import dmd.backend.type; 23 24 import dmd.backend.cc : Symbol; 25 26 import dmd.backend.dlist; 27 28 @nogc: 29 nothrow: 30 @safe: 31 32 /* Routines to handle elems. */ 33 34 alias eflags_t = ubyte; 35 enum 36 { 37 EFLAGS_variadic = 1, // variadic function call 38 } 39 40 alias pef_flags_t = uint; 41 enum 42 { 43 PEFnotlvalue = 1, // although elem may look like 44 // an lvalue, it isn't 45 PEFtemplate_id = 0x10, // symbol is a template-id 46 PEFparentheses = 0x20, // expression was within () 47 PEFaddrmem = 0x40, // address of member 48 PEFdependent = 0x80, // value-dependent 49 PEFmember = 0x100, // was a class member access 50 } 51 52 alias nflags_t = ubyte; 53 enum 54 { 55 NFLli = 1, // loop invariant 56 NFLnogoal = 2, // evaluate elem for side effects only 57 NFLassign = 8, // unambiguous assignment elem 58 NFLdelcse = 0x40, // this is not the generating CSE 59 NFLtouns = 0x80, // relational operator was changed from signed to unsigned 60 } 61 62 /****************************************** 63 * Elems: 64 * Elems are the basic tree element. They can be either 65 * terminal elems (leaves), unary elems (left subtree exists) 66 * or binary elems (left and right subtrees exist). 67 */ 68 69 struct elem 70 { 71 debug ushort id; 72 enum IDelem = 0x4C45; // 'EL' 73 74 version (OSX) // workaround https://issues.dlang.org/show_bug.cgi?id=16466 75 align(16) eve EV; // variants for each type of elem 76 else 77 eve EV; // variants for each type of elem 78 79 ubyte Eoper; // operator (OPxxxx) 80 ubyte Ecount; // # of parents of this elem - 1, 81 // always 0 until CSE elimination is done 82 eflags_t Eflags; 83 84 union 85 { 86 // PARSER 87 struct 88 { 89 pef_flags_t PEFflags; 90 } 91 92 // OPTIMIZER 93 struct 94 { 95 tym_t Ety; // data type (TYxxxx) 96 uint Eexp; // index into expnod[] 97 uint Edef; // index into expdef[] 98 99 // These flags are all temporary markers, used once and then 100 // thrown away. 101 nflags_t Nflags; // NFLxxx 102 103 // MARS 104 ubyte Ejty; // original Mars type 105 } 106 107 // CODGEN 108 struct 109 { 110 // Ety2: Must be in same position as Ety! 111 tym_t Ety2; // data type (TYxxxx) 112 ubyte Ecomsub; // number of remaining references to 113 // this common subexp (used to determine 114 // first, intermediate, and last references 115 // to a CSE) 116 } 117 } 118 119 type *ET; // pointer to type of elem if TYstruct | TYarray 120 Srcpos Esrcpos; // source file position 121 } 122 123 void elem_debug(const elem* e) 124 { 125 debug assert(e.id == e.IDelem); 126 } 127 128 @trusted tym_t typemask(const elem* e) 129 { 130 return e.Ety; 131 } 132 133 @trusted 134 FL el_fl(const elem* e) { return e.EV.Vsym.Sfl; } 135 136 //#define Eoffset EV.sp.Voffset 137 //#define Esymnum EV.sp.Vsymnum 138 139 @trusted 140 inout(elem)* list_elem(inout list_t list) { return cast(inout(elem)*)list_ptr(list); } 141 142 @trusted 143 void list_setelem(list_t list, void* ptr) { list.ptr = cast(elem *)ptr; } 144 145 public import dmd.backend.elem; 146 public import dmd.backend.elpicpie : el_var, el_ptr;