OSDN Git Service

89th Cygnus<->FSF quick merge
[pf3gnuchains/gcc-fork.git] / gcc / cp / init.c
1 /* Handle initialization things in C++.
2    Copyright (C) 1987, 89, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
3    Contributed by Michael Tiemann (tiemann@cygnus.com)
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 /* High-level class interface.  */
24
25 #include "config.h"
26 #include "tree.h"
27 #include "rtl.h"
28 #include "cp-tree.h"
29 #include "flags.h"
30 #include "output.h"
31
32 #undef NULL
33 #define NULL 0
34
35 /* In C++, structures with well-defined constructors are initialized by
36    those constructors, unasked.  CURRENT_BASE_INIT_LIST
37    holds a list of stmts for a BASE_INIT term in the grammar.
38    This list has one element for each base class which must be
39    initialized.  The list elements are [basename, init], with
40    type basetype.  This allows the possibly anachronistic form
41    (assuming d : a, b, c) "d (int a) : c(a+5), b (a-4), a (a+3)"
42    where each successive term can be handed down the constructor
43    line.  Perhaps this was not intended.  */
44 tree current_base_init_list, current_member_init_list;
45
46 extern tree cleanups_this_call;
47
48 void emit_base_init ();
49 void check_base_init ();
50 static void expand_aggr_vbase_init ();
51 void expand_member_init ();
52 void expand_aggr_init ();
53
54 static void expand_aggr_init_1 PROTO((tree, tree, tree, tree, int, int));
55 static void expand_virtual_init PROTO((tree, tree));
56 tree expand_vec_init ();
57
58 static void add_friend (), add_friends ();
59
60 /* Cache _builtin_new and _builtin_delete exprs.  */
61 static tree BIN, BID, BIVN, BIVD;
62
63 /* Cache the identifier nodes for the magic field of a new cookie.  */
64 static tree nc_nelts_field_id;
65
66 static tree minus_one;
67
68 /* Set up local variable for this file.  MUST BE CALLED AFTER
69    INIT_DECL_PROCESSING.  */
70
71 static tree BI_header_type, BI_header_size;
72
73 void init_init_processing ()
74 {
75   tree fields[1];
76
77   /* Define implicit `operator new' and `operator delete' functions.  */
78   BIN = default_conversion (get_first_fn (IDENTIFIER_GLOBAL_VALUE (ansi_opname[(int) NEW_EXPR])));
79   TREE_USED (TREE_OPERAND (BIN, 0)) = 0;
80   BID = default_conversion (get_first_fn (IDENTIFIER_GLOBAL_VALUE (ansi_opname[(int) DELETE_EXPR])));
81   TREE_USED (TREE_OPERAND (BID, 0)) = 0;
82   BIVN = default_conversion (get_first_fn (IDENTIFIER_GLOBAL_VALUE (ansi_opname[(int) VEC_NEW_EXPR])));
83   TREE_USED (TREE_OPERAND (BIVN, 0)) = 0;
84   BIVD = default_conversion (get_first_fn (IDENTIFIER_GLOBAL_VALUE (ansi_opname[(int) VEC_DELETE_EXPR])));
85   TREE_USED (TREE_OPERAND (BIVD, 0)) = 0;
86   minus_one = build_int_2 (-1, -1);
87
88   /* Define the structure that holds header information for
89      arrays allocated via operator new.  */
90   BI_header_type = make_lang_type (RECORD_TYPE);
91   nc_nelts_field_id = get_identifier ("nelts");
92   fields[0] = build_lang_field_decl (FIELD_DECL, nc_nelts_field_id, sizetype);
93   finish_builtin_type (BI_header_type, "__new_cookie", fields,
94                        0, double_type_node);
95   BI_header_size = size_in_bytes (BI_header_type);
96 }
97
98 /* Subroutine of emit_base_init.  For BINFO, initialize all the
99    virtual function table pointers, except those that come from
100    virtual base classes.  Initialize binfo's vtable pointer, if
101    INIT_SELF is true.  CAN_ELIDE is true when we know that all virtual
102    function table pointers in all bases have been initialized already,
103    probably because their constructors have just be run.  ADDR is the
104    pointer to the object whos vtables we are going to initialize.
105
106    REAL_BINFO is usually the same as BINFO, except when addr is not of
107    pointer to the type of the real derived type that we want to
108    initialize for.  This is the case when addr is a pointer to a sub
109    object of a complete object, and we only want to do part of the
110    complete object's initialization of vtable pointers.  This is done
111    for all virtual table pointers in virtual base classes.  REAL_BINFO
112    is used to find the BINFO_VTABLE that we initialize with.  BINFO is
113    used for conversions of addr to subobjects.
114
115    BINFO_TYPE (real_binfo) must be BINFO_TYPE (binfo).
116
117    Relies upon binfo being inside TYPE_BINFO (TREE_TYPE (TREE_TYPE
118    (addr))).  */
119
120 void
121 expand_direct_vtbls_init (real_binfo, binfo, init_self, can_elide, addr)
122      tree real_binfo, binfo, addr;
123      int init_self, can_elide;
124 {
125   tree real_binfos = BINFO_BASETYPES (real_binfo);
126   tree binfos = BINFO_BASETYPES (binfo);
127   int i, n_baselinks = real_binfos ? TREE_VEC_LENGTH (real_binfos) : 0;
128
129   for (i = 0; i < n_baselinks; i++)
130     {
131       tree real_base_binfo = TREE_VEC_ELT (real_binfos, i);
132       tree base_binfo = TREE_VEC_ELT (binfos, i);
133       int is_not_base_vtable =
134         i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (real_binfo));
135       if (! TREE_VIA_VIRTUAL (real_base_binfo))
136         expand_direct_vtbls_init (real_base_binfo, base_binfo,
137                                   is_not_base_vtable, can_elide, addr);
138     }
139 #if 0
140   /* Before turning this on, make sure it is correct.  */
141   if (can_elide && ! BINFO_MODIFIED (binfo))
142     return;
143 #endif
144   /* Should we use something besides CLASSTYPE_VFIELDS? */
145   if (init_self && CLASSTYPE_VFIELDS (BINFO_TYPE (real_binfo)))
146     {
147       tree base_ptr = convert_pointer_to_real (binfo, addr);
148       expand_virtual_init (real_binfo, base_ptr);
149     }
150 }
151 \f
152 /* 348 - 351 */
153 /* Subroutine of emit_base_init.  */
154
155 static void
156 perform_member_init (member, name, init, explicit)
157      tree member, name, init;
158      int explicit;
159 {
160   tree decl;
161   tree type = TREE_TYPE (member);
162   extern int temp_slot_level;
163   extern int target_temp_slot_level; 
164   tree old_cleanups = cleanups_this_call;
165   int old_temp_level = target_temp_slot_level;
166   push_temp_slots ();
167   push_temp_slots ();
168   target_temp_slot_level = temp_slot_level;
169
170   if (TYPE_NEEDS_CONSTRUCTING (type)
171       || (init && TYPE_HAS_CONSTRUCTOR (type)))
172     {
173       /* Since `init' is already a TREE_LIST on the current_member_init_list,
174          only build it into one if we aren't already a list.  */
175       if (init != NULL_TREE && TREE_CODE (init) != TREE_LIST)
176         init = build_tree_list (NULL_TREE, init);
177
178       decl = build_component_ref (current_class_ref, name, NULL_TREE, explicit);
179
180       if (explicit
181           && TREE_CODE (type) == ARRAY_TYPE
182           && init != NULL_TREE
183           && TREE_CHAIN (init) == NULL_TREE
184           && TREE_CODE (TREE_TYPE (TREE_VALUE (init))) == ARRAY_TYPE)
185         {
186           /* Initialization of one array from another.  */
187           expand_vec_init (TREE_OPERAND (decl, 1), decl,
188                            array_type_nelts (type), TREE_VALUE (init), 1);
189         }
190       else
191         expand_aggr_init (decl, init, 0, 0);
192     }
193   else
194     {
195       if (init == NULL_TREE)
196         {
197           if (explicit)
198             {
199               cp_error ("incomplete initializer for member `%D' of class `%T' which has no constructor",
200                         member, current_class_type);
201               init = error_mark_node;
202             }
203           /* member traversal: note it leaves init NULL */
204           else if (TREE_CODE (TREE_TYPE (member)) == REFERENCE_TYPE)
205             cp_pedwarn ("uninitialized reference member `%D'", member);
206         }
207       else if (TREE_CODE (init) == TREE_LIST)
208         {
209           /* There was an explicit member initialization.  Do some
210              work in that case.  */
211           if (TREE_CHAIN (init))
212             {
213               warning ("initializer list treated as compound expression");
214               init = build_compound_expr (init);
215             }
216           else
217             init = TREE_VALUE (init);
218         }
219
220       /* We only build this with a null init if we got it from the
221          current_member_init_list.  */
222       if (init || explicit)
223         {
224           decl = build_component_ref (current_class_ref, name, NULL_TREE, explicit);
225           expand_expr_stmt (build_modify_expr (decl, INIT_EXPR, init));
226         }
227     }
228   expand_cleanups_to (old_cleanups);
229   pop_temp_slots ();
230   pop_temp_slots ();
231   target_temp_slot_level = old_temp_level;
232   /* There might something left from building the trees.  */
233   if (cleanups_this_call)
234     {
235       expand_cleanups_to (NULL_TREE);
236     }
237   free_temp_slots ();
238
239   if (TYPE_NEEDS_DESTRUCTOR (type))
240     {
241       tree expr = build_component_ref (current_class_ref, name, NULL_TREE, explicit);
242       expr = build_delete (type, expr, integer_zero_node,
243                            LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0);
244
245       if (expr != error_mark_node)
246         add_partial_entry (expr);
247     }
248 }
249
250 extern int warn_reorder;
251
252 /* Subroutine of emit_member_init.  */
253
254 static tree
255 sort_member_init (t)
256      tree t;
257 {
258   tree x, member, name, field;
259   tree init_list = NULL_TREE;
260   int last_pos = 0;
261   tree last_field;
262
263   for (member = TYPE_FIELDS (t); member ; member = TREE_CHAIN (member))
264     {
265       int pos;
266
267       /* member could be, for example, a CONST_DECL for an enumerated
268          tag; we don't want to try to initialize that, since it already
269          has a value.  */
270       if (TREE_CODE (member) != FIELD_DECL || !DECL_NAME (member))
271         continue;
272
273       for (x = current_member_init_list, pos = 0; x; x = TREE_CHAIN (x), ++pos)
274         {
275           /* If we cleared this out, then pay no attention to it.  */
276           if (TREE_PURPOSE (x) == NULL_TREE)
277             continue;
278           name = TREE_PURPOSE (x);
279
280 #if 0
281           /* This happens in templates, since the IDENTIFIER is replaced
282              with the COMPONENT_REF in tsubst_expr.  */
283           field = (TREE_CODE (name) == COMPONENT_REF
284                    ? TREE_OPERAND (name, 1) : IDENTIFIER_CLASS_VALUE (name));
285 #else
286           /* Let's find out when this happens.  */
287           my_friendly_assert (TREE_CODE (name) != COMPONENT_REF, 348);
288           field = IDENTIFIER_CLASS_VALUE (name);
289 #endif
290
291           /* If one member shadows another, get the outermost one.  */
292           if (TREE_CODE (field) == TREE_LIST)
293             field = TREE_VALUE (field);
294
295           if (field == member)
296             {
297               if (warn_reorder)
298                 {
299                   if (pos < last_pos)
300                     {
301                       cp_warning_at ("member initializers for `%#D'", last_field);
302                       cp_warning_at ("  and `%#D'", field);
303                       warning ("  will be re-ordered to match declaration order");
304                     }
305                   last_pos = pos;
306                   last_field = field;
307                 }
308
309               /* Make sure we won't try to work on this init again.  */
310               TREE_PURPOSE (x) = NULL_TREE;
311               x = build_tree_list (name, TREE_VALUE (x));
312               goto got_it;
313             }
314         }
315
316       /* If we didn't find MEMBER in the list, create a dummy entry
317          so the two lists (INIT_LIST and the list of members) will be
318          symmetrical.  */
319       x = build_tree_list (NULL_TREE, NULL_TREE);
320     got_it:
321       init_list = chainon (init_list, x); 
322     }
323
324   /* Initializers for base members go at the end.  */
325   for (x = current_member_init_list ; x ; x = TREE_CHAIN (x))
326     {
327       name = TREE_PURPOSE (x);
328       if (name)
329         {
330           if (purpose_member (name, init_list))
331             {
332               cp_error ("multiple initializations given for member `%D'",
333                         IDENTIFIER_CLASS_VALUE (name));
334               continue;
335             }
336               
337           init_list = chainon (init_list,
338                                build_tree_list (name, TREE_VALUE (x)));
339           TREE_PURPOSE (x) = NULL_TREE;
340         }
341     }
342
343   return init_list;
344 }
345
346 static void
347 sort_base_init (t, rbase_ptr, vbase_ptr)
348      tree t, *rbase_ptr, *vbase_ptr;
349 {
350   tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));
351   int n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
352
353   int i;
354   tree x;
355   tree last;
356
357   /* For warn_reorder.  */
358   int last_pos = 0;
359   tree last_base = NULL_TREE;
360
361   tree rbases = NULL_TREE;
362   tree vbases = NULL_TREE;
363
364   /* First walk through and splice out vbase and invalid initializers.
365      Also replace names with binfos.  */
366
367   last = tree_cons (NULL_TREE, NULL_TREE, current_base_init_list);
368   for (x = TREE_CHAIN (last); x; x = TREE_CHAIN (x))
369     {
370       tree basetype = TREE_PURPOSE (x);
371       tree binfo;
372
373       if (basetype == NULL_TREE)
374         {
375           /* Initializer for single base class.  Must not
376              use multiple inheritance or this is ambiguous.  */
377           switch (n_baseclasses)
378             {
379             case 0:
380               cp_error ("`%T' does not have a base class to initialize",
381                         current_class_type);
382               return;
383             case 1:
384               break;
385             default:
386               cp_error ("unnamed initializer ambiguous for `%T' which uses multiple inheritance",
387                         current_class_type);
388               return;
389             }
390           binfo = TREE_VEC_ELT (binfos, 0);
391         }
392       else if (is_aggr_type (basetype, 1))
393         {
394           binfo = binfo_or_else (basetype, t);
395           if (binfo == NULL_TREE)
396             continue;
397
398           /* Virtual base classes are special cases.  Their initializers
399              are recorded with this constructor, and they are used when
400              this constructor is the top-level constructor called.  */
401           if (TREE_VIA_VIRTUAL (binfo))
402             {
403               tree v = CLASSTYPE_VBASECLASSES (t);
404               while (BINFO_TYPE (v) != BINFO_TYPE (binfo))
405                 v = TREE_CHAIN (v);
406
407               vbases = tree_cons (v, TREE_VALUE (x), vbases);
408               continue;
409             }
410           else
411             {
412               /* Otherwise, if it is not an immediate base class, complain.  */
413               for (i = n_baseclasses-1; i >= 0; i--)
414                 if (BINFO_TYPE (binfo) == BINFO_TYPE (TREE_VEC_ELT (binfos, i)))
415                   break;
416               if (i < 0)
417                 {
418                   cp_error ("`%T' is not an immediate base class of `%T'",
419                             basetype, current_class_type);
420                   continue;
421                 }
422             }
423         }
424       else
425         my_friendly_abort (365);
426
427       TREE_PURPOSE (x) = binfo;
428       TREE_CHAIN (last) = x;
429       last = x;
430     }
431   TREE_CHAIN (last) = NULL_TREE;
432
433   /* Now walk through our regular bases and make sure they're initialized.  */
434
435   for (i = 0; i < n_baseclasses; ++i)
436     {
437       tree base_binfo = TREE_VEC_ELT (binfos, i);
438       int pos;
439
440       if (TREE_VIA_VIRTUAL (base_binfo))
441         continue;
442
443       for (x = current_base_init_list, pos = 0; x; x = TREE_CHAIN (x), ++pos)
444         {
445           tree binfo = TREE_PURPOSE (x);
446
447           if (binfo == NULL_TREE)
448             continue;
449
450           if (binfo == base_binfo)
451             {
452               if (warn_reorder)
453                 {
454                   if (pos < last_pos)
455                     {
456                       cp_warning_at ("base initializers for `%#T'", last_base);
457                       cp_warning_at ("  and `%#T'", BINFO_TYPE (binfo));
458                       warning ("  will be re-ordered to match inheritance order");
459                     }
460                   last_pos = pos;
461                   last_base = BINFO_TYPE (binfo);
462                 }
463
464               /* Make sure we won't try to work on this init again.  */
465               TREE_PURPOSE (x) = NULL_TREE;
466               x = build_tree_list (binfo, TREE_VALUE (x));
467               goto got_it;
468             }
469         }
470
471       /* If we didn't find BASE_BINFO in the list, create a dummy entry
472          so the two lists (RBASES and the list of bases) will be
473          symmetrical.  */
474       x = build_tree_list (NULL_TREE, NULL_TREE);
475     got_it:
476       rbases = chainon (rbases, x);
477     }
478
479   *rbase_ptr = rbases;
480   *vbase_ptr = vbases;
481 }
482
483 /* Perform partial cleanups for a base for exception handling.  */
484
485 static tree
486 build_partial_cleanup_for (binfo)
487      tree binfo;
488 {
489   tree expr = convert_pointer_to_real (binfo,
490                                        build_unary_op (ADDR_EXPR, current_class_ref, 0));
491
492   return build_delete (TREE_TYPE (expr),
493                        expr,
494                        integer_zero_node,
495                        LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0);
496 }
497
498 /* Perform whatever initializations have yet to be done on the base
499    class of the class variable.  These actions are in the global
500    variable CURRENT_BASE_INIT_LIST.  Such an action could be
501    NULL_TREE, meaning that the user has explicitly called the base
502    class constructor with no arguments.
503
504    If there is a need for a call to a constructor, we must surround
505    that call with a pushlevel/poplevel pair, since we are technically
506    at the PARM level of scope.
507
508    Argument IMMEDIATELY, if zero, forces a new sequence to be
509    generated to contain these new insns, so it can be emitted later.
510    This sequence is saved in the global variable BASE_INIT_EXPR.
511    Otherwise, the insns are emitted into the current sequence.
512
513    Note that emit_base_init does *not* initialize virtual base
514    classes.  That is done specially, elsewhere.  */
515
516 extern tree base_init_expr, rtl_expr_chain;
517
518 void
519 emit_base_init (t, immediately)
520      tree t;
521      int immediately;
522 {
523   tree member;
524   tree mem_init_list;
525   tree rbase_init_list, vbase_init_list;
526   tree t_binfo = TYPE_BINFO (t);
527   tree binfos = BINFO_BASETYPES (t_binfo);
528   int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
529   tree expr = NULL_TREE;
530
531   if (! immediately)
532     {
533       int momentary;
534       do_pending_stack_adjust ();
535       /* Make the RTL_EXPR node temporary, not momentary,
536          so that rtl_expr_chain doesn't become garbage.  */
537       momentary = suspend_momentary ();
538       expr = make_node (RTL_EXPR);
539       resume_momentary (momentary);
540       start_sequence_for_rtl_expr (expr); 
541     }
542
543   if (write_symbols == NO_DEBUG)
544     /* As a matter of principle, `start_sequence' should do this.  */
545     emit_note (0, -1);
546   else
547     /* Always emit a line number note so we can step into constructors.  */
548     emit_line_note_force (DECL_SOURCE_FILE (current_function_decl),
549                           DECL_SOURCE_LINE (current_function_decl));
550
551   mem_init_list = sort_member_init (t);
552   current_member_init_list = NULL_TREE;
553
554   sort_base_init (t, &rbase_init_list, &vbase_init_list);
555   current_base_init_list = NULL_TREE;
556
557   if (TYPE_USES_VIRTUAL_BASECLASSES (t))
558     {
559       tree first_arg = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl));
560
561       expand_start_cond (first_arg, 0);
562       expand_aggr_vbase_init (t_binfo, current_class_ref, current_class_ptr,
563                               vbase_init_list);
564       expand_end_cond ();
565     }
566
567   /* Now, perform initialization of non-virtual base classes.  */
568   for (i = 0; i < n_baseclasses; i++)
569     {
570       tree base_binfo = TREE_VEC_ELT (binfos, i);
571       tree init = void_list_node;
572
573       if (TREE_VIA_VIRTUAL (base_binfo))
574         continue;
575
576 #if 0 /* Once unsharing happens soon enough.  */
577       my_friendly_assert (BINFO_INHERITANCE_CHAIN (base_binfo) == t_binfo, 999);
578 #else
579       BINFO_INHERITANCE_CHAIN (base_binfo) = t_binfo;
580 #endif
581
582       if (TREE_PURPOSE (rbase_init_list))
583         init = TREE_VALUE (rbase_init_list);
584       else if (TYPE_NEEDS_CONSTRUCTING (BINFO_TYPE (base_binfo)))
585         init = NULL_TREE;
586
587       if (init != void_list_node)
588         {
589           extern int temp_slot_level;
590           extern int target_temp_slot_level; 
591           tree old_cleanups = cleanups_this_call;
592           int old_temp_level = target_temp_slot_level;
593           push_temp_slots ();
594           push_temp_slots ();
595           target_temp_slot_level = temp_slot_level;
596
597           member = convert_pointer_to_real (base_binfo, current_class_ptr);
598           expand_aggr_init_1 (base_binfo, NULL_TREE,
599                               build_indirect_ref (member, NULL_PTR), init,
600                               BINFO_OFFSET_ZEROP (base_binfo), LOOKUP_NORMAL);
601           expand_cleanups_to (old_cleanups);
602           pop_temp_slots ();
603           pop_temp_slots ();
604           target_temp_slot_level = old_temp_level;
605           /* There might something left from building the trees.  */
606           if (cleanups_this_call)
607             {
608               expand_cleanups_to (NULL_TREE);
609             }
610           free_temp_slots ();
611         }
612
613       if (TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo)))
614         {
615           tree expr;
616
617           /* All cleanups must be on the function_obstack.  */
618           push_obstacks_nochange ();
619           resume_temporary_allocation ();
620           expr = build_partial_cleanup_for (base_binfo);
621           pop_obstacks ();
622           add_partial_entry (expr);
623         }
624
625       rbase_init_list = TREE_CHAIN (rbase_init_list);
626     }
627
628   /* Initialize all the virtual function table fields that
629      do come from virtual base classes.  */
630   if (TYPE_USES_VIRTUAL_BASECLASSES (t))
631     expand_indirect_vtbls_init (t_binfo, current_class_ref, current_class_ptr);
632
633   /* Initialize all the virtual function table fields that
634      do not come from virtual base classes.  */
635   expand_direct_vtbls_init (t_binfo, t_binfo, 1, 1, current_class_ptr);
636
637   for (member = TYPE_FIELDS (t); member; member = TREE_CHAIN (member))
638     {
639       tree init, name;
640       int from_init_list;
641
642       /* member could be, for example, a CONST_DECL for an enumerated
643          tag; we don't want to try to initialize that, since it already
644          has a value.  */
645       if (TREE_CODE (member) != FIELD_DECL || !DECL_NAME (member))
646         continue;
647
648       /* See if we had a user-specified member initialization.  */
649       if (TREE_PURPOSE (mem_init_list))
650         {
651           name = TREE_PURPOSE (mem_init_list);
652           init = TREE_VALUE (mem_init_list);
653           from_init_list = 1;
654
655 #if 0
656           if (TREE_CODE (name) == COMPONENT_REF)
657             name = DECL_NAME (TREE_OPERAND (name, 1));
658 #else
659           /* Also see if it's ever a COMPONENT_REF here.  If it is, we
660              need to do `expand_assignment (name, init, 0, 0);' and
661              a continue.  */
662           my_friendly_assert (TREE_CODE (name) != COMPONENT_REF, 349);
663 #endif
664         }
665       else
666         {
667           name = DECL_NAME (member);
668           init = DECL_INITIAL (member);
669
670           from_init_list = 0;
671         }
672
673       perform_member_init (member, name, init, from_init_list);
674       mem_init_list = TREE_CHAIN (mem_init_list);
675     }
676
677   /* Now initialize any members from our bases.  */
678   while (mem_init_list)
679     {
680       tree name, init, field;
681
682       if (TREE_PURPOSE (mem_init_list))
683         {
684           name = TREE_PURPOSE (mem_init_list);
685           init = TREE_VALUE (mem_init_list);
686           /* XXX: this may need the COMPONENT_REF operand 0 check if
687              it turns out we actually get them.  */
688           field = IDENTIFIER_CLASS_VALUE (name);
689
690           /* If one member shadows another, get the outermost one.  */
691           if (TREE_CODE (field) == TREE_LIST)
692             {
693               field = TREE_VALUE (field);
694               if (decl_type_context (field) != current_class_type)
695                 cp_error ("field `%D' not in immediate context", field);
696             }
697
698 #if 0
699           /* It turns out if you have an anonymous union in the
700              class, a member from it can end up not being on the
701              list of fields (rather, the type is), and therefore
702              won't be seen by the for loop above.  */
703
704           /* The code in this for loop is derived from a general loop
705              which had this check in it.  Theoretically, we've hit
706              every initialization for the list of members in T, so
707              we shouldn't have anything but these left in this list.  */
708           my_friendly_assert (DECL_FIELD_CONTEXT (field) != t, 351);
709 #endif
710
711           perform_member_init (field, name, init, 1);
712         }
713       mem_init_list = TREE_CHAIN (mem_init_list);
714     }
715
716   if (! immediately)
717     {
718       do_pending_stack_adjust ();
719       my_friendly_assert (base_init_expr == 0, 207);
720       base_init_expr = expr;
721       TREE_TYPE (expr) = void_type_node;
722       RTL_EXPR_RTL (expr) = const0_rtx;
723       RTL_EXPR_SEQUENCE (expr) = get_insns ();
724       rtl_expr_chain = tree_cons (NULL_TREE, expr, rtl_expr_chain);
725       end_sequence ();
726       TREE_SIDE_EFFECTS (expr) = 1;
727     }
728
729   /* All the implicit try blocks we built up will be zapped
730      when we come to a real binding contour boundary.  */
731 }
732
733 /* Check that all fields are properly initialized after
734    an assignment to `this'.  */
735
736 void
737 check_base_init (t)
738      tree t;
739 {
740   tree member;
741   for (member = TYPE_FIELDS (t); member; member = TREE_CHAIN (member))
742     if (DECL_NAME (member) && TREE_USED (member))
743       cp_error ("field `%D' used before initialized (after assignment to `this')",
744                 member);
745 }
746
747 /* This code sets up the virtual function tables appropriate for
748    the pointer DECL.  It is a one-ply initialization.
749
750    BINFO is the exact type that DECL is supposed to be.  In
751    multiple inheritance, this might mean "C's A" if C : A, B.  */
752
753 static void
754 expand_virtual_init (binfo, decl)
755      tree binfo, decl;
756 {
757   tree type = BINFO_TYPE (binfo);
758   tree vtbl, vtbl_ptr;
759   tree vtype, vtype_binfo;
760
761   /* This code is crusty.  Should be simple, like:
762      vtbl = BINFO_VTABLE (binfo);
763      */
764   vtype = DECL_CONTEXT (CLASSTYPE_VFIELD (type));
765   vtype_binfo = get_binfo (vtype, TREE_TYPE (TREE_TYPE (decl)), 0);
766   vtbl = BINFO_VTABLE (binfo_value (DECL_FIELD_CONTEXT (CLASSTYPE_VFIELD (type)), binfo));
767   assemble_external (vtbl);
768   TREE_USED (vtbl) = 1;
769   vtbl = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (vtbl)), vtbl);
770   decl = convert_pointer_to_real (vtype_binfo, decl);
771   vtbl_ptr = build_vfield_ref (build_indirect_ref (decl, NULL_PTR), vtype);
772   if (vtbl_ptr == error_mark_node)
773     return;
774
775   /* Have to convert VTBL since array sizes may be different.  */
776   vtbl = convert_force (TREE_TYPE (vtbl_ptr), vtbl, 0);
777   expand_expr_stmt (build_modify_expr (vtbl_ptr, NOP_EXPR, vtbl));
778 }
779
780 /* Subroutine of `expand_aggr_vbase_init'.
781    BINFO is the binfo of the type that is being initialized.
782    INIT_LIST is the list of initializers for the virtual baseclass.  */
783
784 static void
785 expand_aggr_vbase_init_1 (binfo, exp, addr, init_list)
786      tree binfo, exp, addr, init_list;
787 {
788   tree init = purpose_member (binfo, init_list);
789   tree ref = build_indirect_ref (addr, NULL_PTR);
790
791   extern int temp_slot_level;
792   extern int target_temp_slot_level; 
793   tree old_cleanups = cleanups_this_call;
794   int old_temp_level = target_temp_slot_level;
795   push_temp_slots ();
796   push_temp_slots ();
797   target_temp_slot_level = temp_slot_level;
798
799   if (init)
800     init = TREE_VALUE (init);
801   /* Call constructors, but don't set up vtables.  */
802   expand_aggr_init_1 (binfo, exp, ref, init, 0, LOOKUP_COMPLAIN);
803
804   expand_cleanups_to (old_cleanups);
805   pop_temp_slots ();
806   pop_temp_slots ();
807   target_temp_slot_level = old_temp_level;
808   /* There might something left from building the trees.  */
809   if (cleanups_this_call)
810     {
811       expand_cleanups_to (NULL_TREE);
812     }
813   free_temp_slots ();
814 }
815
816 /* Initialize this object's virtual base class pointers.  This must be
817    done only at the top-level of the object being constructed.
818
819    INIT_LIST is list of initialization for constructor to perform.  */
820
821 static void
822 expand_aggr_vbase_init (binfo, exp, addr, init_list)
823      tree binfo;
824      tree exp;
825      tree addr;
826      tree init_list;
827 {
828   tree type = BINFO_TYPE (binfo);
829
830   if (TYPE_USES_VIRTUAL_BASECLASSES (type))
831     {
832       tree result = init_vbase_pointers (type, addr);
833       tree vbases;
834
835       if (result)
836         expand_expr_stmt (build_compound_expr (result));
837
838       for (vbases = CLASSTYPE_VBASECLASSES (type); vbases;
839            vbases = TREE_CHAIN (vbases))
840         {
841           tree tmp = purpose_member (vbases, result);
842           expand_aggr_vbase_init_1 (vbases, exp,
843                                     TREE_OPERAND (TREE_VALUE (tmp), 0),
844                                     init_list);
845         }
846     }
847 }
848
849 /* Subroutine to perform parser actions for member initialization.
850    S_ID is the scoped identifier.
851    NAME is the name of the member.
852    INIT is the initializer, or `void_type_node' if none.  */
853
854 void
855 do_member_init (s_id, name, init)
856      tree s_id, name, init;
857 {
858   tree binfo, base;
859
860   if (current_class_type == NULL_TREE
861       || ! is_aggr_typedef (s_id, 1))
862     return;
863   binfo = get_binfo (IDENTIFIER_TYPE_VALUE (s_id),
864                           current_class_type, 1);
865   if (binfo == error_mark_node)
866     return;
867   if (binfo == 0)
868     {
869       error_not_base_type (IDENTIFIER_TYPE_VALUE (s_id), current_class_type);
870       return;
871     }
872
873   base = convert_pointer_to (binfo, current_class_ptr);
874   expand_member_init (build_indirect_ref (base, NULL_PTR), name, init);
875 }
876
877 /* Find the context in which this FIELD can be initialized.  */
878
879 static tree
880 initializing_context (field)
881      tree field;
882 {
883   tree t = DECL_CONTEXT (field);
884
885   /* Anonymous union members can be initialized in the first enclosing
886      non-anonymous union context.  */
887   while (t && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
888     t = TYPE_CONTEXT (t);
889   return t;
890 }
891
892 /* Function to give error message if member initialization specification
893    is erroneous.  FIELD is the member we decided to initialize.
894    TYPE is the type for which the initialization is being performed.
895    FIELD must be a member of TYPE.
896    
897    MEMBER_NAME is the name of the member.  */
898
899 static int
900 member_init_ok_or_else (field, type, member_name)
901      tree field;
902      tree type;
903      char *member_name;
904 {
905   if (field == error_mark_node)
906     return 0;
907   if (field == NULL_TREE || initializing_context (field) != type)
908     {
909       cp_error ("class `%T' does not have any field named `%s'", type,
910                 member_name);
911       return 0;
912     }
913   if (TREE_STATIC (field))
914     {
915       cp_error ("field `%#D' is static; only point of initialization is its declaration",
916                 field);
917       return 0;
918     }
919
920   return 1;
921 }
922
923 /* If NAME is a viable field name for the aggregate DECL,
924    and PARMS is a viable parameter list, then expand an _EXPR
925    which describes this initialization.
926
927    Note that we do not need to chase through the class's base classes
928    to look for NAME, because if it's in that list, it will be handled
929    by the constructor for that base class.
930
931    We do not yet have a fixed-point finder to instantiate types
932    being fed to overloaded constructors.  If there is a unique
933    constructor, then argument types can be got from that one.
934
935    If INIT is non-NULL, then it the initialization should
936    be placed in `current_base_init_list', where it will be processed
937    by `emit_base_init'.  */
938
939 void
940 expand_member_init (exp, name, init)
941      tree exp, name, init;
942 {
943   extern tree ptr_type_node;    /* should be in tree.h */
944
945   tree basetype = NULL_TREE, field;
946   tree parm;
947   tree rval, type;
948
949   if (exp == NULL_TREE)
950     return;                     /* complain about this later */
951
952   type = TYPE_MAIN_VARIANT (TREE_TYPE (exp));
953
954   if (name && TREE_CODE (name) == TYPE_DECL)
955     {
956       basetype = TREE_TYPE (name);
957       name = DECL_NAME (name);
958     }
959
960   if (name == NULL_TREE && IS_AGGR_TYPE (type))
961     switch (CLASSTYPE_N_BASECLASSES (type))
962       {
963       case 0:
964         error ("base class initializer specified, but no base class to initialize");
965         return;
966       case 1:
967         basetype = TYPE_BINFO_BASETYPE (type, 0);
968         break;
969       default:
970         error ("initializer for unnamed base class ambiguous");
971         cp_error ("(type `%T' uses multiple inheritance)", type);
972         return;
973       }
974
975   if (init)
976     {
977       /* The grammar should not allow fields which have names
978          that are TYPENAMEs.  Therefore, if the field has
979          a non-NULL TREE_TYPE, we may assume that this is an
980          attempt to initialize a base class member of the current
981          type.  Otherwise, it is an attempt to initialize a
982          member field.  */
983
984       if (init == void_type_node)
985         init = NULL_TREE;
986
987       if (name == NULL_TREE || basetype)
988         {
989           tree base_init;
990
991           if (name == NULL_TREE)
992             {
993 #if 0
994               if (basetype)
995                 name = TYPE_IDENTIFIER (basetype);
996               else
997                 {
998                   error ("no base class to initialize");
999                   return;
1000                 }
1001 #endif
1002             }
1003           else
1004             {
1005               if (basetype != type
1006                   && ! vec_binfo_member (basetype, TYPE_BINFO_BASETYPES (type))
1007                   && ! binfo_member (basetype, CLASSTYPE_VBASECLASSES (type)))
1008                 {
1009                   if (IDENTIFIER_CLASS_VALUE (name))
1010                     goto try_member;
1011                   if (TYPE_USES_VIRTUAL_BASECLASSES (type))
1012                     cp_error ("type `%T' is not an immediate or virtual basetype for `%T'",
1013                               basetype, type);
1014                   else
1015                     cp_error ("type `%T' is not an immediate basetype for `%T'",
1016                               basetype, type);
1017                   return;
1018                 }
1019             }
1020
1021           if (purpose_member (basetype, current_base_init_list))
1022             {
1023               cp_error ("base class `%T' already initialized", basetype);
1024               return;
1025             }
1026
1027           if (warn_reorder && current_member_init_list)
1028             {
1029               cp_warning ("base initializer for `%T'", basetype);
1030               warning ("   will be re-ordered to precede member initializations");
1031             }
1032
1033           base_init = build_tree_list (basetype, init);
1034           current_base_init_list = chainon (current_base_init_list, base_init);
1035         }
1036       else
1037         {
1038           tree member_init;
1039
1040         try_member:
1041           field = lookup_field (type, name, 1, 0);
1042
1043           if (! member_init_ok_or_else (field, type, IDENTIFIER_POINTER (name)))
1044             return;
1045
1046           if (purpose_member (name, current_member_init_list))
1047             {
1048               cp_error ("field `%D' already initialized", field);
1049               return;
1050             }
1051
1052           member_init = build_tree_list (name, init);
1053           current_member_init_list = chainon (current_member_init_list, member_init);
1054         }
1055       return;
1056     }
1057   else if (name == NULL_TREE)
1058     {
1059       compiler_error ("expand_member_init: name == NULL_TREE");
1060       return;
1061     }
1062
1063   basetype = type;
1064   field = lookup_field (basetype, name, 0, 0);
1065
1066   if (! member_init_ok_or_else (field, basetype, IDENTIFIER_POINTER (name)))
1067     return;
1068
1069   /* now see if there is a constructor for this type
1070      which will take these args.  */
1071
1072   if (TYPE_HAS_CONSTRUCTOR (TREE_TYPE (field)))
1073     {
1074       tree parmtypes, fndecl;
1075
1076       if (TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == PARM_DECL)
1077         {
1078           /* just know that we've seen something for this node */
1079           DECL_INITIAL (exp) = error_mark_node;
1080           TREE_USED (exp) = 1;
1081         }
1082       type = TYPE_MAIN_VARIANT (TREE_TYPE (field));
1083       parm = build_component_ref (exp, name, NULL_TREE, 0);
1084
1085       /* Now get to the constructors.  */
1086       fndecl = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 0);
1087
1088       if (fndecl)
1089         my_friendly_assert (TREE_CODE (fndecl) == FUNCTION_DECL, 209);
1090
1091       /* If the field is unique, we can use the parameter
1092          types to guide possible type instantiation.  */
1093       if (DECL_CHAIN (fndecl) == NULL_TREE)
1094         {
1095           /* There was a confusion here between
1096              FIELD and FNDECL.  The following code
1097              should be correct, but abort is here
1098              to make sure.  */
1099           my_friendly_abort (48);
1100           parmtypes = FUNCTION_ARG_CHAIN (fndecl);
1101         }
1102       else
1103         {
1104           parmtypes = NULL_TREE;
1105           fndecl = NULL_TREE;
1106         }
1107
1108       init = convert_arguments (parm, parmtypes, NULL_TREE, fndecl, LOOKUP_NORMAL);
1109       if (init == NULL_TREE || TREE_TYPE (init) != error_mark_node)
1110         rval = build_method_call (NULL_TREE, ctor_identifier, init,
1111                                   TYPE_BINFO (type), LOOKUP_NORMAL);
1112       else
1113         return;
1114
1115       if (rval != error_mark_node)
1116         {
1117           /* Now, fill in the first parm with our guy */
1118           TREE_VALUE (TREE_OPERAND (rval, 1))
1119             = build_unary_op (ADDR_EXPR, parm, 0);
1120           TREE_TYPE (rval) = ptr_type_node;
1121           TREE_SIDE_EFFECTS (rval) = 1;
1122         }
1123     }
1124   else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (field)))
1125     {
1126       parm = build_component_ref (exp, name, NULL_TREE, 0);
1127       expand_aggr_init (parm, NULL_TREE, 0, 0);
1128       rval = error_mark_node;
1129     }
1130
1131   /* Now initialize the member.  It does not have to
1132      be of aggregate type to receive initialization.  */
1133   if (rval != error_mark_node)
1134     expand_expr_stmt (rval);
1135 }
1136
1137 /* This is like `expand_member_init', only it stores one aggregate
1138    value into another.
1139
1140    INIT comes in two flavors: it is either a value which
1141    is to be stored in EXP, or it is a parameter list
1142    to go to a constructor, which will operate on EXP.
1143    If INIT is not a parameter list for a constructor, then set
1144    LOOKUP_ONLYCONVERTING.
1145    If FLAGS is LOOKUP_ONLYCONVERTING then it is the = init form of
1146    the initializer, if FLAGS is 0, then it is the (init) form.
1147    If `init' is a CONSTRUCTOR, then we emit a warning message,
1148    explaining that such initializations are invalid.
1149
1150    ALIAS_THIS is nonzero iff we are initializing something which is
1151    essentially an alias for current_class_ref.  In this case, the base
1152    constructor may move it on us, and we must keep track of such
1153    deviations.
1154
1155    If INIT resolves to a CALL_EXPR which happens to return
1156    something of the type we are looking for, then we know
1157    that we can safely use that call to perform the
1158    initialization.
1159
1160    The virtual function table pointer cannot be set up here, because
1161    we do not really know its type.
1162
1163    Virtual baseclass pointers are also set up here.
1164
1165    This never calls operator=().
1166
1167    When initializing, nothing is CONST.
1168
1169    A default copy constructor may have to be used to perform the
1170    initialization.
1171
1172    A constructor or a conversion operator may have to be used to
1173    perform the initialization, but not both, as it would be ambiguous.  */
1174
1175 void
1176 expand_aggr_init (exp, init, alias_this, flags)
1177      tree exp, init;
1178      int alias_this;
1179      int flags;
1180 {
1181   tree type = TREE_TYPE (exp);
1182   int was_const = TREE_READONLY (exp);
1183   int was_volatile = TREE_THIS_VOLATILE (exp);
1184
1185   if (init == error_mark_node)
1186     return;
1187
1188   TREE_READONLY (exp) = 0;
1189   TREE_THIS_VOLATILE (exp) = 0;
1190
1191   if (init && TREE_CODE (init) != TREE_LIST)
1192     flags |= LOOKUP_ONLYCONVERTING;
1193
1194   if (TREE_CODE (type) == ARRAY_TYPE)
1195     {
1196       /* Must arrange to initialize each element of EXP
1197          from elements of INIT.  */
1198       tree itype = init ? TREE_TYPE (init) : NULL_TREE;
1199       if (TYPE_READONLY (TREE_TYPE (type)) || TYPE_VOLATILE (TREE_TYPE (type)))
1200         {
1201           TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type);
1202           if (init)
1203             TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype);
1204         }
1205       if (init && TREE_TYPE (init) == NULL_TREE)
1206         {
1207           /* Handle bad initializers like:
1208              class COMPLEX {
1209              public:
1210                double re, im;
1211                COMPLEX(double r = 0.0, double i = 0.0) {re = r; im = i;};
1212                ~COMPLEX() {};
1213              };
1214
1215              int main(int argc, char **argv) {
1216                COMPLEX zees(1.0, 0.0)[10];
1217              }
1218           */
1219           error ("bad array initializer");
1220           return;
1221         }
1222       expand_vec_init (exp, exp, array_type_nelts (type), init,
1223                        init && comptypes (TREE_TYPE (init), TREE_TYPE (exp), 1));
1224       TREE_READONLY (exp) = was_const;
1225       TREE_THIS_VOLATILE (exp) = was_volatile;
1226       TREE_TYPE (exp) = type;
1227       if (init)
1228         TREE_TYPE (init) = itype;
1229       return;
1230     }
1231
1232   if (TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == PARM_DECL)
1233     /* just know that we've seen something for this node */
1234     TREE_USED (exp) = 1;
1235
1236 #if 0
1237   /* If initializing from a GNU C CONSTRUCTOR, consider the elts in the
1238      constructor as parameters to an implicit GNU C++ constructor.  */
1239   if (init && TREE_CODE (init) == CONSTRUCTOR
1240       && TYPE_HAS_CONSTRUCTOR (type)
1241       && TREE_TYPE (init) == type)
1242     init = CONSTRUCTOR_ELTS (init);
1243 #endif
1244
1245   TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type);
1246   expand_aggr_init_1 (TYPE_BINFO (type), exp, exp,
1247                       init, alias_this, LOOKUP_NORMAL|flags);
1248   TREE_TYPE (exp) = type;
1249   TREE_READONLY (exp) = was_const;
1250   TREE_THIS_VOLATILE (exp) = was_volatile;
1251 }
1252
1253 static void
1254 expand_default_init (binfo, true_exp, exp, init, alias_this, flags)
1255      tree binfo;
1256      tree true_exp, exp;
1257      tree init;
1258      int alias_this;
1259      int flags;
1260 {
1261   tree type = TREE_TYPE (exp);
1262
1263   /* It fails because there may not be a constructor which takes
1264      its own type as the first (or only parameter), but which does
1265      take other types via a conversion.  So, if the thing initializing
1266      the expression is a unit element of type X, first try X(X&),
1267      followed by initialization by X.  If neither of these work
1268      out, then look hard.  */
1269   tree rval;
1270   tree parms;
1271
1272   if (init == NULL_TREE
1273       || (TREE_CODE (init) == TREE_LIST && ! TREE_TYPE (init)))
1274     {
1275       parms = init;
1276       if (parms)
1277         init = TREE_VALUE (parms);
1278     }
1279   else if (TREE_CODE (init) == INDIRECT_REF && TREE_HAS_CONSTRUCTOR (init)
1280            && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (init)))
1281     {
1282       rval = convert_for_initialization (exp, type, init, 0, 0, 0, 0);
1283       TREE_USED (rval) = 1;
1284       expand_expr_stmt (rval);
1285       return;
1286     }
1287   else
1288     parms = build_tree_list (NULL_TREE, init);
1289
1290   if (TYPE_USES_VIRTUAL_BASECLASSES (type))
1291     {
1292       if (true_exp == exp)
1293         parms = tree_cons (NULL_TREE, integer_one_node, parms);
1294       else
1295         parms = tree_cons (NULL_TREE, integer_zero_node, parms);
1296       flags |= LOOKUP_HAS_IN_CHARGE;
1297     }
1298
1299   if (init && TREE_CHAIN (parms) == NULL_TREE
1300       && TYPE_HAS_TRIVIAL_INIT_REF (type)
1301       && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (init)))
1302     {
1303       rval = build (INIT_EXPR, type, exp, init);
1304       TREE_SIDE_EFFECTS (rval) = 1;
1305       expand_expr_stmt (rval);
1306     }
1307   else
1308     {
1309       if (flags & LOOKUP_ONLYCONVERTING)
1310         flags |= LOOKUP_NO_CONVERSION;
1311       rval = build_method_call (exp, ctor_identifier,
1312                                 parms, binfo, flags);
1313
1314       /* Private, protected, or otherwise unavailable.  */
1315       if (rval == error_mark_node)
1316         {
1317           if (flags & LOOKUP_COMPLAIN)
1318             cp_error ("in base initialization for %sclass `%T'",
1319                       TREE_VIA_VIRTUAL (binfo) ? "virtual base " : "",
1320                       binfo);
1321         }
1322       else if (rval == NULL_TREE)
1323         my_friendly_abort (361);
1324       else
1325         {
1326           /* p. 222: if the base class assigns to `this', then that
1327              value is used in the derived class.  */
1328           if ((flag_this_is_variable & 1) && alias_this)
1329             {
1330               TREE_TYPE (rval) = TREE_TYPE (current_class_ptr);
1331               expand_assignment (current_class_ptr, rval, 0, 0);
1332             }
1333           else
1334             expand_expr_stmt (rval);
1335         }
1336     }
1337 }
1338
1339 /* This function is responsible for initializing EXP with INIT
1340    (if any).
1341
1342    BINFO is the binfo of the type for who we are performing the
1343    initialization.  For example, if W is a virtual base class of A and B,
1344    and C : A, B.
1345    If we are initializing B, then W must contain B's W vtable, whereas
1346    were we initializing C, W must contain C's W vtable.
1347
1348    TRUE_EXP is nonzero if it is the true expression being initialized.
1349    In this case, it may be EXP, or may just contain EXP.  The reason we
1350    need this is because if EXP is a base element of TRUE_EXP, we
1351    don't necessarily know by looking at EXP where its virtual
1352    baseclass fields should really be pointing.  But we do know
1353    from TRUE_EXP.  In constructors, we don't know anything about
1354    the value being initialized.
1355
1356    ALIAS_THIS serves the same purpose it serves for expand_aggr_init.
1357
1358    FLAGS is just passes to `build_method_call'.  See that function for
1359    its description.  */
1360
1361 static void
1362 expand_aggr_init_1 (binfo, true_exp, exp, init, alias_this, flags)
1363      tree binfo;
1364      tree true_exp, exp;
1365      tree init;
1366      int alias_this;
1367      int flags;
1368 {
1369   tree type = TREE_TYPE (exp);
1370   tree init_type = NULL_TREE;
1371
1372   my_friendly_assert (init != error_mark_node && type != error_mark_node, 211);
1373
1374   /* Use a function returning the desired type to initialize EXP for us.
1375      If the function is a constructor, and its first argument is
1376      NULL_TREE, know that it was meant for us--just slide exp on
1377      in and expand the constructor.  Constructors now come
1378      as TARGET_EXPRs.  */
1379   if (init)
1380     {
1381       tree init_list = NULL_TREE;
1382
1383       if (TREE_CODE (init) == TREE_LIST)
1384         {
1385           init_list = init;
1386           if (TREE_CHAIN (init) == NULL_TREE)
1387             init = TREE_VALUE (init);
1388         }
1389
1390       init_type = TREE_TYPE (init);
1391
1392       if (TREE_CODE (init) != TREE_LIST)
1393         {
1394           if (TREE_CODE (init_type) == ERROR_MARK)
1395             return;
1396
1397           /* This happens when we use C++'s functional cast notation.
1398              If the types match, then just use the TARGET_EXPR
1399              directly.  Otherwise, we need to create the initializer
1400              separately from the object being initialized.  */
1401           if (TREE_CODE (init) == TARGET_EXPR)
1402             {
1403               if (TYPE_MAIN_VARIANT (init_type) == TYPE_MAIN_VARIANT (type))
1404                 {
1405                   if (TREE_CODE (exp) == VAR_DECL
1406                       || TREE_CODE (exp) == RESULT_DECL)
1407                     /* Unify the initialization targets.  */
1408                     DECL_RTL (TREE_OPERAND (init, 0)) = DECL_RTL (exp);
1409                   else
1410                     DECL_RTL (TREE_OPERAND (init, 0)) = expand_expr (exp, NULL_RTX, VOIDmode, 0);
1411
1412                   expand_expr_stmt (init);
1413                   return;
1414                 }
1415             }
1416
1417           if (init_type == type && TREE_CODE (init) == CALL_EXPR)
1418             {
1419               /* A CALL_EXPR is a legitimate form of initialization, so
1420                  we should not print this warning message.  */
1421
1422               expand_assignment (exp, init, 0, 0);
1423               if (exp == DECL_RESULT (current_function_decl))
1424                 {
1425                   /* Failing this assertion means that the return value
1426                      from receives multiple initializations.  */
1427                   my_friendly_assert (DECL_INITIAL (exp) == NULL_TREE
1428                                       || DECL_INITIAL (exp) == error_mark_node,
1429                                       212);
1430                   DECL_INITIAL (exp) = init;
1431                 }
1432               return;
1433             }
1434           else if (init_type == type
1435                    && TREE_CODE (init) == COND_EXPR)
1436             {
1437               /* Push value to be initialized into the cond, where possible.
1438                  Avoid spurious warning messages when initializing the
1439                  result of this function.  */
1440               TREE_OPERAND (init, 1)
1441                 = build_modify_expr (exp, INIT_EXPR, TREE_OPERAND (init, 1));
1442               if (exp == DECL_RESULT (current_function_decl))
1443                 DECL_INITIAL (exp) = NULL_TREE;
1444               TREE_OPERAND (init, 2)
1445                 = build_modify_expr (exp, INIT_EXPR, TREE_OPERAND (init, 2));
1446               if (exp == DECL_RESULT (current_function_decl))
1447                 DECL_INITIAL (exp) = init;
1448               TREE_SIDE_EFFECTS (init) = 1;
1449               expand_expr (init, const0_rtx, VOIDmode, 0);
1450               free_temp_slots ();
1451               return;
1452             }
1453         }
1454
1455       /* We did not know what we were initializing before.  Now we do.  */
1456       if (TREE_CODE (init) == TARGET_EXPR)
1457         {
1458           tree tmp = TREE_OPERAND (TREE_OPERAND (init, 1), 1);
1459
1460           if (TREE_CODE (TREE_VALUE (tmp)) == NOP_EXPR
1461               && TREE_OPERAND (TREE_VALUE (tmp), 0) == integer_zero_node)
1462             {
1463               /* In order for this to work for RESULT_DECLs, if their
1464                  type has a constructor, then they must be BLKmode
1465                  so that they will be meaningfully addressable.  */
1466               tree arg = build_unary_op (ADDR_EXPR, exp, 0);
1467               init = TREE_OPERAND (init, 1);
1468               init = build (CALL_EXPR, build_pointer_type (TREE_TYPE (init)),
1469                             TREE_OPERAND (init, 0), TREE_OPERAND (init, 1), NULL_TREE);
1470               TREE_SIDE_EFFECTS (init) = 1;
1471               TREE_VALUE (TREE_OPERAND (init, 1))
1472                 = convert_pointer_to (TREE_TYPE (TREE_TYPE (TREE_VALUE (tmp))), arg);
1473
1474               if (alias_this)
1475                 {
1476                   expand_assignment (current_function_decl, init, 0, 0);
1477                   return;
1478                 }
1479               if (exp == DECL_RESULT (current_function_decl))
1480                 {
1481                   if (DECL_INITIAL (DECL_RESULT (current_function_decl)))
1482                     fatal ("return value from function receives multiple initializations");
1483                   DECL_INITIAL (exp) = init;
1484                 }
1485               expand_expr_stmt (init);
1486               return;
1487             }
1488         }
1489
1490       if (TREE_CODE (exp) == VAR_DECL
1491           && TREE_CODE (init) == CONSTRUCTOR
1492           && TREE_HAS_CONSTRUCTOR (init))
1493         {
1494           tree t = store_init_value (exp, init);
1495           if (!t)
1496             {
1497               expand_decl_init (exp);
1498               return;
1499             }
1500           t = build (INIT_EXPR, type, exp, init);
1501           TREE_SIDE_EFFECTS (t) = 1;
1502           expand_expr_stmt (t);
1503           return;
1504         }
1505
1506       /* Handle this case: when calling a constructor: xyzzy foo(bar);
1507          which really means:  xyzzy foo = bar; Ugh!
1508
1509          More useful for this case: xyzzy *foo = new xyzzy (bar);  */
1510
1511       if (! TYPE_NEEDS_CONSTRUCTING (type) && ! IS_AGGR_TYPE (type))
1512         {
1513           if (init_list && TREE_CHAIN (init_list))
1514             {
1515               warning ("initializer list being treated as compound expression");
1516               init = convert (type, build_compound_expr (init_list));
1517               if (init == error_mark_node)
1518                 return;
1519             }
1520
1521           expand_assignment (exp, init, 0, 0);
1522
1523           return;
1524         }
1525
1526       /* If this is copy-initialization, see whether we can go through a
1527          type conversion operator.  */
1528       if (TREE_CODE (init) != TREE_LIST && (flags & LOOKUP_ONLYCONVERTING))
1529         {
1530           tree ttype = TREE_CODE (init_type) == REFERENCE_TYPE
1531             ? TREE_TYPE (init_type) : init_type;
1532
1533           if (ttype != type && IS_AGGR_TYPE (ttype))
1534             {
1535               tree rval = build_type_conversion (CONVERT_EXPR, type, init, 1);
1536
1537               if (flag_ansi_overloading && rval)
1538                 {
1539                   if (rval != error_mark_node)
1540                     expand_aggr_init_1 (binfo, true_exp, exp, rval, alias_this, flags);
1541                   return;
1542                 }
1543               else if (rval)
1544                 {
1545                   /* See if there is a constructor for``type'' that takes a
1546                      ``ttype''-typed object.  */
1547                   tree parms = build_tree_list (NULL_TREE, init);
1548                   tree as_cons = NULL_TREE;
1549                   if (TYPE_HAS_CONSTRUCTOR (type))
1550                     as_cons = build_method_call (exp, ctor_identifier,
1551                                                  parms, binfo,
1552                                                  LOOKUP_SPECULATIVELY|LOOKUP_NO_CONVERSION);
1553                   if (as_cons != NULL_TREE && as_cons != error_mark_node)
1554                     /* ANSI C++ June 5 1992 WP 12.3.2.6.1 */
1555                     cp_error ("ambiguity between conversion to `%T' and constructor",
1556                               type);
1557                   else
1558                     if (rval != error_mark_node)
1559                       expand_aggr_init_1 (binfo, true_exp, exp, rval, alias_this, flags);
1560                   return;
1561                 }
1562             }
1563         }
1564     }
1565
1566   /* We know that expand_default_init can handle everything we want
1567      at this point.  */
1568   expand_default_init (binfo, true_exp, exp, init, alias_this, flags);
1569 }
1570
1571 /* Report an error if NAME is not the name of a user-defined,
1572    aggregate type.  If OR_ELSE is nonzero, give an error message.  */
1573
1574 int
1575 is_aggr_typedef (name, or_else)
1576      tree name;
1577      int or_else;
1578 {
1579   tree type;
1580
1581   if (name == error_mark_node)
1582     return 0;
1583
1584   if (IDENTIFIER_HAS_TYPE_VALUE (name))
1585     type = IDENTIFIER_TYPE_VALUE (name);
1586   else
1587     {
1588       if (or_else)
1589         cp_error ("`%T' is not an aggregate typedef", name);
1590       return 0;
1591     }
1592
1593   if (! IS_AGGR_TYPE (type)
1594       && TREE_CODE (type) != TEMPLATE_TYPE_PARM)
1595     {
1596       if (or_else)
1597         cp_error ("`%T' is not an aggregate type", type);
1598       return 0;
1599     }
1600   return 1;
1601 }
1602
1603 /* Report an error if TYPE is not a user-defined, aggregate type.  If
1604    OR_ELSE is nonzero, give an error message.  */
1605
1606 int
1607 is_aggr_type (type, or_else)
1608      tree type;
1609      int or_else;
1610 {
1611   if (type == error_mark_node)
1612     return 0;
1613
1614   if (! IS_AGGR_TYPE (type)
1615       && TREE_CODE (type) != TEMPLATE_TYPE_PARM)
1616     {
1617       if (or_else)
1618         cp_error ("`%T' is not an aggregate type", type);
1619       return 0;
1620     }
1621   return 1;
1622 }
1623
1624 /* Like is_aggr_typedef, but returns typedef if successful.  */
1625
1626 tree
1627 get_aggr_from_typedef (name, or_else)
1628      tree name;
1629      int or_else;
1630 {
1631   tree type;
1632
1633   if (name == error_mark_node)
1634     return NULL_TREE;
1635
1636   if (IDENTIFIER_HAS_TYPE_VALUE (name))
1637     type = IDENTIFIER_TYPE_VALUE (name);
1638   else
1639     {
1640       if (or_else)
1641         cp_error ("`%T' fails to be an aggregate typedef", name);
1642       return NULL_TREE;
1643     }
1644
1645   if (! IS_AGGR_TYPE (type)
1646       && TREE_CODE (type) != TEMPLATE_TYPE_PARM)
1647     {
1648       if (or_else)
1649         cp_error ("type `%T' is of non-aggregate type", type);
1650       return NULL_TREE;
1651     }
1652   return type;
1653 }
1654
1655 tree
1656 get_type_value (name)
1657      tree name;
1658 {
1659   if (name == error_mark_node)
1660     return NULL_TREE;
1661
1662   if (IDENTIFIER_HAS_TYPE_VALUE (name))
1663     return IDENTIFIER_TYPE_VALUE (name);
1664   else
1665     return NULL_TREE;
1666 }
1667   
1668 \f
1669 /* This code could just as well go in `class.c', but is placed here for
1670    modularity.  */
1671
1672 /* For an expression of the form TYPE :: NAME (PARMLIST), build
1673    the appropriate function call.  */
1674
1675 tree
1676 build_member_call (type, name, parmlist)
1677      tree type, name, parmlist;
1678 {
1679   tree t;
1680   tree method_name = name;
1681   int dtor = 0;
1682   int dont_use_this = 0;
1683   tree basetype_path, decl;
1684
1685   if (TREE_CODE (method_name) == BIT_NOT_EXPR)
1686     {
1687       method_name = TREE_OPERAND (method_name, 0);
1688       dtor = 1;
1689     }
1690
1691   /* This shouldn't be here, and build_member_call shouldn't appear in
1692      parse.y!  (mrs)  */
1693   if (type && TREE_CODE (type) == IDENTIFIER_NODE
1694       && get_aggr_from_typedef (type, 0) == 0)
1695     {
1696       tree ns = lookup_name (type, 0);
1697       if (ns && TREE_CODE (ns) == NAMESPACE_DECL)
1698         {
1699           return build_x_function_call (build_offset_ref (type, name), parmlist, current_class_ref);
1700         }
1701     }
1702
1703   if (type == NULL_TREE || ! is_aggr_type (type, 1))
1704     return error_mark_node;
1705
1706   /* An operator we did not like.  */
1707   if (name == NULL_TREE)
1708     return error_mark_node;
1709
1710   if (dtor)
1711     {
1712       cp_error ("cannot call destructor `%T::~%T' without object", type,
1713                 method_name);
1714       return error_mark_node;
1715     }
1716
1717   /* No object?  Then just fake one up, and let build_method_call
1718      figure out what to do.  */
1719   if (current_class_type == 0
1720       || get_base_distance (type, current_class_type, 0, &basetype_path) == -1)
1721     dont_use_this = 1;
1722
1723   if (dont_use_this)
1724     {
1725       basetype_path = TYPE_BINFO (type);
1726       decl = build1 (NOP_EXPR, build_pointer_type (type), error_mark_node);
1727     }
1728   else if (current_class_ptr == 0)
1729     {
1730       dont_use_this = 1;
1731       decl = build1 (NOP_EXPR, build_pointer_type (type), error_mark_node);
1732     }
1733   else
1734     {
1735       tree olddecl = current_class_ptr;
1736       tree oldtype = TREE_TYPE (TREE_TYPE (olddecl));
1737       if (oldtype != type)
1738         {
1739           tree newtype = build_type_variant (type, TYPE_READONLY (oldtype),
1740                                              TYPE_VOLATILE (oldtype));
1741           decl = convert_force (build_pointer_type (newtype), olddecl, 0);
1742         }
1743       else
1744         decl = olddecl;
1745     }
1746
1747   decl = build_indirect_ref (decl, NULL_PTR);
1748
1749   if (method_name == constructor_name (type)
1750       || method_name == constructor_name_full (type))
1751     return build_functional_cast (type, parmlist);
1752   if (t = lookup_fnfields (basetype_path, method_name, 0))
1753     return build_method_call (decl, method_name, parmlist, basetype_path,
1754                               LOOKUP_NORMAL|LOOKUP_NONVIRTUAL);
1755   if (TREE_CODE (name) == IDENTIFIER_NODE
1756       && ((t = lookup_field (TYPE_BINFO (type), name, 1, 0))))
1757     {
1758       if (t == error_mark_node)
1759         return error_mark_node;
1760       if (TREE_CODE (t) == FIELD_DECL)
1761         {
1762           if (dont_use_this)
1763             {
1764               cp_error ("invalid use of non-static field `%D'", t);
1765               return error_mark_node;
1766             }
1767           decl = build (COMPONENT_REF, TREE_TYPE (t), decl, t);
1768         }
1769       else if (TREE_CODE (t) == VAR_DECL)
1770         decl = t;
1771       else
1772         {
1773           cp_error ("invalid use of member `%D'", t);
1774           return error_mark_node;
1775         }
1776       if (TYPE_LANG_SPECIFIC (TREE_TYPE (decl))
1777           && TYPE_OVERLOADS_CALL_EXPR (TREE_TYPE (decl)))
1778         return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, decl, parmlist, NULL_TREE);
1779       return build_function_call (decl, parmlist);
1780     }
1781   else
1782     {
1783       cp_error ("no method `%T::%D'", type, name);
1784       return error_mark_node;
1785     }
1786 }
1787
1788 /* Build a reference to a member of an aggregate.  This is not a
1789    C++ `&', but really something which can have its address taken,
1790    and then act as a pointer to member, for example TYPE :: FIELD
1791    can have its address taken by saying & TYPE :: FIELD.
1792
1793    @@ Prints out lousy diagnostics for operator <typename>
1794    @@ fields.
1795
1796    @@ This function should be rewritten and placed in search.c.  */
1797
1798 tree
1799 build_offset_ref (type, name)
1800      tree type, name;
1801 {
1802   tree decl, fnfields, fields, t = error_mark_node;
1803   tree basebinfo = NULL_TREE;
1804   int dtor = 0;
1805
1806   if (processing_template_decl)
1807     return build_min_nt (SCOPE_REF, type, name);
1808
1809   /* Handle namespace names fully here.  */
1810   if (TREE_CODE (type) == IDENTIFIER_NODE
1811       && get_aggr_from_typedef (type, 0) == 0)
1812     {
1813       tree ns = lookup_name (type, 0);
1814       tree val;
1815       if (ns && TREE_CODE (ns) == NAMESPACE_DECL)
1816         {
1817           val = lookup_namespace_name (ns, name);
1818           if (val)
1819             return val;
1820           cp_error ("namespace `%D' has no member named `%D'", ns, name);
1821           return error_mark_node;
1822         }
1823     }
1824
1825   if (type == NULL_TREE || ! is_aggr_type (type, 1))
1826     return error_mark_node;
1827
1828   if (TREE_CODE (name) == BIT_NOT_EXPR)
1829     {
1830       dtor = 1;
1831       name = TREE_OPERAND (name, 0);
1832     }
1833
1834   if (name == constructor_name_full (type))
1835     name = constructor_name (type);
1836
1837   if (TYPE_SIZE (complete_type (type)) == 0)
1838     {
1839       if (type == current_class_type)
1840         t = IDENTIFIER_CLASS_VALUE (name);
1841       else
1842         t = NULL_TREE;
1843       if (t == 0)
1844         {
1845           cp_error ("incomplete type `%T' does not have member `%D'", type,
1846                       name);
1847           return error_mark_node;
1848         }
1849       if (TREE_CODE (t) == TYPE_DECL || TREE_CODE (t) == VAR_DECL
1850           || TREE_CODE (t) == CONST_DECL)
1851         {
1852           mark_used (t);
1853           return t;
1854         }
1855       if (TREE_CODE (t) == FIELD_DECL)
1856         sorry ("use of member in incomplete aggregate type");
1857       else if (TREE_CODE (t) == FUNCTION_DECL)
1858         sorry ("use of member function in incomplete aggregate type");
1859       else
1860         my_friendly_abort (52);
1861       return error_mark_node;
1862     }
1863
1864   if (current_class_type == 0
1865       || get_base_distance (type, current_class_type, 0, &basebinfo) == -1)
1866     {
1867       basebinfo = TYPE_BINFO (type);
1868       decl = build1 (NOP_EXPR, type, error_mark_node);
1869     }
1870   else if (current_class_ptr == 0)
1871     decl = build1 (NOP_EXPR, type, error_mark_node);
1872   else
1873     decl = current_class_ref;
1874
1875   if (constructor_name (BINFO_TYPE (basebinfo)) == name)
1876     if (dtor)
1877       name = dtor_identifier;
1878     else
1879       name = ctor_identifier;
1880   else
1881     if (dtor)
1882       my_friendly_abort (999);
1883
1884     
1885   fnfields = lookup_fnfields (basebinfo, name, 1);
1886   fields = lookup_field (basebinfo, name, 0, 0);
1887
1888   if (fields == error_mark_node || fnfields == error_mark_node)
1889     return error_mark_node;
1890
1891   /* A lot of this logic is now handled in lookup_field and
1892      lookup_fnfield.  */
1893   if (fnfields)
1894     {
1895       extern int flag_save_memoized_contexts;
1896       basebinfo = TREE_PURPOSE (fnfields);
1897
1898       /* Go from the TREE_BASELINK to the member function info.  */
1899       t = TREE_VALUE (fnfields);
1900
1901       if (DECL_CHAIN (t) == NULL_TREE)
1902         {
1903           tree access;
1904
1905           /* unique functions are handled easily.  */
1906         unique:
1907           access = compute_access (basebinfo, t);
1908           if (access == access_protected_node)
1909             {
1910               cp_error_at ("member function `%#D' is protected", t);
1911               error ("in this context");
1912               return error_mark_node;
1913             }
1914           if (access == access_private_node)
1915             {
1916               cp_error_at ("member function `%#D' is private", t);
1917               error ("in this context");
1918               return error_mark_node;
1919             }
1920           mark_used (t);
1921           return build (OFFSET_REF, TREE_TYPE (t), decl, t);
1922         }
1923
1924       /* FNFIELDS is most likely allocated on the search_obstack,
1925          which will go away after this class scope.  If we need
1926          to save this value for later (either for memoization
1927          or for use as an initializer for a static variable), then
1928          do so here.
1929
1930          ??? The smart thing to do for the case of saving initializers
1931          is to resolve them before we're done with this scope.  */
1932       if (!TREE_PERMANENT (fnfields)
1933           && ((flag_save_memoized_contexts && global_bindings_p ())
1934               || ! allocation_temporary_p ()))
1935         fnfields = copy_list (fnfields);
1936
1937       t = build_tree_list (error_mark_node, fnfields);
1938       TREE_TYPE (t) = build_offset_type (type, unknown_type_node);
1939       return t;
1940     }
1941
1942   /* Now that we know we are looking for a field, see if we
1943      have access to that field.  Lookup_field will give us the
1944      error message.  */
1945
1946   t = lookup_field (basebinfo, name, 1, 0);
1947
1948   if (t == error_mark_node)
1949     return error_mark_node;
1950
1951   if (t == NULL_TREE)
1952     {
1953       cp_error ("`%D' is not a member of type `%T'", name, type);
1954       return error_mark_node;
1955     }
1956
1957   if (TREE_CODE (t) == TYPE_DECL)
1958     {
1959       TREE_USED (t) = 1;
1960       return t;
1961     }
1962   /* static class members and class-specific enum
1963      values can be returned without further ado.  */
1964   if (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == CONST_DECL)
1965     {
1966       mark_used (t);
1967       return t;
1968     }
1969
1970   if (TREE_CODE (t) == FIELD_DECL && DECL_BIT_FIELD (t))
1971     {
1972       cp_error ("illegal pointer to bit field `%D'", t);
1973       return error_mark_node;
1974     }
1975
1976   /* static class functions too.  */
1977   if (TREE_CODE (t) == FUNCTION_DECL
1978       && TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1979     my_friendly_abort (53);
1980
1981   /* In member functions, the form `type::name' is no longer
1982      equivalent to `this->type::name', at least not until
1983      resolve_offset_ref.  */
1984   return build (OFFSET_REF, build_offset_type (type, TREE_TYPE (t)), decl, t);
1985 }
1986
1987 /* If a OFFSET_REF made it through to here, then it did
1988    not have its address taken.  */
1989
1990 tree
1991 resolve_offset_ref (exp)
1992      tree exp;
1993 {
1994   tree type = TREE_TYPE (exp);
1995   tree base = NULL_TREE;
1996   tree member;
1997   tree basetype, addr;
1998
1999   if (TREE_CODE (exp) == TREE_LIST)
2000     return build_unary_op (ADDR_EXPR, exp, 0);
2001
2002   if (TREE_CODE (exp) == OFFSET_REF)
2003     {
2004       member = TREE_OPERAND (exp, 1);
2005       base = TREE_OPERAND (exp, 0);
2006     }
2007   else
2008     {
2009       my_friendly_assert (TREE_CODE (type) == OFFSET_TYPE, 214);
2010       if (TYPE_OFFSET_BASETYPE (type) != current_class_type)
2011         {
2012           error ("object missing in use of pointer-to-member construct");
2013           return error_mark_node;
2014         }
2015       member = exp;
2016       type = TREE_TYPE (type);
2017       base = current_class_ref;
2018     }
2019
2020   if ((TREE_CODE (member) == VAR_DECL
2021        && ! TYPE_PTRMEMFUNC_P (TREE_TYPE (member)))
2022       || TREE_CODE (TREE_TYPE (member)) == FUNCTION_TYPE
2023       || TREE_CODE (TREE_TYPE (member)) == METHOD_TYPE)
2024     {
2025       /* These were static members.  */
2026       if (mark_addressable (member) == 0)
2027         return error_mark_node;
2028       return member;
2029     }
2030
2031   /* Syntax error can cause a member which should
2032      have been seen as static to be grok'd as non-static.  */
2033   if (TREE_CODE (member) == FIELD_DECL && current_class_ref == NULL_TREE)
2034     {
2035       if (TREE_ADDRESSABLE (member) == 0)
2036         {
2037           cp_error_at ("member `%D' is non-static but referenced as a static member",
2038                        member);
2039           error ("at this point in file");
2040           TREE_ADDRESSABLE (member) = 1;
2041         }
2042       return error_mark_node;
2043     }
2044
2045   /* The first case is really just a reference to a member of `this'.  */
2046   if (TREE_CODE (member) == FIELD_DECL
2047       && (base == current_class_ref
2048           || (TREE_CODE (base) == NOP_EXPR
2049               && TREE_OPERAND (base, 0) == error_mark_node)))
2050     {
2051       tree basetype_path, access;
2052
2053       if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE)
2054         basetype = TYPE_OFFSET_BASETYPE (type);
2055       else
2056         basetype = DECL_CONTEXT (member);
2057
2058       base = current_class_ptr;
2059       
2060       if (get_base_distance (basetype, TREE_TYPE (TREE_TYPE (base)), 0, &basetype_path) < 0)
2061         {
2062           error_not_base_type (basetype, TREE_TYPE (TREE_TYPE (base)));
2063           return error_mark_node;
2064         }
2065       addr = convert_pointer_to (basetype, base);
2066       access = compute_access (basetype_path, member);
2067       if (access == access_public_node)
2068         return build (COMPONENT_REF, TREE_TYPE (member),
2069                       build_indirect_ref (addr, NULL_PTR), member);
2070       if (access == access_protected_node)
2071         {
2072           cp_error_at ("member `%D' is protected", member);
2073           error ("in this context");
2074           return error_mark_node;
2075         }
2076       if (access == access_private_node)
2077         {
2078           cp_error_at ("member `%D' is private", member);
2079           error ("in this context");
2080           return error_mark_node;
2081         }
2082       my_friendly_abort (55);
2083     }
2084
2085   /* Ensure that we have an object.  */
2086   if (TREE_CODE (base) == NOP_EXPR
2087       && TREE_OPERAND (base, 0) == error_mark_node)
2088     addr = error_mark_node;
2089   else
2090     {
2091       /* If this is a reference to a member function, then return the
2092          address of the member function (which may involve going
2093          through the object's vtable), otherwise, return an expression
2094          for the dereferenced pointer-to-member construct.  */
2095       addr = build_unary_op (ADDR_EXPR, base, 0);
2096     }
2097
2098   if (TREE_CODE (TREE_TYPE (member)) == OFFSET_TYPE)
2099     {
2100       if (addr == error_mark_node)
2101         {
2102           cp_error ("object missing in `%E'", exp);
2103           return error_mark_node;
2104         }
2105
2106       basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (member));
2107       addr = convert_pointer_to (basetype, addr);
2108       member = convert (ptrdiff_type_node,
2109                         build_unary_op (ADDR_EXPR, member, 0));
2110       
2111       /* Pointer to data mebers are offset by one, so that a null
2112          pointer with a real value of 0 is distinguishable from an
2113          offset of the first member of a structure.  */
2114       member = build_binary_op (MINUS_EXPR, member,
2115                                 convert (ptrdiff_type_node, integer_one_node),
2116                                 0);
2117
2118       return build1 (INDIRECT_REF, type,
2119                      build (PLUS_EXPR, build_pointer_type (type),
2120                             addr, member));
2121     }
2122   else if (TYPE_PTRMEMFUNC_P (TREE_TYPE (member)))
2123     {
2124       return get_member_function_from_ptrfunc (&addr, member);
2125     }
2126   my_friendly_abort (56);
2127   /* NOTREACHED */
2128   return NULL_TREE;
2129 }
2130
2131 /* Return either DECL or its known constant value (if it has one).  */
2132
2133 tree
2134 decl_constant_value (decl)
2135      tree decl;
2136 {
2137   if (! TREE_THIS_VOLATILE (decl)
2138 #if 0
2139       /* These may be necessary for C, but they break C++.  */
2140       ! TREE_PUBLIC (decl)
2141       /* Don't change a variable array bound or initial value to a constant
2142          in a place where a variable is invalid.  */
2143       && ! pedantic
2144 #endif /* 0 */
2145       && DECL_INITIAL (decl) != 0
2146       && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK
2147       /* This is invalid if initial value is not constant.
2148          If it has either a function call, a memory reference,
2149          or a variable, then re-evaluating it could give different results.  */
2150       && TREE_CONSTANT (DECL_INITIAL (decl))
2151       /* Check for cases where this is sub-optimal, even though valid.  */
2152       && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR
2153 #if 0
2154       /* We must allow this to work outside of functions so that
2155          static constants can be used for array sizes.  */
2156       && current_function_decl != 0
2157       && DECL_MODE (decl) != BLKmode
2158 #endif
2159       )
2160     return DECL_INITIAL (decl);
2161   return decl;
2162 }
2163 \f
2164 /* Friend handling routines.  */
2165 /* Friend data structures:
2166
2167    Lists of friend functions come from TYPE_DECL nodes.  Since all
2168    aggregate types are automatically typedef'd, these nodes are guaranteed
2169    to exist.
2170
2171    The TREE_PURPOSE of a friend list is the name of the friend,
2172    and its TREE_VALUE is another list.
2173
2174    For each element of that list, either the TREE_VALUE or the TREE_PURPOSE
2175    will be filled in, but not both.  The TREE_VALUE of that list is an
2176    individual function which is a friend.  The TREE_PURPOSE of that list
2177    indicates a type in which all functions by that name are friends.
2178
2179    Lists of friend classes come from _TYPE nodes.  Love that consistency
2180    thang.  */
2181
2182 int
2183 is_friend_type (type1, type2)
2184      tree type1, type2;
2185 {
2186   return is_friend (type1, type2);
2187 }
2188
2189 int
2190 is_friend (type, supplicant)
2191      tree type, supplicant;
2192 {
2193   int declp;
2194   register tree list;
2195
2196   if (supplicant == NULL_TREE || type == NULL_TREE)
2197     return 0;
2198
2199   declp = (TREE_CODE_CLASS (TREE_CODE (supplicant)) == 'd');
2200
2201   if (declp)
2202     /* It's a function decl.  */
2203     {
2204       tree list = DECL_FRIENDLIST (TYPE_NAME (type));
2205       tree name = DECL_NAME (supplicant);
2206       tree ctype;
2207
2208       if (DECL_FUNCTION_MEMBER_P (supplicant))
2209         ctype = DECL_CLASS_CONTEXT (supplicant);
2210       else
2211         ctype = NULL_TREE;
2212
2213       for (; list ; list = TREE_CHAIN (list))
2214         {
2215           if (name == TREE_PURPOSE (list))
2216             {
2217               tree friends = TREE_VALUE (list);
2218               for (; friends ; friends = TREE_CHAIN (friends))
2219                 {
2220                   if (ctype == TREE_PURPOSE (friends))
2221                     return 1;
2222                   if (comptypes (TREE_TYPE (supplicant),
2223                                  TREE_TYPE (TREE_VALUE (friends)), 1))
2224                     return 1;
2225                 }
2226               break;
2227             }
2228         }
2229     }
2230   else
2231     /* It's a type.  */
2232     {
2233       if (type == supplicant)
2234         return 1;
2235       
2236       list = CLASSTYPE_FRIEND_CLASSES (TREE_TYPE (TYPE_NAME (type)));
2237       for (; list ; list = TREE_CHAIN (list))
2238         if (supplicant == TREE_VALUE (list))
2239           return 1;
2240     }      
2241
2242   {
2243     tree context;
2244
2245     if (! declp)
2246       {
2247         /* Are we a nested or local class?  If so, we aren't friends
2248            with the CONTEXT.  */
2249         if (IS_AGGR_TYPE (supplicant))
2250           context = NULL_TREE;
2251         else
2252           context = DECL_CONTEXT (TYPE_NAME (supplicant));
2253       }
2254     else if (DECL_FUNCTION_MEMBER_P (supplicant))
2255       context = DECL_CLASS_CONTEXT (supplicant);
2256     else
2257       context = NULL_TREE;
2258
2259     if (context)
2260       return is_friend (type, context);
2261   }
2262
2263   return 0;
2264 }
2265
2266 /* Add a new friend to the friends of the aggregate type TYPE.
2267    DECL is the FUNCTION_DECL of the friend being added.  */
2268
2269 static void
2270 add_friend (type, decl)
2271      tree type, decl;
2272 {
2273   tree typedecl = TYPE_NAME (type);
2274   tree list = DECL_FRIENDLIST (typedecl);
2275   tree name = DECL_NAME (decl);
2276
2277   while (list)
2278     {
2279       if (name == TREE_PURPOSE (list))
2280         {
2281           tree friends = TREE_VALUE (list);
2282           for (; friends ; friends = TREE_CHAIN (friends))
2283             {
2284               if (decl == TREE_VALUE (friends))
2285                 {
2286                   cp_warning ("`%D' is already a friend of class `%T'",
2287                               decl, type);
2288                   cp_warning_at ("previous friend declaration of `%D'",
2289                                  TREE_VALUE (friends));
2290                   return;
2291                 }
2292             }
2293           TREE_VALUE (list) = tree_cons (error_mark_node, decl,
2294                                          TREE_VALUE (list));
2295           return;
2296         }
2297       list = TREE_CHAIN (list);
2298     }
2299   DECL_FRIENDLIST (typedecl)
2300     = tree_cons (DECL_NAME (decl), build_tree_list (error_mark_node, decl),
2301                  DECL_FRIENDLIST (typedecl));
2302   if (DECL_NAME (decl) == ansi_opname[(int) MODIFY_EXPR])
2303     {
2304       tree parmtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
2305       TYPE_HAS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1;
2306       if (parmtypes && TREE_CHAIN (parmtypes))
2307         {
2308           tree parmtype = TREE_VALUE (TREE_CHAIN (parmtypes));
2309           if (TREE_CODE (parmtype) == REFERENCE_TYPE
2310               && TREE_TYPE (parmtypes) == TREE_TYPE (typedecl))
2311             TYPE_HAS_ASSIGN_REF (TREE_TYPE (typedecl)) = 1;
2312         }
2313     }
2314 }
2315
2316 /* Declare that every member function NAME in FRIEND_TYPE
2317    (which may be NULL_TREE) is a friend of type TYPE.  */
2318
2319 static void
2320 add_friends (type, name, friend_type)
2321      tree type, name, friend_type;
2322 {
2323   tree typedecl = TYPE_NAME (type);
2324   tree list = DECL_FRIENDLIST (typedecl);
2325
2326   while (list)
2327     {
2328       if (name == TREE_PURPOSE (list))
2329         {
2330           tree friends = TREE_VALUE (list);
2331           while (friends && TREE_PURPOSE (friends) != friend_type)
2332             friends = TREE_CHAIN (friends);
2333           if (friends)
2334             if (friend_type)
2335               warning ("method `%s::%s' is already a friend of class",
2336                        TYPE_NAME_STRING (friend_type),
2337                        IDENTIFIER_POINTER (name));
2338             else
2339               warning ("function `%s' is already a friend of class `%s'",
2340                        IDENTIFIER_POINTER (name),
2341                        IDENTIFIER_POINTER (DECL_NAME (typedecl)));
2342           else
2343             TREE_VALUE (list) = tree_cons (friend_type, NULL_TREE,
2344                                            TREE_VALUE (list));
2345           return;
2346         }
2347       list = TREE_CHAIN (list);
2348     }
2349   DECL_FRIENDLIST (typedecl) =
2350     tree_cons (name,
2351                build_tree_list (friend_type, NULL_TREE),
2352                DECL_FRIENDLIST (typedecl));
2353   if (! strncmp (IDENTIFIER_POINTER (name),
2354                  IDENTIFIER_POINTER (ansi_opname[(int) MODIFY_EXPR]),
2355                  strlen (IDENTIFIER_POINTER (ansi_opname[(int) MODIFY_EXPR]))))
2356     {
2357       TYPE_HAS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1;
2358       sorry ("declaring \"friend operator =\" will not find \"operator = (X&)\" if it exists");
2359     }
2360 }
2361
2362 /* Make FRIEND_TYPE a friend class to TYPE.  If FRIEND_TYPE has already
2363    been defined, we make all of its member functions friends of
2364    TYPE.  If not, we make it a pending friend, which can later be added
2365    when its definition is seen.  If a type is defined, then its TYPE_DECL's
2366    DECL_UNDEFINED_FRIENDS contains a (possibly empty) list of friend
2367    classes that are not defined.  If a type has not yet been defined,
2368    then the DECL_WAITING_FRIENDS contains a list of types
2369    waiting to make it their friend.  Note that these two can both
2370    be in use at the same time!  */
2371
2372 void
2373 make_friend_class (type, friend_type)
2374      tree type, friend_type;
2375 {
2376   tree classes;
2377
2378   if (IS_SIGNATURE (type))
2379     {
2380       error ("`friend' declaration in signature definition");
2381       return;
2382     }
2383   if (IS_SIGNATURE (friend_type))
2384     {
2385       error ("signature type `%s' declared `friend'",
2386              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (friend_type))));
2387       return;
2388     }
2389   if (type == friend_type)
2390     {
2391       pedwarn ("class `%s' is implicitly friends with itself",
2392                TYPE_NAME_STRING (type));
2393       return;
2394     }
2395
2396   GNU_xref_hier (TYPE_NAME_STRING (type),
2397                  TYPE_NAME_STRING (friend_type), 0, 0, 1);
2398
2399   classes = CLASSTYPE_FRIEND_CLASSES (type);
2400   while (classes && TREE_VALUE (classes) != friend_type)
2401     classes = TREE_CHAIN (classes);
2402   if (classes)
2403     warning ("class `%s' is already friends with class `%s'",
2404              TYPE_NAME_STRING (TREE_VALUE (classes)), TYPE_NAME_STRING (type));
2405   else
2406     {
2407       CLASSTYPE_FRIEND_CLASSES (type)
2408         = tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type));
2409     }
2410 }
2411
2412 /* Main friend processor.  This is large, and for modularity purposes,
2413    has been removed from grokdeclarator.  It returns `void_type_node'
2414    to indicate that something happened, though a FIELD_DECL is
2415    not returned.
2416
2417    CTYPE is the class this friend belongs to.
2418
2419    DECLARATOR is the name of the friend.
2420
2421    DECL is the FUNCTION_DECL that the friend is.
2422
2423    In case we are parsing a friend which is part of an inline
2424    definition, we will need to store PARM_DECL chain that comes
2425    with it into the DECL_ARGUMENTS slot of the FUNCTION_DECL.
2426
2427    FLAGS is just used for `grokclassfn'.
2428
2429    QUALS say what special qualifies should apply to the object
2430    pointed to by `this'.  */
2431
2432 tree
2433 do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag)
2434      tree ctype, declarator, decl, parmdecls;
2435      enum overload_flags flags;
2436      tree quals;
2437      int funcdef_flag;
2438 {
2439   /* Every decl that gets here is a friend of something.  */
2440   DECL_FRIEND_P (decl) = 1;
2441
2442   if (ctype)
2443     {
2444       tree cname = TYPE_NAME (ctype);
2445       if (TREE_CODE (cname) == TYPE_DECL)
2446         cname = DECL_NAME (cname);
2447
2448       /* A method friend.  */
2449       if (TREE_CODE (decl) == FUNCTION_DECL)
2450         {
2451           if (flags == NO_SPECIAL && ctype && declarator == cname)
2452             DECL_CONSTRUCTOR_P (decl) = 1;
2453
2454           /* This will set up DECL_ARGUMENTS for us.  */
2455           grokclassfn (ctype, cname, decl, flags, quals);
2456           if (TYPE_SIZE (ctype) != 0)
2457             decl = check_classfn (ctype, decl);
2458
2459           if (TREE_TYPE (decl) != error_mark_node)
2460             {
2461               if (TYPE_SIZE (ctype))
2462                 add_friend (current_class_type, decl);
2463               else
2464                 {
2465                   cp_error ("member `%D' declared as friend before type `%T' defined",
2466                             decl, ctype);
2467                 }
2468             }
2469         }
2470       else
2471         {
2472           /* Possibly a bunch of method friends.  */
2473
2474           /* Get the class they belong to.  */
2475           tree ctype = IDENTIFIER_TYPE_VALUE (cname);
2476           tree fields = lookup_fnfields (TYPE_BINFO (ctype), declarator, 0);
2477
2478           if (fields)
2479             add_friends (current_class_type, declarator, ctype);
2480           else
2481             error ("method `%s' is not a member of class `%s'",
2482                    IDENTIFIER_POINTER (declarator),
2483                    IDENTIFIER_POINTER (cname));
2484           decl = void_type_node;
2485         }
2486     }
2487   else if (TREE_CODE (decl) == FUNCTION_DECL
2488            && ((IDENTIFIER_LENGTH (declarator) == 4
2489                 && IDENTIFIER_POINTER (declarator)[0] == 'm'
2490                 && ! strcmp (IDENTIFIER_POINTER (declarator), "main"))
2491                || (IDENTIFIER_LENGTH (declarator) > 10
2492                    && IDENTIFIER_POINTER (declarator)[0] == '_'
2493                    && IDENTIFIER_POINTER (declarator)[1] == '_'
2494                    && strncmp (IDENTIFIER_POINTER (declarator)+2,
2495                                "builtin_", 8) == 0)))
2496     {
2497       /* raw "main", and builtin functions never gets overloaded,
2498          but they can become friends.  */
2499       add_friend (current_class_type, decl);
2500       DECL_FRIEND_P (decl) = 1;
2501       decl = void_type_node;
2502     }
2503   /* A global friend.
2504      @@ or possibly a friend from a base class ?!?  */
2505   else if (TREE_CODE (decl) == FUNCTION_DECL)
2506     {
2507       /* Friends must all go through the overload machinery,
2508          even though they may not technically be overloaded.
2509
2510          Note that because classes all wind up being top-level
2511          in their scope, their friend wind up in top-level scope as well.  */
2512       DECL_ASSEMBLER_NAME (decl)
2513         = build_decl_overload (declarator, TYPE_ARG_TYPES (TREE_TYPE (decl)),
2514                                TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE);
2515       DECL_ARGUMENTS (decl) = parmdecls;
2516       if (funcdef_flag)
2517         DECL_CLASS_CONTEXT (decl) = current_class_type;
2518
2519       /* We can call pushdecl here, because the TREE_CHAIN of this
2520          FUNCTION_DECL is not needed for other purposes.  */
2521       decl = pushdecl (decl);
2522
2523       make_decl_rtl (decl, NULL_PTR, 1);
2524       add_friend (current_class_type, decl);
2525
2526       DECL_FRIEND_P (decl) = 1;
2527     }
2528   else
2529     {
2530       /* @@ Should be able to ingest later definitions of this function
2531          before use.  */
2532       tree decl = lookup_name_nonclass (declarator);
2533       if (decl == NULL_TREE)
2534         {
2535           warning ("implicitly declaring `%s' as struct",
2536                    IDENTIFIER_POINTER (declarator));
2537           decl = xref_tag (record_type_node, declarator, NULL_TREE, 1);
2538           decl = TYPE_NAME (decl);
2539         }
2540
2541       /* Allow abbreviated declarations of overloaded functions,
2542          but not if those functions are really class names.  */
2543       if (TREE_CODE (decl) == TREE_LIST && TREE_TYPE (TREE_PURPOSE (decl)))
2544         {
2545           warning ("`friend %s' archaic, use `friend class %s' instead",
2546                    IDENTIFIER_POINTER (declarator),
2547                    IDENTIFIER_POINTER (declarator));
2548           decl = TREE_TYPE (TREE_PURPOSE (decl));
2549         }
2550
2551       if (TREE_CODE (decl) == TREE_LIST)
2552         add_friends (current_class_type, TREE_PURPOSE (decl), NULL_TREE);
2553       else
2554         make_friend_class (current_class_type, TREE_TYPE (decl));
2555       decl = void_type_node;
2556     }
2557   return decl;
2558 }
2559 \f
2560 /* Common subroutines of build_new and build_vec_delete.  */
2561
2562 /* Common interface for calling "builtin" functions that are not
2563    really builtin.  */
2564
2565 tree
2566 build_builtin_call (type, node, arglist)
2567      tree type;
2568      tree node;
2569      tree arglist;
2570 {
2571   tree rval = build (CALL_EXPR, type, node, arglist, NULL_TREE);
2572   TREE_SIDE_EFFECTS (rval) = 1;
2573   assemble_external (TREE_OPERAND (node, 0));
2574   TREE_USED (TREE_OPERAND (node, 0)) = 1;
2575   return rval;
2576 }
2577 \f
2578 /* Generate a C++ "new" expression. DECL is either a TREE_LIST
2579    (which needs to go through some sort of groktypename) or it
2580    is the name of the class we are newing. INIT is an initialization value.
2581    It is either an EXPRLIST, an EXPR_NO_COMMAS, or something in braces.
2582    If INIT is void_type_node, it means do *not* call a constructor
2583    for this instance.
2584
2585    For types with constructors, the data returned is initialized
2586    by the appropriate constructor.
2587
2588    Whether the type has a constructor or not, if it has a pointer
2589    to a virtual function table, then that pointer is set up
2590    here.
2591
2592    Unless I am mistaken, a call to new () will return initialized
2593    data regardless of whether the constructor itself is private or
2594    not.  NOPE; new fails if the constructor is private (jcm).
2595
2596    Note that build_new does nothing to assure that any special
2597    alignment requirements of the type are met.  Rather, it leaves
2598    it up to malloc to do the right thing.  Otherwise, folding to
2599    the right alignment cal cause problems if the user tries to later
2600    free the memory returned by `new'.
2601
2602    PLACEMENT is the `placement' list for user-defined operator new ().  */
2603
2604 extern int flag_check_new;
2605
2606 tree
2607 build_new (placement, decl, init, use_global_new)
2608      tree placement;
2609      tree decl, init;
2610      int use_global_new;
2611 {
2612   tree type, true_type, size, rval;
2613   tree nelts;
2614   tree alloc_expr, alloc_temp;
2615   int has_array = 0;
2616   enum tree_code code = NEW_EXPR;
2617   int use_cookie;
2618
2619   tree pending_sizes = NULL_TREE;
2620
2621   if (decl == error_mark_node)
2622     return error_mark_node;
2623
2624   if (TREE_CODE (decl) == TREE_LIST)
2625     {
2626       tree absdcl = TREE_VALUE (decl);
2627       tree last_absdcl = NULL_TREE;
2628       int old_immediate_size_expand;
2629
2630       if (current_function_decl
2631           && DECL_CONSTRUCTOR_P (current_function_decl))
2632         {
2633           old_immediate_size_expand = immediate_size_expand;
2634           immediate_size_expand = 0;
2635         }
2636
2637       nelts = integer_one_node;
2638
2639       if (absdcl && TREE_CODE (absdcl) == CALL_EXPR)
2640         my_friendly_abort (215);
2641       while (absdcl && TREE_CODE (absdcl) == INDIRECT_REF)
2642         {
2643           last_absdcl = absdcl;
2644           absdcl = TREE_OPERAND (absdcl, 0);
2645         }
2646
2647       if (absdcl && TREE_CODE (absdcl) == ARRAY_REF)
2648         {
2649           /* probably meant to be a vec new */
2650           tree this_nelts;
2651
2652           while (TREE_OPERAND (absdcl, 0)
2653                  && TREE_CODE (TREE_OPERAND (absdcl, 0)) == ARRAY_REF)
2654             {
2655               last_absdcl = absdcl;
2656               absdcl = TREE_OPERAND (absdcl, 0);
2657             }
2658
2659           has_array = 1;
2660           this_nelts = TREE_OPERAND (absdcl, 1);
2661           if (this_nelts != error_mark_node)
2662             {
2663               if (this_nelts == NULL_TREE)
2664                 error ("new of array type fails to specify size");
2665               else if (processing_template_decl)
2666                 {
2667                   nelts = this_nelts;
2668                   absdcl = TREE_OPERAND (absdcl, 0);
2669                 }
2670               else
2671                 {
2672                   this_nelts = save_expr (convert (sizetype, this_nelts));
2673                   absdcl = TREE_OPERAND (absdcl, 0);
2674                   if (this_nelts == integer_zero_node)
2675                     {
2676                       warning ("zero size array reserves no space");
2677                       nelts = integer_zero_node;
2678                     }
2679                   else
2680                     nelts = build_binary_op (MULT_EXPR, nelts, this_nelts, 1);
2681                 }
2682             }
2683           else
2684             nelts = integer_zero_node;
2685         }
2686
2687       if (last_absdcl)
2688         TREE_OPERAND (last_absdcl, 0) = absdcl;
2689       else
2690         TREE_VALUE (decl) = absdcl;
2691
2692       type = true_type = groktypename (decl);
2693       if (! type || type == error_mark_node)
2694         {
2695           immediate_size_expand = old_immediate_size_expand;
2696           return error_mark_node;
2697         }
2698
2699       if (current_function_decl
2700           && DECL_CONSTRUCTOR_P (current_function_decl))
2701         {
2702           pending_sizes = get_pending_sizes ();
2703           immediate_size_expand = old_immediate_size_expand;
2704         }
2705     }
2706   else if (TREE_CODE (decl) == IDENTIFIER_NODE)
2707     {
2708       if (IDENTIFIER_HAS_TYPE_VALUE (decl))
2709         {
2710           /* An aggregate type.  */
2711           type = IDENTIFIER_TYPE_VALUE (decl);
2712           decl = TYPE_NAME (type);
2713         }
2714       else
2715         {
2716           /* A builtin type.  */
2717           decl = lookup_name (decl, 1);
2718           my_friendly_assert (TREE_CODE (decl) == TYPE_DECL, 215);
2719           type = TREE_TYPE (decl);
2720         }
2721       true_type = type;
2722     }
2723   else if (TREE_CODE (decl) == TYPE_DECL)
2724     {
2725       type = TREE_TYPE (decl);
2726       true_type = type;
2727     }
2728   else
2729     {
2730       type = decl;
2731       true_type = type;
2732       decl = TYPE_NAME (type);
2733     }
2734
2735   if (processing_template_decl)
2736     {
2737       tree t;
2738       if (has_array)
2739         t = min_tree_cons (min_tree_cons (NULL_TREE, type, NULL_TREE),
2740                            build_min_nt (ARRAY_REF, NULL_TREE, nelts),
2741                            NULL_TREE);
2742       else
2743         t = type;
2744         
2745       rval = build_min_nt (NEW_EXPR, placement, t, init);
2746       NEW_EXPR_USE_GLOBAL (rval) = use_global_new;
2747       return rval;
2748     }
2749
2750   /* ``A reference cannot be created by the new operator.  A reference
2751      is not an object (8.2.2, 8.4.3), so a pointer to it could not be
2752      returned by new.'' ARM 5.3.3 */
2753   if (TREE_CODE (type) == REFERENCE_TYPE)
2754     {
2755       error ("new cannot be applied to a reference type");
2756       type = true_type = TREE_TYPE (type);
2757     }
2758
2759   if (TREE_CODE (type) == FUNCTION_TYPE)
2760     {
2761       error ("new cannot be applied to a function type");
2762       return error_mark_node;
2763     }
2764
2765   /* When the object being created is an array, the new-expression yields a
2766      pointer to the initial element (if any) of the array.  For example,
2767      both new int and new int[10] return an int*.  5.3.4.  */
2768   if (TREE_CODE (type) == ARRAY_TYPE && has_array == 0)
2769     {
2770       nelts = array_type_nelts_top (type);
2771       has_array = 1;
2772       type = true_type = TREE_TYPE (type);
2773     }
2774
2775   if (TYPE_READONLY (type) || TYPE_VOLATILE (type))
2776     type = TYPE_MAIN_VARIANT (type);
2777
2778   /* If our base type is an array, then make sure we know how many elements
2779      it has.  */
2780   while (TREE_CODE (true_type) == ARRAY_TYPE)
2781     {
2782       tree this_nelts = array_type_nelts_top (true_type);
2783       nelts = build_binary_op (MULT_EXPR, nelts, this_nelts, 1);
2784       true_type = TREE_TYPE (true_type);
2785     }
2786
2787   if (TYPE_SIZE (complete_type (true_type)) == 0)
2788     {
2789       incomplete_type_error (0, true_type);
2790       return error_mark_node;
2791     }
2792
2793   if (has_array)
2794     size = fold (build_binary_op (MULT_EXPR, size_in_bytes (true_type),
2795                                   nelts, 1));
2796   else
2797     size = size_in_bytes (type);
2798
2799   if (true_type == void_type_node)
2800     {
2801       error ("invalid type `void' for new");
2802       return error_mark_node;
2803     }
2804
2805   if (TYPE_LANG_SPECIFIC (true_type)
2806       && CLASSTYPE_ABSTRACT_VIRTUALS (true_type))
2807     {
2808       abstract_virtuals_error (NULL_TREE, true_type);
2809       return error_mark_node;
2810     }
2811
2812   if (TYPE_LANG_SPECIFIC (true_type) && IS_SIGNATURE (true_type))
2813     {
2814       signature_error (NULL_TREE, true_type);
2815       return error_mark_node;
2816     }
2817
2818 #if 1
2819   /* Get a little extra space to store a couple of things before the new'ed
2820      array, if this isn't the default placement new.  */
2821
2822   use_cookie = (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type)
2823                 && ! (placement && ! TREE_CHAIN (placement)
2824                       && TREE_TYPE (TREE_VALUE (placement)) == ptr_type_node));
2825 #else
2826   /* Get a little extra space to store a couple of things before the new'ed
2827      array, if this is either non-placement new or new (nothrow).  */
2828   
2829   use_cookie = (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type)
2830                 && (! placement
2831                     || (IS_AGGR_TYPE (TREE_TYPE (placement))
2832                         && (TYPE_IDENTIFIER (TREE_TYPE (placement))
2833                             == get_identifier ("nothrow_t")))));
2834 #endif
2835
2836   if (use_cookie)
2837     {
2838       tree extra = BI_header_size;
2839
2840       size = size_binop (PLUS_EXPR, size, extra);
2841     }
2842
2843   if (has_array)
2844     {
2845       code = VEC_NEW_EXPR;
2846
2847       if (init && pedantic)
2848         cp_pedwarn ("initialization in array new");
2849     }
2850
2851   /* Allocate the object.  */
2852   if (! use_global_new && TYPE_LANG_SPECIFIC (true_type)
2853       && (TYPE_GETS_NEW (true_type) & (1 << has_array)))
2854     rval = build_opfncall (code, LOOKUP_NORMAL,
2855                            build_pointer_type (true_type), size, placement);
2856   else if (placement)
2857     {
2858       rval = build_opfncall (code, LOOKUP_GLOBAL|LOOKUP_COMPLAIN,
2859                              ptr_type_node, size, placement);
2860       rval = convert (build_pointer_type (true_type), rval);
2861     }
2862   else if (! has_array && flag_this_is_variable > 0
2863            && TYPE_NEEDS_CONSTRUCTING (true_type) && init != void_type_node)
2864     {
2865       if (init == NULL_TREE || TREE_CODE (init) == TREE_LIST)
2866         rval = NULL_TREE;
2867       else
2868         {
2869           error ("constructors take parameter lists");
2870           return error_mark_node;
2871         }
2872     }
2873   else
2874     {
2875       rval = build_builtin_call (build_pointer_type (true_type),
2876                                  has_array ? BIVN : BIN,
2877                                  build_tree_list (NULL_TREE, size));
2878       TREE_CALLS_NEW (rval) = 1;
2879     }
2880
2881   if (flag_check_new && rval)
2882     alloc_expr = rval = save_expr (rval);
2883   else
2884     alloc_expr = NULL_TREE;
2885
2886   /* if rval is NULL_TREE I don't have to allocate it, but are we totally
2887      sure we have some extra bytes in that case for the BI_header_size
2888      cookies? And how does that interact with the code below? (mrs) */
2889   /* Finish up some magic for new'ed arrays */
2890   if (use_cookie && rval != NULL_TREE)
2891     {
2892       tree extra = BI_header_size;
2893       tree cookie, exp1;
2894       rval = convert (ptr_type_node, rval);    /* convert to void * first */
2895       rval = convert (string_type_node, rval); /* lets not add void* and ints */
2896       rval = save_expr (build_binary_op (PLUS_EXPR, rval, extra, 1));
2897       /* Store header info.  */
2898       cookie = build_indirect_ref (build (MINUS_EXPR, build_pointer_type (BI_header_type),
2899                                           rval, extra), NULL_PTR);
2900       exp1 = build (MODIFY_EXPR, void_type_node,
2901                     build_component_ref (cookie, nc_nelts_field_id, NULL_TREE, 0),
2902                     nelts);
2903       TREE_SIDE_EFFECTS (exp1) = 1;
2904       rval = convert (build_pointer_type (true_type), rval);
2905       TREE_CALLS_NEW (rval) = 1;
2906       TREE_SIDE_EFFECTS (rval) = 1;
2907       rval = build_compound_expr (tree_cons (NULL_TREE, exp1,
2908                                              build_tree_list (NULL_TREE, rval)));
2909     }
2910
2911   if (rval == error_mark_node)
2912     return error_mark_node;
2913
2914   /* Don't call any constructors or do any initialization.  */
2915   if (init == void_type_node)
2916     goto done;
2917
2918   if (TYPE_NEEDS_CONSTRUCTING (type) || init)
2919     {
2920       if (! TYPE_NEEDS_CONSTRUCTING (type)
2921           && ! IS_AGGR_TYPE (type) && ! has_array)
2922         {
2923           /* New 2.0 interpretation: `new int (10)' means
2924              allocate an int, and initialize it with 10.  */
2925           tree deref;
2926
2927           rval = save_expr (rval);
2928           deref = build_indirect_ref (rval, NULL_PTR);
2929           TREE_READONLY (deref) = 0;
2930
2931           if (TREE_CHAIN (init) != NULL_TREE)
2932             pedwarn ("initializer list being treated as compound expression");
2933           else if (TREE_CODE (init) == CONSTRUCTOR)
2934             {
2935               pedwarn ("initializer list appears where operand should be used");
2936               init = TREE_OPERAND (init, 1);
2937             }
2938           init = build_compound_expr (init);
2939
2940           init = convert_for_initialization (deref, type, init, LOOKUP_NORMAL,
2941                                              "new", NULL_TREE, 0);
2942           rval = build (COMPOUND_EXPR, TREE_TYPE (rval),
2943                         build_modify_expr (deref, NOP_EXPR, init),
2944                         rval);
2945           TREE_NO_UNUSED_WARNING (rval) = 1;
2946           TREE_SIDE_EFFECTS (rval) = 1;
2947           TREE_CALLS_NEW (rval) = 1;
2948         }
2949       else if (! has_array)
2950         {
2951           tree newrval;
2952           /* Constructors are never virtual. If it has an initialization, we
2953              need to complain if we aren't allowed to use the ctor that took
2954              that argument.  */
2955           int flags = LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_COMPLAIN;
2956
2957           if (rval && TYPE_USES_VIRTUAL_BASECLASSES (true_type))
2958             {
2959               init = tree_cons (NULL_TREE, integer_one_node, init);
2960               flags |= LOOKUP_HAS_IN_CHARGE;
2961             }
2962
2963           newrval = rval;
2964
2965           if (newrval && TREE_CODE (TREE_TYPE (newrval)) == POINTER_TYPE)
2966             newrval = build_indirect_ref (newrval, NULL_PTR);
2967
2968           newrval = build_method_call (newrval, ctor_identifier,
2969                                        init, TYPE_BINFO (true_type), flags);
2970
2971           if (newrval)
2972             {
2973               rval = newrval;
2974               TREE_HAS_CONSTRUCTOR (rval) = 1;
2975             }
2976           else
2977             rval = error_mark_node;
2978         }
2979       else
2980         rval = build (VEC_INIT_EXPR, TREE_TYPE (rval),
2981                       save_expr (rval), init, nelts);
2982 #if 0   
2983       else if (current_function_decl == NULL_TREE)
2984         {
2985           extern tree static_aggregates;
2986
2987           /* In case of static initialization, SAVE_EXPR is good enough.  */
2988           rval = save_expr (rval);
2989           rval = copy_to_permanent (rval);
2990           init = copy_to_permanent (init);
2991           init = expand_vec_init (decl, rval,
2992                                   build_binary_op (MINUS_EXPR, nelts,
2993                                                    integer_one_node, 1),
2994                                   init, 0);
2995           init = copy_to_permanent (init);
2996           static_aggregates = perm_tree_cons (init, rval, static_aggregates);
2997         }
2998       else
2999         {
3000           /* Have to wrap this in RTL_EXPR for two cases:
3001              in base or member initialization and if we
3002              are a branch of a ?: operator.  Since we
3003              can't easily know the latter, just do it always.  */
3004           tree xval = make_node (RTL_EXPR);
3005
3006           /* If we want to check the value of the allocation expression,
3007              and the number of elements in the array is not a constant, we
3008              *must* expand the SAVE_EXPR for nelts in alloc_expr before we
3009              expand it in the actual initialization.  So we need to build up
3010              an RTL_EXPR for alloc_expr.  Sigh.  */
3011           if (alloc_expr && ! TREE_CONSTANT (nelts))
3012             {
3013               tree xval = make_node (RTL_EXPR);
3014               rtx rtxval;
3015               TREE_TYPE (xval) = TREE_TYPE (alloc_expr);
3016               do_pending_stack_adjust ();
3017               start_sequence_for_rtl_expr (xval);
3018               emit_note (0, -1);
3019               rtxval = expand_expr (alloc_expr, NULL_RTX, VOIDmode, 0);
3020               do_pending_stack_adjust ();
3021               TREE_SIDE_EFFECTS (xval) = 1;
3022               RTL_EXPR_SEQUENCE (xval) = get_insns ();
3023               end_sequence ();
3024               RTL_EXPR_RTL (xval) = rtxval;
3025               TREE_TYPE (xval) = TREE_TYPE (alloc_expr);
3026               alloc_expr = xval;
3027             }
3028
3029           TREE_TYPE (xval) = TREE_TYPE (rval);
3030           do_pending_stack_adjust ();
3031           start_sequence_for_rtl_expr (xval);
3032
3033           /* As a matter of principle, `start_sequence' should do this.  */
3034           emit_note (0, -1);
3035
3036           rval = save_expr (rval);
3037           rval = expand_vec_init (decl, rval,
3038                                   build_binary_op (MINUS_EXPR, nelts,
3039                                                    integer_one_node, 1),
3040                                   init, 0);
3041
3042           do_pending_stack_adjust ();
3043
3044           TREE_SIDE_EFFECTS (xval) = 1;
3045           TREE_CALLS_NEW (xval) = 1;
3046           RTL_EXPR_SEQUENCE (xval) = get_insns ();
3047           end_sequence ();
3048
3049           if (TREE_CODE (rval) == SAVE_EXPR)
3050             {
3051               /* Errors may cause this to not get evaluated.  */
3052               if (SAVE_EXPR_RTL (rval) == 0)
3053                 SAVE_EXPR_RTL (rval) = const0_rtx;
3054               RTL_EXPR_RTL (xval) = SAVE_EXPR_RTL (rval);
3055             }
3056           else
3057             {
3058               my_friendly_assert (TREE_CODE (rval) == VAR_DECL, 217);
3059               RTL_EXPR_RTL (xval) = DECL_RTL (rval);
3060             }
3061           rval = xval;
3062         }
3063 #endif
3064     }
3065   else if (TYPE_READONLY (true_type))
3066     cp_error ("uninitialized const in `new' of `%#T'", true_type);
3067
3068  done:
3069
3070   if (alloc_expr && rval != alloc_expr)
3071     {
3072       /* Did we modify the storage?  */
3073       tree ifexp = build_binary_op (NE_EXPR, alloc_expr,
3074                                     integer_zero_node, 1);
3075       rval = build_conditional_expr (ifexp, rval, alloc_expr);
3076     }
3077
3078   if (rval && TREE_TYPE (rval) != build_pointer_type (type))
3079     {
3080       /* The type of new int [3][3] is not int *, but int [3] * */
3081       rval = build_c_cast (build_pointer_type (type), rval, 0);
3082     }
3083
3084   if (pending_sizes)
3085     rval = build_compound_expr (chainon (pending_sizes,
3086                                          build_tree_list (NULL_TREE, rval)));
3087
3088   return rval;
3089 }
3090 \f
3091 static tree
3092 build_vec_delete_1 (base, maxindex, type, auto_delete_vec, auto_delete,
3093                     use_global_delete)
3094      tree base, maxindex, type;
3095      tree auto_delete_vec, auto_delete;
3096      int use_global_delete;
3097 {
3098   tree virtual_size;
3099   tree ptype = build_pointer_type (type = complete_type (type));
3100   tree size_exp = size_in_bytes (type);
3101
3102   /* Temporary variables used by the loop.  */
3103   tree tbase, tbase_init;
3104
3105   /* This is the body of the loop that implements the deletion of a
3106      single element, and moves temp variables to next elements.  */
3107   tree body;
3108
3109   /* This is the LOOP_EXPR that governs the deletion of the elements.  */
3110   tree loop;
3111
3112   /* This is the thing that governs what to do after the loop has run.  */
3113   tree deallocate_expr = 0;
3114
3115   /* This is the BIND_EXPR which holds the outermost iterator of the
3116      loop.  It is convenient to set this variable up and test it before
3117      executing any other code in the loop.
3118      This is also the containing expression returned by this function.  */
3119   tree controller = NULL_TREE;
3120
3121   /* This is the BLOCK to record the symbol binding for debugging.  */
3122   tree block;
3123
3124   if (! IS_AGGR_TYPE (type) || ! TYPE_NEEDS_DESTRUCTOR (type))
3125     {
3126       loop = integer_zero_node;
3127       goto no_destructor;
3128     }
3129
3130   /* The below is short by BI_header_size */
3131   virtual_size = fold (size_binop (MULT_EXPR, size_exp, maxindex));
3132
3133   tbase = build_decl (VAR_DECL, NULL_TREE, ptype);
3134   tbase_init = build_modify_expr (tbase, NOP_EXPR,
3135                                   fold (build (PLUS_EXPR, ptype,
3136                                                base,
3137                                                virtual_size)));
3138   DECL_REGISTER (tbase) = 1;
3139   controller = build (BIND_EXPR, void_type_node, tbase, NULL_TREE, NULL_TREE);
3140   TREE_SIDE_EFFECTS (controller) = 1;
3141   block = build_block (tbase, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE);
3142   add_block_current_level (block);
3143
3144   if (auto_delete != integer_zero_node
3145       && auto_delete != integer_two_node)
3146     {
3147       tree base_tbd = convert (ptype,
3148                                build_binary_op (MINUS_EXPR,
3149                                                 convert (ptr_type_node, base),
3150                                                 BI_header_size,
3151                                                 1));
3152       /* This is the real size */
3153       virtual_size = size_binop (PLUS_EXPR, virtual_size, BI_header_size);
3154       body = build_tree_list (NULL_TREE,
3155                               build_x_delete (ptype, base_tbd,
3156                                               2 | use_global_delete,
3157                                               virtual_size));
3158       body = build (COND_EXPR, void_type_node,
3159                     build (BIT_AND_EXPR, integer_type_node,
3160                            auto_delete, integer_one_node),
3161                     body, integer_zero_node);
3162     }
3163   else
3164     body = NULL_TREE;
3165
3166   body = tree_cons (NULL_TREE,
3167                     build_delete (ptype, tbase, auto_delete,
3168                                   LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 1),
3169                     body);
3170
3171   body = tree_cons (NULL_TREE,
3172                     build_modify_expr (tbase, NOP_EXPR, build (MINUS_EXPR, ptype, tbase, size_exp)),
3173                     body);
3174
3175   body = tree_cons (NULL_TREE,
3176                     build (EXIT_EXPR, void_type_node,
3177                            build (EQ_EXPR, boolean_type_node, base, tbase)),
3178                     body);
3179
3180   loop = build (LOOP_EXPR, void_type_node, build_compound_expr (body));
3181
3182   loop = tree_cons (NULL_TREE, tbase_init,
3183                     tree_cons (NULL_TREE, loop, NULL_TREE));
3184   loop = build_compound_expr (loop);
3185
3186  no_destructor:
3187   /* If the delete flag is one, or anything else with the low bit set,
3188      delete the storage.  */
3189   if (auto_delete_vec == integer_zero_node
3190       || auto_delete_vec == integer_two_node)
3191     deallocate_expr = integer_zero_node;
3192   else
3193     {
3194       tree base_tbd;
3195
3196       /* The below is short by BI_header_size */
3197       virtual_size = fold (size_binop (MULT_EXPR, size_exp, maxindex));
3198
3199       if (! TYPE_VEC_NEW_USES_COOKIE (type))
3200         /* no header */
3201         base_tbd = base;
3202       else
3203         {
3204           base_tbd = convert (ptype,
3205                               build_binary_op (MINUS_EXPR,
3206                                                convert (string_type_node, base),
3207                                                BI_header_size,
3208                                                1));
3209           /* True size with header.  */
3210           virtual_size = size_binop (PLUS_EXPR, virtual_size, BI_header_size);
3211         }
3212       deallocate_expr = build_x_delete (ptype, base_tbd,
3213                                         2 | use_global_delete,
3214                                         virtual_size);
3215       if (auto_delete_vec != integer_one_node)
3216         deallocate_expr = build (COND_EXPR, void_type_node,
3217                                  build (BIT_AND_EXPR, integer_type_node,
3218                                         auto_delete_vec, integer_one_node),
3219                                  deallocate_expr, integer_zero_node);
3220     }
3221
3222   if (loop && deallocate_expr != integer_zero_node)
3223     {
3224       body = tree_cons (NULL_TREE, loop,
3225                         tree_cons (NULL_TREE, deallocate_expr, NULL_TREE));
3226       body = build_compound_expr (body);
3227     }
3228   else
3229     body = loop;
3230
3231   /* Outermost wrapper: If pointer is null, punt.  */
3232   body = build (COND_EXPR, void_type_node,
3233                 build (NE_EXPR, boolean_type_node, base, integer_zero_node),
3234                 body, integer_zero_node);
3235   body = build1 (NOP_EXPR, void_type_node, body);
3236
3237   if (controller)
3238     {
3239       TREE_OPERAND (controller, 1) = body;
3240       return controller;
3241     }
3242   else
3243     return convert (void_type_node, body);
3244 }
3245
3246 /* Build a tree to cleanup partially built arrays.
3247    BASE is that starting address of the array.
3248    COUNT is the count of objects that have been built, that need destroying.
3249    TYPE is the type of elements in the array.  */
3250
3251 static tree
3252 build_array_eh_cleanup (base, count, type)
3253      tree base, count, type;
3254 {
3255   tree expr = build_vec_delete_1 (base, count, type, integer_two_node,
3256                                   integer_zero_node, 0);
3257   return expr;
3258 }
3259
3260 /* `expand_vec_init' performs initialization of a vector of aggregate
3261    types.
3262
3263    DECL is passed only for error reporting, and provides line number
3264    and source file name information.
3265    BASE is the space where the vector will be.
3266    MAXINDEX is the maximum index of the array (one less than the
3267             number of elements).
3268    INIT is the (possibly NULL) initializer.
3269
3270    FROM_ARRAY is 0 if we should init everything with INIT
3271    (i.e., every element initialized from INIT).
3272    FROM_ARRAY is 1 if we should index into INIT in parallel
3273    with initialization of DECL.
3274    FROM_ARRAY is 2 if we should index into INIT in parallel,
3275    but use assignment instead of initialization.  */
3276
3277 tree
3278 expand_vec_init (decl, base, maxindex, init, from_array)
3279      tree decl, base, maxindex, init;
3280      int from_array;
3281 {
3282   tree rval;
3283   tree iterator, base2 = NULL_TREE;
3284   tree type = TREE_TYPE (TREE_TYPE (base));
3285   tree size;
3286
3287   maxindex = convert (ptrdiff_type_node, maxindex);
3288   if (maxindex == error_mark_node)
3289     return error_mark_node;
3290
3291   if (current_function_decl == NULL_TREE)
3292     {
3293       rval = make_tree_vec (3);
3294       TREE_VEC_ELT (rval, 0) = base;
3295       TREE_VEC_ELT (rval, 1) = maxindex;
3296       TREE_VEC_ELT (rval, 2) = init;
3297       return rval;
3298     }
3299
3300   size = size_in_bytes (type);
3301
3302   /* Set to zero in case size is <= 0.  Optimizer will delete this if
3303      it is not needed.  */
3304   rval = get_temp_regvar (build_pointer_type (type),
3305                           convert (build_pointer_type (type), null_pointer_node));
3306   base = default_conversion (base);
3307   base = convert (build_pointer_type (type), base);
3308   expand_assignment (rval, base, 0, 0);
3309   base = get_temp_regvar (build_pointer_type (type), base);
3310
3311   if (init != NULL_TREE && TREE_CODE (init) == TREE_LIST)
3312     init = build_compound_expr (init);
3313
3314   if (init != NULL_TREE
3315       && TREE_CODE (init) == CONSTRUCTOR
3316       && (! decl || TREE_TYPE (init) == TREE_TYPE (decl)))
3317     {
3318       /* Initialization of array from {...}.  */
3319       tree elts = CONSTRUCTOR_ELTS (init);
3320       tree baseref = build1 (INDIRECT_REF, type, base);
3321       tree baseinc = build (PLUS_EXPR, build_pointer_type (type), base, size);
3322       int host_i = TREE_INT_CST_LOW (maxindex);
3323
3324       if (IS_AGGR_TYPE (type))
3325         {
3326           while (elts)
3327             {
3328               host_i -= 1;
3329               expand_aggr_init (baseref, TREE_VALUE (elts), 0, 0);
3330
3331               expand_assignment (base, baseinc, 0, 0);
3332               elts = TREE_CHAIN (elts);
3333             }
3334           /* Initialize any elements by default if possible.  */
3335           if (host_i >= 0)
3336             {
3337               if (TYPE_NEEDS_CONSTRUCTING (type) == 0)
3338                 {
3339                   if (obey_regdecls)
3340                     use_variable (DECL_RTL (base));
3341                   goto done_init;
3342                 }
3343
3344               iterator = get_temp_regvar (ptrdiff_type_node,
3345                                           build_int_2 (host_i, 0));
3346               init = NULL_TREE;
3347               goto init_by_default;
3348             }
3349         }
3350       else
3351         while (elts)
3352           {
3353             expand_assignment (baseref, TREE_VALUE (elts), 0, 0);
3354
3355             expand_assignment (base, baseinc, 0, 0);
3356             elts = TREE_CHAIN (elts);
3357           }
3358
3359       if (obey_regdecls)
3360         use_variable (DECL_RTL (base));
3361     }
3362   else
3363     {
3364       tree itype;
3365
3366       iterator = get_temp_regvar (ptrdiff_type_node, maxindex);
3367
3368     init_by_default:
3369
3370       /* If initializing one array from another,
3371          initialize element by element.  */
3372       if (from_array)
3373         {
3374           /* We rely upon the below calls the do argument checking */
3375           if (decl == NULL_TREE)
3376             {
3377               sorry ("initialization of array from dissimilar array type");
3378               return error_mark_node;
3379             }
3380           if (init)
3381             {
3382               base2 = default_conversion (init);
3383               itype = TREE_TYPE (base2);
3384               base2 = get_temp_regvar (itype, base2);
3385               itype = TREE_TYPE (itype);
3386             }
3387           else if (TYPE_LANG_SPECIFIC (type)
3388                    && TYPE_NEEDS_CONSTRUCTING (type)
3389                    && ! TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
3390             {
3391               error ("initializer ends prematurely");
3392               return error_mark_node;
3393             }
3394         }
3395
3396       expand_start_cond (build (GE_EXPR, boolean_type_node,
3397                                 iterator, integer_zero_node), 0);
3398       if (TYPE_NEEDS_DESTRUCTOR (type))
3399         expand_eh_region_start ();
3400       expand_start_loop_continue_elsewhere (1);
3401
3402       if (from_array)
3403         {
3404           tree to = build1 (INDIRECT_REF, type, base);
3405           tree from;
3406
3407           if (base2)
3408             from = build1 (INDIRECT_REF, itype, base2);
3409           else
3410             from = NULL_TREE;
3411
3412           if (from_array == 2)
3413             expand_expr_stmt (build_modify_expr (to, NOP_EXPR, from));
3414           else if (TYPE_NEEDS_CONSTRUCTING (type))
3415             expand_aggr_init (to, from, 0, 0);
3416           else if (from)
3417             expand_assignment (to, from, 0, 0);
3418           else
3419             my_friendly_abort (57);
3420         }
3421       else if (TREE_CODE (type) == ARRAY_TYPE)
3422         {
3423           if (init != 0)
3424             sorry ("cannot initialize multi-dimensional array with initializer");
3425           expand_vec_init (decl, build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (type)), base),
3426                            array_type_nelts (type), 0, 0);
3427         }
3428       else
3429         {
3430           tree targ = build1 (INDIRECT_REF, type, base);
3431           tree rhs;
3432
3433           if (init)
3434             rhs = convert_for_initialization (targ, type, init, LOOKUP_NORMAL,
3435                                               "initialization", NULL_TREE, 0);
3436           else
3437             rhs = NULL_TREE;
3438
3439           expand_aggr_init (targ, rhs, 0, 0);
3440         }
3441
3442       expand_assignment (base,
3443                          build (PLUS_EXPR, build_pointer_type (type), base, size),
3444                          0, 0);
3445       if (base2)
3446         expand_assignment (base2,
3447                            build (PLUS_EXPR, build_pointer_type (type), base2, size), 0, 0);
3448       expand_loop_continue_here ();
3449       expand_exit_loop_if_false (0, build (NE_EXPR, boolean_type_node,
3450                                            build (PREDECREMENT_EXPR, ptrdiff_type_node, iterator, integer_one_node), minus_one));
3451
3452       if (obey_regdecls)
3453         {
3454           use_variable (DECL_RTL (base));
3455           if (base2)
3456             use_variable (DECL_RTL (base2));
3457         }
3458       expand_end_loop ();
3459       if (TYPE_NEEDS_DESTRUCTOR (type) && flag_exceptions)
3460         {
3461           /* We have to ensure that this can live to the cleanup
3462              expansion time, since we know it is only ever needed
3463              once, generate code now.  */
3464           push_obstacks_nochange ();
3465           resume_temporary_allocation ();
3466           {
3467             tree e1, e2 = make_node (RTL_EXPR);
3468             TREE_TYPE (e2) = void_type_node;
3469             RTL_EXPR_RTL (e2) = const0_rtx;
3470             TREE_SIDE_EFFECTS (e2) = 1;
3471             start_sequence_for_rtl_expr (e2);
3472
3473             e1 = build_array_eh_cleanup
3474               (rval,
3475                build_binary_op (MINUS_EXPR, maxindex, iterator, 1),
3476                type);
3477             expand_expr (e1, const0_rtx, VOIDmode, 0);
3478             RTL_EXPR_SEQUENCE (e2) = get_insns ();
3479             end_sequence ();
3480             expand_eh_region_end (e2);
3481           }
3482           pop_obstacks ();
3483         }
3484       expand_end_cond ();
3485       if (obey_regdecls)
3486         use_variable (DECL_RTL (iterator));
3487     }
3488  done_init:
3489
3490   if (obey_regdecls)
3491     use_variable (DECL_RTL (rval));
3492   return rval;
3493 }
3494
3495 /* Free up storage of type TYPE, at address ADDR.
3496
3497    TYPE is a POINTER_TYPE and can be ptr_type_node for no special type
3498    of pointer.
3499
3500    VIRTUAL_SIZE is the amount of storage that was allocated, and is
3501    used as the second argument to operator delete.  It can include
3502    things like padding and magic size cookies.  It has virtual in it,
3503    because if you have a base pointer and you delete through a virtual
3504    destructor, it should be the size of the dynamic object, not the
3505    static object, see Free Store 12.5 ANSI C++ WP.
3506
3507    This does not call any destructors.  */
3508
3509 tree
3510 build_x_delete (type, addr, which_delete, virtual_size)
3511      tree type, addr;
3512      int which_delete;
3513      tree virtual_size;
3514 {
3515   int use_global_delete = which_delete & 1;
3516   int use_vec_delete = !!(which_delete & 2);
3517   tree rval;
3518   enum tree_code code = use_vec_delete ? VEC_DELETE_EXPR : DELETE_EXPR;
3519
3520   if (! use_global_delete && TYPE_LANG_SPECIFIC (TREE_TYPE (type))
3521       && (TYPE_GETS_DELETE (TREE_TYPE (type)) & (1 << use_vec_delete)))
3522     rval = build_opfncall (code, LOOKUP_NORMAL, addr, virtual_size, NULL_TREE);
3523   else
3524     rval = build_builtin_call (void_type_node, use_vec_delete ? BIVD : BID,
3525                                build_tree_list (NULL_TREE, addr));
3526   return rval;
3527 }
3528
3529 /* Generate a call to a destructor. TYPE is the type to cast ADDR to.
3530    ADDR is an expression which yields the store to be destroyed.
3531    AUTO_DELETE is nonzero if a call to DELETE should be made or not.
3532    If in the program, (AUTO_DELETE & 2) is non-zero, we tear down the
3533    virtual baseclasses.
3534    If in the program, (AUTO_DELETE & 1) is non-zero, then we deallocate.
3535
3536    FLAGS is the logical disjunction of zero or more LOOKUP_
3537    flags.  See cp-tree.h for more info.
3538
3539    This function does not delete an object's virtual base classes.  */
3540
3541 tree
3542 build_delete (type, addr, auto_delete, flags, use_global_delete)
3543      tree type, addr;
3544      tree auto_delete;
3545      int flags;
3546      int use_global_delete;
3547 {
3548   tree function;
3549   tree member;
3550   tree expr;
3551   tree ref;
3552   int ptr;
3553
3554   if (addr == error_mark_node)
3555     return error_mark_node;
3556
3557   /* Can happen when CURRENT_EXCEPTION_OBJECT gets its type
3558      set to `error_mark_node' before it gets properly cleaned up.  */
3559   if (type == error_mark_node)
3560     return error_mark_node;
3561
3562   type = TYPE_MAIN_VARIANT (type);
3563
3564   if (TREE_CODE (type) == POINTER_TYPE)
3565     {
3566       type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
3567       if (TYPE_SIZE (complete_type (type)) == 0)
3568         {
3569           incomplete_type_error (0, type);
3570           return error_mark_node;
3571         }
3572       if (TREE_CODE (type) == ARRAY_TYPE)
3573         goto handle_array;
3574       if (! IS_AGGR_TYPE (type))
3575         {
3576           /* Call the builtin operator delete.  */
3577           return build_builtin_call (void_type_node, BID,
3578                                      build_tree_list (NULL_TREE, addr));
3579         }
3580       if (TREE_SIDE_EFFECTS (addr))
3581         addr = save_expr (addr);
3582
3583       /* throw away const and volatile on target type of addr */
3584       addr = convert_force (build_pointer_type (type), addr, 0);
3585       ref = build_indirect_ref (addr, NULL_PTR);
3586       ptr = 1;
3587     }
3588   else if (TREE_CODE (type) == ARRAY_TYPE)
3589     {
3590     handle_array:
3591       if (TREE_SIDE_EFFECTS (addr))
3592         addr = save_expr (addr);
3593       if (TYPE_DOMAIN (type) == NULL_TREE)
3594         {
3595           error ("unknown array size in delete");
3596           return error_mark_node;
3597         }
3598       return build_vec_delete (addr, array_type_nelts (type),
3599                                auto_delete, integer_two_node,
3600                                use_global_delete);
3601     }
3602   else
3603     {
3604       /* Don't check PROTECT here; leave that decision to the
3605          destructor.  If the destructor is accessible, call it,
3606          else report error.  */
3607       addr = build_unary_op (ADDR_EXPR, addr, 0);
3608       if (TREE_SIDE_EFFECTS (addr))
3609         addr = save_expr (addr);
3610
3611       if (TREE_CONSTANT (addr))
3612         addr = convert_pointer_to (type, addr);
3613       else
3614         addr = convert_force (build_pointer_type (type), addr, 0);
3615
3616       if (TREE_CODE (addr) == NOP_EXPR
3617           && TREE_OPERAND (addr, 0) == current_class_ptr)
3618         ref = current_class_ref;
3619       else
3620         ref = build_indirect_ref (addr, NULL_PTR);
3621       ptr = 0;
3622     }
3623
3624   my_friendly_assert (IS_AGGR_TYPE (type), 220);
3625
3626   if (! TYPE_NEEDS_DESTRUCTOR (type))
3627     {
3628       if (auto_delete == integer_zero_node)
3629         return void_zero_node;
3630
3631       /* Pass the size of the object down to the operator delete() in
3632          addition to the ADDR.  */
3633       if (TYPE_GETS_REG_DELETE (type) && !use_global_delete)
3634         {
3635           tree virtual_size = c_sizeof_nowarn (type);
3636           return build_opfncall (DELETE_EXPR, LOOKUP_NORMAL, addr,
3637                                  virtual_size, NULL_TREE);
3638         }
3639
3640       /* Call the builtin operator delete.  */
3641       return build_builtin_call (void_type_node, BID,
3642                                  build_tree_list (NULL_TREE, addr));
3643     }
3644
3645   /* Below, we will reverse the order in which these calls are made.
3646      If we have a destructor, then that destructor will take care
3647      of the base classes; otherwise, we must do that here.  */
3648   if (TYPE_HAS_DESTRUCTOR (type))
3649     {
3650       tree parms = build_tree_list (NULL_TREE, addr);
3651       tree dtor = DECL_MAIN_VARIANT (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 1));
3652       tree passed_auto_delete;
3653       tree do_delete = NULL_TREE;
3654
3655       if (use_global_delete)
3656         {
3657           tree cond = fold (build (BIT_AND_EXPR, integer_type_node,
3658                                    auto_delete, integer_one_node));
3659           tree call = build_builtin_call
3660             (void_type_node, BID, build_tree_list (NULL_TREE, addr));
3661
3662           cond = fold (build (COND_EXPR, void_type_node, cond,
3663                               call, void_zero_node));
3664           if (cond != void_zero_node)
3665             do_delete = cond;
3666
3667           passed_auto_delete = fold (build (BIT_AND_EXPR, integer_type_node,
3668                                             auto_delete, integer_two_node));
3669         }
3670       else
3671         passed_auto_delete = auto_delete;
3672
3673       if (flags & LOOKUP_PROTECT)
3674         {
3675           tree access;
3676           tree basetypes = NULL_TREE;
3677           if (current_class_type != NULL_TREE)
3678             basetypes = get_binfo (type, current_class_type, 0);
3679           if (basetypes == NULL_TREE)
3680             basetypes = TYPE_BINFO (type);
3681           access = compute_access (basetypes, dtor);
3682
3683           if (access == access_private_node)
3684             {
3685               if (flags & LOOKUP_COMPLAIN)
3686                 cp_error ("destructor for type `%T' is private in this scope", type);
3687               return error_mark_node;
3688             }
3689           else if (access == access_protected_node)
3690             {
3691               if (flags & LOOKUP_COMPLAIN)
3692                 cp_error ("destructor for type `%T' is protected in this scope", type);
3693               return error_mark_node;
3694             }
3695         }
3696
3697       /* Once we are in a destructor, try not going through
3698          the virtual function table to find the next destructor.  */
3699       if (DECL_VINDEX (dtor)
3700           && ! (flags & LOOKUP_NONVIRTUAL)
3701           && TREE_CODE (auto_delete) != PARM_DECL
3702           && (ptr == 1 || ! resolves_to_fixed_type_p (ref, 0)))
3703         {
3704           tree binfo, basetype;
3705           /* The code below is probably all broken.  See call.c for the
3706              complete right way to do this. this offsets may not be right
3707              in the below.  (mrs) */
3708           /* This destructor must be called via virtual function table.  */
3709           dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (DECL_CONTEXT (dtor)), 1);
3710           basetype = DECL_CLASS_CONTEXT (dtor);
3711           binfo = get_binfo (basetype,
3712                              TREE_TYPE (TREE_TYPE (TREE_VALUE (parms))),
3713                              0);
3714           expr = convert_pointer_to_real (binfo, TREE_VALUE (parms));
3715           if (expr != TREE_VALUE (parms))
3716             {
3717               expr = fold (expr);
3718               ref = build_indirect_ref (expr, NULL_PTR);
3719               TREE_VALUE (parms) = expr;
3720             }
3721           function = build_vfn_ref (&TREE_VALUE (parms), ref, DECL_VINDEX (dtor));
3722           if (function == error_mark_node)
3723             return error_mark_node;
3724           TREE_TYPE (function) = build_pointer_type (TREE_TYPE (dtor));
3725           TREE_CHAIN (parms) = build_tree_list (NULL_TREE, passed_auto_delete);
3726           expr = build_function_call (function, parms);
3727           if (do_delete)
3728             expr = build (COMPOUND_EXPR, void_type_node, expr, do_delete);
3729           if (ptr && (flags & LOOKUP_DESTRUCTOR) == 0)
3730             {
3731               /* Handle the case where a virtual destructor is
3732                  being called on an item that is 0.
3733
3734                  @@ Does this really need to be done?  */
3735               tree ifexp = build_binary_op(NE_EXPR, addr, integer_zero_node,1);
3736
3737               expr = build (COND_EXPR, void_type_node,
3738                             ifexp, expr, void_zero_node);
3739             }
3740         }
3741       else
3742         {
3743           tree ifexp;
3744
3745           if ((flags & LOOKUP_DESTRUCTOR)
3746               || TREE_CODE (ref) == VAR_DECL
3747               || TREE_CODE (ref) == PARM_DECL
3748               || TREE_CODE (ref) == COMPONENT_REF
3749               || TREE_CODE (ref) == ARRAY_REF)
3750             /* These can't be 0.  */
3751             ifexp = integer_one_node;
3752           else
3753             /* Handle the case where a non-virtual destructor is
3754                being called on an item that is 0.  */
3755             ifexp = build_binary_op (NE_EXPR, addr, integer_zero_node, 1);
3756
3757           /* Used to mean that this destructor was known to be empty,
3758              but that's now obsolete.  */
3759           my_friendly_assert (DECL_INITIAL (dtor) != void_type_node, 221);
3760
3761           TREE_CHAIN (parms) = build_tree_list (NULL_TREE, passed_auto_delete);
3762           expr = build_function_call (dtor, parms);
3763           if (do_delete)
3764             expr = build (COMPOUND_EXPR, void_type_node, expr, do_delete);
3765
3766           if (ifexp != integer_one_node)
3767             expr = build (COND_EXPR, void_type_node,
3768                           ifexp, expr, void_zero_node);
3769         }
3770       return expr;
3771     }
3772   else
3773     {
3774       /* This can get visibilities wrong.  */
3775       tree binfos = BINFO_BASETYPES (TYPE_BINFO (type));
3776       int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
3777       tree base_binfo = n_baseclasses > 0 ? TREE_VEC_ELT (binfos, 0) : NULL_TREE;
3778       tree exprstmt = NULL_TREE;
3779       tree parent_auto_delete = auto_delete;
3780       tree cond;
3781
3782       /* If this type does not have a destructor, but does have
3783          operator delete, call the parent parent destructor (if any),
3784          but let this node do the deleting.  Otherwise, it is ok
3785          to let the parent destructor do the deleting.  */
3786       if (TYPE_GETS_REG_DELETE (type) && !use_global_delete)
3787         {
3788           parent_auto_delete = integer_zero_node;
3789           if (auto_delete == integer_zero_node)
3790             cond = NULL_TREE;
3791           else
3792             {
3793               tree virtual_size;
3794
3795                 /* This is probably wrong. It should be the size of the
3796                    virtual object being deleted.  */
3797               virtual_size = c_sizeof_nowarn (type);
3798
3799               expr = build_opfncall (DELETE_EXPR, LOOKUP_NORMAL, addr,
3800                                      virtual_size, NULL_TREE);
3801               if (expr == error_mark_node)
3802                 return error_mark_node;
3803               if (auto_delete != integer_one_node)
3804                 cond = build (COND_EXPR, void_type_node,
3805                               build (BIT_AND_EXPR, integer_type_node,
3806                                      auto_delete, integer_one_node),
3807                               expr, void_zero_node);
3808               else
3809                 cond = expr;
3810             }
3811         }
3812       else if (base_binfo == NULL_TREE
3813                || (TREE_VIA_VIRTUAL (base_binfo) == 0
3814                    && ! TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo))))
3815         {
3816           cond = build (COND_EXPR, void_type_node,
3817                         build (BIT_AND_EXPR, integer_type_node, auto_delete, integer_one_node),
3818                         build_builtin_call (void_type_node, BID,
3819                                             build_tree_list (NULL_TREE, addr)),
3820                         void_zero_node);
3821         }
3822       else
3823         cond = NULL_TREE;
3824
3825       if (cond)
3826         exprstmt = build_tree_list (NULL_TREE, cond);
3827
3828       if (base_binfo
3829           && ! TREE_VIA_VIRTUAL (base_binfo)
3830           && TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo)))
3831         {
3832           tree this_auto_delete;
3833
3834           if (BINFO_OFFSET_ZEROP (base_binfo))
3835             this_auto_delete = parent_auto_delete;
3836           else
3837             this_auto_delete = integer_zero_node;
3838
3839           expr = build_delete (build_pointer_type (BINFO_TYPE (base_binfo)), addr,
3840                                this_auto_delete, flags, 0);
3841           exprstmt = tree_cons (NULL_TREE, expr, exprstmt);
3842         }
3843
3844       /* Take care of the remaining baseclasses.  */
3845       for (i = 1; i < n_baseclasses; i++)
3846         {
3847           base_binfo = TREE_VEC_ELT (binfos, i);
3848           if (! TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo))
3849               || TREE_VIA_VIRTUAL (base_binfo))
3850             continue;
3851
3852           /* May be zero offset if other baseclasses are virtual.  */
3853           expr = fold (build (PLUS_EXPR, build_pointer_type (BINFO_TYPE (base_binfo)),
3854                               addr, BINFO_OFFSET (base_binfo)));
3855
3856           expr = build_delete (build_pointer_type (BINFO_TYPE (base_binfo)), expr,
3857                                integer_zero_node,
3858                                flags, 0);
3859
3860           exprstmt = tree_cons (NULL_TREE, expr, exprstmt);
3861         }
3862
3863       for (member = TYPE_FIELDS (type); member; member = TREE_CHAIN (member))
3864         {
3865           if (TREE_CODE (member) != FIELD_DECL)
3866             continue;
3867           if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (member)))
3868             {
3869               tree this_member = build_component_ref (ref, DECL_NAME (member), NULL_TREE, 0);
3870               tree this_type = TREE_TYPE (member);
3871               expr = build_delete (this_type, this_member, integer_two_node, flags, 0);
3872               exprstmt = tree_cons (NULL_TREE, expr, exprstmt);
3873             }
3874         }
3875
3876       if (exprstmt)
3877         return build_compound_expr (exprstmt);
3878       /* Virtual base classes make this function do nothing.  */
3879       return void_zero_node;
3880     }
3881 }
3882
3883 /* For type TYPE, delete the virtual baseclass objects of DECL.  */
3884
3885 tree
3886 build_vbase_delete (type, decl)
3887      tree type, decl;
3888 {
3889   tree vbases = CLASSTYPE_VBASECLASSES (type);
3890   tree result = NULL_TREE;
3891   tree addr = build_unary_op (ADDR_EXPR, decl, 0);
3892
3893   my_friendly_assert (addr != error_mark_node, 222);
3894
3895   while (vbases)
3896     {
3897       tree this_addr = convert_force (build_pointer_type (BINFO_TYPE (vbases)),
3898                                       addr, 0);
3899       result = tree_cons (NULL_TREE,
3900                           build_delete (TREE_TYPE (this_addr), this_addr,
3901                                         integer_zero_node,
3902                                         LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0),
3903                           result);
3904       vbases = TREE_CHAIN (vbases);
3905     }
3906   return build_compound_expr (nreverse (result));
3907 }
3908
3909 /* Build a C++ vector delete expression.
3910    MAXINDEX is the number of elements to be deleted.
3911    ELT_SIZE is the nominal size of each element in the vector.
3912    BASE is the expression that should yield the store to be deleted.
3913    This function expands (or synthesizes) these calls itself.
3914    AUTO_DELETE_VEC says whether the container (vector) should be deallocated.
3915    AUTO_DELETE say whether each item in the container should be deallocated.
3916
3917    This also calls delete for virtual baseclasses of elements of the vector.
3918
3919    Update: MAXINDEX is no longer needed.  The size can be extracted from the
3920    start of the vector for pointers, and from the type for arrays.  We still
3921    use MAXINDEX for arrays because it happens to already have one of the
3922    values we'd have to extract.  (We could use MAXINDEX with pointers to
3923    confirm the size, and trap if the numbers differ; not clear that it'd
3924    be worth bothering.)  */
3925
3926 tree
3927 build_vec_delete (base, maxindex, auto_delete_vec, auto_delete,
3928                   use_global_delete)
3929      tree base, maxindex;
3930      tree auto_delete_vec, auto_delete;
3931      int use_global_delete;
3932 {
3933   tree type;
3934
3935   if (TREE_CODE (base) == OFFSET_REF)
3936     base = resolve_offset_ref (base);
3937
3938   type = TREE_TYPE (base);
3939
3940   base = stabilize_reference (base);
3941
3942   /* Since we can use base many times, save_expr it.  */
3943   if (TREE_SIDE_EFFECTS (base))
3944     base = save_expr (base);
3945
3946   if (TREE_CODE (type) == POINTER_TYPE)
3947     {
3948       /* Step back one from start of vector, and read dimension.  */
3949       tree cookie_addr = build (MINUS_EXPR, build_pointer_type (BI_header_type),
3950                                 base, BI_header_size);
3951       tree cookie = build_indirect_ref (cookie_addr, NULL_PTR);
3952       maxindex = build_component_ref (cookie, nc_nelts_field_id, NULL_TREE, 0);
3953       do
3954         type = TREE_TYPE (type);
3955       while (TREE_CODE (type) == ARRAY_TYPE);
3956     }
3957   else if (TREE_CODE (type) == ARRAY_TYPE)
3958     {
3959       /* get the total number of things in the array, maxindex is a bad name */
3960       maxindex = array_type_nelts_total (type);
3961       while (TREE_CODE (type) == ARRAY_TYPE)
3962         type = TREE_TYPE (type);
3963       base = build_unary_op (ADDR_EXPR, base, 1);
3964     }
3965   else
3966     {
3967       if (base != error_mark_node)
3968         error ("type to vector delete is neither pointer or array type");
3969       return error_mark_node;
3970     }
3971
3972   return build_vec_delete_1 (base, maxindex, type, auto_delete_vec, auto_delete,
3973                              use_global_delete);
3974 }