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