diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /gcc/testsuite/objc/execute | |
download | cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2 cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'gcc/testsuite/objc/execute')
103 files changed, 5174 insertions, 0 deletions
diff --git a/gcc/testsuite/objc/execute/IMP.m b/gcc/testsuite/objc/execute/IMP.m new file mode 100644 index 000000000..f07909757 --- /dev/null +++ b/gcc/testsuite/objc/execute/IMP.m @@ -0,0 +1,41 @@ +/* Contributed by Nicola Pero - Fri Mar 9 19:39:15 CET 2001 */ + +#include <stdlib.h> +#include "../../objc-obj-c++-shared/next-mapping.h" +#include <objc/objc.h> +#include <objc/objc-api.h> + +/* Test getting and calling the IMP of a method */ + +@interface TestClass +{ + Class isa; +} +- (int) next: (int)a; +@end + +@implementation TestClass +- (int) next: (int)a +{ + return a + 1; +} +@end + +int main (void) +{ + Class class; + SEL selector; + int (* imp) (id, SEL, int); + + class = objc_get_class ("TestClass"); + selector = @selector (next:); + imp = (int (*)(id, SEL, int))method_get_imp + (class_get_class_method (class, selector)); + + if (imp (class, selector, 5) != 6) + { + abort (); + } + + return 0; +} diff --git a/gcc/testsuite/objc/execute/_cmd.m b/gcc/testsuite/objc/execute/_cmd.m new file mode 100644 index 000000000..6c579d771 --- /dev/null +++ b/gcc/testsuite/objc/execute/_cmd.m @@ -0,0 +1,35 @@ +/* Contributed by Nicola Pero - Fri Mar 9 19:39:15 CET 2001 */ + +#include <stdlib.h> +#include "../../objc-obj-c++-shared/next-mapping.h" +#include <objc/objc-api.h> + +/* Test the hidden argument _cmd to method calls */ + +@interface TestClass +{ + Class isa; +} ++ (const char*) method; +@end + +@implementation TestClass ++ (const char*) method +{ + return sel_get_name (_cmd); +} +#ifdef __NEXT_RUNTIME__ ++ initialize { return self; } +#endif +@end + + +int main (void) +{ + if (strcmp ([TestClass method], "method")) + { + abort (); + } + + return 0; +} diff --git a/gcc/testsuite/objc/execute/accessing_ivars.m b/gcc/testsuite/objc/execute/accessing_ivars.m new file mode 100644 index 000000000..e4c9cf4cd --- /dev/null +++ b/gcc/testsuite/objc/execute/accessing_ivars.m @@ -0,0 +1,58 @@ +/* Contributed by Nicola Pero - Thu Mar 8 16:27:46 CET 2001 */ +#include <stdlib.h> +#ifndef __NEXT_RUNTIME__ +#include <objc/objc-api.h> +#endif +#include "../../objc-obj-c++-shared/Object1.h" + +/* Test that by using -> we can access ivars of other objects of the same + class */ + +@interface TestClass : Object +{ + int value; +} +- (int) value; +- (int) setValue: (int)number; +- (void) takeValueFrom: (TestClass *)object; +@end + +@implementation TestClass : Object +{ + int value; +} +- (int) value +{ + return value; +} +- (int) setValue: (int)number +{ + value = number; +} +- (void) takeValueFrom: (TestClass *)object +{ + value = object->value; +} +@end + +int main (void) +{ + TestClass *a; + TestClass *b; + + a = [TestClass new]; + [a setValue: 10]; + + b = [TestClass new]; + [b setValue: -10]; + + [b takeValueFrom: a]; + + if ([b value] != [a value]) + { + abort (); + } + + return 0; +} +#include "../../objc-obj-c++-shared/Object1-implementation.h" diff --git a/gcc/testsuite/objc/execute/bf-1.m b/gcc/testsuite/objc/execute/bf-1.m new file mode 100644 index 000000000..a5d219108 --- /dev/null +++ b/gcc/testsuite/objc/execute/bf-1.m @@ -0,0 +1,22 @@ +#include <objc/objc.h> + +@interface MyObject +{ + Class isa; + float f; + char a; + struct { + int i:2; + int j:3; + int k:12; + } flags; + char c; +// void *pointer; +} +@end + +@implementation MyObject +@end + +#include "bf-common.h" + diff --git a/gcc/testsuite/objc/execute/bf-10.m b/gcc/testsuite/objc/execute/bf-10.m new file mode 100644 index 000000000..6cbdc225b --- /dev/null +++ b/gcc/testsuite/objc/execute/bf-10.m @@ -0,0 +1,19 @@ +#include <objc/objc.h> + +@interface MyObject +{ + Class isa; + float f; + char a[3]; + int i:2; + int j:6; + char c; + int k:12; + char d; +} +@end + +@implementation MyObject +@end + +#include "bf-common.h" diff --git a/gcc/testsuite/objc/execute/bf-11.m b/gcc/testsuite/objc/execute/bf-11.m new file mode 100644 index 000000000..42a97a57a --- /dev/null +++ b/gcc/testsuite/objc/execute/bf-11.m @@ -0,0 +1,21 @@ +#include <objc/objc.h> + +@interface MyObject +{ + Class isa; + float f; + char a[3]; + int i:2; + int j:6; + short s; + int k:12; + char d; + void *pointer; +} +@end + +@implementation MyObject +@end + +#include "bf-common.h" + diff --git a/gcc/testsuite/objc/execute/bf-12.m b/gcc/testsuite/objc/execute/bf-12.m new file mode 100644 index 000000000..78a19d306 --- /dev/null +++ b/gcc/testsuite/objc/execute/bf-12.m @@ -0,0 +1,21 @@ +#include <objc/objc.h> + +@interface MyObject +{ + Class isa; + float f; + char a[3]; + int i:2; + int j:6; + int s; + int k:12; + char d; + void *pointer; +} +@end + +@implementation MyObject +@end + +#include "bf-common.h" + diff --git a/gcc/testsuite/objc/execute/bf-13.m b/gcc/testsuite/objc/execute/bf-13.m new file mode 100644 index 000000000..fa47238b0 --- /dev/null +++ b/gcc/testsuite/objc/execute/bf-13.m @@ -0,0 +1,23 @@ +#include <objc/objc.h> + +@interface MyObject +{ + Class isa; + float f; + char a[3]; + struct { + int i:2; + int j:6; + char s; + int k:12; + } flags; + char d; + void *pointer; +} +@end + +@implementation MyObject +@end + +#include "bf-common.h" + diff --git a/gcc/testsuite/objc/execute/bf-14.m b/gcc/testsuite/objc/execute/bf-14.m new file mode 100644 index 000000000..99fa8fef5 --- /dev/null +++ b/gcc/testsuite/objc/execute/bf-14.m @@ -0,0 +1,22 @@ +#include <objc/objc.h> + +@interface MyObject +{ + Class isa; + float f; + char a[3]; + struct { + int i:2; + int j:6; + short s; + int k:12; + } flags; + char d; + void *pointer; +} +@end + +@implementation MyObject +@end + +#include "bf-common.h" diff --git a/gcc/testsuite/objc/execute/bf-15.m b/gcc/testsuite/objc/execute/bf-15.m new file mode 100644 index 000000000..c32e66331 --- /dev/null +++ b/gcc/testsuite/objc/execute/bf-15.m @@ -0,0 +1,23 @@ +#include <objc/objc.h> + +@interface MyObject +{ + Class isa; + float f; + char a; + struct { + int i:2; + int j:6; + int s; + int k:12; + } flags; + char d; + void *pointer; +} +@end + +@implementation MyObject +@end + +#include "bf-common.h" + diff --git a/gcc/testsuite/objc/execute/bf-16.m b/gcc/testsuite/objc/execute/bf-16.m new file mode 100644 index 000000000..e286de7c2 --- /dev/null +++ b/gcc/testsuite/objc/execute/bf-16.m @@ -0,0 +1,23 @@ +#include <objc/objc.h> + +struct A { + int i; + float f; + int a:3; + int b:2; +}; + +@interface MyObject +{ + Class isa; + int i; + float f[3]; + struct A a, b; + char c; +} +@end + +@implementation MyObject +@end + +#include "bf-common.h" diff --git a/gcc/testsuite/objc/execute/bf-17.m b/gcc/testsuite/objc/execute/bf-17.m new file mode 100644 index 000000000..7650ffae7 --- /dev/null +++ b/gcc/testsuite/objc/execute/bf-17.m @@ -0,0 +1,22 @@ +#include <objc/objc.h> + +struct A { + int i; + float f; + int a:3; + int b:2; +}; + +@interface MyObject +{ + Class isa; + int i; + float f[3]; + struct A a; +} +@end + +@implementation MyObject +@end + +#include "bf-common.h" diff --git a/gcc/testsuite/objc/execute/bf-18.m b/gcc/testsuite/objc/execute/bf-18.m new file mode 100644 index 000000000..528829554 --- /dev/null +++ b/gcc/testsuite/objc/execute/bf-18.m @@ -0,0 +1,15 @@ +#include <objc/objc.h> + +@interface MyObject +{ + Class isa; + int i; + char c[1]; +} +@end + +@implementation MyObject +@end + +#include "bf-common.h" + diff --git a/gcc/testsuite/objc/execute/bf-19.m b/gcc/testsuite/objc/execute/bf-19.m new file mode 100644 index 000000000..d9306df00 --- /dev/null +++ b/gcc/testsuite/objc/execute/bf-19.m @@ -0,0 +1,14 @@ +#include <objc/objc.h> + +@interface MyObject +{ + Class isa; + unsigned int i; + MyObject *object; +} +@end + +@implementation MyObject +@end + +#include "bf-common.h" diff --git a/gcc/testsuite/objc/execute/bf-2.m b/gcc/testsuite/objc/execute/bf-2.m new file mode 100644 index 000000000..f776eea5d --- /dev/null +++ b/gcc/testsuite/objc/execute/bf-2.m @@ -0,0 +1,22 @@ +#include <objc/objc.h> + +@interface MyObject +{ + Class isa; + float f; + char a[3]; + struct { + int i:2; + int j:3; + int k:12; + } flags; + char c; + void *pointer; +} +@end + +@implementation MyObject +@end + +#include "bf-common.h" + diff --git a/gcc/testsuite/objc/execute/bf-20.m b/gcc/testsuite/objc/execute/bf-20.m new file mode 100644 index 000000000..311a0fd5b --- /dev/null +++ b/gcc/testsuite/objc/execute/bf-20.m @@ -0,0 +1,13 @@ +#include <objc/objc.h> + +@interface MyObject +{ + short s; + char c; +} +@end + +@implementation MyObject +@end + +#include "bf-common.h" diff --git a/gcc/testsuite/objc/execute/bf-21.m b/gcc/testsuite/objc/execute/bf-21.m new file mode 100644 index 000000000..587060d1d --- /dev/null +++ b/gcc/testsuite/objc/execute/bf-21.m @@ -0,0 +1,18 @@ +#include <objc/objc.h> + +typedef enum +{ + A, B +} enumeration; + +@interface MyObject +{ + enumeration g:4; +} +@end + +@implementation MyObject +@end + +#include "bf-common.h" + diff --git a/gcc/testsuite/objc/execute/bf-3.m b/gcc/testsuite/objc/execute/bf-3.m new file mode 100644 index 000000000..52863bb6f --- /dev/null +++ b/gcc/testsuite/objc/execute/bf-3.m @@ -0,0 +1,22 @@ +#include <objc/objc.h> + +@interface MyObject +{ + Class isa; + float f; + char a; + struct { + int i:2; + int j:6; + int k:12; + } flags; + char c; + void *pointer; +} +@end + +@implementation MyObject +@end + +#include "bf-common.h" + diff --git a/gcc/testsuite/objc/execute/bf-4.m b/gcc/testsuite/objc/execute/bf-4.m new file mode 100644 index 000000000..5654b6fed --- /dev/null +++ b/gcc/testsuite/objc/execute/bf-4.m @@ -0,0 +1,22 @@ +#include <objc/objc.h> + +@interface MyObject +{ + Class isa; + float f; + char a[3]; + struct { + int i:2; + int j:6; + int k:12; + } flags; + char c; + void *pointer; +} +@end + +@implementation MyObject +@end + +#include "bf-common.h" + diff --git a/gcc/testsuite/objc/execute/bf-5.m b/gcc/testsuite/objc/execute/bf-5.m new file mode 100644 index 000000000..b75509ddd --- /dev/null +++ b/gcc/testsuite/objc/execute/bf-5.m @@ -0,0 +1,20 @@ +#include <objc/objc.h> + +@interface MyObject +{ + Class isa; + float f; + char a; + int i:2; + int j:3; + int k:12; + char c; + void *pointer; +} +@end + +@implementation MyObject +@end + +#include "bf-common.h" + diff --git a/gcc/testsuite/objc/execute/bf-6.m b/gcc/testsuite/objc/execute/bf-6.m new file mode 100644 index 000000000..187c7582d --- /dev/null +++ b/gcc/testsuite/objc/execute/bf-6.m @@ -0,0 +1,20 @@ +#include <objc/objc.h> + +@interface MyObject +{ + Class isa; + float f; + char a[3]; + int i:2; + int j:3; + int k:12; + char c; + void *pointer; +} +@end + +@implementation MyObject +@end + +#include "bf-common.h" + diff --git a/gcc/testsuite/objc/execute/bf-7.m b/gcc/testsuite/objc/execute/bf-7.m new file mode 100644 index 000000000..f1ee46e0c --- /dev/null +++ b/gcc/testsuite/objc/execute/bf-7.m @@ -0,0 +1,19 @@ +#include <objc/objc.h> + +@interface MyObject +{ + Class isa; + float f; + char a; + int i:2; + int j:6; + int k:12; + char c; + void *pointer; +} +@end + +@implementation MyObject +@end + +#include "bf-common.h" diff --git a/gcc/testsuite/objc/execute/bf-8.m b/gcc/testsuite/objc/execute/bf-8.m new file mode 100644 index 000000000..164950fca --- /dev/null +++ b/gcc/testsuite/objc/execute/bf-8.m @@ -0,0 +1,20 @@ +#include <objc/objc.h> + +@interface MyObject +{ + Class isa; + float f; + char a[3]; + int i:2; + int j:6; + int k:12; + char c; + void *pointer; +} +@end + +@implementation MyObject +@end + +#include "bf-common.h" + diff --git a/gcc/testsuite/objc/execute/bf-9.m b/gcc/testsuite/objc/execute/bf-9.m new file mode 100644 index 000000000..9fc7c704b --- /dev/null +++ b/gcc/testsuite/objc/execute/bf-9.m @@ -0,0 +1,20 @@ +#include <objc/objc.h> + +@interface MyObject +{ + Class isa; + float f; + char a[3]; + int i:2; + int j:3; + char c; + int k:12; + char d; + void *pointer; +} +@end + +@implementation MyObject +@end + +#include "bf-common.h" diff --git a/gcc/testsuite/objc/execute/bf-common.h b/gcc/testsuite/objc/execute/bf-common.h new file mode 100644 index 000000000..ca70c21a4 --- /dev/null +++ b/gcc/testsuite/objc/execute/bf-common.h @@ -0,0 +1,92 @@ +#include <stdio.h> +#include <stdlib.h> + +#ifndef __NEXT_RUNTIME__ +#include <objc/encoding.h> +#else +/* The following header, together with the implementation included below, + emulate functionality provided by the GNU runtime but not available from + the NeXT runtime. */ +#include "../../objc-obj-c++-shared/objc-test-suite-next-encode-assist.h" +#define objc_get_class(C) objc_getClass(C) +#endif + +#ifndef __OBJC2__ +void print_ivars (Class class) +{ + struct objc_ivar_list* ivars = class->ivars; + int i; + + for (i = 0; i < ivars->ivar_count; i++) { + struct objc_ivar *ivar = &(ivars->ivar_list[i]); + printf ("ivar '%s', type '%s', offset %d\n", + ivar->ivar_name, ivar->ivar_type, ivar->ivar_offset); + } +} + +void compare_structures (Class class, const char* type) +{ + struct objc_struct_layout layout; + struct objc_ivar_list* ivars = class->ivars; + int i = 0; + int position; + + objc_layout_structure (type, &layout); + + while (objc_layout_structure_next_member (&layout)) + { + struct objc_ivar *ivar; + const char *ivar_type; + + if (i > ivars->ivar_count) + { + printf ("too many ivars in type %s, layout = %s\n", + type, layout.type); + exit (1); + } + + ivar = &(ivars->ivar_list[i]); + objc_layout_structure_get_info (&layout, &position, NULL, &ivar_type); + printf ("real ivar '%s' offset %d\n", + ivar->ivar_name, ivar->ivar_offset); + printf ("computed type '%s' offset %d\n", ivar_type, position); + if (position != ivar->ivar_offset) + { + printf ("offset %d and computed position %d don't match on ivar '%s'" + " (i = %d)\n", + ivar->ivar_offset, position, ivar->ivar_name, i); + exit (1); + } + i++; + } + + printf ("%d ivars checked\n", i); +} +#endif + +int main () +{ +#ifndef __OBJC2__ + struct class_vars + { + @defs (MyObject); + }; + int size1, size2; + Class class = objc_get_class ("MyObject"); + printf ("type = %s\n", @encode (struct class_vars)); + print_ivars (class); + + compare_structures (class, @encode(struct class_vars)); + if ((size1 = objc_sizeof_type (@encode(struct class_vars))) + != (size2 = sizeof (struct class_vars))) + { + printf ("sizes don't match (computed %d, exact %d)\n", size1, size2); + abort (); + } +#endif + + exit (0); +} +#ifndef __OBJC2__ +#include "../../objc-obj-c++-shared/objc-test-suite-next-encode-assist-impl.h" +#endif diff --git a/gcc/testsuite/objc/execute/bycopy-1.m b/gcc/testsuite/objc/execute/bycopy-1.m new file mode 100644 index 000000000..c719d27d1 --- /dev/null +++ b/gcc/testsuite/objc/execute/bycopy-1.m @@ -0,0 +1,19 @@ +/* + * Contributed by Nicola Pero <nicola@brainstorm.co.uk> + * Fri Feb 2 11:48:01 GMT 2001 + */ + +#include "../../objc-obj-c++-shared/Protocol1.h" + +@protocol MyProtocol +- (bycopy id) bycopyMethod; +@end + +int main (void) +{ + [nil bycopyMethod]; + + exit (0); +} + + diff --git a/gcc/testsuite/objc/execute/bycopy-2.m b/gcc/testsuite/objc/execute/bycopy-2.m new file mode 100644 index 000000000..840881f4a --- /dev/null +++ b/gcc/testsuite/objc/execute/bycopy-2.m @@ -0,0 +1,30 @@ +/* + * Contributed by Nicola Pero <nicola@brainstorm.co.uk> + * Fri Feb 2 11:48:01 GMT 2001 + */ + +#include "../../objc-obj-c++-shared/Protocol1.h" + +@protocol MyProtocol ++ (bycopy id<MyProtocol>) bycopyMethod; +@end + +@interface MyObject : Object <MyProtocol> +@end + +@implementation MyObject ++ (bycopy id<MyProtocol>) bycopyMethod +{ + return [MyObject alloc]; +} +@end + +int main (void) +{ + MyObject *object; + + object = [MyObject bycopyMethod]; + + exit (0); +} +#include "../../objc-obj-c++-shared/Object1-implementation.h" diff --git a/gcc/testsuite/objc/execute/bycopy-3.m b/gcc/testsuite/objc/execute/bycopy-3.m new file mode 100644 index 000000000..15c49a5dd --- /dev/null +++ b/gcc/testsuite/objc/execute/bycopy-3.m @@ -0,0 +1,115 @@ +/* + * Contributed by Nicola Pero <nicola@brainstorm.co.uk> + * Wed Feb 28 12:27:03 CET 2001 + */ + +/* + * This test contains some no-op code which is needed to keep it + * compile on broken gcc 3.x. Anyway, the no-op code does not + * interfere with what we are testing, which is that the `bycopy' + * keyword generates the _F_BYCOPY qualifier for the return type. */ + +extern void exit (int) __attribute__ ((noreturn)); +extern int printf (const char *, ...); + +#include <objc/Protocol.h> + +#ifndef __NEXT_RUNTIME__ +#include <objc/encoding.h> +#endif + +@protocol MyProtocol ++ (bycopy id<MyProtocol>) bycopyMethod; +@end + +/* This no-op class to keep it compile under broken gcc 3.x */ +@interface MyObject : Object <MyProtocol> +#ifdef __OBJC2__ ++ (id) initialize; ++ (id) alloc; ++ new; +- init; +#endif +@end + +@implementation MyObject ++ (bycopy id<MyProtocol>) bycopyMethod +{ + return [MyObject alloc]; +} +#ifdef __OBJC2__ ++ initialize {return self;} ++ alloc { return class_createInstance (self, 0);} ++ new { return [[self alloc] init]; } +- init {return self;} +#endif +@end + +/* The following header, together with the implementation included below, + emulate functionality provided by the GNU runtime but not available from + the NeXT runtime. */ +#include "../../objc-obj-c++-shared/objc-test-suite-next-encode-assist.h" + +int main (void) +{ + struct objc_method_description *method; + const char *method_types; + unsigned qualifiers; + Protocol *protocol; + /* This no-op command is needed to keep the test compile on broken + gcc 3.x */ + MyObject *object = [MyObject bycopyMethod]; + + /* Get the protocol object */ + protocol = @protocol (MyProtocol); + + /* Ask to the protocol for the description of the method bycopyMethod */ + method = [protocol descriptionForClassMethod: @selector (bycopyMethod)]; + if (method == NULL) + { + printf ("Could not find method bycopyMethod in protocol!\n"); + exit (1); + } + + /* Get the method types for the method - which encode return type, + arguments etc. */ + method_types = method->types; + + /* Get the qualifiers for the return type */ + qualifiers = objc_get_type_qualifiers (method_types); + + /* If _F_BYCOPY is not there, the compiler is broken */ + if (! (qualifiers & _F_BYCOPY)) + { + printf ("Failed - selector does not contain _F_BYCOPY qualifier!\n"); + exit (1); + } + + /* Else, happy end */ + return 0; +} + +#ifdef __NEXT_RUNTIME__ +unsigned +objc_get_type_qualifiers (const char *type) +{ + unsigned res = 0; + BOOL flag = YES; + + while (flag) + switch (*type++) + { + case _C_CONST: res |= _F_CONST; break; + case _C_IN: res |= _F_IN; break; + case _C_INOUT: res |= _F_INOUT; break; + case _C_OUT: res |= _F_OUT; break; + case _C_BYCOPY: res |= _F_BYCOPY; break; + case _C_BYREF: res |= _F_BYREF; break; + case _C_ONEWAY: res |= _F_ONEWAY; break; + case _C_GCINVISIBLE: res |= _F_GCINVISIBLE; break; + default: flag = NO; + } + + return res; +} +#endif diff --git a/gcc/testsuite/objc/execute/cascading-1.m b/gcc/testsuite/objc/execute/cascading-1.m new file mode 100644 index 000000000..b823ea816 --- /dev/null +++ b/gcc/testsuite/objc/execute/cascading-1.m @@ -0,0 +1,34 @@ +#include <stdlib.h> +#import "../../objc-obj-c++-shared/Object1.h" + +@interface Foo : Object ++ foo; ++ bar; +@end + +int foocalled = 0; +int barcalled = 0; + + +@implementation Foo ++ foo +{ + if (foocalled) + abort (); + foocalled = 1; + return self; +} ++ bar +{ + if (barcalled) + abort (); + barcalled = 1; + return self; +} +@end + +int main(int argc,char **argv) +{ + [[Foo foo] bar]; + return 0; +} diff --git a/gcc/testsuite/objc/execute/class-1.m b/gcc/testsuite/objc/execute/class-1.m new file mode 100644 index 000000000..2ac2c0646 --- /dev/null +++ b/gcc/testsuite/objc/execute/class-1.m @@ -0,0 +1,25 @@ +/* Contributed by Nicola Pero - Tue Mar 6 23:05:53 CET 2001 */ + +#include "../../objc-obj-c++-shared/next-mapping.h" +#include <objc/objc.h> +#include <objc/objc-api.h> + +/* Tests creating a RootClass */ + +@interface RootClass +{ + Class isa; +} +@end + +@implementation RootClass +@end + +#include "class-tests-1.h" + +int main (void) +{ + test_class_with_superclass ("RootClass", ""); + + return 0; +} diff --git a/gcc/testsuite/objc/execute/class-10.m b/gcc/testsuite/objc/execute/class-10.m new file mode 100644 index 000000000..0908609f0 --- /dev/null +++ b/gcc/testsuite/objc/execute/class-10.m @@ -0,0 +1,82 @@ +/* Contributed by Nicola Pero - Tue Mar 6 23:05:53 CET 2001 */ + +#include "../../objc-obj-c++-shared/next-mapping.h" +#include <objc/objc.h> +#include <objc/objc-api.h> + +/* Tests creating a root class and a subclass with an ivar and + accessor methods and a subclass overriding the superclass' + implementation, and using self to call another method of itself */ + +@interface RootClass +{ + Class isa; +} +@end + +@implementation RootClass +#ifdef __NEXT_RUNTIME__ ++ initialize { return self; } +#endif +@end + +@interface SubClass : RootClass +{ + int state; +} +- (void) setState: (int)number; +- (int) state; +@end + +@implementation SubClass +- (void) setState: (int)number +{ + state = number; +} +- (int) state +{ + return state; +} +@end + +@interface SubSubClass : SubClass +- (int) shift; +@end + +@implementation SubSubClass +- (int) state +{ + return state + [self shift]; +} +- (int) shift +{ + return 1; +} +@end + +#include "class-tests-1.h" +#define TYPE_OF_OBJECT_WITH_ACCESSOR_METHOD SubClass * +#include "class-tests-2.h" + +int main (void) +{ + SubClass *object; + SubSubClass *sub_object; + + test_class_with_superclass ("SubClass", "RootClass"); + test_that_class_has_instance_method ("SubClass", @selector (setState:)); + test_that_class_has_instance_method ("SubClass", @selector (state)); + + test_class_with_superclass ("SubSubClass", "SubClass"); + test_that_class_has_instance_method ("SubSubClass", @selector (setState:)); + test_that_class_has_instance_method ("SubSubClass", @selector (state)); + test_that_class_has_instance_method ("SubSubClass", @selector (shift)); + + object = class_create_instance (objc_lookup_class ("SubClass")); + test_accessor_method (object, 0, -1, -1, 1, 1); + + sub_object = class_create_instance (objc_lookup_class ("SubSubClass")); + test_accessor_method (sub_object, 1, -1, 0, 1, 2); + + return 0; +} diff --git a/gcc/testsuite/objc/execute/class-11.m b/gcc/testsuite/objc/execute/class-11.m new file mode 100644 index 000000000..33cd0492d --- /dev/null +++ b/gcc/testsuite/objc/execute/class-11.m @@ -0,0 +1,86 @@ +/* Contributed by Nicola Pero - Tue Mar 6 23:05:53 CET 2001 */ + +#include "../../objc-obj-c++-shared/next-mapping.h" +#include <objc/objc.h> +#include <objc/objc-api.h> + +/* Tests creating a root class and a subclass with an ivar and + accessor methods and a subclass overriding the superclass' + implementation and using self to call another method of itself - in + a category */ + +@interface RootClass +{ + Class isa; +} +@end + +@implementation RootClass +#ifdef __NEXT_RUNTIME__ ++ initialize { return self; } +#endif +@end + +@interface SubClass : RootClass +{ + int state; +} +- (void) setState: (int)number; +- (int) state; +@end + +@implementation SubClass +- (void) setState: (int)number +{ + state = number; +} +- (int) state +{ + return state; +} +@end + +@interface SubSubClass : SubClass +- (int) shift; +@end + +@implementation SubSubClass +- (int) shift +{ + return 1; +} +@end + +@implementation SubSubClass (Additions) +- (int) state +{ + return state + [self shift]; +} +@end + +#include "class-tests-1.h" +#define TYPE_OF_OBJECT_WITH_ACCESSOR_METHOD SubClass * +#include "class-tests-2.h" + +int main (void) +{ + SubClass *object; + SubSubClass *sub_object; + + test_class_with_superclass ("SubClass", "RootClass"); + test_that_class_has_instance_method ("SubClass", @selector (setState:)); + test_that_class_has_instance_method ("SubClass", @selector (state)); + + test_class_with_superclass ("SubSubClass", "SubClass"); + test_that_class_has_instance_method ("SubSubClass", @selector (setState:)); + test_that_class_has_instance_method ("SubSubClass", @selector (state)); + test_that_class_has_instance_method ("SubSubClass", @selector (shift)); + + object = class_create_instance (objc_lookup_class ("SubClass")); + test_accessor_method (object, 0, -1, -1, 1, 1); + + sub_object = class_create_instance (objc_lookup_class ("SubSubClass")); + test_accessor_method (sub_object, 1, -1, 0, 1, 2); + + return 0; +} diff --git a/gcc/testsuite/objc/execute/class-12.m b/gcc/testsuite/objc/execute/class-12.m new file mode 100644 index 000000000..3f4c4fbd5 --- /dev/null +++ b/gcc/testsuite/objc/execute/class-12.m @@ -0,0 +1,55 @@ +/* Contributed by Nicola Pero - Tue Mar 6 23:05:53 CET 2001 */ + +#include "../../objc-obj-c++-shared/next-mapping.h" +#include <objc/objc.h> +#include <objc/objc-api.h> + +/* Tests creating a root class and a subclass with a class methods */ + +@interface RootClass +{ + Class isa; +} +@end + +@implementation RootClass +#ifdef __NEXT_RUNTIME__ ++ initialize { return self; } +#endif +@end + +static int class_variable = 0; + +@interface SubClass : RootClass ++ (void) setState: (int)number; ++ (int) state; +@end + +@implementation SubClass ++ (void) setState: (int)number +{ + class_variable = number; +} ++ (int) state +{ + return class_variable; +} +@end + +#include "class-tests-1.h" +#define TYPE_OF_OBJECT_WITH_ACCESSOR_METHOD Class +#include "class-tests-2.h" + +int main (void) +{ + Class class; + + test_class_with_superclass ("SubClass", "RootClass"); + test_that_class_has_class_method ("SubClass", @selector (setState:)); + test_that_class_has_class_method ("SubClass", @selector (state)); + + class = objc_lookup_class ("SubClass"); + test_accessor_method (class, 0, -1, -1, 1, 1); + + return 0; +} diff --git a/gcc/testsuite/objc/execute/class-13.m b/gcc/testsuite/objc/execute/class-13.m new file mode 100644 index 000000000..790654d10 --- /dev/null +++ b/gcc/testsuite/objc/execute/class-13.m @@ -0,0 +1,76 @@ +/* Contributed by Nicola Pero - Tue Mar 6 23:05:53 CET 2001 */ + +#include "../../objc-obj-c++-shared/next-mapping.h" +#include <objc/objc.h> +#include <objc/objc-api.h> + +/* Tests creating a root class and a subclass with a class accessor + methods and a subclass overriding the superclass' implementation + but reusing it with super */ + +@interface RootClass +{ + Class isa; +} +@end + +@implementation RootClass +#ifdef __NEXT_RUNTIME__ ++ initialize { return self; } +#endif +@end + +static int class_variable = 0; + +@interface SubClass : RootClass ++ (void) setState: (int)number; ++ (int) state; +@end + +@implementation SubClass ++ (void) setState: (int)number +{ + class_variable = number; +} ++ (int) state +{ + return class_variable; +} +@end + +@interface SubSubClass : SubClass +@end + +@implementation SubSubClass ++ (int) state +{ + return [super state] + 1; +} +@end + +#include "class-tests-1.h" +#define TYPE_OF_OBJECT_WITH_ACCESSOR_METHOD Class +#include "class-tests-2.h" + +int main (void) +{ + Class class; + Class sub_class; + + test_class_with_superclass ("SubClass", "RootClass"); + test_that_class_has_class_method ("SubClass", @selector (setState:)); + test_that_class_has_class_method ("SubClass", @selector (state)); + + test_class_with_superclass ("SubSubClass", "SubClass"); + test_that_class_has_class_method ("SubSubClass", @selector (setState:)); + test_that_class_has_class_method ("SubSubClass", @selector (state)); + + class = objc_lookup_class ("SubClass"); + test_accessor_method (class, 0, -1, -1, 1, 1); + + sub_class = objc_lookup_class ("SubSubClass"); + class_variable = 0; + test_accessor_method (sub_class, 1, -1, 0, 1, 2); + + return 0; +} diff --git a/gcc/testsuite/objc/execute/class-14.m b/gcc/testsuite/objc/execute/class-14.m new file mode 100644 index 000000000..e04452e52 --- /dev/null +++ b/gcc/testsuite/objc/execute/class-14.m @@ -0,0 +1,81 @@ +/* Contributed by Nicola Pero - Tue Mar 6 23:05:53 CET 2001 */ + +#include "../../objc-obj-c++-shared/next-mapping.h" +#include <objc/objc.h> +#include <objc/objc-api.h> + +/* Tests creating a root class and a subclass with a class accessor + methods and a subclass overriding the superclass' implementation, + and using self to call another method of itself */ + +@interface RootClass +{ + Class isa; +} +@end + +@implementation RootClass +#ifdef __NEXT_RUNTIME__ ++ initialize { return self; } +#endif +@end + +static int class_variable = 0; + +@interface SubClass : RootClass ++ (void) setState: (int)number; ++ (int) state; +@end + +@implementation SubClass ++ (void) setState: (int)number +{ + class_variable = number; +} ++ (int) state +{ + return class_variable; +} +@end + +@interface SubSubClass : SubClass ++ (int) shift; +@end + +@implementation SubSubClass ++ (int) state +{ + return class_variable + [self shift]; +} ++ (int) shift +{ + return 1; +} +@end + +#include "class-tests-1.h" +#define TYPE_OF_OBJECT_WITH_ACCESSOR_METHOD Class +#include "class-tests-2.h" + +int main (void) +{ + Class class, sub_class; + + test_class_with_superclass ("SubClass", "RootClass"); + test_that_class_has_class_method ("SubClass", @selector (setState:)); + test_that_class_has_class_method ("SubClass", @selector (state)); + + test_class_with_superclass ("SubSubClass", "SubClass"); + test_that_class_has_class_method ("SubSubClass", @selector (setState:)); + test_that_class_has_class_method ("SubSubClass", @selector (state)); + test_that_class_has_class_method ("SubSubClass", @selector (shift)); + + class = objc_lookup_class ("SubClass"); + test_accessor_method (class, 0, -1, -1, 1, 1); + + sub_class = objc_lookup_class ("SubSubClass"); + class_variable = 0; + test_accessor_method (sub_class, 1, -1, 0, 1, 2); + + return 0; +} diff --git a/gcc/testsuite/objc/execute/class-2.m b/gcc/testsuite/objc/execute/class-2.m new file mode 100644 index 000000000..c20f95fd6 --- /dev/null +++ b/gcc/testsuite/objc/execute/class-2.m @@ -0,0 +1,31 @@ +/* Contributed by Nicola Pero - Tue Mar 6 23:05:53 CET 2001 */ + +#include "../../objc-obj-c++-shared/next-mapping.h" +#include <objc/objc.h> +#include <objc/objc-api.h> + +/* Tests creating a root class and a subclass */ + +@interface RootClass +{ + Class isa; +} +@end + +@implementation RootClass +@end + +@interface SubClass : RootClass +@end + +@implementation SubClass +@end + +#include "class-tests-1.h" + +int main (void) +{ + test_class_with_superclass ("SubClass", "RootClass"); + + return 0; +} diff --git a/gcc/testsuite/objc/execute/class-3.m b/gcc/testsuite/objc/execute/class-3.m new file mode 100644 index 000000000..dbdc0b9f2 --- /dev/null +++ b/gcc/testsuite/objc/execute/class-3.m @@ -0,0 +1,45 @@ +/* Contributed by Nicola Pero - Tue Mar 6 23:05:53 CET 2001 */ + +#include "../../objc-obj-c++-shared/next-mapping.h" +#include <objc/objc.h> +#include <objc/objc-api.h> + +/* Tests creating a root class and a minimal subclass tree */ + +@interface RootClass +{ + Class isa; +} +@end + +@implementation RootClass +@end + +@interface SubClassA : RootClass +@end + +@implementation SubClassA +@end + +@interface SubClassB : RootClass +@end + +@implementation SubClassB +@end + +@interface SubSubClass : SubClassA +@end + +@implementation SubSubClass +@end + +#include "class-tests-1.h" + +int main (void) +{ + test_class_with_superclass ("SubClassA", "RootClass"); + test_class_with_superclass ("SubClassB", "RootClass"); + test_class_with_superclass ("SubSubClass", "SubClassA"); + + return 0; +} diff --git a/gcc/testsuite/objc/execute/class-4.m b/gcc/testsuite/objc/execute/class-4.m new file mode 100644 index 000000000..61ce30a6a --- /dev/null +++ b/gcc/testsuite/objc/execute/class-4.m @@ -0,0 +1,57 @@ +/* Contributed by Nicola Pero - Tue Mar 6 23:05:53 CET 2001 */ + +#include "../../objc-obj-c++-shared/next-mapping.h" +#include <objc/objc.h> +#include <objc/objc-api.h> + +/* Tests creating a root class and a subclass with an ivar and + accessor methods */ + +@interface RootClass +{ + Class isa; +} +@end + +@implementation RootClass +#ifdef __NEXT_RUNTIME__ ++ initialize { return self; } +#endif +@end + +@interface SubClass : RootClass +{ + int state; +} +- (void) setState: (int)number; +- (int) state; +@end + +@implementation SubClass +- (void) setState: (int)number +{ + state = number; +} +- (int) state +{ + return state; +} +@end + +#include "class-tests-1.h" +#define TYPE_OF_OBJECT_WITH_ACCESSOR_METHOD SubClass * +#include "class-tests-2.h" + +int main (void) +{ + SubClass *object; + + test_class_with_superclass ("SubClass", "RootClass"); + test_that_class_has_instance_method ("SubClass", @selector (setState:)); + test_that_class_has_instance_method ("SubClass", @selector (state)); + + object = class_create_instance (objc_lookup_class ("SubClass")); + test_accessor_method (object, 0, 1, 1, -3, -3); + + return 0; +} diff --git a/gcc/testsuite/objc/execute/class-5.m b/gcc/testsuite/objc/execute/class-5.m new file mode 100644 index 000000000..c10df1be0 --- /dev/null +++ b/gcc/testsuite/objc/execute/class-5.m @@ -0,0 +1,76 @@ +/* Contributed by Nicola Pero - Tue Mar 6 23:05:53 CET 2001 */ + +#include "../../objc-obj-c++-shared/next-mapping.h" +#include <objc/objc.h> +#include <objc/objc-api.h> + +/* Tests creating a root class and a subclass with an ivar and + accessor methods and a subclass overriding the superclass' + implementation */ + +@interface RootClass +{ + Class isa; +} +@end + +@implementation RootClass +#ifdef __NEXT_RUNTIME__ ++ initialize { return self; } +#endif +@end + +@interface SubClass : RootClass +{ + int state; +} +- (void) setState: (int)number; +- (int) state; +@end + +@implementation SubClass +- (void) setState: (int)number +{ + state = number; +} +- (int) state +{ + return state; +} +@end + +@interface SubSubClass : SubClass +@end + +@implementation SubSubClass +- (int) state +{ + return state + 1; +} +@end + +#include "class-tests-1.h" +#define TYPE_OF_OBJECT_WITH_ACCESSOR_METHOD SubClass * +#include "class-tests-2.h" + +int main (void) +{ + SubClass *object; + SubSubClass *sub_object; + + test_class_with_superclass ("SubClass", "RootClass"); + test_that_class_has_instance_method ("SubClass", @selector (setState:)); + test_that_class_has_instance_method ("SubClass", @selector (state)); + + test_class_with_superclass ("SubSubClass", "SubClass"); + test_that_class_has_instance_method ("SubSubClass", @selector (setState:)); + test_that_class_has_instance_method ("SubSubClass", @selector (state)); + + object = class_create_instance (objc_lookup_class ("SubClass")); + test_accessor_method (object, 0, -1, -1, 1, 1); + + sub_object = class_create_instance (objc_lookup_class ("SubSubClass")); + test_accessor_method (sub_object, 1, -1, 0, 1, 2); + + return 0; +} diff --git a/gcc/testsuite/objc/execute/class-6.m b/gcc/testsuite/objc/execute/class-6.m new file mode 100644 index 000000000..064462280 --- /dev/null +++ b/gcc/testsuite/objc/execute/class-6.m @@ -0,0 +1,76 @@ +/* Contributed by Nicola Pero - Tue Mar 6 23:05:53 CET 2001 */ + +#include "../../objc-obj-c++-shared/next-mapping.h" +#include <objc/objc.h> +#include <objc/objc-api.h> + +/* Tests creating a root class and a subclass with an ivar and + accessor methods and a subclass overriding the superclass' + implementation but reusing it with super */ + +@interface RootClass +{ + Class isa; +} +@end + +@implementation RootClass +#ifdef __NEXT_RUNTIME__ ++ initialize { return self; } +#endif +@end + +@interface SubClass : RootClass +{ + int state; +} +- (void) setState: (int)number; +- (int) state; +@end + +@implementation SubClass +- (void) setState: (int)number +{ + state = number; +} +- (int) state +{ + return state; +} +@end + +@interface SubSubClass : SubClass +@end + +@implementation SubSubClass +- (int) state +{ + return [super state] + 1; +} +@end + +#include "class-tests-1.h" +#define TYPE_OF_OBJECT_WITH_ACCESSOR_METHOD SubClass * +#include "class-tests-2.h" + +int main (void) +{ + SubClass *object; + SubSubClass *sub_object; + + test_class_with_superclass ("SubClass", "RootClass"); + test_that_class_has_instance_method ("SubClass", @selector (setState:)); + test_that_class_has_instance_method ("SubClass", @selector (state)); + + test_class_with_superclass ("SubSubClass", "SubClass"); + test_that_class_has_instance_method ("SubSubClass", @selector (setState:)); + test_that_class_has_instance_method ("SubSubClass", @selector (state)); + + object = class_create_instance (objc_lookup_class ("SubClass")); + test_accessor_method (object, 0, -1, -1, 1, 1); + + sub_object = class_create_instance (objc_lookup_class ("SubSubClass")); + test_accessor_method (sub_object, 1, -1, 0, 1, 2); + + return 0; +} diff --git a/gcc/testsuite/objc/execute/class-7.m b/gcc/testsuite/objc/execute/class-7.m new file mode 100644 index 000000000..06de61fef --- /dev/null +++ b/gcc/testsuite/objc/execute/class-7.m @@ -0,0 +1,71 @@ +/* Contributed by Nicola Pero - Tue Mar 6 23:05:53 CET 2001 */ + +#include "../../objc-obj-c++-shared/next-mapping.h" +#include <objc/objc.h> +#include <objc/objc-api.h> + +/* Tests creating a root class and a subclass with an ivar and + accessor methods; accessor methods implemented in a separate + category */ + +@interface RootClass +{ + Class isa; +} +@end + +@implementation RootClass +#ifdef __NEXT_RUNTIME__ ++ initialize { return self; } +#endif +@end + +@interface SubClass : RootClass +{ + int state; +} +@end + +@implementation SubClass +@end + +@interface SubClass (Additions) +- (void) setState: (int)number; +- (int) state; +@end + +@implementation SubClass (Additions) +- (void) setState: (int)number +{ + state = number; +} +- (int) state +{ + return state; +} +@end + +#include "class-tests-1.h" +#define TYPE_OF_OBJECT_WITH_ACCESSOR_METHOD SubClass * +#include "class-tests-2.h" + +int main (void) +{ + SubClass *object; + + test_class_with_superclass ("SubClass", "RootClass"); + + /* The NeXT runtime's category implementation is lazy: categories are not attached + to classes until the class is initialized (at +initialize time). */ +#ifdef __NEXT_RUNTIME__ + [SubClass initialize]; +#endif + + test_that_class_has_instance_method ("SubClass", @selector (setState:)); + test_that_class_has_instance_method ("SubClass", @selector (state)); + + object = class_create_instance (objc_lookup_class ("SubClass")); + test_accessor_method (object, 0, 1, 1, -3, -3); + + return 0; +} diff --git a/gcc/testsuite/objc/execute/class-8.m b/gcc/testsuite/objc/execute/class-8.m new file mode 100644 index 000000000..0471994d3 --- /dev/null +++ b/gcc/testsuite/objc/execute/class-8.m @@ -0,0 +1,79 @@ +/* Contributed by Nicola Pero - Tue Mar 6 23:05:53 CET 2001 */ + +#include "../../objc-obj-c++-shared/next-mapping.h" +#include <objc/objc.h> +#include <objc/objc-api.h> + +/* Tests creating a root class and a subclass with an ivar and + accessor methods and a subclass overriding the superclass' + implementation - in a category */ + +@interface RootClass +{ + Class isa; +} +@end + +@implementation RootClass +#ifdef __NEXT_RUNTIME__ ++ initialize { return self; } +#endif +@end + +@interface SubClass : RootClass +{ + int state; +} +- (void) setState: (int)number; +- (int) state; +@end + +@implementation SubClass +- (void) setState: (int)number +{ + state = number; +} +- (int) state +{ + return state; +} +@end + +@interface SubSubClass : SubClass +@end + +@implementation SubSubClass +@end + +@implementation SubSubClass (Additions) +- (int) state +{ + return state + 1; +} +@end + +#include "class-tests-1.h" +#define TYPE_OF_OBJECT_WITH_ACCESSOR_METHOD SubClass * +#include "class-tests-2.h" + +int main (void) +{ + SubClass *object; + SubSubClass *sub_object; + + test_class_with_superclass ("SubClass", "RootClass"); + test_that_class_has_instance_method ("SubClass", @selector (setState:)); + test_that_class_has_instance_method ("SubClass", @selector (state)); + + test_class_with_superclass ("SubSubClass", "SubClass"); + test_that_class_has_instance_method ("SubSubClass", @selector (setState:)); + test_that_class_has_instance_method ("SubSubClass", @selector (state)); + + object = class_create_instance (objc_lookup_class ("SubClass")); + test_accessor_method (object, 0, -1, -1, 1, 1); + + sub_object = class_create_instance (objc_lookup_class ("SubSubClass")); + test_accessor_method (sub_object, 1, -1, 0, 1, 2); + + return 0; +} diff --git a/gcc/testsuite/objc/execute/class-9.m b/gcc/testsuite/objc/execute/class-9.m new file mode 100644 index 000000000..367a4c912 --- /dev/null +++ b/gcc/testsuite/objc/execute/class-9.m @@ -0,0 +1,79 @@ +/* Contributed by Nicola Pero - Tue Mar 6 23:05:53 CET 2001 */ + +#include "../../objc-obj-c++-shared/next-mapping.h" +#include <objc/objc.h> +#include <objc/objc-api.h> + +/* Tests creating a root class and a subclass with an ivar and + accessor methods and a subclass overriding the superclass' + implementation but reusing it with super - in a category */ + +@interface RootClass +{ + Class isa; +} +@end + +@implementation RootClass +#ifdef __NEXT_RUNTIME__ ++ initialize { return self; } +#endif +@end + +@interface SubClass : RootClass +{ + int state; +} +- (void) setState: (int)number; +- (int) state; +@end + +@implementation SubClass +- (void) setState: (int)number +{ + state = number; +} +- (int) state +{ + return state; +} +@end + +@interface SubSubClass : SubClass +@end + +@implementation SubSubClass +@end + +@implementation SubSubClass (Additions) +- (int) state +{ + return [super state] + 1; +} +@end + +#include "class-tests-1.h" +#define TYPE_OF_OBJECT_WITH_ACCESSOR_METHOD SubClass * +#include "class-tests-2.h" + +int main (void) +{ + SubClass *object; + SubSubClass *sub_object; + + test_class_with_superclass ("SubClass", "RootClass"); + test_that_class_has_instance_method ("SubClass", @selector (setState:)); + test_that_class_has_instance_method ("SubClass", @selector (state)); + + test_class_with_superclass ("SubSubClass", "SubClass"); + test_that_class_has_instance_method ("SubSubClass", @selector (setState:)); + test_that_class_has_instance_method ("SubSubClass", @selector (state)); + + object = class_create_instance (objc_lookup_class ("SubClass")); + test_accessor_method (object, 0, -1, -1, 1, 1); + + sub_object = class_create_instance (objc_lookup_class ("SubSubClass")); + test_accessor_method (sub_object, 1, -1, 0, 1, 2); + + return 0; +} diff --git a/gcc/testsuite/objc/execute/class-tests-1.h b/gcc/testsuite/objc/execute/class-tests-1.h new file mode 100644 index 000000000..54a77d247 --- /dev/null +++ b/gcc/testsuite/objc/execute/class-tests-1.h @@ -0,0 +1,139 @@ +/* Contributed by Nicola Pero on Tue Mar 6 23:05:53 CET 2001 */ + +#include <stdio.h> +#include <stdlib.h> +#include "../../objc-obj-c++-shared/Object1.h" +#include <objc/objc.h> +#include <objc/objc-api.h> + +/* + * Standard Tests For Classes and Objects - abort upon failing; return + * normally if all is well. + */ + +/* Test that `class' is a Class */ +static void test_is_class (Class class) +{ + if (object_is_class (class) == NO) + { + printf ("test_is_class failed\n"); + abort (); + } + + if (class_is_class (class) == NO) + { + printf ("test_is_class failed\n"); + abort (); + } +} + +/* Test that the superclass of `class' is `superclass' */ +static void test_superclass (Class class, Class superclass) +{ + if (class_get_super_class (class) != superclass) + { + printf ("test_superclass failed\n"); + abort (); + } +} + +/* Test that the classname of `class' is `classname' */ +static void test_class_name (Class class, const char *classname) +{ + if (strcmp (class_get_class_name (class), classname)) + { + printf ("test_class_name failed\n"); + abort (); + } +} + +/* Test that we can allocate instances of `class' */ +static void test_allocate (Class class) +{ + /* The object we create is leaked but who cares, this is only a test */ + id object = class_create_instance (class); + + if (object == nil) + { + printf ("test_allocate failed\n"); + abort (); + } +} + +/* Test that instances of `class' are instances and not classes */ +static void test_instances (Class class) +{ + id object = class_create_instance (class); + + if (object_is_class (object) == YES) + { + printf ("test_instances failed\n"); + abort (); + } +} + +/* Test that we can deallocate instances of `class' */ +static void test_deallocate (Class class) +{ + id object = class_create_instance (class); + + object_dispose (object); +} + +/* Test that the object and the class agree on what the class is */ +static void test_object_class (Class class) +{ + id object = class_create_instance (class); + + if (object_get_class (object) != class) + { + printf ("test_object_class failed\n"); + abort (); + } +} + +/* Test that the object and the class agree on what the superclass is */ +static void test_object_super_class (Class class) +{ + id object = class_create_instance (class); + + if (object_get_super_class (object) != class_get_super_class (class)) + { + printf ("test_object_super_class failed\n"); + abort (); + } +} + +/* + * Runs all the tests in this file for the specified class + */ +void test_class_with_superclass (const char *class_name, + const char *superclass_name) +{ + Class class; + Class superclass; + + /* We need at least a method call before playing with the internals, + so that the runtime will call __objc_resolve_class_links () */ + [Object class]; + + /* class_name must be an existing class */ + class = objc_lookup_class (class_name); + test_is_class (class); + + /* But superclass_name can be "", which means `Nil' */ + superclass = objc_lookup_class (superclass_name); + if (superclass != Nil) + { + test_is_class (superclass); + } + + /* Now the tests */ + test_superclass (class, superclass); + test_class_name (class, class_name); + test_allocate (class); + test_instances (class); + test_deallocate (class); + test_object_class (class); + test_object_super_class (class); +} diff --git a/gcc/testsuite/objc/execute/class-tests-2.h b/gcc/testsuite/objc/execute/class-tests-2.h new file mode 100644 index 000000000..1aa73947d --- /dev/null +++ b/gcc/testsuite/objc/execute/class-tests-2.h @@ -0,0 +1,68 @@ +/* Contributed by Nicola Pero on Tue Mar 6 23:05:53 CET 2001 */ +#include <objc/objc.h> +#include <objc/objc-api.h> +#include <stdio.h> +#include <stdlib.h> + +/* + * Standard Tests For Methods of Classes and Objects - abort upon + * failing; return normally if all is well. + */ + +/* Test that `class' has an instance method for the selector `selector' */ +void test_that_class_has_instance_method (const char *class_name, + SEL selector) +{ + Class class = objc_lookup_class (class_name); + + if (class_get_instance_method (class, selector) == NULL) + { + printf ("test_class_has_instance_method failed\n"); + abort (); + } +} + +/* Test that `class' has a class method for the selector `selector' */ +void test_that_class_has_class_method (const char *class_name, + SEL selector) +{ + Class meta_class = objc_get_meta_class (class_name); + + if (class_get_class_method (meta_class, selector) == NULL) + { + printf ("test_class_has_class_method failed\n"); + abort (); + } +} + +/* Test the accessor methods (called -state and -setState:) on the + object `object'. */ +#ifdef TYPE_OF_OBJECT_WITH_ACCESSOR_METHOD +void test_accessor_method (TYPE_OF_OBJECT_WITH_ACCESSOR_METHOD object, + int initial_state, + int new_state_0, int expected_result_0, + int new_state_1, int expected_result_1) +{ + if ([object state] != initial_state) + { + printf ("test_accessor_method (initial state) failed\n"); + abort (); + } + + [object setState: new_state_0]; + if ([object state] != expected_result_0) + { + printf ("test_accessor_method (new_state_0) failed\n"); + abort (); + } + + [object setState: new_state_1]; + if ([object state] != expected_result_1) + { + printf ("test_accessor_method (new_state_1) failed\n"); + abort (); + } +} +#endif /* CLASS_WITH_ACCESSOR_METHOD */ + + diff --git a/gcc/testsuite/objc/execute/class_self-1.m b/gcc/testsuite/objc/execute/class_self-1.m new file mode 100644 index 000000000..1690f8f6b --- /dev/null +++ b/gcc/testsuite/objc/execute/class_self-1.m @@ -0,0 +1,65 @@ +/* Contributed by Nicola Pero - Fri Oct 26 22:39:32 BST 2001 */ +#include <objc/objc.h> + +/* Test calling a class method when there is an instance method + with conflicting types */ + +/* This class should be unused but on broken compilers its instance + method might get picked up and used instead of the class method of + another class ! */ +struct d +{ + int a; +}; + +@interface UnusedClass +{ + Class isa; +} +- (struct d) method; +@end + +@implementation UnusedClass +- (struct d) method +{ + struct d u; + u.a = 0; + + return u; +} +@end + +/* The real class */ +@interface TestClass +{ + Class isa; +} ++ (void) test; ++ (int) method; +@end + +@implementation TestClass ++ (void) test +{ + if ([self method] != 4) + { + abort (); + } +} + ++ (int) method +{ + return 4; +} +#ifdef __NEXT_RUNTIME__ ++ initialize { return self; } +#endif +@end + + +int main (void) +{ + [TestClass test]; + + return 0; +} diff --git a/gcc/testsuite/objc/execute/class_self-2.m b/gcc/testsuite/objc/execute/class_self-2.m new file mode 100644 index 000000000..ad2b76b50 --- /dev/null +++ b/gcc/testsuite/objc/execute/class_self-2.m @@ -0,0 +1,72 @@ +/* Contributed by Nicola Pero - Fri Oct 26 22:39:32 BST 2001 */ +#include <stdlib.h> +#include <objc/objc.h> + +/* Test calling a class method on self where self has been redefined + to be another class - the call requires a cast */ + + +/* The first class */ +struct d +{ + int a; +}; + +@interface ClassA +{ + Class isa; +} ++ (Class) class; ++ (struct d) method; +@end + +@implementation ClassA ++ (Class) class +{ + return self; +} + ++ (struct d) method +{ + struct d u; + u.a = 5; + + return u; +} +#ifdef __NEXT_RUNTIME__ ++ initialize { return self; } +#endif +@end + +/* The second class */ +@interface TestClass +{ + Class isa; +} ++ (void) test; +@end + +@implementation TestClass ++ (void) test +{ + self = [ClassA class]; + + + if ([(Class)self method].a != 5) + { + abort (); + } +} + +#ifdef __NEXT_RUNTIME__ ++ initialize { return self; } +#endif +@end + + +int main (void) +{ + [TestClass test]; + + return 0; +} diff --git a/gcc/testsuite/objc/execute/compatibility_alias.m b/gcc/testsuite/objc/execute/compatibility_alias.m new file mode 100644 index 000000000..61d762512 --- /dev/null +++ b/gcc/testsuite/objc/execute/compatibility_alias.m @@ -0,0 +1,13 @@ +/* Contributed by Nicola Pero - Thu Mar 8 17:23:59 CET 2001 */ +#import "../../objc-obj-c++-shared/Object1.h" +#include <objc/objc.h> + +@compatibility_alias MyObject Object; + +int main (void) +{ + MyObject *object = [MyObject alloc]; + + return 0; +} +#include "../../objc-obj-c++-shared/Object1-implementation.h" diff --git a/gcc/testsuite/objc/execute/encode-1.m b/gcc/testsuite/objc/execute/encode-1.m new file mode 100644 index 000000000..3e2412e46 --- /dev/null +++ b/gcc/testsuite/objc/execute/encode-1.m @@ -0,0 +1,32 @@ +/* Contributed by Nicola Pero - Thu Mar 8 16:27:46 CET 2001 */ +#include <stdlib.h> +#import "../../objc-obj-c++-shared/Object1.h" +#include <objc/objc.h> +#include <objc/objc-api.h> + +/* Test very simple @encode */ + +int main (void) +{ + if (strcmp ("i", @encode (int))) + { + abort (); + } + + if (strcmp ("@", @encode (id))) + { + abort (); + } + + if (strcmp ("@", @encode (Object *))) + { + abort (); + } + + if (strcmp (":", @encode (SEL))) + { + abort (); + } + + return 0; +} diff --git a/gcc/testsuite/objc/execute/enumeration-1.m b/gcc/testsuite/objc/execute/enumeration-1.m new file mode 100644 index 000000000..57d1a4bf6 --- /dev/null +++ b/gcc/testsuite/objc/execute/enumeration-1.m @@ -0,0 +1,51 @@ +/* Contributed by Nicola Pero - Wed Dec 5 17:12:40 GMT 2001 */ +#include <stdlib.h> +#import "../../objc-obj-c++-shared/Object1.h" +#include <objc/objc.h> + +/* Test using a bitfield enumeration ivar. */ + +typedef enum +{ + black, + white +} color; + +@interface TestClass: Object +{ + color c:2; +} +- (color)color; +- (void)setColor: (color)a; +@end + +@implementation TestClass +- (color)color +{ + return c; +} +- (void)setColor: (color)a +{ + c = a; +} +@end + + +int main (void) +{ + TestClass *c; + + c = [TestClass new]; + + [c setColor: black]; + [c setColor: white]; + [c setColor: black]; + if ([c color] != black) + { + abort (); + } + + + return 0; +} +#include "../../objc-obj-c++-shared/Object1-implementation.h" diff --git a/gcc/testsuite/objc/execute/enumeration-2.m b/gcc/testsuite/objc/execute/enumeration-2.m new file mode 100644 index 000000000..3094963c6 --- /dev/null +++ b/gcc/testsuite/objc/execute/enumeration-2.m @@ -0,0 +1,53 @@ +/* Contributed by Nicola Pero - Wed Dec 5 17:12:40 GMT 2001 */ +#include <stdlib.h> +#import "../../objc-obj-c++-shared/Object1.h" +#include <objc/objc.h> + +typedef enum { black, white } color; + +typedef struct +{ + color a:2; + color b:2; +} color_couple; + +@interface TestClass: Object +{ + color_couple *c; +} +- (color_couple *)colorCouple; +- (void)setColorCouple: (color_couple *)a; +@end + +@implementation TestClass +- (color_couple *)colorCouple +{ + return c; +} +- (void)setColorCouple: (color_couple *)a +{ + c = a; +} +@end + + +int main (void) +{ + color_couple cc; + TestClass *c; + + c = [TestClass new]; + + cc.a = black; + cc.b = white; + + [c setColorCouple: &cc]; + if ([c colorCouple] != &cc) + { + abort (); + } + + + return 0; +} +#include "../../objc-obj-c++-shared/Object1-implementation.h" diff --git a/gcc/testsuite/objc/execute/exceptions/catchall-1.m b/gcc/testsuite/objc/execute/exceptions/catchall-1.m new file mode 100644 index 000000000..2db40a854 --- /dev/null +++ b/gcc/testsuite/objc/execute/exceptions/catchall-1.m @@ -0,0 +1,77 @@ +/* Test out '@catch(id foo) {...}', which should catch all uncaught + exceptions. */ +/* Developed by Ziemowit Laski <zlaski@apple.com>. */ + +#include <stdio.h> +#include <stdlib.h> +#import "../../../objc-obj-c++-shared/Object1.h" + +/* The following is not required in actual user code; we include it + here to check that the compiler generates an internal definition of + _setjmp that is consistent with what <setjmp.h> provides. */ +#include <setjmp.h> + +#define CHECK_IF(expr) if(!(expr)) abort() + +@interface Frob: Object +@end + +@implementation Frob: Object +@end + +static Frob* _connection = nil; + +//-------------------------------------------------------------------- + + +void test (Object* sendPort) +{ + int cleanupPorts = 1; + Frob* receivePort = nil; + + @try { + printf ("receivePort = %p\n", receivePort); + printf ("sendPort = %p\n", sendPort); + printf ("cleanupPorts = %d\n", cleanupPorts); + printf ("---\n"); + + receivePort = (Frob *) -1; + _connection = (Frob *) -1; + printf ("receivePort = %p\n", receivePort); + printf ("sendPort = %p\n", sendPort); + printf ("cleanupPorts = %d\n", cleanupPorts); + printf ("---\n"); + + receivePort = nil; + sendPort = nil; + cleanupPorts = 0; + + printf ("receivePort = %p\n", receivePort); + printf ("sendPort = %p\n", sendPort); + printf ("cleanupPorts = %d\n", cleanupPorts); + printf ("---\n"); + + @throw [Object new]; + } + @catch(Frob *obj) { + printf ("Exception caught by incorrect handler!\n"); + CHECK_IF(0); + } + @catch(id exc) { + printf ("Exception caught by correct handler.\n"); + printf ("receivePort = %p (expected 0x0)\n", receivePort); + printf ("sendPort = %p (expected 0x0)\n", sendPort); + printf ("cleanupPorts = %d (expected 0)\n", cleanupPorts); + printf ("---"); + CHECK_IF(!receivePort); + CHECK_IF(!sendPort); + CHECK_IF(!cleanupPorts); + } +} + +int main (void) { + + test((Object *)-1); + return 0; +} +#import "../../../objc-obj-c++-shared/Object1-implementation.h" diff --git a/gcc/testsuite/objc/execute/exceptions/exceptions.exp b/gcc/testsuite/objc/execute/exceptions/exceptions.exp new file mode 100644 index 000000000..0443ca130 --- /dev/null +++ b/gcc/testsuite/objc/execute/exceptions/exceptions.exp @@ -0,0 +1,50 @@ +# Copyright (C) 1991, 1992, 1993, 1995, 1997, 2007, 2008, 2010 +# Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# This file was written by Rob Savoye. (rob@cygnus.com) +# Modified by Ovidiu Predescu (ovidiu@aracnet.com) + + +if $tracelevel then { + strace $tracelevel +} + +set additional_flags "" +lappend additional_flags "-fobjc-exceptions" +# load support procs +load_lib objc-torture.exp +load_lib torture-options.exp +load_lib target-supports.exp + +torture-init +objc-set-runtime-options "execute" "additional_flags=-fobjc-exceptions" +set-torture-options $OBJC_TORTURE_OPTIONS $OBJC_RUNTIME_OPTIONS + +# +# main test loop +# + +foreach src [lsort [glob -nocomplain $srcdir/$subdir/*.m]] { + # If we're only testing specific files and this isn't one of them, skip it. + if ![runtest_file_p $runtests $src] then { + continue + } + + objc-torture-execute $src $additional_flags +} + +torture-finish diff --git a/gcc/testsuite/objc/execute/exceptions/finally-1.m b/gcc/testsuite/objc/execute/exceptions/finally-1.m new file mode 100644 index 000000000..370b19bb5 --- /dev/null +++ b/gcc/testsuite/objc/execute/exceptions/finally-1.m @@ -0,0 +1,76 @@ +#include <stdio.h> +#include <stdlib.h> +//#import "../../../objc-obj-c++-shared/Object1.h" +#ifdef __OBJC2__ +#include <objc/runtime.h> +@interface Object ++ initialize; ++ new; +- free; +@end +@implementation Object ++ initialize { return self; } ++ new { return class_createInstance (self, 0); } +- free { return object_dispose(self);} +@end + +#else +#import "../../../objc-obj-c++-shared/Object1.h" +#endif + +static int made_try = 0; + +int +thrower_try_body() +{ + made_try++; + return (0); +} + +static int made_finally = 0; + +int +finally_body() +{ + made_finally++; + return (0); +} + +int +thrower() +{ + @try + { + thrower_try_body(); + @throw [Object new]; + } + @finally + { + finally_body(); + } + return 0; +} + +static int made_catch = 0; + +int +main(int ac, char *av[]) +{ + @try + { + thrower(); + } + @catch (id exc) + { + made_catch++; + [exc free]; + } + if (made_try != 1) + abort (); + if (made_finally != 1) + abort (); + if (made_catch != 1) + abort (); + return 0; +} +//#import "../../../objc-obj-c++-shared/Object1-implementation.h" diff --git a/gcc/testsuite/objc/execute/exceptions/foward-1.m b/gcc/testsuite/objc/execute/exceptions/foward-1.m new file mode 100644 index 000000000..6b31d7cc8 --- /dev/null +++ b/gcc/testsuite/objc/execute/exceptions/foward-1.m @@ -0,0 +1,62 @@ +/* Check that throwing an exception from a -forward:: works. */ +/* Developed by Marcin Koziej <creep@desk.pl>. */ + +#include <stdlib.h> +#include <objc/Object.h> +#ifndef __NEXT_RUNTIME__ +#import <objc/objc-api.h> +#endif + +#ifdef __OBJC2__ +@interface Object (TEST_SUITE_ADDITIONS) ++ initialize; ++ alloc; ++ new; +- init; +- free; +@end + +@implementation Object (TEST_SUITE_ADDITIONS) ++ initialize { return self; } ++ alloc { return class_createInstance (self, 0); } ++ new { return [[self alloc] init]; } +- init { return self; } +- free { return object_dispose(self); } +@end +#endif + +static int i; + +__attribute__((objc_exception)) +@interface Thrower : Object +- forward: (SEL) s : (void*) a; +@end + +@implementation Thrower +- forward: (SEL) s : (void*) a +{ + i++; + @throw [Object new]; + return nil; +} +@end + +int +main() +{ + id t = [Thrower new]; + @try + { + [t doesnotexist]; + } + @catch (id error) + { + i++; + [error free]; + } + + if (i != 2) + abort (); + + return 0; +} diff --git a/gcc/testsuite/objc/execute/exceptions/foward-1.x b/gcc/testsuite/objc/execute/exceptions/foward-1.x new file mode 100644 index 000000000..9acd2737a --- /dev/null +++ b/gcc/testsuite/objc/execute/exceptions/foward-1.x @@ -0,0 +1,11 @@ +# XFAIL the run for m64 Darwin NeXT (seems to be a system runtime lib problem). +if { [istarget *-*-darwin*] && [check_effective_target_lp64] } { + set torture_eval_before_execute { + global compiler_conditional_xfail_data + set compiler_conditional_xfail_data { + "Target fails for fnext-runtime" "*-*-*" { "-fnext-runtime" } { "" } + } + } +} +# carry on... +return false diff --git a/gcc/testsuite/objc/execute/exceptions/handler-1.m b/gcc/testsuite/objc/execute/exceptions/handler-1.m new file mode 100644 index 000000000..ab2fe8c53 --- /dev/null +++ b/gcc/testsuite/objc/execute/exceptions/handler-1.m @@ -0,0 +1,53 @@ +/* Test custom exception handlers */ +/* Author: David Ayers */ + +#ifdef __NEXT_RUNTIME__ +/* This test only runs for the GNU runtime. TODO: It should work on + the NEXT runtime as well (needs testing). + */ + +int main(void) +{ + return 0; +} + +#else + +#include <objc/objc-api.h> +#include <objc/objc-exception.h> +#include <objc/Object.h> +#include <stdlib.h> + +static unsigned int handlerExpected = 0; + +void +my_exception_handler(id excp) +{ + /* Returning from the handler would abort. */ + if (handlerExpected) + exit(0); + + abort(); +} + +int +main(int argc, char *argv[]) +{ + objc_setUncaughtExceptionHandler (my_exception_handler); + + @try + { + @throw [Object new]; + } + @catch (id exc) + { + handlerExpected = 1; + } + + @throw [Object new]; + abort(); + return 0; +} + + +#endif diff --git a/gcc/testsuite/objc/execute/exceptions/local-variables-1.m b/gcc/testsuite/objc/execute/exceptions/local-variables-1.m new file mode 100644 index 000000000..0488d792d --- /dev/null +++ b/gcc/testsuite/objc/execute/exceptions/local-variables-1.m @@ -0,0 +1,63 @@ +/* Check that local variables that get modified inside the @try + block survive until the @catch block is reached. */ +/* Developed by Ziemowit Laski <zlaski@apple.com>. */ + +#include <stdlib.h> +#include <stdio.h> +#import "../../../objc-obj-c++-shared/Object1.h" + +int gi1 = 9, gi2 = 19; +float gf1 = 9.0, gf2 = 19.0; +id obj2 = nil; + +void foo (int arg1, float *arg2) +{ + int *pi = &gi1; + float *pf = &gf1; + id obj1 = nil; + int local1 = 45, local2 = 47; + float local3 = 3.0, local4 = 4.0; + register int local5 = 15; + static float local6 = 16.0; + + @try { + local1 = 123; + local2 = 345; + local3 = 5.0; + local4 = 6.0; + local5 = 17; + local6 = 18.0; + pi = &gi2; + pf = &gf2; + obj2 = obj1 = [Object new]; + arg1 = 17; + arg2 = &gf2; + + @throw [Object new]; + } + @catch (Object *obj) { + if (local1 != 123 || local2 != 345 || local3 != 5.0 || local4 != 6.0 + || local5 != 17 || local6 != 18.0) { + printf("Abort 1\n"); + abort(); + } + if(pi != &gi2 || pf != &gf2) { + printf("Abort 2\n"); + abort(); + } + if(!obj1 || obj1 != obj2) { + printf("Abort 3\n"); + abort(); + } + if(arg1 != 17 || arg2 != &gf2) { + printf("Abort 4\n"); + abort(); + } + } +} + +int main(void) { + foo(15, &gf1); + return 0; +} +#import "../../../objc-obj-c++-shared/Object1-implementation.h" diff --git a/gcc/testsuite/objc/execute/exceptions/matcher-1.m b/gcc/testsuite/objc/execute/exceptions/matcher-1.m new file mode 100644 index 000000000..ef0b627da --- /dev/null +++ b/gcc/testsuite/objc/execute/exceptions/matcher-1.m @@ -0,0 +1,68 @@ +/* Test custom exception matchers */ +/* Author: Nicola Pero */ + +#ifdef __NEXT_RUNTIME__ +/* This test only runs for the GNU runtime. TODO: It should work on + the NEXT runtime as well (needs testing). + */ + +int main(void) +{ + return 0; +} + +#else + +#include <objc/objc-api.h> +#include <objc/objc-exception.h> +#include <objc/Object.h> +#include <stdlib.h> + +static unsigned int handlerExpected = 0; + +void +my_exception_matcher(Class match_class, id exception) +{ + /* Always matches. */ + return 1; +} + +@interface A : Object +@end + +@implementation A +@end + +@interface B : Object +@end + +@implementation B +@end + +int +main(int argc, char *argv[]) +{ + objc_setExceptionMatcher (my_exception_matcher); + + @try + { + @throw [A new]; + } + @catch (B *exception) + { + /* Since we installed an exception matcher that always matches, + the exception should be sent here even if it's of class A and + this is looking for exceptions of class B. + */ + return 0; + } + @catch (id exception) + { + abort (); + } + + abort (); +} + + +#endif diff --git a/gcc/testsuite/objc/execute/exceptions/pr31281.m b/gcc/testsuite/objc/execute/exceptions/pr31281.m new file mode 100644 index 000000000..41e7a8e16 --- /dev/null +++ b/gcc/testsuite/objc/execute/exceptions/pr31281.m @@ -0,0 +1,27 @@ +/* From PR31281. */ +extern void abort (void); +int __attribute__((noinline)) +f(unsigned int i) +{ + int j, k; + @try { } @catch(id) { return 13; } + for (j=0; j<i; j++) + for (k=0; k<i; k++) + { + @try { + if (i) + break; + } @catch(id) { } + return 9; + } + return 0; +} + + +int +main() +{ + if (f(1)) + abort (); + return 0 ; +} diff --git a/gcc/testsuite/objc/execute/exceptions/throw-nil.m b/gcc/testsuite/objc/execute/exceptions/throw-nil.m new file mode 100644 index 000000000..cd9a797f5 --- /dev/null +++ b/gcc/testsuite/objc/execute/exceptions/throw-nil.m @@ -0,0 +1,50 @@ +#include <objc/objc.h> +#include <objc/Object.h> + +#ifdef __NEXT_RUNTIME__ +/* This test only runs for the GNU runtime. */ + +int main(void) +{ + return 0; +} + +#else + +/* Test throwing a nil exception. A 'nil' exception can only be + caugth by a generic exception handler. + */ + +int main (void) +{ + int exception_catched = 0; + int finally_called = 0; + + @try + { + @throw nil; + } + @catch (Object *exc) + { + abort (); + } + @catch (id exc) + { + exception_catched = 1; + } + @finally + { + finally_called = 1; + } + + + if (exception_catched != 1 + || finally_called != 1) + { + abort (); + } + + return 0; +} + +#endif diff --git a/gcc/testsuite/objc/execute/exceptions/trivial.m b/gcc/testsuite/objc/execute/exceptions/trivial.m new file mode 100644 index 000000000..4e55e9d84 --- /dev/null +++ b/gcc/testsuite/objc/execute/exceptions/trivial.m @@ -0,0 +1,19 @@ +#include <stdlib.h> +#import "../../../objc-obj-c++-shared/Object1.h" + +/* do nothing except prove we can compile and link code calling the + ecceptions mechanism */ + +int main(void) +{ + @try { + int a = 1 ; + @throw [Object new]; + } + @catch (Object *obj) { + return 0; + } + abort(); +} + +#import "../../../objc-obj-c++-shared/Object1-implementation.h" diff --git a/gcc/testsuite/objc/execute/execute.exp b/gcc/testsuite/objc/execute/execute.exp new file mode 100644 index 000000000..40ca40b61 --- /dev/null +++ b/gcc/testsuite/objc/execute/execute.exp @@ -0,0 +1,47 @@ +# Copyright (C) 1991, 1992, 1993, 1995, 1997, 2007, 2008, 2010 +# Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# This file was written by Rob Savoye. (rob@cygnus.com) +# Modified by Ovidiu Predescu (ovidiu@aracnet.com) + + +if $tracelevel then { + strace $tracelevel +} + +# load support procs +load_lib objc-torture.exp +load_lib torture-options.exp + +torture-init +objc-set-runtime-options "execute" +set-torture-options $OBJC_TORTURE_OPTIONS $OBJC_RUNTIME_OPTIONS + +# +# main test loop +# + +foreach src [lsort [glob -nocomplain $srcdir/$subdir/*.m]] { + # If we're only testing specific files and this isn't one of them, skip it. + if ![runtest_file_p $runtests $src] then { + continue + } + + objc-torture-execute $src +} + +torture-finish diff --git a/gcc/testsuite/objc/execute/fdecl.m b/gcc/testsuite/objc/execute/fdecl.m new file mode 100644 index 000000000..807be0381 --- /dev/null +++ b/gcc/testsuite/objc/execute/fdecl.m @@ -0,0 +1,19 @@ +/* Bug report submitted by igorkh@hotbot.com on submit@bugs.debian.org + Thu, 13 Apr 2000 09:42:08 -0400 */ + +@class AClass; + +@interface test +{ + AClass *foo; +} +@end + +@implementation test +@end + +int main (void) +{ + return 0; +} + diff --git a/gcc/testsuite/objc/execute/formal_protocol-1.m b/gcc/testsuite/objc/execute/formal_protocol-1.m new file mode 100644 index 000000000..651444963 --- /dev/null +++ b/gcc/testsuite/objc/execute/formal_protocol-1.m @@ -0,0 +1,45 @@ +/* Contributed by Nicola Pero - Fri Mar 9 21:35:47 CET 2001 */ + +#include <stdlib.h> +#import "../../objc-obj-c++-shared/Object1.h" + +/* Tests defining a protocol and a class adopting it */ + +@protocol Enabling +- (BOOL) isEnabled; +- (void) setEnabled: (BOOL)flag; +@end + +@interface Feature : Object <Enabling> +{ + const char *name; + BOOL isEnabled; +} +@end + +@implementation Feature +- (BOOL) isEnabled +{ + return isEnabled; +} +- (void) setEnabled: (BOOL)flag +{ + isEnabled = flag; +} +@end + +int main (void) +{ + Feature *object; + + object = [Feature new]; + + [object setEnabled: YES]; + if (![object isEnabled]) + { + abort (); + } + + return 0; +} +#include "../../objc-obj-c++-shared/Object1-implementation.h" diff --git a/gcc/testsuite/objc/execute/formal_protocol-2.m b/gcc/testsuite/objc/execute/formal_protocol-2.m new file mode 100644 index 000000000..b830cd96e --- /dev/null +++ b/gcc/testsuite/objc/execute/formal_protocol-2.m @@ -0,0 +1,46 @@ +/* Contributed by Nicola Pero - Fri Mar 9 21:35:47 CET 2001 */ + +#include <stdlib.h> +#import "../../objc-obj-c++-shared/Object1.h" + +/* Test defining a protocol, a class adopting it, and using an object + of type `id <protocol>'. */ + +@protocol Enabling +- (BOOL) isEnabled; +- (void) setEnabled: (BOOL)flag; +@end + +@interface Feature : Object <Enabling> +{ + const char *name; + BOOL isEnabled; +} +@end + +@implementation Feature +- (BOOL) isEnabled +{ + return isEnabled; +} +- (void) setEnabled: (BOOL)flag +{ + isEnabled = flag; +} +@end + +int main (void) +{ + id <Enabling> object; + + object = [Feature new]; + + [object setEnabled: YES]; + if (![object isEnabled]) + { + abort (); + } + + return 0; +} +#include "../../objc-obj-c++-shared/Object1-implementation.h" diff --git a/gcc/testsuite/objc/execute/formal_protocol-3.m b/gcc/testsuite/objc/execute/formal_protocol-3.m new file mode 100644 index 000000000..f28c95fec --- /dev/null +++ b/gcc/testsuite/objc/execute/formal_protocol-3.m @@ -0,0 +1,59 @@ +/* Contributed by Nicola Pero - Fri Mar 9 21:35:47 CET 2001 */ + +#include <stdlib.h> +#import "../../objc-obj-c++-shared/Object1.h" + +/* Test defining two protocol, a class adopting both of them, + and using an object of type `id <Protocol1, Protocol2>' */ + +@protocol Enabling +- (BOOL) isEnabled; +- (void) setEnabled: (BOOL)flag; +@end + +@protocol Evaluating +- (int) importance; +@end + +@interface Feature : Object <Enabling, Evaluating> +{ + const char *name; + BOOL isEnabled; +} +@end + +@implementation Feature +- (BOOL) isEnabled +{ + return isEnabled; +} +- (void) setEnabled: (BOOL)flag +{ + isEnabled = flag; +} +- (int) importance +{ + return 1000; +} +@end + +int main (void) +{ + id <Enabling, Evaluating> object; + + object = [Feature new]; + + [object setEnabled: YES]; + if (![object isEnabled]) + { + abort (); + } + + if ([object importance] != 1000) + { + abort (); + } + + return 0; +} +#include "../../objc-obj-c++-shared/Object1-implementation.h" diff --git a/gcc/testsuite/objc/execute/formal_protocol-4.m b/gcc/testsuite/objc/execute/formal_protocol-4.m new file mode 100644 index 000000000..10aba8936 --- /dev/null +++ b/gcc/testsuite/objc/execute/formal_protocol-4.m @@ -0,0 +1,41 @@ +/* Contributed by Nicola Pero - Fri Mar 9 21:35:47 CET 2001 */ + +#include <stdlib.h> +#import "../../objc-obj-c++-shared/Object1.h" + +/* Test defining a protocol, a class adopting it in a category */ + +@protocol Evaluating +- (int) importance; +@end + +@interface Feature : Object +@end + +@implementation Feature +@end + +@interface Feature (EvaluatingProtocol) <Evaluating> +@end + +@implementation Feature (EvaluatingProtocol) +- (int) importance +{ + return 1000; +} +@end + +int main (void) +{ + id <Evaluating> object; + + object = [Feature new]; + + if ([object importance] != 1000) + { + abort (); + } + + return 0; +} +#include "../../objc-obj-c++-shared/Object1-implementation.h" diff --git a/gcc/testsuite/objc/execute/formal_protocol-5.m b/gcc/testsuite/objc/execute/formal_protocol-5.m new file mode 100644 index 000000000..c3bd53d3a --- /dev/null +++ b/gcc/testsuite/objc/execute/formal_protocol-5.m @@ -0,0 +1,38 @@ +/* Contributed by Nicola Pero - Fri Mar 9 21:35:47 CET 2001 */ + +#include <stdlib.h> +#include <objc/Protocol.h> +#include "../../objc-obj-c++-shared/next-mapping.h" + +/* Test defining a protocol, and accessing it using @protocol */ + +@protocol Evaluating +- (int) importance; +@end + +/* A class adopting the protocol */ +@interface Test <Evaluating> +@end + +@implementation Test +- (int) importance +{ + return 1000; +} +@end + +int main (void) +{ + Protocol *protocol = @protocol (Evaluating); + +#ifdef NEXT_OBJC_USE_NEW_INTERFACE + if (strcmp (protocol_getName(protocol), "Evaluating")) +#else + if (strcmp ([protocol name], "Evaluating")) +#endif + { + abort (); + } + + return 0; +} diff --git a/gcc/testsuite/objc/execute/formal_protocol-6.m b/gcc/testsuite/objc/execute/formal_protocol-6.m new file mode 100644 index 000000000..b02fc1ea4 --- /dev/null +++ b/gcc/testsuite/objc/execute/formal_protocol-6.m @@ -0,0 +1,31 @@ +/* Contributed by Nicola Pero - Fri Mar 9 21:35:47 CET 2001 */ + +#include <stdlib.h> +#include <objc/Protocol.h> +#include "../../objc-obj-c++-shared/next-mapping.h" + +/* Test defining a protocol, and accessing it using @protocol */ + +@protocol Evaluating +- (int) importance; +@end + +/* Without a class adopting the protocol - this doesn't work + with gcc-2.95.2 as well */ + +int main (void) +{ + Protocol *protocol = @protocol (Evaluating); + +#ifdef NEXT_OBJC_USE_NEW_INTERFACE + if (strcmp (protocol_getName(protocol), "Evaluating")) +#else + if (strcmp ([protocol name], "Evaluating")) +#endif + { + abort (); + } + + return 0; +} + diff --git a/gcc/testsuite/objc/execute/formal_protocol-7.m b/gcc/testsuite/objc/execute/formal_protocol-7.m new file mode 100644 index 000000000..d15013a29 --- /dev/null +++ b/gcc/testsuite/objc/execute/formal_protocol-7.m @@ -0,0 +1,44 @@ +/* Contributed by Nicola Pero - Fri Mar 9 21:35:47 CET 2001 */ + +#include <stdlib.h> +#import "../../objc-obj-c++-shared/Protocol1.h" + +/* Test defining two protocols, one incorporating the other one. */ + +@protocol Configuring +- (void) configure; +@end + +@protocol Processing <Configuring> +- (void) process; +@end + +/* A class adopting the protocol */ +@interface Test : Object <Processing> +{ + BOOL didConfigure; + BOOL didProcess; +} +@end + +@implementation Test +- (void) configure +{ + didConfigure = YES; +} +- (void) process +{ + didProcess = YES; +} +@end + +int main (void) +{ + id <Processing> object = [Test new]; + + [object configure]; + [object process]; + + return 0; +} +#include "../../objc-obj-c++-shared/Object1-implementation.h" diff --git a/gcc/testsuite/objc/execute/function-message-1.m b/gcc/testsuite/objc/execute/function-message-1.m new file mode 100644 index 000000000..6f4d87920 --- /dev/null +++ b/gcc/testsuite/objc/execute/function-message-1.m @@ -0,0 +1,33 @@ +#import "../../objc-obj-c++-shared/Object1.h" + +@interface Foo : Object ++ bar; +@end + +int foocalled = 0; +int barcalled = 0; + + +id foo() +{ + if (foocalled) + abort (); + foocalled = 1; + return [Foo class]; +} + +@implementation Foo ++ bar +{ + if (barcalled) + abort (); + barcalled = 1; + return self; +} +@end + +int main(int argc,char **argv) +{ + [foo() bar]; + return 0; +} diff --git a/gcc/testsuite/objc/execute/informal_protocol.m b/gcc/testsuite/objc/execute/informal_protocol.m new file mode 100644 index 000000000..3978e6aa2 --- /dev/null +++ b/gcc/testsuite/objc/execute/informal_protocol.m @@ -0,0 +1,13 @@ +/* Contributed by Nicola Pero - Fri Mar 9 21:35:47 CET 2001 */ +#import "../../objc-obj-c++-shared/Object1.h" +#include <objc/objc.h> + +@interface Object (StopProtocol) +- (void) stop; +@end + +int main (void) +{ + return 0; +} + diff --git a/gcc/testsuite/objc/execute/initialize.m b/gcc/testsuite/objc/execute/initialize.m new file mode 100644 index 000000000..537839829 --- /dev/null +++ b/gcc/testsuite/objc/execute/initialize.m @@ -0,0 +1,36 @@ +/* Contributed by Nicola Pero - Wed Mar 7 17:55:04 CET 2001 */ +#include <objc/objc.h> + +/* Test that +initialize is automatically called before the class is + accessed */ + +static int class_variable = 0; + +@interface TestClass +{ + Class isa; +} ++ (void) initialize; ++ (int) classVariable; +@end + +@implementation TestClass ++ (void) initialize +{ + class_variable = 1; +} ++ (int) classVariable +{ + return class_variable; +} +@end + +int main (void) +{ + if ([TestClass classVariable] != 1) + { + abort (); + } + + return 0; +} diff --git a/gcc/testsuite/objc/execute/load-2.m b/gcc/testsuite/objc/execute/load-2.m new file mode 100644 index 000000000..eb9065836 --- /dev/null +++ b/gcc/testsuite/objc/execute/load-2.m @@ -0,0 +1,46 @@ +/* Contributed by Nicola Pero - Wed Jun 6 14:34:23 CEST 2001 */ +#include <objc/objc.h> + +/* Test that +load is automatically called before main is run; + on two different classes. */ + +static int static_variable1 = 0; +static int static_variable2 = 0; + +@interface TestClass1 +{ + Class isa; +} ++ (void) load; +@end + +@implementation TestClass1 ++ (void) load +{ + static_variable1 = 1; +} +@end + +@interface TestClass2 +{ + Class isa; +} ++ (void) load; +@end + +@implementation TestClass2 ++ (void) load +{ + static_variable2 = 1; +} +@end + +int main (void) +{ + if (static_variable1 != 1 || static_variable2 != 1) + { + abort (); + } + + return 0; +} diff --git a/gcc/testsuite/objc/execute/load-3.m b/gcc/testsuite/objc/execute/load-3.m new file mode 100644 index 000000000..15dfc0b48 --- /dev/null +++ b/gcc/testsuite/objc/execute/load-3.m @@ -0,0 +1,109 @@ +/* + load-3.m + + Author: Ovidiu Predescu <ovidiu@cup.hp.com> + Date: June 3, 2001 + + Test if the +load methods are invoked, and are invoked in the + proper order. + */ + +#include <stdlib.h> +#import "../../objc-obj-c++-shared/Object1.h" +#include <objc/objc.h> + +@interface A : Object +@end + +@interface B : A +@end + +static a_load = 0; +static b_load = 0; +static a_category_load = 0; +static b_category_load = 0; + +@implementation A (Category) ++ (void)load +{ + a_category_load = 1; + printf("+[A(Category) load]\n"); + + if (a_load != 1) + { + printf("+load for A(Category) invoked before A's!\n"); + abort(); + } +} +@end + +@implementation B(Category) ++ (void)load +{ + b_category_load = 1; + printf("+[B(Category) load]\n"); + + if (b_load != 1) + { + printf ("+load for B(Category) invoked before B!\n"); + abort(); + } +} +@end + +@implementation B ++ (void)load +{ + b_load = 1; + printf("+[B load]\n"); + + if (a_load != 1) + { + printf("+load for B invoked before A's!\n"); + abort(); + } + + if (b_category_load != 0) + { + printf("+load for B invoked after B(Category)!\n"); + abort(); + } +} +@end + +@implementation A ++ (void)load +{ + a_load = 1; + printf("+[A load]\n"); + + if (a_category_load != 0) + { + printf("+load for A(Category) invoked before A!\n"); + abort(); + } + + if (b_load != 0) + { + printf("+load for A invoked after B!\n"); + abort(); + } + + if (b_category_load != 0) + { + printf("+load for B(Category) invoked before A and B!\n"); + abort(); + } +} +@end + +int main (void) +{ + if (a_load + b_load + a_category_load + b_category_load != 4) + { + printf("Not all +load methods invoked!\n"); + abort(); + } + + return 0; +} diff --git a/gcc/testsuite/objc/execute/load.m b/gcc/testsuite/objc/execute/load.m new file mode 100644 index 000000000..fad662384 --- /dev/null +++ b/gcc/testsuite/objc/execute/load.m @@ -0,0 +1,30 @@ +/* Contributed by Nicola Pero - Wed Mar 7 17:55:04 CET 2001 */ +#include <objc/objc.h> + +/* Test that +load is automatically called before main is run */ + +static int static_variable = 0; + +@interface TestClass +{ + Class isa; +} ++ (void) load; +@end + +@implementation TestClass ++ (void) load +{ + static_variable = 1; +} +@end + +int main (void) +{ + if (static_variable != 1) + { + abort (); + } + + return 0; +} diff --git a/gcc/testsuite/objc/execute/many_args_method.m b/gcc/testsuite/objc/execute/many_args_method.m new file mode 100644 index 000000000..6cc2e2535 --- /dev/null +++ b/gcc/testsuite/objc/execute/many_args_method.m @@ -0,0 +1,59 @@ +/* Contributed by Nicola Pero - Fri Mar 9 19:39:15 CET 2001 */ +#include <objc/objc.h> + +/* Test the syntax of methods with many arguments */ + +@interface TestClass +{ + Class isa; +} ++ (int) sumInteger: (int)a withInteger: (int)b; ++ (int) sum: (int)a : (int)b; ++ (int) sumInteger: (int)a withInteger: (int)b withInteger: (int)c; ++ (int) sum: (int)a : (int)b : (int)c; +@end + +@implementation TestClass ++ (int) sumInteger: (int)a withInteger: (int)b +{ + return a + b; +} ++ (int) sum: (int)a : (int)b +{ + return [self sumInteger: a withInteger: b]; +} ++ (int) sumInteger: (int)a withInteger: (int)b withInteger: (int)c +{ + return a + b + c; +} ++ (int) sum: (int)a : (int)b : (int)c +{ + return [self sumInteger: a withInteger: b withInteger: c]; +} +#ifdef __NEXT_RUNTIME__ ++ initialize { return self; } +#endif +@end + + +int main (void) +{ + if ([TestClass sumInteger: 1 withInteger: 1] != 2) + { + abort (); + } + if ([TestClass sum: 1 : 1] != 2) + { + abort (); + } + if ([TestClass sumInteger: 1 withInteger: 1 withInteger: 1] != 3) + { + abort (); + } + if ([TestClass sum: 1 : 1 : 1] != 3) + { + abort (); + } + + return 0; +} diff --git a/gcc/testsuite/objc/execute/nested-1.m b/gcc/testsuite/objc/execute/nested-1.m new file mode 100644 index 000000000..02a390368 --- /dev/null +++ b/gcc/testsuite/objc/execute/nested-1.m @@ -0,0 +1,12 @@ +/* Contributed by Nicola Pero Wed Feb 21 12:08:16 GMT 2001 */ + +int main (void) +{ + void nested (void) + { + return; + } + + return 0; +} + diff --git a/gcc/testsuite/objc/execute/nested-2.m b/gcc/testsuite/objc/execute/nested-2.m new file mode 100644 index 000000000..0c67ec147 --- /dev/null +++ b/gcc/testsuite/objc/execute/nested-2.m @@ -0,0 +1,17 @@ +/* Contributed by Nicola Pero Mon Mar 5 19:57:11 CET 2001 */ + +int main (void) +{ + inline int nested (void) + { + return 1; + } + + if (nested () != 1) + { + exit (1); + } + + return 0; +} + diff --git a/gcc/testsuite/objc/execute/nested-3.m b/gcc/testsuite/objc/execute/nested-3.m new file mode 100644 index 000000000..5462fd5ef --- /dev/null +++ b/gcc/testsuite/objc/execute/nested-3.m @@ -0,0 +1,40 @@ +/* Contributed by Nicola Pero - Fri Mar 9 19:39:15 CET 2001 */ +#include <objc/objc.h> + +/* Test defining a nested function inside a method */ + +@interface Test +{ + Class isa; +} ++ (int) test; +@end + +@implementation Test + ++ (int) test +{ + int test (void) + { + return 1; + } + + return test (); +} + +#ifdef __NEXT_RUNTIME__ ++ initialize { return self; } +#endif +@end + +int main (void) +{ + if ([Test test] != 1) + { + abort (); + } + + return 0; +} + + diff --git a/gcc/testsuite/objc/execute/nested-func-1.m b/gcc/testsuite/objc/execute/nested-func-1.m new file mode 100644 index 000000000..a4c9a5619 --- /dev/null +++ b/gcc/testsuite/objc/execute/nested-func-1.m @@ -0,0 +1,36 @@ +/* Test basic nested C function functionality within ObjC + methods. */ +/* Contributed by Ziemowit Laski <zlaski@apple.com>. */ +#include <stdio.h> +#include <stdlib.h> +#import "../../objc-obj-c++-shared/Object1.h" +#include <objc/objc.h> + +int bappy (int (*blargh) (int a, int b, int c)) +{ + return blargh (4, 7, 2) + 3; +} + +@interface Foo: Object ++ (int)foo; +@end + +@implementation Foo ++ (int)foo +{ + int blargh (int a, int b, int c) + { + return a * b + c; + } + return bappy (blargh); +} +@end + +int main () +{ + int f = [Foo foo]; + if (f != 33) + abort (); + + return 0; +} diff --git a/gcc/testsuite/objc/execute/next_mapping.h b/gcc/testsuite/objc/execute/next_mapping.h new file mode 100644 index 000000000..41d40fdf0 --- /dev/null +++ b/gcc/testsuite/objc/execute/next_mapping.h @@ -0,0 +1,906 @@ +/* This file "renames" various ObjC GNU runtime entry points + (and fakes the existence of several others) + if the NeXT runtime is being used. */ +/* Authors: Ziemowit Laski <zlaski@apple.com> */ +/* David Ayers <d.ayers@inode.at> */ + +#ifdef __NEXT_RUNTIME__ +#include <objc/objc-class.h> +#include <objc/Object.h> +#include <ctype.h> +#include <stdlib.h> +#include <string.h> + +#define objc_get_class(C) objc_getClass(C) +#define objc_get_meta_class(C) objc_getMetaClass(C) +#define class_get_class_method(C, S) class_getClassMethod(C, S) +#define class_get_instance_method(C, S) class_getInstanceMethod(C, S) +#define method_get_imp(M) (((Method)M)->method_imp) +#define sel_get_name(S) sel_getName(S) +#define class_create_instance(C) class_createInstance(C, 0) +#define class_get_class_name(C) object_getClassName(C) +#define class_get_super_class(C) (((struct objc_class *)C)->super_class) +#define object_get_super_class(O) class_get_super_class(*(struct objc_class **)O) +#define objc_lookup_class(N) objc_lookUpClass(N) +#define object_get_class(O) (*(struct objc_class **)O) +#define class_is_class(C) (CLS_GETINFO((struct objc_class *)C, CLS_CLASS)? YES: NO) +#define class_is_meta_class(C) (CLS_GETINFO((struct objc_class *)C, CLS_META)? YES: NO) +#define object_is_class(O) class_is_meta_class(*(struct objc_class **)O) +#define object_is_meta_class(O) (class_is_meta_class(O) && class_is_meta_class(*(struct objc_class **)O)) + +/* You need either an empty +initialize method or an empty -forward:: method. + The NeXT runtime unconditionally sends +initialize to classes when they are + first used, and unconditionally tries to forward methods that the class + doesn't understand (including +initialize). If you have neither +initialize + nor -forward::, the runtime complains. + + The simplest workaround is to add + + + initialize { return self; } + + to every root class @implementation. */ + +#ifndef NULL +#define NULL 0 +#endif + +/* The following is necessary to "cover" the bf*.m test cases on NeXT. */ + +#undef MAX +#undef MIN +#undef ROUND + +#ifdef __cplusplus +#define MAX(X, Y) ((X > Y) ? X : Y) +#define MIN(X, Y) ((X < Y) ? X : Y) +#define ROUND(V, A) (A * ((V + A - 1) / A)) +#else +#define MAX(X, Y) \ + ({ typeof (X) __x = (X), __y = (Y); \ + (__x > __y ? __x : __y); }) +#define MIN(X, Y) \ + ({ typeof (X) __x = (X), __y = (Y); \ + (__x < __y ? __x : __y); }) +#define ROUND(V, A) \ + ({ typeof (V) __v = (V); typeof (A) __a = (A); \ + __a * ((__v+__a - 1)/__a); }) +#endif + +#define BITS_PER_UNIT __CHAR_BIT__ +typedef struct{ char a; } __small_struct; +#define STRUCTURE_SIZE_BOUNDARY (BITS_PER_UNIT * sizeof (__small_struct)) + +/* Not sure why the following are missing from NeXT objc headers... */ + +#ifndef _C_LNG_LNG +#define _C_LNG_LNG 'q' +#endif +#ifndef _C_ULNG_LNG +#define _C_ULNG_LNG 'Q' +#endif +#ifndef _C_ATOM +#define _C_ATOM '%' +#endif +#ifndef _C_BOOL +#define _C_BOOL 'B' +#endif + +#define _C_CONST 'r' +#define _C_IN 'n' +#define _C_INOUT 'N' +#define _C_OUT 'o' +#define _C_BYCOPY 'O' +#define _C_BYREF 'R' +#define _C_ONEWAY 'V' +#define _C_GCINVISIBLE '!' + +#define _F_CONST 0x01 +#define _F_IN 0x01 +#define _F_OUT 0x02 +#define _F_INOUT 0x03 +#define _F_BYCOPY 0x04 +#define _F_BYREF 0x08 +#define _F_ONEWAY 0x10 +#define _F_GCINVISIBLE 0x20 + +struct objc_struct_layout +{ + const char *original_type; + const char *type; + const char *prev_type; + unsigned int record_size; + unsigned int record_align; +}; + +typedef union arglist { + char *arg_ptr; + char arg_regs[sizeof (char*)]; +} *arglist_t; /* argument frame */ + +const char *objc_skip_typespec (const char *type); +void objc_layout_structure_get_info (struct objc_struct_layout *layout, + unsigned int *offset, unsigned int *align, const char **type); +void objc_layout_structure (const char *type, + struct objc_struct_layout *layout); +BOOL objc_layout_structure_next_member (struct objc_struct_layout *layout); +void objc_layout_finish_structure (struct objc_struct_layout *layout, + unsigned int *size, unsigned int *align); +int objc_aligned_size (const char *type); + +/* + return the size of an object specified by type +*/ + +int +objc_sizeof_type (const char *type) +{ + /* Skip the variable name if any */ + if (*type == '"') + { + for (type++; *type++ != '"';) + /* do nothing */; + } + + switch (*type) { + case _C_ID: + return sizeof (id); + break; + + case _C_CLASS: + return sizeof (Class); + break; + + case _C_SEL: + return sizeof (SEL); + break; + + case _C_CHR: + return sizeof (char); + break; + + case _C_UCHR: + return sizeof (unsigned char); + break; + + case _C_SHT: + return sizeof (short); + break; + + case _C_USHT: + return sizeof (unsigned short); + break; + + case _C_INT: + return sizeof (int); + break; + + case _C_UINT: + return sizeof (unsigned int); + break; + + case _C_LNG: + return sizeof (long); + break; + + case _C_ULNG: + return sizeof (unsigned long); + break; + + case _C_LNG_LNG: + return sizeof (long long); + break; + + case _C_ULNG_LNG: + return sizeof (unsigned long long); + break; + + case _C_FLT: + return sizeof (float); + break; + + case _C_DBL: + return sizeof (double); + break; + + case _C_PTR: + case _C_ATOM: + case _C_CHARPTR: + return sizeof (char *); + break; + + case _C_ARY_B: + { + int len = atoi (type + 1); + while (isdigit ((unsigned char)*++type)) + ; + return len * objc_aligned_size (type); + } + break; + + case _C_BFLD: + { + /* The NeXT encoding of bitfields is _still_: b 'size' */ + int size = atoi (type + 1); + /* Return an upper bound on byte size */ + return (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT; + } + + case _C_STRUCT_B: + { + struct objc_struct_layout layout; + unsigned int size; + + objc_layout_structure (type, &layout); + while (objc_layout_structure_next_member (&layout)) + /* do nothing */ ; + objc_layout_finish_structure (&layout, &size, NULL); + + return size; + } + + case _C_UNION_B: + { + int max_size = 0; + while (*type != _C_UNION_E && *type++ != '=') + /* do nothing */; + while (*type != _C_UNION_E) + { + /* Skip the variable name if any */ + if (*type == '"') + { + for (type++; *type++ != '"';) + /* do nothing */; + } + max_size = MAX (max_size, objc_sizeof_type (type)); + type = objc_skip_typespec (type); + } + return max_size; + } + } + return 0; /* error */ +} + + +/* + Return the alignment of an object specified by type +*/ + +int +objc_alignof_type (const char *type) +{ + /* Skip the variable name if any */ + if (*type == '"') + { + for (type++; *type++ != '"';) + /* do nothing */; + } + switch (*type) { + case _C_ID: + return __alignof__ (id); + break; + + case _C_CLASS: + return __alignof__ (Class); + break; + + case _C_SEL: + return __alignof__ (SEL); + break; + + case _C_CHR: + return __alignof__ (char); + break; + + case _C_UCHR: + return __alignof__ (unsigned char); + break; + + case _C_SHT: + return __alignof__ (short); + break; + + case _C_USHT: + return __alignof__ (unsigned short); + break; + + case _C_INT: + case _C_BFLD: /* This is for the NeXT only */ + return __alignof__ (int); + break; + + case _C_UINT: + return __alignof__ (unsigned int); + break; + + case _C_LNG: + return __alignof__ (long); + break; + + case _C_ULNG: + return __alignof__ (unsigned long); + break; + + case _C_LNG_LNG: + return __alignof__ (long long); + break; + + case _C_ULNG_LNG: + return __alignof__ (unsigned long long); + break; + + case _C_FLT: + return __alignof__ (float); + break; + + case _C_DBL: + return __alignof__ (double); + break; + + case _C_PTR: + case _C_ATOM: + case _C_CHARPTR: + return __alignof__ (char *); + break; + + case _C_ARY_B: + while (isdigit ((unsigned char)*++type)) + /* do nothing */; + return objc_alignof_type (type); + + case _C_STRUCT_B: + { + struct objc_struct_layout layout; + unsigned int align; + + objc_layout_structure (type, &layout); + while (objc_layout_structure_next_member (&layout)) + /* do nothing */; + objc_layout_finish_structure (&layout, NULL, &align); + + return align; + } + + case _C_UNION_B: + { + int maxalign = 0; + while (*type != _C_UNION_E && *type++ != '=') + /* do nothing */; + while (*type != _C_UNION_E) + { + /* Skip the variable name if any */ + if (*type == '"') + { + for (type++; *type++ != '"';) + /* do nothing */; + } + maxalign = MAX (maxalign, objc_alignof_type (type)); + type = objc_skip_typespec (type); + } + return maxalign; + } + } + return 0; /* error */ +} + +/* + The aligned size if the size rounded up to the nearest alignment. +*/ + +int +objc_aligned_size (const char *type) +{ + int size, align; + + /* Skip the variable name */ + if (*type == '"') + { + for (type++; *type++ != '"';) + /* do nothing */; + } + + size = objc_sizeof_type (type); + align = objc_alignof_type (type); + + return ROUND (size, align); +} + +/* + The size rounded up to the nearest integral of the wordsize, taken + to be the size of a void *. +*/ + +int +objc_promoted_size (const char *type) +{ + int size, wordsize; + + /* Skip the variable name */ + if (*type == '"') + { + for (type++; *type++ != '"';) + /* do nothing */; + } + + size = objc_sizeof_type (type); + wordsize = sizeof (void *); + + return ROUND (size, wordsize); +} + +/* + Skip type qualifiers. These may eventually precede typespecs + occurring in method prototype encodings. +*/ + +inline const char * +objc_skip_type_qualifiers (const char *type) +{ + while (*type == _C_CONST + || *type == _C_IN + || *type == _C_INOUT + || *type == _C_OUT + || *type == _C_BYCOPY + || *type == _C_BYREF + || *type == _C_ONEWAY + || *type == _C_GCINVISIBLE) + { + type += 1; + } + return type; +} + + +/* + Skip one typespec element. If the typespec is prepended by type + qualifiers, these are skipped as well. +*/ + +const char * +objc_skip_typespec (const char *type) +{ + /* Skip the variable name if any */ + if (*type == '"') + { + for (type++; *type++ != '"';) + /* do nothing */; + } + + type = objc_skip_type_qualifiers (type); + + switch (*type) { + + case _C_ID: + /* An id may be annotated by the actual type if it is known + with the @"ClassName" syntax */ + + if (*++type != '"') + return type; + else + { + while (*++type != '"') + /* do nothing */; + return type + 1; + } + + /* The following are one character type codes */ + case _C_CLASS: + case _C_SEL: + case _C_CHR: + case _C_UCHR: + case _C_CHARPTR: + case _C_ATOM: + case _C_SHT: + case _C_USHT: + case _C_INT: + case _C_UINT: + case _C_LNG: + case _C_ULNG: + case _C_LNG_LNG: + case _C_ULNG_LNG: + case _C_FLT: + case _C_DBL: + case _C_VOID: + case _C_UNDEF: + return ++type; + break; + + case _C_ARY_B: + /* skip digits, typespec and closing ']' */ + + while (isdigit ((unsigned char)*++type)) + ; + type = objc_skip_typespec (type); + if (*type == _C_ARY_E) + return ++type; + else + break; /* error */ + + case _C_BFLD: + /* The NeXT encoding for bitfields is _still_: b 'size' */ + while (isdigit ((unsigned char)*++type)) + ; /* skip type and size */ + return type; + + case _C_STRUCT_B: + /* skip name, and elements until closing '}' */ + + while (*type != _C_STRUCT_E && *type++ != '=') + ; + while (*type != _C_STRUCT_E) + { + type = objc_skip_typespec (type); + } + return ++type; + + case _C_UNION_B: + /* skip name, and elements until closing ')' */ + + while (*type != _C_UNION_E && *type++ != '=') + ; + while (*type != _C_UNION_E) + { + type = objc_skip_typespec (type); + } + return ++type; + + case _C_PTR: + /* Just skip the following typespec */ + + return objc_skip_typespec (++type); + } + return 0; /* error */ +} + +/* + Skip an offset as part of a method encoding. This is prepended by a + '+' if the argument is passed in registers. +*/ +inline const char * +objc_skip_offset (const char *type) +{ + if (*type == '+') + type++; + while (isdigit ((unsigned char) *++type)) + ; + return type; +} + +/* + Skip an argument specification of a method encoding. +*/ +const char * +objc_skip_argspec (const char *type) +{ + type = objc_skip_typespec (type); + type = objc_skip_offset (type); + return type; +} + +/* + Return the number of arguments that the method MTH expects. + Note that all methods need two implicit arguments `self' and + `_cmd'. +*/ +int +method_get_number_of_arguments (struct objc_method *mth) +{ + int i = 0; + const char *type = mth->method_types; + while (*type) + { + type = objc_skip_argspec (type); + i += 1; + } + return i - 1; +} + +/* + Return the size of the argument block needed on the stack to invoke + the method MTH. This may be zero, if all arguments are passed in + registers. +*/ + +int +method_get_sizeof_arguments (struct objc_method *mth) +{ + const char *type = objc_skip_typespec (mth->method_types); + return atoi (type); +} + +/* + Return a pointer to the next argument of ARGFRAME. type points to + the last argument. Typical use of this look like: + + { + char *datum, *type; + for (datum = method_get_first_argument (method, argframe, &type); + datum; datum = method_get_next_argument (argframe, &type)) + { + unsigned flags = objc_get_type_qualifiers (type); + type = objc_skip_type_qualifiers (type); + if (*type != _C_PTR) + [portal encodeData: datum ofType: type]; + else + { + if ((flags & _F_IN) == _F_IN) + [portal encodeData: *(char **) datum ofType: ++type]; + } + } + } +*/ + +char * +method_get_next_argument (arglist_t argframe, const char **type) +{ + const char *t = objc_skip_argspec (*type); + + if (*t == '\0') + return 0; + + *type = t; + t = objc_skip_typespec (t); + + if (*t == '+') + return argframe->arg_regs + atoi (++t); + else + return argframe->arg_ptr + atoi (t); +} + +/* + Return a pointer to the value of the first argument of the method + described in M with the given argumentframe ARGFRAME. The type + is returned in TYPE. type must be passed to successive calls of + method_get_next_argument. +*/ +char * +method_get_first_argument (struct objc_method *m, + arglist_t argframe, + const char **type) +{ + *type = m->method_types; + return method_get_next_argument (argframe, type); +} + +/* + Return a pointer to the ARGth argument of the method + M from the frame ARGFRAME. The type of the argument + is returned in the value-result argument TYPE +*/ + +char * +method_get_nth_argument (struct objc_method *m, + arglist_t argframe, int arg, + const char **type) +{ + const char *t = objc_skip_argspec (m->method_types); + + if (arg > method_get_number_of_arguments (m)) + return 0; + + while (arg--) + t = objc_skip_argspec (t); + + *type = t; + t = objc_skip_typespec (t); + + if (*t == '+') + return argframe->arg_regs + atoi (++t); + else + return argframe->arg_ptr + atoi (t); +} + +unsigned +objc_get_type_qualifiers (const char *type) +{ + unsigned res = 0; + BOOL flag = YES; + + while (flag) + switch (*type++) + { + case _C_CONST: res |= _F_CONST; break; + case _C_IN: res |= _F_IN; break; + case _C_INOUT: res |= _F_INOUT; break; + case _C_OUT: res |= _F_OUT; break; + case _C_BYCOPY: res |= _F_BYCOPY; break; + case _C_BYREF: res |= _F_BYREF; break; + case _C_ONEWAY: res |= _F_ONEWAY; break; + case _C_GCINVISIBLE: res |= _F_GCINVISIBLE; break; + default: flag = NO; + } + + return res; +} + + +/* The following three functions can be used to determine how a + structure is laid out by the compiler. For example: + + struct objc_struct_layout layout; + int i; + + objc_layout_structure (type, &layout); + while (objc_layout_structure_next_member (&layout)) + { + int position, align; + const char *type; + + objc_layout_structure_get_info (&layout, &position, &align, &type); + printf ("element %d has offset %d, alignment %d\n", + i++, position, align); + } + + These functions are used by objc_sizeof_type and objc_alignof_type + functions to compute the size and alignment of structures. The + previous method of computing the size and alignment of a structure + was not working on some architectures, particulary on AIX, and in + the presence of bitfields inside the structure. */ +void +objc_layout_structure (const char *type, + struct objc_struct_layout *layout) +{ + const char *ntype; + + layout->original_type = ++type; + + /* Skip "<name>=" if any. Avoid embedded structures and unions. */ + ntype = type; + while (*ntype != _C_STRUCT_E && *ntype != _C_STRUCT_B && *ntype != _C_UNION_B + && *ntype++ != '=') + /* do nothing */; + + /* If there's a "<name>=", ntype - 1 points to '='; skip the the name */ + if (*(ntype - 1) == '=') + type = ntype; + + layout->type = type; + layout->prev_type = NULL; + layout->record_size = 0; + layout->record_align = MAX (BITS_PER_UNIT, STRUCTURE_SIZE_BOUNDARY); +} + + +BOOL +objc_layout_structure_next_member (struct objc_struct_layout *layout) +{ + register int desired_align = 0; + + /* The current type without the type qualifiers */ + const char *type; + + /* Add the size of the previous field to the size of the record. */ + if (layout->prev_type) + { + type = objc_skip_type_qualifiers (layout->prev_type); + + if (*type != _C_BFLD) + layout->record_size += objc_sizeof_type (type) * BITS_PER_UNIT; + else + layout->record_size += atoi (++type); + } + + if (*layout->type == _C_STRUCT_E) + return NO; + + /* Skip the variable name if any */ + if (*layout->type == '"') + { + for (layout->type++; *layout->type++ != '"';) + /* do nothing */; + } + + type = objc_skip_type_qualifiers (layout->type); + + desired_align = objc_alignof_type (type) * BITS_PER_UNIT; + + /* Record must have at least as much alignment as any field. + Otherwise, the alignment of the field within the record + is meaningless. */ + layout->record_align = MAX (layout->record_align, desired_align); + + if (*type == _C_BFLD) + { + int bfld_size = atoi (++type); + int int_align = __alignof__ (int) * BITS_PER_UNIT; + /* If this bitfield would traverse a word alignment boundary, push it out + to that boundary instead. */ + if (layout->record_size % int_align + && (layout->record_size / int_align + < (layout->record_size + bfld_size - 1) / int_align)) + layout->record_size = ROUND (layout->record_size, int_align); + } + else if (layout->record_size % desired_align != 0) + { + /* We need to skip space before this field. + Bump the cumulative size to multiple of field alignment. */ + layout->record_size = ROUND (layout->record_size, desired_align); + } + + /* Jump to the next field in record. */ + + layout->prev_type = layout->type; + layout->type = objc_skip_typespec (layout->type); /* skip component */ + + return YES; +} + + +void objc_layout_finish_structure (struct objc_struct_layout *layout, + unsigned int *size, + unsigned int *align) +{ + if (layout->type && *layout->type == _C_STRUCT_E) + { + /* Round the size up to be a multiple of the required alignment */ + layout->record_size = ROUND (layout->record_size, layout->record_align); + layout->type = NULL; + } + if (size) + *size = layout->record_size / BITS_PER_UNIT; + if (align) + *align = layout->record_align / BITS_PER_UNIT; +} + + +void objc_layout_structure_get_info (struct objc_struct_layout *layout, + unsigned int *offset, + unsigned int *align, + const char **type) +{ + if (offset) + *offset = layout->record_size / BITS_PER_UNIT; + if (align) + *align = layout->record_align / BITS_PER_UNIT; + if (type) + *type = layout->prev_type; +} + +/* A small, portable NSConstantString implementation for use with the NeXT + runtime. + + On full-fledged Mac OS X systems, NSConstantString is provided + as part of the Foundation framework. However, on bare Darwin systems, + Foundation is not included, and hence there is no NSConstantString + implementation to link against. + + This code is derived from the GNU runtime's NXConstantString implementation. +*/ + +struct objc_class _NSConstantStringClassReference; + +@interface NSConstantString : Object +{ + char *c_string; + unsigned int len; +} + +-(const char *) cString; +-(unsigned int) length; + +@end + +@implementation NSConstantString + +-(const char *) cString +{ + return (c_string); +} + +-(unsigned int) length +{ + return (len); +} + +@end + +/* The NSConstantString metaclass will need to be initialized before we can + send messages to strings. */ + +void objc_constant_string_init (void) __attribute__((constructor)); +void objc_constant_string_init (void) { + memcpy (&_NSConstantStringClassReference, + objc_getClass ("NSConstantString"), + sizeof (_NSConstantStringClassReference)); +} + +#endif /* #ifdef __NEXT_RUNTIME__ */ diff --git a/gcc/testsuite/objc/execute/nil_method-1.m b/gcc/testsuite/objc/execute/nil_method-1.m new file mode 100644 index 000000000..137d2072e --- /dev/null +++ b/gcc/testsuite/objc/execute/nil_method-1.m @@ -0,0 +1,61 @@ +/* Contributed by Nicola Pero - Fri Aug 30 12:55:37 2002 */ +#include <objc/objc.h> +#include <objc/Object.h> + +/* Test that calling a method of a nil object results in + nothing to happen (but not a crash), and nil to be + returned. */ + +@interface TestClass : Object + +- (void) testVoid; +- (id) testId; + +- (void) testVoidWithA: (int)a; +- (id) testIdWithA: (id)a; + +- (void) testVoidWithA: (int)a andB: (int)b; +- (id) testIdWithA: (id)g andB: (id)b; + +- (void) voidSum: (int)firstNumber, ...; +- (id) sum: (int)firstNumber, ...; + +@end + +int main (void) +{ + TestClass *t = nil; + + [t testVoid]; + + if ([t testId] != nil) + { + abort (); + } + + [t testVoidWithA: 234]; + + if ([t testIdWithA: t] != nil) + { + abort (); + } + + [t testVoidWithA: 12004 andB: -123]; + + if ([t testIdWithA: t andB: nil] != nil) + { + abort (); + } + + + [t voidSum: 1, -2, 3, -4, 5, -6, 7, -8, 9, -10, + 11, -12, 13, -14, 15, -16, 17, -18, 19, -20]; + + if ([t sum: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] != nil) + { + abort (); + } + + return 0; +} diff --git a/gcc/testsuite/objc/execute/no_clash.m b/gcc/testsuite/objc/execute/no_clash.m new file mode 100644 index 000000000..d4ab4cb1c --- /dev/null +++ b/gcc/testsuite/objc/execute/no_clash.m @@ -0,0 +1,42 @@ +/* Contributed by Nicola Pero - Fri Mar 9 19:39:15 CET 2001 */ +#import "../../objc-obj-c++-shared/Object1.h" +#import <objc/objc.h> + +/* Test that using the same name for different things makes no + problem */ + +@interface TestClass : Object +{ + int test; +} ++ (int) test; +- (int) test; +@end + +@implementation TestClass ++ (int) test +{ + return 1; +} +- (int) test +{ + /* 0 + 2 as `test' is implicitly initialized to zero */ + return test + 2; +} +@end + + +int main (void) +{ + if ([TestClass test] != 1) + { + abort (); + } + if ([[[TestClass alloc] init] test] != 2) + { + abort (); + } + + return 0; +} +#include "../../objc-obj-c++-shared/Object1-implementation.h" diff --git a/gcc/testsuite/objc/execute/np-1.m b/gcc/testsuite/objc/execute/np-1.m new file mode 100644 index 000000000..1cf83ff7f --- /dev/null +++ b/gcc/testsuite/objc/execute/np-1.m @@ -0,0 +1,31 @@ +/* + * Contributed by Nicola Pero <n.pero@mi.flashnet.it> + * Tue Sep 19 4:29AM + */ + +#include "../../objc-obj-c++-shared/Protocol1.h" +#include <objc/objc.h> + +@protocol MyProtocol +- (oneway void) methodA; +@end + +@interface MyObject <MyProtocol> +@end + +@implementation MyObject +- (oneway void) methodA +{ +} +@end + +int main (void) +{ + MyObject *object = nil; + + [object methodA]; + + exit (0); +} + + diff --git a/gcc/testsuite/objc/execute/np-2.m b/gcc/testsuite/objc/execute/np-2.m new file mode 100644 index 000000000..da276be98 --- /dev/null +++ b/gcc/testsuite/objc/execute/np-2.m @@ -0,0 +1,32 @@ +/* + * Contributed by Nicola Pero <n.pero@mi.flashnet.it> + * Tue Sep 19 4:34AM + */ +#include "../../objc-obj-c++-shared/Protocol1.h" +#include <objc/objc.h> + +@protocol MyProtocol ++ (oneway void) methodA; +@end + +@interface MyObject <MyProtocol> +@end + +@implementation MyObject ++ (oneway void) methodA +{ + printf ("methodA\n"); +} +#ifdef __NEXT_RUNTIME__ ++ initialize { return self; } +#endif +@end + +int main (void) +{ + [MyObject methodA]; + + exit (0); +} + + diff --git a/gcc/testsuite/objc/execute/object_is_class.m b/gcc/testsuite/objc/execute/object_is_class.m new file mode 100644 index 000000000..14a7f5232 --- /dev/null +++ b/gcc/testsuite/objc/execute/object_is_class.m @@ -0,0 +1,46 @@ +/* Contributed by Nicola Pero - Tue Jul 3 10:55:21 BST 2001 */ +#ifdef __NEXT_RUNTIME__ +# include "../../objc-obj-c++-shared/next-mapping.h" +#else +# include <objc/objc-api.h> +#endif +#include "../../objc-obj-c++-shared/Object1.h" + +/* This test demonstrate a failure in object_is_class which was fixed */ + +/* Create a class whose instance variables mirror the struct used for + Class structures in the runtime ... yes we're feeling evil today */ +@interface EvilClass : Object +{ + Class super_class; + const char* name; + long version; + unsigned long info; +} +@end + +@implementation EvilClass +- (id) init +{ + self = [super init]; + /* The following one is used in the runtime to mark classes */ + info = 0x1L; + return self; +} +@end + +int main (void) +{ + /* Create an object of our EvilClass */ + EvilClass *evilObject = [EvilClass new]; + + /* Now check that the object is not a class object */ + if (object_is_class (evilObject)) + { + printf ("object_is_class failed\n"); + abort (); + } + + return 0; +} +#include "../../objc-obj-c++-shared/Object1-implementation.h" diff --git a/gcc/testsuite/objc/execute/object_is_meta_class.m b/gcc/testsuite/objc/execute/object_is_meta_class.m new file mode 100644 index 000000000..91a628eba --- /dev/null +++ b/gcc/testsuite/objc/execute/object_is_meta_class.m @@ -0,0 +1,44 @@ +/* Contributed by Nicola Pero - Tue Jul 3 10:55:21 BST 2001 */ +#ifdef __NEXT_RUNTIME__ +# include "../../objc-obj-c++-shared/next-mapping.h" +#else +# include <objc/objc-api.h> +#endif +#include "../../objc-obj-c++-shared/Object1.h" + +/* This test demonstrate a failure in object_is_meta_class which was fixed */ + +@interface EvilClass : Object +{ + Class super_class; + const char* name; + long version; + unsigned long info; +} +@end + +@implementation EvilClass +- (id) init +{ + self = [super init]; + /* The following one is used in the runtime to mark meta classes */ + info = 0x2L; + return self; +} +@end + +int main (void) +{ + /* Create an object of our EvilClass */ + EvilClass *evilObject = [EvilClass new]; + + /* Now check that the object is not a meta class object */ + if (object_is_meta_class (evilObject)) + { + printf ("object_is_meta_class failed\n"); + abort (); + } + + return 0; +} +#include "../../objc-obj-c++-shared/Object1-implementation.h" diff --git a/gcc/testsuite/objc/execute/pr25328.m b/gcc/testsuite/objc/execute/pr25328.m new file mode 100644 index 000000000..7b8502353 --- /dev/null +++ b/gcc/testsuite/objc/execute/pr25328.m @@ -0,0 +1,11 @@ +/* PR objc/25328 */ + +int +main () +{ + int status = 0; + char msg[100] = ""; + if (__builtin_strcmp (msg, "")) + status = 200; + return status; +} diff --git a/gcc/testsuite/objc/execute/private.m b/gcc/testsuite/objc/execute/private.m new file mode 100644 index 000000000..5040ccec4 --- /dev/null +++ b/gcc/testsuite/objc/execute/private.m @@ -0,0 +1,32 @@ +/* Contributed by Nicola Pero - Fri Mar 9 19:39:15 CET 2001 */ +#import "../../objc-obj-c++-shared/Object1.h" +#include <objc/objc.h> + +/* Test the @private, @protected, @public keyworks for ivars. We only + check syntax. */ + +@interface TestClass : Object +{ + int a; + +@private + int ivarOne, ivarTwo; + id ivarThree; + +@protected + int ivarFour; + +@public + id ivarFive; +} +@end + +@implementation TestClass +@end + + +int main (void) +{ + /* Only test compilation */ + return 0; +} diff --git a/gcc/testsuite/objc/execute/protocol-isEqual-1.m b/gcc/testsuite/objc/execute/protocol-isEqual-1.m new file mode 100644 index 000000000..29b5c3ded --- /dev/null +++ b/gcc/testsuite/objc/execute/protocol-isEqual-1.m @@ -0,0 +1,24 @@ +/* Contributed by Nicola Pero - Fri Jun 4 03:16:17 BST 2004 */ +/* Test that a protocol is equal to itself. */ +#include "../../objc-obj-c++-shared/Protocol1.h" + +@protocol Foo +- (void)foo; +@end + +int main (void) +{ + Protocol *protocol = @protocol(Foo); + +#ifdef NEXT_OBJC_USE_NEW_INTERFACE + if ( !protocol_isEqual (protocol, protocol)) +#else + if (! [protocol isEqual: protocol]) +#endif + { + abort (); + } + + return 0; +} + diff --git a/gcc/testsuite/objc/execute/protocol-isEqual-2.m b/gcc/testsuite/objc/execute/protocol-isEqual-2.m new file mode 100644 index 000000000..70ab8ccdd --- /dev/null +++ b/gcc/testsuite/objc/execute/protocol-isEqual-2.m @@ -0,0 +1,27 @@ +/* Contributed by Nicola Pero - Fri Jun 4 03:16:17 BST 2004 */ +/* Test that protocols with different names are different. */ + +#include "../../objc-obj-c++-shared/Protocol1.h" + +@protocol Foo1 +- (void)foo1; +@end + +@protocol Foo2 +- (void)foo2; +@end + +int main (void) +{ +#ifdef NEXT_OBJC_USE_NEW_INTERFACE + if (protocol_isEqual (@protocol(Foo1), @protocol(Foo2))) +#else + if ([@protocol(Foo1) isEqual: @protocol(Foo2)]) +#endif + { + abort (); + } + + return 0; +} + diff --git a/gcc/testsuite/objc/execute/protocol-isEqual-3.m b/gcc/testsuite/objc/execute/protocol-isEqual-3.m new file mode 100644 index 000000000..238638294 --- /dev/null +++ b/gcc/testsuite/objc/execute/protocol-isEqual-3.m @@ -0,0 +1,23 @@ +/* Contributed by Nicola Pero - Fri Jun 4 03:16:17 BST 2004 */ +/* Test that a protocol is not equal to nil. */ + +#include "../../objc-obj-c++-shared/Protocol1.h" + +@protocol Foo +- (void)foo; +@end + +int main (void) +{ +#ifdef NEXT_OBJC_USE_NEW_INTERFACE + if (protocol_isEqual (@protocol(Foo), nil)) +#else + if ([@protocol(Foo) isEqual: nil]) +#endif + { + abort (); + } + + return 0; +} + diff --git a/gcc/testsuite/objc/execute/protocol-isEqual-4.m b/gcc/testsuite/objc/execute/protocol-isEqual-4.m new file mode 100644 index 000000000..4d5af640e --- /dev/null +++ b/gcc/testsuite/objc/execute/protocol-isEqual-4.m @@ -0,0 +1,24 @@ +/* Contributed by David Ayers - Fri Jun 4 03:16:17 BST 2004 */ +/* Test that a protocol is not equal to something which is not a protocol. */ + +#include "../../objc-obj-c++-shared/Protocol1.h" + +@protocol Foo +- (void)foo; +@end + +int main (void) +{ + /* A Protocol object should not be equal to a Class object. */ +#ifdef NEXT_OBJC_USE_NEW_INTERFACE + if (protocol_isEqual (@protocol(Foo), objc_getClass("Protocol"))) +#else + if ([@protocol(Foo) isEqual: [Protocol class]]) +#endif + { + abort (); + } + + return 0; +} + diff --git a/gcc/testsuite/objc/execute/protocol.m b/gcc/testsuite/objc/execute/protocol.m new file mode 100644 index 000000000..539fc2994 --- /dev/null +++ b/gcc/testsuite/objc/execute/protocol.m @@ -0,0 +1,21 @@ +@protocol Foo +- (void)foo; +@end + +@interface Foo_c <Foo> +{ +} +- (void)foo; +@end + +@implementation Foo_c +- (void)foo +{ +} +@end + +int main (void) +{ + return 0; +} + diff --git a/gcc/testsuite/objc/execute/redefining_self.m b/gcc/testsuite/objc/execute/redefining_self.m new file mode 100644 index 000000000..ddb2eb2e3 --- /dev/null +++ b/gcc/testsuite/objc/execute/redefining_self.m @@ -0,0 +1,34 @@ +/* Contributed by Nicola Pero - Fri Mar 9 19:39:15 CET 2001 */ +#include <objc/objc.h> + +/* Test redefining self */ + +@interface TestClass +{ + Class isa; +} ++ (Class) class; +@end + +@implementation TestClass ++ (Class) class +{ + self = Nil; + + return self; +} +#ifdef __NEXT_RUNTIME__ ++ initialize { return self; } +#endif +@end + + +int main (void) +{ + if ([TestClass class] != Nil) + { + abort (); + } + + return 0; +} diff --git a/gcc/testsuite/objc/execute/root_methods.m b/gcc/testsuite/objc/execute/root_methods.m new file mode 100644 index 000000000..d9085ae7b --- /dev/null +++ b/gcc/testsuite/objc/execute/root_methods.m @@ -0,0 +1,47 @@ +/* Contributed by Nicola Pero - Thu Mar 8 16:27:46 CET 2001 */ + +#import "../../objc-obj-c++-shared/next-mapping.h" +#import <objc/objc.h> + +/* Test that instance methods of root classes are available as class + methods to other classes as well */ + +@interface RootClass +{ + Class isa; +} +- (id) self; +@end + +@implementation RootClass +- (id) self +{ + return self; +} +#ifdef __NEXT_RUNTIME__ ++ initialize { return self; } +#endif +@end + +@interface NormalClass : RootClass +@end + +@implementation NormalClass : RootClass +@end + +int main (void) +{ + Class normal = objc_get_class ("NormalClass"); + + if (normal == Nil) + { + abort (); + } + + if ([NormalClass self] != normal) + { + abort (); + } + + return 0; +} diff --git a/gcc/testsuite/objc/execute/selector-1.m b/gcc/testsuite/objc/execute/selector-1.m new file mode 100644 index 000000000..531e02bab --- /dev/null +++ b/gcc/testsuite/objc/execute/selector-1.m @@ -0,0 +1,21 @@ +/* Contributed by Nicola Pero - Thu Mar 8 16:27:46 CET 2001 */ +#include <objc/objc.h> +#include <objc/objc-api.h> +#include <objc/Object.h> + +int main (void) +{ + SEL selector; + char *selname; + + selector = @selector (alloc); +#ifdef __NEXT_RUNTIME__ + selname = sel_getName (selector); +#else + selname = sel_get_name (selector); +#endif + if (strcmp (selname, "alloc")) + abort (); + + return 0; +} diff --git a/gcc/testsuite/objc/execute/static-1.m b/gcc/testsuite/objc/execute/static-1.m new file mode 100644 index 000000000..a778b722c --- /dev/null +++ b/gcc/testsuite/objc/execute/static-1.m @@ -0,0 +1,37 @@ +/* Contributed by Nicola Pero - Fri Mar 9 19:39:15 CET 2001 */ +#include <objc/objc.h> + +/* Test defining a static variable *inside* a class implementation */ + +@interface Test +{ + Class isa; +} ++ (int) test; +@end + +@implementation Test + +static int test = 1; + ++ (int) test +{ + return test; +} + +#ifdef __NEXT_RUNTIME__ ++ initialize { return self; } +#endif +@end + +int main (void) +{ + if ([Test test] != 1) + { + abort (); + } + + return 0; +} + + diff --git a/gcc/testsuite/objc/execute/static-2.m b/gcc/testsuite/objc/execute/static-2.m new file mode 100644 index 000000000..4d7e7449b --- /dev/null +++ b/gcc/testsuite/objc/execute/static-2.m @@ -0,0 +1,40 @@ +/* Contributed by Nicola Pero - Fri Mar 9 19:39:15 CET 2001 */ +#include <objc/objc.h> + +/* Test defining a static function *inside* a class implementation */ + +@interface Test +{ + Class isa; +} ++ (int) test; +@end + +@implementation Test + +static int test (void) +{ + return 1; +} + ++ (int) test +{ + return test (); +} + +#ifdef __NEXT_RUNTIME__ ++ initialize { return self; } +#endif +@end + +int main (void) +{ + if ([Test test] != 1) + { + abort (); + } + + return 0; +} + + diff --git a/gcc/testsuite/objc/execute/trivial.m b/gcc/testsuite/objc/execute/trivial.m new file mode 100644 index 000000000..0fc61dbe5 --- /dev/null +++ b/gcc/testsuite/objc/execute/trivial.m @@ -0,0 +1,9 @@ +#import "../../objc-obj-c++-shared/Object1.h" + +int main(void) +{ + [Object class]; + return 0; +} + +#import "../../objc-obj-c++-shared/Object1-implementation.h" diff --git a/gcc/testsuite/objc/execute/va_method.m b/gcc/testsuite/objc/execute/va_method.m new file mode 100644 index 000000000..51619b8d3 --- /dev/null +++ b/gcc/testsuite/objc/execute/va_method.m @@ -0,0 +1,48 @@ +/* Contributed by Nicola Pero - Thu Mar 8 16:27:46 CET 2001 */ +#include <objc/objc.h> +#include <objc/objc-api.h> +#include <stdarg.h> + +/* Test method with variable number of arguments */ + +@interface MathClass +{ + Class isa; +} +/* sum positive numbers; -1 ends the list */ ++ (int) sum: (int)firstNumber, ...; +@end + +@implementation MathClass ++ (int) sum: (int)firstNumber, ... +{ + va_list ap; + int sum = 0, number = 0; + + va_start (ap, firstNumber); + number = firstNumber; + + while (number >= 0) + { + sum += number; + number = va_arg (ap, int); + } + + va_end (ap); + + return sum; +} +#ifdef __NEXT_RUNTIME__ ++ initialize { return self; } +#endif +@end + +int main (void) +{ + if ([MathClass sum: 1, 2, 3, 4, 5, -1] != 15) + { + abort (); + } + + return 0; +} |