1 /* GNU Runtime ABI version 8 2 Copyright (C) 2011-2017 Free Software Foundation, Inc. 3 Contributed by Iain Sandoe (split from objc-act.c) 4 5 This file is part of GCC. 6 7 GCC is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3, or (at your option) 10 any later version. 11 12 GCC is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GCC; see the file COPYING3. If not see 19 <http://www.gnu.org/licenses/>. */ 20 21 #include "config.h" 22 #include "system.h" 23 #include "coretypes.h" 24 #include "options.h" 25 #include "stringpool.h" 26 27 #ifdef OBJCPLUS 28 #include "cp/cp-tree.h" 29 #else 30 #include "c/c-tree.h" 31 #include "c/c-lang.h" 32 #endif 33 34 #include "langhooks.h" 35 #include "c-family/c-objc.h" 36 #include "objc-act.h" 37 38 /* When building Objective-C++, we are not linking against the C front-end 39 and so need to replicate the C tree-construction functions in some way. */ 40 #ifdef OBJCPLUS 41 #define OBJCP_REMAP_FUNCTIONS 42 #include "objcp-decl.h" 43 #endif /* OBJCPLUS */ 44 45 #include "toplev.h" 46 #include "tree-iterator.h" 47 48 #include "objc-runtime-hooks.h" 49 #include "objc-runtime-shared-support.h" 50 #include "objc-encoding.h" 51 52 /* GNU runtime private definitions. */ 53 #define DEF_CONSTANT_STRING_CLASS_NAME "NXConstantString" 54 55 #define TAG_GETCLASS "objc_get_class" 56 #define TAG_GETMETACLASS "objc_get_meta_class" 57 58 #define TAG_MSGSEND "objc_msg_lookup" 59 #define TAG_MSGSENDSUPER "objc_msg_lookup_super" 60 61 /* GNU-specific tags. */ 62 63 #define TAG_EXECCLASS "__objc_exec_class" 64 #define TAG_GNUINIT "__objc_gnu_init" 65 66 /* The version identifies which language generation and runtime 67 the module (file) was compiled for, and is recorded in the 68 module descriptor. */ 69 #define OBJC_VERSION 8 70 71 #define PROTOCOL_VERSION 2 72 73 /* This macro provides a method of removing ambiguity between runtimes 74 when LTO is in use on targets supporting multiple runtimes. 75 76 For example, at present, any target that includes an implementation of 77 the NeXT runtime needs to place Objective-C meta-data into specific 78 named sections. This should _not_ be done for the GNU runtime, and the 79 following macro is used to attach Objective-C private attributes that may 80 be used to identify the runtime for which the meta-data are intended. */ 81 82 #define OBJCMETA(DECL,VERS,KIND) \ 83 if (VERS) \ 84 DECL_ATTRIBUTES (DECL) = build_tree_list ((VERS), (KIND)); 85 86 static void gnu_runtime_01_initialize (void); 87 88 static void build_selector_template (void); 89 90 static tree gnu_runtime_abi_01_super_superclassfield_id (void); 91 92 static tree gnu_runtime_abi_01_class_decl (tree); 93 static tree gnu_runtime_abi_01_metaclass_decl (tree); 94 static tree gnu_runtime_abi_01_category_decl (tree); 95 static tree gnu_runtime_abi_01_protocol_decl (tree); 96 static tree gnu_runtime_abi_01_string_decl (tree, const char *, string_section); 97 98 static tree gnu_runtime_abi_01_get_class_reference (tree); 99 static tree gnu_runtime_abi_01_build_typed_selector_reference (location_t, tree, 100 tree); 101 static tree gnu_runtime_abi_01_get_protocol_reference (location_t, tree); 102 static tree gnu_runtime_abi_01_build_ivar_ref (location_t, tree, tree); 103 static tree gnu_runtime_abi_01_get_class_super_ref (location_t, struct imp_entry *, bool); 104 static tree gnu_runtime_abi_01_get_category_super_ref (location_t, struct imp_entry *, bool); 105 106 static tree gnu_runtime_abi_01_receiver_is_class_object (tree); 107 static void gnu_runtime_abi_01_get_arg_type_list_base (vec<tree, va_gc> **, 108 tree, int, int); 109 static tree gnu_runtime_abi_01_build_objc_method_call (location_t, tree, tree, 110 tree, tree, tree, int); 111 112 static bool gnu_runtime_abi_01_setup_const_string_class_decl (void); 113 static tree gnu_runtime_abi_01_build_const_string_constructor (location_t, tree,int); 114 115 static void objc_generate_v1_gnu_metadata (void); 116 117 static tree objc_eh_runtime_type (tree type); 118 static tree objc_eh_personality (void); 119 static tree objc_build_exc_ptr (struct objc_try_context **); 120 static tree build_throw_stmt (location_t, tree, bool); 121 static tree begin_catch (struct objc_try_context **, tree, tree, tree, bool); 122 static void finish_catch (struct objc_try_context **, tree); 123 static tree finish_try_stmt (struct objc_try_context **); 124 125 bool 126 objc_gnu_runtime_abi_01_init (objc_runtime_hooks *rthooks) 127 { 128 /* GNU runtime does not need the compiler to change code in order to do GC. */ 129 if (flag_objc_gc) 130 { 131 warning_at (0, 0, "%<-fobjc-gc%> is ignored for %<-fgnu-runtime%>"); 132 flag_objc_gc = 0; 133 } 134 135 /* Although I guess we could, we don't currently support SJLJ exceptions for the 136 GNU runtime. */ 137 if (flag_objc_sjlj_exceptions) 138 { 139 inform (UNKNOWN_LOCATION, "%<-fobjc-sjlj-exceptions%> is ignored for %<-fgnu-runtime%>"); 140 flag_objc_sjlj_exceptions = 0; 141 } 142 143 /* TODO: Complain if -fobjc-abi-version=N was used. */ 144 145 /* TODO: Complain if -fobj-nilcheck was used. */ 146 147 rthooks->initialize = gnu_runtime_01_initialize; 148 rthooks->default_constant_string_class_name = DEF_CONSTANT_STRING_CLASS_NAME; 149 rthooks->tag_getclass = TAG_GETCLASS; 150 rthooks->super_superclassfield_ident = gnu_runtime_abi_01_super_superclassfield_id; 151 152 rthooks->class_decl = gnu_runtime_abi_01_class_decl; 153 rthooks->metaclass_decl = gnu_runtime_abi_01_metaclass_decl; 154 rthooks->category_decl = gnu_runtime_abi_01_category_decl; 155 rthooks->protocol_decl = gnu_runtime_abi_01_protocol_decl; 156 rthooks->string_decl = gnu_runtime_abi_01_string_decl; 157 158 rthooks->get_class_reference = gnu_runtime_abi_01_get_class_reference; 159 rthooks->build_selector_reference = gnu_runtime_abi_01_build_typed_selector_reference; 160 rthooks->get_protocol_reference = gnu_runtime_abi_01_get_protocol_reference; 161 rthooks->build_ivar_reference = gnu_runtime_abi_01_build_ivar_ref; 162 rthooks->get_class_super_ref = gnu_runtime_abi_01_get_class_super_ref; 163 rthooks->get_category_super_ref = gnu_runtime_abi_01_get_category_super_ref; 164 165 rthooks->receiver_is_class_object = gnu_runtime_abi_01_receiver_is_class_object; 166 rthooks->get_arg_type_list_base = gnu_runtime_abi_01_get_arg_type_list_base; 167 rthooks->build_objc_method_call = gnu_runtime_abi_01_build_objc_method_call; 168 169 rthooks->setup_const_string_class_decl = 170 gnu_runtime_abi_01_setup_const_string_class_decl; 171 rthooks->build_const_string_constructor = 172 gnu_runtime_abi_01_build_const_string_constructor; 173 174 rthooks->build_throw_stmt = build_throw_stmt; 175 rthooks->build_exc_ptr = objc_build_exc_ptr; 176 rthooks->begin_catch = begin_catch; 177 rthooks->finish_catch = finish_catch; 178 rthooks->finish_try_stmt = finish_try_stmt; 179 180 rthooks->generate_metadata = objc_generate_v1_gnu_metadata; 181 return true; 182 } 183 184 static void build_selector_table_decl (void); 185 static void build_class_template (void); 186 static void build_category_template (void); 187 static void build_protocol_template (void); 188 189 static GTY(()) tree objc_meta; 190 static GTY(()) tree meta_base; 191 192 static void gnu_runtime_01_initialize (void) 193 { 194 tree type, ftype, IMP_type; 195 196 /* We do not need to mark GNU ObjC metadata for different sections, 197 however, we do need to make sure that it is not mistaken for NeXT 198 metadata. */ 199 objc_meta = get_identifier ("OBJC1METG"); 200 meta_base = get_identifier ("NONE"); 201 202 /* Declare type of selector-objects that represent an operation name. */ 203 /* `const struct objc_selector *' */ 204 type = xref_tag (RECORD_TYPE, get_identifier (TAG_SELECTOR)); 205 type = build_qualified_type (type, TYPE_QUAL_CONST); 206 objc_selector_type = build_pointer_type (type); 207 208 /* typedef id (*IMP)(id, SEL, ...); */ 209 ftype = build_varargs_function_type_list (objc_object_type, 210 objc_object_type, 211 objc_selector_type, 212 NULL_TREE); 213 214 IMP_type = build_pointer_type (ftype); 215 216 build_class_template (); 217 build_super_template (); 218 build_protocol_template (); 219 build_category_template (); 220 221 /* GNU runtime messenger entry points. */ 222 /* TREE_NOTHROW is cleared for the message-sending functions, 223 because the function that gets called can throw in Obj-C++, or 224 could itself call something that can throw even in Obj-C. */ 225 226 /* IMP objc_msg_lookup (id, SEL); */ 227 type = build_function_type_list (IMP_type, 228 objc_object_type, 229 objc_selector_type, 230 NULL_TREE); 231 232 umsg_decl = add_builtin_function (TAG_MSGSEND, 233 type, 0, NOT_BUILT_IN, 234 NULL, NULL_TREE); 235 TREE_NOTHROW (umsg_decl) = 0; 236 237 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */ 238 type = build_function_type_list (IMP_type, 239 objc_super_type, 240 objc_selector_type, 241 NULL_TREE); 242 243 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER, 244 type, 0, NOT_BUILT_IN, 245 NULL, NULL_TREE); 246 TREE_NOTHROW (umsg_super_decl) = 0; 247 248 /* The following GNU runtime entry point is called to initialize 249 each module: 250 251 __objc_exec_class (void *); */ 252 type = build_function_type_list (void_type_node, 253 ptr_type_node, 254 NULL_TREE); 255 256 execclass_decl = add_builtin_function (TAG_EXECCLASS, 257 type, 0, NOT_BUILT_IN, 258 NULL, NULL_TREE); 259 260 type = build_function_type_list (objc_object_type, 261 const_string_type_node, 262 NULL_TREE); 263 264 /* id objc_getClass (const char *); */ 265 objc_get_class_decl 266 = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN, 267 NULL, NULL_TREE); 268 269 /* id objc_getMetaClass (const char *); */ 270 objc_get_meta_class_decl = add_builtin_function (TAG_GETMETACLASS, type, 271 0, NOT_BUILT_IN, NULL, 272 NULL_TREE); 273 274 /* static SEL _OBJC_SELECTOR_TABLE[]; */ 275 build_selector_table_decl (); 276 277 /* Stuff for properties. 278 The codegen relies on this being NULL for GNU. */ 279 objc_copyStruct_decl = NULL_TREE; 280 281 /* This is the type of all of the following functions 282 bjc_getPropertyStruct() and objc_setPropertyStruct(). */ 283 type = build_function_type_list (void_type_node, 284 ptr_type_node, 285 const_ptr_type_node, 286 ptrdiff_type_node, 287 boolean_type_node, 288 boolean_type_node, 289 NULL_TREE); 290 291 /* Declare the following function: 292 void 293 objc_getPropertyStruct (void *destination, const void *source, 294 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */ 295 objc_getPropertyStruct_decl = add_builtin_function ("objc_getPropertyStruct", 296 type, 0, NOT_BUILT_IN, 297 NULL, NULL_TREE); 298 TREE_NOTHROW (objc_getPropertyStruct_decl) = 0; 299 /* Declare the following function: 300 void 301 objc_setPropertyStruct (void *destination, const void *source, 302 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */ 303 objc_setPropertyStruct_decl = add_builtin_function ("objc_setPropertyStruct", 304 type, 0, NOT_BUILT_IN, 305 NULL, NULL_TREE); 306 TREE_NOTHROW (objc_setPropertyStruct_decl) = 0; 307 308 using_eh_for_cleanups (); 309 lang_hooks.eh_runtime_type = objc_eh_runtime_type; 310 lang_hooks.eh_personality = objc_eh_personality; 311 } 312 313 /* --- templates --- */ 314 /* struct _objc_selector { 315 SEL sel_id; 316 char *sel_type; 317 }; */ 318 319 static void 320 build_selector_template (void) 321 { 322 tree decls, *chain = NULL; 323 324 objc_selector_template = objc_start_struct (get_identifier (UTAG_SELECTOR)); 325 326 /* SEL sel_id; */ 327 decls = add_field_decl (objc_selector_type, "sel_id", &chain); 328 329 /* char *sel_type; */ 330 add_field_decl (string_type_node, "sel_type", &chain); 331 332 objc_finish_struct (objc_selector_template, decls); 333 } 334 335 /* struct _objc_class { 336 struct _objc_class *isa; 337 struct _objc_class *super_class; 338 char *name; 339 long version; 340 long info; 341 long instance_size; 342 struct _objc_ivar_list *ivars; 343 struct _objc_method_list *methods; 344 struct sarray *dtable; 345 struct _objc_class *subclass_list; 346 struct _objc_class *sibling_class; 347 struct _objc_protocol_list *protocols; 348 void *gc_object_type; 349 }; */ 350 351 static void 352 build_class_template (void) 353 { 354 tree ptype, decls, *chain = NULL; 355 356 objc_class_template = objc_start_struct (get_identifier (UTAG_CLASS)); 357 358 /* struct _objc_class *isa; */ 359 decls = add_field_decl (build_pointer_type (objc_class_template), 360 "isa", &chain); 361 362 /* struct _objc_class *super_class; */ 363 add_field_decl (build_pointer_type (objc_class_template), 364 "super_class", &chain); 365 366 /* char *name; */ 367 add_field_decl (string_type_node, "name", &chain); 368 369 /* long version; */ 370 add_field_decl (long_integer_type_node, "version", &chain); 371 372 /* long info; */ 373 add_field_decl (long_integer_type_node, "info", &chain); 374 375 /* long instance_size; */ 376 add_field_decl (long_integer_type_node, "instance_size", &chain); 377 378 /* struct _objc_ivar_list *ivars; */ 379 add_field_decl (objc_ivar_list_ptr,"ivars", &chain); 380 381 /* struct _objc_method_list *methods; */ 382 add_field_decl (objc_method_list_ptr, "methods", &chain); 383 384 /* struct sarray *dtable; */ 385 ptype = build_pointer_type(xref_tag (RECORD_TYPE, 386 get_identifier ("sarray"))); 387 add_field_decl (ptype, "dtable", &chain); 388 389 /* struct objc_class *subclass_list; */ 390 ptype = build_pointer_type (objc_class_template); 391 add_field_decl (ptype, "subclass_list", &chain); 392 393 /* struct objc_class *sibling_class; */ 394 ptype = build_pointer_type (objc_class_template); 395 add_field_decl (ptype, "sibling_class", &chain); 396 397 /* struct _objc_protocol **protocol_list; */ 398 ptype = build_pointer_type (build_pointer_type 399 (xref_tag (RECORD_TYPE, 400 get_identifier (UTAG_PROTOCOL)))); 401 add_field_decl (ptype, "protocol_list", &chain); 402 403 /* void *gc_object_type; */ 404 add_field_decl (build_pointer_type (void_type_node), 405 "gc_object_type", &chain); 406 407 objc_finish_struct (objc_class_template, decls); 408 } 409 410 /* struct _objc_category { 411 char *category_name; 412 char *class_name; 413 struct _objc_method_list *instance_methods; 414 struct _objc_method_list *class_methods; 415 struct _objc_protocol_list *protocols; 416 }; */ 417 418 static void 419 build_category_template (void) 420 { 421 tree ptype, decls, *chain = NULL; 422 423 objc_category_template = objc_start_struct (get_identifier (UTAG_CATEGORY)); 424 425 /* char *category_name; */ 426 decls = add_field_decl (string_type_node, "category_name", &chain); 427 428 /* char *class_name; */ 429 add_field_decl (string_type_node, "class_name", &chain); 430 431 /* struct _objc_method_list *instance_methods; */ 432 add_field_decl (objc_method_list_ptr, "instance_methods", &chain); 433 434 /* struct _objc_method_list *class_methods; */ 435 add_field_decl (objc_method_list_ptr, "class_methods", &chain); 436 437 /* struct _objc_protocol **protocol_list; */ 438 ptype = build_pointer_type (build_pointer_type (objc_protocol_template)); 439 add_field_decl (ptype, "protocol_list", &chain); 440 441 objc_finish_struct (objc_category_template, decls); 442 } 443 444 /* struct _objc_protocol { 445 struct _objc_class *isa; 446 char *protocol_name; 447 struct _objc_protocol **protocol_list; 448 struct _objc__method_prototype_list *instance_methods; 449 struct _objc__method_prototype_list *class_methods; 450 }; */ 451 452 static void 453 build_protocol_template (void) 454 { 455 tree ptype, decls, *chain = NULL; 456 457 objc_protocol_template = objc_start_struct (get_identifier (UTAG_PROTOCOL)); 458 459 /* struct _objc_class *isa; */ 460 ptype = build_pointer_type (xref_tag (RECORD_TYPE, 461 get_identifier (UTAG_CLASS))); 462 decls = add_field_decl (ptype, "isa", &chain); 463 464 /* char *protocol_name; */ 465 add_field_decl (string_type_node, "protocol_name", &chain); 466 467 /* struct _objc_protocol **protocol_list; */ 468 ptype = build_pointer_type (build_pointer_type (objc_protocol_template)); 469 add_field_decl (ptype, "protocol_list", &chain); 470 471 /* struct _objc__method_prototype_list *instance_methods; */ 472 add_field_decl (objc_method_proto_list_ptr, "instance_methods", &chain); 473 474 /* struct _objc__method_prototype_list *class_methods; */ 475 add_field_decl (objc_method_proto_list_ptr, "class_methods", &chain); 476 477 objc_finish_struct (objc_protocol_template, decls); 478 } 479 480 /* --- names, decls + identifiers --- */ 481 482 static void 483 build_selector_table_decl (void) 484 { 485 tree temp; 486 487 build_selector_template (); 488 temp = build_array_type (objc_selector_template, NULL_TREE); 489 490 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE"); 491 /* Squash `defined but not used' warning check_global_declaration. */ 492 TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1; 493 OBJCMETA (UOBJC_SELECTOR_TABLE_decl, objc_meta, meta_base); 494 } 495 496 497 static tree 498 gnu_runtime_abi_01_super_superclassfield_id (void) 499 { 500 if (!super_superclassfield_id) 501 super_superclassfield_id = get_identifier ("super_class"); 502 return super_superclassfield_id; 503 } 504 505 506 static tree 507 gnu_runtime_abi_01_class_decl (tree klass) 508 { 509 tree decl; 510 char buf[BUFSIZE]; 511 snprintf (buf, BUFSIZE, "_OBJC_Class_%s", 512 IDENTIFIER_POINTER (CLASS_NAME (klass))); 513 decl = start_var_decl (objc_class_template, buf); 514 OBJCMETA (decl, objc_meta, meta_base); 515 return decl; 516 } 517 518 static tree 519 gnu_runtime_abi_01_metaclass_decl (tree klass) 520 { 521 tree decl; 522 char buf[BUFSIZE]; 523 snprintf (buf, BUFSIZE, "_OBJC_MetaClass_%s", 524 IDENTIFIER_POINTER (CLASS_NAME (klass))); 525 decl = start_var_decl (objc_class_template, buf); 526 OBJCMETA (decl, objc_meta, meta_base); 527 return decl; 528 } 529 530 static tree 531 gnu_runtime_abi_01_category_decl (tree klass) 532 { 533 tree decl; 534 char buf[BUFSIZE]; 535 snprintf (buf, BUFSIZE, "_OBJC_Category_%s_on_%s", 536 IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass)), 537 IDENTIFIER_POINTER (CLASS_NAME (klass))); 538 decl = start_var_decl (objc_category_template, buf); 539 OBJCMETA (decl, objc_meta, meta_base); 540 return decl; 541 } 542 543 static tree 544 gnu_runtime_abi_01_protocol_decl (tree p) 545 { 546 tree decl; 547 char buf[BUFSIZE]; 548 549 /* static struct _objc_protocol _OBJC_Protocol_<mumble>; */ 550 snprintf (buf, BUFSIZE, "_OBJC_Protocol_%s", 551 IDENTIFIER_POINTER (PROTOCOL_NAME (p))); 552 decl = start_var_decl (objc_protocol_template, buf); 553 OBJCMETA (decl, objc_meta, meta_base); 554 return decl; 555 } 556 557 static tree 558 gnu_runtime_abi_01_string_decl (tree type, const char *name, 559 string_section where ATTRIBUTE_UNUSED) 560 { 561 tree decl = start_var_decl (type, name); 562 OBJCMETA (decl, objc_meta, meta_base); 563 return decl; 564 } 565 566 /* --- entry --- */ 567 568 static tree 569 gnu_runtime_abi_01_get_class_reference (tree ident) 570 { 571 tree params; 572 573 add_class_reference (ident); 574 575 params = build_tree_list (NULL_TREE, my_build_string_pointer 576 (IDENTIFIER_LENGTH (ident) + 1, 577 IDENTIFIER_POINTER (ident))); 578 579 return build_function_call (input_location, objc_get_class_decl, params); 580 } 581 582 /* Used by build_function_type_for_method. Append the types for 583 receiver & _cmd at the start of a method argument list to ARGTYPES. 584 CONTEXT is either METHOD_DEF or METHOD_REF, saying whether we are 585 trying to define a method or call one. SUPERFLAG says this is for a 586 send to super. METH may be NULL, in the case that there is no 587 prototype. */ 588 589 static void 590 gnu_runtime_abi_01_get_arg_type_list_base (vec<tree, va_gc> **argtypes, 591 tree meth, int context, 592 int superflag ATTRIBUTE_UNUSED) 593 { 594 tree receiver_type; 595 596 if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL) 597 receiver_type = objc_instance_type; 598 else 599 receiver_type = objc_object_type; 600 601 vec_safe_push (*argtypes, receiver_type); 602 /* Selector type - will eventually change to `int'. */ 603 vec_safe_push (*argtypes, objc_selector_type); 604 } 605 606 /* Unused for GNU runtime. */ 607 static tree 608 gnu_runtime_abi_01_receiver_is_class_object (tree a ATTRIBUTE_UNUSED) 609 { 610 return NULL_TREE; 611 } 612 613 /* sel_ref_chain is a list whose "value" fields will be instances of 614 identifier_node that represent the selector. LOC is the location of 615 the @selector. */ 616 617 static tree 618 gnu_runtime_abi_01_build_typed_selector_reference (location_t loc, tree ident, 619 tree prototype) 620 { 621 tree *chain = &sel_ref_chain; 622 tree expr; 623 int index = 0; 624 625 while (*chain) 626 { 627 /* When we do a lookup for @selector () we have no idea of the 628 prototype - so match the first we find. */ 629 if (TREE_VALUE (*chain) == ident 630 && (!prototype || TREE_PURPOSE (*chain) == prototype)) 631 goto return_at_index; 632 633 index++; 634 chain = &TREE_CHAIN (*chain); 635 } 636 637 *chain = tree_cons (prototype, ident, NULL_TREE); 638 639 /* TODO: Use a vec and keep this in it to (a) avoid re-creating and 640 (b) provide better diagnostics for the first time an undefined 641 selector is used. */ 642 return_at_index: 643 expr = build_unary_op (loc, ADDR_EXPR, 644 build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl, 645 build_int_cst (NULL_TREE, index)), 646 1); 647 return convert (objc_selector_type, expr); 648 } 649 650 /* Build a tree expression to send OBJECT the operation SELECTOR, 651 looking up the method on object LOOKUP_OBJECT (often same as OBJECT), 652 assuming the method has prototype METHOD_PROTOTYPE. 653 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.) 654 LOC is the location of the expression to build. 655 Use METHOD_PARAMS as list of args to pass to the method. 656 If SUPER_FLAG is nonzero, we look up the superclass's method. */ 657 658 static tree 659 build_objc_method_call (location_t loc, int super_flag, tree method_prototype, 660 tree lookup_object, tree selector, 661 tree method_params) 662 { 663 tree sender = (super_flag ? umsg_super_decl 664 : (flag_objc_direct_dispatch ? umsg_fast_decl 665 : umsg_decl)); 666 tree rcv_p = (super_flag ? objc_super_type : objc_object_type); 667 vec<tree, va_gc> *parms; 668 vec<tree, va_gc> *tv; 669 unsigned nparm = (method_params ? list_length (method_params) : 0); 670 671 /* If a prototype for the method to be called exists, then cast 672 the sender's return type and arguments to match that of the method. 673 Otherwise, leave sender as is. */ 674 tree ret_type 675 = (method_prototype 676 ? TREE_VALUE (TREE_TYPE (method_prototype)) 677 : objc_object_type); 678 tree ftype 679 = build_function_type_for_method (ret_type, method_prototype, 680 METHOD_REF, super_flag); 681 tree sender_cast; 682 tree method, t; 683 684 if (method_prototype && METHOD_TYPE_ATTRIBUTES (method_prototype)) 685 ftype = build_type_attribute_variant (ftype, 686 METHOD_TYPE_ATTRIBUTES 687 (method_prototype)); 688 689 sender_cast = build_pointer_type (ftype); 690 691 lookup_object = build_c_cast (loc, rcv_p, lookup_object); 692 693 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */ 694 lookup_object = save_expr (lookup_object); 695 696 /* Param list + 2 slots for object and selector. */ 697 vec_alloc (parms, nparm + 2); 698 vec_alloc (tv, 2); 699 700 /* First, call the lookup function to get a pointer to the method, 701 then cast the pointer, then call it with the method arguments. */ 702 tv->quick_push (lookup_object); 703 tv->quick_push (selector); 704 method = build_function_call_vec (loc, vNULL, sender, tv, NULL); 705 vec_free (tv); 706 707 /* Pass the appropriate object to the method. */ 708 parms->quick_push ((super_flag ? self_decl : lookup_object)); 709 710 /* Pass the selector to the method. */ 711 parms->quick_push (selector); 712 /* Now append the remainder of the parms. */ 713 if (nparm) 714 for (; method_params; method_params = TREE_CHAIN (method_params)) 715 parms->quick_push (TREE_VALUE (method_params)); 716 717 /* Build an obj_type_ref, with the correct cast for the method call. */ 718 t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node); 719 t = build_function_call_vec (loc, vNULL, t, parms, NULL); 720 vec_free (parms); 721 return t; 722 } 723 724 static tree 725 gnu_runtime_abi_01_build_objc_method_call (location_t loc, 726 tree method_prototype, 727 tree receiver, 728 tree rtype ATTRIBUTE_UNUSED, 729 tree sel_name, 730 tree method_params, 731 int super ATTRIBUTE_UNUSED) 732 { 733 tree selector = 734 gnu_runtime_abi_01_build_typed_selector_reference (loc, 735 sel_name, 736 method_prototype); 737 738 return build_objc_method_call (loc, super, method_prototype, receiver, 739 selector, method_params); 740 } 741 742 static tree 743 gnu_runtime_abi_01_get_protocol_reference (location_t loc, tree p) 744 { 745 tree expr, protocol_struct_type, *chain; 746 if (!PROTOCOL_FORWARD_DECL (p)) 747 PROTOCOL_FORWARD_DECL (p) = gnu_runtime_abi_01_protocol_decl (p); 748 749 expr = build_unary_op (loc, ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0); 750 751 /* ??? Ideally we'd build the reference with objc_protocol_type directly, 752 if we have it, rather than converting it here. */ 753 expr = convert (objc_protocol_type, expr); 754 755 /* The @protocol() expression is being compiled into a pointer to a 756 statically allocated instance of the Protocol class. To become 757 usable at runtime, the 'isa' pointer of the instance need to be 758 fixed up at runtime by the runtime library, to point to the 759 actual 'Protocol' class. */ 760 761 /* For the GNU runtime, put the static Protocol instance in the list 762 of statically allocated instances, so that we make sure that its 763 'isa' pointer is fixed up at runtime by the GNU runtime library 764 to point to the Protocol class (at runtime, when loading the 765 module, the GNU runtime library loops on the statically allocated 766 instances (as found in the defs field in objc_symtab) and fixups 767 all the 'isa' pointers of those objects). */ 768 769 /* This type is a struct containing the fields of a Protocol 770 object. (Cfr. objc_protocol_type instead is the type of a pointer 771 to such a struct). */ 772 protocol_struct_type = xref_tag (RECORD_TYPE, 773 get_identifier (PROTOCOL_OBJECT_CLASS_NAME)); 774 775 /* Look for the list of Protocol statically allocated instances 776 to fixup at runtime. Create a new list to hold Protocol 777 statically allocated instances, if the list is not found. At 778 present there is only another list, holding NSConstantString 779 static instances to be fixed up at runtime. */ 780 781 for (chain = &objc_static_instances; 782 *chain && TREE_VALUE (*chain) != protocol_struct_type; 783 chain = &TREE_CHAIN (*chain)); 784 785 if (!*chain) 786 { 787 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE); 788 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type), 789 class_names); 790 } 791 792 /* Add this statically allocated instance to the Protocol list. */ 793 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, 794 PROTOCOL_FORWARD_DECL (p), 795 TREE_PURPOSE (*chain)); 796 return expr; 797 } 798 799 /* For ABI 8 an IVAR is just a fixed offset in the class struct. */ 800 801 static tree 802 gnu_runtime_abi_01_build_ivar_ref (location_t loc ATTRIBUTE_UNUSED, 803 tree base, tree id) 804 { 805 return objc_build_component_ref (base, id); 806 } 807 808 /* We build super class references as we need them (but keep them once 809 built for the sake of efficiency). */ 810 811 static tree 812 gnu_runtime_abi_01_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED, 813 struct imp_entry *imp, bool inst_meth) 814 { 815 if (inst_meth) 816 { 817 if (!ucls_super_ref) 818 ucls_super_ref = 819 objc_build_component_ref (imp->class_decl, 820 get_identifier ("super_class")); 821 return ucls_super_ref; 822 } 823 else 824 { 825 if (!uucls_super_ref) 826 uucls_super_ref = 827 objc_build_component_ref (imp->meta_decl, 828 get_identifier ("super_class")); 829 return uucls_super_ref; 830 } 831 } 832 833 static tree 834 gnu_runtime_abi_01_get_category_super_ref (location_t loc ATTRIBUTE_UNUSED, 835 struct imp_entry *imp, bool inst_meth) 836 { 837 tree super_name = CLASS_SUPER_NAME (imp->imp_template); 838 tree super_class; 839 840 add_class_reference (super_name); 841 super_class = (inst_meth ? objc_get_class_decl : objc_get_meta_class_decl); 842 super_name = my_build_string_pointer (IDENTIFIER_LENGTH (super_name) + 1, 843 IDENTIFIER_POINTER (super_name)); 844 /* super_class = get_{meta_}class("CLASS_SUPER_NAME"); */ 845 return build_function_call (input_location, 846 super_class, 847 build_tree_list (NULL_TREE, super_name)); 848 } 849 850 static bool 851 gnu_runtime_abi_01_setup_const_string_class_decl (void) 852 { 853 /* Do nothing, and create no error. */ 854 return true; 855 } 856 857 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */ 858 859 static GTY(()) int num_static_inst; 860 861 static tree 862 objc_add_static_instance (tree constructor, tree class_decl) 863 { 864 tree *chain, decl; 865 char buf[BUFSIZE]; 866 867 /* Find the list of static instances for the CLASS_DECL. Create one if 868 not found. */ 869 for (chain = &objc_static_instances; 870 *chain && TREE_VALUE (*chain) != class_decl; 871 chain = &TREE_CHAIN (*chain)); 872 if (!*chain) 873 { 874 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE); 875 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names); 876 } 877 878 snprintf (buf, BUFSIZE, "_OBJC_INSTANCE_%d", num_static_inst++); 879 decl = build_decl (input_location, 880 VAR_DECL, get_identifier (buf), class_decl); 881 TREE_STATIC (decl) = 1; 882 DECL_ARTIFICIAL (decl) = 1; 883 TREE_USED (decl) = 1; 884 DECL_INITIAL (decl) = constructor; 885 DECL_CONTEXT (decl) = NULL; 886 OBJCMETA (decl, objc_meta, meta_base); 887 888 /* We may be writing something else just now. 889 Postpone till end of input. */ 890 DECL_DEFER_OUTPUT (decl) = 1; 891 pushdecl_top_level (decl); 892 rest_of_decl_compilation (decl, 1, 0); 893 894 /* Add the DECL to the head of this CLASS' list. */ 895 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain)); 896 897 return decl; 898 } 899 900 static tree 901 gnu_runtime_abi_01_build_const_string_constructor (location_t loc, tree string, 902 int length) 903 { 904 tree constructor, fields; 905 vec<constructor_elt, va_gc> *v = NULL; 906 907 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */ 908 fields = TYPE_FIELDS (internal_const_str_type); 909 CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, 0)); 910 911 fields = DECL_CHAIN (fields); 912 CONSTRUCTOR_APPEND_ELT (v, fields, build_unary_op (loc, 913 ADDR_EXPR, string, 1)); 914 915 fields = DECL_CHAIN (fields); 916 CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, length)); 917 constructor = objc_build_constructor (internal_const_str_type, v); 918 919 constructor = objc_add_static_instance (constructor, constant_string_type); 920 return constructor; 921 } 922 923 /* --- metadata - module initializer --- */ 924 925 /* The GNU runtime requires us to provide a static initializer function 926 for each module: 927 928 static void __objc_gnu_init (void) { 929 __objc_exec_class (&L_OBJC_MODULES); 930 } */ 931 932 933 static void 934 build_module_initializer_routine (void) 935 { 936 tree body; 937 938 #ifdef OBJCPLUS 939 push_lang_context (lang_name_c); /* extern "C" */ 940 #endif 941 942 objc_push_parm (build_decl (input_location, 943 PARM_DECL, NULL_TREE, void_type_node)); 944 #ifdef OBJCPLUS 945 objc_start_function (get_identifier (TAG_GNUINIT), 946 build_function_type_list (void_type_node, NULL_TREE), 947 NULL_TREE, NULL_TREE); 948 #else 949 objc_start_function (get_identifier (TAG_GNUINIT), 950 build_function_type_list (void_type_node, NULL_TREE), 951 NULL_TREE, objc_get_parm_info (0, NULL_TREE)); 952 #endif 953 body = c_begin_compound_stmt (true); 954 add_stmt (build_function_call 955 (input_location, 956 execclass_decl, 957 build_tree_list 958 (NULL_TREE, 959 build_unary_op (input_location, ADDR_EXPR, 960 UOBJC_MODULES_decl, 0)))); 961 add_stmt (c_end_compound_stmt (input_location, body, true)); 962 963 TREE_PUBLIC (current_function_decl) = 0; 964 965 #ifndef OBJCPLUS 966 /* For Objective-C++, we will need to call __objc_gnu_init 967 from objc_generate_static_init_call() below. */ 968 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1; 969 #endif 970 971 GNU_INIT_decl = current_function_decl; 972 finish_function (); 973 974 #ifdef OBJCPLUS 975 pop_lang_context (); 976 #endif 977 } 978 979 #ifdef OBJCPLUS 980 /* Return 1 if the __objc_gnu_init function has been synthesized and needs 981 to be called by the module initializer routine. */ 982 983 int 984 objc_static_init_needed_p (void) 985 { 986 return (GNU_INIT_decl != NULL_TREE); 987 } 988 989 /* Generate a call to the __objc_gnu_init initializer function. */ 990 991 tree 992 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED) 993 { 994 add_stmt (build_stmt (input_location, EXPR_STMT, 995 build_function_call (input_location, 996 GNU_INIT_decl, NULL_TREE))); 997 998 return ctors; 999 } 1000 #endif /* OBJCPLUS */ 1001 1002 /* --- Output GNU Meta-data --- */ 1003 1004 static void 1005 generate_classref_translation_entry (tree chain) 1006 { 1007 tree expr, decl, type; 1008 1009 decl = TREE_PURPOSE (chain); 1010 type = TREE_TYPE (decl); 1011 1012 expr = add_objc_string (TREE_VALUE (chain), class_names); 1013 expr = convert (type, expr); /* cast! */ 1014 1015 /* This is a class reference. It is re-written by the runtime, 1016 but will be optimized away unless we force it. */ 1017 DECL_PRESERVE_P (decl) = 1; 1018 OBJCMETA (decl, objc_meta, meta_base); 1019 finish_var_decl (decl, expr); 1020 return; 1021 } 1022 1023 1024 static void 1025 handle_impent (struct imp_entry *impent) 1026 { 1027 char *string; 1028 1029 /* objc_implementation_context = impent->imp_context; 1030 implementation_template = impent->imp_template;*/ 1031 1032 switch (TREE_CODE (impent->imp_context)) 1033 { 1034 case CLASS_IMPLEMENTATION_TYPE: 1035 { 1036 const char *const class_name = 1037 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)); 1038 1039 string = (char *) alloca (strlen (class_name) + 30); 1040 1041 sprintf (string, "__objc_class_name_%s", class_name); 1042 break; 1043 } 1044 case CATEGORY_IMPLEMENTATION_TYPE: 1045 { 1046 const char *const class_name = 1047 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)); 1048 const char *const class_super_name = 1049 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context)); 1050 1051 string = (char *) alloca (strlen (class_name) 1052 + strlen (class_super_name) + 30); 1053 1054 /* Do the same for categories. Even though no references to 1055 these symbols are generated automatically by the compiler, 1056 it gives you a handle to pull them into an archive by 1057 hand. */ 1058 sprintf (string, "*__objc_category_name_%s_%s", class_name, class_super_name); 1059 break; 1060 } 1061 default: 1062 return; 1063 } 1064 1065 { 1066 tree decl, init; 1067 1068 init = integer_zero_node; 1069 decl = build_decl (input_location, 1070 VAR_DECL, get_identifier (string), TREE_TYPE (init)); 1071 TREE_PUBLIC (decl) = 1; 1072 TREE_READONLY (decl) = 1; 1073 TREE_USED (decl) = 1; 1074 TREE_CONSTANT (decl) = 1; 1075 DECL_CONTEXT (decl) = NULL_TREE; 1076 DECL_ARTIFICIAL (decl) = 1; 1077 TREE_STATIC (decl) = 1; 1078 DECL_INITIAL (decl) = error_mark_node; /* A real initializer is coming... */ 1079 /* We must force the reference. */ 1080 DECL_PRESERVE_P (decl) = 1; 1081 1082 finish_var_decl(decl, init) ; 1083 } 1084 } 1085 1086 tree 1087 build_protocol_initializer (tree type, tree protocol_name, tree protocol_list, 1088 tree inst_methods, tree class_methods) 1089 { 1090 tree expr, ttyp; 1091 location_t loc; 1092 vec<constructor_elt, va_gc> *inits = NULL; 1093 1094 /* TODO: pass the loc in or find it from args. */ 1095 loc = input_location; 1096 ttyp = build_pointer_type (xref_tag (RECORD_TYPE, 1097 get_identifier (UTAG_CLASS))); 1098 /* Filling the "isa" in with a version allows the runtime system to 1099 detect this ... */ 1100 expr = build_int_cst (ttyp, PROTOCOL_VERSION); 1101 1102 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr); 1103 1104 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_name); 1105 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_list); 1106 1107 ttyp = objc_method_proto_list_ptr; 1108 if (inst_methods) 1109 expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0)); 1110 else 1111 expr = convert (ttyp, null_pointer_node); 1112 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr); 1113 1114 if (class_methods) 1115 expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0)); 1116 else 1117 expr = convert (ttyp, null_pointer_node); 1118 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr); 1119 1120 return objc_build_constructor (type, inits); 1121 } 1122 1123 static tree 1124 generate_protocol_list (tree i_or_p, tree klass_ctxt) 1125 { 1126 tree array_type, ptype, refs_decl, lproto, e, plist; 1127 vec<constructor_elt, va_gc> *v = NULL; 1128 char buf[BUFSIZE]; 1129 int size = 0; 1130 1131 switch (TREE_CODE (i_or_p)) 1132 { 1133 case CLASS_INTERFACE_TYPE: 1134 case CATEGORY_INTERFACE_TYPE: 1135 plist = CLASS_PROTOCOL_LIST (i_or_p); 1136 break; 1137 case PROTOCOL_INTERFACE_TYPE: 1138 plist = PROTOCOL_LIST (i_or_p); 1139 break; 1140 default: 1141 gcc_unreachable (); 1142 } 1143 1144 /* Compute size. */ 1145 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) 1146 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE 1147 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto))) 1148 size++; 1149 1150 /* Build initializer. */ 1151 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0)); 1152 e = build_int_cst (build_pointer_type (objc_protocol_template), size); 1153 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e); 1154 1155 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) 1156 { 1157 tree pval = TREE_VALUE (lproto); 1158 1159 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE 1160 && PROTOCOL_FORWARD_DECL (pval)) 1161 { 1162 tree fwref = PROTOCOL_FORWARD_DECL (pval); 1163 location_t loc = DECL_SOURCE_LOCATION (fwref) ; 1164 e = build_unary_op (loc, ADDR_EXPR, fwref, 0); 1165 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e); 1166 } 1167 } 1168 1169 /* static struct objc_protocol *refs[n]; */ 1170 1171 switch (TREE_CODE (i_or_p)) 1172 { 1173 case PROTOCOL_INTERFACE_TYPE: 1174 snprintf (buf, BUFSIZE, "_OBJC_ProtocolRefs_%s", 1175 IDENTIFIER_POINTER (PROTOCOL_NAME (i_or_p))); 1176 break; 1177 case CLASS_INTERFACE_TYPE: 1178 snprintf (buf, BUFSIZE, "_OBJC_ClassProtocols_%s", 1179 IDENTIFIER_POINTER (CLASS_NAME (i_or_p))); 1180 break; 1181 case CATEGORY_INTERFACE_TYPE: 1182 snprintf (buf, BUFSIZE, "_OBJC_CategoryProtocols_%s_%s", 1183 IDENTIFIER_POINTER (CLASS_NAME (klass_ctxt)), 1184 IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass_ctxt))); 1185 break; 1186 default: 1187 gcc_unreachable (); 1188 } 1189 1190 ptype = build_pointer_type (objc_protocol_template); 1191 array_type = build_sized_array_type (ptype, size + 3); 1192 refs_decl = start_var_decl (array_type, buf); 1193 OBJCMETA (refs_decl, objc_meta, meta_base); 1194 finish_var_decl (refs_decl, 1195 objc_build_constructor (TREE_TYPE (refs_decl), v)); 1196 1197 return refs_decl; 1198 } 1199 1200 static tree 1201 generate_v1_meth_descriptor_table (tree chain, tree protocol, const char *prefix) 1202 { 1203 tree method_list_template, initlist, decl; 1204 int size; 1205 vec<constructor_elt, va_gc> *v = NULL; 1206 char buf[BUFSIZE]; 1207 1208 if (!chain || !prefix) 1209 return NULL_TREE; 1210 1211 if (!objc_method_prototype_template) 1212 objc_method_prototype_template = build_method_prototype_template (); 1213 1214 size = list_length (chain); 1215 method_list_template = 1216 build_method_prototype_list_template (objc_method_prototype_template, 1217 size); 1218 snprintf (buf, BUFSIZE, "%s_%s", prefix, 1219 IDENTIFIER_POINTER (PROTOCOL_NAME (protocol))); 1220 1221 decl = start_var_decl (method_list_template, buf); 1222 1223 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size)); 1224 initlist = 1225 build_descriptor_table_initializer (objc_method_prototype_template, 1226 chain); 1227 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist); 1228 OBJCMETA (decl, objc_meta, meta_base); 1229 finish_var_decl (decl, objc_build_constructor (method_list_template, v)); 1230 return decl; 1231 } 1232 1233 /* For each protocol which was referenced either from a @protocol() 1234 expression, or because a class/category implements it (then a 1235 pointer to the protocol is stored in the struct describing the 1236 class/category), we create a statically allocated instance of the 1237 Protocol class. The code is written in such a way as to generate 1238 as few Protocol objects as possible; we generate a unique Protocol 1239 instance for each protocol, and we don't generate a Protocol 1240 instance if the protocol is never referenced (either from a 1241 @protocol() or from a class/category implementation). These 1242 statically allocated objects can be referred to via the static 1243 (that is, private to this module) symbols _OBJC_PROTOCOL_n. 1244 1245 The statically allocated Protocol objects that we generate here 1246 need to be fixed up at runtime in order to be used: the 'isa' 1247 pointer of the objects need to be set up to point to the 'Protocol' 1248 class, as known at runtime. 1249 1250 The GNU runtime fixes up all protocols before user code from the module 1251 is executed; it requires pointers to those symbols 1252 to be put in the objc_symtab (which is then passed as argument to 1253 the function __objc_exec_class() which the compiler sets up to be 1254 executed automatically when the module is loaded); setup of those 1255 Protocol objects happen in two ways in the GNU runtime: all 1256 Protocol objects referred to by a class or category implementation 1257 are fixed up when the class/category is loaded; all Protocol 1258 objects referred to by a @protocol() expression are added by the 1259 compiler to the list of statically allocated instances to fixup 1260 (the same list holding the statically allocated constant string 1261 objects). Because, as explained above, the compiler generates as 1262 few Protocol objects as possible, some Protocol object might end up 1263 being referenced multiple times when compiled with the GNU runtime, 1264 and end up being fixed up multiple times at runtime initialization. 1265 But that doesn't hurt, it's just a little inefficient. */ 1266 1267 static void 1268 generate_protocols (void) 1269 { 1270 tree p, encoding; 1271 tree decl; 1272 tree initlist, protocol_name_expr, refs_decl, refs_expr; 1273 1274 /* If a protocol was directly referenced, pull in indirect references. */ 1275 for (p = protocol_chain; p; p = TREE_CHAIN (p)) 1276 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p)) 1277 generate_protocol_references (PROTOCOL_LIST (p)); 1278 1279 for (p = protocol_chain; p; p = TREE_CHAIN (p)) 1280 { 1281 tree nst_methods = PROTOCOL_NST_METHODS (p); 1282 tree cls_methods = PROTOCOL_CLS_METHODS (p); 1283 1284 /* If protocol wasn't referenced, don't generate any code. */ 1285 decl = PROTOCOL_FORWARD_DECL (p); 1286 1287 if (!decl) 1288 continue; 1289 1290 /* Make sure we link in the Protocol class. */ 1291 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME)); 1292 1293 while (nst_methods) 1294 { 1295 if (! METHOD_ENCODING (nst_methods)) 1296 { 1297 encoding = encode_method_prototype (nst_methods); 1298 METHOD_ENCODING (nst_methods) = encoding; 1299 } 1300 nst_methods = DECL_CHAIN (nst_methods); 1301 } 1302 1303 UOBJC_INSTANCE_METHODS_decl = 1304 generate_v1_meth_descriptor_table (PROTOCOL_NST_METHODS (p), p, 1305 "_OBJC_PROTOCOL_INSTANCE_METHODS"); 1306 1307 while (cls_methods) 1308 { 1309 if (! METHOD_ENCODING (cls_methods)) 1310 { 1311 encoding = encode_method_prototype (cls_methods); 1312 METHOD_ENCODING (cls_methods) = encoding; 1313 } 1314 1315 cls_methods = DECL_CHAIN (cls_methods); 1316 } 1317 1318 UOBJC_CLASS_METHODS_decl = 1319 generate_v1_meth_descriptor_table (PROTOCOL_CLS_METHODS (p), p, 1320 "_OBJC_PROTOCOL_CLASS_METHODS"); 1321 /* generate_method_descriptors (p);*/ 1322 1323 if (PROTOCOL_LIST (p)) 1324 refs_decl = generate_protocol_list (p, NULL_TREE); 1325 else 1326 refs_decl = 0; 1327 1328 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */ 1329 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names); 1330 1331 if (refs_decl) 1332 refs_expr = convert (build_pointer_type (build_pointer_type 1333 (objc_protocol_template)), 1334 build_unary_op (input_location, 1335 ADDR_EXPR, refs_decl, 0)); 1336 else 1337 refs_expr = build_int_cst (NULL_TREE, 0); 1338 1339 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set 1340 by generate_method_descriptors, which is called above. */ 1341 initlist = build_protocol_initializer (TREE_TYPE (decl), 1342 protocol_name_expr, refs_expr, 1343 UOBJC_INSTANCE_METHODS_decl, 1344 UOBJC_CLASS_METHODS_decl); 1345 finish_var_decl (decl, initlist); 1346 } 1347 } 1348 1349 static tree 1350 generate_dispatch_table (tree chain, const char *name) 1351 { 1352 tree decl, method_list_template, initlist; 1353 vec<constructor_elt, va_gc> *v = NULL; 1354 int size = list_length (chain); 1355 1356 if (!objc_method_template) 1357 objc_method_template = build_method_template (); 1358 1359 method_list_template = build_method_list_template (objc_method_template, 1360 size); 1361 initlist = build_dispatch_table_initializer (objc_method_template, chain); 1362 1363 decl = start_var_decl (method_list_template, name); 1364 1365 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node); 1366 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, 1367 build_int_cst (integer_type_node, size)); 1368 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist); 1369 1370 OBJCMETA (decl, objc_meta, meta_base); 1371 finish_var_decl (decl, 1372 objc_build_constructor (TREE_TYPE (decl), v)); 1373 1374 return decl; 1375 } 1376 1377 /* Init a category. */ 1378 static tree 1379 build_category_initializer (tree type, tree cat_name, tree class_name, 1380 tree inst_methods, tree class_methods, 1381 tree protocol_list) 1382 { 1383 tree expr, ltyp; 1384 location_t loc; 1385 vec<constructor_elt, va_gc> *v = NULL; 1386 1387 /* TODO: pass the loc in or find it from args. */ 1388 /* TODO: pass the loc in or find it from args. */ 1389 loc = UNKNOWN_LOCATION; 1390 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name); 1391 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name); 1392 1393 ltyp = objc_method_list_ptr; 1394 if (inst_methods) 1395 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0)); 1396 else 1397 expr = convert (ltyp, null_pointer_node); 1398 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); 1399 1400 if (class_methods) 1401 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0)); 1402 else 1403 expr = convert (ltyp, null_pointer_node); 1404 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); 1405 1406 /* protocol_list = */ 1407 ltyp = build_pointer_type (build_pointer_type (objc_protocol_template)); 1408 if (protocol_list) 1409 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, protocol_list, 0)); 1410 else 1411 expr = convert (ltyp, null_pointer_node); 1412 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); 1413 1414 return objc_build_constructor (type, v); 1415 } 1416 1417 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */ 1418 1419 static void 1420 generate_category (struct imp_entry *impent) 1421 { 1422 tree initlist, cat_name_expr, class_name_expr; 1423 tree protocol_decl, category, cat_decl; 1424 tree inst_methods = NULL_TREE, class_methods = NULL_TREE; 1425 tree cat = impent->imp_context; 1426 char buf[BUFSIZE]; 1427 1428 cat_decl = impent->class_decl; 1429 1430 add_class_reference (CLASS_NAME (cat)); 1431 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names); 1432 1433 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names); 1434 1435 category = lookup_category (impent->imp_template, CLASS_SUPER_NAME (cat)); 1436 1437 if (category && CLASS_PROTOCOL_LIST (category)) 1438 { 1439 generate_protocol_references (CLASS_PROTOCOL_LIST (category)); 1440 protocol_decl = generate_protocol_list (category, cat); 1441 } 1442 else 1443 protocol_decl = 0; 1444 1445 if (CLASS_NST_METHODS (cat)) 1446 { 1447 snprintf (buf, BUFSIZE, "_OBJC_CategoryInstanceMethods_%s_%s", 1448 IDENTIFIER_POINTER (CLASS_NAME (cat)), 1449 IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat))); 1450 inst_methods = generate_dispatch_table (CLASS_NST_METHODS (cat), buf); 1451 } 1452 1453 if (CLASS_CLS_METHODS (cat)) 1454 { 1455 snprintf (buf, BUFSIZE, "_OBJC_CategoryClassMethods_%s_%s", 1456 IDENTIFIER_POINTER (CLASS_NAME (cat)), 1457 IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat))); 1458 class_methods = generate_dispatch_table (CLASS_CLS_METHODS (cat), buf); 1459 } 1460 1461 initlist = build_category_initializer (TREE_TYPE (cat_decl), 1462 cat_name_expr, class_name_expr, 1463 inst_methods, class_methods, 1464 protocol_decl); 1465 /* Finish and initialize the forward decl. */ 1466 finish_var_decl (cat_decl, initlist); 1467 impent->class_decl = cat_decl; 1468 } 1469 1470 /* struct _objc_class { 1471 struct objc_class *isa; 1472 struct objc_class *super_class; 1473 char *name; 1474 long version; 1475 long info; 1476 long instance_size; 1477 struct objc_ivar_list *ivars; 1478 struct objc_method_list *methods; 1479 struct sarray *dtable; 1480 struct objc_class *subclass_list; 1481 struct objc_class *sibling_class; 1482 struct objc_protocol_list *protocols; 1483 void *gc_object_type; 1484 }; */ 1485 1486 static tree 1487 build_shared_structure_initializer (tree type, tree isa, tree super, 1488 tree name, tree size, int status, 1489 tree dispatch_table, tree ivar_list, 1490 tree protocol_list) 1491 { 1492 tree expr, ltyp; 1493 vec<constructor_elt, va_gc> *v = NULL; 1494 1495 /* isa = */ 1496 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, isa); 1497 1498 /* super_class = */ 1499 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, super); 1500 1501 /* name = */ 1502 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, default_conversion (name)); 1503 1504 /* version = */ 1505 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, 1506 build_int_cst (long_integer_type_node, 0)); 1507 1508 /* info = */ 1509 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, 1510 build_int_cst (long_integer_type_node, status)); 1511 1512 /* instance_size = */ 1513 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, 1514 convert (long_integer_type_node, size)); 1515 1516 /* objc_ivar_list = */ 1517 if (!ivar_list) 1518 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, 1519 build_int_cst (objc_ivar_list_ptr, 0)); 1520 else 1521 { 1522 expr = convert (objc_ivar_list_ptr, 1523 build_unary_op (input_location, ADDR_EXPR, 1524 ivar_list, 0)); 1525 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); 1526 } 1527 1528 /* objc_method_list = */ 1529 if (!dispatch_table) 1530 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, 1531 convert (objc_method_list_ptr, null_pointer_node)); 1532 else 1533 { 1534 expr = convert (objc_method_list_ptr, 1535 build_unary_op (input_location, ADDR_EXPR, 1536 dispatch_table, 0)); 1537 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); 1538 } 1539 1540 /* FIXME: Remove NeXT runtime code. */ 1541 if (flag_next_runtime) 1542 { 1543 ltyp = build_pointer_type (xref_tag (RECORD_TYPE, 1544 get_identifier ("objc_cache"))); 1545 /* method_cache = */ 1546 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, convert (ltyp, null_pointer_node)); 1547 } 1548 else 1549 { 1550 /* dtable = */ 1551 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0)); 1552 1553 /* subclass_list = */ 1554 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0)); 1555 1556 /* sibling_class = */ 1557 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0)); 1558 } 1559 1560 /* protocol_list = */ 1561 ltyp = build_pointer_type (build_pointer_type (objc_protocol_template)); 1562 if (! protocol_list) 1563 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (ltyp, 0)); 1564 else 1565 { 1566 expr = convert (ltyp, 1567 build_unary_op (input_location, ADDR_EXPR, 1568 protocol_list, 0)); 1569 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); 1570 } 1571 1572 /* FIXME: Remove NeXT runtime code. */ 1573 if (flag_next_runtime) 1574 /* sel_id = NULL */ 1575 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0)); 1576 1577 /* gc_object_type = NULL */ 1578 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0)); 1579 1580 return objc_build_constructor (type, v); 1581 } 1582 1583 1584 static tree 1585 generate_ivars_list (tree chain, const char *name) 1586 { 1587 tree initlist, ivar_list_template, decl; 1588 int size; 1589 vec<constructor_elt, va_gc> *inits = NULL; 1590 1591 if (!chain) 1592 return NULL_TREE; 1593 1594 if (!objc_ivar_template) 1595 objc_ivar_template = build_ivar_template (); 1596 1597 size = ivar_list_length (chain); 1598 1599 generating_instance_variables = 1; 1600 ivar_list_template = build_ivar_list_template (objc_ivar_template, size); 1601 initlist = build_ivar_list_initializer (objc_ivar_template, chain); 1602 generating_instance_variables = 0; 1603 1604 decl = start_var_decl (ivar_list_template, name); 1605 1606 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, size)); 1607 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, initlist); 1608 1609 OBJCMETA (decl, objc_meta, meta_base); 1610 finish_var_decl (decl, 1611 objc_build_constructor (TREE_TYPE (decl), inits)); 1612 1613 return decl; 1614 } 1615 1616 /* static struct objc_class _OBJC_METACLASS_Foo={ ... }; 1617 static struct objc_class _OBJC_CLASS_Foo={ ... }; */ 1618 1619 static void 1620 generate_class_structures (struct imp_entry *impent) 1621 { 1622 tree name_expr, super_expr, root_expr, class_decl, meta_decl; 1623 tree my_root_id, my_super_id; 1624 tree cast_type, initlist, protocol_decl; 1625 tree inst_methods = NULL_TREE, class_methods = NULL_TREE; 1626 tree chain, inst_ivars = NULL_TREE, class_ivars = NULL_TREE; 1627 location_t loc; 1628 char buf[BUFSIZE]; 1629 int cls_flags = 0 ; 1630 1631 /* objc_implementation_context = impent->imp_context; 1632 implementation_template = impent->imp_template;*/ 1633 class_decl = impent->class_decl; 1634 meta_decl = impent->meta_decl; 1635 /* UOBJC_CLASS_decl = impent->class_decl; 1636 UOBJC_METACLASS_decl = impent->meta_decl;*/ 1637 1638 loc = DECL_SOURCE_LOCATION (impent->class_decl); 1639 1640 my_super_id = CLASS_SUPER_NAME (impent->imp_template); 1641 if (my_super_id) 1642 { 1643 add_class_reference (my_super_id); 1644 1645 /* Compute "my_root_id" - this is required for code generation. 1646 the "isa" for all meta class structures points to the root of 1647 the inheritance hierarchy (e.g. "__Object")... */ 1648 my_root_id = my_super_id; 1649 do 1650 { 1651 tree my_root_int = lookup_interface (my_root_id); 1652 1653 if (my_root_int && CLASS_SUPER_NAME (my_root_int)) 1654 my_root_id = CLASS_SUPER_NAME (my_root_int); 1655 else 1656 break; 1657 } 1658 while (1); 1659 } 1660 else 1661 /* No super class. */ 1662 my_root_id = CLASS_NAME (impent->imp_template); 1663 1664 cast_type = build_pointer_type (objc_class_template); 1665 name_expr = add_objc_string (CLASS_NAME (impent->imp_template), 1666 class_names); 1667 1668 /* Install class `isa' and `super' pointers at runtime. */ 1669 if (my_super_id) 1670 super_expr = add_objc_string (my_super_id, class_names); 1671 else 1672 super_expr = null_pointer_node; 1673 1674 super_expr = build_c_cast (loc, cast_type, super_expr); 1675 1676 root_expr = add_objc_string (my_root_id, class_names); 1677 root_expr = build_c_cast (loc, cast_type, root_expr); 1678 1679 if (CLASS_PROTOCOL_LIST (impent->imp_template)) 1680 { 1681 generate_protocol_references (CLASS_PROTOCOL_LIST (impent->imp_template)); 1682 protocol_decl = generate_protocol_list (impent->imp_template, 1683 impent->imp_context); 1684 } 1685 else 1686 protocol_decl = NULL_TREE; 1687 1688 if (CLASS_CLS_METHODS (impent->imp_context)) 1689 { 1690 snprintf (buf, BUFSIZE, "_OBJC_ClassMethods_%s", 1691 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context))); 1692 class_methods = generate_dispatch_table (CLASS_CLS_METHODS (impent->imp_context), 1693 buf); 1694 } 1695 1696 if (CLASS_SUPER_NAME (impent->imp_template) == NULL_TREE 1697 && (chain = TYPE_FIELDS (objc_class_template))) 1698 { 1699 snprintf (buf, BUFSIZE, "_OBJC_ClassIvars_%s", 1700 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context))); 1701 class_ivars = generate_ivars_list (chain, buf); 1702 } 1703 1704 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */ 1705 1706 initlist = 1707 build_shared_structure_initializer 1708 (TREE_TYPE (meta_decl), 1709 root_expr, super_expr, name_expr, 1710 convert (integer_type_node, 1711 TYPE_SIZE_UNIT (objc_class_template)), 1712 CLS_META, class_methods, class_ivars, 1713 protocol_decl); 1714 1715 finish_var_decl (meta_decl, initlist); 1716 impent->meta_decl = meta_decl; 1717 1718 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */ 1719 if (CLASS_NST_METHODS (impent->imp_context)) 1720 { 1721 snprintf (buf, BUFSIZE, "_OBJC_InstanceMethods_%s", 1722 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context))); 1723 inst_methods = generate_dispatch_table (CLASS_NST_METHODS (impent->imp_context), 1724 buf); 1725 } 1726 1727 if ((chain = CLASS_IVARS (impent->imp_template))) 1728 { 1729 snprintf (buf, BUFSIZE, "_OBJC_InstanceIvars_%s", 1730 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context))); 1731 inst_ivars = generate_ivars_list (chain, buf); 1732 } 1733 1734 initlist = 1735 build_shared_structure_initializer 1736 (TREE_TYPE (class_decl), 1737 build_unary_op (loc, ADDR_EXPR, meta_decl, 0), 1738 super_expr, name_expr, 1739 convert (integer_type_node, 1740 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE 1741 (impent->imp_template))), 1742 CLS_FACTORY | cls_flags, inst_methods, inst_ivars, 1743 protocol_decl); 1744 1745 finish_var_decl (class_decl, initlist); 1746 impent->class_decl = class_decl; 1747 } 1748 1749 /* --- Output GNU Metadata --- */ 1750 1751 /* TODO: Make this into an array of refs. */ 1752 static void 1753 handle_class_ref (tree chain) 1754 { 1755 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain)); 1756 char *string = (char *) alloca (strlen (name) + 30); 1757 tree decl; 1758 tree exp; 1759 1760 sprintf (string, "__objc_class_name_%s", name); 1761 1762 /* Make a decl for this name, so we can use its address in a tree. */ 1763 decl = build_decl (input_location, 1764 VAR_DECL, get_identifier (string), TREE_TYPE (integer_zero_node)); 1765 DECL_EXTERNAL (decl) = 1; 1766 TREE_PUBLIC (decl) = 1; 1767 DECL_CONTEXT (decl) = NULL_TREE; 1768 finish_var_decl (decl, 0); 1769 1770 /* Make a decl for the address. */ 1771 sprintf (string, "__objc_class_ref_%s", name); 1772 exp = build1 (ADDR_EXPR, string_type_node, decl); 1773 decl = build_decl (input_location, 1774 VAR_DECL, get_identifier (string), string_type_node); 1775 TREE_STATIC (decl) = 1; 1776 TREE_USED (decl) = 1; 1777 DECL_READ_P (decl) = 1; 1778 DECL_ARTIFICIAL (decl) = 1; 1779 DECL_INITIAL (decl) = error_mark_node; 1780 1781 /* We must force the reference. */ 1782 DECL_PRESERVE_P (decl) = 1; 1783 1784 DECL_CONTEXT (decl) = NULL_TREE; 1785 finish_var_decl (decl, exp); 1786 } 1787 1788 static tree 1789 get_proto_encoding (tree proto) 1790 { 1791 tree encoding; 1792 if (proto) 1793 { 1794 if (! METHOD_ENCODING (proto)) 1795 { 1796 encoding = encode_method_prototype (proto); 1797 METHOD_ENCODING (proto) = encoding; 1798 } 1799 else 1800 encoding = METHOD_ENCODING (proto); 1801 1802 return add_objc_string (encoding, meth_var_types); 1803 } 1804 else 1805 return build_int_cst (NULL_TREE, 0); 1806 } 1807 1808 static void 1809 build_gnu_selector_translation_table (void) 1810 { 1811 tree chain, expr; 1812 vec<constructor_elt, va_gc> *inits = NULL; 1813 vec<constructor_elt, va_gc> *v ; 1814 1815 /* Cause the selector table (previously forward-declared) 1816 to be actually output. */ 1817 1818 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain)) 1819 { 1820 tree encoding; 1821 if (warn_selector) 1822 { 1823 /* TODO: improve on the location for the diagnostic. */ 1824 location_t loc = input_location; 1825 diagnose_missing_method (TREE_VALUE (chain), loc); 1826 } 1827 1828 v = NULL; 1829 expr = build_selector (TREE_VALUE (chain)); 1830 encoding = get_proto_encoding (TREE_PURPOSE (chain)); 1831 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); 1832 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, encoding); 1833 expr = objc_build_constructor (objc_selector_template, v); 1834 1835 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr); 1836 } /* each element in the chain */ 1837 1838 /* List terminator. */ 1839 v = NULL; 1840 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node); 1841 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node); 1842 expr = objc_build_constructor (objc_selector_template, v); 1843 1844 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr); 1845 expr = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl), 1846 inits); 1847 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, expr); 1848 } 1849 1850 /* Output references to all statically allocated objects. Return the DECL 1851 for the array built. */ 1852 1853 static void 1854 generate_static_references (void) 1855 { 1856 tree expr = NULL_TREE; 1857 tree class_name, klass, decl; 1858 tree cl_chain, in_chain, type 1859 = build_array_type (build_pointer_type (void_type_node), NULL_TREE); 1860 int num_inst, num_class; 1861 char buf[BUFSIZE]; 1862 vec<constructor_elt, va_gc> *decls = NULL; 1863 1864 /* FIXME: Remove NeXT runtime code. */ 1865 if (flag_next_runtime) 1866 gcc_unreachable (); 1867 1868 for (cl_chain = objc_static_instances, num_class = 0; 1869 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++) 1870 { 1871 vec<constructor_elt, va_gc> *v = NULL; 1872 1873 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain); 1874 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain)); 1875 1876 snprintf (buf, BUFSIZE, "_OBJC_STATIC_INSTANCES_%d", num_class); 1877 decl = start_var_decl (type, buf); 1878 1879 /* Output {class_name, ...}. */ 1880 klass = TREE_VALUE (cl_chain); 1881 class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names); 1882 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, 1883 build_unary_op (input_location, 1884 ADDR_EXPR, class_name, 1)); 1885 1886 /* Output {..., instance, ...}. */ 1887 for (in_chain = TREE_PURPOSE (cl_chain); 1888 in_chain; in_chain = TREE_CHAIN (in_chain)) 1889 { 1890 expr = build_unary_op (input_location, 1891 ADDR_EXPR, TREE_VALUE (in_chain), 1); 1892 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); 1893 } 1894 1895 /* Output {..., NULL}. */ 1896 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0)); 1897 1898 expr = objc_build_constructor (TREE_TYPE (decl), v); 1899 OBJCMETA (decl, objc_meta, meta_base); 1900 finish_var_decl (decl, expr); 1901 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE, 1902 build_unary_op (input_location, 1903 ADDR_EXPR, decl, 1)); 1904 } 1905 1906 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE, build_int_cst (NULL_TREE, 0)); 1907 expr = objc_build_constructor (type, decls); 1908 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES"); 1909 OBJCMETA (static_instances_decl, objc_meta, meta_base); 1910 finish_var_decl (static_instances_decl, expr); 1911 } 1912 1913 /* Create the initial value for the `defs' field of _objc_symtab. 1914 This is a CONSTRUCTOR. */ 1915 1916 static tree 1917 init_def_list (tree type) 1918 { 1919 tree expr; 1920 struct imp_entry *impent; 1921 location_t loc; 1922 vec<constructor_elt, va_gc> *v = NULL; 1923 1924 if (imp_count) 1925 for (impent = imp_list; impent; impent = impent->next) 1926 { 1927 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE) 1928 { 1929 loc = DECL_SOURCE_LOCATION (impent->class_decl); 1930 expr = build_unary_op (loc, 1931 ADDR_EXPR, impent->class_decl, 0); 1932 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); 1933 } 1934 } 1935 1936 if (cat_count) 1937 for (impent = imp_list; impent; impent = impent->next) 1938 { 1939 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE) 1940 { 1941 loc = DECL_SOURCE_LOCATION (impent->class_decl); 1942 expr = build_unary_op (loc, 1943 ADDR_EXPR, impent->class_decl, 0); 1944 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); 1945 } 1946 } 1947 1948 loc = UNKNOWN_LOCATION; 1949 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */ 1950 if (static_instances_decl) 1951 expr = build_unary_op (loc, ADDR_EXPR, static_instances_decl, 0); 1952 else 1953 expr = integer_zero_node; 1954 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); 1955 1956 return objc_build_constructor (type, v); 1957 } 1958 1959 /* Take care of defining and initializing _OBJC_SYMBOLS. */ 1960 1961 /* Predefine the following data type: 1962 1963 struct _objc_symtab 1964 { 1965 long sel_ref_cnt; 1966 SEL *refs; 1967 short cls_def_cnt; 1968 short cat_def_cnt; 1969 void *defs[cls_def_cnt + cat_def_cnt]; 1970 }; */ 1971 1972 static void 1973 build_objc_symtab_template (void) 1974 { 1975 tree fields, array_type, *chain = NULL; 1976 int index; 1977 1978 objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB)); 1979 1980 /* long sel_ref_cnt; */ 1981 fields = add_field_decl (long_integer_type_node, "sel_ref_cnt", &chain); 1982 1983 /* SEL *refs; */ 1984 add_field_decl (build_pointer_type (objc_selector_type), "refs", &chain); 1985 1986 /* short cls_def_cnt; */ 1987 add_field_decl (short_integer_type_node, "cls_def_cnt", &chain); 1988 1989 /* short cat_def_cnt; */ 1990 add_field_decl (short_integer_type_node, "cat_def_cnt", &chain); 1991 1992 /* Note that padding will be added here on LP64. */ 1993 1994 /* void *defs[imp_count + cat_count (+ 1)]; */ 1995 /* NB: The index is one less than the size of the array. */ 1996 index = imp_count + cat_count; 1997 array_type = build_sized_array_type (ptr_type_node, index + 1); 1998 add_field_decl (array_type, "defs", &chain); 1999 2000 objc_finish_struct (objc_symtab_template, fields); 2001 } 2002 /* Construct the initial value for all of _objc_symtab. */ 2003 2004 static tree 2005 init_objc_symtab (tree type) 2006 { 2007 tree field, expr, ltyp; 2008 location_t loc; 2009 vec<constructor_elt, va_gc> *v = NULL; 2010 2011 loc = UNKNOWN_LOCATION; 2012 2013 /* sel_ref_cnt = { ..., 5, ... } */ 2014 2015 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, 2016 build_int_cst (long_integer_type_node, 0)); 2017 2018 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */ 2019 2020 ltyp = build_pointer_type (objc_selector_type); 2021 if (sel_ref_chain) 2022 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, 2023 UOBJC_SELECTOR_TABLE_decl, 1)); 2024 else 2025 expr = convert (ltyp, null_pointer_node); 2026 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); 2027 2028 /* cls_def_cnt = { ..., 5, ... } */ 2029 2030 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, 2031 build_int_cst (short_integer_type_node, imp_count)); 2032 2033 /* cat_def_cnt = { ..., 5, ... } */ 2034 2035 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, 2036 build_int_cst (short_integer_type_node, cat_count)); 2037 2038 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */ 2039 2040 field = TYPE_FIELDS (type); 2041 field = DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field)))); 2042 2043 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init_def_list (TREE_TYPE (field))); 2044 2045 return objc_build_constructor (type, v); 2046 } 2047 2048 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab' 2049 and initialized appropriately. */ 2050 2051 static void 2052 generate_objc_symtab_decl (void) 2053 { 2054 build_objc_symtab_template (); 2055 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS"); 2056 OBJCMETA (UOBJC_SYMBOLS_decl, objc_meta, meta_base); 2057 finish_var_decl (UOBJC_SYMBOLS_decl, 2058 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl))); 2059 } 2060 2061 static void 2062 objc_generate_v1_gnu_metadata (void) 2063 { 2064 struct imp_entry *impent; 2065 tree chain; 2066 2067 /* Process the static instances here because initialization of objc_symtab 2068 depends on them. */ 2069 if (objc_static_instances) 2070 generate_static_references (); 2071 2072 objc_implementation_context = 2073 implementation_template = 2074 UOBJC_CLASS_decl = 2075 UOBJC_METACLASS_decl = NULL_TREE; 2076 2077 for (impent = imp_list; impent; impent = impent->next) 2078 { 2079 /* If -gen-decls is present, Dump the @interface of each class. 2080 TODO: Dump the classes in the order they were found, rather than in 2081 reverse order as we are doing now. */ 2082 if (flag_gen_declaration) 2083 dump_interface (gen_declaration_file, impent->imp_context); 2084 2085 /* all of the following reference the string pool... */ 2086 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE) 2087 generate_class_structures (impent); 2088 else 2089 generate_category (impent); 2090 } 2091 2092 /* If we are using an array of selectors, we must always 2093 finish up the array decl even if no selectors were used. */ 2094 build_gnu_selector_translation_table (); 2095 2096 if (protocol_chain) 2097 generate_protocols (); 2098 2099 /* Arrange for ObjC data structures to be initialized at run time. */ 2100 /* FIXME: Have some more elegant way to determine if we need to 2101 generate objc_symtab_decl or not, instead of checking these 2102 global symbols. */ 2103 if (imp_list || class_names_chain 2104 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain 2105 || prop_names_attr_chain) 2106 generate_objc_symtab_decl (); 2107 2108 if (imp_list || class_names_chain || objc_static_instances 2109 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain) 2110 { 2111 /* Make sure that the meta-data are identified as being 2112 GNU-runtime. */ 2113 build_module_descriptor (OBJC_VERSION, 2114 build_tree_list (objc_meta, meta_base)); 2115 build_module_initializer_routine (); 2116 } 2117 2118 /* Dump the class references. This forces the appropriate classes 2119 to be linked into the executable image, preserving unix archive 2120 semantics. This can be removed when we move to a more dynamically 2121 linked environment. */ 2122 2123 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain)) 2124 { 2125 handle_class_ref (chain); 2126 if (TREE_PURPOSE (chain)) 2127 generate_classref_translation_entry (chain); 2128 } 2129 2130 for (impent = imp_list; impent; impent = impent->next) 2131 handle_impent (impent); 2132 2133 generate_strings (); 2134 } 2135 2136 /* --- exceptions --- */ 2137 2138 static GTY(()) tree objc_eh_personality_decl; 2139 2140 static tree 2141 objc_eh_runtime_type (tree type) 2142 { 2143 tree ident, eh_id, decl, str; 2144 2145 if (type == error_mark_node 2146 || errorcount || sorrycount) 2147 { 2148 /* Use 'ErrorMarkNode' as class name when error_mark_node is found 2149 to prevent an ICE. Note that we know that the compiler will 2150 terminate with an error and this 'ErrorMarkNode' class name will 2151 never be actually used. */ 2152 ident = get_identifier ("ErrorMarkNode"); 2153 goto make_err_class; 2154 } 2155 2156 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type))) 2157 /* We don't want to identify 'id' for GNU. Instead, build a 0 2158 entry in the exceptions table. */ 2159 return null_pointer_node; 2160 2161 if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type))) 2162 { 2163 #ifdef OBJCPLUS 2164 /* This routine is also called for c++ catch clauses; in which case, 2165 we use the c++ typeinfo decl. */ 2166 return build_eh_type_type (type); 2167 #else 2168 error ("non-objective-c type '%T' cannot be caught", type); 2169 ident = get_identifier ("ErrorMarkNode"); 2170 goto make_err_class; 2171 #endif 2172 } 2173 else 2174 ident = OBJC_TYPE_NAME (TREE_TYPE (type)); 2175 2176 make_err_class: 2177 /* If this class was already referenced, then it will be output during 2178 meta-data emission, so we don't need to do it here. */ 2179 decl = get_objc_string_decl (ident, class_names); 2180 eh_id = add_objc_string (ident, class_names); 2181 if (!decl) 2182 { 2183 /* Not found ... so we need to build it - from the freshly-entered id. */ 2184 decl = get_objc_string_decl (ident, class_names); 2185 str = my_build_string (IDENTIFIER_LENGTH (ident) + 1, 2186 IDENTIFIER_POINTER (ident)); 2187 /* We have to finalize this var here, because this might be called after 2188 all the other metadata strings have been emitted. */ 2189 finish_var_decl (decl, str); 2190 } 2191 return eh_id; 2192 } 2193 2194 static tree 2195 objc_eh_personality (void) 2196 { 2197 if (!objc_eh_personality_decl) 2198 #ifndef OBJCPLUS 2199 objc_eh_personality_decl = build_personality_function ("gnu_objc"); 2200 #else 2201 objc_eh_personality_decl = build_personality_function ("gxx"); 2202 #endif 2203 return objc_eh_personality_decl; 2204 } 2205 2206 /* -- interfaces --- */ 2207 2208 static tree 2209 build_throw_stmt (location_t loc, tree throw_expr, bool rethrown ATTRIBUTE_UNUSED) 2210 { 2211 tree t; 2212 vec<tree, va_gc> *parms; 2213 vec_alloc (parms, 1); 2214 /* A throw is just a call to the runtime throw function with the 2215 object as a parameter. */ 2216 parms->quick_push (throw_expr); 2217 t = build_function_call_vec (loc, vNULL, objc_exception_throw_decl, parms, 2218 NULL); 2219 vec_free (parms); 2220 return add_stmt (t); 2221 } 2222 2223 /* Build __builtin_eh_pointer. */ 2224 2225 static tree 2226 objc_build_exc_ptr (struct objc_try_context **x ATTRIBUTE_UNUSED) 2227 { 2228 tree t; 2229 t = builtin_decl_explicit (BUILT_IN_EH_POINTER); 2230 t = build_call_expr (t, 1, integer_zero_node); 2231 return fold_convert (objc_object_type, t); 2232 } 2233 2234 static tree 2235 begin_catch (struct objc_try_context **cur_try_context, tree type, 2236 tree decl, tree compound, bool ellipsis ATTRIBUTE_UNUSED) 2237 { 2238 tree t; 2239 /* Record the data for the catch in the try context so that we can 2240 finalize it later. */ 2241 if (ellipsis) 2242 t = build_stmt (input_location, CATCH_EXPR, NULL, compound); 2243 else 2244 t = build_stmt (input_location, CATCH_EXPR, type, compound); 2245 (*cur_try_context)->current_catch = t; 2246 2247 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */ 2248 t = objc_build_exc_ptr (cur_try_context); 2249 t = convert (TREE_TYPE (decl), t); 2250 return build2 (MODIFY_EXPR, void_type_node, decl, t); 2251 } 2252 2253 static void 2254 finish_catch (struct objc_try_context **cur_try_context, tree current_catch) 2255 { 2256 append_to_statement_list (current_catch, &((*cur_try_context)->catch_list)); 2257 } 2258 2259 static tree 2260 finish_try_stmt (struct objc_try_context **cur_try_context) 2261 { 2262 struct objc_try_context *c = *cur_try_context; 2263 tree stmt = c->try_body; 2264 if (c->catch_list) 2265 stmt = build_stmt (c->try_locus, TRY_CATCH_EXPR, stmt, c->catch_list); 2266 if (c->finally_body) 2267 stmt = build_stmt (c->try_locus, TRY_FINALLY_EXPR, stmt, c->finally_body); 2268 return stmt; 2269 } 2270 2271 #include "gt-objc-objc-gnu-runtime-abi-01.h" 2272