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