home *** CD-ROM | disk | FTP | other *** search
/ Education Sampler 1992 [NeXTSTEP] / Education_1992_Sampler.iso / NeXT / GnuSource / cc-61.0.1 / cc / cplus-search.c < prev    next >
C/C++ Source or Header  |  1991-06-03  |  91KB  |  3,254 lines

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