expr.c revision 50397
1207753Smm/* Convert language-specific tree expression to rtl instructions,
2207753Smm   for GNU compiler.
3207753Smm   Copyright (C) 1988, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
4207753Smm
5207753SmmThis file is part of GNU CC.
6207753Smm
7207753SmmGNU CC is free software; you can redistribute it and/or modify
8207753Smmit under the terms of the GNU General Public License as published by
9207753Smmthe Free Software Foundation; either version 2, or (at your option)
10207753Smmany later version.
11207753Smm
12207753SmmGNU CC is distributed in the hope that it will be useful,
13207753Smmbut WITHOUT ANY WARRANTY; without even the implied warranty of
14207753SmmMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15207753SmmGNU General Public License for more details.
16207753Smm
17207753SmmYou should have received a copy of the GNU General Public License
18207753Smmalong with GNU CC; see the file COPYING.  If not, write to
19207753Smmthe Free Software Foundation, 59 Temple Place - Suite 330,
20207753SmmBoston, MA 02111-1307, USA.  */
21207753Smm
22207753Smm
23207753Smm#include "config.h"
24207753Smm#include "system.h"
25207753Smm#include "rtl.h"
26207753Smm#include "tree.h"
27207753Smm#include "flags.h"
28207753Smm#include "expr.h"
29207753Smm#include "cp-tree.h"
30207753Smm#include "toplev.h"
31207753Smm
32207753Smm#if 0
33207753Smmstatic tree extract_aggr_init PROTO((tree, tree));
34207753Smmstatic tree extract_scalar_init PROTO((tree, tree));
35207753Smm#endif
36207753Smmstatic rtx cplus_expand_expr PROTO((tree, rtx, enum machine_mode,
37207753Smm				    enum expand_modifier));
38207753Smm
39207753Smm/* Hook used by expand_expr to expand language-specific tree codes.  */
40207753Smm
41207753Smmstatic rtx
42207753Smmcplus_expand_expr (exp, target, tmode, modifier)
43207753Smm     tree exp;
44207753Smm     rtx target;
45207753Smm     enum machine_mode tmode;
46207753Smm     enum expand_modifier modifier;
47207753Smm{
48207753Smm  tree type = TREE_TYPE (exp);
49207753Smm  register enum machine_mode mode = TYPE_MODE (type);
50207753Smm  register enum tree_code code = TREE_CODE (exp);
51207753Smm  int ignore = target == const0_rtx;
52207753Smm
53207753Smm  if (ignore)
54207753Smm    target = 0;
55207753Smm
56207753Smm  /* No sense saving up arithmetic to be done
57207753Smm     if it's all in the wrong mode to form part of an address.
58207753Smm     And force_operand won't know whether to sign-extend or zero-extend.  */
59207753Smm
60207753Smm  if (mode != Pmode && modifier == EXPAND_SUM)
61207753Smm    modifier = EXPAND_NORMAL;
62207753Smm
63207753Smm  switch (code)
64207753Smm    {
65207753Smm    case AGGR_INIT_EXPR:
66207753Smm      {
67207753Smm	/* Something needs to be initialized, but we didn't know
68207753Smm	   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;
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
90	/* Should always be called with a target.  */
91	my_friendly_assert (target != NULL_RTX, 205);
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	  {
105	    type = build_pointer_type (type);
106	    /* Don't clobber a value that might be part of a default
107	       parameter value.  */
108	    mark_addressable (slot);
109	    if (TREE_PERMANENT (args))
110	      args = expr_tree_cons (0, build1 (ADDR_EXPR, type, slot),
111				TREE_CHAIN (args));
112	    else
113	      TREE_VALUE (args) = build1 (ADDR_EXPR, type, slot);
114	    call_target = 0;
115	  }
116	else
117	  {
118	    call_target = target;
119#ifdef PCC_STATIC_STRUCT_RETURN
120	    if (aggregate_value_p (type))
121	      {
122		pcc_struct_return = 1;
123		call_target = 0;
124	      }
125#endif
126	  }
127
128	call_exp = build (CALL_EXPR, type, func, args, NULL_TREE);
129	TREE_SIDE_EFFECTS (call_exp) = 1;
130	return_target = expand_call (call_exp, call_target, ignore);
131
132	if (call_target)
133	  /* Trust that the right thing has been done; it's too hard to
134	     verify.  */
135	  return return_target;
136
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)
141	  {
142	    extern int flag_access_control;
143	    int old_ac = flag_access_control;
144
145	    tree init = build_decl (VAR_DECL, NULL_TREE,
146				    build_reference_type (type));
147	    DECL_RTL (init) = XEXP (return_target, 0);
148	    init = convert_from_reference (init);
149
150	    flag_access_control = 0;
151	    expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING);
152	    flag_access_control = old_ac;
153
154	    if (TYPE_NEEDS_DESTRUCTOR (type))
155	      {
156		init = maybe_build_cleanup (init);
157		if (init != NULL_TREE)
158		  expand_expr (init, const0_rtx, VOIDmode, 0);
159	      }
160	  }
161
162	return DECL_RTL (slot);
163      }
164
165    case OFFSET_REF:
166      {
167#if 1
168	return expand_expr (default_conversion (resolve_offset_ref (exp)),
169			    target, tmode, EXPAND_NORMAL);
170#else
171	/* This is old crusty code, and does not handle all that the
172	   resolve_offset_ref function does.  (mrs) */
173	tree base = build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 0), 0);
174	tree offset = build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 1), 0);
175	return expand_expr (build (PLUS_EXPR, TREE_TYPE (exp), base, offset),
176			    target, tmode, EXPAND_NORMAL);
177#endif
178      }
179
180    case THUNK_DECL:
181      return DECL_RTL (exp);
182
183    case THROW_EXPR:
184      expand_throw (TREE_OPERAND (exp, 0));
185      return NULL;
186
187    case VEC_INIT_EXPR:
188      return expand_expr
189	(expand_vec_init
190	 (NULL_TREE, TREE_OPERAND (exp, 0),
191	  build_binary_op (MINUS_EXPR, TREE_OPERAND (exp, 2),
192			   integer_one_node, 1),
193	  TREE_OPERAND (exp, 1), 0), target, tmode, modifier);
194
195    case NEW_EXPR:
196      return expand_expr (build_new_1 (exp), target, tmode, modifier);
197
198    default:
199      break;
200    }
201  my_friendly_abort (40);
202  /* NOTREACHED */
203  return NULL;
204}
205
206void
207init_cplus_expand ()
208{
209  lang_expand_expr = cplus_expand_expr;
210}
211
212/* If DECL had its rtl moved from where callers expect it
213   to be, fix it up.  RESULT is the nominal rtl for the RESULT_DECL,
214   which may be a pseudo instead of a hard register.  */
215
216void
217fixup_result_decl (decl, result)
218     tree decl;
219     rtx result;
220{
221  if (REG_P (result))
222    {
223      if (REGNO (result) >= FIRST_PSEUDO_REGISTER)
224	{
225	  rtx real_decl_result;
226
227#ifdef FUNCTION_OUTGOING_VALUE
228	  real_decl_result
229	    = FUNCTION_OUTGOING_VALUE (TREE_TYPE (decl), current_function_decl);
230#else
231	  real_decl_result
232	    = FUNCTION_VALUE (TREE_TYPE (decl), current_function_decl);
233#endif
234	  REG_FUNCTION_VALUE_P (real_decl_result) = 1;
235	  result = real_decl_result;
236	}
237      store_expr (decl, result, 0);
238      emit_insn (gen_rtx (USE, VOIDmode, result));
239    }
240}
241
242#if 0
243/* Expand this initialization inline and see if it's simple enough that
244   it can be done at compile-time.  */
245
246static tree
247extract_aggr_init (decl, init)
248     tree decl, init;
249{
250  return 0;
251}
252
253static tree
254extract_scalar_init (decl, init)
255     tree decl, init;
256{
257  rtx value, insns, insn;
258  extern struct obstack temporary_obstack;
259  tree t = NULL_TREE;
260
261  push_obstacks (&temporary_obstack, &temporary_obstack);
262  start_sequence ();
263  value = expand_expr (init, NULL_RTX, VOIDmode, 0);
264  insns = get_insns ();
265  end_sequence ();
266  reg_scan (insns, max_reg_num (), 0);
267  jump_optimize (insns, 0, 0, 1);
268  pop_obstacks ();
269
270  for (insn = insns; insn; insn = NEXT_INSN (insn))
271    {
272      rtx r, to;
273
274      if (GET_CODE (insn) == NOTE)
275	continue;
276      else if (GET_CODE (insn) != INSN)
277	return 0;
278
279      r = PATTERN (insn);
280      if (GET_CODE (r) != SET)
281	return 0;
282
283      to = XEXP (r, 0);
284
285      if (! (to == value
286	     || (GET_CODE (to) == SUBREG && XEXP (to, 0) == value)))
287	return 0;
288
289      r = XEXP (r, 1);
290
291      switch (GET_CODE (r))
292	{
293	case CONST_INT:
294	  t = build_int_2 (XEXP (r, 0), 0);
295	  break;
296	default:
297	  return 0;
298	}
299    }
300
301  return t;
302}
303#endif
304
305int
306extract_init (decl, init)
307     tree decl, init;
308{
309  return 0;
310
311#if 0
312  if (IS_AGGR_TYPE (TREE_TYPE (decl))
313      || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
314    init = extract_aggr_init (decl, init);
315  else
316    init = extract_scalar_init (decl, init);
317
318  if (init == NULL_TREE)
319    return 0;
320
321  DECL_INITIAL (decl) = init;
322  return 1;
323#endif
324}
325
326void
327do_case (start, end)
328     tree start, end;
329{
330  tree value1 = NULL_TREE, value2 = NULL_TREE, label;
331
332  if (start != NULL_TREE && TREE_TYPE (start) != NULL_TREE
333      && POINTER_TYPE_P (TREE_TYPE (start)))
334    error ("pointers are not permitted as case values");
335
336  if (end && pedantic)
337    pedwarn ("ANSI C++ forbids range expressions in switch statement");
338
339  if (processing_template_decl)
340    {
341      add_tree (build_min_nt (CASE_LABEL, start, end));
342      return;
343    }
344
345  if (start)
346    value1 = check_cp_case_value (start);
347  if (end)
348    value2 = check_cp_case_value (end);
349
350  label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
351
352  if (value1 != error_mark_node
353      && value2 != error_mark_node)
354    {
355      tree duplicate;
356      int success;
357
358      if (end)
359	success = pushcase_range (value1, value2, convert_and_check,
360				  label, &duplicate);
361      else if (start)
362	success = pushcase (value1, convert_and_check, label, &duplicate);
363      else
364	success = pushcase (NULL_TREE, 0, label, &duplicate);
365
366      if (success == 1)
367	{
368	  if (end)
369	    error ("case label not within a switch statement");
370	  else if (start)
371	    cp_error ("case label `%E' not within a switch statement", start);
372	  else
373	    error ("default label not within a switch statement");
374	}
375      else if (success == 2)
376	{
377	  if (end)
378	    {
379	      error ("duplicate (or overlapping) case value");
380	      cp_error_at ("this is the first entry overlapping that value",
381			   duplicate);
382	    }
383	  else if (start)
384	    {
385	      cp_error ("duplicate case value `%E'", start);
386	      cp_error_at ("previously used here", duplicate);
387	    }
388	  else
389	    {
390	      error ("multiple default labels in one switch");
391	      cp_error_at ("this is the first default label", duplicate);
392	    }
393	}
394      else if (success == 3)
395	warning ("case value out of range");
396      else if (success == 4)
397	warning ("empty range specified");
398      else if (success == 5)
399	{
400	  if (end)
401	    error ("case label within scope of cleanup or variable array");
402	  else if (! start)
403	    error ("`default' label within scope of cleanup or variable array");
404	  else
405	    cp_error ("case label `%E' within scope of cleanup or variable array", start);
406	}
407    }
408  if (start)
409    define_case_label (label);
410  else
411    define_case_label (NULL_TREE);
412}
413