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