annotate gcc/d/expr.cc @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1 /* expr.cc -- Lower D frontend expressions to GCC trees.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2 Copyright (C) 2015-2020 Free Software Foundation, Inc.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
4 GCC is free software; you can redistribute it and/or modify
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
5 it under the terms of the GNU General Public License as published by
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
6 the Free Software Foundation; either version 3, or (at your option)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
7 any later version.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
8
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
9 GCC is distributed in the hope that it will be useful,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
12 GNU General Public License for more details.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
13
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
14 You should have received a copy of the GNU General Public License
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
15 along with GCC; see the file COPYING3. If not see
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
16 <http://www.gnu.org/licenses/>. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
17
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
18 #include "config.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
19 #include "system.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
20 #include "coretypes.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
21
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
22 #include "dmd/aggregate.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
23 #include "dmd/ctfe.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
24 #include "dmd/declaration.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
25 #include "dmd/expression.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
26 #include "dmd/identifier.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
27 #include "dmd/init.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
28 #include "dmd/module.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
29 #include "dmd/mtype.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
30 #include "dmd/template.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
31
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
32 #include "tree.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
33 #include "fold-const.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
34 #include "diagnostic.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
35 #include "langhooks.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
36 #include "tm.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
37 #include "function.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
38 #include "toplev.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
39 #include "varasm.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
40 #include "predict.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
41 #include "stor-layout.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
42
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
43 #include "d-tree.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
44
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
45
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
46 /* Implements the visitor interface to build the GCC trees of all Expression
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
47 AST classes emitted from the D Front-end.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
48 All visit methods accept one parameter E, which holds the frontend AST
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
49 of the expression to compile. They also don't return any value, instead
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
50 generated code is cached in RESULT_ and returned from the caller. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
51
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
52 class ExprVisitor : public Visitor
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
53 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
54 using Visitor::visit;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
55
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
56 tree result_;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
57 bool constp_;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
58
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
59 /* Determine if type is a struct that has a postblit. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
60
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
61 bool needs_postblit (Type *t)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
62 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
63 t = t->baseElemOf ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
64
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
65 if (t->ty == Tstruct)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
66 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
67 StructDeclaration *sd = ((TypeStruct *) t)->sym;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
68 if (sd->postblit)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
69 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
70 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
71
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
72 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
73 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
74
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
75 /* Determine if type is a struct that has a destructor. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
76
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
77 bool needs_dtor (Type *t)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
78 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
79 t = t->baseElemOf ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
80
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
81 if (t->ty == Tstruct)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
82 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
83 StructDeclaration *sd = ((TypeStruct *) t)->sym;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
84 if (sd->dtor)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
85 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
86 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
87
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
88 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
89 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
90
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
91 /* Determine if expression is suitable lvalue. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
92
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
93 bool lvalue_p (Expression *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
94 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
95 return ((e->op != TOKslice && e->isLvalue ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
96 || (e->op == TOKslice && ((UnaExp *) e)->e1->isLvalue ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
97 || (e->op == TOKcast && ((UnaExp *) e)->e1->isLvalue ()));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
98 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
99
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
100 /* Build an expression of code CODE, data type TYPE, and operands ARG0 and
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
101 ARG1. Perform relevant conversions needed for correct code operations. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
102
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
103 tree binary_op (tree_code code, tree type, tree arg0, tree arg1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
104 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
105 tree t0 = TREE_TYPE (arg0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
106 tree t1 = TREE_TYPE (arg1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
107 tree ret = NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
108
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
109 bool unsignedp = TYPE_UNSIGNED (t0) || TYPE_UNSIGNED (t1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
110
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
111 /* Deal with float mod expressions immediately. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
112 if (code == FLOAT_MOD_EXPR)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
113 return build_float_modulus (type, arg0, arg1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
114
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
115 if (POINTER_TYPE_P (t0) && INTEGRAL_TYPE_P (t1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
116 return build_nop (type, build_offset_op (code, arg0, arg1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
117
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
118 if (INTEGRAL_TYPE_P (t0) && POINTER_TYPE_P (t1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
119 return build_nop (type, build_offset_op (code, arg1, arg0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
120
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
121 if (POINTER_TYPE_P (t0) && POINTER_TYPE_P (t1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
122 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
123 gcc_assert (code == MINUS_EXPR);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
124 tree ptrtype = lang_hooks.types.type_for_mode (ptr_mode, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
125
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
126 /* POINTER_DIFF_EXPR requires a signed integer type of the same size as
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
127 pointers. If some platform cannot provide that, or has a larger
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
128 ptrdiff_type to support differences larger than half the address
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
129 space, cast the pointers to some larger integer type and do the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
130 computations in that type. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
131 if (TYPE_PRECISION (ptrtype) > TYPE_PRECISION (t0))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
132 ret = fold_build2 (MINUS_EXPR, ptrtype,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
133 d_convert (ptrtype, arg0),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
134 d_convert (ptrtype, arg1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
135 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
136 ret = fold_build2 (POINTER_DIFF_EXPR, ptrtype, arg0, arg1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
137 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
138 else if (INTEGRAL_TYPE_P (type) && (TYPE_UNSIGNED (type) != unsignedp))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
139 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
140 tree inttype = (unsignedp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
141 ? d_unsigned_type (type) : d_signed_type (type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
142 ret = fold_build2 (code, inttype, arg0, arg1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
143 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
144 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
145 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
146 /* If the operation needs excess precision. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
147 tree eptype = excess_precision_type (type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
148 if (eptype != NULL_TREE)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
149 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
150 arg0 = d_convert (eptype, arg0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
151 arg1 = d_convert (eptype, arg1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
152 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
153 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
154 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
155 /* Front-end does not do this conversion and GCC does not
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
156 always do it right. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
157 if (COMPLEX_FLOAT_TYPE_P (t0) && !COMPLEX_FLOAT_TYPE_P (t1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
158 arg1 = d_convert (t0, arg1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
159 else if (COMPLEX_FLOAT_TYPE_P (t1) && !COMPLEX_FLOAT_TYPE_P (t0))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
160 arg0 = d_convert (t1, arg0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
161
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
162 eptype = type;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
163 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
164
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
165 ret = fold_build2 (code, eptype, arg0, arg1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
166 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
167
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
168 return d_convert (type, ret);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
169 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
170
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
171 /* Build a binary expression of code CODE, assigning the result into E1. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
172
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
173 tree binop_assignment (tree_code code, Expression *e1, Expression *e2)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
174 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
175 /* Skip casts for lhs assignment. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
176 Expression *e1b = e1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
177 while (e1b->op == TOKcast)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
178 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
179 CastExp *ce = (CastExp *) e1b;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
180 gcc_assert (same_type_p (ce->type, ce->to));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
181 e1b = ce->e1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
182 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
183
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
184 /* Stabilize LHS for assignment. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
185 tree lhs = build_expr (e1b);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
186 tree lexpr = stabilize_expr (&lhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
187
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
188 /* The LHS expression could be an assignment, to which its operation gets
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
189 lost during gimplification. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
190 if (TREE_CODE (lhs) == MODIFY_EXPR)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
191 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
192 /* If LHS has side effects, call stabilize_reference on it, so it can
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
193 be evaluated multiple times. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
194 if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
195 lhs = build_assign (MODIFY_EXPR,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
196 stabilize_reference (TREE_OPERAND (lhs, 0)),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
197 TREE_OPERAND (lhs, 1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
198
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
199 lexpr = compound_expr (lexpr, lhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
200 lhs = TREE_OPERAND (lhs, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
201 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
202
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
203 lhs = stabilize_reference (lhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
204
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
205 /* Save RHS, to ensure that the expression is evaluated before LHS. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
206 tree rhs = build_expr (e2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
207 tree rexpr = d_save_expr (rhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
208
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
209 rhs = this->binary_op (code, build_ctype (e1->type),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
210 convert_expr (lhs, e1b->type, e1->type), rexpr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
211 if (TREE_SIDE_EFFECTS (rhs))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
212 rhs = compound_expr (rexpr, rhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
213
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
214 tree expr = modify_expr (lhs, convert_expr (rhs, e1->type, e1b->type));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
215 return compound_expr (lexpr, expr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
216 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
217
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
218 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
219 ExprVisitor (bool constp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
220 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
221 this->result_ = NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
222 this->constp_ = constp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
223 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
224
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
225 tree result (void)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
226 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
227 return this->result_;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
228 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
229
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
230 /* Visitor interfaces, each Expression class should have
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
231 overridden the default. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
232
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
233 void visit (Expression *)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
234 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
235 gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
236 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
237
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
238 /* Build a conditional expression. If either the second or third
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
239 expression is void, then the resulting type is void. Otherwise
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
240 they are implicitly converted to a common type. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
241
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
242 void visit (CondExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
243 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
244 tree cond = convert_for_condition (build_expr (e->econd),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
245 e->econd->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
246 tree t1 = build_expr (e->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
247 tree t2 = build_expr (e->e2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
248
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
249 if (e->type->ty != Tvoid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
250 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
251 t1 = convert_expr (t1, e->e1->type, e->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
252 t2 = convert_expr (t2, e->e2->type, e->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
253 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
254
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
255 this->result_ = build_condition (build_ctype (e->type), cond, t1, t2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
256 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
257
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
258 /* Build an identity comparison expression. Operands go through the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
259 usual conversions to bring them to a common type before comparison.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
260 The result type is bool. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
261
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
262 void visit (IdentityExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
263 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
264 tree_code code = (e->op == TOKidentity) ? EQ_EXPR : NE_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
265 Type *tb1 = e->e1->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
266 Type *tb2 = e->e2->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
267
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
268 if ((tb1->ty == Tsarray || tb1->ty == Tarray)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
269 && (tb2->ty == Tsarray || tb2->ty == Tarray))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
270 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
271 /* For static and dynamic arrays, identity is defined as referring to
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
272 the same array elements and the same number of elements. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
273 tree t1 = d_array_convert (e->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
274 tree t2 = d_array_convert (e->e2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
275 this->result_ = d_convert (build_ctype (e->type),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
276 build_boolop (code, t1, t2));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
277 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
278 else if (tb1->isfloating () && tb1->ty != Tvector)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
279 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
280 /* For floating-point values, identity is defined as the bits in the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
281 operands being identical. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
282 tree t1 = d_save_expr (build_expr (e->e1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
283 tree t2 = d_save_expr (build_expr (e->e2));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
284
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
285 if (!tb1->iscomplex ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
286 this->result_ = build_float_identity (code, t1, t2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
287 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
288 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
289 /* Compare the real and imaginary parts separately. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
290 tree req = build_float_identity (code, real_part (t1),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
291 real_part (t2));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
292 tree ieq = build_float_identity (code, imaginary_part (t1),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
293 imaginary_part (t2));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
294
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
295 if (code == EQ_EXPR)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
296 this->result_ = build_boolop (TRUTH_ANDIF_EXPR, req, ieq);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
297 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
298 this->result_ = build_boolop (TRUTH_ORIF_EXPR, req, ieq);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
299 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
300 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
301 else if (tb1->ty == Tstruct)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
302 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
303 /* For struct objects, identity is defined as bits in operands being
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
304 identical also. Alignment holes in structs are ignored. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
305 StructDeclaration *sd = ((TypeStruct *) tb1)->sym;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
306 tree t1 = build_expr (e->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
307 tree t2 = build_expr (e->e2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
308
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
309 gcc_assert (same_type_p (tb1, tb2));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
310
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
311 this->result_ = build_struct_comparison (code, sd, t1, t2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
312 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
313 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
314 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
315 /* For operands of other types, identity is defined as being the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
316 same as equality expressions. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
317 tree t1 = build_expr (e->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
318 tree t2 = build_expr (e->e2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
319 this->result_ = d_convert (build_ctype (e->type),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
320 build_boolop (code, t1, t2));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
321 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
322 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
323
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
324 /* Build an equality expression, which compare the two operands for either
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
325 equality or inequality. Operands go through the usual conversions to bring
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
326 them to a common type before comparison. The result type is bool. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
327
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
328 void visit (EqualExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
329 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
330 Type *tb1 = e->e1->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
331 Type *tb2 = e->e2->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
332 tree_code code = (e->op == TOKequal) ? EQ_EXPR : NE_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
333
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
334 if ((tb1->ty == Tsarray || tb1->ty == Tarray)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
335 && (tb2->ty == Tsarray || tb2->ty == Tarray))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
336 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
337 /* For static and dynamic arrays, equality is defined as the lengths of
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
338 the arrays matching, and all the elements are equal. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
339 Type *t1elem = tb1->nextOf ()->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
340 Type *t2elem = tb1->nextOf ()->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
341
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
342 /* Check if comparisons of arrays can be optimized using memcmp.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
343 This will inline EQ expressions as:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
344 e1.length == e2.length && memcmp(e1.ptr, e2.ptr, size) == 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
345 Or when generating a NE expression:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
346 e1.length != e2.length || memcmp(e1.ptr, e2.ptr, size) != 0; */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
347 if ((t1elem->isintegral () || t1elem->ty == Tvoid
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
348 || (t1elem->ty == Tstruct && !((TypeStruct *)t1elem)->sym->xeq))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
349 && t1elem->ty == t2elem->ty)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
350 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
351 tree t1 = d_array_convert (e->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
352 tree t2 = d_array_convert (e->e2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
353 tree result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
354
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
355 /* Make temporaries to prevent multiple evaluations. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
356 tree t1saved = d_save_expr (t1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
357 tree t2saved = d_save_expr (t2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
358
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
359 /* Length of arrays, for comparisons done before calling memcmp. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
360 tree t1len = d_array_length (t1saved);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
361 tree t2len = d_array_length (t2saved);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
362
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
363 /* Reference to array data. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
364 tree t1ptr = d_array_ptr (t1saved);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
365 tree t2ptr = d_array_ptr (t2saved);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
366
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
367 /* Compare arrays using memcmp if possible, otherwise for structs,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
368 each field is compared inline. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
369 if (t1elem->ty != Tstruct
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
370 || identity_compare_p (((TypeStruct *) t1elem)->sym))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
371 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
372 tree size = size_mult_expr (t1len, size_int (t1elem->size ()));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
373 tree tmemcmp = builtin_decl_explicit (BUILT_IN_MEMCMP);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
374
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
375 result = build_call_expr (tmemcmp, 3, t1ptr, t2ptr, size);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
376 result = build_boolop (code, result, integer_zero_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
377 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
378 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
379 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
380 StructDeclaration *sd = ((TypeStruct *) t1elem)->sym;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
381
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
382 result = build_array_struct_comparison (code, sd, t1len,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
383 t1ptr, t2ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
384 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
385
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
386 /* Check array length first before passing to memcmp.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
387 For equality expressions, this becomes:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
388 (e1.length == 0 || memcmp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
389 Otherwise for inequality:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
390 (e1.length != 0 && memcmp); */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
391 tree tsizecmp = build_boolop (code, t1len, size_zero_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
392 if (e->op == TOKequal)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
393 result = build_boolop (TRUTH_ORIF_EXPR, tsizecmp, result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
394 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
395 result = build_boolop (TRUTH_ANDIF_EXPR, tsizecmp, result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
396
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
397 /* Finally, check if lengths of both arrays match if dynamic.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
398 The frontend should have already guaranteed that static arrays
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
399 have same size. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
400 if (tb1->ty == Tsarray && tb2->ty == Tsarray)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
401 gcc_assert (tb1->size () == tb2->size ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
402 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
403 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
404 tree tlencmp = build_boolop (code, t1len, t2len);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
405 if (e->op == TOKequal)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
406 result = build_boolop (TRUTH_ANDIF_EXPR, tlencmp, result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
407 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
408 result = build_boolop (TRUTH_ORIF_EXPR, tlencmp, result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
409 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
410
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
411 /* Ensure left-to-right order of evaluation. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
412 if (TREE_SIDE_EFFECTS (t2))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
413 result = compound_expr (t2saved, result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
414
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
415 if (TREE_SIDE_EFFECTS (t1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
416 result = compound_expr (t1saved, result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
417
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
418 this->result_ = result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
419 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
420 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
421 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
422 /* Use _adEq2() to compare each element. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
423 Type *t1array = t1elem->arrayOf ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
424 tree result = build_libcall (LIBCALL_ADEQ2, e->type, 3,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
425 d_array_convert (e->e1),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
426 d_array_convert (e->e2),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
427 build_typeinfo (e->loc, t1array));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
428
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
429 if (e->op == TOKnotequal)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
430 result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
431
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
432 this->result_ = result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
433 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
434 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
435 else if (tb1->ty == Tstruct)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
436 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
437 /* Equality for struct objects means the logical product of all
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
438 equality results of the corresponding object fields. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
439 StructDeclaration *sd = ((TypeStruct *) tb1)->sym;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
440 tree t1 = build_expr (e->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
441 tree t2 = build_expr (e->e2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
442
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
443 gcc_assert (same_type_p (tb1, tb2));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
444
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
445 this->result_ = build_struct_comparison (code, sd, t1, t2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
446 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
447 else if (tb1->ty == Taarray && tb2->ty == Taarray)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
448 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
449 /* Use _aaEqual() for associative arrays. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
450 TypeAArray *taa1 = (TypeAArray *) tb1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
451 tree result = build_libcall (LIBCALL_AAEQUAL, e->type, 3,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
452 build_typeinfo (e->loc, taa1),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
453 build_expr (e->e1),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
454 build_expr (e->e2));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
455
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
456 if (e->op == TOKnotequal)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
457 result = build1 (TRUTH_NOT_EXPR, build_ctype (e->type), result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
458
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
459 this->result_ = result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
460 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
461 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
462 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
463 /* For operands of other types, equality is defined as the bit pattern
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
464 of the type matches exactly. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
465 tree t1 = build_expr (e->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
466 tree t2 = build_expr (e->e2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
467
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
468 this->result_ = d_convert (build_ctype (e->type),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
469 build_boolop (code, t1, t2));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
470 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
471 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
472
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
473 /* Build an `in' expression. This is a condition to see if an element
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
474 exists in an associative array. The result is a pointer to the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
475 element, or null if false. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
476
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
477 void visit (InExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
478 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
479 Type *tb2 = e->e2->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
480 gcc_assert (tb2->ty == Taarray);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
481
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
482 Type *tkey = ((TypeAArray *) tb2)->index->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
483 tree key = convert_expr (build_expr (e->e1), e->e1->type, tkey);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
484
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
485 /* Build a call to _aaInX(). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
486 this->result_ = build_libcall (LIBCALL_AAINX, e->type, 3,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
487 build_expr (e->e2),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
488 build_typeinfo (e->loc, tkey),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
489 build_address (key));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
490 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
491
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
492 /* Build a relational expression. The result type is bool. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
493
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
494 void visit (CmpExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
495 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
496 Type *tb1 = e->e1->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
497 Type *tb2 = e->e2->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
498
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
499 tree result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
500 tree_code code;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
501
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
502 switch (e->op)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
503 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
504 case TOKle:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
505 code = LE_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
506 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
507
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
508 case TOKlt:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
509 code = LT_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
510 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
511
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
512 case TOKge:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
513 code = GE_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
514 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
515
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
516 case TOKgt:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
517 code = GT_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
518 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
519
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
520 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
521 gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
522 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
523
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
524 if ((tb1->ty == Tsarray || tb1->ty == Tarray)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
525 && (tb2->ty == Tsarray || tb2->ty == Tarray))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
526 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
527 /* For static and dynamic arrays, the result of the relational op is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
528 the result of the operator applied to the first non-equal element
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
529 of the array. If two arrays compare equal, but are of different
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
530 lengths, the shorter array compares as less than the longer. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
531 Type *telem = tb1->nextOf ()->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
532
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
533 tree call = build_libcall (LIBCALL_ADCMP2, Type::tint32, 3,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
534 d_array_convert (e->e1),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
535 d_array_convert (e->e2),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
536 build_typeinfo (e->loc, telem->arrayOf ()));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
537 result = build_boolop (code, call, integer_zero_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
538
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
539 this->result_ = d_convert (build_ctype (e->type), result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
540 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
541 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
542
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
543 /* Simple comparison. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
544 result = build_boolop (code, build_expr (e->e1), build_expr (e->e2));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
545 this->result_ = d_convert (build_ctype (e->type), result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
546 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
547
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
548 /* Build an `and if' expression. If the right operand expression is void,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
549 then the resulting type is void. Otherwise the result is bool. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
550
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
551 void visit (AndAndExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
552 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
553 if (e->e2->type->toBasetype ()->ty != Tvoid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
554 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
555 tree t1 = build_expr (e->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
556 tree t2 = build_expr (e->e2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
557
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
558 t1 = convert_for_condition (t1, e->e1->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
559 t2 = convert_for_condition (t2, e->e2->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
560
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
561 this->result_ = d_convert (build_ctype (e->type),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
562 build_boolop (TRUTH_ANDIF_EXPR, t1, t2));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
563 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
564 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
565 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
566 tree t1 = convert_for_condition (build_expr (e->e1), e->e1->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
567 tree t2 = build_expr_dtor (e->e2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
568
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
569 this->result_ = build_condition (build_ctype (e->type),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
570 t1, t2, void_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
571 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
572 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
573
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
574 /* Build an `or if' expression. If the right operand expression is void,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
575 then the resulting type is void. Otherwise the result is bool. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
576
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
577 void visit (OrOrExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
578 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
579 if (e->e2->type->toBasetype ()->ty != Tvoid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
580 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
581 tree t1 = convert_for_condition (build_expr (e->e1), e->e1->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
582 tree t2 = convert_for_condition (build_expr (e->e2), e->e2->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
583
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
584 this->result_ = d_convert (build_ctype (e->type),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
585 build_boolop (TRUTH_ORIF_EXPR, t1, t2));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
586 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
587 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
588 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
589 tree t1 = convert_for_condition (build_expr (e->e1), e->e1->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
590 tree t2 = build_expr_dtor (e->e2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
591 tree cond = build1 (TRUTH_NOT_EXPR, d_bool_type, t1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
592
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
593 this->result_ = build_condition (build_ctype (e->type),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
594 cond, t2, void_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
595 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
596 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
597
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
598 /* Build a binary operand expression. Operands go through usual arithmetic
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
599 conversions to bring them to a common type before evaluating. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
600
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
601 void visit (BinExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
602 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
603 tree_code code;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
604
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
605 switch (e->op)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
606 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
607 case TOKadd:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
608 case TOKmin:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
609 if ((e->e1->type->isreal () && e->e2->type->isimaginary ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
610 || (e->e1->type->isimaginary () && e->e2->type->isreal ()))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
611 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
612 /* If the result is complex, then we can shortcut binary_op.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
613 Frontend should have already validated types and sizes. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
614 tree t1 = build_expr (e->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
615 tree t2 = build_expr (e->e2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
616
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
617 if (e->op == TOKmin)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
618 t2 = build1 (NEGATE_EXPR, TREE_TYPE (t2), t2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
619
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
620 if (e->e1->type->isreal ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
621 this->result_ = complex_expr (build_ctype (e->type), t1, t2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
622 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
623 this->result_ = complex_expr (build_ctype (e->type), t2, t1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
624
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
625 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
626 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
627 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
628 code = (e->op == TOKadd)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
629 ? PLUS_EXPR : MINUS_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
630 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
631
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
632 case TOKmul:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
633 code = MULT_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
634 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
635
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
636 case TOKdiv:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
637 code = e->e1->type->isintegral ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
638 ? TRUNC_DIV_EXPR : RDIV_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
639 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
640
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
641 case TOKmod:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
642 code = e->e1->type->isfloating ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
643 ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
644 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
645
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
646 case TOKand:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
647 code = BIT_AND_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
648 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
649
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
650 case TOKor:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
651 code = BIT_IOR_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
652 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
653
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
654 case TOKxor:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
655 code = BIT_XOR_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
656 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
657
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
658 case TOKshl:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
659 code = LSHIFT_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
660 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
661
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
662 case TOKshr:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
663 code = RSHIFT_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
664 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
665
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
666 case TOKushr:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
667 code = UNSIGNED_RSHIFT_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
668 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
669
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
670 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
671 gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
672 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
673
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
674 this->result_ = this->binary_op (code, build_ctype (e->type),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
675 build_expr (e->e1), build_expr (e->e2));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
676 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
677
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
678
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
679 /* Build a concat expression, which concatenates two or more arrays of the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
680 same type, producing a dynamic array with the result. If one operand
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
681 is an element type, that element is converted to an array of length 1. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
682
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
683 void visit (CatExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
684 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
685 Type *tb1 = e->e1->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
686 Type *tb2 = e->e2->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
687 Type *etype;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
688
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
689 if (tb1->ty == Tarray || tb1->ty == Tsarray)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
690 etype = tb1->nextOf ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
691 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
692 etype = tb2->nextOf ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
693
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
694 vec<tree, va_gc> *elemvars = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
695 tree result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
696
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
697 if (e->e1->op == TOKcat)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
698 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
699 /* Flatten multiple concatenations to an array.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
700 So the expression ((a ~ b) ~ c) becomes [a, b, c] */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
701 int ndims = 2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
702
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
703 for (Expression *ex = e->e1; ex->op == TOKcat;)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
704 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
705 if (ex->op == TOKcat)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
706 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
707 ex = ((CatExp *) ex)->e1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
708 ndims++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
709 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
710 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
711
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
712 /* Store all concatenation args to a temporary byte[][ndims] array. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
713 Type *targselem = Type::tint8->arrayOf ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
714 tree var = create_temporary_var (make_array_type (targselem, ndims));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
715 tree init = build_constructor (TREE_TYPE (var), NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
716 vec_safe_push (elemvars, var);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
717
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
718 /* Loop through each concatenation from right to left. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
719 vec<constructor_elt, va_gc> *elms = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
720 CatExp *ce = e;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
721 int dim = ndims - 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
722
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
723 for (Expression *oe = ce->e2; oe != NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
724 (ce->e1->op != TOKcat
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
725 ? (oe = ce->e1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
726 : (ce = (CatExp *)ce->e1, oe = ce->e2)))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
727 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
728 tree arg = d_array_convert (etype, oe, &elemvars);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
729 tree index = size_int (dim);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
730 CONSTRUCTOR_APPEND_ELT (elms, index, d_save_expr (arg));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
731
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
732 /* Finished pushing all arrays. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
733 if (oe == ce->e1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
734 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
735
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
736 dim -= 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
737 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
738
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
739 /* Check there is no logic bug in constructing byte[][] of arrays. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
740 gcc_assert (dim == 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
741 CONSTRUCTOR_ELTS (init) = elms;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
742 DECL_INITIAL (var) = init;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
743
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
744 tree arrs = d_array_value (build_ctype (targselem->arrayOf ()),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
745 size_int (ndims), build_address (var));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
746
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
747 result = build_libcall (LIBCALL_ARRAYCATNTX, e->type, 2,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
748 build_typeinfo (e->loc, e->type), arrs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
749 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
750 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
751 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
752 /* Handle single concatenation (a ~ b). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
753 result = build_libcall (LIBCALL_ARRAYCATT, e->type, 3,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
754 build_typeinfo (e->loc, e->type),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
755 d_array_convert (etype, e->e1, &elemvars),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
756 d_array_convert (etype, e->e2, &elemvars));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
757 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
758
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
759 for (size_t i = 0; i < vec_safe_length (elemvars); ++i)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
760 result = bind_expr ((*elemvars)[i], result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
761
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
762 this->result_ = result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
763 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
764
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
765 /* Build an assignment operator expression. The right operand is implicitly
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
766 converted to the type of the left operand, and assigned to it. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
767
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
768 void visit (BinAssignExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
769 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
770 tree_code code;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
771 Expression *e1b = e->e1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
772
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
773 switch (e->op)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
774 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
775 case TOKaddass:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
776 code = PLUS_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
777 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
778
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
779 case TOKminass:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
780 code = MINUS_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
781 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
782
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
783 case TOKmulass:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
784 code = MULT_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
785 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
786
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
787 case TOKdivass:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
788 code = e->e1->type->isintegral ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
789 ? TRUNC_DIV_EXPR : RDIV_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
790 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
791
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
792 case TOKmodass:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
793 code = e->e1->type->isfloating ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
794 ? FLOAT_MOD_EXPR : TRUNC_MOD_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
795 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
796
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
797 case TOKandass:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
798 code = BIT_AND_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
799 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
800
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
801 case TOKorass:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
802 code = BIT_IOR_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
803 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
804
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
805 case TOKxorass:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
806 code = BIT_XOR_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
807 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
808
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
809 case TOKpowass:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
810 gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
811
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
812 case TOKshlass:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
813 code = LSHIFT_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
814 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
815
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
816 case TOKshrass:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
817 case TOKushrass:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
818 /* Use the original lhs type before it was promoted. The left operand
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
819 of `>>>=' does not undergo integral promotions before shifting.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
820 Strip off casts just incase anyway. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
821 while (e1b->op == TOKcast)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
822 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
823 CastExp *ce = (CastExp *) e1b;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
824 gcc_assert (same_type_p (ce->type, ce->to));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
825 e1b = ce->e1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
826 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
827 code = (e->op == TOKshrass) ? RSHIFT_EXPR : UNSIGNED_RSHIFT_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
828 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
829
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
830 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
831 gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
832 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
833
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
834 tree exp = this->binop_assignment (code, e1b, e->e2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
835 this->result_ = convert_expr (exp, e1b->type, e->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
836 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
837
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
838 /* Build a concat assignment expression. The right operand is appended
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
839 to the the left operand. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
840
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
841 void visit (CatAssignExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
842 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
843 Type *tb1 = e->e1->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
844 Type *tb2 = e->e2->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
845 Type *etype = tb1->nextOf ()->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
846
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
847 if (tb1->ty == Tarray && tb2->ty == Tdchar
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
848 && (etype->ty == Tchar || etype->ty == Twchar))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
849 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
850 /* Append a dchar to a char[] or wchar[] */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
851 libcall_fn libcall = (etype->ty == Tchar)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
852 ? LIBCALL_ARRAYAPPENDCD : LIBCALL_ARRAYAPPENDWD;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
853
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
854 this->result_ = build_libcall (libcall, e->type, 2,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
855 build_address (build_expr (e->e1)),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
856 build_expr (e->e2));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
857 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
858 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
859 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
860 gcc_assert (tb1->ty == Tarray || tb2->ty == Tsarray);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
861
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
862 tree tinfo = build_typeinfo (e->loc, e->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
863 tree ptr = build_address (build_expr (e->e1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
864
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
865 if ((tb2->ty == Tarray || tb2->ty == Tsarray)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
866 && same_type_p (etype, tb2->nextOf ()->toBasetype ()))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
867 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
868 /* Append an array. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
869 this->result_ = build_libcall (LIBCALL_ARRAYAPPENDT, e->type, 3,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
870 tinfo, ptr, d_array_convert (e->e2));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
871
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
872 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
873 else if (same_type_p (etype, tb2))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
874 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
875 /* Append an element. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
876 tree result = build_libcall (LIBCALL_ARRAYAPPENDCTX, e->type, 3,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
877 tinfo, ptr, size_one_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
878 result = d_save_expr (result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
879
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
880 /* Assign e2 to last element. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
881 tree offexp = d_array_length (result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
882 offexp = build2 (MINUS_EXPR, TREE_TYPE (offexp),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
883 offexp, size_one_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
884 offexp = d_save_expr (offexp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
885
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
886 tree ptrexp = d_array_ptr (result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
887 ptrexp = void_okay_p (ptrexp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
888 ptrexp = build_array_index (ptrexp, offexp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
889
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
890 /* Evaluate expression before appending. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
891 tree t2 = build_expr (e->e2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
892 tree expr = stabilize_expr (&t2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
893
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
894 t2 = d_save_expr (t2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
895 result = modify_expr (build_deref (ptrexp), t2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
896 result = compound_expr (t2, result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
897
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
898 this->result_ = compound_expr (expr, result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
899 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
900 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
901 gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
902 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
903 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
904
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
905 /* Build an assignment expression. The right operand is implicitly
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
906 converted to the type of the left operand, and assigned to it. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
907
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
908 void visit (AssignExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
909 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
910 /* First, handle special assignment semantics. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
911
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
912 /* Look for array.length = n; */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
913 if (e->e1->op == TOKarraylength)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
914 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
915 /* Assignment to an array's length property; resize the array. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
916 ArrayLengthExp *ale = (ArrayLengthExp *) e->e1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
917 tree newlength = convert_expr (build_expr (e->e2), e->e2->type,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
918 Type::tsize_t);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
919 tree ptr = build_address (build_expr (ale->e1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
920
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
921 /* Don't want the basetype for the element type. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
922 Type *etype = ale->e1->type->toBasetype ()->nextOf ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
923 libcall_fn libcall = etype->isZeroInit ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
924 ? LIBCALL_ARRAYSETLENGTHT : LIBCALL_ARRAYSETLENGTHIT;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
925
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
926 tree result = build_libcall (libcall, ale->e1->type, 3,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
927 build_typeinfo (ale->loc, ale->e1->type),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
928 newlength, ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
929
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
930 this->result_ = d_array_length (result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
931 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
932 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
933
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
934 /* Look for array[] = n; */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
935 if (e->e1->op == TOKslice)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
936 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
937 SliceExp *se = (SliceExp *) e->e1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
938 Type *stype = se->e1->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
939 Type *etype = stype->nextOf ()->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
940
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
941 /* Determine if we need to run postblit or dtor. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
942 bool postblit = this->needs_postblit (etype) && this->lvalue_p (e->e2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
943 bool destructor = this->needs_dtor (etype);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
944
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
945 if (e->memset & blockAssign)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
946 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
947 /* Set a range of elements to one value. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
948 tree t1 = d_save_expr (build_expr (e->e1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
949 tree t2 = build_expr (e->e2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
950 tree result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
951
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
952 if ((postblit || destructor) && e->op != TOKblit)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
953 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
954 libcall_fn libcall = (e->op == TOKconstruct)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
955 ? LIBCALL_ARRAYSETCTOR : LIBCALL_ARRAYSETASSIGN;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
956 /* So we can call postblits on const/immutable objects. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
957 Type *tm = etype->unSharedOf ()->mutableOf ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
958 tree ti = build_typeinfo (e->loc, tm);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
959
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
960 tree result = build_libcall (libcall, Type::tvoid, 4,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
961 d_array_ptr (t1),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
962 build_address (t2),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
963 d_array_length (t1), ti);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
964 this->result_ = compound_expr (result, t1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
965 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
966 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
967
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
968 if (integer_zerop (t2))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
969 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
970 tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
971 tree size = size_mult_expr (d_array_length (t1),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
972 size_int (etype->size ()));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
973
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
974 result = build_call_expr (tmemset, 3, d_array_ptr (t1),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
975 integer_zero_node, size);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
976 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
977 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
978 result = build_array_set (d_array_ptr (t1),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
979 d_array_length (t1), t2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
980
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
981 this->result_ = compound_expr (result, t1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
982 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
983 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
984 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
985 /* Perform a memcpy operation. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
986 gcc_assert (e->e2->type->ty != Tpointer);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
987
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
988 if (!postblit && !destructor && !array_bounds_check ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
989 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
990 tree t1 = d_save_expr (d_array_convert (e->e1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
991 tree t2 = d_array_convert (e->e2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
992 tree tmemcpy = builtin_decl_explicit (BUILT_IN_MEMCPY);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
993 tree size = size_mult_expr (d_array_length (t1),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
994 size_int (etype->size ()));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
995
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
996 tree result = build_call_expr (tmemcpy, 3, d_array_ptr (t1),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
997 d_array_ptr (t2), size);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
998 this->result_ = compound_expr (result, t1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
999 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1000 else if ((postblit || destructor) && e->op != TOKblit)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1001 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1002 /* Generate: _d_arrayassign(ti, from, to)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1003 or: _d_arrayctor(ti, from, to) */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1004 libcall_fn libcall = (e->op == TOKconstruct)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1005 ? LIBCALL_ARRAYCTOR : LIBCALL_ARRAYASSIGN;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1006
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1007 this->result_ = build_libcall (libcall, e->type, 3,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1008 build_typeinfo (e->loc, etype),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1009 d_array_convert (e->e2),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1010 d_array_convert (e->e1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1011 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1012 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1013 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1014 /* Generate: _d_arraycopy() */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1015 this->result_ = build_libcall (LIBCALL_ARRAYCOPY, e->type, 3,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1016 size_int (etype->size ()),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1017 d_array_convert (e->e2),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1018 d_array_convert (e->e1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1019 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1020 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1021
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1022 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1023 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1024
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1025 /* Look for reference initializations. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1026 if (e->memset & referenceInit)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1027 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1028 gcc_assert (e->op == TOKconstruct || e->op == TOKblit);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1029 gcc_assert (e->e1->op == TOKvar);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1030
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1031 Declaration *decl = ((VarExp *) e->e1)->var;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1032 if (decl->storage_class & (STCout | STCref))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1033 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1034 tree t2 = convert_for_assignment (build_expr (e->e2),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1035 e->e2->type, e->e1->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1036 tree t1 = build_expr (e->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1037 /* Want reference to lhs, not indirect ref. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1038 t1 = TREE_OPERAND (t1, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1039 t2 = build_address (t2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1040
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1041 this->result_ = indirect_ref (build_ctype (e->type),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1042 build_assign (INIT_EXPR, t1, t2));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1043 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1044 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1045 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1046
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1047 /* Other types of assignments that may require post construction. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1048 Type *tb1 = e->e1->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1049 tree_code modifycode = (e->op == TOKconstruct) ? INIT_EXPR : MODIFY_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1050
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1051 /* Look for struct assignment. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1052 if (tb1->ty == Tstruct)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1053 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1054 tree t1 = build_expr (e->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1055 tree t2 = convert_for_assignment (build_expr (e->e2),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1056 e->e2->type, e->e1->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1057
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1058 /* Look for struct = 0. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1059 if (e->e2->op == TOKint64)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1060 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1061 /* Use memset to fill struct. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1062 gcc_assert (e->op == TOKblit);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1063 StructDeclaration *sd = ((TypeStruct *) tb1)->sym;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1064
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1065 tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1066 tree result = build_call_expr (tmemset, 3, build_address (t1),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1067 t2, size_int (sd->structsize));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1068
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1069 /* Maybe set-up hidden pointer to outer scope context. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1070 if (sd->isNested ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1071 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1072 tree field = get_symbol_decl (sd->vthis);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1073 tree value = build_vthis (sd);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1074
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1075 tree vthis_exp = modify_expr (component_ref (t1, field), value);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1076 result = compound_expr (result, vthis_exp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1077 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1078
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1079 this->result_ = compound_expr (result, t1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1080 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1081 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1082 this->result_ = build_assign (modifycode, t1, t2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1083
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1084 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1085 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1086
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1087 /* Look for static array assignment. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1088 if (tb1->ty == Tsarray)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1089 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1090 /* Look for array = 0. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1091 if (e->e2->op == TOKint64)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1092 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1093 /* Use memset to fill the array. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1094 gcc_assert (e->op == TOKblit);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1095
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1096 tree t1 = build_expr (e->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1097 tree t2 = convert_for_assignment (build_expr (e->e2),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1098 e->e2->type, e->e1->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1099 tree size = size_int (e->e1->type->size ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1100
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1101 tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1102 this->result_ = build_call_expr (tmemset, 3, build_address (t1),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1103 t2, size);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1104 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1105 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1106
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1107 Type *etype = tb1->nextOf ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1108 gcc_assert (e->e2->type->toBasetype ()->ty == Tsarray);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1109
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1110 /* Determine if we need to run postblit. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1111 bool postblit = this->needs_postblit (etype);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1112 bool destructor = this->needs_dtor (etype);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1113 bool lvalue_p = this->lvalue_p (e->e2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1114
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1115 /* Even if the elements in rhs are all rvalues and don't have
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1116 to call postblits, this assignment should call dtors on old
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1117 assigned elements. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1118 if ((!postblit && !destructor)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1119 || (e->op == TOKconstruct && !lvalue_p && postblit)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1120 || (e->op == TOKblit || e->e1->type->size () == 0))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1121 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1122 tree t1 = build_expr (e->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1123 tree t2 = convert_for_assignment (build_expr (e->e2),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1124 e->e2->type, e->e1->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1125
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1126 this->result_ = build_assign (modifycode, t1, t2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1127 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1128 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1129
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1130 Type *arrtype = (e->type->ty == Tsarray) ? etype->arrayOf () : e->type;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1131 tree result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1132
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1133 if (e->op == TOKconstruct)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1134 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1135 /* Generate: _d_arrayctor(ti, from, to) */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1136 result = build_libcall (LIBCALL_ARRAYCTOR, arrtype, 3,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1137 build_typeinfo (e->loc, etype),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1138 d_array_convert (e->e2),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1139 d_array_convert (e->e1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1140 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1141 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1142 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1143 /* Generate: _d_arrayassign_l()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1144 or: _d_arrayassign_r() */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1145 libcall_fn libcall = (lvalue_p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1146 ? LIBCALL_ARRAYASSIGN_L : LIBCALL_ARRAYASSIGN_R;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1147 tree elembuf = build_local_temp (build_ctype (etype));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1148
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1149 result = build_libcall (libcall, arrtype, 4,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1150 build_typeinfo (e->loc, etype),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1151 d_array_convert (e->e2),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1152 d_array_convert (e->e1),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1153 build_address (elembuf));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1154 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1155
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1156 /* Cast the libcall result back to a static array. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1157 if (e->type->ty == Tsarray)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1158 result = indirect_ref (build_ctype (e->type),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1159 d_array_ptr (result));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1160
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1161 this->result_ = result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1162 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1163 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1164
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1165 /* Simple assignment. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1166 tree t1 = build_expr (e->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1167 tree t2 = convert_for_assignment (build_expr (e->e2),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1168 e->e2->type, e->e1->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1169
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1170 this->result_ = build_assign (modifycode, t1, t2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1171 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1172
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1173 /* Build a postfix expression. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1174
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1175 void visit (PostExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1176 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1177 tree result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1178
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1179 if (e->op == TOKplusplus)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1180 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1181 result = build2 (POSTINCREMENT_EXPR, build_ctype (e->type),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1182 build_expr (e->e1), build_expr (e->e2));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1183 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1184 else if (e->op == TOKminusminus)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1185 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1186 result = build2 (POSTDECREMENT_EXPR, build_ctype (e->type),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1187 build_expr (e->e1), build_expr (e->e2));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1188 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1189 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1190 gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1191
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1192 TREE_SIDE_EFFECTS (result) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1193 this->result_ = result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1194 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1195
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1196 /* Build an index expression. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1197
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1198 void visit (IndexExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1199 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1200 Type *tb1 = e->e1->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1201
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1202 if (tb1->ty == Taarray)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1203 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1204 /* Get the key for the associative array. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1205 Type *tkey = ((TypeAArray *) tb1)->index->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1206 tree key = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1207 libcall_fn libcall;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1208 tree tinfo, ptr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1209
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1210 if (e->modifiable)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1211 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1212 libcall = LIBCALL_AAGETY;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1213 ptr = build_address (build_expr (e->e1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1214 tinfo = build_typeinfo (e->loc, tb1->unSharedOf ()->mutableOf ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1215 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1216 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1217 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1218 libcall = LIBCALL_AAGETRVALUEX;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1219 ptr = build_expr (e->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1220 tinfo = build_typeinfo (e->loc, tkey);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1221 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1222
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1223 /* Index the associative array. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1224 tree result = build_libcall (libcall, e->type->pointerTo (), 4,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1225 ptr, tinfo,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1226 size_int (tb1->nextOf ()->size ()),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1227 build_address (key));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1228
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1229 if (!e->indexIsInBounds && array_bounds_check ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1230 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1231 tree tassert = (global.params.checkAction == CHECKACTION_D)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1232 ? d_assert_call (e->loc, LIBCALL_ARRAY_BOUNDS)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1233 : build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1234
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1235 result = d_save_expr (result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1236 result = build_condition (TREE_TYPE (result),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1237 d_truthvalue_conversion (result),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1238 result, tassert);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1239 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1240
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1241 this->result_ = indirect_ref (build_ctype (e->type), result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1242 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1243 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1244 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1245 /* Get the data pointer and length for static and dynamic arrays. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1246 tree array = d_save_expr (build_expr (e->e1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1247 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1248
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1249 tree length = NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1250 if (tb1->ty != Tpointer)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1251 length = get_array_length (array, tb1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1252 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1253 gcc_assert (e->lengthVar == NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1254
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1255 /* The __dollar variable just becomes a placeholder for the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1256 actual length. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1257 if (e->lengthVar)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1258 e->lengthVar->csym = length;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1259
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1260 /* Generate the index. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1261 tree index = build_expr (e->e2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1262
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1263 /* If it's a static array and the index is constant, the front end has
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1264 already checked the bounds. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1265 if (tb1->ty != Tpointer && !e->indexIsInBounds)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1266 index = build_bounds_condition (e->e2->loc, index, length, false);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1267
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1268 /* Index the .ptr. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1269 ptr = void_okay_p (ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1270 this->result_ = indirect_ref (TREE_TYPE (TREE_TYPE (ptr)),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1271 build_array_index (ptr, index));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1272 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1273 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1274
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1275 /* Build a comma expression. The type is the type of the right operand. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1276
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1277 void visit (CommaExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1278 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1279 tree t1 = build_expr (e->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1280 tree t2 = build_expr (e->e2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1281 tree type = e->type ? build_ctype (e->type) : void_type_node;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1282
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1283 this->result_ = build2 (COMPOUND_EXPR, type, t1, t2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1284 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1285
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1286 /* Build an array length expression. Returns the number of elements
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1287 in the array. The result is of type size_t. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1288
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1289 void visit (ArrayLengthExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1290 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1291 if (e->e1->type->toBasetype ()->ty == Tarray)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1292 this->result_ = d_array_length (build_expr (e->e1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1293 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1294 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1295 /* Static arrays have already been handled by the front-end. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1296 error ("unexpected type for array length: %qs", e->type->toChars ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1297 this->result_ = error_mark_node;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1298 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1299 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1300
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1301 /* Build a delegate pointer expression. This will return the frame
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1302 pointer value as a type void*. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1303
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1304 void visit (DelegatePtrExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1305 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1306 tree t1 = build_expr (e->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1307 this->result_ = delegate_object (t1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1308 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1309
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1310 /* Build a delegate function pointer expression. This will return the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1311 function pointer value as a function type. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1312
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1313 void visit (DelegateFuncptrExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1314 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1315 tree t1 = build_expr (e->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1316 this->result_ = delegate_method (t1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1317 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1318
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1319 /* Build a slice expression. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1320
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1321 void visit (SliceExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1322 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1323 Type *tb = e->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1324 Type *tb1 = e->e1->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1325 gcc_assert (tb->ty == Tarray || tb->ty == Tsarray);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1326
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1327 /* Use convert-to-dynamic-array code if possible. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1328 if (!e->lwr)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1329 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1330 tree result = build_expr (e->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1331 if (e->e1->type->toBasetype ()->ty == Tsarray)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1332 result = convert_expr (result, e->e1->type, e->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1333
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1334 this->result_ = result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1335 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1336 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1337 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1338 gcc_assert (e->upr != NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1339
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1340 /* Get the data pointer and length for static and dynamic arrays. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1341 tree array = d_save_expr (build_expr (e->e1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1342 tree ptr = convert_expr (array, tb1, tb1->nextOf ()->pointerTo ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1343 tree length = NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1344
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1345 /* Our array is already a SAVE_EXPR if necessary, so we don't make length
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1346 a SAVE_EXPR which is, at most, a COMPONENT_REF on top of array. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1347 if (tb1->ty != Tpointer)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1348 length = get_array_length (array, tb1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1349 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1350 gcc_assert (e->lengthVar == NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1351
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1352 /* The __dollar variable just becomes a placeholder for the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1353 actual length. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1354 if (e->lengthVar)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1355 e->lengthVar->csym = length;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1356
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1357 /* Generate upper and lower bounds. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1358 tree lwr_tree = d_save_expr (build_expr (e->lwr));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1359 tree upr_tree = d_save_expr (build_expr (e->upr));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1360
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1361 /* If the upper bound has any side effects, then the lower bound should be
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1362 copied to a temporary always. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1363 if (TREE_CODE (upr_tree) == SAVE_EXPR && TREE_CODE (lwr_tree) != SAVE_EXPR)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1364 lwr_tree = save_expr (lwr_tree);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1365
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1366 /* Adjust the .ptr offset. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1367 if (!integer_zerop (lwr_tree))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1368 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1369 tree ptrtype = TREE_TYPE (ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1370 ptr = build_array_index (void_okay_p (ptr), lwr_tree);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1371 ptr = build_nop (ptrtype, ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1372 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1373 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1374 lwr_tree = NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1375
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1376 /* Nothing more to do for static arrays, their bounds checking has been
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1377 done at compile-time. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1378 if (tb->ty == Tsarray)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1379 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1380 this->result_ = indirect_ref (build_ctype (e->type), ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1381 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1382 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1383 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1384 gcc_assert (tb->ty == Tarray);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1385
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1386 /* Generate bounds checking code. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1387 tree newlength;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1388
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1389 if (!e->upperIsInBounds)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1390 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1391 if (length)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1392 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1393 newlength = build_bounds_condition (e->upr->loc, upr_tree,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1394 length, true);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1395 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1396 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1397 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1398 /* Still need to check bounds lwr <= upr for pointers. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1399 gcc_assert (tb1->ty == Tpointer);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1400 newlength = upr_tree;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1401 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1402 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1403 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1404 newlength = upr_tree;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1405
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1406 if (lwr_tree)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1407 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1408 /* Enforces lwr <= upr. No need to check lwr <= length as
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1409 we've already ensured that upr <= length. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1410 if (!e->lowerIsLessThanUpper)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1411 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1412 tree cond = build_bounds_condition (e->lwr->loc, lwr_tree,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1413 upr_tree, true);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1414
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1415 /* When bounds checking is off, the index value is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1416 returned directly. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1417 if (cond != lwr_tree)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1418 newlength = compound_expr (cond, newlength);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1419 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1420
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1421 /* Need to ensure lwr always gets evaluated first, as it may be a
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1422 function call. Generates (lwr, upr) - lwr. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1423 newlength = fold_build2 (MINUS_EXPR, TREE_TYPE (newlength),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1424 compound_expr (lwr_tree, newlength), lwr_tree);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1425 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1426
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1427 tree result = d_array_value (build_ctype (e->type), newlength, ptr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1428 this->result_ = compound_expr (array, result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1429 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1430
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1431 /* Build a cast expression, which converts the given unary expression to the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1432 type of result. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1433
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1434 void visit (CastExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1435 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1436 Type *ebtype = e->e1->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1437 Type *tbtype = e->to->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1438 tree result = build_expr (e->e1, this->constp_);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1439
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1440 /* Just evaluate e1 if it has any side effects. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1441 if (tbtype->ty == Tvoid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1442 this->result_ = build_nop (build_ctype (tbtype), result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1443 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1444 this->result_ = convert_expr (result, ebtype, tbtype);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1445 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1446
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1447 /* Build a delete expression. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1448
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1449 void visit (DeleteExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1450 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1451 tree t1 = build_expr (e->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1452 Type *tb1 = e->e1->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1453
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1454 if (tb1->ty == Tclass)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1455 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1456 /* For class object references, if there is a destructor for that class,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1457 the destructor is called for the object instance. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1458 libcall_fn libcall;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1459
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1460 if (e->e1->op == TOKvar)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1461 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1462 VarDeclaration *v = ((VarExp *) e->e1)->var->isVarDeclaration ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1463 if (v && v->onstack)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1464 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1465 libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1466 ? LIBCALL_CALLINTERFACEFINALIZER : LIBCALL_CALLFINALIZER;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1467
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1468 this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1469 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1470 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1471 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1472
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1473 /* Otherwise, the garbage collector is called to immediately free the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1474 memory allocated for the class instance. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1475 libcall = tb1->isClassHandle ()->isInterfaceDeclaration ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1476 ? LIBCALL_DELINTERFACE : LIBCALL_DELCLASS;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1477
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1478 t1 = build_address (t1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1479 this->result_ = build_libcall (libcall, Type::tvoid, 1, t1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1480 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1481 else if (tb1->ty == Tarray)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1482 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1483 /* For dynamic arrays, the garbage collector is called to immediately
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1484 release the memory. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1485 Type *telem = tb1->nextOf ()->baseElemOf ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1486 tree ti = null_pointer_node;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1487
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1488 if (telem->ty == Tstruct)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1489 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1490 /* Might need to run destructor on array contents. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1491 TypeStruct *ts = (TypeStruct *) telem;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1492 if (ts->sym->dtor)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1493 ti = build_typeinfo (e->loc, tb1->nextOf ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1494 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1495
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1496 /* Generate: _delarray_t (&t1, ti); */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1497 this->result_ = build_libcall (LIBCALL_DELARRAYT, Type::tvoid, 2,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1498 build_address (t1), ti);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1499 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1500 else if (tb1->ty == Tpointer)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1501 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1502 /* For pointers to a struct instance, if the struct has overloaded
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1503 operator delete, then that operator is called. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1504 t1 = build_address (t1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1505 Type *tnext = ((TypePointer *)tb1)->next->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1506
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1507 if (tnext->ty == Tstruct)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1508 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1509 TypeStruct *ts = (TypeStruct *)tnext;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1510 if (ts->sym->dtor)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1511 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1512 tree ti = build_typeinfo (e->loc, tnext);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1513 this->result_ = build_libcall (LIBCALL_DELSTRUCT, Type::tvoid,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1514 2, t1, ti);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1515 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1516 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1517 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1518
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1519 /* Otherwise, the garbage collector is called to immediately free the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1520 memory allocated for the pointer. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1521 this->result_ = build_libcall (LIBCALL_DELMEMORY, Type::tvoid, 1, t1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1522 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1523 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1524 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1525 error ("don%'t know how to delete %qs", e->e1->toChars ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1526 this->result_ = error_mark_node;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1527 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1528 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1529
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1530 /* Build a remove expression, which removes a particular key from an
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1531 associative array. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1532
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1533 void visit (RemoveExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1534 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1535 /* Check that the array is actually an associative array. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1536 if (e->e1->type->toBasetype ()->ty == Taarray)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1537 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1538 Type *tb = e->e1->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1539 Type *tkey = ((TypeAArray *) tb)->index->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1540 tree index = convert_expr (build_expr (e->e2), e->e2->type, tkey);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1541
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1542 this->result_ = build_libcall (LIBCALL_AADELX, Type::tbool, 3,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1543 build_expr (e->e1),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1544 build_typeinfo (e->loc, tkey),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1545 build_address (index));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1546 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1547 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1548 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1549 error ("%qs is not an associative array", e->e1->toChars ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1550 this->result_ = error_mark_node;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1551 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1552 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1553
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1554 /* Build an unary not expression. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1555
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1556 void visit (NotExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1557 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1558 tree result = convert_for_condition (build_expr (e->e1), e->e1->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1559 /* Need to convert to boolean type or this will fail. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1560 result = fold_build1 (TRUTH_NOT_EXPR, d_bool_type, result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1561
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1562 this->result_ = d_convert (build_ctype (e->type), result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1563 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1564
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1565 /* Build a compliment expression, where all the bits in the value are
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1566 complemented. Note: unlike in C, the usual integral promotions
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1567 are not performed prior to the complement operation. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1568
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1569 void visit (ComExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1570 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1571 TY ty1 = e->e1->type->toBasetype ()->ty;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1572 gcc_assert (ty1 != Tarray && ty1 != Tsarray);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1573
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1574 this->result_ = fold_build1 (BIT_NOT_EXPR, build_ctype (e->type),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1575 build_expr (e->e1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1576 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1577
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1578 /* Build an unary negation expression. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1579
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1580 void visit (NegExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1581 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1582 TY ty1 = e->e1->type->toBasetype ()->ty;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1583 gcc_assert (ty1 != Tarray && ty1 != Tsarray);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1584
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1585 tree type = build_ctype (e->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1586 tree expr = build_expr (e->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1587
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1588 /* If the operation needs excess precision. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1589 tree eptype = excess_precision_type (type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1590 if (eptype != NULL_TREE)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1591 expr = d_convert (eptype, expr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1592 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1593 eptype = type;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1594
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1595 tree ret = fold_build1 (NEGATE_EXPR, eptype, expr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1596 this->result_ = d_convert (type, ret);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1597 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1598
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1599 /* Build a pointer index expression. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1600
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1601 void visit (PtrExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1602 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1603 Type *tnext = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1604 size_t offset;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1605 tree result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1606
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1607 if (e->e1->op == TOKadd)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1608 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1609 BinExp *be = (BinExp *) e->e1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1610 if (be->e1->op == TOKaddress
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1611 && be->e2->isConst () && be->e2->type->isintegral ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1612 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1613 Expression *ae = ((AddrExp *) be->e1)->e1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1614 tnext = ae->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1615 result = build_expr (ae);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1616 offset = be->e2->toUInteger ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1617 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1618 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1619 else if (e->e1->op == TOKsymoff)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1620 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1621 SymOffExp *se = (SymOffExp *) e->e1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1622 if (!declaration_reference_p (se->var))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1623 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1624 tnext = se->var->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1625 result = get_decl_tree (se->var);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1626 offset = se->offset;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1627 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1628 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1629
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1630 /* Produce better code by converting *(#record + n) to
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1631 COMPONENT_REFERENCE. Otherwise, the variable will always be
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1632 allocated in memory because its address is taken. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1633 if (tnext && tnext->ty == Tstruct)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1634 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1635 StructDeclaration *sd = ((TypeStruct *) tnext)->sym;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1636
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1637 for (size_t i = 0; i < sd->fields.dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1638 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1639 VarDeclaration *field = sd->fields[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1640
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1641 if (field->offset == offset
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1642 && same_type_p (field->type, e->type))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1643 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1644 /* Catch errors, backend will ICE otherwise. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1645 if (error_operand_p (result))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1646 this->result_ = result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1647 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1648 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1649 result = component_ref (result, get_symbol_decl (field));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1650 this->result_ = result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1651 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1652 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1653 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1654 else if (field->offset > offset)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1655 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1656 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1657 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1658
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1659 this->result_ = indirect_ref (build_ctype (e->type), build_expr (e->e1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1660 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1661
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1662 /* Build an unary address expression. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1663
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1664 void visit (AddrExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1665 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1666 tree type = build_ctype (e->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1667 tree exp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1668
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1669 /* The frontend optimizer can convert const symbol into a struct literal.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1670 Taking the address of a struct literal is otherwise illegal. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1671 if (e->e1->op == TOKstructliteral)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1672 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1673 StructLiteralExp *sle = ((StructLiteralExp *) e->e1)->origin;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1674 gcc_assert (sle != NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1675
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1676 /* Build the reference symbol, the decl is built first as the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1677 initializer may have recursive references. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1678 if (!sle->sym)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1679 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1680 sle->sym = build_artificial_decl (build_ctype (sle->type),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1681 NULL_TREE, "S");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1682 DECL_INITIAL (sle->sym) = build_expr (sle, true);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1683 d_pushdecl (sle->sym);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1684 rest_of_decl_compilation (sle->sym, 1, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1685 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1686
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1687 exp = sle->sym;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1688 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1689 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1690 exp = build_expr (e->e1, this->constp_);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1691
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1692 TREE_CONSTANT (exp) = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1693 this->result_ = d_convert (type, build_address (exp));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1694 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1695
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1696 /* Build a function call expression. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1697
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1698 void visit (CallExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1699 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1700 Type *tb = e->e1->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1701 Expression *e1b = e->e1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1702
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1703 tree callee = NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1704 tree object = NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1705 tree cleanup = NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1706 TypeFunction *tf = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1707
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1708 /* Calls to delegates can sometimes look like this. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1709 if (e1b->op == TOKcomma)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1710 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1711 e1b = ((CommaExp *) e1b)->e2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1712 gcc_assert (e1b->op == TOKvar);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1713
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1714 Declaration *var = ((VarExp *) e1b)->var;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1715 gcc_assert (var->isFuncDeclaration () && !var->needThis ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1716 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1717
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1718 if (e1b->op == TOKdotvar && tb->ty != Tdelegate)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1719 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1720 DotVarExp *dve = (DotVarExp *) e1b;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1721
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1722 /* Don't modify the static initializer for struct literals. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1723 if (dve->e1->op == TOKstructliteral)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1724 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1725 StructLiteralExp *sle = (StructLiteralExp *) dve->e1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1726 sle->useStaticInit = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1727 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1728
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1729 FuncDeclaration *fd = dve->var->isFuncDeclaration ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1730 if (fd != NULL)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1731 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1732 /* Get the correct callee from the DotVarExp object. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1733 tree fndecl = get_symbol_decl (fd);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1734 AggregateDeclaration *ad = fd->isThis ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1735
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1736 /* Static method; ignore the object instance. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1737 if (!ad)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1738 callee = build_address (fndecl);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1739 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1740 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1741 tree thisexp = build_expr (dve->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1742
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1743 /* When constructing temporaries, if the constructor throws,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1744 then the object is destructed even though it is not a fully
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1745 constructed object yet. And so this call will need to be
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1746 moved inside the TARGET_EXPR_INITIAL slot. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1747 if (fd->isCtorDeclaration ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1748 && TREE_CODE (thisexp) == COMPOUND_EXPR
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1749 && TREE_CODE (TREE_OPERAND (thisexp, 0)) == TARGET_EXPR
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1750 && TARGET_EXPR_CLEANUP (TREE_OPERAND (thisexp, 0)))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1751 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1752 cleanup = TREE_OPERAND (thisexp, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1753 thisexp = TREE_OPERAND (thisexp, 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1754 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1755
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1756 /* Want reference to 'this' object. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1757 if (!POINTER_TYPE_P (TREE_TYPE (thisexp)))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1758 thisexp = build_address (thisexp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1759
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1760 /* Make the callee a virtual call. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1761 if (fd->isVirtual () && !fd->isFinalFunc () && !e->directcall)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1762 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1763 tree fntype = build_pointer_type (TREE_TYPE (fndecl));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1764 tree thistype = build_ctype (ad->handleType ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1765 thisexp = build_nop (thistype, d_save_expr (thisexp));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1766 fndecl = build_vindex_ref (thisexp, fntype, fd->vtblIndex);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1767 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1768 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1769 fndecl = build_address (fndecl);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1770
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1771 callee = build_method_call (fndecl, thisexp, fd->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1772 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1773 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1774 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1775
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1776 if (callee == NULL_TREE)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1777 callee = build_expr (e1b);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1778
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1779 if (METHOD_CALL_EXPR (callee))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1780 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1781 /* This could be a delegate expression (TY == Tdelegate), but not
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1782 actually a delegate variable. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1783 if (e1b->op == TOKdotvar)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1784 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1785 /* This gets the true function type, getting the function type
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1786 from e1->type can sometimes be incorrect, such as when calling
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1787 a 'ref' return function. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1788 tf = get_function_type (((DotVarExp *) e1b)->var->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1789 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1790 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1791 tf = get_function_type (tb);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1792
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1793 extract_from_method_call (callee, callee, object);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1794 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1795 else if (tb->ty == Tdelegate)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1796 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1797 /* Delegate call, extract .object and .funcptr from var. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1798 callee = d_save_expr (callee);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1799 tf = get_function_type (tb);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1800 object = delegate_object (callee);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1801 callee = delegate_method (callee);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1802 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1803 else if (e1b->op == TOKvar)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1804 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1805 FuncDeclaration *fd = ((VarExp *) e1b)->var->isFuncDeclaration ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1806 gcc_assert (fd != NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1807 tf = get_function_type (fd->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1808
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1809 if (fd->isNested ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1810 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1811 /* Maybe re-evaluate symbol storage treating 'fd' as public. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1812 if (call_by_alias_p (d_function_chain->function, fd))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1813 TREE_PUBLIC (callee) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1814
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1815 object = get_frame_for_symbol (fd);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1816 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1817 else if (fd->needThis ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1818 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1819 error_at (make_location_t (e1b->loc),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1820 "need %<this%> to access member %qs", fd->toChars ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1821 /* Continue compiling... */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1822 object = null_pointer_node;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1823 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1824 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1825 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1826 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1827 /* Normal direct function call. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1828 tf = get_function_type (tb);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1829 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1830
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1831 gcc_assert (tf != NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1832
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1833 /* Now we have the type, callee and maybe object reference,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1834 build the call expression. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1835 tree exp = d_build_call (tf, callee, object, e->arguments);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1836
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1837 if (tf->isref)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1838 exp = build_deref (exp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1839
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1840 /* Some library calls are defined to return a generic type.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1841 this->type is the real type we want to return. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1842 if (e->type->isTypeBasic ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1843 exp = d_convert (build_ctype (e->type), exp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1844
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1845 /* If this call was found to be a constructor for a temporary with a
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1846 cleanup, then move the call inside the TARGET_EXPR. The original
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1847 initializer is turned into an assignment, to keep its side effect. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1848 if (cleanup != NULL_TREE)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1849 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1850 tree init = TARGET_EXPR_INITIAL (cleanup);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1851 tree slot = TARGET_EXPR_SLOT (cleanup);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1852 d_mark_addressable (slot);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1853 init = build_assign (INIT_EXPR, slot, init);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1854
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1855 TARGET_EXPR_INITIAL (cleanup) = compound_expr (init, exp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1856 exp = cleanup;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1857 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1858
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1859 this->result_ = exp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1860 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1861
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1862 /* Build a delegate expression. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1863
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1864 void visit (DelegateExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1865 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1866 if (e->func->semanticRun == PASSsemantic3done)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1867 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1868 /* Add the function as nested function if it belongs to this module.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1869 ie: it is a member of this module, or it is a template instance. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1870 Dsymbol *owner = e->func->toParent ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1871 while (!owner->isTemplateInstance () && owner->toParent ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1872 owner = owner->toParent ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1873 if (owner->isTemplateInstance () || owner == d_function_chain->module)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1874 build_decl_tree (e->func);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1875 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1876
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1877 tree fndecl;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1878 tree object;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1879
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1880 if (e->func->isNested ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1881 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1882 if (e->e1->op == TOKnull)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1883 object = build_expr (e->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1884 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1885 object = get_frame_for_symbol (e->func);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1886
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1887 fndecl = build_address (get_symbol_decl (e->func));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1888 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1889 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1890 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1891 if (!e->func->isThis ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1892 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1893 error ("delegates are only for non-static functions");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1894 this->result_ = error_mark_node;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1895 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1896 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1897
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1898 object = build_expr (e->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1899
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1900 /* Want reference to `this' object. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1901 if (e->e1->type->ty != Tclass && e->e1->type->ty != Tpointer)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1902 object = build_address (object);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1903
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1904 /* Object reference could be the outer `this' field of a class or
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1905 closure of type `void*'. Cast it to the right type. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1906 if (e->e1->type->ty == Tclass)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1907 object = d_convert (build_ctype (e->e1->type), object);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1908
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1909 fndecl = get_symbol_decl (e->func);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1910
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1911 /* Get pointer to function out of the virtual table. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1912 if (e->func->isVirtual () && !e->func->isFinalFunc ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1913 && e->e1->op != TOKsuper && e->e1->op != TOKdottype)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1914 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1915 tree fntype = build_pointer_type (TREE_TYPE (fndecl));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1916 object = d_save_expr (object);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1917 fndecl = build_vindex_ref (object, fntype, e->func->vtblIndex);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1918 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1919 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1920 fndecl = build_address (fndecl);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1921 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1922
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1923 this->result_ = build_method_call (fndecl, object, e->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1924 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1925
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1926 /* Build a type component expression. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1927
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1928 void visit (DotTypeExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1929 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1930 /* Just a pass through to underlying expression. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1931 this->result_ = build_expr (e->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1932 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1933
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1934 /* Build a component reference expression. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1935
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1936 void visit (DotVarExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1937 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1938 VarDeclaration *vd = e->var->isVarDeclaration ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1939
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1940 /* This could also be a function, but relying on that being taken
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1941 care of by the visitor interface for CallExp. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1942 if (vd != NULL)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1943 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1944 if (!vd->isField ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1945 this->result_ = get_decl_tree (vd);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1946 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1947 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1948 tree object = build_expr (e->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1949
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1950 if (e->e1->type->toBasetype ()->ty != Tstruct)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1951 object = build_deref (object);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1952
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1953 this->result_ = component_ref (object, get_symbol_decl (vd));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1954 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1955 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1956 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1957 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1958 error ("%qs is not a field, but a %qs",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1959 e->var->toChars (), e->var->kind ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1960 this->result_ = error_mark_node;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1961 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1962 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1963
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1964 /* Build an assert expression, used to declare conditions that must hold at
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1965 that a given point in the program. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1966
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1967 void visit (AssertExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1968 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1969 Type *tb1 = e->e1->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1970 tree arg = build_expr (e->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1971 tree tmsg = NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1972 tree assert_pass = void_node;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1973 tree assert_fail;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1974
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1975 if (global.params.useAssert
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1976 && global.params.checkAction == CHECKACTION_D)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1977 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1978 /* Generate: ((bool) e1 ? (void)0 : _d_assert (...))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1979 or: (e1 != null ? e1._invariant() : _d_assert (...)) */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1980 bool unittest_p = d_function_chain->function->isUnitTestDeclaration ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1981 libcall_fn libcall;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1982
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1983 if (e->msg)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1984 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1985 tmsg = build_expr_dtor (e->msg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1986 libcall = unittest_p ? LIBCALL_UNITTEST_MSG : LIBCALL_ASSERT_MSG;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1987 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1988 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1989 libcall = unittest_p ? LIBCALL_UNITTEST : LIBCALL_ASSERT;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1990
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1991 /* Build a call to _d_assert(). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1992 assert_fail = d_assert_call (e->loc, libcall, tmsg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1993
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1994 if (global.params.useInvariants)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1995 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1996 /* If the condition is a D class or struct object with an invariant,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1997 call it if the condition result is true. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1998 if (tb1->ty == Tclass)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1999 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2000 ClassDeclaration *cd = tb1->isClassHandle ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2001 if (!cd->isInterfaceDeclaration () && !cd->isCPPclass ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2002 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2003 arg = d_save_expr (arg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2004 assert_pass = build_libcall (LIBCALL_INVARIANT,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2005 Type::tvoid, 1, arg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2006 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2007 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2008 else if (tb1->ty == Tpointer && tb1->nextOf ()->ty == Tstruct)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2009 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2010 StructDeclaration *sd = ((TypeStruct *) tb1->nextOf ())->sym;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2011 if (sd->inv != NULL)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2012 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2013 Expressions args;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2014 arg = d_save_expr (arg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2015 assert_pass = d_build_call_expr (sd->inv, arg, &args);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2016 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2017 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2018 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2019 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2020 else if (global.params.useAssert
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2021 && global.params.checkAction == CHECKACTION_C)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2022 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2023 /* Generate: __builtin_trap() */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2024 tree fn = builtin_decl_explicit (BUILT_IN_TRAP);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2025 assert_fail = build_call_expr (fn, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2026 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2027 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2028 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2029 /* Assert contracts are turned off, if the contract condition has no
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2030 side effects can still use it as a predicate for the optimizer. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2031 if (TREE_SIDE_EFFECTS (arg))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2032 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2033 this->result_ = void_node;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2034 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2035 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2036
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2037 assert_fail = build_predict_expr (PRED_NORETURN, NOT_TAKEN);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2038 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2039
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2040 /* Build condition that we are asserting in this contract. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2041 tree condition = convert_for_condition (arg, e->e1->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2042
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2043 /* We expect the condition to always be true, as what happens if an assert
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2044 contract is false is undefined behavior. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2045 tree fn = builtin_decl_explicit (BUILT_IN_EXPECT);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2046 tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2047 tree pred_type = TREE_VALUE (arg_types);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2048 tree expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2049
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2050 condition = build_call_expr (fn, 2, d_convert (pred_type, condition),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2051 build_int_cst (expected_type, 1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2052 condition = d_truthvalue_conversion (condition);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2053
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2054 this->result_ = build_vcondition (condition, assert_pass, assert_fail);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2055 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2056
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2057 /* Build a declaration expression. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2058
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2059 void visit (DeclarationExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2060 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2061 /* Compile the declaration. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2062 push_stmt_list ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2063 build_decl_tree (e->declaration);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2064 tree result = pop_stmt_list ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2065
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2066 /* Construction of an array for typesafe-variadic function arguments
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2067 can cause an empty STMT_LIST here. This can causes problems
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2068 during gimplification. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2069 if (TREE_CODE (result) == STATEMENT_LIST && !STATEMENT_LIST_HEAD (result))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2070 result = build_empty_stmt (input_location);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2071
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2072 this->result_ = result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2073 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2074
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2075 /* Build a typeid expression. Returns an instance of class TypeInfo
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2076 corresponding to. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2077
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2078 void visit (TypeidExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2079 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2080 if (Type *tid = isType (e->obj))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2081 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2082 tree ti = build_typeinfo (e->loc, tid);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2083
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2084 /* If the typeinfo is at an offset. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2085 if (tid->vtinfo->offset)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2086 ti = build_offset (ti, size_int (tid->vtinfo->offset));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2087
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2088 this->result_ = build_nop (build_ctype (e->type), ti);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2089 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2090 else if (Expression *tid = isExpression (e->obj))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2091 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2092 Type *type = tid->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2093 assert (type->ty == Tclass);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2094
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2095 /* Generate **classptr to get the classinfo. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2096 tree ci = build_expr (tid);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2097 ci = indirect_ref (ptr_type_node, ci);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2098 ci = indirect_ref (ptr_type_node, ci);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2099
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2100 /* Add extra indirection for interfaces. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2101 if (((TypeClass *) type)->sym->isInterfaceDeclaration ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2102 ci = indirect_ref (ptr_type_node, ci);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2103
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2104 this->result_ = build_nop (build_ctype (e->type), ci);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2105 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2106 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2107 gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2108 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2109
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2110 /* Build a function/lambda expression. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2111
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2112 void visit (FuncExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2113 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2114 Type *ftype = e->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2115
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2116 /* This check is for lambda's, remove 'vthis' as function isn't nested. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2117 if (e->fd->tok == TOKreserved && ftype->ty == Tpointer)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2118 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2119 e->fd->tok = TOKfunction;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2120 e->fd->vthis = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2121 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2122
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2123 /* Compile the function literal body. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2124 build_decl_tree (e->fd);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2125
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2126 /* If nested, this will be a trampoline. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2127 if (e->fd->isNested ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2128 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2129 tree func = build_address (get_symbol_decl (e->fd));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2130 tree object;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2131
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2132 if (this->constp_)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2133 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2134 /* Static delegate variables have no context pointer. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2135 object = null_pointer_node;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2136 this->result_ = build_method_call (func, object, e->fd->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2137 TREE_CONSTANT (this->result_) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2138 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2139 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2140 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2141 object = get_frame_for_symbol (e->fd);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2142 this->result_ = build_method_call (func, object, e->fd->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2143 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2144 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2145 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2146 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2147 this->result_ = build_nop (build_ctype (e->type),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2148 build_address (get_symbol_decl (e->fd)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2149 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2150 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2151
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2152 /* Build a halt expression. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2153
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2154 void visit (HaltExp *)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2155 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2156 /* Should we use trap() or abort()? */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2157 tree ttrap = builtin_decl_explicit (BUILT_IN_TRAP);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2158 this->result_ = build_call_expr (ttrap, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2159 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2160
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2161 /* Build a symbol pointer offset expression. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2162
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2163 void visit (SymOffExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2164 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2165 /* Build the address and offset of the symbol. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2166 size_t soffset = ((SymOffExp *) e)->offset;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2167 tree result = get_decl_tree (e->var);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2168 TREE_USED (result) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2169
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2170 if (declaration_reference_p (e->var))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2171 gcc_assert (POINTER_TYPE_P (TREE_TYPE (result)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2172 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2173 result = build_address (result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2174
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2175 if (!soffset)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2176 result = d_convert (build_ctype (e->type), result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2177 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2178 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2179 tree offset = size_int (soffset);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2180 result = build_nop (build_ctype (e->type),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2181 build_offset (result, offset));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2182 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2183
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2184 this->result_ = result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2185 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2186
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2187 /* Build a variable expression. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2188
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2189 void visit (VarExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2190 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2191 if (e->var->needThis ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2192 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2193 error ("need %<this%> to access member %qs", e->var->ident->toChars ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2194 this->result_ = error_mark_node;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2195 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2196 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2197 else if (e->var->ident == Identifier::idPool ("__ctfe"))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2198 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2199 /* __ctfe is always false at run-time. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2200 this->result_ = integer_zero_node;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2201 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2202 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2203
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2204 /* This check is same as is done in FuncExp for lambdas. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2205 FuncLiteralDeclaration *fld = e->var->isFuncLiteralDeclaration ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2206 if (fld != NULL)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2207 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2208 if (fld->tok == TOKreserved)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2209 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2210 fld->tok = TOKfunction;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2211 fld->vthis = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2212 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2213
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2214 /* Compiler the function literal body. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2215 build_decl_tree (fld);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2216 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2217
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2218 if (this->constp_)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2219 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2220 /* Want the initializer, not the expression. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2221 VarDeclaration *var = e->var->isVarDeclaration ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2222 SymbolDeclaration *sd = e->var->isSymbolDeclaration ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2223 tree init = NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2224
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2225 if (var && (var->isConst () || var->isImmutable ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2226 && e->type->toBasetype ()->ty != Tsarray && var->_init)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2227 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2228 if (var->inuse)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2229 error_at (make_location_t (e->loc), "recursive reference %qs",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2230 e->toChars ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2231 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2232 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2233 var->inuse++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2234 init = build_expr (initializerToExpression (var->_init), true);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2235 var->inuse--;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2236 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2237 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2238 else if (sd && sd->dsym)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2239 init = layout_struct_initializer (sd->dsym);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2240 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2241 error_at (make_location_t (e->loc), "non-constant expression %qs",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2242 e->toChars ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2243
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2244 if (init != NULL_TREE)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2245 this->result_ = init;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2246 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2247 this->result_ = error_mark_node;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2248 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2249 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2250 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2251 tree result = get_decl_tree (e->var);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2252 TREE_USED (result) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2253
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2254 /* For variables that are references - currently only out/inout
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2255 arguments; objects don't count - evaluating the variable means
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2256 we want what it refers to. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2257 if (declaration_reference_p (e->var))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2258 result = indirect_ref (build_ctype (e->var->type), result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2259
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2260 this->result_ = result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2261 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2262 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2263
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2264 /* Build a this variable expression. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2265
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2266 void visit (ThisExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2267 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2268 FuncDeclaration *fd = d_function_chain ? d_function_chain->function : NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2269 tree result = NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2270
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2271 if (e->var)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2272 result = get_decl_tree (e->var);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2273 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2274 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2275 gcc_assert (fd && fd->vthis);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2276 result = get_decl_tree (fd->vthis);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2277 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2278
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2279 if (e->type->ty == Tstruct)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2280 result = build_deref (result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2281
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2282 this->result_ = result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2283 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2284
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2285 /* Build a new expression, which allocates memory either on the garbage
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2286 collected heap or by using a class or struct specific allocator. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2287
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2288 void visit (NewExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2289 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2290 Type *tb = e->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2291 tree result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2292
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2293 if (e->allocator)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2294 gcc_assert (e->newargs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2295
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2296 if (tb->ty == Tclass)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2297 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2298 /* Allocating a new class. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2299 tb = e->newtype->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2300 gcc_assert (tb->ty == Tclass);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2301
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2302 ClassDeclaration *cd = ((TypeClass *) tb)->sym;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2303 tree type = build_ctype (tb);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2304 tree setup_exp = NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2305 tree new_call;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2306
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2307 if (e->onstack)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2308 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2309 /* If being used as an initializer for a local variable with scope
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2310 storage class, then the instance is allocated on the stack
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2311 rather than the heap or using the class specific allocator. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2312 tree var = build_local_temp (TREE_TYPE (type));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2313 new_call = build_nop (type, build_address (var));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2314 setup_exp = modify_expr (var, aggregate_initializer_decl (cd));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2315 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2316 else if (e->allocator)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2317 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2318 /* Call class allocator, and copy the initializer into memory. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2319 new_call = d_build_call_expr (e->allocator, NULL_TREE, e->newargs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2320 new_call = d_save_expr (new_call);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2321 new_call = build_nop (type, new_call);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2322 setup_exp = modify_expr (build_deref (new_call),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2323 aggregate_initializer_decl (cd));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2324 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2325 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2326 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2327 /* Generate: _d_newclass() */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2328 tree arg = build_address (get_classinfo_decl (cd));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2329 new_call = build_libcall (LIBCALL_NEWCLASS, tb, 1, arg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2330 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2331
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2332 /* Set the context pointer for nested classes. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2333 if (cd->isNested ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2334 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2335 tree field = get_symbol_decl (cd->vthis);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2336 tree value = NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2337
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2338 if (e->thisexp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2339 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2340 ClassDeclaration *tcd = e->thisexp->type->isClassHandle ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2341 Dsymbol *outer = cd->toParent2 ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2342 int offset = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2343
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2344 value = build_expr (e->thisexp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2345 if (outer != tcd)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2346 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2347 ClassDeclaration *ocd = outer->isClassDeclaration ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2348 gcc_assert (ocd->isBaseOf (tcd, &offset));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2349 /* Could just add offset... */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2350 value = convert_expr (value, e->thisexp->type, ocd->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2351 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2352 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2353 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2354 value = build_vthis (cd);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2355
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2356 if (value != NULL_TREE)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2357 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2358 /* Generate: (new())->vthis = this; */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2359 new_call = d_save_expr (new_call);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2360 field = component_ref (build_deref (new_call), field);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2361 setup_exp = compound_expr (setup_exp,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2362 modify_expr (field, value));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2363 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2364 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2365 new_call = compound_expr (setup_exp, new_call);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2366
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2367 /* Call the class constructor. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2368 if (e->member)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2369 result = d_build_call_expr (e->member, new_call, e->arguments);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2370 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2371 result = new_call;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2372
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2373 if (e->argprefix)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2374 result = compound_expr (build_expr (e->argprefix), result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2375 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2376 else if (tb->ty == Tpointer && tb->nextOf ()->toBasetype ()->ty == Tstruct)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2377 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2378 /* Allocating memory for a new struct. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2379 Type *htype = e->newtype->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2380 gcc_assert (htype->ty == Tstruct);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2381 gcc_assert (!e->onstack);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2382
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2383 TypeStruct *stype = (TypeStruct *) htype;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2384 StructDeclaration *sd = stype->sym;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2385 tree new_call;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2386
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2387 /* Cannot new an opaque struct. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2388 if (sd->size (e->loc) == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2389 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2390 this->result_ = d_convert (build_ctype (e->type),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2391 integer_zero_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2392 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2393 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2394
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2395 if (e->allocator)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2396 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2397 /* Call struct allocator. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2398 new_call = d_build_call_expr (e->allocator, NULL_TREE, e->newargs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2399 new_call = build_nop (build_ctype (tb), new_call);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2400 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2401 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2402 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2403 /* Generate: _d_newitemT() */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2404 libcall_fn libcall = htype->isZeroInit ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2405 ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2406 tree arg = build_typeinfo (e->loc, e->newtype);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2407 new_call = build_libcall (libcall, tb, 1, arg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2408 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2409
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2410 if (e->member || !e->arguments)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2411 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2412 /* Set the context pointer for nested structs. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2413 if (sd->isNested ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2414 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2415 tree value = build_vthis (sd);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2416 tree field = get_symbol_decl (sd->vthis);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2417 tree type = build_ctype (stype);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2418
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2419 new_call = d_save_expr (new_call);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2420 field = component_ref (indirect_ref (type, new_call), field);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2421 new_call = compound_expr (modify_expr (field, value), new_call);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2422 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2423
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2424 /* Call the struct constructor. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2425 if (e->member)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2426 result = d_build_call_expr (e->member, new_call, e->arguments);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2427 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2428 result = new_call;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2429 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2430 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2431 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2432 /* If we have a user supplied initializer, then set-up with a
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2433 struct literal. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2434 if (e->arguments != NULL && sd->fields.dim != 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2435 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2436 StructLiteralExp *se = StructLiteralExp::create (e->loc, sd,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2437 e->arguments,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2438 htype);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2439 new_call = d_save_expr (new_call);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2440 se->type = sd->type;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2441 se->sym = new_call;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2442 result = compound_expr (build_expr (se), new_call);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2443 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2444 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2445 result = new_call;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2446 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2447
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2448 if (e->argprefix)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2449 result = compound_expr (build_expr (e->argprefix), result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2450 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2451 else if (tb->ty == Tarray)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2452 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2453 /* Allocating memory for a new D array. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2454 tb = e->newtype->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2455 gcc_assert (tb->ty == Tarray);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2456 TypeDArray *tarray = (TypeDArray *) tb;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2457
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2458 gcc_assert (!e->allocator);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2459 gcc_assert (e->arguments && e->arguments->dim >= 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2460
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2461 if (e->arguments->dim == 1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2462 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2463 /* Single dimension array allocations. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2464 Expression *arg = (*e->arguments)[0];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2465
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2466 if (tarray->next->size () == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2467 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2468 /* Array element size is unknown. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2469 this->result_ = d_array_value (build_ctype (e->type),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2470 size_int (0), null_pointer_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2471 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2472 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2473
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2474 libcall_fn libcall = tarray->next->isZeroInit ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2475 ? LIBCALL_NEWARRAYT : LIBCALL_NEWARRAYIT;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2476 result = build_libcall (libcall, tb, 2,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2477 build_typeinfo (e->loc, e->type),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2478 build_expr (arg));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2479 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2480 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2481 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2482 /* Multidimensional array allocations. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2483 vec<constructor_elt, va_gc> *elms = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2484 Type *telem = e->newtype->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2485 tree tarray = make_array_type (Type::tsize_t, e->arguments->dim);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2486 tree var = create_temporary_var (tarray);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2487 tree init = build_constructor (TREE_TYPE (var), NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2488
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2489 for (size_t i = 0; i < e->arguments->dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2490 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2491 Expression *arg = (*e->arguments)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2492 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), build_expr (arg));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2493
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2494 gcc_assert (telem->ty == Tarray);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2495 telem = telem->toBasetype ()->nextOf ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2496 gcc_assert (telem);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2497 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2498
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2499 CONSTRUCTOR_ELTS (init) = elms;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2500 DECL_INITIAL (var) = init;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2501
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2502 /* Generate: _d_newarraymTX(ti, dims)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2503 or: _d_newarraymiTX(ti, dims) */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2504 libcall_fn libcall = telem->isZeroInit ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2505 ? LIBCALL_NEWARRAYMTX : LIBCALL_NEWARRAYMITX;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2506
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2507 tree tinfo = build_typeinfo (e->loc, e->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2508 tree dims = d_array_value (build_ctype (Type::tsize_t->arrayOf ()),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2509 size_int (e->arguments->dim),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2510 build_address (var));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2511
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2512 result = build_libcall (libcall, tb, 2, tinfo, dims);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2513 result = bind_expr (var, result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2514 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2515
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2516 if (e->argprefix)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2517 result = compound_expr (build_expr (e->argprefix), result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2518 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2519 else if (tb->ty == Tpointer)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2520 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2521 /* Allocating memory for a new pointer. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2522 TypePointer *tpointer = (TypePointer *) tb;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2523
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2524 if (tpointer->next->size () == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2525 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2526 /* Pointer element size is unknown. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2527 this->result_ = d_convert (build_ctype (e->type),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2528 integer_zero_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2529 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2530 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2531
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2532 libcall_fn libcall = tpointer->next->isZeroInit (e->loc)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2533 ? LIBCALL_NEWITEMT : LIBCALL_NEWITEMIT;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2534
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2535 tree arg = build_typeinfo (e->loc, e->newtype);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2536 result = build_libcall (libcall, tb, 1, arg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2537
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2538 if (e->arguments && e->arguments->dim == 1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2539 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2540 result = d_save_expr (result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2541 tree init = modify_expr (build_deref (result),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2542 build_expr ((*e->arguments)[0]));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2543 result = compound_expr (init, result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2544 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2545
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2546 if (e->argprefix)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2547 result = compound_expr (build_expr (e->argprefix), result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2548 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2549 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2550 gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2551
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2552 this->result_ = convert_expr (result, tb, e->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2553 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2554
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2555 /* Build an integer literal. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2556
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2557 void visit (IntegerExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2558 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2559 tree ctype = build_ctype (e->type->toBasetype ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2560 this->result_ = build_integer_cst (e->value, ctype);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2561 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2562
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2563 /* Build a floating-point literal. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2564
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2565 void visit (RealExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2566 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2567 this->result_ = build_float_cst (e->value, e->type->toBasetype ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2568 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2569
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2570 /* Build a complex literal. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2571
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2572 void visit (ComplexExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2573 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2574 Type *tnext;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2575
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2576 switch (e->type->toBasetype ()->ty)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2577 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2578 case Tcomplex32:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2579 tnext = (TypeBasic *) Type::tfloat32;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2580 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2581
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2582 case Tcomplex64:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2583 tnext = (TypeBasic *) Type::tfloat64;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2584 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2585
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2586 case Tcomplex80:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2587 tnext = (TypeBasic *) Type::tfloat80;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2588 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2589
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2590 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2591 gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2592 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2593
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2594 this->result_ = build_complex (build_ctype (e->type),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2595 build_float_cst (creall (e->value), tnext),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2596 build_float_cst (cimagl (e->value), tnext));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2597 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2598
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2599 /* Build a string literal, all strings are null terminated except for
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2600 static arrays. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2601
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2602 void visit (StringExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2603 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2604 Type *tb = e->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2605 tree type = build_ctype (e->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2606
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2607 if (tb->ty == Tsarray)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2608 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2609 /* Turn the string into a constructor for the static array. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2610 vec<constructor_elt, va_gc> *elms = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2611 vec_safe_reserve (elms, e->len);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2612 tree etype = TREE_TYPE (type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2613
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2614 for (size_t i = 0; i < e->len; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2615 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2616 tree value = build_integer_cst (e->charAt (i), etype);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2617 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2618 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2619
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2620 tree ctor = build_constructor (type, elms);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2621 TREE_CONSTANT (ctor) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2622 this->result_ = ctor;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2623 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2624 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2625 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2626 /* Copy the string contents to a null terminated string. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2627 dinteger_t length = (e->len * e->sz);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2628 char *string = XALLOCAVEC (char, length + 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2629 memcpy (string, e->string, length);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2630 string[length] = '\0';
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2631
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2632 /* String value and type includes the null terminator. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2633 tree value = build_string (length, string);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2634 TREE_TYPE (value) = make_array_type (tb->nextOf (), length + 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2635 value = build_address (value);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2636
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2637 if (tb->ty == Tarray)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2638 value = d_array_value (type, size_int (e->len), value);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2639
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2640 TREE_CONSTANT (value) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2641 this->result_ = d_convert (type, value);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2642 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2643 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2644
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2645 /* Build a tuple literal. Just an argument list that may have
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2646 side effects that need evaluation. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2647
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2648 void visit (TupleExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2649 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2650 tree result = NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2651
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2652 if (e->e0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2653 result = build_expr (e->e0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2654
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2655 for (size_t i = 0; i < e->exps->dim; ++i)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2656 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2657 Expression *exp = (*e->exps)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2658 result = compound_expr (result, build_expr (exp));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2659 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2660
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2661 if (result == NULL_TREE)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2662 result = void_node;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2663
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2664 this->result_ = result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2665 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2666
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2667 /* Build an array literal. The common type of the all elements is taken to
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2668 be the type of the array element, and all elements are implicitly
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2669 converted to that type. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2670
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2671 void visit (ArrayLiteralExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2672 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2673 Type *tb = e->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2674
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2675 /* Implicitly convert void[n] to ubyte[n]. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2676 if (tb->ty == Tsarray && tb->nextOf ()->toBasetype ()->ty == Tvoid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2677 tb = Type::tuns8->sarrayOf (((TypeSArray *) tb)->dim->toUInteger ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2678
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2679 gcc_assert (tb->ty == Tarray || tb->ty == Tsarray || tb->ty == Tpointer);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2680
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2681 /* Handle empty array literals. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2682 if (e->elements->dim == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2683 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2684 if (tb->ty == Tarray)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2685 this->result_ = d_array_value (build_ctype (e->type),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2686 size_int (0), null_pointer_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2687 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2688 this->result_ = build_constructor (make_array_type (tb->nextOf (), 0),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2689 NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2690
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2691 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2692 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2693
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2694 /* Build an expression that assigns the expressions in ELEMENTS to
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2695 a constructor. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2696 vec<constructor_elt, va_gc> *elms = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2697 vec_safe_reserve (elms, e->elements->dim);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2698 bool constant_p = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2699 tree saved_elems = NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2700
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2701 Type *etype = tb->nextOf ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2702 tree satype = make_array_type (etype, e->elements->dim);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2703
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2704 for (size_t i = 0; i < e->elements->dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2705 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2706 Expression *expr = e->getElement (i);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2707 tree value = build_expr (expr, this->constp_);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2708
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2709 /* Only append nonzero values, the backend will zero out the rest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2710 of the constructor as we don't set CONSTRUCTOR_NO_CLEARING. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2711 if (!initializer_zerop (value))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2712 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2713 if (!TREE_CONSTANT (value))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2714 constant_p = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2715
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2716 /* Split construction of values out of the constructor if there
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2717 may be side effects. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2718 tree init = stabilize_expr (&value);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2719 if (init != NULL_TREE)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2720 saved_elems = compound_expr (saved_elems, init);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2721
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2722 CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2723 convert_expr (value, expr->type, etype));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2724 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2725 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2726
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2727 /* Now return the constructor as the correct type. For static arrays there
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2728 is nothing else to do. For dynamic arrays, return a two field struct.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2729 For pointers, return the address. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2730 tree ctor = build_constructor (satype, elms);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2731 tree type = build_ctype (e->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2732
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2733 /* Nothing else to do for static arrays. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2734 if (tb->ty == Tsarray || this->constp_)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2735 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2736 /* Can't take the address of the constructor, so create an anonymous
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2737 static symbol, and then refer to it. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2738 if (tb->ty != Tsarray)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2739 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2740 tree decl = build_artificial_decl (TREE_TYPE (ctor), ctor, "A");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2741 ctor = build_address (decl);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2742 if (tb->ty == Tarray)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2743 ctor = d_array_value (type, size_int (e->elements->dim), ctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2744
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2745 d_pushdecl (decl);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2746 rest_of_decl_compilation (decl, 1, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2747 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2748
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2749 /* If the array literal is readonly or static. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2750 if (constant_p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2751 TREE_CONSTANT (ctor) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2752 if (constant_p && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2753 TREE_STATIC (ctor) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2754
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2755 this->result_ = compound_expr (saved_elems, d_convert (type, ctor));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2756 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2757 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2758 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2759 /* Allocate space on the memory managed heap. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2760 tree mem = build_libcall (LIBCALL_ARRAYLITERALTX,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2761 etype->pointerTo (), 2,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2762 build_typeinfo (e->loc, etype->arrayOf ()),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2763 size_int (e->elements->dim));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2764 mem = d_save_expr (mem);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2765
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2766 /* Now copy the constructor into memory. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2767 tree tmemcpy = builtin_decl_explicit (BUILT_IN_MEMCPY);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2768 tree size = size_mult_expr (size_int (e->elements->dim),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2769 size_int (tb->nextOf ()->size ()));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2770
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2771 tree result = build_call_expr (tmemcpy, 3, mem,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2772 build_address (ctor), size);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2773
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2774 /* Return the array pointed to by MEM. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2775 result = compound_expr (result, mem);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2776
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2777 if (tb->ty == Tarray)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2778 result = d_array_value (type, size_int (e->elements->dim), result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2779
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2780 this->result_ = compound_expr (saved_elems, result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2781 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2782 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2783
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2784 /* Build an associative array literal. The common type of the all keys is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2785 taken to be the key type, and common type of all values the value type.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2786 All keys and values are then implicitly converted as needed. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2787
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2788 void visit (AssocArrayLiteralExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2789 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2790 /* Want the mutable type for typeinfo reference. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2791 Type *tb = e->type->toBasetype ()->mutableOf ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2792 gcc_assert (tb->ty == Taarray);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2793
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2794 /* Handle empty assoc array literals. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2795 TypeAArray *ta = (TypeAArray *) tb;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2796 if (e->keys->dim == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2797 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2798 this->result_ = build_constructor (build_ctype (ta), NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2799 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2800 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2801
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2802 /* Build an expression that assigns all expressions in KEYS
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2803 to a constructor. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2804 vec<constructor_elt, va_gc> *kelts = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2805 vec_safe_reserve (kelts, e->keys->dim);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2806 for (size_t i = 0; i < e->keys->dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2807 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2808 Expression *key = (*e->keys)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2809 tree t = build_expr (key);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2810 CONSTRUCTOR_APPEND_ELT (kelts, size_int (i),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2811 convert_expr (t, key->type, ta->index));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2812 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2813 tree tkeys = make_array_type (ta->index, e->keys->dim);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2814 tree akeys = build_constructor (tkeys, kelts);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2815
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2816 /* Do the same with all expressions in VALUES. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2817 vec<constructor_elt, va_gc> *velts = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2818 vec_safe_reserve (velts, e->values->dim);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2819 for (size_t i = 0; i < e->values->dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2820 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2821 Expression *value = (*e->values)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2822 tree t = build_expr (value);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2823 CONSTRUCTOR_APPEND_ELT (velts, size_int (i),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2824 convert_expr (t, value->type, ta->next));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2825 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2826 tree tvals = make_array_type (ta->next, e->values->dim);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2827 tree avals = build_constructor (tvals, velts);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2828
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2829 /* Generate: _d_assocarrayliteralTX (ti, keys, vals); */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2830 tree keys = d_array_value (build_ctype (ta->index->arrayOf ()),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2831 size_int (e->keys->dim), build_address (akeys));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2832 tree vals = d_array_value (build_ctype (ta->next->arrayOf ()),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2833 size_int (e->values->dim),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2834 build_address (avals));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2835
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2836 tree mem = build_libcall (LIBCALL_ASSOCARRAYLITERALTX, Type::tvoidptr, 3,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2837 build_typeinfo (e->loc, ta), keys, vals);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2838
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2839 /* Return an associative array pointed to by MEM. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2840 tree aatype = build_ctype (ta);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2841 vec<constructor_elt, va_gc> *ce = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2842 CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2843
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2844 this->result_ = build_nop (build_ctype (e->type),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2845 build_constructor (aatype, ce));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2846 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2847
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2848 /* Build a struct literal. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2849
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2850 void visit (StructLiteralExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2851 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2852 /* Handle empty struct literals. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2853 if (e->elements == NULL || e->sd->fields.dim == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2854 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2855 this->result_ = build_constructor (build_ctype (e->type), NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2856 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2857 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2858
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2859 /* Building sinit trees are delayed until after frontend semantic
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2860 processing has complete. Build the static initializer now. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2861 if (e->useStaticInit && !this->constp_)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2862 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2863 this->result_ = aggregate_initializer_decl (e->sd);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2864 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2865 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2866
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2867 /* Build a constructor that assigns the expressions in ELEMENTS
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2868 at each field index that has been filled in. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2869 vec<constructor_elt, va_gc> *ve = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2870 tree saved_elems = NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2871
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2872 /* CTFE may fill the hidden pointer by NullExp. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2873 gcc_assert (e->elements->dim <= e->sd->fields.dim);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2874
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2875 Type *tb = e->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2876 gcc_assert (tb->ty == Tstruct);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2877
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2878 for (size_t i = 0; i < e->elements->dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2879 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2880 Expression *exp = (*e->elements)[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2881 if (!exp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2882 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2883
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2884 VarDeclaration *field = e->sd->fields[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2885 Type *type = exp->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2886 Type *ftype = field->type->toBasetype ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2887 tree value = NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2888
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2889 if (ftype->ty == Tsarray && !same_type_p (type, ftype))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2890 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2891 /* Initialize a static array with a single element. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2892 tree elem = build_expr (exp, this->constp_);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2893 elem = d_save_expr (elem);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2894
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2895 if (initializer_zerop (elem))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2896 value = build_constructor (build_ctype (ftype), NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2897 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2898 value = build_array_from_val (ftype, elem);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2899 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2900 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2901 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2902 value = convert_expr (build_expr (exp, this->constp_),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2903 exp->type, field->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2904 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2905
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2906 /* Split construction of values out of the constructor. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2907 tree init = stabilize_expr (&value);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2908 if (init != NULL_TREE)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2909 saved_elems = compound_expr (saved_elems, init);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2910
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2911 CONSTRUCTOR_APPEND_ELT (ve, get_symbol_decl (field), value);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2912 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2913
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2914 /* Maybe setup hidden pointer to outer scope context. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2915 if (e->sd->isNested () && e->elements->dim != e->sd->fields.dim
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2916 && this->constp_ == false)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2917 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2918 tree field = get_symbol_decl (e->sd->vthis);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2919 tree value = build_vthis (e->sd);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2920 CONSTRUCTOR_APPEND_ELT (ve, field, value);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2921 gcc_assert (e->useStaticInit == false);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2922 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2923
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2924 /* Build a constructor in the correct shape of the aggregate type. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2925 tree ctor = build_struct_literal (build_ctype (e->type), ve);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2926
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2927 /* Nothing more to do for constant literals. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2928 if (this->constp_)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2929 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2930 /* If the struct literal is a valid for static data. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2931 if (TREE_CONSTANT (ctor)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2932 && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2933 TREE_STATIC (ctor) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2934
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2935 this->result_ = compound_expr (saved_elems, ctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2936 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2937 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2938
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2939 if (e->sym != NULL)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2940 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2941 tree var = build_deref (e->sym);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2942 ctor = compound_expr (modify_expr (var, ctor), var);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2943 this->result_ = compound_expr (saved_elems, ctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2944 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2945 else if (e->sd->isUnionDeclaration ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2946 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2947 /* For unions, use memset to fill holes in the object. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2948 tree var = build_local_temp (TREE_TYPE (ctor));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2949 tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2950 tree init = build_call_expr (tmemset, 3, build_address (var),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2951 size_zero_node,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2952 size_int (e->sd->structsize));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2953
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2954 init = compound_expr (init, saved_elems);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2955 init = compound_expr (init, modify_expr (var, ctor));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2956 this->result_ = compound_expr (init, var);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2957 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2958 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2959 this->result_ = compound_expr (saved_elems, ctor);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2960 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2961
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2962 /* Build a null literal. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2963
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2964 void visit (NullExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2965 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2966 this->result_ = build_typeof_null_value (e->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2967 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2968
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2969 /* Build a vector literal. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2970
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2971 void visit (VectorExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2972 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2973 tree type = build_ctype (e->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2974 tree etype = TREE_TYPE (type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2975
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2976 /* First handle array literal expressions. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2977 if (e->e1->op == TOKarrayliteral)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2978 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2979 ArrayLiteralExp *ale = ((ArrayLiteralExp *) e->e1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2980 vec<constructor_elt, va_gc> *elms = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2981 bool constant_p = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2982
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2983 vec_safe_reserve (elms, ale->elements->dim);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2984 for (size_t i = 0; i < ale->elements->dim; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2985 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2986 Expression *expr = ale->getElement (i);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2987 tree value = d_convert (etype, build_expr (expr, this->constp_));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2988 if (!CONSTANT_CLASS_P (value))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2989 constant_p = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2990
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2991 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2992 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2993
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2994 /* Build a VECTOR_CST from a constant vector constructor. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2995 if (constant_p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2996 this->result_ = build_vector_from_ctor (type, elms);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2997 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2998 this->result_ = build_constructor (type, elms);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2999 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3000 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3001 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3002 /* Build constructor from single value. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3003 tree val = d_convert (etype, build_expr (e->e1, this->constp_));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3004 this->result_ = build_vector_from_val (type, val);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3005 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3006 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3007
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3008 /* Build a static array representation of a vector expression. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3009
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3010 void visit (VectorArrayExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3011 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3012 this->result_ = convert_expr (build_expr (e->e1, this->constp_),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3013 e->e1->type, e->type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3014 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3015
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3016 /* Build a static class literal, return its reference. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3017
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3018 void visit (ClassReferenceExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3019 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3020 /* The result of build_new_class_expr is a RECORD_TYPE, we want
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3021 the reference. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3022 tree var = build_address (build_new_class_expr (e));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3023
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3024 /* If the type of this literal is an interface, the we must add the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3025 interface offset to symbol. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3026 if (this->constp_)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3027 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3028 TypeClass *tc = (TypeClass *) e->type;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3029 InterfaceDeclaration *to = tc->sym->isInterfaceDeclaration ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3030
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3031 if (to != NULL)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3032 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3033 ClassDeclaration *from = e->originalClass ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3034 int offset = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3035
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3036 gcc_assert (to->isBaseOf (from, &offset) != 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3037
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3038 if (offset != 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3039 var = build_offset (var, size_int (offset));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3040 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3041 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3042
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3043 this->result_ = var;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3044 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3045
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3046 /* These expressions are mainly just a placeholders in the frontend.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3047 We shouldn't see them here. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3048
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3049 void visit (ScopeExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3050 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3051 error_at (make_location_t (e->loc), "%qs is not an expression",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3052 e->toChars ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3053 this->result_ = error_mark_node;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3054 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3055
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3056 void visit (TypeExp *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3057 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3058 error_at (make_location_t (e->loc), "type %qs is not an expression",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3059 e->toChars ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3060 this->result_ = error_mark_node;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3061 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3062 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3063
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3064
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3065 /* Main entry point for ExprVisitor interface to generate code for
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3066 the Expression AST class E. If CONST_P is true, then E is a
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3067 constant expression. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3068
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3069 tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3070 build_expr (Expression *e, bool const_p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3071 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3072 ExprVisitor v = ExprVisitor (const_p);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3073 location_t saved_location = input_location;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3074
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3075 input_location = make_location_t (e->loc);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3076 e->accept (&v);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3077 tree expr = v.result ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3078 input_location = saved_location;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3079
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3080 /* Check if initializer expression is valid constant. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3081 if (const_p && !initializer_constant_valid_p (expr, TREE_TYPE (expr)))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3082 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3083 error_at (make_location_t (e->loc), "non-constant expression %qs",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3084 e->toChars ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3085 return error_mark_node;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3086 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3087
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3088 return expr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3089 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3090
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3091 /* Same as build_expr, but also calls destructors on any temporaries. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3092
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3093 tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3094 build_expr_dtor (Expression *e)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3095 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3096 /* Codegen can be improved by determining if no exceptions can be thrown
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3097 between the ctor and dtor, and eliminating the ctor and dtor. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3098 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3099 tree result = build_expr (e);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3100
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3101 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3102 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3103 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3104 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3105 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3106
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3107 return result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3108 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3109
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3110 /* Same as build_expr_dtor, but handles the result of E as a return value. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3111
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3112 tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3113 build_return_dtor (Expression *e, Type *type, TypeFunction *tf)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3114 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3115 size_t saved_vars = vec_safe_length (d_function_chain->vars_in_scope);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3116 tree result = build_expr (e);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3117
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3118 /* Convert for initializing the DECL_RESULT. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3119 result = convert_expr (result, e->type, type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3120
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3121 /* If we are returning a reference, take the address. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3122 if (tf->isref)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3123 result = build_address (result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3124
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3125 /* The decl to store the return expression. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3126 tree decl = DECL_RESULT (cfun->decl);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3127
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3128 /* Split comma expressions, so that the result is returned directly. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3129 tree expr = stabilize_expr (&result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3130 result = build_assign (INIT_EXPR, decl, result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3131 result = compound_expr (expr, return_expr (result));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3132
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3133 /* May nest the return expression inside the try/finally expression. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3134 if (saved_vars != vec_safe_length (d_function_chain->vars_in_scope))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3135 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3136 result = fold_build_cleanup_point_expr (TREE_TYPE (result), result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3137 vec_safe_truncate (d_function_chain->vars_in_scope, saved_vars);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3138 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3139
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3140 return result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3141 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3142