(cplus_expand_expr): Don't mess with temp slots.
[gcc.git] / gcc / cp / expr.c
1 /* Convert language-specific tree expression to rtl instructions,
2 for GNU compiler.
3 Copyright (C) 1988, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22
23 #include "config.h"
24 #include "rtl.h"
25 #include "tree.h"
26 #include "flags.h"
27 #include "expr.h"
28 #include "cp-tree.h"
29
30 #undef NULL
31 #define NULL 0
32
33 /* Hook used by expand_expr to expand language-specific tree codes. */
34
35 rtx
36 cplus_expand_expr (exp, target, tmode, modifier)
37 tree exp;
38 rtx target;
39 enum machine_mode tmode;
40 enum expand_modifier modifier;
41 {
42 tree type = TREE_TYPE (exp);
43 register enum machine_mode mode = TYPE_MODE (type);
44 register enum tree_code code = TREE_CODE (exp);
45 rtx original_target = target;
46 int ignore = target == const0_rtx;
47
48 if (ignore)
49 target = 0, original_target = 0;
50
51 /* No sense saving up arithmetic to be done
52 if it's all in the wrong mode to form part of an address.
53 And force_operand won't know whether to sign-extend or zero-extend. */
54
55 if (mode != Pmode && modifier == EXPAND_SUM)
56 modifier = EXPAND_NORMAL;
57
58 switch (code)
59 {
60 case NEW_EXPR:
61 {
62 /* Something needs to be initialized, but we didn't know
63 where that thing was when building the tree. For example,
64 it could be the return value of a function, or a parameter
65 to a function which lays down in the stack, or a temporary
66 variable which must be passed by reference.
67
68 Cleanups are handled in a language-specific way: they
69 might be run by the called function (true in GNU C++
70 for parameters with cleanups), or they might be
71 run by the caller, after the call (true in GNU C++
72 for other cleanup needs). */
73
74 tree func = TREE_OPERAND (exp, 0);
75 tree args = TREE_OPERAND (exp, 1);
76 tree type = TREE_TYPE (exp), slot;
77 tree fn_type = TREE_TYPE (TREE_TYPE (func));
78 tree return_type = TREE_TYPE (fn_type);
79 tree call_exp;
80 rtx call_target, return_target;
81 int pcc_struct_return = 0;
82
83 /* The expression `init' wants to initialize what
84 `target' represents. SLOT holds the slot for TARGET. */
85 slot = TREE_OPERAND (exp, 2);
86
87 if (target == 0)
88 {
89 /* Should always be called with a target in BLKmode case. */
90 my_friendly_assert (mode != BLKmode, 205);
91 my_friendly_assert (DECL_RTL (slot) != 0, 206);
92
93 target = gen_reg_rtx (mode);
94 }
95
96 /* The target the initializer will initialize (CALL_TARGET)
97 must now be directed to initialize the target we are
98 supposed to initialize (TARGET). The semantics for
99 choosing what CALL_TARGET is is language-specific,
100 as is building the call which will perform the
101 initialization. It is left here to show the choices that
102 exist for C++. */
103
104 if (TREE_CODE (func) == ADDR_EXPR
105 && TREE_CODE (TREE_OPERAND (func, 0)) == FUNCTION_DECL
106 && DECL_CONSTRUCTOR_P (TREE_OPERAND (func, 0)))
107 {
108 type = TYPE_POINTER_TO (type);
109 /* Don't clobber a value that might be part of a default
110 parameter value. */
111 mark_addressable (slot);
112 if (TREE_PERMANENT (args))
113 args = tree_cons (0, build1 (ADDR_EXPR, type, slot),
114 TREE_CHAIN (args));
115 else
116 TREE_VALUE (args) = build1 (ADDR_EXPR, type, slot);
117 call_target = 0;
118 }
119 else if (TREE_CODE (return_type) == REFERENCE_TYPE)
120 {
121 type = return_type;
122 call_target = 0;
123 }
124 else
125 {
126 #ifdef PCC_STATIC_STRUCT_RETURN
127 pcc_struct_return = 1;
128 call_target = 0;
129 #else
130 call_target = target;
131 #endif
132 }
133 if (call_target)
134 {
135 /* Make this a valid memory address now. The code below assumes
136 that it can compare rtx and make assumptions based on the
137 result. The assumptions are true only if the address was
138 valid to begin with. */
139 call_target = validize_mem (call_target);
140 }
141
142 call_exp = build (CALL_EXPR, type, func, args, 0);
143 TREE_SIDE_EFFECTS (call_exp) = 1;
144 return_target = expand_call (call_exp, call_target, ignore);
145 if (call_target == 0)
146 {
147 if (pcc_struct_return)
148 {
149 extern int flag_access_control;
150 int old_ac = flag_access_control;
151
152 tree init = build_decl (VAR_DECL, 0, type);
153 TREE_ADDRESSABLE (init) = 1;
154 DECL_RTL (init) = return_target;
155
156 flag_access_control = 0;
157 expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING);
158 flag_access_control = old_ac;
159
160 if (TYPE_NEEDS_DESTRUCTOR (type))
161 {
162 init = build_decl (VAR_DECL, 0,
163 build_reference_type (type));
164 DECL_RTL (init) = XEXP (return_target, 0);
165
166 init = maybe_build_cleanup (convert_from_reference (init));
167 if (init != NULL_TREE)
168 expand_expr (init, 0, 0, 0);
169 }
170 call_target = return_target = DECL_RTL (slot);
171 }
172 else
173 call_target = return_target;
174 }
175
176 if (call_target != return_target)
177 {
178 my_friendly_assert (TYPE_HAS_TRIVIAL_INIT_REF (type), 317);
179 if (GET_MODE (return_target) == BLKmode)
180 emit_block_move (call_target, return_target, expr_size (exp),
181 TYPE_ALIGN (type) / BITS_PER_UNIT);
182 else
183 emit_move_insn (call_target, return_target);
184 }
185
186 if (TREE_CODE (return_type) == REFERENCE_TYPE)
187 {
188 tree init;
189
190 if (GET_CODE (call_target) == REG
191 && REGNO (call_target) < FIRST_PSEUDO_REGISTER)
192 my_friendly_abort (39);
193
194 type = TREE_TYPE (exp);
195
196 init = build (RTL_EXPR, return_type, 0, call_target);
197 /* We got back a reference to the type we want. Now initialize
198 target with that. */
199 expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING);
200 }
201
202 if (DECL_RTL (slot) != target)
203 emit_move_insn (DECL_RTL (slot), target);
204 return DECL_RTL (slot);
205 }
206
207 case OFFSET_REF:
208 {
209 #if 1
210 return expand_expr (default_conversion (resolve_offset_ref (exp)),
211 target, tmode, EXPAND_NORMAL);
212 #else
213 /* This is old crusty code, and does not handle all that the
214 resolve_offset_ref function does. (mrs) */
215 tree base = build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 0), 0);
216 tree offset = build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 1), 0);
217 return expand_expr (build (PLUS_EXPR, TREE_TYPE (exp), base, offset),
218 target, tmode, EXPAND_NORMAL);
219 #endif
220 }
221
222 case THUNK_DECL:
223 return DECL_RTL (exp);
224
225 case THROW_EXPR:
226 expand_throw (TREE_OPERAND (exp, 0));
227 return NULL;
228
229 default:
230 break;
231 }
232 my_friendly_abort (40);
233 /* NOTREACHED */
234 return NULL;
235 }
236
237 void
238 init_cplus_expand ()
239 {
240 lang_expand_expr = cplus_expand_expr;
241 }
242
243 /* If DECL had its rtl moved from where callers expect it
244 to be, fix it up. RESULT is the nominal rtl for the RESULT_DECL,
245 which may be a pseudo instead of a hard register. */
246
247 void
248 fixup_result_decl (decl, result)
249 tree decl;
250 rtx result;
251 {
252 if (REG_P (result))
253 {
254 if (REGNO (result) >= FIRST_PSEUDO_REGISTER)
255 {
256 rtx real_decl_result;
257
258 #ifdef FUNCTION_OUTGOING_VALUE
259 real_decl_result
260 = FUNCTION_OUTGOING_VALUE (TREE_TYPE (decl), current_function_decl);
261 #else
262 real_decl_result
263 = FUNCTION_VALUE (TREE_TYPE (decl), current_function_decl);
264 #endif
265 REG_FUNCTION_VALUE_P (real_decl_result) = 1;
266 result = real_decl_result;
267 }
268 store_expr (decl, result, 0);
269 emit_insn (gen_rtx (USE, VOIDmode, result));
270 }
271 }
272
273 /* Return nonzero iff DECL is memory-based. The DECL_RTL of
274 certain const variables might be a CONST_INT, or a REG
275 in some cases. We cannot use `memory_operand' as a test
276 here because on most RISC machines, a variable's address
277 is not, by itself, a legitimate address. */
278
279 int
280 decl_in_memory_p (decl)
281 tree decl;
282 {
283 return DECL_RTL (decl) != 0 && GET_CODE (DECL_RTL (decl)) == MEM;
284 }
285
286 /* Expand this initialization inline and see if it's simple enough that
287 it can be done at compile-time. */
288
289 static tree
290 extract_aggr_init (decl, init)
291 tree decl, init;
292 {
293 return 0;
294 }
295
296 static tree
297 extract_scalar_init (decl, init)
298 tree decl, init;
299 {
300 rtx value, insns, insn;
301 extern struct obstack temporary_obstack;
302 tree t = NULL_TREE;
303
304 push_obstacks (&temporary_obstack, &temporary_obstack);
305 start_sequence ();
306 value = expand_expr (init, NULL_RTX, VOIDmode, 0);
307 insns = get_insns ();
308 end_sequence ();
309 reg_scan (insns, max_reg_num (), 0);
310 jump_optimize (insns, 0, 0, 1);
311 pop_obstacks ();
312
313 for (insn = insns; insn; insn = NEXT_INSN (insn))
314 {
315 rtx r, to;
316
317 if (GET_CODE (insn) == NOTE)
318 continue;
319 else if (GET_CODE (insn) != INSN)
320 return 0;
321
322 r = PATTERN (insn);
323 if (GET_CODE (r) != SET)
324 return 0;
325
326 to = XEXP (r, 0);
327
328 if (! (to == value ||
329 (GET_CODE (to) == SUBREG && XEXP (to, 0) == value)))
330 return 0;
331
332 r = XEXP (r, 1);
333
334 switch (GET_CODE (r))
335 {
336 case CONST_INT:
337 t = build_int_2 (XEXP (r, 0), 0);
338 break;
339 default:
340 return 0;
341 }
342 }
343
344 return t;
345 }
346
347 int
348 extract_init (decl, init)
349 tree decl, init;
350 {
351 return 0;
352
353 if (IS_AGGR_TYPE (TREE_TYPE (decl))
354 || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
355 init = extract_aggr_init (decl, init);
356 else
357 init = extract_scalar_init (decl, init);
358
359 if (init == NULL_TREE)
360 return 0;
361
362 DECL_INITIAL (decl) = init;
363 return 1;
364 }