Annotation of gcc/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: /* This list is used by push_class_decls to know what decls need to
                    152:    be pushed into class scope.  */
                    153: static tree closed_envelopes = NULL_TREE;
                    154: 
                    155: /* Allocate a level of type memoization context.  */
                    156: static struct type_level *
                    157: push_type_level (stack, obstack)
                    158:      struct stack_level *stack;
                    159:      struct obstack *obstack;
                    160: {
                    161:   struct type_level tem;
                    162: 
                    163:   tem.base.prev = stack;
                    164: 
                    165:   obstack_finish (&type_obstack_entries);
                    166:   tem.entries = (char *) obstack_base (&type_obstack_entries);
                    167:   tem.len = 0;
                    168:   tem.type = NULL_TREE;
                    169: 
                    170:   return (struct type_level *)push_stack_level (obstack, (char *)&tem, sizeof (tem));
                    171: }
                    172: 
                    173: /* Discard a level of type memoization context.  */
                    174: 
                    175: static struct type_level *
                    176: pop_type_level (stack)
                    177:      struct type_level *stack;
                    178: {
                    179:   obstack_free (&type_obstack_entries, stack->entries);
                    180:   return (struct type_level *)pop_stack_level ((struct stack_level *)stack);
                    181: }
                    182: 
                    183: /* Make something that looks like a TREE_LIST, but
                    184:    do it on the type_obstack_entries obstack.  */
                    185: static tree
                    186: my_tree_cons (purpose, value, chain)
                    187:      tree purpose, value, chain;
                    188: {
                    189:   tree p = (tree)obstack_alloc (&type_obstack_entries, sizeof (struct tree_list));
                    190:   ++my_tree_node_counter;
                    191:   TREE_TYPE (p) = NULL_TREE;
                    192:   ((HOST_WIDE_INT *)p)[3] = 0;
                    193:   TREE_SET_CODE (p, TREE_LIST);
                    194:   TREE_PURPOSE (p) = purpose;
                    195:   TREE_VALUE (p) = value;
                    196:   TREE_CHAIN (p) = chain;
                    197:   return p;
                    198: }
                    199: 
                    200: static tree
                    201: my_build_string (str)
                    202:      char *str;
                    203: {
                    204:   tree p = (tree)obstack_alloc (&type_obstack_entries, sizeof (struct tree_string));
                    205:   ++my_tree_node_counter;
                    206:   TREE_TYPE (p) = 0;
                    207:   ((int *)p)[3] = 0;
                    208:   TREE_SET_CODE (p, STRING_CST);
                    209:   TREE_STRING_POINTER (p) = str;
                    210:   TREE_STRING_LENGTH (p) = strlen (str);
                    211:   return p;
                    212: }
                    213: 
                    214: /* Memoizing machinery to make searches for multiple inheritance
                    215:    reasonably efficient.  */
                    216: #define MEMOIZE_HASHSIZE 8
                    217: typedef struct memoized_entry
                    218: {
                    219:   struct memoized_entry *chain;
                    220:   int uid;
                    221:   tree data_members[MEMOIZE_HASHSIZE];
                    222:   tree function_members[MEMOIZE_HASHSIZE];
                    223: } *ME;
                    224: 
                    225: #define MEMOIZED_CHAIN(ENTRY) (((ME)ENTRY)->chain)
                    226: #define MEMOIZED_UID(ENTRY) (((ME)ENTRY)->uid)
                    227: #define MEMOIZED_FIELDS(ENTRY,INDEX) (((ME)ENTRY)->data_members[INDEX])
                    228: #define MEMOIZED_FNFIELDS(ENTRY,INDEX) (((ME)ENTRY)->function_members[INDEX])
                    229: /* The following is probably a lousy hash function.  */
                    230: #define MEMOIZED_HASH_FN(NODE) (((long)(NODE)>>4)&(MEMOIZE_HASHSIZE - 1))
                    231: 
                    232: static struct memoized_entry *
                    233: my_new_memoized_entry (chain)
                    234:      struct memoized_entry *chain;
                    235: {
                    236:   struct memoized_entry *p =
                    237:     (struct memoized_entry *)obstack_alloc (&type_obstack_entries,
                    238:                                            sizeof (struct memoized_entry));
                    239:   bzero ((char *) p, sizeof (struct memoized_entry));
                    240:   MEMOIZED_CHAIN (p) = chain;
                    241:   MEMOIZED_UID (p) = ++my_memoized_entry_counter;
                    242:   return p;
                    243: }
                    244: 
                    245: /* Make an entry in the memoized table for type TYPE
                    246:    that the entry for NAME is FIELD.  */
                    247: 
                    248: tree
                    249: make_memoized_table_entry (type, name, function_p)
                    250:      tree type, name;
                    251:      int function_p;
                    252: {
                    253:   int index = MEMOIZED_HASH_FN (name);
                    254:   tree entry, *prev_entry;
                    255: 
                    256:   memoized_adds[function_p] += 1;
                    257:   if (CLASSTYPE_MTABLE_ENTRY (type) == 0)
                    258:     {
                    259:       obstack_ptr_grow (&type_obstack, type);
                    260:       obstack_blank (&type_obstack, sizeof (struct memoized_entry *));
                    261:       CLASSTYPE_MTABLE_ENTRY (type) = (char *)my_new_memoized_entry ((struct memoized_entry *)0);
                    262:       type_stack->len++;
                    263:       if (type_stack->len * 2 >= type_stack->base.limit)
                    264:        my_friendly_abort (88);
                    265:     }
                    266:   if (function_p)
                    267:     prev_entry = &MEMOIZED_FNFIELDS (CLASSTYPE_MTABLE_ENTRY (type), index);
                    268:   else
                    269:     prev_entry = &MEMOIZED_FIELDS (CLASSTYPE_MTABLE_ENTRY (type), index);
                    270: 
                    271:   entry = my_tree_cons (name, NULL_TREE, *prev_entry);
                    272:   *prev_entry = entry;
                    273: 
                    274:   /* Don't know the error message to give yet.  */
                    275:   TREE_TYPE (entry) = error_mark_node;
                    276: 
                    277:   return entry;
                    278: }
                    279: 
                    280: /* When a new function or class context is entered, we build
                    281:    a table of types which have been searched for members.
                    282:    The table is an array (obstack) of types.  When a type is
                    283:    entered into the obstack, its CLASSTYPE_MTABLE_ENTRY
                    284:    field is set to point to a new record, of type struct memoized_entry.
                    285: 
                    286:    A non-NULL TREE_TYPE of the entry contains an access control error message.
                    287: 
                    288:    The slots for the data members are arrays of tree nodes.
                    289:    These tree nodes are lists, with the TREE_PURPOSE
                    290:    of this list the known member name, and the TREE_VALUE
                    291:    as the FIELD_DECL for the member.
                    292: 
                    293:    For member functions, the TREE_PURPOSE is again the
                    294:    name of the member functions for that class,
                    295:    and the TREE_VALUE of the list is a pairs
                    296:    whose TREE_PURPOSE is a member functions of this name,
                    297:    and whose TREE_VALUE is a list of known argument lists this
                    298:    member function has been called with.  The TREE_TYPE of the pair,
                    299:    if non-NULL, is an error message to print.  */
                    300: 
                    301: /* Tell search machinery that we are entering a new context, and
                    302:    to update tables appropriately.
                    303: 
                    304:    TYPE is the type of the context we are entering, which can
                    305:    be NULL_TREE if we are not in a class's scope.
                    306: 
                    307:    USE_OLD, if nonzero tries to use previous context.  */
                    308: void
                    309: push_memoized_context (type, use_old)
                    310:      tree type;
                    311:      int use_old;
                    312: {
                    313:   int len;
                    314:   tree *tem;
                    315: 
                    316:   if (prev_type_stack)
                    317:     {
                    318:       if (use_old && prev_type_memoized == type)
                    319:        {
                    320: #ifdef GATHER_STATISTICS
                    321:          n_contexts_saved++;
                    322: #endif
                    323:          type_stack = prev_type_stack;
                    324:          prev_type_stack = 0;
                    325: 
                    326:          tem = &type_stack->base.first[0];
                    327:          len = type_stack->len;
                    328:          while (len--)
                    329:            CLASSTYPE_MTABLE_ENTRY (tem[len*2]) = (char *)tem[len*2+1];
                    330:          return;
                    331:        }
                    332:       /* Otherwise, need to pop old stack here.  */
                    333:       type_stack = pop_type_level (prev_type_stack);
                    334:       prev_type_memoized = 0;
                    335:       prev_type_stack = 0;
                    336:     }
                    337: 
                    338:   type_stack = push_type_level ((struct stack_level *)type_stack,
                    339:                                &type_obstack);
                    340:   type_stack->type = type;
                    341: }
                    342: 
                    343: /* Tell search machinery that we have left a context.
                    344:    We do not currently save these contexts for later use.
                    345:    If we wanted to, we could not use pop_search_level, since
                    346:    poping that level allows the data we have collected to
                    347:    be clobbered; a stack of obstacks would be needed.  */
                    348: void
                    349: pop_memoized_context (use_old)
                    350:      int use_old;
                    351: {
                    352:   int len;
                    353:   tree *tem = &type_stack->base.first[0];
                    354: 
                    355:   if (! flag_save_memoized_contexts)
                    356:     use_old = 0;
                    357:   else if (use_old)
                    358:     {
                    359:       len = type_stack->len;
                    360:       while (len--)
                    361:        tem[len*2+1] = (tree)CLASSTYPE_MTABLE_ENTRY (tem[len*2]);
                    362: 
                    363:       prev_type_stack = type_stack;
                    364:       prev_type_memoized = type_stack->type;
                    365:     }
                    366: 
                    367:   if (flag_memoize_lookups)
                    368:     {
                    369:       len = type_stack->len;
                    370:       while (len--)
                    371:        CLASSTYPE_MTABLE_ENTRY (tem[len*2])
                    372:          = (char *)MEMOIZED_CHAIN (CLASSTYPE_MTABLE_ENTRY (tem[len*2]));
                    373:     }
                    374:   if (! use_old)
                    375:     type_stack = pop_type_level (type_stack);
                    376:   else
                    377:     type_stack = (struct type_level *)type_stack->base.prev;
                    378: }
                    379: 
                    380: #if 0                          /* unused */
                    381: /* This is the newer recursive depth first search routine. */
                    382: /* Return non-zero if PARENT is directly derived from TYPE.  By directly
                    383:    we mean it's only one step up the inheritance lattice.  We check this
                    384:    by walking horizontally across the types that TYPE directly inherits
                    385:    from, to see if PARENT is among them.  This is used by get_binfo and
                    386:    by compute_access.  */
                    387: static int
                    388: immediately_derived (parent, type)
                    389:      tree parent, type;
                    390: {
                    391:   if (TYPE_BINFO (type))
                    392:     {
                    393:       tree binfos = BINFO_BASETYPES (TYPE_BINFO (type));
                    394:       int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
                    395: 
                    396:       for (i = 0; i < n_baselinks; i++)
                    397:        {
                    398:          tree base_binfo = TREE_VEC_ELT (binfos, i);
                    399: 
                    400:          if (parent == BINFO_TYPE (base_binfo))
                    401:            return 1;
                    402:        }
                    403:     }
                    404:   return 0;
                    405: }
                    406: #endif
                    407: 
                    408: /* Check whether the type given in BINFO is derived from PARENT.  If
                    409:    it isn't, return 0.  If it is, but the derivation is MI-ambiguous
                    410:    AND protect != 0, emit an error message and return error_mark_node.
                    411: 
                    412:    Otherwise, if TYPE is derived from PARENT, return the actual base
                    413:    information, unless a one of the protection violations below
                    414:    occurs, in which case emit an error message and return error_mark_node.
                    415: 
                    416:    If PROTECT is 1, then check if access to a public field of PARENT
                    417:    would be private.  Also check for ambiguity.  */
                    418: 
                    419: tree
                    420: get_binfo (parent, binfo, protect)
                    421:      register tree parent, binfo;
                    422:      int protect;
                    423: {
                    424:   tree type;
                    425:   int dist;
                    426:   tree rval = NULL_TREE;
                    427:   
                    428:   if (TREE_CODE (parent) == TREE_VEC)
                    429:     parent = BINFO_TYPE (parent);
                    430:   /* unions cannot participate in inheritance relationships */
                    431:   else if (TREE_CODE (parent) == UNION_TYPE)
                    432:     return NULL_TREE;
                    433:   else if (TREE_CODE (parent) != RECORD_TYPE)
                    434:     my_friendly_abort (89);
                    435: 
                    436:   if (TREE_CODE (binfo) == TREE_VEC)
                    437:     type = BINFO_TYPE (binfo);
                    438:   else if (TREE_CODE (binfo) == RECORD_TYPE)
                    439:     type = binfo;
                    440:   else if (TREE_CODE (binfo) == UNION_TYPE)
                    441:     return NULL_TREE;
                    442:   else
                    443:     my_friendly_abort (90);
                    444:   
                    445:   dist = get_base_distance (parent, binfo, protect, &rval);
                    446: 
                    447:   if (dist == -3)
                    448:     {
                    449:       cp_error ("fields of `%T' are inaccessible in `%T' due to private inheritance",
                    450:                parent, type);
                    451:       return error_mark_node;
                    452:     }
                    453:   else if (dist == -2 && protect)
                    454:     {
                    455:       cp_error ("type `%T' is ambiguous base class for type `%T'", parent,
                    456:                type);
                    457:       return error_mark_node;
                    458:     }
                    459: 
                    460:   return rval;
                    461: }
                    462: 
                    463: /* This is the newer depth first get_base_distance routine.  */
                    464: static int
                    465: get_base_distance_recursive (binfo, depth, is_private, basetype_path, rval,
                    466:                             rval_private_ptr, new_binfo_ptr, parent, path_ptr,
                    467:                             protect, via_virtual_ptr, via_virtual)
                    468:      tree binfo, basetype_path, *new_binfo_ptr, parent, *path_ptr;
                    469:      int *rval_private_ptr, depth, is_private, rval, protect, *via_virtual_ptr,
                    470:        via_virtual;
                    471: {
                    472:   tree binfos;
                    473:   int i, n_baselinks;
                    474: 
                    475:   if (BINFO_TYPE (binfo) == parent || binfo == parent)
                    476:     {
                    477:       if (rval == -1)
                    478:        {
                    479:          rval = depth;
                    480:          *rval_private_ptr = is_private;
                    481:          *new_binfo_ptr = binfo;
                    482:          *via_virtual_ptr = via_virtual;
                    483:        }
                    484:       else
                    485:        {
                    486:          int same_object = (tree_int_cst_equal (BINFO_OFFSET (*new_binfo_ptr),
                    487:                                                 BINFO_OFFSET (binfo))
                    488:                             && *via_virtual_ptr && via_virtual);
                    489:                             
                    490:          if (*via_virtual_ptr && via_virtual==0)
                    491:            {
                    492:              *rval_private_ptr = is_private;
                    493:              *new_binfo_ptr = binfo;
                    494:              *via_virtual_ptr = via_virtual;
                    495:            }
                    496:          else if (same_object)
                    497:            {
                    498:              if (*rval_private_ptr && ! is_private)
                    499:                {
                    500:                  *rval_private_ptr = is_private;
                    501:                  *new_binfo_ptr = binfo;
                    502:                  *via_virtual_ptr = via_virtual;
                    503:                }
                    504:              return rval;
                    505:            }
                    506: 
                    507:          rval = -2;
                    508:        }
                    509:       return rval;
                    510:     }
                    511: 
                    512:   binfos = BINFO_BASETYPES (binfo);
                    513:   n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
                    514:   depth += 1;
                    515: 
                    516:   /* Process base types.  */
                    517:   for (i = 0; i < n_baselinks; i++)
                    518:     {
                    519:       tree base_binfo = TREE_VEC_ELT (binfos, i);
                    520: 
                    521:       /* Find any specific instance of a virtual base, when searching with
                    522:         a binfo... */
                    523:       if (BINFO_MARKED (base_binfo) == 0 || TREE_CODE (parent) == TREE_VEC)
                    524:        {
                    525:          int via_private
                    526:            = (protect
                    527:               && (is_private
                    528:                   || (!TREE_VIA_PUBLIC (base_binfo)
                    529:                       && !is_friend (BINFO_TYPE (binfo), current_scope ()))));
                    530:          int this_virtual = via_virtual || TREE_VIA_VIRTUAL (base_binfo);
                    531:          int was;
                    532: 
                    533:          /* When searching for a non-virtual, we cannot mark
                    534:             virtually found binfos. */
                    535:          if (! this_virtual)
                    536:            SET_BINFO_MARKED (base_binfo);
                    537: 
                    538: #define WATCH_VALUES(rval, via_private) (rval == -1 ? 3 : via_private)
                    539: 
                    540:          was = WATCH_VALUES (rval, *via_virtual_ptr);
                    541:          rval = get_base_distance_recursive (base_binfo, depth, via_private,
                    542:                                              binfo, rval, rval_private_ptr,
                    543:                                              new_binfo_ptr, parent, path_ptr,
                    544:                                              protect, via_virtual_ptr,
                    545:                                              this_virtual);
                    546:          /* watch for updates; only update if path is good. */
                    547:          if (path_ptr && WATCH_VALUES (rval, *via_virtual_ptr) != was)
                    548:            BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
                    549:          if (rval == -2 && *via_virtual_ptr == 0)
                    550:            return rval;
                    551: 
                    552: #undef WATCH_VALUES
                    553: 
                    554:        }
                    555:     }
                    556: 
                    557:   return rval;
                    558: }
                    559: 
                    560: /* Return the number of levels between type PARENT and the type given
                    561:    in BINFO, following the leftmost path to PARENT not found along a
                    562:    virtual path, if there are no real PARENTs (all come from virtual
                    563:    base classes), then follow the leftmost path to PARENT.
                    564: 
                    565:    Return -1 if TYPE is not derived from PARENT.
                    566:    Return -2 if PARENT is an ambiguous base class of TYPE, and PROTECT is
                    567:     non-negative.
                    568:    Return -3 if PARENT is private to TYPE, and PROTECT is non-zero.
                    569: 
                    570:    If PATH_PTR is non-NULL, then also build the list of types
                    571:    from PARENT to TYPE, with TREE_VIA_VIRUAL and TREE_VIA_PUBLIC
                    572:    set.
                    573: 
                    574:    PARENT can also be a binfo, in which case that exact parent is found
                    575:    and no other.  convert_pointer_to_real uses this functionality.
                    576: 
                    577:    If BINFO is a binfo, its BINFO_INHERITANCE_CHAIN will be left alone.  */
                    578: 
                    579: int
                    580: get_base_distance (parent, binfo, protect, path_ptr)
                    581:      register tree parent, binfo;
                    582:      int protect;
                    583:      tree *path_ptr;
                    584: {
                    585:   int rval;
                    586:   int rval_private = 0;
                    587:   tree type;
                    588:   tree new_binfo = NULL_TREE;
                    589:   int via_virtual;
                    590:   int watch_access = protect;
                    591: 
                    592:   if (TREE_CODE (parent) != TREE_VEC)
                    593:     parent = TYPE_MAIN_VARIANT (parent);
                    594: 
                    595:   if (TREE_CODE (binfo) == TREE_VEC)
                    596:     type = BINFO_TYPE (binfo);
                    597:   else if (IS_AGGR_TYPE_CODE (TREE_CODE (binfo)))
                    598:     {
                    599:       type = binfo;
                    600:       binfo = TYPE_BINFO (type);
                    601: 
                    602:       if (path_ptr)
                    603:        BINFO_INHERITANCE_CHAIN (binfo) = NULL_TREE;
                    604:     }
                    605:   else
                    606:     my_friendly_abort (92);
                    607: 
                    608:   if (parent == type || parent == binfo)
                    609:     {
                    610:       /* If the distance is 0, then we don't really need
                    611:         a path pointer, but we shouldn't let garbage go back.  */
                    612:       if (path_ptr)
                    613:        *path_ptr = binfo;
                    614:       return 0;
                    615:     }
                    616: 
                    617:   if (path_ptr)
                    618:     watch_access = 1;
                    619: 
                    620:   rval = get_base_distance_recursive (binfo, 0, 0, NULL_TREE, -1,
                    621:                                      &rval_private, &new_binfo, parent,
                    622:                                      path_ptr, watch_access, &via_virtual, 0);
                    623: 
                    624:   dfs_walk (binfo, dfs_unmark, markedp);
                    625: 
                    626:   /* Access restrictions don't count if we found an ambiguous basetype.  */
                    627:   if (rval == -2 && protect >= 0)
                    628:     rval_private = 0;
                    629: 
                    630:   if (rval && protect && rval_private)
                    631:     return -3;
                    632: 
                    633:   /* find real virtual base classes. */
                    634:   if (rval == -1 && TREE_CODE (parent) == TREE_VEC
                    635:       && parent == binfo_member (BINFO_TYPE (parent),
                    636:                                 CLASSTYPE_VBASECLASSES (type)))
                    637:     {
                    638:       BINFO_INHERITANCE_CHAIN (parent) = binfo;
                    639:       new_binfo = parent;
                    640:       rval = 1;
                    641:     }
                    642: 
                    643:   if (path_ptr)
                    644:     *path_ptr = new_binfo;
                    645:   return rval;
                    646: }
                    647: 
                    648: /* Search for a member with name NAME in a multiple inheritance lattice
                    649:    specified by TYPE.  If it does not exist, return NULL_TREE.
                    650:    If the member is ambiguously referenced, return `error_mark_node'.
                    651:    Otherwise, return the FIELD_DECL.  */
                    652: 
                    653: /* Do a 1-level search for NAME as a member of TYPE.  The caller must
                    654:    figure out whether it can access this field.  (Since it is only one
                    655:    level, this is reasonable.)  */
                    656: static tree
                    657: lookup_field_1 (type, name)
                    658:      tree type, name;
                    659: {
                    660:   register tree field = TYPE_FIELDS (type);
                    661: 
                    662: #ifdef GATHER_STATISTICS
                    663:   n_calls_lookup_field_1++;
                    664: #endif
                    665:   while (field)
                    666:     {
                    667: #ifdef GATHER_STATISTICS
                    668:       n_fields_searched++;
                    669: #endif
                    670:       if (DECL_NAME (field) == NULL_TREE
                    671:          && TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
                    672:        {
                    673:          tree temp = lookup_field_1 (TREE_TYPE (field), name);
                    674:          if (temp)
                    675:            return temp;
                    676:        }
                    677:       if (DECL_NAME (field) == name)
                    678:        {
                    679:          if ((TREE_CODE(field) == VAR_DECL || TREE_CODE(field) == CONST_DECL)
                    680:              && DECL_ASSEMBLER_NAME (field) != NULL)
                    681:            GNU_xref_ref(current_function_decl,
                    682:                         IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (field)));
                    683:          return field;
                    684:        }
                    685:       field = TREE_CHAIN (field);
                    686:     }
                    687:   /* Not found.  */
                    688:   if (name == _vptr_name)
                    689:     {
                    690:       /* Give the user what s/he thinks s/he wants.  */
                    691:       if (TYPE_VIRTUAL_P (type))
                    692:        return CLASSTYPE_VFIELD (type);
                    693:     }
                    694:   return NULL_TREE;
                    695: }
                    696: 
                    697: /* There are a number of cases we need to be aware of here:
                    698:                         current_class_type     current_function_decl
                    699:    * global                    NULL                    NULL
                    700:    * fn-local                  NULL                    SET
                    701:    * class-local               SET                     NULL
                    702:    * class->fn                 SET                     SET
                    703:    * fn->class                 SET                     SET
                    704: 
                    705:    Those last two make life interesting.  If we're in a function which is
                    706:    itself inside a class, we need decls to go into the fn's decls (our
                    707:    second case below).  But if we're in a class and the class itself is
                    708:    inside a function, we need decls to go into the decls for the class.  To
                    709:    achieve this last goal, we must see if, when both current_class_decl and
                    710:    current_function_decl are set, the class was declared inside that
                    711:    function.  If so, we know to put the decls into the class's scope.  */
                    712: 
                    713: tree
                    714: current_scope ()
                    715: {
                    716:   if (current_function_decl == NULL_TREE)
                    717:     return current_class_type;
                    718:   if (current_class_type == NULL_TREE)
                    719:     return current_function_decl;
                    720:   if (DECL_CLASS_CONTEXT (current_function_decl) == current_class_type)
                    721:     return current_function_decl;
                    722: 
                    723:   return current_class_type;
                    724: }
                    725: 
                    726: /* Compute the access of FIELD.  This is done by computing
                    727:    the access available to each type in BASETYPES (which comes
                    728:    as a list of [via_public/basetype] in reverse order, namely base
                    729:    class before derived class).  The first one which defines a
                    730:    access defines the access for the field.  Otherwise, the
                    731:    access of the field is that which occurs normally.
                    732: 
                    733:    Uses global variables CURRENT_CLASS_TYPE and
                    734:    CURRENT_FUNCTION_DECL to use friend relationships
                    735:    if necessary.
                    736: 
                    737:    This will be static when lookup_fnfield comes into this file.
                    738: 
                    739:    access_public means that the field can be accessed by the current lexical
                    740:    scope.
                    741: 
                    742:    access_protected means that the field cannot be accessed by the current
                    743:    lexical scope because it is protected.
                    744: 
                    745:    access_private means that the field cannot be accessed by the current
                    746:    lexical scope because it is private. */
                    747: 
                    748: #if 0
                    749: #define PUBLIC_RETURN return (DECL_PUBLIC (field) = 1), access_public
                    750: #define PROTECTED_RETURN return (DECL_PROTECTED (field) = 1), access_protected
                    751: #define PRIVATE_RETURN return (DECL_PRIVATE (field) = 1), access_private
                    752: #else
                    753: #define PUBLIC_RETURN return access_public
                    754: #define PROTECTED_RETURN return access_protected
                    755: #define PRIVATE_RETURN return access_private
                    756: #endif
                    757: 
                    758: #if 0
                    759: /* Disabled with DECL_PUBLIC &c.  */
                    760: static tree previous_scope = NULL_TREE;
                    761: #endif
                    762: 
                    763: enum access_type
                    764: compute_access (basetype_path, field)
                    765:      tree basetype_path, field;
                    766: {
                    767:   enum access_type access;
                    768:   tree types;
                    769:   tree context;
                    770:   int protected_ok, via_protected;
                    771:   extern int flag_access_control;
                    772: #if 1
                    773:   /* Replaces static decl above.  */
                    774:   tree previous_scope;
                    775: #endif
                    776:   int static_mem =
                    777:     ((TREE_CODE (field) == FUNCTION_DECL && DECL_STATIC_FUNCTION_P (field))
                    778:      || (TREE_CODE (field) != FUNCTION_DECL && TREE_STATIC (field)));
                    779: 
                    780:   if (! flag_access_control)
                    781:     return access_public;
                    782: 
                    783:   /* The field lives in the current class.  */
                    784:   if (BINFO_TYPE (basetype_path) == current_class_type)
                    785:     return access_public;
                    786: 
                    787: #if 0
                    788:   /* Disabled until pushing function scope clears these out.  If ever.  */
                    789:   /* Make these special cases fast.  */
                    790:   if (current_scope () == previous_scope)
                    791:     {
                    792:       if (DECL_PUBLIC (field))
                    793:        return access_public;
                    794:       if (DECL_PROTECTED (field))
                    795:        return access_protected;
                    796:       if (DECL_PRIVATE (field))
                    797:        return access_private;
                    798:     }
                    799: #endif
                    800: 
                    801:   previous_scope = current_scope ();
                    802:   
                    803:   context = DECL_CLASS_CONTEXT (field);
                    804:   if (context == NULL_TREE)
                    805:     context = DECL_CONTEXT (field);
                    806: 
                    807:   /* Fields coming from nested anonymous unions have their DECL_CLASS_CONTEXT
                    808:      slot set to the union type rather than the record type containing
                    809:      the anonymous union.  In this case, DECL_FIELD_CONTEXT is correct.  */
                    810:   if (context && TREE_CODE (context) == UNION_TYPE
                    811:       && ANON_AGGRNAME_P (TYPE_IDENTIFIER (context)))
                    812:     context = DECL_FIELD_CONTEXT (field);
                    813: 
                    814:   /* Virtual function tables are never private.  But we should know that
                    815:      we are looking for this, and not even try to hide it.  */
                    816:   if (DECL_NAME (field) && VFIELD_NAME_P (DECL_NAME (field)) == 1)
                    817:     PUBLIC_RETURN;
                    818: 
                    819:   /* Member found immediately within object.  */
                    820:   if (BINFO_INHERITANCE_CHAIN (basetype_path) == NULL_TREE)
                    821:     {
                    822:       /* Are we (or an enclosing scope) friends with the class that has
                    823:          FIELD? */
                    824:       if (is_friend (context, previous_scope))
                    825:        PUBLIC_RETURN;
                    826: 
                    827:       /* If it's private, it's private, you letch.  */
                    828:       if (TREE_PRIVATE (field))
                    829:        PRIVATE_RETURN;
                    830: 
                    831:       /* ARM $11.5.  Member functions of a derived class can access the
                    832:         non-static protected members of a base class only through a
                    833:         pointer to the derived class, a reference to it, or an object
                    834:         of it. Also any subsequently derived classes also have
                    835:         access.  */
                    836:       else if (TREE_PROTECTED (field))
                    837:        {
                    838:          if (current_class_type
                    839:              && static_mem
                    840:              && ACCESSIBLY_DERIVED_FROM_P (context, current_class_type))
                    841:            PUBLIC_RETURN;
                    842:          else
                    843:            PROTECTED_RETURN;
                    844:        }
                    845:       else
                    846:        PUBLIC_RETURN;
                    847:     }
                    848: 
                    849:   /* must reverse more than one element */
                    850:   basetype_path = reverse_path (basetype_path);
                    851:   types = basetype_path;
                    852:   via_protected = 0;
                    853:   access = access_default;
                    854:   protected_ok = static_mem && current_class_type
                    855:     && ACCESSIBLY_DERIVED_FROM_P (BINFO_TYPE (types), current_class_type);
                    856: 
                    857:   while (1)
                    858:     {
                    859:       tree member;
                    860:       tree binfo = types;
                    861:       tree type = BINFO_TYPE (binfo);
                    862:       int private_ok = 0;
                    863: 
                    864:       /* Friends of a class can see protected members of its bases.
                    865:          Note that classes are their own friends.  */
                    866:       if (is_friend (type, previous_scope))
                    867:        {
                    868:          protected_ok = 1;
                    869:          private_ok = 1;
                    870:        }
                    871: 
                    872:       member = purpose_member (type, DECL_ACCESS (field));
                    873:       if (member)
                    874:        {
                    875:          access = (enum access_type) TREE_VALUE (member);
                    876:          break;
                    877:        }
                    878: 
                    879:       types = BINFO_INHERITANCE_CHAIN (types);
                    880: 
                    881:       /* If the next type was VIA_PROTECTED, then fields of all remaining
                    882:         classes past that one are *at least* protected.  */
                    883:       if (types)
                    884:        {
                    885:          if (TREE_VIA_PROTECTED (types))
                    886:            via_protected = 1;
                    887:          else if (! TREE_VIA_PUBLIC (types) && ! private_ok)
                    888:            {
                    889:              access = access_private;
                    890:              break;
                    891:            }
                    892:        }
                    893:       else
                    894:        break;
                    895:     }
                    896:   reverse_path (basetype_path);
                    897: 
                    898:   /* No special visibilities apply.  Use normal rules.  */
                    899: 
                    900:   if (access == access_default)
                    901:     {
                    902:       if (is_friend (context, previous_scope))
                    903:        access = access_public;
                    904:       else if (TREE_PRIVATE (field))
                    905:        access = access_private;
                    906:       else if (TREE_PROTECTED (field))
                    907:        access = access_protected;
                    908:       else
                    909:        access = access_public;
                    910:     }
                    911: 
                    912:   if (access == access_public && via_protected)
                    913:     access = access_protected;
                    914: 
                    915:   if (access == access_protected && protected_ok)
                    916:     access = access_public;
                    917: 
                    918: #if 0
                    919:   if (access == access_public)
                    920:     DECL_PUBLIC (field) = 1;
                    921:   else if (access == access_protected)
                    922:     DECL_PROTECTED (field) = 1;
                    923:   else if (access == access_private)
                    924:     DECL_PRIVATE (field) = 1;
                    925:   else my_friendly_abort (96);
                    926: #endif
                    927:   return access;
                    928: }
                    929: 
                    930: /* Routine to see if the sub-object denoted by the binfo PARENT can be
                    931:    found as a base class and sub-object of the object denoted by
                    932:    BINFO.  This routine relies upon binfos not being shared, except
                    933:    for binfos for virtual bases.  */
                    934: static int
                    935: is_subobject_of_p (parent, binfo)
                    936:      tree parent, binfo;
                    937: {
                    938:   tree binfos = BINFO_BASETYPES (binfo);
                    939:   int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
                    940: 
                    941:   if (parent == binfo)
                    942:     return 1;
                    943: 
                    944:   /* Process and/or queue base types.  */
                    945:   for (i = 0; i < n_baselinks; i++)
                    946:     {
                    947:       tree base_binfo = TREE_VEC_ELT (binfos, i);
                    948:       if (TREE_VIA_VIRTUAL (base_binfo))
                    949:        base_binfo = TYPE_BINFO (BINFO_TYPE (base_binfo));
                    950:       if (is_subobject_of_p (parent, base_binfo))
                    951:        return 1;
                    952:     }
                    953:   return 0;
                    954: }
                    955: 
                    956: /* See if a one FIELD_DECL hides another.  This routine is meant to
                    957:    correspond to ANSI working paper Sept 17, 1992 10p4.  The two
                    958:    binfos given are the binfos corresponding to the particular places
                    959:    the FIELD_DECLs are found.  This routine relies upon binfos not
                    960:    being shared, except for virtual bases. */
                    961: static int
                    962: hides (hider_binfo, hidee_binfo)
                    963:      tree hider_binfo, hidee_binfo;
                    964: {
                    965:   /* hider hides hidee, if hider has hidee as a base class and
                    966:      the instance of hidee is a sub-object of hider.  The first
                    967:      part is always true is the second part is true.
                    968: 
                    969:      When hider and hidee are the same (two ways to get to the exact
                    970:      same member) we consider either one as hiding the other. */
                    971:   return is_subobject_of_p (hidee_binfo, hider_binfo);
                    972: }
                    973: 
                    974: /* Very similar to lookup_fnfields_1 but it ensures that at least one
                    975:    function was declared inside the class given by TYPE.  It really should
                    976:    only return functions that match the given TYPE.  */
                    977: static int
                    978: lookup_fnfields_here (type, name)
                    979:      tree type, name;
                    980: {
                    981:   int index = lookup_fnfields_1 (type, name);
                    982:   tree fndecls;
                    983: 
                    984:   if (index <= 0)
                    985:     return index;
                    986:   fndecls = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), index);
                    987:   while (fndecls)
                    988:     {
                    989:       if (TYPE_MAIN_VARIANT (DECL_CLASS_CONTEXT (fndecls))
                    990:          == TYPE_MAIN_VARIANT (type))
                    991:        return index;
                    992:       fndecls = TREE_CHAIN (fndecls);
                    993:     }
                    994:   return -1;
                    995: }
                    996: 
                    997: /* Look for a field named NAME in an inheritance lattice dominated by
                    998:    XBASETYPE.  PROTECT is zero if we can avoid computing access
                    999:    information, otherwise it is 1.  WANT_TYPE is 1 when we should only
                   1000:    return TYPE_DECLs, if no TYPE_DECL can be found return NULL_TREE.
                   1001: 
                   1002:    It was not clear what should happen if WANT_TYPE is set, and an
                   1003:    ambiguity is found.  At least one use (lookup_name) to not see
                   1004:    the error.  */
                   1005: tree
                   1006: lookup_field (xbasetype, name, protect, want_type)
                   1007:      register tree xbasetype, name;
                   1008:      int protect, want_type;
                   1009: {
                   1010:   int head = 0, tail = 0;
                   1011:   tree rval, rval_binfo = NULL_TREE, rval_binfo_h;
                   1012:   tree type, basetype_chain, basetype_path;
                   1013:   enum access_type this_v = access_default;
                   1014:   tree entry, binfo, binfo_h;
                   1015:   enum access_type own_access = access_default;
                   1016:   int vbase_name_p = VBASE_NAME_P (name);
                   1017: 
                   1018:   /* rval_binfo is the binfo associated with the found member, note,
                   1019:      this can be set with useful information, even when rval is not
                   1020:      set, because it must deal with ALL members, not just non-function
                   1021:      members.  It is used for ambiguity checking and the hidden
                   1022:      checks.  Whereas rval is only set if a proper (not hidden)
                   1023:      non-function member is found.  */
                   1024: 
                   1025:   /* rval_binfo_h and binfo_h are binfo values used when we perform the
                   1026:      hiding checks, as virtual base classes may not be shared.  The strategy
                   1027:      is we always go into the the binfo hierarchy owned by TYPE_BINFO of
                   1028:      virtual base classes, as we cross virtual base class lines.  This way
                   1029:      we know that binfo of a virtual base class will always == itself when
                   1030:      found along any line.  (mrs)  */
                   1031: 
                   1032:   char *errstr = 0;
                   1033: 
                   1034:   /* Set this to nonzero if we don't know how to compute
                   1035:      accurate error messages for access control.  */
                   1036:   int index = MEMOIZED_HASH_FN (name);
                   1037: 
                   1038:   /* If we are looking for a constructor in a templated type, use the
                   1039:      unspecialized name, as that is how we store it.  */
                   1040:   if (IDENTIFIER_TEMPLATE (name))
                   1041:     name = constructor_name (name);
                   1042: 
                   1043:   if (TREE_CODE (xbasetype) == TREE_VEC)
                   1044:     {
                   1045:       type = BINFO_TYPE (xbasetype);
                   1046:       basetype_path = xbasetype;
                   1047:     }
                   1048:   else if (IS_AGGR_TYPE_CODE (TREE_CODE (xbasetype)))
                   1049:     {
                   1050:       type = xbasetype;
                   1051:       basetype_path = TYPE_BINFO (xbasetype);
                   1052:       BINFO_VIA_PUBLIC (basetype_path) = 1;
                   1053:       BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE;
                   1054:     }
                   1055:   else my_friendly_abort (97);
                   1056: 
                   1057:   if (CLASSTYPE_MTABLE_ENTRY (type))
                   1058:     {
                   1059:       tree tem = MEMOIZED_FIELDS (CLASSTYPE_MTABLE_ENTRY (type), index);
                   1060: 
                   1061:       while (tem && TREE_PURPOSE (tem) != name)
                   1062:        {
                   1063:          memoized_fields_searched[0]++;
                   1064:          tem = TREE_CHAIN (tem);
                   1065:        }
                   1066:       if (tem)
                   1067:        {
                   1068:          if (protect && TREE_TYPE (tem))
                   1069:            {
                   1070:              error (TREE_STRING_POINTER (TREE_TYPE (tem)),
                   1071:                     IDENTIFIER_POINTER (name),
                   1072:                     TYPE_NAME_STRING (DECL_FIELD_CONTEXT (TREE_VALUE (tem))));
                   1073:              return error_mark_node;
                   1074:            }
                   1075:          if (TREE_VALUE (tem) == NULL_TREE)
                   1076:            memoized_fast_rejects[0] += 1;
                   1077:          else
                   1078:            memoized_fast_finds[0] += 1;
                   1079:          return TREE_VALUE (tem);
                   1080:        }
                   1081:     }
                   1082: 
                   1083: #ifdef GATHER_STATISTICS
                   1084:   n_calls_lookup_field++;
                   1085: #endif
                   1086:   if (protect && flag_memoize_lookups && ! global_bindings_p ())
                   1087:     entry = make_memoized_table_entry (type, name, 0);
                   1088:   else
                   1089:     entry = 0;
                   1090: 
                   1091:   rval = lookup_field_1 (type, name);
                   1092:   if (rval || lookup_fnfields_here (type, name)>=0)
                   1093:     {
                   1094:       rval_binfo = basetype_path;
                   1095:       rval_binfo_h = rval_binfo;
                   1096:     }
                   1097: 
                   1098:   if (rval && TREE_CODE (rval) != TYPE_DECL && want_type)
                   1099:     rval = NULL_TREE;
                   1100: 
                   1101:   if (rval)
                   1102:     {
                   1103:       if (protect)
                   1104:        {
                   1105:          if (TREE_PRIVATE (rval) | TREE_PROTECTED (rval))
                   1106:            this_v = compute_access (basetype_path, rval);
                   1107:          if (TREE_CODE (rval) == CONST_DECL)
                   1108:            {
                   1109:              if (this_v == access_private)
                   1110:                errstr = "enum `%D' is a private value of class `%T'";
                   1111:              else if (this_v == access_protected)
                   1112:                errstr = "enum `%D' is a protected value of class `%T'";
                   1113:            }
                   1114:          else
                   1115:            {
                   1116:              if (this_v == access_private)
                   1117:                errstr = "member `%D' is a private member of class `%T'";
                   1118:              else if (this_v == access_protected)
                   1119:                errstr = "member `%D' is a protected member of class `%T'";
                   1120:            }
                   1121:        }
                   1122: 
                   1123:       if (entry)
                   1124:        {
                   1125:          if (errstr)
                   1126:            {
                   1127:              /* This depends on behavior of lookup_field_1!  */
                   1128:              tree error_string = my_build_string (errstr);
                   1129:              TREE_TYPE (entry) = error_string;
                   1130:            }
                   1131:          else
                   1132:            {
                   1133:              /* Let entry know there is no problem with this access.  */
                   1134:              TREE_TYPE (entry) = NULL_TREE;
                   1135:            }
                   1136:          TREE_VALUE (entry) = rval;
                   1137:        }
                   1138: 
                   1139:       if (errstr && protect)
                   1140:        {
                   1141:          cp_error (errstr, name, type);
                   1142:          return error_mark_node;
                   1143:        }
                   1144:       return rval;
                   1145:     }
                   1146: 
                   1147:   basetype_chain = build_tree_list (NULL_TREE, basetype_path);
                   1148:   TREE_VIA_PUBLIC (basetype_chain) = TREE_VIA_PUBLIC (basetype_path);
                   1149:   TREE_VIA_PROTECTED (basetype_chain) = TREE_VIA_PROTECTED (basetype_path);
                   1150:   TREE_VIA_VIRTUAL (basetype_chain) = TREE_VIA_VIRTUAL (basetype_path);
                   1151: 
                   1152:   /* The ambiguity check relies upon breadth first searching. */
                   1153: 
                   1154:   search_stack = push_search_level (search_stack, &search_obstack);
                   1155:   binfo = basetype_path;
                   1156:   binfo_h = binfo;
                   1157: 
                   1158:   while (1)
                   1159:     {
                   1160:       tree binfos = BINFO_BASETYPES (binfo);
                   1161:       int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
                   1162:       tree nval;
                   1163: 
                   1164:       /* Process and/or queue base types.  */
                   1165:       for (i = 0; i < n_baselinks; i++)
                   1166:        {
                   1167:          tree base_binfo = TREE_VEC_ELT (binfos, i);
                   1168:          if (BINFO_FIELDS_MARKED (base_binfo) == 0)
                   1169:            {
                   1170:              tree btypes;
                   1171: 
                   1172:              SET_BINFO_FIELDS_MARKED (base_binfo);
                   1173:              btypes = my_tree_cons (NULL_TREE, base_binfo, basetype_chain);
                   1174:              TREE_VIA_PUBLIC (btypes) = TREE_VIA_PUBLIC (base_binfo);
                   1175:              TREE_VIA_PROTECTED (btypes) = TREE_VIA_PROTECTED (base_binfo);
                   1176:              TREE_VIA_VIRTUAL (btypes) = TREE_VIA_VIRTUAL (base_binfo);
                   1177:              if (TREE_VIA_VIRTUAL (base_binfo))
                   1178:                btypes = tree_cons (NULL_TREE,
                   1179:                                    TYPE_BINFO (BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo_h), i))),
                   1180:                                    btypes);
                   1181:              else
                   1182:                btypes = tree_cons (NULL_TREE,
                   1183:                                    TREE_VEC_ELT (BINFO_BASETYPES (binfo_h), i),
                   1184:                                    btypes);
                   1185:              obstack_ptr_grow (&search_obstack, btypes);
                   1186:              tail += 1;
                   1187:              if (tail >= search_stack->limit)
                   1188:                my_friendly_abort (98);
                   1189:            }
                   1190:        }
                   1191: 
                   1192:       /* Process head of queue, if one exists.  */
                   1193:       if (head >= tail)
                   1194:        break;
                   1195: 
                   1196:       basetype_chain = search_stack->first[head++];
                   1197:       binfo_h = TREE_VALUE (basetype_chain);
                   1198:       basetype_chain = TREE_CHAIN (basetype_chain);
                   1199:       basetype_path = TREE_VALUE (basetype_chain);
                   1200:       if (TREE_CHAIN (basetype_chain))
                   1201:        BINFO_INHERITANCE_CHAIN (basetype_path) = TREE_VALUE (TREE_CHAIN (basetype_chain));
                   1202:       else
                   1203:        BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE;
                   1204: 
                   1205:       binfo = basetype_path;
                   1206:       type = BINFO_TYPE (binfo);
                   1207: 
                   1208:       /* See if we can find NAME in TYPE.  If RVAL is nonzero,
                   1209:         and we do find NAME in TYPE, verify that such a second
                   1210:         sighting is in fact legal.  */
                   1211: 
                   1212:       nval = lookup_field_1 (type, name);
                   1213: 
                   1214:       if (nval || lookup_fnfields_here (type, name)>=0)
                   1215:        {
                   1216:          if (nval && nval == rval && SHARED_MEMBER_P (nval))
                   1217:            {
                   1218:              /* This is ok, the member found is the same [class.ambig] */
                   1219:            }
                   1220:          else if (rval_binfo && hides (rval_binfo_h, binfo_h))
                   1221:            {
                   1222:              /* This is ok, the member found is in rval_binfo, not
                   1223:                 here (binfo). */
                   1224:            }
                   1225:          else if (rval_binfo==NULL_TREE || hides (binfo_h, rval_binfo_h))
                   1226:            {
                   1227:              /* This is ok, the member found is here (binfo), not in
                   1228:                 rval_binfo. */
                   1229:              if (nval)
                   1230:                {
                   1231:                  rval = nval;
                   1232:                  if (entry || protect)
                   1233:                    this_v = compute_access (basetype_path, rval);
                   1234:                  /* These may look ambiguous, but they really are not.  */
                   1235:                  if (vbase_name_p)
                   1236:                    break;
                   1237:                }
                   1238:              else
                   1239:                {
                   1240:                  /* Undo finding it before, as something else hides it. */
                   1241:                  rval = NULL_TREE;
                   1242:                }
                   1243:              rval_binfo = binfo;
                   1244:              rval_binfo_h = binfo_h;
                   1245:            }
                   1246:          else
                   1247:            {
                   1248:              /* This is ambiguous. */
                   1249:              errstr = "request for member `%D' is ambiguous";
                   1250:              protect = 2;
                   1251:              break;
                   1252:            }
                   1253:        }
                   1254:     }
                   1255:   {
                   1256:     tree *tp = search_stack->first;
                   1257:     tree *search_tail = tp + tail;
                   1258: 
                   1259:     if (entry)
                   1260:       TREE_VALUE (entry) = rval;
                   1261: 
                   1262:     if (want_type && (rval == NULL_TREE || TREE_CODE (rval) != TYPE_DECL))
                   1263:       {
                   1264:        rval = NULL_TREE;
                   1265:        errstr = 0;
                   1266:       }
                   1267: 
                   1268:     /* If this FIELD_DECL defines its own access level, deal with that.  */
                   1269:     if (rval && errstr == 0
                   1270:        && ((protect&1) || entry)
                   1271:        && DECL_LANG_SPECIFIC (rval)
                   1272:        && DECL_ACCESS (rval))
                   1273:       {
                   1274:        while (tp < search_tail)
                   1275:          {
                   1276:            /* If is possible for one of the derived types on the path to
                   1277:               have defined special access for this field.  Look for such
                   1278:               declarations and report an error if a conflict is found.  */
                   1279:            enum access_type new_v;
                   1280: 
                   1281:            if (this_v != access_default)
                   1282:              new_v = compute_access (TREE_VALUE (TREE_CHAIN (*tp)), rval);
                   1283:            if (this_v != access_default && new_v != this_v)
                   1284:              {
                   1285:                errstr = "conflicting access to member `%D'";
                   1286:                this_v = access_default;
                   1287:              }
                   1288:            own_access = new_v;
                   1289:            CLEAR_BINFO_FIELDS_MARKED (TREE_VALUE (TREE_CHAIN (*tp)));
                   1290:            tp += 1;
                   1291:          }
                   1292:       }
                   1293:     else
                   1294:       {
                   1295:        while (tp < search_tail)
                   1296:          {
                   1297:            CLEAR_BINFO_FIELDS_MARKED (TREE_VALUE (TREE_CHAIN (*tp)));
                   1298:            tp += 1;
                   1299:          }
                   1300:       }
                   1301:   }
                   1302:   search_stack = pop_search_level (search_stack);
                   1303: 
                   1304:   if (errstr == 0)
                   1305:     {
                   1306:       if (own_access == access_private)
                   1307:        errstr = "member `%D' declared private";
                   1308:       else if (own_access == access_protected)
                   1309:        errstr = "member `%D' declared protected";
                   1310:       else if (this_v == access_private)
                   1311:        errstr = TREE_PRIVATE (rval)
                   1312:          ? "member `%D' is private"
                   1313:            : "member `%D' is from private base class";
                   1314:       else if (this_v == access_protected)
                   1315:        errstr = TREE_PROTECTED (rval)
                   1316:          ? "member `%D' is protected"
                   1317:            : "member `%D' is from protected base class";
                   1318:     }
                   1319: 
                   1320:   if (entry)
                   1321:     {
                   1322:       if (errstr)
                   1323:        {
                   1324:          tree error_string = my_build_string (errstr);
                   1325:          /* Save error message with entry.  */
                   1326:          TREE_TYPE (entry) = error_string;
                   1327:        }
                   1328:       else
                   1329:        {
                   1330:          /* Mark entry as having no error string.  */
                   1331:          TREE_TYPE (entry) = NULL_TREE;
                   1332:        }
                   1333:     }
                   1334: 
                   1335:   if (errstr && protect)
                   1336:     {
                   1337:       cp_error (errstr, name, type);
                   1338:       rval = error_mark_node;
                   1339:     }
                   1340:   return rval;
                   1341: }
                   1342: 
                   1343: /* Try to find NAME inside a nested class.  */
                   1344: tree
                   1345: lookup_nested_field (name, complain)
                   1346:      tree name;
                   1347:      int complain;
                   1348: {
                   1349:   register tree t;
                   1350: 
                   1351:   tree id = NULL_TREE;
                   1352:   if (TREE_CHAIN (current_class_type))
                   1353:     {
                   1354:       /* Climb our way up the nested ladder, seeing if we're trying to
                   1355:         modify a field in an enclosing class.  If so, we should only
                   1356:         be able to modify if it's static.  */
                   1357:       for (t = TREE_CHAIN (current_class_type);
                   1358:           t && DECL_CONTEXT (t);
                   1359:           t = TREE_CHAIN (DECL_CONTEXT (t)))
                   1360:        {
                   1361:          if (TREE_CODE (DECL_CONTEXT (t)) != RECORD_TYPE)
                   1362:            break;
                   1363: 
                   1364:          /* N.B.: lookup_field will do the access checking for us */
                   1365:          id = lookup_field (DECL_CONTEXT (t), name, complain, 0);
                   1366:          if (id == error_mark_node)
                   1367:            {
                   1368:              id = NULL_TREE;
                   1369:              continue;
                   1370:            }
                   1371: 
                   1372:          if (id != NULL_TREE)
                   1373:            {
                   1374:              if (TREE_CODE (id) == FIELD_DECL
                   1375:                  && ! TREE_STATIC (id)
                   1376:                  && TREE_TYPE (id) != error_mark_node)
                   1377:                {
                   1378:                  if (complain)
                   1379:                    {
                   1380:                      /* At parse time, we don't want to give this error, since
                   1381:                         we won't have enough state to make this kind of
                   1382:                         decision properly.  But there are times (e.g., with
                   1383:                         enums in nested classes) when we do need to call
                   1384:                         this fn at parse time.  So, in those cases, we pass
                   1385:                         complain as a 0 and just return a NULL_TREE.  */
                   1386:                      error ("assignment to non-static member `%s' of enclosing class `%s'",
                   1387:                             lang_printable_name (id),
                   1388:                             IDENTIFIER_POINTER (TYPE_IDENTIFIER
                   1389:                                                 (DECL_CONTEXT (t))));
                   1390:                      /* Mark this for do_identifier().  It would otherwise
                   1391:                         claim that the variable was undeclared.  */
                   1392:                      TREE_TYPE (id) = error_mark_node;
                   1393:                    }
                   1394:                  else
                   1395:                    {
                   1396:                      id = NULL_TREE;
                   1397:                      continue;
                   1398:                    }
                   1399:                }
                   1400:              break;
                   1401:            }
                   1402:        }
                   1403:     }
                   1404: 
                   1405:   return id;
                   1406: }
                   1407: 
                   1408: /* TYPE is a class type. Return the index of the fields within
                   1409:    the method vector with name NAME, or -1 is no such field exists.  */
                   1410: static int
                   1411: lookup_fnfields_1 (type, name)
                   1412:      tree type, name;
                   1413: {
                   1414:   register tree method_vec = CLASSTYPE_METHOD_VEC (type);
                   1415: 
                   1416:   if (method_vec != 0)
                   1417:     {
                   1418:       register tree *methods = &TREE_VEC_ELT (method_vec, 0);
                   1419:       register tree *end = TREE_VEC_END (method_vec);
                   1420: 
                   1421: #ifdef GATHER_STATISTICS
                   1422:       n_calls_lookup_fnfields_1++;
                   1423: #endif
                   1424:       if (*methods && name == constructor_name (type))
                   1425:        return 0;
                   1426: 
                   1427:       while (++methods != end)
                   1428:        {
                   1429: #ifdef GATHER_STATISTICS
                   1430:          n_outer_fields_searched++;
                   1431: #endif
                   1432:          if (DECL_NAME (*methods) == name)
                   1433:            break;
                   1434:        }
                   1435:       if (methods != end)
                   1436:        return methods - &TREE_VEC_ELT (method_vec, 0);
                   1437:     }
                   1438: 
                   1439:   return -1;
                   1440: }
                   1441: 
                   1442: /* Starting from BASETYPE, return a TREE_BASELINK-like object
                   1443:    which gives the following information (in a list):
                   1444: 
                   1445:    TREE_TYPE: list of basetypes needed to get to...
                   1446:    TREE_VALUE: list of all functions in of given type
                   1447:    which have name NAME.
                   1448: 
                   1449:    No access information is computed by this function,
                   1450:    other then to adorn the list of basetypes with
                   1451:    TREE_VIA_PUBLIC.
                   1452: 
                   1453:    If there are two ways to find a name (two members), if COMPLAIN is
                   1454:    non-zero, then error_mark_node is returned, and an error message is
                   1455:    printed, otherwise, just an error_mark_node is returned.
                   1456: 
                   1457:    As a special case, is COMPLAIN is -1, we don't complain, and we
                   1458:    don't return error_mark_node, but rather the complete list of
                   1459:    virtuals.  This is used by get_virtuals_named_this.  */
                   1460: tree
                   1461: lookup_fnfields (basetype_path, name, complain)
                   1462:      tree basetype_path, name;
                   1463:      int complain;
                   1464: {
                   1465:   int head = 0, tail = 0;
                   1466:   tree type, rval, rval_binfo = NULL_TREE, rvals = NULL_TREE, rval_binfo_h;
                   1467:   tree entry, binfo, basetype_chain, binfo_h;
                   1468:   int find_all = 0;
                   1469: 
                   1470:   /* rval_binfo is the binfo associated with the found member, note,
                   1471:      this can be set with useful information, even when rval is not
                   1472:      set, because it must deal with ALL members, not just function
                   1473:      members.  It is used for ambiguity checking and the hidden
                   1474:      checks.  Whereas rval is only set if a proper (not hidden)
                   1475:      function member is found.  */
                   1476: 
                   1477:   /* rval_binfo_h and binfo_h are binfo values used when we perform the
                   1478:      hiding checks, as virtual base classes may not be shared.  The strategy
                   1479:      is we always go into the the binfo hierarchy owned by TYPE_BINFO of
                   1480:      virtual base classes, as we cross virtual base class lines.  This way
                   1481:      we know that binfo of a virtual base class will always == itself when
                   1482:      found along any line.  (mrs)  */
                   1483: 
                   1484:   /* For now, don't try this.  */
                   1485:   int protect = complain;
                   1486: 
                   1487:   char *errstr = 0;
                   1488: 
                   1489:   /* Set this to nonzero if we don't know how to compute
                   1490:      accurate error messages for access control.  */
                   1491:   int index = MEMOIZED_HASH_FN (name);
                   1492: 
                   1493:   if (complain == -1)
                   1494:     {
                   1495:       find_all = 1;
                   1496:       protect = complain = 0;
                   1497:     }
                   1498: 
                   1499:   /* If we are looking for a constructor in a templated type, use the
                   1500:      unspecialized name, as that is how we store it.  */
                   1501:   if (IDENTIFIER_TEMPLATE (name))
                   1502:     name = constructor_name (name);
                   1503: 
                   1504:   binfo = basetype_path;
                   1505:   binfo_h = binfo;
                   1506:   type = BINFO_TYPE (basetype_path);
                   1507: 
                   1508:   /* The memoization code is in need of maintenance. */
                   1509:   if (!find_all && CLASSTYPE_MTABLE_ENTRY (type))
                   1510:     {
                   1511:       tree tem = MEMOIZED_FNFIELDS (CLASSTYPE_MTABLE_ENTRY (type), index);
                   1512: 
                   1513:       while (tem && TREE_PURPOSE (tem) != name)
                   1514:        {
                   1515:          memoized_fields_searched[1]++;
                   1516:          tem = TREE_CHAIN (tem);
                   1517:        }
                   1518:       if (tem)
                   1519:        {
                   1520:          if (protect && TREE_TYPE (tem))
                   1521:            {
                   1522:              error (TREE_STRING_POINTER (TREE_TYPE (tem)),
                   1523:                     IDENTIFIER_POINTER (name),
                   1524:                     TYPE_NAME_STRING (DECL_CLASS_CONTEXT (TREE_VALUE (TREE_VALUE (tem)))));
                   1525:              return error_mark_node;
                   1526:            }
                   1527:          if (TREE_VALUE (tem) == NULL_TREE)
                   1528:            {
                   1529:              memoized_fast_rejects[1] += 1;
                   1530:              return NULL_TREE;
                   1531:            }
                   1532:          else
                   1533:            {
                   1534:              /* Want to return this, but we must make sure
                   1535:                 that access information is consistent.  */
                   1536:              tree baselink = TREE_VALUE (tem);
                   1537:              tree memoized_basetypes = TREE_PURPOSE (baselink);
                   1538:              tree these_basetypes = basetype_path;
                   1539:              while (memoized_basetypes && these_basetypes)
                   1540:                {
                   1541:                  memoized_fields_searched[1]++;
                   1542:                  if (TREE_VALUE (memoized_basetypes) != these_basetypes)
                   1543:                    break;
                   1544:                  memoized_basetypes = TREE_CHAIN (memoized_basetypes);
                   1545:                  these_basetypes = BINFO_INHERITANCE_CHAIN (these_basetypes);
                   1546:                }
                   1547:              /* The following statement is true only when both are NULL.  */
                   1548:              if (memoized_basetypes == these_basetypes)
                   1549:                {
                   1550:                  memoized_fast_finds[1] += 1;
                   1551:                  return TREE_VALUE (tem);
                   1552:                }
                   1553:              /* else, we must re-find this field by hand.  */
                   1554:              baselink = tree_cons (basetype_path, TREE_VALUE (baselink), TREE_CHAIN (baselink));
                   1555:              return baselink;
                   1556:            }
                   1557:        }
                   1558:     }
                   1559: 
                   1560: #ifdef GATHER_STATISTICS
                   1561:   n_calls_lookup_fnfields++;
                   1562: #endif
                   1563:   if (protect && flag_memoize_lookups && ! global_bindings_p ())
                   1564:     entry = make_memoized_table_entry (type, name, 1);
                   1565:   else
                   1566:     entry = 0;
                   1567: 
                   1568:   index = lookup_fnfields_here (type, name);
                   1569:   if (index >= 0 || lookup_field_1 (type, name))
                   1570:     {
                   1571:       rval_binfo = basetype_path;
                   1572:       rval_binfo_h = rval_binfo;
                   1573:     }
                   1574: 
                   1575:   if (index >= 0)
                   1576:     {
                   1577:       rval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), index);
                   1578:       rvals = my_tree_cons (basetype_path, rval, rvals);
                   1579:       if (BINFO_BASETYPES (binfo) && CLASSTYPE_BASELINK_VEC (type))
                   1580:        TREE_TYPE (rvals) = TREE_VEC_ELT (CLASSTYPE_BASELINK_VEC (type), index);
                   1581: 
                   1582:       if (entry)
                   1583:        {
                   1584:          TREE_VALUE (entry) = rvals;
                   1585:          TREE_TYPE (entry) = NULL_TREE;
                   1586:        }
                   1587: 
                   1588:       return rvals;
                   1589:     }
                   1590:   rval = NULL_TREE;
                   1591: 
                   1592:   if (basetype_path == TYPE_BINFO (type))
                   1593:     {
                   1594:       basetype_chain = CLASSTYPE_BINFO_AS_LIST (type);
                   1595:       TREE_VIA_PUBLIC (basetype_chain) = 1;
                   1596:       BINFO_VIA_PUBLIC (basetype_path) = 1;
                   1597:       BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE;
                   1598:     }
                   1599:   else
                   1600:     {
                   1601:       basetype_chain = build_tree_list (NULL_TREE, basetype_path);
                   1602:       TREE_VIA_PUBLIC (basetype_chain) = TREE_VIA_PUBLIC (basetype_path);
                   1603:       TREE_VIA_PROTECTED (basetype_chain) = TREE_VIA_PROTECTED (basetype_path);
                   1604:       TREE_VIA_VIRTUAL (basetype_chain) = TREE_VIA_VIRTUAL (basetype_path);
                   1605:     }
                   1606: 
                   1607:   /* The ambiguity check relies upon breadth first searching. */
                   1608: 
                   1609:   search_stack = push_search_level (search_stack, &search_obstack);
                   1610:   binfo = basetype_path;
                   1611:   binfo_h = binfo;
                   1612: 
                   1613:   while (1)
                   1614:     {
                   1615:       tree binfos = BINFO_BASETYPES (binfo);
                   1616:       int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
                   1617:       int index;
                   1618: 
                   1619:       /* Process and/or queue base types.  */
                   1620:       for (i = 0; i < n_baselinks; i++)
                   1621:        {
                   1622:          tree base_binfo = TREE_VEC_ELT (binfos, i);
                   1623:          if (BINFO_FIELDS_MARKED (base_binfo) == 0)
                   1624:            {
                   1625:              tree btypes;
                   1626: 
                   1627:              SET_BINFO_FIELDS_MARKED (base_binfo);
                   1628:              btypes = my_tree_cons (NULL_TREE, base_binfo, basetype_chain);
                   1629:              TREE_VIA_PUBLIC (btypes) = TREE_VIA_PUBLIC (base_binfo);
                   1630:              TREE_VIA_PROTECTED (btypes) = TREE_VIA_PROTECTED (base_binfo);
                   1631:              TREE_VIA_VIRTUAL (btypes) = TREE_VIA_VIRTUAL (base_binfo);
                   1632:              if (TREE_VIA_VIRTUAL (base_binfo))
                   1633:                btypes = tree_cons (NULL_TREE,
                   1634:                                    TYPE_BINFO (BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo_h), i))),
                   1635:                                    btypes);
                   1636:              else
                   1637:                btypes = tree_cons (NULL_TREE,
                   1638:                                    TREE_VEC_ELT (BINFO_BASETYPES (binfo_h), i),
                   1639:                                    btypes);
                   1640:              obstack_ptr_grow (&search_obstack, btypes);
                   1641:              tail += 1;
                   1642:              if (tail >= search_stack->limit)
                   1643:                my_friendly_abort (99);
                   1644:            }
                   1645:        }
                   1646: 
                   1647:       /* Process head of queue, if one exists.  */
                   1648:       if (head >= tail)
                   1649:        break;
                   1650: 
                   1651:       basetype_chain = search_stack->first[head++];
                   1652:       binfo_h = TREE_VALUE (basetype_chain);
                   1653:       basetype_chain = TREE_CHAIN (basetype_chain);
                   1654:       basetype_path = TREE_VALUE (basetype_chain);
                   1655:       if (TREE_CHAIN (basetype_chain))
                   1656:        BINFO_INHERITANCE_CHAIN (basetype_path) = TREE_VALUE (TREE_CHAIN (basetype_chain));
                   1657:       else
                   1658:        BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE;
                   1659: 
                   1660:       binfo = basetype_path;
                   1661:       type = BINFO_TYPE (binfo);
                   1662: 
                   1663:       /* See if we can find NAME in TYPE.  If RVAL is nonzero,
                   1664:         and we do find NAME in TYPE, verify that such a second
                   1665:         sighting is in fact legal.  */
                   1666: 
                   1667:       index = lookup_fnfields_here (type, name);
                   1668: 
                   1669:       if (index >= 0 || (lookup_field_1 (type, name)!=NULL_TREE && !find_all))
                   1670:        {
                   1671:          if (rval_binfo && !find_all && hides (rval_binfo_h, binfo_h))
                   1672:            {
                   1673:              /* This is ok, the member found is in rval_binfo, not
                   1674:                 here (binfo). */
                   1675:            }
                   1676:          else if (rval_binfo==NULL_TREE || find_all || hides (binfo_h, rval_binfo_h))
                   1677:            {
                   1678:              /* This is ok, the member found is here (binfo), not in
                   1679:                 rval_binfo. */
                   1680:              if (index >= 0)
                   1681:                {
                   1682:                  rval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), index);
                   1683:                  /* Note, rvals can only be previously set if find_all is
                   1684:                     true.  */
                   1685:                  rvals = my_tree_cons (basetype_path, rval, rvals);
                   1686:                  if (TYPE_BINFO_BASETYPES (type)
                   1687:                      && CLASSTYPE_BASELINK_VEC (type))
                   1688:                    TREE_TYPE (rvals) = TREE_VEC_ELT (CLASSTYPE_BASELINK_VEC (type), index);
                   1689:                }
                   1690:              else
                   1691:                {
                   1692:                  /* Undo finding it before, as something else hides it. */
                   1693:                  rval = NULL_TREE;
                   1694:                  rvals = NULL_TREE;
                   1695:                }
                   1696:              rval_binfo = binfo;
                   1697:              rval_binfo_h = binfo_h;
                   1698:            }
                   1699:          else
                   1700:            {
                   1701:              /* This is ambiguous. */
                   1702:              errstr = "request for method `%D' is ambiguous";
                   1703:              rvals = error_mark_node;
                   1704:              break;
                   1705:            }
                   1706:        }
                   1707:     }
                   1708:   {
                   1709:     tree *tp = search_stack->first;
                   1710:     tree *search_tail = tp + tail;
                   1711: 
                   1712:     while (tp < search_tail)
                   1713:       {
                   1714:        CLEAR_BINFO_FIELDS_MARKED (TREE_VALUE (TREE_CHAIN (*tp)));
                   1715:        tp += 1;
                   1716:       }
                   1717:   }
                   1718:   search_stack = pop_search_level (search_stack);
                   1719: 
                   1720:   if (entry)
                   1721:     {
                   1722:       if (errstr)
                   1723:        {
                   1724:          tree error_string = my_build_string (errstr);
                   1725:          /* Save error message with entry.  */
                   1726:          TREE_TYPE (entry) = error_string;
                   1727:        }
                   1728:       else
                   1729:        {
                   1730:          /* Mark entry as having no error string.  */
                   1731:          TREE_TYPE (entry) = NULL_TREE;
                   1732:          TREE_VALUE (entry) = rvals;
                   1733:        }
                   1734:     }
                   1735: 
                   1736:   if (errstr && protect)
                   1737:     {
                   1738:       cp_error (errstr, name);
                   1739:       rvals = error_mark_node;
                   1740:     }
                   1741: 
                   1742:   return rvals;
                   1743: }
                   1744: 
                   1745: /* BREADTH-FIRST SEARCH ROUTINES.  */
                   1746: 
                   1747: /* Search a multiple inheritance hierarchy by breadth-first search.
                   1748: 
                   1749:    TYPE is an aggregate type, possibly in a multiple-inheritance hierarchy.
                   1750:    TESTFN is a function, which, if true, means that our condition has been met,
                   1751:    and its return value should be returned.
                   1752:    QFN, if non-NULL, is a predicate dictating whether the type should
                   1753:    even be queued.  */
                   1754: 
                   1755: HOST_WIDE_INT
                   1756: breadth_first_search (binfo, testfn, qfn)
                   1757:      tree binfo;
                   1758:      int (*testfn)();
                   1759:      int (*qfn)();
                   1760: {
                   1761:   int head = 0, tail = 0;
                   1762:   int rval = 0;
                   1763: 
                   1764:   search_stack = push_search_level (search_stack, &search_obstack);
                   1765: 
                   1766:   while (1)
                   1767:     {
                   1768:       tree binfos = BINFO_BASETYPES (binfo);
                   1769:       int n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
                   1770:       int i;
                   1771: 
                   1772:       /* Process and/or queue base types.  */
                   1773:       for (i = 0; i < n_baselinks; i++)
                   1774:        {
                   1775:          tree base_binfo = TREE_VEC_ELT (binfos, i);
                   1776: 
                   1777:          if (BINFO_MARKED (base_binfo) == 0
                   1778:              && (qfn == 0 || (*qfn) (binfo, i)))
                   1779:            {
                   1780:              SET_BINFO_MARKED (base_binfo);
                   1781:              obstack_ptr_grow (&search_obstack, binfo);
                   1782:              obstack_ptr_grow (&search_obstack, (HOST_WIDE_INT) i);
                   1783:              tail += 2;
                   1784:              if (tail >= search_stack->limit)
                   1785:                my_friendly_abort (100);
                   1786:            }
                   1787:        }
                   1788:       /* Process head of queue, if one exists.  */
                   1789:       if (head >= tail)
                   1790:        {
                   1791:          rval = 0;
                   1792:          break;
                   1793:        }
                   1794: 
                   1795:       binfo = search_stack->first[head++];
                   1796:       i = (HOST_WIDE_INT) search_stack->first[head++];
                   1797:       if (rval = (*testfn) (binfo, i))
                   1798:        break;
                   1799:       binfo = BINFO_BASETYPE (binfo, i);
                   1800:     }
                   1801:   {
                   1802:     tree *tp = search_stack->first;
                   1803:     tree *search_tail = tp + tail;
                   1804:     while (tp < search_tail)
                   1805:       {
                   1806:        tree binfo = *tp++;
                   1807:        int i = (HOST_WIDE_INT)(*tp++);
                   1808:        CLEAR_BINFO_MARKED (BINFO_BASETYPE (binfo, i));
                   1809:       }
                   1810:   }
                   1811: 
                   1812:   search_stack = pop_search_level (search_stack);
                   1813:   return rval;
                   1814: }
                   1815: 
                   1816: /* Functions to use in breadth first searches.  */
                   1817: typedef tree (*pft)();
                   1818: typedef int (*pfi)();
                   1819: 
                   1820: int tree_needs_constructor_p (binfo, i)
                   1821:      tree binfo;
                   1822:      int i;
                   1823: {
                   1824:   tree basetype;
                   1825:   my_friendly_assert (i != 0, 296);
                   1826:   basetype = BINFO_TYPE (BINFO_BASETYPE (binfo, i));
                   1827:   return TYPE_NEEDS_CONSTRUCTING (basetype);
                   1828: }
                   1829: 
                   1830: static tree declarator;
                   1831: 
                   1832: static tree
                   1833: get_virtuals_named_this (binfo)
                   1834:      tree binfo;
                   1835: {
                   1836:   tree fields;
                   1837: 
                   1838:   fields = lookup_fnfields (binfo, declarator, -1);
                   1839:   /* fields cannot be error_mark_node */
                   1840: 
                   1841:   if (fields == 0)
                   1842:     return 0;
                   1843: 
                   1844:   /* Get to the function decls, and return the first virtual function
                   1845:      with this name, if there is one.  */
                   1846:   while (fields)
                   1847:     {
                   1848:       tree fndecl;
                   1849: 
                   1850:       for (fndecl = TREE_VALUE (fields); fndecl; fndecl = DECL_CHAIN (fndecl))
                   1851:        if (DECL_VINDEX (fndecl))
                   1852:          return fields;
                   1853:       fields = next_baselink (fields);
                   1854:     }
                   1855:   return NULL_TREE;
                   1856: }
                   1857: 
                   1858: static tree get_virtual_destructor (binfo, i)
                   1859:      tree binfo;
                   1860:      int i;
                   1861: {
                   1862:   tree type = BINFO_TYPE (binfo);
                   1863:   if (i >= 0)
                   1864:     type = BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo), i));
                   1865:   if (TYPE_HAS_DESTRUCTOR (type)
                   1866:       && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 0)))
                   1867:     return TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 0);
                   1868:   return 0;
                   1869: }
                   1870: 
                   1871: int tree_has_any_destructor_p (binfo, i)
                   1872:      tree binfo;
                   1873:      int i;
                   1874: {
                   1875:   tree type = BINFO_TYPE (binfo);
                   1876:   if (i >= 0)
                   1877:     type = BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo), i));
                   1878:   return TYPE_NEEDS_DESTRUCTOR (type);
                   1879: }
                   1880: 
                   1881: /* Given a class type TYPE, and a function decl FNDECL, look for a
                   1882:    virtual function in TYPE's hierarchy which FNDECL could match as a
                   1883:    virtual function.  It doesn't matter which one we find.
                   1884: 
                   1885:    DTORP is nonzero if we are looking for a destructor.  Destructors
                   1886:    need special treatment because they do not match by name.  */
                   1887: tree
                   1888: get_matching_virtual (binfo, fndecl, dtorp)
                   1889:      tree binfo, fndecl;
                   1890:      int dtorp;
                   1891: {
                   1892:   tree tmp = NULL_TREE;
                   1893: 
                   1894:   /* Breadth first search routines start searching basetypes
                   1895:      of TYPE, so we must perform first ply of search here.  */
                   1896:   if (dtorp)
                   1897:     {
                   1898:       if (tree_has_any_destructor_p (binfo, -1))
                   1899:        tmp = get_virtual_destructor (binfo, -1);
                   1900: 
                   1901:       if (tmp)
                   1902:        return tmp;
                   1903: 
                   1904:       tmp = (tree) breadth_first_search (binfo,
                   1905:                                         (pfi) get_virtual_destructor,
                   1906:                                         tree_has_any_destructor_p);
                   1907:       return tmp;
                   1908:     }
                   1909:   else
                   1910:     {
                   1911:       tree drettype, dtypes, btypes, instptr_type;
                   1912:       tree basetype = DECL_CLASS_CONTEXT (fndecl);
                   1913:       tree baselink, best = NULL_TREE;
                   1914:       tree name = DECL_ASSEMBLER_NAME (fndecl);
                   1915: 
                   1916:       declarator = DECL_NAME (fndecl);
                   1917:       if (IDENTIFIER_VIRTUAL_P (declarator) == 0)
                   1918:        return NULL_TREE;
                   1919: 
                   1920:       baselink = get_virtuals_named_this (binfo);
                   1921:       if (baselink == NULL_TREE)
                   1922:        return NULL_TREE;
                   1923: 
                   1924:       drettype = TREE_TYPE (TREE_TYPE (fndecl));
                   1925:       dtypes = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
                   1926:       if (DECL_STATIC_FUNCTION_P (fndecl))
                   1927:        instptr_type = NULL_TREE;
                   1928:       else
                   1929:        instptr_type = TREE_TYPE (TREE_VALUE (dtypes));
                   1930: 
                   1931:       for (; baselink; baselink = next_baselink (baselink))
                   1932:        {
                   1933:          for (tmp = TREE_VALUE (baselink); tmp; tmp = DECL_CHAIN (tmp))
                   1934:            {
                   1935:              if (! DECL_VINDEX (tmp))
                   1936:                continue;
                   1937: 
                   1938:              btypes = TYPE_ARG_TYPES (TREE_TYPE (tmp));
                   1939:              if (instptr_type == NULL_TREE)
                   1940:                {
                   1941:                  if (compparms (TREE_CHAIN (btypes), dtypes, 3))
                   1942:                    /* Caller knows to give error in this case.  */
                   1943:                    return tmp;
                   1944:                  return NULL_TREE;
                   1945:                }
                   1946: 
                   1947:              if ((TYPE_READONLY (TREE_TYPE (TREE_VALUE (btypes)))
                   1948:                   == TYPE_READONLY (instptr_type))
                   1949:                  && compparms (TREE_CHAIN (btypes), TREE_CHAIN (dtypes), 3))
                   1950:                {
                   1951:                  if (IDENTIFIER_ERROR_LOCUS (name) == NULL_TREE
                   1952:                      && ! comptypes (TREE_TYPE (TREE_TYPE (tmp)), drettype, 1))
                   1953:                    {
                   1954:                      cp_error ("conflicting return type specified for virtual function `%#D'", fndecl);
                   1955:                      cp_error_at ("overriding definition as `%#D'", tmp);
                   1956:                      SET_IDENTIFIER_ERROR_LOCUS (name, basetype);
                   1957:                    }
                   1958:                  break;
                   1959:                }
                   1960:            }
                   1961:          if (tmp)
                   1962:            {
                   1963:              best = tmp;
                   1964:              break;
                   1965:            }
                   1966:        }
                   1967:       if (best == NULL_TREE && warn_overloaded_virtual)
                   1968:        cp_warning_at ("conflicting specification deriving virtual function `%D'", fndecl);
                   1969: 
                   1970:       return best;
                   1971:     }
                   1972: }
                   1973: 
                   1974: /* Return the list of virtual functions which are abstract in type
                   1975:    TYPE that come from non virtual base classes.  See
                   1976:    expand_direct_vtbls_init for the style of search we do.  */
                   1977: static tree
                   1978: get_abstract_virtuals_1 (binfo, do_self, abstract_virtuals)
                   1979:      tree binfo, abstract_virtuals;
                   1980:      int do_self;
                   1981: {
                   1982:   tree binfos = BINFO_BASETYPES (binfo);
                   1983:   int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
                   1984: 
                   1985:   for (i = 0; i < n_baselinks; i++)
                   1986:     {
                   1987:       tree base_binfo = TREE_VEC_ELT (binfos, i);
                   1988:       int is_not_base_vtable =
                   1989:        i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
                   1990:       if (! TREE_VIA_VIRTUAL (base_binfo))
                   1991:        abstract_virtuals
                   1992:          = get_abstract_virtuals_1 (base_binfo, is_not_base_vtable,
                   1993:                                     abstract_virtuals);
                   1994:     }
                   1995:   /* Should we use something besides CLASSTYPE_VFIELDS? */
                   1996:   if (do_self && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)))
                   1997:     {
                   1998:       tree tmp = TREE_CHAIN (BINFO_VIRTUALS (binfo));
                   1999: 
                   2000:       /* Get around dossier entry if there is one.  */
                   2001:       if (flag_dossier)
                   2002:        tmp = TREE_CHAIN (tmp);
                   2003: 
                   2004:       while (tmp)
                   2005:        {
                   2006:          tree base_pfn = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (tmp));
                   2007:          tree base_fndecl = TREE_OPERAND (base_pfn, 0);
                   2008:          if (DECL_ABSTRACT_VIRTUAL_P (base_fndecl))
                   2009:            abstract_virtuals = tree_cons (NULL_TREE, base_fndecl, abstract_virtuals);
                   2010:          tmp = TREE_CHAIN (tmp);
                   2011:        }
                   2012:     }
                   2013:   return abstract_virtuals;
                   2014: }
                   2015: 
                   2016: /* Return the list of virtual functions which are abstract in type TYPE.
                   2017:    This information is cached, and so must be built on a
                   2018:    non-temporary obstack.  */
                   2019: tree
                   2020: get_abstract_virtuals (type)
                   2021:      tree type;
                   2022: {
                   2023:   tree vbases, tmp;
                   2024:   tree abstract_virtuals = CLASSTYPE_ABSTRACT_VIRTUALS (type);
                   2025: 
                   2026:   /* First get all from non-virtual bases. */
                   2027:   abstract_virtuals
                   2028:     = get_abstract_virtuals_1 (TYPE_BINFO (type), 1, abstract_virtuals);
                   2029:                                               
                   2030:   for (vbases = CLASSTYPE_VBASECLASSES (type); vbases; vbases = TREE_CHAIN (vbases))
                   2031:     {
                   2032:       if (! BINFO_VIRTUALS (vbases))
                   2033:        continue;
                   2034: 
                   2035:       tmp = TREE_CHAIN (BINFO_VIRTUALS (vbases));
                   2036:       while (tmp)
                   2037:        {
                   2038:          tree base_pfn = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (tmp));
                   2039:          tree base_fndecl = TREE_OPERAND (base_pfn, 0);
                   2040:          if (DECL_ABSTRACT_VIRTUAL_P (base_fndecl))
                   2041:            abstract_virtuals = tree_cons (NULL_TREE, base_fndecl, abstract_virtuals);
                   2042:          tmp = TREE_CHAIN (tmp);
                   2043:        }
                   2044:     }
                   2045:   return nreverse (abstract_virtuals);
                   2046: }
                   2047: 
                   2048: /* For the type TYPE, return a list of member functions available from
                   2049:    base classes with name NAME.  The TREE_VALUE of the list is a chain of
                   2050:    member functions with name NAME.  The TREE_PURPOSE of the list is a
                   2051:    basetype, or a list of base types (in reverse order) which were
                   2052:    traversed to reach the chain of member functions.  If we reach a base
                   2053:    type which provides a member function of name NAME, and which has at
                   2054:    most one base type itself, then we can terminate the search.  */
                   2055: 
                   2056: tree
                   2057: get_baselinks (type_as_binfo_list, type, name)
                   2058:      tree type_as_binfo_list;
                   2059:      tree type, name;
                   2060: {
                   2061:   int head = 0, tail = 0, index;
                   2062:   tree rval = 0, nval = 0;
                   2063:   tree basetypes = type_as_binfo_list;
                   2064:   tree binfo = TYPE_BINFO (type);
                   2065: 
                   2066:   search_stack = push_search_level (search_stack, &search_obstack);
                   2067: 
                   2068:   while (1)
                   2069:     {
                   2070:       tree binfos = BINFO_BASETYPES (binfo);
                   2071:       int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
                   2072: 
                   2073:       /* Process and/or queue base types.  */
                   2074:       for (i = 0; i < n_baselinks; i++)
                   2075:        {
                   2076:          tree base_binfo = TREE_VEC_ELT (binfos, i);
                   2077:          tree btypes;
                   2078: 
                   2079:          btypes = hash_tree_cons (TREE_VIA_PUBLIC (base_binfo),
                   2080:                                   TREE_VIA_VIRTUAL (base_binfo),
                   2081:                                   TREE_VIA_PROTECTED (base_binfo),
                   2082:                                   NULL_TREE, base_binfo,
                   2083:                                   basetypes);
                   2084:          obstack_ptr_grow (&search_obstack, btypes);
                   2085:          search_stack->first = (tree *)obstack_base (&search_obstack);
                   2086:          tail += 1;
                   2087:        }
                   2088: 
                   2089:     dont_queue:
                   2090:       /* Process head of queue, if one exists.  */
                   2091:       if (head >= tail)
                   2092:        break;
                   2093: 
                   2094:       basetypes = search_stack->first[head++];
                   2095:       binfo = TREE_VALUE (basetypes);
                   2096:       type = BINFO_TYPE (binfo);
                   2097:       index = lookup_fnfields_1 (type, name);
                   2098:       if (index >= 0)
                   2099:        {
                   2100:          nval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), index);
                   2101:          rval = hash_tree_cons (0, 0, 0, basetypes, nval, rval);
                   2102:          if (TYPE_BINFO_BASETYPES (type) == 0)
                   2103:            goto dont_queue;
                   2104:          else if (TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type)) == 1)
                   2105:            {
                   2106:              if (CLASSTYPE_BASELINK_VEC (type))
                   2107:                TREE_TYPE (rval) = TREE_VEC_ELT (CLASSTYPE_BASELINK_VEC (type), index);
                   2108:              goto dont_queue;
                   2109:            }
                   2110:        }
                   2111:       nval = NULL_TREE;
                   2112:     }
                   2113: 
                   2114:   search_stack = pop_search_level (search_stack);
                   2115:   return rval;
                   2116: }
                   2117: 
                   2118: tree
                   2119: next_baselink (baselink)
                   2120:      tree baselink;
                   2121: {
                   2122:   tree tmp = TREE_TYPE (baselink);
                   2123:   baselink = TREE_CHAIN (baselink);
                   2124:   while (tmp)
                   2125:     {
                   2126:       /* @@ does not yet add previous base types.  */
                   2127:       baselink = tree_cons (TREE_PURPOSE (tmp), TREE_VALUE (tmp),
                   2128:                            baselink);
                   2129:       TREE_TYPE (baselink) = TREE_TYPE (tmp);
                   2130:       tmp = TREE_CHAIN (tmp);
                   2131:     }
                   2132:   return baselink;
                   2133: }
                   2134: 
                   2135: /* DEPTH-FIRST SEARCH ROUTINES.  */
                   2136: 
                   2137: /* Assign unique numbers to _CLASSTYPE members of the lattice
                   2138:    specified by TYPE.  The root nodes are marked first; the nodes
                   2139:    are marked depth-fisrt, left-right.  */
                   2140: 
                   2141: static int cid;
                   2142: 
                   2143: /* Matrix implementing a relation from CLASSTYPE X CLASSTYPE => INT.
                   2144:    Relation yields 1 if C1 <= C2, 0 otherwise.  */
                   2145: typedef char mi_boolean;
                   2146: static mi_boolean *mi_matrix;
                   2147: 
                   2148: /* Type for which this matrix is defined.  */
                   2149: static tree mi_type;
                   2150: 
                   2151: /* Size of the matrix for indexing purposes.  */
                   2152: static int mi_size;
                   2153: 
                   2154: /* Return nonzero if class C2 derives from class C1.  */
                   2155: #define BINFO_DERIVES_FROM(C1, C2)     \
                   2156:   ((mi_matrix+mi_size*(BINFO_CID (C1)-1))[BINFO_CID (C2)-1])
                   2157: #define TYPE_DERIVES_FROM(C1, C2)      \
                   2158:   ((mi_matrix+mi_size*(CLASSTYPE_CID (C1)-1))[CLASSTYPE_CID (C2)-1])
                   2159: #define BINFO_DERIVES_FROM_STAR(C)     \
                   2160:   (mi_matrix+(BINFO_CID (C)-1))
                   2161: 
                   2162: /* This routine converts a pointer to be a pointer of an immediate
                   2163:    base class.  The normal convert_pointer_to routine would diagnose
                   2164:    the conversion as ambiguous, under MI code that has the base class
                   2165:    as an ambiguous base class. */
                   2166: static tree
                   2167: convert_pointer_to_single_level (to_type, expr)
                   2168:      tree to_type, expr;
                   2169: {
                   2170:   tree binfo_of_derived;
                   2171:   tree last;
                   2172: 
                   2173:   binfo_of_derived = TYPE_BINFO (TREE_TYPE (TREE_TYPE (expr)));
                   2174:   last = get_binfo (to_type, TREE_TYPE (TREE_TYPE (expr)), 0);
                   2175:   BINFO_INHERITANCE_CHAIN (last) = binfo_of_derived;
                   2176:   BINFO_INHERITANCE_CHAIN (binfo_of_derived) = NULL_TREE;
                   2177:   return build_vbase_path (PLUS_EXPR, TYPE_POINTER_TO (to_type), expr, last, 1);
                   2178: }
                   2179: 
                   2180: /* The main function which implements depth first search.
                   2181: 
                   2182:    This routine has to remember the path it walked up, when
                   2183:    dfs_init_vbase_pointers is the work function, as otherwise there
                   2184:    would be no record. */
                   2185: static void
                   2186: dfs_walk (binfo, fn, qfn)
                   2187:      tree binfo;
                   2188:      void (*fn)();
                   2189:      int (*qfn)();
                   2190: {
                   2191:   tree binfos = BINFO_BASETYPES (binfo);
                   2192:   int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
                   2193: 
                   2194:   for (i = 0; i < n_baselinks; i++)
                   2195:     {
                   2196:       tree base_binfo = TREE_VEC_ELT (binfos, i);
                   2197: 
                   2198:       if ((*qfn)(base_binfo))
                   2199:        {
                   2200:          if (fn == dfs_init_vbase_pointers)
                   2201:            {
                   2202:              /* When traversing an arbitrary MI hierarchy, we need to keep
                   2203:                 a record of the path we took to get down to the final base
                   2204:                 type, as otherwise there would be no record of it, and just
                   2205:                 trying to blindly convert at the bottom would be ambiguous.
                   2206: 
                   2207:                 The easiest way is to do the conversions one step at a time,
                   2208:                 as we know we want the immediate base class at each step.
                   2209: 
                   2210:                 The only special trick to converting one step at a time,
                   2211:                 is that when we hit the last virtual base class, we must
                   2212:                 use the SLOT value for it, and not use the normal convert
                   2213:                 routine.  We use the last virtual base class, as in our
                   2214:                 implementation, we have pointers to all virtual base
                   2215:                 classes in the base object.  */
                   2216: 
                   2217:              tree saved_vbase_decl_ptr_intermediate
                   2218:                = vbase_decl_ptr_intermediate;
                   2219: 
                   2220:              if (TREE_VIA_VIRTUAL (base_binfo))
                   2221:                {
                   2222:                  /* No need for the conversion here, as we know it is the
                   2223:                     right type.  */
                   2224:                  vbase_decl_ptr_intermediate
                   2225:                    = (tree)CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (base_binfo));
                   2226:                }
                   2227:              else
                   2228:                {
                   2229:                  vbase_decl_ptr_intermediate
                   2230:                    = convert_pointer_to_single_level (BINFO_TYPE (base_binfo),
                   2231:                                                       vbase_decl_ptr_intermediate);
                   2232:                }
                   2233: 
                   2234:              dfs_walk (base_binfo, fn, qfn);
                   2235: 
                   2236:              vbase_decl_ptr_intermediate = saved_vbase_decl_ptr_intermediate;
                   2237:            } else
                   2238:              dfs_walk (base_binfo, fn, qfn);
                   2239:        }
                   2240:     }
                   2241: 
                   2242:   fn (binfo);
                   2243: }
                   2244: 
                   2245: /* Predicate functions which serve for dfs_walk.  */
                   2246: static int numberedp (binfo) tree binfo;
                   2247: { return BINFO_CID (binfo); }
                   2248: static int unnumberedp (binfo) tree binfo;
                   2249: { return BINFO_CID (binfo) == 0; }
                   2250: 
                   2251: static int markedp (binfo) tree binfo;
                   2252: { return BINFO_MARKED (binfo); }
                   2253: static int bfs_markedp (binfo, i) tree binfo; int i;
                   2254: { return BINFO_MARKED (BINFO_BASETYPE (binfo, i)); }
                   2255: static int unmarkedp (binfo) tree binfo;
                   2256: { return BINFO_MARKED (binfo) == 0; }
                   2257: static int bfs_unmarkedp (binfo, i) tree binfo; int i;
                   2258: { return BINFO_MARKED (BINFO_BASETYPE (binfo, i)) == 0; }
                   2259: static int marked_vtable_pathp (binfo) tree binfo;
                   2260: { return BINFO_VTABLE_PATH_MARKED (binfo); }
                   2261: static int bfs_marked_vtable_pathp (binfo, i) tree binfo; int i;
                   2262: { return BINFO_VTABLE_PATH_MARKED (BINFO_BASETYPE (binfo, i)); }
                   2263: static int unmarked_vtable_pathp (binfo) tree binfo;
                   2264: { return BINFO_VTABLE_PATH_MARKED (binfo) == 0; }
                   2265: static int bfs_unmarked_vtable_pathp (binfo, i) tree binfo; int i;
                   2266: { return BINFO_VTABLE_PATH_MARKED (BINFO_BASETYPE (binfo, i)) == 0; }
                   2267: static int marked_new_vtablep (binfo) tree binfo;
                   2268: { return BINFO_NEW_VTABLE_MARKED (binfo); }
                   2269: static int bfs_marked_new_vtablep (binfo, i) tree binfo; int i;
                   2270: { return BINFO_NEW_VTABLE_MARKED (BINFO_BASETYPE (binfo, i)); }
                   2271: static int unmarked_new_vtablep (binfo) tree binfo;
                   2272: { return BINFO_NEW_VTABLE_MARKED (binfo) == 0; }
                   2273: static int bfs_unmarked_new_vtablep (binfo, i) tree binfo; int i;
                   2274: { return BINFO_NEW_VTABLE_MARKED (BINFO_BASETYPE (binfo, i)) == 0; }
                   2275: 
                   2276: static int dfs_search_slot_nonempty_p (binfo) tree binfo;
                   2277: { return CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (binfo)) != 0; }
                   2278: 
                   2279: static int dfs_debug_unmarkedp (binfo) tree binfo;
                   2280: { return CLASSTYPE_DEBUG_REQUESTED (BINFO_TYPE (binfo)) == 0; }
                   2281: 
                   2282: /* The worker functions for `dfs_walk'.  These do not need to
                   2283:    test anything (vis a vis marking) if they are paired with
                   2284:    a predicate function (above).  */
                   2285: 
                   2286: /* Assign each type within the lattice a number which is unique
                   2287:    in the lattice.  The first number assigned is 1.  */
                   2288: 
                   2289: static void
                   2290: dfs_number (binfo)
                   2291:      tree binfo;
                   2292: {
                   2293:   BINFO_CID (binfo) = ++cid;
                   2294: }
                   2295: 
                   2296: static void
                   2297: dfs_unnumber (binfo)
                   2298:      tree binfo;
                   2299: {
                   2300:   BINFO_CID (binfo) = 0;
                   2301: }
                   2302: 
                   2303: static void
                   2304: dfs_mark (binfo) tree binfo;
                   2305: { SET_BINFO_MARKED (binfo); }
                   2306: 
                   2307: static void
                   2308: dfs_unmark (binfo) tree binfo;
                   2309: { CLEAR_BINFO_MARKED (binfo); }
                   2310: 
                   2311: static void
                   2312: dfs_mark_vtable_path (binfo) tree binfo;
                   2313: { SET_BINFO_VTABLE_PATH_MARKED (binfo); }
                   2314: 
                   2315: static void
                   2316: dfs_unmark_vtable_path (binfo) tree binfo;
                   2317: { CLEAR_BINFO_VTABLE_PATH_MARKED (binfo); }
                   2318: 
                   2319: static void
                   2320: dfs_mark_new_vtable (binfo) tree binfo;
                   2321: { SET_BINFO_NEW_VTABLE_MARKED (binfo); }
                   2322: 
                   2323: static void
                   2324: dfs_unmark_new_vtable (binfo) tree binfo;
                   2325: { CLEAR_BINFO_NEW_VTABLE_MARKED (binfo); }
                   2326: 
                   2327: static void
                   2328: dfs_clear_search_slot (binfo) tree binfo;
                   2329: { CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (binfo)) = 0; }
                   2330: 
                   2331: static void
                   2332: dfs_debug_mark (binfo)
                   2333:      tree binfo;
                   2334: {
                   2335:   tree t = BINFO_TYPE (binfo);
                   2336: 
                   2337:   /* Use heuristic that if there are virtual functions,
                   2338:      ignore until we see a non-inline virtual function.  */
                   2339:   tree methods = CLASSTYPE_METHOD_VEC (t);
                   2340: 
                   2341:   CLASSTYPE_DEBUG_REQUESTED (t) = 1;
                   2342: 
                   2343:   /* If interface info is known, the value of (?@@?) is correct.  */
                   2344:   if (methods == 0
                   2345:       || CLASSTYPE_INTERFACE_KNOWN (t)
                   2346:       || (write_virtuals == 2 && TYPE_VIRTUAL_P (t)))
                   2347:     return;
                   2348: 
                   2349:   /* If debug info is requested from this context for this type, supply it.
                   2350:      If debug info is requested from another context for this type,
                   2351:      see if some third context can supply it.  */
                   2352:   if (current_function_decl == NULL_TREE
                   2353:       || DECL_CLASS_CONTEXT (current_function_decl) != t)
                   2354:     {
                   2355:       if (TREE_VEC_ELT (methods, 0))
                   2356:        methods = TREE_VEC_ELT (methods, 0);
                   2357:       else
                   2358:        methods = TREE_VEC_ELT (methods, 1);
                   2359:       while (methods)
                   2360:        {
                   2361:          if (DECL_VINDEX (methods)
                   2362:              && DECL_SAVED_INSNS (methods) == 0
                   2363:              && DECL_PENDING_INLINE_INFO (methods) == 0
                   2364:              && DECL_ABSTRACT_VIRTUAL_P (methods) == 0)
                   2365:            {
                   2366:              /* Somebody, somewhere is going to have to define this
                   2367:                 virtual function.  When they do, they will provide
                   2368:                 the debugging info.  */
                   2369:              return;
                   2370:            }
                   2371:          methods = TREE_CHAIN (methods);
                   2372:        }
                   2373:     }
                   2374:   /* We cannot rely on some alien method to solve our problems,
                   2375:      so we must write out the debug info ourselves.  */
                   2376:   TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 0;
                   2377:   rest_of_type_compilation (t, global_bindings_p ());
                   2378: }
                   2379: 
                   2380: /*  Attach to the type of the virtual base class, the pointer to the
                   2381:     virtual base class, given the global pointer vbase_decl_ptr.
                   2382: 
                   2383:     We use the global vbase_types.  ICK!  */
                   2384: static void
                   2385: dfs_find_vbases (binfo)
                   2386:      tree binfo;
                   2387: {
                   2388:   tree binfos = BINFO_BASETYPES (binfo);
                   2389:   int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
                   2390: 
                   2391:   for (i = n_baselinks-1; i >= 0; i--)
                   2392:     {
                   2393:       tree base_binfo = TREE_VEC_ELT (binfos, i);
                   2394: 
                   2395:       if (TREE_VIA_VIRTUAL (base_binfo)
                   2396:          && CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (base_binfo)) == 0)
                   2397:        {
                   2398:          tree vbase = BINFO_TYPE (base_binfo);
                   2399:          tree binfo = binfo_member (vbase, vbase_types);
                   2400: 
                   2401:          CLASSTYPE_SEARCH_SLOT (vbase)
                   2402:            = (char *) build (PLUS_EXPR, TYPE_POINTER_TO (vbase),
                   2403:                              vbase_decl_ptr, BINFO_OFFSET (binfo));
                   2404:        }
                   2405:     }
                   2406:   SET_BINFO_VTABLE_PATH_MARKED (binfo);
                   2407:   SET_BINFO_NEW_VTABLE_MARKED (binfo);
                   2408: }
                   2409: 
                   2410: static void
                   2411: dfs_init_vbase_pointers (binfo)
                   2412:      tree binfo;
                   2413: {
                   2414:   tree type = BINFO_TYPE (binfo);
                   2415:   tree fields = TYPE_FIELDS (type);
                   2416:   tree this_vbase_ptr;
                   2417: 
                   2418:   CLEAR_BINFO_VTABLE_PATH_MARKED (binfo);
                   2419: 
                   2420:   /* If there is a dossier, it is the first field, though perhaps from
                   2421:      the base class.  Otherwise, the first fields are virtual base class
                   2422:      pointer fields.  */
                   2423:   if (CLASSTYPE_DOSSIER (type) && VFIELD_NAME_P (DECL_NAME (fields)))
                   2424:     /* Get past vtable for the object.  */
                   2425:     fields = TREE_CHAIN (fields);
                   2426: 
                   2427:   if (fields == NULL_TREE
                   2428:       || DECL_NAME (fields) == NULL_TREE
                   2429:       || ! VBASE_NAME_P (DECL_NAME (fields)))
                   2430:     return;
                   2431: 
                   2432:   this_vbase_ptr = vbase_decl_ptr_intermediate;
                   2433: 
                   2434:   if (TYPE_POINTER_TO (type) != TYPE_MAIN_VARIANT (TREE_TYPE (this_vbase_ptr)))
                   2435:     my_friendly_abort (125);
                   2436: 
                   2437:   while (fields && DECL_NAME (fields)
                   2438:         && VBASE_NAME_P (DECL_NAME (fields)))
                   2439:     {
                   2440:       tree ref = build (COMPONENT_REF, TREE_TYPE (fields),
                   2441:                        build_indirect_ref (this_vbase_ptr, NULL_PTR), fields);
                   2442:       tree init = (tree)CLASSTYPE_SEARCH_SLOT (TREE_TYPE (TREE_TYPE (fields)));
                   2443:       vbase_init_result = tree_cons (binfo_member (TREE_TYPE (TREE_TYPE (fields)),
                   2444:                                                   vbase_types),
                   2445:                                     build_modify_expr (ref, NOP_EXPR, init),
                   2446:                                     vbase_init_result);
                   2447:       fields = TREE_CHAIN (fields);
                   2448:     }
                   2449: }
                   2450: 
                   2451: /* Sometimes this needs to clear both VTABLE_PATH and NEW_VTABLE.  Other
                   2452:    times, just NEW_VTABLE, but optimizer should make both with equal
                   2453:    efficiency (though it does not currently).  */
                   2454: static void
                   2455: dfs_clear_vbase_slots (binfo)
                   2456:      tree binfo;
                   2457: {
                   2458:   tree type = BINFO_TYPE (binfo);
                   2459:   CLASSTYPE_SEARCH_SLOT (type) = 0;
                   2460:   CLEAR_BINFO_VTABLE_PATH_MARKED (binfo);
                   2461:   CLEAR_BINFO_NEW_VTABLE_MARKED (binfo);
                   2462: }
                   2463: 
                   2464: tree
                   2465: init_vbase_pointers (type, decl_ptr)
                   2466:      tree type;
                   2467:      tree decl_ptr;
                   2468: {
                   2469:   if (TYPE_USES_VIRTUAL_BASECLASSES (type))
                   2470:     {
                   2471:       int old_flag = flag_this_is_variable;
                   2472:       tree binfo = TYPE_BINFO (type);
                   2473:       flag_this_is_variable = -2;
                   2474:       vbase_types = CLASSTYPE_VBASECLASSES (type);
                   2475:       vbase_decl_ptr = decl_ptr;
                   2476:       vbase_decl = build_indirect_ref (decl_ptr, NULL_PTR);
                   2477:       vbase_decl_ptr_intermediate = vbase_decl_ptr;
                   2478:       vbase_init_result = NULL_TREE;
                   2479:       dfs_walk (binfo, dfs_find_vbases, unmarked_vtable_pathp);
                   2480:       dfs_walk (binfo, dfs_init_vbase_pointers, marked_vtable_pathp);
                   2481:       dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep);
                   2482:       flag_this_is_variable = old_flag;
                   2483:       return vbase_init_result;
                   2484:     }
                   2485:   return 0;
                   2486: }
                   2487: 
                   2488: /* Build a COMPOUND_EXPR which when expanded will generate the code
                   2489:    needed to initialize all the virtual function table slots of all
                   2490:    the virtual baseclasses.  MAIN_BINFO is the binfo which determines
                   2491:    the virtual baseclasses to use; TYPE is the type of the object to
                   2492:    which the initialization applies.  TRUE_EXP is the true object we
                   2493:    are initializing, and DECL_PTR is the pointer to the sub-object we
                   2494:    are initializing.
                   2495: 
                   2496:    When USE_COMPUTED_OFFSETS is non-zero, we can assume that the
                   2497:    object was laidout by a top-level contructor and the computed
                   2498:    offsets are valid to store vtables.  When zero, we must store new
                   2499:    vtables through virtual baseclass pointers.
                   2500: 
                   2501:    We setup and use the globals: vbase_decl, vbase_decl_ptr, vbase_types
                   2502:    ICK!  */
                   2503: 
                   2504: void
                   2505: expand_indirect_vtbls_init (binfo, true_exp, decl_ptr, use_computed_offsets)
                   2506:      tree binfo;
                   2507:      tree true_exp, decl_ptr;
                   2508:      int use_computed_offsets;
                   2509: {
                   2510:   tree type = BINFO_TYPE (binfo);
                   2511:   if (TYPE_USES_VIRTUAL_BASECLASSES (type))
                   2512:     {
                   2513:       int old_flag = flag_this_is_variable;
                   2514:       tree vbases = CLASSTYPE_VBASECLASSES (type);
                   2515:       vbase_types = vbases;
                   2516:       vbase_decl_ptr = true_exp ? build_unary_op (ADDR_EXPR, true_exp, 0) : decl_ptr;
                   2517:       vbase_decl = true_exp ? true_exp : build_indirect_ref (decl_ptr, NULL_PTR);
                   2518: 
                   2519:       if (use_computed_offsets)
                   2520:        {
                   2521:          /* This is an object of type IN_TYPE,  */
                   2522:          flag_this_is_variable = -2;
                   2523:          dfs_walk (binfo, dfs_find_vbases, unmarked_new_vtablep);
                   2524:        }
                   2525: 
                   2526:       /* Initialized with vtables of type TYPE.  */
                   2527:       for (; vbases; vbases = TREE_CHAIN (vbases))
                   2528:        {
                   2529:          tree addr;
                   2530:          if (use_computed_offsets)
                   2531:            addr = (tree)CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (vbases));
                   2532:          else
                   2533:            {
                   2534:              tree vbinfo = get_binfo (TREE_TYPE (vbases),
                   2535:                                       TREE_TYPE (vbase_decl),
                   2536:                                       0);
                   2537: 
                   2538:              /* See is we can get lucky.  */
                   2539:              if (TREE_VIA_VIRTUAL (vbinfo))
                   2540:                addr = convert_pointer_to_real (vbinfo, vbase_decl_ptr);
                   2541:              else
                   2542:                {
                   2543:                  /* We go through all these contortions to avoid this
                   2544:                     call, as it will fail when the virtual base type
                   2545:                     is ambiguous from here.  We don't yet have a way
                   2546:                     to search for and find just an instance of the
                   2547:                     virtual base class.  Searching for the binfo in
                   2548:                     vbases won't work, as we don't have the vbase
                   2549:                     pointer field, for all vbases in the main class,
                   2550:                     only direct vbases.  */
                   2551:                  addr = convert_pointer_to_real (TREE_TYPE (vbases),
                   2552:                                                  vbase_decl_ptr);
                   2553:                  if (addr == error_mark_node)
                   2554:                    continue;
                   2555:                }
                   2556:            }
                   2557: 
                   2558:          /* Do all vtables from this virtual base. */
                   2559:          /* This assumes that virtual bases can never serve as parent
                   2560:             binfos.  (in the CLASSTPE_VFIELD_PARENT sense)  */
                   2561:          expand_direct_vtbls_init (vbases, TYPE_BINFO (BINFO_TYPE (vbases)),
                   2562:                                    1, 0, addr);
                   2563:        }
                   2564: 
                   2565:       dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep);
                   2566: 
                   2567:       flag_this_is_variable = old_flag;
                   2568:     }
                   2569: }
                   2570: 
                   2571: void
                   2572: clear_search_slots (type)
                   2573:      tree type;
                   2574: {
                   2575:   dfs_walk (TYPE_BINFO (type),
                   2576:            dfs_clear_search_slot, dfs_search_slot_nonempty_p);
                   2577: }
                   2578: 
                   2579: /* get virtual base class types.
                   2580:    This adds type to the vbase_types list in reverse dfs order.
                   2581:    Ordering is very important, so don't change it.  */
                   2582: 
                   2583: static void
                   2584: dfs_get_vbase_types (binfo)
                   2585:      tree binfo;
                   2586: {
                   2587:   if (TREE_VIA_VIRTUAL (binfo) && ! BINFO_VBASE_MARKED (binfo))
                   2588:     {
                   2589:       vbase_types = make_binfo (integer_zero_node, binfo,
                   2590:                                BINFO_VTABLE (binfo),
                   2591:                                BINFO_VIRTUALS (binfo), vbase_types);
                   2592:       TREE_VIA_VIRTUAL (vbase_types) = 1;
                   2593:       SET_BINFO_VBASE_MARKED (binfo);
                   2594:     }
                   2595:   SET_BINFO_MARKED (binfo);
                   2596: }
                   2597: 
                   2598: /* get a list of virtual base classes in dfs order.  */
                   2599: tree
                   2600: get_vbase_types (type)
                   2601:      tree type;
                   2602: {
                   2603:   tree vbases;
                   2604:   tree binfo;
                   2605: 
                   2606:   if (TREE_CODE (type) == TREE_VEC)
                   2607:     binfo = type;
                   2608:   else
                   2609:     binfo = TYPE_BINFO (type);
                   2610: 
                   2611:   vbase_types = NULL_TREE;
                   2612:   dfs_walk (binfo, dfs_get_vbase_types, unmarkedp);
                   2613:   dfs_walk (binfo, dfs_unmark, markedp);
                   2614:   /* Rely upon the reverse dfs ordering from dfs_get_vbase_types, and now
                   2615:      reverse it so that we get normal dfs ordering.  */
                   2616:   vbase_types = nreverse (vbase_types);
                   2617: 
                   2618:   /* unmark marked vbases */
                   2619:   for (vbases = vbase_types; vbases; vbases = TREE_CHAIN (vbases))
                   2620:     CLEAR_BINFO_VBASE_MARKED (vbases);
                   2621: 
                   2622:   return vbase_types;
                   2623: }
                   2624: 
                   2625: static void
                   2626: dfs_record_inheritance (binfo)
                   2627:      tree binfo;
                   2628: {
                   2629:   tree binfos = BINFO_BASETYPES (binfo);
                   2630:   int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
                   2631:   mi_boolean *derived_row = BINFO_DERIVES_FROM_STAR (binfo);
                   2632: 
                   2633:   for (i = n_baselinks-1; i >= 0; i--)
                   2634:     {
                   2635:       int j;
                   2636:       tree base_binfo = TREE_VEC_ELT (binfos, i);
                   2637:       tree baseclass = BINFO_TYPE (base_binfo);
                   2638:       mi_boolean *base_row = BINFO_DERIVES_FROM_STAR (base_binfo);
                   2639: 
                   2640:       /* Don't search if there's nothing there!  MI_SIZE can be
                   2641:         zero as a result of parse errors.  */
                   2642:       if (TYPE_BINFO_BASETYPES (baseclass) && mi_size > 0)
                   2643:        for (j = mi_size*(CLASSTYPE_CID (baseclass)-1); j >= 0; j -= mi_size)
                   2644:          derived_row[j] |= base_row[j];
                   2645:       TYPE_DERIVES_FROM (baseclass, BINFO_TYPE (binfo)) = 1;
                   2646:     }
                   2647: 
                   2648:   SET_BINFO_MARKED (binfo);
                   2649: }
                   2650: 
                   2651: /* Given a _CLASSTYPE node in a multiple inheritance lattice,
                   2652:    convert the lattice into a simple relation such that,
                   2653:    given to CIDs, C1 and C2, one can determine if C1 <= C2
                   2654:    or C2 <= C1 or C1 <> C2.
                   2655: 
                   2656:    Once constructed, we walk the lattice depth fisrt,
                   2657:    applying various functions to elements as they are encountered.
                   2658: 
                   2659:    We use xmalloc here, in case we want to randomly free these tables.  */
                   2660: 
                   2661: #define SAVE_MI_MATRIX
                   2662: 
                   2663: void
                   2664: build_mi_matrix (type)
                   2665:      tree type;
                   2666: {
                   2667:   tree binfo = TYPE_BINFO (type);
                   2668:   cid = 0;
                   2669: 
                   2670: #ifdef SAVE_MI_MATRIX
                   2671:   if (CLASSTYPE_MI_MATRIX (type))
                   2672:     {
                   2673:       mi_size = CLASSTYPE_N_SUPERCLASSES (type) + CLASSTYPE_N_VBASECLASSES (type);
                   2674:       mi_matrix = CLASSTYPE_MI_MATRIX (type);
                   2675:       mi_type = type;
                   2676:       dfs_walk (binfo, dfs_number, unnumberedp);
                   2677:       return;
                   2678:     }
                   2679: #endif
                   2680: 
                   2681:   mi_size = CLASSTYPE_N_SUPERCLASSES (type) + CLASSTYPE_N_VBASECLASSES (type);
                   2682:   mi_matrix = (char *)xmalloc ((mi_size + 1) * (mi_size + 1));
                   2683:   mi_type = type;
                   2684:   bzero (mi_matrix, (mi_size + 1) * (mi_size + 1));
                   2685:   dfs_walk (binfo, dfs_number, unnumberedp);
                   2686:   dfs_walk (binfo, dfs_record_inheritance, unmarkedp);
                   2687:   dfs_walk (binfo, dfs_unmark, markedp);
                   2688: }
                   2689: 
                   2690: void
                   2691: free_mi_matrix ()
                   2692: {
                   2693:   dfs_walk (TYPE_BINFO (mi_type), dfs_unnumber, numberedp);
                   2694: 
                   2695: #ifdef SAVE_MI_MATRIX
                   2696:   CLASSTYPE_MI_MATRIX (mi_type) = mi_matrix;
                   2697: #else
                   2698:   free (mi_matrix);
                   2699:   mi_size = 0;
                   2700:   cid = 0;
                   2701: #endif
                   2702: }
                   2703: 
                   2704: /* If we want debug info for a type TYPE, make sure all its base types
                   2705:    are also marked as being potentially interesting.  This avoids
                   2706:    the problem of not writing any debug info for intermediate basetypes
                   2707:    that have abstract virtual functions.  Also mark member types.  */
                   2708: 
                   2709: void
                   2710: note_debug_info_needed (type)
                   2711:      tree type;
                   2712: {
                   2713:   tree field;
                   2714:   dfs_walk (TYPE_BINFO (type), dfs_debug_mark, dfs_debug_unmarkedp);
                   2715:   for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
                   2716:     {
                   2717:       tree ttype;
                   2718:       if (TREE_CODE (field) == FIELD_DECL
                   2719:          && IS_AGGR_TYPE (ttype = target_type (TREE_TYPE (field)))
                   2720:          && dfs_debug_unmarkedp (TYPE_BINFO (ttype)))
                   2721:        note_debug_info_needed (ttype);
                   2722:     }
                   2723: }
                   2724: 
                   2725: /* Subroutines of push_class_decls ().  */
                   2726: 
                   2727: /* Add the instance variables which this class contributed to the
                   2728:    current class binding contour.  When a redefinition occurs,
                   2729:    if the redefinition is strictly within a single inheritance path,
                   2730:    we just overwrite (in the case of a data field) or
                   2731:    cons (in the case of a member function) the old declaration with
                   2732:    the new.  If the fields are not within a single inheritance path,
                   2733:    we must cons them in either case.
                   2734: 
                   2735:    In order to know what decls are new (stemming from the current
                   2736:    invocation of push_class_decls) we enclose them in an "envelope",
                   2737:    which is a TREE_LIST node where the TREE_PURPOSE slot contains the
                   2738:    new decl (or possibly a list of competing ones), the TREE_VALUE slot
                   2739:    points to the old value and the TREE_CHAIN slot chains together all
                   2740:    envelopes which needs to be "opened" in push_class_decls.  Opening an
                   2741:    envelope means: push the old value onto the class_shadowed list,
                   2742:    install the new one and if it's a TYPE_DECL do the same to the
                   2743:    IDENTIFIER_TYPE_VALUE.  Such an envelope is recognized by seeing that
                   2744:    the TREE_PURPOSE slot is non-null, and that it is not an identifier.
                   2745:    Because if it is, it could be a set of overloaded methods from an
                   2746:    outer scope.  */
                   2747: 
                   2748: static void
                   2749: dfs_pushdecls (binfo)
                   2750:      tree binfo;
                   2751: {
                   2752:   tree type = BINFO_TYPE (binfo);
                   2753:   tree fields, *methods, *end;
                   2754:   tree method_vec;
                   2755: 
                   2756:   for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields))
                   2757:     {
                   2758:       /* Unmark so that if we are in a constructor, and then find that
                   2759:         this field was initialized by a base initializer,
                   2760:         we can emit an error message.  */
                   2761:       if (TREE_CODE (fields) == FIELD_DECL)
                   2762:        TREE_USED (fields) = 0;
                   2763: 
                   2764:       /* Recurse into anonymous unions.  */
                   2765:       if (DECL_NAME (fields) == NULL_TREE
                   2766:          && TREE_CODE (TREE_TYPE (fields)) == UNION_TYPE)
                   2767:        {
                   2768:          dfs_pushdecls (TYPE_BINFO (TREE_TYPE (fields)));
                   2769:          continue;
                   2770:        }
                   2771: 
                   2772: #if 0
                   2773:       if (TREE_CODE (fields) != TYPE_DECL)
                   2774:        {
                   2775:          DECL_PUBLIC (fields) = 0;
                   2776:          DECL_PROTECTED (fields) = 0;
                   2777:          DECL_PRIVATE (fields) = 0;
                   2778:        }
                   2779: #endif
                   2780: 
                   2781:       if (DECL_NAME (fields))
                   2782:        {
                   2783:          tree class_value = IDENTIFIER_CLASS_VALUE (DECL_NAME (fields));
                   2784: 
                   2785:          /* If the class value is an envelope of the kind described in
                   2786:             the comment above, we try to rule out possible ambiguities.
                   2787:             If we can't do that, keep a TREE_LIST with possibly ambiguous
                   2788:             decls in there.  */
                   2789:          if (class_value && TREE_CODE (class_value) == TREE_LIST
                   2790:              && TREE_PURPOSE (class_value) != NULL_TREE
                   2791:              && (TREE_CODE (TREE_PURPOSE (class_value))
                   2792:                  != IDENTIFIER_NODE))
                   2793:            {
                   2794:              tree value = TREE_PURPOSE (class_value);
                   2795:              tree context;
                   2796: 
                   2797:              /* Possible ambiguity.  If its defining type(s)
                   2798:                 is (are all) derived from us, no problem.  */
                   2799:              if (TREE_CODE (value) != TREE_LIST)
                   2800:                {
                   2801:                  context = (TREE_CODE (value) == FUNCTION_DECL
                   2802:                             && DECL_VIRTUAL_P (value))
                   2803:                    ? DECL_CLASS_CONTEXT (value)
                   2804:                      : DECL_CONTEXT (value);
                   2805: 
                   2806:                  if (context && (context == type
                   2807:                                  || TYPE_DERIVES_FROM (context, type)))
                   2808:                    value = fields;
                   2809:                  else
                   2810:                    value = tree_cons (NULL_TREE, fields,
                   2811:                                       build_tree_list (NULL_TREE, value));
                   2812:                }
                   2813:              else
                   2814:                {
                   2815:                  /* All children may derive from us, in which case
                   2816:                     there is no problem.  Otherwise, we have to
                   2817:                     keep lists around of what the ambiguities might be.  */
                   2818:                  tree values;
                   2819:                  int problem = 0;
                   2820: 
                   2821:                  for (values = value; values; values = TREE_CHAIN (values))
                   2822:                    {
                   2823:                      tree sub_values = TREE_VALUE (values);
                   2824: 
                   2825:                      if (TREE_CODE (sub_values) == TREE_LIST)
                   2826:                        {
                   2827:                          for (; sub_values; sub_values = TREE_CHAIN (sub_values))
                   2828:                            {
                   2829:                              register tree list_mbr = TREE_VALUE (sub_values);
                   2830: 
                   2831:                              context = (TREE_CODE (list_mbr) == FUNCTION_DECL
                   2832:                                         && DECL_VIRTUAL_P (list_mbr))
                   2833:                                ? DECL_CLASS_CONTEXT (list_mbr)
                   2834:                                  : DECL_CONTEXT (list_mbr);
                   2835: 
                   2836:                              if (! TYPE_DERIVES_FROM (context, type))
                   2837:                                {
                   2838:                                  value = tree_cons (NULL_TREE, TREE_VALUE (values), value);
                   2839:                                  problem = 1;
                   2840:                                  break;
                   2841:                                }
                   2842:                            }
                   2843:                        }
                   2844:                      else
                   2845:                        {
                   2846:                          context = (TREE_CODE (sub_values) == FUNCTION_DECL
                   2847:                                     && DECL_VIRTUAL_P (sub_values))
                   2848:                            ? DECL_CLASS_CONTEXT (sub_values)
                   2849:                              : DECL_CONTEXT (sub_values);
                   2850: 
                   2851:                          if (context && ! TYPE_DERIVES_FROM (context, type))
                   2852:                            {
                   2853:                              value = tree_cons (NULL_TREE, values, value);
                   2854:                              problem = 1;
                   2855:                              break;
                   2856:                            }
                   2857:                        }
                   2858:                    }
                   2859:                  if (! problem) value = fields;
                   2860:                }
                   2861: 
                   2862:              /* Mark this as a potentially ambiguous member.  */
                   2863:              if (TREE_CODE (value) == TREE_LIST)
                   2864:                {
                   2865:                  /* Leaving TREE_TYPE blank is intentional.
                   2866:                     We cannot use `error_mark_node' (lookup_name)
                   2867:                     or `unknown_type_node' (all member functions use this).  */
                   2868:                  TREE_NONLOCAL_FLAG (value) = 1;
                   2869:                }
                   2870: 
                   2871:              /* Put the new contents in our envelope.  */
                   2872:              TREE_PURPOSE (class_value) = value;
                   2873:            }
                   2874:          else
                   2875:            {
                   2876:              /* See comment above for a description of envelopes.  */
                   2877:              tree envelope = tree_cons (fields, class_value,
                   2878:                                         closed_envelopes);
                   2879: 
                   2880:              closed_envelopes = envelope;
                   2881:              IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) = envelope;
                   2882:            }
                   2883:        }
                   2884:     }
                   2885: 
                   2886:   method_vec = CLASSTYPE_METHOD_VEC (type);
                   2887:   if (method_vec != 0)
                   2888:     {
                   2889:       /* Farm out constructors and destructors.  */
                   2890:       methods = &TREE_VEC_ELT (method_vec, 1);
                   2891:       end = TREE_VEC_END (method_vec);
                   2892: 
                   2893:       /* This does not work for multiple inheritance yet.  */
                   2894:       while (methods != end)
                   2895:        {
                   2896:          /* This will cause lookup_name to return a pointer
                   2897:             to the tree_list of possible methods of this name.
                   2898:             If the order is a problem, we can nreverse them.  */
                   2899:          tree tmp;
                   2900:          tree class_value = IDENTIFIER_CLASS_VALUE (DECL_NAME (*methods));
                   2901: 
                   2902:          if (class_value && TREE_CODE (class_value) == TREE_LIST
                   2903:              && TREE_PURPOSE (class_value) != NULL_TREE
                   2904:              && TREE_CODE (TREE_PURPOSE (class_value)) != IDENTIFIER_NODE)
                   2905:            {
                   2906:              tree old = TREE_PURPOSE (class_value);
                   2907: 
                   2908:              maybe_push_cache_obstack ();
                   2909:              if (TREE_CODE (old) == TREE_LIST)
                   2910:                tmp = tree_cons (DECL_NAME (*methods), *methods, old);
                   2911:              else
                   2912:                {
                   2913:                  /* Only complain if we shadow something we can access.  */
                   2914:                  if (old
                   2915:                      && warn_shadow
                   2916:                      && ((DECL_LANG_SPECIFIC (old)
                   2917:                           && DECL_CLASS_CONTEXT (old) == current_class_type)
                   2918:                          || ! TREE_PRIVATE (old)))
                   2919:                    /* Should figure out access control more accurately.  */
                   2920:                    {
                   2921:                      cp_warning_at ("member `%#D' is shadowed", old);
                   2922:                      cp_warning_at ("by member function `%#D'", *methods);
                   2923:                      warning ("in this context");
                   2924:                    }
                   2925:                  tmp = build_tree_list (DECL_NAME (*methods), *methods);
                   2926:                }
                   2927:              pop_obstacks ();
                   2928: 
                   2929:              TREE_TYPE (tmp) = unknown_type_node;
                   2930: #if 0
                   2931:              TREE_OVERLOADED (tmp) = DECL_OVERLOADED (*methods);
                   2932: #endif
                   2933:              TREE_NONLOCAL_FLAG (tmp) = 1;
                   2934:              
                   2935:              /* Put the new contents in our envelope.  */
                   2936:              TREE_PURPOSE (class_value) = tmp;
                   2937:            }
                   2938:          else
                   2939:            {
                   2940:              maybe_push_cache_obstack ();
                   2941:              tmp = build_tree_list (DECL_NAME (*methods), *methods);
                   2942:              pop_obstacks ();
                   2943: 
                   2944:              TREE_TYPE (tmp) = unknown_type_node;
                   2945: #if 0
                   2946:              TREE_OVERLOADED (tmp) = DECL_OVERLOADED (*methods);
                   2947: #endif
                   2948:              TREE_NONLOCAL_FLAG (tmp) = 1;
                   2949:              
                   2950:              /* See comment above for a description of envelopes.  */
                   2951:              closed_envelopes = tree_cons (tmp, class_value,
                   2952:                                            closed_envelopes);
                   2953:              IDENTIFIER_CLASS_VALUE (DECL_NAME (*methods)) = closed_envelopes;
                   2954:            }
                   2955: #if 0
                   2956:          tmp = *methods;
                   2957:          while (tmp != 0)
                   2958:            {
                   2959:              DECL_PUBLIC (tmp) = 0;
                   2960:              DECL_PROTECTED (tmp) = 0;
                   2961:              DECL_PRIVATE (tmp) = 0;
                   2962:              tmp = DECL_CHAIN (tmp);
                   2963:            }
                   2964: #endif
                   2965: 
                   2966:          methods++;
                   2967:        }
                   2968:     }
                   2969:   SET_BINFO_MARKED (binfo);
                   2970: }
                   2971: 
                   2972: /* Consolidate unique (by name) member functions.  */
                   2973: static void
                   2974: dfs_compress_decls (binfo)
                   2975:      tree binfo;
                   2976: {
                   2977:   tree type = BINFO_TYPE (binfo);
                   2978:   tree method_vec = CLASSTYPE_METHOD_VEC (type);
                   2979: 
                   2980:   if (method_vec != 0)
                   2981:     {
                   2982:       /* Farm out constructors and destructors.  */
                   2983:       tree *methods = &TREE_VEC_ELT (method_vec, 1);
                   2984:       tree *end = TREE_VEC_END (method_vec);
                   2985: 
                   2986:       for (; methods != end; methods++)
                   2987:        {
                   2988:          /* This is known to be an envelope of the kind described before
                   2989:             dfs_pushdecls.  */
                   2990:          tree class_value = IDENTIFIER_CLASS_VALUE (DECL_NAME (*methods));
                   2991:          tree tmp = TREE_PURPOSE (class_value);
                   2992: 
                   2993:          /* This was replaced in scope by somebody else.  Just leave it
                   2994:             alone.  */
                   2995:          if (TREE_CODE (tmp) != TREE_LIST)
                   2996:            continue;
                   2997: 
                   2998:          if (TREE_CHAIN (tmp) == NULL_TREE
                   2999:              && TREE_VALUE (tmp)
                   3000:              && DECL_CHAIN (TREE_VALUE (tmp)) == NULL_TREE)
                   3001:            {
                   3002:              TREE_PURPOSE (class_value) = TREE_VALUE (tmp);
                   3003:            }
                   3004:        }
                   3005:     }
                   3006:   CLEAR_BINFO_MARKED (binfo);
                   3007: }
                   3008: 
                   3009: /* When entering the scope of a class, we cache all of the
                   3010:    fields that that class provides within its inheritance
                   3011:    lattice.  Where ambiguities result, we mark them
                   3012:    with `error_mark_node' so that if they are encountered
                   3013:    without explicit qualification, we can emit an error
                   3014:    message.  */
                   3015: void
                   3016: push_class_decls (type)
                   3017:      tree type;
                   3018: {
                   3019:   tree id;
                   3020:   struct obstack *ambient_obstack = current_obstack;
                   3021: 
                   3022: #if 0
                   3023:   tree tags = CLASSTYPE_TAGS (type);
                   3024: 
                   3025:   while (tags)
                   3026:     {
                   3027:       tree code_type_node;
                   3028:       tree tag;
                   3029: 
                   3030:       switch (TREE_CODE (TREE_VALUE (tags)))
                   3031:        {
                   3032:        case ENUMERAL_TYPE:
                   3033:          code_type_node = enum_type_node;
                   3034:          break;
                   3035:        case RECORD_TYPE:
                   3036:          code_type_node = record_type_node;
                   3037:          break;
                   3038:        case CLASS_TYPE:
                   3039:          code_type_node = class_type_node;
                   3040:          break;
                   3041:        case UNION_TYPE:
                   3042:          code_type_node = union_type_node;
                   3043:          break;
                   3044:        default:
                   3045:          my_friendly_abort (297);
                   3046:        }
                   3047:       tag = xref_tag (code_type_node, TREE_PURPOSE (tags),
                   3048:                      TYPE_BINFO_BASETYPE (TREE_VALUE (tags), 0), 0);
                   3049: #if 0 /* not yet, should get fixed properly later */
                   3050:       pushdecl (make_type_decl (TREE_PURPOSE (tags), TREE_VALUE (tags)));
                   3051: #else
                   3052:       pushdecl (build_decl (TYPE_DECL, TREE_PURPOSE (tags), TREE_VALUE (tags)));
                   3053: #endif
                   3054:     }
                   3055: #endif
                   3056: 
                   3057:   search_stack = push_search_level (search_stack, &search_obstack);
                   3058: 
                   3059:   id = TYPE_IDENTIFIER (type);
                   3060: #if 0
                   3061:   if (IDENTIFIER_TEMPLATE (id) != 0)
                   3062:     {
                   3063:       tree tmpl = IDENTIFIER_TEMPLATE (id);
                   3064:       push_template_decls (DECL_ARGUMENTS (TREE_PURPOSE (tmpl)),
                   3065:                           TREE_VALUE (tmpl), 1);
                   3066:       overload_template_name (id, 1);
                   3067:     }
                   3068: #endif
                   3069: 
                   3070:   /* Push class fields into CLASS_VALUE scope, and mark.  */
                   3071:   dfs_walk (TYPE_BINFO (type), dfs_pushdecls, unmarkedp);
                   3072: 
                   3073:   /* Compress fields which have only a single entry
                   3074:      by a given name, and unmark.  */
                   3075:   dfs_walk (TYPE_BINFO (type), dfs_compress_decls, markedp);
                   3076: 
                   3077:   /* Open up all the closed envelopes and push the contained decls into
                   3078:      class scope.  */
                   3079:   while (closed_envelopes)
                   3080:     {
                   3081:       tree new = TREE_PURPOSE (closed_envelopes);
                   3082:       tree id;
                   3083: 
                   3084:       /* This is messy because the class value may be a *_DECL, or a
                   3085:         TREE_LIST of overloaded *_DECLs or even a TREE_LIST of ambiguous
                   3086:         *_DECLs.  The name is stored at different places in these three
                   3087:         cases.  */
                   3088:       if (TREE_CODE (new) == TREE_LIST)
                   3089:        {
                   3090:          if (TREE_PURPOSE (new) != NULL_TREE)
                   3091:            id = TREE_PURPOSE (new);
                   3092:          else
                   3093:            {
                   3094:              tree node = TREE_VALUE (new);
                   3095: 
                   3096:              while (TREE_CODE (node) == TREE_LIST)
                   3097:                node = TREE_VALUE (node);
                   3098:              id = DECL_NAME (node);
                   3099:            }
                   3100:        }
                   3101:       else
                   3102:        id = DECL_NAME (new);
                   3103: 
                   3104:       /* Install the original class value in order to make
                   3105:         pushdecl_class_level work correctly.  */
                   3106:       IDENTIFIER_CLASS_VALUE (id) = TREE_VALUE (closed_envelopes);
                   3107:       if (TREE_CODE (new) == TREE_LIST)
                   3108:        push_class_level_binding (id, new);
                   3109:       else
                   3110:        pushdecl_class_level (new);
                   3111:       closed_envelopes = TREE_CHAIN (closed_envelopes);
                   3112:     }
                   3113:   current_obstack = ambient_obstack;
                   3114: }
                   3115: 
                   3116: /* Here's a subroutine we need because C lacks lambdas.  */
                   3117: static void
                   3118: dfs_unuse_fields (binfo)
                   3119:      tree binfo;
                   3120: {
                   3121:   tree type = TREE_TYPE (binfo);
                   3122:   tree fields;
                   3123: 
                   3124:   for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields))
                   3125:     {
                   3126:       if (TREE_CODE (fields) != FIELD_DECL)
                   3127:        continue;
                   3128: 
                   3129:       TREE_USED (fields) = 0;
                   3130:       if (DECL_NAME (fields) == NULL_TREE
                   3131:          && TREE_CODE (TREE_TYPE (fields)) == UNION_TYPE)
                   3132:        unuse_fields (TREE_TYPE (fields));
                   3133:     }
                   3134: }
                   3135: 
                   3136: void
                   3137: unuse_fields (type)
                   3138:      tree type;
                   3139: {
                   3140:   dfs_walk (TYPE_BINFO (type), dfs_unuse_fields, unmarkedp);
                   3141: }
                   3142: 
                   3143: void
                   3144: pop_class_decls (type)
                   3145:      tree type;
                   3146: {
                   3147:   /* We haven't pushed a search level when dealing with cached classes,
                   3148:      so we'd better not try to pop it.  */
                   3149:   if (search_stack)
                   3150:     search_stack = pop_search_level (search_stack);
                   3151: }
                   3152: 
                   3153: void
                   3154: print_search_statistics ()
                   3155: {
                   3156: #ifdef GATHER_STATISTICS
                   3157:   if (flag_memoize_lookups)
                   3158:     {
                   3159:       fprintf (stderr, "%d memoized contexts saved\n",
                   3160:               n_contexts_saved);
                   3161:       fprintf (stderr, "%d local tree nodes made\n", my_tree_node_counter);
                   3162:       fprintf (stderr, "%d local hash nodes made\n", my_memoized_entry_counter);
                   3163:       fprintf (stderr, "fields statistics:\n");
                   3164:       fprintf (stderr, "  memoized finds = %d; rejects = %d; (searches = %d)\n",
                   3165:               memoized_fast_finds[0], memoized_fast_rejects[0],
                   3166:               memoized_fields_searched[0]);
                   3167:       fprintf (stderr, "  memoized_adds = %d\n", memoized_adds[0]);
                   3168:       fprintf (stderr, "fnfields statistics:\n");
                   3169:       fprintf (stderr, "  memoized finds = %d; rejects = %d; (searches = %d)\n",
                   3170:               memoized_fast_finds[1], memoized_fast_rejects[1],
                   3171:               memoized_fields_searched[1]);
                   3172:       fprintf (stderr, "  memoized_adds = %d\n", memoized_adds[1]);
                   3173:     }
                   3174:   fprintf (stderr, "%d fields searched in %d[%d] calls to lookup_field[_1]\n",
                   3175:           n_fields_searched, n_calls_lookup_field, n_calls_lookup_field_1);
                   3176:   fprintf (stderr, "%d fnfields searched in %d calls to lookup_fnfields\n",
                   3177:           n_outer_fields_searched, n_calls_lookup_fnfields);
                   3178:   fprintf (stderr, "%d calls to get_base_type\n", n_calls_get_base_type);
                   3179: #else
                   3180:   fprintf (stderr, "no search statistics\n");
                   3181: #endif
                   3182: }
                   3183: 
                   3184: void
                   3185: init_search_processing ()
                   3186: {
                   3187:   gcc_obstack_init (&search_obstack);
                   3188:   gcc_obstack_init (&type_obstack);
                   3189:   gcc_obstack_init (&type_obstack_entries);
                   3190: 
                   3191:   /* This gives us room to build our chains of basetypes,
                   3192:      whether or not we decide to memoize them.  */
                   3193:   type_stack = push_type_level (0, &type_obstack);
                   3194:   _vptr_name = get_identifier ("_vptr");
                   3195: }
                   3196: 
                   3197: void
                   3198: reinit_search_statistics ()
                   3199: {
                   3200:   my_memoized_entry_counter = 0;
                   3201:   memoized_fast_finds[0] = 0;
                   3202:   memoized_fast_finds[1] = 0;
                   3203:   memoized_adds[0] = 0;
                   3204:   memoized_adds[1] = 0;
                   3205:   memoized_fast_rejects[0] = 0;
                   3206:   memoized_fast_rejects[1] = 0;
                   3207:   memoized_fields_searched[0] = 0;
                   3208:   memoized_fields_searched[1] = 0;
                   3209:   n_fields_searched = 0;
                   3210:   n_calls_lookup_field = 0, n_calls_lookup_field_1 = 0;
                   3211:   n_calls_lookup_fnfields = 0, n_calls_lookup_fnfields_1 = 0;
                   3212:   n_calls_get_base_type = 0;
                   3213:   n_outer_fields_searched = 0;
                   3214:   n_contexts_saved = 0;
                   3215: }

unix.superglobalmegacorp.com

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