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