1/* Test the Modern GNU Objective-C Runtime API. 2 3 This is test 'protocol', covering all functions starting with 'protocol'. */ 4 5/* { dg-do run } */ 6/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */ 7/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ 8// { dg-additional-options "-Wno-objc-root-class" } 9 10/* To get the modern GNU Objective-C Runtime API, you include 11 objc/runtime.h. */ 12#include <objc/runtime.h> 13#include <stdlib.h> 14#include <iostream> 15#include <cstring> 16 17@interface MyRootClass 18{ Class isa; } 19+ alloc; 20- init; 21+ initialize; 22@end 23 24@implementation MyRootClass 25+ alloc { return class_createInstance (self, 0); } 26- init { return self; } 27+ initialize { return self; } 28@end 29 30@protocol MyProtocol 31- (id) variable; 32@end 33 34@protocol MySecondProtocol 35- (id) setVariable: (id)value; 36@end 37 38@protocol MyThirdProtocol <MySecondProtocol> 39- (id) setAnotherVariable: (id)value; 40@end 41 42@interface MySubClass : MyRootClass <MyProtocol> 43{ id variable_ivar; } 44- (void) setVariable: (id)value; 45- (id) variable; 46@end 47 48@implementation MySubClass 49- (void) setVariable: (id)value { variable_ivar = value; } 50- (id) variable { return variable_ivar; } 51@end 52 53 54int main () 55{ 56 /* Functions are tested in alphabetical order. */ 57 58 std::cout << "Testing protocol_conformsToProtocol ()...\n"; 59 { 60 if (!protocol_conformsToProtocol (@protocol (MyProtocol), 61 @protocol (MyProtocol))) 62 abort (); 63 64 if (!protocol_conformsToProtocol (@protocol (MyThirdProtocol), 65 @protocol (MySecondProtocol))) 66 abort (); 67 68 if (protocol_conformsToProtocol (@protocol (MyProtocol), 69 @protocol (MySecondProtocol))) 70 abort (); 71 } 72 73 std::cout << "Testing protocol_copyMethodDescriptionList ()...\n"; 74 { 75 unsigned int count; 76 struct objc_method_description *list; 77 78 list = protocol_copyMethodDescriptionList (@protocol (MyThirdProtocol), 79 YES, YES, &count); 80 81 if (count != 1) 82 abort (); 83 84 if (std::strcmp (sel_getName (list[0].name), "setAnotherVariable:") != 0) 85 abort (); 86 87 if (list[1].name != NULL && list[1].types != NULL) 88 abort (); 89 } 90 91 /* TODO: Test new ABI (when available). */ 92 std::cout << "Testing protocol_copyPropertyList ()...\n"; 93 { 94 unsigned int count; 95 objc_property_t *list; 96 97 list = protocol_copyPropertyList (@protocol (MyProtocol), &count); 98 99 if (count != 0 || list != NULL) 100 abort (); 101 } 102 103 std::cout << "Testing protocol_copyProtocolList ()...\n"; 104 { 105 unsigned int count; 106 Protocol **list; 107 108 list = protocol_copyProtocolList (@protocol (MyThirdProtocol), &count); 109 110 if (count != 1) 111 abort (); 112 113 if (std::strcmp (protocol_getName (list[0]), "MySecondProtocol") != 0) 114 abort (); 115 116 if (list[1] != NULL) 117 abort (); 118 } 119 120 std::cout << "Testing protocol_getMethodDescription ()...\n"; 121 { 122 struct objc_method_description description; 123 124 description = protocol_getMethodDescription (@protocol (MySecondProtocol), 125 @selector (setVariable:), 126 YES, YES); 127 if (description.name == NULL && description.types == NULL) 128 abort (); 129 130 if (std::strcmp (sel_getName (description.name), "setVariable:") != 0) 131 abort (); 132 } 133 134 std::cout << "Testing protocol_getName ()...\n"; 135 { 136 if (std::strcmp (protocol_getName (@protocol (MyProtocol)), "MyProtocol") != 0) 137 abort (); 138 } 139 140 /* TODO: Test new ABI (when available). */ 141 std::cout << "Testing protocol_getProperty ()...\n"; 142 { 143 objc_property_t property; 144 145 property = protocol_getProperty (objc_getProtocol ("MyProtocol"), "someProperty", 146 YES, YES); 147 148 if (property != NULL) 149 abort (); 150 } 151 152 std::cout << "Testing protocol_isEqual ()...\n"; 153 { 154 if (!protocol_isEqual (@protocol (MyProtocol), 155 @protocol (MyProtocol))) 156 abort (); 157 158 if (!protocol_isEqual (@protocol (MyProtocol), 159 objc_getProtocol ("MyProtocol"))) 160 abort (); 161 } 162 163 return (0); 164} 165