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