OSDN Git Service

2011-01-08 Dominique d'Humieres <dominiq@lps.ens.fr>
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / objc.dg / encode-2.m
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
20 #include "../objc-obj-c++-shared/Object1.h"
21 #include "../objc-obj-c++-shared/next-mapping.h"
22
23 #ifdef __NEXT_RUNTIME__
24 #define METHOD Method
25 #else
26 #include <objc/objc-api.h>
27 #define METHOD Method_t
28 #define method_get_types(M) (M)->method_types
29 #endif
30
31 extern int sscanf(const char *str, const char *format, ...);
32 extern void abort(void);
33 #define CHECK_IF(expr) if(!(expr)) abort()
34
35 @interface Foo: Object
36 typedef struct { float x, y; } XXPoint;
37 typedef struct { float width, height; } XXSize;
38 typedef struct _XXRect { XXPoint origin; XXSize size; } XXRect;
39 -(id)setRect:(XXRect)r withInt:(int)i;
40 -(void) char:(signed char)c float:(float)f double:(double)d long:(long)l;
41 @end
42
43 XXRect my_rect;
44 unsigned offs1, offs2, offs3, offs4, offs5, offs6, offs7;
45
46 @implementation Foo
47 -(id)setRect:(XXRect)r withInt:(int)i {
48   unsigned offs = sizeof(self);
49   CHECK_IF(offs == offs3);
50   offs += sizeof(_cmd);
51   CHECK_IF(offs == offs4);
52   offs += sizeof(r);
53   CHECK_IF(offs == offs5);
54   offs += sizeof(i); 
55   CHECK_IF(offs == offs1); 
56   return nil; 
57 }
58 -(void) char:(signed char)c float:(float)f double:(double)d long:(long)l {
59   unsigned offs = sizeof(self);
60   CHECK_IF(offs == offs3);
61   offs += sizeof(_cmd);
62   CHECK_IF(offs == offs4);
63   offs += sizeof((int)c);
64   CHECK_IF(offs == offs5);
65   offs += sizeof(f);
66   CHECK_IF(offs == offs6);
67   offs += sizeof(d);
68   CHECK_IF(offs == offs7);
69   offs += sizeof(l);
70   CHECK_IF(offs == offs1);
71 }
72 @end
73
74
75 int main(void) {
76   Foo *foo = [[Foo alloc] init];
77   Class fooClass = objc_get_class("Foo");
78   METHOD meth;
79   const char *string;
80
81   meth = class_get_instance_method(fooClass, @selector(setRect:withInt:));
82   offs2 = 9999;
83
84   sscanf(method_get_types(meth), "@%u@%u:%u{_XXRect={?=ff}{?=ff}}%ui%u", &offs1, &offs2, &offs3,
85       &offs4, &offs5);
86    
87   CHECK_IF(!offs2);
88   [foo setRect:my_rect withInt:123];
89
90   meth = class_get_instance_method(fooClass, @selector(char:float:double:long:));
91   offs2 = 9999;
92   if (sizeof (long) == 8)
93     string = "v%u@%u:%uc%uf%ud%uq%u";
94   else
95     string = "v%u@%u:%uc%uf%ud%ul%u";
96   sscanf(method_get_types(meth), string, &offs1, &offs2, &offs3,  
97          &offs4, &offs5, &offs6, &offs7);
98   CHECK_IF(!offs2);
99   [foo char:'c' float:2.3 double:3.5 long:2345L];
100
101   return 0;
102 }  
103
104 #include "../objc-obj-c++-shared/Object1-implementation.h"