Annotation of GNUtools/cc/cp-search.c, revision 1.1.1.1

1.1       root        1: /* Breadth-first and depth-first routines for
                      2:    searching multiple-inheritance lattice for GNU C++.
                      3:    Copyright (C) 1987, 1989, 1992, 1993 Free Software Foundation, Inc.
                      4:    Contributed by Michael Tiemann ([email protected])
                      5: 
                      6: This file is part of GNU CC.
                      7: 
                      8: GNU CC is free software; you can redistribute it and/or modify
                      9: it under the terms of the GNU General Public License as published by
                     10: the Free Software Foundation; either version 2, or (at your option)
                     11: any later version.
                     12: 
                     13: GNU CC is distributed in the hope that it will be useful,
                     14: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     16: GNU General Public License for more details.
                     17: 
                     18: You should have received a copy of the GNU General Public License
                     19: along with GNU CC; see the file COPYING.  If not, write to
                     20: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
                     21: 
                     22: /* High-level class interface. */
                     23: 
                     24: #include "config.h"
                     25: #include "tree.h"
                     26: #include <stdio.h>
                     27: #include "cp-tree.h"
                     28: #include "obstack.h"
                     29: #include "flags.h"
                     30: 
                     31: #define obstack_chunk_alloc xmalloc
                     32: #define obstack_chunk_free free
                     33: 
                     34: void init_search ();
                     35: extern struct obstack *current_obstack;
                     36: 
                     37: #include "stack.h"
                     38: 
                     39: /* Obstack used for remembering decision points of breadth-first.  */
                     40: static struct obstack search_obstack;
                     41: 
                     42: /* Methods for pushing and popping objects to and from obstacks.  */
                     43: struct stack_level *
                     44: push_stack_level (obstack, tp, size)
                     45:      struct obstack *obstack;
                     46:      char *tp;  /* Sony NewsOS 5.0 compiler doesn't like void * here.  */
                     47:      int size;
                     48: {
                     49:   struct stack_level *stack;
                     50:   obstack_grow (obstack, tp, size);
                     51:   stack = (struct stack_level *) ((char*)obstack_next_free (obstack) - size);
                     52:   obstack_finish (obstack);
                     53:   stack->obstack = obstack;
                     54:   stack->first = (tree *) obstack_base (obstack);
                     55:   stack->limit = obstack_room (obstack) / sizeof (tree *);
                     56:   return stack;
                     57: }
                     58: 
                     59: struct stack_level *
                     60: pop_stack_level (stack)
                     61:      struct stack_level *stack;
                     62: {
                     63:   struct stack_level *tem = stack;
                     64:   struct obstack *obstack = tem->obstack;
                     65:   stack = tem->prev;
                     66:   obstack_free (obstack, tem);
                     67:   return stack;
                     68: }
                     69: 
                     70: #define search_level stack_level
                     71: static struct search_level *search_stack;
                     72: 
                     73: static tree lookup_field_1 ();
                     74: static int lookup_fnfields_1 ();
                     75: static void dfs_walk ();
                     76: static int markedp ();
                     77: static void dfs_unmark ();
                     78: static void dfs_init_vbase_pointers ();
                     79: 
                     80: static tree vbase_types;
                     81: static tree vbase_decl, vbase_decl_ptr;
                     82: static tree vbase_decl_ptr_intermediate;
                     83: static tree vbase_init_result;
                     84: 
                     85: /* Allocate a level of searching.  */
                     86: static struct search_level *
                     87: push_search_level (stack, obstack)
                     88:      struct stack_level *stack;
                     89:      struct obstack *obstack;
                     90: {
                     91:   struct search_level tem;
                     92: 
                     93:   tem.prev = stack;
                     94:   return push_stack_level (obstack, (char *)&tem, sizeof (tem));
                     95: }
                     96: 
                     97: /* Discard a level of search allocation.  */
                     98: static struct search_level *
                     99: pop_search_level (obstack)
                    100:      struct stack_level *obstack;
                    101: {
                    102:   register struct search_level *stack = pop_stack_level (obstack);
                    103: 
                    104:   return stack;
                    105: }
                    106: 
                    107: /* Search memoization.  */
                    108: struct type_level
                    109: {
                    110:   struct stack_level base;
                    111: 
                    112:   /* First object allocated in obstack of entries.  */
                    113:   char *entries;
                    114: 
                    115:   /* Number of types memoized in this context.  */
                    116:   int len;
                    117: 
                    118:   /* Type being memoized; save this if we are saving
                    119:      memoized contexts.  */
                    120:   tree type;
                    121: };
                    122: 
                    123: /* Obstack used for memoizing member and member function lookup.  */
                    124: 
                    125: static struct obstack type_obstack, type_obstack_entries;
                    126: static struct type_level *type_stack;
                    127: static tree _vptr_name;
                    128: 
                    129: /* Make things that look like tree nodes, but allocate them
                    130:    on type_obstack_entries.  */
                    131: static int my_tree_node_counter;
                    132: static tree my_tree_cons (), my_build_string ();
                    133: 
                    134: extern int flag_memoize_lookups, flag_save_memoized_contexts;
                    135: 
                    136: /* Variables for gathering statistics.  */
                    137: static int my_memoized_entry_counter;
                    138: static int memoized_fast_finds[2], memoized_adds[2], memoized_fast_rejects[2];
                    139: static int memoized_fields_searched[2];
                    140: static int n_fields_searched;
                    141: static int n_calls_lookup_field, n_calls_lookup_field_1;
                    142: static int n_calls_lookup_fnfields, n_calls_lookup_fnfields_1;
                    143: static int n_calls_get_base_type;
                    144: static int n_outer_fields_searched;
                    145: static int n_contexts_saved;
                    146: 
                    147: /* Local variables to help save memoization contexts.  */
                    148: static tree prev_type_memoized;
                    149: static struct type_level *prev_type_stack;
                    150: 
                    151: #if NEW_CLASS_SCOPING
                    152: /* This list is used by push_class_decls to know what decls need to
                    153:    be pushed into class scope.  */
                    154: static tree closed_envelopes = NULL_TREE;
                    155: #endif
                    156: 
                    157: /* Allocate a level of type memoization context.  */
                    158: static struct type_level *
                    159: push_type_level (stack, obstack)
                    160:      struct stack_level *stack;
                    161:      struct obstack *obstack;
                    162: {
                    163:   struct type_level tem;
                    164: 
                    165:   tem.base.prev = stack;
                    166: 
                    167:   obstack_finish (&type_obstack_entries);
                    168:   tem.entries = (char *) obstack_base (&type_obstack_entries);
                    169:   tem.len = 0;
                    170:   tem.type = NULL_TREE;
                    171: 
                    172:   return (struct type_level *)push_stack_level (obstack, (char *)&tem, sizeof (tem));
                    173: }
                    174: 
                    175: /* Discard a level of type memoization context.  */
                    176: 
                    177: static struct type_level *
                    178: pop_type_level (stack)
                    179:      struct type_level *stack;
                    180: {
                    181:   obstack_free (&type_obstack_entries, stack->entries);
                    182:   return (struct type_level *)pop_stack_level ((struct stack_level *)stack);
                    183: }
                    184: 
                    185: /* Make something that looks like a TREE_LIST, but
                    186:    do it on the type_obstack_entries obstack.  */
                    187: static tree
                    188: my_tree_cons (purpose, value, chain)
                    189:      tree purpose, value, chain;
                    190: {
                    191:   tree p = (tree)obstack_alloc (&type_obstack_entries, sizeof (struct tree_list));
                    192:   ++my_tree_node_counter;
                    193:   TREE_TYPE (p) = NULL_TREE;
                    194:   ((HOST_WIDE_INT *)p)[3] = 0;
                    195:   TREE_SET_CODE (p, TREE_LIST);
                    196:   TREE_PURPOSE (p) = purpose;
                    197:   TREE_VALUE (p) = value;
                    198:   TREE_CHAIN (p) = chain;
                    199:   return p;
                    200: }
                    201: 
                    202: static tree
                    203: my_build_string (str)
                    204:      char *str;
                    205: {
                    206:   tree p = (tree)obstack_alloc (&type_obstack_entries, sizeof (struct tree_string));
                    207:   ++my_tree_node_counter;
                    208:   TREE_TYPE (p) = 0;
                    209:   ((int *)p)[3] = 0;
                    210:   TREE_SET_CODE (p, STRING_CST);
                    211:   TREE_STRING_POINTER (p) = str;
                    212:   TREE_STRING_LENGTH (p) = strlen (str);
                    213:   return p;
                    214: }
                    215: 
                    216: /* Memoizing machinery to make searches for multiple inheritance
                    217:    reasonably efficient.  */
                    218: #define MEMOIZE_HASHSIZE 8
                    219: typedef struct memoized_entry
                    220: {
                    221:   struct memoized_entry *chain;
                    222:   int uid;
                    223:   tree data_members[MEMOIZE_HASHSIZE];
                    224:   tree function_members[MEMOIZE_HASHSIZE];
                    225: } *ME;
                    226: 
                    227: #define MEMOIZED_CHAIN(ENTRY) (((ME)ENTRY)->chain)
                    228: #define MEMOIZED_UID(ENTRY) (((ME)ENTRY)->uid)
                    229: #define MEMOIZED_FIELDS(ENTRY,INDEX) (((ME)ENTRY)->data_members[INDEX])
                    230: #define MEMOIZED_FNFIELDS(ENTRY,INDEX) (((ME)ENTRY)->function_members[INDEX])
                    231: /* The following is probably a lousy hash function.  */
                    232: #define MEMOIZED_HASH_FN(NODE) (((long)(NODE)>>4)&(MEMOIZE_HASHSIZE - 1))
                    233: 
                    234: static struct memoized_entry *
                    235: my_new_memoized_entry (chain)
                    236:      struct memoized_entry *chain;
                    237: {
                    238:   struct memoized_entry *p =
                    239:     (struct memoized_entry *)obstack_alloc (&type_obstack_entries,
                    240:                                            sizeof (struct memoized_entry));
                    241:   bzero (p, sizeof (struct memoized_entry));
                    242:   MEMOIZED_CHAIN (p) = chain;
                    243:   MEMOIZED_UID (p) = ++my_memoized_entry_counter;
                    244:   return p;
                    245: }
                    246: 
                    247: /* Make an entry in the memoized table for type TYPE
                    248:    that the entry for NAME is FIELD.  */
                    249: 
                    250: tree
                    251: make_memoized_table_entry (type, name, function_p)
                    252:      tree type, name;
                    253:      int function_p;
                    254: {
                    255:   int index = MEMOIZED_HASH_FN (name);
                    256:   tree entry, *prev_entry;
                    257: 
                    258:   memoized_adds[function_p] += 1;
                    259:   if (CLASSTYPE_MTABLE_ENTRY (type) == 0)
                    260:     {
                    261:       obstack_ptr_grow (&type_obstack, type);
                    262:       obstack_blank (&type_obstack, sizeof (struct memoized_entry *));
                    263:       CLASSTYPE_MTABLE_ENTRY (type) = (char *)my_new_memoized_entry ((struct memoized_entry *)0);
                    264:       type_stack->len++;
                    265:       if (type_stack->len * 2 >= type_stack->base.limit)
                    266:        my_friendly_abort (88);
                    267:     }
                    268:   if (function_p)
                    269:     prev_entry = &MEMOIZED_FNFIELDS (CLASSTYPE_MTABLE_ENTRY (type), index);
                    270:   else
                    271:     prev_entry = &MEMOIZED_FIELDS (CLASSTYPE_MTABLE_ENTRY (type), index);
                    272: 
                    273:   entry = my_tree_cons (name, NULL_TREE, *prev_entry);
                    274:   *prev_entry = entry;
                    275: 
                    276:   /* Don't know the error message to give yet.  */
                    277:   TREE_TYPE (entry) = error_mark_node;
                    278: 
                    279:   return entry;
                    280: }
                    281: 
                    282: /* When a new function or class context is entered, we build
                    283:    a table of types which have been searched for members.
                    284:    The table is an array (obstack) of types.  When a type is
                    285:    entered into the obstack, its CLASSTYPE_MTABLE_ENTRY
                    286:    field is set to point to a new record, of type struct memoized_entry.
                    287: 
                    288:    A non-NULL TREE_TYPE of the entry contains a visibility error message.
                    289: 
                    290:    The slots for the data members are arrays of tree nodes.
                    291:    These tree nodes are lists, with the TREE_PURPOSE
                    292:    of this list the known member name, and the TREE_VALUE
                    293:    as the FIELD_DECL for the member.
                    294: 
                    295:    For member functions, the TREE_PURPOSE is again the
                    296:    name of the member functions for that class,
                    297:    and the TREE_VALUE of the list is a pairs
                    298:    whose TREE_PURPOSE is a member functions of this name,
                    299:    and whose TREE_VALUE is a list of known argument lists this
                    300:    member function has been called with.  The TREE_TYPE of the pair,
                    301:    if non-NULL, is an error message to print.  */
                    302: 
                    303: /* Tell search machinery that we are entering a new context, and
                    304:    to update tables appropriately.
                    305: 
                    306:    TYPE is the type of the context we are entering, which can
                    307:    be NULL_TREE if we are not in a class's scope.
                    308: 
                    309:    USE_OLD, if nonzero tries to use previous context.  */
                    310: void
                    311: push_memoized_context (type, use_old)
                    312:      tree type;
                    313:      int use_old;
                    314: {
                    315:   int len;
                    316:   tree *tem;
                    317: 
                    318:   if (prev_type_stack)
                    319:     {
                    320:       if (use_old && prev_type_memoized == type)
                    321:        {
                    322: #ifdef GATHER_STATISTICS
                    323:          n_contexts_saved++;
                    324: #endif
                    325:          type_stack = prev_type_stack;
                    326:          prev_type_stack = 0;
                    327: 
                    328:          tem = &type_stack->base.first[0];
                    329:          len = type_stack->len;
                    330:          while (len--)
                    331:            CLASSTYPE_MTABLE_ENTRY (tem[len*2]) = (char *)tem[len*2+1];
                    332:          return;
                    333:        }
                    334:       /* Otherwise, need to pop old stack here.  */
                    335:       type_stack = pop_type_level (prev_type_stack);
                    336:       prev_type_memoized = 0;
                    337:       prev_type_stack = 0;
                    338:     }
                    339: 
                    340:   type_stack = push_type_level ((struct stack_level *)type_stack,
                    341:                                &type_obstack);
                    342:   type_stack->type = type;
                    343: }
                    344: 
                    345: /* Tell search machinery that we have left a context.
                    346:    We do not currently save these contexts for later use.
                    347:    If we wanted to, we could not use pop_search_level, since
                    348:    poping that level allows the data we have collected to
                    349:    be clobbered; a stack of obstacks would be needed.  */
                    350: void
                    351: pop_memoized_context (use_old)
                    352:      int use_old;
                    353: {
                    354:   int len;
                    355:   tree *tem = &type_stack->base.first[0];
                    356: 
                    357:   if (! flag_save_memoized_contexts)
                    358:     use_old = 0;
                    359:   else if (use_old)
                    360:     {
                    361:       len = type_stack->len;
                    362:       while (len--)
                    363:        tem[len*2+1] = (tree)CLASSTYPE_MTABLE_ENTRY (tem[len*2]);
                    364: 
                    365:       prev_type_stack = type_stack;
                    366:       prev_type_memoized = type_stack->type;
                    367:     }
                    368: 
                    369:   if (flag_memoize_lookups)
                    370:     {
                    371:       len = type_stack->len;
                    372:       while (len--)
                    373:        CLASSTYPE_MTABLE_ENTRY (tem[len*2])
                    374:          = (char *)MEMOIZED_CHAIN (CLASSTYPE_MTABLE_ENTRY (tem[len*2]));
                    375:     }
                    376:   if (! use_old)
                    377:     type_stack = pop_type_level (type_stack);
                    378:   else
                    379:     type_stack = (struct type_level *)type_stack->base.prev;
                    380: }
                    381: 
                    382: /* This is the newer recursive depth first search routine. */
                    383: static tree
                    384: get_binfo_recursive (binfo, is_private, parent, rval, rval_private_ptr, xtype,
                    385:                     friends, protect)
                    386:      tree binfo, parent, rval, xtype, friends;
                    387:      int *rval_private_ptr, protect, is_private;
                    388: {
                    389:   tree binfos;
                    390:   int i, n_baselinks;
                    391: 
                    392:   if (BINFO_TYPE (binfo) == parent)
                    393:     {
                    394:       if (rval == NULL_TREE)
                    395:        {
                    396:          rval = binfo;
                    397:          *rval_private_ptr = is_private;
                    398:        }
                    399:       else
                    400:        {
                    401:          /* I believe it is the case that this error is only an error
                    402:             when used by someone that wants error messages printed.
                    403:             Routines that call this one, that don't set protect want
                    404:             the first one found, even if there are more.  */
                    405:          if (protect)
                    406:            {
                    407:              /* Found two or more possible return values.  */
                    408:              cp_error ("type `%T' is ambiguous base class for type `%T'",
                    409:                          parent, xtype);
                    410:              rval = error_mark_node;
                    411:            }
                    412:        }
                    413:       return rval;
                    414:     }
                    415: 
                    416:   binfos = BINFO_BASETYPES (binfo);
                    417:   n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
                    418: 
                    419:   /* Process base types.  */
                    420:   for (i = 0; i < n_baselinks; i++)
                    421:     {
                    422:       tree base_binfo = TREE_VEC_ELT (binfos, i);
                    423: 
                    424:       if (BINFO_MARKED (base_binfo) == 0)
                    425:        {
                    426:          int via_private = is_private || !TREE_VIA_PUBLIC (base_binfo);
                    427: 
                    428:          SET_BINFO_MARKED (base_binfo);
                    429: 
                    430:          if (via_private == 0)
                    431:            ;
                    432:          else if (protect == 0)
                    433:            via_private = 0;
                    434:          else if (protect == 1 && BINFO_TYPE (binfo) == current_class_type)
                    435:            /* The immediate base class of the class we are in
                    436:               does let its public members through.  */
                    437:            via_private = 0;
                    438: #ifndef NOJJG
                    439:          else if (protect
                    440:                   && friends != NULL_TREE
                    441:                   && BINFO_TYPE (binfo) == xtype
                    442:                   && value_member (current_class_type, friends))
                    443:            /* Friend types of the most derived type have access
                    444:               to its baseclass pointers.  */
                    445:            via_private = 0;
                    446: #endif
                    447: 
                    448:          rval = get_binfo_recursive (base_binfo, via_private, parent, rval,
                    449:                                      rval_private_ptr, xtype, friends,
                    450:                                      protect);
                    451:          if (rval == error_mark_node)
                    452:            return rval;
                    453:        }
                    454:     }
                    455: 
                    456:   return rval;
                    457: }
                    458: 
                    459: /* Return non-zero if PARENT is directly derived from TYPE.  By directly
                    460:    we mean it's only one step up the inheritance lattice.  We check this
                    461:    by walking horizontally across the types that TYPE directly inherits
                    462:    from, to see if PARENT is among them.  This is used by get_binfo and
                    463:    by compute_visibility.  */
                    464: static int
                    465: immediately_derived (parent, type)
                    466:      tree parent, type;
                    467: {
                    468:   if (TYPE_BINFO (type))
                    469:     {
                    470:       tree binfos = BINFO_BASETYPES (TYPE_BINFO (type));
                    471:       int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
                    472: 
                    473:       for (i = 0; i < n_baselinks; i++)
                    474:        {
                    475:          tree base_binfo = TREE_VEC_ELT (binfos, i);
                    476: 
                    477:          if (parent == BINFO_TYPE (base_binfo))
                    478:            return 1;
                    479:        }
                    480:     }
                    481:   return 0;
                    482: }
                    483: 
                    484: /* Check whether the type given in BINFO is derived from PARENT.  If
                    485:    it isn't, return 0.  If it is, but the derivation is MI-ambiguous
                    486:    AND protect != 0, emit an error message and return error_mark_node.
                    487: 
                    488:    Otherwise, if TYPE is derived from PARENT, return the actual base
                    489:    information, unless a one of the protection violations below
                    490:    occurs, in which case emit an error message and return error_mark_node.
                    491: 
                    492:    The below should be worded better.  It may not be exactly what the code
                    493:    does, but there should be a lose correlation.  If you understand the code
                    494:    well, please try and make the comments below more readable.
                    495: 
                    496:    If PROTECT is 1, then check if access to a public field of PARENT
                    497:    would be private.
                    498: 
                    499:    If PROTECT is 2, then check if the given type is derived from
                    500:    PARENT via private visibility rules.
                    501: 
                    502:    If PROTECT is 3, then immediately private baseclass is ok,
                    503:    but deeper than that, check if private.  */
                    504: tree
                    505: get_binfo (parent, binfo, protect)
                    506:      register tree parent, binfo;
                    507:      int protect;
                    508: {
                    509:   tree xtype, type;
                    510:   tree otype;
                    511:   int head = 0, tail = 0;
                    512:   int is_private = 0;
                    513:   tree rval = NULL_TREE;
                    514:   int rval_private = 0;
                    515:   tree friends;
                    516: 
                    517: #ifdef GATHER_STATISTICS
                    518:   n_calls_get_base_type++;
                    519: #endif
                    520: 
                    521:   if (TREE_CODE (parent) == TREE_VEC)
                    522:     parent = BINFO_TYPE (parent);
                    523:   /* unions cannot participate in inheritance relationships */
                    524:   else if (TREE_CODE (parent) == UNION_TYPE)
                    525:     return NULL_TREE;
                    526:   else if (TREE_CODE (parent) != RECORD_TYPE)
                    527:     my_friendly_abort (89);
                    528: 
                    529:   parent = TYPE_MAIN_VARIANT (parent);
                    530: 
                    531:   if (TREE_CODE (binfo) == TREE_VEC)
                    532:     type = BINFO_TYPE (binfo);
                    533:   else if (TREE_CODE (binfo) == RECORD_TYPE)
                    534:     {
                    535:       type = binfo;
                    536:       binfo = TYPE_BINFO (type);
                    537:     }
                    538:   else my_friendly_abort (90);
                    539:   xtype = type;
                    540:   friends = current_class_type ? CLASSTYPE_FRIEND_CLASSES (type) : NULL_TREE;
                    541: 
                    542:   rval = get_binfo_recursive (binfo, is_private, parent, rval, &rval_private,
                    543:                              xtype, friends, protect);
                    544: 
                    545:   dfs_walk (binfo, dfs_unmark, markedp);
                    546: 
                    547:   if (rval && protect && rval_private)
                    548:     {
                    549:       if (protect == 3 && immediately_derived (parent, xtype))
                    550:        return rval;
                    551:       cp_error ("type `%T' is derived from private `%T'", xtype, parent);
                    552:       return error_mark_node;
                    553:     }
                    554: 
                    555: #ifdef OBJCPLUS
                    556:   if (!rval)
                    557:     {
                    558:       if (objc_comptypes (parent, type, 1) == 1)
                    559:        return parent;
                    560:     }
                    561: #endif
                    562: 
                    563:   return rval;
                    564: }
                    565: 
                    566: /* This is the newer depth first get_base_distance routine.  */
                    567: static
                    568: get_base_distance_recursive (binfo, depth, is_private, basetype_path, rval,
                    569:                             rval_private_ptr, new_binfo_ptr, parent, path_ptr,
                    570:                             protect, via_virtual_ptr, via_virtual)
                    571:      tree binfo, basetype_path, *new_binfo_ptr, parent, *path_ptr;
                    572:      int *rval_private_ptr, depth, is_private, rval, protect, *via_virtual_ptr,
                    573:        via_virtual;
                    574: {
                    575:   tree binfos;
                    576:   int i, n_baselinks;
                    577: 
                    578:   if (BINFO_TYPE (binfo) == parent || binfo == parent)
                    579:     {
                    580:       if (rval == -1)
                    581:        {
                    582:          rval = depth;
                    583:          *rval_private_ptr = is_private;
                    584:          *new_binfo_ptr = binfo;
                    585:          *via_virtual_ptr = via_virtual;
                    586:        }
                    587:       else
                    588:        {
                    589:          int same_object = tree_int_cst_equal (BINFO_OFFSET (*new_binfo_ptr),
                    590:                                                BINFO_OFFSET (binfo));
                    591: 
                    592:          if (*via_virtual_ptr && via_virtual==0)
                    593:            {
                    594:              *rval_private_ptr = is_private;
                    595:              *new_binfo_ptr = binfo;
                    596:              *via_virtual_ptr = via_virtual;
                    597:            }
                    598:          else if (same_object)
                    599:            {
                    600:              /* Note, this should probably succeed to find, and
                    601:                 override the old one if the old one was private and
                    602:                 this one isn't.  */
                    603:              return rval;
                    604:            }
                    605: 
                    606:          rval = -2;
                    607:        }
                    608:       return rval;
                    609:     }
                    610: 
                    611:   binfos = BINFO_BASETYPES (binfo);
                    612:   n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
                    613:   depth += 1;
                    614: 
                    615:   /* Process base types.  */
                    616:   for (i = 0; i < n_baselinks; i++)
                    617:     {
                    618:       tree base_binfo = TREE_VEC_ELT (binfos, i);
                    619: 
                    620:       if (BINFO_MARKED (base_binfo) == 0)
                    621:        {
                    622:          int via_private = is_private || !TREE_VIA_PUBLIC (base_binfo);
                    623:          int was;
                    624: 
                    625:          /* When searching for a non-virtual, we cannot mark
                    626:             virtually found binfos. */
                    627:          if (!via_virtual)
                    628:            SET_BINFO_MARKED (base_binfo);
                    629: 
                    630:          if (via_private == 0)
                    631:            ;
                    632:          else if (protect == 0)
                    633:            via_private = 0;
                    634: 
                    635: #define WATCH_VALUES(rval, via_private) (rval == -1 ? 3 : via_private)
                    636: 
                    637:          was = WATCH_VALUES (rval, *via_virtual_ptr);
                    638:          rval = get_base_distance_recursive (base_binfo, depth, via_private,
                    639:                                              binfo, rval, rval_private_ptr,
                    640:                                              new_binfo_ptr, parent, path_ptr,
                    641:                                              protect, via_virtual_ptr,
                    642:                                              TREE_VIA_VIRTUAL (base_binfo)|via_virtual);
                    643:          /* watch for updates, only update, if path is good. */
                    644:          if (path_ptr && WATCH_VALUES (rval, *via_virtual_ptr) != was)
                    645:            BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
                    646:          if (rval == -2 && *via_virtual_ptr == 0)
                    647:            return rval;
                    648: 
                    649: #undef WATCH_VALUES
                    650: 
                    651:        }
                    652:     }
                    653: 
                    654:   return rval;
                    655: }
                    656: 
                    657: /* Return the number of levels between type PARENT and the type given
                    658:    in BINFO, following the leftmost path to PARENT not found along a
                    659:    virtual path, if there are no real PARENTs (all come from virtual
                    660:    base classes), then follow the leftmost path to PARENT.
                    661: 
                    662:    Return -1 if TYPE is not derived from PARENT.
                    663:    Return -2 if PARENT is an ambiguous base class of TYPE.
                    664:    Return -3 if PARENT is private to TYPE, and protect is non-zero.
                    665: 
                    666:    If PATH_PTR is non-NULL, then also build the list of types
                    667:    from PARENT to TYPE, with TREE_VIA_VIRUAL and TREE_VIA_PUBLIC
                    668:    set.
                    669: 
                    670:    PARENT can also be a binfo, in which case that exact parent is found
                    671:    and no other.  convert_pointer_to_real uses this functionality.
                    672: 
                    673:    Code in prepare_fresh_vtable relies upon the path being built even
                    674:    when -2 is returned.  */
                    675: 
                    676: int
                    677: get_base_distance (parent, binfo, protect, path_ptr)
                    678:      register tree parent, binfo;
                    679:      int protect;
                    680:      tree *path_ptr;
                    681: {
                    682:   int head, tail;
                    683:   int is_private = 0;
                    684:   int rval;
                    685:   int depth = 0;
                    686:   int rval_private = 0;
                    687:   tree type, basetype_path = NULL_TREE;
                    688:   tree friends;
                    689:   tree new_binfo = NULL_TREE;
                    690:   int via_virtual;
                    691: 
                    692:   if (TREE_CODE (parent) != TREE_VEC)
                    693:     parent = TYPE_MAIN_VARIANT (parent);
                    694: 
                    695:   if (TREE_CODE (binfo) == TREE_VEC)
                    696:     type = BINFO_TYPE (binfo);
                    697:   else if (TREE_CODE (binfo) == RECORD_TYPE)
                    698:     {
                    699:       type = binfo;
                    700:       binfo = TYPE_BINFO (type);
                    701:     }
                    702:   else
                    703:     my_friendly_abort (92);
                    704: 
                    705:   friends = current_class_type ? CLASSTYPE_FRIEND_CLASSES (type) : NULL_TREE;
                    706: 
                    707:   if (path_ptr)
                    708:     {
                    709:       basetype_path = TYPE_BINFO (type);
                    710:       BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE;
                    711:     }
                    712: 
                    713:   if (parent == type || parent == basetype_path)
                    714:     {
                    715:       /* If the distance is 0, then we don't really need
                    716:         a path pointer, but we shouldn't let garbage go back.  */
                    717:       if (path_ptr)
                    718:        *path_ptr = basetype_path;
                    719:       return 0;
                    720:     }
                    721: 
                    722:   rval = get_base_distance_recursive (binfo, 0, 0, NULL_TREE, -1,
                    723:                                      &rval_private, &new_binfo, parent,
                    724:                                      path_ptr, protect, &via_virtual, 0);
                    725: 
                    726:   if (path_ptr)
                    727:     BINFO_INHERITANCE_CHAIN (binfo) = NULL_TREE;
                    728: 
                    729:   basetype_path = binfo;
                    730: 
                    731:   dfs_walk (binfo, dfs_unmark, markedp);
                    732: 
                    733:   binfo = new_binfo;
                    734: 
                    735:   /* Visibilities don't count if we found an ambiguous basetype.  */
                    736:   if (rval == -2)
                    737:     rval_private = 0;
                    738: 
                    739:   if (rval && protect && rval_private)
                    740:     return -3;
                    741: 
                    742:   if (path_ptr)
                    743:     *path_ptr = binfo;
                    744:   return rval;
                    745: }
                    746: 
                    747: /* Search for a member with name NAME in a multiple inheritance lattice
                    748:    specified by TYPE.  If it does not exist, return NULL_TREE.
                    749:    If the member is ambiguously referenced, return `error_mark_node'.
                    750:    Otherwise, return the FIELD_DECL.  */
                    751: 
                    752: /* Do a 1-level search for NAME as a member of TYPE.  The caller
                    753:    must figure out whether it has a visible path to this field.
                    754:    (Since it is only one level, this is reasonable.)  */
                    755: static tree
                    756: lookup_field_1 (type, name)
                    757:      tree type, name;
                    758: {
                    759:   register tree field = TYPE_FIELDS (type);
                    760: 
                    761: #ifdef GATHER_STATISTICS
                    762:   n_calls_lookup_field_1++;
                    763: #endif
                    764:   while (field)
                    765:     {
                    766: #ifdef GATHER_STATISTICS
                    767:       n_fields_searched++;
                    768: #endif
                    769:       if (DECL_NAME (field) == NULL_TREE
                    770:          && TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
                    771:        {
                    772:          tree temp = lookup_field_1 (TREE_TYPE (field), name);
                    773:          if (temp)
                    774:            return temp;
                    775:        }
                    776:       if (DECL_NAME (field) == name)
                    777:        {
                    778:          if ((TREE_CODE(field) == VAR_DECL || TREE_CODE(field) == CONST_DECL)
                    779:              && DECL_ASSEMBLER_NAME (field) != NULL)
                    780:            GNU_xref_ref(current_function_decl,
                    781:                         IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (field)));
                    782:          return field;
                    783:        }
                    784:       field = TREE_CHAIN (field);
                    785:     }
                    786:   /* Not found.  */
                    787:   if (name == _vptr_name)
                    788:     {
                    789:       /* Give the user what s/he thinks s/he wants.  */
                    790:       if (TYPE_VIRTUAL_P (type))
                    791:        return CLASSTYPE_VFIELD (type);
                    792:     }
                    793:   return NULL_TREE;
                    794: }
                    795: 
                    796: /* Compute the visibility of FIELD.  This is done by computing
                    797:    the visibility available to each type in BASETYPES (which comes
                    798:    as a list of [via_public/basetype] in reverse order, namely base
                    799:    class before derived class).  The first one which defines a
                    800:    visibility defines the visibility for the field.  Otherwise, the
                    801:    visibility of the field is that which occurs normally.
                    802: 
                    803:    Uses global variables CURRENT_CLASS_TYPE and
                    804:    CURRENT_FUNCTION_DECL to use friend relationships
                    805:    if necessary.
                    806: 
                    807:    This will be static when lookup_fnfield comes into this file.  */
                    808: 
                    809: #define PUBLIC_RETURN return (DECL_PUBLIC (field) = 1), visibility_public
                    810: #define PROTECTED_RETURN return (DECL_PROTECTED (field) = 1), visibility_protected
                    811: #define PRIVATE_RETURN return (DECL_PRIVATE (field) = 1), visibility_private
                    812: 
                    813: enum visibility_type
                    814: compute_visibility (basetype_path, field)
                    815:      tree basetype_path, field;
                    816: {
                    817:   enum visibility_type visibility = visibility_public;
                    818:   tree types;
                    819:   tree context = DECL_CLASS_CONTEXT (field);
                    820:   /* Used once we go past an access gate that makes private really
                    821:      deny us access from the context.  */
                    822:   int really_private;
                    823: 
                    824:   if (context == NULL_TREE)
                    825:     context = DECL_CONTEXT (field);
                    826: 
                    827:   /* Fields coming from nested anonymous unions have their DECL_CLASS_CONTEXT
                    828:      slot set to the union type rather than the record type containing
                    829:      the anonymous union.  In this case, DECL_FIELD_CONTEXT is correct.  */
                    830:   if (context && TREE_CODE (context) == UNION_TYPE
                    831:       && ANON_AGGRNAME_P (TYPE_IDENTIFIER (context)))
                    832:     context = DECL_FIELD_CONTEXT (field);
                    833: 
                    834:   /* Virtual function tables are never private.  But we should know that
                    835:      we are looking for this, and not even try to hide it.  */
                    836:   if (DECL_NAME (field) && VFIELD_NAME_P (DECL_NAME (field)) == 1)
                    837:     return visibility_public;
                    838: 
                    839:   /* Member function manipulating its own members.  */
                    840:   if (current_class_type == context
                    841:       || (context && current_class_type == TYPE_MAIN_VARIANT (context)))
                    842:     PUBLIC_RETURN;
                    843: 
                    844:   /* Make these special cases fast.  */
                    845:   if (BINFO_TYPE (basetype_path) == current_class_type)
                    846:     {
                    847:       if (DECL_PUBLIC (field))
                    848:        return visibility_public;
                    849:       if (DECL_PROTECTED (field))
                    850:        return visibility_protected;
                    851:       if (DECL_PRIVATE (field))
                    852:        return visibility_private;
                    853:     }
                    854: 
                    855:   /* Member found immediately within object.  */
                    856:   if (BINFO_INHERITANCE_CHAIN (basetype_path) == NULL_TREE)
                    857:     {
                    858:       /* At the object's top level, public members are public.  */
                    859:       if (!TREE_PROTECTED (field) && !TREE_PRIVATE (field))
                    860:        PUBLIC_RETURN;
                    861: 
                    862:       /* Is it a friend function manipulating members that it gets by
                    863:         virtue of its friendship?  Or are we friends with the class
                    864:         that has FIELD?  */
                    865:       if ((current_function_decl && is_friend (context, current_function_decl))
                    866:          || (is_friend_type (context, current_class_type)))
                    867:        PUBLIC_RETURN;
                    868: 
                    869:       if (current_class_type && DECL_VISIBILITY (field) == NULL_TREE)
                    870:        {
                    871:          /* If it's private, it's private, you letch.  */
                    872:          if (TREE_PRIVATE (field))
                    873:            PRIVATE_RETURN;
                    874: 
                    875:          /* ARM $11.5.  Member functions of a derived class can access the
                    876:             non-static protected members of a base class only through a
                    877:             pointer to the derived class, a reference to it, or an object
                    878:             of it. Also any subsequently derived classes also have
                    879:             access.  */
                    880:          if (TREE_PROTECTED (field))
                    881:            {
                    882:              if (context == current_class_type
                    883:                  || UNIQUELY_DERIVED_FROM_P (context, current_class_type))
                    884:                PUBLIC_RETURN;
                    885:              else
                    886:                PROTECTED_RETURN;
                    887:            }
                    888:          else
                    889:            /* Will we ever actually reach here?  Doubt it.  */
                    890:            my_friendly_abort (94);
                    891:        }
                    892:     }
                    893: 
                    894:   /* Is it a friend function manipulating members that it gets by
                    895:      virtue of its friendship?  */
                    896:   if (is_friend (context, current_function_decl))
                    897:     PUBLIC_RETURN;
                    898: 
                    899:   /* must reverse more than one element */
                    900:   basetype_path = reverse_path (basetype_path);
                    901:   types = basetype_path;
                    902:   really_private = 0;
                    903: 
                    904:   while (types)
                    905:     {
                    906:       tree member;
                    907:       tree binfo = types;
                    908:       tree type = BINFO_TYPE (binfo);
                    909: 
                    910:       member = purpose_member (type, DECL_VISIBILITY (field));
                    911:       if (member)
                    912:        {
                    913:          visibility = (enum visibility_type)TREE_VALUE (member);
                    914:          if (visibility == visibility_public
                    915:              || is_friend (type, current_function_decl)
                    916:              || (visibility == visibility_protected
                    917:                  && current_class_type
                    918:                  && UNIQUELY_DERIVED_FROM_P (context, current_class_type)))
                    919:            visibility = visibility_public;
                    920:          goto ret;
                    921:        }
                    922: 
                    923:       /* Friends inherit the visibility of the class they inherit from.  */
                    924:       if (is_friend (type, current_function_decl))
                    925:        {
                    926:          if (type == context)
                    927:            {
                    928:              visibility = visibility_public;
                    929:              goto ret;
                    930:            }
                    931:          if (TREE_PROTECTED (field))
                    932:            {
                    933:              visibility = visibility_public;
                    934:              goto ret;
                    935:            }
                    936:          /* else, may be a friend of a deeper base class */
                    937:        }
                    938: 
                    939:       if (type == context)
                    940:        break;
                    941: 
                    942:       types = BINFO_INHERITANCE_CHAIN (types);
                    943: 
                    944:       /* If the next type was not VIA_PUBLIC, then fields of all
                    945:         remaining class past that one are private.  */
                    946:       if (types)
                    947:        {
                    948:          if (TREE_VIA_PROTECTED (types))
                    949:            {
                    950:              if (really_private == 0)
                    951:                really_private = 1;
                    952:              else
                    953:                visibility = visibility_protected;
                    954:            }
                    955:          else if (! TREE_VIA_PUBLIC (types))
                    956:            {
                    957:              if (really_private == 0)
                    958:                really_private = 2;
                    959:              else
                    960:                visibility = visibility_private;
                    961:            }
                    962:        }
                    963:     }
                    964: 
                    965:   /* No special visibilities apply.  Use normal rules.
                    966:      No assignment needed for BASETYPEs here from the nreverse.
                    967:      This is because we use it only for information about the
                    968:      path to the base.  The code earlier dealt with what
                    969:      happens when we are at the base level.  */
                    970: 
                    971:   if (visibility == visibility_public)
                    972:     {
                    973:       reverse_path (basetype_path);
                    974:       if (TREE_PRIVATE (field))
                    975:        PRIVATE_RETURN;
                    976:       if (TREE_PROTECTED (field))
                    977:        {
                    978:          /* Used to check if the current class type was derived from
                    979:             the type that contains the field.  This is wrong for
                    980:             multiple inheritance because is gives one class reference
                    981:             to protected members via another classes protected path.
                    982:             I.e., if A; B1 : A; B2 : A;  Then B1 and B2 can access
                    983:             their own members which are protected in A, but not
                    984:             those same members in one another.  */
                    985:          if (current_class_type
                    986:              && UNIQUELY_DERIVED_FROM_P (context, current_class_type))
                    987:            PUBLIC_RETURN;
                    988:          PROTECTED_RETURN;
                    989:        }
                    990:       PUBLIC_RETURN;
                    991:     }
                    992: 
                    993:   if (visibility == visibility_protected)
                    994:     {
                    995:       reverse_path (basetype_path);
                    996: 
                    997:       if (TREE_PRIVATE (field))
                    998:        PRIVATE_RETURN;
                    999:       /* We want to make sure that all non-private members in
                   1000:         the current class (as derived) are accessible.  */
                   1001:       if (current_class_type
                   1002:          && UNIQUELY_DERIVED_FROM_P (context, current_class_type))
                   1003:        PUBLIC_RETURN;
                   1004:       PROTECTED_RETURN;
                   1005:     }
                   1006: 
                   1007:   if (visibility == visibility_private && current_class_type != NULL_TREE)
                   1008:     {
                   1009:       reverse_path (basetype_path);
                   1010: 
                   1011:       /* If it's private in the base class, it stays private.  */
                   1012:       if (TREE_PRIVATE (field))
                   1013:        PRIVATE_RETURN;
                   1014: 
                   1015:       /* ARM $11.2: Specifying a base class private does not affect access
                   1016:         to static members of the base class.  */
                   1017:       if ((TREE_CODE (field) != FUNCTION_DECL
                   1018:           && TREE_STATIC (field))
                   1019:          || (TREE_CODE (field) == FUNCTION_DECL
                   1020:              && DECL_STATIC_FUNCTION_P (field)))
                   1021:        PUBLIC_RETURN;
                   1022: 
                   1023:       /* If it's public or protected in the base class, it becomes
                   1024:         private in the derived class.  If we (the current_class_type)
                   1025:         are not that immediately derived type that gets it as a
                   1026:         private member, then the member is not visibile.  */
                   1027:       if (immediately_derived (context, current_class_type))
                   1028:        PUBLIC_RETURN;
                   1029: 
                   1030:       PRIVATE_RETURN;
                   1031:     }
                   1032: 
                   1033:  ret:
                   1034:   reverse_path (basetype_path);
                   1035: 
                   1036:   if (visibility == visibility_public)
                   1037:     DECL_PUBLIC (field) = 1;
                   1038:   else if (visibility == visibility_protected)
                   1039:     DECL_PROTECTED (field) = 1;
                   1040:   else if (visibility == visibility_private)
                   1041:     DECL_PRIVATE (field) = 1;
                   1042:   else my_friendly_abort (96);
                   1043:   return visibility;
                   1044: }
                   1045: 
                   1046: /* Routine to see if the sub-object denoted by the binfo PARENT can be
                   1047:    found as a base class and sub-object of the object denoted by
                   1048:    BINFO.  This routine relies upon binfos not being shared, except
                   1049:    for binfos for virtual bases.  */
                   1050: static int
                   1051: is_subobject_of_p (parent, binfo)
                   1052:      tree parent, binfo;
                   1053: {
                   1054:   tree binfos = BINFO_BASETYPES (binfo);
                   1055:   int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
                   1056: 
                   1057:   if (parent == binfo)
                   1058:     return 1;
                   1059: 
                   1060:   /* Process and/or queue base types.  */
                   1061:   for (i = 0; i < n_baselinks; i++)
                   1062:     {
                   1063:       tree base_binfo = TREE_VEC_ELT (binfos, i);
                   1064:       if (TREE_VIA_VIRTUAL (base_binfo))
                   1065:        base_binfo = TYPE_BINFO (BINFO_TYPE (base_binfo));
                   1066:       if (is_subobject_of_p (parent, base_binfo))
                   1067:        return 1;
                   1068:     }
                   1069:   return 0;
                   1070: }
                   1071: 
                   1072: /* See if a one FIELD_DECL hides another.  This routine is meant to
                   1073:    correspond to ANSI working paper Sept 17, 1992 10p4.  The two
                   1074:    binfos given are the binfos corresponding to the particular places
                   1075:    the FIELD_DECLs are found.  This routine relies upon binfos not
                   1076:    being shared, except for virtual bases. */
                   1077: static int
                   1078: hides (hider_binfo, hidee_binfo)
                   1079:      tree hider_binfo, hidee_binfo;
                   1080: {
                   1081:   /* hider hides hidee, if hider has hidee as a base class and
                   1082:      the instance of hidee is a sub-object of hider.  The first
                   1083:      part is always true is the second part is true.
                   1084: 
                   1085:      When hider and hidee are the same (two ways to get to the exact
                   1086:      same member) we consider either one as hiding the other. */
                   1087:   return is_subobject_of_p (hidee_binfo, hider_binfo);
                   1088: }
                   1089: 
                   1090: /* Very similar to lookup_fnfields_1 but it ensures that at least one
                   1091:    function was declared inside the class given by TYPE.  It really should
                   1092:    only return functions that match the given TYPE.  */
                   1093: static int
                   1094: lookup_fnfields_here (type, name)
                   1095:      tree type, name;
                   1096: {
                   1097:   int index = lookup_fnfields_1 (type, name);
                   1098:   tree fndecls;
                   1099: 
                   1100:   if (index <= 0)
                   1101:     return index;
                   1102:   fndecls = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), index);
                   1103:   while (fndecls)
                   1104:     {
                   1105:       if (TYPE_MAIN_VARIANT (DECL_CLASS_CONTEXT (fndecls))
                   1106:          == TYPE_MAIN_VARIANT (type))
                   1107:        return index;
                   1108:       fndecls = TREE_CHAIN (fndecls);
                   1109:     }
                   1110:   return -1;
                   1111: }
                   1112: 
                   1113: /* Look for a field named NAME in an inheritance lattice dominated by
                   1114:    XBASETYPE.  PROTECT is zero if we can avoid computing visibility
                   1115:    information, otherwise it is 1.  WANT_TYPE is 1 when we should only
                   1116:    return TYPE_DECLs, if no TYPE_DECL can be found return NULL_TREE.
                   1117: 
                   1118:    It was not clear what should happen if WANT_TYPE is set, and an
                   1119:    ambiguity is found.  At least one use (lookup_name) to not see
                   1120:    the error.  */
                   1121: tree
                   1122: lookup_field (xbasetype, name, protect, want_type)
                   1123:      register tree xbasetype, name;
                   1124:      int protect, want_type;
                   1125: {
                   1126:   int head = 0, tail = 0;
                   1127:   tree rval, rval_binfo = NULL_TREE, rval_binfo_h;
                   1128:   tree type, basetype_chain, basetype_path;
                   1129:   enum visibility_type this_v = visibility_default;
                   1130:   tree entry, binfo, binfo_h;
                   1131:   enum visibility_type own_visibility = visibility_default;
                   1132:   int vbase_name_p = VBASE_NAME_P (name);
                   1133: 
                   1134:   /* rval_binfo is the binfo associated with the found member, note,
                   1135:      this can be set with useful information, even when rval is not
                   1136:      set, because it must deal with ALL members, not just non-function
                   1137:      members.  It is used for ambiguity checking and the hidden
                   1138:      checks.  Whereas rval is only set if a proper (not hidden)
                   1139:      non-function member is found.  */
                   1140: 
                   1141:   /* rval_binfo_h and binfo_h are binfo values used when we perform the
                   1142:      hiding checks, as virtual base classes may not be shared.  The strategy
                   1143:      is we always go into the the binfo hierarchy owned by TYPE_BINFO of
                   1144:      virtual base classes, as we cross virtual base class lines.  This way
                   1145:      we know that binfo of a virtual base class will always == itself when
                   1146:      found along any line.  (mrs)  */
                   1147: 
                   1148:   /* Things for memoization.  */
                   1149:   char *errstr = 0;
                   1150: 
                   1151:   /* Set this to nonzero if we don't know how to compute
                   1152:      accurate error messages for visibility.  */
                   1153:   int index = MEMOIZED_HASH_FN (name);
                   1154: 
                   1155:   /* If we are looking for a constructor in a templated type, use the
                   1156:      unspecialized name, as that is how we store it.  */
                   1157:   if (IDENTIFIER_TEMPLATE (name))
                   1158:     name = constructor_name (name);
                   1159: 
                   1160:   if (TREE_CODE (xbasetype) == TREE_VEC)
                   1161:     basetype_path = xbasetype, type = BINFO_TYPE (xbasetype);
                   1162:   else if (IS_AGGR_TYPE_CODE (TREE_CODE (xbasetype)))
                   1163:     basetype_path = TYPE_BINFO (xbasetype), type = xbasetype;
                   1164:   else my_friendly_abort (97);
                   1165: 
                   1166:   if (CLASSTYPE_MTABLE_ENTRY (type))
                   1167:     {
                   1168:       tree tem = MEMOIZED_FIELDS (CLASSTYPE_MTABLE_ENTRY (type), index);
                   1169: 
                   1170:       while (tem && TREE_PURPOSE (tem) != name)
                   1171:        {
                   1172:          memoized_fields_searched[0]++;
                   1173:          tem = TREE_CHAIN (tem);
                   1174:        }
                   1175:       if (tem)
                   1176:        {
                   1177:          if (protect && TREE_TYPE (tem))
                   1178:            {
                   1179:              error (TREE_STRING_POINTER (TREE_TYPE (tem)),
                   1180:                     IDENTIFIER_POINTER (name),
                   1181:                     TYPE_NAME_STRING (DECL_FIELD_CONTEXT (TREE_VALUE (tem))));
                   1182:              return error_mark_node;
                   1183:            }
                   1184:          if (TREE_VALUE (tem) == NULL_TREE)
                   1185:            memoized_fast_rejects[0] += 1;
                   1186:          else
                   1187:            memoized_fast_finds[0] += 1;
                   1188:          return TREE_VALUE (tem);
                   1189:        }
                   1190:     }
                   1191: 
                   1192: #ifdef GATHER_STATISTICS
                   1193:   n_calls_lookup_field++;
                   1194: #endif
                   1195:   if (protect && flag_memoize_lookups && ! global_bindings_p ())
                   1196:     entry = make_memoized_table_entry (type, name, 0);
                   1197:   else
                   1198:     entry = 0;
                   1199: 
                   1200:   rval = lookup_field_1 (type, name);
                   1201:   if (rval || lookup_fnfields_here (type, name)>=0)
                   1202:     {
                   1203:       rval_binfo = basetype_path;
                   1204:       rval_binfo_h = rval_binfo;
                   1205:     }
                   1206: 
                   1207:   if (rval && TREE_CODE (rval) != TYPE_DECL && want_type)
                   1208:     rval = NULL_TREE;
                   1209: 
                   1210:   if (rval)
                   1211:     {
                   1212:       if (protect)
                   1213:        {
                   1214:          if (TREE_PRIVATE (rval) | TREE_PROTECTED (rval))
                   1215:            this_v = compute_visibility (basetype_path, rval);
                   1216:          if (TREE_CODE (rval) == CONST_DECL)
                   1217:            {
                   1218:              if (this_v == visibility_private)
                   1219:                errstr = "enum `%s' is a private value of class `%s'";
                   1220:              else if (this_v == visibility_protected)
                   1221:                errstr = "enum `%s' is a protected value of class `%s'";
                   1222:            }
                   1223:          else
                   1224:            {
                   1225:              if (this_v == visibility_private)
                   1226:                errstr = "member `%s' is a private member of class `%s'";
                   1227:              else if (this_v == visibility_protected)
                   1228:                errstr = "member `%s' is a protected member of class `%s'";
                   1229:            }
                   1230:        }
                   1231: 
                   1232:       if (entry)
                   1233:        {
                   1234:          if (errstr)
                   1235:            {
                   1236:              /* This depends on behavior of lookup_field_1!  */
                   1237:              tree error_string = my_build_string (errstr);
                   1238:              TREE_TYPE (entry) = error_string;
                   1239:            }
                   1240:          else
                   1241:            {
                   1242:              /* Let entry know there is no problem with this access.  */
                   1243:              TREE_TYPE (entry) = NULL_TREE;
                   1244:            }
                   1245:          TREE_VALUE (entry) = rval;
                   1246:        }
                   1247: 
                   1248:       if (errstr && protect)
                   1249:        {
                   1250:          error (errstr, IDENTIFIER_POINTER (name), TYPE_NAME_STRING (type));
                   1251:          return error_mark_node;
                   1252:        }
                   1253:       return rval;
                   1254:     }
                   1255: 
                   1256:   basetype_chain = CLASSTYPE_BINFO_AS_LIST (type);
                   1257:   TREE_VIA_PUBLIC (basetype_chain) = 1;
                   1258: 
                   1259:   /* The ambiguity check relies upon breadth first searching. */
                   1260: 
                   1261:   search_stack = push_search_level (search_stack, &search_obstack);
                   1262:   BINFO_VIA_PUBLIC (basetype_path) = 1;
                   1263:   BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE;
                   1264:   binfo = basetype_path;
                   1265:   binfo_h = binfo;
                   1266: 
                   1267:   while (1)
                   1268:     {
                   1269:       tree binfos = BINFO_BASETYPES (binfo);
                   1270:       int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
                   1271:       tree nval;
                   1272: 
                   1273:       /* Process and/or queue base types.  */
                   1274:       for (i = 0; i < n_baselinks; i++)
                   1275:        {
                   1276:          tree base_binfo = TREE_VEC_ELT (binfos, i);
                   1277:          if (BINFO_FIELDS_MARKED (base_binfo) == 0)
                   1278:            {
                   1279:              tree btypes;
                   1280: 
                   1281:              SET_BINFO_FIELDS_MARKED (base_binfo);
                   1282:              btypes = my_tree_cons (NULL_TREE, base_binfo, basetype_chain);
                   1283:              TREE_VIA_PUBLIC (btypes) = TREE_VIA_PUBLIC (base_binfo);
                   1284:              TREE_VIA_PROTECTED (btypes) = TREE_VIA_PROTECTED (base_binfo);
                   1285:              TREE_VIA_VIRTUAL (btypes) = TREE_VIA_VIRTUAL (base_binfo);
                   1286:              if (TREE_VIA_VIRTUAL (base_binfo))
                   1287:                btypes = tree_cons (NULL_TREE,
                   1288:                                    TYPE_BINFO (BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo_h), i))),
                   1289:                                    btypes);
                   1290:              else
                   1291:                btypes = tree_cons (NULL_TREE,
                   1292:                                    TREE_VEC_ELT (BINFO_BASETYPES (binfo_h), i),
                   1293:                                    btypes);
                   1294:              obstack_ptr_grow (&search_obstack, btypes);
                   1295:              tail += 1;
                   1296:              if (tail >= search_stack->limit)
                   1297:                my_friendly_abort (98);
                   1298:            }
                   1299:        }
                   1300: 
                   1301:       /* Process head of queue, if one exists.  */
                   1302:       if (head >= tail)
                   1303:        break;
                   1304: 
                   1305:       basetype_chain = search_stack->first[head++];
                   1306:       binfo_h = TREE_VALUE (basetype_chain);
                   1307:       basetype_chain = TREE_CHAIN (basetype_chain);
                   1308:       basetype_path = TREE_VALUE (basetype_chain);
                   1309:       if (TREE_CHAIN (basetype_chain))
                   1310:        BINFO_INHERITANCE_CHAIN (basetype_path) = TREE_VALUE (TREE_CHAIN (basetype_chain));
                   1311:       else
                   1312:        BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE;
                   1313: 
                   1314:       binfo = basetype_path;
                   1315:       type = BINFO_TYPE (binfo);
                   1316: 
                   1317:       /* See if we can find NAME in TYPE.  If RVAL is nonzero,
                   1318:         and we do find NAME in TYPE, verify that such a second
                   1319:         sighting is in fact legal.  */
                   1320: 
                   1321:       nval = lookup_field_1 (type, name);
                   1322: 
                   1323:       if (nval || lookup_fnfields_here (type, name)>=0)
                   1324:        {
                   1325:          if (rval_binfo && hides (rval_binfo_h, binfo_h))
                   1326:            {
                   1327:              /* This is ok, the member found is in rval_binfo, not
                   1328:                 here (binfo). */
                   1329:            }
                   1330:          else if (rval_binfo==NULL_TREE || hides (binfo_h, rval_binfo_h))
                   1331:            {
                   1332:              /* This is ok, the member found is here (binfo), not in
                   1333:                 rval_binfo. */
                   1334:              if (nval)
                   1335:                {
                   1336:                  rval = nval;
                   1337:                  if (entry || protect)
                   1338:                    this_v = compute_visibility (basetype_path, rval);
                   1339:                  /* These may look ambiguous, but they really are not.  */
                   1340:                  if (vbase_name_p)
                   1341:                    break;
                   1342:                }
                   1343:              else
                   1344:                {
                   1345:                  /* Undo finding it before, as something else hides it. */
                   1346:                  rval = NULL_TREE;
                   1347:                }
                   1348:              rval_binfo = binfo;
                   1349:              rval_binfo_h = binfo_h;
                   1350:            }
                   1351:          else
                   1352:            {
                   1353:              /* This is ambiguous. */
                   1354:              errstr = "request for member `%s' is ambiguous";
                   1355:              protect = 2;
                   1356:              break;
                   1357:            }
                   1358:        }
                   1359:     }
                   1360:   {
                   1361:     tree *tp = search_stack->first;
                   1362:     tree *search_tail = tp + tail;
                   1363: 
                   1364:     if (entry)
                   1365:       TREE_VALUE (entry) = rval;
                   1366: 
                   1367:     if (want_type && (rval == NULL_TREE || TREE_CODE (rval) != TYPE_DECL))
                   1368:       {
                   1369:        rval = NULL_TREE;
                   1370:        errstr = 0;
                   1371:       }
                   1372: 
                   1373:     /* If this FIELD_DECL defines its own visibility, deal with that.  */
                   1374:     if (rval && errstr == 0
                   1375:        && ((protect&1) || entry)
                   1376:        && DECL_LANG_SPECIFIC (rval)
                   1377:        && DECL_VISIBILITY (rval))
                   1378:       {
                   1379:        while (tp < search_tail)
                   1380:          {
                   1381:            /* If is possible for one of the derived types on the
                   1382:               path to have defined special visibility for this
                   1383:               field.  Look for such declarations and report an
                   1384:               error if a conflict is found.  */
                   1385:            enum visibility_type new_v;
                   1386: 
                   1387:            if (this_v != visibility_default)
                   1388:              new_v = compute_visibility (TREE_VALUE (TREE_CHAIN (*tp)), rval);
                   1389:            if (this_v != visibility_default && new_v != this_v)
                   1390:              {
                   1391:                errstr = "conflicting visibilities to member `%s'";
                   1392:                this_v = visibility_default;
                   1393:              }
                   1394:            own_visibility = new_v;
                   1395:            CLEAR_BINFO_FIELDS_MARKED (TREE_VALUE (TREE_CHAIN (*tp)));
                   1396:            tp += 1;
                   1397:          }
                   1398:       }
                   1399:     else
                   1400:       {
                   1401:        while (tp < search_tail)
                   1402:          {
                   1403:            CLEAR_BINFO_FIELDS_MARKED (TREE_VALUE (TREE_CHAIN (*tp)));
                   1404:            tp += 1;
                   1405:          }
                   1406:       }
                   1407:   }
                   1408:   search_stack = pop_search_level (search_stack);
                   1409: 
                   1410:   if (errstr == 0)
                   1411:     {
                   1412:       if (own_visibility == visibility_private)
                   1413:        errstr = "member `%s' declared private";
                   1414:       else if (own_visibility == visibility_protected)
                   1415:        errstr = "member `%s' declared protected";
                   1416:       else if (this_v == visibility_private)
                   1417:        errstr = TREE_PRIVATE (rval)
                   1418:          ? "member `%s' is private"
                   1419:            : "member `%s' is from private base class";
                   1420:       else if (this_v == visibility_protected)
                   1421:        errstr = TREE_PROTECTED (rval)
                   1422:          ? "member `%s' is protected"
                   1423:            : "member `%s' is from protected base class";
                   1424:     }
                   1425: 
                   1426:   if (entry)
                   1427:     {
                   1428:       if (errstr)
                   1429:        {
                   1430:          tree error_string = my_build_string (errstr);
                   1431:          /* Save error message with entry.  */
                   1432:          TREE_TYPE (entry) = error_string;
                   1433:        }
                   1434:       else
                   1435:        {
                   1436:          /* Mark entry as having no error string.  */
                   1437:          TREE_TYPE (entry) = NULL_TREE;
                   1438:        }
                   1439:     }
                   1440: 
                   1441:   if (errstr && protect)
                   1442:     {
                   1443:       char *p = IDENTIFIER_POINTER (name), *q = NULL;
                   1444:       if (IDENTIFIER_OPNAME_P (name))
                   1445:        {
                   1446:          q = operator_name_string (name);
                   1447:          p = (char *) xmalloc (9 + strlen (q) + 1);
                   1448:          sprintf (p, "operator %s", q);
                   1449:        }
                   1450: 
                   1451:       error (errstr, p, TYPE_NAME_STRING (type));
                   1452:       if (q)
                   1453:        free (p);
                   1454:       rval = error_mark_node;
                   1455:     }
                   1456:   return rval;
                   1457: }
                   1458: 
                   1459: /* Try to find NAME inside a nested class.  */
                   1460: tree
                   1461: lookup_nested_field (name, complain)
                   1462:      tree name;
                   1463:      int complain;
                   1464: {
                   1465:   register tree t;
                   1466: 
                   1467:   tree id = NULL_TREE;
                   1468:   if (TREE_CHAIN (current_class_type))
                   1469:     {
                   1470:       /* Climb our way up the nested ladder, seeing if we're trying to
                   1471:         modify a field in an enclosing class.  If so, we should only
                   1472:         be able to modify if it's static.  */
                   1473:       for (t = TREE_CHAIN (current_class_type);
                   1474:           t && DECL_CONTEXT (t);
                   1475:           t = TREE_CHAIN (DECL_CONTEXT (t)))
                   1476:        {
                   1477:          if (TREE_CODE (DECL_CONTEXT (t)) != RECORD_TYPE)
                   1478:            break;
                   1479: 
                   1480:          /* N.B.: lookup_field will do the visibility checking for us */
                   1481:          id = lookup_field (DECL_CONTEXT (t), name, complain, 0);
                   1482:          if (id == error_mark_node)
                   1483:            {
                   1484:              id = NULL_TREE;
                   1485:              continue;
                   1486:            }
                   1487: 
                   1488:          if (id != NULL_TREE)
                   1489:            {
                   1490:              if (TREE_CODE (id) == FIELD_DECL
                   1491:                  && ! TREE_STATIC (id)
                   1492:                  && TREE_TYPE (id) != error_mark_node)
                   1493:                {
                   1494:                  if (complain)
                   1495:                    {
                   1496:                      /* At parse time, we don't want to give this error, since
                   1497:                         we won't have enough state to make this kind of
                   1498:                         decision properly.  But there are times (e.g., with
                   1499:                         enums in nested classes) when we do need to call
                   1500:                         this fn at parse time.  So, in those cases, we pass
                   1501:                         complain as a 0 and just return a NULL_TREE.  */
                   1502:                      error ("assignment to non-static member `%s' of enclosing class `%s'",
                   1503:                             lang_printable_name (id),
                   1504:                             IDENTIFIER_POINTER (TYPE_IDENTIFIER
                   1505:                                                 (DECL_CONTEXT (t))));
                   1506:                      /* Mark this for do_identifier().  It would otherwise
                   1507:                         claim that the variable was undeclared.  */
                   1508:                      TREE_TYPE (id) = error_mark_node;
                   1509:                    }
                   1510:                  else
                   1511:                    {
                   1512:                      id = NULL_TREE;
                   1513:                      continue;
                   1514:                    }
                   1515:                }
                   1516:              break;
                   1517:            }
                   1518:        }
                   1519:     }
                   1520: 
                   1521:   return id;
                   1522: }
                   1523: 
                   1524: /* TYPE is a class type. Return the index of the fields within
                   1525:    the method vector with name NAME, or -1 is no such field exists.  */
                   1526: static int
                   1527: lookup_fnfields_1 (type, name)
                   1528:      tree type, name;
                   1529: {
                   1530:   register tree method_vec = CLASSTYPE_METHOD_VEC (type);
                   1531: 
                   1532:   if (method_vec != 0)
                   1533:     {
                   1534:       register tree *methods = &TREE_VEC_ELT (method_vec, 0);
                   1535:       register tree *end = TREE_VEC_END (method_vec);
                   1536: 
                   1537: #ifdef GATHER_STATISTICS
                   1538:       n_calls_lookup_fnfields_1++;
                   1539: #endif
                   1540:       if (*methods && name == constructor_name (type))
                   1541:        return 0;
                   1542: 
                   1543:       while (++methods != end)
                   1544:        {
                   1545: #ifdef GATHER_STATISTICS
                   1546:          n_outer_fields_searched++;
                   1547: #endif
                   1548:          if (DECL_NAME (*methods) == name)
                   1549:            break;
                   1550:        }
                   1551:       if (methods != end)
                   1552:        return methods - &TREE_VEC_ELT (method_vec, 0);
                   1553:     }
                   1554: 
                   1555:   return -1;
                   1556: }
                   1557: 
                   1558: /* Starting from BASETYPE, return a TREE_BASELINK-like object
                   1559:    which gives the following information (in a list):
                   1560: 
                   1561:    TREE_TYPE: list of basetypes needed to get to...
                   1562:    TREE_VALUE: list of all functions in of given type
                   1563:    which have name NAME.
                   1564: 
                   1565:    No visibility information is computed by this function,
                   1566:    other then to adorn the list of basetypes with
                   1567:    TREE_VIA_PUBLIC.
                   1568: 
                   1569:    If there are two ways to find a name (two members), if COMPLAIN is
                   1570:    non-zero, then error_mark_node is returned, and an error message is
                   1571:    printed, otherwise, just an error_mark_node is returned.
                   1572: 
                   1573:    As a special case, is COMPLAIN is -1, we don't complain, and we
                   1574:    don't return error_mark_node, but rather the complete list of
                   1575:    virtuals.  This is used by get_virtuals_named_this.  */
                   1576: tree
                   1577: lookup_fnfields (basetype_path, name, complain)
                   1578:      tree basetype_path, name;
                   1579:      int complain;
                   1580: {
                   1581:   int head = 0, tail = 0;
                   1582:   tree type, rval, rval_binfo = NULL_TREE, rvals = NULL_TREE, rval_binfo_h;
                   1583:   tree entry, binfo, basetype_chain, binfo_h;
                   1584:   int find_all = 0;
                   1585: 
                   1586:   /* rval_binfo is the binfo associated with the found member, note,
                   1587:      this can be set with useful information, even when rval is not
                   1588:      set, because it must deal with ALL members, not just function
                   1589:      members.  It is used for ambiguity checking and the hidden
                   1590:      checks.  Whereas rval is only set if a proper (not hidden)
                   1591:      function member is found.  */
                   1592: 
                   1593:   /* rval_binfo_h and binfo_h are binfo values used when we perform the
                   1594:      hiding checks, as virtual base classes may not be shared.  The strategy
                   1595:      is we always go into the the binfo hierarchy owned by TYPE_BINFO of
                   1596:      virtual base classes, as we cross virtual base class lines.  This way
                   1597:      we know that binfo of a virtual base class will always == itself when
                   1598:      found along any line.  (mrs)  */
                   1599: 
                   1600:   /* For now, don't try this.  */
                   1601:   int protect = complain;
                   1602: 
                   1603:   /* Things for memoization.  */
                   1604:   char *errstr = 0;
                   1605: 
                   1606:   /* Set this to nonzero if we don't know how to compute
                   1607:      accurate error messages for visibility.  */
                   1608:   int index = MEMOIZED_HASH_FN (name);
                   1609: 
                   1610:   if (complain == -1)
                   1611:     {
                   1612:       find_all = 1;
                   1613:       protect = complain = 0;
                   1614:     }
                   1615: 
                   1616:   /* If we are looking for a constructor in a templated type, use the
                   1617:      unspecialized name, as that is how we store it.  */
                   1618:   if (IDENTIFIER_TEMPLATE (name))
                   1619:     name = constructor_name (name);
                   1620: 
                   1621:   binfo = basetype_path;
                   1622:   binfo_h = binfo;
                   1623:   type = BINFO_TYPE (basetype_path);
                   1624: 
                   1625:   /* The memoization code is in need of maintenance. */
                   1626:   if (!find_all && CLASSTYPE_MTABLE_ENTRY (type))
                   1627:     {
                   1628:       tree tem = MEMOIZED_FNFIELDS (CLASSTYPE_MTABLE_ENTRY (type), index);
                   1629: 
                   1630:       while (tem && TREE_PURPOSE (tem) != name)
                   1631:        {
                   1632:          memoized_fields_searched[1]++;
                   1633:          tem = TREE_CHAIN (tem);
                   1634:        }
                   1635:       if (tem)
                   1636:        {
                   1637:          if (protect && TREE_TYPE (tem))
                   1638:            {
                   1639:              error (TREE_STRING_POINTER (TREE_TYPE (tem)),
                   1640:                     IDENTIFIER_POINTER (name),
                   1641:                     TYPE_NAME_STRING (DECL_CLASS_CONTEXT (TREE_VALUE (TREE_VALUE (tem)))));
                   1642:              return error_mark_node;
                   1643:            }
                   1644:          if (TREE_VALUE (tem) == NULL_TREE)
                   1645:            {
                   1646:              memoized_fast_rejects[1] += 1;
                   1647:              return NULL_TREE;
                   1648:            }
                   1649:          else
                   1650:            {
                   1651:              /* Want to return this, but we must make sure
                   1652:                 that visibility information is consistent.  */
                   1653:              tree baselink = TREE_VALUE (tem);
                   1654:              tree memoized_basetypes = TREE_PURPOSE (baselink);
                   1655:              tree these_basetypes = basetype_path;
                   1656:              while (memoized_basetypes && these_basetypes)
                   1657:                {
                   1658:                  memoized_fields_searched[1]++;
                   1659:                  if (TREE_VALUE (memoized_basetypes) != these_basetypes)
                   1660:                    break;
                   1661:                  memoized_basetypes = TREE_CHAIN (memoized_basetypes);
                   1662:                  these_basetypes = BINFO_INHERITANCE_CHAIN (these_basetypes);
                   1663:                }
                   1664:              /* The following statement is true only when both are NULL.  */
                   1665:              if (memoized_basetypes == these_basetypes)
                   1666:                {
                   1667:                  memoized_fast_finds[1] += 1;
                   1668:                  return TREE_VALUE (tem);
                   1669:                }
                   1670:              /* else, we must re-find this field by hand.  */
                   1671:              baselink = tree_cons (basetype_path, TREE_VALUE (baselink), TREE_CHAIN (baselink));
                   1672:              return baselink;
                   1673:            }
                   1674:        }
                   1675:     }
                   1676: 
                   1677: #ifdef GATHER_STATISTICS
                   1678:   n_calls_lookup_fnfields++;
                   1679: #endif
                   1680:   if (protect && flag_memoize_lookups && ! global_bindings_p ())
                   1681:     entry = make_memoized_table_entry (type, name, 1);
                   1682:   else
                   1683:     entry = 0;
                   1684: 
                   1685:   index = lookup_fnfields_here (type, name);
                   1686:   if (index >= 0 || lookup_field_1 (type, name))
                   1687:     {
                   1688:       rval_binfo = basetype_path;
                   1689:       rval_binfo_h = rval_binfo;
                   1690:     }
                   1691: 
                   1692:   if (index >= 0)
                   1693:     {
                   1694:       rval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), index);
                   1695:       rvals = my_tree_cons (basetype_path, rval, rvals);
                   1696:       if (BINFO_BASETYPES (binfo) && CLASSTYPE_BASELINK_VEC (type))
                   1697:        TREE_TYPE (rvals) = TREE_VEC_ELT (CLASSTYPE_BASELINK_VEC (type), index);
                   1698: 
                   1699:       if (entry)
                   1700:        {
                   1701:          TREE_VALUE (entry) = rvals;
                   1702:          TREE_TYPE (entry) = NULL_TREE;
                   1703:        }
                   1704: 
                   1705:       if (errstr && protect)
                   1706:        {
                   1707:          error (errstr, IDENTIFIER_POINTER (name), TYPE_NAME_STRING (type));
                   1708:          return error_mark_node;
                   1709:        }
                   1710:       return rvals;
                   1711:     }
                   1712:   rval = NULL_TREE;
                   1713: 
                   1714:   basetype_chain = CLASSTYPE_BINFO_AS_LIST (type);
                   1715:   TREE_VIA_PUBLIC (basetype_chain) = 1;
                   1716: 
                   1717:   /* The ambiguity check relies upon breadth first searching. */
                   1718: 
                   1719:   search_stack = push_search_level (search_stack, &search_obstack);
                   1720:   BINFO_VIA_PUBLIC (basetype_path) = 1;
                   1721:   BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE;
                   1722:   binfo = basetype_path;
                   1723:   binfo_h = binfo;
                   1724: 
                   1725:   while (1)
                   1726:     {
                   1727:       tree binfos = BINFO_BASETYPES (binfo);
                   1728:       int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
                   1729:       int index;
                   1730: 
                   1731:       /* Process and/or queue base types.  */
                   1732:       for (i = 0; i < n_baselinks; i++)
                   1733:        {
                   1734:          tree base_binfo = TREE_VEC_ELT (binfos, i);
                   1735:          if (BINFO_FIELDS_MARKED (base_binfo) == 0)
                   1736:            {
                   1737:              tree btypes;
                   1738: 
                   1739:              SET_BINFO_FIELDS_MARKED (base_binfo);
                   1740:              btypes = my_tree_cons (NULL_TREE, base_binfo, basetype_chain);
                   1741:              TREE_VIA_PUBLIC (btypes) = TREE_VIA_PUBLIC (base_binfo);
                   1742:              TREE_VIA_PROTECTED (btypes) = TREE_VIA_PROTECTED (base_binfo);
                   1743:              TREE_VIA_VIRTUAL (btypes) = TREE_VIA_VIRTUAL (base_binfo);
                   1744:              if (TREE_VIA_VIRTUAL (base_binfo))
                   1745:                btypes = tree_cons (NULL_TREE,
                   1746:                                    TYPE_BINFO (BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo_h), i))),
                   1747:                                    btypes);
                   1748:              else
                   1749:                btypes = tree_cons (NULL_TREE,
                   1750:                                    TREE_VEC_ELT (BINFO_BASETYPES (binfo_h), i),
                   1751:                                    btypes);
                   1752:              obstack_ptr_grow (&search_obstack, btypes);
                   1753:              tail += 1;
                   1754:              if (tail >= search_stack->limit)
                   1755:                my_friendly_abort (99);
                   1756:            }
                   1757:        }
                   1758: 
                   1759:       /* Process head of queue, if one exists.  */
                   1760:       if (head >= tail)
                   1761:        break;
                   1762: 
                   1763:       basetype_chain = search_stack->first[head++];
                   1764:       binfo_h = TREE_VALUE (basetype_chain);
                   1765:       basetype_chain = TREE_CHAIN (basetype_chain);
                   1766:       basetype_path = TREE_VALUE (basetype_chain);
                   1767:       if (TREE_CHAIN (basetype_chain))
                   1768:        BINFO_INHERITANCE_CHAIN (basetype_path) = TREE_VALUE (TREE_CHAIN (basetype_chain));
                   1769:       else
                   1770:        BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE;
                   1771: 
                   1772:       binfo = basetype_path;
                   1773:       type = BINFO_TYPE (binfo);
                   1774: 
                   1775:       /* See if we can find NAME in TYPE.  If RVAL is nonzero,
                   1776:         and we do find NAME in TYPE, verify that such a second
                   1777:         sighting is in fact legal.  */
                   1778: 
                   1779:       index = lookup_fnfields_here (type, name);
                   1780: 
                   1781:       if (index >= 0 || (lookup_field_1 (type, name)!=NULL_TREE && !find_all))
                   1782:        {
                   1783:          if (rval_binfo && !find_all && hides (rval_binfo_h, binfo_h))
                   1784:            {
                   1785:              /* This is ok, the member found is in rval_binfo, not
                   1786:                 here (binfo). */
                   1787:            }
                   1788:          else if (rval_binfo==NULL_TREE || find_all || hides (binfo_h, rval_binfo_h))
                   1789:            {
                   1790:              /* This is ok, the member found is here (binfo), not in
                   1791:                 rval_binfo. */
                   1792:              if (index >= 0)
                   1793:                {
                   1794:                  rval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), index);
                   1795:                  /* Note, rvals can only be previously set if find_all is
                   1796:                     true.  */
                   1797:                  rvals = my_tree_cons (basetype_path, rval, rvals);
                   1798:                  if (TYPE_BINFO_BASETYPES (type)
                   1799:                      && CLASSTYPE_BASELINK_VEC (type))
                   1800:                    TREE_TYPE (rvals) = TREE_VEC_ELT (CLASSTYPE_BASELINK_VEC (type), index);
                   1801:                }
                   1802:              else
                   1803:                {
                   1804:                  /* Undo finding it before, as something else hides it. */
                   1805:                  rval = NULL_TREE;
                   1806:                  rvals = NULL_TREE;
                   1807:                }
                   1808:              rval_binfo = binfo;
                   1809:              rval_binfo_h = binfo_h;
                   1810:            }
                   1811:          else
                   1812:            {
                   1813:              /* This is ambiguous. */
                   1814:              errstr = "request for member `%s' is ambiguous";
                   1815:              rvals = error_mark_node;
                   1816:              break;
                   1817:            }
                   1818:        }
                   1819:     }
                   1820:   {
                   1821:     tree *tp = search_stack->first;
                   1822:     tree *search_tail = tp + tail;
                   1823: 
                   1824:     while (tp < search_tail)
                   1825:       {
                   1826:        CLEAR_BINFO_FIELDS_MARKED (TREE_VALUE (TREE_CHAIN (*tp)));
                   1827:        tp += 1;
                   1828:       }
                   1829:   }
                   1830:   search_stack = pop_search_level (search_stack);
                   1831: 
                   1832:   if (entry)
                   1833:     {
                   1834:       if (errstr)
                   1835:        {
                   1836:          tree error_string = my_build_string (errstr);
                   1837:          /* Save error message with entry.  */
                   1838:          TREE_TYPE (entry) = error_string;
                   1839:        }
                   1840:       else
                   1841:        {
                   1842:          /* Mark entry as having no error string.  */
                   1843:          TREE_TYPE (entry) = NULL_TREE;
                   1844:          TREE_VALUE (entry) = rvals;
                   1845:        }
                   1846:     }
                   1847: 
                   1848:   if (errstr && protect)
                   1849:     {
                   1850:       error (errstr, IDENTIFIER_POINTER (name), TYPE_NAME_STRING (type));
                   1851:       rvals = error_mark_node;
                   1852:     }
                   1853: 
                   1854:   return rvals;
                   1855: }
                   1856: 
                   1857: /* BREADTH-FIRST SEARCH ROUTINES.  */
                   1858: 
                   1859: /* Search a multiple inheritance hierarchy by breadth-first search.
                   1860: 
                   1861:    TYPE is an aggregate type, possibly in a multiple-inheritance hierarchy.
                   1862:    TESTFN is a function, which, if true, means that our condition has been met,
                   1863:    and its return value should be returned.
                   1864:    QFN, if non-NULL, is a predicate dictating whether the type should
                   1865:    even be queued.  */
                   1866: 
                   1867: HOST_WIDE_INT
                   1868: breadth_first_search (binfo, testfn, qfn)
                   1869:      tree binfo;
                   1870:      int (*testfn)();
                   1871:      int (*qfn)();
                   1872: {
                   1873:   int head = 0, tail = 0;
                   1874:   int rval = 0;
                   1875: 
                   1876:   search_stack = push_search_level (search_stack, &search_obstack);
                   1877: 
                   1878:   while (1)
                   1879:     {
                   1880:       tree binfos = BINFO_BASETYPES (binfo);
                   1881:       int n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
                   1882:       int i;
                   1883: 
                   1884:       /* Process and/or queue base types.  */
                   1885:       for (i = 0; i < n_baselinks; i++)
                   1886:        {
                   1887:          tree base_binfo = TREE_VEC_ELT (binfos, i);
                   1888: 
                   1889:          if (BINFO_MARKED (base_binfo) == 0
                   1890:              && (qfn == 0 || (*qfn) (binfo, i)))
                   1891:            {
                   1892:              SET_BINFO_MARKED (base_binfo);
                   1893:              obstack_ptr_grow (&search_obstack, binfo);
                   1894:              obstack_ptr_grow (&search_obstack, (HOST_WIDE_INT) i);
                   1895:              tail += 2;
                   1896:              if (tail >= search_stack->limit)
                   1897:                my_friendly_abort (100);
                   1898:            }
                   1899:        }
                   1900:       /* Process head of queue, if one exists.  */
                   1901:       if (head >= tail)
                   1902:        {
                   1903:          rval = 0;
                   1904:          break;
                   1905:        }
                   1906: 
                   1907:       binfo = search_stack->first[head++];
                   1908:       i = (HOST_WIDE_INT) search_stack->first[head++];
                   1909:       if (rval = (*testfn) (binfo, i))
                   1910:        break;
                   1911:       binfo = BINFO_BASETYPE (binfo, i);
                   1912:     }
                   1913:   {
                   1914:     tree *tp = search_stack->first;
                   1915:     tree *search_tail = tp + tail;
                   1916:     while (tp < search_tail)
                   1917:       {
                   1918:        tree binfo = *tp++;
                   1919:        int i = (HOST_WIDE_INT)(*tp++);
                   1920:        CLEAR_BINFO_MARKED (BINFO_BASETYPE (binfo, i));
                   1921:       }
                   1922:   }
                   1923: 
                   1924:   search_stack = pop_search_level (search_stack);
                   1925:   return rval;
                   1926: }
                   1927: 
                   1928: /* Functions to use in breadth first searches.  */
                   1929: typedef tree (*pft)();
                   1930: typedef int (*pfi)();
                   1931: 
                   1932: int tree_needs_constructor_p (binfo, i)
                   1933:      tree binfo;
                   1934:      int i;
                   1935: {
                   1936:   tree basetype;
                   1937:   my_friendly_assert (i != 0, 296);
                   1938:   basetype = BINFO_TYPE (BINFO_BASETYPE (binfo, i));
                   1939:   return TYPE_NEEDS_CONSTRUCTOR (basetype);
                   1940: }
                   1941: 
                   1942: static tree declarator;
                   1943: 
                   1944: static tree
                   1945: get_virtuals_named_this (binfo)
                   1946:      tree binfo;
                   1947: {
                   1948:   tree fields;
                   1949: 
                   1950:   fields = lookup_fnfields (binfo, declarator, -1);
                   1951:   /* fields cannot be error_mark_node */
                   1952: 
                   1953:   if (fields == 0)
                   1954:     return 0;
                   1955: 
                   1956:   /* Get to the function decls, and return the first virtual function
                   1957:      with this name, if there is one.  */
                   1958:   while (fields)
                   1959:     {
                   1960:       tree fndecl;
                   1961: 
                   1962:       for (fndecl = TREE_VALUE (fields); fndecl; fndecl = DECL_CHAIN (fndecl))
                   1963:        if (DECL_VINDEX (fndecl))
                   1964:          return fields;
                   1965:       fields = next_baselink (fields);
                   1966:     }
                   1967:   return NULL_TREE;
                   1968: }
                   1969: 
                   1970: static tree get_virtual_destructor (binfo, i)
                   1971:      tree binfo;
                   1972:      int i;
                   1973: {
                   1974:   tree type = BINFO_TYPE (binfo);
                   1975:   if (i >= 0)
                   1976:     type = BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo), i));
                   1977:   if (TYPE_HAS_DESTRUCTOR (type)
                   1978:       && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 0)))
                   1979:     return TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 0);
                   1980:   return 0;
                   1981: }
                   1982: 
                   1983: int tree_has_any_destructor_p (binfo, i)
                   1984:      tree binfo;
                   1985:      int i;
                   1986: {
                   1987:   tree type = BINFO_TYPE (binfo);
                   1988:   if (i >= 0)
                   1989:     type = BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo), i));
                   1990:   return TYPE_NEEDS_DESTRUCTOR (type);
                   1991: }
                   1992: 
                   1993: /* Given a class type TYPE, and a function decl FNDECL,
                   1994:    look for the first function the TYPE's hierarchy which
                   1995:    FNDECL could match as a virtual function.
                   1996: 
                   1997:    DTORP is nonzero if we are looking for a destructor.  Destructors
                   1998:    need special treatment because they do not match by name.  */
                   1999: tree
                   2000: get_first_matching_virtual (binfo, fndecl, dtorp)
                   2001:      tree binfo, fndecl;
                   2002:      int dtorp;
                   2003: {
                   2004:   tree tmp = NULL_TREE;
                   2005: 
                   2006:   /* Breadth first search routines start searching basetypes
                   2007:      of TYPE, so we must perform first ply of search here.  */
                   2008:   if (dtorp)
                   2009:     {
                   2010:       if (tree_has_any_destructor_p (binfo, -1))
                   2011:        tmp = get_virtual_destructor (binfo, -1);
                   2012: 
                   2013:       if (tmp)
                   2014:        {
                   2015:          if (get_base_distance (DECL_CONTEXT (tmp),
                   2016:                                 DECL_CONTEXT (fndecl), 0, 0) > 0)
                   2017:            DECL_CONTEXT (fndecl) = DECL_CONTEXT (tmp);
                   2018:          return tmp;
                   2019:        }
                   2020: 
                   2021:       tmp = (tree) breadth_first_search (binfo,
                   2022:                                         (pfi) get_virtual_destructor,
                   2023:                                         tree_has_any_destructor_p);
                   2024:       if (tmp)
                   2025:        {
                   2026:          if (get_base_distance (DECL_CONTEXT (tmp),
                   2027:                                 DECL_CONTEXT (fndecl), 0, 0) > 0)
                   2028:            DECL_CONTEXT (fndecl) = DECL_CONTEXT (tmp);
                   2029:        }
                   2030:       return tmp;
                   2031:     }
                   2032:   else
                   2033:     {
                   2034:       tree drettype, dtypes, btypes, instptr_type;
                   2035:       tree basetype = DECL_CLASS_CONTEXT (fndecl);
                   2036:       tree baselink, best = NULL_TREE;
                   2037:       tree name = DECL_ASSEMBLER_NAME (fndecl);
                   2038: 
                   2039:       declarator = DECL_NAME (fndecl);
                   2040:       if (IDENTIFIER_VIRTUAL_P (declarator) == 0)
                   2041:        return NULL_TREE;
                   2042: 
                   2043:       drettype = TREE_TYPE (TREE_TYPE (fndecl));
                   2044:       dtypes = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
                   2045:       if (DECL_STATIC_FUNCTION_P (fndecl))
                   2046:        instptr_type = NULL_TREE;
                   2047:       else
                   2048:        instptr_type = TREE_TYPE (TREE_VALUE (dtypes));
                   2049: 
                   2050:       for (baselink = get_virtuals_named_this (binfo);
                   2051:           baselink; baselink = next_baselink (baselink))
                   2052:        {
                   2053:          for (tmp = TREE_VALUE (baselink); tmp; tmp = DECL_CHAIN (tmp))
                   2054:            {
                   2055:              if (! DECL_VINDEX (tmp))
                   2056:                continue;
                   2057: 
                   2058:              btypes = TYPE_ARG_TYPES (TREE_TYPE (tmp));
                   2059:              if (instptr_type == NULL_TREE)
                   2060:                {
                   2061:                  if (compparms (TREE_CHAIN (btypes), dtypes, 3))
                   2062:                    /* Caller knows to give error in this case.  */
                   2063:                    return tmp;
                   2064:                  return NULL_TREE;
                   2065:                }
                   2066: 
                   2067:              if ((TYPE_READONLY (TREE_TYPE (TREE_VALUE (btypes)))
                   2068:                   == TYPE_READONLY (instptr_type))
                   2069:                  && compparms (TREE_CHAIN (btypes), TREE_CHAIN (dtypes), 3))
                   2070:                {
                   2071:                  if (IDENTIFIER_ERROR_LOCUS (name) == NULL_TREE
                   2072:                      && ! comptypes (TREE_TYPE (TREE_TYPE (tmp)), drettype, 1))
                   2073:                    {
                   2074:                      cp_error ("conflicting return type specified for virtual function `%D'", fndecl);
                   2075:                      SET_IDENTIFIER_ERROR_LOCUS (name, basetype);
                   2076:                    }
                   2077:                  break;
                   2078:                }
                   2079:            }
                   2080:          if (tmp)
                   2081:            {
                   2082:              /* If this is ambiguous, we will warn about it later.  */
                   2083:              if (best)
                   2084:                {
                   2085:                  if (get_base_distance (DECL_CLASS_CONTEXT (best),
                   2086:                                         DECL_CLASS_CONTEXT (tmp), 0, 0) > 0)
                   2087:                    best = tmp;
                   2088:                }
                   2089:              else
                   2090:                best = tmp;
                   2091:            }
                   2092:        }
                   2093:       if (best == NULL_TREE && warn_overloaded_virtual)
                   2094:        cp_warning_at ("conflicting specification deriving virtual function `%D'", fndecl);
                   2095: 
                   2096:       if (best)
                   2097:        {
                   2098:          if (get_base_distance (DECL_CONTEXT (best),
                   2099:                                 DECL_CONTEXT (fndecl), 0, 0) > 0)
                   2100:            DECL_CONTEXT (fndecl) = DECL_CONTEXT (best);
                   2101:        }
                   2102:       return best;
                   2103:     }
                   2104: }
                   2105: 
                   2106: /* Return the list of virtual functions which are abstract in type TYPE.
                   2107:    This information is cached, and so must be built on a
                   2108:    non-temporary obstack.  */
                   2109: tree
                   2110: get_abstract_virtuals (type)
                   2111:      tree type;
                   2112: {
                   2113:   /* For each layer of base class (i.e., the first base class, and each
                   2114:      virtual base class from that one), modify the virtual function table
                   2115:      of the derived class to contain the new virtual function.
                   2116:      A class has as many vfields as it has virtual base classes (total).  */
                   2117:   tree vfields, vbases, base, tmp;
                   2118:   tree vfield = CLASSTYPE_VFIELD (type);
                   2119:   tree fcontext = vfield ? DECL_FCONTEXT (vfield) : NULL_TREE;
                   2120:   tree abstract_virtuals = CLASSTYPE_ABSTRACT_VIRTUALS (type);
                   2121: 
                   2122:   for (vfields = CLASSTYPE_VFIELDS (type); vfields; vfields = TREE_CHAIN (vfields))
                   2123:     {
                   2124:       int normal;
                   2125: 
                   2126:       /* This code is most likely wrong, and probably only works for single
                   2127:         inheritance or by accident. */
                   2128: 
                   2129:       /* Find the right base class for this derived class, call it BASE.  */
                   2130:       base = VF_BASETYPE_VALUE (vfields);
                   2131:       if (base == type)
                   2132:        continue;
                   2133: 
                   2134:       /* We call this case NORMAL iff this virtual function table
                   2135:         pointer field has its storage reserved in this class.
                   2136:         This is normally the case without virtual baseclasses
                   2137:         or off-center multiple baseclasses.  */
                   2138:       normal = (base == fcontext
                   2139:                && (VF_BINFO_VALUE (vfields) == NULL_TREE
                   2140:                    || ! TREE_VIA_VIRTUAL (VF_BINFO_VALUE (vfields))));
                   2141: 
                   2142:       if (normal)
                   2143:        tmp = TREE_CHAIN (TYPE_BINFO_VIRTUALS (type));
                   2144:       else
                   2145:        {
                   2146:          /* n.b.: VF_BASETYPE_VALUE (vfields) is the first basetype
                   2147:             that provides the virtual function table, whereas
                   2148:             VF_DERIVED_VALUE (vfields) is an immediate base type of TYPE
                   2149:             that dominates VF_BASETYPE_VALUE (vfields).  The list of
                   2150:             vfields we want lies between these two values.  */
                   2151:          tree binfo = get_binfo (VF_NORMAL_VALUE (vfields), type, 0);
                   2152:          tmp = TREE_CHAIN (BINFO_VIRTUALS (binfo));
                   2153:        }
                   2154: 
                   2155:       /* Get around dossier entry if there is one.  */
                   2156:       if (flag_dossier)
                   2157:        tmp = TREE_CHAIN (tmp);
                   2158: 
                   2159:       while (tmp)
                   2160:        {
                   2161:          tree base_pfn = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (tmp));
                   2162:          tree base_fndecl = TREE_OPERAND (base_pfn, 0);
                   2163:          if (DECL_ABSTRACT_VIRTUAL_P (base_fndecl))
                   2164:            abstract_virtuals = tree_cons (NULL_TREE, base_fndecl, abstract_virtuals);
                   2165:          tmp = TREE_CHAIN (tmp);
                   2166:        }
                   2167:     }
                   2168:   for (vbases = CLASSTYPE_VBASECLASSES (type); vbases; vbases = TREE_CHAIN (vbases))
                   2169:     {
                   2170:       if (! BINFO_VIRTUALS (vbases))
                   2171:        continue;
                   2172: 
                   2173:       tmp = TREE_CHAIN (BINFO_VIRTUALS (vbases));
                   2174:       while (tmp)
                   2175:        {
                   2176:          tree base_pfn = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (tmp));
                   2177:          tree base_fndecl = TREE_OPERAND (base_pfn, 0);
                   2178:          if (DECL_ABSTRACT_VIRTUAL_P (base_fndecl))
                   2179:            abstract_virtuals = tree_cons (NULL_TREE, base_fndecl, abstract_virtuals);
                   2180:          tmp = TREE_CHAIN (tmp);
                   2181:        }
                   2182:     }
                   2183:   return nreverse (abstract_virtuals);
                   2184: }
                   2185: 
                   2186: /* For the type TYPE, return a list of member functions available from
                   2187:    base classes with name NAME.  The TREE_VALUE of the list is a chain of
                   2188:    member functions with name NAME.  The TREE_PURPOSE of the list is a
                   2189:    basetype, or a list of base types (in reverse order) which were
                   2190:    traversed to reach the chain of member functions.  If we reach a base
                   2191:    type which provides a member function of name NAME, and which has at
                   2192:    most one base type itself, then we can terminate the search.  */
                   2193: 
                   2194: tree
                   2195: get_baselinks (type_as_binfo_list, type, name)
                   2196:      tree type_as_binfo_list;
                   2197:      tree type, name;
                   2198: {
                   2199:   int head = 0, tail = 0, index;
                   2200:   tree rval = 0, nval = 0;
                   2201:   tree basetypes = type_as_binfo_list;
                   2202:   tree binfo = TYPE_BINFO (type);
                   2203: 
                   2204:   search_stack = push_search_level (search_stack, &search_obstack);
                   2205: 
                   2206:   while (1)
                   2207:     {
                   2208:       tree binfos = BINFO_BASETYPES (binfo);
                   2209:       int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
                   2210: 
                   2211:       /* Process and/or queue base types.  */
                   2212:       for (i = 0; i < n_baselinks; i++)
                   2213:        {
                   2214:          tree base_binfo = TREE_VEC_ELT (binfos, i);
                   2215:          tree btypes;
                   2216: 
                   2217:          btypes = hash_tree_cons (TREE_VIA_PUBLIC (base_binfo),
                   2218:                                   TREE_VIA_VIRTUAL (base_binfo),
                   2219:                                   TREE_VIA_PROTECTED (base_binfo),
                   2220:                                   NULL_TREE, base_binfo,
                   2221:                                   basetypes);
                   2222:          obstack_ptr_grow (&search_obstack, btypes);
                   2223:          search_stack->first = (tree *)obstack_base (&search_obstack);
                   2224:          tail += 1;
                   2225:        }
                   2226: 
                   2227:     dont_queue:
                   2228:       /* Process head of queue, if one exists.  */
                   2229:       if (head >= tail)
                   2230:        break;
                   2231: 
                   2232:       basetypes = search_stack->first[head++];
                   2233:       binfo = TREE_VALUE (basetypes);
                   2234:       type = BINFO_TYPE (binfo);
                   2235:       index = lookup_fnfields_1 (type, name);
                   2236:       if (index >= 0)
                   2237:        {
                   2238:          nval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), index);
                   2239:          rval = hash_tree_cons (0, 0, 0, basetypes, nval, rval);
                   2240:          if (TYPE_BINFO_BASETYPES (type) == 0)
                   2241:            goto dont_queue;
                   2242:          else if (TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type)) == 1)
                   2243:            {
                   2244:              if (CLASSTYPE_BASELINK_VEC (type))
                   2245:                TREE_TYPE (rval) = TREE_VEC_ELT (CLASSTYPE_BASELINK_VEC (type), index);
                   2246:              goto dont_queue;
                   2247:            }
                   2248:        }
                   2249:       nval = NULL_TREE;
                   2250:     }
                   2251: 
                   2252:   search_stack = pop_search_level (search_stack);
                   2253:   return rval;
                   2254: }
                   2255: 
                   2256: tree
                   2257: next_baselink (baselink)
                   2258:      tree baselink;
                   2259: {
                   2260:   tree tmp = TREE_TYPE (baselink);
                   2261:   baselink = TREE_CHAIN (baselink);
                   2262:   while (tmp)
                   2263:     {
                   2264:       /* @@ does not yet add previous base types.  */
                   2265:       baselink = tree_cons (TREE_PURPOSE (tmp), TREE_VALUE (tmp),
                   2266:                            baselink);
                   2267:       TREE_TYPE (baselink) = TREE_TYPE (tmp);
                   2268:       tmp = TREE_CHAIN (tmp);
                   2269:     }
                   2270:   return baselink;
                   2271: }
                   2272: 
                   2273: /* DEPTH-FIRST SEARCH ROUTINES.  */
                   2274: 
                   2275: /* Assign unique numbers to _CLASSTYPE members of the lattice
                   2276:    specified by TYPE.  The root nodes are marked first; the nodes
                   2277:    are marked depth-fisrt, left-right.  */
                   2278: 
                   2279: static int cid;
                   2280: 
                   2281: /* Matrix implementing a relation from CLASSTYPE X CLASSTYPE => INT.
                   2282:    Relation yields 1 if C1 <= C2, 0 otherwise.  */
                   2283: typedef char mi_boolean;
                   2284: static mi_boolean *mi_matrix;
                   2285: 
                   2286: /* Type for which this matrix is defined.  */
                   2287: static tree mi_type;
                   2288: 
                   2289: /* Size of the matrix for indexing purposes.  */
                   2290: static int mi_size;
                   2291: 
                   2292: /* Return nonzero if class C2 derives from class C1.  */
                   2293: #define BINFO_DERIVES_FROM(C1, C2)     \
                   2294:   ((mi_matrix+mi_size*(BINFO_CID (C1)-1))[BINFO_CID (C2)-1])
                   2295: #define TYPE_DERIVES_FROM(C1, C2)      \
                   2296:   ((mi_matrix+mi_size*(CLASSTYPE_CID (C1)-1))[CLASSTYPE_CID (C2)-1])
                   2297: #define BINFO_DERIVES_FROM_STAR(C)     \
                   2298:   (mi_matrix+(BINFO_CID (C)-1))
                   2299: 
                   2300: /* This routine converts a pointer to be a pointer of an immediate
                   2301:    base class.  The normal convert_pointer_to routine would diagnose
                   2302:    the conversion as ambiguous, under MI code that has the base class
                   2303:    as an ambiguous base class. */
                   2304: static tree
                   2305: convert_pointer_to_single_level (to_type, expr)
                   2306:      tree to_type, expr;
                   2307: {
                   2308:   tree binfo_of_derived;
                   2309:   tree last;
                   2310: 
                   2311:   binfo_of_derived = TYPE_BINFO (TREE_TYPE (TREE_TYPE (expr)));
                   2312:   last = get_binfo (to_type, TREE_TYPE (TREE_TYPE (expr)), 0);
                   2313:   BINFO_INHERITANCE_CHAIN (last) = binfo_of_derived;
                   2314:   BINFO_INHERITANCE_CHAIN (binfo_of_derived) = NULL_TREE;
                   2315:   return build_vbase_path (PLUS_EXPR, TYPE_POINTER_TO (to_type), expr, last, 1);
                   2316: }
                   2317: 
                   2318: /* The main function which implements depth first search.
                   2319: 
                   2320:    This routine has to remember the path it walked up, when
                   2321:    dfs_init_vbase_pointers is the work function, as otherwise there
                   2322:    would be no record. */
                   2323: static void
                   2324: dfs_walk (binfo, fn, qfn)
                   2325:      tree binfo;
                   2326:      void (*fn)();
                   2327:      int (*qfn)();
                   2328: {
                   2329:   tree binfos = BINFO_BASETYPES (binfo);
                   2330:   int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
                   2331: 
                   2332:   for (i = 0; i < n_baselinks; i++)
                   2333:     {
                   2334:       tree base_binfo = TREE_VEC_ELT (binfos, i);
                   2335: 
                   2336:       if ((*qfn)(base_binfo))
                   2337:        {
                   2338:          if (fn == dfs_init_vbase_pointers)
                   2339:            {
                   2340:              /* When traversing an arbitrary MI hierarchy, we need to keep
                   2341:                 a record of the path we took to get down to the final base
                   2342:                 type, as otherwise there would be no record of it, and just
                   2343:                 trying to blindly convert at the bottom would be ambiguous.
                   2344: 
                   2345:                 The easiest way is to do the conversions one step at a time,
                   2346:                 as we know we want the immediate base class at each step.
                   2347: 
                   2348:                 The only special trick to converting one step at a time,
                   2349:                 is that when we hit the last virtual base class, we must
                   2350:                 use the SLOT value for it, and not use the normal convert
                   2351:                 routine.  We use the last virtual base class, as in our
                   2352:                 implementation, we have pointers to all virtual base
                   2353:                 classes in the base object.  */
                   2354: 
                   2355:              tree saved_vbase_decl_ptr_intermediate
                   2356:                = vbase_decl_ptr_intermediate;
                   2357: 
                   2358:              if (TREE_VIA_VIRTUAL (base_binfo))
                   2359:                {
                   2360:                  /* No need for the conversion here, as we know it is the
                   2361:                     right type.  */
                   2362:                  vbase_decl_ptr_intermediate
                   2363:                    = (tree)CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (base_binfo));
                   2364:                }
                   2365:              else
                   2366:                {
                   2367:                  vbase_decl_ptr_intermediate
                   2368:                    = convert_pointer_to_single_level (BINFO_TYPE (base_binfo),
                   2369:                                                       vbase_decl_ptr_intermediate);
                   2370:                }
                   2371: 
                   2372:              dfs_walk (base_binfo, fn, qfn);
                   2373: 
                   2374:              vbase_decl_ptr_intermediate = saved_vbase_decl_ptr_intermediate;
                   2375:            } else
                   2376:              dfs_walk (base_binfo, fn, qfn);
                   2377:        }
                   2378:     }
                   2379: 
                   2380:   fn (binfo);
                   2381: }
                   2382: 
                   2383: /* Predicate functions which serve for dfs_walk.  */
                   2384: static int numberedp (binfo) tree binfo;
                   2385: { return BINFO_CID (binfo); }
                   2386: static int unnumberedp (binfo) tree binfo;
                   2387: { return BINFO_CID (binfo) == 0; }
                   2388: 
                   2389: static int markedp (binfo) tree binfo;
                   2390: { return BINFO_MARKED (binfo); }
                   2391: static int bfs_markedp (binfo, i) tree binfo; int i;
                   2392: { return BINFO_MARKED (BINFO_BASETYPE (binfo, i)); }
                   2393: static int unmarkedp (binfo) tree binfo;
                   2394: { return BINFO_MARKED (binfo) == 0; }
                   2395: static int bfs_unmarkedp (binfo, i) tree binfo; int i;
                   2396: { return BINFO_MARKED (BINFO_BASETYPE (binfo, i)) == 0; }
                   2397: static int marked_vtable_pathp (binfo) tree binfo;
                   2398: { return BINFO_VTABLE_PATH_MARKED (binfo); }
                   2399: static int bfs_marked_vtable_pathp (binfo, i) tree binfo; int i;
                   2400: { return BINFO_VTABLE_PATH_MARKED (BINFO_BASETYPE (binfo, i)); }
                   2401: static int unmarked_vtable_pathp (binfo) tree binfo;
                   2402: { return BINFO_VTABLE_PATH_MARKED (binfo) == 0; }
                   2403: static int bfs_unmarked_vtable_pathp (binfo, i) tree binfo; int i;
                   2404: { return BINFO_VTABLE_PATH_MARKED (BINFO_BASETYPE (binfo, i)) == 0; }
                   2405: static int marked_new_vtablep (binfo) tree binfo;
                   2406: { return BINFO_NEW_VTABLE_MARKED (binfo); }
                   2407: static int bfs_marked_new_vtablep (binfo, i) tree binfo; int i;
                   2408: { return BINFO_NEW_VTABLE_MARKED (BINFO_BASETYPE (binfo, i)); }
                   2409: static int unmarked_new_vtablep (binfo) tree binfo;
                   2410: { return BINFO_NEW_VTABLE_MARKED (binfo) == 0; }
                   2411: static int bfs_unmarked_new_vtablep (binfo, i) tree binfo; int i;
                   2412: { return BINFO_NEW_VTABLE_MARKED (BINFO_BASETYPE (binfo, i)) == 0; }
                   2413: 
                   2414: static int dfs_search_slot_nonempty_p (binfo) tree binfo;
                   2415: { return CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (binfo)) != 0; }
                   2416: 
                   2417: static int dfs_debug_unmarkedp (binfo) tree binfo;
                   2418: { return CLASSTYPE_DEBUG_REQUESTED (BINFO_TYPE (binfo)) == 0; }
                   2419: 
                   2420: /* The worker functions for `dfs_walk'.  These do not need to
                   2421:    test anything (vis a vis marking) if they are paired with
                   2422:    a predicate function (above).  */
                   2423: 
                   2424: /* Assign each type within the lattice a number which is unique
                   2425:    in the lattice.  The first number assigned is 1.  */
                   2426: 
                   2427: static void
                   2428: dfs_number (binfo)
                   2429:      tree binfo;
                   2430: {
                   2431:   BINFO_CID (binfo) = ++cid;
                   2432: }
                   2433: 
                   2434: static void
                   2435: dfs_unnumber (binfo)
                   2436:      tree binfo;
                   2437: {
                   2438:   BINFO_CID (binfo) = 0;
                   2439: }
                   2440: 
                   2441: static void
                   2442: dfs_mark (binfo) tree binfo;
                   2443: { SET_BINFO_MARKED (binfo); }
                   2444: 
                   2445: static void
                   2446: dfs_unmark (binfo) tree binfo;
                   2447: { CLEAR_BINFO_MARKED (binfo); }
                   2448: 
                   2449: static void
                   2450: dfs_mark_vtable_path (binfo) tree binfo;
                   2451: { SET_BINFO_VTABLE_PATH_MARKED (binfo); }
                   2452: 
                   2453: static void
                   2454: dfs_unmark_vtable_path (binfo) tree binfo;
                   2455: { CLEAR_BINFO_VTABLE_PATH_MARKED (binfo); }
                   2456: 
                   2457: static void
                   2458: dfs_mark_new_vtable (binfo) tree binfo;
                   2459: { SET_BINFO_NEW_VTABLE_MARKED (binfo); }
                   2460: 
                   2461: static void
                   2462: dfs_unmark_new_vtable (binfo) tree binfo;
                   2463: { CLEAR_BINFO_NEW_VTABLE_MARKED (binfo); }
                   2464: 
                   2465: static void
                   2466: dfs_clear_search_slot (binfo) tree binfo;
                   2467: { CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (binfo)) = 0; }
                   2468: 
                   2469: static void
                   2470: dfs_debug_mark (binfo)
                   2471:      tree binfo;
                   2472: {
                   2473:   tree t = BINFO_TYPE (binfo);
                   2474: 
                   2475:   /* Use heuristic that if there are virtual functions,
                   2476:      ignore until we see a non-inline virtual function.  */
                   2477:   tree methods = CLASSTYPE_METHOD_VEC (t);
                   2478: 
                   2479:   CLASSTYPE_DEBUG_REQUESTED (t) = 1;
                   2480: 
                   2481:   /* If interface info is known, the value of (?@@?) is correct.  */
                   2482:   if (methods == 0
                   2483:       || CLASSTYPE_INTERFACE_KNOWN (t)
                   2484:       || (write_virtuals == 2 && TYPE_VIRTUAL_P (t)))
                   2485:     return;
                   2486: 
                   2487:   /* If debug info is requested from this context for this type, supply it.
                   2488:      If debug info is requested from another context for this type,
                   2489:      see if some third context can supply it.  */
                   2490:   if (current_function_decl == NULL_TREE
                   2491:       || DECL_CLASS_CONTEXT (current_function_decl) != t)
                   2492:     {
                   2493:       if (TREE_VEC_ELT (methods, 0))
                   2494:        methods = TREE_VEC_ELT (methods, 0);
                   2495:       else
                   2496:        methods = TREE_VEC_ELT (methods, 1);
                   2497:       while (methods)
                   2498:        {
                   2499:          if (DECL_VINDEX (methods)
                   2500:              && DECL_SAVED_INSNS (methods) == 0
                   2501:              && DECL_PENDING_INLINE_INFO (methods) == 0
                   2502:              && DECL_ABSTRACT_VIRTUAL_P (methods) == 0)
                   2503:            {
                   2504:              /* Somebody, somewhere is going to have to define this
                   2505:                 virtual function.  When they do, they will provide
                   2506:                 the debugging info.  */
                   2507:              return;
                   2508:            }
                   2509:          methods = TREE_CHAIN (methods);
                   2510:        }
                   2511:     }
                   2512:   /* We cannot rely on some alien method to solve our problems,
                   2513:      so we must write out the debug info ourselves.  */
                   2514:   if (write_symbols != DWARF_DEBUG)
                   2515:     DECL_IGNORED_P (TYPE_NAME (t)) = 0;
                   2516:   if (! TREE_ASM_WRITTEN (TYPE_NAME (t)))
                   2517:     rest_of_type_compilation (t, global_bindings_p ());
                   2518: }
                   2519: 
                   2520: /*  Attach to the type of the virtual base class, the pointer to the
                   2521:     virtual base class, given the global pointer vbase_decl_ptr.  */
                   2522: static void
                   2523: dfs_find_vbases (binfo)
                   2524:      tree binfo;
                   2525: {
                   2526:   tree binfos = BINFO_BASETYPES (binfo);
                   2527:   int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
                   2528: 
                   2529:   for (i = n_baselinks-1; i >= 0; i--)
                   2530:     {
                   2531:       tree base_binfo = TREE_VEC_ELT (binfos, i);
                   2532: 
                   2533:       if (TREE_VIA_VIRTUAL (base_binfo)
                   2534:          && CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (base_binfo)) == 0)
                   2535:        {
                   2536:          tree vbase = BINFO_TYPE (base_binfo);
                   2537:          tree binfo = binfo_member (vbase, vbase_types);
                   2538: 
                   2539:          CLASSTYPE_SEARCH_SLOT (vbase)
                   2540:            = (char *) build (PLUS_EXPR, TYPE_POINTER_TO (vbase),
                   2541:                              vbase_decl_ptr, BINFO_OFFSET (binfo));
                   2542:        }
                   2543:     }
                   2544:   SET_BINFO_VTABLE_PATH_MARKED (binfo);
                   2545:   SET_BINFO_NEW_VTABLE_MARKED (binfo);
                   2546: }
                   2547: 
                   2548: static void
                   2549: dfs_init_vbase_pointers (binfo)
                   2550:      tree binfo;
                   2551: {
                   2552:   tree type = BINFO_TYPE (binfo);
                   2553:   tree fields = TYPE_FIELDS (type);
                   2554:   tree path, this_vbase_ptr;
                   2555:   int distance;
                   2556: 
                   2557:   CLEAR_BINFO_VTABLE_PATH_MARKED (binfo);
                   2558: 
                   2559:   /* If there is a dossier, it is the first field, though perhaps from
                   2560:      the base class.  Otherwise, the first fields are virtual base class
                   2561:      pointer fields.  */
                   2562:   if (CLASSTYPE_DOSSIER (type) && VFIELD_NAME_P (DECL_NAME (fields)))
                   2563:     /* Get past vtable for the object.  */
                   2564:     fields = TREE_CHAIN (fields);
                   2565: 
                   2566:   if (fields == NULL_TREE
                   2567:       || DECL_NAME (fields) == NULL_TREE
                   2568:       || ! VBASE_NAME_P (DECL_NAME (fields)))
                   2569:     return;
                   2570: 
                   2571:   this_vbase_ptr = vbase_decl_ptr_intermediate;
                   2572: 
                   2573:   if (TYPE_POINTER_TO (type) != TREE_TYPE (this_vbase_ptr))
                   2574:     my_friendly_abort (125);
                   2575: 
                   2576:   while (fields && DECL_NAME (fields)
                   2577:         && VBASE_NAME_P (DECL_NAME (fields)))
                   2578:     {
                   2579:       tree ref = build (COMPONENT_REF, TREE_TYPE (fields),
                   2580:                        build_indirect_ref (this_vbase_ptr, NULL_PTR), fields);
                   2581:       tree init = (tree)CLASSTYPE_SEARCH_SLOT (TREE_TYPE (TREE_TYPE (fields)));
                   2582:       vbase_init_result = tree_cons (binfo_member (TREE_TYPE (TREE_TYPE (fields)),
                   2583:                                                   vbase_types),
                   2584:                                     build_modify_expr (ref, NOP_EXPR, init),
                   2585:                                     vbase_init_result);
                   2586:       fields = TREE_CHAIN (fields);
                   2587:     }
                   2588: }
                   2589: 
                   2590: /* Sometimes this needs to clear both VTABLE_PATH and NEW_VTABLE.  Other
                   2591:    times, just NEW_VTABLE, but optimizer should make both with equal
                   2592:    efficiency (though it does not currently).  */
                   2593: static void
                   2594: dfs_clear_vbase_slots (binfo)
                   2595:      tree binfo;
                   2596: {
                   2597:   tree type = BINFO_TYPE (binfo);
                   2598:   CLASSTYPE_SEARCH_SLOT (type) = 0;
                   2599:   CLEAR_BINFO_VTABLE_PATH_MARKED (binfo);
                   2600:   CLEAR_BINFO_NEW_VTABLE_MARKED (binfo);
                   2601: }
                   2602: 
                   2603: tree
                   2604: init_vbase_pointers (type, decl_ptr)
                   2605:      tree type;
                   2606:      tree decl_ptr;
                   2607: {
                   2608:   if (TYPE_USES_VIRTUAL_BASECLASSES (type))
                   2609:     {
                   2610:       int old_flag = flag_this_is_variable;
                   2611:       tree binfo = TYPE_BINFO (type);
                   2612:       flag_this_is_variable = -2;
                   2613:       vbase_types = CLASSTYPE_VBASECLASSES (type);
                   2614:       vbase_decl_ptr = decl_ptr;
                   2615:       vbase_decl = build_indirect_ref (decl_ptr, NULL_PTR);
                   2616:       vbase_decl_ptr_intermediate = vbase_decl_ptr;
                   2617:       vbase_init_result = NULL_TREE;
                   2618:       dfs_walk (binfo, dfs_find_vbases, unmarked_vtable_pathp);
                   2619:       dfs_walk (binfo, dfs_init_vbase_pointers, marked_vtable_pathp);
                   2620:       dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep);
                   2621:       flag_this_is_variable = old_flag;
                   2622:       return vbase_init_result;
                   2623:     }
                   2624:   return 0;
                   2625: }
                   2626: 
                   2627: /* Build a COMPOUND_EXPR which when expanded will generate the code
                   2628:    needed to initialize all the virtual function table slots of all
                   2629:    the virtual baseclasses.  FOR_TYPE is the type which determines the
                   2630:    virtual baseclasses to use; TYPE is the type of the object to which
                   2631:    the initialization applies.  TRUE_EXP is the true object we are
                   2632:    initializing, and DECL_PTR is the pointer to the sub-object we
                   2633:    are initializing.
                   2634: 
                   2635:    When USE_COMPUTED_OFFSETS is non-zero, we can assume that the
                   2636:    object was laidout by a top-level contructor and the computed
                   2637:    offsets are valid to store vtables.  When zero, we must store new
                   2638:    vtables through virtual baseclass pointers.  */
                   2639: 
                   2640: tree
                   2641: build_vbase_vtables_init (main_binfo, binfo, true_exp, decl_ptr,
                   2642:                          use_computed_offsets)
                   2643:      tree main_binfo, binfo;
                   2644:      tree true_exp, decl_ptr;
                   2645:      int use_computed_offsets;
                   2646: {
                   2647:   tree for_type = BINFO_TYPE (main_binfo);
                   2648:   tree type = BINFO_TYPE (binfo);
                   2649:   if (TYPE_USES_VIRTUAL_BASECLASSES (type))
                   2650:     {
                   2651:       int old_flag = flag_this_is_variable;
                   2652:       tree vtable_init_result = NULL_TREE;
                   2653:       tree vbases = CLASSTYPE_VBASECLASSES (type);
                   2654: 
                   2655:       vbase_types = CLASSTYPE_VBASECLASSES (for_type);
                   2656:       vbase_decl_ptr = true_exp ? build_unary_op (ADDR_EXPR, true_exp, 0) : decl_ptr;
                   2657:       vbase_decl = true_exp ? true_exp : build_indirect_ref (decl_ptr, NULL_PTR);
                   2658: 
                   2659:       if (use_computed_offsets)
                   2660:        {
                   2661:          /* This is an object of type IN_TYPE,  */
                   2662:          flag_this_is_variable = -2;
                   2663:          dfs_walk (main_binfo, dfs_find_vbases, unmarked_new_vtablep);
                   2664:        }
                   2665: 
                   2666:       /* Initialized with vtables of type TYPE.  */
                   2667:       while (vbases)
                   2668:        {
                   2669:          /* This time through, not every class's vtable
                   2670:             is going to be initialized.  That is, we only initialize
                   2671:             the "last" vtable pointer.  */
                   2672: 
                   2673:          if (CLASSTYPE_VSIZE (BINFO_TYPE (vbases)))
                   2674:            {
                   2675:              tree addr;
                   2676:              tree vtbl = BINFO_VTABLE (vbases);
                   2677:              tree init = build_unary_op (ADDR_EXPR, vtbl, 0);
                   2678:              assemble_external (vtbl);
                   2679:              TREE_USED (vtbl) = 1;
                   2680: 
                   2681:              if (use_computed_offsets)
                   2682:                addr = (tree)CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (vbases));
                   2683:              else
                   2684:                addr = convert_pointer_to (vbases, vbase_decl_ptr);
                   2685: 
                   2686:              if (addr)
                   2687:                {
                   2688:                  tree ref = build_vfield_ref (build_indirect_ref (addr, NULL_PTR),
                   2689:                                               BINFO_TYPE (vbases));
                   2690:                  init = convert_force (TREE_TYPE (ref), init);
                   2691:                  vtable_init_result = tree_cons (NULL_TREE, build_modify_expr (ref, NOP_EXPR, init),
                   2692:                                                  vtable_init_result);
                   2693:                }
                   2694:            }
                   2695:          vbases = TREE_CHAIN (vbases);
                   2696:        }
                   2697: 
                   2698:       dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep);
                   2699: 
                   2700:       flag_this_is_variable = old_flag;
                   2701:       if (vtable_init_result)
                   2702:        return build_compound_expr (vtable_init_result);
                   2703:     }
                   2704:   return error_mark_node;
                   2705: }
                   2706: 
                   2707: void
                   2708: clear_search_slots (type)
                   2709:      tree type;
                   2710: {
                   2711:   dfs_walk (TYPE_BINFO (type),
                   2712:            dfs_clear_search_slot, dfs_search_slot_nonempty_p);
                   2713: }
                   2714: 
                   2715: /* get virtual base class types.
                   2716:    This adds type to the vbase_types list in reverse dfs order.
                   2717:    Ordering is very important, so don't change it.  */
                   2718: 
                   2719: static void
                   2720: dfs_get_vbase_types (binfo)
                   2721:      tree binfo;
                   2722: {
                   2723:   tree binfos = BINFO_BASETYPES (binfo);
                   2724:   tree type = BINFO_TYPE (binfo);
                   2725:   tree these_vbase_types = CLASSTYPE_VBASECLASSES (type);
                   2726:   int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
                   2727: 
                   2728:   if (these_vbase_types)
                   2729:     {
                   2730:       while (these_vbase_types)
                   2731:        {
                   2732:          tree this_type = BINFO_TYPE (these_vbase_types);
                   2733: 
                   2734:          /* We really need to start from a fresh copy of this
                   2735:             virtual basetype!  CLASSTYPE_MARKED2 is the shortcut
                   2736:             for BINFO_VBASE_MARKED.  */
                   2737:          if (! CLASSTYPE_MARKED2 (this_type))
                   2738:            {
                   2739:              vbase_types = make_binfo (integer_zero_node,
                   2740:                                        this_type,
                   2741:                                        TYPE_BINFO_VTABLE (this_type),
                   2742:                                        TYPE_BINFO_VIRTUALS (this_type),
                   2743:                                        vbase_types);
                   2744:              TREE_VIA_VIRTUAL (vbase_types) = 1;
                   2745:              SET_CLASSTYPE_MARKED2 (this_type);
                   2746:            }
                   2747:          these_vbase_types = TREE_CHAIN (these_vbase_types);
                   2748:        }
                   2749:     }
                   2750:   else for (i = 0; i < n_baselinks; i++)
                   2751:     {
                   2752:       tree base_binfo = TREE_VEC_ELT (binfos, i);
                   2753:       if (TREE_VIA_VIRTUAL (base_binfo) && ! BINFO_VBASE_MARKED (base_binfo))
                   2754:        {
                   2755:          vbase_types = make_binfo (integer_zero_node, BINFO_TYPE (base_binfo),
                   2756:                                    BINFO_VTABLE (base_binfo),
                   2757:                                    BINFO_VIRTUALS (base_binfo), vbase_types);
                   2758:          TREE_VIA_VIRTUAL (vbase_types) = 1;
                   2759:          SET_BINFO_VBASE_MARKED (base_binfo);
                   2760:        }
                   2761:     }
                   2762:   SET_BINFO_MARKED (binfo);
                   2763: }
                   2764: 
                   2765: /* Some virtual baseclasses might be virtual baseclasses for
                   2766:    other virtual baseclasses.  We sort the virtual baseclasses
                   2767:    topologically: in the list returned, the first virtual base
                   2768:    classes have no virtual baseclasses themselves, and any entry
                   2769:    on the list has no dependency on virtual base classes later in the
                   2770:    list.  */
                   2771: tree
                   2772: get_vbase_types (type)
                   2773:      tree type;
                   2774: {
                   2775:   tree ordered_vbase_types = NULL_TREE, prev, next;
                   2776:   tree vbases;
                   2777: 
                   2778:   vbase_types = NULL_TREE;
                   2779:   dfs_walk (TYPE_BINFO (type), dfs_get_vbase_types, unmarkedp);
                   2780:   dfs_walk (TYPE_BINFO (type), dfs_unmark, markedp);
                   2781:   /* Rely upon the reverse dfs ordering from dfs_get_vbase_types, and now
                   2782:      reverse it so that we get normal dfs ordering.  */
                   2783:   vbase_types = nreverse (vbase_types);
                   2784: 
                   2785:   /* Almost all of the below is not needed now.  We should be able to just
                   2786:      return vbase_types directly... (mrs) */
                   2787:   while (vbase_types)
                   2788:     {
                   2789:       /* Now sort these types.  This is essentially a bubble merge.  */
                   2790: 
                   2791:       /* Farm out virtual baseclasses which have no marked ancestors.  */
                   2792:       for (vbases = vbase_types, prev = NULL_TREE;
                   2793:           vbases; vbases = next)
                   2794:        {
                   2795:          next = TREE_CHAIN (vbases);
                   2796:          /* If VBASES does not have any vbases itself, or it's
                   2797:             topologically safe, it goes into the sorted list.  */
                   2798:          if (1 /* ANSI C++ specifies dfs ordering now. */
                   2799:              || ! CLASSTYPE_VBASECLASSES (BINFO_TYPE (vbases))
                   2800:              || BINFO_VBASE_MARKED (vbases) == 0)
                   2801:            {
                   2802:              if (prev)
                   2803:                TREE_CHAIN (prev) = TREE_CHAIN (vbases);
                   2804:              else
                   2805:                vbase_types = TREE_CHAIN (vbases);
                   2806:              TREE_CHAIN (vbases) = NULL_TREE;
                   2807:              ordered_vbase_types = chainon (ordered_vbase_types, vbases);
                   2808:              CLEAR_BINFO_VBASE_MARKED (vbases);
                   2809:            }
                   2810:          else
                   2811:            prev = vbases;
                   2812:        }
                   2813: 
                   2814:       /* Now unmark types all of whose ancestors are now on the
                   2815:         `ordered_vbase_types' list.  */
                   2816:       for (vbases = vbase_types; vbases; vbases = TREE_CHAIN (vbases))
                   2817:        {
                   2818:          /* If all our virtual baseclasses are unmarked, ok.  */
                   2819:          tree t = CLASSTYPE_VBASECLASSES (BINFO_TYPE (vbases));
                   2820:          while (t && (BINFO_VBASE_MARKED (t) == 0
                   2821:                       || ! CLASSTYPE_VBASECLASSES (BINFO_TYPE (t))))
                   2822:            t = TREE_CHAIN (t);
                   2823:          if (t == NULL_TREE)
                   2824:            CLEAR_BINFO_VBASE_MARKED (vbases);
                   2825:        }
                   2826:     }
                   2827: 
                   2828:   return ordered_vbase_types;
                   2829: }
                   2830: 
                   2831: static void
                   2832: dfs_record_inheritance (binfo)
                   2833:      tree binfo;
                   2834: {
                   2835:   tree binfos = BINFO_BASETYPES (binfo);
                   2836:   int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
                   2837:   mi_boolean *derived_row = BINFO_DERIVES_FROM_STAR (binfo);
                   2838: 
                   2839:   for (i = n_baselinks-1; i >= 0; i--)
                   2840:     {
                   2841:       int j;
                   2842:       tree base_binfo = TREE_VEC_ELT (binfos, i);
                   2843:       tree baseclass = BINFO_TYPE (base_binfo);
                   2844:       mi_boolean *base_row = BINFO_DERIVES_FROM_STAR (base_binfo);
                   2845: 
                   2846:       /* Don't search if there's nothing there!  MI_SIZE can be
                   2847:         zero as a result of parse errors.  */
                   2848:       if (TYPE_BINFO_BASETYPES (baseclass) && mi_size > 0)
                   2849:        for (j = mi_size*(CLASSTYPE_CID (baseclass)-1); j >= 0; j -= mi_size)
                   2850:          derived_row[j] |= base_row[j];
                   2851:       TYPE_DERIVES_FROM (baseclass, BINFO_TYPE (binfo)) = 1;
                   2852:     }
                   2853: 
                   2854:   SET_BINFO_MARKED (binfo);
                   2855: }
                   2856: 
                   2857: /* Given a _CLASSTYPE node in a multiple inheritance lattice,
                   2858:    convert the lattice into a simple relation such that,
                   2859:    given to CIDs, C1 and C2, one can determine if C1 <= C2
                   2860:    or C2 <= C1 or C1 <> C2.
                   2861: 
                   2862:    Once constructed, we walk the lattice depth fisrt,
                   2863:    applying various functions to elements as they are encountered.
                   2864: 
                   2865:    We use xmalloc here, in case we want to randomly free these tables.  */
                   2866: 
                   2867: #define SAVE_MI_MATRIX
                   2868: 
                   2869: void
                   2870: build_mi_matrix (type)
                   2871:      tree type;
                   2872: {
                   2873:   tree binfo = TYPE_BINFO (type);
                   2874:   cid = 0;
                   2875: 
                   2876: #ifdef SAVE_MI_MATRIX
                   2877:   if (CLASSTYPE_MI_MATRIX (type))
                   2878:     {
                   2879:       mi_size = CLASSTYPE_N_SUPERCLASSES (type) + CLASSTYPE_N_VBASECLASSES (type);
                   2880:       mi_matrix = CLASSTYPE_MI_MATRIX (type);
                   2881:       mi_type = type;
                   2882:       dfs_walk (binfo, dfs_number, unnumberedp);
                   2883:       return;
                   2884:     }
                   2885: #endif
                   2886: 
                   2887:   mi_size = CLASSTYPE_N_SUPERCLASSES (type) + CLASSTYPE_N_VBASECLASSES (type);
                   2888:   mi_matrix = (char *)xmalloc ((mi_size + 1) * (mi_size + 1));
                   2889:   mi_type = type;
                   2890:   bzero (mi_matrix, (mi_size + 1) * (mi_size + 1));
                   2891:   dfs_walk (binfo, dfs_number, unnumberedp);
                   2892:   dfs_walk (binfo, dfs_record_inheritance, unmarkedp);
                   2893:   dfs_walk (binfo, dfs_unmark, markedp);
                   2894: }
                   2895: 
                   2896: void
                   2897: free_mi_matrix ()
                   2898: {
                   2899:   dfs_walk (TYPE_BINFO (mi_type), dfs_unnumber, numberedp);
                   2900: 
                   2901: #ifdef SAVE_MI_MATRIX
                   2902:   CLASSTYPE_MI_MATRIX (mi_type) = mi_matrix;
                   2903: #else
                   2904:   free (mi_matrix);
                   2905:   mi_size = 0;
                   2906:   cid = 0;
                   2907: #endif
                   2908: }
                   2909: 
                   2910: /* Local variables for detecting ambiguities of virtual functions
                   2911:    when two or more classes are joined at a multiple inheritance
                   2912:    seam.  */
                   2913: typedef struct {
                   2914:   tree decl;
                   2915:   tree args;
                   2916:   tree ptr;
                   2917: } mi_ventry;
                   2918: static mi_ventry *mi_vmatrix;
                   2919: static int *mi_vmax;
                   2920: static int mi_vrows, mi_vcols;
                   2921: #define MI_VMATRIX(ROW,COL) ((mi_vmatrix + (ROW)*mi_vcols)[COL])
                   2922: 
                   2923: /* Build a table of virtual functions for a multiple-inheritance
                   2924:    structure.  Here, there are N base classes, and at most
                   2925:    M entries per class.
                   2926: 
                   2927:    This function does nothing if N is 0 or 1.  */
                   2928: void
                   2929: build_mi_virtuals (rows, cols)
                   2930:      int rows, cols;
                   2931: {
                   2932:   if (rows < 2 || cols == 0)
                   2933:     return;
                   2934:   mi_vrows = rows;
                   2935:   mi_vcols = cols;
                   2936:   mi_vmatrix = (mi_ventry *)xmalloc ((rows+1) * cols * sizeof (mi_ventry));
                   2937:   mi_vmax = (int *)xmalloc ((rows+1) * sizeof (int));
                   2938: 
                   2939:   bzero (mi_vmax, rows * sizeof (int));
                   2940: 
                   2941:   /* Row indices start at 1, so adjust this.  */
                   2942:   mi_vmatrix -= cols;
                   2943:   mi_vmax -= 1;
                   2944: }
                   2945: 
                   2946: /* Comparison function for ordering virtual function table entries.  */
                   2947: static int
                   2948: rank_mi_virtuals (v1, v2)
                   2949:      mi_ventry *v1, *v2;
                   2950: {
                   2951:   tree p1, p2;
                   2952:   int i;
                   2953: 
                   2954:   i = (long) (DECL_NAME (v1->decl)) - (long) (DECL_NAME (v2->decl));
                   2955:   if (i)
                   2956:     return i;
                   2957:   p1 = v1->args;
                   2958:   p2 = v2->args;
                   2959: 
                   2960:   if (p1 == p2)
                   2961:     return 0;
                   2962: 
                   2963:   while (p1 && p2)
                   2964:     {
                   2965:       i = ((long) (TREE_VALUE (p1)) - (long) (TREE_VALUE (p2)));
                   2966:       if (i)
                   2967:        return i;
                   2968: 
                   2969:       if (TREE_CHAIN (p1))
                   2970:        {
                   2971:          if (! TREE_CHAIN (p2))
                   2972:            return 1;
                   2973:          p1 = TREE_CHAIN (p1);
                   2974:          p2 = TREE_CHAIN (p2);
                   2975:        }
                   2976:       else if (TREE_CHAIN (p2))
                   2977:        return -1;
                   2978:       else
                   2979:        {
                   2980:          /* When matches of argument lists occur, pick lowest
                   2981:             address to keep searching time to a minimum on
                   2982:             later passes--like hashing, only different.
                   2983:             *MUST BE STABLE*.  */
                   2984:          if ((long) (v2->args) < (long) (v1->args))
                   2985:            v1->args = v2->args;
                   2986:          else
                   2987:            v2->args = v1->args;
                   2988:          return 0;
                   2989:        }
                   2990:     }
                   2991:   return 0;
                   2992: }
                   2993: 
                   2994: /* Install the virtuals functions got from the initializer VIRTUALS to
                   2995:    the table at index ROW.  */
                   2996: void
                   2997: add_mi_virtuals (row, virtuals)
                   2998:      int row;
                   2999:      tree virtuals;
                   3000: {
                   3001:   int col = 0;
                   3002: 
                   3003:   if (mi_vmatrix == 0)
                   3004:     return;
                   3005:   while (virtuals)
                   3006:     {
                   3007:       tree decl = TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals)), 0);
                   3008:       MI_VMATRIX (row, col).decl = decl;
                   3009:       MI_VMATRIX (row, col).args = FUNCTION_ARG_CHAIN (decl);
                   3010:       MI_VMATRIX (row, col).ptr = TREE_VALUE (virtuals);
                   3011:       virtuals = TREE_CHAIN (virtuals);
                   3012:       col += 1;
                   3013:     }
                   3014:   mi_vmax[row] = col;
                   3015: 
                   3016:   qsort (mi_vmatrix + row * mi_vcols,
                   3017:         col,
                   3018:         sizeof (mi_ventry),
                   3019:         rank_mi_virtuals);
                   3020: }
                   3021: 
                   3022: /* If joining two types results in an ambiguity in the virtual
                   3023:    function table, report such here.  */
                   3024: void
                   3025: report_ambiguous_mi_virtuals (rows, type)
                   3026:      int rows;
                   3027:      tree type;
                   3028: {
                   3029:   int *mi_vmin;
                   3030:   int row1, col1, row, col;
                   3031: 
                   3032:   if (mi_vmatrix == 0)
                   3033:     return;
                   3034: 
                   3035:   /* Now virtuals are all sorted, so we merge to find ambiguous cases.  */
                   3036:   mi_vmin = (int *)alloca ((rows+1) * sizeof (int));
                   3037:   bzero (mi_vmin, rows * sizeof (int));
                   3038: 
                   3039:   /* adjust.  */
                   3040:   mi_vmin -= 1;
                   3041: 
                   3042:   /* For each base class with virtual functions (and this includes views
                   3043:      of the virtual baseclasses from different base classes), see that
                   3044:      each virtual function in that base class has a unique meet.
                   3045: 
                   3046:      When the column loop is finished, THIS_DECL is in fact the meet.
                   3047:      If that value does not appear in the virtual function table for
                   3048:      the row, install it.  This happens when that virtual function comes
                   3049:      from a virtual baseclass, or a non-leftmost baseclass.  */
                   3050: 
                   3051:   for (row1 = 1; row1 < rows; row1++)
                   3052:     {
                   3053:       tree this_decl = 0;
                   3054: 
                   3055:       for (col1 = mi_vmax[row1]-1; col1 >= mi_vmin[row1]; col1--)
                   3056:        {
                   3057:          tree these_args = MI_VMATRIX (row1, col1).args;
                   3058:          tree this_context;
                   3059: 
                   3060:          this_decl = MI_VMATRIX (row1, col1).decl;
                   3061:          if (this_decl == 0)
                   3062:            continue;
                   3063:          this_context = TYPE_BINFO (DECL_CLASS_CONTEXT (this_decl));
                   3064: 
                   3065:          if (this_context != TYPE_BINFO (type))
                   3066:            this_context = get_binfo (this_context, type, 0);
                   3067: 
                   3068:          for (row = row1+1; row <= rows; row++)
                   3069:            for (col = mi_vmax[row]-1; col >= mi_vmin[row]; col--)
                   3070:              {
                   3071:                mi_ventry this_entry;
                   3072: 
                   3073:                if (MI_VMATRIX (row, col).decl == 0)
                   3074:                  continue;
                   3075: 
                   3076:                this_entry.decl = this_decl;
                   3077:                this_entry.args = these_args;
                   3078:                this_entry.ptr = MI_VMATRIX (row1, col1).ptr;
                   3079:                if (rank_mi_virtuals (&this_entry, &MI_VMATRIX (row, col)) == 0)
                   3080:                  {
                   3081:                    /* They are equal.  There are four possibilities:
                   3082: 
                   3083:                       (1) Derived class is defining this virtual function.
                   3084:                       (2) Two paths to the same virtual function in the
                   3085:                       same base class.
                   3086:                       (3) A path to a virtual function declared in one base
                   3087:                       class, and another path to a virtual function in a
                   3088:                       base class of the base class.
                   3089:                       (4) Two paths to the same virtual function in different
                   3090:                       base classes.
                   3091: 
                   3092:                       The first three cases are ok (non-ambiguous).  */
                   3093: 
                   3094:                    tree that_context, tmp;
                   3095:                    int this_before_that;
                   3096: 
                   3097:                    if (type == BINFO_TYPE (this_context))
                   3098:                      /* case 1.  */
                   3099:                      goto ok;
                   3100:                    that_context = get_binfo (DECL_CLASS_CONTEXT (MI_VMATRIX (row, col).decl), type, 0);
                   3101:                    if (that_context == this_context)
                   3102:                      /* case 2.  */
                   3103:                      goto ok;
                   3104:                    if (that_context != NULL_TREE)
                   3105:                      {
                   3106:                        tmp = get_binfo (that_context, this_context, 0);
                   3107:                        this_before_that = (that_context != tmp);
                   3108:                        if (this_before_that == 0)
                   3109:                          /* case 3a.  */
                   3110:                          goto ok;
                   3111:                        tmp = get_binfo (this_context, that_context, 0);
                   3112:                        this_before_that = (this_context == tmp);
                   3113:                        if (this_before_that != 0)
                   3114:                          /* case 3b.  */
                   3115:                          goto ok;
                   3116: 
                   3117:                        /* case 4.  */
                   3118:                        /* These two are not hard errors, but could be
                   3119:                           symptoms of bad code.  The resultant code
                   3120:                           the compiler generates needs to be checked.
                   3121:                           (mrs) */
                   3122: #if 0
                   3123:                        cp_error_at ("ambiguous virtual function `%s'",
                   3124:                                       MI_VMATRIX (row, col).decl);
                   3125:                        cp_error_at ("ambiguating function `%D' (joined by type `%T')", this_decl, current_class_name);
                   3126: #endif
                   3127:                      }
                   3128:                  ok:
                   3129:                    MI_VMATRIX (row, col).decl = 0;
                   3130: 
                   3131:                    /* Let zeros propagate.  */
                   3132:                    if (col == mi_vmax[row]-1)
                   3133:                      {
                   3134:                        int i = col;
                   3135:                        while (i >= mi_vmin[row]
                   3136:                               && MI_VMATRIX (row, i).decl == 0)
                   3137:                          i--;
                   3138:                        mi_vmax[row] = i+1;
                   3139:                      }
                   3140:                    else if (col == mi_vmin[row])
                   3141:                      {
                   3142:                        int i = col;
                   3143:                        while (i < mi_vmax[row]
                   3144:                               && MI_VMATRIX (row, i).decl == 0)
                   3145:                          i++;
                   3146:                        mi_vmin[row] = i;
                   3147:                      }
                   3148:                  }
                   3149:              }
                   3150:        }
                   3151:     }
                   3152:   free (mi_vmatrix + mi_vcols);
                   3153:   mi_vmatrix = 0;
                   3154:   free (mi_vmax + 1);
                   3155:   mi_vmax = 0;
                   3156: }
                   3157: 
                   3158: /* If we want debug info for a type TYPE, make sure all its base types
                   3159:    are also marked as being potentially interesting.  This avoids
                   3160:    the problem of not writing any debug info for intermediate basetypes
                   3161:    that have abstract virtual functions.  */
                   3162: 
                   3163: void
                   3164: note_debug_info_needed (type)
                   3165:      tree type;
                   3166: {
                   3167:   dfs_walk (TYPE_BINFO (type), dfs_debug_mark, dfs_debug_unmarkedp);
                   3168: }
                   3169: 
                   3170: /* Subroutines of push_class_decls ().  */
                   3171: 
                   3172: /* Add the instance variables which this class contributed to the
                   3173:    current class binding contour.  When a redefinition occurs,
                   3174:    if the redefinition is strictly within a single inheritance path,
                   3175:    we just overwrite (in the case of a data field) or
                   3176:    cons (in the case of a member function) the old declaration with
                   3177:    the new.  If the fields are not within a single inheritance path,
                   3178:    we must cons them in either case.
                   3179: 
                   3180:    when NEW_CLASS_SCOPING is 1:
                   3181: 
                   3182:    In order to know what decls are new (stemming from the current
                   3183:    invocation of push_class_decls) we enclose them in an "envelope",
                   3184:    which is a TREE_LIST node where the TREE_PURPOSE slot contains the
                   3185:    new decl (or possibly a list of competing ones), the TREE_VALUE slot
                   3186:    points to the old value and the TREE_CHAIN slot chains together all
                   3187:    envelopes which needs to be "opened" in push_class_decls.  Opening an
                   3188:    envelope means: push the old value onto the class_shadowed list,
                   3189:    install the new one and if it's a TYPE_DECL do the same to the
                   3190:    IDENTIFIER_TYPE_VALUE.  Such an envelope is recognized by seeing that
                   3191:    the TREE_PURPOSE slot is non-null, and that it is not an identifier.
                   3192:    Because if it is, it could be a set of overloaded methods from an
                   3193:    outer scope.  */
                   3194: 
                   3195: static void
                   3196: dfs_pushdecls (binfo)
                   3197:      tree binfo;
                   3198: {
                   3199:   tree type = BINFO_TYPE (binfo);
                   3200:   tree fields, *methods, *end;
                   3201:   tree method_vec;
                   3202: 
                   3203:   for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields))
                   3204:     {
                   3205:       /* Unmark so that if we are in a constructor, and then find that
                   3206:         this field was initialized by a base initializer,
                   3207:         we can emit an error message.  */
                   3208:       if (TREE_CODE (fields) == FIELD_DECL)
                   3209:        TREE_USED (fields) = 0;
                   3210: 
                   3211:       /* Recurse into anonymous unions.  */
                   3212:       if (DECL_NAME (fields) == NULL_TREE
                   3213:          && TREE_CODE (TREE_TYPE (fields)) == UNION_TYPE)
                   3214:        {
                   3215:          dfs_pushdecls (TYPE_BINFO (TREE_TYPE (fields)));
                   3216:          continue;
                   3217:        }
                   3218: 
                   3219:       if (TREE_CODE (fields) != TYPE_DECL)
                   3220:        {
                   3221:          DECL_PUBLIC (fields) = 0;
                   3222:          DECL_PROTECTED (fields) = 0;
                   3223:          DECL_PRIVATE (fields) = 0;
                   3224:        }
                   3225: 
                   3226:       if (DECL_NAME (fields))
                   3227:        {
                   3228: #if NEW_CLASS_SCOPING
                   3229:          tree class_value = IDENTIFIER_CLASS_VALUE (DECL_NAME (fields));
                   3230: 
                   3231:          /* If the class value is an envelope of the kind described in
                   3232:             the comment above, we try to rule out possible ambiguities.
                   3233:             If we can't do that, keep a TREE_LIST with possibly ambiguous
                   3234:             decls in there.  */
                   3235:          if (class_value && TREE_CODE (class_value) == TREE_LIST
                   3236:              && TREE_PURPOSE (class_value) != NULL_TREE
                   3237:              && (TREE_CODE (TREE_PURPOSE (class_value))
                   3238:                  != IDENTIFIER_NODE))
                   3239:            {
                   3240:              tree value = TREE_PURPOSE (class_value);
                   3241: #else
                   3242:          tree value = IDENTIFIER_CLASS_VALUE (DECL_NAME (fields));
                   3243:          if (value)
                   3244:            {
                   3245: #endif
                   3246:              tree context;
                   3247: 
                   3248:              /* Possible ambiguity.  If its defining type(s)
                   3249:                 is (are all) derived from us, no problem.  */
                   3250:              if (TREE_CODE (value) != TREE_LIST)
                   3251:                {
                   3252:                  context = (TREE_CODE (value) == FUNCTION_DECL
                   3253:                             && DECL_VIRTUAL_P (value))
                   3254:                    ? DECL_CLASS_CONTEXT (value)
                   3255:                      : DECL_CONTEXT (value);
                   3256: 
                   3257:                  if (context && (context == type
                   3258:                                  || TYPE_DERIVES_FROM (context, type)))
                   3259:                    value = fields;
                   3260:                  else
                   3261:                    value = tree_cons (NULL_TREE, fields,
                   3262:                                       build_tree_list (NULL_TREE, value));
                   3263:                }
                   3264:              else
                   3265:                {
                   3266:                  /* All children may derive from us, in which case
                   3267:                     there is no problem.  Otherwise, we have to
                   3268:                     keep lists around of what the ambiguities might be.  */
                   3269:                  tree values;
                   3270:                  int problem = 0;
                   3271: 
                   3272:                  for (values = value; values; values = TREE_CHAIN (values))
                   3273:                    {
                   3274:                      tree sub_values = TREE_VALUE (values);
                   3275: 
                   3276:                      if (TREE_CODE (sub_values) == TREE_LIST)
                   3277:                        {
                   3278:                          for (; sub_values; sub_values = TREE_CHAIN (sub_values))
                   3279:                            {
                   3280:                              register tree list_mbr = TREE_VALUE (sub_values);
                   3281: 
                   3282:                              context = (TREE_CODE (list_mbr) == FUNCTION_DECL
                   3283:                                         && DECL_VIRTUAL_P (list_mbr))
                   3284:                                ? DECL_CLASS_CONTEXT (list_mbr)
                   3285:                                  : DECL_CONTEXT (list_mbr);
                   3286: 
                   3287:                              if (! TYPE_DERIVES_FROM (context, type))
                   3288:                                {
                   3289:                                  value = tree_cons (NULL_TREE, TREE_VALUE (values), value);
                   3290:                                  problem = 1;
                   3291:                                  break;
                   3292:                                }
                   3293:                            }
                   3294:                        }
                   3295:                      else
                   3296:                        {
                   3297:                          context = (TREE_CODE (sub_values) == FUNCTION_DECL
                   3298:                                     && DECL_VIRTUAL_P (sub_values))
                   3299:                            ? DECL_CLASS_CONTEXT (sub_values)
                   3300:                              : DECL_CONTEXT (sub_values);
                   3301: 
                   3302:                          if (context && ! TYPE_DERIVES_FROM (context, type))
                   3303:                            {
                   3304:                              value = tree_cons (NULL_TREE, values, value);
                   3305:                              problem = 1;
                   3306:                              break;
                   3307:                            }
                   3308:                        }
                   3309:                    }
                   3310:                  if (! problem) value = fields;
                   3311:                }
                   3312: 
                   3313:              /* Mark this as a potentially ambiguous member.  */
                   3314:              if (TREE_CODE (value) == TREE_LIST)
                   3315:                {
                   3316:                  /* Leaving TREE_TYPE blank is intentional.
                   3317:                     We cannot use `error_mark_node' (lookup_name)
                   3318:                     or `unknown_type_node' (all member functions use this).  */
                   3319:                  TREE_NONLOCAL_FLAG (value) = 1;
                   3320:                }
                   3321: 
                   3322: #if NEW_CLASS_SCOPING
                   3323:              /* Put the new contents in our envelope.  */
                   3324:              TREE_PURPOSE (class_value) = value;
                   3325:            }
                   3326:          else
                   3327:            {
                   3328:              /* See comment above for a description of envelopes.  */
                   3329:              tree envelope = tree_cons (fields, class_value,
                   3330:                                         closed_envelopes);
                   3331: 
                   3332:              closed_envelopes = envelope;
                   3333:              IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) = envelope;
                   3334:            }
                   3335: #else
                   3336:              IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) = value;
                   3337:            }
                   3338:          else IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) = fields;
                   3339: #endif
                   3340:        }
                   3341:     }
                   3342: 
                   3343:   method_vec = CLASSTYPE_METHOD_VEC (type);
                   3344:   if (method_vec != 0)
                   3345:     {
                   3346:       /* Farm out constructors and destructors.  */
                   3347:       methods = &TREE_VEC_ELT (method_vec, 1);
                   3348:       end = TREE_VEC_END (method_vec);
                   3349: 
                   3350:       /* This does not work for multiple inheritance yet.  */
                   3351:       while (methods != end)
                   3352:        {
                   3353:          /* This will cause lookup_name to return a pointer
                   3354:             to the tree_list of possible methods of this name.
                   3355:             If the order is a problem, we can nreverse them.  */
                   3356:          tree tmp;
                   3357: #if NEW_CLASS_SCOPING
                   3358:          tree class_value = IDENTIFIER_CLASS_VALUE (DECL_NAME (*methods));
                   3359: 
                   3360:          if (class_value && TREE_CODE (class_value) == TREE_LIST
                   3361:              && TREE_PURPOSE (class_value) != NULL_TREE
                   3362:              && TREE_CODE (TREE_PURPOSE (class_value)) != IDENTIFIER_NODE)
                   3363:            {
                   3364:              tree old = TREE_PURPOSE (class_value);
                   3365: 
                   3366:              maybe_push_cache_obstack ();
                   3367:              if (TREE_CODE (old) == TREE_LIST)
                   3368:                tmp = tree_cons (DECL_NAME (*methods), *methods, old);
                   3369:              else
                   3370:                {
                   3371:                  /* Only complain if we shadow something we can access.  */
                   3372:                  if (old
                   3373:                      && ((DECL_LANG_SPECIFIC (old)
                   3374:                           && DECL_CLASS_CONTEXT (old) == current_class_type)
                   3375:                          || ! TREE_PRIVATE (old)))
                   3376:                    /* Should figure out visibility more accurately.  */
                   3377:                    cp_warning ("shadowing member `%#D' with member function `%#D'",
                   3378:                                old, *methods);
                   3379:                  tmp = build_tree_list (DECL_NAME (*methods), *methods);
                   3380:                }
                   3381:              pop_obstacks ();
                   3382: 
                   3383:              TREE_TYPE (tmp) = unknown_type_node;
                   3384: #if 0
                   3385:              TREE_OVERLOADED (tmp) = DECL_OVERLOADED (*methods);
                   3386: #endif
                   3387:              TREE_NONLOCAL_FLAG (tmp) = 1;
                   3388:              
                   3389:              /* Put the new contents in our envelope.  */
                   3390:              TREE_PURPOSE (class_value) = tmp;
                   3391:            }
                   3392:          else
                   3393:            {
                   3394:              maybe_push_cache_obstack ();
                   3395:              tmp = build_tree_list (DECL_NAME (*methods), *methods);
                   3396:              pop_obstacks ();
                   3397: 
                   3398:              TREE_TYPE (tmp) = unknown_type_node;
                   3399: #if 0
                   3400:              TREE_OVERLOADED (tmp) = DECL_OVERLOADED (*methods);
                   3401: #endif
                   3402:              TREE_NONLOCAL_FLAG (tmp) = 1;
                   3403:              
                   3404:              /* See comment above for a description of envelopes.  */
                   3405:              closed_envelopes = tree_cons (tmp, class_value,
                   3406:                                            closed_envelopes);
                   3407:              IDENTIFIER_CLASS_VALUE (DECL_NAME (*methods)) = closed_envelopes;
                   3408:            }
                   3409: #else
                   3410:          tree old = IDENTIFIER_CLASS_VALUE (DECL_NAME (*methods));
                   3411: 
                   3412:          if (old && TREE_CODE (old) == TREE_LIST)
                   3413:            tmp = tree_cons (DECL_NAME (*methods), *methods, old);
                   3414:          else
                   3415:            {
                   3416:              /* Only complain if we shadow something we can access.  */
                   3417:              if (old && (DECL_CLASS_CONTEXT (old) == current_class_type
                   3418:                          || ! TREE_PRIVATE (old)))
                   3419:                /* Should figure out visibility more accurately.  */
                   3420:                cp_warning_at ("member function `%D' shadows member `%s'", *methods,
                   3421:                                   IDENTIFIER_POINTER (DECL_NAME (old)));
                   3422:              tmp = build_tree_list (DECL_NAME (*methods), *methods);
                   3423:            }
                   3424: 
                   3425:          TREE_TYPE (tmp) = unknown_type_node;
                   3426: #if 0
                   3427:          TREE_OVERLOADED (tmp) = DECL_OVERLOADED (*methods);
                   3428: #endif
                   3429:          TREE_NONLOCAL_FLAG (tmp) = 1;
                   3430:          IDENTIFIER_CLASS_VALUE (DECL_NAME (*methods)) = tmp;
                   3431: #endif
                   3432: 
                   3433:          tmp = *methods;
                   3434:          while (tmp != 0)
                   3435:            {
                   3436:              DECL_PUBLIC (tmp) = 0;
                   3437:              DECL_PROTECTED (tmp) = 0;
                   3438:              DECL_PRIVATE (tmp) = 0;
                   3439:              tmp = DECL_CHAIN (tmp);
                   3440:            }
                   3441: 
                   3442:          methods++;
                   3443:        }
                   3444:     }
                   3445:   SET_BINFO_MARKED (binfo);
                   3446: }
                   3447: 
                   3448: /* Consolidate unique (by name) member functions.  */
                   3449: static void
                   3450: dfs_compress_decls (binfo)
                   3451:      tree binfo;
                   3452: {
                   3453:   tree type = BINFO_TYPE (binfo);
                   3454:   tree method_vec = CLASSTYPE_METHOD_VEC (type);
                   3455: 
                   3456:   if (method_vec != 0)
                   3457:     {
                   3458:       /* Farm out constructors and destructors.  */
                   3459:       tree *methods = &TREE_VEC_ELT (method_vec, 1);
                   3460:       tree *end = TREE_VEC_END (method_vec);
                   3461: 
                   3462:       for (; methods != end; methods++)
                   3463:        {
                   3464: #if NEW_CLASS_SCOPING
                   3465:          /* This is known to be an envelope of the kind described before
                   3466:             dfs_pushdecls.  */
                   3467:          tree class_value = IDENTIFIER_CLASS_VALUE (DECL_NAME (*methods));
                   3468:          tree tmp = TREE_PURPOSE (class_value);
                   3469: #else
                   3470:          tree tmp = IDENTIFIER_CLASS_VALUE (DECL_NAME (*methods));
                   3471: #endif
                   3472: 
                   3473:          /* This was replaced in scope by somebody else.  Just leave it
                   3474:             alone.  */
                   3475:          if (TREE_CODE (tmp) != TREE_LIST)
                   3476:            continue;
                   3477: 
                   3478:          if (TREE_CHAIN (tmp) == NULL_TREE
                   3479:              && TREE_VALUE (tmp)
                   3480:              && DECL_CHAIN (TREE_VALUE (tmp)) == NULL_TREE)
                   3481:            {
                   3482: #if NEW_CLASS_SCOPING
                   3483:              TREE_PURPOSE (class_value) = TREE_VALUE (tmp);
                   3484: #else
                   3485:              IDENTIFIER_CLASS_VALUE (DECL_NAME (*methods)) = TREE_VALUE (tmp);
                   3486: #endif
                   3487:            }
                   3488:        }
                   3489:     }
                   3490:   CLEAR_BINFO_MARKED (binfo);
                   3491: }
                   3492: 
                   3493: /* When entering the scope of a class, we cache all of the
                   3494:    fields that that class provides within its inheritance
                   3495:    lattice.  Where ambiguities result, we mark them
                   3496:    with `error_mark_node' so that if they are encountered
                   3497:    without explicit qualification, we can emit an error
                   3498:    message.  */
                   3499: void
                   3500: push_class_decls (type)
                   3501:      tree type;
                   3502: {
                   3503:   tree id;
                   3504:   struct obstack *ambient_obstack = current_obstack;
                   3505: 
                   3506: #if 0
                   3507:   tree tags = CLASSTYPE_TAGS (type);
                   3508: 
                   3509:   while (tags)
                   3510:     {
                   3511:       tree code_type_node;
                   3512:       tree tag;
                   3513: 
                   3514:       switch (TREE_CODE (TREE_VALUE (tags)))
                   3515:        {
                   3516:        case ENUMERAL_TYPE:
                   3517:          code_type_node = enum_type_node;
                   3518:          break;
                   3519:        case RECORD_TYPE:
                   3520:          code_type_node = record_type_node;
                   3521:          break;
                   3522:        case CLASS_TYPE:
                   3523:          code_type_node = class_type_node;
                   3524:          break;
                   3525:        case UNION_TYPE:
                   3526:          code_type_node = union_type_node;
                   3527:          break;
                   3528:        default:
                   3529:          my_friendly_abort (297);
                   3530:        }
                   3531:       tag = xref_tag (code_type_node, TREE_PURPOSE (tags),
                   3532:                      TYPE_BINFO_BASETYPE (TREE_VALUE (tags), 0));
                   3533: #if 0 /* not yet, should get fixed properly later */
                   3534:       pushdecl (make_type_decl (TREE_PURPOSE (tags), TREE_VALUE (tags)));
                   3535: #else
                   3536:       pushdecl (build_decl (TYPE_DECL, TREE_PURPOSE (tags), TREE_VALUE (tags)));
                   3537: #endif
                   3538:     }
                   3539: #endif
                   3540: 
                   3541:   search_stack = push_search_level (search_stack, &search_obstack);
                   3542: 
                   3543:   id = TYPE_IDENTIFIER (type);
                   3544:   if (IDENTIFIER_TEMPLATE (id) != 0)
                   3545:     {
                   3546: #if 0
                   3547:       tree tmpl = IDENTIFIER_TEMPLATE (id);
                   3548:       push_template_decls (DECL_ARGUMENTS (TREE_PURPOSE (tmpl)),
                   3549:                           TREE_VALUE (tmpl), 1);
                   3550: #endif
                   3551: #if NEW_CLASS_SCOPING
                   3552:       overload_template_name (id, 1);
                   3553: #else
                   3554:       overload_template_name (id, 0);
                   3555: #endif
                   3556:     }
                   3557: 
                   3558:   /* Push class fields into CLASS_VALUE scope, and mark.  */
                   3559:   dfs_walk (TYPE_BINFO (type), dfs_pushdecls, unmarkedp);
                   3560: 
                   3561:   /* Compress fields which have only a single entry
                   3562:      by a given name, and unmark.  */
                   3563:   dfs_walk (TYPE_BINFO (type), dfs_compress_decls, markedp);
                   3564: 
                   3565: #if NEW_CLASS_SCOPING
                   3566:   /* Open up all the closed envelopes and push the contained decls into
                   3567:      class scope.  */
                   3568:   while (closed_envelopes)
                   3569:     {
                   3570:       tree new = TREE_PURPOSE (closed_envelopes);
                   3571:       tree id;
                   3572: 
                   3573:       /* This is messy because the class value may be a *_DECL, or a
                   3574:         TREE_LIST of overloaded *_DECLs or even a TREE_LIST of ambiguous
                   3575:         *_DECLs.  The name is stored at different places in these three
                   3576:         cases.  */
                   3577:       if (TREE_CODE (new) == TREE_LIST)
                   3578:        {
                   3579:          if (TREE_PURPOSE (new) != NULL_TREE)
                   3580:            id = TREE_PURPOSE (new);
                   3581:          else
                   3582:            {
                   3583:              tree node = TREE_VALUE (new);
                   3584: 
                   3585:              while (TREE_CODE (node) == TREE_LIST)
                   3586:                node = TREE_VALUE (node);
                   3587:              id = DECL_NAME (node);
                   3588:            }
                   3589:        }
                   3590:       else
                   3591:        id = DECL_NAME (new);
                   3592: 
                   3593:       /* Install the original class value in order to make
                   3594:         pushdecl_class_level work correctly.  */
                   3595:       IDENTIFIER_CLASS_VALUE (id) = TREE_VALUE (closed_envelopes);
                   3596:       if (TREE_CODE (new) == TREE_LIST)
                   3597:        push_class_level_binding (id, new);
                   3598:       else
                   3599:        pushdecl_class_level (new);
                   3600:       closed_envelopes = TREE_CHAIN (closed_envelopes);
                   3601:     }
                   3602: #endif
                   3603:   current_obstack = ambient_obstack;
                   3604: }
                   3605: 
                   3606: #if !NEW_CLASS_SCOPING
                   3607: static void
                   3608: dfs_popdecls (binfo)
                   3609:      tree binfo;
                   3610: {
                   3611:   tree type = BINFO_TYPE (binfo);
                   3612:   tree fields = TYPE_FIELDS (type);
                   3613:   tree method_vec = CLASSTYPE_METHOD_VEC (type);
                   3614: 
                   3615:   while (fields)
                   3616:     {
                   3617:       if (DECL_NAME (fields) == NULL_TREE
                   3618:          && TREE_CODE (TREE_TYPE (fields)) == UNION_TYPE)
                   3619:        {
                   3620:          dfs_popdecls (TYPE_BINFO (TREE_TYPE (fields)));
                   3621:        }
                   3622:       else if (DECL_NAME (fields))
                   3623:        IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) = NULL_TREE;
                   3624:       fields = TREE_CHAIN (fields);
                   3625:     }
                   3626:   if (method_vec != 0)
                   3627:     {
                   3628:       tree *methods = &TREE_VEC_ELT (method_vec, 0);
                   3629:       tree *end = TREE_VEC_END (method_vec);
                   3630: 
                   3631:       /* Clear out ctors and dtors.  */
                   3632:       if (*methods)
                   3633:        IDENTIFIER_CLASS_VALUE (TYPE_IDENTIFIER (type)) = NULL_TREE;
                   3634: 
                   3635:       for (methods += 1; methods != end; methods++)
                   3636:        IDENTIFIER_CLASS_VALUE (DECL_NAME (*methods)) = NULL_TREE;
                   3637:     }
                   3638: 
                   3639:   SET_BINFO_MARKED (binfo);
                   3640: }
                   3641: #endif
                   3642: 
                   3643: void
                   3644: pop_class_decls (type)
                   3645:      tree type;
                   3646: {
                   3647: #if !NEW_CLASS_SCOPING
                   3648:   tree binfo = TYPE_BINFO (type);
                   3649: 
                   3650:   /* Clear out the IDENTIFIER_CLASS_VALUE which this
                   3651:      class may have occupied, and mark.  */
                   3652:   dfs_walk (binfo, dfs_popdecls, unmarkedp);
                   3653: 
                   3654:   /* Unmark.  */
                   3655:   dfs_walk (binfo, dfs_unmark, markedp);
                   3656: #else
                   3657:   /* We haven't pushed a search level when dealing with cached classes,
                   3658:      so we'd better not try to pop it.  */
                   3659:   if (search_stack)
                   3660: #endif
                   3661:     search_stack = pop_search_level (search_stack);
                   3662: }
                   3663: 
                   3664: static int
                   3665: bfs_unmark_finished_struct (binfo, i)
                   3666:      tree binfo;
                   3667:      int i;
                   3668: {
                   3669:   if (i >= 0)
                   3670:     binfo = BINFO_BASETYPE (binfo, i);
                   3671: 
                   3672:   if (BINFO_NEW_VTABLE_MARKED (binfo))
                   3673:     {
                   3674:       tree decl, context;
                   3675: 
                   3676:       if (TREE_VIA_VIRTUAL (binfo))
                   3677:        binfo = binfo_member (BINFO_TYPE (binfo),
                   3678:                              CLASSTYPE_VBASECLASSES (current_class_type));
                   3679: 
                   3680:       decl = BINFO_VTABLE (binfo);
                   3681:       context = DECL_CONTEXT (decl);
                   3682:       DECL_CONTEXT (decl) = 0;
                   3683:       if (write_virtuals >= 0
                   3684:          && DECL_INITIAL (decl) != BINFO_VIRTUALS (binfo))
                   3685:        DECL_INITIAL (decl) = build_nt (CONSTRUCTOR, NULL_TREE,
                   3686:                                        BINFO_VIRTUALS (binfo));
                   3687:       finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0);
                   3688:       DECL_CONTEXT (decl) = context;
                   3689:     }
                   3690:   CLEAR_BINFO_VTABLE_PATH_MARKED (binfo);
                   3691:   CLEAR_BINFO_NEW_VTABLE_MARKED (binfo);
                   3692:   return 0;
                   3693: }
                   3694: 
                   3695: void
                   3696: unmark_finished_struct (type)
                   3697:      tree type;
                   3698: {
                   3699:   tree binfo = TYPE_BINFO (type);
                   3700:   bfs_unmark_finished_struct (binfo, -1);
                   3701:   breadth_first_search (binfo, bfs_unmark_finished_struct, bfs_marked_vtable_pathp);
                   3702: }
                   3703: 
                   3704: void
                   3705: print_search_statistics ()
                   3706: {
                   3707: #ifdef GATHER_STATISTICS
                   3708:   if (flag_memoize_lookups)
                   3709:     {
                   3710:       fprintf (stderr, "%d memoized contexts saved\n",
                   3711:               n_contexts_saved);
                   3712:       fprintf (stderr, "%d local tree nodes made\n", my_tree_node_counter);
                   3713:       fprintf (stderr, "%d local hash nodes made\n", my_memoized_entry_counter);
                   3714:       fprintf (stderr, "fields statistics:\n");
                   3715:       fprintf (stderr, "  memoized finds = %d; rejects = %d; (searches = %d)\n",
                   3716:               memoized_fast_finds[0], memoized_fast_rejects[0],
                   3717:               memoized_fields_searched[0]);
                   3718:       fprintf (stderr, "  memoized_adds = %d\n", memoized_adds[0]);
                   3719:       fprintf (stderr, "fnfields statistics:\n");
                   3720:       fprintf (stderr, "  memoized finds = %d; rejects = %d; (searches = %d)\n",
                   3721:               memoized_fast_finds[1], memoized_fast_rejects[1],
                   3722:               memoized_fields_searched[1]);
                   3723:       fprintf (stderr, "  memoized_adds = %d\n", memoized_adds[1]);
                   3724:     }
                   3725:   fprintf (stderr, "%d fields searched in %d[%d] calls to lookup_field[_1]\n",
                   3726:           n_fields_searched, n_calls_lookup_field, n_calls_lookup_field_1);
                   3727:   fprintf (stderr, "%d fnfields searched in %d calls to lookup_fnfields\n",
                   3728:           n_outer_fields_searched, n_calls_lookup_fnfields);
                   3729:   fprintf (stderr, "%d calls to get_base_type\n", n_calls_get_base_type);
                   3730: #else
                   3731:   fprintf (stderr, "no search statistics\n");
                   3732: #endif
                   3733: }
                   3734: 
                   3735: void
                   3736: init_search_processing ()
                   3737: {
                   3738:   gcc_obstack_init (&search_obstack);
                   3739:   gcc_obstack_init (&type_obstack);
                   3740:   gcc_obstack_init (&type_obstack_entries);
                   3741: 
                   3742:   /* This gives us room to build our chains of basetypes,
                   3743:      whether or not we decide to memoize them.  */
                   3744:   type_stack = push_type_level (0, &type_obstack);
                   3745:   _vptr_name = get_identifier ("_vptr");
                   3746: }
                   3747: 
                   3748: void
                   3749: reinit_search_statistics ()
                   3750: {
                   3751:   my_memoized_entry_counter = 0;
                   3752:   memoized_fast_finds[0] = 0;
                   3753:   memoized_fast_finds[1] = 0;
                   3754:   memoized_adds[0] = 0;
                   3755:   memoized_adds[1] = 0;
                   3756:   memoized_fast_rejects[0] = 0;
                   3757:   memoized_fast_rejects[1] = 0;
                   3758:   memoized_fields_searched[0] = 0;
                   3759:   memoized_fields_searched[1] = 0;
                   3760:   n_fields_searched = 0;
                   3761:   n_calls_lookup_field = 0, n_calls_lookup_field_1 = 0;
                   3762:   n_calls_lookup_fnfields = 0, n_calls_lookup_fnfields_1 = 0;
                   3763:   n_calls_get_base_type = 0;
                   3764:   n_outer_fields_searched = 0;
                   3765:   n_contexts_saved = 0;
                   3766: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.