1 /* Convert language-specific tree expression to rtl instructions,
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)
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. */
31 static tree extract_aggr_init PROTO((tree, tree));
32 static tree extract_scalar_init PROTO((tree, tree));
33 static rtx cplus_expand_expr PROTO((tree, rtx, enum machine_mode,
34 enum expand_modifier));
36 /* Hook used by expand_expr to expand language-specific tree codes. */
39 cplus_expand_expr (exp, target, tmode, modifier)
42 enum machine_mode tmode;
43 enum expand_modifier modifier;
45 tree type = TREE_TYPE (exp);
46 register enum machine_mode mode = TYPE_MODE (type);
47 register enum tree_code code = TREE_CODE (exp);
48 int ignore = target == const0_rtx;
53 /* No sense saving up arithmetic to be done
54 if it's all in the wrong mode to form part of an address.
55 And force_operand won't know whether to sign-extend or zero-extend. */
57 if (mode != Pmode && modifier == EXPAND_SUM)
58 modifier = EXPAND_NORMAL;
64 /* Something needs to be initialized, but we didn't know
65 where that thing was when building the tree. For example,
66 it could be the return value of a function, or a parameter
67 to a function which lays down in the stack, or a temporary
68 variable which must be passed by reference.
70 Cleanups are handled in a language-specific way: they
71 might be run by the called function (true in GNU C++
72 for parameters with cleanups), or they might be
73 run by the caller, after the call (true in GNU C++
74 for other cleanup needs). */
76 tree func = TREE_OPERAND (exp, 0);
77 tree args = TREE_OPERAND (exp, 1);
78 tree type = TREE_TYPE (exp), slot;
79 tree fn_type = TREE_TYPE (TREE_TYPE (func));
80 tree return_type = TREE_TYPE (fn_type);
82 rtx call_target, return_target;
83 int pcc_struct_return = 0;
85 /* The expression `init' wants to initialize what
86 `target' represents. SLOT holds the slot for TARGET. */
87 slot = TREE_OPERAND (exp, 2);
91 /* Should always be called with a target in BLKmode case. */
92 my_friendly_assert (mode != BLKmode, 205);
93 my_friendly_assert (DECL_RTL (slot) != 0, 206);
95 target = gen_reg_rtx (mode);
98 /* The target the initializer will initialize (CALL_TARGET)
99 must now be directed to initialize the target we are
100 supposed to initialize (TARGET). The semantics for
101 choosing what CALL_TARGET is is language-specific,
102 as is building the call which will perform the
103 initialization. It is left here to show the choices that
106 if (TREE_CODE (func) == ADDR_EXPR
107 && TREE_CODE (TREE_OPERAND (func, 0)) == FUNCTION_DECL
108 && DECL_CONSTRUCTOR_P (TREE_OPERAND (func, 0)))
110 type = build_pointer_type (type);
111 /* Don't clobber a value that might be part of a default
113 mark_addressable (slot);
114 if (TREE_PERMANENT (args))
115 args = tree_cons (0, build1 (ADDR_EXPR, type, slot),
118 TREE_VALUE (args) = build1 (ADDR_EXPR, type, slot);
121 else if (TREE_CODE (return_type) == REFERENCE_TYPE)
128 #ifdef PCC_STATIC_STRUCT_RETURN
129 pcc_struct_return = 1;
132 call_target = target;
137 /* Make this a valid memory address now. The code below assumes
138 that it can compare rtx and make assumptions based on the
139 result. The assumptions are true only if the address was
140 valid to begin with. */
141 call_target = validize_mem (call_target);
143 /* If this is a reference to a symbol, expand_inline_function
144 will do this transformation and return a different target
145 than the one we gave it, though functionally equivalent. Do
146 the transformation here to avoid confusion. */
147 if (! cse_not_expected && GET_CODE (call_target) == MEM
148 && GET_CODE (XEXP (call_target, 0)) == SYMBOL_REF)
150 call_target = gen_rtx
151 (MEM, mode, memory_address (mode, XEXP (call_target, 0)));
152 MEM_IN_STRUCT_P (call_target) = 1;
156 call_exp = build (CALL_EXPR, type, func, args, NULL_TREE);
157 TREE_SIDE_EFFECTS (call_exp) = 1;
158 return_target = expand_call (call_exp, call_target, ignore);
159 if (call_target == 0)
161 if (pcc_struct_return)
163 extern int flag_access_control;
164 int old_ac = flag_access_control;
166 tree init = build_decl (VAR_DECL, 0, type);
167 TREE_ADDRESSABLE (init) = 1;
168 DECL_RTL (init) = return_target;
170 flag_access_control = 0;
171 expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING);
172 flag_access_control = old_ac;
174 if (TYPE_NEEDS_DESTRUCTOR (type))
176 init = build_decl (VAR_DECL, 0,
177 build_reference_type (type));
178 DECL_RTL (init) = XEXP (return_target, 0);
180 init = maybe_build_cleanup (convert_from_reference (init));
181 if (init != NULL_TREE)
182 expand_expr (init, const0_rtx, VOIDmode, 0);
184 call_target = return_target = DECL_RTL (slot);
187 call_target = return_target;
190 if (call_target != return_target)
192 my_friendly_assert (TYPE_HAS_TRIVIAL_INIT_REF (type), 317);
193 if (GET_MODE (return_target) == BLKmode)
194 emit_block_move (call_target, return_target, expr_size (exp),
195 TYPE_ALIGN (type) / BITS_PER_UNIT);
197 emit_move_insn (call_target, return_target);
200 if (TREE_CODE (return_type) == REFERENCE_TYPE)
204 if (GET_CODE (call_target) == REG
205 && REGNO (call_target) < FIRST_PSEUDO_REGISTER)
206 my_friendly_abort (39);
208 type = TREE_TYPE (exp);
210 init = build (RTL_EXPR, return_type, 0, call_target);
211 /* We got back a reference to the type we want. Now initialize
213 expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING);
216 if (DECL_RTL (slot) != target)
217 emit_move_insn (DECL_RTL (slot), target);
218 return DECL_RTL (slot);
224 return expand_expr (default_conversion (resolve_offset_ref (exp)),
225 target, tmode, EXPAND_NORMAL);
227 /* This is old crusty code, and does not handle all that the
228 resolve_offset_ref function does. (mrs) */
229 tree base = build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 0), 0);
230 tree offset = build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 1), 0);
231 return expand_expr (build (PLUS_EXPR, TREE_TYPE (exp), base, offset),
232 target, tmode, EXPAND_NORMAL);
237 return DECL_RTL (exp);
240 expand_throw (TREE_OPERAND (exp, 0));
246 (NULL_TREE, TREE_OPERAND (exp, 0),
247 build_binary_op (MINUS_EXPR, TREE_OPERAND (exp, 2),
248 integer_one_node, 1),
249 TREE_OPERAND (exp, 1), 0), target, tmode, modifier);
254 my_friendly_abort (40);
262 lang_expand_expr = cplus_expand_expr;
265 /* If DECL had its rtl moved from where callers expect it
266 to be, fix it up. RESULT is the nominal rtl for the RESULT_DECL,
267 which may be a pseudo instead of a hard register. */
270 fixup_result_decl (decl, result)
276 if (REGNO (result) >= FIRST_PSEUDO_REGISTER)
278 rtx real_decl_result;
280 #ifdef FUNCTION_OUTGOING_VALUE
282 = FUNCTION_OUTGOING_VALUE (TREE_TYPE (decl), current_function_decl);
285 = FUNCTION_VALUE (TREE_TYPE (decl), current_function_decl);
287 REG_FUNCTION_VALUE_P (real_decl_result) = 1;
288 result = real_decl_result;
290 store_expr (decl, result, 0);
291 emit_insn (gen_rtx (USE, VOIDmode, result));
295 /* Expand this initialization inline and see if it's simple enough that
296 it can be done at compile-time. */
299 extract_aggr_init (decl, init)
306 extract_scalar_init (decl, init)
309 rtx value, insns, insn;
310 extern struct obstack temporary_obstack;
313 push_obstacks (&temporary_obstack, &temporary_obstack);
315 value = expand_expr (init, NULL_RTX, VOIDmode, 0);
316 insns = get_insns ();
318 reg_scan (insns, max_reg_num (), 0);
319 jump_optimize (insns, 0, 0, 1);
322 for (insn = insns; insn; insn = NEXT_INSN (insn))
326 if (GET_CODE (insn) == NOTE)
328 else if (GET_CODE (insn) != INSN)
332 if (GET_CODE (r) != SET)
338 || (GET_CODE (to) == SUBREG && XEXP (to, 0) == value)))
343 switch (GET_CODE (r))
346 t = build_int_2 (XEXP (r, 0), 0);
357 extract_init (decl, init)
363 if (IS_AGGR_TYPE (TREE_TYPE (decl))
364 || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
365 init = extract_aggr_init (decl, init);
367 init = extract_scalar_init (decl, init);
369 if (init == NULL_TREE)
372 DECL_INITIAL (decl) = init;
381 tree value1 = NULL_TREE, value2 = NULL_TREE, label;
383 if (start != NULL_TREE && TREE_TYPE (start) != NULL_TREE
384 && POINTER_TYPE_P (TREE_TYPE (start)))
385 error ("pointers are not permitted as case values");
388 pedwarn ("ANSI C++ forbids range expressions in switch statement");
390 if (processing_template_decl)
392 add_tree (build_min_nt (CASE_LABEL, start, end));
397 value1 = check_cp_case_value (start);
399 value2 = check_cp_case_value (end);
401 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
403 if (value1 != error_mark_node
404 && value2 != error_mark_node)
410 success = pushcase_range (value1, value2, convert_and_check,
413 success = pushcase (value1, convert_and_check, label, &duplicate);
415 success = pushcase (NULL_TREE, 0, label, &duplicate);
420 error ("case label not within a switch statement");
422 cp_error ("case label `%E' not within a switch statement", start);
424 error ("default label not within a switch statement");
426 else if (success == 2)
430 error ("duplicate (or overlapping) case value");
431 cp_error_at ("this is the first entry overlapping that value",
436 cp_error ("duplicate case value `%E'", start);
437 cp_error_at ("previously used here", duplicate);
441 error ("multiple default labels in one switch");
442 cp_error_at ("this is the first default label", duplicate);
445 else if (success == 3)
446 warning ("case value out of range");
447 else if (success == 4)
448 warning ("empty range specified");
449 else if (success == 5)
452 error ("case label within scope of cleanup or variable array");
454 error ("`default' label within scope of cleanup or variable array");
456 cp_error ("case label `%E' within scope of cleanup or variable array", start);
460 define_case_label (label);
462 define_case_label (NULL_TREE);