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