1 /* Test the Modern GNU Objective-C Runtime API.
3 This is test 'objc', covering all functions starting with 'objc'. */
6 /* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
8 /* To get the modern GNU Objective-C Runtime API, you include
10 #include <objc/runtime.h>
15 @interface MyRootClass
21 @implementation MyRootClass
22 + alloc { return class_createInstance (self, 0); }
23 - init { return self; }
30 @protocol MySecondProtocol
31 - (id) setVariable: (id)value;
34 @interface MySubClass : MyRootClass <MyProtocol>
36 - (void) setVariable: (id)value;
40 @implementation MySubClass
41 - (void) setVariable: (id)value { variable_ivar = value; }
42 - (id) variable { return variable_ivar; }
46 int main(int argc, void **args)
48 /* Functions are tested in alphabetical order. */
50 printf ("Testing objc_allocateClassPair ()...\n");
52 Class new_root_class = objc_allocateClassPair (Nil, "MyNewRootClass", 0);
53 Class new_class = objc_allocateClassPair (objc_getClass ("MyRootClass"), "MyNewSubClass", 0);
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. */
59 objc_registerClassPair (new_root_class);
60 objc_registerClassPair (new_class);
62 if (strcmp (class_getName (new_class), "MyNewSubClass") != 0)
65 if (class_getSuperclass (new_class) != objc_getClass ("MyRootClass"))
68 if (strcmp (class_getName (new_root_class), "MyNewRootClass") != 0)
71 if (class_getSuperclass (new_root_class) != Nil)
75 MySubClass *o = [[objc_getClass ("MyNewSubClass") alloc] init];
77 if (object_getClass (o) != objc_getClass ("MyNewSubClass"))
82 printf ("Testing objc_copyProtocolList ()...\n");
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);
88 Protocol ** list = objc_copyProtocolList (&count);
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)))
103 printf ("Testing objc_disposeClassPair ()...\n");
105 Method method = class_getInstanceMethod (objc_getClass ("MySubClass"), @selector (setVariable:));
106 Class new_class = objc_allocateClassPair (objc_getClass ("MyRootClass"), "MyNewSubClass", 0);
108 /* Add a bit of everything to the class to exercise undoing all these changes. */
110 /* Instance variable. */
111 class_addIvar (new_class, "my_variable", sizeof (float), __alignof__ (float), @encode (float));
113 /* Instance method. */
114 class_addMethod (new_class, @selector (setVariable:), method_getImplementation (method),
115 method_getTypeEncoding (method));
118 class_addMethod (object_getClass (new_class), @selector (setVariable:), method_getImplementation (method),
119 method_getTypeEncoding (method));
122 class_addProtocol (new_class, @protocol (MyProtocol));
124 objc_disposeClassPair (new_class);
127 /* This function currently does not exist with the GNU runtime. */
128 /* printf ("Testing objc_duplicateClass ()...\n"); */
130 /* TODO - Test it when implemented in the GNU Runtime */
131 /* printf ("Testing objc_getAssociatedObject ()...\n"); */
133 printf ("Testing objc_getClass ()...\n");
135 if (strcmp (class_getName (objc_getClass ("MySubClass")),
140 printf ("Testing objc_getClassList ()...\n");
143 int i, count, other_count;
144 count = objc_getClassList (NULL, 0);
146 /* count most likely will be 5, (MyRootClass, MySubClass,
147 Protocol, Object, NXConstantString). */
151 list = malloc (sizeof (Class) * count);
152 other_count = objc_getClassList (list, count);
154 if (other_count != count)
157 /* Spot-check: search for class 'MyRootClass' in the list. */
158 for (i = 0; i < count; i++)
160 if (strcmp (class_getName (list[i]), "MyRootClass") == 0)
166 /* Spot-check: search for class 'MySubClass' in the list. */
167 for (i = 0; i < count; i++)
169 if (strcmp (class_getName (list[i]), "MySubClass") == 0)
175 /* Spot-check: search for class 'Protocol' in the list. */
176 for (i = 0; i < count; i++)
178 if (strcmp (class_getName (list[i]), "Protocol") == 0)
185 /* This function does not exist with the GNU runtime. */
186 /* printf ("Testing objc_getFutureClass ()...\n"); */
188 printf ("Testing objc_getMetaClass ()...\n");
190 if (! class_isMetaClass (objc_getMetaClass ("MyRootClass")))
194 printf ("Testing objc_getProtocol ()...\n");
196 if (! protocol_isEqual (objc_getProtocol ("MyProtocol"), @protocol (MyProtocol)))
200 printf ("Testing objc_getRequiredClass ()...\n");
202 if (strcmp (class_getName (objc_getRequiredClass ("MyRootClass")),
207 printf ("Testing objc_lookupClass ()...\n");
209 if (strcmp (class_getName (objc_lookupClass ("MyRootClass")),
214 /* This function does not exist with the GNU runtime. */
215 /* printf ("Testing objc_setFutureClass ()...\n"); */
217 printf ("Testing objc_registerClassPair ()...\n");
219 Class new_class = objc_allocateClassPair (objc_getClass ("MySubClass"), "MySubSubClass", 0);
221 class_addProtocol (new_class, @protocol (MySecondProtocol));
223 objc_registerClassPair (new_class);
225 if (strcmp (class_getName (new_class), "MySubSubClass") != 0)
228 if (class_getSuperclass (new_class) != objc_getClass ("MySubClass"))
231 if (! class_conformsToProtocol (new_class, @protocol (MySecondProtocol)))
235 /* TODO - Test it when implemented in the GNU Runtime */
236 /* printf ("Testing objc_removeAssociatedObjects ()...\n"); */
238 /* TODO - Test it when implemented in the GNU Runtime */
239 /* printf ("Testing objc_setAssociatedObject ()...\n"); */