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;