2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / gcc / testsuite / objc.dg / encode-2.m
blobebfd8d3fa2d108572644635523269233043cfeab
1 /* Test Objective-C method encodings. */
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 int-promoted size of the k-1-st parameter.
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.  */
16 /* Contributed by Ziemowit Laski <zlaski@apple.com>.  */
17 /* { dg-do run } */
19 #include <objc/objc.h>
20 #include <objc/Object.h>
22 #ifdef __NEXT_RUNTIME__
23 #define METHOD Method
24 #define OBJC_GETCLASS objc_getClass
25 #define CLASS_GETINSTANCEMETHOD class_getInstanceMethod
26 #else
27 #include <objc/objc-api.h>
28 #define METHOD Method_t
29 #define OBJC_GETCLASS objc_get_class
30 #define CLASS_GETINSTANCEMETHOD class_get_instance_method
31 #endif
33 extern int sscanf(const char *str, const char *format, ...);
34 extern void abort(void);
35 #define CHECK_IF(expr) if(!(expr)) abort()
37 @interface Foo: Object
38 typedef struct { float x, y; } XXPoint;
39 typedef struct { float width, height; } XXSize;
40 typedef struct _XXRect { XXPoint origin; XXSize size; } XXRect;
41 -(id)setRect:(XXRect)r withInt:(int)i;
42 -(void) char:(char)c float:(float)f double:(double)d long:(long)l;
43 @end
45 XXRect my_rect;
46 unsigned offs1, offs2, offs3, offs4, offs5, offs6, offs7;
48 @implementation Foo
49 -(id)setRect:(XXRect)r withInt:(int)i {
50   unsigned offs = sizeof(self);
51   CHECK_IF(offs == offs3);
52   offs += sizeof(_cmd);
53   CHECK_IF(offs == offs4);
54   offs += sizeof(r);
55   CHECK_IF(offs == offs5);
56   offs += sizeof(i); 
57   CHECK_IF(offs == offs1); 
58   return nil; 
60 -(void) char:(char)c float:(float)f double:(double)d long:(long)l {
61   unsigned offs = sizeof(self);
62   CHECK_IF(offs == offs3);
63   offs += sizeof(_cmd);
64   CHECK_IF(offs == offs4);
65   offs += sizeof((int)c);
66   CHECK_IF(offs == offs5);
67   offs += sizeof(f);
68   CHECK_IF(offs == offs6);
69   offs += sizeof(d);
70   CHECK_IF(offs == offs7);
71   offs += sizeof(l);
72   CHECK_IF(offs == offs1);
74 @end
77 int main(void) {
78   Foo *foo = [[Foo alloc] init];
79   Class fooClass = OBJC_GETCLASS("Foo");
80   METHOD meth;
82   meth = CLASS_GETINSTANCEMETHOD(fooClass, @selector(setRect:withInt:));
83   offs2 = 9999;
84   sscanf(meth->method_types, "@%u@%u:%u{_XXRect={?=ff}{?=ff}}%ui%u", &offs1, &offs2, &offs3,
85       &offs4, &offs5);
86   CHECK_IF(!offs2);
87   [foo setRect:my_rect withInt:123];
89   meth = CLASS_GETINSTANCEMETHOD(fooClass, @selector(char:float:double:long:));
90   offs2 = 9999;
91   sscanf(meth->method_types, "v%u@%u:%uc%uf%ud%ul%u", &offs1, &offs2, &offs3,  
92       &offs4, &offs5, &offs6, &offs7);
93   CHECK_IF(!offs2);
94   [foo char:'c' float:2.3 double:3.5 long:2345L];
96   return 0;
97 }