]> gcc.gnu.org Git - gcc.git/blame - gcc/cp/expr.c
cp-tree.h (build_binary_op): Remove unneeded parameter.
[gcc.git] / gcc / cp / expr.c
CommitLineData
8d08fdba
MS
1/* Convert language-specific tree expression to rtl instructions,
2 for GNU compiler.
0b5be897 3 Copyright (C) 1988, 92-97, 1998 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"
8d052bc7 24#include "system.h"
8d08fdba
MS
25#include "rtl.h"
26#include "tree.h"
27#include "flags.h"
28#include "expr.h"
29#include "cp-tree.h"
54f92bfb 30#include "toplev.h"
8d08fdba 31
1bbe34be 32#if 0
994ac65b 33static tree extract_aggr_init PROTO((tree, tree));
49c249e1 34static tree extract_scalar_init PROTO((tree, tree));
1bbe34be 35#endif
9f617717
L
36static rtx cplus_expand_expr PROTO((tree, rtx, enum machine_mode,
37 enum expand_modifier));
49c249e1 38
8d08fdba
MS
39/* Hook used by expand_expr to expand language-specific tree codes. */
40
9f617717 41static rtx
8d08fdba
MS
42cplus_expand_expr (exp, target, tmode, modifier)
43 tree exp;
44 rtx target;
45 enum machine_mode tmode;
46 enum expand_modifier modifier;
47{
48 tree type = TREE_TYPE (exp);
49 register enum machine_mode mode = TYPE_MODE (type);
50 register enum tree_code code = TREE_CODE (exp);
8d08fdba
MS
51 int ignore = target == const0_rtx;
52
53 if (ignore)
de22184b 54 target = 0;
8d08fdba
MS
55
56 /* No sense saving up arithmetic to be done
57 if it's all in the wrong mode to form part of an address.
58 And force_operand won't know whether to sign-extend or zero-extend. */
59
60 if (mode != Pmode && modifier == EXPAND_SUM)
61 modifier = EXPAND_NORMAL;
62
63 switch (code)
64 {
02531345 65 case AGGR_INIT_EXPR:
8d08fdba
MS
66 {
67 /* Something needs to be initialized, but we didn't know
68 where that thing was when building the tree. For example,
69 it could be the return value of a function, or a parameter
70 to a function which lays down in the stack, or a temporary
71 variable which must be passed by reference.
72
73 Cleanups are handled in a language-specific way: they
74 might be run by the called function (true in GNU C++
75 for parameters with cleanups), or they might be
76 run by the caller, after the call (true in GNU C++
77 for other cleanup needs). */
78
79 tree func = TREE_OPERAND (exp, 0);
80 tree args = TREE_OPERAND (exp, 1);
81 tree type = TREE_TYPE (exp), slot;
8d08fdba
MS
82 tree call_exp;
83 rtx call_target, return_target;
84 int pcc_struct_return = 0;
85
86 /* The expression `init' wants to initialize what
87 `target' represents. SLOT holds the slot for TARGET. */
88 slot = TREE_OPERAND (exp, 2);
89
02531345
JM
90 /* Should always be called with a target. */
91 my_friendly_assert (target != NULL_RTX, 205);
8d08fdba
MS
92
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
99 exist for C++. */
100
101 if (TREE_CODE (func) == ADDR_EXPR
102 && TREE_CODE (TREE_OPERAND (func, 0)) == FUNCTION_DECL
103 && DECL_CONSTRUCTOR_P (TREE_OPERAND (func, 0)))
104 {
f30432d7 105 type = build_pointer_type (type);
8d08fdba
MS
106 /* Don't clobber a value that might be part of a default
107 parameter value. */
c19a8067 108 mark_addressable (slot);
8d08fdba 109 if (TREE_PERMANENT (args))
e66d884e 110 args = expr_tree_cons (0, build1 (ADDR_EXPR, type, slot),
8d08fdba
MS
111 TREE_CHAIN (args));
112 else
113 TREE_VALUE (args) = build1 (ADDR_EXPR, type, slot);
114 call_target = 0;
115 }
8d08fdba
MS
116 else
117 {
8d08fdba 118 call_target = target;
6b4e8391
JM
119#ifdef PCC_STATIC_STRUCT_RETURN
120 if (aggregate_value_p (type))
121 {
122 pcc_struct_return = 1;
123 call_target = 0;
124 }
8d08fdba
MS
125#endif
126 }
8d08fdba 127
4dabb379 128 call_exp = build (CALL_EXPR, type, func, args, NULL_TREE);
8d08fdba 129 TREE_SIDE_EFFECTS (call_exp) = 1;
e8abc66f 130 return_target = expand_call (call_exp, call_target, ignore);
8d08fdba 131
02531345 132 if (call_target)
56841f01
JM
133 /* Trust that the right thing has been done; it's too hard to
134 verify. */
135 return return_target;
8d08fdba 136
02531345
JM
137 /* If we're suffering under the ancient PCC_STATIC_STRUCT_RETURN
138 calling convention, we need to copy the return value out of
139 the static return buffer into slot. */
140 if (pcc_struct_return)
8d08fdba 141 {
02531345
JM
142 extern int flag_access_control;
143 int old_ac = flag_access_control;
8d08fdba 144
02531345
JM
145 tree init = build_decl (VAR_DECL, NULL_TREE,
146 build_reference_type (type));
147 DECL_RTL (init) = XEXP (return_target, 0);
2a66ec2b 148 init = convert_from_reference (init);
8d08fdba 149
02531345 150 flag_access_control = 0;
b370501f 151 expand_aggr_init (slot, init, LOOKUP_ONLYCONVERTING);
02531345
JM
152 flag_access_control = old_ac;
153
154 if (TYPE_NEEDS_DESTRUCTOR (type))
155 {
2a66ec2b 156 init = maybe_build_cleanup (init);
02531345
JM
157 if (init != NULL_TREE)
158 expand_expr (init, const0_rtx, VOIDmode, 0);
159 }
8d08fdba
MS
160 }
161
8d08fdba
MS
162 return DECL_RTL (slot);
163 }
164
61a127b3
MM
165 case PTRMEM_CST:
166 {
167 tree member;
168 tree offset;
169
170 /* Find the member. */
171 member = PTRMEM_CST_MEMBER (exp);
172
173 if (TREE_CODE (member) == FIELD_DECL)
174 {
175 /* Find the offset for the field. */
176 offset = convert (sizetype,
177 size_binop (EASY_DIV_EXPR,
178 DECL_FIELD_BITPOS (member),
179 size_int (BITS_PER_UNIT)));
180
181 /* We offset all pointer to data members by 1 so that we
182 can distinguish between a null pointer to data member
183 and the first data member of a structure. */
184 offset = size_binop (PLUS_EXPR, offset, size_int (1));
185
186 return expand_expr (cp_convert (type, offset), target, tmode,
187 modifier);
188 }
189 else
190 {
e08a8f45
MM
191 tree delta;
192 tree idx;
193 tree pfn;
194 tree delta2;
195
196 expand_ptrmemfunc_cst (exp, &delta, &idx, &pfn, &delta2);
197
198 return expand_expr (build_ptrmemfunc1 (type, delta, idx,
199 pfn, delta2),
200 target, tmode, modifier);
61a127b3
MM
201 }
202 }
203
8d08fdba
MS
204 case OFFSET_REF:
205 {
8d08fdba
MS
206 return expand_expr (default_conversion (resolve_offset_ref (exp)),
207 target, tmode, EXPAND_NORMAL);
8d08fdba
MS
208 }
209
8926095f
MS
210 case THUNK_DECL:
211 return DECL_RTL (exp);
212
8d2733ca
MS
213 case THROW_EXPR:
214 expand_throw (TREE_OPERAND (exp, 0));
215 return NULL;
216
a80e4195
MS
217 case VEC_INIT_EXPR:
218 return expand_expr
219 (expand_vec_init
220 (NULL_TREE, TREE_OPERAND (exp, 0),
221 build_binary_op (MINUS_EXPR, TREE_OPERAND (exp, 2),
337c90cc 222 integer_one_node),
a80e4195
MS
223 TREE_OPERAND (exp, 1), 0), target, tmode, modifier);
224
a0d5fba7
JM
225 case NEW_EXPR:
226 return expand_expr (build_new_1 (exp), target, tmode, modifier);
227
8d08fdba
MS
228 default:
229 break;
230 }
231 my_friendly_abort (40);
232 /* NOTREACHED */
233 return NULL;
234}
235
236void
237init_cplus_expand ()
238{
239 lang_expand_expr = cplus_expand_expr;
240}
241
242/* If DECL had its rtl moved from where callers expect it
243 to be, fix it up. RESULT is the nominal rtl for the RESULT_DECL,
244 which may be a pseudo instead of a hard register. */
245
246void
247fixup_result_decl (decl, result)
248 tree decl;
249 rtx result;
250{
251 if (REG_P (result))
252 {
253 if (REGNO (result) >= FIRST_PSEUDO_REGISTER)
254 {
255 rtx real_decl_result;
256
257#ifdef FUNCTION_OUTGOING_VALUE
258 real_decl_result
259 = FUNCTION_OUTGOING_VALUE (TREE_TYPE (decl), current_function_decl);
260#else
261 real_decl_result
262 = FUNCTION_VALUE (TREE_TYPE (decl), current_function_decl);
263#endif
264 REG_FUNCTION_VALUE_P (real_decl_result) = 1;
265 result = real_decl_result;
266 }
28cbf42c 267 store_expr (decl, result, 0);
8d08fdba
MS
268 emit_insn (gen_rtx (USE, VOIDmode, result));
269 }
270}
271
994ac65b 272#if 0
28cbf42c
MS
273/* Expand this initialization inline and see if it's simple enough that
274 it can be done at compile-time. */
275
276static tree
277extract_aggr_init (decl, init)
278 tree decl, init;
279{
280 return 0;
281}
282
283static tree
284extract_scalar_init (decl, init)
285 tree decl, init;
286{
287 rtx value, insns, insn;
288 extern struct obstack temporary_obstack;
289 tree t = NULL_TREE;
290
291 push_obstacks (&temporary_obstack, &temporary_obstack);
292 start_sequence ();
293 value = expand_expr (init, NULL_RTX, VOIDmode, 0);
294 insns = get_insns ();
295 end_sequence ();
296 reg_scan (insns, max_reg_num (), 0);
297 jump_optimize (insns, 0, 0, 1);
298 pop_obstacks ();
299
300 for (insn = insns; insn; insn = NEXT_INSN (insn))
301 {
302 rtx r, to;
303
304 if (GET_CODE (insn) == NOTE)
305 continue;
306 else if (GET_CODE (insn) != INSN)
307 return 0;
308
309 r = PATTERN (insn);
310 if (GET_CODE (r) != SET)
311 return 0;
312
313 to = XEXP (r, 0);
314
beb53fb8
JM
315 if (! (to == value
316 || (GET_CODE (to) == SUBREG && XEXP (to, 0) == value)))
28cbf42c
MS
317 return 0;
318
319 r = XEXP (r, 1);
320
321 switch (GET_CODE (r))
322 {
323 case CONST_INT:
324 t = build_int_2 (XEXP (r, 0), 0);
325 break;
326 default:
327 return 0;
328 }
329 }
330
331 return t;
332}
1bbe34be 333#endif
28cbf42c
MS
334
335int
336extract_init (decl, init)
b370501f 337 tree decl ATTRIBUTE_UNUSED, init ATTRIBUTE_UNUSED;
28cbf42c
MS
338{
339 return 0;
340
9e9ff709 341#if 0
28cbf42c
MS
342 if (IS_AGGR_TYPE (TREE_TYPE (decl))
343 || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
344 init = extract_aggr_init (decl, init);
345 else
346 init = extract_scalar_init (decl, init);
347
348 if (init == NULL_TREE)
349 return 0;
350
351 DECL_INITIAL (decl) = init;
352 return 1;
9e9ff709 353#endif
28cbf42c 354}
5566b478
MS
355
356void
357do_case (start, end)
358 tree start, end;
359{
360 tree value1 = NULL_TREE, value2 = NULL_TREE, label;
361
ce122a86
MS
362 if (start != NULL_TREE && TREE_TYPE (start) != NULL_TREE
363 && POINTER_TYPE_P (TREE_TYPE (start)))
8251199e 364 error ("pointers are not permitted as case values");
fc378698 365
5566b478 366 if (end && pedantic)
8251199e 367 pedwarn ("ANSI C++ forbids range expressions in switch statement");
5566b478 368
5156628f 369 if (processing_template_decl)
5566b478
MS
370 {
371 add_tree (build_min_nt (CASE_LABEL, start, end));
372 return;
373 }
374
375 if (start)
376 value1 = check_cp_case_value (start);
377 if (end)
378 value2 = check_cp_case_value (end);
379
380 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
381
382 if (value1 != error_mark_node
383 && value2 != error_mark_node)
384 {
385 tree duplicate;
386 int success;
387
388 if (end)
389 success = pushcase_range (value1, value2, convert_and_check,
390 label, &duplicate);
391 else if (start)
392 success = pushcase (value1, convert_and_check, label, &duplicate);
393 else
394 success = pushcase (NULL_TREE, 0, label, &duplicate);
395
396 if (success == 1)
397 {
398 if (end)
8251199e 399 error ("case label not within a switch statement");
5566b478 400 else if (start)
8251199e 401 cp_error ("case label `%E' not within a switch statement", start);
5566b478 402 else
8251199e 403 error ("default label not within a switch statement");
5566b478
MS
404 }
405 else if (success == 2)
406 {
407 if (end)
408 {
8251199e
JM
409 error ("duplicate (or overlapping) case value");
410 cp_error_at ("this is the first entry overlapping that value",
5566b478
MS
411 duplicate);
412 }
413 else if (start)
414 {
8251199e
JM
415 cp_error ("duplicate case value `%E'", start);
416 cp_error_at ("previously used here", duplicate);
5566b478
MS
417 }
418 else
419 {
8251199e
JM
420 error ("multiple default labels in one switch");
421 cp_error_at ("this is the first default label", duplicate);
5566b478
MS
422 }
423 }
424 else if (success == 3)
8251199e 425 warning ("case value out of range");
5566b478 426 else if (success == 4)
8251199e 427 warning ("empty range specified");
5566b478
MS
428 else if (success == 5)
429 {
430 if (end)
8251199e 431 error ("case label within scope of cleanup or variable array");
eb448459 432 else if (! start)
8251199e 433 error ("`default' label within scope of cleanup or variable array");
5566b478 434 else
8251199e 435 cp_error ("case label `%E' within scope of cleanup or variable array", start);
5566b478
MS
436 }
437 }
b370501f 438 define_case_label ();
5566b478 439}
This page took 0.509741 seconds and 5 git commands to generate.