Annotation of gcc/cp-search.c, revision 1.1.1.6

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

unix.superglobalmegacorp.com

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