1 1.1 mrg /* Encoding of types for Objective C. 2 1.15 mrg Copyright (C) 1993-2024 Free Software Foundation, Inc. 3 1.1 mrg Contributed by Kresten Krab Thorup 4 1.1 mrg Bitfield support by Ovidiu Predescu 5 1.1 mrg 6 1.1 mrg This file is part of GCC. 7 1.1 mrg 8 1.1 mrg GCC is free software; you can redistribute it and/or modify 9 1.1 mrg it under the terms of the GNU General Public License as published by 10 1.1 mrg the Free Software Foundation; either version 3, or (at your option) 11 1.1 mrg any later version. 12 1.1 mrg 13 1.1 mrg GCC is distributed in the hope that it will be useful, 14 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of 15 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 1.1 mrg GNU General Public License for more details. 17 1.1 mrg 18 1.1 mrg Under Section 7 of GPL version 3, you are granted additional 19 1.1 mrg permissions described in the GCC Runtime Library Exception, version 20 1.1 mrg 3.1, as published by the Free Software Foundation. 21 1.1 mrg 22 1.1 mrg You should have received a copy of the GNU General Public License and 23 1.1 mrg a copy of the GCC Runtime Library Exception along with this program; 24 1.1 mrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 25 1.1 mrg <http://www.gnu.org/licenses/>. */ 26 1.1 mrg 27 1.1 mrg /* FIXME: This file has no business including tm.h. */ 28 1.1 mrg 29 1.3 mrg /* FIXME: This file contains functions that will abort the entire 30 1.3 mrg program if they fail. Is that really needed ? */ 31 1.3 mrg 32 1.7 mrg #include "config.h" 33 1.3 mrg #include "objc-private/common.h" 34 1.3 mrg #include "objc-private/error.h" 35 1.1 mrg #include "tconfig.h" 36 1.1 mrg #include "coretypes.h" 37 1.1 mrg #include "tm.h" 38 1.3 mrg #include "objc/runtime.h" 39 1.3 mrg #include "objc-private/module-abi-8.h" /* For struct objc_method */ 40 1.1 mrg #include <stdlib.h> 41 1.3 mrg #include <ctype.h> 42 1.3 mrg #include <string.h> /* For memcpy. */ 43 1.1 mrg 44 1.1 mrg #undef MAX 45 1.1 mrg #define MAX(X, Y) \ 46 1.1 mrg ({ typeof (X) __x = (X), __y = (Y); \ 47 1.1 mrg (__x > __y ? __x : __y); }) 48 1.1 mrg 49 1.1 mrg #undef MIN 50 1.1 mrg #define MIN(X, Y) \ 51 1.1 mrg ({ typeof (X) __x = (X), __y = (Y); \ 52 1.1 mrg (__x < __y ? __x : __y); }) 53 1.1 mrg 54 1.1 mrg #undef ROUND 55 1.1 mrg #define ROUND(V, A) \ 56 1.1 mrg ({ typeof (V) __v = (V); typeof (A) __a = (A); \ 57 1.1 mrg __a * ((__v+__a - 1)/__a); }) 58 1.1 mrg 59 1.1 mrg 60 1.1 mrg /* Various hacks for objc_layout_record. These are used by the target 61 1.1 mrg macros. */ 62 1.1 mrg 63 1.1 mrg #define TREE_CODE(TYPE) *(TYPE) 64 1.1 mrg #define TREE_TYPE(TREE) (TREE) 65 1.1 mrg 66 1.1 mrg #define RECORD_TYPE _C_STRUCT_B 67 1.1 mrg #define UNION_TYPE _C_UNION_B 68 1.1 mrg #define QUAL_UNION_TYPE _C_UNION_B 69 1.1 mrg #define ARRAY_TYPE _C_ARY_B 70 1.15 mrg #define RECORD_OR_UNION_TYPE_P(TYPE) \ 71 1.15 mrg ((TREE_CODE (TYPE) == RECORD_TYPE) \ 72 1.15 mrg || (TREE_CODE (TYPE) == UNION_TYPE) \ 73 1.15 mrg || (TREE_CODE (TYPE) == QUAL_UNION_TYPE)) 74 1.15 mrg #define VECTOR_TYPE_P(TYPE) (TREE_CODE (TYPE) == VECTOR_TYPE) 75 1.1 mrg 76 1.1 mrg #define REAL_TYPE _C_DBL 77 1.1 mrg 78 1.1 mrg #define VECTOR_TYPE _C_VECTOR 79 1.1 mrg 80 1.1 mrg #define TYPE_FIELDS(TYPE) ({const char *_field = (TYPE)+1; \ 81 1.1 mrg while (*_field != _C_STRUCT_E && *_field != _C_STRUCT_B \ 82 1.1 mrg && *_field != _C_UNION_B && *_field++ != '=') \ 83 1.1 mrg /* do nothing */; \ 84 1.1 mrg _field;}) 85 1.1 mrg 86 1.1 mrg #define DECL_MODE(TYPE) *(TYPE) 87 1.1 mrg #define TYPE_MODE(TYPE) *(TYPE) 88 1.1 mrg 89 1.12 mrg #undef DFmode 90 1.1 mrg #define DFmode _C_DBL 91 1.1 mrg 92 1.1 mrg #define strip_array_types(TYPE) ({const char *_field = (TYPE); \ 93 1.1 mrg while (*_field == _C_ARY_B)\ 94 1.1 mrg {\ 95 1.1 mrg while (isdigit ((unsigned char)*++_field))\ 96 1.1 mrg ;\ 97 1.1 mrg }\ 98 1.1 mrg _field;}) 99 1.1 mrg 100 1.1 mrg /* Some ports (eg ARM) allow the structure size boundary to be 101 1.1 mrg selected at compile-time. We override the normal definition with 102 1.1 mrg one that has a constant value for this compilation. */ 103 1.1 mrg #undef STRUCTURE_SIZE_BOUNDARY 104 1.7 mrg #define STRUCTURE_SIZE_BOUNDARY (__CHAR_BIT__ * sizeof (struct{char a;})) 105 1.1 mrg 106 1.1 mrg /* Some ROUND_TYPE_ALIGN macros use TARGET_foo, and consequently 107 1.1 mrg target_flags. Define a dummy entry here to so we don't die. 108 1.1 mrg We have to rename it because target_flags may already have been 109 1.1 mrg declared extern. */ 110 1.1 mrg #define target_flags not_target_flags 111 1.1 mrg static int __attribute__ ((__unused__)) not_target_flags = 0; 112 1.1 mrg 113 1.1 mrg /* Some ROUND_TYPE_ALIGN use ALTIVEC_VECTOR_MODE (rs6000 darwin). 114 1.1 mrg Define a dummy ALTIVEC_VECTOR_MODE so it will not die. */ 115 1.1 mrg #undef ALTIVEC_VECTOR_MODE 116 1.1 mrg #define ALTIVEC_VECTOR_MODE(MODE) (0) 117 1.1 mrg 118 1.3 mrg /* Replace TARGET_VSX, TARGET_ALTIVEC, and TARGET_64BIT with constants based on 119 1.3 mrg the current switches, rather than looking in the options structure. */ 120 1.3 mrg #ifdef _ARCH_PPC 121 1.3 mrg #undef TARGET_VSX 122 1.3 mrg #undef TARGET_ALTIVEC 123 1.3 mrg #undef TARGET_64BIT 124 1.3 mrg 125 1.3 mrg #ifdef __VSX__ 126 1.3 mrg #define TARGET_VSX 1 127 1.3 mrg #else 128 1.3 mrg #define TARGET_VSX 0 129 1.3 mrg #endif 130 1.3 mrg 131 1.3 mrg #ifdef __ALTIVEC__ 132 1.3 mrg #define TARGET_ALTIVEC 1 133 1.3 mrg #else 134 1.3 mrg #define TARGET_ALTIVEC 0 135 1.3 mrg #endif 136 1.3 mrg 137 1.3 mrg #ifdef _ARCH_PPC64 138 1.3 mrg #define TARGET_64BIT 1 139 1.3 mrg #else 140 1.3 mrg #define TARGET_64BIT 0 141 1.3 mrg #endif 142 1.3 mrg #endif 143 1.3 mrg 144 1.3 mrg /* Furthermore, some (powerpc) targets also use TARGET_ALIGN_NATURAL 145 1.3 mrg in their alignment macros. Currently[4.5/6], rs6000.h points this 146 1.3 mrg to a static variable, initialized by target overrides. This is reset 147 1.3 mrg in linux64.h but not in darwin64.h. The macro is not used by *86*. */ 148 1.3 mrg 149 1.3 mrg #if __MACH__ 150 1.3 mrg # if __LP64__ 151 1.3 mrg # undef TARGET_ALIGN_NATURAL 152 1.3 mrg # define TARGET_ALIGN_NATURAL 1 153 1.3 mrg # endif 154 1.3 mrg /* On Darwin32, we need to recurse until we find the starting stuct type. */ 155 1.3 mrg static int 156 1.3 mrg _darwin_rs6000_special_round_type_align (const char *struc, int comp, int spec) 157 1.3 mrg { 158 1.3 mrg const char *_stp , *_fields = TYPE_FIELDS (struc); 159 1.3 mrg if (!_fields) 160 1.3 mrg return MAX (comp, spec); 161 1.3 mrg _stp = strip_array_types (_fields); 162 1.3 mrg if (TYPE_MODE(_stp) == _C_COMPLEX) 163 1.3 mrg _stp++; 164 1.3 mrg switch (TYPE_MODE(_stp)) 165 1.3 mrg { 166 1.3 mrg case RECORD_TYPE: 167 1.3 mrg case UNION_TYPE: 168 1.7 mrg return MAX (MAX (comp, spec), objc_alignof_type (_stp) * __CHAR_BIT__); 169 1.3 mrg break; 170 1.13 mrg case DFmode: 171 1.3 mrg case _C_LNG_LNG: 172 1.3 mrg case _C_ULNG_LNG: 173 1.3 mrg return MAX (MAX (comp, spec), 64); 174 1.3 mrg break; 175 1.3 mrg 176 1.3 mrg default: 177 1.3 mrg return MAX (comp, spec); 178 1.3 mrg break; 179 1.3 mrg } 180 1.3 mrg } 181 1.3 mrg 182 1.3 mrg /* See comment below. */ 183 1.3 mrg #define darwin_rs6000_special_round_type_align(S,C,S2) \ 184 1.3 mrg (_darwin_rs6000_special_round_type_align ((char*)(S), (int)(C), (int)(S2))) 185 1.3 mrg #endif 186 1.1 mrg 187 1.1 mrg /* FIXME: while this file has no business including tm.h, this 188 1.1 mrg definitely has no business defining this macro but it 189 1.1 mrg is only way around without really rewritting this file, 190 1.3 mrg should look after the branch of 3.4 to fix this. */ 191 1.1 mrg #define rs6000_special_round_type_align(STRUCT, COMPUTED, SPECIFIED) \ 192 1.3 mrg ({ const char *_fields = TYPE_FIELDS (STRUCT); \ 193 1.1 mrg ((_fields != 0 \ 194 1.1 mrg && TYPE_MODE (strip_array_types (TREE_TYPE (_fields))) == DFmode) \ 195 1.1 mrg ? MAX (MAX (COMPUTED, SPECIFIED), 64) \ 196 1.1 mrg : MAX (COMPUTED, SPECIFIED));}) 197 1.1 mrg 198 1.6 mrg #define rs6000_special_adjust_field_align_p(FIELD, COMPUTED) 0 199 1.1 mrg 200 1.3 mrg /* Skip a variable name, enclosed in quotes ("). */ 201 1.3 mrg static inline 202 1.3 mrg const char * 203 1.3 mrg objc_skip_variable_name (const char *type) 204 1.1 mrg { 205 1.3 mrg /* Skip the variable name if any. */ 206 1.1 mrg if (*type == '"') 207 1.1 mrg { 208 1.3 mrg /* FIXME: How do we know we won't read beyond the end of the 209 1.3 mrg string. Here and in the rest of the file! */ 210 1.3 mrg /* Skip '"'. */ 211 1.3 mrg type++; 212 1.3 mrg /* Skip to the next '"'. */ 213 1.3 mrg while (*type != '"') 214 1.3 mrg type++; 215 1.3 mrg /* Skip '"'. */ 216 1.3 mrg type++; 217 1.1 mrg } 218 1.1 mrg 219 1.3 mrg return type; 220 1.3 mrg } 221 1.3 mrg 222 1.3 mrg int 223 1.3 mrg objc_sizeof_type (const char *type) 224 1.3 mrg { 225 1.3 mrg type = objc_skip_variable_name (type); 226 1.3 mrg 227 1.1 mrg switch (*type) { 228 1.1 mrg case _C_BOOL: 229 1.1 mrg return sizeof (_Bool); 230 1.1 mrg break; 231 1.1 mrg 232 1.1 mrg case _C_ID: 233 1.1 mrg return sizeof (id); 234 1.1 mrg break; 235 1.1 mrg 236 1.1 mrg case _C_CLASS: 237 1.1 mrg return sizeof (Class); 238 1.1 mrg break; 239 1.1 mrg 240 1.1 mrg case _C_SEL: 241 1.1 mrg return sizeof (SEL); 242 1.1 mrg break; 243 1.1 mrg 244 1.1 mrg case _C_CHR: 245 1.1 mrg return sizeof (char); 246 1.1 mrg break; 247 1.1 mrg 248 1.1 mrg case _C_UCHR: 249 1.1 mrg return sizeof (unsigned char); 250 1.1 mrg break; 251 1.1 mrg 252 1.1 mrg case _C_SHT: 253 1.1 mrg return sizeof (short); 254 1.1 mrg break; 255 1.1 mrg 256 1.1 mrg case _C_USHT: 257 1.1 mrg return sizeof (unsigned short); 258 1.1 mrg break; 259 1.1 mrg 260 1.1 mrg case _C_INT: 261 1.1 mrg return sizeof (int); 262 1.1 mrg break; 263 1.1 mrg 264 1.1 mrg case _C_UINT: 265 1.1 mrg return sizeof (unsigned int); 266 1.1 mrg break; 267 1.1 mrg 268 1.1 mrg case _C_LNG: 269 1.1 mrg return sizeof (long); 270 1.1 mrg break; 271 1.1 mrg 272 1.1 mrg case _C_ULNG: 273 1.1 mrg return sizeof (unsigned long); 274 1.1 mrg break; 275 1.1 mrg 276 1.1 mrg case _C_LNG_LNG: 277 1.1 mrg return sizeof (long long); 278 1.1 mrg break; 279 1.1 mrg 280 1.1 mrg case _C_ULNG_LNG: 281 1.1 mrg return sizeof (unsigned long long); 282 1.1 mrg break; 283 1.1 mrg 284 1.1 mrg case _C_FLT: 285 1.1 mrg return sizeof (float); 286 1.1 mrg break; 287 1.1 mrg 288 1.1 mrg case _C_DBL: 289 1.1 mrg return sizeof (double); 290 1.1 mrg break; 291 1.1 mrg 292 1.3 mrg case _C_LNG_DBL: 293 1.3 mrg return sizeof (long double); 294 1.3 mrg break; 295 1.3 mrg 296 1.1 mrg case _C_VOID: 297 1.1 mrg return sizeof (void); 298 1.1 mrg break; 299 1.1 mrg 300 1.1 mrg case _C_PTR: 301 1.1 mrg case _C_ATOM: 302 1.1 mrg case _C_CHARPTR: 303 1.1 mrg return sizeof (char *); 304 1.1 mrg break; 305 1.1 mrg 306 1.1 mrg case _C_ARY_B: 307 1.1 mrg { 308 1.1 mrg int len = atoi (type + 1); 309 1.1 mrg while (isdigit ((unsigned char)*++type)) 310 1.1 mrg ; 311 1.1 mrg return len * objc_aligned_size (type); 312 1.1 mrg } 313 1.1 mrg break; 314 1.1 mrg 315 1.3 mrg case _C_VECTOR: 316 1.3 mrg { 317 1.3 mrg /* Skip the '!'. */ 318 1.3 mrg type++; 319 1.3 mrg /* Skip the '['. */ 320 1.3 mrg type++; 321 1.3 mrg 322 1.3 mrg /* The size in bytes is the following number. */ 323 1.3 mrg int size = atoi (type); 324 1.3 mrg return size; 325 1.3 mrg } 326 1.3 mrg break; 327 1.3 mrg 328 1.1 mrg case _C_BFLD: 329 1.1 mrg { 330 1.3 mrg /* The GNU encoding of bitfields is: b 'position' 'type' 331 1.3 mrg 'size'. */ 332 1.1 mrg int position, size; 333 1.1 mrg int startByte, endByte; 334 1.1 mrg 335 1.1 mrg position = atoi (type + 1); 336 1.1 mrg while (isdigit ((unsigned char)*++type)) 337 1.1 mrg ; 338 1.1 mrg size = atoi (type + 1); 339 1.1 mrg 340 1.7 mrg startByte = position / __CHAR_BIT__; 341 1.7 mrg endByte = (position + size) / __CHAR_BIT__; 342 1.1 mrg return endByte - startByte; 343 1.1 mrg } 344 1.1 mrg 345 1.1 mrg case _C_UNION_B: 346 1.1 mrg case _C_STRUCT_B: 347 1.1 mrg { 348 1.1 mrg struct objc_struct_layout layout; 349 1.1 mrg unsigned int size; 350 1.1 mrg 351 1.1 mrg objc_layout_structure (type, &layout); 352 1.1 mrg while (objc_layout_structure_next_member (&layout)) 353 1.1 mrg /* do nothing */ ; 354 1.1 mrg objc_layout_finish_structure (&layout, &size, NULL); 355 1.1 mrg 356 1.1 mrg return size; 357 1.1 mrg } 358 1.1 mrg 359 1.1 mrg case _C_COMPLEX: 360 1.1 mrg { 361 1.1 mrg type++; /* Skip after the 'j'. */ 362 1.1 mrg switch (*type) 363 1.1 mrg { 364 1.1 mrg case _C_CHR: 365 1.1 mrg return sizeof (_Complex char); 366 1.1 mrg break; 367 1.1 mrg 368 1.1 mrg case _C_UCHR: 369 1.1 mrg return sizeof (_Complex unsigned char); 370 1.1 mrg break; 371 1.1 mrg 372 1.1 mrg case _C_SHT: 373 1.1 mrg return sizeof (_Complex short); 374 1.1 mrg break; 375 1.1 mrg 376 1.1 mrg case _C_USHT: 377 1.1 mrg return sizeof (_Complex unsigned short); 378 1.1 mrg break; 379 1.1 mrg 380 1.1 mrg case _C_INT: 381 1.1 mrg return sizeof (_Complex int); 382 1.1 mrg break; 383 1.1 mrg 384 1.1 mrg case _C_UINT: 385 1.1 mrg return sizeof (_Complex unsigned int); 386 1.1 mrg break; 387 1.1 mrg 388 1.1 mrg case _C_LNG: 389 1.1 mrg return sizeof (_Complex long); 390 1.1 mrg break; 391 1.1 mrg 392 1.1 mrg case _C_ULNG: 393 1.1 mrg return sizeof (_Complex unsigned long); 394 1.1 mrg break; 395 1.1 mrg 396 1.1 mrg case _C_LNG_LNG: 397 1.1 mrg return sizeof (_Complex long long); 398 1.1 mrg break; 399 1.1 mrg 400 1.1 mrg case _C_ULNG_LNG: 401 1.1 mrg return sizeof (_Complex unsigned long long); 402 1.1 mrg break; 403 1.1 mrg 404 1.1 mrg case _C_FLT: 405 1.1 mrg return sizeof (_Complex float); 406 1.1 mrg break; 407 1.1 mrg 408 1.1 mrg case _C_DBL: 409 1.1 mrg return sizeof (_Complex double); 410 1.1 mrg break; 411 1.3 mrg 412 1.3 mrg case _C_LNG_DBL: 413 1.3 mrg return sizeof (_Complex long double); 414 1.3 mrg break; 415 1.1 mrg 416 1.1 mrg default: 417 1.1 mrg { 418 1.3 mrg /* FIXME: Is this so bad that we have to abort the 419 1.3 mrg entire program ? (it applies to all the other 420 1.3 mrg _objc_abort calls in this file). 421 1.3 mrg */ 422 1.3 mrg _objc_abort ("unknown complex type %s\n", type); 423 1.1 mrg return 0; 424 1.1 mrg } 425 1.1 mrg } 426 1.1 mrg } 427 1.1 mrg 428 1.1 mrg default: 429 1.1 mrg { 430 1.3 mrg _objc_abort ("unknown type %s\n", type); 431 1.1 mrg return 0; 432 1.1 mrg } 433 1.1 mrg } 434 1.1 mrg } 435 1.1 mrg 436 1.1 mrg int 437 1.1 mrg objc_alignof_type (const char *type) 438 1.1 mrg { 439 1.3 mrg type = objc_skip_variable_name (type); 440 1.3 mrg 441 1.1 mrg switch (*type) { 442 1.1 mrg case _C_BOOL: 443 1.1 mrg return __alignof__ (_Bool); 444 1.1 mrg break; 445 1.1 mrg 446 1.1 mrg case _C_ID: 447 1.1 mrg return __alignof__ (id); 448 1.1 mrg break; 449 1.1 mrg 450 1.1 mrg case _C_CLASS: 451 1.1 mrg return __alignof__ (Class); 452 1.1 mrg break; 453 1.1 mrg 454 1.1 mrg case _C_SEL: 455 1.1 mrg return __alignof__ (SEL); 456 1.1 mrg break; 457 1.1 mrg 458 1.1 mrg case _C_CHR: 459 1.1 mrg return __alignof__ (char); 460 1.1 mrg break; 461 1.1 mrg 462 1.1 mrg case _C_UCHR: 463 1.1 mrg return __alignof__ (unsigned char); 464 1.1 mrg break; 465 1.1 mrg 466 1.1 mrg case _C_SHT: 467 1.1 mrg return __alignof__ (short); 468 1.1 mrg break; 469 1.1 mrg 470 1.1 mrg case _C_USHT: 471 1.1 mrg return __alignof__ (unsigned short); 472 1.1 mrg break; 473 1.1 mrg 474 1.1 mrg case _C_INT: 475 1.1 mrg return __alignof__ (int); 476 1.1 mrg break; 477 1.1 mrg 478 1.1 mrg case _C_UINT: 479 1.1 mrg return __alignof__ (unsigned int); 480 1.1 mrg break; 481 1.1 mrg 482 1.1 mrg case _C_LNG: 483 1.1 mrg return __alignof__ (long); 484 1.1 mrg break; 485 1.1 mrg 486 1.1 mrg case _C_ULNG: 487 1.1 mrg return __alignof__ (unsigned long); 488 1.1 mrg break; 489 1.1 mrg 490 1.1 mrg case _C_LNG_LNG: 491 1.1 mrg return __alignof__ (long long); 492 1.1 mrg break; 493 1.1 mrg 494 1.1 mrg case _C_ULNG_LNG: 495 1.1 mrg return __alignof__ (unsigned long long); 496 1.1 mrg break; 497 1.1 mrg 498 1.1 mrg case _C_FLT: 499 1.1 mrg return __alignof__ (float); 500 1.1 mrg break; 501 1.1 mrg 502 1.1 mrg case _C_DBL: 503 1.1 mrg return __alignof__ (double); 504 1.1 mrg break; 505 1.1 mrg 506 1.3 mrg case _C_LNG_DBL: 507 1.3 mrg return __alignof__ (long double); 508 1.3 mrg break; 509 1.3 mrg 510 1.1 mrg case _C_PTR: 511 1.1 mrg case _C_ATOM: 512 1.1 mrg case _C_CHARPTR: 513 1.1 mrg return __alignof__ (char *); 514 1.1 mrg break; 515 1.1 mrg 516 1.1 mrg case _C_ARY_B: 517 1.1 mrg while (isdigit ((unsigned char)*++type)) 518 1.1 mrg /* do nothing */; 519 1.1 mrg return objc_alignof_type (type); 520 1.1 mrg 521 1.3 mrg case _C_VECTOR: 522 1.3 mrg { 523 1.3 mrg /* Skip the '!'. */ 524 1.3 mrg type++; 525 1.3 mrg /* Skip the '['. */ 526 1.3 mrg type++; 527 1.3 mrg 528 1.3 mrg /* Skip the size. */ 529 1.3 mrg while (isdigit ((unsigned char)*type)) 530 1.3 mrg type++; 531 1.3 mrg 532 1.3 mrg /* Skip the ','. */ 533 1.3 mrg type++; 534 1.3 mrg 535 1.3 mrg /* The alignment in bytes is the following number. */ 536 1.3 mrg return atoi (type); 537 1.3 mrg } 538 1.1 mrg case _C_STRUCT_B: 539 1.1 mrg case _C_UNION_B: 540 1.1 mrg { 541 1.1 mrg struct objc_struct_layout layout; 542 1.1 mrg unsigned int align; 543 1.1 mrg 544 1.1 mrg objc_layout_structure (type, &layout); 545 1.1 mrg while (objc_layout_structure_next_member (&layout)) 546 1.1 mrg /* do nothing */; 547 1.1 mrg objc_layout_finish_structure (&layout, NULL, &align); 548 1.1 mrg 549 1.1 mrg return align; 550 1.1 mrg } 551 1.1 mrg 552 1.1 mrg 553 1.1 mrg case _C_COMPLEX: 554 1.1 mrg { 555 1.1 mrg type++; /* Skip after the 'j'. */ 556 1.1 mrg switch (*type) 557 1.1 mrg { 558 1.1 mrg case _C_CHR: 559 1.1 mrg return __alignof__ (_Complex char); 560 1.1 mrg break; 561 1.1 mrg 562 1.1 mrg case _C_UCHR: 563 1.1 mrg return __alignof__ (_Complex unsigned char); 564 1.1 mrg break; 565 1.1 mrg 566 1.1 mrg case _C_SHT: 567 1.1 mrg return __alignof__ (_Complex short); 568 1.1 mrg break; 569 1.1 mrg 570 1.1 mrg case _C_USHT: 571 1.1 mrg return __alignof__ (_Complex unsigned short); 572 1.1 mrg break; 573 1.1 mrg 574 1.1 mrg case _C_INT: 575 1.1 mrg return __alignof__ (_Complex int); 576 1.1 mrg break; 577 1.1 mrg 578 1.1 mrg case _C_UINT: 579 1.1 mrg return __alignof__ (_Complex unsigned int); 580 1.1 mrg break; 581 1.1 mrg 582 1.1 mrg case _C_LNG: 583 1.1 mrg return __alignof__ (_Complex long); 584 1.1 mrg break; 585 1.1 mrg 586 1.1 mrg case _C_ULNG: 587 1.1 mrg return __alignof__ (_Complex unsigned long); 588 1.1 mrg break; 589 1.1 mrg 590 1.1 mrg case _C_LNG_LNG: 591 1.1 mrg return __alignof__ (_Complex long long); 592 1.1 mrg break; 593 1.1 mrg 594 1.1 mrg case _C_ULNG_LNG: 595 1.1 mrg return __alignof__ (_Complex unsigned long long); 596 1.1 mrg break; 597 1.1 mrg 598 1.1 mrg case _C_FLT: 599 1.1 mrg return __alignof__ (_Complex float); 600 1.1 mrg break; 601 1.1 mrg 602 1.1 mrg case _C_DBL: 603 1.1 mrg return __alignof__ (_Complex double); 604 1.1 mrg break; 605 1.3 mrg 606 1.3 mrg case _C_LNG_DBL: 607 1.3 mrg return __alignof__ (_Complex long double); 608 1.3 mrg break; 609 1.1 mrg 610 1.1 mrg default: 611 1.1 mrg { 612 1.3 mrg _objc_abort ("unknown complex type %s\n", type); 613 1.1 mrg return 0; 614 1.1 mrg } 615 1.1 mrg } 616 1.1 mrg } 617 1.1 mrg 618 1.1 mrg default: 619 1.1 mrg { 620 1.3 mrg _objc_abort ("unknown type %s\n", type); 621 1.1 mrg return 0; 622 1.1 mrg } 623 1.1 mrg } 624 1.1 mrg } 625 1.1 mrg 626 1.1 mrg int 627 1.1 mrg objc_aligned_size (const char *type) 628 1.1 mrg { 629 1.1 mrg int size, align; 630 1.1 mrg 631 1.3 mrg type = objc_skip_variable_name (type); 632 1.1 mrg size = objc_sizeof_type (type); 633 1.1 mrg align = objc_alignof_type (type); 634 1.1 mrg 635 1.1 mrg return ROUND (size, align); 636 1.1 mrg } 637 1.1 mrg 638 1.1 mrg int 639 1.1 mrg objc_promoted_size (const char *type) 640 1.1 mrg { 641 1.1 mrg int size, wordsize; 642 1.1 mrg 643 1.3 mrg type = objc_skip_variable_name (type); 644 1.1 mrg size = objc_sizeof_type (type); 645 1.1 mrg wordsize = sizeof (void *); 646 1.1 mrg 647 1.1 mrg return ROUND (size, wordsize); 648 1.1 mrg } 649 1.1 mrg 650 1.1 mrg /* 651 1.1 mrg Skip type qualifiers. These may eventually precede typespecs 652 1.1 mrg occurring in method prototype encodings. 653 1.1 mrg */ 654 1.1 mrg 655 1.2 joerg const char * 656 1.1 mrg objc_skip_type_qualifiers (const char *type) 657 1.1 mrg { 658 1.1 mrg while (*type == _C_CONST 659 1.1 mrg || *type == _C_IN 660 1.1 mrg || *type == _C_INOUT 661 1.1 mrg || *type == _C_OUT 662 1.1 mrg || *type == _C_BYCOPY 663 1.1 mrg || *type == _C_BYREF 664 1.1 mrg || *type == _C_ONEWAY 665 1.1 mrg || *type == _C_GCINVISIBLE) 666 1.1 mrg { 667 1.1 mrg type += 1; 668 1.1 mrg } 669 1.1 mrg return type; 670 1.1 mrg } 671 1.1 mrg 672 1.1 mrg const char * 673 1.1 mrg objc_skip_typespec (const char *type) 674 1.1 mrg { 675 1.3 mrg type = objc_skip_variable_name (type); 676 1.1 mrg type = objc_skip_type_qualifiers (type); 677 1.1 mrg 678 1.1 mrg switch (*type) { 679 1.1 mrg 680 1.1 mrg case _C_ID: 681 1.1 mrg /* An id may be annotated by the actual type if it is known 682 1.1 mrg with the @"ClassName" syntax */ 683 1.1 mrg 684 1.1 mrg if (*++type != '"') 685 1.1 mrg return type; 686 1.1 mrg else 687 1.1 mrg { 688 1.1 mrg while (*++type != '"') 689 1.1 mrg /* do nothing */; 690 1.1 mrg return type + 1; 691 1.1 mrg } 692 1.1 mrg 693 1.1 mrg /* The following are one character type codes */ 694 1.1 mrg case _C_CLASS: 695 1.1 mrg case _C_SEL: 696 1.1 mrg case _C_CHR: 697 1.1 mrg case _C_UCHR: 698 1.1 mrg case _C_CHARPTR: 699 1.1 mrg case _C_ATOM: 700 1.1 mrg case _C_SHT: 701 1.1 mrg case _C_USHT: 702 1.1 mrg case _C_INT: 703 1.1 mrg case _C_UINT: 704 1.1 mrg case _C_LNG: 705 1.1 mrg case _C_BOOL: 706 1.1 mrg case _C_ULNG: 707 1.1 mrg case _C_LNG_LNG: 708 1.1 mrg case _C_ULNG_LNG: 709 1.1 mrg case _C_FLT: 710 1.1 mrg case _C_DBL: 711 1.3 mrg case _C_LNG_DBL: 712 1.1 mrg case _C_VOID: 713 1.1 mrg case _C_UNDEF: 714 1.1 mrg return ++type; 715 1.1 mrg break; 716 1.1 mrg 717 1.1 mrg case _C_COMPLEX: 718 1.1 mrg return type + 2; 719 1.1 mrg break; 720 1.1 mrg 721 1.1 mrg case _C_ARY_B: 722 1.1 mrg /* skip digits, typespec and closing ']' */ 723 1.1 mrg while (isdigit ((unsigned char)*++type)) 724 1.1 mrg ; 725 1.1 mrg type = objc_skip_typespec (type); 726 1.1 mrg if (*type == _C_ARY_E) 727 1.1 mrg return ++type; 728 1.1 mrg else 729 1.1 mrg { 730 1.3 mrg _objc_abort ("bad array type %s\n", type); 731 1.3 mrg return 0; 732 1.3 mrg } 733 1.3 mrg 734 1.3 mrg case _C_VECTOR: 735 1.3 mrg /* Skip '!' */ 736 1.3 mrg type++; 737 1.3 mrg /* Skip '[' */ 738 1.3 mrg type++; 739 1.3 mrg /* Skip digits (size) */ 740 1.3 mrg while (isdigit ((unsigned char)*type)) 741 1.3 mrg type++; 742 1.3 mrg /* Skip ',' */ 743 1.3 mrg type++; 744 1.3 mrg /* Skip digits (alignment) */ 745 1.3 mrg while (isdigit ((unsigned char)*type)) 746 1.3 mrg type++; 747 1.3 mrg /* Skip typespec. */ 748 1.3 mrg type = objc_skip_typespec (type); 749 1.3 mrg /* Skip closing ']'. */ 750 1.3 mrg if (*type == _C_ARY_E) 751 1.3 mrg return ++type; 752 1.3 mrg else 753 1.3 mrg { 754 1.3 mrg _objc_abort ("bad vector type %s\n", type); 755 1.1 mrg return 0; 756 1.1 mrg } 757 1.1 mrg 758 1.1 mrg case _C_BFLD: 759 1.3 mrg /* The GNU encoding of bitfields is: b 'position' 'type' 760 1.3 mrg 'size'. */ 761 1.1 mrg while (isdigit ((unsigned char)*++type)) 762 1.1 mrg ; /* skip position */ 763 1.1 mrg while (isdigit ((unsigned char)*++type)) 764 1.1 mrg ; /* skip type and size */ 765 1.1 mrg return type; 766 1.1 mrg 767 1.1 mrg case _C_STRUCT_B: 768 1.1 mrg /* skip name, and elements until closing '}' */ 769 1.1 mrg 770 1.1 mrg while (*type != _C_STRUCT_E && *type++ != '=') 771 1.1 mrg ; 772 1.1 mrg while (*type != _C_STRUCT_E) 773 1.1 mrg { 774 1.1 mrg type = objc_skip_typespec (type); 775 1.1 mrg } 776 1.1 mrg return ++type; 777 1.1 mrg 778 1.1 mrg case _C_UNION_B: 779 1.1 mrg /* skip name, and elements until closing ')' */ 780 1.1 mrg 781 1.1 mrg while (*type != _C_UNION_E && *type++ != '=') 782 1.1 mrg ; 783 1.1 mrg while (*type != _C_UNION_E) 784 1.1 mrg { 785 1.1 mrg type = objc_skip_typespec (type); 786 1.1 mrg } 787 1.1 mrg return ++type; 788 1.1 mrg 789 1.1 mrg case _C_PTR: 790 1.1 mrg /* Just skip the following typespec */ 791 1.1 mrg 792 1.1 mrg return objc_skip_typespec (++type); 793 1.1 mrg 794 1.1 mrg default: 795 1.1 mrg { 796 1.3 mrg _objc_abort ("unknown type %s\n", type); 797 1.1 mrg return 0; 798 1.1 mrg } 799 1.1 mrg } 800 1.1 mrg } 801 1.1 mrg 802 1.1 mrg /* 803 1.1 mrg Skip an offset as part of a method encoding. This is prepended by a 804 1.1 mrg '+' if the argument is passed in registers. 805 1.1 mrg */ 806 1.2 joerg const char * 807 1.1 mrg objc_skip_offset (const char *type) 808 1.1 mrg { 809 1.3 mrg /* The offset is prepended by a '+' if the argument is passed in 810 1.3 mrg registers. PS: The compiler stopped generating this '+' in 811 1.3 mrg version 3.4. */ 812 1.1 mrg if (*type == '+') 813 1.1 mrg type++; 814 1.3 mrg 815 1.3 mrg /* Some people claim that on some platforms, where the stack grows 816 1.3 mrg backwards, the compiler generates negative offsets (??). Skip a 817 1.3 mrg '-' for such a negative offset. */ 818 1.3 mrg if (*type == '-') 819 1.3 mrg type++; 820 1.3 mrg 821 1.3 mrg /* Skip the digits that represent the offset. */ 822 1.3 mrg while (isdigit ((unsigned char) *type)) 823 1.3 mrg type++; 824 1.3 mrg 825 1.1 mrg return type; 826 1.1 mrg } 827 1.1 mrg 828 1.1 mrg const char * 829 1.1 mrg objc_skip_argspec (const char *type) 830 1.1 mrg { 831 1.1 mrg type = objc_skip_typespec (type); 832 1.1 mrg type = objc_skip_offset (type); 833 1.1 mrg return type; 834 1.1 mrg } 835 1.1 mrg 836 1.3 mrg char * 837 1.3 mrg method_copyReturnType (struct objc_method *method) 838 1.1 mrg { 839 1.3 mrg if (method == NULL) 840 1.3 mrg return 0; 841 1.3 mrg else 842 1.1 mrg { 843 1.3 mrg char *returnValue; 844 1.3 mrg size_t returnValueSize; 845 1.3 mrg 846 1.3 mrg /* Determine returnValueSize. */ 847 1.3 mrg { 848 1.3 mrg /* Find the end of the first argument. We want to return the 849 1.3 mrg first argument spec, plus 1 byte for the \0 at the end. */ 850 1.3 mrg const char *type = method->method_types; 851 1.3 mrg if (*type == '\0') 852 1.3 mrg return NULL; 853 1.3 mrg type = objc_skip_argspec (type); 854 1.3 mrg returnValueSize = type - method->method_types + 1; 855 1.3 mrg } 856 1.3 mrg 857 1.3 mrg /* Copy the first argument into returnValue. */ 858 1.3 mrg returnValue = malloc (sizeof (char) * returnValueSize); 859 1.3 mrg memcpy (returnValue, method->method_types, returnValueSize); 860 1.3 mrg returnValue[returnValueSize - 1] = '\0'; 861 1.3 mrg 862 1.3 mrg return returnValue; 863 1.1 mrg } 864 1.1 mrg } 865 1.1 mrg 866 1.3 mrg char * 867 1.3 mrg method_copyArgumentType (struct objc_method * method, unsigned int argumentNumber) 868 1.3 mrg { 869 1.3 mrg if (method == NULL) 870 1.3 mrg return 0; 871 1.3 mrg else 872 1.3 mrg { 873 1.3 mrg char *returnValue; 874 1.3 mrg const char *returnValueStart; 875 1.3 mrg size_t returnValueSize; 876 1.1 mrg 877 1.3 mrg /* Determine returnValueStart and returnValueSize. */ 878 1.3 mrg { 879 1.3 mrg const char *type = method->method_types; 880 1.1 mrg 881 1.3 mrg /* Skip the first argument (return type). */ 882 1.3 mrg type = objc_skip_argspec (type); 883 1.1 mrg 884 1.3 mrg /* Now keep skipping arguments until we get to 885 1.3 mrg argumentNumber. */ 886 1.3 mrg while (argumentNumber > 0) 887 1.1 mrg { 888 1.3 mrg /* We are supposed to skip an argument, but the string is 889 1.3 mrg finished. This means we were asked for a non-existing 890 1.3 mrg argument. */ 891 1.3 mrg if (*type == '\0') 892 1.3 mrg return NULL; 893 1.3 mrg 894 1.3 mrg type = objc_skip_argspec (type); 895 1.3 mrg argumentNumber--; 896 1.1 mrg } 897 1.3 mrg 898 1.3 mrg /* If the argument does not exist, return NULL. */ 899 1.3 mrg if (*type == '\0') 900 1.3 mrg return NULL; 901 1.3 mrg 902 1.3 mrg returnValueStart = type; 903 1.3 mrg type = objc_skip_argspec (type); 904 1.3 mrg returnValueSize = type - returnValueStart + 1; 905 1.1 mrg } 906 1.3 mrg 907 1.3 mrg /* Copy the argument into returnValue. */ 908 1.3 mrg returnValue = malloc (sizeof (char) * returnValueSize); 909 1.3 mrg memcpy (returnValue, returnValueStart, returnValueSize); 910 1.3 mrg returnValue[returnValueSize - 1] = '\0'; 911 1.3 mrg 912 1.3 mrg return returnValue; 913 1.3 mrg } 914 1.3 mrg } 915 1.1 mrg 916 1.3 mrg void method_getReturnType (struct objc_method * method, char *returnValue, 917 1.3 mrg size_t returnValueSize) 918 1.1 mrg { 919 1.3 mrg if (returnValue == NULL || returnValueSize == 0) 920 1.3 mrg return; 921 1.1 mrg 922 1.3 mrg /* Zero the string; we'll then write the argument type at the 923 1.3 mrg beginning of it, if needed. */ 924 1.3 mrg memset (returnValue, 0, returnValueSize); 925 1.1 mrg 926 1.3 mrg if (method == NULL) 927 1.3 mrg return; 928 1.3 mrg else 929 1.3 mrg { 930 1.3 mrg size_t argumentTypeSize; 931 1.1 mrg 932 1.3 mrg /* Determine argumentTypeSize. */ 933 1.3 mrg { 934 1.3 mrg /* Find the end of the first argument. We want to return the 935 1.3 mrg first argument spec. */ 936 1.3 mrg const char *type = method->method_types; 937 1.3 mrg if (*type == '\0') 938 1.3 mrg return; 939 1.3 mrg type = objc_skip_argspec (type); 940 1.3 mrg argumentTypeSize = type - method->method_types; 941 1.3 mrg if (argumentTypeSize > returnValueSize) 942 1.3 mrg argumentTypeSize = returnValueSize; 943 1.3 mrg } 944 1.3 mrg /* Copy the argument at the beginning of the string. */ 945 1.3 mrg memcpy (returnValue, method->method_types, argumentTypeSize); 946 1.3 mrg } 947 1.1 mrg } 948 1.1 mrg 949 1.3 mrg void method_getArgumentType (struct objc_method * method, unsigned int argumentNumber, 950 1.3 mrg char *returnValue, size_t returnValueSize) 951 1.1 mrg { 952 1.3 mrg if (returnValue == NULL || returnValueSize == 0) 953 1.3 mrg return; 954 1.3 mrg 955 1.3 mrg /* Zero the string; we'll then write the argument type at the 956 1.3 mrg beginning of it, if needed. */ 957 1.3 mrg memset (returnValue, 0, returnValueSize); 958 1.3 mrg 959 1.3 mrg if (method == NULL) 960 1.3 mrg return; 961 1.3 mrg else 962 1.3 mrg { 963 1.3 mrg const char *returnValueStart; 964 1.3 mrg size_t argumentTypeSize; 965 1.1 mrg 966 1.3 mrg /* Determine returnValueStart and argumentTypeSize. */ 967 1.3 mrg { 968 1.3 mrg const char *type = method->method_types; 969 1.1 mrg 970 1.3 mrg /* Skip the first argument (return type). */ 971 1.3 mrg type = objc_skip_argspec (type); 972 1.1 mrg 973 1.3 mrg /* Now keep skipping arguments until we get to 974 1.3 mrg argumentNumber. */ 975 1.3 mrg while (argumentNumber > 0) 976 1.3 mrg { 977 1.3 mrg /* We are supposed to skip an argument, but the string is 978 1.3 mrg finished. This means we were asked for a non-existing 979 1.3 mrg argument. */ 980 1.3 mrg if (*type == '\0') 981 1.3 mrg return; 982 1.1 mrg 983 1.3 mrg type = objc_skip_argspec (type); 984 1.3 mrg argumentNumber--; 985 1.3 mrg } 986 1.1 mrg 987 1.3 mrg /* If the argument does not exist, it's game over. */ 988 1.3 mrg if (*type == '\0') 989 1.3 mrg return; 990 1.3 mrg 991 1.3 mrg returnValueStart = type; 992 1.3 mrg type = objc_skip_argspec (type); 993 1.3 mrg argumentTypeSize = type - returnValueStart; 994 1.3 mrg if (argumentTypeSize > returnValueSize) 995 1.3 mrg argumentTypeSize = returnValueSize; 996 1.3 mrg } 997 1.3 mrg /* Copy the argument at the beginning of the string. */ 998 1.3 mrg memcpy (returnValue, returnValueStart, argumentTypeSize); 999 1.3 mrg } 1000 1.3 mrg } 1001 1.1 mrg 1002 1.3 mrg unsigned int 1003 1.3 mrg method_getNumberOfArguments (struct objc_method *method) 1004 1.3 mrg { 1005 1.3 mrg if (method == NULL) 1006 1.3 mrg return 0; 1007 1.1 mrg else 1008 1.3 mrg { 1009 1.3 mrg unsigned int i = 0; 1010 1.3 mrg const char *type = method->method_types; 1011 1.3 mrg while (*type) 1012 1.3 mrg { 1013 1.3 mrg type = objc_skip_argspec (type); 1014 1.3 mrg i += 1; 1015 1.3 mrg } 1016 1.3 mrg 1017 1.3 mrg if (i == 0) 1018 1.3 mrg { 1019 1.3 mrg /* This could only happen if method_types is invalid; in 1020 1.3 mrg that case, return 0. */ 1021 1.3 mrg return 0; 1022 1.3 mrg } 1023 1.3 mrg else 1024 1.3 mrg { 1025 1.3 mrg /* Remove the return type. */ 1026 1.3 mrg return (i - 1); 1027 1.3 mrg } 1028 1.3 mrg } 1029 1.1 mrg } 1030 1.1 mrg 1031 1.1 mrg unsigned 1032 1.1 mrg objc_get_type_qualifiers (const char *type) 1033 1.1 mrg { 1034 1.1 mrg unsigned res = 0; 1035 1.1 mrg BOOL flag = YES; 1036 1.1 mrg 1037 1.1 mrg while (flag) 1038 1.1 mrg switch (*type++) 1039 1.1 mrg { 1040 1.3 mrg case _C_CONST: res |= _F_CONST; break; 1041 1.3 mrg case _C_IN: res |= _F_IN; break; 1042 1.3 mrg case _C_INOUT: res |= _F_INOUT; break; 1043 1.3 mrg case _C_OUT: res |= _F_OUT; break; 1044 1.3 mrg case _C_BYCOPY: res |= _F_BYCOPY; break; 1045 1.3 mrg case _C_BYREF: res |= _F_BYREF; break; 1046 1.3 mrg case _C_ONEWAY: res |= _F_ONEWAY; break; 1047 1.1 mrg case _C_GCINVISIBLE: res |= _F_GCINVISIBLE; break; 1048 1.1 mrg default: flag = NO; 1049 1.1 mrg } 1050 1.1 mrg 1051 1.1 mrg return res; 1052 1.1 mrg } 1053 1.1 mrg 1054 1.1 mrg /* The following three functions can be used to determine how a 1055 1.1 mrg structure is laid out by the compiler. For example: 1056 1.1 mrg 1057 1.1 mrg struct objc_struct_layout layout; 1058 1.1 mrg int i; 1059 1.1 mrg 1060 1.1 mrg objc_layout_structure (type, &layout); 1061 1.1 mrg while (objc_layout_structure_next_member (&layout)) 1062 1.1 mrg { 1063 1.1 mrg int position, align; 1064 1.1 mrg const char *type; 1065 1.1 mrg 1066 1.1 mrg objc_layout_structure_get_info (&layout, &position, &align, &type); 1067 1.1 mrg printf ("element %d has offset %d, alignment %d\n", 1068 1.1 mrg i++, position, align); 1069 1.1 mrg } 1070 1.1 mrg 1071 1.1 mrg These functions are used by objc_sizeof_type and objc_alignof_type 1072 1.1 mrg functions to compute the size and alignment of structures. The 1073 1.1 mrg previous method of computing the size and alignment of a structure 1074 1.6 mrg was not working on some architectures, particularly on AIX, and in 1075 1.3 mrg the presence of bitfields inside the structure. */ 1076 1.1 mrg void 1077 1.1 mrg objc_layout_structure (const char *type, 1078 1.3 mrg struct objc_struct_layout *layout) 1079 1.1 mrg { 1080 1.1 mrg const char *ntype; 1081 1.1 mrg 1082 1.1 mrg if (*type != _C_UNION_B && *type != _C_STRUCT_B) 1083 1.1 mrg { 1084 1.3 mrg _objc_abort ("record (or union) type expected in objc_layout_structure, got %s\n", 1085 1.3 mrg type); 1086 1.1 mrg } 1087 1.1 mrg 1088 1.1 mrg type ++; 1089 1.1 mrg layout->original_type = type; 1090 1.1 mrg 1091 1.1 mrg /* Skip "<name>=" if any. Avoid embedded structures and unions. */ 1092 1.1 mrg ntype = type; 1093 1.1 mrg while (*ntype != _C_STRUCT_E && *ntype != _C_STRUCT_B && *ntype != _C_UNION_B 1094 1.1 mrg && *ntype++ != '=') 1095 1.1 mrg /* do nothing */; 1096 1.1 mrg 1097 1.15 mrg /* If there's a "<name>=", ntype - 1 points to '='; skip the name. */ 1098 1.1 mrg if (*(ntype - 1) == '=') 1099 1.1 mrg type = ntype; 1100 1.1 mrg 1101 1.1 mrg layout->type = type; 1102 1.1 mrg layout->prev_type = NULL; 1103 1.1 mrg layout->record_size = 0; 1104 1.7 mrg layout->record_align = __CHAR_BIT__; 1105 1.1 mrg 1106 1.1 mrg layout->record_align = MAX (layout->record_align, STRUCTURE_SIZE_BOUNDARY); 1107 1.1 mrg } 1108 1.1 mrg 1109 1.1 mrg BOOL 1110 1.1 mrg objc_layout_structure_next_member (struct objc_struct_layout *layout) 1111 1.1 mrg { 1112 1.1 mrg register int desired_align = 0; 1113 1.1 mrg 1114 1.1 mrg /* The following are used only if the field is a bitfield */ 1115 1.1 mrg register const char *bfld_type = 0; 1116 1.8 mrg #ifdef HAVE_BITFIELD_TYPE_MATTERS 1117 1.8 mrg register int bfld_type_align = 0; 1118 1.8 mrg #endif 1119 1.8 mrg register int bfld_field_size = 0; 1120 1.1 mrg 1121 1.1 mrg /* The current type without the type qualifiers */ 1122 1.1 mrg const char *type; 1123 1.1 mrg BOOL unionp = layout->original_type[-1] == _C_UNION_B; 1124 1.1 mrg 1125 1.1 mrg /* Add the size of the previous field to the size of the record. */ 1126 1.1 mrg if (layout->prev_type) 1127 1.1 mrg { 1128 1.1 mrg type = objc_skip_type_qualifiers (layout->prev_type); 1129 1.1 mrg if (unionp) 1130 1.1 mrg layout->record_size = MAX (layout->record_size, 1131 1.7 mrg objc_sizeof_type (type) * __CHAR_BIT__); 1132 1.1 mrg 1133 1.1 mrg else if (*type != _C_BFLD) 1134 1.7 mrg layout->record_size += objc_sizeof_type (type) * __CHAR_BIT__; 1135 1.1 mrg else { 1136 1.1 mrg /* Get the bitfield's type */ 1137 1.1 mrg for (bfld_type = type + 1; 1138 1.1 mrg isdigit ((unsigned char)*bfld_type); 1139 1.1 mrg bfld_type++) 1140 1.1 mrg /* do nothing */; 1141 1.1 mrg 1142 1.8 mrg #ifdef HAVE_BITFIELD_TYPE_MATTERS 1143 1.7 mrg bfld_type_align = objc_alignof_type (bfld_type) * __CHAR_BIT__; 1144 1.8 mrg #endif 1145 1.1 mrg bfld_field_size = atoi (objc_skip_typespec (bfld_type)); 1146 1.1 mrg layout->record_size += bfld_field_size; 1147 1.1 mrg } 1148 1.1 mrg } 1149 1.1 mrg 1150 1.1 mrg if ((unionp && *layout->type == _C_UNION_E) 1151 1.1 mrg || (!unionp && *layout->type == _C_STRUCT_E)) 1152 1.1 mrg return NO; 1153 1.1 mrg 1154 1.1 mrg /* Skip the variable name if any */ 1155 1.3 mrg layout->type = objc_skip_variable_name (layout->type); 1156 1.1 mrg type = objc_skip_type_qualifiers (layout->type); 1157 1.1 mrg 1158 1.1 mrg if (*type != _C_BFLD) 1159 1.7 mrg desired_align = objc_alignof_type (type) * __CHAR_BIT__; 1160 1.1 mrg else 1161 1.1 mrg { 1162 1.1 mrg desired_align = 1; 1163 1.1 mrg /* Skip the bitfield's offset */ 1164 1.1 mrg for (bfld_type = type + 1; 1165 1.1 mrg isdigit ((unsigned char) *bfld_type); 1166 1.1 mrg bfld_type++) 1167 1.1 mrg /* do nothing */; 1168 1.1 mrg 1169 1.8 mrg #ifdef HAVE_BITFIELD_TYPE_MATTERS 1170 1.7 mrg bfld_type_align = objc_alignof_type (bfld_type) * __CHAR_BIT__; 1171 1.8 mrg #endif 1172 1.1 mrg bfld_field_size = atoi (objc_skip_typespec (bfld_type)); 1173 1.1 mrg } 1174 1.1 mrg 1175 1.3 mrg /* The following won't work for vectors. */ 1176 1.1 mrg #ifdef BIGGEST_FIELD_ALIGNMENT 1177 1.1 mrg desired_align = MIN (desired_align, BIGGEST_FIELD_ALIGNMENT); 1178 1.1 mrg #endif 1179 1.1 mrg #ifdef ADJUST_FIELD_ALIGN 1180 1.9 mrg desired_align = ADJUST_FIELD_ALIGN (type, type, desired_align); 1181 1.1 mrg #endif 1182 1.1 mrg 1183 1.1 mrg /* Record must have at least as much alignment as any field. 1184 1.1 mrg Otherwise, the alignment of the field within the record 1185 1.1 mrg is meaningless. */ 1186 1.7 mrg #ifndef HAVE_BITFIELD_TYPE_MATTERS 1187 1.1 mrg layout->record_align = MAX (layout->record_align, desired_align); 1188 1.1 mrg #else /* PCC_BITFIELD_TYPE_MATTERS */ 1189 1.1 mrg if (*type == _C_BFLD) 1190 1.1 mrg { 1191 1.1 mrg /* For these machines, a zero-length field does not 1192 1.1 mrg affect the alignment of the structure as a whole. 1193 1.1 mrg It does, however, affect the alignment of the next field 1194 1.1 mrg within the structure. */ 1195 1.1 mrg if (bfld_field_size) 1196 1.1 mrg layout->record_align = MAX (layout->record_align, desired_align); 1197 1.1 mrg else 1198 1.7 mrg desired_align = objc_alignof_type (bfld_type) * __CHAR_BIT__; 1199 1.1 mrg 1200 1.1 mrg /* A named bit field of declared type `int' 1201 1.1 mrg forces the entire structure to have `int' alignment. 1202 1.1 mrg Q1: How is encoded this thing and how to check for it? 1203 1.1 mrg Q2: How to determine maximum_field_alignment at runtime? */ 1204 1.1 mrg 1205 1.1 mrg /* if (DECL_NAME (field) != 0) */ 1206 1.1 mrg { 1207 1.1 mrg int type_align = bfld_type_align; 1208 1.1 mrg #if 0 1209 1.1 mrg if (maximum_field_alignment != 0) 1210 1.1 mrg type_align = MIN (type_align, maximum_field_alignment); 1211 1.1 mrg else if (DECL_PACKED (field)) 1212 1.7 mrg type_align = MIN (type_align, __CHAR_BIT__); 1213 1.1 mrg #endif 1214 1.1 mrg 1215 1.1 mrg layout->record_align = MAX (layout->record_align, type_align); 1216 1.1 mrg } 1217 1.1 mrg } 1218 1.1 mrg else 1219 1.1 mrg layout->record_align = MAX (layout->record_align, desired_align); 1220 1.1 mrg #endif /* PCC_BITFIELD_TYPE_MATTERS */ 1221 1.1 mrg 1222 1.1 mrg /* Does this field automatically have alignment it needs 1223 1.1 mrg by virtue of the fields that precede it and the record's 1224 1.1 mrg own alignment? */ 1225 1.1 mrg 1226 1.1 mrg if (*type == _C_BFLD) 1227 1.1 mrg layout->record_size = atoi (type + 1); 1228 1.1 mrg else if (layout->record_size % desired_align != 0) 1229 1.1 mrg { 1230 1.1 mrg /* No, we need to skip space before this field. 1231 1.1 mrg Bump the cumulative size to multiple of field alignment. */ 1232 1.1 mrg layout->record_size = ROUND (layout->record_size, desired_align); 1233 1.1 mrg } 1234 1.1 mrg 1235 1.1 mrg /* Jump to the next field in record. */ 1236 1.1 mrg 1237 1.1 mrg layout->prev_type = layout->type; 1238 1.1 mrg layout->type = objc_skip_typespec (layout->type); /* skip component */ 1239 1.1 mrg 1240 1.1 mrg return YES; 1241 1.1 mrg } 1242 1.1 mrg 1243 1.1 mrg void objc_layout_finish_structure (struct objc_struct_layout *layout, 1244 1.1 mrg unsigned int *size, 1245 1.1 mrg unsigned int *align) 1246 1.1 mrg { 1247 1.1 mrg BOOL unionp = layout->original_type[-1] == _C_UNION_B; 1248 1.1 mrg if (layout->type 1249 1.1 mrg && ((!unionp && *layout->type == _C_STRUCT_E) 1250 1.1 mrg || (unionp && *layout->type == _C_UNION_E))) 1251 1.1 mrg { 1252 1.1 mrg /* Work out the alignment of the record as one expression and store 1253 1.1 mrg in the record type. Round it up to a multiple of the record's 1254 1.1 mrg alignment. */ 1255 1.1 mrg #if defined (ROUND_TYPE_ALIGN) && ! defined (__sparc__) 1256 1.1 mrg layout->record_align = ROUND_TYPE_ALIGN (layout->original_type-1, 1257 1.1 mrg 1, 1258 1.1 mrg layout->record_align); 1259 1.1 mrg #else 1260 1.1 mrg layout->record_align = MAX (1, layout->record_align); 1261 1.1 mrg #endif 1262 1.1 mrg 1263 1.1 mrg /* Round the size up to be a multiple of the required alignment */ 1264 1.1 mrg layout->record_size = ROUND (layout->record_size, layout->record_align); 1265 1.1 mrg 1266 1.1 mrg layout->type = NULL; 1267 1.1 mrg } 1268 1.1 mrg if (size) 1269 1.7 mrg *size = layout->record_size / __CHAR_BIT__; 1270 1.1 mrg if (align) 1271 1.7 mrg *align = layout->record_align / __CHAR_BIT__; 1272 1.1 mrg } 1273 1.1 mrg 1274 1.1 mrg void objc_layout_structure_get_info (struct objc_struct_layout *layout, 1275 1.1 mrg unsigned int *offset, 1276 1.1 mrg unsigned int *align, 1277 1.1 mrg const char **type) 1278 1.1 mrg { 1279 1.1 mrg if (offset) 1280 1.7 mrg *offset = layout->record_size / __CHAR_BIT__; 1281 1.1 mrg if (align) 1282 1.7 mrg *align = layout->record_align / __CHAR_BIT__; 1283 1.1 mrg if (type) 1284 1.1 mrg *type = layout->prev_type; 1285 1.1 mrg } 1286