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