1 /* Routines dealing with ObjC encoding of types 2 Copyright (C) 1992-2016 Free Software Foundation, Inc. 3 4 This file is part of GCC. 5 6 GCC is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3, or (at your option) 9 any later version. 10 11 GCC is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GCC; see the file COPYING3. If not see 18 <http://www.gnu.org/licenses/>. */ 19 20 #include "config.h" 21 #include "system.h" 22 #include "coretypes.h" 23 #include "tree.h" 24 #include "options.h" 25 #include "stringpool.h" 26 #include "stor-layout.h" 27 28 #ifdef OBJCPLUS 29 #include "cp/cp-tree.h" 30 #else 31 #include "c/c-tree.h" 32 #include "c/c-lang.h" 33 #endif 34 35 #include "c-family/c-objc.h" 36 37 #include "objc-encoding.h" 38 #include "objc-act.h" 39 40 /* For my_build_string(). */ 41 #include "objc-runtime-shared-support.h" 42 43 /* For BITS_PER_UNIT. */ 44 45 /* When building Objective-C++, we are not linking against the C front-end 46 and so need to replicate the C tree-construction functions in some way. */ 47 #ifdef OBJCPLUS 48 #define OBJCP_REMAP_FUNCTIONS 49 #include "objcp-decl.h" 50 #endif /* OBJCPLUS */ 51 52 /* Set up for use of obstacks. */ 53 54 /* This obstack is used to accumulate the encoding of a data type. */ 55 static struct obstack util_obstack; 56 57 /* This points to the beginning of obstack contents, so we can free 58 the whole contents. */ 59 static char *util_firstobj; 60 61 void objc_encoding_init (void) 62 { 63 gcc_obstack_init (&util_obstack); 64 util_firstobj = (char *) obstack_finish (&util_obstack); 65 } 66 67 int generating_instance_variables = 0; 68 69 static void encode_type_qualifiers (tree); 70 static void encode_type (tree, int, int); 71 static void encode_field (tree field_decl, int curtype, int format); 72 73 static tree 74 objc_method_parm_type (tree type) 75 { 76 type = TREE_VALUE (TREE_TYPE (type)); 77 if (TREE_CODE (type) == TYPE_DECL) 78 type = TREE_TYPE (type); 79 return type; 80 } 81 82 static int 83 objc_encoded_type_size (tree type) 84 { 85 int sz = int_size_in_bytes (type); 86 87 /* Make all integer and enum types at least as large 88 as an int. */ 89 if (sz > 0 && INTEGRAL_TYPE_P (type)) 90 sz = MAX (sz, int_size_in_bytes (integer_type_node)); 91 /* Treat arrays as pointers, since that's how they're 92 passed in. */ 93 else if (TREE_CODE (type) == ARRAY_TYPE) 94 sz = int_size_in_bytes (ptr_type_node); 95 return sz; 96 } 97 98 /* Encode a method prototype. */ 99 tree 100 encode_method_prototype (tree method_decl) 101 { 102 tree parms; 103 int parm_offset, i; 104 char buf[40]; 105 tree result; 106 107 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */ 108 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl))); 109 110 /* Encode return type. */ 111 encode_type (objc_method_parm_type (method_decl), 112 obstack_object_size (&util_obstack), 113 OBJC_ENCODE_INLINE_DEFS); 114 115 /* Stack size. */ 116 /* The first two arguments (self and _cmd) are pointers; account for 117 their size. */ 118 i = int_size_in_bytes (ptr_type_node); 119 parm_offset = 2 * i; 120 for (parms = METHOD_SEL_ARGS (method_decl); parms; 121 parms = DECL_CHAIN (parms)) 122 { 123 tree type = objc_method_parm_type (parms); 124 int sz = objc_encoded_type_size (type); 125 126 /* If a type size is not known, bail out. */ 127 if (sz < 0) 128 { 129 error_at (DECL_SOURCE_LOCATION (method_decl), 130 "type %qT does not have a known size", 131 type); 132 /* Pretend that the encoding succeeded; the compilation will 133 fail nevertheless. */ 134 goto finish_encoding; 135 } 136 parm_offset += sz; 137 } 138 139 sprintf (buf, "%d@0:%d", parm_offset, i); 140 obstack_grow (&util_obstack, buf, strlen (buf)); 141 142 /* Argument types. */ 143 parm_offset = 2 * i; 144 for (parms = METHOD_SEL_ARGS (method_decl); parms; 145 parms = DECL_CHAIN (parms)) 146 { 147 tree type = objc_method_parm_type (parms); 148 149 /* Process argument qualifiers for user supplied arguments. */ 150 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms))); 151 152 /* Type. */ 153 encode_type (type, obstack_object_size (&util_obstack), 154 OBJC_ENCODE_INLINE_DEFS); 155 156 /* Compute offset. */ 157 sprintf (buf, "%d", parm_offset); 158 parm_offset += objc_encoded_type_size (type); 159 160 obstack_grow (&util_obstack, buf, strlen (buf)); 161 } 162 163 finish_encoding: 164 obstack_1grow (&util_obstack, '\0'); 165 result = get_identifier (XOBFINISH (&util_obstack, char *)); 166 obstack_free (&util_obstack, util_firstobj); 167 return result; 168 } 169 170 /* This is used to implement @encode(). */ 171 tree 172 objc_build_encode_expr (tree type) 173 { 174 tree result; 175 const char *string; 176 177 encode_type (type, obstack_object_size (&util_obstack), 178 OBJC_ENCODE_INLINE_DEFS); 179 obstack_1grow (&util_obstack, 0); /* null terminate string */ 180 string = XOBFINISH (&util_obstack, const char *); 181 182 /* Synthesize a string that represents the encoded struct/union. */ 183 result = my_build_string (strlen (string) + 1, string); 184 obstack_free (&util_obstack, util_firstobj); 185 return result; 186 } 187 188 /* "Encode" a data type into a string, which grows in util_obstack. 189 190 The format is described in gcc/doc/objc.texi, section 'Type 191 encoding'. 192 193 Most of the encode_xxx functions have a 'type' argument, which is 194 the type to encode, and an integer 'curtype' argument, which is the 195 index in the encoding string of the beginning of the encoding of 196 the current type, and allows you to find what characters have 197 already been written for the current type (they are the ones in the 198 current encoding string starting from 'curtype'). 199 200 For example, if we are encoding a method which returns 'int' and 201 takes a 'char **' argument, then when we get to the point of 202 encoding the 'char **' argument, the encoded string already 203 contains 'i12@0:4' (assuming a pointer size of 4 bytes). So, 204 'curtype' will be set to 7 when starting to encode 'char **'. 205 During the whole of the encoding of 'char **', 'curtype' will be 206 fixed at 7, so the routine encoding the second pointer can find out 207 that it's actually encoding a pointer to a pointer by looking 208 backwards at what has already been encoded for the current type, 209 and seeing there is a "^" (meaning a pointer) in there. */ 210 211 212 /* Encode type qualifiers encodes one of the "PQ" Objective-C 213 keywords, ie 'in', 'out', 'inout', 'bycopy', 'byref', 'oneway'. 214 'const', instead, is encoded directly as part of the type. */ 215 static void 216 encode_type_qualifiers (tree declspecs) 217 { 218 tree spec; 219 220 for (spec = declspecs; spec; spec = TREE_CHAIN (spec)) 221 { 222 /* FIXME: Shouldn't we use token->keyword here ? */ 223 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec)) 224 obstack_1grow (&util_obstack, 'n'); 225 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec)) 226 obstack_1grow (&util_obstack, 'N'); 227 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec)) 228 obstack_1grow (&util_obstack, 'o'); 229 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec)) 230 obstack_1grow (&util_obstack, 'O'); 231 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec)) 232 obstack_1grow (&util_obstack, 'R'); 233 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec)) 234 obstack_1grow (&util_obstack, 'V'); 235 else 236 gcc_unreachable (); 237 } 238 } 239 240 /* Determine if a pointee is marked read-only. Only used by the NeXT 241 runtime to be compatible with gcc-3.3. */ 242 static bool 243 pointee_is_readonly (tree pointee) 244 { 245 while (POINTER_TYPE_P (pointee)) 246 pointee = TREE_TYPE (pointee); 247 248 return TYPE_READONLY (pointee); 249 } 250 251 /* Encode a pointer type. */ 252 static void 253 encode_pointer (tree type, int curtype, int format) 254 { 255 tree pointer_to = TREE_TYPE (type); 256 257 if (flag_next_runtime) 258 { 259 /* This code is used to be compatible with gcc-3.3. */ 260 /* For historical/compatibility reasons, the read-only qualifier 261 of the pointee gets emitted _before_ the '^'. The read-only 262 qualifier of the pointer itself gets ignored, _unless_ we are 263 looking at a typedef! Also, do not emit the 'r' for anything 264 but the outermost type! */ 265 if (!generating_instance_variables 266 && (obstack_object_size (&util_obstack) - curtype <= 1) 267 && (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL 268 ? TYPE_READONLY (type) 269 : pointee_is_readonly (pointer_to))) 270 obstack_1grow (&util_obstack, 'r'); 271 } 272 273 if (TREE_CODE (pointer_to) == RECORD_TYPE) 274 { 275 if (OBJC_TYPE_NAME (pointer_to) 276 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE) 277 { 278 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to)); 279 280 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */ 281 { 282 obstack_1grow (&util_obstack, '@'); 283 return; 284 } 285 else if (TYPE_HAS_OBJC_INFO (pointer_to) 286 && TYPE_OBJC_INTERFACE (pointer_to)) 287 { 288 if (generating_instance_variables) 289 { 290 obstack_1grow (&util_obstack, '@'); 291 obstack_1grow (&util_obstack, '"'); 292 obstack_grow (&util_obstack, name, strlen (name)); 293 obstack_1grow (&util_obstack, '"'); 294 return; 295 } 296 else 297 { 298 obstack_1grow (&util_obstack, '@'); 299 return; 300 } 301 } 302 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */ 303 { 304 obstack_1grow (&util_obstack, '#'); 305 return; 306 } 307 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */ 308 { 309 obstack_1grow (&util_obstack, ':'); 310 return; 311 } 312 } 313 } 314 else if (TREE_CODE (pointer_to) == INTEGER_TYPE 315 && TYPE_MODE (pointer_to) == QImode) 316 { 317 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE 318 ? OBJC_TYPE_NAME (pointer_to) 319 : DECL_NAME (OBJC_TYPE_NAME (pointer_to)); 320 321 /* (BOOL *) are an exception and are encoded as ^c, while all 322 other pointers to char are encoded as *. */ 323 if (strcmp (IDENTIFIER_POINTER (pname), "BOOL")) 324 { 325 if (!flag_next_runtime) 326 { 327 /* The NeXT runtime adds the 'r' before getting here. */ 328 329 /* It appears that "r*" means "const char *" rather than 330 "char *const". "char *const" is encoded as "*", 331 which is identical to "char *", so the "const" is 332 unfortunately lost. */ 333 if (TYPE_READONLY (pointer_to)) 334 obstack_1grow (&util_obstack, 'r'); 335 } 336 337 obstack_1grow (&util_obstack, '*'); 338 return; 339 } 340 } 341 342 /* We have a normal pointer type that does not get special treatment. */ 343 obstack_1grow (&util_obstack, '^'); 344 encode_type (pointer_to, curtype, format); 345 } 346 347 static void 348 encode_array (tree type, int curtype, int format) 349 { 350 tree an_int_cst = TYPE_SIZE (type); 351 tree array_of = TREE_TYPE (type); 352 char buffer[40]; 353 354 if (an_int_cst == NULL) 355 { 356 /* We are trying to encode an incomplete array. An incomplete 357 array is forbidden as part of an instance variable; but it 358 may occur if the instance variable is a pointer to such an 359 array. */ 360 361 /* So the only case in which an incomplete array could occur 362 (without being pointed to) is if we are encoding the 363 arguments or return value of a method. In that case, an 364 incomplete array argument or return value (eg, 365 -(void)display: (char[])string) is treated like a pointer 366 because that is how the compiler does the function call. A 367 special, more complicated case, is when the incomplete array 368 is the last member of a struct (eg, if we are encoding 369 "struct { unsigned long int a;double b[];}"), which is again 370 part of a method argument/return value. In that case, we 371 really need to communicate to the runtime that there is an 372 incomplete array (not a pointer!) there. So, we detect that 373 special case and encode it as a zero-length array. 374 375 Try to detect that we are part of a struct. We do this by 376 searching for '=' in the type encoding for the current type. 377 NB: This hack assumes that you can't use '=' as part of a C 378 identifier. 379 */ 380 { 381 char *enc = (char *) obstack_base (&util_obstack) + curtype; 382 if (memchr (enc, '=', 383 obstack_object_size (&util_obstack) - curtype) == NULL) 384 { 385 /* We are not inside a struct. Encode the array as a 386 pointer. */ 387 encode_pointer (type, curtype, format); 388 return; 389 } 390 } 391 392 /* Else, we are in a struct, and we encode it as a zero-length 393 array. */ 394 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0); 395 } 396 else if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0) 397 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0); 398 else 399 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, 400 TREE_INT_CST_LOW (an_int_cst) 401 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))); 402 403 obstack_grow (&util_obstack, buffer, strlen (buffer)); 404 encode_type (array_of, curtype, format); 405 obstack_1grow (&util_obstack, ']'); 406 return; 407 } 408 409 /* Encode a vector. The vector type is a GCC extension to C. */ 410 static void 411 encode_vector (tree type, int curtype, int format) 412 { 413 tree vector_of = TREE_TYPE (type); 414 char buffer[40]; 415 416 /* Vectors are like simple fixed-size arrays. */ 417 418 /* Output ![xx,yy,<code>] where xx is the vector_size, yy is the 419 alignment of the vector, and <code> is the base type. Eg, int 420 __attribute__ ((vector_size (16))) gets encoded as ![16,32,i] 421 assuming that the alignment is 32 bytes. We include size and 422 alignment in bytes so that the runtime does not have to have any 423 knowledge of the actual types. 424 */ 425 sprintf (buffer, "![" HOST_WIDE_INT_PRINT_DEC ",%d", 426 /* We want to compute the equivalent of sizeof (<vector>). 427 Code inspired by c_sizeof_or_alignof_type. */ 428 ((TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type)) 429 / (TYPE_PRECISION (char_type_node) / BITS_PER_UNIT))), 430 /* We want to compute the equivalent of __alignof__ 431 (<vector>). Code inspired by 432 c_sizeof_or_alignof_type. */ 433 TYPE_ALIGN_UNIT (type)); 434 obstack_grow (&util_obstack, buffer, strlen (buffer)); 435 encode_type (vector_of, curtype, format); 436 obstack_1grow (&util_obstack, ']'); 437 return; 438 } 439 440 static void 441 encode_aggregate_fields (tree type, bool pointed_to, int curtype, int format) 442 { 443 tree field = TYPE_FIELDS (type); 444 445 for (; field; field = DECL_CHAIN (field)) 446 { 447 #ifdef OBJCPLUS 448 /* C++ static members, and things that are not field at all, 449 should not appear in the encoding. */ 450 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field)) 451 continue; 452 #endif 453 454 /* Recursively encode fields of embedded base classes. */ 455 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field) 456 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE) 457 { 458 encode_aggregate_fields (TREE_TYPE (field), 459 pointed_to, curtype, format); 460 continue; 461 } 462 463 if (generating_instance_variables && !pointed_to) 464 { 465 tree fname = DECL_NAME (field); 466 467 obstack_1grow (&util_obstack, '"'); 468 469 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE) 470 obstack_grow (&util_obstack, 471 IDENTIFIER_POINTER (fname), 472 strlen (IDENTIFIER_POINTER (fname))); 473 474 obstack_1grow (&util_obstack, '"'); 475 } 476 477 encode_field (field, curtype, format); 478 } 479 } 480 481 static void 482 encode_aggregate_within (tree type, int curtype, int format, int left, 483 int right) 484 { 485 tree name; 486 /* NB: aggregates that are pointed to have slightly different encoding 487 rules in that you never encode the names of instance variables. */ 488 int ob_size = obstack_object_size (&util_obstack); 489 bool inline_contents = false; 490 bool pointed_to = false; 491 492 if (flag_next_runtime) 493 { 494 if (ob_size > 0 495 && *((char *) obstack_next_free (&util_obstack) - 1) == '^') 496 pointed_to = true; 497 498 if ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables) 499 && (!pointed_to || ob_size - curtype == 1 500 || (ob_size - curtype == 2 501 && *((char *) obstack_next_free (&util_obstack) - 2) == 'r'))) 502 inline_contents = true; 503 } 504 else 505 { 506 /* c0 and c1 are the last two characters in the encoding of the 507 current type; if the last two characters were '^' or '^r', 508 then we are encoding an aggregate that is "pointed to". The 509 comment above applies: in that case we should avoid encoding 510 the names of instance variables. 511 */ 512 char c0, c1; 513 514 c1 = ob_size > 1 ? *((char *) obstack_next_free (&util_obstack) - 2) : 0; 515 c0 = ob_size > 0 ? *((char *) obstack_next_free (&util_obstack) - 1) : 0; 516 if (c0 == '^' || (c1 == '^' && c0 == 'r')) 517 pointed_to = true; 518 519 if (format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables) 520 { 521 if (!pointed_to) 522 inline_contents = true; 523 else 524 { 525 /* Note that the check (ob_size - curtype < 2) prevents 526 infinite recursion when encoding a structure which is 527 a linked list (eg, struct node { struct node *next; 528 }). Each time we follow a pointer, we add one 529 character to ob_size, and curtype is fixed, so after 530 at most two pointers we stop inlining contents and 531 break the loop. 532 533 The other case where we don't inline is "^r", which 534 is a pointer to a constant struct. 535 */ 536 if ((ob_size - curtype <= 2) && !(c0 == 'r')) 537 inline_contents = true; 538 } 539 } 540 } 541 542 /* Traverse struct aliases; it is important to get the 543 original struct and its tag name (if any). */ 544 type = TYPE_MAIN_VARIANT (type); 545 name = OBJC_TYPE_NAME (type); 546 /* Open parenth/bracket. */ 547 obstack_1grow (&util_obstack, left); 548 549 /* Encode the struct/union tag name, or '?' if a tag was 550 not provided. Typedef aliases do not qualify. */ 551 #ifdef OBJCPLUS 552 /* For compatibility with the NeXT runtime, ObjC++ encodes template 553 args as a composite struct tag name. */ 554 if (name && TREE_CODE (name) == IDENTIFIER_NODE 555 /* Did this struct have a tag? */ 556 && !TYPE_WAS_ANONYMOUS (type)) 557 obstack_grow (&util_obstack, 558 decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME), 559 strlen (decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME))); 560 #else 561 if (name && TREE_CODE (name) == IDENTIFIER_NODE) 562 obstack_grow (&util_obstack, 563 IDENTIFIER_POINTER (name), 564 strlen (IDENTIFIER_POINTER (name))); 565 #endif 566 else 567 obstack_1grow (&util_obstack, '?'); 568 569 /* Encode the types (and possibly names) of the inner fields, 570 if required. */ 571 if (inline_contents) 572 { 573 obstack_1grow (&util_obstack, '='); 574 encode_aggregate_fields (type, pointed_to, curtype, format); 575 } 576 /* Close parenth/bracket. */ 577 obstack_1grow (&util_obstack, right); 578 } 579 580 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying 581 field type. */ 582 static void 583 encode_next_bitfield (int width) 584 { 585 char buffer[40]; 586 sprintf (buffer, "b%d", width); 587 obstack_grow (&util_obstack, buffer, strlen (buffer)); 588 } 589 590 /* Encodes 'type', ignoring type qualifiers (which you should encode 591 beforehand if needed) with the exception of 'const', which is 592 encoded by encode_type. See above for the explanation of 593 'curtype'. 'format' can be OBJC_ENCODE_INLINE_DEFS or 594 OBJC_ENCODE_DONT_INLINE_DEFS. */ 595 static void 596 encode_type (tree type, int curtype, int format) 597 { 598 enum tree_code code = TREE_CODE (type); 599 600 /* Ignore type qualifiers other than 'const' when encoding a 601 type. */ 602 603 if (type == error_mark_node) 604 return; 605 606 if (!flag_next_runtime) 607 { 608 if (TYPE_READONLY (type)) 609 obstack_1grow (&util_obstack, 'r'); 610 } 611 612 switch (code) 613 { 614 case ENUMERAL_TYPE: 615 if (flag_next_runtime) 616 { 617 /* Kludge for backwards-compatibility with gcc-3.3: enums 618 are always encoded as 'i' no matter what type they 619 actually are (!). */ 620 obstack_1grow (&util_obstack, 'i'); 621 break; 622 } 623 /* Else, they are encoded exactly like the integer type that is 624 used by the compiler to store them. */ 625 case INTEGER_TYPE: 626 { 627 char c; 628 switch (GET_MODE_BITSIZE (TYPE_MODE (type))) 629 { 630 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break; 631 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break; 632 case 32: 633 { 634 tree int_type = type; 635 if (flag_next_runtime) 636 { 637 /* Another legacy kludge for compatibility with 638 gcc-3.3: 32-bit longs are encoded as 'l' or 'L', 639 but not always. For typedefs, we need to use 'i' 640 or 'I' instead if encoding a struct field, or a 641 pointer! */ 642 int_type = ((!generating_instance_variables 643 && (obstack_object_size (&util_obstack) 644 == (unsigned) curtype)) 645 ? TYPE_MAIN_VARIANT (type) 646 : type); 647 } 648 if (int_type == long_unsigned_type_node 649 || int_type == long_integer_type_node) 650 c = TYPE_UNSIGNED (type) ? 'L' : 'l'; 651 else 652 c = TYPE_UNSIGNED (type) ? 'I' : 'i'; 653 } 654 break; 655 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break; 656 case 128: c = TYPE_UNSIGNED (type) ? 'T' : 't'; break; 657 default: gcc_unreachable (); 658 } 659 obstack_1grow (&util_obstack, c); 660 break; 661 } 662 case REAL_TYPE: 663 { 664 char c; 665 /* Floating point types. */ 666 switch (GET_MODE_BITSIZE (TYPE_MODE (type))) 667 { 668 case 32: c = 'f'; break; 669 case 64: c = 'd'; break; 670 case 96: 671 case 128: c = 'D'; break; 672 default: gcc_unreachable (); 673 } 674 obstack_1grow (&util_obstack, c); 675 break; 676 } 677 case VOID_TYPE: 678 obstack_1grow (&util_obstack, 'v'); 679 break; 680 681 case BOOLEAN_TYPE: 682 obstack_1grow (&util_obstack, 'B'); 683 break; 684 685 case ARRAY_TYPE: 686 encode_array (type, curtype, format); 687 break; 688 689 case POINTER_TYPE: 690 #ifdef OBJCPLUS 691 case REFERENCE_TYPE: 692 #endif 693 encode_pointer (type, curtype, format); 694 break; 695 696 case RECORD_TYPE: 697 encode_aggregate_within (type, curtype, format, '{', '}'); 698 break; 699 700 case UNION_TYPE: 701 encode_aggregate_within (type, curtype, format, '(', ')'); 702 break; 703 704 case FUNCTION_TYPE: /* '?' means an unknown type. */ 705 obstack_1grow (&util_obstack, '?'); 706 break; 707 708 case COMPLEX_TYPE: 709 /* A complex is encoded as 'j' followed by the inner type (eg, 710 "_Complex int" is encoded as 'ji'). */ 711 obstack_1grow (&util_obstack, 'j'); 712 encode_type (TREE_TYPE (type), curtype, format); 713 break; 714 715 case VECTOR_TYPE: 716 encode_vector (type, curtype, format); 717 break; 718 719 default: 720 warning (0, "unknown type %<%T%> found during Objective-C encoding", 721 TREE_TYPE (type)); 722 obstack_1grow (&util_obstack, '?'); 723 break; 724 } 725 726 if (flag_next_runtime) 727 { 728 /* Super-kludge. Some ObjC qualifier and type combinations need 729 to be rearranged for compatibility with gcc-3.3. */ 730 if (code == POINTER_TYPE && obstack_object_size (&util_obstack) >= 3) 731 { 732 char *enc = (char *) obstack_base (&util_obstack) + curtype; 733 734 /* Rewrite "in const" from "nr" to "rn". */ 735 if (curtype >= 1 && !strncmp (enc - 1, "nr", 2)) 736 strncpy (enc - 1, "rn", 2); 737 } 738 } 739 } 740 741 static void 742 encode_gnu_bitfield (int position, tree type, int size) 743 { 744 enum tree_code code = TREE_CODE (type); 745 char buffer[40]; 746 char charType = '?'; 747 748 /* This code is only executed for the GNU runtime, so we can ignore 749 the NeXT runtime kludge of always encoding enums as 'i' no matter 750 what integers they actually are. */ 751 if (code == INTEGER_TYPE || code == ENUMERAL_TYPE) 752 { 753 if (integer_zerop (TYPE_MIN_VALUE (type))) 754 /* Unsigned integer types. */ 755 { 756 switch (TYPE_MODE (type)) 757 { 758 case QImode: 759 charType = 'C'; break; 760 case HImode: 761 charType = 'S'; break; 762 case SImode: 763 { 764 if (type == long_unsigned_type_node) 765 charType = 'L'; 766 else 767 charType = 'I'; 768 break; 769 } 770 case DImode: 771 charType = 'Q'; break; 772 default: 773 gcc_unreachable (); 774 } 775 } 776 else 777 /* Signed integer types. */ 778 { 779 switch (TYPE_MODE (type)) 780 { 781 case QImode: 782 charType = 'c'; break; 783 case HImode: 784 charType = 's'; break; 785 case SImode: 786 { 787 if (type == long_integer_type_node) 788 charType = 'l'; 789 else 790 charType = 'i'; 791 break; 792 } 793 case DImode: 794 charType = 'q'; break; 795 default: 796 gcc_unreachable (); 797 } 798 } 799 } 800 else 801 { 802 /* Do not do any encoding, produce an error and keep going. */ 803 error ("trying to encode non-integer type as a bitfield"); 804 return; 805 } 806 807 sprintf (buffer, "b%d%c%d", position, charType, size); 808 obstack_grow (&util_obstack, buffer, strlen (buffer)); 809 } 810 811 static void 812 encode_field (tree field_decl, int curtype, int format) 813 { 814 #ifdef OBJCPLUS 815 /* C++ static members, and things that are not fields at all, 816 should not appear in the encoding. */ 817 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl)) 818 return; 819 #endif 820 821 /* Generate the bitfield typing information, if needed. Note the difference 822 between GNU and NeXT runtimes. */ 823 if (DECL_BIT_FIELD_TYPE (field_decl)) 824 { 825 int size = tree_to_uhwi (DECL_SIZE (field_decl)); 826 827 if (flag_next_runtime) 828 encode_next_bitfield (size); 829 else 830 encode_gnu_bitfield (int_bit_position (field_decl), 831 DECL_BIT_FIELD_TYPE (field_decl), size); 832 } 833 else 834 encode_type (TREE_TYPE (field_decl), curtype, format); 835 } 836 837 tree 838 encode_field_decl (tree field_decl) 839 { 840 tree result; 841 842 encode_field (field_decl, 843 obstack_object_size (&util_obstack), 844 OBJC_ENCODE_DONT_INLINE_DEFS); 845 846 /* Null terminate string. */ 847 obstack_1grow (&util_obstack, 0); 848 849 /* Get identifier for the string. */ 850 result = get_identifier (XOBFINISH (&util_obstack, char *)); 851 obstack_free (&util_obstack, util_firstobj); 852 853 return result; 854 } 855 856 /* This routine encodes the attribute of the input PROPERTY according 857 to following formula: 858 859 Property attributes are stored as a comma-delimited C string. 860 Simple attributes such as readonly are encoded as single 861 character. The parametrized attributes, getter=name and 862 setter=name, are encoded as a single character followed by an 863 identifier. Property types are also encoded as a parametrized 864 attribute. The characters used to encode these attributes are 865 defined by the following enumeration: 866 867 enum PropertyAttributes { 868 kPropertyReadOnly = 'R', 869 kPropertyBycopy = 'C', 870 kPropertyByref = '&', 871 kPropertyDynamic = 'D', 872 kPropertyGetter = 'G', 873 kPropertySetter = 'S', 874 kPropertyInstanceVariable = 'V', 875 kPropertyType = 'T', 876 kPropertyWeak = 'W', 877 kPropertyStrong = 'P', 878 kPropertyNonAtomic = 'N' 879 }; */ 880 tree 881 objc_v2_encode_prop_attr (tree property) 882 { 883 const char *string; 884 tree type = TREE_TYPE (property); 885 886 obstack_1grow (&util_obstack, 'T'); 887 encode_type (type, obstack_object_size (&util_obstack), 888 OBJC_ENCODE_INLINE_DEFS); 889 890 if (PROPERTY_READONLY (property)) 891 obstack_grow (&util_obstack, ",R", 2); 892 893 switch (PROPERTY_ASSIGN_SEMANTICS (property)) 894 { 895 case OBJC_PROPERTY_COPY: 896 obstack_grow (&util_obstack, ",C", 2); 897 break; 898 case OBJC_PROPERTY_RETAIN: 899 obstack_grow (&util_obstack, ",&", 2); 900 break; 901 case OBJC_PROPERTY_ASSIGN: 902 default: 903 break; 904 } 905 906 if (PROPERTY_DYNAMIC (property)) 907 obstack_grow (&util_obstack, ",D", 2); 908 909 if (PROPERTY_NONATOMIC (property)) 910 obstack_grow (&util_obstack, ",N", 2); 911 912 /* Here we want to encode the getter name, but only if it's not the 913 standard one. */ 914 if (PROPERTY_GETTER_NAME (property) != PROPERTY_NAME (property)) 915 { 916 obstack_grow (&util_obstack, ",G", 2); 917 string = IDENTIFIER_POINTER (PROPERTY_GETTER_NAME (property)); 918 obstack_grow (&util_obstack, string, strlen (string)); 919 } 920 921 if (!PROPERTY_READONLY (property)) 922 { 923 /* Here we want to encode the setter name, but only if it's not 924 the standard one. */ 925 tree standard_setter = get_identifier (objc_build_property_setter_name (PROPERTY_NAME (property))); 926 if (PROPERTY_SETTER_NAME (property) != standard_setter) 927 { 928 obstack_grow (&util_obstack, ",S", 2); 929 string = IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (property)); 930 obstack_grow (&util_obstack, string, strlen (string)); 931 } 932 } 933 934 /* TODO: Encode strong ('P'), weak ('W') for garbage collection. */ 935 936 if (!PROPERTY_DYNAMIC (property)) 937 { 938 obstack_grow (&util_obstack, ",V", 2); 939 if (PROPERTY_IVAR_NAME (property)) 940 string = IDENTIFIER_POINTER (PROPERTY_IVAR_NAME (property)); 941 else 942 string = IDENTIFIER_POINTER (PROPERTY_NAME (property)); 943 obstack_grow (&util_obstack, string, strlen (string)); 944 } 945 946 /* NULL-terminate string. */ 947 obstack_1grow (&util_obstack, 0); 948 string = XOBFINISH (&util_obstack, char *); 949 obstack_free (&util_obstack, util_firstobj); 950 return get_identifier (string); 951 } 952