OSDN Git Service

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