Update FSF address.
[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 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 "rtl.h"
25 #include "tree.h"
26 #include "flags.h"
27 #include "expr.h"
28 #include "cp-tree.h"
29
30 #undef NULL
31 #define NULL 0
32
33 /* Hook used by expand_expr to expand language-specific tree codes. */
34
35 rtx
36 cplus_expand_expr (exp, target, tmode, modifier)
37 tree exp;
38 rtx target;
39 enum machine_mode tmode;
40 enum expand_modifier modifier;
41 {
42 tree type = TREE_TYPE (exp);
43 register enum machine_mode mode = TYPE_MODE (type);
44 register enum tree_code code = TREE_CODE (exp);
45 rtx original_target = target;
46 int ignore = target == const0_rtx;
47
48 if (ignore)
49 target = 0, original_target = 0;
50
51 /* No sense saving up arithmetic to be done
52 if it's all in the wrong mode to form part of an address.
53 And force_operand won't know whether to sign-extend or zero-extend. */
54
55 if (mode != Pmode && modifier == EXPAND_SUM)
56 modifier = EXPAND_NORMAL;
57
58 switch (code)
59 {
60 case NEW_EXPR:
61 {
62 /* Something needs to be initialized, but we didn't know
63 where that thing was when building the tree. For example,
64 it could be the return value of a function, or a parameter
65 to a function which lays down in the stack, or a temporary
66 variable which must be passed by reference.
67
68 Cleanups are handled in a language-specific way: they
69 might be run by the called function (true in GNU C++
70 for parameters with cleanups), or they might be
71 run by the caller, after the call (true in GNU C++
72 for other cleanup needs). */
73
74 tree func = TREE_OPERAND (exp, 0);
75 tree args = TREE_OPERAND (exp, 1);
76 tree type = TREE_TYPE (exp), slot;
77 tree fn_type = TREE_TYPE (TREE_TYPE (func));
78 tree return_type = TREE_TYPE (fn_type);
79 tree call_exp;
80 rtx call_target, return_target;
81 int pcc_struct_return = 0;
82
83 /* The expression `init' wants to initialize what
84 `target' represents. SLOT holds the slot for TARGET. */
85 slot = TREE_OPERAND (exp, 2);
86
87 if (target == 0)
88 {
89 /* Should always be called with a target in BLKmode case. */
90 my_friendly_assert (mode != BLKmode, 205);
91 my_friendly_assert (DECL_RTL (slot) != 0, 206);
92
93 target = gen_reg_rtx (mode);
94 }
95
96 /* The target the initializer will initialize (CALL_TARGET)
97 must now be directed to initialize the target we are
98 supposed to initialize (TARGET). The semantics for
99 choosing what CALL_TARGET is is language-specific,
100 as is building the call which will perform the
101 initialization. It is left here to show the choices that
102 exist for C++. */
103
104 if (TREE_CODE (func) == ADDR_EXPR
105 && TREE_CODE (TREE_OPERAND (func, 0)) == FUNCTION_DECL
106 && DECL_CONSTRUCTOR_P (TREE_OPERAND (func, 0)))
107 {
108 type = TYPE_POINTER_TO (type);
109 /* Don't clobber a value that might be part of a default
110 parameter value. */
111 mark_addressable (slot);
112 if (TREE_PERMANENT (args))
113 args = tree_cons (0, build1 (ADDR_EXPR, type, slot),
114 TREE_CHAIN (args));
115 else
116 TREE_VALUE (args) = build1 (ADDR_EXPR, type, slot);
117 call_target = 0;
118 }
119 else if (TREE_CODE (return_type) == REFERENCE_TYPE)
120 {
121 type = return_type;
122 call_target = 0;
123 }
124 else
125 {
126 #ifdef PCC_STATIC_STRUCT_RETURN
127 pcc_struct_return = 1;
128 call_target = 0;
129 #else
130 call_target = target;
131 #endif
132 }
133 if (call_target)
134 {
135 preserve_temp_slots (call_target);
136
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);
142 }
143
144 preserve_temp_slots (DECL_RTL (slot));
145 call_exp = build (CALL_EXPR, type, func, args, 0);
146 TREE_SIDE_EFFECTS (call_exp) = 1;
147 return_target = expand_call (call_exp, call_target, ignore);
148 free_temp_slots ();
149 if (call_target == 0)
150 {
151 if (pcc_struct_return)
152 {
153 extern int flag_access_control;
154 int old_ac = flag_access_control;
155
156 tree init = build_decl (VAR_DECL, 0, type);
157 TREE_ADDRESSABLE (init) = 1;
158 DECL_RTL (init) = return_target;
159
160 flag_access_control = 0;
161 expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING);
162 flag_access_control = old_ac;
163
164 if (TYPE_NEEDS_DESTRUCTOR (type))
165 {
166 init = build_decl (VAR_DECL, 0,
167 build_reference_type (type));
168 DECL_RTL (init) = XEXP (return_target, 0);
169
170 init = maybe_build_cleanup (convert_from_reference (init));
171 if (init != NULL_TREE)
172 expand_expr (init, 0, 0, 0);
173 }
174 call_target = return_target = DECL_RTL (slot);
175 }
176 else
177 call_target = return_target;
178 }
179
180 if (call_target != return_target)
181 {
182 my_friendly_assert (TYPE_HAS_TRIVIAL_INIT_REF (type), 317);
183 if (GET_MODE (return_target) == BLKmode)
184 emit_block_move (call_target, return_target, expr_size (exp),
185 TYPE_ALIGN (type) / BITS_PER_UNIT);
186 else
187 emit_move_insn (call_target, return_target);
188 }
189
190 if (TREE_CODE (return_type) == REFERENCE_TYPE)
191 {
192 tree init;
193
194 if (GET_CODE (call_target) == REG
195 && REGNO (call_target) < FIRST_PSEUDO_REGISTER)
196 my_friendly_abort (39);
197
198 type = TREE_TYPE (exp);
199
200 init = build (RTL_EXPR, return_type, 0, call_target);
201 /* We got back a reference to the type we want. Now initialize
202 target with that. */
203 expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING);
204 }
205
206 if (DECL_RTL (slot) != target)
207 emit_move_insn (DECL_RTL (slot), target);
208 return DECL_RTL (slot);
209 }
210
211 case OFFSET_REF:
212 {
213 #if 1
214 return expand_expr (default_conversion (resolve_offset_ref (exp)),
215 target, tmode, EXPAND_NORMAL);
216 #else
217 /* This is old crusty code, and does not handle all that the
218 resolve_offset_ref function does. (mrs) */
219 tree base = build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 0), 0);
220 tree offset = build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 1), 0);
221 return expand_expr (build (PLUS_EXPR, TREE_TYPE (exp), base, offset),
222 target, tmode, EXPAND_NORMAL);
223 #endif
224 }
225
226 case THUNK_DECL:
227 return DECL_RTL (exp);
228
229 case THROW_EXPR:
230 expand_throw (TREE_OPERAND (exp, 0));
231 return NULL;
232
233 default:
234 break;
235 }
236 my_friendly_abort (40);
237 /* NOTREACHED */
238 return NULL;
239 }
240
241 void
242 init_cplus_expand ()
243 {
244 lang_expand_expr = cplus_expand_expr;
245 }
246
247 /* If DECL had its rtl moved from where callers expect it
248 to be, fix it up. RESULT is the nominal rtl for the RESULT_DECL,
249 which may be a pseudo instead of a hard register. */
250
251 void
252 fixup_result_decl (decl, result)
253 tree decl;
254 rtx result;
255 {
256 if (REG_P (result))
257 {
258 if (REGNO (result) >= FIRST_PSEUDO_REGISTER)
259 {
260 rtx real_decl_result;
261
262 #ifdef FUNCTION_OUTGOING_VALUE
263 real_decl_result
264 = FUNCTION_OUTGOING_VALUE (TREE_TYPE (decl), current_function_decl);
265 #else
266 real_decl_result
267 = FUNCTION_VALUE (TREE_TYPE (decl), current_function_decl);
268 #endif
269 REG_FUNCTION_VALUE_P (real_decl_result) = 1;
270 result = real_decl_result;
271 }
272 store_expr (decl, result, 0);
273 emit_insn (gen_rtx (USE, VOIDmode, result));
274 }
275 }
276
277 /* Return nonzero iff DECL is memory-based. The DECL_RTL of
278 certain const variables might be a CONST_INT, or a REG
279 in some cases. We cannot use `memory_operand' as a test
280 here because on most RISC machines, a variable's address
281 is not, by itself, a legitimate address. */
282
283 int
284 decl_in_memory_p (decl)
285 tree decl;
286 {
287 return DECL_RTL (decl) != 0 && GET_CODE (DECL_RTL (decl)) == MEM;
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 (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);
362
363 if (init == NULL_TREE)
364 return 0;
365
366 DECL_INITIAL (decl) = init;
367 return 1;
368 }