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