89th Cygnus<->FSF quick merge
[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 = build_pointer_type (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 /* If this is a reference to a symbol, expand_inline_function
142 will do this transformation and return a different target
143 than the one we gave it, though functionally equivalent. Do
144 the transformation here to avoid confusion. */
145 if (! cse_not_expected && GET_CODE (call_target) == MEM
146 && GET_CODE (XEXP (call_target, 0)) == SYMBOL_REF)
147 {
148 call_target = gen_rtx
149 (MEM, mode, memory_address (mode, XEXP (call_target, 0)));
150 MEM_IN_STRUCT_P (call_target) = 1;
151 }
152 }
153
154 call_exp = build (CALL_EXPR, type, func, args, NULL_TREE);
155 TREE_SIDE_EFFECTS (call_exp) = 1;
156 return_target = expand_call (call_exp, call_target, ignore);
157 if (call_target == 0)
158 {
159 if (pcc_struct_return)
160 {
161 extern int flag_access_control;
162 int old_ac = flag_access_control;
163
164 tree init = build_decl (VAR_DECL, 0, type);
165 TREE_ADDRESSABLE (init) = 1;
166 DECL_RTL (init) = return_target;
167
168 flag_access_control = 0;
169 expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING);
170 flag_access_control = old_ac;
171
172 if (TYPE_NEEDS_DESTRUCTOR (type))
173 {
174 init = build_decl (VAR_DECL, 0,
175 build_reference_type (type));
176 DECL_RTL (init) = XEXP (return_target, 0);
177
178 init = maybe_build_cleanup (convert_from_reference (init));
179 if (init != NULL_TREE)
180 expand_expr (init, const0_rtx, VOIDmode, 0);
181 }
182 call_target = return_target = DECL_RTL (slot);
183 }
184 else
185 call_target = return_target;
186 }
187
188 if (call_target != return_target)
189 {
190 my_friendly_assert (TYPE_HAS_TRIVIAL_INIT_REF (type), 317);
191 if (GET_MODE (return_target) == BLKmode)
192 emit_block_move (call_target, return_target, expr_size (exp),
193 TYPE_ALIGN (type) / BITS_PER_UNIT);
194 else
195 emit_move_insn (call_target, return_target);
196 }
197
198 if (TREE_CODE (return_type) == REFERENCE_TYPE)
199 {
200 tree init;
201
202 if (GET_CODE (call_target) == REG
203 && REGNO (call_target) < FIRST_PSEUDO_REGISTER)
204 my_friendly_abort (39);
205
206 type = TREE_TYPE (exp);
207
208 init = build (RTL_EXPR, return_type, 0, call_target);
209 /* We got back a reference to the type we want. Now initialize
210 target with that. */
211 expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING);
212 }
213
214 if (DECL_RTL (slot) != target)
215 emit_move_insn (DECL_RTL (slot), target);
216 return DECL_RTL (slot);
217 }
218
219 case OFFSET_REF:
220 {
221 #if 1
222 return expand_expr (default_conversion (resolve_offset_ref (exp)),
223 target, tmode, EXPAND_NORMAL);
224 #else
225 /* This is old crusty code, and does not handle all that the
226 resolve_offset_ref function does. (mrs) */
227 tree base = build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 0), 0);
228 tree offset = build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 1), 0);
229 return expand_expr (build (PLUS_EXPR, TREE_TYPE (exp), base, offset),
230 target, tmode, EXPAND_NORMAL);
231 #endif
232 }
233
234 case THUNK_DECL:
235 return DECL_RTL (exp);
236
237 case THROW_EXPR:
238 expand_throw (TREE_OPERAND (exp, 0));
239 return NULL;
240
241 case VEC_INIT_EXPR:
242 return expand_expr
243 (expand_vec_init
244 (NULL_TREE, TREE_OPERAND (exp, 0),
245 build_binary_op (MINUS_EXPR, TREE_OPERAND (exp, 2),
246 integer_one_node, 1),
247 TREE_OPERAND (exp, 1), 0), target, tmode, modifier);
248
249 default:
250 break;
251 }
252 my_friendly_abort (40);
253 /* NOTREACHED */
254 return NULL;
255 }
256
257 void
258 init_cplus_expand ()
259 {
260 lang_expand_expr = cplus_expand_expr;
261 }
262
263 /* If DECL had its rtl moved from where callers expect it
264 to be, fix it up. RESULT is the nominal rtl for the RESULT_DECL,
265 which may be a pseudo instead of a hard register. */
266
267 void
268 fixup_result_decl (decl, result)
269 tree decl;
270 rtx result;
271 {
272 if (REG_P (result))
273 {
274 if (REGNO (result) >= FIRST_PSEUDO_REGISTER)
275 {
276 rtx real_decl_result;
277
278 #ifdef FUNCTION_OUTGOING_VALUE
279 real_decl_result
280 = FUNCTION_OUTGOING_VALUE (TREE_TYPE (decl), current_function_decl);
281 #else
282 real_decl_result
283 = FUNCTION_VALUE (TREE_TYPE (decl), current_function_decl);
284 #endif
285 REG_FUNCTION_VALUE_P (real_decl_result) = 1;
286 result = real_decl_result;
287 }
288 store_expr (decl, result, 0);
289 emit_insn (gen_rtx (USE, VOIDmode, result));
290 }
291 }
292
293 /* Expand this initialization inline and see if it's simple enough that
294 it can be done at compile-time. */
295
296 static tree
297 extract_aggr_init (decl, init)
298 tree decl, init;
299 {
300 return 0;
301 }
302
303 static tree
304 extract_scalar_init (decl, init)
305 tree decl, init;
306 {
307 rtx value, insns, insn;
308 extern struct obstack temporary_obstack;
309 tree t = NULL_TREE;
310
311 push_obstacks (&temporary_obstack, &temporary_obstack);
312 start_sequence ();
313 value = expand_expr (init, NULL_RTX, VOIDmode, 0);
314 insns = get_insns ();
315 end_sequence ();
316 reg_scan (insns, max_reg_num (), 0);
317 jump_optimize (insns, 0, 0, 1);
318 pop_obstacks ();
319
320 for (insn = insns; insn; insn = NEXT_INSN (insn))
321 {
322 rtx r, to;
323
324 if (GET_CODE (insn) == NOTE)
325 continue;
326 else if (GET_CODE (insn) != INSN)
327 return 0;
328
329 r = PATTERN (insn);
330 if (GET_CODE (r) != SET)
331 return 0;
332
333 to = XEXP (r, 0);
334
335 if (! (to == value ||
336 (GET_CODE (to) == SUBREG && XEXP (to, 0) == value)))
337 return 0;
338
339 r = XEXP (r, 1);
340
341 switch (GET_CODE (r))
342 {
343 case CONST_INT:
344 t = build_int_2 (XEXP (r, 0), 0);
345 break;
346 default:
347 return 0;
348 }
349 }
350
351 return t;
352 }
353
354 int
355 extract_init (decl, init)
356 tree decl, init;
357 {
358 return 0;
359
360 #if 0
361 if (IS_AGGR_TYPE (TREE_TYPE (decl))
362 || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
363 init = extract_aggr_init (decl, init);
364 else
365 init = extract_scalar_init (decl, init);
366
367 if (init == NULL_TREE)
368 return 0;
369
370 DECL_INITIAL (decl) = init;
371 return 1;
372 #endif
373 }
374
375 void
376 do_case (start, end)
377 tree start, end;
378 {
379 tree value1 = NULL_TREE, value2 = NULL_TREE, label;
380
381 if (start != NULL_TREE && TREE_TYPE (start) != NULL_TREE
382 && POINTER_TYPE_P (TREE_TYPE (start)))
383 error ("pointers are not permitted as case values");
384
385 if (end && pedantic)
386 pedwarn ("ANSI C++ forbids range expressions in switch statement");
387
388 if (processing_template_decl)
389 {
390 add_tree (build_min_nt (CASE_LABEL, start, end));
391 return;
392 }
393
394 if (start)
395 value1 = check_cp_case_value (start);
396 if (end)
397 value2 = check_cp_case_value (end);
398
399 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
400
401 if (value1 != error_mark_node
402 && value2 != error_mark_node)
403 {
404 tree duplicate;
405 int success;
406
407 if (end)
408 success = pushcase_range (value1, value2, convert_and_check,
409 label, &duplicate);
410 else if (start)
411 success = pushcase (value1, convert_and_check, label, &duplicate);
412 else
413 success = pushcase (NULL_TREE, 0, label, &duplicate);
414
415 if (success == 1)
416 {
417 if (end)
418 error ("case label not within a switch statement");
419 else if (start)
420 cp_error ("case label `%E' not within a switch statement", start);
421 else
422 error ("default label not within a switch statement");
423 }
424 else if (success == 2)
425 {
426 if (end)
427 {
428 error ("duplicate (or overlapping) case value");
429 cp_error_at ("this is the first entry overlapping that value",
430 duplicate);
431 }
432 else if (start)
433 {
434 cp_error ("duplicate case value `%E'", start);
435 cp_error_at ("previously used here", duplicate);
436 }
437 else
438 {
439 error ("multiple default labels in one switch");
440 cp_error_at ("this is the first default label", duplicate);
441 }
442 }
443 else if (success == 3)
444 warning ("case value out of range");
445 else if (success == 4)
446 warning ("empty range specified");
447 else if (success == 5)
448 {
449 if (end)
450 error ("case label within scope of cleanup or variable array");
451 else
452 cp_error ("case label `%E' within scope of cleanup or variable array", start);
453 }
454 }
455 if (start)
456 define_case_label (label);
457 else
458 define_case_label (NULL_TREE);
459 }