OSDN Git Service

In gcc/testsuite/:
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / objc.dg / gnu-api-2-objc.m
1 /* Test the Modern GNU Objective-C Runtime API.
2
3   This is test 'objc', covering all functions starting with 'objc'.  */
4
5 /* { dg-do run } */
6 /* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
7
8 /* To get the modern GNU Objective-C Runtime API, you include
9    objc/runtime.h.  */
10 #include <objc/runtime.h>
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <string.h>
14
15 @interface MyRootClass
16 { Class isa; }
17 + alloc;
18 - init;
19 @end
20
21 @implementation MyRootClass
22 + alloc { return class_createInstance (self, 0); }
23 - init  { return self; }
24 @end
25
26 @protocol MyProtocol
27 - (id) variable;
28 @end
29
30 @protocol MySecondProtocol
31 - (id) setVariable: (id)value;
32 @end
33
34 @interface MySubClass : MyRootClass <MyProtocol>
35 { id variable_ivar; }
36 - (void) setVariable: (id)value;
37 - (id) variable;
38 @end
39
40 @implementation MySubClass
41 - (void) setVariable: (id)value { variable_ivar = value; }
42 - (id) variable { return variable_ivar; }
43 @end
44
45
46 int main(int argc, void **args)
47 {
48   /* Functions are tested in alphabetical order.  */
49
50   printf ("Testing objc_allocateClassPair ()...\n");
51   {
52     Class new_root_class = objc_allocateClassPair (Nil, "MyNewRootClass", 0);
53     Class new_class = objc_allocateClassPair (objc_getClass ("MyRootClass"), "MyNewSubClass", 0);
54
55     /* A new root class would obviously need at least an 'isa'
56        instance variable.  We don't add it so we never actually
57        instantiate an instance of the class, which wouldn't work.  */
58
59     objc_registerClassPair (new_root_class);
60     objc_registerClassPair (new_class);
61
62     if (strcmp (class_getName (new_class), "MyNewSubClass") != 0)
63       abort ();
64
65     if (class_getSuperclass (new_class) != objc_getClass ("MyRootClass"))
66       abort ();
67
68     if (strcmp (class_getName (new_root_class), "MyNewRootClass") != 0)
69       abort ();
70
71     if (class_getSuperclass (new_root_class) != Nil)
72       abort ();
73
74     {
75       MySubClass *o = [[objc_getClass ("MyNewSubClass") alloc] init];
76       
77       if (object_getClass (o) != objc_getClass ("MyNewSubClass"))
78         abort ();
79     }
80   }
81
82   printf ("Testing objc_copyProtocolList ()...\n");
83   {
84     /* Make sure both our two protocols are known to the runtime.  */
85     id my_protocol = @protocol (MyProtocol);
86     id my_second_protocol = @protocol (MySecondProtocol);
87     unsigned int count;
88     Protocol ** list = objc_copyProtocolList (&count);
89
90     if (count != 2)
91       abort ();
92
93     if (! ((strcmp (protocol_getName (list[0]), "MyProtocol") == 0
94             && strcmp (protocol_getName (list[1]), "MySecondProtocol") == 0)
95            || (strcmp (protocol_getName (list[0]), "MySecondProtocol") == 0
96                && strcmp (protocol_getName (list[1]), "MyProtocol") == 0)))
97       abort ();
98     
99     if (list[2] != NULL)
100       abort ();
101   }
102
103   printf ("Testing objc_disposeClassPair ()...\n");
104   {
105     Method method = class_getInstanceMethod (objc_getClass ("MySubClass"), @selector (setVariable:));
106     Class new_class = objc_allocateClassPair (objc_getClass ("MyRootClass"), "MyNewSubClass", 0);
107
108     /* Add a bit of everything to the class to exercise undoing all these changes.  */
109
110     /* Instance variable.  */
111     class_addIvar (new_class, "my_variable", sizeof (float), __alignof__ (float), @encode (float));
112
113     /* Instance method.  */
114     class_addMethod (new_class, @selector (setVariable:), method_getImplementation (method),
115                      method_getTypeEncoding (method));
116
117     /* Class method.  */
118     class_addMethod (object_getClass (new_class), @selector (setVariable:), method_getImplementation (method),
119                      method_getTypeEncoding (method));
120
121     /* Protocol.  */
122     class_addProtocol (new_class, @protocol (MyProtocol));
123
124     objc_disposeClassPair (new_class);
125   }
126
127   /* This function currently does not exist with the GNU runtime.  */
128   /* printf ("Testing objc_duplicateClass ()...\n"); */
129
130   /* TODO - Test it when implemented in the GNU Runtime */
131   /*  printf ("Testing objc_getAssociatedObject ()...\n");  */
132
133   printf ("Testing objc_getClass ()...\n");
134   {
135     if (strcmp (class_getName (objc_getClass ("MySubClass")),
136                 "MySubClass") != 0)
137       abort ();
138   }
139
140   printf ("Testing objc_getClassList ()...\n");
141   {
142     Class *list;
143     int i, count, other_count;
144     count = objc_getClassList (NULL, 0);
145
146     /* count most likely will be 5, (MyRootClass, MySubClass,
147        Protocol, Object, NXConstantString).  */
148     if (count < 3)
149       abort ();
150     
151     list = malloc (sizeof (Class) * count);
152     other_count = objc_getClassList (list, count);
153
154     if (other_count != count)
155       abort ();
156
157     /* Spot-check: search for class 'MyRootClass' in the list.  */
158     for (i = 0; i < count; i++)
159       {
160         if (strcmp (class_getName (list[i]), "MyRootClass") == 0)
161           break;
162       }
163     if (i == count)
164       abort ();
165
166     /* Spot-check: search for class 'MySubClass' in the list.  */
167     for (i = 0; i < count; i++)
168       {
169         if (strcmp (class_getName (list[i]), "MySubClass") == 0)
170           break;
171       }
172     if (i == count)
173       abort ();
174
175     /* Spot-check: search for class 'Protocol' in the list.  */
176     for (i = 0; i < count; i++)
177       {
178         if (strcmp (class_getName (list[i]), "Protocol") == 0)
179           break;
180       }
181     if (i == count)
182       abort ();
183   }
184
185   /* This function does not exist with the GNU runtime.  */
186   /* printf ("Testing objc_getFutureClass ()...\n"); */
187
188   printf ("Testing objc_getMetaClass ()...\n");
189   {
190     if (! class_isMetaClass (objc_getMetaClass ("MyRootClass")))
191       abort ();
192   }
193
194   printf ("Testing objc_getProtocol ()...\n");
195   {
196     if (! protocol_isEqual (objc_getProtocol ("MyProtocol"), @protocol (MyProtocol)))
197       abort ();
198   }
199
200   printf ("Testing objc_getRequiredClass ()...\n");
201   {
202     if (strcmp (class_getName (objc_getRequiredClass ("MyRootClass")),
203                 "MyRootClass") != 0)
204       abort ();
205   }
206
207   printf ("Testing objc_lookupClass ()...\n");
208   {
209     if (strcmp (class_getName (objc_lookupClass ("MyRootClass")),
210                 "MyRootClass") != 0)
211       abort ();
212   }
213
214   /* This function does not exist with the GNU runtime.  */
215   /* printf ("Testing objc_setFutureClass ()...\n"); */
216
217   printf ("Testing objc_registerClassPair ()...\n");
218   {
219     Class new_class = objc_allocateClassPair (objc_getClass ("MySubClass"), "MySubSubClass", 0);
220
221     class_addProtocol (new_class, @protocol (MySecondProtocol));
222     
223     objc_registerClassPair (new_class);
224     
225     if (strcmp (class_getName (new_class), "MySubSubClass") != 0)
226       abort ();
227
228     if (class_getSuperclass (new_class) != objc_getClass ("MySubClass"))
229       abort ();
230
231     if (! class_conformsToProtocol (new_class, @protocol (MySecondProtocol)))
232       abort ();
233   }
234
235   /* TODO - Test it when implemented in the GNU Runtime */
236   /*  printf ("Testing objc_removeAssociatedObjects ()...\n");  */
237
238   /* TODO - Test it when implemented in the GNU Runtime */
239   /*  printf ("Testing objc_setAssociatedObject ()...\n");  */
240
241   return 0;
242 }