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