Merge from mainline (168000:168310).
[official-gcc/graphite-test-results.git] / gcc / testsuite / objc.dg / gnu-api-2-objc.m
blob19b3a37c152fbe2d4e1074220de22a5590b4ca66
1 /* Test the Modern GNU Objective-C Runtime API.
3   This is test 'objc', covering all functions starting with 'objc'.  */
5 /* { dg-do run } */
6 /* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
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>
15 @interface MyRootClass
16 { Class isa; }
17 + alloc;
18 - init;
19 + initialize;
20 @end
22 @implementation MyRootClass
23 + alloc { return class_createInstance (self, 0); }
24 - init  { return self; }
25 + initialize { return self; }
26 @end
28 @protocol MyProtocol
29 - (id) variable;
30 @end
32 @protocol MySecondProtocol
33 - (id) setVariable: (id)value;
34 @end
36 @interface MySubClass : MyRootClass <MyProtocol>
37 { id variable_ivar; }
38 - (void) setVariable: (id)value;
39 - (id) variable;
40 @end
42 @implementation MySubClass
43 - (void) setVariable: (id)value { variable_ivar = value; }
44 - (id) variable { return variable_ivar; }
45 @end
48 int main(int argc, void **args)
50   /* Functions are tested in alphabetical order.  */
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);
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.  */
61     objc_registerClassPair (new_root_class);
62     objc_registerClassPair (new_class);
64     if (strcmp (class_getName (new_class), "MyNewSubClass") != 0)
65       abort ();
67     if (class_getSuperclass (new_class) != objc_getClass ("MyRootClass"))
68       abort ();
70     if (strcmp (class_getName (new_root_class), "MyNewRootClass") != 0)
71       abort ();
73     if (class_getSuperclass (new_root_class) != Nil)
74       abort ();
76     {
77       MySubClass *o = [[objc_getClass ("MyNewSubClass") alloc] init];
78       
79       if (object_getClass (o) != objc_getClass ("MyNewSubClass"))
80         abort ();
81     }
82   }
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);
92     if (count != 2)
93       abort ();
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   }
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);
110     if (new_class == Nil)
111       abort ();
113     /* Add a bit of everything to the class to exercise undoing all these changes.  */
115     /* Instance variable.  */
116     class_addIvar (new_class, "my_variable", sizeof (float), __alignof__ (float), @encode (float));
118     /* Instance method.  */
119     class_addMethod (new_class, @selector (setVariable:), method_getImplementation (method),
120                      method_getTypeEncoding (method));
122     /* Class method.  */
123     class_addMethod (object_getClass (new_class), @selector (setVariable:), method_getImplementation (method),
124                      method_getTypeEncoding (method));
126     /* Protocol.  */
127     class_addProtocol (new_class, @protocol (MyProtocol));
129     objc_disposeClassPair (new_class);
130   }
132   /* This function currently does not exist with the GNU runtime.  */
133   /* printf ("Testing objc_duplicateClass ()...\n"); */
135   /* TODO - Test it when implemented in the GNU Runtime */
136   /*  printf ("Testing objc_getAssociatedObject ()...\n");  */
138   printf ("Testing objc_getClass ()...\n");
139   {
140     if (strcmp (class_getName (objc_getClass ("MySubClass")),
141                 "MySubClass") != 0)
142       abort ();
143   }
145   printf ("Testing objc_getClassList ()...\n");
146   {
147     Class *list;
148     int i, count, other_count;
149     count = objc_getClassList (NULL, 0);
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);
159     if (other_count != count)
160       abort ();
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 ();
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 ();
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   }
190   /* This function does not exist with the GNU runtime.  */
191   /* printf ("Testing objc_getFutureClass ()...\n"); */
193   printf ("Testing objc_getMetaClass ()...\n");
194   {
195     if (! class_isMetaClass (objc_getMetaClass ("MyRootClass")))
196       abort ();
197   }
199   printf ("Testing objc_getProtocol ()...\n");
200   {
201     if (! protocol_isEqual (objc_getProtocol ("MyProtocol"), @protocol (MyProtocol)))
202       abort ();
203   }
205   printf ("Testing objc_getRequiredClass ()...\n");
206   {
207     if (strcmp (class_getName (objc_getRequiredClass ("MyRootClass")),
208                 "MyRootClass") != 0)
209       abort ();
210   }
212   printf ("Testing objc_lookUpClass ()...\n");
213   {
214     if (strcmp (class_getName (objc_lookUpClass ("MyRootClass")),
215                 "MyRootClass") != 0)
216       abort ();
217   }
219   /* This function does not exist with the GNU runtime.  */
220   /* printf ("Testing objc_setFutureClass ()...\n"); */
222   printf ("Testing objc_registerClassPair ()...\n");
223   {
224     Class new_class = objc_allocateClassPair (objc_getClass ("MySubClass"), "MySubSubClass", 0);
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 ();
233     if (class_getSuperclass (new_class) != objc_getClass ("MySubClass"))
234       abort ();
236     if (! class_conformsToProtocol (new_class, @protocol (MySecondProtocol)))
237       abort ();
238   }
240   /* TODO - Test it when implemented in the GNU Runtime */
241   /*  printf ("Testing objc_removeAssociatedObjects ()...\n");  */
243   /* TODO - Test it when implemented in the GNU Runtime */
244   /*  printf ("Testing objc_setAssociatedObject ()...\n");  */
246   return 0;