OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [testsuite/] [obj-c++.dg/] [gnu-api-2-class.mm] - Blame information for rev 703

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 703 jeremybenn
/* Test the Modern GNU Objective-C Runtime API.
2
 
3
  This is test 'class', covering all functions starting with 'class'.
4
  Tests calling the functions with a meta class as argument are covered
5
  in the separate file, gnu-api-2-class-meta.mm.  */
6
 
7
/* { dg-do run } */
8
/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
9
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
10
 
11
/* To get the modern GNU Objective-C Runtime API, you include
12
   objc/runtime.h.  */
13
#include 
14
#include 
15
#include 
16
#include 
17
 
18
@interface MyRootClass
19
{ Class isa; }
20
+ alloc;
21
- init;
22
+ initialize;
23
@end
24
 
25
@implementation MyRootClass
26
+ alloc { return class_createInstance (self, 0); }
27
- init  { return self; }
28
+ initialize { return self; }
29
@end
30
 
31
@protocol MyProtocol
32
- (id) variable;
33
@end
34
 
35
@protocol MySecondProtocol
36
- (id) setVariable: (id)value;
37
@end
38
 
39
@interface MySubClass : MyRootClass 
40
{ id variable_ivar; }
41
- (void) setVariable: (id)value;
42
- (id) variable;
43
@end
44
 
45
@implementation MySubClass
46
- (void) setVariable: (id)value { variable_ivar = value; }
47
- (id) variable { return variable_ivar; }
48
@end
49
 
50
@interface MyOtherSubClass : MySubClass
51
@end
52
 
53
@implementation MyOtherSubClass
54
@end
55
 
56
@interface DifferentClass : MyRootClass
57
- (id) myClass;
58
- (id) self;
59
@end
60
 
61
@implementation DifferentClass
62
- (id) myClass { return object_getClass (self); }
63
- (id) self { return self; }
64
@end
65
 
66
@interface MySubClass (MySelf)
67
- (id) mySelf;
68
@end
69
 
70
/* Hack to calculate the log2 of a byte alignment.  */
71
unsigned char
72
log_2_of (unsigned int x)
73
{
74
  unsigned char result = 0;
75
 
76
  /* We count how many times we need to divide by 2 before we reach 1.
77
     This algorithm is good enough for the small numbers (such as 8,
78
     16 or 64) that we have to deal with.  */
79
  while (x > 1)
80
    {
81
      x = x / 2;
82
      result++;
83
    }
84
 
85
  return result;
86
}
87
 
