]> gcc.gnu.org Git - gcc.git/blame - gcc/cp/expr.c
new
[gcc.git] / gcc / cp / expr.c
CommitLineData
8d08fdba
MS
1/* Convert language-specific tree expression to rtl instructions,
2 for GNU compiler.
8ecb1d92 3 Copyright (C) 1988, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
8d08fdba
MS
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
e9fa0c7c
RK
19the Free Software Foundation, 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
8d08fdba
MS
21
22
23#include "config.h"
da20811c 24#include <stdio.h>
8d08fdba
MS
25#include "rtl.h"
26#include "tree.h"
27#include "flags.h"
28#include "expr.h"
29#include "cp-tree.h"
30
49c249e1
JM
31static tree extract_aggr_init PROTO((tree, tree));
32static tree extract_scalar_init PROTO((tree, tree));
9f617717
L
33static rtx cplus_expand_expr PROTO((tree, rtx, enum machine_mode,
34 enum expand_modifier));
49c249e1 35
8d08fdba
MS
36/* Hook used by expand_expr to expand language-specific tree codes. */
37
9f617717 38static rtx
8d08fdba
MS
39cplus_expand_expr (exp, target, tmode, modifier)
40 tree exp;
41 rtx target;
42 enum machine_mode tmode;
43 enum expand_modifier modifier;
44{
45 tree type = TREE_TYPE (exp);
46 register enum machine_mode mode = TYPE_MODE (type);
47 register enum tree_code code = TREE_CODE (exp);
8d08fdba
MS
48 int ignore = target == const0_rtx;
49
50 if (ignore)
de22184b 51 target = 0;
8d08fdba
MS
52
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. */
56
57 if (mode != Pmode && modifier == EXPAND_SUM)
58 modifier = EXPAND_NORMAL;
59
60 switch (code)
61 {
62 case NEW_EXPR:
63 {
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.
69
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). */
75
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);
81 tree call_exp;
82 rtx call_target, return_target;
83 int pcc_struct_return = 0;
84
85 /* The expression `init' wants to initialize what
86 `target' represents. SLOT holds the slot for TARGET. */
87 slot = TREE_OPERAND (exp, 2);
88
89 if (target == 0)
90 {
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);
94
95 target = gen_reg_rtx (mode);
96 }
97
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
104 exist for C++. */
105
106 if (TREE_CODE (func) == ADDR_EXPR
107 && TREE_CODE (TREE_OPERAND (func, 0)) == FUNCTION_DECL
108 && DECL_CONSTRUCTOR_P (TREE_OPERAND (func, 0)))
109 {
f30432d7 110 type = build_pointer_type (type);
8d08fdba
MS
111 /* Don't clobber a value that might be part of a default
112 parameter value. */
c19a8067 113 mark_addressable (slot);
8d08fdba 114 if (TREE_PERMANENT (args))
e66d884e 115 args = expr_tree_cons (0, build1 (ADDR_EXPR, type, slot),
8d08fdba
MS
116 TREE_CHAIN (args));
117 else
118 TREE_VALUE (args) = build1 (ADDR_EXPR, type, slot);
119 call_target = 0;
120 }
121 else if (TREE_CODE (return_type) == REFERENCE_TYPE)
122 {
123 type = return_type;
124 call_target = 0;
125 }
126 else
127 {
128#ifdef PCC_STATIC_STRUCT_RETURN
129 pcc_struct_return = 1;
130 call_target = 0;
131#else
132 call_target = target;
133#endif
134 }
135 if (call_target)
136 {
8d08fdba
MS
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);
f49422da
MS
142
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)
149 {
150 call_target = gen_rtx
151 (MEM, mode, memory_address (mode, XEXP (call_target, 0)));
152 MEM_IN_STRUCT_P (call_target) = 1;
153 }
8d08fdba
MS
154 }
155
4dabb379 156 call_exp = build (CALL_EXPR, type, func, args, NULL_TREE);
8d08fdba 157 TREE_SIDE_EFFECTS (call_exp) = 1;
e8abc66f 158 return_target = expand_call (call_exp, call_target, ignore);
8d08fdba
MS
159 if (call_target == 0)
160 {
161 if (pcc_struct_return)
162 {
eae89e04
JM
163 extern int flag_access_control;
164 int old_ac = flag_access_control;
165
a5894242 166 tree init = build_decl (VAR_DECL, 0, type);
8d08fdba 167 TREE_ADDRESSABLE (init) = 1;
a5894242 168 DECL_RTL (init) = return_target;
eae89e04
JM
169
170 flag_access_control = 0;
6060a796 171 expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING);
eae89e04
JM
172 flag_access_control = old_ac;
173
8d08fdba
MS
174 if (TYPE_NEEDS_DESTRUCTOR (type))
175 {
a5894242
MS
176 init = build_decl (VAR_DECL, 0,
177 build_reference_type (type));
178 DECL_RTL (init) = XEXP (return_target, 0);
179
8d08fdba
MS
180 init = maybe_build_cleanup (convert_from_reference (init));
181 if (init != NULL_TREE)
a0128b67 182 expand_expr (init, const0_rtx, VOIDmode, 0);
8d08fdba
MS
183 }
184 call_target = return_target = DECL_RTL (slot);
185 }
186 else
187 call_target = return_target;
188 }
189
190 if (call_target != return_target)
191 {
e8abc66f 192 my_friendly_assert (TYPE_HAS_TRIVIAL_INIT_REF (type), 317);
8d08fdba
MS
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);
196 else
197 emit_move_insn (call_target, return_target);
198 }
199
200 if (TREE_CODE (return_type) == REFERENCE_TYPE)
201 {
202 tree init;
203
204 if (GET_CODE (call_target) == REG
205 && REGNO (call_target) < FIRST_PSEUDO_REGISTER)
206 my_friendly_abort (39);
207
208 type = TREE_TYPE (exp);
209
210 init = build (RTL_EXPR, return_type, 0, call_target);
211 /* We got back a reference to the type we want. Now initialize
212 target with that. */
6060a796 213 expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING);
8d08fdba
MS
214 }
215
216 if (DECL_RTL (slot) != target)
217 emit_move_insn (DECL_RTL (slot), target);
218 return DECL_RTL (slot);
219 }
220
221 case OFFSET_REF:
222 {
223#if 1
224 return expand_expr (default_conversion (resolve_offset_ref (exp)),
225 target, tmode, EXPAND_NORMAL);
226#else
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);
233#endif
234 }
235
8926095f
MS
236 case THUNK_DECL:
237 return DECL_RTL (exp);
238
8d2733ca
MS
239 case THROW_EXPR:
240 expand_throw (TREE_OPERAND (exp, 0));
241 return NULL;
242
a80e4195
MS
243 case VEC_INIT_EXPR:
244 return expand_expr
245 (expand_vec_init
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);
250
8d08fdba
MS
251 default:
252 break;
253 }
254 my_friendly_abort (40);
255 /* NOTREACHED */
256 return NULL;
257}
258
259void
260init_cplus_expand ()
261{
262 lang_expand_expr = cplus_expand_expr;
263}
264
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. */
268
269void
270fixup_result_decl (decl, result)
271 tree decl;
272 rtx result;
273{
274 if (REG_P (result))
275 {
276 if (REGNO (result) >= FIRST_PSEUDO_REGISTER)
277 {
278 rtx real_decl_result;
279
280#ifdef FUNCTION_OUTGOING_VALUE
281 real_decl_result
282 = FUNCTION_OUTGOING_VALUE (TREE_TYPE (decl), current_function_decl);
283#else
284 real_decl_result
285 = FUNCTION_VALUE (TREE_TYPE (decl), current_function_decl);
286#endif
287 REG_FUNCTION_VALUE_P (real_decl_result) = 1;
288 result = real_decl_result;
289 }
28cbf42c 290 store_expr (decl, result, 0);
8d08fdba
MS
291 emit_insn (gen_rtx (USE, VOIDmode, result));
292 }
293}
294
28cbf42c
MS
295/* Expand this initialization inline and see if it's simple enough that
296 it can be done at compile-time. */
297
298static tree
299extract_aggr_init (decl, init)
300 tree decl, init;
301{
302 return 0;
303}
304
305static tree
306extract_scalar_init (decl, init)
307 tree decl, init;
308{
309 rtx value, insns, insn;
310 extern struct obstack temporary_obstack;
311 tree t = NULL_TREE;
312
313 push_obstacks (&temporary_obstack, &temporary_obstack);
314 start_sequence ();
315 value = expand_expr (init, NULL_RTX, VOIDmode, 0);
316 insns = get_insns ();
317 end_sequence ();
318 reg_scan (insns, max_reg_num (), 0);
319 jump_optimize (insns, 0, 0, 1);
320 pop_obstacks ();
321
322 for (insn = insns; insn; insn = NEXT_INSN (insn))
323 {
324 rtx r, to;
325
326 if (GET_CODE (insn) == NOTE)
327 continue;
328 else if (GET_CODE (insn) != INSN)
329 return 0;
330
331 r = PATTERN (insn);
332 if (GET_CODE (r) != SET)
333 return 0;
334
335 to = XEXP (r, 0);
336
beb53fb8
JM
337 if (! (to == value
338 || (GET_CODE (to) == SUBREG && XEXP (to, 0) == value)))
28cbf42c
MS
339 return 0;
340
341 r = XEXP (r, 1);
342
343 switch (GET_CODE (r))
344 {
345 case CONST_INT:
346 t = build_int_2 (XEXP (r, 0), 0);
347 break;
348 default:
349 return 0;
350 }
351 }
352
353 return t;
354}
355
356int
357extract_init (decl, init)
358 tree decl, init;
359{
360 return 0;
361
9e9ff709 362#if 0
28cbf42c
MS
363 if (IS_AGGR_TYPE (TREE_TYPE (decl))
364 || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
365 init = extract_aggr_init (decl, init);
366 else
367 init = extract_scalar_init (decl, init);
368
369 if (init == NULL_TREE)
370 return 0;
371
372 DECL_INITIAL (decl) = init;
373 return 1;
9e9ff709 374#endif
28cbf42c 375}
5566b478
MS
376
377void
378do_case (start, end)
379 tree start, end;
380{
381 tree value1 = NULL_TREE, value2 = NULL_TREE, label;
382
ce122a86
MS
383 if (start != NULL_TREE && TREE_TYPE (start) != NULL_TREE
384 && POINTER_TYPE_P (TREE_TYPE (start)))
fc378698
MS
385 error ("pointers are not permitted as case values");
386
5566b478
MS
387 if (end && pedantic)
388 pedwarn ("ANSI C++ forbids range expressions in switch statement");
389
5156628f 390 if (processing_template_decl)
5566b478
MS
391 {
392 add_tree (build_min_nt (CASE_LABEL, start, end));
393 return;
394 }
395
396 if (start)
397 value1 = check_cp_case_value (start);
398 if (end)
399 value2 = check_cp_case_value (end);
400
401 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
402
403 if (value1 != error_mark_node
404 && value2 != error_mark_node)
405 {
406 tree duplicate;
407 int success;
408
409 if (end)
410 success = pushcase_range (value1, value2, convert_and_check,
411 label, &duplicate);
412 else if (start)
413 success = pushcase (value1, convert_and_check, label, &duplicate);
414 else
415 success = pushcase (NULL_TREE, 0, label, &duplicate);
416
417 if (success == 1)
418 {
419 if (end)
420 error ("case label not within a switch statement");
421 else if (start)
422 cp_error ("case label `%E' not within a switch statement", start);
423 else
424 error ("default label not within a switch statement");
425 }
426 else if (success == 2)
427 {
428 if (end)
429 {
430 error ("duplicate (or overlapping) case value");
431 cp_error_at ("this is the first entry overlapping that value",
432 duplicate);
433 }
434 else if (start)
435 {
436 cp_error ("duplicate case value `%E'", start);
437 cp_error_at ("previously used here", duplicate);
438 }
439 else
440 {
441 error ("multiple default labels in one switch");
442 cp_error_at ("this is the first default label", duplicate);
443 }
444 }
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)
450 {
451 if (end)
452 error ("case label within scope of cleanup or variable array");
eb448459
MS
453 else if (! start)
454 error ("`default' label within scope of cleanup or variable array");
5566b478
MS
455 else
456 cp_error ("case label `%E' within scope of cleanup or variable array", start);
457 }
458 }
459 if (start)
460 define_case_label (label);
461 else
462 define_case_label (NULL_TREE);
463}
This page took 0.284667 seconds and 5 git commands to generate.