1 /* Support routines shared by all runtimes. 2 Copyright (C) 2011 Free Software Foundation, Inc. 3 Contributed by Iain Sandoe (partially split from objc-act.c) 4 5 This file is part of GCC. 6 7 GCC 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 3, or (at your option) 10 any later version. 11 12 GCC 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 GCC; see the file COPYING3. If not see 19 <http://www.gnu.org/licenses/>. */ 20 21 #include "config.h" 22 #include "system.h" 23 #include "coretypes.h" 24 #include "tm.h" 25 #include "tree.h" 26 27 #ifdef OBJCPLUS 28 #include "cp-tree.h" 29 #else 30 #include "c-tree.h" 31 #include "c-lang.h" 32 #endif 33 #include "langhooks.h" 34 #include "c-family/c-objc.h" 35 #include "objc-act.h" 36 37 /* When building Objective-C++, we are not linking against the C front-end 38 and so need to replicate the C tree-construction functions in some way. */ 39 #ifdef OBJCPLUS 40 #define OBJCP_REMAP_FUNCTIONS 41 #include "objcp-decl.h" 42 #endif /* OBJCPLUS */ 43 44 /* Hooks for string decls etc. */ 45 #include "objc-runtime-hooks.h" 46 47 #include "objc-runtime-shared-support.h" 48 #include "objc-encoding.h" 49 50 /* rt_trees identifiers - shared between NeXT implementations. These allow 51 the FE to tag meta-data in a manner that survives LTO and can be used when 52 the runtime requires that certain meta-data items appear in particular 53 named sections. */ 54 #include "objc-next-metadata-tags.h" 55 extern GTY(()) tree objc_rt_trees[OCTI_RT_META_MAX]; 56 57 /* Rather than repeatedly looking up the identifiers, we save them here. */ 58 tree objc_rt_trees[OCTI_RT_META_MAX]; 59 60 /* For building an objc struct. These might not be used when this file 61 is compiled as part of obj-c++. */ 62 63 static bool objc_building_struct; 64 static struct c_struct_parse_info *objc_struct_info ATTRIBUTE_UNUSED; 65 66 /* Start building a struct for objc. */ 67 68 tree 69 objc_start_struct (tree name) 70 { 71 gcc_assert (!objc_building_struct); 72 objc_building_struct = true; 73 return start_struct (input_location, RECORD_TYPE, name, &objc_struct_info); 74 } 75 76 /* Finish building a struct for objc. */ 77 78 tree 79 objc_finish_struct (tree type, tree fieldlist) 80 { 81 gcc_assert (objc_building_struct); 82 objc_building_struct = false; 83 return finish_struct (input_location, type, fieldlist, NULL_TREE, 84 objc_struct_info); 85 } 86 87 tree 88 build_sized_array_type (tree base_type, int size) 89 { 90 tree index_type = build_index_type (build_int_cst (NULL_TREE, size - 1)); 91 return build_array_type (base_type, index_type); 92 } 93 94 /* Create a declaration for field NAME of a given TYPE. */ 95 96 static tree 97 create_field_decl (tree type, const char *name) 98 { 99 return build_decl (input_location, 100 FIELD_DECL, get_identifier (name), type); 101 } 102 103 tree 104 add_field_decl (tree type, const char *name, tree **chain) 105 { 106 tree field = create_field_decl (type, name); 107 108 if (*chain != NULL) 109 **chain = field; 110 *chain = &DECL_CHAIN (field); 111 112 return field; 113 } 114 115 /* Create a global, static declaration for variable NAME of a given TYPE. The 116 finish_var_decl() routine will need to be called on it afterwards. */ 117 118 tree 119 start_var_decl (tree type, const char *name) 120 { 121 tree var = build_decl (input_location, 122 VAR_DECL, get_identifier (name), type); 123 TREE_STATIC (var) = 1; 124 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */ 125 DECL_IGNORED_P (var) = 1; 126 DECL_ARTIFICIAL (var) = 1; 127 DECL_CONTEXT (var) = NULL_TREE; 128 #ifdef OBJCPLUS 129 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */ 130 #endif 131 return var; 132 } 133 134 /* Finish off the variable declaration created by start_var_decl(). */ 135 136 void 137 finish_var_decl (tree var, tree initializer) 138 { 139 finish_decl (var, input_location, initializer, NULL_TREE, NULL_TREE); 140 } 141 142 /* Just a handy wrapper for add_objc_string. */ 143 144 tree 145 build_selector (tree ident) 146 { 147 return convert (objc_selector_type, add_objc_string (ident, meth_var_names)); 148 } 149 150 /* --- templates --- */ 151 152 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'. 153 This needs to be done just once per compilation. */ 154 155 /* struct _objc_super { 156 struct _objc_object *self; 157 struct _objc_class *super_class; 158 [or Class cls; for the abi v2] 159 }; */ 160 161 void 162 build_super_template (void) 163 { 164 tree decls, *chain = NULL; 165 166 objc_super_template = objc_start_struct (get_identifier (UTAG_SUPER)); 167 168 /* struct _objc_object *self; */ 169 decls = add_field_decl (objc_object_type, "self", &chain); 170 171 /* struct _objc_class *super_class; */ 172 add_field_decl (build_pointer_type (objc_class_template), 173 "super_class", &chain); 174 175 objc_finish_struct (objc_super_template, decls); 176 } 177 178 /* To accomplish method prototyping without generating all kinds of 179 inane warnings, the definition of the dispatch table entries were 180 changed from: 181 182 struct objc_method { SEL _cmd; ...; id (*_imp)(); }; 183 to: 184 struct objc_method { SEL _cmd; ...; void *_imp; }; */ 185 186 tree 187 build_method_template (void) 188 { 189 tree _SLT_record; 190 tree decls, *chain = NULL; 191 192 _SLT_record = objc_start_struct (get_identifier (UTAG_METHOD)); 193 194 /* SEL _cmd; */ 195 decls = add_field_decl (objc_selector_type, "_cmd", &chain); 196 197 /* char *method_types; */ 198 add_field_decl (string_type_node, "method_types", &chain); 199 200 /* void *_imp; */ 201 add_field_decl (build_pointer_type (void_type_node), "_imp", &chain); 202 203 objc_finish_struct (_SLT_record, decls); 204 205 return _SLT_record; 206 } 207 208 tree 209 build_method_prototype_template (void) 210 { 211 tree proto_record; 212 tree decls, *chain = NULL; 213 214 proto_record = objc_start_struct (get_identifier (UTAG_METHOD_PROTOTYPE)); 215 216 /* SEL _cmd; */ 217 decls = add_field_decl (objc_selector_type, "_cmd", &chain); 218 219 /* char *method_types; */ 220 add_field_decl (string_type_node, "method_types", &chain); 221 222 objc_finish_struct (proto_record, decls); 223 224 return proto_record; 225 } 226 227 /* struct { 228 struct _objc__method_prototype_list *method_next; 229 int method_count; 230 struct objc_method method_list[method_count]; 231 }; */ 232 233 tree 234 build_method_list_template (tree list_type, int size) 235 { 236 tree objc_ivar_list_record; 237 tree array_type, decls, *chain = NULL; 238 239 objc_ivar_list_record = objc_start_struct (NULL_TREE); 240 241 /* struct _objc__method_prototype_list *method_next; */ 242 decls = add_field_decl (objc_method_proto_list_ptr, "method_next", &chain); 243 244 /* int method_count; */ 245 add_field_decl (integer_type_node, "method_count", &chain); 246 247 /* struct objc_method method_list[]; */ 248 array_type = build_sized_array_type (list_type, size); 249 add_field_decl (array_type, "method_list", &chain); 250 251 objc_finish_struct (objc_ivar_list_record, decls); 252 253 return objc_ivar_list_record; 254 } 255 256 /* struct objc_method_prototype_list { 257 int count; 258 struct objc_method_prototype { 259 SEL name; 260 char *types; 261 } list[1]; 262 }; */ 263 264 tree 265 build_method_prototype_list_template (tree list_type, int size) 266 { 267 tree objc_ivar_list_record; 268 tree array_type, decls, *chain = NULL; 269 270 /* Generate an unnamed struct definition. */ 271 272 objc_ivar_list_record = objc_start_struct (NULL_TREE); 273 274 /* int method_count; */ 275 decls = add_field_decl (integer_type_node, "method_count", &chain); 276 277 /* struct objc_method method_list[]; */ 278 array_type = build_sized_array_type (list_type, size); 279 add_field_decl (array_type, "method_list", &chain); 280 281 objc_finish_struct (objc_ivar_list_record, decls); 282 283 return objc_ivar_list_record; 284 } 285 286 /* --- names, decls entry --- */ 287 288 /* For each string section we have a chain which maps identifier nodes 289 to decls for the strings. */ 290 291 static GTY(()) int meth_var_names_idx; 292 static GTY(()) int meth_var_types_idx; 293 static GTY(()) int property_name_attr_idx; 294 295 tree 296 add_objc_string (tree ident, string_section section) 297 { 298 tree *chain, decl, type; 299 char buf[BUFSIZE]; 300 301 switch (section) 302 { 303 case class_names: 304 chain = &class_names_chain; 305 snprintf (buf, BUFSIZE, "_OBJC_ClassName_%s", IDENTIFIER_POINTER (ident)); 306 break; 307 case meth_var_names: 308 chain = &meth_var_names_chain; 309 snprintf (buf, BUFSIZE, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++); 310 break; 311 case meth_var_types: 312 chain = &meth_var_types_chain; 313 snprintf (buf, BUFSIZE, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++); 314 break; 315 case prop_names_attr: 316 chain = &prop_names_attr_chain; 317 snprintf (buf, BUFSIZE, "_OBJC_PropertyAttributeOrName_%d", property_name_attr_idx++); 318 break; 319 default: 320 gcc_unreachable (); 321 } 322 323 while (*chain) 324 { 325 if (TREE_VALUE (*chain) == ident) 326 return convert (string_type_node, 327 build_unary_op (input_location, 328 ADDR_EXPR, TREE_PURPOSE (*chain), 1)); 329 330 chain = &TREE_CHAIN (*chain); 331 } 332 333 type = build_sized_array_type (char_type_node, IDENTIFIER_LENGTH (ident) + 1); 334 /* Get a runtime-specific string decl which will be finish_var()'ed in 335 generate_strings (). */ 336 decl = (*runtime.string_decl) (type, buf, section); 337 TREE_CONSTANT (decl) = 1; 338 *chain = tree_cons (decl, ident, NULL_TREE); 339 340 return convert (string_type_node, 341 build_unary_op (input_location, ADDR_EXPR, decl, 1)); 342 } 343 344 /* --- shared metadata routines --- */ 345 346 tree 347 build_descriptor_table_initializer (tree type, tree entries) 348 { 349 VEC(constructor_elt,gc) *inits = NULL; 350 351 do 352 { 353 VEC(constructor_elt,gc) *elts = NULL; 354 355 CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE, 356 build_selector (METHOD_SEL_NAME (entries))); 357 CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE, 358 add_objc_string (METHOD_ENCODING (entries), 359 meth_var_types)); 360 361 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, 362 objc_build_constructor (type, elts)); 363 364 entries = DECL_CHAIN (entries); 365 } 366 while (entries); 367 368 return objc_build_constructor (build_array_type (type, 0), inits); 369 } 370 371 tree 372 build_dispatch_table_initializer (tree type, tree entries) 373 { 374 VEC(constructor_elt,gc) *inits = NULL; 375 376 do 377 { 378 VEC(constructor_elt,gc) *elems = NULL; 379 tree expr; 380 381 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE, 382 build_selector (METHOD_SEL_NAME (entries))); 383 384 /* Generate the method encoding if we don't have one already. */ 385 if (! METHOD_ENCODING (entries)) 386 METHOD_ENCODING (entries) = 387 encode_method_prototype (entries); 388 389 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE, 390 add_objc_string (METHOD_ENCODING (entries), 391 meth_var_types)); 392 393 expr = convert (ptr_type_node, 394 build_unary_op (input_location, ADDR_EXPR, 395 METHOD_DEFINITION (entries), 1)); 396 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE, expr); 397 398 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, 399 objc_build_constructor (type, elems)); 400 401 entries = DECL_CHAIN (entries); 402 } 403 while (entries); 404 405 return objc_build_constructor (build_array_type (type, 0), inits); 406 } 407 408 /* Used only by build_*_selector_translation_table (). */ 409 void 410 diagnose_missing_method (tree meth, location_t here) 411 { 412 tree method_chain; 413 bool found = false; 414 for (method_chain = meth_var_names_chain; 415 method_chain; 416 method_chain = TREE_CHAIN (method_chain)) 417 { 418 if (TREE_VALUE (method_chain) == meth) 419 { 420 found = true; 421 break; 422 } 423 } 424 425 if (!found) 426 warning_at (here, 0, "creating selector for nonexistent method %qE", 427 meth); 428 } 429 430 431 static tree 432 init_module_descriptor (tree type, long vers) 433 { 434 tree expr, ltyp; 435 location_t loc; 436 VEC(constructor_elt,gc) *v = NULL; 437 438 /* No really useful place to point to. */ 439 loc = UNKNOWN_LOCATION; 440 441 /* version = { 1, ... } */ 442 443 expr = build_int_cst (long_integer_type_node, vers); 444 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); 445 446 /* size = { ..., sizeof (struct _objc_module), ... } */ 447 448 expr = convert (long_integer_type_node, 449 size_in_bytes (objc_module_template)); 450 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); 451 452 /* Don't provide any file name for security reasons. */ 453 /* name = { ..., "", ... } */ 454 455 expr = add_objc_string (get_identifier (""), class_names); 456 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); 457 458 /* symtab = { ..., _OBJC_SYMBOLS, ... } */ 459 460 ltyp = build_pointer_type (xref_tag (RECORD_TYPE, 461 get_identifier (UTAG_SYMTAB))); 462 if (UOBJC_SYMBOLS_decl) 463 expr = convert (ltyp, build_unary_op (loc, 464 ADDR_EXPR, UOBJC_SYMBOLS_decl, 0)); 465 else 466 expr = convert (ltyp, null_pointer_node); 467 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); 468 469 return objc_build_constructor (type, v); 470 } 471 472 /* Write out the data structures to describe Objective C classes defined. 473 474 struct _objc_module { ... } _OBJC_MODULE = { ... }; */ 475 476 void 477 build_module_descriptor (long vers, tree attr) 478 { 479 tree decls, *chain = NULL; 480 481 #ifdef OBJCPLUS 482 push_lang_context (lang_name_c); /* extern "C" */ 483 #endif 484 485 objc_module_template = objc_start_struct (get_identifier (UTAG_MODULE)); 486 487 /* long version; */ 488 decls = add_field_decl (long_integer_type_node, "version", &chain); 489 490 /* long size; */ 491 add_field_decl (long_integer_type_node, "size", &chain); 492 493 /* char *name; */ 494 add_field_decl (string_type_node, "name", &chain); 495 496 /* struct _objc_symtab *symtab; */ 497 add_field_decl (build_pointer_type (xref_tag (RECORD_TYPE, 498 get_identifier (UTAG_SYMTAB))), 499 "symtab", &chain); 500 501 objc_finish_struct (objc_module_template, decls); 502 503 /* Create an instance of "_objc_module". */ 504 UOBJC_MODULES_decl = start_var_decl (objc_module_template, 505 /* FIXME - why the conditional 506 if the symbol is the 507 same. */ 508 flag_next_runtime ? "_OBJC_Module" : "_OBJC_Module"); 509 510 /* This is the root of the metadata for defined classes and categories, it 511 is referenced by the runtime and, therefore, needed. */ 512 DECL_PRESERVE_P (UOBJC_MODULES_decl) = 1; 513 514 /* Allow the runtime to mark meta-data such that it can be assigned to target 515 specific sections by the back-end. */ 516 if (attr) 517 DECL_ATTRIBUTES (UOBJC_MODULES_decl) = attr; 518 519 finish_var_decl (UOBJC_MODULES_decl, 520 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl), 521 vers)); 522 523 #ifdef OBJCPLUS 524 pop_lang_context (); 525 #endif 526 } 527 528 tree 529 build_ivar_list_initializer (tree type, tree field_decl) 530 { 531 VEC(constructor_elt,gc) *inits = NULL; 532 533 do 534 { 535 VEC(constructor_elt,gc) *ivar = NULL; 536 tree id; 537 538 /* Set name. */ 539 if (DECL_NAME (field_decl)) 540 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, 541 add_objc_string (DECL_NAME (field_decl), 542 meth_var_names)); 543 else 544 /* Unnamed bit-field ivar (yuck). */ 545 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, build_int_cst (NULL_TREE, 0)); 546 547 /* Set type. */ 548 id = add_objc_string (encode_field_decl (field_decl), 549 meth_var_types); 550 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id); 551 552 /* Set offset. */ 553 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, byte_position (field_decl)); 554 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, 555 objc_build_constructor (type, ivar)); 556 do 557 field_decl = DECL_CHAIN (field_decl); 558 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL); 559 } 560 while (field_decl); 561 562 return objc_build_constructor (build_array_type (type, 0), inits); 563 } 564 565 /* struct { 566 int ivar_count; 567 struct objc_ivar ivar_list[ivar_count]; 568 }; */ 569 570 tree 571 build_ivar_list_template (tree list_type, int size) 572 { 573 tree objc_ivar_list_record; 574 tree array_type, decls, *chain = NULL; 575 576 objc_ivar_list_record = objc_start_struct (NULL_TREE); 577 578 /* int ivar_count; */ 579 decls = add_field_decl (integer_type_node, "ivar_count", &chain); 580 581 /* struct objc_ivar ivar_list[]; */ 582 array_type = build_sized_array_type (list_type, size); 583 add_field_decl (array_type, "ivar_list", &chain); 584 585 objc_finish_struct (objc_ivar_list_record, decls); 586 587 return objc_ivar_list_record; 588 } 589 590 /* struct _objc_ivar { 591 char *ivar_name; 592 char *ivar_type; 593 int ivar_offset; 594 }; */ 595 596 tree 597 build_ivar_template (void) 598 { 599 tree objc_ivar_id, objc_ivar_record; 600 tree decls, *chain = NULL; 601 602 objc_ivar_id = get_identifier (UTAG_IVAR); 603 objc_ivar_record = objc_start_struct (objc_ivar_id); 604 605 /* char *ivar_name; */ 606 decls = add_field_decl (string_type_node, "ivar_name", &chain); 607 608 /* char *ivar_type; */ 609 add_field_decl (string_type_node, "ivar_type", &chain); 610 611 /* int ivar_offset; */ 612 add_field_decl (integer_type_node, "ivar_offset", &chain); 613 614 objc_finish_struct (objc_ivar_record, decls); 615 616 return objc_ivar_record; 617 } 618 619 /* Used by NeXT ABI=0..2 */ 620 void 621 build_next_selector_translation_table (void) 622 { 623 tree chain; 624 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain)) 625 { 626 tree expr; 627 tree decl = TREE_PURPOSE (chain); 628 if (warn_selector) 629 { 630 location_t loc; 631 if (decl) 632 loc = DECL_SOURCE_LOCATION (decl); 633 else 634 loc = UNKNOWN_LOCATION; 635 diagnose_missing_method (TREE_VALUE (chain), loc); 636 } 637 638 expr = build_selector (TREE_VALUE (chain)); 639 640 if (decl) 641 { 642 /* Entries of this form are used for references to methods. 643 The runtime re-writes these on start-up, but the compiler can't see 644 that and optimizes it away unless we force it. */ 645 DECL_PRESERVE_P (decl) = 1; 646 finish_var_decl (decl, expr); 647 } 648 } 649 } 650 651 void 652 generate_protocol_references (tree plist) 653 { 654 tree lproto; 655 656 /* Forward declare protocols referenced. */ 657 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) 658 { 659 tree proto = TREE_VALUE (lproto); 660 661 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE 662 && PROTOCOL_NAME (proto)) 663 { 664 if (! PROTOCOL_FORWARD_DECL (proto)) 665 PROTOCOL_FORWARD_DECL (proto) = (*runtime.protocol_decl) (proto); 666 667 if (PROTOCOL_LIST (proto)) 668 generate_protocol_references (PROTOCOL_LIST (proto)); 669 } 670 } 671 } 672 673 /* --- new routines --- */ 674 675 /* Output all strings. */ 676 677 /* FIXME: don't use global vars for all this... */ 678 679 /* This emits all the meta-data string tables (and finalizes each var 680 as it goes). */ 681 void 682 generate_strings (void) 683 { 684 tree chain, string_expr; 685 tree string, decl; /* , type;*/ 686 687 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain)) 688 { 689 string = TREE_VALUE (chain); 690 decl = TREE_PURPOSE (chain); 691 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1, 692 IDENTIFIER_POINTER (string)); 693 finish_var_decl (decl, string_expr); 694 } 695 696 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain)) 697 { 698 string = TREE_VALUE (chain); 699 decl = TREE_PURPOSE (chain); 700 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1, 701 IDENTIFIER_POINTER (string)); 702 finish_var_decl (decl, string_expr); 703 } 704 705 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain)) 706 { 707 string = TREE_VALUE (chain); 708 decl = TREE_PURPOSE (chain); 709 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1, 710 IDENTIFIER_POINTER (string)); 711 finish_var_decl (decl, string_expr); 712 } 713 714 for (chain = prop_names_attr_chain; chain; chain = TREE_CHAIN (chain)) 715 { 716 string = TREE_VALUE (chain); 717 decl = TREE_PURPOSE (chain); 718 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1, 719 IDENTIFIER_POINTER (string)); 720 finish_var_decl (decl, string_expr); 721 } 722 } 723 724 #include "gt-objc-objc-runtime-shared-support.h" 725