2014-04-15 Richard Biener <rguenther@suse.de>
[official-gcc.git] / gcc / testsuite / obj-c++.dg / gnu-api-2-sel.mm
blobff50058566b4d5a5ecfc99dc617db3eaceeffdc9
1 /* Test the Modern GNU Objective-C Runtime API.
3   This is test 'sel', covering all functions starting with 'sel'.  */
5 /* { dg-do run } */
6 /* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-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 <iostream>
13 #include <cstring>
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 - (void) method;
41 @end
43 @implementation MySubClass
44 - (void) setVariable: (id)value { variable_ivar = value; }
45 - (id) variable { return variable_ivar; }
46 - (void) method { return; }
47 @end
49 @interface ClassA : MyRootClass
50 - (id) conflictingSelectorMethod;
51 @end
53 @implementation ClassA
54 - (id) conflictingSelectorMethod { return nil; }
55 @end
57 @interface ClassB : MyRootClass
58 - (void) conflictingSelectorMethod;
59 @end
61 @implementation ClassB
62 - (void) conflictingSelectorMethod { return; }
63 @end
65 int main ()
67   /* Functions are tested in alphabetical order.  */
69 #ifdef __GNU_LIBOBJC__
70   std::cout << "Testing sel_copyTypedSelectorList ()...\n";
71   {
72     unsigned int count;
73     SEL * list = sel_copyTypedSelectorList ("method", &count);
75     /* There should only be two, since 'method' is referenced twice,
76        once with types and once without (in this very test).  */
77     if (count != 2)
78       abort ();
80     /* Check that both selectors are not-NULL, and have the correct
81        name.  We use @selector() here, which wouldn't really be
82        needed, just to register a second, untyped selector with name
83        'method'.  */
84     if (std::strcmp (sel_getName (list[0]), sel_getName (@selector (method))) != 0)
85       abort ();
87     if (std::strcmp (sel_getName (list[1]), sel_getName (@selector (method))) != 0)
88       abort ();
89     
90     if (list[2] != NULL)
91       abort ();
92   }
93 #endif
95   std::cout << "Testing sel_getName () ...\n";
96   {
97     if (std::strcmp (sel_getName (@selector (variable)), "variable") != 0)
98       abort ();
100     if (std::strcmp (sel_getName (NULL), "<null selector>") != 0)
101       abort ();
102   }
104 #ifdef __GNU_LIBOBJC__
105   std::cout << "Testing sel_getTypeEncoding () ...\n";
106   {
107     /* Get a selector from a real class, so it has interesting
108        types.  */
109     Method method = class_getInstanceMethod (objc_getClass ("MySubClass"),
110                                              @selector (variable));
111     
112     if (std::strcmp (sel_getTypeEncoding (method_getName (method)),
113                 method_getTypeEncoding (method)) != 0)
114       abort ();
116     if (sel_getTypeEncoding (NULL) != NULL)
117       abort ();
118   }
119 #endif
121 #ifdef __GNU_LIBOBJC__
122   std::cout << "Testing sel_getTypedSelector () ...\n";
123   {
124     /* First try with a selector where we know that a typed one has
125        been registered.  */
126     SEL selector = sel_getTypedSelector ("variable");
128     if (selector == NULL)
129       abort ();
131     if (sel_getTypeEncoding (selector) == NULL)
132       abort ();
134     /* Now try a selector which was never registered.  */
135     selector = sel_getTypedSelector ("not_registered");
137     if (selector != NULL)
138       abort ();
140     /* Now try registering a selector with no types.  The following
141        line is just a way to have an unused '@selector()' expression
142        without the compiler complaining.  */
143     if (@selector (registered_with_no_types) == NULL)
144       abort ();
146     /* Try getting it.  Nothing should be returned because it is
147        untyped.  */
148     selector = sel_getTypedSelector ("registered_with_no_types");
150     if (selector != NULL)
151       abort ();
153     /* Now try a selector with multiple, conflicting types.  NULL
154        should be returned.  */
155     selector = sel_getTypedSelector ("conflictingSelectorMethod");
157     if (selector != NULL)
158       abort ();
159   }
160 #endif
162   std::cout << "Testing sel_getUid () ...\n";
163   {
164     if (std::strcmp (sel_getName (sel_getUid ("myMethod")), "myMethod") != 0)
165       abort ();
167     if (sel_getUid (NULL) != NULL)
168       abort ();
169   }
171   std::cout << "Testing sel_isEqual () ...\n";
172   {
173     if (! sel_isEqual (@selector (setVariable:), @selector (setVariable:)))
174       abort ();
175   }
176   
177   std::cout << "Testing sel_registerName () ...\n";
178   {
179     if (std::strcmp (sel_getName (sel_registerName ("myMethod")), "myMethod") != 0)
180       abort ();
182     if (sel_registerName (NULL) != NULL)
183       abort ();
184   }
186 #ifdef __GNU_LIBOBJC__
187   std::cout << "Testing set_registerTypedName () ...\n";
188   {
189     const char *types = method_getTypeEncoding (class_getInstanceMethod 
190                                                 (objc_getClass ("MySubClass"),
191                                                  @selector (variable)));
192     SEL selector = sel_registerTypedName ("aMethod", types);
193     
194     if (std::strcmp (sel_getName (selector), "aMethod") != 0)
195       abort ();
197     if (std::strcmp (sel_getTypeEncoding (selector), types) != 0)
198       abort ();
200     if (sel_registerTypedName (NULL, NULL) != NULL)
201       abort ();
203     if (sel_registerTypedName (NULL, types) != NULL)
204       abort ();
205   }
206 #endif
208   return (0);