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 <stdio.h>
25 #include "rtl.h"
26 #include "tree.h"
27 #include "flags.h"
28 #include "expr.h"
29 #include "cp-tree.h"
30
31 /* Hook used by expand_expr to expand language-specific tree codes. */
32
33 rtx
34 cplus_expand_expr (exp, target, tmode, modifier)
35 tree exp;
36 rtx target;
37 enum machine_mode tmode;
38 enum expand_modifier modifier;
39 {
40 tree type = TREE_TYPE (exp);
41 register enum machine_mode mode = TYPE_MODE (type);
42 register enum tree_code code = TREE_CODE (exp);
43 int ignore = target == const0_rtx;
44
45 if (ignore)
46 target = 0;
47
48 /* No sense saving up arithmetic to be done
49 if it's all in the wrong mode to form part of an address.
50 And force_operand won't know whether to sign-extend or zero-extend. */
51
52 if (mode != Pmode && modifier == EXPAND_SUM)
53 modifier = EXPAND_NORMAL;
54
55 switch (code)
56 {
57 case NEW_EXPR:
58 {
59 /* Something needs to be initialized, but we didn't know
60 where that thing was when building the tree. For example,
61 it could be the return value of a function, or a parameter
62 to a function which lays down in the stack, or a temporary
63 variable which must be passed by reference.
64
65 Cleanups are handled in a language-specific way: they
66 might be run by the called function (true in GNU C++
67 for parameters with cleanups), or they might be
68 run by the caller, after the call (true in GNU C++
69 for other cleanup needs). */
70
71 tree func = TREE_OPERAND (exp, 0);
72 tree args = TREE_OPERAND (exp, 1);
73 tree type = TREE_TYPE (exp), slot;
74 tree fn_type = TREE_TYPE (TREE_TYPE (func));
75 tree return_type = TREE_TYPE (fn_type);
76 tree call_exp;
77 rtx call_target, return_target;
78 int pcc_struct_return = 0;
79
80 /* The expression `init' wants to initialize what
81 `target' represents. SLOT holds the slot for TARGET. */
82 slot = TREE_OPERAND (exp, 2);
83
84 if (target == 0)
85 {
86 /* Should always be called with a target in BLKmode case. */
87 my_friendly_assert (mode != BLKmode, 205);
88 my_friendly_assert (DECL_RTL (slot) != 0, 206);
89
90 target = gen_reg_rtx (mode);
91 }
92
93 /* The target the initializer will initialize (CALL_TARGET)
94 must now be directed to initialize the target we are
95 supposed to initialize (TARGET). The semantics for
96 choosing what CALL_TARGET is is language-specific,
97 as is building the call which will perform the
98 initialization. It is left here to show the choices that
99 exist for C++. */
100
101 if (TREE_CODE (func) == ADDR_EXPR
102 && TREE_CODE (TREE_OPERAND (func, 0)) == FUNCTION_DECL
103 && DECL_CONSTRUCTOR_P (TREE_OPERAND (func, 0)))
104 {
105 type = build_pointer_type (type);
106 /* Don't clobber a value that might be part of a default
107 parameter value. */
108 mark_addressable (slot);
109 if (TREE_PERMANENT (args))
110 args = tree_cons (0, build1 (ADDR_EXPR, type, slot),
111 TREE_CHAIN (args));
112 else
113 TREE_VALUE (args) = build1 (ADDR_EXPR, type, slot);
114 call_target = 0;
115 }
116 else if (TREE_CODE (return_type) == REFERENCE_TYPE)
117 {
118 type = return_type;
119 call_target = 0;
120 }
121 else
122 {
123 #ifdef PCC_STATIC_STRUCT_RETURN
124 pcc_struct_return = 1;
125 call_target = 0;
126 #else
127 call_target = target;
128 #endif
129 }
130 if (call_target)
131 {
132 /* Make this a valid memory address now. The code below assumes
133 that it can compare rtx and make assumptions based on the
134 result. The assumptions are true only if the address was
135 valid to begin with. */
136 call_target = validize_mem (call_target);
137
138 /* If this is a reference to a symbol, expand_inline_function
139 will do this transformation and return a different target
140 than the one we gave it, though functionally equivalent. Do
141 the transformation here to avoid confusion. */
142 if (! cse_not_expected && GET_CODE (call_target) == MEM
143 && GET_CODE (XEXP (call_target, 0)) == SYMBOL_REF)
144 {
145 call_target = gen_rtx
146 (MEM, mode, memory_address (mode, XEXP (call_target, 0)));
147 MEM_IN_STRUCT_P (call_target) = 1;
148 }
149 }
150
151 call_exp = build (CALL_EXPR, type, func, args, NULL_TREE);
152 TREE_SIDE_EFFECTS (call_exp) = 1;
153 return_target = expand_call (call_exp, call_target, ignore);
154 if (call_target == 0)
155 {
156 if (pcc_struct_return)
157 {
158 extern int flag_access_control;
159 int old_ac = flag_access_control;
160
161 tree init = build_decl (VAR_DECL, 0, type);
162 TREE_ADDRESSABLE (init) = 1;
163 DECL_RTL (init) = return_target;
164
165 flag_access_control = 0;
166 expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING);
167 flag_access_control = old_ac;
168
169 if (TYPE_NEEDS_DESTRUCTOR (type))
170 {
171 init = build_decl (VAR_DECL, 0,
172 build_reference_type (type));
173 DECL_RTL (init) = XEXP (return_target, 0);
174
175 init = maybe_build_cleanup (convert_from_reference (init));
176 if (init != NULL_TREE)
177 expand_expr (init, const0_rtx, VOIDmode, 0);
178 }
179 call_target = return_target = DECL_RTL (slot);
180 }
181 else
182 call_target = return_target;
183 }
184
185 if (call_target != return_target)
186 {
187 my_friendly_assert (TYPE_HAS_TRIVIAL_INIT_REF (type), 317);
188 if (GET_MODE (return_target) == BLKmode)
189 emit_block_move (call_target, return_target, expr_size (exp),
190 TYPE_ALIGN (type) / BITS_PER_UNIT);
191 else
192 emit_move_insn (call_target, return_target);
193 }
194
195 if (TREE_CODE (return_type) == REFERENCE_TYPE)
196 {
197 tree init;
198
199 if (GET_CODE (call_target) == REG
200 && REGNO (call_target) < FIRST_PSEUDO_REGISTER)
201 my_friendly_abort (39);
202
203 type = TREE_TYPE (exp);
204
205 init = build (RTL_EXPR, return_type, 0, call_target);
206 /* We got back a reference to the type we want. Now initialize
207 target with that. */
208 expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING);
209 }
210
211 if (DECL_RTL (slot) != target)
212 emit_move_insn (DECL_RTL (slot), target);
213 return DECL_RTL (slot);
214 }
215
216 case OFFSET_REF:
217 {
218 #if 1
219 return expand_expr (default_conversion (resolve_offset_ref (exp)),
220 target, tmode, EXPAND_NORMAL);
221 #else
222 /* This is old crusty code, and does not handle all that the
223 resolve_offset_ref function does. (mrs) */
224 tree base = build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 0), 0);
225 tree offset = build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 1), 0);
226 return expand_expr (build (PLUS_EXPR, TREE_TYPE (exp), base, offset),
227 target, tmode, EXPAND_NORMAL);
228 #endif
229 }
230
231 case THUNK_DECL:
232 return DECL_RTL (exp);
233
234 case THROW_EXPR:
235 expand_throw (TREE_OPERAND (exp, 0));
236 return NULL;
237
238 case VEC_INIT_EXPR:
239 return expand_expr
240 (expand_vec_init
241 (NULL_TREE, TREE_OPERAND (exp, 0),
242 build_binary_op (MINUS_EXPR, TREE_OPERAND (exp, 2),
243 integer_one_node, 1),
244 TREE_OPERAND (exp, 1), 0), target, tmode, modifier);
245
246 default:
247 break;
248 }
249 my_friendly_abort (40);
250 /* NOTREACHED */
251 return NULL;
252 }
253
254 void
255 init_cplus_expand ()
256 {
257 lang_expand_expr = cplus_expand_expr;
258 }
259
260 /* If DECL had its rtl moved from where callers expect it
261 to be, fix it up. RESULT is the nominal rtl for the RESULT_DECL,
262 which may be a pseudo instead of a hard register. */
263
264 void
265 fixup_result_decl (decl, result)
266 tree decl;
267 rtx result;
268 {
269 if (REG_P (result))
270 {
271 if (REGNO (result) >= FIRST_PSEUDO_REGISTER)
272 {
273 rtx real_decl_result;
274
275 #ifdef FUNCTION_OUTGOING_VALUE
276 real_decl_result
277 = FUNCTION_OUTGOING_VALUE (TREE_TYPE (decl), current_function_decl);
278 #else
279 real_decl_result
280 = FUNCTION_VALUE (TREE_TYPE (decl), current_function_decl);
281 #endif
282 REG_FUNCTION_VALUE_P (real_decl_result) = 1;
283 result = real_decl_result;
284 }
285 store_expr (decl, result, 0);
286 emit_insn (gen_rtx (USE, VOIDmode, result));
287 }
288 }
289
290 /* Expand this initialization inline and see if it's simple enough that
291 it can be done at compile-time. */
292
293 static tree
294 extract_aggr_init (decl, init)
295 tree decl, init;
296 {
297 return 0;
298 }
299
300 static tree
301 extract_scalar_init (decl, init)
302 tree decl, init;
303 {
304 rtx value, insns, insn;
305 extern struct obstack temporary_obstack;
306 tree t = NULL_TREE;
307
308 push_obstacks (&temporary_obstack, &temporary_obstack);
309 start_sequence ();
310 value = expand_expr (init, NULL_RTX, VOIDmode, 0);
311 insns = get_insns ();
312 end_sequence ();
313 reg_scan (insns, max_reg_num (), 0);
314 jump_optimize (insns, 0, 0, 1);
315 pop_obstacks ();
316
317 for (insn = insns; insn; insn = NEXT_INSN (insn))
318 {
319 rtx r, to;
320
321 if (GET_CODE (insn) == NOTE)
322 continue;
323 else if (GET_CODE (insn) != INSN)
324 return 0;
325
326 r = PATTERN (insn);
327 if (GET_CODE (r) != SET)
328 return 0;
329
330 to = XEXP (r, 0);
331
332 if (! (to == value
333 || (GET_CODE (to) == SUBREG && XEXP (to, 0) == value)))
334 return 0;
335
336 r = XEXP (r, 1);
337
338 switch (GET_CODE (r))
339 {
340 case CONST_INT:
341 t = build_int_2 (XEXP (r, 0), 0);
342 break;
343 default:
344 return 0;
345 }
346 }
347
348 return t;
349 }
350
351 int
352 extract_init (decl, init)
353 tree decl, init;
354 {
355 return 0;
356
357 #if 0
358 if (IS_AGGR_TYPE (TREE_TYPE (decl))
359 || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
360 init = extract_aggr_init (decl, init);
361 else
362 init = extract_scalar_init (decl, init);
363
364 if (init == NULL_TREE)
365 return 0;
366
367 DECL_INITIAL (decl) = init;
368 return 1;
369 #endif
370 }
371
372 void
373 do_case (start, end)
374 tree start, end;
375 {
376 tree value1 = NULL_TREE, value2 = NULL_TREE, label;
377
378 if (start != NULL_TREE && TREE_TYPE (start) != NULL_TREE
379 && POINTER_TYPE_P (TREE_TYPE (start)))
380 error ("pointers are not permitted as case values");
381
382 if (end && pedantic)
383 pedwarn ("ANSI C++ forbids range expressions in switch statement");
384
385 if (processing_template_decl)
386 {
387 add_tree (build_min_nt (CASE_LABEL, start, end));
388 return;
389 }
390
391 if (start)
392 value1 = check_cp_case_value (start);
393 if (end)
394 value2 = check_cp_case_value (end);
395
396 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
397
398 if (value1 != error_mark_node
399 && value2 != error_mark_node)
400 {
401 tree duplicate;
402 int success;
403
404 if (end)
405 success = pushcase_range (value1, value2, convert_and_check,
406 label, &duplicate);
407 else if (start)
408 success = pushcase (value1, convert_and_check, label, &duplicate);
409 else
410 success = pushcase (NULL_TREE, 0, label, &duplicate);
411
412 if (success == 1)
413 {
414 if (end)
415 error ("case label not within a switch statement");
416 else if (start)
417 cp_error ("case label `%E' not within a switch statement", start);
418 else
419 error ("default label not within a switch statement");
420 }
421 else if (success == 2)
422 {
423 if (end)
424 {
425 error ("duplicate (or overlapping) case value");
426 cp_error_at ("this is the first entry overlapping that value",
427 duplicate);
428 }
429 else if (start)
430 {
431 cp_error ("duplicate case value `%E'", start);
432 cp_error_at ("previously used here", duplicate);
433 }
434 else
435 {
436 error ("multiple default labels in one switch");
437 cp_error_at ("this is the first default label", duplicate);
438 }
439 }
440 else if (success == 3)
441 warning ("case value out of range");
442 else if (success == 4)
443 warning ("empty range specified");
444 else if (success == 5)
445 {
446 if (end)
447 error ("case label within scope of cleanup or variable array");
448 else if (! start)
449 error ("`default' label within scope of cleanup or variable array");
450 else
451 cp_error ("case label `%E' within scope of cleanup or variable array", start);
452 }
453 }
454 if (start)
455 define_case_label (label);
456 else
457 define_case_label (NULL_TREE);
458 }