|
|
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;
55: void *tp;
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:
149: /* Allocate a level of type memoziation context. */
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:
167: /* Discard a level of type memoziation context. */
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)
258: abort ();
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)
445: abort ();
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: }
457: else abort ();
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)
499: abort ();
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))
556: /* It's ok, since it's immedate. */
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: }
606: else abort ();
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)
670: abort ();
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: }
899: else abort ();
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: }
1036: abort ();
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;
1048: else abort ();
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;
1079: else abort ();
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)
1191: abort ();
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)
1523: abort ();
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:
1568: if (index >= 0 && binfo != get_binfo (type, context, 0))
1569: {
1570: /* We found it in other than a baseclass of RVAL's. */
1571: rvals = my_tree_cons (basetype_path, TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), index), rvals);
1572: if (CLASSTYPE_BASELINK_VEC (type))
1573: TREE_TYPE (rvals) = TREE_VEC_ELT (CLASSTYPE_BASELINK_VEC (type), index);
1574: }
1575: }
1576: if (errstr && entry)
1577: {
1578: tree error_string = my_build_string (errstr);
1579: TREE_TYPE (entry) = error_string;
1580: }
1581: if (errstr && find_ambiguous)
1582: {
1583: rvals = error_mark_node;
1584: break;
1585: }
1586: }
1587: else
1588: {
1589: int index = lookup_fnfields_1 (type, name);
1590: if (index >= 0)
1591: {
1592: rval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), index);
1593: rvals = my_tree_cons (basetype_path, rval, NULL_TREE);
1594: if (TYPE_BINFO_BASETYPES (type) && CLASSTYPE_BASELINK_VEC (type))
1595: TREE_TYPE (rvals) = TREE_VEC_ELT (CLASSTYPE_BASELINK_VEC (type), index);
1596: if (entry)
1597: TREE_VALUE (entry) = rvals;
1598: }
1599: else
1600: rval = NULL_TREE;
1601: }
1602: }
1603: {
1604: tree *tp = search_stack->first;
1605: tree *search_tail = tp + tail;
1606:
1607: while (tp < search_tail)
1608: {
1609: CLEAR_BINFO_FIELDS_MARKED (TREE_VALUE (*tp));
1610: tp += 1;
1611: }
1612: }
1613: search_stack = pop_search_level (search_stack);
1614:
1615: if (entry)
1616: {
1617: if (errstr)
1618: {
1619: tree error_string = my_build_string (errstr);
1620: /* Save error message with entry. */
1621: TREE_TYPE (entry) = error_string;
1622: }
1623: else
1624: {
1625: /* Mark entry as having no error string. */
1626: TREE_TYPE (entry) = NULL_TREE;
1627: }
1628: }
1629:
1630: if (errstr && protect)
1631: {
1632: error (errstr, IDENTIFIER_POINTER (name), TYPE_NAME_STRING (type));
1633: rvals = error_mark_node;
1634: }
1635:
1636: return rvals;
1637: }
1638:
1639: /* BREADTH-FIRST SEARCH ROUTINES. */
1640:
1641: /* Search a multiple inheritance hierarchy by breadth-first search.
1642:
1643: TYPE is an aggregate type, possibly in a multiple-inheritance hierarchy.
1644: TESTFN is a function, which, if true, means that our condition has been met,
1645: and its return value should be returned.
1646: QFN, if non-NULL, is a predicate dictating whether the type should
1647: even be queued. */
1648:
1649: int
1650: breadth_first_search (binfo, testfn, qfn)
1651: tree binfo;
1652: int (*testfn)();
1653: int (*qfn)();
1654: {
1655: int head = 0, tail = 0;
1656: int rval = 0;
1657:
1658: search_stack = push_search_level (search_stack, &search_obstack);
1659:
1660: while (1)
1661: {
1662: tree binfos = BINFO_BASETYPES (binfo);
1663: int n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
1664: int i;
1665:
1666: /* Process and/or queue base types. */
1667: for (i = 0; i < n_baselinks; i++)
1668: {
1669: tree child = TREE_VEC_ELT (binfos, i);
1670:
1671: if (BINFO_MARKED (child) == 0
1672: && (qfn == 0 || (*qfn) (binfo, i)))
1673: {
1674: SET_BINFO_MARKED (child);
1675: obstack_ptr_grow (&search_obstack, binfo);
1676: obstack_int_grow (&search_obstack, i);
1677: tail += 2;
1678: if (tail >= search_stack->limit)
1679: abort ();
1680: }
1681: }
1682: /* Process head of queue, if one exists. */
1683: if (head >= tail)
1684: {
1685: rval = 0;
1686: break;
1687: }
1688:
1689: binfo = search_stack->first[head++];
1690: i = (int)search_stack->first[head++];
1691: if (rval = (*testfn) (binfo, i))
1692: break;
1693: binfo = BINFO_BASETYPE (binfo, i);
1694: }
1695: {
1696: tree *tp = search_stack->first;
1697: tree *search_tail = tp + tail;
1698: while (tp < search_tail)
1699: {
1700: tree binfo = *tp++;
1701: int i = (int)(*tp++);
1702: CLEAR_BINFO_MARKED (BINFO_BASETYPE (binfo, i));
1703: }
1704: }
1705:
1706: search_stack = pop_search_level (search_stack);
1707: return rval;
1708: }
1709:
1710: /* Functions to use in breadth first searches. */
1711: typedef tree (*pft)();
1712: typedef int (*pfi)();
1713:
1714: int tree_needs_constructor_p (binfo, i)
1715: tree binfo;
1716: {
1717: tree basetype;
1718: assert (i != 0);
1719: basetype = BINFO_TYPE (BINFO_BASETYPE (binfo, i));
1720: return TYPE_NEEDS_CONSTRUCTOR (basetype);
1721: }
1722:
1723: static tree declarator;
1724:
1725: static tree
1726: get_virtuals_named_this (binfo, i)
1727: tree binfo;
1728: int i;
1729: {
1730: tree fields;
1731: tree type = BINFO_TYPE (binfo);
1732:
1733: if (i >= 0)
1734: type = BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo), i));
1735: fields = lookup_fnfields (binfo, declarator, 0);
1736:
1737: if (fields == 0 || fields == error_mark_node)
1738: return 0;
1739:
1740: /* Get to the function decls, and return the first virtual function
1741: with this name, if there is one. */
1742: while (fields)
1743: {
1744: tree fndecl;
1745:
1746: for (fndecl = TREE_VALUE (fields); fndecl; fndecl = DECL_CHAIN (fndecl))
1747: if (DECL_VINDEX (fndecl))
1748: return fields;
1749: fields = next_baselink (fields);
1750: }
1751: return NULL_TREE;
1752: }
1753:
1754: static tree get_virtual_destructor (binfo, i)
1755: tree binfo;
1756: int i;
1757: {
1758: tree type = BINFO_TYPE (binfo);
1759: if (i >= 0)
1760: type = BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo), i));
1761: if (TYPE_HAS_DESTRUCTOR (type)
1762: && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 0)))
1763: return TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 0);
1764: return 0;
1765: }
1766:
1767: int tree_has_any_destructor_p (binfo, i)
1768: tree binfo;
1769: int i;
1770: {
1771: tree type = BINFO_TYPE (binfo);
1772: if (i >= 0)
1773: type = BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo), i));
1774: return TYPE_NEEDS_DESTRUCTOR (type);
1775: }
1776:
1777: /* Given a class type TYPE, and a function decl FNDECL,
1778: look for the first function the TYPE's heirarchy which
1779: FNDECL could match as a virtual function.
1780:
1781: DTORP is nonzero if we are looking for a destructor. Destructors
1782: need special treatment because they do not match by name. */
1783: tree
1784: get_first_matching_virtual (binfo, fndecl, dtorp)
1785: tree binfo, fndecl;
1786: int dtorp;
1787: {
1788: tree tmp = NULL_TREE;
1789:
1790: /* Breadth first search routines start searching basetypes
1791: of TYPE, so we must perform first ply of search here. */
1792: if (dtorp)
1793: {
1794: if (tree_has_any_destructor_p (binfo, -1))
1795: tmp = get_virtual_destructor (binfo, -1);
1796:
1797: if (tmp)
1798: {
1799: DECL_CONTEXT (fndecl) = DECL_CONTEXT (tmp);
1800: return tmp;
1801: }
1802:
1803: tmp = (tree) breadth_first_search (binfo,
1804: (pfi) get_virtual_destructor,
1805: tree_has_any_destructor_p);
1806: if (tmp)
1807: DECL_CONTEXT (fndecl) = DECL_CONTEXT (tmp);
1808: return tmp;
1809: }
1810: else
1811: {
1812: tree drettype, dtypes, btypes, instptr_type;
1813: tree basetype = DECL_CLASS_CONTEXT (fndecl);
1814: tree baselink, best = NULL_TREE;
1815: tree name = DECL_ASSEMBLER_NAME (fndecl);
1816:
1817: declarator = DECL_NAME (fndecl);
1818: if (IDENTIFIER_VIRTUAL_P (declarator) == 0)
1819: return 0;
1820:
1821: drettype = TREE_TYPE (TREE_TYPE (fndecl));
1822: dtypes = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
1823: if (DECL_STATIC_FUNCTION_P (fndecl))
1824: instptr_type = NULL_TREE;
1825: else
1826: instptr_type = TREE_TYPE (TREE_VALUE (dtypes));
1827:
1828: for (baselink = get_virtuals_named_this (binfo, -1);
1829: baselink; baselink = next_baselink (baselink))
1830: {
1831: for (tmp = TREE_VALUE (baselink); tmp; tmp = DECL_CHAIN (tmp))
1832: {
1833: if (! DECL_VINDEX (tmp))
1834: continue;
1835:
1836: btypes = TYPE_ARG_TYPES (TREE_TYPE (tmp));
1837: if (instptr_type == NULL_TREE
1838: && compparms (TREE_CHAIN (btypes), dtypes, 3))
1839: /* Caller knows to give error in this case. */
1840: return tmp;
1841:
1842: if ((TYPE_READONLY (TREE_TYPE (TREE_VALUE (btypes)))
1843: == TYPE_READONLY (instptr_type))
1844: && compparms (TREE_CHAIN (btypes), TREE_CHAIN (dtypes), 3))
1845: {
1846: if (IDENTIFIER_ERROR_LOCUS (name) == NULL_TREE
1847: && ! comptypes (TREE_TYPE (TREE_TYPE (tmp)), drettype, 1))
1848: {
1849: error_with_decl (fndecl, "conflicting return type specified for virtual function `%s'");
1850: SET_IDENTIFIER_ERROR_LOCUS (name, basetype);
1851: }
1852: break;
1853: }
1854: }
1855: if (tmp)
1856: {
1857: /* If this is ambiguous, we will warn about it later. */
1858: if (best)
1859: {
1860: if (get_base_distance (DECL_CLASS_CONTEXT (best),
1861: DECL_CLASS_CONTEXT (tmp), 0, 0) > 0)
1862: best = tmp;
1863: }
1864: else
1865: best = tmp;
1866: }
1867: }
1868: if (IDENTIFIER_ERROR_LOCUS (name) == NULL_TREE
1869: && best == NULL_TREE && warn_overloaded_virtual)
1870: {
1871: error_with_decl (fndecl, "conficting specification deriving virtual function `%s'");
1872: SET_IDENTIFIER_ERROR_LOCUS (name, basetype);
1873: }
1874: if (best)
1875: {
1876: DECL_CONTEXT (fndecl) = DECL_CONTEXT (best);
1877: }
1878: return best;
1879: }
1880: }
1881:
1882: /* Return the list of virtual functions which are abstract in type TYPE.
1883: This information is cached, and so must be built on a
1884: non-temporary obstack. */
1885: tree
1886: get_abstract_virtuals (type)
1887: tree type;
1888: {
1889: /* For each layer of base class (i.e., the first base class, and each
1890: virtual base class from that one), modify the virtual function table
1891: of the derived class to contain the new virtual function.
1892: A class has as many vfields as it has virtual base classes (total). */
1893: tree vfields, vbases, base, tmp;
1894: tree vfield = CLASSTYPE_VFIELD (type);
1895: tree fcontext = vfield ? DECL_FCONTEXT (vfield) : NULL_TREE;
1896: tree abstract_virtuals = CLASSTYPE_ABSTRACT_VIRTUALS (type);
1897:
1898: for (vfields = CLASSTYPE_VFIELDS (type); vfields; vfields = TREE_CHAIN (vfields))
1899: {
1900: int normal;
1901:
1902: /* Find the right base class for this derived class, call it BASE. */
1903: base = VF_BASETYPE_VALUE (vfields);
1904: if (base == type)
1905: continue;
1906:
1907: /* We call this case NORMAL iff this virtual function table
1908: pointer field has its storage reserved in this class.
1909: This is normally the case without virtual baseclasses
1910: or off-center multiple baseclasses. */
1911: normal = (base == fcontext
1912: && (VF_BINFO_VALUE (vfields) == NULL_TREE
1913: || ! TREE_VIA_VIRTUAL (VF_BINFO_VALUE (vfields))));
1914:
1915: if (normal)
1916: tmp = TREE_CHAIN (TYPE_BINFO_VIRTUALS (type));
1917: else
1918: {
1919: /* n.b.: VF_BASETYPE_VALUE (vfields) is the first basetype
1920: that provides the virtual function table, whereas
1921: VF_DERIVED_VALUE (vfields) is an immediate base type of TYPE
1922: that dominates VF_BASETYPE_VALUE (vfields). The list of
1923: vfields we want lies between these two values. */
1924: tree binfo = get_binfo (VF_NORMAL_VALUE (vfields), type, 0);
1925: tmp = TREE_CHAIN (BINFO_VIRTUALS (binfo));
1926: }
1927:
1928: /* Get around dossier entry if there is one. */
1929: if (flag_dossier)
1930: tmp = TREE_CHAIN (tmp);
1931:
1932: while (tmp)
1933: {
1934: tree base_pfn = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (tmp));
1935: tree base_fndecl = TREE_OPERAND (base_pfn, 0);
1936: if (DECL_ABSTRACT_VIRTUAL_P (base_fndecl))
1937: abstract_virtuals = tree_cons (NULL_TREE, base_fndecl, abstract_virtuals);
1938: tmp = TREE_CHAIN (tmp);
1939: }
1940: }
1941: for (vbases = CLASSTYPE_VBASECLASSES (type); vbases; vbases = TREE_CHAIN (vbases))
1942: {
1943: if (! BINFO_VIRTUALS (vbases))
1944: continue;
1945:
1946: tmp = TREE_CHAIN (BINFO_VIRTUALS (vbases));
1947: while (tmp)
1948: {
1949: tree base_pfn = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (tmp));
1950: tree base_fndecl = TREE_OPERAND (base_pfn, 0);
1951: if (DECL_ABSTRACT_VIRTUAL_P (base_fndecl))
1952: abstract_virtuals = tree_cons (NULL_TREE, base_fndecl, abstract_virtuals);
1953: tmp = TREE_CHAIN (tmp);
1954: }
1955: }
1956: return nreverse (abstract_virtuals);
1957: }
1958:
1959: /* For the type TYPE, return a list of member functions available from
1960: base classes with name NAME. The TREE_VALUE of the list is a chain of
1961: member functions with name NAME. The TREE_PURPOSE of the list is a
1962: basetype, or a list of base types (in reverse order) which were
1963: traversed to reach the chain of member functions. If we reach a base
1964: type which provides a member function of name NAME, and which has at
1965: most one base type itself, then we can terminate the search. */
1966:
1967: tree
1968: get_baselinks (type_as_binfo_list, type, name)
1969: tree type_as_binfo_list;
1970: tree type, name;
1971: {
1972: tree hash_tree_cons ();
1973: int head = 0, tail = 0, index;
1974: tree rval = 0, nval = 0;
1975: tree basetypes = type_as_binfo_list;
1976: tree binfo = TYPE_BINFO (type);
1977:
1978: search_stack = push_search_level (search_stack, &search_obstack);
1979:
1980: while (1)
1981: {
1982: tree binfos = BINFO_BASETYPES (binfo);
1983: int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
1984:
1985: /* Process and/or queue base types. */
1986: for (i = 0; i < n_baselinks; i++)
1987: {
1988: tree child = TREE_VEC_ELT (binfos, i);
1989: tree btypes;
1990:
1991: btypes = hash_tree_cons (TREE_VIA_PUBLIC (child),
1992: TREE_VIA_VIRTUAL (child),
1993: NULL_TREE, child,
1994: basetypes);
1995: obstack_ptr_grow (&search_obstack, btypes);
1996: search_stack->first = (tree *)obstack_base (&search_obstack);
1997: tail += 1;
1998: }
1999:
2000: dont_queue:
2001: /* Process head of queue, if one exists. */
2002: if (head >= tail)
2003: break;
2004:
2005: basetypes = search_stack->first[head++];
2006: binfo = TREE_VALUE (basetypes);
2007: type = BINFO_TYPE (binfo);
2008: index = lookup_fnfields_1 (type, name);
2009: if (index >= 0)
2010: {
2011: nval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), index);
2012: rval = hash_tree_cons (0, 0, basetypes, nval, rval);
2013: if (TYPE_BINFO_BASETYPES (type) == 0)
2014: goto dont_queue;
2015: else if (TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type)) == 1)
2016: {
2017: if (CLASSTYPE_BASELINK_VEC (type))
2018: TREE_TYPE (rval) = TREE_VEC_ELT (CLASSTYPE_BASELINK_VEC (type), index);
2019: goto dont_queue;
2020: }
2021: }
2022: nval = NULL_TREE;
2023: }
2024:
2025: search_stack = pop_search_level (search_stack);
2026: return rval;
2027: }
2028:
2029: tree
2030: next_baselink (baselink)
2031: tree baselink;
2032: {
2033: tree tmp = TREE_TYPE (baselink);
2034: baselink = TREE_CHAIN (baselink);
2035: while (tmp)
2036: {
2037: /* @@ does not yet add previous base types. */
2038: baselink = tree_cons (TREE_PURPOSE (tmp), TREE_VALUE (tmp),
2039: baselink);
2040: TREE_TYPE (baselink) = TREE_TYPE (tmp);
2041: tmp = TREE_CHAIN (tmp);
2042: }
2043: return baselink;
2044: }
2045:
2046: /* DEPTH-FIRST SEARCH ROUTINES. */
2047:
2048: /* Assign unique numbers to _CLASSTYPE members of the lattice
2049: specified by TYPE. The root nodes are marked first; the nodes
2050: are marked depth-fisrt, left-right. */
2051:
2052: static int cid;
2053:
2054: /* Matrix implementing a relation from CLASSTYPE X CLASSTYPE => INT.
2055: Relation yields 1 if C1 <= C2, 0 otherwise. */
2056: typedef char mi_boolean;
2057: static mi_boolean *mi_matrix;
2058:
2059: /* Type for which this matrix is defined. */
2060: static tree mi_type;
2061:
2062: /* Size of the matrix for indexing purposes. */
2063: static int mi_size;
2064:
2065: /* Return nonzero if class C2 derives from class C1. */
2066: #define BINFO_DERIVES_FROM(C1, C2) \
2067: ((mi_matrix+mi_size*(BINFO_CID (C1)-1))[BINFO_CID (C2)-1])
2068: #define TYPE_DERIVES_FROM(C1, C2) \
2069: ((mi_matrix+mi_size*(CLASSTYPE_CID (C1)-1))[CLASSTYPE_CID (C2)-1])
2070: #define BINFO_DERIVES_FROM_STAR(C) \
2071: (mi_matrix+(BINFO_CID (C)-1))
2072:
2073: /* The main function which implements depth first search. */
2074: static void
2075: dfs_walk (binfo, fn, qfn)
2076: tree binfo;
2077: void (*fn)();
2078: int (*qfn)();
2079: {
2080: tree binfos = BINFO_BASETYPES (binfo);
2081: int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
2082:
2083: for (i = 0; i < n_baselinks; i++)
2084: {
2085: tree child = TREE_VEC_ELT (binfos, i);
2086:
2087: if ((*qfn)(child))
2088: {
2089: dfs_walk (child, fn, qfn);
2090: }
2091: }
2092:
2093: fn (binfo);
2094: }
2095:
2096: /* Predicate functions which serve for dfs_walk. */
2097: static int numberedp (binfo) tree binfo;
2098: { return BINFO_CID (binfo); }
2099: static int unnumberedp (binfo) tree binfo;
2100: { return BINFO_CID (binfo) == 0; }
2101:
2102: static int markedp (binfo) tree binfo;
2103: { return BINFO_MARKED (binfo); }
2104: static int bfs_markedp (binfo, i) tree binfo; int i;
2105: { return BINFO_MARKED (BINFO_BASETYPE (binfo, i)); }
2106: static int unmarkedp (binfo) tree binfo;
2107: { return BINFO_MARKED (binfo) == 0; }
2108: static int bfs_unmarkedp (binfo, i) tree binfo; int i;
2109: { return BINFO_MARKED (BINFO_BASETYPE (binfo, i)) == 0; }
2110: static int marked3p (binfo) tree binfo;
2111: { return BINFO_VTABLE_PATH_MARKED (binfo); }
2112: static int bfs_marked3p (binfo, i) tree binfo; int i;
2113: { return BINFO_VTABLE_PATH_MARKED (BINFO_BASETYPE (binfo, i)); }
2114: static int unmarked3p (binfo) tree binfo;
2115: { return BINFO_VTABLE_PATH_MARKED (binfo) == 0; }
2116: static int bfs_unmarked3p (binfo, i) tree binfo; int i;
2117: { return BINFO_VTABLE_PATH_MARKED (BINFO_BASETYPE (binfo, i)) == 0; }
2118: static int marked4p (binfo) tree binfo;
2119: { return BINFO_NEW_VTABLE_MARKED (binfo); }
2120: static int bfs_marked4p (binfo, i) tree binfo; int i;
2121: { return BINFO_NEW_VTABLE_MARKED (BINFO_BASETYPE (binfo, i)); }
2122: static int unmarked4p (binfo) tree binfo;
2123: { return BINFO_NEW_VTABLE_MARKED (binfo) == 0; }
2124: static int bfs_unmarked4p (binfo, i) tree binfo; int i;
2125: { return BINFO_NEW_VTABLE_MARKED (BINFO_BASETYPE (binfo, i)) == 0; }
2126:
2127: static int dfs_search_slot_nonempty_p (binfo) tree binfo;
2128: { return CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (binfo)) != 0; }
2129:
2130: static int dfs_debug_unmarkedp (binfo) tree binfo;
2131: { return CLASSTYPE_DEBUG_REQUESTED (BINFO_TYPE (binfo)) == 0; }
2132:
2133: /* The worker functions for `dfs_walk'. These do not need to
2134: test anything (vis a vis marking) if they are paired with
2135: a predicate function (above). */
2136:
2137: /* Assign each type within the lattice a number which is unique
2138: in the lattice. The first number assigned is 1. */
2139:
2140: static void
2141: dfs_number (binfo)
2142: tree binfo;
2143: {
2144: BINFO_CID (binfo) = ++cid;
2145: }
2146:
2147: static void
2148: dfs_unnumber (binfo)
2149: tree binfo;
2150: {
2151: BINFO_CID (binfo) = 0;
2152: }
2153:
2154: static void
2155: dfs_mark (binfo) tree binfo;
2156: { SET_BINFO_MARKED (binfo); }
2157:
2158: static void
2159: dfs_unmark (binfo) tree binfo;
2160: { CLEAR_BINFO_MARKED (binfo); }
2161:
2162: static void
2163: dfs_mark3 (binfo) tree binfo;
2164: { SET_BINFO_VTABLE_PATH_MARKED (binfo); }
2165:
2166: static void
2167: dfs_unmark3 (binfo) tree binfo;
2168: { CLEAR_BINFO_VTABLE_PATH_MARKED (binfo); }
2169:
2170: static void
2171: dfs_mark4 (binfo) tree binfo;
2172: { SET_BINFO_NEW_VTABLE_MARKED (binfo); }
2173:
2174: static void
2175: dfs_unmark4 (binfo) tree binfo;
2176: { CLEAR_BINFO_NEW_VTABLE_MARKED (binfo); }
2177:
2178: static void
2179: dfs_unmark34 (binfo) tree binfo;
2180: { CLEAR_BINFO_VTABLE_PATH_MARKED (binfo);
2181: CLEAR_BINFO_NEW_VTABLE_MARKED (binfo); }
2182:
2183: static void
2184: dfs_clear_search_slot (binfo) tree binfo;
2185: { CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (binfo)) = 0; }
2186:
2187: static void
2188: dfs_debug_mark (binfo)
2189: tree binfo;
2190: {
2191: extern tree pending_vtables;
2192:
2193: tree t = BINFO_TYPE (binfo);
2194:
2195: /* Use heuristic that if there are virtual functions,
2196: ignore until we see a non-inline virtual function. */
2197: tree methods = CLASSTYPE_METHOD_VEC (t);
2198:
2199: CLASSTYPE_DEBUG_REQUESTED (t) = 1;
2200:
2201: /* If interface info is known, the value of DECL_IGNORED_P is correct. */
2202: if (methods == 0
2203: || ! CLASSTYPE_INTERFACE_UNKNOWN (t)
2204: || (write_virtuals == 2 && TYPE_VIRTUAL_P (t)))
2205: return;
2206:
2207: /* If debug info is requested from this context for this type, supply it.
2208: If debug info is requested from another context for this type,
2209: see if some third context can supply it. */
2210: if (current_function_decl == NULL_TREE
2211: || DECL_CLASS_CONTEXT (current_function_decl) != t)
2212: {
2213: if (TREE_VEC_ELT (methods, 0))
2214: methods = TREE_VEC_ELT (methods, 0);
2215: else
2216: methods = TREE_VEC_ELT (methods, 1);
2217: while (methods)
2218: {
2219: if (DECL_VINDEX (methods)
2220: && DECL_SAVED_INSNS (methods) == 0
2221: && DECL_PENDING_INLINE_INFO (methods) == 0
2222: && DECL_ABSTRACT_VIRTUAL_P (methods) == 0)
2223: {
2224: /* Somebody, somewhere is going to have to define this
2225: virtual function. When they do, they will provide
2226: the debugging info. */
2227: return;
2228: }
2229: methods = TREE_CHAIN (methods);
2230: }
2231: }
2232: /* We cannot rely on some alien method to solve our problems,
2233: so we must write out the debug info ourselves. */
2234: DECL_IGNORED_P (TYPE_NAME (t)) = 0;
2235: if (! TREE_ASM_WRITTEN (TYPE_NAME (t)))
2236: rest_of_type_compilation (t, global_bindings_p ());
2237: }
2238:
2239: static tree vbase_types;
2240: static tree vbase_decl, vbase_decl_ptr;
2241: static tree vbase_init_result;
2242:
2243: static void
2244: dfs_find_vbases (binfo)
2245: tree binfo;
2246: {
2247: tree binfos = BINFO_BASETYPES (binfo);
2248: int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
2249:
2250: for (i = n_baselinks-1; i >= 0; i--)
2251: {
2252: tree child = TREE_VEC_ELT (binfos, i);
2253:
2254: if (TREE_VIA_VIRTUAL (child)
2255: && CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (child)) == 0)
2256: {
2257: tree vbase = BINFO_TYPE (child);
2258: tree binfo = binfo_member (vbase, vbase_types);
2259:
2260: CLASSTYPE_SEARCH_SLOT (vbase)
2261: = (char *) build (PLUS_EXPR, TYPE_POINTER_TO (vbase),
2262: vbase_decl_ptr, BINFO_OFFSET (binfo));
2263: }
2264: }
2265: SET_BINFO_VTABLE_PATH_MARKED (binfo);
2266: SET_BINFO_NEW_VTABLE_MARKED (binfo);
2267: }
2268:
2269: static void
2270: dfs_init_vbase_pointers (binfo)
2271: tree binfo;
2272: {
2273: tree type = BINFO_TYPE (binfo);
2274: tree fields = TYPE_FIELDS (type);
2275: tree path, this_vbase_ptr;
2276: int distance;
2277:
2278: CLEAR_BINFO_VTABLE_PATH_MARKED (binfo);
2279:
2280: /* If there is a dossier, it is the first field, though perhaps from
2281: the base class. Otherwise, the first fields are virtual base class
2282: pointer fields. */
2283: if (CLASSTYPE_DOSSIER (type) && VFIELD_NAME_P (DECL_NAME (fields)))
2284: /* Get past vtable for the object. */
2285: fields = TREE_CHAIN (fields);
2286:
2287: if (fields == NULL_TREE
2288: || DECL_NAME (fields) == NULL_TREE
2289: || ! VBASE_NAME_P (DECL_NAME (fields)))
2290: return;
2291:
2292: distance = get_base_distance (type, TREE_TYPE (vbase_decl), 0, &path);
2293: while (path)
2294: {
2295: if (TREE_VIA_VIRTUAL (path))
2296: break;
2297: distance -= 1;
2298: path = BINFO_INHERITANCE_CHAIN (path);
2299: }
2300:
2301: if (distance > 0)
2302: this_vbase_ptr = convert_pointer_to (type, CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (path)));
2303: else
2304: this_vbase_ptr = convert_pointer_to (type, vbase_decl_ptr);
2305:
2306: while (fields && DECL_NAME (fields)
2307: && VBASE_NAME_P (DECL_NAME (fields)))
2308: {
2309: tree ref = build (COMPONENT_REF, TREE_TYPE (fields),
2310: build_indirect_ref (this_vbase_ptr, 0), fields);
2311: tree init = (tree)CLASSTYPE_SEARCH_SLOT (TREE_TYPE (TREE_TYPE (fields)));
2312: vbase_init_result = tree_cons (binfo_member (TREE_TYPE (TREE_TYPE (fields)),
2313: vbase_types),
2314: build_modify_expr (ref, NOP_EXPR, init),
2315: vbase_init_result);
2316: fields = TREE_CHAIN (fields);
2317: }
2318: }
2319:
2320: /* Sometimes this needs to clear both 3 and 4. Other times,
2321: just 4, but optimizer should make both with equal efficiency
2322: (though it does not currently). */
2323: static void
2324: dfs_clear_vbase_slots (binfo)
2325: tree binfo;
2326: {
2327: tree type = BINFO_TYPE (binfo);
2328: CLASSTYPE_SEARCH_SLOT (type) = 0;
2329: CLEAR_BINFO_VTABLE_PATH_MARKED (binfo);
2330: CLEAR_BINFO_NEW_VTABLE_MARKED (binfo);
2331: }
2332:
2333: tree
2334: init_vbase_pointers (type, decl_ptr)
2335: tree type;
2336: tree decl_ptr;
2337: {
2338: if (TYPE_USES_VIRTUAL_BASECLASSES (type))
2339: {
2340: int old_flag = flag_this_is_variable;
2341: tree binfo = TYPE_BINFO (type);
2342: flag_this_is_variable = 0;
2343: vbase_types = CLASSTYPE_VBASECLASSES (type);
2344: vbase_decl_ptr = decl_ptr;
2345: vbase_decl = build_indirect_ref (decl_ptr, 0);
2346: vbase_init_result = NULL_TREE;
2347: dfs_walk (binfo, dfs_find_vbases, unmarked3p);
2348: dfs_walk (binfo, dfs_init_vbase_pointers, marked3p);
2349: dfs_walk (binfo, dfs_clear_vbase_slots, marked4p);
2350: flag_this_is_variable = old_flag;
2351: return vbase_init_result;
2352: }
2353: return 0;
2354: }
2355:
2356: /* Build a COMPOUND_EXPR which when expanded will generate the code
2357: needed to initialize all the virtual function table slots of all
2358: the virtual baseclasses. FOR_TYPE is the type which determines the
2359: virtual baseclasses to use; TYPE is the type of the object to which
2360: the initialization applies. TRUE_EXP is the true object we are
2361: initializing, and DECL_PTR is the pointer to the sub-object we
2362: are initializing.
2363:
2364: CTOR_P is non-zero if the caller of this function is a top-level
2365: constructor. It is zero when called from a destructor. When
2366: non-zero, we can use computed offsets to store the vtables. When
2367: zero, we must store new vtables through virtual baseclass pointers. */
2368:
2369: tree
2370: build_vbase_vtables_init (main_binfo, binfo, true_exp, decl_ptr, ctor_p)
2371: tree main_binfo, binfo;
2372: tree true_exp, decl_ptr;
2373: int ctor_p;
2374: {
2375: tree for_type = BINFO_TYPE (main_binfo);
2376: tree type = BINFO_TYPE (binfo);
2377: if (TYPE_USES_VIRTUAL_BASECLASSES (type))
2378: {
2379: int old_flag = flag_this_is_variable;
2380: tree vtable_init_result = NULL_TREE;
2381: tree vbases = CLASSTYPE_VBASECLASSES (type);
2382:
2383: vbase_types = CLASSTYPE_VBASECLASSES (for_type);
2384: vbase_decl_ptr = true_exp ? build_unary_op (ADDR_EXPR, true_exp, 0) : decl_ptr;
2385: vbase_decl = true_exp ? true_exp : build_indirect_ref (decl_ptr, 0);
2386: flag_this_is_variable = 0;
2387:
2388: if (ctor_p)
2389: /* This is an object of type IN_TYPE, */
2390: dfs_walk (main_binfo, dfs_find_vbases, unmarked4p);
2391:
2392: /* Initialized with vtables of type TYPE. */
2393: while (vbases)
2394: {
2395: /* This time through, not every class's vtable
2396: is going to be initialized. That is, we only initialize
2397: the "last" vtable pointer. */
2398:
2399: if (CLASSTYPE_VSIZE (BINFO_TYPE (vbases)))
2400: {
2401: tree addr;
2402: tree vtbl = BINFO_VTABLE (vbases);
2403: tree init = build_unary_op (ADDR_EXPR, vtbl, 0);
2404: TREE_USED (vtbl) = 1;
2405:
2406: if (ctor_p == 0)
2407: addr = convert_pointer_to (vbases, vbase_decl_ptr);
2408: else
2409: addr = (tree)CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (vbases));
2410:
2411: if (addr)
2412: {
2413: tree ref = build_vfield_ref (build_indirect_ref (addr, 0),
2414: BINFO_TYPE (vbases));
2415: init = convert_force (TREE_TYPE (ref), init);
2416: vtable_init_result = tree_cons (NULL_TREE, build_modify_expr (ref, NOP_EXPR, init),
2417: vtable_init_result);
2418: }
2419: }
2420: vbases = TREE_CHAIN (vbases);
2421: }
2422:
2423: dfs_walk (binfo, dfs_clear_vbase_slots, marked4p);
2424:
2425: flag_this_is_variable = old_flag;
2426: if (vtable_init_result)
2427: return build_compound_expr (vtable_init_result);
2428: }
2429: return error_mark_node;
2430: }
2431:
2432: void
2433: clear_search_slots (type)
2434: tree type;
2435: {
2436: dfs_walk (TYPE_BINFO (type),
2437: dfs_clear_search_slot, dfs_search_slot_nonempty_p);
2438: }
2439:
2440: static void
2441: dfs_get_vbase_types (binfo)
2442: tree binfo;
2443: {
2444: int i;
2445: tree binfos = BINFO_BASETYPES (binfo);
2446: tree type = BINFO_TYPE (binfo);
2447: tree these_vbase_types = CLASSTYPE_VBASECLASSES (type);
2448: tree basetype;
2449:
2450: if (these_vbase_types)
2451: {
2452: while (these_vbase_types)
2453: {
2454: tree this_type = BINFO_TYPE (these_vbase_types);
2455:
2456: /* We really need to start from a fresh copy of this
2457: virtual basetype! CLASSTYPE_MARKED2 is the shortcut
2458: for BINFO_VBASE_MARKED. */
2459: if (! CLASSTYPE_MARKED2 (this_type))
2460: {
2461: vbase_types = make_binfo (integer_zero_node,
2462: this_type,
2463: TYPE_BINFO_VTABLE (this_type),
2464: TYPE_BINFO_VIRTUALS (this_type),
2465: vbase_types);
2466: TREE_VIA_VIRTUAL (vbase_types) = 1;
2467: SET_CLASSTYPE_MARKED2 (this_type);
2468: }
2469: these_vbase_types = TREE_CHAIN (these_vbase_types);
2470: }
2471: }
2472: else for (i = binfos ? TREE_VEC_LENGTH (binfos)-1 : -1; i >= 0; i--)
2473: {
2474: tree child = TREE_VEC_ELT (binfos, i);
2475: if (TREE_VIA_VIRTUAL (child) && ! BINFO_VBASE_MARKED (child))
2476: {
2477: vbase_types = make_binfo (integer_zero_node, BINFO_TYPE (child),
2478: BINFO_VTABLE (child),
2479: BINFO_VIRTUALS (child), vbase_types);
2480: TREE_VIA_VIRTUAL (vbase_types) = 1;
2481: SET_BINFO_VBASE_MARKED (child);
2482: }
2483: }
2484: SET_BINFO_MARKED (binfo);
2485: }
2486:
2487: /* Some virtual baseclasses might be virtual baseclasses for
2488: other virtual baseclasses. We sort the virtual baseclasses
2489: topologically: in the list returned, the first virtual base
2490: classes have no virtual baseclasses themselves, and any entry
2491: on the list has no dependency on virtual base classes later in the
2492: list. */
2493: tree
2494: get_vbase_types (type)
2495: tree type;
2496: {
2497: tree ordered_vbase_types = NULL_TREE, prev, next;
2498: tree vbases;
2499:
2500: vbase_types = NULL_TREE;
2501: dfs_walk (TYPE_BINFO (type), dfs_get_vbase_types, unmarkedp);
2502: dfs_walk (TYPE_BINFO (type), dfs_unmark, markedp);
2503:
2504: while (vbase_types)
2505: {
2506: /* Now sort these types. This is essentially a bubble merge. */
2507:
2508: /* Farm out virtual baseclasses which have no marked ancestors. */
2509: for (vbases = vbase_types, prev = NULL_TREE;
2510: vbases; vbases = next)
2511: {
2512: next = TREE_CHAIN (vbases);
2513: /* If VBASES does not have any vbases itself, or it's
2514: topologically safe, it goes into the sorted list. */
2515: if (! CLASSTYPE_VBASECLASSES (BINFO_TYPE (vbases))
2516: || BINFO_VBASE_MARKED (vbases) == 0)
2517: {
2518: if (prev)
2519: TREE_CHAIN (prev) = TREE_CHAIN (vbases);
2520: else
2521: vbase_types = TREE_CHAIN (vbases);
2522: TREE_CHAIN (vbases) = NULL_TREE;
2523: ordered_vbase_types = chainon (ordered_vbase_types, vbases);
2524: CLEAR_BINFO_VBASE_MARKED (vbases);
2525: }
2526: else
2527: prev = vbases;
2528: }
2529:
2530: /* Now unmark types all of whose ancestors are now on the
2531: `ordered_vbase_types' list. */
2532: for (vbases = vbase_types; vbases; vbases = TREE_CHAIN (vbases))
2533: {
2534: /* If all our virtual baseclasses are unmarked, ok. */
2535: tree t = CLASSTYPE_VBASECLASSES (BINFO_TYPE (vbases));
2536: while (t && (BINFO_VBASE_MARKED (t) == 0
2537: || ! CLASSTYPE_VBASECLASSES (BINFO_TYPE (t))))
2538: t = TREE_CHAIN (t);
2539: if (t == NULL_TREE)
2540: CLEAR_BINFO_VBASE_MARKED (vbases);
2541: }
2542: }
2543:
2544: return ordered_vbase_types;
2545: }
2546:
2547: static void
2548: dfs_record_inheritance (binfo)
2549: tree binfo;
2550: {
2551: tree binfos = BINFO_BASETYPES (binfo);
2552: int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
2553: mi_boolean *derived_row = BINFO_DERIVES_FROM_STAR (binfo);
2554:
2555: for (i = n_baselinks-1; i >= 0; i--)
2556: {
2557: int j;
2558: tree child = TREE_VEC_ELT (binfos, i);
2559: tree baseclass = BINFO_TYPE (child);
2560: mi_boolean *base_row = BINFO_DERIVES_FROM_STAR (child);
2561:
2562: /* Don't search if there's nothing there! MI_SIZE can be
2563: zero as a result of parse errors. */
2564: if (TYPE_BINFO_BASETYPES (baseclass) && mi_size > 0)
2565: for (j = mi_size*(CLASSTYPE_CID (baseclass)-1); j >= 0; j -= mi_size)
2566: derived_row[j] |= base_row[j];
2567: TYPE_DERIVES_FROM (baseclass, BINFO_TYPE (binfo)) = 1;
2568: }
2569:
2570: SET_BINFO_MARKED (binfo);
2571: }
2572:
2573: /* Given a _CLASSTYPE node in a multiple inheritance lattice,
2574: convert the lattice into a simple relation such that,
2575: given to CIDs, C1 and C2, one can determine if C1 <= C2
2576: or C2 <= C1 or C1 <> C2.
2577:
2578: Once constructed, we walk the lattice depth fisrt,
2579: applying various functions to elements as they are encountered.
2580:
2581: We use xmalloc here, in case we want to randomly free these tables. */
2582:
2583: #define SAVE_MI_MATRIX
2584:
2585: void
2586: build_mi_matrix (type)
2587: tree type;
2588: {
2589: tree binfo = TYPE_BINFO (type);
2590: cid = 0;
2591:
2592: #ifdef SAVE_MI_MATRIX
2593: if (CLASSTYPE_MI_MATRIX (type))
2594: {
2595: mi_size = CLASSTYPE_N_SUPERCLASSES (type) + CLASSTYPE_N_VBASECLASSES (type);
2596: mi_matrix = CLASSTYPE_MI_MATRIX (type);
2597: mi_type = type;
2598: dfs_walk (binfo, dfs_number, unnumberedp);
2599: return;
2600: }
2601: #endif
2602:
2603: mi_size = CLASSTYPE_N_SUPERCLASSES (type) + CLASSTYPE_N_VBASECLASSES (type);
2604: mi_matrix = (char *)xmalloc ((mi_size+1) * (mi_size+1));
2605: mi_type = type;
2606: bzero (mi_matrix, mi_size * mi_size);
2607: dfs_walk (binfo, dfs_number, unnumberedp);
2608: dfs_walk (binfo, dfs_record_inheritance, unmarkedp);
2609: dfs_walk (binfo, dfs_unmark, markedp);
2610: }
2611:
2612: void
2613: free_mi_matrix ()
2614: {
2615: dfs_walk (TYPE_BINFO (mi_type), dfs_unnumber, numberedp);
2616:
2617: #ifdef SAVE_MI_MATRIX
2618: CLASSTYPE_MI_MATRIX (mi_type) = mi_matrix;
2619: #else
2620: free (mi_matrix);
2621: mi_size = 0;
2622: cid = 0;
2623: #endif
2624: }
2625:
2626: /* Local variables for detecting ambiguities of virtual functions
2627: when two or more classes are joined at a multiple inheritance
2628: seam. */
2629: typedef tree mi_ventry[3];
2630: static mi_ventry *mi_vmatrix;
2631: static int *mi_vmax;
2632: static int mi_vrows, mi_vcols;
2633: #define MI_VMATRIX(ROW,COL) ((mi_vmatrix + (ROW)*mi_vcols)[COL])
2634:
2635: /* Build a table of virtual functions for a multiple-inheritance
2636: structure. Here, there are N base classes, and at most
2637: M entries per class.
2638:
2639: This function does nothing if N is 0 or 1. */
2640: void
2641: build_mi_virtuals (rows, cols)
2642: int rows, cols;
2643: {
2644: if (rows < 2 || cols == 0)
2645: return;
2646: mi_vrows = rows;
2647: mi_vcols = cols;
2648: mi_vmatrix = (mi_ventry *)xmalloc ((rows+1) * cols * sizeof (mi_ventry));
2649: mi_vmax = (int *)xmalloc ((rows+1) * sizeof (int));
2650:
2651: bzero (mi_vmax, rows * sizeof (int));
2652:
2653: /* Row indicies start at 1, so adjust this. */
2654: mi_vmatrix -= cols;
2655: mi_vmax -= 1;
2656: }
2657:
2658: /* Comparison function for ordering virtual function table entries. */
2659: static int
2660: rank_mi_virtuals (v1, v2)
2661: mi_ventry *v1, *v2;
2662: {
2663: tree p1, p2;
2664: int i;
2665:
2666: i = ((long) (DECL_NAME ((*v1)[0])) - (long) (DECL_NAME ((*v2)[0])));
2667: if (i)
2668: return i;
2669: p1 = (*v1)[1];
2670: p2 = (*v2)[1];
2671:
2672: if (p1 == p2)
2673: return 0;
2674:
2675: while (p1 && p2)
2676: {
2677: i = ((long) (TREE_VALUE (p1)) - (long) (TREE_VALUE (p2)));
2678: if (i)
2679: return i;
2680:
2681: if (TREE_CHAIN (p1))
2682: {
2683: if (! TREE_CHAIN (p2))
2684: return 1;
2685: p1 = TREE_CHAIN (p1);
2686: p2 = TREE_CHAIN (p2);
2687: }
2688: else if (TREE_CHAIN (p2))
2689: return -1;
2690: else
2691: {
2692: /* When matches of argument lists occur, pick lowest
2693: address to keep searching time to a minimum on
2694: later passes--like hashing, only different.
2695: *MUST BE STABLE*. */
2696: if ((long) ((*v2)[1]) < (long) ((*v1)[1]))
2697: (*v1)[1] = (*v2)[1];
2698: else
2699: (*v2)[1] = (*v1)[1];
2700: return 0;
2701: }
2702: }
2703: return 0;
2704: }
2705:
2706: /* Install the virtuals functions got from the initializer VIRTUALS to
2707: the table at index ROW. */
2708: void
2709: add_mi_virtuals (row, virtuals)
2710: int row;
2711: tree virtuals;
2712: {
2713: int col = 0;
2714:
2715: if (mi_vmatrix == 0)
2716: return;
2717: while (virtuals)
2718: {
2719: tree decl = TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals)), 0);
2720: MI_VMATRIX (row, col)[0] = decl;
2721: MI_VMATRIX (row, col)[1] = FUNCTION_ARG_CHAIN (decl);
2722: MI_VMATRIX (row, col)[2] = TREE_VALUE (virtuals);
2723: virtuals = TREE_CHAIN (virtuals);
2724: col += 1;
2725: }
2726: mi_vmax[row] = col;
2727:
2728: qsort (mi_vmatrix + row * mi_vcols,
2729: col,
2730: sizeof (mi_ventry),
2731: rank_mi_virtuals);
2732: }
2733:
2734: /* If joining two types results in an ambiguity in the virtual
2735: function table, report such here. */
2736: void
2737: report_ambiguous_mi_virtuals (rows, type)
2738: int rows;
2739: tree type;
2740: {
2741: int *mi_vmin;
2742: int row1, col1, row, col;
2743:
2744: if (mi_vmatrix == 0)
2745: return;
2746:
2747: /* Now virtuals are all sorted, so we merge to find ambiguous cases. */
2748: mi_vmin = (int *)alloca ((rows+1) * sizeof (int));
2749: bzero (mi_vmin, rows * sizeof (int));
2750:
2751: /* adjust. */
2752: mi_vmin -= 1;
2753:
2754: /* For each base class with virtual functions (and this includes views
2755: of the virtual baseclasses from different base classes), see that
2756: each virtual function in that base class has a unique meet.
2757:
2758: When the column loop is finished, THIS_DECL is in fact the meet.
2759: If that value does not appear in the virtual function table for
2760: the row, install it. This happens when that virtual function comes
2761: from a virtual baseclass, or a non-leftmost baseclass. */
2762:
2763: for (row1 = 1; row1 < rows; row1++)
2764: {
2765: tree this_decl = 0;
2766:
2767: for (col1 = mi_vmax[row1]-1; col1 >= mi_vmin[row1]; col1--)
2768: {
2769: tree these_args = MI_VMATRIX (row1, col1)[1];
2770: tree this_context;
2771:
2772: this_decl = MI_VMATRIX (row1, col1)[0];
2773: if (this_decl == 0)
2774: continue;
2775: this_context = TYPE_BINFO (DECL_CLASS_CONTEXT (this_decl));
2776:
2777: if (this_context != TYPE_BINFO (type))
2778: this_context = get_binfo (this_context, type, 0);
2779:
2780: for (row = row1+1; row <= rows; row++)
2781: for (col = mi_vmax[row]-1; col >= mi_vmin[row]; col--)
2782: {
2783: mi_ventry this_entry;
2784:
2785: if (MI_VMATRIX (row, col)[0] == 0)
2786: continue;
2787:
2788: this_entry[0] = this_decl;
2789: this_entry[1] = these_args;
2790: this_entry[2] = MI_VMATRIX (row1, col1)[2];
2791: if (rank_mi_virtuals (this_entry, MI_VMATRIX (row, col)) == 0)
2792: {
2793: /* They are equal. There are four possibilities:
2794:
2795: (1) Derived class is defining this virtual function.
2796: (2) Two paths to the same virtual function in the
2797: same base class.
2798: (3) A path to a virtual function declared in one base
2799: class, and another path to a virtual function in a
2800: base class of the base class.
2801: (4) Two paths to the same virtual function in different
2802: base classes.
2803:
2804: The first three cases are ok (non-ambiguous). */
2805:
2806: tree that_context, tmp;
2807: int this_before_that;
2808:
2809: if (type == BINFO_TYPE (this_context))
2810: /* case 1. */
2811: goto ok;
2812: that_context = get_binfo (DECL_CLASS_CONTEXT (MI_VMATRIX (row, col)[0]), type, 0);
2813: if (that_context == this_context)
2814: /* case 2. */
2815: goto ok;
2816: if (that_context != NULL_TREE)
2817: {
2818: tmp = get_binfo (that_context, this_context, 0);
2819: this_before_that = (that_context != tmp);
2820: if (this_before_that == 0)
2821: /* case 3a. */
2822: goto ok;
2823: tmp = get_binfo (this_context, that_context, 0);
2824: this_before_that = (this_context == tmp);
2825: if (this_before_that != 0)
2826: /* case 3b. */
2827: goto ok;
2828:
2829: /* case 4. */
2830: error_with_decl (MI_VMATRIX (row, col)[0], "ambiguous virtual function `%s'");
2831: error_with_decl (this_decl, "ambiguating function `%s' (joined by type `%s')", IDENTIFIER_POINTER (current_class_name));
2832: }
2833: ok:
2834: MI_VMATRIX (row, col)[0] = 0;
2835:
2836: /* Let zeros propagate. */
2837: if (col == mi_vmax[row]-1)
2838: {
2839: int i = col;
2840: while (i >= mi_vmin[row]
2841: && MI_VMATRIX (row, i)[0] == 0)
2842: i--;
2843: mi_vmax[row] = i+1;
2844: }
2845: else if (col == mi_vmin[row])
2846: {
2847: int i = col;
2848: while (i < mi_vmax[row]
2849: && MI_VMATRIX (row, i)[0] == 0)
2850: i++;
2851: mi_vmin[row] = i;
2852: }
2853: }
2854: }
2855: }
2856: }
2857: free (mi_vmatrix + mi_vcols);
2858: mi_vmatrix = 0;
2859: free (mi_vmax + 1);
2860: mi_vmax = 0;
2861: }
2862:
2863: /* If we want debug info for a type TYPE, make sure all its base types
2864: are also marked as being potentially interesting. This avoids
2865: the problem of not writing any debug info for intermediate basetypes
2866: that have abstract virtual functions. */
2867:
2868: void
2869: note_debug_info_needed (type)
2870: tree type;
2871: {
2872: dfs_walk (TYPE_BINFO (type), dfs_debug_mark, dfs_debug_unmarkedp);
2873: }
2874:
2875: /* Subroutines of push_class_decls (). */
2876:
2877: /* Add the instance variables which this class contributed to the
2878: current class binding contour. When a redefinition occurs,
2879: if the redefinition is strictly within a single inheritance path,
2880: we just overwrite (in the case of a data field) or
2881: cons (in the case of a member function) the old declaration with
2882: the new. If the fields are not within a single inheritance path,
2883: we must cons them in either case. */
2884:
2885: static void
2886: dfs_pushdecls (binfo)
2887: tree binfo;
2888: {
2889: tree type = BINFO_TYPE (binfo);
2890: tree fields, *methods, *end;
2891: tree method_vec;
2892:
2893: for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields))
2894: {
2895: /* Unmark so that if we are in a constructor, and then find that
2896: this field was initialized by a base initializer,
2897: we can emit an error message. */
2898: if (TREE_CODE (fields) == FIELD_DECL)
2899: TREE_USED (fields) = 0;
2900:
2901: if (DECL_NAME (fields) == NULL_TREE
2902: && TREE_CODE (TREE_TYPE (fields)) == UNION_TYPE)
2903: {
2904: dfs_pushdecls (TYPE_BINFO (TREE_TYPE (fields)));
2905: continue;
2906: }
2907: if (TREE_CODE (fields) != TYPE_DECL)
2908: {
2909: DECL_PUBLIC (fields) = 0;
2910: DECL_PROTECTED (fields) = 0;
2911: DECL_PRIVATE (fields) = 0;
2912: }
2913:
2914: if (DECL_NAME (fields))
2915: {
2916: tree value = IDENTIFIER_CLASS_VALUE (DECL_NAME (fields));
2917: if (value)
2918: {
2919: tree context;
2920:
2921: /* Possible ambiguity. If its defining type(s)
2922: is (are all) derived from us, no problem. */
2923:
2924: if (TREE_CODE (value) != TREE_LIST)
2925: {
2926: context = DECL_CLASS_CONTEXT (value);
2927:
2928: if (context == type || TYPE_DERIVES_FROM (context, type))
2929: value = fields;
2930: else
2931: value = tree_cons (NULL_TREE, fields,
2932: build_tree_list (NULL_TREE, value));
2933: }
2934: else
2935: {
2936: /* All children may derive from us, in which case
2937: there is no problem. Otherwise, we have to
2938: keep lists around of what the ambiguities might be. */
2939: tree values;
2940: int problem = 0;
2941:
2942: for (values = value; values; values = TREE_CHAIN (values))
2943: {
2944: tree sub_values = TREE_VALUE (values);
2945:
2946: if (TREE_CODE (sub_values) == TREE_LIST)
2947: {
2948: for (; sub_values; sub_values = TREE_CHAIN (sub_values))
2949: {
2950: context = DECL_CLASS_CONTEXT (TREE_VALUE (sub_values));
2951:
2952: if (! TYPE_DERIVES_FROM (context, type))
2953: {
2954: value = tree_cons (NULL_TREE, TREE_VALUE (values), value);
2955: problem = 1;
2956: break;
2957: }
2958: }
2959: }
2960: else
2961: {
2962: context = DECL_CLASS_CONTEXT (sub_values);
2963:
2964: if (! TYPE_DERIVES_FROM (context, type))
2965: {
2966: value = tree_cons (NULL_TREE, values, value);
2967: problem = 1;
2968: break;
2969: }
2970: }
2971: }
2972: if (! problem) value = fields;
2973: }
2974:
2975: /* Mark this as a potentially ambiguous member. */
2976: if (TREE_CODE (value) == TREE_LIST)
2977: {
2978: /* Leaving TREE_TYPE blank is intentional.
2979: We cannot use `error_mark_node' (lookup_name)
2980: or `unknown_type_node' (all member functions use this). */
2981: TREE_NONLOCAL_FLAG (value) = 1;
2982: }
2983:
2984: IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) = value;
2985: }
2986: else IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) = fields;
2987: }
2988: }
2989:
2990: method_vec = CLASSTYPE_METHOD_VEC (type);
2991: if (method_vec != 0)
2992: {
2993: /* Farm out constructors and destructors. */
2994: methods = &TREE_VEC_ELT (method_vec, 1);
2995: end = TREE_VEC_END (method_vec);
2996:
2997: /* This does not work for multiple inheritance yet. */
2998: while (methods != end)
2999: {
3000: /* This will cause lookup_name to return a pointer
3001: to the tree_list of possible methods of this name.
3002: If the order is a problem, we can nreverse them. */
3003: tree tmp;
3004: tree old = IDENTIFIER_CLASS_VALUE (DECL_NAME (*methods));
3005:
3006: if (old && TREE_CODE (old) == TREE_LIST)
3007: tmp = tree_cons (DECL_NAME (*methods), *methods, old);
3008: else
3009: {
3010: /* Only complain if we shadow something we can access. */
3011: if (old && (DECL_CLASS_CONTEXT (old) == current_class_type
3012: || ! TREE_PRIVATE (old)))
3013: /* Should figure out visibility more accurately. */
3014: warning ("shadowing member `%s' with member function",
3015: IDENTIFIER_POINTER (DECL_NAME (*methods)));
3016: tmp = build_tree_list (DECL_NAME (*methods), *methods);
3017: }
3018:
3019: TREE_TYPE (tmp) = unknown_type_node;
3020: #if 0
3021: TREE_OVERLOADED (tmp) = DECL_OVERLOADED (*methods);
3022: #endif
3023: TREE_NONLOCAL_FLAG (tmp) = 1;
3024: IDENTIFIER_CLASS_VALUE (DECL_NAME (*methods)) = tmp;
3025:
3026: tmp = *methods;
3027: while (tmp != 0)
3028: {
3029: DECL_PUBLIC (tmp) = 0;
3030: DECL_PROTECTED (tmp) = 0;
3031: DECL_PRIVATE (tmp) = 0;
3032: tmp = DECL_CHAIN (tmp);
3033: }
3034:
3035: methods++;
3036: }
3037: }
3038: SET_BINFO_MARKED (binfo);
3039: }
3040:
3041: /* Consolidate unique (by name) member functions. */
3042: static void
3043: dfs_compress_decls (binfo)
3044: tree binfo;
3045: {
3046: tree type = BINFO_TYPE (binfo);
3047: tree method_vec = CLASSTYPE_METHOD_VEC (type);
3048:
3049: if (method_vec != 0)
3050: {
3051: /* Farm out constructors and destructors. */
3052: tree *methods = &TREE_VEC_ELT (method_vec, 1);
3053: tree *end = TREE_VEC_END (method_vec);
3054:
3055: for (; methods != end; methods++)
3056: {
3057: tree tmp = IDENTIFIER_CLASS_VALUE (DECL_NAME (*methods));
3058:
3059: /* This was replaced in scope by somebody else. Just leave it
3060: alone. */
3061: if (TREE_CODE (tmp) != TREE_LIST)
3062: continue;
3063:
3064: if (TREE_CHAIN (tmp) == NULL_TREE
3065: && TREE_VALUE (tmp)
3066: && DECL_CHAIN (TREE_VALUE (tmp)) == NULL_TREE)
3067: {
3068: IDENTIFIER_CLASS_VALUE (DECL_NAME (*methods)) = TREE_VALUE (tmp);
3069: }
3070: }
3071: }
3072: CLEAR_BINFO_MARKED (binfo);
3073: }
3074:
3075: /* When entering the scope of a class, we cache all of the
3076: fields that that class provides within its inheritance
3077: lattice. Where ambiguities result, we mark them
3078: with `error_mark_node' so that if they are encountered
3079: without explicit qualification, we can emit an error
3080: message. */
3081: void
3082: push_class_decls (type)
3083: tree type;
3084: {
3085: tree id;
3086: struct obstack *ambient_obstack = current_obstack;
3087:
3088: #if 0
3089: tree tags = CLASSTYPE_TAGS (type);
3090:
3091: while (tags)
3092: {
3093: tree code_type_node;
3094: tree tag;
3095:
3096: switch (TREE_CODE (TREE_VALUE (tags)))
3097: {
3098: case ENUMERAL_TYPE:
3099: code_type_node = enum_type_node;
3100: break;
3101: case RECORD_TYPE:
3102: code_type_node = record_type_node;
3103: break;
3104: case CLASS_TYPE:
3105: code_type_node = class_type_node;
3106: break;
3107: case UNION_TYPE:
3108: code_type_node = union_type_node;
3109: break;
3110: default:
3111: assert (0);
3112: }
3113: tag = xref_tag (code_type_node, TREE_PURPOSE (tags),
3114: TYPE_BINFO_BASETYPE (TREE_VALUE (tags), 0));
3115: pushdecl (build_decl (TYPE_DECL, TREE_PURPOSE (tags), TREE_VALUE (tags)));
3116: }
3117: #endif
3118:
3119: current_obstack = &bridge_obstack;
3120: search_stack = push_search_level (search_stack, &bridge_obstack);
3121:
3122: id = DECL_NAME (TYPE_NAME (type));
3123: if (IDENTIFIER_TEMPLATE (id) != 0)
3124: {
3125: #if 0
3126: tree tmpl = IDENTIFIER_TEMPLATE (id);
3127: push_template_decls (DECL_ARGUMENTS (TREE_PURPOSE (tmpl)),
3128: TREE_VALUE (tmpl), 1);
3129: #endif
3130: overload_template_name (id, 0);
3131: }
3132:
3133: /* Push class fields into CLASS_VALUE scope, and mark. */
3134: dfs_walk (TYPE_BINFO (type), dfs_pushdecls, unmarkedp);
3135:
3136: /* Compress fields which have only a single entry
3137: by a given name, and unmark. */
3138: dfs_walk (TYPE_BINFO (type), dfs_compress_decls, markedp);
3139: current_obstack = ambient_obstack;
3140: }
3141:
3142: static void
3143: dfs_popdecls (binfo)
3144: tree binfo;
3145: {
3146: tree type = BINFO_TYPE (binfo);
3147: tree fields = TYPE_FIELDS (type);
3148: tree method_vec = CLASSTYPE_METHOD_VEC (type);
3149:
3150: while (fields)
3151: {
3152: if (DECL_NAME (fields) == NULL_TREE
3153: && TREE_CODE (TREE_TYPE (fields)) == UNION_TYPE)
3154: {
3155: dfs_popdecls (TYPE_BINFO (TREE_TYPE (fields)));
3156: }
3157: else if (DECL_NAME (fields))
3158: IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) = NULL_TREE;
3159: fields = TREE_CHAIN (fields);
3160: }
3161: if (method_vec != 0)
3162: {
3163: tree *methods = &TREE_VEC_ELT (method_vec, 0);
3164: tree *end = TREE_VEC_END (method_vec);
3165:
3166: /* Clear out ctors and dtors. */
3167: if (*methods)
3168: IDENTIFIER_CLASS_VALUE (DECL_NAME (TYPE_NAME (type))) = NULL_TREE;
3169:
3170: for (methods += 1; methods != end; methods++)
3171: IDENTIFIER_CLASS_VALUE (DECL_NAME (*methods)) = NULL_TREE;
3172: }
3173:
3174: SET_BINFO_MARKED (binfo);
3175: }
3176:
3177: void
3178: pop_class_decls (type)
3179: tree type;
3180: {
3181: tree binfo = TYPE_BINFO (type);
3182:
3183: /* Clear out the IDENTIFIER_CLASS_VALUE which this
3184: class may have occupied, and mark. */
3185: dfs_walk (binfo, dfs_popdecls, unmarkedp);
3186:
3187: /* Unmark. */
3188: dfs_walk (binfo, dfs_unmark, markedp);
3189:
3190: #if 0
3191: tmpl = IDENTIFIER_TEMPLATE (DECL_NAME (TYPE_NAME (type)));
3192: if (tmpl != 0)
3193: pop_template_decls (DECL_ARGUMENTS (TREE_PURPOSE (tmpl)),
3194: TREE_VALUE (tmpl), 1);
3195: #endif
3196:
3197: search_stack = pop_search_level (search_stack);
3198: }
3199:
3200: /* Given a base type PARENT, and a derived type TYPE, build
3201: a name which distinguishes exactly the PARENT member of TYPE's type.
3202:
3203: FORMAT is a string which controls how sprintf formats the name
3204: we have generated.
3205:
3206: For example, given
3207:
3208: class A; class B; class C : A, B;
3209:
3210: it is possible to distinguish "A" from "C's A". And given
3211:
3212: class L;
3213: class A : L; class B : L; class C : A, B;
3214:
3215: it is possible to distinguish "L" from "A's L", and also from
3216: "C's L from A". */
3217: tree
3218: build_type_pathname (format, parent, type)
3219: char *format;
3220: tree parent, type;
3221: {
3222: extern struct obstack temporary_obstack;
3223: char *first, *base, *name;
3224: int i;
3225: tree id;
3226:
3227: parent = TYPE_MAIN_VARIANT (parent);
3228:
3229: /* Remember where to cut the obstack to. */
3230: first = obstack_base (&temporary_obstack);
3231:
3232: /* Put on TYPE+PARENT. */
3233: obstack_grow (&temporary_obstack,
3234: TYPE_NAME_STRING (type), TYPE_NAME_LENGTH (type));
3235: obstack_1grow (&temporary_obstack, JOINER);
3236: obstack_grow0 (&temporary_obstack,
3237: TYPE_NAME_STRING (parent), TYPE_NAME_LENGTH (parent));
3238: i = obstack_object_size (&temporary_obstack);
3239: base = obstack_base (&temporary_obstack);
3240: obstack_finish (&temporary_obstack);
3241:
3242: /* Put on FORMAT+TYPE+PARENT. */
3243: obstack_blank (&temporary_obstack, strlen (format) + i + 1);
3244: name = obstack_base (&temporary_obstack);
3245: sprintf (name, format, base);
3246: id = get_identifier (name);
3247: obstack_free (&temporary_obstack, first);
3248:
3249: return id;
3250: }
3251:
3252: static int
3253: bfs_unmark_finished_struct (binfo, i)
3254: tree binfo;
3255: int i;
3256: {
3257: if (i >= 0)
3258: binfo = BINFO_BASETYPE (binfo, i);
3259:
3260: if (BINFO_NEW_VTABLE_MARKED (binfo))
3261: {
3262: tree decl, context;
3263:
3264: if (TREE_VIA_VIRTUAL (binfo))
3265: binfo = binfo_member (BINFO_TYPE (binfo),
3266: CLASSTYPE_VBASECLASSES (current_class_type));
3267:
3268: decl = BINFO_VTABLE (binfo);
3269: context = DECL_CONTEXT (decl);
3270: DECL_CONTEXT (decl) = 0;
3271: if (write_virtuals >= 0
3272: && DECL_INITIAL (decl) != BINFO_VIRTUALS (binfo))
3273: DECL_INITIAL (decl) = build_nt (CONSTRUCTOR, NULL_TREE,
3274: BINFO_VIRTUALS (binfo));
3275: finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0);
3276: DECL_CONTEXT (decl) = context;
3277: }
3278: CLEAR_BINFO_VTABLE_PATH_MARKED (binfo);
3279: CLEAR_BINFO_NEW_VTABLE_MARKED (binfo);
3280: return 0;
3281: }
3282:
3283: void
3284: unmark_finished_struct (type)
3285: tree type;
3286: {
3287: tree binfo = TYPE_BINFO (type);
3288: bfs_unmark_finished_struct (binfo, -1);
3289: breadth_first_search (binfo, bfs_unmark_finished_struct, bfs_marked3p);
3290: }
3291:
3292: void
3293: print_search_statistics ()
3294: {
3295: #ifdef GATHER_STATISTICS
3296: if (flag_memoize_lookups)
3297: {
3298: fprintf (stderr, "%d memoized contexts saved\n",
3299: n_contexts_saved);
3300: fprintf (stderr, "%d local tree nodes made\n", my_tree_node_counter);
3301: fprintf (stderr, "%d local hash nodes made\n", my_memoized_entry_counter);
3302: fprintf (stderr, "fields statistics:\n");
3303: fprintf (stderr, " memoized finds = %d; rejects = %d; (searches = %d)\n",
3304: memoized_fast_finds[0], memoized_fast_rejects[0],
3305: memoized_fields_searched[0]);
3306: fprintf (stderr, " memoized_adds = %d\n", memoized_adds[0]);
3307: fprintf (stderr, "fnfields statistics:\n");
3308: fprintf (stderr, " memoized finds = %d; rejects = %d; (searches = %d)\n",
3309: memoized_fast_finds[1], memoized_fast_rejects[1],
3310: memoized_fields_searched[1]);
3311: fprintf (stderr, " memoized_adds = %d\n", memoized_adds[1]);
3312: }
3313: fprintf (stderr, "%d fields searched in %d[%d] calls to lookup_field[_1]\n",
3314: n_fields_searched, n_calls_lookup_field, n_calls_lookup_field_1);
3315: fprintf (stderr, "%d fnfields searched in %d calls to lookup_fnfields\n",
3316: n_outer_fields_searched, n_calls_lookup_fnfields);
3317: fprintf (stderr, "%d calls to get_base_type\n", n_calls_get_base_type);
3318: #else
3319: fprintf (stderr, "no search statistics\n");
3320: #endif
3321: }
3322:
3323: void
3324: init_search_processing ()
3325: {
3326: gcc_obstack_init (&search_obstack);
3327: gcc_obstack_init (&type_obstack);
3328: gcc_obstack_init (&type_obstack_entries);
3329: gcc_obstack_init (&bridge_obstack);
3330:
3331: /* This gives us room to build our chains of basetypes,
3332: whether or not we decide to memoize them. */
3333: type_stack = push_type_level (0, &type_obstack);
3334: _vptr_name = get_identifier ("_vptr");
3335: }
3336:
3337: tree
3338: get_wrapper (type)
3339: tree type;
3340: {
3341: tree wrap_type;
3342: char *name;
3343: assert (IS_AGGR_TYPE (type));
3344: wrap_type = TYPE_WRAP_TYPE (type);
3345: name = (char *)alloca (TYPE_NAME_LENGTH (wrap_type)
3346: + strlen (WRAPPER_NAME_FORMAT));
3347: sprintf (name, WRAPPER_NAME_FORMAT, TYPE_NAME_STRING (wrap_type));
3348: return lookup_fnfields (TYPE_BINFO (wrap_type),
3349: get_identifier (name), 0);
3350: }
3351:
3352: void
3353: reinit_search_statistics ()
3354: {
3355: my_memoized_entry_counter = 0;
3356: memoized_fast_finds[0] = 0;
3357: memoized_fast_finds[1] = 0;
3358: memoized_adds[0] = 0;
3359: memoized_adds[1] = 0;
3360: memoized_fast_rejects[0] = 0;
3361: memoized_fast_rejects[1] = 0;
3362: memoized_fields_searched[0] = 0;
3363: memoized_fields_searched[1] = 0;
3364: n_fields_searched = 0;
3365: n_calls_lookup_field = 0, n_calls_lookup_field_1 = 0;
3366: n_calls_lookup_fnfields = 0, n_calls_lookup_fnfields_1 = 0;
3367: n_calls_get_base_type = 0;
3368: n_outer_fields_searched = 0;
3369: n_contexts_saved = 0;
3370: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.