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