home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 7 / FreshFishVol7.bin / bbs / gnu / gcc-2.3.3-src.lha / GNU / src / amiga / gcc-2.3.3 / cp-search.c < prev    next >
C/C++ Source or Header  |  1994-02-06  |  109KB  |  3,755 lines

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