|
|
1.1 root 1: /* Functions dealing with signatures and signature pointers/references. 1.1.1.2 ! root 2: Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. 1.1 root 3: Contributed by Gerald Baumgartner ([email protected]) 4: 5: This file is part of GNU CC. 6: 7: GNU CC is free software; you can redistribute it and/or modify 8: it under the terms of the GNU General Public License as published by 9: the Free Software Foundation; either version 2, or (at your option) 10: any later version. 11: 12: GNU CC is distributed in the hope that it will be useful, 13: but WITHOUT ANY WARRANTY; without even the implied warranty of 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15: GNU General Public License for more details. 16: 17: You should have received a copy of the GNU General Public License 18: along with GNU CC; see the file COPYING. If not, write to 1.1.1.2 ! root 19: the Free Software Foundation, 59 Temple Place - Suite 330, ! 20: Boston, MA 02111-1307, USA. */ 1.1 root 21: 22: 23: #include "config.h" 24: #include <stdio.h> 25: #include "obstack.h" 26: #include "tree.h" 27: #include "cp-tree.h" 28: #include "flags.h" 29: #include "assert.h" 30: 31: extern struct obstack *current_obstack; 32: extern struct obstack permanent_obstack; 33: extern struct obstack *saveable_obstack; 34: 35: extern void error (); 36: extern void sorry (); 37: extern void compiler_error (); 38: extern void make_decl_rtl PROTO((tree, char *, int)); 39: 40: /* Used to help generate globally unique names for signature tables. */ 41: 42: static int global_sigtable_name_counter; 43: 44: /* Build an identifier for a signature pointer or reference, so we 45: can use it's name in function name mangling. */ 46: 47: static tree 48: build_signature_pointer_or_reference_name (to_type, constp, volatilep, refp) 49: tree to_type; 50: int constp, volatilep, refp; 51: { 52: char * sig_name = TYPE_NAME_STRING (to_type); 53: int name_len = TYPE_NAME_LENGTH (to_type) + constp + volatilep; 54: char * name; 55: 56: if (refp) 57: { 58: name = (char *) alloca (name_len + sizeof (SIGNATURE_REFERENCE_NAME) +2); 59: sprintf (name, SIGNATURE_REFERENCE_NAME_FORMAT, 60: constp ? "C" : "", volatilep ? "V": "", sig_name); 61: } 62: else 63: { 64: name = (char *) alloca (name_len + sizeof (SIGNATURE_POINTER_NAME) + 2); 65: sprintf (name, SIGNATURE_POINTER_NAME_FORMAT, 66: constp ? "C" : "", volatilep ? "V": "", sig_name); 67: } 68: return get_identifier (name); 69: } 70: 71: /* Build a DECL node for a signature pointer or reference, so we can 72: tell the debugger the structure of signature pointers/references. 73: This function is called at most eight times for a given signature, 74: once for each [const] [volatile] signature pointer/reference. */ 75: 76: static void 77: build_signature_pointer_or_reference_decl (type, name) 78: tree type, name; 79: { 80: tree decl; 81: 82: /* We don't enter this declaration in any sort of symbol table. */ 83: decl = build_decl (TYPE_DECL, name, type); 84: TYPE_NAME (type) = decl; 85: TREE_CHAIN (type) = decl; 86: } 87: 88: /* Construct, lay out and return the type of pointers or references 89: to signature TO_TYPE. If such a type has already been constructed, 90: reuse it. If CONSTP or VOLATILEP is specified, make the `optr' const 91: or volatile, respectively. If we are constructing a const/volatile 92: type variant and the main type variant doesn't exist yet, it is built 93: as well. If REFP is 1, we construct a signature reference, otherwise 94: a signature pointer is constructed. 95: 96: This function is a subroutine of `build_signature_pointer_type' and 97: `build_signature_reference_type'. */ 98: 99: static tree 100: build_signature_pointer_or_reference_type (to_type, constp, volatilep, refp) 101: tree to_type; 102: int constp, volatilep, refp; 103: { 104: register tree t, m; 105: register struct obstack *ambient_obstack = current_obstack; 106: register struct obstack *ambient_saveable_obstack = saveable_obstack; 107: 108: m = refp ? SIGNATURE_REFERENCE_TO (to_type) : SIGNATURE_POINTER_TO (to_type); 109: 110: /* If we don't have the main variant yet, construct it. */ 111: if (m == NULL_TREE 112: && (constp || volatilep)) 113: m = build_signature_pointer_or_reference_type (to_type, 0, 0, refp); 114: 115: /* Treat any nonzero argument as 1. */ 116: constp = !!constp; 117: volatilep = !!volatilep; 118: refp = !!refp; 119: 120: /* If not generating auxiliary info, search the chain of variants to see 121: if there is already one there just like the one we need to have. If so, 122: use that existing one. 123: 124: We don't do this in the case where we are generating aux info because 125: in that case we want each typedef names to get it's own distinct type 126: node, even if the type of this new typedef is the same as some other 127: (existing) type. */ 128: 129: if (m && !flag_gen_aux_info) 130: for (t = m; t; t = TYPE_NEXT_VARIANT (t)) 131: if (constp == TYPE_READONLY (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (t)))) 132: && volatilep == TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (t))))) 133: return t; 134: 135: /* We need a new one. If TO_TYPE is permanent, make this permanent too. */ 136: if (TREE_PERMANENT (to_type)) 137: { 138: current_obstack = &permanent_obstack; 139: saveable_obstack = &permanent_obstack; 140: } 141: 142: /* A signature pointer or reference to a signature `s' looks like this: 143: 144: struct { 145: void * optr; 146: const s * sptr; 147: }; 148: 149: A `const' signature pointer/reference is a 150: 151: struct { 152: const void * optr; 153: const s * sptr; 154: }; 155: 156: Similarly, for `volatile' and `const volatile'. 157: */ 158: 159: t = make_lang_type (RECORD_TYPE); 160: { 161: tree obj_type = build_type_variant (void_type_node, constp, volatilep); 162: tree optr_type = build_pointer_type (obj_type); 1.1.1.2 ! root 163: tree optr, sptr; 1.1 root 164: 165: optr = build_lang_field_decl (FIELD_DECL, 166: get_identifier (SIGNATURE_OPTR_NAME), 167: optr_type); 168: DECL_FIELD_CONTEXT (optr) = t; 169: DECL_CLASS_CONTEXT (optr) = t; 170: 171: if (m) 1.1.1.2 ! root 172: /* We can share the `sptr' field among type variants. */ ! 173: sptr = TREE_CHAIN (TYPE_FIELDS (m)); 1.1 root 174: else 175: { 176: tree sig_tbl_type = cp_build_type_variant (to_type, 1, 0); 177: 178: sptr = build_lang_field_decl (FIELD_DECL, 179: get_identifier (SIGNATURE_SPTR_NAME), 180: build_pointer_type (sig_tbl_type)); 181: DECL_FIELD_CONTEXT (sptr) = t; 182: DECL_CLASS_CONTEXT (sptr) = t; 1.1.1.2 ! root 183: TREE_CHAIN (sptr) = NULL_TREE; 1.1 root 184: } 185: 186: TREE_CHAIN (optr) = sptr; 187: TYPE_FIELDS (t) = optr; 188: TYPE_ALIGN (t) = TYPE_ALIGN (optr_type); 1.1.1.2 ! root 189: ! 190: /* A signature pointer/reference type isn't a `real' class type. */ ! 191: IS_AGGR_TYPE (t) = 0; 1.1 root 192: } 193: 194: { 195: tree name = build_signature_pointer_or_reference_name (to_type, constp, 196: volatilep, refp); 197: 198: /* Build a DECL node for this type, so the debugger has access to it. */ 199: build_signature_pointer_or_reference_decl (t, name); 200: } 201: 202: CLASSTYPE_GOT_SEMICOLON (t) = 1; 203: IS_SIGNATURE_POINTER (t) = ! refp; 204: IS_SIGNATURE_REFERENCE (t) = refp; 205: SIGNATURE_TYPE (t) = to_type; 206: 207: if (m) 208: { 209: /* Add this type to the chain of variants of TYPE. 210: Every type has to be its own TYPE_MAIN_VARIANT. */ 211: TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m); 212: TYPE_NEXT_VARIANT (m) = t; 213: } 214: else if (refp) 215: /* Record this type as the reference to TO_TYPE. */ 216: SIGNATURE_REFERENCE_TO (to_type) = t; 217: else 218: /* Record this type as the pointer to TO_TYPE. */ 219: SIGNATURE_POINTER_TO (to_type) = t; 220: 221: /* Lay out the type. This function has many callers that are concerned 222: with expression-construction, and this simplifies them all. 223: Also, it guarantees the TYPE_SIZE is permanent if the type is. */ 224: layout_type (t); 225: 226: current_obstack = ambient_obstack; 227: saveable_obstack = ambient_saveable_obstack; 228: 1.1.1.2 ! root 229: /* Output debug information for this type. */ 1.1 root 230: rest_of_type_compilation (t, 1); 231: 232: return t; 233: } 234: 235: /* Construct, lay out and return the type of pointers to signature TO_TYPE. */ 236: 237: tree 238: build_signature_pointer_type (to_type, constp, volatilep) 239: tree to_type; 240: int constp, volatilep; 241: { 242: return 243: build_signature_pointer_or_reference_type (to_type, constp, volatilep, 0); 244: } 245: 246: /* Construct, lay out and return the type of pointers to signature TO_TYPE. */ 247: 248: tree 249: build_signature_reference_type (to_type, constp, volatilep) 250: tree to_type; 251: int constp, volatilep; 252: { 253: return 254: build_signature_pointer_or_reference_type (to_type, constp, volatilep, 1); 255: } 256: 257: /* Return the name of the signature table (as an IDENTIFIER_NODE) 258: for the given signature type SIG_TYPE and rhs type RHS_TYPE. */ 259: 260: static tree 261: get_sigtable_name (sig_type, rhs_type) 262: tree sig_type, rhs_type; 263: { 264: tree sig_type_id = build_typename_overload (sig_type); 265: tree rhs_type_id = build_typename_overload (rhs_type); 266: char *buf = (char *) alloca (sizeof (SIGTABLE_NAME_FORMAT_LONG) 267: + IDENTIFIER_LENGTH (sig_type_id) 268: + IDENTIFIER_LENGTH (rhs_type_id) + 20); 269: char *sig_ptr = IDENTIFIER_POINTER (sig_type_id); 270: char *rhs_ptr = IDENTIFIER_POINTER (rhs_type_id); 271: int i, j; 272: 273: for (i = 0; sig_ptr[i] == OPERATOR_TYPENAME_FORMAT[i]; i++) 274: /* do nothing */; 275: while (sig_ptr[i] >= '0' && sig_ptr[i] <= '9') 276: i += 1; 277: 278: for (j = 0; rhs_ptr[j] == OPERATOR_TYPENAME_FORMAT[j]; j++) 279: /* do nothing */; 280: while (rhs_ptr[j] >= '0' && rhs_ptr[j] <= '9') 281: j += 1; 282: 283: if (IS_SIGNATURE (rhs_type)) 284: sprintf (buf, SIGTABLE_NAME_FORMAT_LONG, sig_ptr+i, rhs_ptr+j, 285: global_sigtable_name_counter++); 286: else 287: sprintf (buf, SIGTABLE_NAME_FORMAT, sig_ptr+i, rhs_ptr+j); 288: return get_identifier (buf); 289: } 290: 291: /* Build a field decl that points to a signature member function. */ 292: 293: static tree 294: build_member_function_pointer (member) 295: tree member; 296: { 297: char *namstr = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (member)); 298: int namlen = IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (member)); 299: char *name; 300: tree entry; 301: 302: name = (char *) alloca (namlen + sizeof (SIGNATURE_FIELD_NAME) + 2); 303: sprintf (name, SIGNATURE_FIELD_NAME_FORMAT, namstr); 304: 305: /* @@ Do we really want to xref signature table fields? */ 306: GNU_xref_ref (current_function_decl, name); 307: 308: entry = build_lang_field_decl (FIELD_DECL, get_identifier (name), 309: TYPE_MAIN_VARIANT (sigtable_entry_type)); 310: TREE_CONSTANT (entry) = 1; 311: TREE_READONLY (entry) = 1; 312: 313: /* @@ Do we really want to xref signature table fields? */ 314: GNU_xref_decl (current_function_decl, entry); 315: 316: return entry; 317: } 318: 319: /* For each FUNCTION_DECL in a signature we construct a member function 320: pointer of the appropriate type. We also need two flags to test 321: whether the member function pointer points to a virtual function or 322: to a default implementation. Those flags will be the two lower order 323: bits of the member function pointer (or the two higher order bits, 324: based on the configuration). 325: 326: The new FIELD_DECLs are appended at the end of the last (and only) 327: sublist of `list_of_fieldlists.' 328: 329: As a side effect, each member function in the signature gets the 330: `decl.ignored' bit turned on, so we don't output debug info for it. */ 331: 332: void 333: append_signature_fields (list_of_fieldlists) 334: tree list_of_fieldlists; 335: { 336: tree l, x; 337: tree last_x = NULL_TREE; 338: tree mfptr; 339: tree last_mfptr; 340: tree mfptr_list = NULL_TREE; 341: 342: /* For signatures it should actually be only a list with one element. */ 343: for (l = list_of_fieldlists; l; l = TREE_CHAIN (l)) 344: { 345: for (x = TREE_VALUE (l); x; x = TREE_CHAIN (x)) 346: { 347: if (TREE_CODE (x) == FUNCTION_DECL) 348: { 349: mfptr = build_member_function_pointer (x); 350: DECL_MEMFUNC_POINTER_TO (x) = mfptr; 351: DECL_MEMFUNC_POINTING_TO (mfptr) = x; 352: DECL_IGNORED_P (x) = 1; 353: DECL_IN_AGGR_P (mfptr) = 1; 354: if (! mfptr_list) 355: mfptr_list = last_mfptr = mfptr; 356: else 357: { 358: TREE_CHAIN (last_mfptr) = mfptr; 359: last_mfptr = mfptr; 360: } 361: } 362: last_x = x; 363: } 364: } 365: 366: /* Append the lists. */ 367: if (last_x && mfptr_list) 368: { 369: TREE_CHAIN (last_x) = mfptr_list; 370: TREE_CHAIN (last_mfptr) = NULL_TREE; 371: } 372: } 373: 374: /* Compare the types of a signature member function and a class member 375: function. Returns 1 if the types are in the C++ `<=' relationship. 376: 377: If we have a signature pointer/reference as argument or return type 378: we don't want to do a recursive conformance check. The conformance 379: check only succeeds if both LHS and RHS refer to the same signature 380: pointer. Otherwise we need to keep information about parameter types 381: around at run time to initialize the signature table correctly. */ 382: 383: static int 384: match_method_types (sig_mtype, class_mtype) 385: tree sig_mtype, class_mtype; 386: { 387: tree sig_return_type = TREE_TYPE (sig_mtype); 388: tree sig_arg_types = TYPE_ARG_TYPES (sig_mtype); 389: tree class_return_type = TREE_TYPE (class_mtype); 390: tree class_arg_types = TYPE_ARG_TYPES (class_mtype); 391: 392: /* The return types have to be the same. */ 393: if (! comptypes (sig_return_type, class_return_type, 1)) 394: return 0; 395: 396: /* Compare the first argument `this.' */ 397: { 398: /* Get the type of what the `optr' is pointing to. */ 399: tree sig_this = 400: TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_VALUE (sig_arg_types)))); 401: tree class_this = TREE_VALUE (class_arg_types); 402: 403: if (TREE_CODE (class_this) == RECORD_TYPE) /* Is `this' a sig ptr? */ 404: class_this = TREE_TYPE (TREE_TYPE (TYPE_FIELDS (class_this))); 405: else 406: class_this = TREE_TYPE (class_this); 407: 408: /* If a signature method's `this' is const or volatile, so has to be 409: the corresponding class method's `this.' */ 410: if ((TYPE_READONLY (sig_this) && ! TYPE_READONLY (class_this)) 411: || (TYPE_VOLATILE (sig_this) && ! TYPE_VOLATILE (class_this))) 412: return 0; 413: } 414: 415: sig_arg_types = TREE_CHAIN (sig_arg_types); 416: class_arg_types = TREE_CHAIN (class_arg_types); 417: 418: /* The number of arguments and the argument types have to be the same. */ 419: return compparms (sig_arg_types, class_arg_types, 3); 420: } 421: 422: /* Undo casts of opaque type variables to the RHS types. */ 423: static void 424: undo_casts (sig_ty) 425: tree sig_ty; 426: { 427: tree field = TYPE_FIELDS (sig_ty); 428: 429: /* Since all the FIELD_DECLs for the signature table entries are at the end 430: of the chain (see `append_signature_fields'), we can do it this way. */ 431: for (; field && TREE_CODE (field) != FIELD_DECL; field = TREE_CHAIN (field)) 432: if (TYPE_MAIN_VARIANT (TREE_TYPE (field)) == opaque_type_node) 433: TREE_TYPE (TREE_TYPE (field)) = TREE_TYPE (ptr_type_node); 434: } 435: 436: /* Do the type checking necessary to see whether the `rhs' conforms to 437: the lhs's `sig_ty'. Depending on the type of `rhs' return a NULL_TREE, 438: an integer_zero_node, a constructor, or an expression offsetting the 439: `rhs' signature table. */ 440: 441: static tree 442: build_signature_table_constructor (sig_ty, rhs) 443: tree sig_ty, rhs; 444: { 445: tree rhstype = TREE_TYPE (rhs); 446: tree sig_field = TYPE_FIELDS (sig_ty); 447: tree result = NULL_TREE; 448: tree first_rhs_field = NULL_TREE; 449: tree last_rhs_field; 450: int sig_ptr_p = IS_SIGNATURE (rhstype); 451: int offset_p = sig_ptr_p; 452: 453: rhstype = sig_ptr_p ? rhstype : TREE_TYPE (rhstype); 454: 455: if (CLASSTYPE_TAGS (sig_ty)) 456: { 457: sorry ("conformance check with signature containing class declarations"); 458: return error_mark_node; 459: } 460: 461: for (; sig_field; sig_field = TREE_CHAIN (sig_field)) 462: { 463: tree basetype_path, baselink, basetypes; 464: tree sig_method, sig_mname, sig_mtype; 465: tree rhs_method, tbl_entry; 466: 467: if (TREE_CODE (sig_field) == TYPE_DECL) 468: { 469: tree sig_field_type = TREE_TYPE (sig_field); 470: 471: if (TYPE_MAIN_VARIANT (sig_field_type) == opaque_type_node) 472: { 473: /* We've got an opaque type here. */ 474: tree oty_name = DECL_NAME (sig_field); 475: tree oty_type = lookup_field (rhstype, oty_name, 1, 1); 476: 477: if (oty_type == NULL_TREE || oty_type == error_mark_node) 478: { 479: cp_error ("class `%T' does not contain type `%T'", 480: rhstype, oty_type); 481: undo_casts (sig_ty); 482: return error_mark_node; 483: } 484: oty_type = TREE_TYPE (oty_type); 485: 486: /* Cast `sig_field' to be of type `oty_type'. This will be 487: undone in `undo_casts' by walking over all the TYPE_DECLs. */ 488: TREE_TYPE (sig_field_type) = TREE_TYPE (oty_type); 489: } 490: /* If we don't have an opaque type, we can ignore the `typedef'. */ 491: continue; 492: } 493: 494: /* Find the signature method corresponding to `sig_field'. */ 495: sig_method = DECL_MEMFUNC_POINTING_TO (sig_field); 496: sig_mname = DECL_NAME (sig_method); 497: sig_mtype = TREE_TYPE (sig_method); 498: 499: basetype_path = TYPE_BINFO (rhstype); 500: baselink = lookup_fnfields (basetype_path, sig_mname, 0); 501: if (baselink == NULL_TREE || baselink == error_mark_node) 502: { 503: if (! IS_DEFAULT_IMPLEMENTATION (sig_method)) 504: { 505: cp_error ("class `%T' does not contain method `%D'", 506: rhstype, sig_mname); 507: undo_casts (sig_ty); 508: return error_mark_node; 509: } 510: else 511: { 512: /* We use the signature's default implementation. */ 513: rhs_method = sig_method; 514: } 515: } 516: else 517: { 518: /* Find the class method of the correct type. */ 519: 520: basetypes = TREE_PURPOSE (baselink); 521: if (TREE_CODE (basetypes) == TREE_LIST) 522: basetypes = TREE_VALUE (basetypes); 523: 524: rhs_method = TREE_VALUE (baselink); 525: for (; rhs_method; rhs_method = TREE_CHAIN (rhs_method)) 526: if (sig_mname == DECL_NAME (rhs_method) 527: && ! DECL_STATIC_FUNCTION_P (rhs_method) 528: && match_method_types (sig_mtype, TREE_TYPE (rhs_method))) 529: break; 530: 531: if (rhs_method == NULL_TREE 532: || (compute_access (basetypes, rhs_method) 533: != access_public)) 534: { 535: error ("class `%s' does not contain a method conforming to `%s'", 536: TYPE_NAME_STRING (rhstype), 537: fndecl_as_string (NULL, sig_method, 1)); 538: undo_casts (sig_ty); 539: return error_mark_node; 540: } 541: } 542: 543: if (sig_ptr_p && rhs_method != sig_method) 544: { 545: tree rhs_field = DECL_MEMFUNC_POINTER_TO (rhs_method); 546: 547: if (first_rhs_field == NULL_TREE) 548: { 549: first_rhs_field = rhs_field; 550: last_rhs_field = rhs_field; 551: } 552: else if (TREE_CHAIN (last_rhs_field) == rhs_field) 553: last_rhs_field = rhs_field; 554: else 555: offset_p = 0; 556: 557: tbl_entry = build_component_ref (rhs, DECL_NAME (rhs_field), 558: NULL_TREE, 1); 559: } 560: else 561: { 1.1.1.2 ! root 562: tree tag, vb_off, delta, index, pfn, vt_off; ! 563: tree tag_decl, vb_off_decl, delta_decl, index_decl; ! 564: tree pfn_decl, vt_off_decl; 1.1 root 565: 566: if (rhs_method == sig_method) 567: { 1.1.1.2 ! root 568: /* default implementation */ ! 569: tag = build_unary_op (NEGATE_EXPR, integer_one_node, 0); ! 570: vb_off = build_unary_op (NEGATE_EXPR, integer_one_node, 0); ! 571: delta = integer_zero_node; ! 572: index = integer_zero_node; 1.1 root 573: pfn = build_unary_op (ADDR_EXPR, rhs_method, 0); 574: TREE_TYPE (pfn) = ptr_type_node; 1.1.1.2 ! root 575: TREE_ADDRESSABLE (rhs_method) = 1; 1.1 root 576: offset_p = 0; /* we can't offset the rhs sig table */ 577: } 578: else if (DECL_VINDEX (rhs_method)) 579: { 1.1.1.2 ! root 580: /* virtual member function */ ! 581: tag = integer_one_node; ! 582: vb_off = build_unary_op (NEGATE_EXPR, integer_one_node, 0); ! 583: delta = BINFO_OFFSET (get_binfo (DECL_CLASS_CONTEXT (rhs_method), ! 584: rhstype, 1)); ! 585: index = DECL_VINDEX (rhs_method); ! 586: vt_off = get_vfield_offset (get_binfo (DECL_CONTEXT (rhs_method), ! 587: rhstype, 0)); 1.1 root 588: } 589: else 590: { 1.1.1.2 ! root 591: /* non-virtual member function */ ! 592: tag = integer_zero_node; ! 593: vb_off = build_unary_op (NEGATE_EXPR, integer_one_node, 0); ! 594: delta = BINFO_OFFSET (get_binfo (DECL_CLASS_CONTEXT (rhs_method), ! 595: rhstype, 1)); ! 596: index = integer_zero_node; 1.1 root 597: pfn = build_unary_op (ADDR_EXPR, rhs_method, 0); 598: TREE_TYPE (pfn) = ptr_type_node; 599: TREE_ADDRESSABLE (rhs_method) = 1; 600: } 601: 1.1.1.2 ! root 602: /* Since digest_init doesn't handle initializing selected fields ! 603: of a struct (i.e., anonymous union), we build the constructor ! 604: by hand, without calling digest_init. */ ! 605: tag_decl = TYPE_FIELDS (sigtable_entry_type); ! 606: vb_off_decl = TREE_CHAIN (tag_decl); ! 607: delta_decl = TREE_CHAIN (vb_off_decl); ! 608: index_decl = TREE_CHAIN (delta_decl); ! 609: pfn_decl = TREE_CHAIN (index_decl); ! 610: vt_off_decl = TREE_CHAIN (pfn_decl); ! 611: ! 612: tag = convert (TREE_TYPE (tag_decl), tag); ! 613: vb_off = convert (TREE_TYPE (vb_off_decl), vb_off); ! 614: delta = convert (TREE_TYPE (delta_decl), delta); ! 615: index = convert (TREE_TYPE (index_decl), index); ! 616: ! 617: if (DECL_VINDEX (rhs_method)) ! 618: { ! 619: vt_off = convert (TREE_TYPE (vt_off_decl), vt_off); ! 620: ! 621: tbl_entry = build_tree_list (vt_off_decl, vt_off); ! 622: } ! 623: else ! 624: { ! 625: pfn = convert (TREE_TYPE (pfn_decl), pfn); ! 626: ! 627: tbl_entry = build_tree_list (pfn_decl, pfn); ! 628: } ! 629: tbl_entry = tree_cons (delta_decl, delta, ! 630: tree_cons (index_decl, index, tbl_entry)); ! 631: tbl_entry = tree_cons (tag_decl, tag, ! 632: tree_cons (vb_off_decl, vb_off, tbl_entry)); ! 633: tbl_entry = build (CONSTRUCTOR, sigtable_entry_type, ! 634: NULL_TREE, tbl_entry); ! 635: 1.1 root 636: TREE_CONSTANT (tbl_entry) = 1; 637: } 638: 639: /* Chain those function address expressions together. */ 640: if (result) 641: result = tree_cons (NULL_TREE, tbl_entry, result); 642: else 643: result = build_tree_list (NULL_TREE, tbl_entry); 644: } 645: 646: if (result == NULL_TREE) 647: { 648: /* The signature was empty, we don't need a signature table. */ 649: undo_casts (sig_ty); 650: return NULL_TREE; 651: } 652: 653: if (offset_p) 654: { 655: if (first_rhs_field == TYPE_FIELDS (rhstype)) 656: { 657: /* The sptr field on the lhs can be copied from the rhs. */ 658: undo_casts (sig_ty); 659: return integer_zero_node; 660: } 661: else 662: { 663: /* The sptr field on the lhs will point into the rhs sigtable. */ 664: undo_casts (sig_ty); 665: return build_component_ref (rhs, DECL_NAME (first_rhs_field), 666: NULL_TREE, 0); 667: } 668: } 669: 670: /* We need to construct a new signature table. */ 671: result = build_nt (CONSTRUCTOR, NULL_TREE, nreverse (result)); 672: TREE_HAS_CONSTRUCTOR (result) = 1; 673: TREE_CONSTANT (result) = !sig_ptr_p; 674: 675: undo_casts (sig_ty); 676: return result; 677: } 678: 679: /* Build a signature table declaration and initialize it or return an 680: existing one if we built one already. If we don't get a constructor 681: as initialization expression, we don't need a new signature table 682: variable and just hand back the init expression. 683: 1.1.1.2 ! root 684: The declaration processing is done by hand instead of using `cp_finish_decl' 1.1 root 685: so that we can make signature pointers global variables instead of 686: static ones. */ 687: 688: static tree 689: build_sigtable (sig_type, rhs_type, init_from) 690: tree sig_type, rhs_type, init_from; 691: { 692: tree name = NULL_TREE; 693: tree decl = NULL_TREE; 694: tree init_expr; 695: 696: push_obstacks_nochange (); 697: end_temporary_allocation (); 698: 699: if (! IS_SIGNATURE (rhs_type)) 700: { 701: name = get_sigtable_name (sig_type, rhs_type); 702: decl = IDENTIFIER_GLOBAL_VALUE (name); 703: } 704: if (decl == NULL_TREE) 705: { 706: tree init; 707: 708: /* We allow only one signature table to be generated for signatures 709: with opaque types. Otherwise we create a loophole in the type 710: system since we could cast data from one classes implementation 711: of the opaque type to that of another class. */ 712: if (SIGNATURE_HAS_OPAQUE_TYPEDECLS (sig_type) 713: && SIGTABLE_HAS_BEEN_GENERATED (sig_type)) 714: { 715: error ("signature with opaque type implemented by multiple classes"); 716: return error_mark_node; 717: } 718: SIGTABLE_HAS_BEEN_GENERATED (sig_type) = 1; 719: 720: init_expr = build_signature_table_constructor (sig_type, init_from); 721: if (init_expr == NULL_TREE || TREE_CODE (init_expr) != CONSTRUCTOR) 722: return init_expr; 723: 724: if (name == NULL_TREE) 725: name = get_sigtable_name (sig_type, rhs_type); 726: { 727: tree context = current_function_decl; 728: 729: /* Make the signature table global, not just static in whichever 730: function a signature pointer/ref is used for the first time. */ 731: current_function_decl = NULL_TREE; 732: decl = pushdecl_top_level (build_decl (VAR_DECL, name, sig_type)); 733: current_function_decl = context; 734: } 735: IDENTIFIER_GLOBAL_VALUE (name) = decl; 736: store_init_value (decl, init_expr); 737: if (IS_SIGNATURE (rhs_type)) 738: { 739: init = DECL_INITIAL (decl); 740: DECL_INITIAL (decl) = error_mark_node; 741: } 742: 743: DECL_ALIGN (decl) = MAX (TYPE_ALIGN (double_type_node), 744: DECL_ALIGN (decl)); 745: #if 0 746: /* GDB-4.7 doesn't find the initialization value of a signature table 747: when it is constant. */ 748: TREE_READONLY (decl) = 1; 749: #endif 750: TREE_STATIC (decl) = 1; 751: TREE_USED (decl) = 1; 752: 753: make_decl_rtl (decl, NULL, 1); 754: if (IS_SIGNATURE (rhs_type)) 755: expand_static_init (decl, init); 756: } 757: 758: pop_obstacks (); 759: 760: return decl; 761: } 762: 763: /* Create a constructor or modify expression if the LHS of an assignment 764: is a signature pointer or a signature reference. If LHS is a record 765: type node, we build a constructor, otherwise a compound expression. */ 766: 767: tree 768: build_signature_pointer_constructor (lhs, rhs) 769: tree lhs, rhs; 770: { 771: register struct obstack *ambient_obstack = current_obstack; 772: register struct obstack *ambient_saveable_obstack = saveable_obstack; 773: int initp = (TREE_CODE (lhs) == RECORD_TYPE); 774: tree lhstype = initp ? lhs : TREE_TYPE (lhs); 775: tree rhstype = TREE_TYPE (rhs); 776: tree sig_ty = SIGNATURE_TYPE (lhstype); 1.1.1.2 ! root 777: tree sig_tbl, sptr_expr, optr_expr; 1.1 root 778: tree result; 779: 780: if (! ((TREE_CODE (rhstype) == POINTER_TYPE 781: && TREE_CODE (TREE_TYPE (rhstype)) == RECORD_TYPE) 782: || (TYPE_LANG_SPECIFIC (rhstype) && 783: (IS_SIGNATURE_POINTER (rhstype) 784: || IS_SIGNATURE_REFERENCE (rhstype))))) 785: { 786: error ("invalid assignment to signature pointer or reference"); 787: return error_mark_node; 788: } 789: 790: if (TYPE_SIZE (sig_ty) == NULL_TREE) 791: { 792: cp_error ("undefined signature `%T' used in signature %s declaration", 793: sig_ty, 794: IS_SIGNATURE_POINTER (lhstype) ? "pointer" : "reference"); 795: return error_mark_node; 796: } 797: 798: /* If SIG_TY is permanent, make the signature table constructor and 799: the signature pointer/reference constructor permanent too. */ 800: if (TREE_PERMANENT (sig_ty)) 801: { 802: current_obstack = &permanent_obstack; 803: saveable_obstack = &permanent_obstack; 804: } 805: 806: if (TYPE_LANG_SPECIFIC (rhstype) && 807: (IS_SIGNATURE_POINTER (rhstype) || IS_SIGNATURE_REFERENCE (rhstype))) 808: { 809: if (SIGNATURE_TYPE (rhstype) == sig_ty) 810: { 811: /* LHS and RHS are signature pointers/refs of the same signature. */ 812: optr_expr = build_optr_ref (rhs); 813: sptr_expr = build_sptr_ref (rhs); 814: } 815: else 816: { 817: /* We need to create a new signature table and copy 818: elements from the rhs signature table. */ 819: tree rhs_sptr_ref = build_sptr_ref (rhs); 820: tree rhs_tbl = build1 (INDIRECT_REF, SIGNATURE_TYPE (rhstype), 821: rhs_sptr_ref); 822: 823: sig_tbl = build_sigtable (sig_ty, SIGNATURE_TYPE (rhstype), rhs_tbl); 824: if (sig_tbl == error_mark_node) 825: return error_mark_node; 826: 827: optr_expr = build_optr_ref (rhs); 828: if (sig_tbl == NULL_TREE) 829: /* The signature was empty. The signature pointer is 830: pretty useless, but the user has been warned. */ 831: sptr_expr = copy_node (null_pointer_node); 832: else if (sig_tbl == integer_zero_node) 833: sptr_expr = rhs_sptr_ref; 834: else 835: sptr_expr = build_unary_op (ADDR_EXPR, sig_tbl, 0); 836: TREE_TYPE (sptr_expr) = build_pointer_type (sig_ty); 837: } 838: } 839: else 840: { 841: sig_tbl = build_sigtable (sig_ty, TREE_TYPE (rhstype), rhs); 842: if (sig_tbl == error_mark_node) 843: return error_mark_node; 844: 845: optr_expr = rhs; 846: if (sig_tbl == NULL_TREE) 847: /* The signature was empty. The signature pointer is 848: pretty useless, but the user has been warned. */ 849: { 850: sptr_expr = copy_node (null_pointer_node); 851: TREE_TYPE (sptr_expr) = build_pointer_type (sig_ty); 852: } 853: else 854: sptr_expr = build_unary_op (ADDR_EXPR, sig_tbl, 0); 855: } 856: 857: if (initp) 858: { 859: result = tree_cons (NULL_TREE, optr_expr, 1.1.1.2 ! root 860: build_tree_list (NULL_TREE, sptr_expr)); 1.1 root 861: result = build_nt (CONSTRUCTOR, NULL_TREE, result); 862: TREE_HAS_CONSTRUCTOR (result) = 1; 863: result = digest_init (lhstype, result, 0); 864: } 865: else 866: { 867: if (TREE_READONLY (lhs) || TYPE_READONLY (lhstype)) 868: readonly_error (lhs, "assignment", 0); 869: 870: optr_expr = build_modify_expr (build_optr_ref (lhs), NOP_EXPR, 871: optr_expr); 872: sptr_expr = build_modify_expr (build_sptr_ref (lhs), NOP_EXPR, 873: sptr_expr); 874: 875: result = tree_cons (NULL_TREE, optr_expr, 876: tree_cons (NULL_TREE, sptr_expr, 1.1.1.2 ! root 877: build_tree_list (NULL_TREE, lhs))); 1.1 root 878: result = build_compound_expr (result); 879: } 880: 881: current_obstack = ambient_obstack; 882: saveable_obstack = ambient_saveable_obstack; 883: return result; 884: } 885: 886: /* Build a temporary variable declaration for the instance of a signature 887: member function call if it isn't a declaration node already. Simply 888: using a SAVE_EXPR doesn't work since we need `this' in both branches 889: of a conditional expression. */ 890: 891: static tree 892: save_this (instance) 893: tree instance; 894: { 895: tree decl; 896: 897: if (TREE_CODE_CLASS (TREE_CODE (instance)) == 'd') 898: decl = instance; 899: else 900: { 901: decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (instance)); 902: DECL_REGISTER (decl) = 1; 903: layout_decl (decl, 0); 904: expand_decl (decl); 905: } 906: 907: return decl; 908: } 909: 910: /* Build a signature member function call. Looks up the signature table 911: entry corresponding to FUNCTION. Depending on the value of the CODE 912: field, either call the function in PFN directly, or use OFFSET to 913: index INSTANCE's virtual function table. */ 914: 915: tree 916: build_signature_method_call (basetype, instance, function, parms) 917: tree basetype, instance, function, parms; 918: { 919: tree saved_instance = save_this (instance); /* Create temp for `this'. */ 1.1.1.2 ! root 920: tree object_ptr = build_optr_ref (saved_instance); ! 921: tree new_object_ptr, new_parms; 1.1 root 922: tree signature_tbl_ptr = build_sptr_ref (saved_instance); 923: tree sig_field_name = DECL_NAME (DECL_MEMFUNC_POINTER_TO (function)); 924: tree basetype_path = TYPE_BINFO (basetype); 925: tree tbl_entry = build_component_ref (build1 (INDIRECT_REF, basetype, 926: signature_tbl_ptr), 927: sig_field_name, basetype_path, 1); 1.1.1.2 ! root 928: tree tag, delta, pfn, vt_off, index, vfn; 1.1 root 929: tree deflt_call = NULL_TREE, direct_call, virtual_call, result; 930: 1.1.1.2 ! root 931: tbl_entry = save_expr (tbl_entry); ! 932: tag = build_component_ref (tbl_entry, tag_identifier, NULL_TREE, 1); ! 933: delta = build_component_ref (tbl_entry, delta_identifier, NULL_TREE, 1); ! 934: pfn = build_component_ref (tbl_entry, pfn_identifier, NULL_TREE, 1); ! 935: vt_off = build_component_ref (tbl_entry, vt_off_identifier, NULL_TREE, 1); ! 936: index = build_component_ref (tbl_entry, index_identifier, NULL_TREE, 1); 1.1 root 937: TREE_TYPE (pfn) = build_pointer_type (TREE_TYPE (function)); 938: 939: if (IS_DEFAULT_IMPLEMENTATION (function)) 940: { 941: pfn = save_expr (pfn); 1.1.1.2 ! root 942: deflt_call = build_function_call (pfn, parms); 1.1 root 943: } 944: 1.1.1.2 ! root 945: new_object_ptr = build (PLUS_EXPR, build_pointer_type (basetype), ! 946: convert (ptrdiff_type_node, object_ptr), ! 947: convert (ptrdiff_type_node, delta)); ! 948: ! 949: parms = tree_cons (NULL_TREE, ! 950: convert (build_pointer_type (basetype), object_ptr), ! 951: TREE_CHAIN (parms)); ! 952: new_parms = tree_cons (NULL_TREE, new_object_ptr, TREE_CHAIN (parms)); ! 953: 1.1 root 954: { 955: /* Cast the signature method to have `this' of a normal pointer type. */ 956: tree old_this = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (pfn)))); 957: 958: TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (pfn)))) = 1.1.1.2 ! root 959: build_type_variant (build_pointer_type (basetype), 1.1 root 960: TYPE_READONLY (old_this), 961: TYPE_VOLATILE (old_this)); 962: 1.1.1.2 ! root 963: direct_call = build_function_call (pfn, new_parms); ! 964: ! 965: { ! 966: tree vfld, vtbl, aref; 1.1 root 967: 1.1.1.2 ! root 968: vfld = build (PLUS_EXPR, ! 969: build_pointer_type (build_pointer_type (vtbl_type_node)), ! 970: convert (ptrdiff_type_node, object_ptr), ! 971: convert (ptrdiff_type_node, vt_off)); ! 972: vtbl = build_indirect_ref (build_indirect_ref (vfld, NULL_PTR), ! 973: NULL_PTR); ! 974: aref = build_array_ref (vtbl, index); ! 975: ! 976: if (flag_vtable_thunks) ! 977: vfn = aref; ! 978: else ! 979: vfn = build_component_ref (aref, pfn_identifier, 0, 0); ! 980: ! 981: TREE_TYPE (vfn) = build_pointer_type (TREE_TYPE (function)); ! 982: ! 983: if (flag_vtable_thunks) ! 984: virtual_call = build_function_call (vfn, parms); ! 985: else ! 986: virtual_call = build_function_call (vfn, new_parms); ! 987: } 1.1 root 988: 989: /* Undo the cast, make `this' a signature pointer again. */ 990: TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (pfn)))) = old_this; 991: } 992: 993: /* Once the function was found, there should be no reason why we 994: couldn't build the member function pointer call. */ 995: if (!direct_call || direct_call == error_mark_node 996: || !virtual_call || virtual_call == error_mark_node 997: || (IS_DEFAULT_IMPLEMENTATION (function) 998: && (!deflt_call || deflt_call == error_mark_node))) 999: { 1000: compiler_error ("cannot build call of signature member function `%s'", 1001: fndecl_as_string (NULL, function, 1)); 1002: return error_mark_node; 1003: } 1004: 1005: if (IS_DEFAULT_IMPLEMENTATION (function)) 1006: { 1.1.1.2 ! root 1007: tree test = build_binary_op_nodefault (LT_EXPR, tag, integer_zero_node, ! 1008: LT_EXPR); ! 1009: result = build_conditional_expr (tag, 1.1 root 1010: build_conditional_expr (test, 1.1.1.2 ! root 1011: deflt_call, ! 1012: virtual_call), 1.1 root 1013: direct_call); 1014: } 1015: else 1.1.1.2 ! root 1016: result = build_conditional_expr (tag, virtual_call, direct_call); 1.1 root 1017: 1018: /* If we created a temporary variable for `this', initialize it first. */ 1019: if (instance != saved_instance) 1020: result = build (COMPOUND_EXPR, TREE_TYPE (result), 1021: build_modify_expr (saved_instance, NOP_EXPR, instance), 1022: result); 1023: 1024: return result; 1025: } 1026: 1027: /* Create a COMPONENT_REF expression for referencing the OPTR field 1028: of a signature pointer or reference. */ 1029: 1030: tree 1031: build_optr_ref (instance) 1032: tree instance; 1033: { 1034: tree field = get_identifier (SIGNATURE_OPTR_NAME); 1035: 1036: return build_component_ref (instance, field, NULL_TREE, 1); 1037: } 1038: 1039: /* Create a COMPONENT_REF expression for referencing the SPTR field 1040: of a signature pointer or reference. */ 1041: 1042: tree 1043: build_sptr_ref (instance) 1044: tree instance; 1045: { 1046: tree field = get_identifier (SIGNATURE_SPTR_NAME); 1047: 1048: return build_component_ref (instance, field, NULL_TREE, 1); 1049: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.