1/* Test Objective-C method encodings. */ 2 3/* The _encoded_ parameter offsets for Objective-C methods are 4 computed inductively as follows: 5 - The first paramter (self) has offset 0; 6 - The k-th parameter (k > 1) has offset equal to the 7 sum of: 8 - the offset of the k-1-st paramter 9 - the (void *)-promoted size of the k-1-st parameter. 10 11 Note that the encoded offsets need not correspond 12 to the actual placement of parameters (relative to 'self') 13 on the stack! Your target's ABI may have very different 14 opinions on the matter. */ 15 16/* Contributed by Ziemowit Laski <zlaski@apple.com>. */ 17/* { dg-do run } */ 18/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ 19#include "../objc-obj-c++-shared/TestsuiteObject.m" 20#include "../objc-obj-c++-shared/runtime.h" 21 22#include <stdio.h> 23#include <stdlib.h> 24 25#define CHECK_IF(expr) if(!(expr)) abort() 26 27@interface Foo: TestsuiteObject 28typedef struct { float x, y; } XXPoint; 29typedef struct { float width, height; } XXSize; 30typedef struct _XXRect { XXPoint origin; XXSize size; } XXRect; 31-(id)setRect:(XXRect)r withInt:(int)i; 32-(void) char:(signed char)c float:(float)f double:(double)d long:(long)l; 33@end 34 35XXRect my_rect; 36unsigned offs1, offs2, offs3, offs4, offs5, offs6, offs7; 37 38@implementation Foo 39-(id)setRect:(XXRect)r withInt:(int)i { 40 unsigned offs = sizeof(self); 41 CHECK_IF(offs == offs3); 42 offs += sizeof(_cmd); 43 CHECK_IF(offs == offs4); 44 offs += sizeof(r); 45 CHECK_IF(offs == offs5); 46 offs += sizeof(i); 47 CHECK_IF(offs == offs1); 48 return nil; 49} 50-(void) char:(signed char)c float:(float)f double:(double)d long:(long)l { 51 unsigned offs = sizeof(self); 52 CHECK_IF(offs == offs3); 53 offs += sizeof(_cmd); 54 CHECK_IF(offs == offs4); 55 offs += sizeof((int)c); 56 CHECK_IF(offs == offs5); 57 offs += sizeof(f); 58 CHECK_IF(offs == offs6); 59 offs += sizeof(d); 60 CHECK_IF(offs == offs7); 61 offs += sizeof(l); 62 CHECK_IF(offs == offs1); 63} 64@end 65 66 67int main(void) { 68 Foo *foo = [[Foo alloc] init]; 69 Class fooClass = objc_getClass("Foo"); 70 Method meth; 71 const char *string; 72 73 meth = class_getInstanceMethod(fooClass, @selector(setRect:withInt:)); 74 offs2 = 9999; 75 sscanf(method_getTypeEncoding(meth), "@%u@%u:%u{_XXRect={?=ff}{?=ff}}%ui%u", &offs1, &offs2, &offs3, 76 &offs4, &offs5); 77 CHECK_IF(!offs2); 78 [foo setRect:my_rect withInt:123]; 79 80 meth = class_getInstanceMethod(fooClass, @selector(char:float:double:long:)); 81 offs2 = 9999; 82 if (sizeof (long) == 8) 83 string = "v%u@%u:%uc%uf%ud%uq%u"; 84 else 85 string = "v%u@%u:%uc%uf%ud%ul%u"; 86 sscanf(method_getTypeEncoding(meth), string, &offs1, &offs2, &offs3, 87 &offs4, &offs5, &offs6, &offs7); 88 CHECK_IF(!offs2); 89 [foo char:'c' float:2.3 double:3.5 long:2345L]; 90 91 return 0; 92} 93 94