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 /* Hook used by expand_expr to expand language-specific tree codes. */
34 cplus_expand_expr (exp
, target
, tmode
, modifier
)
37 enum machine_mode tmode
;
38 enum expand_modifier modifier
;
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
;
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. */
52 if (mode
!= Pmode
&& modifier
== EXPAND_SUM
)
53 modifier
= EXPAND_NORMAL
;
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.
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). */
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
);
77 rtx call_target
, return_target
;
78 int pcc_struct_return
= 0;
80 /* The expression `init' wants to initialize what
81 `target' represents. SLOT holds the slot for TARGET. */
82 slot
= TREE_OPERAND (exp
, 2);
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);
90 target
= gen_reg_rtx (mode
);
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
101 if (TREE_CODE (func
) == ADDR_EXPR
102 && TREE_CODE (TREE_OPERAND (func
, 0)) == FUNCTION_DECL
103 && DECL_CONSTRUCTOR_P (TREE_OPERAND (func
, 0)))
105 type
= build_pointer_type (type
);
106 /* Don't clobber a value that might be part of a default
108 mark_addressable (slot
);
109 if (TREE_PERMANENT (args
))
110 args
= tree_cons (0, build1 (ADDR_EXPR
, type
, slot
),
113 TREE_VALUE (args
) = build1 (ADDR_EXPR
, type
, slot
);
116 else if (TREE_CODE (return_type
) == REFERENCE_TYPE
)
123 #ifdef PCC_STATIC_STRUCT_RETURN
124 pcc_struct_return
= 1;
127 call_target
= target
;
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
);
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
)
145 call_target
= gen_rtx
146 (MEM
, mode
, memory_address (mode
, XEXP (call_target
, 0)));
147 MEM_IN_STRUCT_P (call_target
) = 1;
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)
156 if (pcc_struct_return
)
158 extern int flag_access_control
;
159 int old_ac
= flag_access_control
;
161 tree init
= build_decl (VAR_DECL
, 0, type
);
162 TREE_ADDRESSABLE (init
) = 1;
163 DECL_RTL (init
) = return_target
;
165 flag_access_control
= 0;
166 expand_aggr_init (slot
, init
, 0, LOOKUP_ONLYCONVERTING
);
167 flag_access_control
= old_ac
;
169 if (TYPE_NEEDS_DESTRUCTOR (type
))
171 init
= build_decl (VAR_DECL
, 0,
172 build_reference_type (type
));
173 DECL_RTL (init
) = XEXP (return_target
, 0);
175 init
= maybe_build_cleanup (convert_from_reference (init
));
176 if (init
!= NULL_TREE
)
177 expand_expr (init
, const0_rtx
, VOIDmode
, 0);
179 call_target
= return_target
= DECL_RTL (slot
);
182 call_target
= return_target
;
185 if (call_target
!= return_target
)
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
);
192 emit_move_insn (call_target
, return_target
);
195 if (TREE_CODE (return_type
) == REFERENCE_TYPE
)
199 if (GET_CODE (call_target
) == REG
200 && REGNO (call_target
) < FIRST_PSEUDO_REGISTER
)
201 my_friendly_abort (39);
203 type
= TREE_TYPE (exp
);
205 init
= build (RTL_EXPR
, return_type
, 0, call_target
);
206 /* We got back a reference to the type we want. Now initialize
208 expand_aggr_init (slot
, init
, 0, LOOKUP_ONLYCONVERTING
);
211 if (DECL_RTL (slot
) != target
)
212 emit_move_insn (DECL_RTL (slot
), target
);
213 return DECL_RTL (slot
);
219 return expand_expr (default_conversion (resolve_offset_ref (exp
)),
220 target
, tmode
, EXPAND_NORMAL
);
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
);
232 return DECL_RTL (exp
);
235 expand_throw (TREE_OPERAND (exp
, 0));
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
);
249 my_friendly_abort (40);
257 lang_expand_expr
= cplus_expand_expr
;
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. */
265 fixup_result_decl (decl
, result
)
271 if (REGNO (result
) >= FIRST_PSEUDO_REGISTER
)
273 rtx real_decl_result
;
275 #ifdef FUNCTION_OUTGOING_VALUE
277 = FUNCTION_OUTGOING_VALUE (TREE_TYPE (decl
), current_function_decl
);
280 = FUNCTION_VALUE (TREE_TYPE (decl
), current_function_decl
);
282 REG_FUNCTION_VALUE_P (real_decl_result
) = 1;
283 result
= real_decl_result
;
285 store_expr (decl
, result
, 0);
286 emit_insn (gen_rtx (USE
, VOIDmode
, result
));
290 /* Expand this initialization inline and see if it's simple enough that
291 it can be done at compile-time. */
294 extract_aggr_init (decl
, init
)
301 extract_scalar_init (decl
, init
)
304 rtx value
, insns
, insn
;
305 extern struct obstack temporary_obstack
;
308 push_obstacks (&temporary_obstack
, &temporary_obstack
);
310 value
= expand_expr (init
, NULL_RTX
, VOIDmode
, 0);
311 insns
= get_insns ();
313 reg_scan (insns
, max_reg_num (), 0);
314 jump_optimize (insns
, 0, 0, 1);
317 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
321 if (GET_CODE (insn
) == NOTE
)
323 else if (GET_CODE (insn
) != INSN
)
327 if (GET_CODE (r
) != SET
)
333 || (GET_CODE (to
) == SUBREG
&& XEXP (to
, 0) == value
)))
338 switch (GET_CODE (r
))
341 t
= build_int_2 (XEXP (r
, 0), 0);
352 extract_init (decl
, init
)
358 if (IS_AGGR_TYPE (TREE_TYPE (decl
))
359 || TREE_CODE (TREE_TYPE (decl
)) == ARRAY_TYPE
)
360 init
= extract_aggr_init (decl
, init
);
362 init
= extract_scalar_init (decl
, init
);
364 if (init
== NULL_TREE
)
367 DECL_INITIAL (decl
) = init
;
376 tree value1
= NULL_TREE
, value2
= NULL_TREE
, label
;
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");
383 pedwarn ("ANSI C++ forbids range expressions in switch statement");
385 if (processing_template_decl
)
387 add_tree (build_min_nt (CASE_LABEL
, start
, end
));
392 value1
= check_cp_case_value (start
);
394 value2
= check_cp_case_value (end
);
396 label
= build_decl (LABEL_DECL
, NULL_TREE
, NULL_TREE
);
398 if (value1
!= error_mark_node
399 && value2
!= error_mark_node
)
405 success
= pushcase_range (value1
, value2
, convert_and_check
,
408 success
= pushcase (value1
, convert_and_check
, label
, &duplicate
);
410 success
= pushcase (NULL_TREE
, 0, label
, &duplicate
);
415 error ("case label not within a switch statement");
417 cp_error ("case label `%E' not within a switch statement", start
);
419 error ("default label not within a switch statement");
421 else if (success
== 2)
425 error ("duplicate (or overlapping) case value");
426 cp_error_at ("this is the first entry overlapping that value",
431 cp_error ("duplicate case value `%E'", start
);
432 cp_error_at ("previously used here", duplicate
);
436 error ("multiple default labels in one switch");
437 cp_error_at ("this is the first default label", duplicate
);
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)
447 error ("case label within scope of cleanup or variable array");
449 error ("`default' label within scope of cleanup or variable array");
451 cp_error ("case label `%E' within scope of cleanup or variable array", start
);
455 define_case_label (label
);
457 define_case_label (NULL_TREE
);