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