OSDN Git Service

91th Cygnus<->FSF quick merge
[pf3gnuchains/gcc-fork.git] / gcc / cp / expr.c
1 /* Convert language-specific tree expression to rtl instructions,
2    for GNU compiler.
3    Copyright (C) 1988, 1992, 1993, 1994, 1995 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 /* Hook used by expand_expr to expand language-specific tree codes.  */
31
32 rtx
33 cplus_expand_expr (exp, target, tmode, modifier)
34      tree exp;
35      rtx target;
36      enum machine_mode tmode;
37      enum expand_modifier modifier;
38 {
39   tree type = TREE_TYPE (exp);
40   register enum machine_mode mode = TYPE_MODE (type);
41   register enum tree_code code = TREE_CODE (exp);
42   int ignore = target == const0_rtx;
43
44   if (ignore)
45     target = 0;
46
47   /* No sense saving up arithmetic to be done
48      if it's all in the wrong mode to form part of an address.
49      And force_operand won't know whether to sign-extend or zero-extend.  */
50
51   if (mode != Pmode && modifier == EXPAND_SUM)
52     modifier = EXPAND_NORMAL;
53
54   switch (code)
55     {
56     case NEW_EXPR:
57       {
58         /* Something needs to be initialized, but we didn't know
59            where that thing was when building the tree.  For example,
60            it could be the return value of a function, or a parameter
61            to a function which lays down in the stack, or a temporary
62            variable which must be passed by reference.
63
64            Cleanups are handled in a language-specific way: they
65            might be run by the called function (true in GNU C++
66            for parameters with cleanups), or they might be
67            run by the caller, after the call (true in GNU C++
68            for other cleanup needs).  */
69
70         tree func = TREE_OPERAND (exp, 0);
71         tree args = TREE_OPERAND (exp, 1);
72         tree type = TREE_TYPE (exp), slot;
73         tree fn_type = TREE_TYPE (TREE_TYPE (func));
74         tree return_type = TREE_TYPE (fn_type);
75         tree call_exp;
76         rtx call_target, return_target;
77         int pcc_struct_return = 0;
78
79         /* The expression `init' wants to initialize what
80            `target' represents.  SLOT holds the slot for TARGET.  */
81         slot = TREE_OPERAND (exp, 2);
82
83         if (target == 0)
84           {
85             /* Should always be called with a target in BLKmode case.  */
86             my_friendly_assert (mode != BLKmode, 205);
87             my_friendly_assert (DECL_RTL (slot) != 0, 206);
88
89             target = gen_reg_rtx (mode);
90           }
91
92         /* The target the initializer will initialize (CALL_TARGET)
93            must now be directed to initialize the target we are
94            supposed to initialize (TARGET).  The semantics for
95            choosing what CALL_TARGET is is language-specific,
96            as is building the call which will perform the
97            initialization.  It is left here to show the choices that
98            exist for C++.  */
99            
100         if (TREE_CODE (func) == ADDR_EXPR
101             && TREE_CODE (TREE_OPERAND (func, 0)) == FUNCTION_DECL
102             && DECL_CONSTRUCTOR_P (TREE_OPERAND (func, 0)))
103           {
104             type = build_pointer_type (type);
105             /* Don't clobber a value that might be part of a default
106                parameter value.  */
107             mark_addressable (slot);
108             if (TREE_PERMANENT (args))
109               args = tree_cons (0, build1 (ADDR_EXPR, type, slot),
110                                 TREE_CHAIN (args));
111             else
112               TREE_VALUE (args) = build1 (ADDR_EXPR, type, slot);
113             call_target = 0;
114           }
115         else if (TREE_CODE (return_type) == REFERENCE_TYPE)
116           {
117             type = return_type;
118             call_target = 0;
119           }
120         else
121           {
122 #ifdef PCC_STATIC_STRUCT_RETURN
123             pcc_struct_return = 1;
124             call_target = 0;
125 #else
126             call_target = target;
127 #endif
128           }
129         if (call_target)
130           {
131             /* Make this a valid memory address now.  The code below assumes
132                that it can compare rtx and make assumptions based on the
133                result.  The assumptions are true only if the address was
134                valid to begin with.  */
135             call_target = validize_mem (call_target);
136
137             /* If this is a reference to a symbol, expand_inline_function
138                will do this transformation and return a different target
139                than the one we gave it, though functionally equivalent.  Do
140                the transformation here to avoid confusion.  */
141             if (! cse_not_expected && GET_CODE (call_target) == MEM
142                 && GET_CODE (XEXP (call_target, 0)) == SYMBOL_REF)
143               {
144                 call_target = gen_rtx
145                   (MEM, mode, memory_address (mode, XEXP (call_target, 0)));
146                 MEM_IN_STRUCT_P (call_target) = 1;
147               }
148           }
149
150         call_exp = build (CALL_EXPR, type, func, args, NULL_TREE);
151         TREE_SIDE_EFFECTS (call_exp) = 1;
152         return_target = expand_call (call_exp, call_target, ignore);
153         if (call_target == 0)
154           {
155             if (pcc_struct_return)
156               {
157                 extern int flag_access_control;
158                 int old_ac = flag_access_control;
159
160                 tree init = build_decl (VAR_DECL, 0, type);
161                 TREE_ADDRESSABLE (init) = 1;
162                 DECL_RTL (init) = return_target;
163
164                 flag_access_control = 0;
165                 expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING);
166                 flag_access_control = old_ac;
167
168                 if (TYPE_NEEDS_DESTRUCTOR (type))
169                   {
170                     init = build_decl (VAR_DECL, 0,
171                                        build_reference_type (type));
172                     DECL_RTL (init) = XEXP (return_target, 0);
173
174                     init = maybe_build_cleanup (convert_from_reference (init));
175                     if (init != NULL_TREE)
176                       expand_expr (init, const0_rtx, VOIDmode, 0);
177                   }
178                 call_target = return_target = DECL_RTL (slot);
179               }
180             else
181               call_target = return_target;
182           }
183
184         if (call_target != return_target)
185           {
186             my_friendly_assert (TYPE_HAS_TRIVIAL_INIT_REF (type), 317);
187             if (GET_MODE (return_target) == BLKmode)
188               emit_block_move (call_target, return_target, expr_size (exp),
189                                TYPE_ALIGN (type) / BITS_PER_UNIT);
190             else
191               emit_move_insn (call_target, return_target);
192           }
193
194         if (TREE_CODE (return_type) == REFERENCE_TYPE)
195           {
196             tree init;
197
198             if (GET_CODE (call_target) == REG
199                 && REGNO (call_target) < FIRST_PSEUDO_REGISTER)
200               my_friendly_abort (39);
201
202             type = TREE_TYPE (exp);
203
204             init = build (RTL_EXPR, return_type, 0, call_target);
205             /* We got back a reference to the type we want.  Now initialize
206                target with that.  */
207             expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING);
208           }
209
210         if (DECL_RTL (slot) != target)
211           emit_move_insn (DECL_RTL (slot), target);
212         return DECL_RTL (slot);
213       }
214
215     case OFFSET_REF:
216       {
217 #if 1
218         return expand_expr (default_conversion (resolve_offset_ref (exp)),
219                             target, tmode, EXPAND_NORMAL);
220 #else
221         /* This is old crusty code, and does not handle all that the
222            resolve_offset_ref function does.  (mrs) */
223         tree base = build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 0), 0);
224         tree offset = build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 1), 0);
225         return expand_expr (build (PLUS_EXPR, TREE_TYPE (exp), base, offset),
226                             target, tmode, EXPAND_NORMAL);
227 #endif
228       }
229
230     case THUNK_DECL:
231       return DECL_RTL (exp);
232
233     case THROW_EXPR:
234       expand_throw (TREE_OPERAND (exp, 0));
235       return NULL;
236
237     case VEC_INIT_EXPR:
238       return expand_expr
239         (expand_vec_init
240          (NULL_TREE, TREE_OPERAND (exp, 0),
241           build_binary_op (MINUS_EXPR, TREE_OPERAND (exp, 2),
242                            integer_one_node, 1),
243           TREE_OPERAND (exp, 1), 0), target, tmode, modifier);
244
245     default:
246       break;
247     }
248   my_friendly_abort (40);
249   /* NOTREACHED */
250   return NULL;
251 }
252
253 void
254 init_cplus_expand ()
255 {
256   lang_expand_expr = cplus_expand_expr;
257 }
258
259 /* If DECL had its rtl moved from where callers expect it
260    to be, fix it up.  RESULT is the nominal rtl for the RESULT_DECL,
261    which may be a pseudo instead of a hard register.  */
262
263 void
264 fixup_result_decl (decl, result)
265      tree decl;
266      rtx result;
267 {
268   if (REG_P (result))
269     {
270       if (REGNO (result) >= FIRST_PSEUDO_REGISTER)
271         {
272           rtx real_decl_result;
273
274 #ifdef FUNCTION_OUTGOING_VALUE
275           real_decl_result
276             = FUNCTION_OUTGOING_VALUE (TREE_TYPE (decl), current_function_decl);
277 #else
278           real_decl_result
279             = FUNCTION_VALUE (TREE_TYPE (decl), current_function_decl);
280 #endif
281           REG_FUNCTION_VALUE_P (real_decl_result) = 1;
282           result = real_decl_result;
283         }
284       store_expr (decl, result, 0);
285       emit_insn (gen_rtx (USE, VOIDmode, result));
286     }
287 }
288
289 /* Expand this initialization inline and see if it's simple enough that
290    it can be done at compile-time.  */
291
292 static tree
293 extract_aggr_init (decl, init)
294      tree decl, init;
295 {
296   return 0;
297 }
298
299 static tree
300 extract_scalar_init (decl, init)
301      tree decl, init;
302 {
303   rtx value, insns, insn;
304   extern struct obstack temporary_obstack;
305   tree t = NULL_TREE;
306
307   push_obstacks (&temporary_obstack, &temporary_obstack);
308   start_sequence ();
309   value = expand_expr (init, NULL_RTX, VOIDmode, 0);
310   insns = get_insns ();
311   end_sequence ();
312   reg_scan (insns, max_reg_num (), 0);
313   jump_optimize (insns, 0, 0, 1);
314   pop_obstacks ();
315
316   for (insn = insns; insn; insn = NEXT_INSN (insn))
317     {
318       rtx r, to;
319
320       if (GET_CODE (insn) == NOTE)
321         continue;
322       else if (GET_CODE (insn) != INSN)
323         return 0;
324
325       r = PATTERN (insn);
326       if (GET_CODE (r) != SET)
327         return 0;
328
329       to = XEXP (r, 0);
330
331       if (! (to == value
332              || (GET_CODE (to) == SUBREG && XEXP (to, 0) == value)))
333         return 0;
334
335       r = XEXP (r, 1);
336
337       switch (GET_CODE (r))
338         {
339         case CONST_INT:
340           t = build_int_2 (XEXP (r, 0), 0);
341           break;
342         default:
343           return 0;
344         }
345     }
346
347   return t; 
348 }
349
350 int
351 extract_init (decl, init)
352      tree decl, init;
353 {
354   return 0;
355
356 #if 0
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 #endif
369 }
370
371 void
372 do_case (start, end)
373      tree start, end;
374 {
375   tree value1 = NULL_TREE, value2 = NULL_TREE, label;
376
377   if (start != NULL_TREE && TREE_TYPE (start) != NULL_TREE 
378       && POINTER_TYPE_P (TREE_TYPE (start)))
379     error ("pointers are not permitted as case values");
380
381   if (end && pedantic)
382     pedwarn ("ANSI C++ forbids range expressions in switch statement");
383
384   if (processing_template_decl)
385     {
386       add_tree (build_min_nt (CASE_LABEL, start, end));
387       return;
388     }
389
390   if (start)
391     value1 = check_cp_case_value (start);
392   if (end)
393     value2 = check_cp_case_value (end);
394   
395   label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
396
397   if (value1 != error_mark_node
398       && value2 != error_mark_node)
399     {
400       tree duplicate;
401       int success;
402
403       if (end)
404         success = pushcase_range (value1, value2, convert_and_check,
405                                   label, &duplicate);
406       else if (start)
407         success = pushcase (value1, convert_and_check, label, &duplicate);
408       else
409         success = pushcase (NULL_TREE, 0, label, &duplicate);
410
411       if (success == 1)
412         {
413           if (end)
414             error ("case label not within a switch statement");
415           else if (start)
416             cp_error ("case label `%E' not within a switch statement", start);
417           else
418             error ("default label not within a switch statement");
419         }
420       else if (success == 2)
421         {
422           if (end)
423             {
424               error ("duplicate (or overlapping) case value");
425               cp_error_at ("this is the first entry overlapping that value",
426                            duplicate);
427             }
428           else if (start)
429             {
430               cp_error ("duplicate case value `%E'", start);
431               cp_error_at ("previously used here", duplicate);
432             }
433           else
434             {
435               error ("multiple default labels in one switch");
436               cp_error_at ("this is the first default label", duplicate);
437             }
438         }
439       else if (success == 3)
440         warning ("case value out of range");
441       else if (success == 4)
442         warning ("empty range specified");
443       else if (success == 5)
444         {
445           if (end)
446             error ("case label within scope of cleanup or variable array");
447           else if (! start)
448             error ("`default' label within scope of cleanup or variable array");
449           else
450             cp_error ("case label `%E' within scope of cleanup or variable array", start);
451         }
452     }
453   if (start)
454     define_case_label (label);
455   else
456     define_case_label (NULL_TREE);
457 }