88
int main ()
89
{
90
  /* Functions are tested in alphabetical order.  */
91
 
92
  std::cout << "Testing class_addIvar ()...\n";
93
  {
94
    Class new_class = objc_allocateClassPair (objc_getClass ("MySubClass"), "MySubSubClass", 0);
95
 
96
    if (new_class == Nil)
97
      abort ();
98
 
99
    if (! class_addIvar (new_class, "variable2_ivar", sizeof (id),
100
                         log_2_of (__alignof__ (id)), @encode (id)))
101
      abort ();
102
 
103
    if (! class_addIvar (new_class, "variable3_ivar", sizeof (unsigned char),
104
                         log_2_of (__alignof__ (unsigned char)), @encode (unsigned char)))
105
      abort ();
106
 
107
    if (! class_addIvar (new_class, "variable4_ivar", sizeof (unsigned long),
108
                         log_2_of (__alignof__ (unsigned long)), @encode (unsigned long)))
109
      abort ();
110
 
111
    objc_registerClassPair (new_class);
112
 
113
    {
114
      MySubClass *o = [[(Class)objc_getClass ("MySubSubClass") alloc] init];
115
      Ivar variable2 = class_getInstanceVariable (objc_getClass ("MySubSubClass"), "variable2_ivar");
116
      Ivar variable3 = class_getInstanceVariable (objc_getClass ("MySubSubClass"), "variable3_ivar");
117
      Ivar variable4 = class_getInstanceVariable (objc_getClass ("MySubSubClass"), "variable4_ivar");
118
 
119
      if (variable2 == NULL  || variable3 == NULL  ||  variable4 == NULL)
120
        abort ();
121
 
122
      if (std::strcmp (ivar_getName (variable2), "variable2_ivar") != 0)
123
        abort ();
124
 
125
      if (std::strcmp (ivar_getName (variable3), "variable3_ivar") != 0)
126
        abort ();
127
 
128
      if (std::strcmp (ivar_getName (variable4), "variable4_ivar") != 0)
129
        abort ();
130
 
131
      {
132
        unsigned char *var3 = (unsigned char *)((char *)o + ivar_getOffset (variable3));
133
        unsigned long *var4 = (unsigned long *)((char *)o + ivar_getOffset (variable4));
134
 
135
        object_setIvar (o, variable2, new_class);
136
        *var3 = 230;
137
        *var4 = 89000L;
138
 
139
        if (object_getIvar (o, variable2) != new_class)
140
          abort ();
141
 
142
        if (*var3 != 230)
143
          abort ();
144
 
145
        if (*var4 != 89000L)
146
          abort ();
147
      }
148
    }
149
  }
150
 
151
  std::cout << "Testing class_addMethod ()...\n";
152
  {
153
    Class new_class = objc_allocateClassPair (objc_getClass ("MyRootClass"), "MySubClass2", 0);
154
    Method method1 = class_getInstanceMethod (objc_getClass ("MySubClass"), @selector (setVariable:));
155
    Method method2 = class_getInstanceMethod (objc_getClass ("MySubClass"), @selector (variable));
156
 
157
    if (new_class == Nil)
158
      abort ();
159
 
160
    if (! class_addIvar (new_class, "variable_ivar", sizeof (id),
161
                         log_2_of (__alignof__ (id)), @encode (id)))
162
      abort ();
163
 
164
    if (! class_addMethod (new_class, @selector (setVariable:), method_getImplementation (method1),
165
                           method_getTypeEncoding (method1)))
166
      abort ();
167
 
168
    if (! class_addMethod (new_class, @selector (variable), method_getImplementation (method2),
169
                           method_getTypeEncoding (method2)))
170
      abort ();
171
 
172
    /* Test that if the method already exists in the class,
173
       class_addMethod() returns NO.  */
174
    if (class_addMethod (new_class, @selector (variable), method_getImplementation (method2),
175
                         method_getTypeEncoding (method2)))
176
      abort ();
177
 
178
    objc_registerClassPair (new_class);
179
 
180
    /* Now, MySubClass2 is basically the same as MySubClass!  We'll
181
       use the variable and setVariable: methods on it.  */
182
    {
183
      MySubClass *o = (MySubClass *)[[(Class)objc_getClass ("MySubClass2") alloc] init];
184
 
185
      [o setVariable: o];
186
 
187
      if ([o variable] != o)
188
        abort ();
189
    }
190
 
191
    /* Now, try that if you take an existing class and try to add an
192
       already existing method, class_addMethod returns NO.  This is
193
       subtly different from before, when 'new_class' was still in
194
       construction.  Now it's a real class and the libobjc internals
195
       differ between the two cases.  */
196
    if (class_addMethod (new_class, @selector (variable), method_getImplementation (method2),
197
                         method_getTypeEncoding (method2)))
198
      abort ();
199
  }
200
 
201
  std::cout << "Testing class_addProtocol ()...\n";
202
  {
203
    if (!class_addProtocol (objc_getClass ("MySubClass"), @protocol (MySecondProtocol)))
204
      abort ();
205
 
206
    if (!class_conformsToProtocol (objc_getClass ("MySubClass"), @protocol (MyProtocol)))
207
      abort ();
208
 
209
    if (!class_conformsToProtocol (objc_getClass ("MySubClass"), @protocol (MySecondProtocol)))
210
      abort ();
211
  }
212
 
213
  std::cout << "Testing class_conformsToProtocol ()...\n";
214
  {
215
    if (class_conformsToProtocol (objc_getClass ("MyRootClass"), @protocol (MyProtocol)))
216
      abort ();
217
 
218
    if (!class_conformsToProtocol (objc_getClass ("MySubClass"), @protocol (MyProtocol)))
219
      abort ();
220
 
221
    /* Test that class_conformsToProtocol checks the class, but not
222
       superclasses.  */
223
    if (class_conformsToProtocol (objc_getClass ("MyOtherSubClass"), @protocol (MyProtocol)))
224
      abort ();
225
  }
226
 
227
  std::cout << "Testing class_copyIvarList ()...\n";
228
  {
229
    unsigned int count;
230
    Ivar * list = class_copyIvarList (objc_getClass ("MySubClass"), &count);
231
 
232
    if (count != 1)
233
      abort ();
234
 
235
    if (std::strcmp (ivar_getName (list[0]), "variable_ivar") != 0)
236
      abort ();
237
 
238
    if (list[1] != NULL)
239
      abort ();
240
  }
241
 
242
  std::cout << "Testing class_copyMethodList ()...\n";
243
  {
244
    unsigned int count;
245
    Method * list = class_copyMethodList (objc_getClass ("MySubClass"), &count);
246
 
247
    if (count != 2)
248
      abort ();
249
 
250
    if (! ((std::strcmp (sel_getName (method_getName (list[0])), "variable") == 0
251
            && std::strcmp (sel_getName (method_getName (list[1])), "setVariable:") == 0)
252
           || (std::strcmp (sel_getName (method_getName (list[0])), "setVariable:") == 0
253
               && std::strcmp (sel_getName (method_getName (list[1])), "variable") == 0)))
254
      abort ();
255
 
256
    if (list[2] != NULL)
257
      abort ();
258
  }
259
 
260
  /* TODO: Test new ABI (when available).  */
261
  std::cout << "Testing class_copyPropertyList ()...\n";
262
  {
263
    unsigned int count;
264
    objc_property_t * list = class_copyPropertyList (objc_getClass ("MySubClass"), &count);
265
 
266
    if (count != 0  ||  list != NULL)
267
      abort ();
268
  }
269
 
270
  std::cout << "Testing class_copyProtocolList ()...\n";
271
  {
272
    unsigned int count;
273
    Protocol ** list = class_copyProtocolList (objc_getClass ("MySubClass"), &count);
274
 
275
    /* Remember that we added MySecondProtocol in the test above.  */
276
    if (count != 2)
277
      abort ();
278
 
279
    if (! ((std::strcmp (protocol_getName (list[0]), "MyProtocol") == 0
280
            && std::strcmp (protocol_getName (list[1]), "MySecondProtocol") == 0)
281
           || (std::strcmp (protocol_getName (list[0]), "MySecondProtocol") == 0
282
               && std::strcmp (protocol_getName (list[1]), "MyProtocol") == 0)))
283
      abort ();
284
 
285
    if (list[2] != NULL)
286
      abort ();
287
  }
288
 
289
  std::cout << "Testing class_createInstance ()...\n";
290
  {
291
    MySubClass *object = [[MySubClass alloc] init];
292
 
293
    [object setVariable: object];
294
    if ([object variable] != object)
295
      abort ();
296
  }
297
 
298
  std::cout << "Testing class_getClassMethod ()...\n";
299
  {
300
    Method method = class_getClassMethod (objc_getClass ("MySubClass"),
301
                                          @selector(alloc));
302
 
303
    if (method == NULL)
304
      abort ();
305
 
306
    if (std::strcmp (sel_getName (method_getName (method)), "alloc") != 0)
307
      abort ();
308
 
309
    if (class_getClassMethod (objc_getClass ("MySubClass"),
310
                              @selector(variable)))
311
      abort ();
312
  }
313
 
314
  std::cout << "Testing class_getClassVariable ()...\n";
315
  {
316
    if (class_getClassVariable (objc_getClass ("MySubClass"), "variable_ivar"))
317
      abort ();
318
  }
319
 
320
  std::cout << "Testing class_getInstanceMethod ()...\n";
321
  {
322
    Method method = class_getInstanceMethod (objc_getClass ("MySubClass"),
323
                                             @selector(variable));
324
 
325
    if (method == NULL)
326
      abort ();
327
 
328
    if (std::strcmp (sel_getName (method_getName (method)), "variable") != 0)
329
      abort ();
330
 
331
    if (class_getInstanceMethod (objc_getClass ("MySubClass"),
332
                                 @selector(alloc)))
333
      abort ();
334
  }
335
 
336
  std::cout << "Testing class_getInstanceSize ()...\n";
337
  {
338
    if (class_getInstanceSize (objc_getClass ("MyRootClass")) != sizeof (struct objc_object))
339
      abort ();
340
  }
341
 
342
  std::cout << "Testing class_getInstanceVariable ()...\n";
343
  {
344
    Ivar variable = class_getInstanceVariable (objc_getClass ("MySubClass"), "variable_ivar");
345
 
346
    if (variable == NULL)
347
      abort ();
348
 
349
    if (std::strcmp (ivar_getName (variable), "variable_ivar") != 0)
350
      abort ();
351
 
352
    if (class_getInstanceVariable (objc_getClass ("MySubClass"), "variable_ivar_no"))
353
      abort ();
354
  }
355
 
356
  std::cout << "Testing class_getIvarLayout ()...\n";
357
  {
358
    if (class_getIvarLayout (objc_getClass ("MyRootClass")) != NULL)
359
      abort ();
360
  }
361
 
362
  std::cout << "Testing class_getMethodImplementation ()...\n";
363
  {
364
    MySubClass *object = [[MySubClass alloc] init];
365
    IMP imp = class_getMethodImplementation (objc_getClass ("MySubClass"),
366
                                             @selector(variable));
367
 
368
    if (imp == NULL)
369
      abort ();
370
 
371
    [object setVariable: object];
372
 
373
    if ((*imp)(object, @selector(variable)) != object)
374
      abort ();
375
  }
376
 
377
  /* This function does not exist with the GNU runtime.  */
378
  /* std::cout << "Testing class_getMethodImplementation_stret ()...\n"; */
379
 
380
  std::cout << "Testing class_getName ()...\n";
381
  {
382
    if (std::strcmp (class_getName (objc_getClass ("MyRootClass")),
383
                "MyRootClass") != 0)
384
      abort ();
385
  }
386
 
387
  /* TODO: Test new ABI (when available).  */
388
  std::cout << "Testing class_getProperty ()...\n";
389
  {
390
    if (class_getProperty (objc_getClass ("MyRootClass"), "property") != NULL)
391
      abort ();
392
  }
393
 
394
  std::cout << "Testing class_getSuperclass ()...\n";
395
  {
396
    MySubClass *object = [[MySubClass alloc] init];
397
    if (class_getSuperclass (object_getClass (object)) != objc_getClass ("MyRootClass"))
398
      abort ();
399
 
400
    /* Test that it works on a newly created, but not registered, class.  */
401
    {
402
      Class new_class = objc_allocateClassPair (objc_getClass ("MyRootClass"), "MySubClass3", 0);
403
 
404
      if (class_getSuperclass (new_class) != objc_getClass ("MyRootClass"))
405
        abort ();
406
    }
407
  }
408
 
409
  std::cout << "Testing class_getVersion ()...\n";
410
  {
411
    if (class_getVersion (objc_getClass ("MySubClass")) != 0)
412
      abort ();
413
  }
414
 
415
   std::cout << "Testing class_getWeakIvarLayout ()...\n";
416
  {
417
    if (class_getWeakIvarLayout (objc_getClass ("MyRootClass")) != NULL)
418
      abort ();
419
  }
420
 
421
  std::cout << "Testing class_isMetaClass ()...\n";
422
  {
423
    MySubClass *object = [[MySubClass alloc] init];
424
    if (class_isMetaClass (object_getClass (object))
425
        || ! class_isMetaClass (object_getClass (object_getClass (object))))
426
      abort ();
427
  }
428
 
429
  std::cout << "Testing class_replaceMethod ()...\n";
430
  {
431
    Method new_method = class_getInstanceMethod (objc_getClass ("DifferentClass"),
432
                                                 @selector (myClass));
433
    Method old_method = class_getInstanceMethod (objc_getClass ("MySubClass"),
434
                                                 @selector (variable));
435
    const char *new_types = method_getTypeEncoding (new_method);
436
    IMP new_imp = method_getImplementation (new_method);
437
    const char *old_types = method_getTypeEncoding (old_method);
438
    IMP old_imp = class_replaceMethod (objc_getClass ("MySubClass"), @selector (variable),
439
                                       method_getImplementation (new_method),
440
                                       method_getTypeEncoding (new_method));
441
    MySubClass *o = [[MySubClass alloc] init];
442
 
443
    [o setVariable: o];
444
 
445
    /* Try the new method implementation.  */
446
    if ([o variable] != objc_getClass ("MySubClass"))
447
      abort ();
448
 
449
    /* Put the original method back.  */
450
    class_replaceMethod (objc_getClass ("MySubClass"), @selector (variable),
451
                         old_imp, old_types);
452
 
453
    /* Test it's back to what it was.  */
454
    if ([o variable] != o)
455
      abort ();
456
 
457
    {
458
      DifferentClass *o = [[DifferentClass alloc] init];
459
 
460
      /* Finally, try adding a new method.  */
461
      class_replaceMethod (objc_getClass ("DifferentClass"), @selector (mySelf),
462
                           new_imp, new_types);
463
 
464
      if ([(MySubClass*)o mySelf] != objc_getClass ("DifferentClass"))
465
        abort ();
466
    }
467
  }
468
 
469
  std::cout << "Testing class_respondsToSelector ()...\n";
470
  {
471
    if (! class_respondsToSelector (objc_getClass ("MySubClass"), @selector(setVariable:)))
472
      abort ();
473
 
474
    if (class_respondsToSelector (objc_getClass ("MyRootClass"), @selector(setVariable:)))
475
      abort ();
476
  }
477
 
478
  /* This is not really implemented with the GNU runtime.  */
479
  /* std::cout << "Testing class_setIvarLayout ()...\n"; */
480
 
481
  std::cout << "Testing class_setVersion ()...\n";
482
  {
483
    class_setVersion (objc_getClass ("MySubClass"), 45);
484
 
485
    if (class_getVersion (objc_getClass ("MySubClass")) != 45)
486
      abort ();
487
 
488
    class_setVersion (objc_getClass ("MySubClass"), 46);
489
 
490
    if (class_getVersion (objc_getClass ("MySubClass")) != 46)
491
      abort ();
492
  }
493
 
494
  /* This is not really implemented with the GNU runtime.  */
495
  /* std::cout << "Testing class_setWeakIvarLayout ()...\n"; */
496
 
497
  return (0);
498
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.