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