1/* Test the Modern GNU Objective-C Runtime API.
2
3   This is test 'objc_msg_lookup', covering objc_msg_lookup(),
4   objc_msg_lookup_super() and struct objc_super.  */
5
6/* { dg-do run } */
7/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
8
9/* To get the modern GNU Objective-C Runtime API, you include
10   objc/runtime.h.  */
11#include <objc/runtime.h>
12
13/* For objc_msg_lookup(), objc_msg_lookup_super() and struct
14   objc_super.  */
15#include <objc/message.h>
16
17#include <stdlib.h>
18#include <iostream>
19#include <cstring>
20
21@interface MyRootClass
22{ Class isa; }
23+ alloc;
24- init;
25- (int) test;
26@end
27
28@implementation MyRootClass
29+ alloc { return class_createInstance (self, 0); }
30- init  { return self; }
31- (int) test { return 20; }
32@end
33
34@interface MySubClass : MyRootClass
35- (int) test;
36@end
37
38@implementation MySubClass
39- (int) test { return 11; }
40@end
41
42int main ()
43{
44  /* Functions are tested in alphabetical order.  */
45
46  std::cout << "Testing objc_msg_lookup () ...\n";
47  {
48    MySubClass *object = [[MySubClass alloc] init];
49    int (* test_IMP) (id receiver, SEL selector);
50
51    test_IMP = (int (*)(id, SEL))objc_msg_lookup (object, @selector (test));
52
53    if (test_IMP (object, @selector (test)) != 11)
54      abort ();
55  }
56
57  std::cout << "Testing objc_msg_lookup_super () ...\n";
58  {
59    MySubClass *object = [[MySubClass alloc] init];
60    struct objc_super super = { 0, 0 };
61    int (* test_IMP) (id receiver, SEL selector);
62
63    /* Get the implementation of -test for the superclass of object -
64       as if we were calling [super test] inside a method
65       implementation of object.  */
66    super.self = object;
67    super.super_class = class_getSuperclass (object_getClass (object));
68    test_IMP = (int (*)(id, SEL))objc_msg_lookup_super (&super, @selector (test));
69
70    /* Invoke it.  The method in MyRootClass, not the one in
71       MySubClass, should be invoked.  */
72    if (test_IMP (object, @selector (test)) != 20)
73      abort ();
74  }
75
76  return (0);
77}
78