1 /* Implement classes and message passing for Objective C. 2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 3 2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. 4 Contributed by Steve Naroff. 5 6 This file is part of GCC. 7 8 GCC is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3, or (at your option) 11 any later version. 12 13 GCC is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with GCC; see the file COPYING3. If not see 20 <http://www.gnu.org/licenses/>. */ 21 22 23 /* Purpose: This module implements the Objective-C 4.0 language. 24 25 compatibility issues (with the Stepstone translator): 26 27 - does not recognize the following 3.3 constructs. 28 @requires, @classes, @messages, = (...) 29 - methods with variable arguments must conform to ANSI standard. 30 - tagged structure definitions that appear in BOTH the interface 31 and implementation are not allowed. 32 - public/private: all instance variables are public within the 33 context of the implementation...I consider this to be a bug in 34 the translator. 35 - statically allocated objects are not supported. the user will 36 receive an error if this service is requested. 37 38 code generation `options': 39 40 */ 41 42 #include "config.h" 43 #include "system.h" 44 #include "coretypes.h" 45 #include "tm.h" 46 #include "tree.h" 47 #include "rtl.h" 48 #include "tm_p.h" 49 #include "expr.h" 50 51 #ifdef OBJCPLUS 52 #include "cp-tree.h" 53 #else 54 #include "c-tree.h" 55 #include "c-lang.h" 56 #endif 57 58 #include "c-common.h" 59 #include "c-pragma.h" 60 #include "flags.h" 61 #include "langhooks.h" 62 #include "objc-act.h" 63 #include "input.h" 64 #include "except.h" 65 #include "function.h" 66 #include "output.h" 67 #include "toplev.h" 68 #include "ggc.h" 69 #include "varray.h" 70 #include "debug.h" 71 #include "target.h" 72 #include "diagnostic.h" 73 #include "intl.h" 74 #include "cgraph.h" 75 #include "tree-iterator.h" 76 #include "libfuncs.h" 77 #include "hashtab.h" 78 #include "langhooks-def.h" 79 80 #define OBJC_VOID_AT_END void_list_node 81 82 static unsigned int should_call_super_dealloc = 0; 83 84 /* When building Objective-C++, we are not linking against the C front-end 85 and so need to replicate the C tree-construction functions in some way. */ 86 #ifdef OBJCPLUS 87 #define OBJCP_REMAP_FUNCTIONS 88 #include "objcp-decl.h" 89 #endif /* OBJCPLUS */ 90 91 /* This is the default way of generating a method name. */ 92 /* I am not sure it is really correct. 93 Perhaps there's a danger that it will make name conflicts 94 if method names contain underscores. -- rms. */ 95 #ifndef OBJC_GEN_METHOD_LABEL 96 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \ 97 do { \ 98 char *temp; \ 99 sprintf ((BUF), "_%s_%s_%s_%s", \ 100 ((IS_INST) ? "i" : "c"), \ 101 (CLASS_NAME), \ 102 ((CAT_NAME)? (CAT_NAME) : ""), \ 103 (SEL_NAME)); \ 104 for (temp = (BUF); *temp; temp++) \ 105 if (*temp == ':') *temp = '_'; \ 106 } while (0) 107 #endif 108 109 /* These need specifying. */ 110 #ifndef OBJC_FORWARDING_STACK_OFFSET 111 #define OBJC_FORWARDING_STACK_OFFSET 0 112 #endif 113 114 #ifndef OBJC_FORWARDING_MIN_OFFSET 115 #define OBJC_FORWARDING_MIN_OFFSET 0 116 #endif 117 118 /* Set up for use of obstacks. */ 119 120 #include "obstack.h" 121 122 /* This obstack is used to accumulate the encoding of a data type. */ 123 static struct obstack util_obstack; 124 125 /* This points to the beginning of obstack contents, so we can free 126 the whole contents. */ 127 char *util_firstobj; 128 129 /* The version identifies which language generation and runtime 130 the module (file) was compiled for, and is recorded in the 131 module descriptor. */ 132 133 #define OBJC_VERSION (flag_next_runtime ? 6 : 8) 134 #define PROTOCOL_VERSION 2 135 136 /* (Decide if these can ever be validly changed.) */ 137 #define OBJC_ENCODE_INLINE_DEFS 0 138 #define OBJC_ENCODE_DONT_INLINE_DEFS 1 139 140 /*** Private Interface (procedures) ***/ 141 142 /* Used by compile_file. */ 143 144 static void init_objc (void); 145 static void finish_objc (void); 146 147 /* Code generation. */ 148 149 static tree objc_build_constructor (tree, tree); 150 static tree build_objc_method_call (location_t, int, tree, tree, tree, tree); 151 static tree get_proto_encoding (tree); 152 static tree lookup_interface (tree); 153 static tree objc_add_static_instance (tree, tree); 154 155 static tree start_class (enum tree_code, tree, tree, tree); 156 static tree continue_class (tree); 157 static void finish_class (tree); 158 static void start_method_def (tree); 159 #ifdef OBJCPLUS 160 static void objc_start_function (tree, tree, tree, tree); 161 #else 162 static void objc_start_function (tree, tree, tree, struct c_arg_info *); 163 #endif 164 static tree start_protocol (enum tree_code, tree, tree); 165 static tree build_method_decl (enum tree_code, tree, tree, tree, bool); 166 static tree objc_add_method (tree, tree, int); 167 static tree add_instance_variable (tree, int, tree); 168 static tree build_ivar_reference (tree); 169 static tree is_ivar (tree, tree); 170 171 static void build_objc_exception_stuff (void); 172 static void build_next_objc_exception_stuff (void); 173 174 /* We only need the following for ObjC; ObjC++ will use C++'s definition 175 of DERIVED_FROM_P. */ 176 #ifndef OBJCPLUS 177 static bool objc_derived_from_p (tree, tree); 178 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD) 179 #endif 180 static void objc_xref_basetypes (tree, tree); 181 182 static void build_class_template (void); 183 static void build_selector_template (void); 184 static void build_category_template (void); 185 static void build_super_template (void); 186 static tree build_protocol_initializer (tree, tree, tree, tree, tree); 187 static tree get_class_ivars (tree, bool); 188 static tree generate_protocol_list (tree); 189 static void build_protocol_reference (tree); 190 191 #ifdef OBJCPLUS 192 static void objc_generate_cxx_cdtors (void); 193 #endif 194 195 static const char *synth_id_with_class_suffix (const char *, tree); 196 197 /* Hash tables to manage the global pool of method prototypes. */ 198 199 hash *nst_method_hash_list = 0; 200 hash *cls_method_hash_list = 0; 201 202 static hash hash_lookup (hash *, tree); 203 static tree lookup_method (tree, tree); 204 static tree lookup_method_static (tree, tree, int); 205 206 enum string_section 207 { 208 class_names, /* class, category, protocol, module names */ 209 meth_var_names, /* method and variable names */ 210 meth_var_types /* method and variable type descriptors */ 211 }; 212 213 static tree add_objc_string (tree, enum string_section); 214 static tree build_objc_string_decl (enum string_section); 215 static void build_selector_table_decl (void); 216 217 /* Protocol additions. */ 218 219 static tree lookup_protocol (tree); 220 static tree lookup_and_install_protocols (tree); 221 222 /* Type encoding. */ 223 224 static void encode_type_qualifiers (tree); 225 static void encode_type (tree, int, int); 226 static void encode_field_decl (tree, int, int); 227 228 #ifdef OBJCPLUS 229 static void really_start_method (tree, tree); 230 #else 231 static void really_start_method (tree, struct c_arg_info *); 232 #endif 233 static int comp_proto_with_proto (tree, tree, int); 234 static void objc_push_parm (tree); 235 #ifdef OBJCPLUS 236 static tree objc_get_parm_info (int); 237 #else 238 static struct c_arg_info *objc_get_parm_info (int); 239 #endif 240 241 /* Utilities for debugging and error diagnostics. */ 242 243 static char *gen_type_name (tree); 244 static char *gen_type_name_0 (tree); 245 static char *gen_method_decl (tree); 246 static char *gen_declaration (tree); 247 248 /* Everything else. */ 249 250 static tree create_field_decl (tree, const char *); 251 static void add_class_reference (tree); 252 static void build_protocol_template (void); 253 static tree encode_method_prototype (tree); 254 static void generate_classref_translation_entry (tree); 255 static void handle_class_ref (tree); 256 static void generate_struct_by_value_array (void) 257 ATTRIBUTE_NORETURN; 258 static void mark_referenced_methods (void); 259 static void generate_objc_image_info (void); 260 261 /*** Private Interface (data) ***/ 262 263 /* Reserved tag definitions. */ 264 265 #define OBJECT_TYPEDEF_NAME "id" 266 #define CLASS_TYPEDEF_NAME "Class" 267 268 #define TAG_OBJECT "objc_object" 269 #define TAG_CLASS "objc_class" 270 #define TAG_SUPER "objc_super" 271 #define TAG_SELECTOR "objc_selector" 272 273 #define UTAG_CLASS "_objc_class" 274 #define UTAG_IVAR "_objc_ivar" 275 #define UTAG_IVAR_LIST "_objc_ivar_list" 276 #define UTAG_METHOD "_objc_method" 277 #define UTAG_METHOD_LIST "_objc_method_list" 278 #define UTAG_CATEGORY "_objc_category" 279 #define UTAG_MODULE "_objc_module" 280 #define UTAG_SYMTAB "_objc_symtab" 281 #define UTAG_SUPER "_objc_super" 282 #define UTAG_SELECTOR "_objc_selector" 283 284 #define UTAG_PROTOCOL "_objc_protocol" 285 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype" 286 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list" 287 288 /* Note that the string object global name is only needed for the 289 NeXT runtime. */ 290 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference" 291 292 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol" 293 294 static const char *TAG_GETCLASS; 295 static const char *TAG_GETMETACLASS; 296 static const char *TAG_MSGSEND; 297 static const char *TAG_MSGSENDSUPER; 298 /* The NeXT Objective-C messenger may have two extra entry points, for use 299 when returning a structure. */ 300 static const char *TAG_MSGSEND_STRET; 301 static const char *TAG_MSGSENDSUPER_STRET; 302 static const char *default_constant_string_class_name; 303 304 /* Runtime metadata flags. */ 305 #define CLS_FACTORY 0x0001L 306 #define CLS_META 0x0002L 307 #define CLS_HAS_CXX_STRUCTORS 0x2000L 308 309 #define OBJC_MODIFIER_STATIC 0x00000001 310 #define OBJC_MODIFIER_FINAL 0x00000002 311 #define OBJC_MODIFIER_PUBLIC 0x00000004 312 #define OBJC_MODIFIER_PRIVATE 0x00000008 313 #define OBJC_MODIFIER_PROTECTED 0x00000010 314 #define OBJC_MODIFIER_NATIVE 0x00000020 315 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040 316 #define OBJC_MODIFIER_ABSTRACT 0x00000080 317 #define OBJC_MODIFIER_VOLATILE 0x00000100 318 #define OBJC_MODIFIER_TRANSIENT 0x00000200 319 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000 320 321 /* NeXT-specific tags. */ 322 323 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil" 324 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret" 325 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract" 326 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter" 327 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit" 328 #define TAG_EXCEPTIONMATCH "objc_exception_match" 329 #define TAG_EXCEPTIONTHROW "objc_exception_throw" 330 #define TAG_SYNCENTER "objc_sync_enter" 331 #define TAG_SYNCEXIT "objc_sync_exit" 332 #define TAG_SETJMP "_setjmp" 333 #define UTAG_EXCDATA "_objc_exception_data" 334 335 #define TAG_ASSIGNIVAR "objc_assign_ivar" 336 #define TAG_ASSIGNGLOBAL "objc_assign_global" 337 #define TAG_ASSIGNSTRONGCAST "objc_assign_strongCast" 338 339 /* Branch entry points. All that matters here are the addresses; 340 functions with these names do not really exist in libobjc. */ 341 342 #define TAG_MSGSEND_FAST "objc_msgSend_Fast" 343 #define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast" 344 345 #define TAG_CXX_CONSTRUCT ".cxx_construct" 346 #define TAG_CXX_DESTRUCT ".cxx_destruct" 347 348 /* GNU-specific tags. */ 349 350 #define TAG_EXECCLASS "__objc_exec_class" 351 #define TAG_GNUINIT "__objc_gnu_init" 352 353 /* Flags for lookup_method_static(). */ 354 #define OBJC_LOOKUP_CLASS 1 /* Look for class methods. */ 355 #define OBJC_LOOKUP_NO_SUPER 2 /* Do not examine superclasses. */ 356 357 /* The OCTI_... enumeration itself is in objc/objc-act.h. */ 358 tree objc_global_trees[OCTI_MAX]; 359 360 static void handle_impent (struct imp_entry *); 361 362 struct imp_entry *imp_list = 0; 363 int imp_count = 0; /* `@implementation' */ 364 int cat_count = 0; /* `@category' */ 365 366 enum tree_code objc_inherit_code; 367 int objc_public_flag; 368 369 /* Use to generate method labels. */ 370 static int method_slot = 0; 371 372 #define BUFSIZE 1024 373 374 static char *errbuf; /* Buffer for error diagnostics */ 375 376 /* Data imported from tree.c. */ 377 378 extern enum debug_info_type write_symbols; 379 380 /* Data imported from toplev.c. */ 381 382 extern const char *dump_base_name; 383 384 static int flag_typed_selectors; 385 386 /* Store all constructed constant strings in a hash table so that 387 they get uniqued properly. */ 388 389 struct GTY(()) string_descriptor { 390 /* The literal argument . */ 391 tree literal; 392 393 /* The resulting constant string. */ 394 tree constructor; 395 }; 396 397 static GTY((param_is (struct string_descriptor))) htab_t string_htab; 398 399 /* Store the EH-volatilized types in a hash table, for easy retrieval. */ 400 struct GTY(()) volatilized_type { 401 tree type; 402 }; 403 404 static GTY((param_is (struct volatilized_type))) htab_t volatilized_htab; 405 406 FILE *gen_declaration_file; 407 408 /* Tells "encode_pointer/encode_aggregate" whether we are generating 409 type descriptors for instance variables (as opposed to methods). 410 Type descriptors for instance variables contain more information 411 than methods (for static typing and embedded structures). */ 412 413 static int generating_instance_variables = 0; 414 415 /* For building an objc struct. These may not be used when this file 416 is compiled as part of obj-c++. */ 417 418 static bool objc_building_struct; 419 static struct c_struct_parse_info *objc_struct_info ATTRIBUTE_UNUSED; 420 421 /* Start building a struct for objc. */ 422 423 static tree 424 objc_start_struct (tree name) 425 { 426 gcc_assert (!objc_building_struct); 427 objc_building_struct = true; 428 return start_struct (input_location, RECORD_TYPE, name, &objc_struct_info); 429 } 430 431 /* Finish building a struct for objc. */ 432 433 static tree 434 objc_finish_struct (tree type, tree fieldlist) 435 { 436 gcc_assert (objc_building_struct); 437 objc_building_struct = false; 438 return finish_struct (input_location, type, fieldlist, NULL_TREE, 439 objc_struct_info); 440 } 441 442 /* Some platforms pass small structures through registers versus 443 through an invisible pointer. Determine at what size structure is 444 the transition point between the two possibilities. */ 445 446 static void 447 generate_struct_by_value_array (void) 448 { 449 tree type; 450 tree field_decl, field_decl_chain; 451 int i, j; 452 int aggregate_in_mem[32]; 453 int found = 0; 454 455 /* Presumably no platform passes 32 byte structures in a register. */ 456 for (i = 1; i < 32; i++) 457 { 458 char buffer[5]; 459 460 /* Create an unnamed struct that has `i' character components */ 461 type = objc_start_struct (NULL_TREE); 462 463 strcpy (buffer, "c1"); 464 field_decl = create_field_decl (char_type_node, 465 buffer); 466 field_decl_chain = field_decl; 467 468 for (j = 1; j < i; j++) 469 { 470 sprintf (buffer, "c%d", j + 1); 471 field_decl = create_field_decl (char_type_node, 472 buffer); 473 chainon (field_decl_chain, field_decl); 474 } 475 objc_finish_struct (type, field_decl_chain); 476 477 aggregate_in_mem[i] = aggregate_value_p (type, 0); 478 if (!aggregate_in_mem[i]) 479 found = 1; 480 } 481 482 /* We found some structures that are returned in registers instead of memory 483 so output the necessary data. */ 484 if (found) 485 { 486 for (i = 31; i >= 0; i--) 487 if (!aggregate_in_mem[i]) 488 break; 489 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i); 490 491 /* The first member of the structure is always 0 because we don't handle 492 structures with 0 members */ 493 printf ("static int struct_forward_array[] = {\n 0"); 494 495 for (j = 1; j <= i; j++) 496 printf (", %d", aggregate_in_mem[j]); 497 printf ("\n};\n"); 498 } 499 500 exit (0); 501 } 502 503 bool 504 objc_init (void) 505 { 506 #ifdef OBJCPLUS 507 if (cxx_init () == false) 508 #else 509 if (c_objc_common_init () == false) 510 #endif 511 return false; 512 513 /* If gen_declaration desired, open the output file. */ 514 if (flag_gen_declaration) 515 { 516 register char * const dumpname = concat (dump_base_name, ".decl", NULL); 517 gen_declaration_file = fopen (dumpname, "w"); 518 if (gen_declaration_file == 0) 519 fatal_error ("can't open %s: %m", dumpname); 520 free (dumpname); 521 } 522 523 if (flag_next_runtime) 524 { 525 TAG_GETCLASS = "objc_getClass"; 526 TAG_GETMETACLASS = "objc_getMetaClass"; 527 TAG_MSGSEND = "objc_msgSend"; 528 TAG_MSGSENDSUPER = "objc_msgSendSuper"; 529 TAG_MSGSEND_STRET = "objc_msgSend_stret"; 530 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret"; 531 default_constant_string_class_name = "NSConstantString"; 532 } 533 else 534 { 535 TAG_GETCLASS = "objc_get_class"; 536 TAG_GETMETACLASS = "objc_get_meta_class"; 537 TAG_MSGSEND = "objc_msg_lookup"; 538 TAG_MSGSENDSUPER = "objc_msg_lookup_super"; 539 /* GNU runtime does not provide special functions to support 540 structure-returning methods. */ 541 default_constant_string_class_name = "NXConstantString"; 542 flag_typed_selectors = 1; 543 /* GNU runtime does not need the compiler to change code 544 in order to do GC. */ 545 if (flag_objc_gc) 546 { 547 warning_at (0, 0, "%<-fobjc-gc%> is ignored for %<-fgnu-runtime%>"); 548 flag_objc_gc=0; 549 } 550 } 551 552 init_objc (); 553 554 if (print_struct_values && !flag_compare_debug) 555 generate_struct_by_value_array (); 556 557 return true; 558 } 559 560 void 561 objc_finish_file (void) 562 { 563 mark_referenced_methods (); 564 565 #ifdef OBJCPLUS 566 /* We need to instantiate templates _before_ we emit ObjC metadata; 567 if we do not, some metadata (such as selectors) may go missing. */ 568 at_eof = 1; 569 instantiate_pending_templates (0); 570 #endif 571 572 /* Finalize Objective-C runtime data. No need to generate tables 573 and code if only checking syntax, or if generating a PCH file. */ 574 if (!flag_syntax_only && !pch_file) 575 finish_objc (); 576 577 if (gen_declaration_file) 578 fclose (gen_declaration_file); 579 } 580 581 /* Return the first occurrence of a method declaration corresponding 582 to sel_name in rproto_list. Search rproto_list recursively. 583 If is_class is 0, search for instance methods, otherwise for class 584 methods. */ 585 static tree 586 lookup_method_in_protocol_list (tree rproto_list, tree sel_name, 587 int is_class) 588 { 589 tree rproto, p; 590 tree fnd = 0; 591 592 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto)) 593 { 594 p = TREE_VALUE (rproto); 595 596 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE) 597 { 598 if ((fnd = lookup_method (is_class 599 ? PROTOCOL_CLS_METHODS (p) 600 : PROTOCOL_NST_METHODS (p), sel_name))) 601 ; 602 else if (PROTOCOL_LIST (p)) 603 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p), 604 sel_name, is_class); 605 } 606 else 607 { 608 ; /* An identifier...if we could not find a protocol. */ 609 } 610 611 if (fnd) 612 return fnd; 613 } 614 615 return 0; 616 } 617 618 static tree 619 lookup_protocol_in_reflist (tree rproto_list, tree lproto) 620 { 621 tree rproto, p; 622 623 /* Make sure the protocol is supported by the object on the rhs. */ 624 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE) 625 { 626 tree fnd = 0; 627 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto)) 628 { 629 p = TREE_VALUE (rproto); 630 631 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE) 632 { 633 if (lproto == p) 634 fnd = lproto; 635 636 else if (PROTOCOL_LIST (p)) 637 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto); 638 } 639 640 if (fnd) 641 return fnd; 642 } 643 } 644 else 645 { 646 ; /* An identifier...if we could not find a protocol. */ 647 } 648 649 return 0; 650 } 651 652 void 653 objc_start_class_interface (tree klass, tree super_class, tree protos) 654 { 655 objc_interface_context 656 = objc_ivar_context 657 = start_class (CLASS_INTERFACE_TYPE, klass, super_class, protos); 658 objc_public_flag = 0; 659 } 660 661 void 662 objc_start_category_interface (tree klass, tree categ, tree protos) 663 { 664 objc_interface_context 665 = start_class (CATEGORY_INTERFACE_TYPE, klass, categ, protos); 666 objc_ivar_chain 667 = continue_class (objc_interface_context); 668 } 669 670 void 671 objc_start_protocol (tree name, tree protos) 672 { 673 objc_interface_context 674 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos); 675 } 676 677 void 678 objc_continue_interface (void) 679 { 680 objc_ivar_chain 681 = continue_class (objc_interface_context); 682 } 683 684 void 685 objc_finish_interface (void) 686 { 687 finish_class (objc_interface_context); 688 objc_interface_context = NULL_TREE; 689 } 690 691 void 692 objc_start_class_implementation (tree klass, tree super_class) 693 { 694 objc_implementation_context 695 = objc_ivar_context 696 = start_class (CLASS_IMPLEMENTATION_TYPE, klass, super_class, NULL_TREE); 697 objc_public_flag = 0; 698 } 699 700 void 701 objc_start_category_implementation (tree klass, tree categ) 702 { 703 objc_implementation_context 704 = start_class (CATEGORY_IMPLEMENTATION_TYPE, klass, categ, NULL_TREE); 705 objc_ivar_chain 706 = continue_class (objc_implementation_context); 707 } 708 709 void 710 objc_continue_implementation (void) 711 { 712 objc_ivar_chain 713 = continue_class (objc_implementation_context); 714 } 715 716 void 717 objc_finish_implementation (void) 718 { 719 #ifdef OBJCPLUS 720 if (flag_objc_call_cxx_cdtors) 721 objc_generate_cxx_cdtors (); 722 #endif 723 724 if (objc_implementation_context) 725 { 726 finish_class (objc_implementation_context); 727 objc_ivar_chain = NULL_TREE; 728 objc_implementation_context = NULL_TREE; 729 } 730 else 731 warning (0, "%<@end%> must appear in an @implementation context"); 732 } 733 734 void 735 objc_set_visibility (int visibility) 736 { 737 objc_public_flag = visibility; 738 } 739 740 void 741 objc_set_method_type (enum tree_code type) 742 { 743 objc_inherit_code = (type == PLUS_EXPR 744 ? CLASS_METHOD_DECL 745 : INSTANCE_METHOD_DECL); 746 } 747 748 tree 749 objc_build_method_signature (tree rettype, tree selector, 750 tree optparms, bool ellipsis) 751 { 752 return build_method_decl (objc_inherit_code, rettype, selector, 753 optparms, ellipsis); 754 } 755 756 void 757 objc_add_method_declaration (tree decl) 758 { 759 if (!objc_interface_context) 760 fatal_error ("method declaration not in @interface context"); 761 762 objc_add_method (objc_interface_context, 763 decl, 764 objc_inherit_code == CLASS_METHOD_DECL); 765 } 766 767 void 768 objc_start_method_definition (tree decl) 769 { 770 if (!objc_implementation_context) 771 fatal_error ("method definition not in @implementation context"); 772 773 objc_add_method (objc_implementation_context, 774 decl, 775 objc_inherit_code == CLASS_METHOD_DECL); 776 start_method_def (decl); 777 } 778 779 void 780 objc_add_instance_variable (tree decl) 781 { 782 (void) add_instance_variable (objc_ivar_context, 783 objc_public_flag, 784 decl); 785 } 786 787 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of 788 an '@'. */ 789 790 int 791 objc_is_reserved_word (tree ident) 792 { 793 unsigned char code = C_RID_CODE (ident); 794 795 return (OBJC_IS_AT_KEYWORD (code) 796 || code == RID_CLASS || code == RID_PUBLIC 797 || code == RID_PROTECTED || code == RID_PRIVATE 798 || code == RID_TRY || code == RID_THROW || code == RID_CATCH); 799 } 800 801 /* Return true if TYPE is 'id'. */ 802 803 static bool 804 objc_is_object_id (tree type) 805 { 806 return OBJC_TYPE_NAME (type) == objc_object_id; 807 } 808 809 static bool 810 objc_is_class_id (tree type) 811 { 812 return OBJC_TYPE_NAME (type) == objc_class_id; 813 } 814 815 /* Construct a C struct with same name as KLASS, a base struct with tag 816 SUPER_NAME (if any), and FIELDS indicated. */ 817 818 static tree 819 objc_build_struct (tree klass, tree fields, tree super_name) 820 { 821 tree name = CLASS_NAME (klass); 822 tree s = objc_start_struct (name); 823 tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE); 824 tree t, objc_info = NULL_TREE; 825 826 if (super) 827 { 828 /* Prepend a packed variant of the base class into the layout. This 829 is necessary to preserve ObjC ABI compatibility. */ 830 tree base = build_decl (input_location, 831 FIELD_DECL, NULL_TREE, super); 832 tree field = TYPE_FIELDS (super); 833 834 while (field && TREE_CHAIN (field) 835 && TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL) 836 field = TREE_CHAIN (field); 837 838 /* For ObjC ABI purposes, the "packed" size of a base class is 839 the sum of the offset and the size (in bits) of the last field 840 in the class. */ 841 DECL_SIZE (base) 842 = (field && TREE_CODE (field) == FIELD_DECL 843 ? size_binop (PLUS_EXPR, 844 size_binop (PLUS_EXPR, 845 size_binop 846 (MULT_EXPR, 847 convert (bitsizetype, 848 DECL_FIELD_OFFSET (field)), 849 bitsize_int (BITS_PER_UNIT)), 850 DECL_FIELD_BIT_OFFSET (field)), 851 DECL_SIZE (field)) 852 : bitsize_zero_node); 853 DECL_SIZE_UNIT (base) 854 = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)), 855 size_int (BITS_PER_UNIT)); 856 DECL_ARTIFICIAL (base) = 1; 857 DECL_ALIGN (base) = 1; 858 DECL_FIELD_CONTEXT (base) = s; 859 #ifdef OBJCPLUS 860 DECL_FIELD_IS_BASE (base) = 1; 861 862 if (fields) 863 TREE_NO_WARNING (fields) = 1; /* Suppress C++ ABI warnings -- we */ 864 #endif /* are following the ObjC ABI here. */ 865 TREE_CHAIN (base) = fields; 866 fields = base; 867 } 868 869 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields 870 in all variants of this RECORD_TYPE to be clobbered, but it is therein 871 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>'). 872 Hence, we must squirrel away the ObjC-specific information before calling 873 finish_struct(), and then reinstate it afterwards. */ 874 875 for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t)) 876 { 877 if (!TYPE_HAS_OBJC_INFO (t)) 878 { 879 INIT_TYPE_OBJC_INFO (t); 880 TYPE_OBJC_INTERFACE (t) = klass; 881 } 882 objc_info 883 = chainon (objc_info, 884 build_tree_list (NULL_TREE, TYPE_OBJC_INFO (t))); 885 } 886 887 /* Point the struct at its related Objective-C class. */ 888 INIT_TYPE_OBJC_INFO (s); 889 TYPE_OBJC_INTERFACE (s) = klass; 890 891 s = objc_finish_struct (s, fields); 892 893 for (t = TYPE_NEXT_VARIANT (s); t; 894 t = TYPE_NEXT_VARIANT (t), objc_info = TREE_CHAIN (objc_info)) 895 { 896 TYPE_OBJC_INFO (t) = TREE_VALUE (objc_info); 897 /* Replace the IDENTIFIER_NODE with an actual @interface. */ 898 TYPE_OBJC_INTERFACE (t) = klass; 899 } 900 901 /* Use TYPE_BINFO structures to point at the super class, if any. */ 902 objc_xref_basetypes (s, super); 903 904 /* Mark this struct as a class template. */ 905 CLASS_STATIC_TEMPLATE (klass) = s; 906 907 return s; 908 } 909 910 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set. 911 Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the 912 process. */ 913 static tree 914 objc_build_volatilized_type (tree type) 915 { 916 tree t; 917 918 /* Check if we have not constructed the desired variant already. */ 919 for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) 920 { 921 /* The type qualifiers must (obviously) match up. */ 922 if (!TYPE_VOLATILE (t) 923 || (TYPE_READONLY (t) != TYPE_READONLY (type)) 924 || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type))) 925 continue; 926 927 /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC 928 info, if any) must match up. */ 929 if (POINTER_TYPE_P (t) 930 && (TREE_TYPE (t) != TREE_TYPE (type))) 931 continue; 932 933 /* Everything matches up! */ 934 return t; 935 } 936 937 /* Ok, we could not re-use any of the pre-existing variants. Create 938 a new one. */ 939 t = build_variant_type_copy (type); 940 TYPE_VOLATILE (t) = 1; 941 942 /* Set up the canonical type information. */ 943 if (TYPE_STRUCTURAL_EQUALITY_P (type)) 944 SET_TYPE_STRUCTURAL_EQUALITY (t); 945 else if (TYPE_CANONICAL (type) != type) 946 TYPE_CANONICAL (t) = objc_build_volatilized_type (TYPE_CANONICAL (type)); 947 else 948 TYPE_CANONICAL (t) = t; 949 950 return t; 951 } 952 953 /* Mark DECL as being 'volatile' for purposes of Darwin 954 _setjmp()/_longjmp() exception handling. Called from 955 objc_mark_locals_volatile(). */ 956 void 957 objc_volatilize_decl (tree decl) 958 { 959 /* Do not mess with variables that are 'static' or (already) 960 'volatile'. */ 961 if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl) 962 && (TREE_CODE (decl) == VAR_DECL 963 || TREE_CODE (decl) == PARM_DECL)) 964 { 965 tree t = TREE_TYPE (decl); 966 struct volatilized_type key; 967 void **loc; 968 969 t = objc_build_volatilized_type (t); 970 key.type = t; 971 loc = htab_find_slot (volatilized_htab, &key, INSERT); 972 973 if (!*loc) 974 { 975 *loc = ggc_alloc (sizeof (key)); 976 ((struct volatilized_type *) *loc)->type = t; 977 } 978 979 TREE_TYPE (decl) = t; 980 TREE_THIS_VOLATILE (decl) = 1; 981 TREE_SIDE_EFFECTS (decl) = 1; 982 DECL_REGISTER (decl) = 0; 983 #ifndef OBJCPLUS 984 C_DECL_REGISTER (decl) = 0; 985 #endif 986 } 987 } 988 989 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS 990 (including its categories and superclasses) or by object type TYP. 991 Issue a warning if PROTO is not adopted anywhere and WARN is set. */ 992 993 static bool 994 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn) 995 { 996 bool class_type = (cls != NULL_TREE); 997 998 while (cls) 999 { 1000 tree c; 1001 1002 /* Check protocols adopted by the class and its categories. */ 1003 for (c = cls; c; c = CLASS_CATEGORY_LIST (c)) 1004 { 1005 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto)) 1006 return true; 1007 } 1008 1009 /* Repeat for superclasses. */ 1010 cls = lookup_interface (CLASS_SUPER_NAME (cls)); 1011 } 1012 1013 /* Check for any protocols attached directly to the object type. */ 1014 if (TYPE_HAS_OBJC_INFO (typ)) 1015 { 1016 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto)) 1017 return true; 1018 } 1019 1020 if (warn) 1021 { 1022 *errbuf = 0; 1023 gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ)); 1024 /* NB: Types 'id' and 'Class' cannot reasonably be described as 1025 "implementing" a given protocol, since they do not have an 1026 implementation. */ 1027 if (class_type) 1028 warning (0, "class %qs does not implement the %qE protocol", 1029 identifier_to_locale (errbuf), PROTOCOL_NAME (proto)); 1030 else 1031 warning (0, "type %qs does not conform to the %qE protocol", 1032 identifier_to_locale (errbuf), PROTOCOL_NAME (proto)); 1033 } 1034 1035 return false; 1036 } 1037 1038 /* Check if class RCLS and instance struct type RTYP conform to at least the 1039 same protocols that LCLS and LTYP conform to. */ 1040 1041 static bool 1042 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn) 1043 { 1044 tree p; 1045 bool have_lproto = false; 1046 1047 while (lcls) 1048 { 1049 /* NB: We do _not_ look at categories defined for LCLS; these may or 1050 may not get loaded in, and therefore it is unreasonable to require 1051 that RCLS/RTYP must implement any of their protocols. */ 1052 for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p)) 1053 { 1054 have_lproto = true; 1055 1056 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn)) 1057 return warn; 1058 } 1059 1060 /* Repeat for superclasses. */ 1061 lcls = lookup_interface (CLASS_SUPER_NAME (lcls)); 1062 } 1063 1064 /* Check for any protocols attached directly to the object type. */ 1065 if (TYPE_HAS_OBJC_INFO (ltyp)) 1066 { 1067 for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p)) 1068 { 1069 have_lproto = true; 1070 1071 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn)) 1072 return warn; 1073 } 1074 } 1075 1076 /* NB: If LTYP and LCLS have no protocols to search for, return 'true' 1077 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get 1078 away with simply checking for 'id' or 'Class' (!RCLS), since this 1079 routine will not get called in other cases. */ 1080 return have_lproto || (rcls != NULL_TREE); 1081 } 1082 1083 /* Determine if it is permissible to assign (if ARGNO is greater than -3) 1084 an instance of RTYP to an instance of LTYP or to compare the two 1085 (if ARGNO is equal to -3), per ObjC type system rules. Before 1086 returning 'true', this routine may issue warnings related to, e.g., 1087 protocol conformance. When returning 'false', the routine must 1088 produce absolutely no warnings; the C or C++ front-end will do so 1089 instead, if needed. If either LTYP or RTYP is not an Objective-C type, 1090 the routine must return 'false'. 1091 1092 The ARGNO parameter is encoded as follows: 1093 >= 1 Parameter number (CALLEE contains function being called); 1094 0 Return value; 1095 -1 Assignment; 1096 -2 Initialization; 1097 -3 Comparison (LTYP and RTYP may match in either direction). */ 1098 1099 bool 1100 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee) 1101 { 1102 tree lcls, rcls, lproto, rproto; 1103 bool pointers_compatible; 1104 1105 /* We must be dealing with pointer types */ 1106 if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp)) 1107 return false; 1108 1109 do 1110 { 1111 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */ 1112 rtyp = TREE_TYPE (rtyp); 1113 } 1114 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp)); 1115 1116 /* Past this point, we are only interested in ObjC class instances, 1117 or 'id' or 'Class'. */ 1118 if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE) 1119 return false; 1120 1121 if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp) 1122 && !TYPE_HAS_OBJC_INFO (ltyp)) 1123 return false; 1124 1125 if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp) 1126 && !TYPE_HAS_OBJC_INFO (rtyp)) 1127 return false; 1128 1129 /* Past this point, we are committed to returning 'true' to the caller. 1130 However, we can still warn about type and/or protocol mismatches. */ 1131 1132 if (TYPE_HAS_OBJC_INFO (ltyp)) 1133 { 1134 lcls = TYPE_OBJC_INTERFACE (ltyp); 1135 lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp); 1136 } 1137 else 1138 lcls = lproto = NULL_TREE; 1139 1140 if (TYPE_HAS_OBJC_INFO (rtyp)) 1141 { 1142 rcls = TYPE_OBJC_INTERFACE (rtyp); 1143 rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp); 1144 } 1145 else 1146 rcls = rproto = NULL_TREE; 1147 1148 /* If we could not find an @interface declaration, we must have 1149 only seen a @class declaration; for purposes of type comparison, 1150 treat it as a stand-alone (root) class. */ 1151 1152 if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE) 1153 lcls = NULL_TREE; 1154 1155 if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE) 1156 rcls = NULL_TREE; 1157 1158 /* If either type is an unqualified 'id', we're done. */ 1159 if ((!lproto && objc_is_object_id (ltyp)) 1160 || (!rproto && objc_is_object_id (rtyp))) 1161 return true; 1162 1163 pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp)); 1164 1165 /* If the underlying types are the same, and at most one of them has 1166 a protocol list, we do not need to issue any diagnostics. */ 1167 if (pointers_compatible && (!lproto || !rproto)) 1168 return true; 1169 1170 /* If exactly one of the types is 'Class', issue a diagnostic; any 1171 exceptions of this rule have already been handled. */ 1172 if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp)) 1173 pointers_compatible = false; 1174 /* Otherwise, check for inheritance relations. */ 1175 else 1176 { 1177 if (!pointers_compatible) 1178 pointers_compatible 1179 = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp)); 1180 1181 if (!pointers_compatible) 1182 pointers_compatible = DERIVED_FROM_P (ltyp, rtyp); 1183 1184 if (!pointers_compatible && argno == -3) 1185 pointers_compatible = DERIVED_FROM_P (rtyp, ltyp); 1186 } 1187 1188 /* If the pointers match modulo protocols, check for protocol conformance 1189 mismatches. */ 1190 if (pointers_compatible) 1191 { 1192 pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp, 1193 argno != -3); 1194 1195 if (!pointers_compatible && argno == -3) 1196 pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp, 1197 argno != -3); 1198 } 1199 1200 if (!pointers_compatible) 1201 { 1202 /* NB: For the time being, we shall make our warnings look like their 1203 C counterparts. In the future, we may wish to make them more 1204 ObjC-specific. */ 1205 switch (argno) 1206 { 1207 case -3: 1208 warning (0, "comparison of distinct Objective-C types lacks a cast"); 1209 break; 1210 1211 case -2: 1212 warning (0, "initialization from distinct Objective-C type"); 1213 break; 1214 1215 case -1: 1216 warning (0, "assignment from distinct Objective-C type"); 1217 break; 1218 1219 case 0: 1220 warning (0, "distinct Objective-C type in return"); 1221 break; 1222 1223 default: 1224 warning (0, "passing argument %d of %qE from distinct " 1225 "Objective-C type", argno, callee); 1226 break; 1227 } 1228 } 1229 1230 return true; 1231 } 1232 1233 /* Check if LTYP and RTYP have the same type qualifiers. If either type 1234 lives in the volatilized hash table, ignore the 'volatile' bit when 1235 making the comparison. */ 1236 1237 bool 1238 objc_type_quals_match (tree ltyp, tree rtyp) 1239 { 1240 int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp); 1241 struct volatilized_type key; 1242 1243 key.type = ltyp; 1244 1245 if (htab_find_slot (volatilized_htab, &key, NO_INSERT)) 1246 lquals &= ~TYPE_QUAL_VOLATILE; 1247 1248 key.type = rtyp; 1249 1250 if (htab_find_slot (volatilized_htab, &key, NO_INSERT)) 1251 rquals &= ~TYPE_QUAL_VOLATILE; 1252 1253 return (lquals == rquals); 1254 } 1255 1256 #ifndef OBJCPLUS 1257 /* Determine if CHILD is derived from PARENT. The routine assumes that 1258 both parameters are RECORD_TYPEs, and is non-reflexive. */ 1259 1260 static bool 1261 objc_derived_from_p (tree parent, tree child) 1262 { 1263 parent = TYPE_MAIN_VARIANT (parent); 1264 1265 for (child = TYPE_MAIN_VARIANT (child); 1266 TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));) 1267 { 1268 child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO 1269 (TYPE_BINFO (child), 1270 0))); 1271 1272 if (child == parent) 1273 return true; 1274 } 1275 1276 return false; 1277 } 1278 #endif 1279 1280 static tree 1281 objc_build_component_ref (tree datum, tree component) 1282 { 1283 /* If COMPONENT is NULL, the caller is referring to the anonymous 1284 base class field. */ 1285 if (!component) 1286 { 1287 tree base = TYPE_FIELDS (TREE_TYPE (datum)); 1288 1289 return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE); 1290 } 1291 1292 /* The 'build_component_ref' routine has been removed from the C++ 1293 front-end, but 'finish_class_member_access_expr' seems to be 1294 a worthy substitute. */ 1295 #ifdef OBJCPLUS 1296 return finish_class_member_access_expr (datum, component, false, 1297 tf_warning_or_error); 1298 #else 1299 return build_component_ref (input_location, datum, component); 1300 #endif 1301 } 1302 1303 /* Recursively copy inheritance information rooted at BINFO. To do this, 1304 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */ 1305 1306 static tree 1307 objc_copy_binfo (tree binfo) 1308 { 1309 tree btype = BINFO_TYPE (binfo); 1310 tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo)); 1311 tree base_binfo; 1312 int ix; 1313 1314 BINFO_TYPE (binfo2) = btype; 1315 BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo); 1316 BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo); 1317 1318 /* Recursively copy base binfos of BINFO. */ 1319 for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++) 1320 { 1321 tree base_binfo2 = objc_copy_binfo (base_binfo); 1322 1323 BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2; 1324 BINFO_BASE_APPEND (binfo2, base_binfo2); 1325 } 1326 1327 return binfo2; 1328 } 1329 1330 /* Record superclass information provided in BASETYPE for ObjC class REF. 1331 This is loosely based on cp/decl.c:xref_basetypes(). */ 1332 1333 static void 1334 objc_xref_basetypes (tree ref, tree basetype) 1335 { 1336 tree binfo = make_tree_binfo (basetype ? 1 : 0); 1337 1338 TYPE_BINFO (ref) = binfo; 1339 BINFO_OFFSET (binfo) = size_zero_node; 1340 BINFO_TYPE (binfo) = ref; 1341 1342 if (basetype) 1343 { 1344 tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype)); 1345 1346 BINFO_INHERITANCE_CHAIN (base_binfo) = binfo; 1347 BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1); 1348 BINFO_BASE_APPEND (binfo, base_binfo); 1349 BINFO_BASE_ACCESS_APPEND (binfo, access_public_node); 1350 } 1351 } 1352 1353 static hashval_t 1354 volatilized_hash (const void *ptr) 1355 { 1356 const_tree const typ = ((const struct volatilized_type *)ptr)->type; 1357 1358 return htab_hash_pointer(typ); 1359 } 1360 1361 static int 1362 volatilized_eq (const void *ptr1, const void *ptr2) 1363 { 1364 const_tree const typ1 = ((const struct volatilized_type *)ptr1)->type; 1365 const_tree const typ2 = ((const struct volatilized_type *)ptr2)->type; 1366 1367 return typ1 == typ2; 1368 } 1369 1370 /* Called from finish_decl. */ 1371 1372 void 1373 objc_check_decl (tree decl) 1374 { 1375 tree type = TREE_TYPE (decl); 1376 1377 if (TREE_CODE (type) != RECORD_TYPE) 1378 return; 1379 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type)))) 1380 error ("statically allocated instance of Objective-C class %qE", 1381 type); 1382 } 1383 1384 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may 1385 either name an Objective-C class, or refer to the special 'id' or 'Class' 1386 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */ 1387 1388 tree 1389 objc_get_protocol_qualified_type (tree interface, tree protocols) 1390 { 1391 /* If INTERFACE is not provided, default to 'id'. */ 1392 tree type = (interface ? objc_is_id (interface) : objc_object_type); 1393 bool is_ptr = (type != NULL_TREE); 1394 1395 if (!is_ptr) 1396 { 1397 type = objc_is_class_name (interface); 1398 1399 if (type) 1400 type = xref_tag (RECORD_TYPE, type); 1401 else 1402 return interface; 1403 } 1404 1405 if (protocols) 1406 { 1407 type = build_variant_type_copy (type); 1408 1409 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s) 1410 to the pointee. */ 1411 if (is_ptr) 1412 { 1413 tree orig_pointee_type = TREE_TYPE (type); 1414 TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type); 1415 1416 /* Set up the canonical type information. */ 1417 TYPE_CANONICAL (type) 1418 = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type)); 1419 1420 TYPE_POINTER_TO (TREE_TYPE (type)) = type; 1421 type = TREE_TYPE (type); 1422 } 1423 1424 /* Look up protocols and install in lang specific list. */ 1425 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type)); 1426 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols); 1427 1428 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class', 1429 return the pointer to the new pointee variant. */ 1430 if (is_ptr) 1431 type = TYPE_POINTER_TO (type); 1432 else 1433 TYPE_OBJC_INTERFACE (type) 1434 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type)); 1435 } 1436 1437 return type; 1438 } 1439 1440 /* Check for circular dependencies in protocols. The arguments are 1441 PROTO, the protocol to check, and LIST, a list of protocol it 1442 conforms to. */ 1443 1444 static void 1445 check_protocol_recursively (tree proto, tree list) 1446 { 1447 tree p; 1448 1449 for (p = list; p; p = TREE_CHAIN (p)) 1450 { 1451 tree pp = TREE_VALUE (p); 1452 1453 if (TREE_CODE (pp) == IDENTIFIER_NODE) 1454 pp = lookup_protocol (pp); 1455 1456 if (pp == proto) 1457 fatal_error ("protocol %qE has circular dependency", 1458 PROTOCOL_NAME (pp)); 1459 if (pp) 1460 check_protocol_recursively (proto, PROTOCOL_LIST (pp)); 1461 } 1462 } 1463 1464 /* Look up PROTOCOLS, and return a list of those that are found. 1465 If none are found, return NULL. */ 1466 1467 static tree 1468 lookup_and_install_protocols (tree protocols) 1469 { 1470 tree proto; 1471 tree return_value = NULL_TREE; 1472 1473 for (proto = protocols; proto; proto = TREE_CHAIN (proto)) 1474 { 1475 tree ident = TREE_VALUE (proto); 1476 tree p = lookup_protocol (ident); 1477 1478 if (p) 1479 return_value = chainon (return_value, 1480 build_tree_list (NULL_TREE, p)); 1481 else if (ident != error_mark_node) 1482 error ("cannot find protocol declaration for %qE", 1483 ident); 1484 } 1485 1486 return return_value; 1487 } 1488 1489 /* Create a declaration for field NAME of a given TYPE. */ 1490 1491 static tree 1492 create_field_decl (tree type, const char *name) 1493 { 1494 return build_decl (input_location, 1495 FIELD_DECL, get_identifier (name), type); 1496 } 1497 1498 /* Create a global, static declaration for variable NAME of a given TYPE. The 1499 finish_var_decl() routine will need to be called on it afterwards. */ 1500 1501 static tree 1502 start_var_decl (tree type, const char *name) 1503 { 1504 tree var = build_decl (input_location, 1505 VAR_DECL, get_identifier (name), type); 1506 1507 TREE_STATIC (var) = 1; 1508 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */ 1509 DECL_IGNORED_P (var) = 1; 1510 DECL_ARTIFICIAL (var) = 1; 1511 DECL_CONTEXT (var) = NULL_TREE; 1512 #ifdef OBJCPLUS 1513 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */ 1514 #endif 1515 1516 return var; 1517 } 1518 1519 /* Finish off the variable declaration created by start_var_decl(). */ 1520 1521 static void 1522 finish_var_decl (tree var, tree initializer) 1523 { 1524 finish_decl (var, input_location, initializer, NULL_TREE, NULL_TREE); 1525 /* Ensure that the variable actually gets output. */ 1526 mark_decl_referenced (var); 1527 /* Mark the decl to avoid "defined but not used" warning. */ 1528 TREE_USED (var) = 1; 1529 /* We reserve the right for the runtime to use/modify these variables 1530 in ways that are opaque to us. */ 1531 DECL_PRESERVE_P (var) = 1; 1532 } 1533 1534 /* Find the decl for the constant string class reference. This is only 1535 used for the NeXT runtime. */ 1536 1537 static tree 1538 setup_string_decl (void) 1539 { 1540 char *name; 1541 size_t length; 1542 1543 /* %s in format will provide room for terminating null */ 1544 length = strlen (STRING_OBJECT_GLOBAL_FORMAT) 1545 + strlen (constant_string_class_name); 1546 name = XNEWVEC (char, length); 1547 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT, 1548 constant_string_class_name); 1549 constant_string_global_id = get_identifier (name); 1550 string_class_decl = lookup_name (constant_string_global_id); 1551 1552 return string_class_decl; 1553 } 1554 1555 /* Purpose: "play" parser, creating/installing representations 1556 of the declarations that are required by Objective-C. 1557 1558 Model: 1559 1560 type_spec--------->sc_spec 1561 (tree_list) (tree_list) 1562 | | 1563 | | 1564 identifier_node identifier_node */ 1565 1566 static void 1567 synth_module_prologue (void) 1568 { 1569 tree type; 1570 enum debug_info_type save_write_symbols = write_symbols; 1571 const struct gcc_debug_hooks *const save_hooks = debug_hooks; 1572 1573 /* Suppress outputting debug symbols, because 1574 dbxout_init hasn't been called yet. */ 1575 write_symbols = NO_DEBUG; 1576 debug_hooks = &do_nothing_debug_hooks; 1577 1578 #ifdef OBJCPLUS 1579 push_lang_context (lang_name_c); /* extern "C" */ 1580 #endif 1581 1582 /* The following are also defined in <objc/objc.h> and friends. */ 1583 1584 objc_object_id = get_identifier (TAG_OBJECT); 1585 objc_class_id = get_identifier (TAG_CLASS); 1586 1587 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id); 1588 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id); 1589 1590 objc_object_type = build_pointer_type (objc_object_reference); 1591 objc_class_type = build_pointer_type (objc_class_reference); 1592 1593 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME); 1594 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME); 1595 1596 /* Declare the 'id' and 'Class' typedefs. */ 1597 1598 type = lang_hooks.decls.pushdecl (build_decl (input_location, 1599 TYPE_DECL, 1600 objc_object_name, 1601 objc_object_type)); 1602 TREE_NO_WARNING (type) = 1; 1603 type = lang_hooks.decls.pushdecl (build_decl (input_location, 1604 TYPE_DECL, 1605 objc_class_name, 1606 objc_class_type)); 1607 TREE_NO_WARNING (type) = 1; 1608 1609 /* Forward-declare '@interface Protocol'. */ 1610 1611 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME); 1612 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE)); 1613 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE, 1614 type)); 1615 1616 /* Declare type of selector-objects that represent an operation name. */ 1617 1618 if (flag_next_runtime) 1619 /* `struct objc_selector *' */ 1620 objc_selector_type 1621 = build_pointer_type (xref_tag (RECORD_TYPE, 1622 get_identifier (TAG_SELECTOR))); 1623 else 1624 /* `const struct objc_selector *' */ 1625 objc_selector_type 1626 = build_pointer_type 1627 (build_qualified_type (xref_tag (RECORD_TYPE, 1628 get_identifier (TAG_SELECTOR)), 1629 TYPE_QUAL_CONST)); 1630 1631 /* Declare receiver type used for dispatching messages to 'super'. */ 1632 1633 /* `struct objc_super *' */ 1634 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE, 1635 get_identifier (TAG_SUPER))); 1636 1637 /* Declare pointers to method and ivar lists. */ 1638 objc_method_list_ptr = build_pointer_type 1639 (xref_tag (RECORD_TYPE, 1640 get_identifier (UTAG_METHOD_LIST))); 1641 objc_method_proto_list_ptr 1642 = build_pointer_type (xref_tag (RECORD_TYPE, 1643 get_identifier (UTAG_METHOD_PROTOTYPE_LIST))); 1644 objc_ivar_list_ptr = build_pointer_type 1645 (xref_tag (RECORD_TYPE, 1646 get_identifier (UTAG_IVAR_LIST))); 1647 1648 /* TREE_NOTHROW is cleared for the message-sending functions, 1649 because the function that gets called can throw in Obj-C++, or 1650 could itself call something that can throw even in Obj-C. */ 1651 1652 if (flag_next_runtime) 1653 { 1654 /* NB: In order to call one of the ..._stret (struct-returning) 1655 functions, the function *MUST* first be cast to a signature that 1656 corresponds to the actual ObjC method being invoked. This is 1657 what is done by the build_objc_method_call() routine below. */ 1658 1659 /* id objc_msgSend (id, SEL, ...); */ 1660 /* id objc_msgSendNonNil (id, SEL, ...); */ 1661 /* id objc_msgSend_stret (id, SEL, ...); */ 1662 /* id objc_msgSendNonNil_stret (id, SEL, ...); */ 1663 type 1664 = build_function_type (objc_object_type, 1665 tree_cons (NULL_TREE, objc_object_type, 1666 tree_cons (NULL_TREE, objc_selector_type, 1667 NULL_TREE))); 1668 umsg_decl = add_builtin_function (TAG_MSGSEND, 1669 type, 0, NOT_BUILT_IN, 1670 NULL, NULL_TREE); 1671 umsg_nonnil_decl = add_builtin_function (TAG_MSGSEND_NONNIL, 1672 type, 0, NOT_BUILT_IN, 1673 NULL, NULL_TREE); 1674 umsg_stret_decl = add_builtin_function (TAG_MSGSEND_STRET, 1675 type, 0, NOT_BUILT_IN, 1676 NULL, NULL_TREE); 1677 umsg_nonnil_stret_decl = add_builtin_function (TAG_MSGSEND_NONNIL_STRET, 1678 type, 0, NOT_BUILT_IN, 1679 NULL, NULL_TREE); 1680 1681 /* These can throw, because the function that gets called can throw 1682 in Obj-C++, or could itself call something that can throw even 1683 in Obj-C. */ 1684 TREE_NOTHROW (umsg_decl) = 0; 1685 TREE_NOTHROW (umsg_nonnil_decl) = 0; 1686 TREE_NOTHROW (umsg_stret_decl) = 0; 1687 TREE_NOTHROW (umsg_nonnil_stret_decl) = 0; 1688 1689 /* id objc_msgSend_Fast (id, SEL, ...) 1690 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */ 1691 #ifdef OFFS_MSGSEND_FAST 1692 umsg_fast_decl = add_builtin_function (TAG_MSGSEND_FAST, 1693 type, 0, NOT_BUILT_IN, 1694 NULL, NULL_TREE); 1695 TREE_NOTHROW (umsg_fast_decl) = 0; 1696 DECL_ATTRIBUTES (umsg_fast_decl) 1697 = tree_cons (get_identifier ("hard_coded_address"), 1698 build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST), 1699 NULL_TREE); 1700 #else 1701 /* No direct dispatch available. */ 1702 umsg_fast_decl = umsg_decl; 1703 #endif 1704 1705 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */ 1706 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */ 1707 type 1708 = build_function_type (objc_object_type, 1709 tree_cons (NULL_TREE, objc_super_type, 1710 tree_cons (NULL_TREE, objc_selector_type, 1711 NULL_TREE))); 1712 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER, 1713 type, 0, NOT_BUILT_IN, 1714 NULL, NULL_TREE); 1715 umsg_super_stret_decl = add_builtin_function (TAG_MSGSENDSUPER_STRET, 1716 type, 0, NOT_BUILT_IN, 0, 1717 NULL_TREE); 1718 TREE_NOTHROW (umsg_super_decl) = 0; 1719 TREE_NOTHROW (umsg_super_stret_decl) = 0; 1720 } 1721 else 1722 { 1723 /* GNU runtime messenger entry points. */ 1724 1725 /* typedef id (*IMP)(id, SEL, ...); */ 1726 tree IMP_type 1727 = build_pointer_type 1728 (build_function_type (objc_object_type, 1729 tree_cons (NULL_TREE, objc_object_type, 1730 tree_cons (NULL_TREE, objc_selector_type, 1731 NULL_TREE)))); 1732 1733 /* IMP objc_msg_lookup (id, SEL); */ 1734 type 1735 = build_function_type (IMP_type, 1736 tree_cons (NULL_TREE, objc_object_type, 1737 tree_cons (NULL_TREE, objc_selector_type, 1738 OBJC_VOID_AT_END))); 1739 umsg_decl = add_builtin_function (TAG_MSGSEND, 1740 type, 0, NOT_BUILT_IN, 1741 NULL, NULL_TREE); 1742 TREE_NOTHROW (umsg_decl) = 0; 1743 1744 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */ 1745 type 1746 = build_function_type (IMP_type, 1747 tree_cons (NULL_TREE, objc_super_type, 1748 tree_cons (NULL_TREE, objc_selector_type, 1749 OBJC_VOID_AT_END))); 1750 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER, 1751 type, 0, NOT_BUILT_IN, 1752 NULL, NULL_TREE); 1753 TREE_NOTHROW (umsg_super_decl) = 0; 1754 1755 /* The following GNU runtime entry point is called to initialize 1756 each module: 1757 1758 __objc_exec_class (void *); */ 1759 type 1760 = build_function_type (void_type_node, 1761 tree_cons (NULL_TREE, ptr_type_node, 1762 OBJC_VOID_AT_END)); 1763 execclass_decl = add_builtin_function (TAG_EXECCLASS, 1764 type, 0, NOT_BUILT_IN, 1765 NULL, NULL_TREE); 1766 } 1767 1768 /* id objc_getClass (const char *); */ 1769 1770 type = build_function_type (objc_object_type, 1771 tree_cons (NULL_TREE, 1772 const_string_type_node, 1773 OBJC_VOID_AT_END)); 1774 1775 objc_get_class_decl 1776 = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN, 1777 NULL, NULL_TREE); 1778 1779 /* id objc_getMetaClass (const char *); */ 1780 1781 objc_get_meta_class_decl 1782 = add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE); 1783 1784 build_class_template (); 1785 build_super_template (); 1786 build_protocol_template (); 1787 build_category_template (); 1788 build_objc_exception_stuff (); 1789 1790 if (flag_next_runtime) 1791 build_next_objc_exception_stuff (); 1792 1793 /* static SEL _OBJC_SELECTOR_TABLE[]; */ 1794 1795 if (! flag_next_runtime) 1796 build_selector_table_decl (); 1797 1798 /* Forward declare constant_string_id and constant_string_type. */ 1799 if (!constant_string_class_name) 1800 constant_string_class_name = default_constant_string_class_name; 1801 1802 constant_string_id = get_identifier (constant_string_class_name); 1803 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE)); 1804 1805 /* Pre-build the following entities - for speed/convenience. */ 1806 self_id = get_identifier ("self"); 1807 ucmd_id = get_identifier ("_cmd"); 1808 1809 #ifdef OBJCPLUS 1810 pop_lang_context (); 1811 #endif 1812 1813 write_symbols = save_write_symbols; 1814 debug_hooks = save_hooks; 1815 } 1816 1817 /* Ensure that the ivar list for NSConstantString/NXConstantString 1818 (or whatever was specified via `-fconstant-string-class') 1819 contains fields at least as large as the following three, so that 1820 the runtime can stomp on them with confidence: 1821 1822 struct STRING_OBJECT_CLASS_NAME 1823 { 1824 Object isa; 1825 char *cString; 1826 unsigned int length; 1827 }; */ 1828 1829 static int 1830 check_string_class_template (void) 1831 { 1832 tree field_decl = objc_get_class_ivars (constant_string_id); 1833 1834 #define AT_LEAST_AS_LARGE_AS(F, T) \ 1835 (F && TREE_CODE (F) == FIELD_DECL \ 1836 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \ 1837 >= TREE_INT_CST_LOW (TYPE_SIZE (T)))) 1838 1839 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node)) 1840 return 0; 1841 1842 field_decl = TREE_CHAIN (field_decl); 1843 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node)) 1844 return 0; 1845 1846 field_decl = TREE_CHAIN (field_decl); 1847 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node); 1848 1849 #undef AT_LEAST_AS_LARGE_AS 1850 } 1851 1852 /* Avoid calling `check_string_class_template ()' more than once. */ 1853 static GTY(()) int string_layout_checked; 1854 1855 /* Construct an internal string layout to be used as a template for 1856 creating NSConstantString/NXConstantString instances. */ 1857 1858 static tree 1859 objc_build_internal_const_str_type (void) 1860 { 1861 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE); 1862 tree fields = build_decl (input_location, 1863 FIELD_DECL, NULL_TREE, ptr_type_node); 1864 tree field = build_decl (input_location, 1865 FIELD_DECL, NULL_TREE, ptr_type_node); 1866 1867 TREE_CHAIN (field) = fields; fields = field; 1868 field = build_decl (input_location, 1869 FIELD_DECL, NULL_TREE, unsigned_type_node); 1870 TREE_CHAIN (field) = fields; fields = field; 1871 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in 1872 reverse order! */ 1873 finish_builtin_struct (type, "__builtin_ObjCString", 1874 fields, NULL_TREE); 1875 1876 return type; 1877 } 1878 1879 /* Custom build_string which sets TREE_TYPE! */ 1880 1881 static tree 1882 my_build_string (int len, const char *str) 1883 { 1884 return fix_string_type (build_string (len, str)); 1885 } 1886 1887 /* Build a string with contents STR and length LEN and convert it to a 1888 pointer. */ 1889 1890 static tree 1891 my_build_string_pointer (int len, const char *str) 1892 { 1893 tree string = my_build_string (len, str); 1894 tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string))); 1895 return build1 (ADDR_EXPR, ptrtype, string); 1896 } 1897 1898 static hashval_t 1899 string_hash (const void *ptr) 1900 { 1901 const_tree const str = ((const struct string_descriptor *)ptr)->literal; 1902 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str); 1903 int i, len = TREE_STRING_LENGTH (str); 1904 hashval_t h = len; 1905 1906 for (i = 0; i < len; i++) 1907 h = ((h * 613) + p[i]); 1908 1909 return h; 1910 } 1911 1912 static int 1913 string_eq (const void *ptr1, const void *ptr2) 1914 { 1915 const_tree const str1 = ((const struct string_descriptor *)ptr1)->literal; 1916 const_tree const str2 = ((const struct string_descriptor *)ptr2)->literal; 1917 int len1 = TREE_STRING_LENGTH (str1); 1918 1919 return (len1 == TREE_STRING_LENGTH (str2) 1920 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2), 1921 len1)); 1922 } 1923 1924 /* Given a chain of STRING_CST's, build a static instance of 1925 NXConstantString which points at the concatenation of those 1926 strings. We place the string object in the __string_objects 1927 section of the __OBJC segment. The Objective-C runtime will 1928 initialize the isa pointers of the string objects to point at the 1929 NXConstantString class object. */ 1930 1931 tree 1932 objc_build_string_object (tree string) 1933 { 1934 tree initlist, constructor, constant_string_class; 1935 int length; 1936 tree fields, addr; 1937 struct string_descriptor *desc, key; 1938 void **loc; 1939 1940 /* Prep the string argument. */ 1941 string = fix_string_type (string); 1942 TREE_SET_CODE (string, STRING_CST); 1943 length = TREE_STRING_LENGTH (string) - 1; 1944 1945 /* Check whether the string class being used actually exists and has the 1946 correct ivar layout. */ 1947 if (!string_layout_checked) 1948 { 1949 string_layout_checked = -1; 1950 constant_string_class = lookup_interface (constant_string_id); 1951 internal_const_str_type = objc_build_internal_const_str_type (); 1952 1953 if (!constant_string_class 1954 || !(constant_string_type 1955 = CLASS_STATIC_TEMPLATE (constant_string_class))) 1956 error ("cannot find interface declaration for %qE", 1957 constant_string_id); 1958 /* The NSConstantString/NXConstantString ivar layout is now known. */ 1959 else if (!check_string_class_template ()) 1960 error ("interface %qE does not have valid constant string layout", 1961 constant_string_id); 1962 /* For the NeXT runtime, we can generate a literal reference 1963 to the string class, don't need to run a constructor. */ 1964 else if (flag_next_runtime && !setup_string_decl ()) 1965 error ("cannot find reference tag for class %qE", 1966 constant_string_id); 1967 else 1968 { 1969 string_layout_checked = 1; /* Success! */ 1970 add_class_reference (constant_string_id); 1971 } 1972 } 1973 1974 if (string_layout_checked == -1) 1975 return error_mark_node; 1976 1977 /* Perhaps we already constructed a constant string just like this one? */ 1978 key.literal = string; 1979 loc = htab_find_slot (string_htab, &key, INSERT); 1980 desc = (struct string_descriptor *) *loc; 1981 1982 if (!desc) 1983 { 1984 tree var; 1985 *loc = desc = GGC_NEW (struct string_descriptor); 1986 desc->literal = string; 1987 1988 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */ 1989 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */ 1990 fields = TYPE_FIELDS (internal_const_str_type); 1991 initlist 1992 = build_tree_list (fields, 1993 flag_next_runtime 1994 ? build_unary_op (input_location, 1995 ADDR_EXPR, string_class_decl, 0) 1996 : build_int_cst (NULL_TREE, 0)); 1997 fields = TREE_CHAIN (fields); 1998 initlist = tree_cons (fields, build_unary_op (input_location, 1999 ADDR_EXPR, string, 1), 2000 initlist); 2001 fields = TREE_CHAIN (fields); 2002 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length), 2003 initlist); 2004 constructor = objc_build_constructor (internal_const_str_type, 2005 nreverse (initlist)); 2006 2007 if (!flag_next_runtime) 2008 constructor 2009 = objc_add_static_instance (constructor, constant_string_type); 2010 else 2011 { 2012 var = build_decl (input_location, 2013 CONST_DECL, NULL, TREE_TYPE (constructor)); 2014 DECL_INITIAL (var) = constructor; 2015 TREE_STATIC (var) = 1; 2016 pushdecl_top_level (var); 2017 constructor = var; 2018 } 2019 desc->constructor = constructor; 2020 } 2021 2022 addr = convert (build_pointer_type (constant_string_type), 2023 build_unary_op (input_location, 2024 ADDR_EXPR, desc->constructor, 1)); 2025 2026 return addr; 2027 } 2028 2029 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */ 2030 2031 static GTY(()) int num_static_inst; 2032 2033 static tree 2034 objc_add_static_instance (tree constructor, tree class_decl) 2035 { 2036 tree *chain, decl; 2037 char buf[256]; 2038 2039 /* Find the list of static instances for the CLASS_DECL. Create one if 2040 not found. */ 2041 for (chain = &objc_static_instances; 2042 *chain && TREE_VALUE (*chain) != class_decl; 2043 chain = &TREE_CHAIN (*chain)); 2044 if (!*chain) 2045 { 2046 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE); 2047 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names); 2048 } 2049 2050 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++); 2051 decl = build_decl (input_location, 2052 VAR_DECL, get_identifier (buf), class_decl); 2053 TREE_STATIC (decl) = 1; 2054 DECL_ARTIFICIAL (decl) = 1; 2055 TREE_USED (decl) = 1; 2056 DECL_INITIAL (decl) = constructor; 2057 2058 /* We may be writing something else just now. 2059 Postpone till end of input. */ 2060 DECL_DEFER_OUTPUT (decl) = 1; 2061 pushdecl_top_level (decl); 2062 rest_of_decl_compilation (decl, 1, 0); 2063 2064 /* Add the DECL to the head of this CLASS' list. */ 2065 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain)); 2066 2067 return decl; 2068 } 2069 2070 /* Build a static constant CONSTRUCTOR 2071 with type TYPE and elements ELTS. */ 2072 2073 static tree 2074 objc_build_constructor (tree type, tree elts) 2075 { 2076 tree constructor = build_constructor_from_list (type, elts); 2077 2078 TREE_CONSTANT (constructor) = 1; 2079 TREE_STATIC (constructor) = 1; 2080 TREE_READONLY (constructor) = 1; 2081 2082 #ifdef OBJCPLUS 2083 /* Adjust for impedance mismatch. We should figure out how to build 2084 CONSTRUCTORs that consistently please both the C and C++ gods. */ 2085 if (!TREE_PURPOSE (elts)) 2086 TREE_TYPE (constructor) = init_list_type_node; 2087 #endif 2088 2089 return constructor; 2090 } 2091 2092 /* Take care of defining and initializing _OBJC_SYMBOLS. */ 2093 2094 /* Predefine the following data type: 2095 2096 struct _objc_symtab 2097 { 2098 long sel_ref_cnt; 2099 SEL *refs; 2100 short cls_def_cnt; 2101 short cat_def_cnt; 2102 void *defs[cls_def_cnt + cat_def_cnt]; 2103 }; */ 2104 2105 static void 2106 build_objc_symtab_template (void) 2107 { 2108 tree field_decl, field_decl_chain; 2109 2110 objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB)); 2111 2112 /* long sel_ref_cnt; */ 2113 field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt"); 2114 field_decl_chain = field_decl; 2115 2116 /* SEL *refs; */ 2117 field_decl = create_field_decl (build_pointer_type (objc_selector_type), 2118 "refs"); 2119 chainon (field_decl_chain, field_decl); 2120 2121 /* short cls_def_cnt; */ 2122 field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt"); 2123 chainon (field_decl_chain, field_decl); 2124 2125 /* short cat_def_cnt; */ 2126 field_decl = create_field_decl (short_integer_type_node, 2127 "cat_def_cnt"); 2128 chainon (field_decl_chain, field_decl); 2129 2130 if (imp_count || cat_count || !flag_next_runtime) 2131 { 2132 /* void *defs[imp_count + cat_count (+ 1)]; */ 2133 /* NB: The index is one less than the size of the array. */ 2134 int index = imp_count + cat_count 2135 + (flag_next_runtime? -1: 0); 2136 field_decl = create_field_decl 2137 (build_array_type 2138 (ptr_type_node, 2139 build_index_type (build_int_cst (NULL_TREE, index))), 2140 "defs"); 2141 chainon (field_decl_chain, field_decl); 2142 } 2143 2144 objc_finish_struct (objc_symtab_template, field_decl_chain); 2145 } 2146 2147 /* Create the initial value for the `defs' field of _objc_symtab. 2148 This is a CONSTRUCTOR. */ 2149 2150 static tree 2151 init_def_list (tree type) 2152 { 2153 tree expr, initlist = NULL_TREE; 2154 struct imp_entry *impent; 2155 2156 if (imp_count) 2157 for (impent = imp_list; impent; impent = impent->next) 2158 { 2159 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE) 2160 { 2161 expr = build_unary_op (input_location, 2162 ADDR_EXPR, impent->class_decl, 0); 2163 initlist = tree_cons (NULL_TREE, expr, initlist); 2164 } 2165 } 2166 2167 if (cat_count) 2168 for (impent = imp_list; impent; impent = impent->next) 2169 { 2170 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE) 2171 { 2172 expr = build_unary_op (input_location, 2173 ADDR_EXPR, impent->class_decl, 0); 2174 initlist = tree_cons (NULL_TREE, expr, initlist); 2175 } 2176 } 2177 2178 if (!flag_next_runtime) 2179 { 2180 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */ 2181 tree expr; 2182 2183 if (static_instances_decl) 2184 expr = build_unary_op (input_location, 2185 ADDR_EXPR, static_instances_decl, 0); 2186 else 2187 expr = build_int_cst (NULL_TREE, 0); 2188 2189 initlist = tree_cons (NULL_TREE, expr, initlist); 2190 } 2191 2192 return objc_build_constructor (type, nreverse (initlist)); 2193 } 2194 2195 /* Construct the initial value for all of _objc_symtab. */ 2196 2197 static tree 2198 init_objc_symtab (tree type) 2199 { 2200 tree initlist; 2201 2202 /* sel_ref_cnt = { ..., 5, ... } */ 2203 2204 initlist = build_tree_list (NULL_TREE, 2205 build_int_cst (long_integer_type_node, 0)); 2206 2207 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */ 2208 2209 if (flag_next_runtime || ! sel_ref_chain) 2210 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist); 2211 else 2212 initlist 2213 = tree_cons (NULL_TREE, 2214 convert (build_pointer_type (objc_selector_type), 2215 build_unary_op (input_location, ADDR_EXPR, 2216 UOBJC_SELECTOR_TABLE_decl, 1)), 2217 initlist); 2218 2219 /* cls_def_cnt = { ..., 5, ... } */ 2220 2221 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist); 2222 2223 /* cat_def_cnt = { ..., 5, ... } */ 2224 2225 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist); 2226 2227 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */ 2228 2229 if (imp_count || cat_count || !flag_next_runtime) 2230 { 2231 2232 tree field = TYPE_FIELDS (type); 2233 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field)))); 2234 2235 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)), 2236 initlist); 2237 } 2238 2239 return objc_build_constructor (type, nreverse (initlist)); 2240 } 2241 2242 /* Generate forward declarations for metadata such as 2243 'OBJC_CLASS_...'. */ 2244 2245 static tree 2246 build_metadata_decl (const char *name, tree type) 2247 { 2248 tree decl; 2249 2250 /* struct TYPE NAME_<name>; */ 2251 decl = start_var_decl (type, synth_id_with_class_suffix 2252 (name, 2253 objc_implementation_context)); 2254 2255 return decl; 2256 } 2257 2258 /* Push forward-declarations of all the categories so that 2259 init_def_list can use them in a CONSTRUCTOR. */ 2260 2261 static void 2262 forward_declare_categories (void) 2263 { 2264 struct imp_entry *impent; 2265 tree sav = objc_implementation_context; 2266 2267 for (impent = imp_list; impent; impent = impent->next) 2268 { 2269 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE) 2270 { 2271 /* Set an invisible arg to synth_id_with_class_suffix. */ 2272 objc_implementation_context = impent->imp_context; 2273 /* extern struct objc_category _OBJC_CATEGORY_<name>; */ 2274 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY", 2275 objc_category_template); 2276 } 2277 } 2278 objc_implementation_context = sav; 2279 } 2280 2281 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab' 2282 and initialized appropriately. */ 2283 2284 static void 2285 generate_objc_symtab_decl (void) 2286 { 2287 /* forward declare categories */ 2288 if (cat_count) 2289 forward_declare_categories (); 2290 2291 build_objc_symtab_template (); 2292 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS"); 2293 finish_var_decl (UOBJC_SYMBOLS_decl, 2294 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl))); 2295 } 2296 2297 static tree 2298 init_module_descriptor (tree type) 2299 { 2300 tree initlist, expr; 2301 2302 /* version = { 1, ... } */ 2303 2304 expr = build_int_cst (long_integer_type_node, OBJC_VERSION); 2305 initlist = build_tree_list (NULL_TREE, expr); 2306 2307 /* size = { ..., sizeof (struct _objc_module), ... } */ 2308 2309 expr = convert (long_integer_type_node, 2310 size_in_bytes (objc_module_template)); 2311 initlist = tree_cons (NULL_TREE, expr, initlist); 2312 2313 /* Don't provide any file name for security reasons. */ 2314 /* name = { ..., "", ... } */ 2315 2316 expr = add_objc_string (get_identifier (""), class_names); 2317 initlist = tree_cons (NULL_TREE, expr, initlist); 2318 2319 /* symtab = { ..., _OBJC_SYMBOLS, ... } */ 2320 2321 if (UOBJC_SYMBOLS_decl) 2322 expr = build_unary_op (input_location, 2323 ADDR_EXPR, UOBJC_SYMBOLS_decl, 0); 2324 else 2325 expr = build_int_cst (NULL_TREE, 0); 2326 initlist = tree_cons (NULL_TREE, expr, initlist); 2327 2328 return objc_build_constructor (type, nreverse (initlist)); 2329 } 2330 2331 /* Write out the data structures to describe Objective C classes defined. 2332 2333 struct _objc_module { ... } _OBJC_MODULE = { ... }; */ 2334 2335 static void 2336 build_module_descriptor (void) 2337 { 2338 tree field_decl, field_decl_chain; 2339 2340 #ifdef OBJCPLUS 2341 push_lang_context (lang_name_c); /* extern "C" */ 2342 #endif 2343 2344 objc_module_template = objc_start_struct (get_identifier (UTAG_MODULE)); 2345 2346 /* long version; */ 2347 field_decl = create_field_decl (long_integer_type_node, "version"); 2348 field_decl_chain = field_decl; 2349 2350 /* long size; */ 2351 field_decl = create_field_decl (long_integer_type_node, "size"); 2352 chainon (field_decl_chain, field_decl); 2353 2354 /* char *name; */ 2355 field_decl = create_field_decl (string_type_node, "name"); 2356 chainon (field_decl_chain, field_decl); 2357 2358 /* struct _objc_symtab *symtab; */ 2359 field_decl 2360 = create_field_decl (build_pointer_type 2361 (xref_tag (RECORD_TYPE, 2362 get_identifier (UTAG_SYMTAB))), 2363 "symtab"); 2364 chainon (field_decl_chain, field_decl); 2365 2366 objc_finish_struct (objc_module_template, field_decl_chain); 2367 2368 /* Create an instance of "_objc_module". */ 2369 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES"); 2370 finish_var_decl (UOBJC_MODULES_decl, 2371 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl))); 2372 2373 #ifdef OBJCPLUS 2374 pop_lang_context (); 2375 #endif 2376 } 2377 2378 /* The GNU runtime requires us to provide a static initializer function 2379 for each module: 2380 2381 static void __objc_gnu_init (void) { 2382 __objc_exec_class (&L_OBJC_MODULES); 2383 } */ 2384 2385 static void 2386 build_module_initializer_routine (void) 2387 { 2388 tree body; 2389 2390 #ifdef OBJCPLUS 2391 push_lang_context (lang_name_c); /* extern "C" */ 2392 #endif 2393 2394 objc_push_parm (build_decl (input_location, 2395 PARM_DECL, NULL_TREE, void_type_node)); 2396 #ifdef OBJCPLUS 2397 objc_start_function (get_identifier (TAG_GNUINIT), 2398 build_function_type (void_type_node, 2399 OBJC_VOID_AT_END), 2400 NULL_TREE, NULL_TREE); 2401 #else 2402 objc_start_function (get_identifier (TAG_GNUINIT), 2403 build_function_type (void_type_node, 2404 OBJC_VOID_AT_END), 2405 NULL_TREE, objc_get_parm_info (0)); 2406 #endif 2407 body = c_begin_compound_stmt (true); 2408 add_stmt (build_function_call 2409 (input_location, 2410 execclass_decl, 2411 build_tree_list 2412 (NULL_TREE, 2413 build_unary_op (input_location, ADDR_EXPR, 2414 UOBJC_MODULES_decl, 0)))); 2415 add_stmt (c_end_compound_stmt (input_location, body, true)); 2416 2417 TREE_PUBLIC (current_function_decl) = 0; 2418 2419 #ifndef OBJCPLUS 2420 /* For Objective-C++, we will need to call __objc_gnu_init 2421 from objc_generate_static_init_call() below. */ 2422 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1; 2423 #endif 2424 2425 GNU_INIT_decl = current_function_decl; 2426 finish_function (); 2427 2428 #ifdef OBJCPLUS 2429 pop_lang_context (); 2430 #endif 2431 } 2432 2433 #ifdef OBJCPLUS 2434 /* Return 1 if the __objc_gnu_init function has been synthesized and needs 2435 to be called by the module initializer routine. */ 2436 2437 int 2438 objc_static_init_needed_p (void) 2439 { 2440 return (GNU_INIT_decl != NULL_TREE); 2441 } 2442 2443 /* Generate a call to the __objc_gnu_init initializer function. */ 2444 2445 tree 2446 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED) 2447 { 2448 add_stmt (build_stmt (input_location, EXPR_STMT, 2449 build_function_call (input_location, 2450 GNU_INIT_decl, NULL_TREE))); 2451 2452 return ctors; 2453 } 2454 #endif /* OBJCPLUS */ 2455 2456 /* Return the DECL of the string IDENT in the SECTION. */ 2457 2458 static tree 2459 get_objc_string_decl (tree ident, enum string_section section) 2460 { 2461 tree chain; 2462 2463 if (section == class_names) 2464 chain = class_names_chain; 2465 else if (section == meth_var_names) 2466 chain = meth_var_names_chain; 2467 else if (section == meth_var_types) 2468 chain = meth_var_types_chain; 2469 else 2470 abort (); 2471 2472 for (; chain != 0; chain = TREE_CHAIN (chain)) 2473 if (TREE_VALUE (chain) == ident) 2474 return (TREE_PURPOSE (chain)); 2475 2476 abort (); 2477 return NULL_TREE; 2478 } 2479 2480 /* Output references to all statically allocated objects. Return the DECL 2481 for the array built. */ 2482 2483 static void 2484 generate_static_references (void) 2485 { 2486 tree decls = NULL_TREE, expr = NULL_TREE; 2487 tree class_name, klass, decl, initlist; 2488 tree cl_chain, in_chain, type 2489 = build_array_type (build_pointer_type (void_type_node), NULL_TREE); 2490 int num_inst, num_class; 2491 char buf[256]; 2492 2493 if (flag_next_runtime) 2494 abort (); 2495 2496 for (cl_chain = objc_static_instances, num_class = 0; 2497 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++) 2498 { 2499 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain); 2500 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain)); 2501 2502 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class); 2503 decl = start_var_decl (type, buf); 2504 2505 /* Output {class_name, ...}. */ 2506 klass = TREE_VALUE (cl_chain); 2507 class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names); 2508 initlist = build_tree_list (NULL_TREE, 2509 build_unary_op (input_location, 2510 ADDR_EXPR, class_name, 1)); 2511 2512 /* Output {..., instance, ...}. */ 2513 for (in_chain = TREE_PURPOSE (cl_chain); 2514 in_chain; in_chain = TREE_CHAIN (in_chain)) 2515 { 2516 expr = build_unary_op (input_location, 2517 ADDR_EXPR, TREE_VALUE (in_chain), 1); 2518 initlist = tree_cons (NULL_TREE, expr, initlist); 2519 } 2520 2521 /* Output {..., NULL}. */ 2522 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist); 2523 2524 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)); 2525 finish_var_decl (decl, expr); 2526 decls 2527 = tree_cons (NULL_TREE, build_unary_op (input_location, 2528 ADDR_EXPR, decl, 1), decls); 2529 } 2530 2531 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls); 2532 expr = objc_build_constructor (type, nreverse (decls)); 2533 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES"); 2534 finish_var_decl (static_instances_decl, expr); 2535 } 2536 2537 static GTY(()) int selector_reference_idx; 2538 2539 static tree 2540 build_selector_reference_decl (void) 2541 { 2542 tree decl; 2543 char buf[256]; 2544 2545 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++); 2546 decl = start_var_decl (objc_selector_type, buf); 2547 2548 return decl; 2549 } 2550 2551 static void 2552 build_selector_table_decl (void) 2553 { 2554 tree temp; 2555 2556 if (flag_typed_selectors) 2557 { 2558 build_selector_template (); 2559 temp = build_array_type (objc_selector_template, NULL_TREE); 2560 } 2561 else 2562 temp = build_array_type (objc_selector_type, NULL_TREE); 2563 2564 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE"); 2565 } 2566 2567 /* Just a handy wrapper for add_objc_string. */ 2568 2569 static tree 2570 build_selector (tree ident) 2571 { 2572 return convert (objc_selector_type, 2573 add_objc_string (ident, meth_var_names)); 2574 } 2575 2576 static void 2577 build_selector_translation_table (void) 2578 { 2579 tree chain, initlist = NULL_TREE; 2580 int offset = 0; 2581 tree decl = NULL_TREE; 2582 2583 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain)) 2584 { 2585 tree expr; 2586 2587 if (warn_selector && objc_implementation_context) 2588 { 2589 tree method_chain; 2590 bool found = false; 2591 for (method_chain = meth_var_names_chain; 2592 method_chain; 2593 method_chain = TREE_CHAIN (method_chain)) 2594 { 2595 if (TREE_VALUE (method_chain) == TREE_VALUE (chain)) 2596 { 2597 found = true; 2598 break; 2599 } 2600 } 2601 if (!found) 2602 { 2603 location_t loc; 2604 if (flag_next_runtime && TREE_PURPOSE (chain)) 2605 loc = DECL_SOURCE_LOCATION (TREE_PURPOSE (chain)); 2606 else 2607 loc = input_location; 2608 warning_at (loc, 0, "creating selector for nonexistent method %qE", 2609 TREE_VALUE (chain)); 2610 } 2611 } 2612 2613 expr = build_selector (TREE_VALUE (chain)); 2614 /* add one for the '\0' character */ 2615 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1; 2616 2617 if (flag_next_runtime) 2618 { 2619 decl = TREE_PURPOSE (chain); 2620 finish_var_decl (decl, expr); 2621 } 2622 else 2623 { 2624 if (flag_typed_selectors) 2625 { 2626 tree eltlist = NULL_TREE; 2627 tree encoding = get_proto_encoding (TREE_PURPOSE (chain)); 2628 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE); 2629 eltlist = tree_cons (NULL_TREE, encoding, eltlist); 2630 expr = objc_build_constructor (objc_selector_template, 2631 nreverse (eltlist)); 2632 } 2633 2634 initlist = tree_cons (NULL_TREE, expr, initlist); 2635 } 2636 } 2637 2638 if (! flag_next_runtime) 2639 { 2640 /* Cause the selector table (previously forward-declared) 2641 to be actually output. */ 2642 initlist = tree_cons (NULL_TREE, 2643 flag_typed_selectors 2644 ? objc_build_constructor 2645 (objc_selector_template, 2646 tree_cons (NULL_TREE, 2647 build_int_cst (NULL_TREE, 0), 2648 tree_cons (NULL_TREE, 2649 build_int_cst (NULL_TREE, 0), 2650 NULL_TREE))) 2651 : build_int_cst (NULL_TREE, 0), initlist); 2652 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl), 2653 nreverse (initlist)); 2654 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist); 2655 } 2656 } 2657 2658 static tree 2659 get_proto_encoding (tree proto) 2660 { 2661 tree encoding; 2662 if (proto) 2663 { 2664 if (! METHOD_ENCODING (proto)) 2665 { 2666 encoding = encode_method_prototype (proto); 2667 METHOD_ENCODING (proto) = encoding; 2668 } 2669 else 2670 encoding = METHOD_ENCODING (proto); 2671 2672 return add_objc_string (encoding, meth_var_types); 2673 } 2674 else 2675 return build_int_cst (NULL_TREE, 0); 2676 } 2677 2678 /* sel_ref_chain is a list whose "value" fields will be instances of 2679 identifier_node that represent the selector. LOC is the location of 2680 the @selector. */ 2681 2682 static tree 2683 build_typed_selector_reference (location_t loc, tree ident, tree prototype) 2684 { 2685 tree *chain = &sel_ref_chain; 2686 tree expr; 2687 int index = 0; 2688 2689 while (*chain) 2690 { 2691 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident) 2692 goto return_at_index; 2693 2694 index++; 2695 chain = &TREE_CHAIN (*chain); 2696 } 2697 2698 *chain = tree_cons (prototype, ident, NULL_TREE); 2699 2700 return_at_index: 2701 expr = build_unary_op (loc, ADDR_EXPR, 2702 build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl, 2703 build_int_cst (NULL_TREE, index)), 2704 1); 2705 return convert (objc_selector_type, expr); 2706 } 2707 2708 static tree 2709 build_selector_reference (location_t loc, tree ident) 2710 { 2711 tree *chain = &sel_ref_chain; 2712 tree expr; 2713 int index = 0; 2714 2715 while (*chain) 2716 { 2717 if (TREE_VALUE (*chain) == ident) 2718 return (flag_next_runtime 2719 ? TREE_PURPOSE (*chain) 2720 : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl, 2721 build_int_cst (NULL_TREE, index))); 2722 2723 index++; 2724 chain = &TREE_CHAIN (*chain); 2725 } 2726 2727 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE); 2728 2729 *chain = tree_cons (expr, ident, NULL_TREE); 2730 2731 return (flag_next_runtime 2732 ? expr 2733 : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl, 2734 build_int_cst (NULL_TREE, index))); 2735 } 2736 2737 static GTY(()) int class_reference_idx; 2738 2739 static tree 2740 build_class_reference_decl (void) 2741 { 2742 tree decl; 2743 char buf[256]; 2744 2745 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++); 2746 decl = start_var_decl (objc_class_type, buf); 2747 2748 return decl; 2749 } 2750 2751 /* Create a class reference, but don't create a variable to reference 2752 it. */ 2753 2754 static void 2755 add_class_reference (tree ident) 2756 { 2757 tree chain; 2758 2759 if ((chain = cls_ref_chain)) 2760 { 2761 tree tail; 2762 do 2763 { 2764 if (ident == TREE_VALUE (chain)) 2765 return; 2766 2767 tail = chain; 2768 chain = TREE_CHAIN (chain); 2769 } 2770 while (chain); 2771 2772 /* Append to the end of the list */ 2773 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE); 2774 } 2775 else 2776 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE); 2777 } 2778 2779 /* Get a class reference, creating it if necessary. Also create the 2780 reference variable. */ 2781 2782 tree 2783 objc_get_class_reference (tree ident) 2784 { 2785 tree orig_ident = (DECL_P (ident) 2786 ? DECL_NAME (ident) 2787 : TYPE_P (ident) 2788 ? OBJC_TYPE_NAME (ident) 2789 : ident); 2790 bool local_scope = false; 2791 2792 #ifdef OBJCPLUS 2793 if (processing_template_decl) 2794 /* Must wait until template instantiation time. */ 2795 return build_min_nt (CLASS_REFERENCE_EXPR, ident); 2796 #endif 2797 2798 if (TREE_CODE (ident) == TYPE_DECL) 2799 ident = (DECL_ORIGINAL_TYPE (ident) 2800 ? DECL_ORIGINAL_TYPE (ident) 2801 : TREE_TYPE (ident)); 2802 2803 #ifdef OBJCPLUS 2804 if (TYPE_P (ident) && TYPE_CONTEXT (ident) 2805 && TYPE_CONTEXT (ident) != global_namespace) 2806 local_scope = true; 2807 #endif 2808 2809 if (local_scope || !(ident = objc_is_class_name (ident))) 2810 { 2811 error ("%qE is not an Objective-C class name or alias", 2812 orig_ident); 2813 return error_mark_node; 2814 } 2815 2816 if (flag_next_runtime && !flag_zero_link) 2817 { 2818 tree *chain; 2819 tree decl; 2820 2821 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain)) 2822 if (TREE_VALUE (*chain) == ident) 2823 { 2824 if (! TREE_PURPOSE (*chain)) 2825 TREE_PURPOSE (*chain) = build_class_reference_decl (); 2826 2827 return TREE_PURPOSE (*chain); 2828 } 2829 2830 decl = build_class_reference_decl (); 2831 *chain = tree_cons (decl, ident, NULL_TREE); 2832 return decl; 2833 } 2834 else 2835 { 2836 tree params; 2837 2838 add_class_reference (ident); 2839 2840 params = build_tree_list (NULL_TREE, 2841 my_build_string_pointer 2842 (IDENTIFIER_LENGTH (ident) + 1, 2843 IDENTIFIER_POINTER (ident))); 2844 2845 assemble_external (objc_get_class_decl); 2846 return build_function_call (input_location, objc_get_class_decl, params); 2847 } 2848 } 2849 2850 /* For each string section we have a chain which maps identifier nodes 2851 to decls for the strings. */ 2852 2853 static tree 2854 add_objc_string (tree ident, enum string_section section) 2855 { 2856 tree *chain, decl, type, string_expr; 2857 2858 if (section == class_names) 2859 chain = &class_names_chain; 2860 else if (section == meth_var_names) 2861 chain = &meth_var_names_chain; 2862 else if (section == meth_var_types) 2863 chain = &meth_var_types_chain; 2864 else 2865 abort (); 2866 2867 while (*chain) 2868 { 2869 if (TREE_VALUE (*chain) == ident) 2870 return convert (string_type_node, 2871 build_unary_op (input_location, 2872 ADDR_EXPR, TREE_PURPOSE (*chain), 1)); 2873 2874 chain = &TREE_CHAIN (*chain); 2875 } 2876 2877 decl = build_objc_string_decl (section); 2878 2879 type = build_array_type 2880 (char_type_node, 2881 build_index_type 2882 (build_int_cst (NULL_TREE, 2883 IDENTIFIER_LENGTH (ident)))); 2884 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl))); 2885 string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1, 2886 IDENTIFIER_POINTER (ident)); 2887 finish_var_decl (decl, string_expr); 2888 2889 *chain = tree_cons (decl, ident, NULL_TREE); 2890 2891 return convert (string_type_node, build_unary_op (input_location, 2892 ADDR_EXPR, decl, 1)); 2893 } 2894 2895 static GTY(()) int class_names_idx; 2896 static GTY(()) int meth_var_names_idx; 2897 static GTY(()) int meth_var_types_idx; 2898 2899 static tree 2900 build_objc_string_decl (enum string_section section) 2901 { 2902 tree decl, ident; 2903 char buf[256]; 2904 2905 if (section == class_names) 2906 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++); 2907 else if (section == meth_var_names) 2908 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++); 2909 else if (section == meth_var_types) 2910 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++); 2911 2912 ident = get_identifier (buf); 2913 2914 decl = build_decl (input_location, 2915 VAR_DECL, ident, build_array_type (char_type_node, 0)); 2916 DECL_EXTERNAL (decl) = 1; 2917 TREE_PUBLIC (decl) = 0; 2918 TREE_USED (decl) = 1; 2919 TREE_CONSTANT (decl) = 1; 2920 DECL_CONTEXT (decl) = 0; 2921 DECL_ARTIFICIAL (decl) = 1; 2922 #ifdef OBJCPLUS 2923 DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */ 2924 #endif 2925 2926 make_decl_rtl (decl); 2927 pushdecl_top_level (decl); 2928 2929 return decl; 2930 } 2931 2932 2933 void 2934 objc_declare_alias (tree alias_ident, tree class_ident) 2935 { 2936 tree underlying_class; 2937 2938 #ifdef OBJCPLUS 2939 if (current_namespace != global_namespace) { 2940 error ("Objective-C declarations may only appear in global scope"); 2941 } 2942 #endif /* OBJCPLUS */ 2943 2944 if (!(underlying_class = objc_is_class_name (class_ident))) 2945 warning (0, "cannot find class %qE", class_ident); 2946 else if (objc_is_class_name (alias_ident)) 2947 warning (0, "class %qE already exists", alias_ident); 2948 else 2949 { 2950 /* Implement @compatibility_alias as a typedef. */ 2951 #ifdef OBJCPLUS 2952 push_lang_context (lang_name_c); /* extern "C" */ 2953 #endif 2954 lang_hooks.decls.pushdecl (build_decl 2955 (input_location, 2956 TYPE_DECL, 2957 alias_ident, 2958 xref_tag (RECORD_TYPE, underlying_class))); 2959 #ifdef OBJCPLUS 2960 pop_lang_context (); 2961 #endif 2962 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain); 2963 } 2964 } 2965 2966 void 2967 objc_declare_class (tree ident_list) 2968 { 2969 tree list; 2970 #ifdef OBJCPLUS 2971 if (current_namespace != global_namespace) { 2972 error ("Objective-C declarations may only appear in global scope"); 2973 } 2974 #endif /* OBJCPLUS */ 2975 2976 for (list = ident_list; list; list = TREE_CHAIN (list)) 2977 { 2978 tree ident = TREE_VALUE (list); 2979 2980 if (! objc_is_class_name (ident)) 2981 { 2982 tree record = lookup_name (ident), type = record; 2983 2984 if (record) 2985 { 2986 if (TREE_CODE (record) == TYPE_DECL) 2987 type = DECL_ORIGINAL_TYPE (record); 2988 2989 if (!TYPE_HAS_OBJC_INFO (type) 2990 || !TYPE_OBJC_INTERFACE (type)) 2991 { 2992 error ("%qE redeclared as different kind of symbol", 2993 ident); 2994 error ("previous declaration of %q+D", 2995 record); 2996 } 2997 } 2998 2999 record = xref_tag (RECORD_TYPE, ident); 3000 INIT_TYPE_OBJC_INFO (record); 3001 TYPE_OBJC_INTERFACE (record) = ident; 3002 class_chain = tree_cons (NULL_TREE, ident, class_chain); 3003 } 3004 } 3005 } 3006 3007 tree 3008 objc_is_class_name (tree ident) 3009 { 3010 tree chain; 3011 3012 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE 3013 && identifier_global_value (ident)) 3014 ident = identifier_global_value (ident); 3015 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident)) 3016 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident)); 3017 3018 if (ident && TREE_CODE (ident) == RECORD_TYPE) 3019 ident = OBJC_TYPE_NAME (ident); 3020 #ifdef OBJCPLUS 3021 if (ident && TREE_CODE (ident) == TYPE_DECL) 3022 ident = DECL_NAME (ident); 3023 #endif 3024 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE) 3025 return NULL_TREE; 3026 3027 if (lookup_interface (ident)) 3028 return ident; 3029 3030 for (chain = class_chain; chain; chain = TREE_CHAIN (chain)) 3031 { 3032 if (ident == TREE_VALUE (chain)) 3033 return ident; 3034 } 3035 3036 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain)) 3037 { 3038 if (ident == TREE_VALUE (chain)) 3039 return TREE_PURPOSE (chain); 3040 } 3041 3042 return 0; 3043 } 3044 3045 /* Check whether TYPE is either 'id' or 'Class'. */ 3046 3047 tree 3048 objc_is_id (tree type) 3049 { 3050 if (type && TREE_CODE (type) == IDENTIFIER_NODE 3051 && identifier_global_value (type)) 3052 type = identifier_global_value (type); 3053 3054 if (type && TREE_CODE (type) == TYPE_DECL) 3055 type = TREE_TYPE (type); 3056 3057 /* NB: This function may be called before the ObjC front-end has 3058 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */ 3059 return (objc_object_type && type 3060 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type)) 3061 ? type 3062 : NULL_TREE); 3063 } 3064 3065 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC 3066 class instance. This is needed by other parts of the compiler to 3067 handle ObjC types gracefully. */ 3068 3069 tree 3070 objc_is_object_ptr (tree type) 3071 { 3072 tree ret; 3073 3074 type = TYPE_MAIN_VARIANT (type); 3075 if (!POINTER_TYPE_P (type)) 3076 return 0; 3077 3078 ret = objc_is_id (type); 3079 if (!ret) 3080 ret = objc_is_class_name (TREE_TYPE (type)); 3081 3082 return ret; 3083 } 3084 3085 static int 3086 objc_is_gcable_type (tree type, int or_strong_p) 3087 { 3088 tree name; 3089 3090 if (!TYPE_P (type)) 3091 return 0; 3092 if (objc_is_id (TYPE_MAIN_VARIANT (type))) 3093 return 1; 3094 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type))) 3095 return 1; 3096 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF) 3097 return 0; 3098 type = TREE_TYPE (type); 3099 if (TREE_CODE (type) != RECORD_TYPE) 3100 return 0; 3101 name = TYPE_NAME (type); 3102 return (objc_is_class_name (name) != NULL_TREE); 3103 } 3104 3105 static tree 3106 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr) 3107 { 3108 if (expr == oldexpr) 3109 return newexpr; 3110 3111 switch (TREE_CODE (expr)) 3112 { 3113 case COMPONENT_REF: 3114 return objc_build_component_ref 3115 (objc_substitute_decl (TREE_OPERAND (expr, 0), 3116 oldexpr, 3117 newexpr), 3118 DECL_NAME (TREE_OPERAND (expr, 1))); 3119 case ARRAY_REF: 3120 return build_array_ref (input_location, 3121 objc_substitute_decl (TREE_OPERAND (expr, 0), 3122 oldexpr, 3123 newexpr), 3124 TREE_OPERAND (expr, 1)); 3125 case INDIRECT_REF: 3126 return build_indirect_ref (input_location, 3127 objc_substitute_decl (TREE_OPERAND (expr, 0), 3128 oldexpr, 3129 newexpr), RO_ARROW); 3130 default: 3131 return expr; 3132 } 3133 } 3134 3135 static tree 3136 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs) 3137 { 3138 tree func_params; 3139 /* The LHS parameter contains the expression 'outervar->memberspec'; 3140 we need to transform it into '&((typeof(outervar) *) 0)->memberspec', 3141 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]'). 3142 */ 3143 tree offs 3144 = objc_substitute_decl 3145 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node)); 3146 tree func 3147 = (flag_objc_direct_dispatch 3148 ? objc_assign_ivar_fast_decl 3149 : objc_assign_ivar_decl); 3150 3151 offs = convert (integer_type_node, build_unary_op (input_location, 3152 ADDR_EXPR, offs, 0)); 3153 offs = fold (offs); 3154 func_params = tree_cons (NULL_TREE, 3155 convert (objc_object_type, rhs), 3156 tree_cons (NULL_TREE, convert (objc_object_type, outervar), 3157 tree_cons (NULL_TREE, offs, 3158 NULL_TREE))); 3159 3160 assemble_external (func); 3161 return build_function_call (input_location, func, func_params); 3162 } 3163 3164 static tree 3165 objc_build_global_assignment (tree lhs, tree rhs) 3166 { 3167 tree func_params = tree_cons (NULL_TREE, 3168 convert (objc_object_type, rhs), 3169 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type), 3170 build_unary_op (input_location, ADDR_EXPR, lhs, 0)), 3171 NULL_TREE)); 3172 3173 assemble_external (objc_assign_global_decl); 3174 return build_function_call (input_location, 3175 objc_assign_global_decl, func_params); 3176 } 3177 3178 static tree 3179 objc_build_strong_cast_assignment (tree lhs, tree rhs) 3180 { 3181 tree func_params = tree_cons (NULL_TREE, 3182 convert (objc_object_type, rhs), 3183 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type), 3184 build_unary_op (input_location, ADDR_EXPR, lhs, 0)), 3185 NULL_TREE)); 3186 3187 assemble_external (objc_assign_strong_cast_decl); 3188 return build_function_call (input_location, 3189 objc_assign_strong_cast_decl, func_params); 3190 } 3191 3192 static int 3193 objc_is_gcable_p (tree expr) 3194 { 3195 return (TREE_CODE (expr) == COMPONENT_REF 3196 ? objc_is_gcable_p (TREE_OPERAND (expr, 1)) 3197 : TREE_CODE (expr) == ARRAY_REF 3198 ? (objc_is_gcable_p (TREE_TYPE (expr)) 3199 || objc_is_gcable_p (TREE_OPERAND (expr, 0))) 3200 : TREE_CODE (expr) == ARRAY_TYPE 3201 ? objc_is_gcable_p (TREE_TYPE (expr)) 3202 : TYPE_P (expr) 3203 ? objc_is_gcable_type (expr, 1) 3204 : (objc_is_gcable_p (TREE_TYPE (expr)) 3205 || (DECL_P (expr) 3206 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr))))); 3207 } 3208 3209 static int 3210 objc_is_ivar_reference_p (tree expr) 3211 { 3212 return (TREE_CODE (expr) == ARRAY_REF 3213 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0)) 3214 : TREE_CODE (expr) == COMPONENT_REF 3215 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL 3216 : 0); 3217 } 3218 3219 static int 3220 objc_is_global_reference_p (tree expr) 3221 { 3222 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR 3223 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0)) 3224 : DECL_P (expr) 3225 ? (!DECL_CONTEXT (expr) || TREE_STATIC (expr)) 3226 : 0); 3227 } 3228 3229 tree 3230 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs) 3231 { 3232 tree result = NULL_TREE, outer; 3233 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0; 3234 3235 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts 3236 will have been transformed to the form '*(type *)&expr'. */ 3237 if (TREE_CODE (lhs) == INDIRECT_REF) 3238 { 3239 outer = TREE_OPERAND (lhs, 0); 3240 3241 while (!strong_cast_p 3242 && (CONVERT_EXPR_P (outer) 3243 || TREE_CODE (outer) == NON_LVALUE_EXPR)) 3244 { 3245 tree lhstype = TREE_TYPE (outer); 3246 3247 /* Descend down the cast chain, and record the first objc_gc 3248 attribute found. */ 3249 if (POINTER_TYPE_P (lhstype)) 3250 { 3251 tree attr 3252 = lookup_attribute ("objc_gc", 3253 TYPE_ATTRIBUTES (TREE_TYPE (lhstype))); 3254 3255 if (attr) 3256 strong_cast_p = 1; 3257 } 3258 3259 outer = TREE_OPERAND (outer, 0); 3260 } 3261 } 3262 3263 /* If we have a __strong cast, it trumps all else. */ 3264 if (strong_cast_p) 3265 { 3266 if (modifycode != NOP_EXPR) 3267 goto invalid_pointer_arithmetic; 3268 3269 if (warn_assign_intercept) 3270 warning (0, "strong-cast assignment has been intercepted"); 3271 3272 result = objc_build_strong_cast_assignment (lhs, rhs); 3273 3274 goto exit_point; 3275 } 3276 3277 /* the lhs must be of a suitable type, regardless of its underlying 3278 structure. */ 3279 if (!objc_is_gcable_p (lhs)) 3280 goto exit_point; 3281 3282 outer = lhs; 3283 3284 while (outer 3285 && (TREE_CODE (outer) == COMPONENT_REF 3286 || TREE_CODE (outer) == ARRAY_REF)) 3287 outer = TREE_OPERAND (outer, 0); 3288 3289 if (TREE_CODE (outer) == INDIRECT_REF) 3290 { 3291 outer = TREE_OPERAND (outer, 0); 3292 indirect_p = 1; 3293 } 3294 3295 outer_gc_p = objc_is_gcable_p (outer); 3296 3297 /* Handle ivar assignments. */ 3298 if (objc_is_ivar_reference_p (lhs)) 3299 { 3300 /* if the struct to the left of the ivar is not an Objective-C object (__strong 3301 doesn't cut it here), the best we can do here is suggest a cast. */ 3302 if (!objc_is_gcable_type (TREE_TYPE (outer), 0)) 3303 { 3304 /* We may still be able to use the global write barrier... */ 3305 if (!indirect_p && objc_is_global_reference_p (outer)) 3306 goto global_reference; 3307 3308 suggest_cast: 3309 if (modifycode == NOP_EXPR) 3310 { 3311 if (warn_assign_intercept) 3312 warning (0, "strong-cast may possibly be needed"); 3313 } 3314 3315 goto exit_point; 3316 } 3317 3318 if (modifycode != NOP_EXPR) 3319 goto invalid_pointer_arithmetic; 3320 3321 if (warn_assign_intercept) 3322 warning (0, "instance variable assignment has been intercepted"); 3323 3324 result = objc_build_ivar_assignment (outer, lhs, rhs); 3325 3326 goto exit_point; 3327 } 3328 3329 /* Likewise, intercept assignment to global/static variables if their type is 3330 GC-marked. */ 3331 if (objc_is_global_reference_p (outer)) 3332 { 3333 if (indirect_p) 3334 goto suggest_cast; 3335 3336 global_reference: 3337 if (modifycode != NOP_EXPR) 3338 { 3339 invalid_pointer_arithmetic: 3340 if (outer_gc_p) 3341 warning (0, "pointer arithmetic for garbage-collected objects not allowed"); 3342 3343 goto exit_point; 3344 } 3345 3346 if (warn_assign_intercept) 3347 warning (0, "global/static variable assignment has been intercepted"); 3348 3349 result = objc_build_global_assignment (lhs, rhs); 3350 } 3351 3352 /* In all other cases, fall back to the normal mechanism. */ 3353 exit_point: 3354 return result; 3355 } 3356 3357 struct GTY(()) interface_tuple { 3358 tree id; 3359 tree class_name; 3360 }; 3361 3362 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab; 3363 3364 static hashval_t 3365 hash_interface (const void *p) 3366 { 3367 const struct interface_tuple *d = (const struct interface_tuple *) p; 3368 return IDENTIFIER_HASH_VALUE (d->id); 3369 } 3370 3371 static int 3372 eq_interface (const void *p1, const void *p2) 3373 { 3374 const struct interface_tuple *d = (const struct interface_tuple *) p1; 3375 return d->id == p2; 3376 } 3377 3378 static tree 3379 lookup_interface (tree ident) 3380 { 3381 #ifdef OBJCPLUS 3382 if (ident && TREE_CODE (ident) == TYPE_DECL) 3383 ident = DECL_NAME (ident); 3384 #endif 3385 3386 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE) 3387 return NULL_TREE; 3388 3389 { 3390 struct interface_tuple **slot; 3391 tree i = NULL_TREE; 3392 3393 if (interface_htab) 3394 { 3395 slot = (struct interface_tuple **) 3396 htab_find_slot_with_hash (interface_htab, ident, 3397 IDENTIFIER_HASH_VALUE (ident), 3398 NO_INSERT); 3399 if (slot && *slot) 3400 i = (*slot)->class_name; 3401 } 3402 return i; 3403 } 3404 } 3405 3406 /* Implement @defs (<classname>) within struct bodies. */ 3407 3408 tree 3409 objc_get_class_ivars (tree class_name) 3410 { 3411 tree interface = lookup_interface (class_name); 3412 3413 if (interface) 3414 return get_class_ivars (interface, true); 3415 3416 error ("cannot find interface declaration for %qE", 3417 class_name); 3418 3419 return error_mark_node; 3420 } 3421 3422 /* Used by: build_private_template, continue_class, 3423 and for @defs constructs. */ 3424 3425 static tree 3426 get_class_ivars (tree interface, bool inherited) 3427 { 3428 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface)); 3429 3430 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared 3431 by the current class (i.e., they do not include super-class ivars). 3432 However, the CLASS_IVARS list will be side-effected by a call to 3433 finish_struct(), which will fill in field offsets. */ 3434 if (!CLASS_IVARS (interface)) 3435 CLASS_IVARS (interface) = ivar_chain; 3436 3437 if (!inherited) 3438 return ivar_chain; 3439 3440 while (CLASS_SUPER_NAME (interface)) 3441 { 3442 /* Prepend super-class ivars. */ 3443 interface = lookup_interface (CLASS_SUPER_NAME (interface)); 3444 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)), 3445 ivar_chain); 3446 } 3447 3448 return ivar_chain; 3449 } 3450 3451 static tree 3452 objc_create_temporary_var (tree type) 3453 { 3454 tree decl; 3455 3456 decl = build_decl (input_location, 3457 VAR_DECL, NULL_TREE, type); 3458 TREE_USED (decl) = 1; 3459 DECL_ARTIFICIAL (decl) = 1; 3460 DECL_IGNORED_P (decl) = 1; 3461 DECL_CONTEXT (decl) = current_function_decl; 3462 3463 return decl; 3464 } 3465 3466 /* Exception handling constructs. We begin by having the parser do most 3467 of the work and passing us blocks. What we do next depends on whether 3468 we're doing "native" exception handling or legacy Darwin setjmp exceptions. 3469 We abstract all of this in a handful of appropriately named routines. */ 3470 3471 /* Stack of open try blocks. */ 3472 3473 struct objc_try_context 3474 { 3475 struct objc_try_context *outer; 3476 3477 /* Statements (or statement lists) as processed by the parser. */ 3478 tree try_body; 3479 tree finally_body; 3480 3481 /* Some file position locations. */ 3482 location_t try_locus; 3483 location_t end_try_locus; 3484 location_t end_catch_locus; 3485 location_t finally_locus; 3486 location_t end_finally_locus; 3487 3488 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1 3489 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */ 3490 tree catch_list; 3491 3492 /* The CATCH_EXPR of an open @catch clause. */ 3493 tree current_catch; 3494 3495 /* The VAR_DECL holding the Darwin equivalent of __builtin_eh_pointer. */ 3496 tree caught_decl; 3497 tree stack_decl; 3498 tree rethrow_decl; 3499 }; 3500 3501 static struct objc_try_context *cur_try_context; 3502 3503 static GTY(()) tree objc_eh_personality_decl; 3504 3505 /* This hook, called via lang_eh_runtime_type, generates a runtime object 3506 that represents TYPE. For Objective-C, this is just the class name. */ 3507 /* ??? Isn't there a class object or some such? Is it easy to get? */ 3508 3509 #ifndef OBJCPLUS 3510 tree 3511 objc_eh_runtime_type (tree type) 3512 { 3513 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names); 3514 } 3515 3516 tree 3517 objc_eh_personality (void) 3518 { 3519 if (!flag_objc_sjlj_exceptions 3520 && !objc_eh_personality_decl) 3521 objc_eh_personality_decl 3522 = build_personality_function (USING_SJLJ_EXCEPTIONS 3523 ? "__gnu_objc_personality_sj0" 3524 : "__gnu_objc_personality_v0"); 3525 3526 return objc_eh_personality_decl; 3527 } 3528 #endif 3529 3530 /* Build __builtin_eh_pointer, or the moral equivalent. In the case 3531 of Darwin, we'll arrange for it to be initialized (and associated 3532 with a binding) later. */ 3533 3534 static tree 3535 objc_build_exc_ptr (void) 3536 { 3537 if (flag_objc_sjlj_exceptions) 3538 { 3539 tree var = cur_try_context->caught_decl; 3540 if (!var) 3541 { 3542 var = objc_create_temporary_var (objc_object_type); 3543 cur_try_context->caught_decl = var; 3544 } 3545 return var; 3546 } 3547 else 3548 { 3549 tree t; 3550 t = built_in_decls[BUILT_IN_EH_POINTER]; 3551 t = build_call_expr (t, 1, integer_zero_node); 3552 return fold_convert (objc_object_type, t); 3553 } 3554 } 3555 3556 /* Build "objc_exception_try_exit(&_stack)". */ 3557 3558 static tree 3559 next_sjlj_build_try_exit (void) 3560 { 3561 tree t; 3562 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl); 3563 t = tree_cons (NULL, t, NULL); 3564 t = build_function_call (input_location, 3565 objc_exception_try_exit_decl, t); 3566 return t; 3567 } 3568 3569 /* Build 3570 objc_exception_try_enter (&_stack); 3571 if (_setjmp(&_stack.buf)) 3572 ; 3573 else 3574 ; 3575 Return the COND_EXPR. Note that the THEN and ELSE fields are left 3576 empty, ready for the caller to fill them in. */ 3577 3578 static tree 3579 next_sjlj_build_enter_and_setjmp (void) 3580 { 3581 tree t, enter, sj, cond; 3582 3583 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl); 3584 t = tree_cons (NULL, t, NULL); 3585 enter = build_function_call (input_location, 3586 objc_exception_try_enter_decl, t); 3587 3588 t = objc_build_component_ref (cur_try_context->stack_decl, 3589 get_identifier ("buf")); 3590 t = build_fold_addr_expr_loc (input_location, t); 3591 #ifdef OBJCPLUS 3592 /* Convert _setjmp argument to type that is expected. */ 3593 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))) 3594 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t); 3595 else 3596 t = convert (ptr_type_node, t); 3597 #else 3598 t = convert (ptr_type_node, t); 3599 #endif 3600 t = tree_cons (NULL, t, NULL); 3601 sj = build_function_call (input_location, 3602 objc_setjmp_decl, t); 3603 3604 cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj); 3605 cond = c_common_truthvalue_conversion (input_location, cond); 3606 3607 return build3 (COND_EXPR, void_type_node, cond, NULL, NULL); 3608 } 3609 3610 /* Build: 3611 3612 DECL = objc_exception_extract(&_stack); */ 3613 3614 static tree 3615 next_sjlj_build_exc_extract (tree decl) 3616 { 3617 tree t; 3618 3619 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl); 3620 t = tree_cons (NULL, t, NULL); 3621 t = build_function_call (input_location, 3622 objc_exception_extract_decl, t); 3623 t = convert (TREE_TYPE (decl), t); 3624 t = build2 (MODIFY_EXPR, void_type_node, decl, t); 3625 3626 return t; 3627 } 3628 3629 /* Build 3630 if (objc_exception_match(obj_get_class(TYPE), _caught) 3631 BODY 3632 else if (...) 3633 ... 3634 else 3635 { 3636 _rethrow = _caught; 3637 objc_exception_try_exit(&_stack); 3638 } 3639 from the sequence of CATCH_EXPRs in the current try context. */ 3640 3641 static tree 3642 next_sjlj_build_catch_list (void) 3643 { 3644 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list); 3645 tree catch_seq, t; 3646 tree *last = &catch_seq; 3647 bool saw_id = false; 3648 3649 for (; !tsi_end_p (i); tsi_next (&i)) 3650 { 3651 tree stmt = tsi_stmt (i); 3652 tree type = CATCH_TYPES (stmt); 3653 tree body = CATCH_BODY (stmt); 3654 3655 if (type == NULL) 3656 { 3657 *last = body; 3658 saw_id = true; 3659 break; 3660 } 3661 else 3662 { 3663 tree args, cond; 3664 3665 if (type == error_mark_node) 3666 cond = error_mark_node; 3667 else 3668 { 3669 args = tree_cons (NULL, cur_try_context->caught_decl, NULL); 3670 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type))); 3671 args = tree_cons (NULL, t, args); 3672 t = build_function_call (input_location, 3673 objc_exception_match_decl, args); 3674 cond = c_common_truthvalue_conversion (input_location, t); 3675 } 3676 t = build3 (COND_EXPR, void_type_node, cond, body, NULL); 3677 SET_EXPR_LOCATION (t, EXPR_LOCATION (stmt)); 3678 3679 *last = t; 3680 last = &COND_EXPR_ELSE (t); 3681 } 3682 } 3683 3684 if (!saw_id) 3685 { 3686 t = build2 (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl, 3687 cur_try_context->caught_decl); 3688 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus); 3689 append_to_statement_list (t, last); 3690 3691 t = next_sjlj_build_try_exit (); 3692 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus); 3693 append_to_statement_list (t, last); 3694 } 3695 3696 return catch_seq; 3697 } 3698 3699 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp 3700 exception handling. We aim to build: 3701 3702 { 3703 struct _objc_exception_data _stack; 3704 id _rethrow = 0; 3705 try 3706 { 3707 objc_exception_try_enter (&_stack); 3708 if (_setjmp(&_stack.buf)) 3709 { 3710 id _caught = objc_exception_extract(&_stack); 3711 objc_exception_try_enter (&_stack); 3712 if (_setjmp(&_stack.buf)) 3713 _rethrow = objc_exception_extract(&_stack); 3714 else 3715 CATCH-LIST 3716 } 3717 else 3718 TRY-BLOCK 3719 } 3720 finally 3721 { 3722 if (!_rethrow) 3723 objc_exception_try_exit(&_stack); 3724 FINALLY-BLOCK 3725 if (_rethrow) 3726 objc_exception_throw(_rethrow); 3727 } 3728 } 3729 3730 If CATCH-LIST is empty, we can omit all of the block containing 3731 "_caught" except for the setting of _rethrow. Note the use of 3732 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se, 3733 but handles goto and other exits from the block. */ 3734 3735 static tree 3736 next_sjlj_build_try_catch_finally (void) 3737 { 3738 tree rethrow_decl, stack_decl, t; 3739 tree catch_seq, try_fin, bind; 3740 3741 /* Create the declarations involved. */ 3742 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA)); 3743 stack_decl = objc_create_temporary_var (t); 3744 cur_try_context->stack_decl = stack_decl; 3745 3746 rethrow_decl = objc_create_temporary_var (objc_object_type); 3747 cur_try_context->rethrow_decl = rethrow_decl; 3748 TREE_CHAIN (rethrow_decl) = stack_decl; 3749 3750 /* Build the outermost variable binding level. */ 3751 bind = build3 (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL); 3752 SET_EXPR_LOCATION (bind, cur_try_context->try_locus); 3753 TREE_SIDE_EFFECTS (bind) = 1; 3754 3755 /* Initialize rethrow_decl. */ 3756 t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl, 3757 convert (objc_object_type, null_pointer_node)); 3758 SET_EXPR_LOCATION (t, cur_try_context->try_locus); 3759 append_to_statement_list (t, &BIND_EXPR_BODY (bind)); 3760 3761 /* Build the outermost TRY_FINALLY_EXPR. */ 3762 try_fin = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL); 3763 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus); 3764 TREE_SIDE_EFFECTS (try_fin) = 1; 3765 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind)); 3766 3767 /* Create the complete catch sequence. */ 3768 if (cur_try_context->catch_list) 3769 { 3770 tree caught_decl = objc_build_exc_ptr (); 3771 catch_seq = build_stmt (input_location, BIND_EXPR, caught_decl, NULL, NULL); 3772 TREE_SIDE_EFFECTS (catch_seq) = 1; 3773 3774 t = next_sjlj_build_exc_extract (caught_decl); 3775 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq)); 3776 3777 t = next_sjlj_build_enter_and_setjmp (); 3778 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl); 3779 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list (); 3780 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq)); 3781 } 3782 else 3783 catch_seq = next_sjlj_build_exc_extract (rethrow_decl); 3784 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus); 3785 3786 /* Build the main register-and-try if statement. */ 3787 t = next_sjlj_build_enter_and_setjmp (); 3788 SET_EXPR_LOCATION (t, cur_try_context->try_locus); 3789 COND_EXPR_THEN (t) = catch_seq; 3790 COND_EXPR_ELSE (t) = cur_try_context->try_body; 3791 TREE_OPERAND (try_fin, 0) = t; 3792 3793 /* Build the complete FINALLY statement list. */ 3794 t = next_sjlj_build_try_exit (); 3795 t = build_stmt (input_location, COND_EXPR, 3796 c_common_truthvalue_conversion 3797 (input_location, rethrow_decl), 3798 NULL, t); 3799 SET_EXPR_LOCATION (t, cur_try_context->finally_locus); 3800 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1)); 3801 3802 append_to_statement_list (cur_try_context->finally_body, 3803 &TREE_OPERAND (try_fin, 1)); 3804 3805 t = tree_cons (NULL, rethrow_decl, NULL); 3806 t = build_function_call (input_location, 3807 objc_exception_throw_decl, t); 3808 t = build_stmt (input_location, COND_EXPR, 3809 c_common_truthvalue_conversion (input_location, 3810 rethrow_decl), 3811 t, NULL); 3812 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus); 3813 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1)); 3814 3815 return bind; 3816 } 3817 3818 /* Called just after parsing the @try and its associated BODY. We now 3819 must prepare for the tricky bits -- handling the catches and finally. */ 3820 3821 void 3822 objc_begin_try_stmt (location_t try_locus, tree body) 3823 { 3824 struct objc_try_context *c = XCNEW (struct objc_try_context); 3825 c->outer = cur_try_context; 3826 c->try_body = body; 3827 c->try_locus = try_locus; 3828 c->end_try_locus = input_location; 3829 cur_try_context = c; 3830 3831 if (flag_objc_sjlj_exceptions) 3832 { 3833 /* On Darwin, ObjC exceptions require a sufficiently recent 3834 version of the runtime, so the user must ask for them explicitly. */ 3835 if (!flag_objc_exceptions) 3836 warning (0, "use %<-fobjc-exceptions%> to enable Objective-C " 3837 "exception syntax"); 3838 } 3839 3840 if (flag_objc_sjlj_exceptions) 3841 objc_mark_locals_volatile (NULL); 3842 } 3843 3844 /* Called just after parsing "@catch (parm)". Open a binding level, 3845 enter DECL into the binding level, and initialize it. Leave the 3846 binding level open while the body of the compound statement is parsed. */ 3847 3848 void 3849 objc_begin_catch_clause (tree decl) 3850 { 3851 tree compound, type, t; 3852 3853 /* Begin a new scope that the entire catch clause will live in. */ 3854 compound = c_begin_compound_stmt (true); 3855 3856 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */ 3857 decl = build_decl (input_location, 3858 VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl)); 3859 lang_hooks.decls.pushdecl (decl); 3860 3861 /* Since a decl is required here by syntax, don't warn if its unused. */ 3862 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to 3863 be what the previous objc implementation did. */ 3864 TREE_USED (decl) = 1; 3865 3866 /* Verify that the type of the catch is valid. It must be a pointer 3867 to an Objective-C class, or "id" (which is catch-all). */ 3868 type = TREE_TYPE (decl); 3869 3870 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type))) 3871 type = NULL; 3872 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type))) 3873 { 3874 error ("@catch parameter is not a known Objective-C class type"); 3875 type = error_mark_node; 3876 } 3877 else if (cur_try_context->catch_list) 3878 { 3879 /* Examine previous @catch clauses and see if we've already 3880 caught the type in question. */ 3881 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list); 3882 for (; !tsi_end_p (i); tsi_next (&i)) 3883 { 3884 tree stmt = tsi_stmt (i); 3885 t = CATCH_TYPES (stmt); 3886 if (t == error_mark_node) 3887 continue; 3888 if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type))) 3889 { 3890 warning (0, "exception of type %<%T%> will be caught", 3891 TREE_TYPE (type)); 3892 warning_at (EXPR_LOCATION (stmt), 0, " by earlier handler for %<%T%>", 3893 TREE_TYPE (t ? t : objc_object_type)); 3894 break; 3895 } 3896 } 3897 } 3898 3899 /* Record the data for the catch in the try context so that we can 3900 finalize it later. */ 3901 t = build_stmt (input_location, CATCH_EXPR, type, compound); 3902 cur_try_context->current_catch = t; 3903 3904 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */ 3905 t = objc_build_exc_ptr (); 3906 t = convert (TREE_TYPE (decl), t); 3907 t = build2 (MODIFY_EXPR, void_type_node, decl, t); 3908 add_stmt (t); 3909 } 3910 3911 /* Called just after parsing the closing brace of a @catch clause. Close 3912 the open binding level, and record a CATCH_EXPR for it. */ 3913 3914 void 3915 objc_finish_catch_clause (void) 3916 { 3917 tree c = cur_try_context->current_catch; 3918 cur_try_context->current_catch = NULL; 3919 cur_try_context->end_catch_locus = input_location; 3920 3921 CATCH_BODY (c) = c_end_compound_stmt (input_location, CATCH_BODY (c), 1); 3922 append_to_statement_list (c, &cur_try_context->catch_list); 3923 } 3924 3925 /* Called after parsing a @finally clause and its associated BODY. 3926 Record the body for later placement. */ 3927 3928 void 3929 objc_build_finally_clause (location_t finally_locus, tree body) 3930 { 3931 cur_try_context->finally_body = body; 3932 cur_try_context->finally_locus = finally_locus; 3933 cur_try_context->end_finally_locus = input_location; 3934 } 3935 3936 /* Called to finalize a @try construct. */ 3937 3938 tree 3939 objc_finish_try_stmt (void) 3940 { 3941 struct objc_try_context *c = cur_try_context; 3942 tree stmt; 3943 3944 if (c->catch_list == NULL && c->finally_body == NULL) 3945 error ("%<@try%> without %<@catch%> or %<@finally%>"); 3946 3947 /* If we're doing Darwin setjmp exceptions, build the big nasty. */ 3948 if (flag_objc_sjlj_exceptions) 3949 { 3950 bool save = in_late_binary_op; 3951 in_late_binary_op = true; 3952 if (!cur_try_context->finally_body) 3953 { 3954 cur_try_context->finally_locus = input_location; 3955 cur_try_context->end_finally_locus = input_location; 3956 } 3957 stmt = next_sjlj_build_try_catch_finally (); 3958 in_late_binary_op = save; 3959 } 3960 else 3961 { 3962 /* Otherwise, nest the CATCH inside a FINALLY. */ 3963 stmt = c->try_body; 3964 if (c->catch_list) 3965 { 3966 stmt = build_stmt (input_location, TRY_CATCH_EXPR, stmt, c->catch_list); 3967 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus); 3968 } 3969 if (c->finally_body) 3970 { 3971 stmt = build_stmt (input_location, TRY_FINALLY_EXPR, stmt, c->finally_body); 3972 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus); 3973 } 3974 } 3975 add_stmt (stmt); 3976 3977 cur_try_context = c->outer; 3978 free (c); 3979 return stmt; 3980 } 3981 3982 tree 3983 objc_build_throw_stmt (location_t loc, tree throw_expr) 3984 { 3985 tree args; 3986 3987 if (flag_objc_sjlj_exceptions) 3988 { 3989 /* On Darwin, ObjC exceptions require a sufficiently recent 3990 version of the runtime, so the user must ask for them explicitly. */ 3991 if (!flag_objc_exceptions) 3992 warning (0, "use %<-fobjc-exceptions%> to enable Objective-C " 3993 "exception syntax"); 3994 } 3995 3996 if (throw_expr == NULL) 3997 { 3998 /* If we're not inside a @catch block, there is no "current 3999 exception" to be rethrown. */ 4000 if (cur_try_context == NULL 4001 || cur_try_context->current_catch == NULL) 4002 { 4003 error_at (loc, "%<@throw%> (rethrow) used outside of a @catch block"); 4004 return NULL_TREE; 4005 } 4006 4007 /* Otherwise the object is still sitting in the EXC_PTR_EXPR 4008 value that we get from the runtime. */ 4009 throw_expr = objc_build_exc_ptr (); 4010 } 4011 4012 /* A throw is just a call to the runtime throw function with the 4013 object as a parameter. */ 4014 args = tree_cons (NULL, throw_expr, NULL); 4015 return add_stmt (build_function_call (loc, 4016 objc_exception_throw_decl, args)); 4017 } 4018 4019 tree 4020 objc_build_synchronized (location_t start_locus, tree mutex, tree body) 4021 { 4022 tree args, call; 4023 4024 /* First lock the mutex. */ 4025 mutex = save_expr (mutex); 4026 args = tree_cons (NULL, mutex, NULL); 4027 call = build_function_call (input_location, 4028 objc_sync_enter_decl, args); 4029 SET_EXPR_LOCATION (call, start_locus); 4030 add_stmt (call); 4031 4032 /* Build the mutex unlock. */ 4033 args = tree_cons (NULL, mutex, NULL); 4034 call = build_function_call (input_location, 4035 objc_sync_exit_decl, args); 4036 SET_EXPR_LOCATION (call, input_location); 4037 4038 /* Put the that and the body in a TRY_FINALLY. */ 4039 objc_begin_try_stmt (start_locus, body); 4040 objc_build_finally_clause (input_location, call); 4041 return objc_finish_try_stmt (); 4042 } 4043 4044 4045 /* Predefine the following data type: 4046 4047 struct _objc_exception_data 4048 { 4049 int buf[OBJC_JBLEN]; 4050 void *pointers[4]; 4051 }; */ 4052 4053 /* The following yuckiness should prevent users from having to #include 4054 <setjmp.h> in their code... */ 4055 4056 /* Define to a harmless positive value so the below code doesn't die. */ 4057 #ifndef OBJC_JBLEN 4058 #define OBJC_JBLEN 18 4059 #endif 4060 4061 static void 4062 build_next_objc_exception_stuff (void) 4063 { 4064 tree field_decl, field_decl_chain, index, temp_type; 4065 4066 objc_exception_data_template 4067 = objc_start_struct (get_identifier (UTAG_EXCDATA)); 4068 4069 /* int buf[OBJC_JBLEN]; */ 4070 4071 index = build_index_type (build_int_cst (NULL_TREE, OBJC_JBLEN - 1)); 4072 field_decl = create_field_decl (build_array_type (integer_type_node, index), 4073 "buf"); 4074 field_decl_chain = field_decl; 4075 4076 /* void *pointers[4]; */ 4077 4078 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1)); 4079 field_decl = create_field_decl (build_array_type (ptr_type_node, index), 4080 "pointers"); 4081 chainon (field_decl_chain, field_decl); 4082 4083 objc_finish_struct (objc_exception_data_template, field_decl_chain); 4084 4085 /* int _setjmp(...); */ 4086 /* If the user includes <setjmp.h>, this shall be superseded by 4087 'int _setjmp(jmp_buf);' */ 4088 temp_type = build_function_type (integer_type_node, NULL_TREE); 4089 objc_setjmp_decl 4090 = add_builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE); 4091 4092 /* id objc_exception_extract(struct _objc_exception_data *); */ 4093 temp_type 4094 = build_function_type (objc_object_type, 4095 tree_cons (NULL_TREE, 4096 build_pointer_type (objc_exception_data_template), 4097 OBJC_VOID_AT_END)); 4098 objc_exception_extract_decl 4099 = add_builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, 4100 NULL_TREE); 4101 /* void objc_exception_try_enter(struct _objc_exception_data *); */ 4102 /* void objc_exception_try_exit(struct _objc_exception_data *); */ 4103 temp_type 4104 = build_function_type (void_type_node, 4105 tree_cons (NULL_TREE, 4106 build_pointer_type (objc_exception_data_template), 4107 OBJC_VOID_AT_END)); 4108 objc_exception_try_enter_decl 4109 = add_builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, 4110 NULL_TREE); 4111 objc_exception_try_exit_decl 4112 = add_builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, 4113 NULL_TREE); 4114 4115 /* int objc_exception_match(id, id); */ 4116 temp_type 4117 = build_function_type (integer_type_node, 4118 tree_cons (NULL_TREE, objc_object_type, 4119 tree_cons (NULL_TREE, objc_object_type, 4120 OBJC_VOID_AT_END))); 4121 objc_exception_match_decl 4122 = add_builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, 4123 NULL_TREE); 4124 4125 /* id objc_assign_ivar (id, id, unsigned int); */ 4126 /* id objc_assign_ivar_Fast (id, id, unsigned int) 4127 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */ 4128 temp_type 4129 = build_function_type (objc_object_type, 4130 tree_cons 4131 (NULL_TREE, objc_object_type, 4132 tree_cons (NULL_TREE, objc_object_type, 4133 tree_cons (NULL_TREE, 4134 unsigned_type_node, 4135 OBJC_VOID_AT_END)))); 4136 objc_assign_ivar_decl 4137 = add_builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN, 4138 NULL, NULL_TREE); 4139 #ifdef OFFS_ASSIGNIVAR_FAST 4140 objc_assign_ivar_fast_decl 4141 = add_builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0, 4142 NOT_BUILT_IN, NULL, NULL_TREE); 4143 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl) 4144 = tree_cons (get_identifier ("hard_coded_address"), 4145 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST), 4146 NULL_TREE); 4147 #else 4148 /* Default to slower ivar method. */ 4149 objc_assign_ivar_fast_decl = objc_assign_ivar_decl; 4150 #endif 4151 4152 /* id objc_assign_global (id, id *); */ 4153 /* id objc_assign_strongCast (id, id *); */ 4154 temp_type = build_function_type (objc_object_type, 4155 tree_cons (NULL_TREE, objc_object_type, 4156 tree_cons (NULL_TREE, build_pointer_type (objc_object_type), 4157 OBJC_VOID_AT_END))); 4158 objc_assign_global_decl 4159 = add_builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL, 4160 NULL_TREE); 4161 objc_assign_strong_cast_decl 4162 = add_builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL, 4163 NULL_TREE); 4164 } 4165 4166 static void 4167 build_objc_exception_stuff (void) 4168 { 4169 tree noreturn_list, nothrow_list, temp_type; 4170 4171 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL); 4172 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL); 4173 4174 /* void objc_exception_throw(id) __attribute__((noreturn)); */ 4175 /* void objc_sync_enter(id); */ 4176 /* void objc_sync_exit(id); */ 4177 temp_type = build_function_type (void_type_node, 4178 tree_cons (NULL_TREE, objc_object_type, 4179 OBJC_VOID_AT_END)); 4180 objc_exception_throw_decl 4181 = add_builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL, 4182 noreturn_list); 4183 objc_sync_enter_decl 4184 = add_builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN, 4185 NULL, nothrow_list); 4186 objc_sync_exit_decl 4187 = add_builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN, 4188 NULL, nothrow_list); 4189 } 4190 4191 /* Construct a C struct corresponding to ObjC class CLASS, with the same 4192 name as the class: 4193 4194 struct <classname> { 4195 struct _objc_class *isa; 4196 ... 4197 }; */ 4198 4199 static void 4200 build_private_template (tree klass) 4201 { 4202 if (!CLASS_STATIC_TEMPLATE (klass)) 4203 { 4204 tree record = objc_build_struct (klass, 4205 get_class_ivars (klass, false), 4206 CLASS_SUPER_NAME (klass)); 4207 4208 /* Set the TREE_USED bit for this struct, so that stab generator 4209 can emit stabs for this struct type. */ 4210 if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record)) 4211 TREE_USED (TYPE_STUB_DECL (record)) = 1; 4212 } 4213 } 4214 4215 /* Begin code generation for protocols... */ 4216 4217 /* struct _objc_protocol { 4218 struct _objc_class *isa; 4219 char *protocol_name; 4220 struct _objc_protocol **protocol_list; 4221 struct _objc__method_prototype_list *instance_methods; 4222 struct _objc__method_prototype_list *class_methods; 4223 }; */ 4224 4225 static void 4226 build_protocol_template (void) 4227 { 4228 tree field_decl, field_decl_chain; 4229 4230 objc_protocol_template = objc_start_struct (get_identifier (UTAG_PROTOCOL)); 4231 4232 /* struct _objc_class *isa; */ 4233 field_decl = create_field_decl (build_pointer_type 4234 (xref_tag (RECORD_TYPE, 4235 get_identifier (UTAG_CLASS))), 4236 "isa"); 4237 field_decl_chain = field_decl; 4238 4239 /* char *protocol_name; */ 4240 field_decl = create_field_decl (string_type_node, "protocol_name"); 4241 chainon (field_decl_chain, field_decl); 4242 4243 /* struct _objc_protocol **protocol_list; */ 4244 field_decl = create_field_decl (build_pointer_type 4245 (build_pointer_type 4246 (objc_protocol_template)), 4247 "protocol_list"); 4248 chainon (field_decl_chain, field_decl); 4249 4250 /* struct _objc__method_prototype_list *instance_methods; */ 4251 field_decl = create_field_decl (objc_method_proto_list_ptr, 4252 "instance_methods"); 4253 chainon (field_decl_chain, field_decl); 4254 4255 /* struct _objc__method_prototype_list *class_methods; */ 4256 field_decl = create_field_decl (objc_method_proto_list_ptr, 4257 "class_methods"); 4258 chainon (field_decl_chain, field_decl); 4259 4260 objc_finish_struct (objc_protocol_template, field_decl_chain); 4261 } 4262 4263 static tree 4264 build_descriptor_table_initializer (tree type, tree entries) 4265 { 4266 tree initlist = NULL_TREE; 4267 4268 do 4269 { 4270 tree eltlist = NULL_TREE; 4271 4272 eltlist 4273 = tree_cons (NULL_TREE, 4274 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE); 4275 eltlist 4276 = tree_cons (NULL_TREE, 4277 add_objc_string (METHOD_ENCODING (entries), 4278 meth_var_types), 4279 eltlist); 4280 4281 initlist 4282 = tree_cons (NULL_TREE, 4283 objc_build_constructor (type, nreverse (eltlist)), 4284 initlist); 4285 4286 entries = TREE_CHAIN (entries); 4287 } 4288 while (entries); 4289 4290 return objc_build_constructor (build_array_type (type, 0), 4291 nreverse (initlist)); 4292 } 4293 4294 /* struct objc_method_prototype_list { 4295 int count; 4296 struct objc_method_prototype { 4297 SEL name; 4298 char *types; 4299 } list[1]; 4300 }; */ 4301 4302 static tree 4303 build_method_prototype_list_template (tree list_type, int size) 4304 { 4305 tree objc_ivar_list_record; 4306 tree field_decl, field_decl_chain; 4307 4308 /* Generate an unnamed struct definition. */ 4309 4310 objc_ivar_list_record = objc_start_struct (NULL_TREE); 4311 4312 /* int method_count; */ 4313 field_decl = create_field_decl (integer_type_node, "method_count"); 4314 field_decl_chain = field_decl; 4315 4316 /* struct objc_method method_list[]; */ 4317 field_decl = create_field_decl (build_array_type 4318 (list_type, 4319 build_index_type 4320 (build_int_cst (NULL_TREE, size - 1))), 4321 "method_list"); 4322 chainon (field_decl_chain, field_decl); 4323 4324 objc_finish_struct (objc_ivar_list_record, field_decl_chain); 4325 4326 return objc_ivar_list_record; 4327 } 4328 4329 static tree 4330 build_method_prototype_template (void) 4331 { 4332 tree proto_record; 4333 tree field_decl, field_decl_chain; 4334 4335 proto_record = objc_start_struct (get_identifier (UTAG_METHOD_PROTOTYPE)); 4336 4337 /* SEL _cmd; */ 4338 field_decl = create_field_decl (objc_selector_type, "_cmd"); 4339 field_decl_chain = field_decl; 4340 4341 /* char *method_types; */ 4342 field_decl = create_field_decl (string_type_node, "method_types"); 4343 chainon (field_decl_chain, field_decl); 4344 4345 objc_finish_struct (proto_record, field_decl_chain); 4346 4347 return proto_record; 4348 } 4349 4350 static tree 4351 objc_method_parm_type (tree type) 4352 { 4353 type = TREE_VALUE (TREE_TYPE (type)); 4354 if (TREE_CODE (type) == TYPE_DECL) 4355 type = TREE_TYPE (type); 4356 return type; 4357 } 4358 4359 static int 4360 objc_encoded_type_size (tree type) 4361 { 4362 int sz = int_size_in_bytes (type); 4363 4364 /* Make all integer and enum types at least as large 4365 as an int. */ 4366 if (sz > 0 && INTEGRAL_TYPE_P (type)) 4367 sz = MAX (sz, int_size_in_bytes (integer_type_node)); 4368 /* Treat arrays as pointers, since that's how they're 4369 passed in. */ 4370 else if (TREE_CODE (type) == ARRAY_TYPE) 4371 sz = int_size_in_bytes (ptr_type_node); 4372 return sz; 4373 } 4374 4375 static tree 4376 encode_method_prototype (tree method_decl) 4377 { 4378 tree parms; 4379 int parm_offset, i; 4380 char buf[40]; 4381 tree result; 4382 4383 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */ 4384 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl))); 4385 4386 /* Encode return type. */ 4387 encode_type (objc_method_parm_type (method_decl), 4388 obstack_object_size (&util_obstack), 4389 OBJC_ENCODE_INLINE_DEFS); 4390 4391 /* Stack size. */ 4392 /* The first two arguments (self and _cmd) are pointers; account for 4393 their size. */ 4394 i = int_size_in_bytes (ptr_type_node); 4395 parm_offset = 2 * i; 4396 for (parms = METHOD_SEL_ARGS (method_decl); parms; 4397 parms = TREE_CHAIN (parms)) 4398 { 4399 tree type = objc_method_parm_type (parms); 4400 int sz = objc_encoded_type_size (type); 4401 4402 /* If a type size is not known, bail out. */ 4403 if (sz < 0) 4404 { 4405 error ("type %q+D does not have a known size", 4406 type); 4407 /* Pretend that the encoding succeeded; the compilation will 4408 fail nevertheless. */ 4409 goto finish_encoding; 4410 } 4411 parm_offset += sz; 4412 } 4413 4414 sprintf (buf, "%d@0:%d", parm_offset, i); 4415 obstack_grow (&util_obstack, buf, strlen (buf)); 4416 4417 /* Argument types. */ 4418 parm_offset = 2 * i; 4419 for (parms = METHOD_SEL_ARGS (method_decl); parms; 4420 parms = TREE_CHAIN (parms)) 4421 { 4422 tree type = objc_method_parm_type (parms); 4423 4424 /* Process argument qualifiers for user supplied arguments. */ 4425 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms))); 4426 4427 /* Type. */ 4428 encode_type (type, obstack_object_size (&util_obstack), 4429 OBJC_ENCODE_INLINE_DEFS); 4430 4431 /* Compute offset. */ 4432 sprintf (buf, "%d", parm_offset); 4433 parm_offset += objc_encoded_type_size (type); 4434 4435 obstack_grow (&util_obstack, buf, strlen (buf)); 4436 } 4437 4438 finish_encoding: 4439 obstack_1grow (&util_obstack, '\0'); 4440 result = get_identifier (XOBFINISH (&util_obstack, char *)); 4441 obstack_free (&util_obstack, util_firstobj); 4442 return result; 4443 } 4444 4445 static tree 4446 generate_descriptor_table (tree type, const char *name, int size, tree list, 4447 tree proto) 4448 { 4449 tree decl, initlist; 4450 4451 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto)); 4452 4453 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size)); 4454 initlist = tree_cons (NULL_TREE, list, initlist); 4455 4456 finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist))); 4457 4458 return decl; 4459 } 4460 4461 static void 4462 generate_method_descriptors (tree protocol) 4463 { 4464 tree initlist, chain, method_list_template; 4465 int size; 4466 4467 if (!objc_method_prototype_template) 4468 objc_method_prototype_template = build_method_prototype_template (); 4469 4470 chain = PROTOCOL_CLS_METHODS (protocol); 4471 if (chain) 4472 { 4473 size = list_length (chain); 4474 4475 method_list_template 4476 = build_method_prototype_list_template (objc_method_prototype_template, 4477 size); 4478 4479 initlist 4480 = build_descriptor_table_initializer (objc_method_prototype_template, 4481 chain); 4482 4483 UOBJC_CLASS_METHODS_decl 4484 = generate_descriptor_table (method_list_template, 4485 "_OBJC_PROTOCOL_CLASS_METHODS", 4486 size, initlist, protocol); 4487 } 4488 else 4489 UOBJC_CLASS_METHODS_decl = 0; 4490 4491 chain = PROTOCOL_NST_METHODS (protocol); 4492 if (chain) 4493 { 4494 size = list_length (chain); 4495 4496 method_list_template 4497 = build_method_prototype_list_template (objc_method_prototype_template, 4498 size); 4499 initlist 4500 = build_descriptor_table_initializer (objc_method_prototype_template, 4501 chain); 4502 4503 UOBJC_INSTANCE_METHODS_decl 4504 = generate_descriptor_table (method_list_template, 4505 "_OBJC_PROTOCOL_INSTANCE_METHODS", 4506 size, initlist, protocol); 4507 } 4508 else 4509 UOBJC_INSTANCE_METHODS_decl = 0; 4510 } 4511 4512 static void 4513 generate_protocol_references (tree plist) 4514 { 4515 tree lproto; 4516 4517 /* Forward declare protocols referenced. */ 4518 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) 4519 { 4520 tree proto = TREE_VALUE (lproto); 4521 4522 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE 4523 && PROTOCOL_NAME (proto)) 4524 { 4525 if (! PROTOCOL_FORWARD_DECL (proto)) 4526 build_protocol_reference (proto); 4527 4528 if (PROTOCOL_LIST (proto)) 4529 generate_protocol_references (PROTOCOL_LIST (proto)); 4530 } 4531 } 4532 } 4533 4534 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the 4535 current class. */ 4536 #ifdef OBJCPLUS 4537 static void 4538 objc_generate_cxx_ctor_or_dtor (bool dtor) 4539 { 4540 tree fn, body, compound_stmt, ivar; 4541 4542 /* - (id) .cxx_construct { ... return self; } */ 4543 /* - (void) .cxx_construct { ... } */ 4544 4545 objc_set_method_type (MINUS_EXPR); 4546 objc_start_method_definition 4547 (objc_build_method_signature (build_tree_list (NULL_TREE, 4548 dtor 4549 ? void_type_node 4550 : objc_object_type), 4551 get_identifier (dtor 4552 ? TAG_CXX_DESTRUCT 4553 : TAG_CXX_CONSTRUCT), 4554 make_node (TREE_LIST), 4555 false)); 4556 body = begin_function_body (); 4557 compound_stmt = begin_compound_stmt (0); 4558 4559 ivar = CLASS_IVARS (implementation_template); 4560 /* Destroy ivars in reverse order. */ 4561 if (dtor) 4562 ivar = nreverse (copy_list (ivar)); 4563 4564 for (; ivar; ivar = TREE_CHAIN (ivar)) 4565 { 4566 if (TREE_CODE (ivar) == FIELD_DECL) 4567 { 4568 tree type = TREE_TYPE (ivar); 4569 4570 /* Call the ivar's default constructor or destructor. Do not 4571 call the destructor unless a corresponding constructor call 4572 has also been made (or is not needed). */ 4573 if (MAYBE_CLASS_TYPE_P (type) 4574 && (dtor 4575 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type) 4576 && (!TYPE_NEEDS_CONSTRUCTING (type) 4577 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type))) 4578 : (TYPE_NEEDS_CONSTRUCTING (type) 4579 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))) 4580 finish_expr_stmt 4581 (build_special_member_call 4582 (build_ivar_reference (DECL_NAME (ivar)), 4583 dtor ? complete_dtor_identifier : complete_ctor_identifier, 4584 NULL, type, LOOKUP_NORMAL, tf_warning_or_error)); 4585 } 4586 } 4587 4588 /* The constructor returns 'self'. */ 4589 if (!dtor) 4590 finish_return_stmt (self_decl); 4591 4592 finish_compound_stmt (compound_stmt); 4593 finish_function_body (body); 4594 fn = current_function_decl; 4595 finish_function (); 4596 objc_finish_method_definition (fn); 4597 } 4598 4599 /* The following routine will examine the current @interface for any 4600 non-POD C++ ivars requiring non-trivial construction and/or 4601 destruction, and then synthesize special '- .cxx_construct' and/or 4602 '- .cxx_destruct' methods which will run the appropriate 4603 construction or destruction code. Note that ivars inherited from 4604 super-classes are _not_ considered. */ 4605 static void 4606 objc_generate_cxx_cdtors (void) 4607 { 4608 bool need_ctor = false, need_dtor = false; 4609 tree ivar; 4610 4611 /* We do not want to do this for categories, since they do not have 4612 their own ivars. */ 4613 4614 if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE) 4615 return; 4616 4617 /* First, determine if we even need a constructor and/or destructor. */ 4618 4619 for (ivar = CLASS_IVARS (implementation_template); ivar; 4620 ivar = TREE_CHAIN (ivar)) 4621 { 4622 if (TREE_CODE (ivar) == FIELD_DECL) 4623 { 4624 tree type = TREE_TYPE (ivar); 4625 4626 if (MAYBE_CLASS_TYPE_P (type)) 4627 { 4628 if (TYPE_NEEDS_CONSTRUCTING (type) 4629 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type)) 4630 /* NB: If a default constructor is not available, we will not 4631 be able to initialize this ivar; the add_instance_variable() 4632 routine will already have warned about this. */ 4633 need_ctor = true; 4634 4635 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type) 4636 && (!TYPE_NEEDS_CONSTRUCTING (type) 4637 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type))) 4638 /* NB: If a default constructor is not available, we will not 4639 call the destructor either, for symmetry. */ 4640 need_dtor = true; 4641 } 4642 } 4643 } 4644 4645 /* Generate '- .cxx_construct' if needed. */ 4646 4647 if (need_ctor) 4648 objc_generate_cxx_ctor_or_dtor (false); 4649 4650 /* Generate '- .cxx_destruct' if needed. */ 4651 4652 if (need_dtor) 4653 objc_generate_cxx_ctor_or_dtor (true); 4654 4655 /* The 'imp_list' variable points at an imp_entry record for the current 4656 @implementation. Record the existence of '- .cxx_construct' and/or 4657 '- .cxx_destruct' methods therein; it will be included in the 4658 metadata for the class. */ 4659 if (flag_next_runtime) 4660 imp_list->has_cxx_cdtors = (need_ctor || need_dtor); 4661 } 4662 #endif 4663 4664 /* For each protocol which was referenced either from a @protocol() 4665 expression, or because a class/category implements it (then a 4666 pointer to the protocol is stored in the struct describing the 4667 class/category), we create a statically allocated instance of the 4668 Protocol class. The code is written in such a way as to generate 4669 as few Protocol objects as possible; we generate a unique Protocol 4670 instance for each protocol, and we don't generate a Protocol 4671 instance if the protocol is never referenced (either from a 4672 @protocol() or from a class/category implementation). These 4673 statically allocated objects can be referred to via the static 4674 (that is, private to this module) symbols _OBJC_PROTOCOL_n. 4675 4676 The statically allocated Protocol objects that we generate here 4677 need to be fixed up at runtime in order to be used: the 'isa' 4678 pointer of the objects need to be set up to point to the 'Protocol' 4679 class, as known at runtime. 4680 4681 The NeXT runtime fixes up all protocols at program startup time, 4682 before main() is entered. It uses a low-level trick to look up all 4683 those symbols, then loops on them and fixes them up. 4684 4685 The GNU runtime as well fixes up all protocols before user code 4686 from the module is executed; it requires pointers to those symbols 4687 to be put in the objc_symtab (which is then passed as argument to 4688 the function __objc_exec_class() which the compiler sets up to be 4689 executed automatically when the module is loaded); setup of those 4690 Protocol objects happen in two ways in the GNU runtime: all 4691 Protocol objects referred to by a class or category implementation 4692 are fixed up when the class/category is loaded; all Protocol 4693 objects referred to by a @protocol() expression are added by the 4694 compiler to the list of statically allocated instances to fixup 4695 (the same list holding the statically allocated constant string 4696 objects). Because, as explained above, the compiler generates as 4697 few Protocol objects as possible, some Protocol object might end up 4698 being referenced multiple times when compiled with the GNU runtime, 4699 and end up being fixed up multiple times at runtime initialization. 4700 But that doesn't hurt, it's just a little inefficient. */ 4701 4702 static void 4703 generate_protocols (void) 4704 { 4705 tree p, encoding; 4706 tree decl; 4707 tree initlist, protocol_name_expr, refs_decl, refs_expr; 4708 4709 /* If a protocol was directly referenced, pull in indirect references. */ 4710 for (p = protocol_chain; p; p = TREE_CHAIN (p)) 4711 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p)) 4712 generate_protocol_references (PROTOCOL_LIST (p)); 4713 4714 for (p = protocol_chain; p; p = TREE_CHAIN (p)) 4715 { 4716 tree nst_methods = PROTOCOL_NST_METHODS (p); 4717 tree cls_methods = PROTOCOL_CLS_METHODS (p); 4718 4719 /* If protocol wasn't referenced, don't generate any code. */ 4720 decl = PROTOCOL_FORWARD_DECL (p); 4721 4722 if (!decl) 4723 continue; 4724 4725 /* Make sure we link in the Protocol class. */ 4726 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME)); 4727 4728 while (nst_methods) 4729 { 4730 if (! METHOD_ENCODING (nst_methods)) 4731 { 4732 encoding = encode_method_prototype (nst_methods); 4733 METHOD_ENCODING (nst_methods) = encoding; 4734 } 4735 nst_methods = TREE_CHAIN (nst_methods); 4736 } 4737 4738 while (cls_methods) 4739 { 4740 if (! METHOD_ENCODING (cls_methods)) 4741 { 4742 encoding = encode_method_prototype (cls_methods); 4743 METHOD_ENCODING (cls_methods) = encoding; 4744 } 4745 4746 cls_methods = TREE_CHAIN (cls_methods); 4747 } 4748 generate_method_descriptors (p); 4749 4750 if (PROTOCOL_LIST (p)) 4751 refs_decl = generate_protocol_list (p); 4752 else 4753 refs_decl = 0; 4754 4755 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */ 4756 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names); 4757 4758 if (refs_decl) 4759 refs_expr = convert (build_pointer_type (build_pointer_type 4760 (objc_protocol_template)), 4761 build_unary_op (input_location, 4762 ADDR_EXPR, refs_decl, 0)); 4763 else 4764 refs_expr = build_int_cst (NULL_TREE, 0); 4765 4766 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set 4767 by generate_method_descriptors, which is called above. */ 4768 initlist = build_protocol_initializer (TREE_TYPE (decl), 4769 protocol_name_expr, refs_expr, 4770 UOBJC_INSTANCE_METHODS_decl, 4771 UOBJC_CLASS_METHODS_decl); 4772 finish_var_decl (decl, initlist); 4773 } 4774 } 4775 4776 static tree 4777 build_protocol_initializer (tree type, tree protocol_name, 4778 tree protocol_list, tree instance_methods, 4779 tree class_methods) 4780 { 4781 tree initlist = NULL_TREE, expr; 4782 tree cast_type = build_pointer_type 4783 (xref_tag (RECORD_TYPE, 4784 get_identifier (UTAG_CLASS))); 4785 4786 /* Filling the "isa" in with one allows the runtime system to 4787 detect that the version change...should remove before final release. */ 4788 4789 expr = build_int_cst (cast_type, PROTOCOL_VERSION); 4790 initlist = tree_cons (NULL_TREE, expr, initlist); 4791 initlist = tree_cons (NULL_TREE, protocol_name, initlist); 4792 initlist = tree_cons (NULL_TREE, protocol_list, initlist); 4793 4794 if (!instance_methods) 4795 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist); 4796 else 4797 { 4798 expr = convert (objc_method_proto_list_ptr, 4799 build_unary_op (input_location, 4800 ADDR_EXPR, instance_methods, 0)); 4801 initlist = tree_cons (NULL_TREE, expr, initlist); 4802 } 4803 4804 if (!class_methods) 4805 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist); 4806 else 4807 { 4808 expr = convert (objc_method_proto_list_ptr, 4809 build_unary_op (input_location, 4810 ADDR_EXPR, class_methods, 0)); 4811 initlist = tree_cons (NULL_TREE, expr, initlist); 4812 } 4813 4814 return objc_build_constructor (type, nreverse (initlist)); 4815 } 4816 4817 /* struct _objc_category { 4818 char *category_name; 4819 char *class_name; 4820 struct _objc_method_list *instance_methods; 4821 struct _objc_method_list *class_methods; 4822 struct _objc_protocol_list *protocols; 4823 }; */ 4824 4825 static void 4826 build_category_template (void) 4827 { 4828 tree field_decl, field_decl_chain; 4829 4830 objc_category_template = objc_start_struct (get_identifier (UTAG_CATEGORY)); 4831 4832 /* char *category_name; */ 4833 field_decl = create_field_decl (string_type_node, "category_name"); 4834 field_decl_chain = field_decl; 4835 4836 /* char *class_name; */ 4837 field_decl = create_field_decl (string_type_node, "class_name"); 4838 chainon (field_decl_chain, field_decl); 4839 4840 /* struct _objc_method_list *instance_methods; */ 4841 field_decl = create_field_decl (objc_method_list_ptr, 4842 "instance_methods"); 4843 chainon (field_decl_chain, field_decl); 4844 4845 /* struct _objc_method_list *class_methods; */ 4846 field_decl = create_field_decl (objc_method_list_ptr, 4847 "class_methods"); 4848 chainon (field_decl_chain, field_decl); 4849 4850 /* struct _objc_protocol **protocol_list; */ 4851 field_decl = create_field_decl (build_pointer_type 4852 (build_pointer_type 4853 (objc_protocol_template)), 4854 "protocol_list"); 4855 chainon (field_decl_chain, field_decl); 4856 4857 objc_finish_struct (objc_category_template, field_decl_chain); 4858 } 4859 4860 /* struct _objc_selector { 4861 SEL sel_id; 4862 char *sel_type; 4863 }; */ 4864 4865 static void 4866 build_selector_template (void) 4867 { 4868 tree field_decl, field_decl_chain; 4869 4870 objc_selector_template = objc_start_struct (get_identifier (UTAG_SELECTOR)); 4871 4872 /* SEL sel_id; */ 4873 field_decl = create_field_decl (objc_selector_type, "sel_id"); 4874 field_decl_chain = field_decl; 4875 4876 /* char *sel_type; */ 4877 field_decl = create_field_decl (string_type_node, "sel_type"); 4878 chainon (field_decl_chain, field_decl); 4879 4880 objc_finish_struct (objc_selector_template, field_decl_chain); 4881 } 4882 4883 /* struct _objc_class { 4884 struct _objc_class *isa; 4885 struct _objc_class *super_class; 4886 char *name; 4887 long version; 4888 long info; 4889 long instance_size; 4890 struct _objc_ivar_list *ivars; 4891 struct _objc_method_list *methods; 4892 #ifdef __NEXT_RUNTIME__ 4893 struct objc_cache *cache; 4894 #else 4895 struct sarray *dtable; 4896 struct _objc_class *subclass_list; 4897 struct _objc_class *sibling_class; 4898 #endif 4899 struct _objc_protocol_list *protocols; 4900 #ifdef __NEXT_RUNTIME__ 4901 void *sel_id; 4902 #endif 4903 void *gc_object_type; 4904 }; */ 4905 4906 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by 4907 the NeXT/Apple runtime; still, the compiler must generate them to 4908 maintain backward binary compatibility (and to allow for future 4909 expansion). */ 4910 4911 static void 4912 build_class_template (void) 4913 { 4914 tree field_decl, field_decl_chain; 4915 4916 objc_class_template = objc_start_struct (get_identifier (UTAG_CLASS)); 4917 4918 /* struct _objc_class *isa; */ 4919 field_decl = create_field_decl (build_pointer_type (objc_class_template), 4920 "isa"); 4921 field_decl_chain = field_decl; 4922 4923 /* struct _objc_class *super_class; */ 4924 field_decl = create_field_decl (build_pointer_type (objc_class_template), 4925 "super_class"); 4926 chainon (field_decl_chain, field_decl); 4927 4928 /* char *name; */ 4929 field_decl = create_field_decl (string_type_node, "name"); 4930 chainon (field_decl_chain, field_decl); 4931 4932 /* long version; */ 4933 field_decl = create_field_decl (long_integer_type_node, "version"); 4934 chainon (field_decl_chain, field_decl); 4935 4936 /* long info; */ 4937 field_decl = create_field_decl (long_integer_type_node, "info"); 4938 chainon (field_decl_chain, field_decl); 4939 4940 /* long instance_size; */ 4941 field_decl = create_field_decl (long_integer_type_node, "instance_size"); 4942 chainon (field_decl_chain, field_decl); 4943 4944 /* struct _objc_ivar_list *ivars; */ 4945 field_decl = create_field_decl (objc_ivar_list_ptr, 4946 "ivars"); 4947 chainon (field_decl_chain, field_decl); 4948 4949 /* struct _objc_method_list *methods; */ 4950 field_decl = create_field_decl (objc_method_list_ptr, 4951 "methods"); 4952 chainon (field_decl_chain, field_decl); 4953 4954 if (flag_next_runtime) 4955 { 4956 /* struct objc_cache *cache; */ 4957 field_decl = create_field_decl (build_pointer_type 4958 (xref_tag (RECORD_TYPE, 4959 get_identifier 4960 ("objc_cache"))), 4961 "cache"); 4962 chainon (field_decl_chain, field_decl); 4963 } 4964 else 4965 { 4966 /* struct sarray *dtable; */ 4967 field_decl = create_field_decl (build_pointer_type 4968 (xref_tag (RECORD_TYPE, 4969 get_identifier 4970 ("sarray"))), 4971 "dtable"); 4972 chainon (field_decl_chain, field_decl); 4973 4974 /* struct objc_class *subclass_list; */ 4975 field_decl = create_field_decl (build_pointer_type 4976 (objc_class_template), 4977 "subclass_list"); 4978 chainon (field_decl_chain, field_decl); 4979 4980 /* struct objc_class *sibling_class; */ 4981 field_decl = create_field_decl (build_pointer_type 4982 (objc_class_template), 4983 "sibling_class"); 4984 chainon (field_decl_chain, field_decl); 4985 } 4986 4987 /* struct _objc_protocol **protocol_list; */ 4988 field_decl = create_field_decl (build_pointer_type 4989 (build_pointer_type 4990 (xref_tag (RECORD_TYPE, 4991 get_identifier 4992 (UTAG_PROTOCOL)))), 4993 "protocol_list"); 4994 chainon (field_decl_chain, field_decl); 4995 4996 if (flag_next_runtime) 4997 { 4998 /* void *sel_id; */ 4999 field_decl = create_field_decl (build_pointer_type (void_type_node), 5000 "sel_id"); 5001 chainon (field_decl_chain, field_decl); 5002 } 5003 5004 /* void *gc_object_type; */ 5005 field_decl = create_field_decl (build_pointer_type (void_type_node), 5006 "gc_object_type"); 5007 chainon (field_decl_chain, field_decl); 5008 5009 objc_finish_struct (objc_class_template, field_decl_chain); 5010 } 5011 5012 /* Generate appropriate forward declarations for an implementation. */ 5013 5014 static void 5015 synth_forward_declarations (void) 5016 { 5017 tree an_id; 5018 5019 /* static struct objc_class _OBJC_CLASS_<my_name>; */ 5020 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS", 5021 objc_class_template); 5022 5023 /* static struct objc_class _OBJC_METACLASS_<my_name>; */ 5024 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS", 5025 objc_class_template); 5026 5027 /* Pre-build the following entities - for speed/convenience. */ 5028 5029 an_id = get_identifier ("super_class"); 5030 ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id); 5031 uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id); 5032 } 5033 5034 static void 5035 error_with_ivar (const char *message, tree decl) 5036 { 5037 error_at (DECL_SOURCE_LOCATION (decl), "%s %qs", 5038 message, identifier_to_locale (gen_declaration (decl))); 5039 5040 } 5041 5042 static void 5043 check_ivars (tree inter, tree imp) 5044 { 5045 tree intdecls = CLASS_RAW_IVARS (inter); 5046 tree impdecls = CLASS_RAW_IVARS (imp); 5047 5048 while (1) 5049 { 5050 tree t1, t2; 5051 5052 #ifdef OBJCPLUS 5053 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL) 5054 intdecls = TREE_CHAIN (intdecls); 5055 #endif 5056 if (intdecls == 0 && impdecls == 0) 5057 break; 5058 if (intdecls == 0 || impdecls == 0) 5059 { 5060 error ("inconsistent instance variable specification"); 5061 break; 5062 } 5063 5064 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls); 5065 5066 if (!comptypes (t1, t2) 5067 || !tree_int_cst_equal (DECL_INITIAL (intdecls), 5068 DECL_INITIAL (impdecls))) 5069 { 5070 if (DECL_NAME (intdecls) == DECL_NAME (impdecls)) 5071 { 5072 error_with_ivar ("conflicting instance variable type", 5073 impdecls); 5074 error_with_ivar ("previous declaration of", 5075 intdecls); 5076 } 5077 else /* both the type and the name don't match */ 5078 { 5079 error ("inconsistent instance variable specification"); 5080 break; 5081 } 5082 } 5083 5084 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls)) 5085 { 5086 error_with_ivar ("conflicting instance variable name", 5087 impdecls); 5088 error_with_ivar ("previous declaration of", 5089 intdecls); 5090 } 5091 5092 intdecls = TREE_CHAIN (intdecls); 5093 impdecls = TREE_CHAIN (impdecls); 5094 } 5095 } 5096 5097 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'. 5098 This needs to be done just once per compilation. */ 5099 5100 /* struct _objc_super { 5101 struct _objc_object *self; 5102 struct _objc_class *super_class; 5103 }; */ 5104 5105 static void 5106 build_super_template (void) 5107 { 5108 tree field_decl, field_decl_chain; 5109 5110 objc_super_template = objc_start_struct (get_identifier (UTAG_SUPER)); 5111 5112 /* struct _objc_object *self; */ 5113 field_decl = create_field_decl (objc_object_type, "self"); 5114 field_decl_chain = field_decl; 5115 5116 /* struct _objc_class *super_class; */ 5117 field_decl = create_field_decl (build_pointer_type (objc_class_template), 5118 "super_class"); 5119 chainon (field_decl_chain, field_decl); 5120 5121 objc_finish_struct (objc_super_template, field_decl_chain); 5122 } 5123 5124 /* struct _objc_ivar { 5125 char *ivar_name; 5126 char *ivar_type; 5127 int ivar_offset; 5128 }; */ 5129 5130 static tree 5131 build_ivar_template (void) 5132 { 5133 tree objc_ivar_id, objc_ivar_record; 5134 tree field_decl, field_decl_chain; 5135 5136 objc_ivar_id = get_identifier (UTAG_IVAR); 5137 objc_ivar_record = objc_start_struct (objc_ivar_id); 5138 5139 /* char *ivar_name; */ 5140 field_decl = create_field_decl (string_type_node, "ivar_name"); 5141 field_decl_chain = field_decl; 5142 5143 /* char *ivar_type; */ 5144 field_decl = create_field_decl (string_type_node, "ivar_type"); 5145 chainon (field_decl_chain, field_decl); 5146 5147 /* int ivar_offset; */ 5148 field_decl = create_field_decl (integer_type_node, "ivar_offset"); 5149 chainon (field_decl_chain, field_decl); 5150 5151 objc_finish_struct (objc_ivar_record, field_decl_chain); 5152 5153 return objc_ivar_record; 5154 } 5155 5156 /* struct { 5157 int ivar_count; 5158 struct objc_ivar ivar_list[ivar_count]; 5159 }; */ 5160 5161 static tree 5162 build_ivar_list_template (tree list_type, int size) 5163 { 5164 tree objc_ivar_list_record; 5165 tree field_decl, field_decl_chain; 5166 5167 objc_ivar_list_record = objc_start_struct (NULL_TREE); 5168 5169 /* int ivar_count; */ 5170 field_decl = create_field_decl (integer_type_node, "ivar_count"); 5171 field_decl_chain = field_decl; 5172 5173 /* struct objc_ivar ivar_list[]; */ 5174 field_decl = create_field_decl (build_array_type 5175 (list_type, 5176 build_index_type 5177 (build_int_cst (NULL_TREE, size - 1))), 5178 "ivar_list"); 5179 chainon (field_decl_chain, field_decl); 5180 5181 objc_finish_struct (objc_ivar_list_record, field_decl_chain); 5182 5183 return objc_ivar_list_record; 5184 } 5185 5186 /* struct { 5187 struct _objc__method_prototype_list *method_next; 5188 int method_count; 5189 struct objc_method method_list[method_count]; 5190 }; */ 5191 5192 static tree 5193 build_method_list_template (tree list_type, int size) 5194 { 5195 tree objc_ivar_list_record; 5196 tree field_decl, field_decl_chain; 5197 5198 objc_ivar_list_record = objc_start_struct (NULL_TREE); 5199 5200 /* struct _objc__method_prototype_list *method_next; */ 5201 field_decl = create_field_decl (objc_method_proto_list_ptr, 5202 "method_next"); 5203 field_decl_chain = field_decl; 5204 5205 /* int method_count; */ 5206 field_decl = create_field_decl (integer_type_node, "method_count"); 5207 chainon (field_decl_chain, field_decl); 5208 5209 /* struct objc_method method_list[]; */ 5210 field_decl = create_field_decl (build_array_type 5211 (list_type, 5212 build_index_type 5213 (build_int_cst (NULL_TREE, size - 1))), 5214 "method_list"); 5215 chainon (field_decl_chain, field_decl); 5216 5217 objc_finish_struct (objc_ivar_list_record, field_decl_chain); 5218 5219 return objc_ivar_list_record; 5220 } 5221 5222 static tree 5223 build_ivar_list_initializer (tree type, tree field_decl) 5224 { 5225 tree initlist = NULL_TREE; 5226 5227 do 5228 { 5229 tree ivar = NULL_TREE; 5230 5231 /* Set name. */ 5232 if (DECL_NAME (field_decl)) 5233 ivar = tree_cons (NULL_TREE, 5234 add_objc_string (DECL_NAME (field_decl), 5235 meth_var_names), 5236 ivar); 5237 else 5238 /* Unnamed bit-field ivar (yuck). */ 5239 ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), ivar); 5240 5241 /* Set type. */ 5242 encode_field_decl (field_decl, 5243 obstack_object_size (&util_obstack), 5244 OBJC_ENCODE_DONT_INLINE_DEFS); 5245 5246 /* Null terminate string. */ 5247 obstack_1grow (&util_obstack, 0); 5248 ivar 5249 = tree_cons 5250 (NULL_TREE, 5251 add_objc_string (get_identifier (XOBFINISH (&util_obstack, char *)), 5252 meth_var_types), 5253 ivar); 5254 obstack_free (&util_obstack, util_firstobj); 5255 5256 /* Set offset. */ 5257 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar); 5258 initlist = tree_cons (NULL_TREE, 5259 objc_build_constructor (type, nreverse (ivar)), 5260 initlist); 5261 do 5262 field_decl = TREE_CHAIN (field_decl); 5263 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL); 5264 } 5265 while (field_decl); 5266 5267 return objc_build_constructor (build_array_type (type, 0), 5268 nreverse (initlist)); 5269 } 5270 5271 static tree 5272 generate_ivars_list (tree type, const char *name, int size, tree list) 5273 { 5274 tree decl, initlist; 5275 5276 decl = start_var_decl (type, synth_id_with_class_suffix 5277 (name, objc_implementation_context)); 5278 5279 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size)); 5280 initlist = tree_cons (NULL_TREE, list, initlist); 5281 5282 finish_var_decl (decl, 5283 objc_build_constructor (TREE_TYPE (decl), 5284 nreverse (initlist))); 5285 5286 return decl; 5287 } 5288 5289 /* Count only the fields occurring in T. */ 5290 5291 static int 5292 ivar_list_length (tree t) 5293 { 5294 int count = 0; 5295 5296 for (; t; t = TREE_CHAIN (t)) 5297 if (TREE_CODE (t) == FIELD_DECL) 5298 ++count; 5299 5300 return count; 5301 } 5302 5303 static void 5304 generate_ivar_lists (void) 5305 { 5306 tree initlist, ivar_list_template, chain; 5307 int size; 5308 5309 generating_instance_variables = 1; 5310 5311 if (!objc_ivar_template) 5312 objc_ivar_template = build_ivar_template (); 5313 5314 /* Only generate class variables for the root of the inheritance 5315 hierarchy since these will be the same for every class. */ 5316 5317 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE 5318 && (chain = TYPE_FIELDS (objc_class_template))) 5319 { 5320 size = ivar_list_length (chain); 5321 5322 ivar_list_template = build_ivar_list_template (objc_ivar_template, size); 5323 initlist = build_ivar_list_initializer (objc_ivar_template, chain); 5324 5325 UOBJC_CLASS_VARIABLES_decl 5326 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES", 5327 size, initlist); 5328 } 5329 else 5330 UOBJC_CLASS_VARIABLES_decl = 0; 5331 5332 chain = CLASS_IVARS (implementation_template); 5333 if (chain) 5334 { 5335 size = ivar_list_length (chain); 5336 ivar_list_template = build_ivar_list_template (objc_ivar_template, size); 5337 initlist = build_ivar_list_initializer (objc_ivar_template, chain); 5338 5339 UOBJC_INSTANCE_VARIABLES_decl 5340 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES", 5341 size, initlist); 5342 } 5343 else 5344 UOBJC_INSTANCE_VARIABLES_decl = 0; 5345 5346 generating_instance_variables = 0; 5347 } 5348 5349 static tree 5350 build_dispatch_table_initializer (tree type, tree entries) 5351 { 5352 tree initlist = NULL_TREE; 5353 5354 do 5355 { 5356 tree elemlist = NULL_TREE; 5357 5358 elemlist = tree_cons (NULL_TREE, 5359 build_selector (METHOD_SEL_NAME (entries)), 5360 NULL_TREE); 5361 5362 /* Generate the method encoding if we don't have one already. */ 5363 if (! METHOD_ENCODING (entries)) 5364 METHOD_ENCODING (entries) = 5365 encode_method_prototype (entries); 5366 5367 elemlist = tree_cons (NULL_TREE, 5368 add_objc_string (METHOD_ENCODING (entries), 5369 meth_var_types), 5370 elemlist); 5371 5372 elemlist 5373 = tree_cons (NULL_TREE, 5374 convert (ptr_type_node, 5375 build_unary_op (input_location, ADDR_EXPR, 5376 METHOD_DEFINITION (entries), 1)), 5377 elemlist); 5378 5379 initlist = tree_cons (NULL_TREE, 5380 objc_build_constructor (type, nreverse (elemlist)), 5381 initlist); 5382 5383 entries = TREE_CHAIN (entries); 5384 } 5385 while (entries); 5386 5387 return objc_build_constructor (build_array_type (type, 0), 5388 nreverse (initlist)); 5389 } 5390 5391 /* To accomplish method prototyping without generating all kinds of 5392 inane warnings, the definition of the dispatch table entries were 5393 changed from: 5394 5395 struct objc_method { SEL _cmd; ...; id (*_imp)(); }; 5396 to: 5397 struct objc_method { SEL _cmd; ...; void *_imp; }; */ 5398 5399 static tree 5400 build_method_template (void) 5401 { 5402 tree _SLT_record; 5403 tree field_decl, field_decl_chain; 5404 5405 _SLT_record = objc_start_struct (get_identifier (UTAG_METHOD)); 5406 5407 /* SEL _cmd; */ 5408 field_decl = create_field_decl (objc_selector_type, "_cmd"); 5409 field_decl_chain = field_decl; 5410 5411 /* char *method_types; */ 5412 field_decl = create_field_decl (string_type_node, "method_types"); 5413 chainon (field_decl_chain, field_decl); 5414 5415 /* void *_imp; */ 5416 field_decl = create_field_decl (build_pointer_type (void_type_node), 5417 "_imp"); 5418 chainon (field_decl_chain, field_decl); 5419 5420 objc_finish_struct (_SLT_record, field_decl_chain); 5421 5422 return _SLT_record; 5423 } 5424 5425 5426 static tree 5427 generate_dispatch_table (tree type, const char *name, int size, tree list) 5428 { 5429 tree decl, initlist; 5430 5431 decl = start_var_decl (type, synth_id_with_class_suffix 5432 (name, objc_implementation_context)); 5433 5434 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0)); 5435 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist); 5436 initlist = tree_cons (NULL_TREE, list, initlist); 5437 5438 finish_var_decl (decl, 5439 objc_build_constructor (TREE_TYPE (decl), 5440 nreverse (initlist))); 5441 5442 return decl; 5443 } 5444 5445 static void 5446 mark_referenced_methods (void) 5447 { 5448 struct imp_entry *impent; 5449 tree chain; 5450 5451 for (impent = imp_list; impent; impent = impent->next) 5452 { 5453 chain = CLASS_CLS_METHODS (impent->imp_context); 5454 while (chain) 5455 { 5456 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain))); 5457 chain = TREE_CHAIN (chain); 5458 } 5459 5460 chain = CLASS_NST_METHODS (impent->imp_context); 5461 while (chain) 5462 { 5463 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain))); 5464 chain = TREE_CHAIN (chain); 5465 } 5466 } 5467 } 5468 5469 static void 5470 generate_dispatch_tables (void) 5471 { 5472 tree initlist, chain, method_list_template; 5473 int size; 5474 5475 if (!objc_method_template) 5476 objc_method_template = build_method_template (); 5477 5478 chain = CLASS_CLS_METHODS (objc_implementation_context); 5479 if (chain) 5480 { 5481 size = list_length (chain); 5482 5483 method_list_template 5484 = build_method_list_template (objc_method_template, size); 5485 initlist 5486 = build_dispatch_table_initializer (objc_method_template, chain); 5487 5488 UOBJC_CLASS_METHODS_decl 5489 = generate_dispatch_table (method_list_template, 5490 ((TREE_CODE (objc_implementation_context) 5491 == CLASS_IMPLEMENTATION_TYPE) 5492 ? "_OBJC_CLASS_METHODS" 5493 : "_OBJC_CATEGORY_CLASS_METHODS"), 5494 size, initlist); 5495 } 5496 else 5497 UOBJC_CLASS_METHODS_decl = 0; 5498 5499 chain = CLASS_NST_METHODS (objc_implementation_context); 5500 if (chain) 5501 { 5502 size = list_length (chain); 5503 5504 method_list_template 5505 = build_method_list_template (objc_method_template, size); 5506 initlist 5507 = build_dispatch_table_initializer (objc_method_template, chain); 5508 5509 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE) 5510 UOBJC_INSTANCE_METHODS_decl 5511 = generate_dispatch_table (method_list_template, 5512 "_OBJC_INSTANCE_METHODS", 5513 size, initlist); 5514 else 5515 /* We have a category. */ 5516 UOBJC_INSTANCE_METHODS_decl 5517 = generate_dispatch_table (method_list_template, 5518 "_OBJC_CATEGORY_INSTANCE_METHODS", 5519 size, initlist); 5520 } 5521 else 5522 UOBJC_INSTANCE_METHODS_decl = 0; 5523 } 5524 5525 static tree 5526 generate_protocol_list (tree i_or_p) 5527 { 5528 tree initlist; 5529 tree refs_decl, lproto, e, plist; 5530 int size = 0; 5531 const char *ref_name; 5532 5533 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE 5534 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE) 5535 plist = CLASS_PROTOCOL_LIST (i_or_p); 5536 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE) 5537 plist = PROTOCOL_LIST (i_or_p); 5538 else 5539 abort (); 5540 5541 /* Compute size. */ 5542 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) 5543 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE 5544 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto))) 5545 size++; 5546 5547 /* Build initializer. */ 5548 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), NULL_TREE); 5549 e = build_int_cst (build_pointer_type (objc_protocol_template), size); 5550 initlist = tree_cons (NULL_TREE, e, initlist); 5551 5552 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) 5553 { 5554 tree pval = TREE_VALUE (lproto); 5555 5556 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE 5557 && PROTOCOL_FORWARD_DECL (pval)) 5558 { 5559 e = build_unary_op (input_location, ADDR_EXPR, 5560 PROTOCOL_FORWARD_DECL (pval), 0); 5561 initlist = tree_cons (NULL_TREE, e, initlist); 5562 } 5563 } 5564 5565 /* static struct objc_protocol *refs[n]; */ 5566 5567 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE) 5568 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p); 5569 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE) 5570 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p); 5571 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE) 5572 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p); 5573 else 5574 abort (); 5575 5576 refs_decl = start_var_decl 5577 (build_array_type 5578 (build_pointer_type (objc_protocol_template), 5579 build_index_type (build_int_cst (NULL_TREE, size + 2))), 5580 ref_name); 5581 5582 finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl), 5583 nreverse (initlist))); 5584 5585 return refs_decl; 5586 } 5587 5588 static tree 5589 build_category_initializer (tree type, tree cat_name, tree class_name, 5590 tree instance_methods, tree class_methods, 5591 tree protocol_list) 5592 { 5593 tree initlist = NULL_TREE, expr; 5594 5595 initlist = tree_cons (NULL_TREE, cat_name, initlist); 5596 initlist = tree_cons (NULL_TREE, class_name, initlist); 5597 5598 if (!instance_methods) 5599 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist); 5600 else 5601 { 5602 expr = convert (objc_method_list_ptr, 5603 build_unary_op (input_location, ADDR_EXPR, 5604 instance_methods, 0)); 5605 initlist = tree_cons (NULL_TREE, expr, initlist); 5606 } 5607 if (!class_methods) 5608 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist); 5609 else 5610 { 5611 expr = convert (objc_method_list_ptr, 5612 build_unary_op (input_location, ADDR_EXPR, 5613 class_methods, 0)); 5614 initlist = tree_cons (NULL_TREE, expr, initlist); 5615 } 5616 5617 /* protocol_list = */ 5618 if (!protocol_list) 5619 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist); 5620 else 5621 { 5622 expr = convert (build_pointer_type 5623 (build_pointer_type 5624 (objc_protocol_template)), 5625 build_unary_op (input_location, ADDR_EXPR, 5626 protocol_list, 0)); 5627 initlist = tree_cons (NULL_TREE, expr, initlist); 5628 } 5629 5630 return objc_build_constructor (type, nreverse (initlist)); 5631 } 5632 5633 /* struct _objc_class { 5634 struct objc_class *isa; 5635 struct objc_class *super_class; 5636 char *name; 5637 long version; 5638 long info; 5639 long instance_size; 5640 struct objc_ivar_list *ivars; 5641 struct objc_method_list *methods; 5642 if (flag_next_runtime) 5643 struct objc_cache *cache; 5644 else { 5645 struct sarray *dtable; 5646 struct objc_class *subclass_list; 5647 struct objc_class *sibling_class; 5648 } 5649 struct objc_protocol_list *protocols; 5650 if (flag_next_runtime) 5651 void *sel_id; 5652 void *gc_object_type; 5653 }; */ 5654 5655 static tree 5656 build_shared_structure_initializer (tree type, tree isa, tree super, 5657 tree name, tree size, int status, 5658 tree dispatch_table, tree ivar_list, 5659 tree protocol_list) 5660 { 5661 tree initlist = NULL_TREE, expr; 5662 5663 /* isa = */ 5664 initlist = tree_cons (NULL_TREE, isa, initlist); 5665 5666 /* super_class = */ 5667 initlist = tree_cons (NULL_TREE, super, initlist); 5668 5669 /* name = */ 5670 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist); 5671 5672 /* version = */ 5673 initlist = tree_cons (NULL_TREE, build_int_cst (long_integer_type_node, 0), 5674 initlist); 5675 5676 /* info = */ 5677 initlist = tree_cons (NULL_TREE, 5678 build_int_cst (long_integer_type_node, status), 5679 initlist); 5680 5681 /* instance_size = */ 5682 initlist = tree_cons (NULL_TREE, convert (long_integer_type_node, size), 5683 initlist); 5684 5685 /* objc_ivar_list = */ 5686 if (!ivar_list) 5687 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist); 5688 else 5689 { 5690 expr = convert (objc_ivar_list_ptr, 5691 build_unary_op (input_location, ADDR_EXPR, 5692 ivar_list, 0)); 5693 initlist = tree_cons (NULL_TREE, expr, initlist); 5694 } 5695 5696 /* objc_method_list = */ 5697 if (!dispatch_table) 5698 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist); 5699 else 5700 { 5701 expr = convert (objc_method_list_ptr, 5702 build_unary_op (input_location, ADDR_EXPR, 5703 dispatch_table, 0)); 5704 initlist = tree_cons (NULL_TREE, expr, initlist); 5705 } 5706 5707 if (flag_next_runtime) 5708 /* method_cache = */ 5709 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist); 5710 else 5711 { 5712 /* dtable = */ 5713 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist); 5714 5715 /* subclass_list = */ 5716 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist); 5717 5718 /* sibling_class = */ 5719 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist); 5720 } 5721 5722 /* protocol_list = */ 5723 if (! protocol_list) 5724 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist); 5725 else 5726 { 5727 expr = convert (build_pointer_type 5728 (build_pointer_type 5729 (objc_protocol_template)), 5730 build_unary_op (input_location, ADDR_EXPR, 5731 protocol_list, 0)); 5732 initlist = tree_cons (NULL_TREE, expr, initlist); 5733 } 5734 5735 if (flag_next_runtime) 5736 /* sel_id = NULL */ 5737 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist); 5738 5739 /* gc_object_type = NULL */ 5740 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist); 5741 5742 return objc_build_constructor (type, nreverse (initlist)); 5743 } 5744 5745 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */ 5746 5747 static inline tree 5748 lookup_category (tree klass, tree cat_name) 5749 { 5750 tree category = CLASS_CATEGORY_LIST (klass); 5751 5752 while (category && CLASS_SUPER_NAME (category) != cat_name) 5753 category = CLASS_CATEGORY_LIST (category); 5754 return category; 5755 } 5756 5757 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */ 5758 5759 static void 5760 generate_category (tree cat) 5761 { 5762 tree decl; 5763 tree initlist, cat_name_expr, class_name_expr; 5764 tree protocol_decl, category; 5765 5766 add_class_reference (CLASS_NAME (cat)); 5767 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names); 5768 5769 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names); 5770 5771 category = lookup_category (implementation_template, 5772 CLASS_SUPER_NAME (cat)); 5773 5774 if (category && CLASS_PROTOCOL_LIST (category)) 5775 { 5776 generate_protocol_references (CLASS_PROTOCOL_LIST (category)); 5777 protocol_decl = generate_protocol_list (category); 5778 } 5779 else 5780 protocol_decl = 0; 5781 5782 decl = start_var_decl (objc_category_template, 5783 synth_id_with_class_suffix 5784 ("_OBJC_CATEGORY", objc_implementation_context)); 5785 5786 initlist = build_category_initializer (TREE_TYPE (decl), 5787 cat_name_expr, class_name_expr, 5788 UOBJC_INSTANCE_METHODS_decl, 5789 UOBJC_CLASS_METHODS_decl, 5790 protocol_decl); 5791 5792 finish_var_decl (decl, initlist); 5793 } 5794 5795 /* static struct objc_class _OBJC_METACLASS_Foo={ ... }; 5796 static struct objc_class _OBJC_CLASS_Foo={ ... }; */ 5797 5798 static void 5799 generate_shared_structures (int cls_flags) 5800 { 5801 tree decl; 5802 tree name_expr, super_expr, root_expr; 5803 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE; 5804 tree cast_type, initlist, protocol_decl; 5805 5806 my_super_id = CLASS_SUPER_NAME (implementation_template); 5807 if (my_super_id) 5808 { 5809 add_class_reference (my_super_id); 5810 5811 /* Compute "my_root_id" - this is required for code generation. 5812 the "isa" for all meta class structures points to the root of 5813 the inheritance hierarchy (e.g. "__Object")... */ 5814 my_root_id = my_super_id; 5815 do 5816 { 5817 tree my_root_int = lookup_interface (my_root_id); 5818 5819 if (my_root_int && CLASS_SUPER_NAME (my_root_int)) 5820 my_root_id = CLASS_SUPER_NAME (my_root_int); 5821 else 5822 break; 5823 } 5824 while (1); 5825 } 5826 else 5827 /* No super class. */ 5828 my_root_id = CLASS_NAME (implementation_template); 5829 5830 cast_type = build_pointer_type (objc_class_template); 5831 name_expr = add_objc_string (CLASS_NAME (implementation_template), 5832 class_names); 5833 5834 /* Install class `isa' and `super' pointers at runtime. */ 5835 if (my_super_id) 5836 { 5837 super_expr = add_objc_string (my_super_id, class_names); 5838 super_expr = build_c_cast (input_location, 5839 cast_type, super_expr); /* cast! */ 5840 } 5841 else 5842 super_expr = build_int_cst (NULL_TREE, 0); 5843 5844 root_expr = add_objc_string (my_root_id, class_names); 5845 root_expr = build_c_cast (input_location, cast_type, root_expr); /* cast! */ 5846 5847 if (CLASS_PROTOCOL_LIST (implementation_template)) 5848 { 5849 generate_protocol_references 5850 (CLASS_PROTOCOL_LIST (implementation_template)); 5851 protocol_decl = generate_protocol_list (implementation_template); 5852 } 5853 else 5854 protocol_decl = 0; 5855 5856 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */ 5857 5858 decl = start_var_decl (objc_class_template, 5859 IDENTIFIER_POINTER 5860 (DECL_NAME (UOBJC_METACLASS_decl))); 5861 5862 initlist 5863 = build_shared_structure_initializer 5864 (TREE_TYPE (decl), 5865 root_expr, super_expr, name_expr, 5866 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)), 5867 2 /*CLS_META*/, 5868 UOBJC_CLASS_METHODS_decl, 5869 UOBJC_CLASS_VARIABLES_decl, 5870 protocol_decl); 5871 5872 finish_var_decl (decl, initlist); 5873 5874 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */ 5875 5876 decl = start_var_decl (objc_class_template, 5877 IDENTIFIER_POINTER 5878 (DECL_NAME (UOBJC_CLASS_decl))); 5879 5880 initlist 5881 = build_shared_structure_initializer 5882 (TREE_TYPE (decl), 5883 build_unary_op (input_location, ADDR_EXPR, UOBJC_METACLASS_decl, 0), 5884 super_expr, name_expr, 5885 convert (integer_type_node, 5886 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE 5887 (implementation_template))), 5888 1 /*CLS_FACTORY*/ | cls_flags, 5889 UOBJC_INSTANCE_METHODS_decl, 5890 UOBJC_INSTANCE_VARIABLES_decl, 5891 protocol_decl); 5892 5893 finish_var_decl (decl, initlist); 5894 } 5895 5896 5897 static const char * 5898 synth_id_with_class_suffix (const char *preamble, tree ctxt) 5899 { 5900 static char string[BUFSIZE]; 5901 5902 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE 5903 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE) 5904 { 5905 sprintf (string, "%s_%s", preamble, 5906 IDENTIFIER_POINTER (CLASS_NAME (ctxt))); 5907 } 5908 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE 5909 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE) 5910 { 5911 /* We have a category. */ 5912 const char *const class_name 5913 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)); 5914 const char *const class_super_name 5915 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)); 5916 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name); 5917 } 5918 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE) 5919 { 5920 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt)); 5921 sprintf (string, "%s_%s", preamble, protocol_name); 5922 } 5923 else 5924 abort (); 5925 5926 return string; 5927 } 5928 5929 /* If type is empty or only type qualifiers are present, add default 5930 type of id (otherwise grokdeclarator will default to int). */ 5931 5932 static tree 5933 adjust_type_for_id_default (tree type) 5934 { 5935 if (!type) 5936 type = make_node (TREE_LIST); 5937 5938 if (!TREE_VALUE (type)) 5939 TREE_VALUE (type) = objc_object_type; 5940 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE 5941 && TYPED_OBJECT (TREE_VALUE (type))) 5942 error ("can not use an object as parameter to a method"); 5943 5944 return type; 5945 } 5946 5947 /* Usage: 5948 keyworddecl: 5949 selector ':' '(' typename ')' identifier 5950 5951 Purpose: 5952 Transform an Objective-C keyword argument into 5953 the C equivalent parameter declarator. 5954 5955 In: key_name, an "identifier_node" (optional). 5956 arg_type, a "tree_list" (optional). 5957 arg_name, an "identifier_node". 5958 5959 Note: It would be really nice to strongly type the preceding 5960 arguments in the function prototype; however, then I 5961 could not use the "accessor" macros defined in "tree.h". 5962 5963 Out: an instance of "keyword_decl". */ 5964 5965 tree 5966 objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name) 5967 { 5968 tree keyword_decl; 5969 5970 /* If no type is specified, default to "id". */ 5971 arg_type = adjust_type_for_id_default (arg_type); 5972 5973 keyword_decl = make_node (KEYWORD_DECL); 5974 5975 TREE_TYPE (keyword_decl) = arg_type; 5976 KEYWORD_ARG_NAME (keyword_decl) = arg_name; 5977 KEYWORD_KEY_NAME (keyword_decl) = key_name; 5978 5979 return keyword_decl; 5980 } 5981 5982 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */ 5983 5984 static tree 5985 build_keyword_selector (tree selector) 5986 { 5987 int len = 0; 5988 tree key_chain, key_name; 5989 char *buf; 5990 5991 /* Scan the selector to see how much space we'll need. */ 5992 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain)) 5993 { 5994 if (TREE_CODE (selector) == KEYWORD_DECL) 5995 key_name = KEYWORD_KEY_NAME (key_chain); 5996 else if (TREE_CODE (selector) == TREE_LIST) 5997 key_name = TREE_PURPOSE (key_chain); 5998 else 5999 abort (); 6000 6001 if (key_name) 6002 len += IDENTIFIER_LENGTH (key_name) + 1; 6003 else 6004 /* Just a ':' arg. */ 6005 len++; 6006 } 6007 6008 buf = (char *) alloca (len + 1); 6009 /* Start the buffer out as an empty string. */ 6010 buf[0] = '\0'; 6011 6012 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain)) 6013 { 6014 if (TREE_CODE (selector) == KEYWORD_DECL) 6015 key_name = KEYWORD_KEY_NAME (key_chain); 6016 else if (TREE_CODE (selector) == TREE_LIST) 6017 { 6018 key_name = TREE_PURPOSE (key_chain); 6019 /* The keyword decl chain will later be used as a function argument 6020 chain. Unhook the selector itself so as to not confuse other 6021 parts of the compiler. */ 6022 TREE_PURPOSE (key_chain) = NULL_TREE; 6023 } 6024 else 6025 abort (); 6026 6027 if (key_name) 6028 strcat (buf, IDENTIFIER_POINTER (key_name)); 6029 strcat (buf, ":"); 6030 } 6031 6032 return get_identifier (buf); 6033 } 6034 6035 /* Used for declarations and definitions. */ 6036 6037 static tree 6038 build_method_decl (enum tree_code code, tree ret_type, tree selector, 6039 tree add_args, bool ellipsis) 6040 { 6041 tree method_decl; 6042 6043 /* If no type is specified, default to "id". */ 6044 ret_type = adjust_type_for_id_default (ret_type); 6045 6046 method_decl = make_node (code); 6047 TREE_TYPE (method_decl) = ret_type; 6048 6049 /* If we have a keyword selector, create an identifier_node that 6050 represents the full selector name (`:' included)... */ 6051 if (TREE_CODE (selector) == KEYWORD_DECL) 6052 { 6053 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector); 6054 METHOD_SEL_ARGS (method_decl) = selector; 6055 METHOD_ADD_ARGS (method_decl) = add_args; 6056 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis; 6057 } 6058 else 6059 { 6060 METHOD_SEL_NAME (method_decl) = selector; 6061 METHOD_SEL_ARGS (method_decl) = NULL_TREE; 6062 METHOD_ADD_ARGS (method_decl) = NULL_TREE; 6063 } 6064 6065 return method_decl; 6066 } 6067 6068 #define METHOD_DEF 0 6069 #define METHOD_REF 1 6070 6071 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return 6072 an argument list for method METH. CONTEXT is either METHOD_DEF or 6073 METHOD_REF, saying whether we are trying to define a method or call 6074 one. SUPERFLAG says this is for a send to super; this makes a 6075 difference for the NeXT calling sequence in which the lookup and 6076 the method call are done together. If METH is null, user-defined 6077 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */ 6078 6079 static tree 6080 get_arg_type_list (tree meth, int context, int superflag) 6081 { 6082 tree arglist, akey; 6083 6084 /* Receiver type. */ 6085 if (flag_next_runtime && superflag) 6086 arglist = build_tree_list (NULL_TREE, objc_super_type); 6087 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL) 6088 arglist = build_tree_list (NULL_TREE, objc_instance_type); 6089 else 6090 arglist = build_tree_list (NULL_TREE, objc_object_type); 6091 6092 /* Selector type - will eventually change to `int'. */ 6093 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type)); 6094 6095 /* No actual method prototype given -- assume that remaining arguments 6096 are `...'. */ 6097 if (!meth) 6098 return arglist; 6099 6100 /* Build a list of argument types. */ 6101 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey)) 6102 { 6103 tree arg_type = TREE_VALUE (TREE_TYPE (akey)); 6104 6105 /* Decay arrays and functions into pointers. */ 6106 if (TREE_CODE (arg_type) == ARRAY_TYPE) 6107 arg_type = build_pointer_type (TREE_TYPE (arg_type)); 6108 else if (TREE_CODE (arg_type) == FUNCTION_TYPE) 6109 arg_type = build_pointer_type (arg_type); 6110 6111 chainon (arglist, build_tree_list (NULL_TREE, arg_type)); 6112 } 6113 6114 if (METHOD_ADD_ARGS (meth)) 6115 { 6116 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth)); 6117 akey; akey = TREE_CHAIN (akey)) 6118 { 6119 tree arg_type = TREE_TYPE (TREE_VALUE (akey)); 6120 6121 chainon (arglist, build_tree_list (NULL_TREE, arg_type)); 6122 } 6123 6124 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth)) 6125 goto lack_of_ellipsis; 6126 } 6127 else 6128 { 6129 lack_of_ellipsis: 6130 chainon (arglist, OBJC_VOID_AT_END); 6131 } 6132 6133 return arglist; 6134 } 6135 6136 static tree 6137 check_duplicates (hash hsh, int methods, int is_class) 6138 { 6139 tree meth = NULL_TREE; 6140 6141 if (hsh) 6142 { 6143 meth = hsh->key; 6144 6145 if (hsh->list) 6146 { 6147 /* We have two or more methods with the same name but 6148 different types. */ 6149 attr loop; 6150 6151 /* But just how different are those types? If 6152 -Wno-strict-selector-match is specified, we shall not 6153 complain if the differences are solely among types with 6154 identical size and alignment. */ 6155 if (!warn_strict_selector_match) 6156 { 6157 for (loop = hsh->list; loop; loop = loop->next) 6158 if (!comp_proto_with_proto (meth, loop->value, 0)) 6159 goto issue_warning; 6160 6161 return meth; 6162 } 6163 6164 issue_warning: 6165 if (methods) 6166 { 6167 bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL; 6168 6169 warning_at (input_location, 0, 6170 "multiple methods named %<%c%E%> found", 6171 (is_class ? '+' : '-'), 6172 METHOD_SEL_NAME (meth)); 6173 inform (DECL_SOURCE_LOCATION (meth), "using %<%c%s%>", 6174 (type ? '-' : '+'), 6175 identifier_to_locale (gen_method_decl (meth))); 6176 } 6177 else 6178 { 6179 bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL; 6180 6181 warning_at (input_location, 0, 6182 "multiple selectors named %<%c%E%> found", 6183 (is_class ? '+' : '-'), 6184 METHOD_SEL_NAME (meth)); 6185 inform (DECL_SOURCE_LOCATION (meth), "found %<%c%s%>", 6186 (type ? '-' : '+'), 6187 identifier_to_locale (gen_method_decl (meth))); 6188 } 6189 6190 for (loop = hsh->list; loop; loop = loop->next) 6191 { 6192 bool type = TREE_CODE (loop->value) == INSTANCE_METHOD_DECL; 6193 6194 inform (DECL_SOURCE_LOCATION (loop->value), "also found %<%c%s%>", 6195 (type ? '-' : '+'), 6196 identifier_to_locale (gen_method_decl (loop->value))); 6197 } 6198 } 6199 } 6200 return meth; 6201 } 6202 6203 /* If RECEIVER is a class reference, return the identifier node for 6204 the referenced class. RECEIVER is created by objc_get_class_reference, 6205 so we check the exact form created depending on which runtimes are 6206 used. */ 6207 6208 static tree 6209 receiver_is_class_object (tree receiver, int self, int super) 6210 { 6211 tree chain, exp, arg; 6212 6213 /* The receiver is 'self' or 'super' in the context of a class method. */ 6214 if (objc_method_context 6215 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL 6216 && (self || super)) 6217 return (super 6218 ? CLASS_SUPER_NAME (implementation_template) 6219 : CLASS_NAME (implementation_template)); 6220 6221 if (flag_next_runtime) 6222 { 6223 /* The receiver is a variable created by 6224 build_class_reference_decl. */ 6225 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver))) 6226 /* Look up the identifier. */ 6227 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain)) 6228 if (TREE_PURPOSE (chain) == receiver) 6229 return TREE_VALUE (chain); 6230 } 6231 6232 /* The receiver is a function call that returns an id. Check if 6233 it is a call to objc_getClass, if so, pick up the class name. */ 6234 if (TREE_CODE (receiver) == CALL_EXPR 6235 && (exp = CALL_EXPR_FN (receiver)) 6236 && TREE_CODE (exp) == ADDR_EXPR 6237 && (exp = TREE_OPERAND (exp, 0)) 6238 && TREE_CODE (exp) == FUNCTION_DECL 6239 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL 6240 prototypes for objc_get_class(). Thankfully, they seem to share the 6241 same function type. */ 6242 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl) 6243 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS) 6244 /* We have a call to objc_get_class/objc_getClass! */ 6245 && (arg = CALL_EXPR_ARG (receiver, 0))) 6246 { 6247 STRIP_NOPS (arg); 6248 if (TREE_CODE (arg) == ADDR_EXPR 6249 && (arg = TREE_OPERAND (arg, 0)) 6250 && TREE_CODE (arg) == STRING_CST) 6251 /* Finally, we have the class name. */ 6252 return get_identifier (TREE_STRING_POINTER (arg)); 6253 } 6254 return 0; 6255 } 6256 6257 /* If we are currently building a message expr, this holds 6258 the identifier of the selector of the message. This is 6259 used when printing warnings about argument mismatches. */ 6260 6261 static tree current_objc_message_selector = 0; 6262 6263 tree 6264 objc_message_selector (void) 6265 { 6266 return current_objc_message_selector; 6267 } 6268 6269 /* Construct an expression for sending a message. 6270 MESS has the object to send to in TREE_PURPOSE 6271 and the argument list (including selector) in TREE_VALUE. 6272 6273 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...); 6274 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */ 6275 6276 tree 6277 objc_build_message_expr (tree mess) 6278 { 6279 tree receiver = TREE_PURPOSE (mess); 6280 tree sel_name; 6281 #ifdef OBJCPLUS 6282 tree args = TREE_PURPOSE (TREE_VALUE (mess)); 6283 #else 6284 tree args = TREE_VALUE (mess); 6285 #endif 6286 tree method_params = NULL_TREE; 6287 6288 if (TREE_CODE (receiver) == ERROR_MARK || TREE_CODE (args) == ERROR_MARK) 6289 return error_mark_node; 6290 6291 /* Obtain the full selector name. */ 6292 if (TREE_CODE (args) == IDENTIFIER_NODE) 6293 /* A unary selector. */ 6294 sel_name = args; 6295 else if (TREE_CODE (args) == TREE_LIST) 6296 sel_name = build_keyword_selector (args); 6297 else 6298 abort (); 6299 6300 /* Build the parameter list to give to the method. */ 6301 if (TREE_CODE (args) == TREE_LIST) 6302 #ifdef OBJCPLUS 6303 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess))); 6304 #else 6305 { 6306 tree chain = args, prev = NULL_TREE; 6307 6308 /* We have a keyword selector--check for comma expressions. */ 6309 while (chain) 6310 { 6311 tree element = TREE_VALUE (chain); 6312 6313 /* We have a comma expression, must collapse... */ 6314 if (TREE_CODE (element) == TREE_LIST) 6315 { 6316 if (prev) 6317 TREE_CHAIN (prev) = element; 6318 else 6319 args = element; 6320 } 6321 prev = chain; 6322 chain = TREE_CHAIN (chain); 6323 } 6324 method_params = args; 6325 } 6326 #endif 6327 6328 #ifdef OBJCPLUS 6329 if (processing_template_decl) 6330 /* Must wait until template instantiation time. */ 6331 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name, 6332 method_params); 6333 #endif 6334 6335 return objc_finish_message_expr (receiver, sel_name, method_params); 6336 } 6337 6338 /* Look up method SEL_NAME that would be suitable for receiver 6339 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is 6340 nonzero), and report on any duplicates. */ 6341 6342 static tree 6343 lookup_method_in_hash_lists (tree sel_name, int is_class) 6344 { 6345 hash method_prototype = NULL; 6346 6347 if (!is_class) 6348 method_prototype = hash_lookup (nst_method_hash_list, 6349 sel_name); 6350 6351 if (!method_prototype) 6352 { 6353 method_prototype = hash_lookup (cls_method_hash_list, 6354 sel_name); 6355 is_class = 1; 6356 } 6357 6358 return check_duplicates (method_prototype, 1, is_class); 6359 } 6360 6361 /* The 'objc_finish_message_expr' routine is called from within 6362 'objc_build_message_expr' for non-template functions. In the case of 6363 C++ template functions, it is called from 'build_expr_from_tree' 6364 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */ 6365 6366 tree 6367 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params) 6368 { 6369 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype; 6370 tree selector, retval, class_tree; 6371 int self, super, have_cast; 6372 6373 /* Extract the receiver of the message, as well as its type 6374 (where the latter may take the form of a cast or be inferred 6375 from the implementation context). */ 6376 rtype = receiver; 6377 while (TREE_CODE (rtype) == COMPOUND_EXPR 6378 || TREE_CODE (rtype) == MODIFY_EXPR 6379 || CONVERT_EXPR_P (rtype) 6380 || TREE_CODE (rtype) == COMPONENT_REF) 6381 rtype = TREE_OPERAND (rtype, 0); 6382 self = (rtype == self_decl); 6383 super = (rtype == UOBJC_SUPER_decl); 6384 rtype = TREE_TYPE (receiver); 6385 have_cast = (TREE_CODE (receiver) == NOP_EXPR 6386 || (TREE_CODE (receiver) == COMPOUND_EXPR 6387 && !IS_SUPER (rtype))); 6388 6389 /* If we are calling [super dealloc], reset our warning flag. */ 6390 if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name))) 6391 should_call_super_dealloc = 0; 6392 6393 /* If the receiver is a class object, retrieve the corresponding 6394 @interface, if one exists. */ 6395 class_tree = receiver_is_class_object (receiver, self, super); 6396 6397 /* Now determine the receiver type (if an explicit cast has not been 6398 provided). */ 6399 if (!have_cast) 6400 { 6401 if (class_tree) 6402 rtype = lookup_interface (class_tree); 6403 /* Handle `self' and `super'. */ 6404 else if (super) 6405 { 6406 if (!CLASS_SUPER_NAME (implementation_template)) 6407 { 6408 error ("no super class declared in @interface for %qE", 6409 CLASS_NAME (implementation_template)); 6410 return error_mark_node; 6411 } 6412 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template)); 6413 } 6414 else if (self) 6415 rtype = lookup_interface (CLASS_NAME (implementation_template)); 6416 } 6417 6418 /* If receiver is of type `id' or `Class' (or if the @interface for a 6419 class is not visible), we shall be satisfied with the existence of 6420 any instance or class method. */ 6421 if (objc_is_id (rtype)) 6422 { 6423 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE); 6424 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype)) 6425 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype)) 6426 : NULL_TREE); 6427 rtype = NULL_TREE; 6428 6429 if (rprotos) 6430 { 6431 /* If messaging 'id <Protos>' or 'Class <Proto>', first search 6432 in protocols themselves for the method prototype. */ 6433 method_prototype 6434 = lookup_method_in_protocol_list (rprotos, sel_name, 6435 class_tree != NULL_TREE); 6436 6437 /* If messaging 'Class <Proto>' but did not find a class method 6438 prototype, search for an instance method instead, and warn 6439 about having done so. */ 6440 if (!method_prototype && !rtype && class_tree != NULL_TREE) 6441 { 6442 method_prototype 6443 = lookup_method_in_protocol_list (rprotos, sel_name, 0); 6444 6445 if (method_prototype) 6446 warning (0, "found %<-%E%> instead of %<+%E%> in protocol(s)", 6447 sel_name, sel_name); 6448 } 6449 } 6450 } 6451 else if (rtype) 6452 { 6453 tree orig_rtype = rtype; 6454 6455 if (TREE_CODE (rtype) == POINTER_TYPE) 6456 rtype = TREE_TYPE (rtype); 6457 /* Traverse typedef aliases */ 6458 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype) 6459 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL 6460 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype))) 6461 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)); 6462 if (TYPED_OBJECT (rtype)) 6463 { 6464 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype); 6465 rtype = TYPE_OBJC_INTERFACE (rtype); 6466 } 6467 /* If we could not find an @interface declaration, we must have 6468 only seen a @class declaration; so, we cannot say anything 6469 more intelligent about which methods the receiver will 6470 understand. */ 6471 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE) 6472 rtype = NULL_TREE; 6473 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE 6474 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE) 6475 { 6476 /* We have a valid ObjC class name. Look up the method name 6477 in the published @interface for the class (and its 6478 superclasses). */ 6479 method_prototype 6480 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE); 6481 6482 /* If the method was not found in the @interface, it may still 6483 exist locally as part of the @implementation. */ 6484 if (!method_prototype && objc_implementation_context 6485 && CLASS_NAME (objc_implementation_context) 6486 == OBJC_TYPE_NAME (rtype)) 6487 method_prototype 6488 = lookup_method 6489 ((class_tree 6490 ? CLASS_CLS_METHODS (objc_implementation_context) 6491 : CLASS_NST_METHODS (objc_implementation_context)), 6492 sel_name); 6493 6494 /* If we haven't found a candidate method by now, try looking for 6495 it in the protocol list. */ 6496 if (!method_prototype && rprotos) 6497 method_prototype 6498 = lookup_method_in_protocol_list (rprotos, sel_name, 6499 class_tree != NULL_TREE); 6500 } 6501 else 6502 { 6503 warning (0, "invalid receiver type %qs", 6504 identifier_to_locale (gen_type_name (orig_rtype))); 6505 /* After issuing the "invalid receiver" warning, perform method 6506 lookup as if we were messaging 'id'. */ 6507 rtype = rprotos = NULL_TREE; 6508 } 6509 } 6510 6511 6512 /* For 'id' or 'Class' receivers, search in the global hash table 6513 as a last resort. For all receivers, warn if protocol searches 6514 have failed. */ 6515 if (!method_prototype) 6516 { 6517 if (rprotos) 6518 warning (0, "%<%c%E%> not found in protocol(s)", 6519 (class_tree ? '+' : '-'), 6520 sel_name); 6521 6522 if (!rtype) 6523 method_prototype 6524 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE); 6525 } 6526 6527 if (!method_prototype) 6528 { 6529 static bool warn_missing_methods = false; 6530 6531 if (rtype) 6532 warning (0, "%qE may not respond to %<%c%E%>", 6533 OBJC_TYPE_NAME (rtype), 6534 (class_tree ? '+' : '-'), 6535 sel_name); 6536 /* If we are messaging an 'id' or 'Class' object and made it here, 6537 then we have failed to find _any_ instance or class method, 6538 respectively. */ 6539 else 6540 warning (0, "no %<%c%E%> method found", 6541 (class_tree ? '+' : '-'), 6542 sel_name); 6543 6544 if (!warn_missing_methods) 6545 { 6546 warning_at (input_location, 6547 0, "(Messages without a matching method signature"); 6548 warning_at (input_location, 6549 0, "will be assumed to return %<id%> and accept"); 6550 warning_at (input_location, 6551 0, "%<...%> as arguments.)"); 6552 warn_missing_methods = true; 6553 } 6554 } 6555 6556 /* Save the selector name for printing error messages. */ 6557 current_objc_message_selector = sel_name; 6558 6559 /* Build the parameters list for looking up the method. 6560 These are the object itself and the selector. */ 6561 6562 if (flag_typed_selectors) 6563 selector = build_typed_selector_reference (input_location, 6564 sel_name, method_prototype); 6565 else 6566 selector = build_selector_reference (input_location, sel_name); 6567 6568 retval = build_objc_method_call (input_location, super, method_prototype, 6569 receiver, 6570 selector, method_params); 6571 6572 current_objc_message_selector = 0; 6573 6574 return retval; 6575 } 6576 6577 /* Build a tree expression to send OBJECT the operation SELECTOR, 6578 looking up the method on object LOOKUP_OBJECT (often same as OBJECT), 6579 assuming the method has prototype METHOD_PROTOTYPE. 6580 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.) 6581 LOC is the location of the expression to build. 6582 Use METHOD_PARAMS as list of args to pass to the method. 6583 If SUPER_FLAG is nonzero, we look up the superclass's method. */ 6584 6585 static tree 6586 build_objc_method_call (location_t loc, int super_flag, tree method_prototype, 6587 tree lookup_object, tree selector, 6588 tree method_params) 6589 { 6590 tree sender = (super_flag ? umsg_super_decl : 6591 (!flag_next_runtime || flag_nil_receivers 6592 ? (flag_objc_direct_dispatch 6593 ? umsg_fast_decl 6594 : umsg_decl) 6595 : umsg_nonnil_decl)); 6596 tree rcv_p = (super_flag ? objc_super_type : objc_object_type); 6597 6598 /* If a prototype for the method to be called exists, then cast 6599 the sender's return type and arguments to match that of the method. 6600 Otherwise, leave sender as is. */ 6601 tree ret_type 6602 = (method_prototype 6603 ? TREE_VALUE (TREE_TYPE (method_prototype)) 6604 : objc_object_type); 6605 tree sender_cast 6606 = build_pointer_type 6607 (build_function_type 6608 (ret_type, 6609 get_arg_type_list 6610 (method_prototype, METHOD_REF, super_flag))); 6611 tree method, t; 6612 6613 lookup_object = build_c_cast (loc, rcv_p, lookup_object); 6614 6615 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */ 6616 lookup_object = save_expr (lookup_object); 6617 6618 if (flag_next_runtime) 6619 { 6620 /* If we are returning a struct in memory, and the address 6621 of that memory location is passed as a hidden first 6622 argument, then change which messenger entry point this 6623 expr will call. NB: Note that sender_cast remains 6624 unchanged (it already has a struct return type). */ 6625 if (!targetm.calls.struct_value_rtx (0, 0) 6626 && (TREE_CODE (ret_type) == RECORD_TYPE 6627 || TREE_CODE (ret_type) == UNION_TYPE) 6628 && targetm.calls.return_in_memory (ret_type, 0)) 6629 sender = (super_flag ? umsg_super_stret_decl : 6630 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl); 6631 6632 method_params = tree_cons (NULL_TREE, lookup_object, 6633 tree_cons (NULL_TREE, selector, 6634 method_params)); 6635 method = build_fold_addr_expr_loc (input_location, sender); 6636 } 6637 else 6638 { 6639 /* This is the portable (GNU) way. */ 6640 tree object; 6641 6642 /* First, call the lookup function to get a pointer to the method, 6643 then cast the pointer, then call it with the method arguments. */ 6644 6645 object = (super_flag ? self_decl : lookup_object); 6646 6647 t = tree_cons (NULL_TREE, selector, NULL_TREE); 6648 t = tree_cons (NULL_TREE, lookup_object, t); 6649 method = build_function_call (loc, sender, t); 6650 6651 /* Pass the object to the method. */ 6652 method_params = tree_cons (NULL_TREE, object, 6653 tree_cons (NULL_TREE, selector, 6654 method_params)); 6655 } 6656 6657 /* ??? Selector is not at this point something we can use inside 6658 the compiler itself. Set it to garbage for the nonce. */ 6659 t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node); 6660 return build_function_call (loc, 6661 t, method_params); 6662 } 6663 6664 static void 6665 build_protocol_reference (tree p) 6666 { 6667 tree decl; 6668 const char *proto_name; 6669 6670 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */ 6671 6672 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p); 6673 decl = start_var_decl (objc_protocol_template, proto_name); 6674 6675 PROTOCOL_FORWARD_DECL (p) = decl; 6676 } 6677 6678 /* This function is called by the parser when (and only when) a 6679 @protocol() expression is found, in order to compile it. */ 6680 tree 6681 objc_build_protocol_expr (tree protoname) 6682 { 6683 tree expr; 6684 tree p = lookup_protocol (protoname); 6685 6686 if (!p) 6687 { 6688 error ("cannot find protocol declaration for %qE", 6689 protoname); 6690 return error_mark_node; 6691 } 6692 6693 if (!PROTOCOL_FORWARD_DECL (p)) 6694 build_protocol_reference (p); 6695 6696 expr = build_unary_op (input_location, 6697 ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0); 6698 6699 /* ??? Ideally we'd build the reference with objc_protocol_type directly, 6700 if we have it, rather than converting it here. */ 6701 expr = convert (objc_protocol_type, expr); 6702 6703 /* The @protocol() expression is being compiled into a pointer to a 6704 statically allocated instance of the Protocol class. To become 6705 usable at runtime, the 'isa' pointer of the instance need to be 6706 fixed up at runtime by the runtime library, to point to the 6707 actual 'Protocol' class. */ 6708 6709 /* For the GNU runtime, put the static Protocol instance in the list 6710 of statically allocated instances, so that we make sure that its 6711 'isa' pointer is fixed up at runtime by the GNU runtime library 6712 to point to the Protocol class (at runtime, when loading the 6713 module, the GNU runtime library loops on the statically allocated 6714 instances (as found in the defs field in objc_symtab) and fixups 6715 all the 'isa' pointers of those objects). */ 6716 if (! flag_next_runtime) 6717 { 6718 /* This type is a struct containing the fields of a Protocol 6719 object. (Cfr. objc_protocol_type instead is the type of a pointer 6720 to such a struct). */ 6721 tree protocol_struct_type = xref_tag 6722 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME)); 6723 tree *chain; 6724 6725 /* Look for the list of Protocol statically allocated instances 6726 to fixup at runtime. Create a new list to hold Protocol 6727 statically allocated instances, if the list is not found. At 6728 present there is only another list, holding NSConstantString 6729 static instances to be fixed up at runtime. */ 6730 for (chain = &objc_static_instances; 6731 *chain && TREE_VALUE (*chain) != protocol_struct_type; 6732 chain = &TREE_CHAIN (*chain)); 6733 if (!*chain) 6734 { 6735 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE); 6736 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type), 6737 class_names); 6738 } 6739 6740 /* Add this statically allocated instance to the Protocol list. */ 6741 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, 6742 PROTOCOL_FORWARD_DECL (p), 6743 TREE_PURPOSE (*chain)); 6744 } 6745 6746 6747 return expr; 6748 } 6749 6750 /* This function is called by the parser when a @selector() expression 6751 is found, in order to compile it. It is only called by the parser 6752 and only to compile a @selector(). LOC is the location of the 6753 @selector. */ 6754 tree 6755 objc_build_selector_expr (location_t loc, tree selnamelist) 6756 { 6757 tree selname; 6758 6759 /* Obtain the full selector name. */ 6760 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE) 6761 /* A unary selector. */ 6762 selname = selnamelist; 6763 else if (TREE_CODE (selnamelist) == TREE_LIST) 6764 selname = build_keyword_selector (selnamelist); 6765 else 6766 abort (); 6767 6768 /* If we are required to check @selector() expressions as they 6769 are found, check that the selector has been declared. */ 6770 if (warn_undeclared_selector) 6771 { 6772 /* Look the selector up in the list of all known class and 6773 instance methods (up to this line) to check that the selector 6774 exists. */ 6775 hash hsh; 6776 6777 /* First try with instance methods. */ 6778 hsh = hash_lookup (nst_method_hash_list, selname); 6779 6780 /* If not found, try with class methods. */ 6781 if (!hsh) 6782 { 6783 hsh = hash_lookup (cls_method_hash_list, selname); 6784 } 6785 6786 /* If still not found, print out a warning. */ 6787 if (!hsh) 6788 { 6789 warning (0, "undeclared selector %qE", selname); 6790 } 6791 } 6792 6793 6794 if (flag_typed_selectors) 6795 return build_typed_selector_reference (loc, selname, 0); 6796 else 6797 return build_selector_reference (loc, selname); 6798 } 6799 6800 tree 6801 objc_build_encode_expr (tree type) 6802 { 6803 tree result; 6804 const char *string; 6805 6806 encode_type (type, obstack_object_size (&util_obstack), 6807 OBJC_ENCODE_INLINE_DEFS); 6808 obstack_1grow (&util_obstack, 0); /* null terminate string */ 6809 string = XOBFINISH (&util_obstack, const char *); 6810 6811 /* Synthesize a string that represents the encoded struct/union. */ 6812 result = my_build_string (strlen (string) + 1, string); 6813 obstack_free (&util_obstack, util_firstobj); 6814 return result; 6815 } 6816 6817 static tree 6818 build_ivar_reference (tree id) 6819 { 6820 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL) 6821 { 6822 /* Historically, a class method that produced objects (factory 6823 method) would assign `self' to the instance that it 6824 allocated. This would effectively turn the class method into 6825 an instance method. Following this assignment, the instance 6826 variables could be accessed. That practice, while safe, 6827 violates the simple rule that a class method should not refer 6828 to an instance variable. It's better to catch the cases 6829 where this is done unknowingly than to support the above 6830 paradigm. */ 6831 warning (0, "instance variable %qE accessed in class method", 6832 id); 6833 self_decl = convert (objc_instance_type, self_decl); /* cast */ 6834 } 6835 6836 return objc_build_component_ref (build_indirect_ref (input_location, 6837 self_decl, RO_ARROW), 6838 id); 6839 } 6840 6841 /* Compute a hash value for a given method SEL_NAME. */ 6842 6843 static size_t 6844 hash_func (tree sel_name) 6845 { 6846 const unsigned char *s 6847 = (const unsigned char *)IDENTIFIER_POINTER (sel_name); 6848 size_t h = 0; 6849 6850 while (*s) 6851 h = h * 67 + *s++ - 113; 6852 return h; 6853 } 6854 6855 static void 6856 hash_init (void) 6857 { 6858 nst_method_hash_list 6859 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash)); 6860 cls_method_hash_list 6861 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash)); 6862 6863 /* Initialize the hash table used to hold the constant string objects. */ 6864 string_htab = htab_create_ggc (31, string_hash, 6865 string_eq, NULL); 6866 6867 /* Initialize the hash table used to hold EH-volatilized types. */ 6868 volatilized_htab = htab_create_ggc (31, volatilized_hash, 6869 volatilized_eq, NULL); 6870 } 6871 6872 /* WARNING!!!! hash_enter is called with a method, and will peek 6873 inside to find its selector! But hash_lookup is given a selector 6874 directly, and looks for the selector that's inside the found 6875 entry's key (method) for comparison. */ 6876 6877 static void 6878 hash_enter (hash *hashlist, tree method) 6879 { 6880 hash obj; 6881 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE; 6882 6883 obj = (hash) ggc_alloc (sizeof (struct hashed_entry)); 6884 obj->list = 0; 6885 obj->next = hashlist[slot]; 6886 obj->key = method; 6887 6888 hashlist[slot] = obj; /* append to front */ 6889 } 6890 6891 static hash 6892 hash_lookup (hash *hashlist, tree sel_name) 6893 { 6894 hash target; 6895 6896 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE]; 6897 6898 while (target) 6899 { 6900 if (sel_name == METHOD_SEL_NAME (target->key)) 6901 return target; 6902 6903 target = target->next; 6904 } 6905 return 0; 6906 } 6907 6908 static void 6909 hash_add_attr (hash entry, tree value) 6910 { 6911 attr obj; 6912 6913 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute)); 6914 obj->next = entry->list; 6915 obj->value = value; 6916 6917 entry->list = obj; /* append to front */ 6918 } 6919 6920 static tree 6921 lookup_method (tree mchain, tree method) 6922 { 6923 tree key; 6924 6925 if (TREE_CODE (method) == IDENTIFIER_NODE) 6926 key = method; 6927 else 6928 key = METHOD_SEL_NAME (method); 6929 6930 while (mchain) 6931 { 6932 if (METHOD_SEL_NAME (mchain) == key) 6933 return mchain; 6934 6935 mchain = TREE_CHAIN (mchain); 6936 } 6937 return NULL_TREE; 6938 } 6939 6940 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method 6941 in INTERFACE, along with any categories and protocols attached thereto. 6942 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS, 6943 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is 6944 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could 6945 be found in INTERFACE or any of its superclasses, look for an _instance_ 6946 method of the same name in the root class as a last resort. 6947 6948 If a suitable method cannot be found, return NULL_TREE. */ 6949 6950 static tree 6951 lookup_method_static (tree interface, tree ident, int flags) 6952 { 6953 tree meth = NULL_TREE, root_inter = NULL_TREE; 6954 tree inter = interface; 6955 int is_class = (flags & OBJC_LOOKUP_CLASS); 6956 int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER); 6957 6958 while (inter) 6959 { 6960 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter); 6961 tree category = inter; 6962 6963 /* First, look up the method in the class itself. */ 6964 if ((meth = lookup_method (chain, ident))) 6965 return meth; 6966 6967 /* Failing that, look for the method in each category of the class. */ 6968 while ((category = CLASS_CATEGORY_LIST (category))) 6969 { 6970 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category); 6971 6972 /* Check directly in each category. */ 6973 if ((meth = lookup_method (chain, ident))) 6974 return meth; 6975 6976 /* Failing that, check in each category's protocols. */ 6977 if (CLASS_PROTOCOL_LIST (category)) 6978 { 6979 if ((meth = (lookup_method_in_protocol_list 6980 (CLASS_PROTOCOL_LIST (category), ident, is_class)))) 6981 return meth; 6982 } 6983 } 6984 6985 /* If not found in categories, check in protocols of the main class. */ 6986 if (CLASS_PROTOCOL_LIST (inter)) 6987 { 6988 if ((meth = (lookup_method_in_protocol_list 6989 (CLASS_PROTOCOL_LIST (inter), ident, is_class)))) 6990 return meth; 6991 } 6992 6993 /* If we were instructed not to look in superclasses, don't. */ 6994 if (no_superclasses) 6995 return NULL_TREE; 6996 6997 /* Failing that, climb up the inheritance hierarchy. */ 6998 root_inter = inter; 6999 inter = lookup_interface (CLASS_SUPER_NAME (inter)); 7000 } 7001 while (inter); 7002 7003 /* If no class (factory) method was found, check if an _instance_ 7004 method of the same name exists in the root class. This is what 7005 the Objective-C runtime will do. If an instance method was not 7006 found, return 0. */ 7007 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE; 7008 } 7009 7010 /* Add the method to the hash list if it doesn't contain an identical 7011 method already. */ 7012 7013 static void 7014 add_method_to_hash_list (hash *hash_list, tree method) 7015 { 7016 hash hsh; 7017 7018 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method)))) 7019 { 7020 /* Install on a global chain. */ 7021 hash_enter (hash_list, method); 7022 } 7023 else 7024 { 7025 /* Check types against those; if different, add to a list. */ 7026 attr loop; 7027 int already_there = comp_proto_with_proto (method, hsh->key, 1); 7028 for (loop = hsh->list; !already_there && loop; loop = loop->next) 7029 already_there |= comp_proto_with_proto (method, loop->value, 1); 7030 if (!already_there) 7031 hash_add_attr (hsh, method); 7032 } 7033 } 7034 7035 static tree 7036 objc_add_method (tree klass, tree method, int is_class) 7037 { 7038 tree mth; 7039 7040 if (!(mth = lookup_method (is_class 7041 ? CLASS_CLS_METHODS (klass) 7042 : CLASS_NST_METHODS (klass), method))) 7043 { 7044 /* put method on list in reverse order */ 7045 if (is_class) 7046 { 7047 TREE_CHAIN (method) = CLASS_CLS_METHODS (klass); 7048 CLASS_CLS_METHODS (klass) = method; 7049 } 7050 else 7051 { 7052 TREE_CHAIN (method) = CLASS_NST_METHODS (klass); 7053 CLASS_NST_METHODS (klass) = method; 7054 } 7055 } 7056 else 7057 { 7058 /* When processing an @interface for a class or category, give hard 7059 errors on methods with identical selectors but differing argument 7060 and/or return types. We do not do this for @implementations, because 7061 C/C++ will do it for us (i.e., there will be duplicate function 7062 definition errors). */ 7063 if ((TREE_CODE (klass) == CLASS_INTERFACE_TYPE 7064 || TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE) 7065 && !comp_proto_with_proto (method, mth, 1)) 7066 error ("duplicate declaration of method %<%c%E%>", 7067 is_class ? '+' : '-', 7068 METHOD_SEL_NAME (mth)); 7069 } 7070 7071 if (is_class) 7072 add_method_to_hash_list (cls_method_hash_list, method); 7073 else 7074 { 7075 add_method_to_hash_list (nst_method_hash_list, method); 7076 7077 /* Instance methods in root classes (and categories thereof) 7078 may act as class methods as a last resort. We also add 7079 instance methods listed in @protocol declarations to 7080 the class hash table, on the assumption that @protocols 7081 may be adopted by root classes or categories. */ 7082 if (TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE 7083 || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE) 7084 klass = lookup_interface (CLASS_NAME (klass)); 7085 7086 if (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE 7087 || !CLASS_SUPER_NAME (klass)) 7088 add_method_to_hash_list (cls_method_hash_list, method); 7089 } 7090 7091 return method; 7092 } 7093 7094 static tree 7095 add_class (tree class_name, tree name) 7096 { 7097 struct interface_tuple **slot; 7098 7099 /* Put interfaces on list in reverse order. */ 7100 TREE_CHAIN (class_name) = interface_chain; 7101 interface_chain = class_name; 7102 7103 if (interface_htab == NULL) 7104 interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL); 7105 slot = (struct interface_tuple **) 7106 htab_find_slot_with_hash (interface_htab, name, 7107 IDENTIFIER_HASH_VALUE (name), 7108 INSERT); 7109 if (!*slot) 7110 { 7111 *slot = (struct interface_tuple *) ggc_alloc_cleared (sizeof (struct interface_tuple)); 7112 (*slot)->id = name; 7113 } 7114 (*slot)->class_name = class_name; 7115 7116 return interface_chain; 7117 } 7118 7119 static void 7120 add_category (tree klass, tree category) 7121 { 7122 /* Put categories on list in reverse order. */ 7123 tree cat = lookup_category (klass, CLASS_SUPER_NAME (category)); 7124 7125 if (cat) 7126 { 7127 warning (0, "duplicate interface declaration for category %<%E(%E)%>", 7128 CLASS_NAME (klass), 7129 CLASS_SUPER_NAME (category)); 7130 } 7131 else 7132 { 7133 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (klass); 7134 CLASS_CATEGORY_LIST (klass) = category; 7135 } 7136 } 7137 7138 /* Called after parsing each instance variable declaration. Necessary to 7139 preserve typedefs and implement public/private... 7140 7141 VISIBILITY is 1 for public, 0 for protected, and 2 for private. */ 7142 7143 static tree 7144 add_instance_variable (tree klass, int visibility, tree field_decl) 7145 { 7146 tree field_type = TREE_TYPE (field_decl); 7147 const char *ivar_name = DECL_NAME (field_decl) 7148 ? identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (field_decl))) 7149 : _("<unnamed>"); 7150 7151 #ifdef OBJCPLUS 7152 if (TREE_CODE (field_type) == REFERENCE_TYPE) 7153 { 7154 error ("illegal reference type specified for instance variable %qs", 7155 ivar_name); 7156 /* Return class as is without adding this ivar. */ 7157 return klass; 7158 } 7159 #endif 7160 7161 if (field_type == error_mark_node || !TYPE_SIZE (field_type) 7162 || TYPE_SIZE (field_type) == error_mark_node) 7163 /* 'type[0]' is allowed, but 'type[]' is not! */ 7164 { 7165 error ("instance variable %qs has unknown size", ivar_name); 7166 /* Return class as is without adding this ivar. */ 7167 return klass; 7168 } 7169 7170 #ifdef OBJCPLUS 7171 /* Check if the ivar being added has a non-POD C++ type. If so, we will 7172 need to either (1) warn the user about it or (2) generate suitable 7173 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct' 7174 methods (if '-fobjc-call-cxx-cdtors' was specified). */ 7175 if (MAYBE_CLASS_TYPE_P (field_type) 7176 && (TYPE_NEEDS_CONSTRUCTING (field_type) 7177 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type) 7178 || TYPE_POLYMORPHIC_P (field_type))) 7179 { 7180 tree type_name = OBJC_TYPE_NAME (field_type); 7181 7182 if (flag_objc_call_cxx_cdtors) 7183 { 7184 /* Since the ObjC runtime will be calling the constructors and 7185 destructors for us, the only thing we can't handle is the lack 7186 of a default constructor. */ 7187 if (TYPE_NEEDS_CONSTRUCTING (field_type) 7188 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type)) 7189 { 7190 warning (0, "type %qE has no default constructor to call", 7191 type_name); 7192 7193 /* If we cannot call a constructor, we should also avoid 7194 calling the destructor, for symmetry. */ 7195 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)) 7196 warning (0, "destructor for %qE shall not be run either", 7197 type_name); 7198 } 7199 } 7200 else 7201 { 7202 static bool warn_cxx_ivars = false; 7203 7204 if (TYPE_POLYMORPHIC_P (field_type)) 7205 { 7206 /* Vtable pointers are Real Bad(tm), since Obj-C cannot 7207 initialize them. */ 7208 error ("type %qE has virtual member functions", type_name); 7209 error ("illegal aggregate type %qE specified " 7210 "for instance variable %qs", 7211 type_name, ivar_name); 7212 /* Return class as is without adding this ivar. */ 7213 return klass; 7214 } 7215 7216 /* User-defined constructors and destructors are not known to Obj-C 7217 and hence will not be called. This may or may not be a problem. */ 7218 if (TYPE_NEEDS_CONSTRUCTING (field_type)) 7219 warning (0, "type %qE has a user-defined constructor", type_name); 7220 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)) 7221 warning (0, "type %qE has a user-defined destructor", type_name); 7222 7223 if (!warn_cxx_ivars) 7224 { 7225 warning (0, "C++ constructors and destructors will not " 7226 "be invoked for Objective-C fields"); 7227 warn_cxx_ivars = true; 7228 } 7229 } 7230 } 7231 #endif 7232 7233 /* Overload the public attribute, it is not used for FIELD_DECLs. */ 7234 switch (visibility) 7235 { 7236 case 0: 7237 TREE_PUBLIC (field_decl) = 0; 7238 TREE_PRIVATE (field_decl) = 0; 7239 TREE_PROTECTED (field_decl) = 1; 7240 break; 7241 7242 case 1: 7243 TREE_PUBLIC (field_decl) = 1; 7244 TREE_PRIVATE (field_decl) = 0; 7245 TREE_PROTECTED (field_decl) = 0; 7246 break; 7247 7248 case 2: 7249 TREE_PUBLIC (field_decl) = 0; 7250 TREE_PRIVATE (field_decl) = 1; 7251 TREE_PROTECTED (field_decl) = 0; 7252 break; 7253 7254 } 7255 7256 CLASS_RAW_IVARS (klass) = chainon (CLASS_RAW_IVARS (klass), field_decl); 7257 7258 return klass; 7259 } 7260 7261 static tree 7262 is_ivar (tree decl_chain, tree ident) 7263 { 7264 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain)) 7265 if (DECL_NAME (decl_chain) == ident) 7266 return decl_chain; 7267 return NULL_TREE; 7268 } 7269 7270 /* True if the ivar is private and we are not in its implementation. */ 7271 7272 static int 7273 is_private (tree decl) 7274 { 7275 return (TREE_PRIVATE (decl) 7276 && ! is_ivar (CLASS_IVARS (implementation_template), 7277 DECL_NAME (decl))); 7278 } 7279 7280 /* We have an instance variable reference;, check to see if it is public. */ 7281 7282 int 7283 objc_is_public (tree expr, tree identifier) 7284 { 7285 tree basetype, decl; 7286 7287 #ifdef OBJCPLUS 7288 if (processing_template_decl) 7289 return 1; 7290 #endif 7291 7292 if (TREE_TYPE (expr) == error_mark_node) 7293 return 1; 7294 7295 basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr)); 7296 7297 if (basetype && TREE_CODE (basetype) == RECORD_TYPE) 7298 { 7299 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype)) 7300 { 7301 tree klass = lookup_interface (OBJC_TYPE_NAME (basetype)); 7302 7303 if (!klass) 7304 { 7305 error ("cannot find interface declaration for %qE", 7306 OBJC_TYPE_NAME (basetype)); 7307 return 0; 7308 } 7309 7310 if ((decl = is_ivar (get_class_ivars (klass, true), identifier))) 7311 { 7312 if (TREE_PUBLIC (decl)) 7313 return 1; 7314 7315 /* Important difference between the Stepstone translator: 7316 all instance variables should be public within the context 7317 of the implementation. */ 7318 if (objc_implementation_context 7319 && ((TREE_CODE (objc_implementation_context) 7320 == CLASS_IMPLEMENTATION_TYPE) 7321 || (TREE_CODE (objc_implementation_context) 7322 == CATEGORY_IMPLEMENTATION_TYPE))) 7323 { 7324 tree curtype = TYPE_MAIN_VARIANT 7325 (CLASS_STATIC_TEMPLATE 7326 (implementation_template)); 7327 7328 if (basetype == curtype 7329 || DERIVED_FROM_P (basetype, curtype)) 7330 { 7331 int priv = is_private (decl); 7332 7333 if (priv) 7334 error ("instance variable %qE is declared private", 7335 DECL_NAME (decl)); 7336 7337 return !priv; 7338 } 7339 } 7340 7341 /* The 2.95.2 compiler sometimes allowed C functions to access 7342 non-@public ivars. We will let this slide for now... */ 7343 if (!objc_method_context) 7344 { 7345 warning (0, "instance variable %qE is %s; " 7346 "this will be a hard error in the future", 7347 identifier, 7348 TREE_PRIVATE (decl) ? "@private" : "@protected"); 7349 return 1; 7350 } 7351 7352 error ("instance variable %qE is declared %s", 7353 identifier, 7354 TREE_PRIVATE (decl) ? "private" : "protected"); 7355 return 0; 7356 } 7357 } 7358 } 7359 7360 return 1; 7361 } 7362 7363 /* Make sure all entries in CHAIN are also in LIST. */ 7364 7365 static int 7366 check_methods (tree chain, tree list, int mtype) 7367 { 7368 int first = 1; 7369 7370 while (chain) 7371 { 7372 if (!lookup_method (list, chain)) 7373 { 7374 if (first) 7375 { 7376 if (TREE_CODE (objc_implementation_context) 7377 == CLASS_IMPLEMENTATION_TYPE) 7378 warning (0, "incomplete implementation of class %qE", 7379 CLASS_NAME (objc_implementation_context)); 7380 else if (TREE_CODE (objc_implementation_context) 7381 == CATEGORY_IMPLEMENTATION_TYPE) 7382 warning (0, "incomplete implementation of category %qE", 7383 CLASS_SUPER_NAME (objc_implementation_context)); 7384 first = 0; 7385 } 7386 7387 warning (0, "method definition for %<%c%E%> not found", 7388 mtype, METHOD_SEL_NAME (chain)); 7389 } 7390 7391 chain = TREE_CHAIN (chain); 7392 } 7393 7394 return first; 7395 } 7396 7397 /* Check if KLASS, or its superclasses, explicitly conforms to PROTOCOL. */ 7398 7399 static int 7400 conforms_to_protocol (tree klass, tree protocol) 7401 { 7402 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE) 7403 { 7404 tree p = CLASS_PROTOCOL_LIST (klass); 7405 while (p && TREE_VALUE (p) != protocol) 7406 p = TREE_CHAIN (p); 7407 7408 if (!p) 7409 { 7410 tree super = (CLASS_SUPER_NAME (klass) 7411 ? lookup_interface (CLASS_SUPER_NAME (klass)) 7412 : NULL_TREE); 7413 int tmp = super ? conforms_to_protocol (super, protocol) : 0; 7414 if (!tmp) 7415 return 0; 7416 } 7417 } 7418 7419 return 1; 7420 } 7421 7422 /* Make sure all methods in CHAIN are accessible as MTYPE methods in 7423 CONTEXT. This is one of two mechanisms to check protocol integrity. */ 7424 7425 static int 7426 check_methods_accessible (tree chain, tree context, int mtype) 7427 { 7428 int first = 1; 7429 tree list; 7430 tree base_context = context; 7431 7432 while (chain) 7433 { 7434 context = base_context; 7435 while (context) 7436 { 7437 if (mtype == '+') 7438 list = CLASS_CLS_METHODS (context); 7439 else 7440 list = CLASS_NST_METHODS (context); 7441 7442 if (lookup_method (list, chain)) 7443 break; 7444 7445 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE 7446 || TREE_CODE (context) == CLASS_INTERFACE_TYPE) 7447 context = (CLASS_SUPER_NAME (context) 7448 ? lookup_interface (CLASS_SUPER_NAME (context)) 7449 : NULL_TREE); 7450 7451 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE 7452 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE) 7453 context = (CLASS_NAME (context) 7454 ? lookup_interface (CLASS_NAME (context)) 7455 : NULL_TREE); 7456 else 7457 abort (); 7458 } 7459 7460 if (context == NULL_TREE) 7461 { 7462 if (first) 7463 { 7464 if (TREE_CODE (objc_implementation_context) 7465 == CLASS_IMPLEMENTATION_TYPE) 7466 warning (0, "incomplete implementation of class %qE", 7467 CLASS_NAME (objc_implementation_context)); 7468 else if (TREE_CODE (objc_implementation_context) 7469 == CATEGORY_IMPLEMENTATION_TYPE) 7470 warning (0, "incomplete implementation of category %qE", 7471 CLASS_SUPER_NAME (objc_implementation_context)); 7472 first = 0; 7473 } 7474 warning (0, "method definition for %<%c%E%> not found", 7475 mtype, METHOD_SEL_NAME (chain)); 7476 } 7477 7478 chain = TREE_CHAIN (chain); /* next method... */ 7479 } 7480 return first; 7481 } 7482 7483 /* Check whether the current interface (accessible via 7484 'objc_implementation_context') actually implements protocol P, along 7485 with any protocols that P inherits. */ 7486 7487 static void 7488 check_protocol (tree p, const char *type, tree name) 7489 { 7490 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE) 7491 { 7492 int f1, f2; 7493 7494 /* Ensure that all protocols have bodies! */ 7495 if (warn_protocol) 7496 { 7497 f1 = check_methods (PROTOCOL_CLS_METHODS (p), 7498 CLASS_CLS_METHODS (objc_implementation_context), 7499 '+'); 7500 f2 = check_methods (PROTOCOL_NST_METHODS (p), 7501 CLASS_NST_METHODS (objc_implementation_context), 7502 '-'); 7503 } 7504 else 7505 { 7506 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p), 7507 objc_implementation_context, 7508 '+'); 7509 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p), 7510 objc_implementation_context, 7511 '-'); 7512 } 7513 7514 if (!f1 || !f2) 7515 warning (0, "%s %qE does not fully implement the %qE protocol", 7516 type, name, PROTOCOL_NAME (p)); 7517 } 7518 7519 /* Check protocols recursively. */ 7520 if (PROTOCOL_LIST (p)) 7521 { 7522 tree subs = PROTOCOL_LIST (p); 7523 tree super_class = 7524 lookup_interface (CLASS_SUPER_NAME (implementation_template)); 7525 7526 while (subs) 7527 { 7528 tree sub = TREE_VALUE (subs); 7529 7530 /* If the superclass does not conform to the protocols 7531 inherited by P, then we must! */ 7532 if (!super_class || !conforms_to_protocol (super_class, sub)) 7533 check_protocol (sub, type, name); 7534 subs = TREE_CHAIN (subs); 7535 } 7536 } 7537 } 7538 7539 /* Check whether the current interface (accessible via 7540 'objc_implementation_context') actually implements the protocols listed 7541 in PROTO_LIST. */ 7542 7543 static void 7544 check_protocols (tree proto_list, const char *type, tree name) 7545 { 7546 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list)) 7547 { 7548 tree p = TREE_VALUE (proto_list); 7549 7550 check_protocol (p, type, name); 7551 } 7552 } 7553 7554 /* Make sure that the class CLASS_NAME is defined 7555 CODE says which kind of thing CLASS_NAME ought to be. 7556 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE, 7557 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */ 7558 7559 static tree 7560 start_class (enum tree_code code, tree class_name, tree super_name, 7561 tree protocol_list) 7562 { 7563 tree klass, decl; 7564 7565 #ifdef OBJCPLUS 7566 if (current_namespace != global_namespace) { 7567 error ("Objective-C declarations may only appear in global scope"); 7568 } 7569 #endif /* OBJCPLUS */ 7570 7571 if (objc_implementation_context) 7572 { 7573 warning (0, "%<@end%> missing in implementation context"); 7574 finish_class (objc_implementation_context); 7575 objc_ivar_chain = NULL_TREE; 7576 objc_implementation_context = NULL_TREE; 7577 } 7578 7579 klass = make_node (code); 7580 TYPE_LANG_SLOT_1 (klass) = make_tree_vec (CLASS_LANG_SLOT_ELTS); 7581 7582 /* Check for existence of the super class, if one was specified. Note 7583 that we must have seen an @interface, not just a @class. If we 7584 are looking at a @compatibility_alias, traverse it first. */ 7585 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE) 7586 && super_name) 7587 { 7588 tree super = objc_is_class_name (super_name); 7589 7590 if (!super || !lookup_interface (super)) 7591 { 7592 error ("cannot find interface declaration for %qE, superclass of %qE", 7593 super ? super : super_name, 7594 class_name); 7595 super_name = NULL_TREE; 7596 } 7597 else 7598 super_name = super; 7599 } 7600 7601 CLASS_NAME (klass) = class_name; 7602 CLASS_SUPER_NAME (klass) = super_name; 7603 CLASS_CLS_METHODS (klass) = NULL_TREE; 7604 7605 if (! objc_is_class_name (class_name) 7606 && (decl = lookup_name (class_name))) 7607 { 7608 error ("%qE redeclared as different kind of symbol", 7609 class_name); 7610 error ("previous declaration of %q+D", 7611 decl); 7612 } 7613 7614 if (code == CLASS_IMPLEMENTATION_TYPE) 7615 { 7616 { 7617 tree chain; 7618 7619 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain)) 7620 if (TREE_VALUE (chain) == class_name) 7621 { 7622 error ("reimplementation of class %qE", 7623 class_name); 7624 return error_mark_node; 7625 } 7626 implemented_classes = tree_cons (NULL_TREE, class_name, 7627 implemented_classes); 7628 } 7629 7630 /* Reset for multiple classes per file. */ 7631 method_slot = 0; 7632 7633 objc_implementation_context = klass; 7634 7635 /* Lookup the interface for this implementation. */ 7636 7637 if (!(implementation_template = lookup_interface (class_name))) 7638 { 7639 warning (0, "cannot find interface declaration for %qE", 7640 class_name); 7641 add_class (implementation_template = objc_implementation_context, 7642 class_name); 7643 } 7644 7645 /* If a super class has been specified in the implementation, 7646 insure it conforms to the one specified in the interface. */ 7647 7648 if (super_name 7649 && (super_name != CLASS_SUPER_NAME (implementation_template))) 7650 { 7651 tree previous_name = CLASS_SUPER_NAME (implementation_template); 7652 error ("conflicting super class name %qE", 7653 super_name); 7654 if (previous_name) 7655 error ("previous declaration of %qE", previous_name); 7656 else 7657 error ("previous declaration"); 7658 } 7659 7660 else if (! super_name) 7661 { 7662 CLASS_SUPER_NAME (objc_implementation_context) 7663 = CLASS_SUPER_NAME (implementation_template); 7664 } 7665 } 7666 7667 else if (code == CLASS_INTERFACE_TYPE) 7668 { 7669 if (lookup_interface (class_name)) 7670 #ifdef OBJCPLUS 7671 error ("duplicate interface declaration for class %qE", 7672 #else 7673 warning (0, "duplicate interface declaration for class %qE", 7674 #endif 7675 class_name); 7676 else 7677 add_class (klass, class_name); 7678 7679 if (protocol_list) 7680 CLASS_PROTOCOL_LIST (klass) 7681 = lookup_and_install_protocols (protocol_list); 7682 } 7683 7684 else if (code == CATEGORY_INTERFACE_TYPE) 7685 { 7686 tree class_category_is_assoc_with; 7687 7688 /* For a category, class_name is really the name of the class that 7689 the following set of methods will be associated with. We must 7690 find the interface so that can derive the objects template. */ 7691 7692 if (!(class_category_is_assoc_with = lookup_interface (class_name))) 7693 { 7694 error ("cannot find interface declaration for %qE", 7695 class_name); 7696 exit (FATAL_EXIT_CODE); 7697 } 7698 else 7699 add_category (class_category_is_assoc_with, klass); 7700 7701 if (protocol_list) 7702 CLASS_PROTOCOL_LIST (klass) 7703 = lookup_and_install_protocols (protocol_list); 7704 } 7705 7706 else if (code == CATEGORY_IMPLEMENTATION_TYPE) 7707 { 7708 /* Reset for multiple classes per file. */ 7709 method_slot = 0; 7710 7711 objc_implementation_context = klass; 7712 7713 /* For a category, class_name is really the name of the class that 7714 the following set of methods will be associated with. We must 7715 find the interface so that can derive the objects template. */ 7716 7717 if (!(implementation_template = lookup_interface (class_name))) 7718 { 7719 error ("cannot find interface declaration for %qE", 7720 class_name); 7721 exit (FATAL_EXIT_CODE); 7722 } 7723 } 7724 return klass; 7725 } 7726 7727 static tree 7728 continue_class (tree klass) 7729 { 7730 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE 7731 || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE) 7732 { 7733 struct imp_entry *imp_entry; 7734 7735 /* Check consistency of the instance variables. */ 7736 7737 if (CLASS_RAW_IVARS (klass)) 7738 check_ivars (implementation_template, klass); 7739 7740 /* code generation */ 7741 7742 #ifdef OBJCPLUS 7743 push_lang_context (lang_name_c); 7744 #endif 7745 7746 build_private_template (implementation_template); 7747 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template); 7748 objc_instance_type = build_pointer_type (uprivate_record); 7749 7750 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry)); 7751 7752 imp_entry->next = imp_list; 7753 imp_entry->imp_context = klass; 7754 imp_entry->imp_template = implementation_template; 7755 7756 synth_forward_declarations (); 7757 imp_entry->class_decl = UOBJC_CLASS_decl; 7758 imp_entry->meta_decl = UOBJC_METACLASS_decl; 7759 imp_entry->has_cxx_cdtors = 0; 7760 7761 /* Append to front and increment count. */ 7762 imp_list = imp_entry; 7763 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE) 7764 imp_count++; 7765 else 7766 cat_count++; 7767 7768 #ifdef OBJCPLUS 7769 pop_lang_context (); 7770 #endif /* OBJCPLUS */ 7771 7772 return get_class_ivars (implementation_template, true); 7773 } 7774 7775 else if (TREE_CODE (klass) == CLASS_INTERFACE_TYPE) 7776 { 7777 #ifdef OBJCPLUS 7778 push_lang_context (lang_name_c); 7779 #endif /* OBJCPLUS */ 7780 7781 build_private_template (klass); 7782 7783 #ifdef OBJCPLUS 7784 pop_lang_context (); 7785 #endif /* OBJCPLUS */ 7786 7787 return NULL_TREE; 7788 } 7789 7790 else 7791 return error_mark_node; 7792 } 7793 7794 /* This is called once we see the "@end" in an interface/implementation. */ 7795 7796 static void 7797 finish_class (tree klass) 7798 { 7799 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE) 7800 { 7801 /* All code generation is done in finish_objc. */ 7802 7803 if (implementation_template != objc_implementation_context) 7804 { 7805 /* Ensure that all method listed in the interface contain bodies. */ 7806 check_methods (CLASS_CLS_METHODS (implementation_template), 7807 CLASS_CLS_METHODS (objc_implementation_context), '+'); 7808 check_methods (CLASS_NST_METHODS (implementation_template), 7809 CLASS_NST_METHODS (objc_implementation_context), '-'); 7810 7811 if (CLASS_PROTOCOL_LIST (implementation_template)) 7812 check_protocols (CLASS_PROTOCOL_LIST (implementation_template), 7813 "class", 7814 CLASS_NAME (objc_implementation_context)); 7815 } 7816 } 7817 7818 else if (TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE) 7819 { 7820 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (klass)); 7821 7822 if (category) 7823 { 7824 /* Ensure all method listed in the interface contain bodies. */ 7825 check_methods (CLASS_CLS_METHODS (category), 7826 CLASS_CLS_METHODS (objc_implementation_context), '+'); 7827 check_methods (CLASS_NST_METHODS (category), 7828 CLASS_NST_METHODS (objc_implementation_context), '-'); 7829 7830 if (CLASS_PROTOCOL_LIST (category)) 7831 check_protocols (CLASS_PROTOCOL_LIST (category), 7832 "category", 7833 CLASS_SUPER_NAME (objc_implementation_context)); 7834 } 7835 } 7836 } 7837 7838 static tree 7839 add_protocol (tree protocol) 7840 { 7841 /* Put protocol on list in reverse order. */ 7842 TREE_CHAIN (protocol) = protocol_chain; 7843 protocol_chain = protocol; 7844 return protocol_chain; 7845 } 7846 7847 static tree 7848 lookup_protocol (tree ident) 7849 { 7850 tree chain; 7851 7852 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain)) 7853 if (ident == PROTOCOL_NAME (chain)) 7854 return chain; 7855 7856 return NULL_TREE; 7857 } 7858 7859 /* This function forward declares the protocols named by NAMES. If 7860 they are already declared or defined, the function has no effect. */ 7861 7862 void 7863 objc_declare_protocols (tree names) 7864 { 7865 tree list; 7866 7867 #ifdef OBJCPLUS 7868 if (current_namespace != global_namespace) { 7869 error ("Objective-C declarations may only appear in global scope"); 7870 } 7871 #endif /* OBJCPLUS */ 7872 7873 for (list = names; list; list = TREE_CHAIN (list)) 7874 { 7875 tree name = TREE_VALUE (list); 7876 7877 if (lookup_protocol (name) == NULL_TREE) 7878 { 7879 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE); 7880 7881 TYPE_LANG_SLOT_1 (protocol) 7882 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS); 7883 PROTOCOL_NAME (protocol) = name; 7884 PROTOCOL_LIST (protocol) = NULL_TREE; 7885 add_protocol (protocol); 7886 PROTOCOL_DEFINED (protocol) = 0; 7887 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE; 7888 } 7889 } 7890 } 7891 7892 static tree 7893 start_protocol (enum tree_code code, tree name, tree list) 7894 { 7895 tree protocol; 7896 7897 #ifdef OBJCPLUS 7898 if (current_namespace != global_namespace) { 7899 error ("Objective-C declarations may only appear in global scope"); 7900 } 7901 #endif /* OBJCPLUS */ 7902 7903 protocol = lookup_protocol (name); 7904 7905 if (!protocol) 7906 { 7907 protocol = make_node (code); 7908 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS); 7909 7910 PROTOCOL_NAME (protocol) = name; 7911 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list); 7912 add_protocol (protocol); 7913 PROTOCOL_DEFINED (protocol) = 1; 7914 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE; 7915 7916 check_protocol_recursively (protocol, list); 7917 } 7918 else if (! PROTOCOL_DEFINED (protocol)) 7919 { 7920 PROTOCOL_DEFINED (protocol) = 1; 7921 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list); 7922 7923 check_protocol_recursively (protocol, list); 7924 } 7925 else 7926 { 7927 warning (0, "duplicate declaration for protocol %qE", 7928 name); 7929 } 7930 return protocol; 7931 } 7932 7933 7934 /* "Encode" a data type into a string, which grows in util_obstack. 7935 ??? What is the FORMAT? Someone please document this! */ 7936 7937 static void 7938 encode_type_qualifiers (tree declspecs) 7939 { 7940 tree spec; 7941 7942 for (spec = declspecs; spec; spec = TREE_CHAIN (spec)) 7943 { 7944 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec)) 7945 obstack_1grow (&util_obstack, 'n'); 7946 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec)) 7947 obstack_1grow (&util_obstack, 'N'); 7948 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec)) 7949 obstack_1grow (&util_obstack, 'o'); 7950 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec)) 7951 obstack_1grow (&util_obstack, 'O'); 7952 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec)) 7953 obstack_1grow (&util_obstack, 'R'); 7954 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec)) 7955 obstack_1grow (&util_obstack, 'V'); 7956 } 7957 } 7958 7959 /* Encode a pointer type. */ 7960 7961 static void 7962 encode_pointer (tree type, int curtype, int format) 7963 { 7964 tree pointer_to = TREE_TYPE (type); 7965 7966 if (TREE_CODE (pointer_to) == RECORD_TYPE) 7967 { 7968 if (OBJC_TYPE_NAME (pointer_to) 7969 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE) 7970 { 7971 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to)); 7972 7973 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */ 7974 { 7975 obstack_1grow (&util_obstack, '@'); 7976 return; 7977 } 7978 else if (TYPE_HAS_OBJC_INFO (pointer_to) 7979 && TYPE_OBJC_INTERFACE (pointer_to)) 7980 { 7981 if (generating_instance_variables) 7982 { 7983 obstack_1grow (&util_obstack, '@'); 7984 obstack_1grow (&util_obstack, '"'); 7985 obstack_grow (&util_obstack, name, strlen (name)); 7986 obstack_1grow (&util_obstack, '"'); 7987 return; 7988 } 7989 else 7990 { 7991 obstack_1grow (&util_obstack, '@'); 7992 return; 7993 } 7994 } 7995 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */ 7996 { 7997 obstack_1grow (&util_obstack, '#'); 7998 return; 7999 } 8000 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */ 8001 { 8002 obstack_1grow (&util_obstack, ':'); 8003 return; 8004 } 8005 } 8006 } 8007 else if (TREE_CODE (pointer_to) == INTEGER_TYPE 8008 && TYPE_MODE (pointer_to) == QImode) 8009 { 8010 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE 8011 ? OBJC_TYPE_NAME (pointer_to) 8012 : DECL_NAME (OBJC_TYPE_NAME (pointer_to)); 8013 8014 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL")) 8015 { 8016 /* It appears that "r*" means "const char *" rather than 8017 "char *const". */ 8018 if (TYPE_READONLY (pointer_to)) 8019 obstack_1grow (&util_obstack, 'r'); 8020 8021 obstack_1grow (&util_obstack, '*'); 8022 return; 8023 } 8024 } 8025 8026 /* We have a type that does not get special treatment. */ 8027 8028 /* NeXT extension */ 8029 obstack_1grow (&util_obstack, '^'); 8030 encode_type (pointer_to, curtype, format); 8031 } 8032 8033 static void 8034 encode_array (tree type, int curtype, int format) 8035 { 8036 tree an_int_cst = TYPE_SIZE (type); 8037 tree array_of = TREE_TYPE (type); 8038 char buffer[40]; 8039 8040 /* An incomplete array is treated like a pointer. */ 8041 if (an_int_cst == NULL) 8042 { 8043 encode_pointer (type, curtype, format); 8044 return; 8045 } 8046 8047 if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0) 8048 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0); 8049 else 8050 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, 8051 TREE_INT_CST_LOW (an_int_cst) 8052 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))); 8053 8054 obstack_grow (&util_obstack, buffer, strlen (buffer)); 8055 encode_type (array_of, curtype, format); 8056 obstack_1grow (&util_obstack, ']'); 8057 return; 8058 } 8059 8060 static void 8061 encode_aggregate_fields (tree type, int pointed_to, int curtype, int format) 8062 { 8063 tree field = TYPE_FIELDS (type); 8064 8065 for (; field; field = TREE_CHAIN (field)) 8066 { 8067 #ifdef OBJCPLUS 8068 /* C++ static members, and things that are not field at all, 8069 should not appear in the encoding. */ 8070 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field)) 8071 continue; 8072 #endif 8073 8074 /* Recursively encode fields of embedded base classes. */ 8075 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field) 8076 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE) 8077 { 8078 encode_aggregate_fields (TREE_TYPE (field), 8079 pointed_to, curtype, format); 8080 continue; 8081 } 8082 8083 if (generating_instance_variables && !pointed_to) 8084 { 8085 tree fname = DECL_NAME (field); 8086 8087 obstack_1grow (&util_obstack, '"'); 8088 8089 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE) 8090 obstack_grow (&util_obstack, 8091 IDENTIFIER_POINTER (fname), 8092 strlen (IDENTIFIER_POINTER (fname))); 8093 8094 obstack_1grow (&util_obstack, '"'); 8095 } 8096 8097 encode_field_decl (field, curtype, format); 8098 } 8099 } 8100 8101 static void 8102 encode_aggregate_within (tree type, int curtype, int format, int left, 8103 int right) 8104 { 8105 tree name; 8106 /* NB: aggregates that are pointed to have slightly different encoding 8107 rules in that you never encode the names of instance variables. */ 8108 int ob_size = obstack_object_size (&util_obstack); 8109 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0; 8110 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0; 8111 int pointed_to = (c0 == '^' || (c1 == '^' && c0 == 'r')); 8112 int inline_contents 8113 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables) 8114 && (!pointed_to || ob_size - curtype == (c1 == 'r' ? 2 : 1))); 8115 8116 /* Traverse struct aliases; it is important to get the 8117 original struct and its tag name (if any). */ 8118 type = TYPE_MAIN_VARIANT (type); 8119 name = OBJC_TYPE_NAME (type); 8120 /* Open parenth/bracket. */ 8121 obstack_1grow (&util_obstack, left); 8122 8123 /* Encode the struct/union tag name, or '?' if a tag was 8124 not provided. Typedef aliases do not qualify. */ 8125 #ifdef OBJCPLUS 8126 /* For compatibility with the NeXT runtime, ObjC++ encodes template 8127 args as a composite struct tag name. */ 8128 if (name && TREE_CODE (name) == IDENTIFIER_NODE 8129 /* Did this struct have a tag? */ 8130 && !TYPE_WAS_ANONYMOUS (type)) 8131 obstack_grow (&util_obstack, 8132 decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME), 8133 strlen (decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME))); 8134 #else 8135 if (name && TREE_CODE (name) == IDENTIFIER_NODE) 8136 obstack_grow (&util_obstack, 8137 IDENTIFIER_POINTER (name), 8138 strlen (IDENTIFIER_POINTER (name))); 8139 #endif 8140 else 8141 obstack_1grow (&util_obstack, '?'); 8142 8143 /* Encode the types (and possibly names) of the inner fields, 8144 if required. */ 8145 if (inline_contents) 8146 { 8147 obstack_1grow (&util_obstack, '='); 8148 encode_aggregate_fields (type, pointed_to, curtype, format); 8149 } 8150 /* Close parenth/bracket. */ 8151 obstack_1grow (&util_obstack, right); 8152 } 8153 8154 static void 8155 encode_aggregate (tree type, int curtype, int format) 8156 { 8157 enum tree_code code = TREE_CODE (type); 8158 8159 switch (code) 8160 { 8161 case RECORD_TYPE: 8162 { 8163 encode_aggregate_within (type, curtype, format, '{', '}'); 8164 break; 8165 } 8166 case UNION_TYPE: 8167 { 8168 encode_aggregate_within (type, curtype, format, '(', ')'); 8169 break; 8170 } 8171 8172 case ENUMERAL_TYPE: 8173 obstack_1grow (&util_obstack, 'i'); 8174 break; 8175 8176 default: 8177 break; 8178 } 8179 } 8180 8181 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying 8182 field type. */ 8183 8184 static void 8185 encode_next_bitfield (int width) 8186 { 8187 char buffer[40]; 8188 sprintf (buffer, "b%d", width); 8189 obstack_grow (&util_obstack, buffer, strlen (buffer)); 8190 } 8191 8192 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */ 8193 static void 8194 encode_type (tree type, int curtype, int format) 8195 { 8196 enum tree_code code = TREE_CODE (type); 8197 char c; 8198 8199 if (type == error_mark_node) 8200 return; 8201 8202 if (TYPE_READONLY (type)) 8203 obstack_1grow (&util_obstack, 'r'); 8204 8205 if (code == INTEGER_TYPE) 8206 { 8207 switch (GET_MODE_BITSIZE (TYPE_MODE (type))) 8208 { 8209 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break; 8210 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break; 8211 case 32: 8212 if (type == long_unsigned_type_node 8213 || type == long_integer_type_node) 8214 c = TYPE_UNSIGNED (type) ? 'L' : 'l'; 8215 else 8216 c = TYPE_UNSIGNED (type) ? 'I' : 'i'; 8217 break; 8218 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break; 8219 default: abort (); 8220 } 8221 obstack_1grow (&util_obstack, c); 8222 } 8223 8224 else if (code == REAL_TYPE) 8225 { 8226 /* Floating point types. */ 8227 switch (GET_MODE_BITSIZE (TYPE_MODE (type))) 8228 { 8229 case 32: c = 'f'; break; 8230 case 64: 8231 case 96: 8232 case 128: c = 'd'; break; 8233 default: abort (); 8234 } 8235 obstack_1grow (&util_obstack, c); 8236 } 8237 8238 else if (code == VOID_TYPE) 8239 obstack_1grow (&util_obstack, 'v'); 8240 8241 else if (code == BOOLEAN_TYPE) 8242 obstack_1grow (&util_obstack, 'B'); 8243 8244 else if (code == ARRAY_TYPE) 8245 encode_array (type, curtype, format); 8246 8247 else if (code == POINTER_TYPE) 8248 encode_pointer (type, curtype, format); 8249 8250 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE) 8251 encode_aggregate (type, curtype, format); 8252 8253 else if (code == FUNCTION_TYPE) /* '?' */ 8254 obstack_1grow (&util_obstack, '?'); 8255 8256 else if (code == COMPLEX_TYPE) 8257 { 8258 obstack_1grow (&util_obstack, 'j'); 8259 encode_type (TREE_TYPE (type), curtype, format); 8260 } 8261 } 8262 8263 static void 8264 encode_gnu_bitfield (int position, tree type, int size) 8265 { 8266 enum tree_code code = TREE_CODE (type); 8267 char buffer[40]; 8268 char charType = '?'; 8269 8270 if (code == INTEGER_TYPE) 8271 { 8272 if (integer_zerop (TYPE_MIN_VALUE (type))) 8273 { 8274 /* Unsigned integer types. */ 8275 8276 if (TYPE_MODE (type) == QImode) 8277 charType = 'C'; 8278 else if (TYPE_MODE (type) == HImode) 8279 charType = 'S'; 8280 else if (TYPE_MODE (type) == SImode) 8281 { 8282 if (type == long_unsigned_type_node) 8283 charType = 'L'; 8284 else 8285 charType = 'I'; 8286 } 8287 else if (TYPE_MODE (type) == DImode) 8288 charType = 'Q'; 8289 } 8290 8291 else 8292 /* Signed integer types. */ 8293 { 8294 if (TYPE_MODE (type) == QImode) 8295 charType = 'c'; 8296 else if (TYPE_MODE (type) == HImode) 8297 charType = 's'; 8298 else if (TYPE_MODE (type) == SImode) 8299 { 8300 if (type == long_integer_type_node) 8301 charType = 'l'; 8302 else 8303 charType = 'i'; 8304 } 8305 8306 else if (TYPE_MODE (type) == DImode) 8307 charType = 'q'; 8308 } 8309 } 8310 else if (code == ENUMERAL_TYPE) 8311 charType = 'i'; 8312 else 8313 abort (); 8314 8315 sprintf (buffer, "b%d%c%d", position, charType, size); 8316 obstack_grow (&util_obstack, buffer, strlen (buffer)); 8317 } 8318 8319 static void 8320 encode_field_decl (tree field_decl, int curtype, int format) 8321 { 8322 #ifdef OBJCPLUS 8323 /* C++ static members, and things that are not fields at all, 8324 should not appear in the encoding. */ 8325 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl)) 8326 return; 8327 #endif 8328 8329 /* Generate the bitfield typing information, if needed. Note the difference 8330 between GNU and NeXT runtimes. */ 8331 if (DECL_BIT_FIELD_TYPE (field_decl)) 8332 { 8333 int size = tree_low_cst (DECL_SIZE (field_decl), 1); 8334 8335 if (flag_next_runtime) 8336 encode_next_bitfield (size); 8337 else 8338 encode_gnu_bitfield (int_bit_position (field_decl), 8339 DECL_BIT_FIELD_TYPE (field_decl), size); 8340 } 8341 else 8342 encode_type (TREE_TYPE (field_decl), curtype, format); 8343 } 8344 8345 static GTY(()) tree objc_parmlist = NULL_TREE; 8346 8347 /* Append PARM to a list of formal parameters of a method, making a necessary 8348 array-to-pointer adjustment along the way. */ 8349 8350 static void 8351 objc_push_parm (tree parm) 8352 { 8353 bool relayout_needed = false; 8354 8355 if (TREE_TYPE (parm) == error_mark_node) 8356 { 8357 objc_parmlist = chainon (objc_parmlist, parm); 8358 return; 8359 } 8360 8361 /* Decay arrays and functions into pointers. */ 8362 if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE) 8363 { 8364 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm))); 8365 relayout_needed = true; 8366 } 8367 else if (TREE_CODE (TREE_TYPE (parm)) == FUNCTION_TYPE) 8368 { 8369 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (parm)); 8370 relayout_needed = true; 8371 } 8372 8373 if (relayout_needed) 8374 relayout_decl (parm); 8375 8376 8377 DECL_ARG_TYPE (parm) 8378 = lang_hooks.types.type_promotes_to (TREE_TYPE (parm)); 8379 8380 /* Record constancy and volatility. */ 8381 c_apply_type_quals_to_decl 8382 ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0) 8383 | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0) 8384 | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm); 8385 8386 objc_parmlist = chainon (objc_parmlist, parm); 8387 } 8388 8389 /* Retrieve the formal parameter list constructed via preceding calls to 8390 objc_push_parm(). */ 8391 8392 #ifdef OBJCPLUS 8393 static tree 8394 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED) 8395 #else 8396 static struct c_arg_info * 8397 objc_get_parm_info (int have_ellipsis) 8398 #endif 8399 { 8400 #ifdef OBJCPLUS 8401 tree parm_info = objc_parmlist; 8402 objc_parmlist = NULL_TREE; 8403 8404 return parm_info; 8405 #else 8406 tree parm_info = objc_parmlist; 8407 struct c_arg_info *arg_info; 8408 /* The C front-end requires an elaborate song and dance at 8409 this point. */ 8410 push_scope (); 8411 declare_parm_level (); 8412 while (parm_info) 8413 { 8414 tree next = TREE_CHAIN (parm_info); 8415 8416 TREE_CHAIN (parm_info) = NULL_TREE; 8417 parm_info = pushdecl (parm_info); 8418 finish_decl (parm_info, input_location, NULL_TREE, NULL_TREE, NULL_TREE); 8419 parm_info = next; 8420 } 8421 arg_info = get_parm_info (have_ellipsis); 8422 pop_scope (); 8423 objc_parmlist = NULL_TREE; 8424 return arg_info; 8425 #endif 8426 } 8427 8428 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC 8429 method definitions. In the case of instance methods, we can be more 8430 specific as to the type of 'self'. */ 8431 8432 static void 8433 synth_self_and_ucmd_args (void) 8434 { 8435 tree self_type; 8436 8437 if (objc_method_context 8438 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL) 8439 self_type = objc_instance_type; 8440 else 8441 /* Really a `struct objc_class *'. However, we allow people to 8442 assign to self, which changes its type midstream. */ 8443 self_type = objc_object_type; 8444 8445 /* id self; */ 8446 objc_push_parm (build_decl (input_location, 8447 PARM_DECL, self_id, self_type)); 8448 8449 /* SEL _cmd; */ 8450 objc_push_parm (build_decl (input_location, 8451 PARM_DECL, ucmd_id, objc_selector_type)); 8452 } 8453 8454 /* Transform an Objective-C method definition into a static C function 8455 definition, synthesizing the first two arguments, "self" and "_cmd", 8456 in the process. */ 8457 8458 static void 8459 start_method_def (tree method) 8460 { 8461 tree parmlist; 8462 #ifdef OBJCPLUS 8463 tree parm_info; 8464 #else 8465 struct c_arg_info *parm_info; 8466 #endif 8467 int have_ellipsis = 0; 8468 8469 /* If we are defining a "dealloc" method in a non-root class, we 8470 will need to check if a [super dealloc] is missing, and warn if 8471 it is. */ 8472 if(CLASS_SUPER_NAME (objc_implementation_context) 8473 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method)))) 8474 should_call_super_dealloc = 1; 8475 else 8476 should_call_super_dealloc = 0; 8477 8478 /* Required to implement _msgSuper. */ 8479 objc_method_context = method; 8480 UOBJC_SUPER_decl = NULL_TREE; 8481 8482 /* Generate prototype declarations for arguments..."new-style". */ 8483 synth_self_and_ucmd_args (); 8484 8485 /* Generate argument declarations if a keyword_decl. */ 8486 parmlist = METHOD_SEL_ARGS (method); 8487 while (parmlist) 8488 { 8489 tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm; 8490 8491 parm = build_decl (input_location, 8492 PARM_DECL, KEYWORD_ARG_NAME (parmlist), type); 8493 objc_push_parm (parm); 8494 parmlist = TREE_CHAIN (parmlist); 8495 } 8496 8497 if (METHOD_ADD_ARGS (method)) 8498 { 8499 tree akey; 8500 8501 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method)); 8502 akey; akey = TREE_CHAIN (akey)) 8503 { 8504 objc_push_parm (TREE_VALUE (akey)); 8505 } 8506 8507 if (METHOD_ADD_ARGS_ELLIPSIS_P (method)) 8508 have_ellipsis = 1; 8509 } 8510 8511 parm_info = objc_get_parm_info (have_ellipsis); 8512 8513 really_start_method (objc_method_context, parm_info); 8514 } 8515 8516 /* Return 1 if TYPE1 is equivalent to TYPE2 8517 for purposes of method overloading. */ 8518 8519 static int 8520 objc_types_are_equivalent (tree type1, tree type2) 8521 { 8522 if (type1 == type2) 8523 return 1; 8524 8525 /* Strip away indirections. */ 8526 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE) 8527 && (TREE_CODE (type1) == TREE_CODE (type2))) 8528 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2); 8529 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2)) 8530 return 0; 8531 8532 type1 = (TYPE_HAS_OBJC_INFO (type1) 8533 ? TYPE_OBJC_PROTOCOL_LIST (type1) 8534 : NULL_TREE); 8535 type2 = (TYPE_HAS_OBJC_INFO (type2) 8536 ? TYPE_OBJC_PROTOCOL_LIST (type2) 8537 : NULL_TREE); 8538 8539 if (list_length (type1) == list_length (type2)) 8540 { 8541 for (; type2; type2 = TREE_CHAIN (type2)) 8542 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2))) 8543 return 0; 8544 return 1; 8545 } 8546 return 0; 8547 } 8548 8549 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */ 8550 8551 static int 8552 objc_types_share_size_and_alignment (tree type1, tree type2) 8553 { 8554 return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2)) 8555 && TYPE_ALIGN (type1) == TYPE_ALIGN (type2)); 8556 } 8557 8558 /* Return 1 if PROTO1 is equivalent to PROTO2 8559 for purposes of method overloading. Ordinarily, the type signatures 8560 should match up exactly, unless STRICT is zero, in which case we 8561 shall allow differences in which the size and alignment of a type 8562 is the same. */ 8563 8564 static int 8565 comp_proto_with_proto (tree proto1, tree proto2, int strict) 8566 { 8567 tree type1, type2; 8568 8569 /* The following test is needed in case there are hashing 8570 collisions. */ 8571 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2)) 8572 return 0; 8573 8574 /* Compare return types. */ 8575 type1 = TREE_VALUE (TREE_TYPE (proto1)); 8576 type2 = TREE_VALUE (TREE_TYPE (proto2)); 8577 8578 if (!objc_types_are_equivalent (type1, type2) 8579 && (strict || !objc_types_share_size_and_alignment (type1, type2))) 8580 return 0; 8581 8582 /* Compare argument types. */ 8583 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0), 8584 type2 = get_arg_type_list (proto2, METHOD_REF, 0); 8585 type1 && type2; 8586 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2)) 8587 { 8588 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2)) 8589 && (strict 8590 || !objc_types_share_size_and_alignment (TREE_VALUE (type1), 8591 TREE_VALUE (type2)))) 8592 return 0; 8593 } 8594 8595 return (!type1 && !type2); 8596 } 8597 8598 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where 8599 this occurs. ObjC method dispatches are _not_ like C++ virtual 8600 member function dispatches, and we account for the difference here. */ 8601 tree 8602 #ifdef OBJCPLUS 8603 objc_fold_obj_type_ref (tree ref, tree known_type) 8604 #else 8605 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED, 8606 tree known_type ATTRIBUTE_UNUSED) 8607 #endif 8608 { 8609 #ifdef OBJCPLUS 8610 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type)); 8611 8612 /* If the receiver does not have virtual member functions, there 8613 is nothing we can (or need to) do here. */ 8614 if (!v) 8615 return NULL_TREE; 8616 8617 /* Let C++ handle C++ virtual functions. */ 8618 return cp_fold_obj_type_ref (ref, known_type); 8619 #else 8620 /* For plain ObjC, we currently do not need to do anything. */ 8621 return NULL_TREE; 8622 #endif 8623 } 8624 8625 static void 8626 objc_start_function (tree name, tree type, tree attrs, 8627 #ifdef OBJCPLUS 8628 tree params 8629 #else 8630 struct c_arg_info *params 8631 #endif 8632 ) 8633 { 8634 tree fndecl = build_decl (input_location, 8635 FUNCTION_DECL, name, type); 8636 8637 #ifdef OBJCPLUS 8638 DECL_ARGUMENTS (fndecl) = params; 8639 DECL_INITIAL (fndecl) = error_mark_node; 8640 DECL_EXTERNAL (fndecl) = 0; 8641 TREE_STATIC (fndecl) = 1; 8642 retrofit_lang_decl (fndecl); 8643 cplus_decl_attributes (&fndecl, attrs, 0); 8644 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT); 8645 #else 8646 current_function_returns_value = 0; /* Assume, until we see it does. */ 8647 current_function_returns_null = 0; 8648 8649 decl_attributes (&fndecl, attrs, 0); 8650 announce_function (fndecl); 8651 DECL_INITIAL (fndecl) = error_mark_node; 8652 DECL_EXTERNAL (fndecl) = 0; 8653 TREE_STATIC (fndecl) = 1; 8654 current_function_decl = pushdecl (fndecl); 8655 push_scope (); 8656 declare_parm_level (); 8657 DECL_RESULT (current_function_decl) 8658 = build_decl (input_location, 8659 RESULT_DECL, NULL_TREE, 8660 TREE_TYPE (TREE_TYPE (current_function_decl))); 8661 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1; 8662 DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1; 8663 start_fname_decls (); 8664 store_parm_decls_from (params); 8665 #endif 8666 8667 TREE_USED (current_function_decl) = 1; 8668 } 8669 8670 /* - Generate an identifier for the function. the format is "_n_cls", 8671 where 1 <= n <= nMethods, and cls is the name the implementation we 8672 are processing. 8673 - Install the return type from the method declaration. 8674 - If we have a prototype, check for type consistency. */ 8675 8676 static void 8677 really_start_method (tree method, 8678 #ifdef OBJCPLUS 8679 tree parmlist 8680 #else 8681 struct c_arg_info *parmlist 8682 #endif 8683 ) 8684 { 8685 tree ret_type, meth_type; 8686 tree method_id; 8687 const char *sel_name, *class_name, *cat_name; 8688 char *buf; 8689 8690 /* Synth the storage class & assemble the return type. */ 8691 ret_type = TREE_VALUE (TREE_TYPE (method)); 8692 8693 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method)); 8694 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)); 8695 cat_name = ((TREE_CODE (objc_implementation_context) 8696 == CLASS_IMPLEMENTATION_TYPE) 8697 ? NULL 8698 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context))); 8699 method_slot++; 8700 8701 /* Make sure this is big enough for any plausible method label. */ 8702 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name) 8703 + (cat_name ? strlen (cat_name) : 0)); 8704 8705 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL, 8706 class_name, cat_name, sel_name, method_slot); 8707 8708 method_id = get_identifier (buf); 8709 8710 #ifdef OBJCPLUS 8711 /* Objective-C methods cannot be overloaded, so we don't need 8712 the type encoding appended. It looks bad anyway... */ 8713 push_lang_context (lang_name_c); 8714 #endif 8715 8716 meth_type 8717 = build_function_type (ret_type, 8718 get_arg_type_list (method, METHOD_DEF, 0)); 8719 objc_start_function (method_id, meth_type, NULL_TREE, parmlist); 8720 8721 /* Set self_decl from the first argument. */ 8722 self_decl = DECL_ARGUMENTS (current_function_decl); 8723 8724 /* Suppress unused warnings. */ 8725 TREE_USED (self_decl) = 1; 8726 TREE_USED (TREE_CHAIN (self_decl)) = 1; 8727 #ifdef OBJCPLUS 8728 pop_lang_context (); 8729 #endif 8730 8731 METHOD_DEFINITION (method) = current_function_decl; 8732 8733 /* Check consistency...start_function, pushdecl, duplicate_decls. */ 8734 8735 if (implementation_template != objc_implementation_context) 8736 { 8737 tree proto 8738 = lookup_method_static (implementation_template, 8739 METHOD_SEL_NAME (method), 8740 ((TREE_CODE (method) == CLASS_METHOD_DECL) 8741 | OBJC_LOOKUP_NO_SUPER)); 8742 8743 if (proto) 8744 { 8745 if (!comp_proto_with_proto (method, proto, 1)) 8746 { 8747 bool type = TREE_CODE (method) == INSTANCE_METHOD_DECL; 8748 8749 warning_at (DECL_SOURCE_LOCATION (method), 0, 8750 "conflicting types for %<%c%s%>", 8751 (type ? '-' : '+'), 8752 identifier_to_locale (gen_method_decl (method))); 8753 inform (DECL_SOURCE_LOCATION (proto), 8754 "previous declaration of %<%c%s%>", 8755 (type ? '-' : '+'), 8756 identifier_to_locale (gen_method_decl (proto))); 8757 } 8758 } 8759 else 8760 { 8761 /* We have a method @implementation even though we did not 8762 see a corresponding @interface declaration (which is allowed 8763 by Objective-C rules). Go ahead and place the method in 8764 the @interface anyway, so that message dispatch lookups 8765 will see it. */ 8766 tree interface = implementation_template; 8767 8768 if (TREE_CODE (objc_implementation_context) 8769 == CATEGORY_IMPLEMENTATION_TYPE) 8770 interface = lookup_category 8771 (interface, 8772 CLASS_SUPER_NAME (objc_implementation_context)); 8773 8774 if (interface) 8775 objc_add_method (interface, copy_node (method), 8776 TREE_CODE (method) == CLASS_METHOD_DECL); 8777 } 8778 } 8779 } 8780 8781 static void *UOBJC_SUPER_scope = 0; 8782 8783 /* _n_Method (id self, SEL sel, ...) 8784 { 8785 struct objc_super _S; 8786 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...); 8787 } */ 8788 8789 static tree 8790 get_super_receiver (void) 8791 { 8792 if (objc_method_context) 8793 { 8794 tree super_expr, super_expr_list; 8795 8796 if (!UOBJC_SUPER_decl) 8797 { 8798 UOBJC_SUPER_decl = build_decl (input_location, 8799 VAR_DECL, get_identifier (TAG_SUPER), 8800 objc_super_template); 8801 /* This prevents `unused variable' warnings when compiling with -Wall. */ 8802 TREE_USED (UOBJC_SUPER_decl) = 1; 8803 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl); 8804 finish_decl (UOBJC_SUPER_decl, input_location, NULL_TREE, NULL_TREE, 8805 NULL_TREE); 8806 UOBJC_SUPER_scope = objc_get_current_scope (); 8807 } 8808 8809 /* Set receiver to self. */ 8810 super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id); 8811 super_expr = build_modify_expr (input_location, super_expr, NULL_TREE, 8812 NOP_EXPR, input_location, self_decl, 8813 NULL_TREE); 8814 super_expr_list = super_expr; 8815 8816 /* Set class to begin searching. */ 8817 super_expr = objc_build_component_ref (UOBJC_SUPER_decl, 8818 get_identifier ("super_class")); 8819 8820 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE) 8821 { 8822 /* [_cls, __cls]Super are "pre-built" in 8823 synth_forward_declarations. */ 8824 8825 super_expr = build_modify_expr (input_location, super_expr, 8826 NULL_TREE, NOP_EXPR, 8827 input_location, 8828 ((TREE_CODE (objc_method_context) 8829 == INSTANCE_METHOD_DECL) 8830 ? ucls_super_ref 8831 : uucls_super_ref), 8832 NULL_TREE); 8833 } 8834 8835 else 8836 /* We have a category. */ 8837 { 8838 tree super_name = CLASS_SUPER_NAME (implementation_template); 8839 tree super_class; 8840 8841 /* Barf if super used in a category of Object. */ 8842 if (!super_name) 8843 { 8844 error ("no super class declared in interface for %qE", 8845 CLASS_NAME (implementation_template)); 8846 return error_mark_node; 8847 } 8848 8849 if (flag_next_runtime && !flag_zero_link) 8850 { 8851 super_class = objc_get_class_reference (super_name); 8852 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL) 8853 /* If we are in a class method, we must retrieve the 8854 _metaclass_ for the current class, pointed at by 8855 the class's "isa" pointer. The following assumes that 8856 "isa" is the first ivar in a class (which it must be). */ 8857 super_class 8858 = build_indirect_ref 8859 (input_location, 8860 build_c_cast (input_location, 8861 build_pointer_type (objc_class_type), 8862 super_class), RO_UNARY_STAR); 8863 } 8864 else 8865 { 8866 add_class_reference (super_name); 8867 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL 8868 ? objc_get_class_decl : objc_get_meta_class_decl); 8869 assemble_external (super_class); 8870 super_class 8871 = build_function_call 8872 (input_location, 8873 super_class, 8874 build_tree_list 8875 (NULL_TREE, 8876 my_build_string_pointer 8877 (IDENTIFIER_LENGTH (super_name) + 1, 8878 IDENTIFIER_POINTER (super_name)))); 8879 } 8880 8881 super_expr 8882 = build_modify_expr (input_location, super_expr, NULL_TREE, 8883 NOP_EXPR, 8884 input_location, 8885 build_c_cast (input_location, 8886 TREE_TYPE (super_expr), 8887 super_class), 8888 NULL_TREE); 8889 } 8890 8891 super_expr_list = build_compound_expr (input_location, 8892 super_expr_list, super_expr); 8893 8894 super_expr = build_unary_op (input_location, 8895 ADDR_EXPR, UOBJC_SUPER_decl, 0); 8896 super_expr_list = build_compound_expr (input_location, 8897 super_expr_list, super_expr); 8898 8899 return super_expr_list; 8900 } 8901 else 8902 { 8903 error ("[super ...] must appear in a method context"); 8904 return error_mark_node; 8905 } 8906 } 8907 8908 /* When exiting a scope, sever links to a 'super' declaration (if any) 8909 therein contained. */ 8910 8911 void 8912 objc_clear_super_receiver (void) 8913 { 8914 if (objc_method_context 8915 && UOBJC_SUPER_scope == objc_get_current_scope ()) { 8916 UOBJC_SUPER_decl = 0; 8917 UOBJC_SUPER_scope = 0; 8918 } 8919 } 8920 8921 void 8922 objc_finish_method_definition (tree fndecl) 8923 { 8924 /* We cannot validly inline ObjC methods, at least not without a language 8925 extension to declare that a method need not be dynamically 8926 dispatched, so suppress all thoughts of doing so. */ 8927 DECL_UNINLINABLE (fndecl) = 1; 8928 8929 #ifndef OBJCPLUS 8930 /* The C++ front-end will have called finish_function() for us. */ 8931 finish_function (); 8932 #endif 8933 8934 METHOD_ENCODING (objc_method_context) 8935 = encode_method_prototype (objc_method_context); 8936 8937 /* Required to implement _msgSuper. This must be done AFTER finish_function, 8938 since the optimizer may find "may be used before set" errors. */ 8939 objc_method_context = NULL_TREE; 8940 8941 if (should_call_super_dealloc) 8942 warning (0, "method possibly missing a [super dealloc] call"); 8943 } 8944 8945 /* Given a tree DECL node, produce a printable description of it in the given 8946 buffer, overwriting the buffer. */ 8947 8948 static char * 8949 gen_declaration (tree decl) 8950 { 8951 errbuf[0] = '\0'; 8952 8953 if (DECL_P (decl)) 8954 { 8955 gen_type_name_0 (TREE_TYPE (decl)); 8956 8957 if (DECL_NAME (decl)) 8958 { 8959 if (!POINTER_TYPE_P (TREE_TYPE (decl))) 8960 strcat (errbuf, " "); 8961 8962 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl))); 8963 } 8964 8965 if (DECL_INITIAL (decl) 8966 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST) 8967 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC, 8968 TREE_INT_CST_LOW (DECL_INITIAL (decl))); 8969 } 8970 8971 return errbuf; 8972 } 8973 8974 /* Given a tree TYPE node, produce a printable description of it in the given 8975 buffer, overwriting the buffer. */ 8976 8977 static char * 8978 gen_type_name_0 (tree type) 8979 { 8980 tree orig = type, proto; 8981 8982 if (TYPE_P (type) && TYPE_NAME (type)) 8983 type = TYPE_NAME (type); 8984 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE) 8985 { 8986 tree inner = TREE_TYPE (type); 8987 8988 while (TREE_CODE (inner) == ARRAY_TYPE) 8989 inner = TREE_TYPE (inner); 8990 8991 gen_type_name_0 (inner); 8992 8993 if (!POINTER_TYPE_P (inner)) 8994 strcat (errbuf, " "); 8995 8996 if (POINTER_TYPE_P (type)) 8997 strcat (errbuf, "*"); 8998 else 8999 while (type != inner) 9000 { 9001 strcat (errbuf, "["); 9002 9003 if (TYPE_DOMAIN (type)) 9004 { 9005 char sz[20]; 9006 9007 sprintf (sz, HOST_WIDE_INT_PRINT_DEC, 9008 (TREE_INT_CST_LOW 9009 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1)); 9010 strcat (errbuf, sz); 9011 } 9012 9013 strcat (errbuf, "]"); 9014 type = TREE_TYPE (type); 9015 } 9016 9017 goto exit_function; 9018 } 9019 9020 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type)) 9021 type = DECL_NAME (type); 9022 9023 strcat (errbuf, TREE_CODE (type) == IDENTIFIER_NODE 9024 ? IDENTIFIER_POINTER (type) 9025 : ""); 9026 9027 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */ 9028 if (objc_is_id (orig)) 9029 orig = TREE_TYPE (orig); 9030 9031 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE; 9032 9033 if (proto) 9034 { 9035 strcat (errbuf, " <"); 9036 9037 while (proto) { 9038 strcat (errbuf, 9039 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto)))); 9040 proto = TREE_CHAIN (proto); 9041 strcat (errbuf, proto ? ", " : ">"); 9042 } 9043 } 9044 9045 exit_function: 9046 return errbuf; 9047 } 9048 9049 static char * 9050 gen_type_name (tree type) 9051 { 9052 errbuf[0] = '\0'; 9053 9054 return gen_type_name_0 (type); 9055 } 9056 9057 /* Given a method tree, put a printable description into the given 9058 buffer (overwriting) and return a pointer to the buffer. */ 9059 9060 static char * 9061 gen_method_decl (tree method) 9062 { 9063 tree chain; 9064 9065 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */ 9066 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method))); 9067 strcat (errbuf, ")"); 9068 chain = METHOD_SEL_ARGS (method); 9069 9070 if (chain) 9071 { 9072 /* We have a chain of keyword_decls. */ 9073 do 9074 { 9075 if (KEYWORD_KEY_NAME (chain)) 9076 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain))); 9077 9078 strcat (errbuf, ":("); 9079 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain))); 9080 strcat (errbuf, ")"); 9081 9082 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain))); 9083 if ((chain = TREE_CHAIN (chain))) 9084 strcat (errbuf, " "); 9085 } 9086 while (chain); 9087 9088 if (METHOD_ADD_ARGS (method)) 9089 { 9090 chain = TREE_CHAIN (METHOD_ADD_ARGS (method)); 9091 9092 /* Know we have a chain of parm_decls. */ 9093 while (chain) 9094 { 9095 strcat (errbuf, ", "); 9096 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain))); 9097 chain = TREE_CHAIN (chain); 9098 } 9099 9100 if (METHOD_ADD_ARGS_ELLIPSIS_P (method)) 9101 strcat (errbuf, ", ..."); 9102 } 9103 } 9104 9105 else 9106 /* We have a unary selector. */ 9107 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method))); 9108 9109 return errbuf; 9110 } 9111 9112 /* Debug info. */ 9113 9114 9115 /* Dump an @interface declaration of the supplied class CHAIN to the 9116 supplied file FP. Used to implement the -gen-decls option (which 9117 prints out an @interface declaration of all classes compiled in 9118 this run); potentially useful for debugging the compiler too. */ 9119 static void 9120 dump_interface (FILE *fp, tree chain) 9121 { 9122 /* FIXME: A heap overflow here whenever a method (or ivar) 9123 declaration is so long that it doesn't fit in the buffer. The 9124 code and all the related functions should be rewritten to avoid 9125 using fixed size buffers. */ 9126 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain)); 9127 tree ivar_decls = CLASS_RAW_IVARS (chain); 9128 tree nst_methods = CLASS_NST_METHODS (chain); 9129 tree cls_methods = CLASS_CLS_METHODS (chain); 9130 9131 fprintf (fp, "\n@interface %s", my_name); 9132 9133 /* CLASS_SUPER_NAME is used to store the superclass name for 9134 classes, and the category name for categories. */ 9135 if (CLASS_SUPER_NAME (chain)) 9136 { 9137 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain)); 9138 9139 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE 9140 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE) 9141 { 9142 fprintf (fp, " (%s)\n", name); 9143 } 9144 else 9145 { 9146 fprintf (fp, " : %s\n", name); 9147 } 9148 } 9149 else 9150 fprintf (fp, "\n"); 9151 9152 /* FIXME - the following doesn't seem to work at the moment. */ 9153 if (ivar_decls) 9154 { 9155 fprintf (fp, "{\n"); 9156 do 9157 { 9158 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls)); 9159 ivar_decls = TREE_CHAIN (ivar_decls); 9160 } 9161 while (ivar_decls); 9162 fprintf (fp, "}\n"); 9163 } 9164 9165 while (nst_methods) 9166 { 9167 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods)); 9168 nst_methods = TREE_CHAIN (nst_methods); 9169 } 9170 9171 while (cls_methods) 9172 { 9173 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods)); 9174 cls_methods = TREE_CHAIN (cls_methods); 9175 } 9176 9177 fprintf (fp, "@end\n"); 9178 } 9179 9180 /* Demangle function for Objective-C */ 9181 static const char * 9182 objc_demangle (const char *mangled) 9183 { 9184 char *demangled, *cp; 9185 9186 if (mangled[0] == '_' && 9187 (mangled[1] == 'i' || mangled[1] == 'c') && 9188 mangled[2] == '_') 9189 { 9190 cp = demangled = XNEWVEC (char, strlen(mangled) + 2); 9191 if (mangled[1] == 'i') 9192 *cp++ = '-'; /* for instance method */ 9193 else 9194 *cp++ = '+'; /* for class method */ 9195 *cp++ = '['; /* opening left brace */ 9196 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */ 9197 while (*cp && *cp == '_') 9198 cp++; /* skip any initial underbars in class name */ 9199 cp = strchr(cp, '_'); /* find first non-initial underbar */ 9200 if (cp == NULL) 9201 { 9202 free(demangled); /* not mangled name */ 9203 return mangled; 9204 } 9205 if (cp[1] == '_') /* easy case: no category name */ 9206 { 9207 *cp++ = ' '; /* replace two '_' with one ' ' */ 9208 strcpy(cp, mangled + (cp - demangled) + 2); 9209 } 9210 else 9211 { 9212 *cp++ = '('; /* less easy case: category name */ 9213 cp = strchr(cp, '_'); 9214 if (cp == 0) 9215 { 9216 free(demangled); /* not mangled name */ 9217 return mangled; 9218 } 9219 *cp++ = ')'; 9220 *cp++ = ' '; /* overwriting 1st char of method name... */ 9221 strcpy(cp, mangled + (cp - demangled)); /* get it back */ 9222 } 9223 while (*cp && *cp == '_') 9224 cp++; /* skip any initial underbars in method name */ 9225 for (; *cp; cp++) 9226 if (*cp == '_') 9227 *cp = ':'; /* replace remaining '_' with ':' */ 9228 *cp++ = ']'; /* closing right brace */ 9229 *cp++ = 0; /* string terminator */ 9230 return demangled; 9231 } 9232 else 9233 return mangled; /* not an objc mangled name */ 9234 } 9235 9236 const char * 9237 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED) 9238 { 9239 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl))); 9240 } 9241 9242 static void 9243 init_objc (void) 9244 { 9245 gcc_obstack_init (&util_obstack); 9246 util_firstobj = (char *) obstack_finish (&util_obstack); 9247 9248 errbuf = XNEWVEC (char, 1024 * 10); 9249 hash_init (); 9250 synth_module_prologue (); 9251 } 9252 9253 static void 9254 finish_objc (void) 9255 { 9256 struct imp_entry *impent; 9257 tree chain; 9258 /* The internally generated initializers appear to have missing braces. 9259 Don't warn about this. */ 9260 int save_warn_missing_braces = warn_missing_braces; 9261 warn_missing_braces = 0; 9262 9263 /* A missing @end may not be detected by the parser. */ 9264 if (objc_implementation_context) 9265 { 9266 warning (0, "%<@end%> missing in implementation context"); 9267 finish_class (objc_implementation_context); 9268 objc_ivar_chain = NULL_TREE; 9269 objc_implementation_context = NULL_TREE; 9270 } 9271 9272 /* Process the static instances here because initialization of objc_symtab 9273 depends on them. */ 9274 if (objc_static_instances) 9275 generate_static_references (); 9276 9277 if (imp_list || class_names_chain 9278 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain) 9279 generate_objc_symtab_decl (); 9280 9281 for (impent = imp_list; impent; impent = impent->next) 9282 { 9283 objc_implementation_context = impent->imp_context; 9284 implementation_template = impent->imp_template; 9285 9286 UOBJC_CLASS_decl = impent->class_decl; 9287 UOBJC_METACLASS_decl = impent->meta_decl; 9288 9289 /* Dump the @interface of each class as we compile it, if the 9290 -gen-decls option is in use. TODO: Dump the classes in the 9291 order they were found, rather than in reverse order as we 9292 are doing now. */ 9293 if (flag_gen_declaration) 9294 { 9295 dump_interface (gen_declaration_file, objc_implementation_context); 9296 } 9297 9298 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE) 9299 { 9300 /* all of the following reference the string pool... */ 9301 generate_ivar_lists (); 9302 generate_dispatch_tables (); 9303 generate_shared_structures (impent->has_cxx_cdtors 9304 ? CLS_HAS_CXX_STRUCTORS 9305 : 0); 9306 } 9307 else 9308 { 9309 generate_dispatch_tables (); 9310 generate_category (objc_implementation_context); 9311 } 9312 } 9313 9314 /* If we are using an array of selectors, we must always 9315 finish up the array decl even if no selectors were used. */ 9316 if (! flag_next_runtime || sel_ref_chain) 9317 build_selector_translation_table (); 9318 9319 if (protocol_chain) 9320 generate_protocols (); 9321 9322 if ((flag_replace_objc_classes && imp_list) || flag_objc_gc) 9323 generate_objc_image_info (); 9324 9325 /* Arrange for ObjC data structures to be initialized at run time. */ 9326 if (objc_implementation_context || class_names_chain || objc_static_instances 9327 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain) 9328 { 9329 build_module_descriptor (); 9330 9331 if (!flag_next_runtime) 9332 build_module_initializer_routine (); 9333 } 9334 9335 /* Dump the class references. This forces the appropriate classes 9336 to be linked into the executable image, preserving unix archive 9337 semantics. This can be removed when we move to a more dynamically 9338 linked environment. */ 9339 9340 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain)) 9341 { 9342 handle_class_ref (chain); 9343 if (TREE_PURPOSE (chain)) 9344 generate_classref_translation_entry (chain); 9345 } 9346 9347 for (impent = imp_list; impent; impent = impent->next) 9348 handle_impent (impent); 9349 9350 if (warn_selector) 9351 { 9352 int slot; 9353 hash hsh; 9354 9355 /* Run through the selector hash tables and print a warning for any 9356 selector which has multiple methods. */ 9357 9358 for (slot = 0; slot < SIZEHASHTABLE; slot++) 9359 { 9360 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next) 9361 check_duplicates (hsh, 0, 1); 9362 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next) 9363 check_duplicates (hsh, 0, 1); 9364 } 9365 } 9366 9367 warn_missing_braces = save_warn_missing_braces; 9368 } 9369 9370 /* Subroutines of finish_objc. */ 9371 9372 static void 9373 generate_classref_translation_entry (tree chain) 9374 { 9375 tree expr, decl, type; 9376 9377 decl = TREE_PURPOSE (chain); 9378 type = TREE_TYPE (decl); 9379 9380 expr = add_objc_string (TREE_VALUE (chain), class_names); 9381 expr = convert (type, expr); /* cast! */ 9382 9383 /* The decl that is the one that we 9384 forward declared in build_class_reference. */ 9385 finish_var_decl (decl, expr); 9386 return; 9387 } 9388 9389 static void 9390 handle_class_ref (tree chain) 9391 { 9392 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain)); 9393 char *string = (char *) alloca (strlen (name) + 30); 9394 tree decl; 9395 tree exp; 9396 9397 sprintf (string, "%sobjc_class_name_%s", 9398 (flag_next_runtime ? "." : "__"), name); 9399 9400 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE 9401 if (flag_next_runtime) 9402 { 9403 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string); 9404 return; 9405 } 9406 #endif 9407 9408 /* Make a decl for this name, so we can use its address in a tree. */ 9409 decl = build_decl (input_location, 9410 VAR_DECL, get_identifier (string), char_type_node); 9411 DECL_EXTERNAL (decl) = 1; 9412 TREE_PUBLIC (decl) = 1; 9413 9414 pushdecl (decl); 9415 rest_of_decl_compilation (decl, 0, 0); 9416 9417 /* Make a decl for the address. */ 9418 sprintf (string, "%sobjc_class_ref_%s", 9419 (flag_next_runtime ? "." : "__"), name); 9420 exp = build1 (ADDR_EXPR, string_type_node, decl); 9421 decl = build_decl (input_location, 9422 VAR_DECL, get_identifier (string), string_type_node); 9423 DECL_INITIAL (decl) = exp; 9424 TREE_STATIC (decl) = 1; 9425 TREE_USED (decl) = 1; 9426 /* Force the output of the decl as this forces the reference of the class. */ 9427 mark_decl_referenced (decl); 9428 9429 pushdecl (decl); 9430 rest_of_decl_compilation (decl, 0, 0); 9431 } 9432 9433 static void 9434 handle_impent (struct imp_entry *impent) 9435 { 9436 char *string; 9437 9438 objc_implementation_context = impent->imp_context; 9439 implementation_template = impent->imp_template; 9440 9441 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE) 9442 { 9443 const char *const class_name = 9444 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)); 9445 9446 string = (char *) alloca (strlen (class_name) + 30); 9447 9448 sprintf (string, "%sobjc_class_name_%s", 9449 (flag_next_runtime ? "." : "__"), class_name); 9450 } 9451 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE) 9452 { 9453 const char *const class_name = 9454 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)); 9455 const char *const class_super_name = 9456 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context)); 9457 9458 string = (char *) alloca (strlen (class_name) 9459 + strlen (class_super_name) + 30); 9460 9461 /* Do the same for categories. Even though no references to 9462 these symbols are generated automatically by the compiler, it 9463 gives you a handle to pull them into an archive by hand. */ 9464 sprintf (string, "*%sobjc_category_name_%s_%s", 9465 (flag_next_runtime ? "." : "__"), class_name, class_super_name); 9466 } 9467 else 9468 return; 9469 9470 #ifdef ASM_DECLARE_CLASS_REFERENCE 9471 if (flag_next_runtime) 9472 { 9473 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string); 9474 return; 9475 } 9476 else 9477 #endif 9478 { 9479 tree decl, init; 9480 9481 init = build_int_cst (c_common_type_for_size (BITS_PER_WORD, 1), 0); 9482 decl = build_decl (input_location, 9483 VAR_DECL, get_identifier (string), TREE_TYPE (init)); 9484 TREE_PUBLIC (decl) = 1; 9485 TREE_READONLY (decl) = 1; 9486 TREE_USED (decl) = 1; 9487 TREE_CONSTANT (decl) = 1; 9488 DECL_CONTEXT (decl) = 0; 9489 DECL_ARTIFICIAL (decl) = 1; 9490 DECL_INITIAL (decl) = init; 9491 assemble_variable (decl, 1, 0, 0); 9492 } 9493 } 9494 9495 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and 9496 later requires that ObjC translation units participating in F&C be 9497 specially marked. The following routine accomplishes this. */ 9498 9499 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */ 9500 9501 static void 9502 generate_objc_image_info (void) 9503 { 9504 tree decl, initlist; 9505 int flags 9506 = ((flag_replace_objc_classes && imp_list ? 1 : 0) 9507 | (flag_objc_gc ? 2 : 0)); 9508 9509 decl = start_var_decl (build_array_type 9510 (integer_type_node, 9511 build_index_type (build_int_cst (NULL_TREE, 2 - 1))), 9512 "_OBJC_IMAGE_INFO"); 9513 9514 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0)); 9515 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), initlist); 9516 initlist = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)); 9517 9518 finish_var_decl (decl, initlist); 9519 } 9520 9521 /* Look up ID as an instance variable. OTHER contains the result of 9522 the C or C++ lookup, which we may want to use instead. */ 9523 9524 tree 9525 objc_lookup_ivar (tree other, tree id) 9526 { 9527 tree ivar; 9528 9529 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */ 9530 if (!objc_method_context) 9531 return other; 9532 9533 if (!strcmp (IDENTIFIER_POINTER (id), "super")) 9534 /* We have a message to super. */ 9535 return get_super_receiver (); 9536 9537 /* In a class method, look up an instance variable only as a last 9538 resort. */ 9539 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL 9540 && other && other != error_mark_node) 9541 return other; 9542 9543 /* Look up the ivar, but do not use it if it is not accessible. */ 9544 ivar = is_ivar (objc_ivar_chain, id); 9545 9546 if (!ivar || is_private (ivar)) 9547 return other; 9548 9549 /* In an instance method, a local variable (or parameter) may hide the 9550 instance variable. */ 9551 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL 9552 && other && other != error_mark_node 9553 #ifdef OBJCPLUS 9554 && CP_DECL_CONTEXT (other) != global_namespace) 9555 #else 9556 && !DECL_FILE_SCOPE_P (other)) 9557 #endif 9558 { 9559 warning (0, "local declaration of %qE hides instance variable", 9560 id); 9561 9562 return other; 9563 } 9564 9565 /* At this point, we are either in an instance method with no obscuring 9566 local definitions, or in a class method with no alternate definitions 9567 at all. */ 9568 return build_ivar_reference (id); 9569 } 9570 9571 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This 9572 needs to be done if we are calling a function through a cast. */ 9573 9574 tree 9575 objc_rewrite_function_call (tree function, tree first_param) 9576 { 9577 if (TREE_CODE (function) == NOP_EXPR 9578 && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR 9579 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0)) 9580 == FUNCTION_DECL) 9581 { 9582 function = build3 (OBJ_TYPE_REF, TREE_TYPE (function), 9583 TREE_OPERAND (function, 0), 9584 first_param, size_zero_node); 9585 } 9586 9587 return function; 9588 } 9589 9590 /* Look for the special case of OBJC_TYPE_REF with the address of 9591 a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one 9592 of its cousins). */ 9593 9594 int 9595 objc_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) 9596 { 9597 enum gimplify_status r0, r1; 9598 if (TREE_CODE (*expr_p) == OBJ_TYPE_REF 9599 && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR 9600 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0)) 9601 == FUNCTION_DECL) 9602 { 9603 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the 9604 value of the OBJ_TYPE_REF, so force them to be emitted 9605 during subexpression evaluation rather than after the 9606 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective 9607 C to use direct rather than indirect calls when the 9608 object expression has a postincrement. */ 9609 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL, 9610 is_gimple_val, fb_rvalue); 9611 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p, 9612 is_gimple_val, fb_rvalue); 9613 9614 return MIN (r0, r1); 9615 } 9616 9617 #ifdef OBJCPLUS 9618 return (enum gimplify_status) cp_gimplify_expr (expr_p, pre_p, post_p); 9619 #else 9620 return (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p); 9621 #endif 9622 } 9623 9624 #include "gt-objc-objc-act.h" 9625