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