OSDN Git Service

86th 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 #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 = build_pointer_type (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             /* Make this a valid memory address now.  The code below assumes
136                that it can compare rtx and make assumptions based on the
137                result.  The assumptions are true only if the address was
138                valid to begin with.  */
139             call_target = validize_mem (call_target);
140           }
141
142         call_exp = build (CALL_EXPR, type, func, args, 0);
143         TREE_SIDE_EFFECTS (call_exp) = 1;
144         return_target = expand_call (call_exp, call_target, ignore);
145         if (call_target == 0)
146           {
147             if (pcc_struct_return)
148               {
149                 extern int flag_access_control;
150                 int old_ac = flag_access_control;
151
152                 tree init = build_decl (VAR_DECL, 0, type);
153                 TREE_ADDRESSABLE (init) = 1;
154                 DECL_RTL (init) = return_target;
155
156                 flag_access_control = 0;
157                 expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING);
158                 flag_access_control = old_ac;
159
160                 if (TYPE_NEEDS_DESTRUCTOR (type))
161                   {
162                     init = build_decl (VAR_DECL, 0,
163                                        build_reference_type (type));
164                     DECL_RTL (init) = XEXP (return_target, 0);
165
166                     init = maybe_build_cleanup (convert_from_reference (init));
167                     if (init != NULL_TREE)
168                       expand_expr (init, 0, 0, 0);
169                   }
170                 call_target = return_target = DECL_RTL (slot);
171               }
172             else
173               call_target = return_target;
174           }
175
176         if (call_target != return_target)
177           {
178             my_friendly_assert (TYPE_HAS_TRIVIAL_INIT_REF (type), 317);
179             if (GET_MODE (return_target) == BLKmode)
180               emit_block_move (call_target, return_target, expr_size (exp),
181                                TYPE_ALIGN (type) / BITS_PER_UNIT);
182             else
183               emit_move_insn (call_target, return_target);
184           }
185
186         if (TREE_CODE (return_type) == REFERENCE_TYPE)
187           {
188             tree init;
189
190             if (GET_CODE (call_target) == REG
191                 && REGNO (call_target) < FIRST_PSEUDO_REGISTER)
192               my_friendly_abort (39);
193
194             type = TREE_TYPE (exp);
195
196             init = build (RTL_EXPR, return_type, 0, call_target);
197             /* We got back a reference to the type we want.  Now initialize
198                target with that.  */
199             expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING);
200           }
201
202         if (DECL_RTL (slot) != target)
203           emit_move_insn (DECL_RTL (slot), target);
204         return DECL_RTL (slot);
205       }
206
207     case OFFSET_REF:
208       {
209 #if 1
210         return expand_expr (default_conversion (resolve_offset_ref (exp)),
211                             target, tmode, EXPAND_NORMAL);
212 #else
213         /* This is old crusty code, and does not handle all that the
214            resolve_offset_ref function does.  (mrs) */
215         tree base = build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 0), 0);
216         tree offset = build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 1), 0);
217         return expand_expr (build (PLUS_EXPR, TREE_TYPE (exp), base, offset),
218                             target, tmode, EXPAND_NORMAL);
219 #endif
220       }
221
222     case THUNK_DECL:
223       return DECL_RTL (exp);
224
225     case THROW_EXPR:
226       expand_throw (TREE_OPERAND (exp, 0));
227       return NULL;
228
229     case UNSAVE_EXPR:
230       {
231         rtx temp;
232         temp = expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier);
233         TREE_OPERAND (exp, 0) = unsave_expr_now (TREE_OPERAND (exp, 0));
234         return temp;
235       }
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 && POINTER_TYPE_P (TREE_TYPE (start)))
378     error ("pointers are not permitted as case values");
379
380   if (end && pedantic)
381     pedwarn ("ANSI C++ forbids range expressions in switch statement");
382
383   if (current_template_parms)
384     {
385       add_tree (build_min_nt (CASE_LABEL, start, end));
386       return;
387     }
388
389   if (start)
390     value1 = check_cp_case_value (start);
391   if (end)
392     value2 = check_cp_case_value (end);
393   
394   label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
395
396   if (value1 != error_mark_node
397       && value2 != error_mark_node)
398     {
399       tree duplicate;
400       int success;
401
402       if (end)
403         success = pushcase_range (value1, value2, convert_and_check,
404                                   label, &duplicate);
405       else if (start)
406         success = pushcase (value1, convert_and_check, label, &duplicate);
407       else
408         success = pushcase (NULL_TREE, 0, label, &duplicate);
409
410       if (success == 1)
411         {
412           if (end)
413             error ("case label not within a switch statement");
414           else if (start)
415             cp_error ("case label `%E' not within a switch statement", start);
416           else
417             error ("default label not within a switch statement");
418         }
419       else if (success == 2)
420         {
421           if (end)
422             {
423               error ("duplicate (or overlapping) case value");
424               cp_error_at ("this is the first entry overlapping that value",
425                            duplicate);
426             }
427           else if (start)
428             {
429               cp_error ("duplicate case value `%E'", start);
430               cp_error_at ("previously used here", duplicate);
431             }
432           else
433             {
434               error ("multiple default labels in one switch");
435               cp_error_at ("this is the first default label", duplicate);
436             }
437         }
438       else if (success == 3)
439         warning ("case value out of range");
440       else if (success == 4)
441         warning ("empty range specified");
442       else if (success == 5)
443         {
444           if (end)
445             error ("case label within scope of cleanup or variable array");
446           else
447             cp_error ("case label `%E' within scope of cleanup or variable array", start);
448         }
449     }
450   if (start)
451     define_case_label (label);
452   else
453     define_case_label (NULL_TREE);
454 }