summaryrefslogtreecommitdiff
path: root/gcc/testsuite
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/testsuite')
-rw-r--r--gcc/testsuite/ChangeLog28
-rw-r--r--gcc/testsuite/lib/objc.exp8
-rw-r--r--gcc/testsuite/objc.dg/anon-1.m14
-rw-r--r--gcc/testsuite/objc.dg/bitfield-2.m2
-rw-r--r--gcc/testsuite/objc.dg/bitfield-3.m50
-rw-r--r--gcc/testsuite/objc.dg/bitfield-4.m29
-rw-r--r--gcc/testsuite/objc.dg/call-super-1.m76
-rw-r--r--gcc/testsuite/objc.dg/call-super-2.m139
-rw-r--r--gcc/testsuite/objc.dg/call-super-3.m54
-rw-r--r--gcc/testsuite/objc.dg/category-1.m43
-rw-r--r--gcc/testsuite/objc.dg/class-2.m5
-rw-r--r--gcc/testsuite/objc.dg/comp-types-1.m2
-rw-r--r--gcc/testsuite/objc.dg/comp-types-4.m5
-rw-r--r--gcc/testsuite/objc.dg/const-str-1.m9
-rw-r--r--gcc/testsuite/objc.dg/const-str-3.m46
-rw-r--r--gcc/testsuite/objc.dg/const-str-4.m31
-rw-r--r--gcc/testsuite/objc.dg/const-str-5.m27
-rw-r--r--gcc/testsuite/objc.dg/const-str-6.m27
-rw-r--r--gcc/testsuite/objc.dg/desig-init-1.m5
-rw-r--r--gcc/testsuite/objc.dg/encode-1.m25
-rw-r--r--gcc/testsuite/objc.dg/encode-2.m97
-rw-r--r--gcc/testsuite/objc.dg/encode-3.m66
-rw-r--r--gcc/testsuite/objc.dg/encode-4.m73
-rw-r--r--gcc/testsuite/objc.dg/func-ptr-1.m48
-rw-r--r--gcc/testsuite/objc.dg/gnu-runtime-1.m19
-rw-r--r--gcc/testsuite/objc.dg/headers.m15
-rw-r--r--gcc/testsuite/objc.dg/image-info.m38
-rw-r--r--gcc/testsuite/objc.dg/method-1.m12
-rw-r--r--gcc/testsuite/objc.dg/method-10.m32
-rw-r--r--gcc/testsuite/objc.dg/method-11.m33
-rw-r--r--gcc/testsuite/objc.dg/method-12.m25
-rw-r--r--gcc/testsuite/objc.dg/method-2.m9
-rw-r--r--gcc/testsuite/objc.dg/method-3.m45
-rw-r--r--gcc/testsuite/objc.dg/method-4.m25
-rw-r--r--gcc/testsuite/objc.dg/method-5.m18
-rw-r--r--gcc/testsuite/objc.dg/method-6.m26
-rw-r--r--gcc/testsuite/objc.dg/method-7.m27
-rw-r--r--gcc/testsuite/objc.dg/method-8.m14
-rw-r--r--gcc/testsuite/objc.dg/method-9.m43
-rw-r--r--gcc/testsuite/objc.dg/missing-proto-1.m6
-rw-r--r--gcc/testsuite/objc.dg/missing-proto-2.m5
-rw-r--r--gcc/testsuite/objc.dg/missing-proto-3.m26
-rw-r--r--gcc/testsuite/objc.dg/nested-func-1.m37
-rw-r--r--gcc/testsuite/objc.dg/proto-hier-1.m6
-rw-r--r--gcc/testsuite/objc.dg/proto-lossage-1.m7
-rw-r--r--gcc/testsuite/objc.dg/proto-lossage-2.m20
-rw-r--r--gcc/testsuite/objc.dg/proto-qual-1.m48
-rw-r--r--gcc/testsuite/objc.dg/sizeof-1.m33
-rw-r--r--gcc/testsuite/objc.dg/special/unclaimed-category-1.h5
-rw-r--r--gcc/testsuite/objc.dg/special/unclaimed-category-1.m3
-rw-r--r--gcc/testsuite/objc.dg/static-1.m33
-rw-r--r--gcc/testsuite/objc.dg/symtab-1.m24
-rw-r--r--gcc/testsuite/objc.dg/try-catch-1.m44
-rw-r--r--gcc/testsuite/objc.dg/try-catch-2.m85
-rw-r--r--gcc/testsuite/objc.dg/try-catch-3.m19
-rw-r--r--gcc/testsuite/objc.dg/try-catch-4.m26
-rw-r--r--gcc/testsuite/objc.dg/type-size-1.m17
-rw-r--r--gcc/testsuite/objc.dg/type-size-2.m58
-rw-r--r--gcc/testsuite/objc.dg/zero-link-1.m28
-rw-r--r--gcc/testsuite/objc.dg/zero-link-2.m28
-rw-r--r--gcc/testsuite/objc/execute/IMP.m2
-rw-r--r--gcc/testsuite/objc/execute/_cmd.m5
-rw-r--r--gcc/testsuite/objc/execute/bf-common.h6
-rw-r--r--gcc/testsuite/objc/execute/bycopy-3.m4
-rw-r--r--gcc/testsuite/objc/execute/cascading-1.m33
-rw-r--r--gcc/testsuite/objc/execute/class-1.m2
-rw-r--r--gcc/testsuite/objc/execute/class-10.m5
-rw-r--r--gcc/testsuite/objc/execute/class-11.m5
-rw-r--r--gcc/testsuite/objc/execute/class-12.m5
-rw-r--r--gcc/testsuite/objc/execute/class-13.m5
-rw-r--r--gcc/testsuite/objc/execute/class-14.m5
-rw-r--r--gcc/testsuite/objc/execute/class-2.m2
-rw-r--r--gcc/testsuite/objc/execute/class-3.m2
-rw-r--r--gcc/testsuite/objc/execute/class-4.m5
-rw-r--r--gcc/testsuite/objc/execute/class-5.m5
-rw-r--r--gcc/testsuite/objc/execute/class-6.m5
-rw-r--r--gcc/testsuite/objc/execute/class-7.m12
-rw-r--r--gcc/testsuite/objc/execute/class-8.m5
-rw-r--r--gcc/testsuite/objc/execute/class-9.m5
-rw-r--r--gcc/testsuite/objc/execute/class-tests-2.h2
-rw-r--r--gcc/testsuite/objc/execute/class_self-1.m3
-rw-r--r--gcc/testsuite/objc/execute/class_self-2.m6
-rw-r--r--gcc/testsuite/objc/execute/function-message-1.m33
-rw-r--r--gcc/testsuite/objc/execute/many_args_method.m3
-rw-r--r--gcc/testsuite/objc/execute/nested-3.m3
-rw-r--r--gcc/testsuite/objc/execute/next_mapping.h851
-rw-r--r--gcc/testsuite/objc/execute/np-2.m3
-rw-r--r--gcc/testsuite/objc/execute/object_is_class.m2
-rw-r--r--gcc/testsuite/objc/execute/object_is_meta_class.m2
-rw-r--r--gcc/testsuite/objc/execute/redefining_self.m3
-rw-r--r--gcc/testsuite/objc/execute/root_methods.m5
-rw-r--r--gcc/testsuite/objc/execute/static-1.m3
-rw-r--r--gcc/testsuite/objc/execute/static-2.m3
-rw-r--r--gcc/testsuite/objc/execute/string1.m5
-rw-r--r--gcc/testsuite/objc/execute/string2.m5
-rw-r--r--gcc/testsuite/objc/execute/string3.m5
-rw-r--r--gcc/testsuite/objc/execute/string4.m5
-rw-r--r--gcc/testsuite/objc/execute/va_method.m4
98 files changed, 2886 insertions, 26 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c1142f07ee3..dd4c187e043 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,31 @@
+2003-09-24 Ziemowit Laski <zlaski@apple.com>
+
+ MERGE OF objc-improvements-branch into MAINLINE:
+ * lib/objc.exp (objc_target_compile): Do not point at libobjc headers
+ if libobjc has not been built.
+ * objc/execute/IMP.m, objc/execute/_cmd.m, objc/execute/bf-common.h,
+ objc/execute/bycopy-3.m, objc/execute/class-{1-14}.m, objc/execute/class-self-2.m,
+ objc/execute/many_args_method.m, objc/execute/nested-3.m, objc/execute/np-2.m,
+ objc/execute/object_is_class.m, objc/execute/object_is_meta_class.m,
+ objc/execute/redefining_self.m, objc/execute/root_methods.m,
+ objc/execute/static-{1-2}.m, objc/execute/string-{1-4}.m, objc/execute/va_method.m,
+ objc.dg/comp-types-4.m, objc.dg/headers.m, objc.dg/special/unclaimed-category-1.h,
+ objc.dg/special/unclaimed-category-1.m: Make usable with NeXT as well as GNU runtime.
+ * execute/next_mapping.h: New header, for GNU->NeXT impedance matching.
+ * execute/cascading-1.m, execute/function-message-1.m, objc.dg/anon-1.m,
+ objc.dg/bitfield-{3-4}.m, objc.dg/call-super-{1-3}.m, objc.dg/category-1.m,
+ objc.dg/const-str-{3-6}.m, objc.dg/encode-{1-4}.m, objc.dg/func-ptr-1.m,
+ objc.dg/gnu-runtime-1.m, objc.dg/image-info.m, objc.dg/method-{3-12}.m,
+ objc.dg/missing-proto-{1-3}.m, objc.dg/nested-func-1.m, objc.dg/proto-lossage-2.m,
+ objc.dg/proto-qual-1.m, objc.dg/sizeof-1.m, objc.dg/static-1.m, objc.dg/symtab-1.m,
+ objc.dg/try-catch-{1-4}.m, objc.dg/type-size-{1-2}.m, objc.dg/zero-link-{1-2}.m:
+ New test cases.
+ * objc.dg/bitfield-2.m: Run only on Darwin.
+ * objc.dg/class-2.m, objc.dg/comp-types-1.m, objc.dg/desig-init-1.m,
+ objc.dg/method-{1-2}.m, objc.dg/proto-hier-1.m, objc.dg/proto-lossage-1.m:
+ Adjust for message wording changes.
+ * objc.dg/const-str-1.m: Fix constant string layout.
+
2003-09-24 Alexandre Oliva <aoliva@redhat.com>
* gcc.dg/cpp/Wunknown-pragmas-1.c: New test.
diff --git a/gcc/testsuite/lib/objc.exp b/gcc/testsuite/lib/objc.exp
index 9e7c445d3ce..1817c7022e8 100644
--- a/gcc/testsuite/lib/objc.exp
+++ b/gcc/testsuite/lib/objc.exp
@@ -168,13 +168,15 @@ proc objc_target_compile { source dest type options } {
set options [concat "additional_flags=$TOOL_OPTIONS" $options];
}
- # Point to the ObjC headers in libobjc.
- set objc_include_dir "${srcdir}/../../libobjc"
- lappend options "additional_flags=-I${objc_include_dir}"
+ # If we have built libobjc along with the compiler (which usually
+ # _is not_ the case on Mac OS X systems), point the test harness
+ # at it (and associated headers).
set objcpath "[get_multilibs]"
set libobjc_dir [lookfor_file ${objcpath} libobjc/.libs/libobjc.a]
if { $libobjc_dir != "" } {
+ set objc_include_dir "${srcdir}/../../libobjc"
+ lappend options "additional_flags=-I${objc_include_dir}"
set libobjc_dir [file dirname ${libobjc_dir}]
set objc_link_flags "-L${libobjc_dir}"
lappend options "additional_flags=${objc_link_flags}"
diff --git a/gcc/testsuite/objc.dg/anon-1.m b/gcc/testsuite/objc.dg/anon-1.m
new file mode 100644
index 00000000000..5f10f7d6026
--- /dev/null
+++ b/gcc/testsuite/objc.dg/anon-1.m
@@ -0,0 +1,14 @@
+/* Test for graceful handling of anonymous ivars. */
+/* { dg-do compile } */
+
+@interface Foo {
+ unsigned char : 1;
+ int e: 3;
+ signed: 2;
+ float f;
+}
+@end
+
+@implementation Foo
+@end
+
diff --git a/gcc/testsuite/objc.dg/bitfield-2.m b/gcc/testsuite/objc.dg/bitfield-2.m
index 0a401dd6afa..83b31748371 100644
--- a/gcc/testsuite/objc.dg/bitfield-2.m
+++ b/gcc/testsuite/objc.dg/bitfield-2.m
@@ -2,7 +2,7 @@
the NeXT runtime is used. */
/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
/* { dg-options "-fnext-runtime -fsigned-char" } */
-/* { dg-do run } */
+/* { dg-do run { target *-*-darwin* } } */
struct objc_object { struct objc_class *class_pointer; } *id;
diff --git a/gcc/testsuite/objc.dg/bitfield-3.m b/gcc/testsuite/objc.dg/bitfield-3.m
new file mode 100644
index 00000000000..f427a3018ad
--- /dev/null
+++ b/gcc/testsuite/objc.dg/bitfield-3.m
@@ -0,0 +1,50 @@
+/* Check if the @defs() construct preserves the correct
+ layout of bitfields. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-options "-lobjc -Wpadded" } */
+/* { dg-do run } */
+
+#include <objc/objc.h>
+#include <objc/Object.h>
+
+extern void abort(void);
+extern int strcmp(const char *str1, const char *str2);
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+enum Enum { one, two, three, four };
+
+@interface Base: Object {
+ unsigned a: 2;
+ int b: 3;
+ enum Enum c: 4;
+ unsigned d: 5;
+} /* { dg-warning "padding struct size to alignment boundary" } */
+@end
+
+@interface Derived: Base {
+ signed e: 5;
+ int f: 4;
+ enum Enum g: 3;
+} /* { dg-warning "padding struct size to alignment boundary" } */
+@end
+
+/* Note that the semicolon after @defs(...) is optional. */
+
+typedef struct { @defs(Base) } Base_t; /* { dg-warning "padding struct size to alignment boundary" } */
+typedef struct { @defs(Derived); } Derived_t; /* { dg-warning "padding struct size to alignment boundary" } */
+
+int main(void)
+{
+ CHECK_IF(sizeof(Base_t) == sizeof(Base));
+ CHECK_IF(sizeof(Derived_t) == sizeof(Derived));
+
+#ifdef __NEXT_RUNTIME__
+ CHECK_IF(!strcmp(@encode(Base), "{Base=#b2b3b4b5}"));
+ CHECK_IF(!strcmp(@encode(Derived), "{Derived=#b2b3b4b5b5b4b3}"));
+
+ CHECK_IF(!strcmp(@encode(Base_t), "{?=#b2b3b4b5}"));
+ CHECK_IF(!strcmp(@encode(Derived_t), "{?=#b2b3b4b5b5b4b3}"));
+#endif /* __NEXT_RUNTIME__ */
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/bitfield-4.m b/gcc/testsuite/objc.dg/bitfield-4.m
new file mode 100644
index 00000000000..858bac2b003
--- /dev/null
+++ b/gcc/testsuite/objc.dg/bitfield-4.m
@@ -0,0 +1,29 @@
+/* Make sure that bitfield types are printed correctly, and that ivar redeclaration
+ (@interface vs. @implementation) checks take the bitfield width into account. */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+/* { dg-do compile } */
+
+@interface Base {
+ int i;
+}
+@end
+
+@interface WithBitfields: Base {
+ void *isa;
+ unsigned a: 3;
+ signed b: 4;
+ int c: 5;
+}
+@end
+
+@implementation WithBitfields {
+ char *isa; /* { dg-error "conflicting instance variable type .char \\*isa." } */
+ /* { dg-error "previous declaration of .void \\*isa." "" { target *-*-* } 12 } */
+ unsigned a: 5; /* { dg-error "conflicting instance variable type .unsigned a: 5." } */
+ /* { dg-error "previous declaration of .unsigned a: 3." "" { target *-*-* } 13 } */
+ signed b: 4; /* This one is fine. */
+ int c: 3; /* { dg-error "conflicting instance variable type .int c: 3." } */
+ /* { dg-error "previous declaration of .int c: 5." "" { target *-*-* } 15 } */
+}
+@end
+
diff --git a/gcc/testsuite/objc.dg/call-super-1.m b/gcc/testsuite/objc.dg/call-super-1.m
new file mode 100644
index 00000000000..19e0d4900dd
--- /dev/null
+++ b/gcc/testsuite/objc.dg/call-super-1.m
@@ -0,0 +1,76 @@
+/* Check if objc_super stack variables are created correctly (and
+ not clobbered by other values). */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-options "-std=c99 -lobjc" } */
+/* { dg-do run } */
+
+#include <objc/objc.h>
+#include <objc/Object.h>
+
+extern void abort(void);
+
+#define CHECK_IF(expr) if(!(expr)) abort();
+
+typedef struct _Point {
+ float x;
+ float y;
+} Point;
+
+Point MakePoint ( float x , float y ) {
+ Point p;
+ p.x = x;
+ p.y = y;
+ return p;
+}
+
+@interface Base: Object
+- ( void ) translateOriginToPoint : ( Point ) translation ;
+@end
+
+@interface Derived : Base
+- ( void ) scrollToPoint : ( Point ) newOrigin ;
+- ( void ) translateOriginToPoint : ( Point ) translation ;
+@end
+
+int blort;
+float result;
+
+@implementation Base
+- ( void ) translateOriginToPoint : ( Point ) translation {
+ result = translation.x + translation.y;
+}
+@end
+
+@implementation Derived
+- ( void ) scrollToPoint : ( Point ) newOrigin {
+ float transDeltaX =newOrigin.x, transDeltaY =newOrigin.y ;
+ Point w;
+ if ( ! blort ) {
+ w.x = transDeltaX ; w.y = transDeltaY ;
+ [ super translateOriginToPoint : w ] ;
+ return;
+ }
+ [ super translateOriginToPoint : MakePoint ( transDeltaX , transDeltaY ) ] ;
+ return;
+}
+- (void) translateOriginToPoint : ( Point ) translation {
+ /* This should never be called. */
+ CHECK_IF(0);
+}
+@end
+
+int main(void) {
+ Derived *v = [Derived new];
+ float r0 = 1.5 + 1.5;
+ blort = 1;
+ [v scrollToPoint: MakePoint(1.5, 1.5)];
+ CHECK_IF(result == r0);
+ blort = 0;
+ [v scrollToPoint: MakePoint(1.5, 1.5)];
+ CHECK_IF(result == r0);
+ blort = 1;
+ [v scrollToPoint: MakePoint(1.5, 1.5)];
+ CHECK_IF(result == r0);
+ [v free];
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/call-super-2.m b/gcc/testsuite/objc.dg/call-super-2.m
new file mode 100644
index 00000000000..cd7db41bffe
--- /dev/null
+++ b/gcc/testsuite/objc.dg/call-super-2.m
@@ -0,0 +1,139 @@
+/* Check if casting 'self' or 'super' affects message lookup in the
+ correct way. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+#include <objc/Object.h>
+
+#ifdef __NEXT_RUNTIME__
+#define OBJC_GETCLASS objc_getClass
+#else
+#define OBJC_GETCLASS objc_get_class
+#endif
+
+@protocol Func
++ (int) class_func0;
+- (int) instance_func0;
+@end
+
+@interface Derived: Object
++ (int) class_func1;
++ (int) class_func2;
++ (int) class_func3;
++ (int) class_func4;
++ (int) class_func5;
++ (int) class_func6;
++ (int) class_func7;
+- (int) instance_func1;
+- (int) instance_func2;
+- (int) instance_func3;
+- (int) instance_func4;
+- (int) instance_func5;
+- (int) instance_func6;
+- (int) instance_func7;
+@end
+
+@interface Derived (Categ)
++ (int) categ_class_func1;
++ (int) categ_class_func2;
+- (int) categ_instance_func1;
+- (int) categ_instance_func2;
+@end
+
+@implementation Derived
++ (int) class_func1
+{
+ int i = (int)[self class_func0]; /* { dg-warning ".Derived. may not respond to .\\+class_func0." } */
+ /* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 47 } */
+ /* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 47 } */
+ /* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 47 } */
+ return i + (int)[super class_func0]; /* { dg-warning ".Object. may not respond to .\\+class_func0." } */
+}
++ (int) class_func2
+{
+ int i = [(id <Func>)self class_func0];
+ return i + [(id <Func>)super class_func0];
+}
++ (int) class_func3
+{
+ return [(Object <Func> *)super class_func0];
+}
++ (int) class_func4
+{
+ return [(Derived <Func> *)super class_func0];
+}
++ (int) class_func5
+{
+ int i = (int)[Derived class_func0]; /* { dg-warning ".Derived. may not respond to .\\+class_func0." } */
+ return i + (int)[Object class_func0]; /* { dg-warning ".Object. may not respond to .\\+class_func0." } */
+}
++ (int) class_func6
+{
+ return (int)[OBJC_GETCLASS("Object") class_func1]; /* { dg-warning ".Object. may not respond to .\\+class_func1." } */
+}
++ (int) class_func7
+{
+ return [OBJC_GETCLASS("Derived") class_func1];
+}
+- (int) instance_func1
+{
+ int i = (int)[self instance_func0]; /* { dg-warning ".Derived. may not respond to .\\-instance_func0." } */
+ return i + (int)[super instance_func0]; /* { dg-warning ".Object. may not respond to .\\-instance_func0." } */
+}
+- (int) instance_func2
+{
+ return [(id <Func>)super instance_func0];
+}
+- (int) instance_func3
+{
+ return [(Object <Func> *)super instance_func0];
+}
+- (int) instance_func4
+{
+ return [(Derived <Func> *)super instance_func0];
+}
+- (int) instance_func5
+{
+ int i = (int)[Derived instance_func1]; /* { dg-warning ".Derived. may not respond to .\\+instance_func1." } */
+ return i + (int)[Object instance_func1]; /* { dg-warning ".Object. may not respond to .\\+instance_func1." } */
+}
+- (int) instance_func6
+{
+ return (int)[OBJC_GETCLASS("Object") class_func1]; /* { dg-warning ".Object. may not respond to .\\+class_func1." } */
+}
+- (int) instance_func7
+{
+ return [OBJC_GETCLASS("Derived") class_func1];
+}
+@end
+
+@implementation Derived (Categ)
++ (int) categ_class_func1
+{
+ int i = (int)[self class_func0]; /* { dg-warning ".Derived. may not respond to .\\+class_func0." } */
+ i += [self class_func1];
+ i += [self categ_class_func2];
+ i += (int)[self categ_instance_func1]; /* { dg-warning ".Derived. may not respond to .\\+categ_instance_func1." } */
+ return i + (int)[super class_func0]; /* { dg-warning ".Object. may not respond to .\\+class_func0." } */
+}
++ (int) categ_class_func2
+{
+ int i = [(id <Func>)self class_func0];
+ return i + [(id <Func>)super class_func0];
+}
+- (int) categ_instance_func1
+{
+ int i = (int)[self instance_func0]; /* { dg-warning ".Derived. may not respond to .\\-instance_func0." } */
+ i += [(Derived <Func> *)self categ_instance_func2];
+ i += (int)[(Object <Func> *)self categ_instance_func2]; /* { dg-warning ".Object. may not respond to .\\-categ_instance_func2." } */
+ /* { dg-warning ".\\-categ_instance_func2. not implemented by protocol" "" { target *-*-* } 129 } */
+ i += (int)[(id <Func>)self categ_instance_func2]; /* { dg-warning ".\\-categ_instance_func2. not implemented by protocol" } */
+ i += [(id)self categ_instance_func2];
+ return i + (int)[super instance_func0]; /* { dg-warning ".Object. may not respond to .\\-instance_func0." } */
+}
+- (int) categ_instance_func2
+{
+ return [(id <Func>)super instance_func0];
+}
+@end
diff --git a/gcc/testsuite/objc.dg/call-super-3.m b/gcc/testsuite/objc.dg/call-super-3.m
new file mode 100644
index 00000000000..05b6233ff5f
--- /dev/null
+++ b/gcc/testsuite/objc.dg/call-super-3.m
@@ -0,0 +1,54 @@
+/* Check if sending messages to super does not interfere with sending messages
+ to classes. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do run } */
+/* { dg-options "-lobjc" } */
+
+#include <objc/Object.h>
+
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+@interface Base: Object
++ (int) class_func1;
+- (int) instance_func1;
+@end
+
+@interface Derived: Base
++ (int) class_func1;
+@end
+
+@interface Derived (Categ)
+- (int) instance_func1;
+@end
+
+@implementation Base
++ (int) class_func1 { return 234; }
+- (int) instance_func1 { return 345; }
+@end
+
+@implementation Derived
++ (int) class_func1 {
+ int i = [super class_func1];
+ i += [Base class_func1];
+ return i;
+}
+@end
+
+@implementation Derived (Categ)
+- (int) instance_func1 {
+ int i = [super instance_func1];
+ i += [Base class_func1]; /* { dg-bogus "invalid receiver type" } */
+ return i;
+}
+@end
+
+int main(void) {
+ Base *base = [[Base alloc] init]; /* { dg-bogus "invalid receiver type" } */
+ Derived *derived = [[Derived alloc] init];
+ CHECK_IF([Base class_func1] == 234); /* { dg-bogus "invalid receiver type" } */
+ CHECK_IF([Derived class_func1] == 234 + 234);
+ CHECK_IF([base instance_func1] == 345);
+ CHECK_IF([derived instance_func1] == 234 + 345);
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/category-1.m b/gcc/testsuite/objc.dg/category-1.m
new file mode 100644
index 00000000000..1d29e374aea
--- /dev/null
+++ b/gcc/testsuite/objc.dg/category-1.m
@@ -0,0 +1,43 @@
+/* Test class methods inside categories. */
+/* Author: Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-options "-lobjc" } */
+/* { dg-do run } */
+
+#include <objc/Object.h>
+
+#ifdef __NEXT_RUNTIME__
+#define SUPERCLASS superclass
+#else
+#define SUPERCLASS superClass
+#endif
+
+extern int strcmp(const char *s1, const char *s2);
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+@interface MyObject: Object
++ (Class)whatever1;
+@end
+
+@implementation MyObject
++ (Class)whatever1 { return [super SUPERCLASS]; }
+@end
+
+@interface MyObject (ThisWontCompile)
++(Class)whatever2;
+@end
+
+@implementation MyObject (ThisWontCompile)
++(Class)whatever2 { return [super SUPERCLASS]; }
+@end
+
+int main (int argc, const char * argv[])
+{
+ Class w1 = [MyObject whatever1];
+ Class w2 = [MyObject whatever2];
+
+ CHECK_IF(!strcmp(w1->name, "Object"));
+ CHECK_IF(!strcmp(w2->name, "Object"));
+ return 0;
+}
+
diff --git a/gcc/testsuite/objc.dg/class-2.m b/gcc/testsuite/objc.dg/class-2.m
index a4514f9290a..b98d117f54c 100644
--- a/gcc/testsuite/objc.dg/class-2.m
+++ b/gcc/testsuite/objc.dg/class-2.m
@@ -10,6 +10,5 @@
@interface class1 : supclass1
@end
-@implementation class1 : supclass2
-@end /* { dg-error "conflicting super class name" } */
-/* { dg-error "previous declaration" "" { target *-*-* } 14 } */
+@implementation class1 : supclass2 /* { dg-error "conflicting super class name" } */
+@end /* { dg-error "previous declaration" "" { target *-*-* } 13 } */
diff --git a/gcc/testsuite/objc.dg/comp-types-1.m b/gcc/testsuite/objc.dg/comp-types-1.m
index 74943860b2d..310b22634c0 100644
--- a/gcc/testsuite/objc.dg/comp-types-1.m
+++ b/gcc/testsuite/objc.dg/comp-types-1.m
@@ -41,7 +41,7 @@ int main()
MyProtocol), but not from an 'id' or from a 'MyOtherClass *'
(which implements MyProtocol). */
obj_p = obj; /* Ok */
- obj_p = obj_c; /* { dg-warning "does not implement" } */ /*FIXME: Duplicated*/
+ obj_p = obj_c; /* { dg-warning "does not implement" } */
obj_p = obj_cp; /* Ok */
obj_p = obj_C; /* { dg-warning "incompatible pointer type" } */
diff --git a/gcc/testsuite/objc.dg/comp-types-4.m b/gcc/testsuite/objc.dg/comp-types-4.m
index e07780485ee..f15390a38d3 100644
--- a/gcc/testsuite/objc.dg/comp-types-4.m
+++ b/gcc/testsuite/objc.dg/comp-types-4.m
@@ -3,6 +3,11 @@
/* { dg-do compile } */
#include <objc/objc.h>
+/* The NeXT runtime headers do not define NULL. */
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
@protocol MyProtocol
- (void) method;
@end
diff --git a/gcc/testsuite/objc.dg/const-str-1.m b/gcc/testsuite/objc.dg/const-str-1.m
index 145c1b31e84..e4cac2e57ec 100644
--- a/gcc/testsuite/objc.dg/const-str-1.m
+++ b/gcc/testsuite/objc.dg/const-str-1.m
@@ -2,12 +2,21 @@
/* { dg-do compile } */
/* { dg-options "-fgnu-runtime" } */
+#ifdef __cplusplus
+extern void baz(...);
+#endif
+
void foo()
{
baz(@"hiya"); /* { dg-error "annot find interface declaration" } */
}
@interface NXConstantString
+{
+ void *isa;
+ char *str;
+ int len;
+}
@end
void bar()
diff --git a/gcc/testsuite/objc.dg/const-str-3.m b/gcc/testsuite/objc.dg/const-str-3.m
new file mode 100644
index 00000000000..edc03ff62c7
--- /dev/null
+++ b/gcc/testsuite/objc.dg/const-str-3.m
@@ -0,0 +1,46 @@
+/* Test the -fconstant-string-class=Foo option under the NeXT
+ runtime. */
+/* Developed by Markus Hitter <mah@jump-ing.de>. */
+
+/* { dg-options "-fnext-runtime -fconstant-string-class=Foo -lobjc" } */
+/* { dg-do run { target *-*-darwin* } } */
+
+#include <stdio.h>
+#include <objc/objc.h>
+#include <objc/Object.h>
+
+@interface Foo: Object {
+ char *cString;
+ unsigned int len;
+}
+- (char *)customString;
+@end
+
+struct objc_class _FooClassReference;
+
+@implementation Foo : Object
+- (char *)customString {
+ return cString;
+}
+@end
+
+int main () {
+ Foo *string = @"bla";
+ Foo *string2 = @"bla";
+
+ if(string != string2)
+ abort();
+ printf("Strings are being uniqued properly\n");
+
+ /* This memcpy has to be done before the first message is sent to a
+ constant string object. Can't be moved to +initialize since _that_
+ is already a message. */
+
+ memcpy(&_FooClassReference, objc_getClass("Foo"), sizeof(_FooClassReference));
+ if (strcmp ([string customString], "bla")) {
+ abort ();
+ }
+
+ printf([@"This is a working constant string object\n" customString]);
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/const-str-4.m b/gcc/testsuite/objc.dg/const-str-4.m
new file mode 100644
index 00000000000..c178bfc4a0c
--- /dev/null
+++ b/gcc/testsuite/objc.dg/const-str-4.m
@@ -0,0 +1,31 @@
+/* Ensure that the preprocessor handles ObjC string constants gracefully. */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+/* { dg-options "-fnext-runtime -fconstant-string-class=MyString -lobjc" } */
+/* { dg-do run { target *-*-darwin* } } */
+
+extern void abort(void);
+
+@interface MyString
+{
+ void *isa;
+ char *str;
+ int len;
+}
+@end
+
+#define kMyStringMacro1 "My String"
+#define kMyStringMacro2 @"My String"
+
+void *_MyStringClassReference;
+
+@implementation MyString
+@end
+
+int main(void) {
+ MyString* aString1 = @kMyStringMacro1;
+ MyString* aString2 = kMyStringMacro2;
+ if(aString1 != aString2) {
+ abort();
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/const-str-5.m b/gcc/testsuite/objc.dg/const-str-5.m
new file mode 100644
index 00000000000..186edcfceb2
--- /dev/null
+++ b/gcc/testsuite/objc.dg/const-str-5.m
@@ -0,0 +1,27 @@
+/* Positive test case for constant string layout. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+
+/* { dg-options "-fconstant-string-class=MyConstantString" } */
+/* { dg-do compile } */
+
+@interface MyBase {
+ const char *p;
+}
+@end
+
+@interface MyConstantString: MyBase {
+ union {
+ void *u;
+ unsigned char *c;
+ } _contents;
+ unsigned int _count;
+}
+@end
+
+/* The NeXT runtime initializes the 'isa' pointer of string constants at
+ compile time. */
+#ifdef __NEXT_RUNTIME__
+extern void *_MyConstantStringClassReference;
+#endif
+
+MyConstantString *str = @"Hello";
diff --git a/gcc/testsuite/objc.dg/const-str-6.m b/gcc/testsuite/objc.dg/const-str-6.m
new file mode 100644
index 00000000000..a7cbbf7141a
--- /dev/null
+++ b/gcc/testsuite/objc.dg/const-str-6.m
@@ -0,0 +1,27 @@
+/* Negative test case for constant string layout. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+
+/* { dg-options "-fconstant-string-class=MyConstantString" } */
+/* { dg-do compile } */
+
+@interface MyBase {
+ char p;
+}
+@end
+
+@interface MyConstantString: MyBase {
+ union {
+ void *u;
+ unsigned char *c;
+ } _contents;
+ char _count;
+}
+@end
+
+/* The NeXT runtime initializes the 'isa' pointer of string constants at
+ compile time. */
+#ifdef __NEXT_RUNTIME__
+extern void *_MyConstantStringClassReference;
+#endif
+
+MyConstantString *str = @"Hello"; /* { dg-error "interface .MyConstantString. does not have valid constant string layout" } */
diff --git a/gcc/testsuite/objc.dg/desig-init-1.m b/gcc/testsuite/objc.dg/desig-init-1.m
index 72fe8330960..44abe440d7b 100644
--- a/gcc/testsuite/objc.dg/desig-init-1.m
+++ b/gcc/testsuite/objc.dg/desig-init-1.m
@@ -22,7 +22,10 @@
0,
[Cls meth1],
[2 + 1] = 3,
- [2 * 2 ... 5] = [0 meth2], /* { dg-warning "invalid receiver type" } */
+ [2 * 2 ... 5] = (int)[0 meth2], /* { dg-warning "invalid receiver type" } */
+ /* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 25 } */
+ /* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 25 } */
+ /* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 25 } */
[2] [Cls meth2]
};
diff --git a/gcc/testsuite/objc.dg/encode-1.m b/gcc/testsuite/objc.dg/encode-1.m
new file mode 100644
index 00000000000..868c3254753
--- /dev/null
+++ b/gcc/testsuite/objc.dg/encode-1.m
@@ -0,0 +1,25 @@
+/* Test if the Objective-C @encode machinery distinguishes between
+ 'BOOL *' (which should be encoded as a pointer to BOOL) and 'char *' (which
+ should be encoded as '*'). This is somewhat tricky wrt the NeXT runtime,
+ where we have 'typedef char BOOL'. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-options "-fnext-runtime -lobjc" } */
+/* { dg-do run } */
+
+#include <string.h>
+#include <stdlib.h>
+#include <objc/objc.h>
+
+int main(void) {
+ const char *BOOL_ptr = @encode(BOOL *);
+ const char *BOOL_ = @encode(BOOL);
+ const char *char_ptr = @encode(char *);
+
+ if(*BOOL_ptr != '^' || strcmp(BOOL_ptr + 1, BOOL_))
+ abort();
+
+ if(strcmp(char_ptr, "*"))
+ abort();
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/encode-2.m b/gcc/testsuite/objc.dg/encode-2.m
new file mode 100644
index 00000000000..ebfd8d3fa2d
--- /dev/null
+++ b/gcc/testsuite/objc.dg/encode-2.m
@@ -0,0 +1,97 @@
+/* Test Objective-C method encodings. */
+
+/* The _encoded_ parameter offsets for Objective-C methods are
+ computed inductively as follows:
+ - The first paramter (self) has offset 0;
+ - The k-th parameter (k > 1) has offset equal to the
+ sum of:
+ - the offset of the k-1-st paramter
+ - the int-promoted size of the k-1-st parameter.
+
+ Note that the encoded offsets need not correspond
+ to the actual placement of parameters (relative to 'self')
+ on the stack! Your target's ABI may have very different
+ opinions on the matter. */
+
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do run } */
+
+#include <objc/objc.h>
+#include <objc/Object.h>
+
+#ifdef __NEXT_RUNTIME__
+#define METHOD Method
+#define OBJC_GETCLASS objc_getClass
+#define CLASS_GETINSTANCEMETHOD class_getInstanceMethod
+#else
+#include <objc/objc-api.h>
+#define METHOD Method_t
+#define OBJC_GETCLASS objc_get_class
+#define CLASS_GETINSTANCEMETHOD class_get_instance_method
+#endif
+
+extern int sscanf(const char *str, const char *format, ...);
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+@interface Foo: Object
+typedef struct { float x, y; } XXPoint;
+typedef struct { float width, height; } XXSize;
+typedef struct _XXRect { XXPoint origin; XXSize size; } XXRect;
+-(id)setRect:(XXRect)r withInt:(int)i;
+-(void) char:(char)c float:(float)f double:(double)d long:(long)l;
+@end
+
+XXRect my_rect;
+unsigned offs1, offs2, offs3, offs4, offs5, offs6, offs7;
+
+@implementation Foo
+-(id)setRect:(XXRect)r withInt:(int)i {
+ unsigned offs = sizeof(self);
+ CHECK_IF(offs == offs3);
+ offs += sizeof(_cmd);
+ CHECK_IF(offs == offs4);
+ offs += sizeof(r);
+ CHECK_IF(offs == offs5);
+ offs += sizeof(i);
+ CHECK_IF(offs == offs1);
+ return nil;
+}
+-(void) char:(char)c float:(float)f double:(double)d long:(long)l {
+ unsigned offs = sizeof(self);
+ CHECK_IF(offs == offs3);
+ offs += sizeof(_cmd);
+ CHECK_IF(offs == offs4);
+ offs += sizeof((int)c);
+ CHECK_IF(offs == offs5);
+ offs += sizeof(f);
+ CHECK_IF(offs == offs6);
+ offs += sizeof(d);
+ CHECK_IF(offs == offs7);
+ offs += sizeof(l);
+ CHECK_IF(offs == offs1);
+}
+@end
+
+
+int main(void) {
+ Foo *foo = [[Foo alloc] init];
+ Class fooClass = OBJC_GETCLASS("Foo");
+ METHOD meth;
+
+ meth = CLASS_GETINSTANCEMETHOD(fooClass, @selector(setRect:withInt:));
+ offs2 = 9999;
+ sscanf(meth->method_types, "@%u@%u:%u{_XXRect={?=ff}{?=ff}}%ui%u", &offs1, &offs2, &offs3,
+ &offs4, &offs5);
+ CHECK_IF(!offs2);
+ [foo setRect:my_rect withInt:123];
+
+ meth = CLASS_GETINSTANCEMETHOD(fooClass, @selector(char:float:double:long:));
+ offs2 = 9999;
+ sscanf(meth->method_types, "v%u@%u:%uc%uf%ud%ul%u", &offs1, &offs2, &offs3,
+ &offs4, &offs5, &offs6, &offs7);
+ CHECK_IF(!offs2);
+ [foo char:'c' float:2.3 double:3.5 long:2345L];
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/encode-3.m b/gcc/testsuite/objc.dg/encode-3.m
new file mode 100644
index 00000000000..b30b956b157
--- /dev/null
+++ b/gcc/testsuite/objc.dg/encode-3.m
@@ -0,0 +1,66 @@
+/* Method encoding tests for stand-alone @protocol declarations. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do run } */
+
+#include <objc/Protocol.h>
+#ifdef __cplusplus
+#define ProtoBool bool
+#else
+#define ProtoBool _Bool
+#endif
+
+#ifndef __NEXT_RUNTIME__
+#include <objc/objc-api.h>
+#endif
+
+extern int sscanf(const char *str, const char *format, ...);
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+enum Enum {
+ zero, one, two, three
+};
+typedef enum Enum Enum;
+typedef signed char ObjCBool; /* as used by the NeXT runtime */
+
+@protocol Proto
+union __XXAngle { unsigned int alpha, beta; };
+typedef struct { float x, y; union __XXAngle a; } XXPoint;
+typedef struct { double width, height; } XXSize;
+typedef struct _XXRect { XXPoint origin; XXSize size; struct _XXRect *next; } XXRect;
+- (void) char:(char)c float:(float)f double:(double)d unsigned:(unsigned)u short:(short)s long:(long)l;
+- (void *)setRect:(XXRect)r withBool:(ProtoBool)b withInt:(int)i;
++ (Enum *)getEnum:(XXPoint *)pt enum:(enum Enum)e bool:(ObjCBool)b;
++ (ProtoBool **)getBool:(ObjCBool **)b;
+@end
+
+Protocol *proto = @protocol(Proto);
+struct objc_method_description *meth;
+unsigned totsize, offs0, offs1, offs2, offs3, offs4, offs5, offs6, offs7;
+
+static void scan_initial(const char *pattern) {
+ totsize = offs0 = offs1 = offs2 = offs3 = offs4 = offs5 = offs6 = offs7 = (unsigned)-1;
+ sscanf(meth->types, pattern, &totsize, &offs0, &offs1, &offs2, &offs3,
+ &offs4, &offs5, &offs6, &offs7);
+ CHECK_IF(!offs0 && offs1 == sizeof(id) && offs2 == offs1 + sizeof(SEL) && totsize >= offs2);
+}
+
+int main(void) {
+ meth = [proto descriptionForInstanceMethod: @selector(char:float:double:unsigned:short:long:)];
+ scan_initial("v%u@%u:%uc%uf%ud%uI%us%ul%u");
+ CHECK_IF(offs3 == offs2 + sizeof(int) && offs4 == offs3 + sizeof(float));
+ CHECK_IF(offs5 == offs4 + sizeof(double) && offs6 == offs5 + sizeof(unsigned));
+ CHECK_IF(offs7 == offs6 + sizeof(int) && totsize == offs7 + sizeof(long));
+ meth = [proto descriptionForInstanceMethod: @selector(setRect:withBool:withInt:)];
+ scan_initial("^v%u@%u:%u{_XXRect={?=ff(__XXAngle=II)}{?=dd}^{_XXRect}}%uB%ui%u");
+ CHECK_IF(offs3 == offs2 + sizeof(XXRect) && offs4 == offs3 + sizeof(int));
+ CHECK_IF(totsize == offs4 + sizeof(int));
+ meth = [proto descriptionForClassMethod: @selector(getEnum:enum:bool:)];
+ scan_initial("^i%u@%u:%u^{?=ff(__XXAngle=II)}%ui%uc%u");
+ CHECK_IF(offs3 == offs2 + sizeof(XXPoint *) && offs4 == offs3 + sizeof(enum Enum));
+ CHECK_IF(totsize == offs4 + sizeof(int)); /* 'ObjCBool' is really 'char' */
+ meth = [proto descriptionForClassMethod: @selector(getBool:)];
+ scan_initial("^^B%u@%u:%u^*%u");
+ CHECK_IF(totsize == offs2 + sizeof(ObjCBool **));
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/encode-4.m b/gcc/testsuite/objc.dg/encode-4.m
new file mode 100644
index 00000000000..1f179e1dad5
--- /dev/null
+++ b/gcc/testsuite/objc.dg/encode-4.m
@@ -0,0 +1,73 @@
+/* Encoding tests for ObjC class layouts. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-options "-lobjc" } */
+/* { dg-do run } */
+
+#include <objc/Object.h>
+#ifdef __NEXT_RUNTIME__
+#include <objc/objc-class.h>
+#define OBJC_GETCLASS objc_getClass
+#else
+#include <objc/objc-api.h>
+#define OBJC_GETCLASS objc_get_class
+#endif
+
+extern void abort(void);
+extern int strcmp(const char *s1, const char *s2);
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+@class Int1, Int2;
+struct Nested;
+
+struct Innermost {
+ unsigned char a, b;
+ struct Nested *encl;
+};
+
+struct Nested {
+ float a, b;
+ Int1 *next;
+ struct Innermost innermost;
+};
+
+@interface Int1: Object {
+ char a, b;
+ Int2 *int2;
+ struct Nested nested;
+}
+@end
+
+@interface Int2: Int1 {
+ struct Innermost *innermost;
+ Int1 *base;
+}
+@end
+
+@implementation Int1
+@end
+
+@implementation Int2
+@end
+
+struct objc_ivar *ivar;
+
+static void check_ivar(const char *name, const char *type) {
+ CHECK_IF(!strcmp(ivar->ivar_name, name));
+ CHECK_IF(!strcmp(ivar->ivar_type, type));
+ ivar++;
+}
+
+int main(void) {
+ ivar = ((Class)OBJC_GETCLASS("Int1"))->ivars->ivar_list;
+ check_ivar("a", "c");
+ check_ivar("b", "c");
+ check_ivar("int2", "@\"Int2\"");
+ check_ivar("nested",
+ "{Nested=\"a\"f\"b\"f\"next\"@\"Int1\"\"innermost\"{Innermost=\"a\"C\"b\"C\"encl\"^{Nested}}}");
+
+ ivar = ((Class)OBJC_GETCLASS("Int2"))->ivars->ivar_list;
+ check_ivar("innermost", "^{Innermost=CC^{Nested}}");
+ check_ivar("base", "@\"Int1\"");
+
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/func-ptr-1.m b/gcc/testsuite/objc.dg/func-ptr-1.m
new file mode 100644
index 00000000000..015d3ac292d
--- /dev/null
+++ b/gcc/testsuite/objc.dg/func-ptr-1.m
@@ -0,0 +1,48 @@
+/* Test for handling of function pointer ivars */
+/* { dg-do run } */
+
+#include <objc/Object.h>
+
+extern int strcmp(const char *, const char *);
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+typedef float (*floatfunc)(float, float);
+
+@interface MyObject : Object
+{
+@public
+ int (*ivar)(int, int, int);
+ floatfunc ffunc;
+}
+- init;
+@end
+
+int foo(int a, int b, int c) {
+ return a + b + c;
+}
+
+float bar(float a, float b) {
+ return a * b;
+}
+
+@implementation MyObject
+- init {
+ [super init];
+ ivar = foo;
+ ffunc = bar;
+ return self;
+}
+@end
+
+int main ()
+{
+ MyObject *obj = [[MyObject alloc] init];
+ const char *enc = @encode(MyObject);
+
+ CHECK_IF(obj->ivar(4, 5, 6) == 15);
+ CHECK_IF(obj->ffunc(34.0, 45.0) == 34.0 * 45.0);
+ CHECK_IF(!strcmp(enc, "{MyObject=#^?^?}"));
+ return(0);
+}
+
diff --git a/gcc/testsuite/objc.dg/gnu-runtime-1.m b/gcc/testsuite/objc.dg/gnu-runtime-1.m
new file mode 100644
index 00000000000..dab921554f1
--- /dev/null
+++ b/gcc/testsuite/objc.dg/gnu-runtime-1.m
@@ -0,0 +1,19 @@
+/* Test that compiling for the GNU runtime works (regardless of
+ the system runtime used). */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+/* { dg-do compile } */
+/* { dg-options "-fgnu-runtime" } */
+
+#include <objc/Object.h>
+
+@interface FooBar: Object
+- (void)boo;
+@end
+
+int main ()
+{
+ id fooBarInst = [[FooBar alloc] init];
+ [fooBarInst boo];
+ return 0;
+}
+
diff --git a/gcc/testsuite/objc.dg/headers.m b/gcc/testsuite/objc.dg/headers.m
index 5435a75deee..4c61e1e5524 100644
--- a/gcc/testsuite/objc.dg/headers.m
+++ b/gcc/testsuite/objc.dg/headers.m
@@ -3,14 +3,29 @@
// { dg-options "-Wall -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wshadow" }
// { dg-do compile }
+#ifdef __NEXT_RUNTIME__
+#include <Foundation/NSString.h>
+#else
#include <objc/NXConstStr.h>
+#endif
#include <objc/Object.h>
#include <objc/Protocol.h>
+#ifdef __NEXT_RUNTIME__
+#include <objc/objc-runtime.h>
+#else
#include <objc/encoding.h>
#include <objc/hash.h>
+#endif
+
#include <objc/objc-api.h>
+#ifndef __NEXT_RUNTIME__
#include <objc/objc-list.h>
+#endif
+
#include <objc/objc.h>
+
+#ifndef __NEXT_RUNTIME__
#include <objc/sarray.h>
#include <objc/thr.h>
#include <objc/typedstream.h>
+#endif
diff --git a/gcc/testsuite/objc.dg/image-info.m b/gcc/testsuite/objc.dg/image-info.m
new file mode 100644
index 00000000000..84e6ad8d0e2
--- /dev/null
+++ b/gcc/testsuite/objc.dg/image-info.m
@@ -0,0 +1,38 @@
+/* Check if the '-freplace-objc-classes' option causes the
+ __OBJC,__image_info section to be emitted. This is only
+ usable on MacOS X 10.3 and later. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-options "-freplace-objc-classes" } */
+/* { dg-do compile { target *-*-darwin* } } */
+
+#ifndef __NEXT_RUNTIME__
+#error Feature not currently supported by the GNU runtime
+#endif
+
+#include <objc/objc.h>
+#include <objc/Object.h>
+
+extern void abort(void);
+
+#define CHECK_IF(expr) if(!(expr)) abort();
+
+@interface Base: Object {
+@public
+ int a;
+ float b;
+ char c;
+}
+- init;
+@end
+
+@implementation Base
+- init {
+ [super init];
+ a = 123;
+ b = 1.23;
+ c = 'c';
+ return self;
+}
+@end
+
+/* { dg-final { scan-assembler "\n.data\n.section __OBJC, __image_info\n\t.align.*\nL_OBJC_IMAGE_INFO:\n\t.long\t0\n\t.long\t1\n.data\n.objc_module_info\n" } } */
diff --git a/gcc/testsuite/objc.dg/method-1.m b/gcc/testsuite/objc.dg/method-1.m
index 8b761c65a28..391ee629c70 100644
--- a/gcc/testsuite/objc.dg/method-1.m
+++ b/gcc/testsuite/objc.dg/method-1.m
@@ -3,12 +3,12 @@
@interface class1
- (int) meth1;
-- (void) meth1; /* { dg-error "duplicate declaration of instance method" } */
+- (void) meth1; /* { dg-error "duplicate declaration of method .\\-meth1." } */
@end
@interface class2
+ (void) meth1;
-+ (int) meth1; /* { dg-error "duplicate declaration of class method" } */
++ (int) meth1; /* { dg-error "duplicate declaration of method .\\+meth1." } */
@end
@interface class3
@@ -17,8 +17,7 @@
@implementation class3
- (int) meth1 { return 0; }
-- (int) meth1 { return 0; } /* { dg-error "duplicate definition of instance method" } */
-/* { dg-error "redefinition of" "" { target *-*-* } 20 } */
+- (int) meth1 { return 0; } /* { dg-error "redefinition of" } */
/* { dg-error "previously defined here" "" { target *-*-* } 19 } */
@end
@@ -28,7 +27,6 @@
@implementation class4
+ (void) meth1 {}
-+ (void) meth1 {} /* { dg-error "duplicate definition of class method" } */
-/* { dg-error "redefinition of" "" { target *-*-* } 31 } */
-/* { dg-error "previously defined here" "" { target *-*-* } 30 } */
++ (void) meth1 {} /* { dg-error "redefinition of" } */
+/* { dg-error "previously defined here" "" { target *-*-* } 29 } */
@end
diff --git a/gcc/testsuite/objc.dg/method-10.m b/gcc/testsuite/objc.dg/method-10.m
new file mode 100644
index 00000000000..5a2a1db3462
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-10.m
@@ -0,0 +1,32 @@
+/* When there is only one candidate method available, make sure the
+ compiler uses its argument/return types when constructing the
+ message sends (so that proper C/C++ argument conversions may
+ take place). */
+/* { dg-do run } */
+
+#include <objc/Object.h>
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+static double d = 4.5920234e2;
+
+@interface Foo : Object
+-(void) brokenType: (int)x floatingPoint: (double)y;
+@end
+
+
+@implementation Foo
+-(void) brokenType: (int)x floatingPoint: (double)y
+{
+ CHECK_IF(x == 459);
+ CHECK_IF(y == d);
+}
+@end
+
+int main(void)
+{
+ Foo *foo=[Foo new];
+ [foo brokenType: d floatingPoint: d];
+ return 0;
+}
+
diff --git a/gcc/testsuite/objc.dg/method-11.m b/gcc/testsuite/objc.dg/method-11.m
new file mode 100644
index 00000000000..5921292c1ba
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-11.m
@@ -0,0 +1,33 @@
+/* Ensure that we indeed cannot obtain the value of a message send
+ if the chosen method signature returns 'void'. There used to
+ exist a cheesy hack that allowed it. While at it, check that
+ the first lexically occurring method signature gets picked
+ when sending messages to 'id'. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com> */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface Object1
+- (void)initWithData:(Object1 *)data;
+@end
+
+@interface Object2
+- (id)initWithData:(Object1 *)data;
+@end
+
+@interface Object3
+- (id)initWithData:(Object2 *)data;
+@end
+
+void foo(void) {
+ id obj1, obj2 = 0;
+ obj2 = [obj1 initWithData: obj2];
+ /* { dg-warning "multiple methods named .\\-initWithData:. found" "" { target *-*-* } 25 } */
+ /* { dg-warning "using .\\-\\(void\\)initWithData:\\(Object1 \\*\\)data." "" { target *-*-* } 12 } */
+ /* { dg-warning "also found .\\-\\(id\\)initWithData:\\(Object1 \\*\\)data." "" { target *-*-* } 16 } */
+ /* { dg-warning "also found .\\-\\(id\\)initWithData:\\(Object2 \\*\\)data." "" { target *-*-* } 20 } */
+
+ /* The following error is a consequence of picking the "wrong" method signature. */
+ /* { dg-error "void value not ignored as it ought to be" "" { target *-*-* } 25 } */
+}
diff --git a/gcc/testsuite/objc.dg/method-12.m b/gcc/testsuite/objc.dg/method-12.m
new file mode 100644
index 00000000000..d6e6ce58a4f
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-12.m
@@ -0,0 +1,25 @@
+/* Contributed by Igor Seleznev <selez@mail.ru>. */
+/* This used to be broken. */
+
+#include <objc/objc-api.h>
+
+@interface A
++ (A *)currentContext;
+@end
+
+@interface B
++ (B *)currentContext;
+@end
+
+int main()
+{
+ [A currentContext]; /* { dg-bogus "multiple declarations" } */
+ return 0;
+}
+
+@implementation A
++ (A *)currentContext { return nil; }
+@end
+@implementation B
++ (B *)currentContext { return nil; }
+@end
diff --git a/gcc/testsuite/objc.dg/method-2.m b/gcc/testsuite/objc.dg/method-2.m
index b4cd4da6376..8bf211f8700 100644
--- a/gcc/testsuite/objc.dg/method-2.m
+++ b/gcc/testsuite/objc.dg/method-2.m
@@ -22,10 +22,11 @@
[self rootInstanceMethod]; /* class is searched for an instance method */
[MyIntermediate rootInstanceMethod]; /* with the same name. */
- [self instanceMethod]; /* { dg-warning "cannot find class" } */
- /* { dg-warning "defaults to id" "" { target *-*-* } 25 } */
- [MyDerived instanceMethod]; /* { dg-warning "cannot find class" } */
- /* { dg-warning "defaults to id" "" { target *-*-* } 27 } */
+ [self instanceMethod]; /* { dg-warning ".MyDerived. may not respond to .\\+instanceMethod." } */
+ /* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 25 } */
+ /* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 25 } */
+ /* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 25 } */
+ [MyDerived instanceMethod]; /* { dg-warning ".MyDerived. may not respond to .\\+instanceMethod." } */
}
@end
diff --git a/gcc/testsuite/objc.dg/method-3.m b/gcc/testsuite/objc.dg/method-3.m
new file mode 100644
index 00000000000..65031b0aa5b
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-3.m
@@ -0,0 +1,45 @@
+/* Test for sending messages to aliased classes (and instances thereof). */
+/* Author: Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-options "-lobjc" } */
+/* { dg-do run } */
+
+#include <objc/Object.h>
+
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+@interface Int1: Object
++ (int) classMeth;
+- (int) instanceMeth;
+@end
+
+@interface Int2: Object
++ (int) classMeth;
+- (int) instanceMeth;
+@end
+
+@implementation Int1
++ (int) classMeth { return 345; }
+- (int) instanceMeth { return 697; }
+@end
+
+@implementation Int2
++ (int) classMeth { return 1345; }
+- (int) instanceMeth { return 1697; }
+@end
+
+typedef Int1 Int1Typedef;
+@compatibility_alias Int1Alias Int1Typedef;
+@compatibility_alias Int2Alias Int2;
+typedef Int2Alias Int2Typedef;
+
+int main(void) {
+ Int1Alias *int1alias = [[Int1Typedef alloc] init];
+ Int2Typedef *int2typedef = [[Int2Alias alloc] init];
+
+ CHECK_IF([Int1Typedef classMeth] == 345 && [Int2Alias classMeth] == 1345);
+ CHECK_IF([int1alias instanceMeth] == 697 && [int2typedef instanceMeth] == 1697);
+ CHECK_IF([(Int2Typedef *)int1alias instanceMeth] == 697);
+ CHECK_IF([(Int1Alias *)int2typedef instanceMeth] == 1697);
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/method-4.m b/gcc/testsuite/objc.dg/method-4.m
new file mode 100644
index 00000000000..c8d092df74d
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-4.m
@@ -0,0 +1,25 @@
+/* Check if class references (generated for the NeXT runtime) are appropriately
+ folded. This test is safe to run on all targets. */
+/* Author: Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-options "-fnext-runtime" } */
+/* { dg-do compile } */
+
+#include <objc/Object.h>
+
+typedef Object ObjectTypedef1;
+typedef ObjectTypedef1 ObjectTypedef2;
+@compatibility_alias ObjectAlias1 ObjectTypedef2;
+@compatibility_alias ObjectAlias2 ObjectAlias1;
+typedef ObjectAlias2 ObjectTypedef3;
+
+void foo(void) {
+ id obj = [Object new];
+ obj = [ObjectTypedef1 new];
+ obj = [ObjectTypedef2 new];
+ obj = [ObjectTypedef3 new];
+ obj = [ObjectAlias1 new];
+ obj = [ObjectAlias2 new];
+}
+
+/* { dg-final { scan-assembler "_OBJC_CLASS_REFERENCES_0" } } */
+/* { dg-final { scan-assembler-not "_OBJC_CLASS_REFERENCES_1" } } */
diff --git a/gcc/testsuite/objc.dg/method-5.m b/gcc/testsuite/objc.dg/method-5.m
new file mode 100644
index 00000000000..e2332ea8bd7
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-5.m
@@ -0,0 +1,18 @@
+/* Check if sending messages to "underspecified" objects is handled gracefully. */
+/* Author: Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do compile } */
+
+@class UnderSpecified;
+typedef struct NotAClass {
+ int a, b;
+} NotAClass;
+
+void foo(UnderSpecified *u, NotAClass *n) {
+ [n nonexistent_method]; /* { dg-warning "invalid receiver type" } */
+ /* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 11 } */
+ /* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 11 } */
+ /* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 11 } */
+ [NotAClass nonexistent_method]; /* { dg-error ".NotAClass. is not an Objective\\-C class name or alias" } */
+ [u nonexistent_method]; /* { dg-warning ".UnderSpecified. may not respond to .\\-nonexistent_method." } */
+ [UnderSpecified nonexistent_method]; /* { dg-warning ".UnderSpecified. may not respond to .\\+nonexistent_method." } */
+}
diff --git a/gcc/testsuite/objc.dg/method-6.m b/gcc/testsuite/objc.dg/method-6.m
new file mode 100644
index 00000000000..212958b55c7
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-6.m
@@ -0,0 +1,26 @@
+/* Check that sending messages to variables of type 'Class' does not involve instance methods. */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+/* { dg-do compile } */
+
+#include <objc/Protocol.h>
+
+@interface Base
+- (unsigned)port;
+- (id)starboard;
+@end
+
+@interface Derived: Base
+- (Object *)port;
++ (Protocol *)port;
+@end
+
+id foo(void) {
+ Class receiver;
+ id p = [receiver port]; /* there should be no warnings here! */
+ p = [receiver starboard]; /* { dg-warning ".Class. may not respond to .\\+starboard." } */
+ /* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 20 } */
+ /* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 20 } */
+ /* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 20 } */
+ p = [Class port]; /* { dg-error ".Class. is not an Objective\\-C class name or alias" } */
+ return p;
+}
diff --git a/gcc/testsuite/objc.dg/method-7.m b/gcc/testsuite/objc.dg/method-7.m
new file mode 100644
index 00000000000..f84759c2169
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-7.m
@@ -0,0 +1,27 @@
+/* Check if finding multiple signatures for a method is handled gracefully. */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+/* { dg-do compile } */
+
+#include <objc/Object.h>
+
+@interface Class1
+- (void)setWindow:(Object *)wdw;
+@end
+
+@interface Class2
+- (void)setWindow:(Class1 *)window;
+@end
+
+id foo(void) {
+ Object *obj = [[Object alloc] init];
+ id obj2 = obj;
+ [obj setWindow:nil]; /* { dg-warning ".Object. may not respond to .\\-setWindow:." } */
+ /* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 18 } */
+ /* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 18 } */
+ /* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 18 } */
+ [obj2 setWindow:nil]; /* { dg-warning "multiple methods named .\\-setWindow:. found" } */
+ /* { dg-warning "using .\\-\\(void\\)setWindow:\\(Object \\*\\)wdw." "" { target *-*-* } 8 } */
+ /* { dg-warning "also found .\\-\\(void\\)setWindow:\\(Class1 \\*\\)window." "" { target *-*-* } 12 } */
+
+ return obj;
+}
diff --git a/gcc/testsuite/objc.dg/method-8.m b/gcc/testsuite/objc.dg/method-8.m
new file mode 100644
index 00000000000..4a13b7d6cbb
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-8.m
@@ -0,0 +1,14 @@
+/* Check if casting the receiver type causes method lookup to succeed. This was broken
+ in Objective-C++. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com> */
+/* { dg-do compile } */
+
+@interface A
+@end
+
+@interface B: A
+- (void)f;
+@end
+
+void g(A *p) { [(B *)p f]; }
+
diff --git a/gcc/testsuite/objc.dg/method-9.m b/gcc/testsuite/objc.dg/method-9.m
new file mode 100644
index 00000000000..ba832840062
--- /dev/null
+++ b/gcc/testsuite/objc.dg/method-9.m
@@ -0,0 +1,43 @@
+/* Check if finding multiple signatures for a method is handled gracefully
+ when method lookup succeeds (see also method-7.m). */
+/* Contributed by Ziemowit Laski <zlaski@apple.com> */
+/* { dg-do compile } */
+
+#include <objc/Object.h>
+
+@protocol MyObject
+- (id)initWithData:(Object *)data;
+@end
+
+@protocol SomeOther
+- (id)initWithData:(int)data;
+@end
+
+@protocol MyCoding
+- (id)initWithData:(id<MyObject, MyCoding>)data;
+@end
+
+@interface NTGridDataObject: Object <MyCoding>
+{
+ Object<MyCoding> *_data;
+}
++ (NTGridDataObject*)dataObject:(id<MyObject, MyCoding>)data;
+@end
+
+@implementation NTGridDataObject
+- (id)initWithData:(id<MyObject, MyCoding>)data {
+ return data;
+}
++ (NTGridDataObject*)dataObject:(id<MyObject, MyCoding>)data
+{
+ NTGridDataObject *result = [[NTGridDataObject alloc] initWithData:data];
+ /* { dg-warning "multiple methods named .\\-initWithData:. found" "" { target *-*-* } 33 } */
+ /* { dg-warning "using .\\-\\(id\\)initWithData:\\(Object \\*\\)data." "" { target *-*-* } 9 } */
+ /* { dg-warning "also found .\\-\\(id\\)initWithData:\\(id <MyObject, MyCoding>\\)data." "" { target *-*-* } 17 } */
+ /* { dg-warning "also found .\\-\\(id\\)initWithData:\\(int\\)data." "" { target *-*-* } 13 } */
+
+ /* The following warning is a consequence of picking the "wrong" method signature. */
+ /* { dg-warning "passing arg 1 of .initWithData:. from incompatible pointer type" "" { target *-*-* } 33 } */
+ return result;
+}
+@end
diff --git a/gcc/testsuite/objc.dg/missing-proto-1.m b/gcc/testsuite/objc.dg/missing-proto-1.m
new file mode 100644
index 00000000000..7132ead4bef
--- /dev/null
+++ b/gcc/testsuite/objc.dg/missing-proto-1.m
@@ -0,0 +1,6 @@
+/* Test for graceful handling of missing protocol declarations. */
+/* Author: Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do compile } */
+
+@interface Foo <Missing> /* { dg-error "cannot find protocol declaration for .Missing." } */
+@end
diff --git a/gcc/testsuite/objc.dg/missing-proto-2.m b/gcc/testsuite/objc.dg/missing-proto-2.m
new file mode 100644
index 00000000000..cb121b496e9
--- /dev/null
+++ b/gcc/testsuite/objc.dg/missing-proto-2.m
@@ -0,0 +1,5 @@
+/* Test for graceful handling of missing protocol declarations. */
+/* Author: Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do compile } */
+
+void *protRef = @protocol(Missing); /* { dg-error "cannot find protocol declaration for .Missing." } */
diff --git a/gcc/testsuite/objc.dg/missing-proto-3.m b/gcc/testsuite/objc.dg/missing-proto-3.m
new file mode 100644
index 00000000000..6c610ce35c9
--- /dev/null
+++ b/gcc/testsuite/objc.dg/missing-proto-3.m
@@ -0,0 +1,26 @@
+/* Ensure that the compiler gracefully handles missing protocol declarations.
+ In addition to not crashing :-), the compiler should properly handle
+ valid protocol references, even when they're mixed with invalid ones. */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@protocol DefinedProtocol
+- (id) missingMethod1;
+@end
+
+@interface MyClass <UndefinedProtocol, DefinedProtocol>
+/* { dg-error "cannot find protocol declaration for .UndefinedProtocol." "" { target *-*-* } 12 } */
+@end
+
+@implementation MyClass
++(Class)class
+{
+ return self;
+}
+@end
+
+/* { dg-warning "incomplete implementation of class .MyClass." "" { target *-*-* } 21 } */
+/* { dg-warning "method definition for .\\-missingMethod1. not found" "" { target *-*-* } 21 } */
+/* { dg-warning "class .MyClass. does not fully implement the .DefinedProtocol. protocol" "" { target *-*-* } 21 } */
+
diff --git a/gcc/testsuite/objc.dg/nested-func-1.m b/gcc/testsuite/objc.dg/nested-func-1.m
new file mode 100644
index 00000000000..7a182bd938e
--- /dev/null
+++ b/gcc/testsuite/objc.dg/nested-func-1.m
@@ -0,0 +1,37 @@
+/* Test basic nested C function functionality within ObjC
+ methods. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-options "-lobjc" } */
+/* { dg-do run } */
+#include <stdio.h>
+#include <objc/objc.h>
+#include <objc/Object.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.dg/proto-hier-1.m b/gcc/testsuite/objc.dg/proto-hier-1.m
index 17ea72e8db1..154e6b62d73 100644
--- a/gcc/testsuite/objc.dg/proto-hier-1.m
+++ b/gcc/testsuite/objc.dg/proto-hier-1.m
@@ -48,7 +48,9 @@ int foo(void) {
id<Booing, Fooing> stupidVar;
[stupidVar boo];
[stupidVar foo];
- [stupidVar anotherMsg]; /* { dg-warning "not implemented by protocol" } */
- /* { dg-warning "return type defaults to id" "" { target *-*-* } 51 } */
+ [stupidVar anotherMsg]; /* { dg-warning ".\-anotherMsg. not implemented by protocol" } */
+ /* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 51 } */
+ /* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 51 } */
+ /* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 51 } */
return 0;
}
diff --git a/gcc/testsuite/objc.dg/proto-lossage-1.m b/gcc/testsuite/objc.dg/proto-lossage-1.m
index d312039262c..1186f8fd9ff 100644
--- a/gcc/testsuite/objc.dg/proto-lossage-1.m
+++ b/gcc/testsuite/objc.dg/proto-lossage-1.m
@@ -35,7 +35,12 @@ typedef struct objc_object { struct objc_class *class_pointer; } *id;
return (id <NSObject>)plate1; /* { dg-bogus "does not conform" } */
}
- (int) getValue {
- int i = [plate1 someValue]; /* { dg-warning "not implemented by protocol" } */
+ int i = [plate1 someValue]; /* { dg-warning ".\\-someValue. not implemented by protocol\\(s\\)" } */
+ /* { dg-warning "\\(Messages without a matching method signature" "" { target *-*-* } 38 } */
+ /* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 38 } */
+ /* { dg-warning ".\.\.\.. as arguments\.\\)" "" { target *-*-* } 38 } */
+ /* { dg-warning "initialization makes integer from pointer without a cast" "" { target *-*-* } 38 } */
+
int j = [(id <NSObject>)plate1 someValue]; /* { dg-bogus "not implemented by protocol" } */
int k = [(id)plate1 someValue]; /* { dg-bogus "not implemented by protocol" } */
return i + j + k;
diff --git a/gcc/testsuite/objc.dg/proto-lossage-2.m b/gcc/testsuite/objc.dg/proto-lossage-2.m
new file mode 100644
index 00000000000..b3ab9681f62
--- /dev/null
+++ b/gcc/testsuite/objc.dg/proto-lossage-2.m
@@ -0,0 +1,20 @@
+/* Don't forget to look in protocols if a class (and its superclasses) do not
+ provide a suitable method. */
+/* { dg-do compile } */
+
+#include <objc/Object.h>
+
+@protocol Zot
+-(void) zot;
+@end
+
+@interface Foo : Object <Zot>
+@end
+
+int foo()
+{
+ Foo *f=nil;
+ [f zot]; /* There should be no warnings here! */
+ return 0;
+}
+
diff --git a/gcc/testsuite/objc.dg/proto-qual-1.m b/gcc/testsuite/objc.dg/proto-qual-1.m
new file mode 100644
index 00000000000..6ae12909380
--- /dev/null
+++ b/gcc/testsuite/objc.dg/proto-qual-1.m
@@ -0,0 +1,48 @@
+/* Check that protocol qualifiers are compiled and encoded properly. */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+/* { dg-options "-lobjc" } */
+/* { dg-do run } */
+
+#include <objc/Protocol.h>
+#ifndef __NEXT_RUNTIME__
+#include <objc/objc-api.h>
+#endif
+
+extern int sscanf(const char *str, const char *format, ...);
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+@protocol Retain
++ (oneway void)retainArgument:(out bycopy id)arg1 with:(in signed char **)arg2;
+- (bycopy) address:(byref inout id)location with:(out short unsigned **)arg2;
+@end
+
+@interface Foo <Retain>
++ (oneway void)retainArgument:(out bycopy id)arg with:(in signed char **)arg2;
+@end
+
+@implementation Foo
++ (oneway void)retainArgument:(out bycopy id)arg1 with:(in signed char **)arg2 { }
+- (bycopy) address:(byref inout id)location with:(out short unsigned **)arg2 { return nil; }
+@end
+
+Protocol *proto = @protocol(Retain);
+struct objc_method_description *meth;
+unsigned totsize, offs0, offs1, offs2, offs3, offs4, offs5, offs6, offs7;
+
+static void scan_initial(const char *pattern) {
+ totsize = offs0 = offs1 = offs2 = offs3 = offs4 = offs5 = offs6 = offs7 = (unsigned)-1;
+ sscanf(meth->types, pattern, &totsize, &offs0, &offs1, &offs2, &offs3,
+ &offs4, &offs5, &offs6, &offs7);
+ CHECK_IF(!offs0 && offs1 == sizeof(id) && offs2 == offs1 + sizeof(SEL) && totsize >= offs2);
+}
+
+int main(void) {
+ meth = [proto descriptionForInstanceMethod: @selector(address:with:)];
+ scan_initial("O@%u@%u:%uNR@%uo^^S%u");
+ CHECK_IF(offs3 == offs2 + sizeof(id) && totsize == offs3 + sizeof(unsigned));
+ meth = [proto descriptionForClassMethod: @selector(retainArgument:with:)];
+ scan_initial("Vv%u@%u:%uOo@%un^*%u");
+ CHECK_IF(offs3 == offs2 + sizeof(id) && totsize == offs3 + sizeof(char **));
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/sizeof-1.m b/gcc/testsuite/objc.dg/sizeof-1.m
new file mode 100644
index 00000000000..5d8def16afe
--- /dev/null
+++ b/gcc/testsuite/objc.dg/sizeof-1.m
@@ -0,0 +1,33 @@
+/* Check that the sizeof() operator works with ObjC classes and their aliases. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-options "-lobjc" } */
+/* { dg-do run } */
+
+#include <objc/objc.h>
+#include <objc/Object.h>
+
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort();
+
+@interface Foo: Object {
+ int a, b;
+ float c, d;
+}
+@end
+
+@implementation Foo
+@end
+
+typedef Object MyObject;
+typedef struct Foo Foo_type;
+
+@compatibility_alias AliasObject Object;
+
+int main(void) {
+ CHECK_IF(sizeof(Foo) > sizeof(Object) && sizeof(Object) > 0);
+ CHECK_IF(sizeof(Foo) == sizeof(Foo_type));
+ CHECK_IF(sizeof(Object) == sizeof(MyObject));
+ CHECK_IF(sizeof(Object) == sizeof(AliasObject));
+ return 0;
+}
+
diff --git a/gcc/testsuite/objc.dg/special/unclaimed-category-1.h b/gcc/testsuite/objc.dg/special/unclaimed-category-1.h
index 6c73d28fd17..52586f01521 100644
--- a/gcc/testsuite/objc.dg/special/unclaimed-category-1.h
+++ b/gcc/testsuite/objc.dg/special/unclaimed-category-1.h
@@ -2,6 +2,11 @@
#include <objc/objc.h>
#include <objc/Object.h>
+#ifdef __NEXT_RUNTIME__
+#define objc_get_class(C) objc_getClass(C)
+#define class_create_instance(C) class_createInstance(C, 0)
+#endif
+
/* Test loading unclaimed categories - categories of a class defined
separately from the class itself. */
diff --git a/gcc/testsuite/objc.dg/special/unclaimed-category-1.m b/gcc/testsuite/objc.dg/special/unclaimed-category-1.m
index 3e521e91248..8b8af5ed307 100644
--- a/gcc/testsuite/objc.dg/special/unclaimed-category-1.m
+++ b/gcc/testsuite/objc.dg/special/unclaimed-category-1.m
@@ -21,6 +21,9 @@
{
return 4;
}
+#ifdef __NEXT_RUNTIME__
++ initialize { return self; }
+#endif
@end
diff --git a/gcc/testsuite/objc.dg/static-1.m b/gcc/testsuite/objc.dg/static-1.m
new file mode 100644
index 00000000000..d6201585939
--- /dev/null
+++ b/gcc/testsuite/objc.dg/static-1.m
@@ -0,0 +1,33 @@
+/* Test out static (non-heap) allocations of ObjC class instances.
+ These should elicit errors. */
+/* Developed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do compile } */
+
+@interface Object {
+ struct objc_class *isa;
+}
+@end
+
+@compatibility_alias MyObject Object;
+
+@interface Foo: Object {
+ int a;
+ Object *b;
+ Object c; /* { dg-error "statically allocated instance of Objective-C class .Object." } */
+}
+@end
+
+@compatibility_alias MyFoo Foo;
+
+typedef Foo FooAlias1;
+typedef FooAlias1 FooAlias2;
+typedef Object ObjectAlias1;
+typedef struct Object ObjectAlias2;
+Object staticObject1; /* { dg-error "statically allocated instance of Objective-C class .Object." } */
+struct Object staticObject2; /* { dg-error "statically allocated instance of Objective-C class .Object." } */
+static ObjectAlias1 staticObject3; /* { dg-error "statically allocated instance of Objective-C class .Object." } */
+FooAlias1 staticFoo1; /* { dg-error "statically allocated instance of Objective-C class .Foo." } */
+extern FooAlias2 externFoo1; /* { dg-error "statically allocated instance of Objective-C class .Foo." } */
+static Foo staticFoo2; /* { dg-error "statically allocated instance of Objective-C class .Foo." } */
+MyObject staticMyObject1; /* { dg-error "statically allocated instance of Objective-C class .Object." } */
+MyFoo staticMyFoo1; /* { dg-error "statically allocated instance of Objective-C class .Foo." } */
diff --git a/gcc/testsuite/objc.dg/symtab-1.m b/gcc/testsuite/objc.dg/symtab-1.m
new file mode 100644
index 00000000000..44e7b5aab34
--- /dev/null
+++ b/gcc/testsuite/objc.dg/symtab-1.m
@@ -0,0 +1,24 @@
+/* Check if the objc_symtab descriptor is being laid out correctly. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-options "-fnext-runtime" } */
+/* { dg-do compile { target *-*-darwin* } } */
+
+#include <objc/Object.h>
+
+@interface Base: Object
+- (void)setValues;
+@end
+
+@interface Derived: Base
+- (void)checkValues;
+@end
+
+@implementation Base
+-(void)setValues { }
+@end
+
+@implementation Derived
+-(void)checkValues { }
+@end
+
+/* { dg-final { scan-assembler "L_OBJC_SYMBOLS:\n\t.long\t0\n\t.long\t0\n\t.short\t2\n\t.short\t0\n\t.long\tL_OBJC_CLASS_Derived\n\t.long\tL_OBJC_CLASS_Base\n" } } */
diff --git a/gcc/testsuite/objc.dg/try-catch-1.m b/gcc/testsuite/objc.dg/try-catch-1.m
new file mode 100644
index 00000000000..e40fdf85994
--- /dev/null
+++ b/gcc/testsuite/objc.dg/try-catch-1.m
@@ -0,0 +1,44 @@
+/* Test if the compiler accepts @throw / @try..@catch..@finally
+ syntax. This will only be usable on MacOS X 10.3 and later. */
+/* Developed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-options "-fobjc-exceptions" } */
+/* { dg-do compile { target *-*-darwin* } } */
+
+#include <objc/objc.h>
+#include <objc/objc-runtime.h>
+#include <objc/Object.h>
+#include <stdio.h>
+#include <setjmp.h>
+
+@interface Frob: Object
+@end
+
+@implementation Frob: Object
+@end
+
+static int exc_control = 0;
+
+int proc() {
+ if(exc_control) {
+ printf ("Throwing (%d)... ", exc_control);
+ @throw [Frob new];
+ }
+ return 1;
+}
+
+int foo()
+{
+ @try {
+ return proc();
+ }
+ @catch (Frob* ex) {
+ if(exc_control > 1) {
+ printf("Rethrowing (%d)... ", exc_control);
+ @throw;
+ }
+ return 0;
+ }
+ @finally {
+ printf("In @finally block (%d)... ", exc_control);
+ }
+}
diff --git a/gcc/testsuite/objc.dg/try-catch-2.m b/gcc/testsuite/objc.dg/try-catch-2.m
new file mode 100644
index 00000000000..fc314f3f128
--- /dev/null
+++ b/gcc/testsuite/objc.dg/try-catch-2.m
@@ -0,0 +1,85 @@
+/* Test out '@catch(id foo) {...}', which should catch
+ all uncaught exceptions. */
+/* Developed by Ziemowit Laski <zlaski@apple.com>. */
+
+/* { dg-options "-fobjc-exceptions -lobjc" } */
+/* { dg-do run { target *-*-darwin[789]* } } */
+
+#include <objc/objc.h>
+#include <objc/objc-runtime.h>
+#include <objc/Object.h>
+#include <stdio.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>
+
+extern void abort(void);
+#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);
+ }
+ @catch(Object *obj) { /* { dg-warning "Exception already handled by preceding .\\@catch\\(id\\)." } */
+ printf ("Exception caught by incorrect handler!\n");
+ CHECK_IF(0);
+ }
+}
+
+int main (void) {
+
+ test((Object *)-1);
+ return 0;
+}
diff --git a/gcc/testsuite/objc.dg/try-catch-3.m b/gcc/testsuite/objc.dg/try-catch-3.m
new file mode 100644
index 00000000000..f49362fbf31
--- /dev/null
+++ b/gcc/testsuite/objc.dg/try-catch-3.m
@@ -0,0 +1,19 @@
+/* Test if caught exception objects are accessible inside the
+ @catch block. (Yes, I managed to break this.) */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+
+/* { dg-do compile { target *-*-darwin* } } */
+/* { dg-options "-fobjc-exceptions" } */
+
+#include <objc/Object.h>
+
+const char *foo(void)
+{
+ @try {
+ return "foo";
+ }
+ @catch (Object* theException) {
+ return [theException name];
+ }
+}
+
diff --git a/gcc/testsuite/objc.dg/try-catch-4.m b/gcc/testsuite/objc.dg/try-catch-4.m
new file mode 100644
index 00000000000..54aea233fed
--- /dev/null
+++ b/gcc/testsuite/objc.dg/try-catch-4.m
@@ -0,0 +1,26 @@
+/* Check that the compiler does not incorrectly complain about
+ exceptions being caught by previous @catch blocks. */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+
+/* { dg-do compile { target *-*-darwin* } } */
+/* { dg-options "-Wall -fobjc-exceptions" } */
+
+@interface Exception
+@end
+
+@interface FooException : Exception
+@end
+
+extern void foo();
+
+void test()
+{
+ @try {
+ foo();
+ }
+ @catch (FooException* fe) {
+ }
+ @catch (Exception* e) {
+ }
+}
+
diff --git a/gcc/testsuite/objc.dg/type-size-1.m b/gcc/testsuite/objc.dg/type-size-1.m
new file mode 100644
index 00000000000..f2fdae5c382
--- /dev/null
+++ b/gcc/testsuite/objc.dg/type-size-1.m
@@ -0,0 +1,17 @@
+/* Reject ivars with an unknown size. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do compile } */
+
+struct unknownStruct;
+
+@interface ArrayTest
+{
+ short unknownSize[unknownValue]; /* { dg-error ".unknownValue. (undeclared|was not declared)" } */
+ /* { dg-error "instance variable .unknownSize. has unknown size" "" { target *-*-* } 9 } */
+ struct unknownStruct unknownObj; /* { dg-error "field .unknownObj. has incomplete type" } */
+ /* { dg-error "instance variable .unknownObj. has unknown size" "" { target *-*-* } 11 } */
+ long knownSize[3]; /* ok */
+ char zeroSize[2 - 2]; /* ok (apparently) */
+ int missingSize[]; /* { dg-error "instance variable .missingSize. has unknown size" } */
+}
+@end
diff --git a/gcc/testsuite/objc.dg/type-size-2.m b/gcc/testsuite/objc.dg/type-size-2.m
new file mode 100644
index 00000000000..446de48345a
--- /dev/null
+++ b/gcc/testsuite/objc.dg/type-size-2.m
@@ -0,0 +1,58 @@
+/* Make sure that array arguments to methods are given the size of pointers. */
+/* As in the case of ivars, arrays without size (e.g., 'int []') are
+ encoded as pointers as well. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-do run } */
+
+#include <objc/objc.h>
+#ifdef __NEXT_RUNTIME__
+#include <objc/objc-runtime.h>
+#define OBJC_GETCLASS objc_getClass
+#define CLASS_GETINSTANCEMETHOD class_getInstanceMethod
+#else
+#include <objc/objc-api.h>
+#define OBJC_GETCLASS objc_get_class
+#define CLASS_GETINSTANCEMETHOD class_get_instance_method
+#endif
+
+extern int sscanf(const char *str, const char *format, ...);
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+enum Enum { one, two, three, four };
+
+@interface ArrayTest
+- (const char *)str:(signed char [])arg1 with:(unsigned char *)arg2 and:(enum Enum[4])en;
+- (int)meth1:(int [])arg1 with:(int [0])arg2 with:(int [2])arg3;
+@end
+
+@implementation ArrayTest
+- (int)meth1:(int [])arg1 with:(int [0])arg2 with:(int [2])arg3 { return 0; }
+- (const char *)str:(signed char [])arg1 with:(unsigned char *)arg2 and:(enum Enum[4])en { return "str"; }
+@end
+
+Class cls;
+struct objc_method *meth;
+unsigned totsize, offs0, offs1, offs2, offs3, offs4, offs5, offs6, offs7;
+
+static void scan_initial(const char *pattern) {
+ totsize = offs0 = offs1 = offs2 = offs3 = offs4 = offs5 = offs6 = offs7 = (unsigned)-1;
+ sscanf(meth->method_types, pattern, &totsize, &offs0, &offs1, &offs2, &offs3,
+ &offs4, &offs5, &offs6, &offs7);
+ CHECK_IF(!offs0 && offs1 == sizeof(id) && offs2 == offs1 + sizeof(SEL) && totsize >= offs2);
+}
+
+int main(void) {
+ cls = OBJC_GETCLASS("ArrayTest");
+
+ meth = CLASS_GETINSTANCEMETHOD(cls, @selector(str:with:and:));
+ scan_initial("r*%u@%u:%u*%u*%u[4i]%u");
+ CHECK_IF(offs3 == offs2 + sizeof(signed char *) && offs4 == offs3 + sizeof(unsigned char *));
+ CHECK_IF(totsize == offs4 + sizeof(enum Enum *));
+ meth = CLASS_GETINSTANCEMETHOD(cls, @selector(meth1:with:with:));
+ scan_initial("i%u@%u:%u^i%u[0i]%u[2i]%u");
+ CHECK_IF(offs3 == offs2 + sizeof(int *) && offs4 == offs3 + sizeof(int *));
+ CHECK_IF(totsize == offs4 + sizeof(int *));
+ return 0;
+}
+
diff --git a/gcc/testsuite/objc.dg/zero-link-1.m b/gcc/testsuite/objc.dg/zero-link-1.m
new file mode 100644
index 00000000000..96fd0c290d3
--- /dev/null
+++ b/gcc/testsuite/objc.dg/zero-link-1.m
@@ -0,0 +1,28 @@
+/* Check if the '-fzero-link' flag correctly emits an objc_getClass() call. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-options "-fnext-runtime -fzero-link" } */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+#include <objc/Object.h>
+
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort();
+
+@interface Base: Object
++ (int) getValue;
+@end
+
+@implementation Base
++ (int) getValue { return 1593; }
+@end
+
+int main(void) {
+ int val = [Base getValue];
+ CHECK_IF(val == 1593);
+ return 0;
+}
+
+/* { dg-final { scan-assembler-not "_OBJC_CLASS_REFERENCES_0" } } */
+/* { dg-final { scan-assembler "objc_getClass" } } */
+
diff --git a/gcc/testsuite/objc.dg/zero-link-2.m b/gcc/testsuite/objc.dg/zero-link-2.m
new file mode 100644
index 00000000000..92b4ab11b0c
--- /dev/null
+++ b/gcc/testsuite/objc.dg/zero-link-2.m
@@ -0,0 +1,28 @@
+/* Check if the '-fno-zero-link' flag correctly _omits_ an objc_getClass() call. */
+/* Contributed by Ziemowit Laski <zlaski@apple.com>. */
+/* { dg-options "-fnext-runtime -fno-zero-link" } */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+#include <objc/Object.h>
+
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort();
+
+@interface Base: Object
++ (int) getValue;
+@end
+
+@implementation Base
++ (int) getValue { return 1593; }
+@end
+
+int main(void) {
+ int val = [Base getValue];
+ CHECK_IF(val == 1593);
+ return 0;
+}
+
+/* { dg-final { scan-assembler "_OBJC_CLASS_REFERENCES_0" } } */
+/* { dg-final { scan-assembler-not "objc_getClass" } } */
+
diff --git a/gcc/testsuite/objc/execute/IMP.m b/gcc/testsuite/objc/execute/IMP.m
index 979aebb0158..99f61933926 100644
--- a/gcc/testsuite/objc/execute/IMP.m
+++ b/gcc/testsuite/objc/execute/IMP.m
@@ -2,6 +2,8 @@
#include <objc/objc.h>
#include <objc/objc-api.h>
+#include "next_mapping.h"
+
/* Test getting and calling the IMP of a method */
@interface TestClass
diff --git a/gcc/testsuite/objc/execute/_cmd.m b/gcc/testsuite/objc/execute/_cmd.m
index 20203b51711..f2b05b6527b 100644
--- a/gcc/testsuite/objc/execute/_cmd.m
+++ b/gcc/testsuite/objc/execute/_cmd.m
@@ -2,6 +2,8 @@
#include <objc/objc.h>
#include <objc/objc-api.h>
+#include "next_mapping.h"
+
/* Test the hidden argument _cmd to method calls */
@interface TestClass
@@ -16,6 +18,9 @@
{
return sel_get_name (_cmd);
}
+#ifdef __NEXT_RUNTIME__
++ initialize { return self; }
+#endif
@end
diff --git a/gcc/testsuite/objc/execute/bf-common.h b/gcc/testsuite/objc/execute/bf-common.h
index 123a45413d0..6cf7a0696b6 100644
--- a/gcc/testsuite/objc/execute/bf-common.h
+++ b/gcc/testsuite/objc/execute/bf-common.h
@@ -1,5 +1,7 @@
+#ifndef __NEXT_RUNTIME__
#include <objc/encoding.h>
-
+#endif
+#include "next_mapping.h"
void print_ivars (Class class)
{
@@ -59,7 +61,7 @@ int main ()
@defs (MyObject);
};
int size1, size2;
- Class class = [MyObject class];
+ Class class = objc_get_class ("MyObject");
printf ("type = %s\n", @encode (struct class_vars));
print_ivars (class);
diff --git a/gcc/testsuite/objc/execute/bycopy-3.m b/gcc/testsuite/objc/execute/bycopy-3.m
index 9c7c0acbadb..60acde52b59 100644
--- a/gcc/testsuite/objc/execute/bycopy-3.m
+++ b/gcc/testsuite/objc/execute/bycopy-3.m
@@ -12,7 +12,11 @@
#include <objc/objc.h>
#include <objc/Object.h>
#include <objc/Protocol.h>
+
+#ifndef __NEXT_RUNTIME__
#include <objc/encoding.h>
+#endif
+#include "next_mapping.h"
@protocol MyProtocol
+ (bycopy id<MyProtocol>) bycopyMethod;
diff --git a/gcc/testsuite/objc/execute/cascading-1.m b/gcc/testsuite/objc/execute/cascading-1.m
new file mode 100644
index 00000000000..67988a5db2a
--- /dev/null
+++ b/gcc/testsuite/objc/execute/cascading-1.m
@@ -0,0 +1,33 @@
+#include <objc/Object.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
index a28cfc3abb8..5fd9aa8e038 100644
--- a/gcc/testsuite/objc/execute/class-1.m
+++ b/gcc/testsuite/objc/execute/class-1.m
@@ -2,6 +2,8 @@
#include <objc/objc.h>
#include <objc/objc-api.h>
+#include "next_mapping.h"
+
/* Tests creating a RootClass */
@interface RootClass
diff --git a/gcc/testsuite/objc/execute/class-10.m b/gcc/testsuite/objc/execute/class-10.m
index 3d9697c0d86..d984d62ac99 100644
--- a/gcc/testsuite/objc/execute/class-10.m
+++ b/gcc/testsuite/objc/execute/class-10.m
@@ -2,6 +2,8 @@
#include <objc/objc.h>
#include <objc/objc-api.h>
+#include "next_mapping.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 */
@@ -13,6 +15,9 @@
@end
@implementation RootClass
+#ifdef __NEXT_RUNTIME__
++ initialize { return self; }
+#endif
@end
@interface SubClass : RootClass
diff --git a/gcc/testsuite/objc/execute/class-11.m b/gcc/testsuite/objc/execute/class-11.m
index 902db2b9a33..00c488bd1b9 100644
--- a/gcc/testsuite/objc/execute/class-11.m
+++ b/gcc/testsuite/objc/execute/class-11.m
@@ -2,6 +2,8 @@
#include <objc/objc.h>
#include <objc/objc-api.h>
+#include "next_mapping.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
@@ -14,6 +16,9 @@
@end
@implementation RootClass
+#ifdef __NEXT_RUNTIME__
++ initialize { return self; }
+#endif
@end
@interface SubClass : RootClass
diff --git a/gcc/testsuite/objc/execute/class-12.m b/gcc/testsuite/objc/execute/class-12.m
index e65611df06b..fcab65b2d36 100644
--- a/gcc/testsuite/objc/execute/class-12.m
+++ b/gcc/testsuite/objc/execute/class-12.m
@@ -2,6 +2,8 @@
#include <objc/objc.h>
#include <objc/objc-api.h>
+#include "next_mapping.h"
+
/* Tests creating a root class and a subclass with a class methods */
@interface RootClass
@@ -11,6 +13,9 @@
@end
@implementation RootClass
+#ifdef __NEXT_RUNTIME__
++ initialize { return self; }
+#endif
@end
static int class_variable = 0;
diff --git a/gcc/testsuite/objc/execute/class-13.m b/gcc/testsuite/objc/execute/class-13.m
index 0d87afd9508..98cf0ccd729 100644
--- a/gcc/testsuite/objc/execute/class-13.m
+++ b/gcc/testsuite/objc/execute/class-13.m
@@ -2,6 +2,8 @@
#include <objc/objc.h>
#include <objc/objc-api.h>
+#include "next_mapping.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 */
@@ -13,6 +15,9 @@
@end
@implementation RootClass
+#ifdef __NEXT_RUNTIME__
++ initialize { return self; }
+#endif
@end
static int class_variable = 0;
diff --git a/gcc/testsuite/objc/execute/class-14.m b/gcc/testsuite/objc/execute/class-14.m
index 2827031358c..7d02c36df7a 100644
--- a/gcc/testsuite/objc/execute/class-14.m
+++ b/gcc/testsuite/objc/execute/class-14.m
@@ -2,6 +2,8 @@
#include <objc/objc.h>
#include <objc/objc-api.h>
+#include "next_mapping.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 */
@@ -13,6 +15,9 @@
@end
@implementation RootClass
+#ifdef __NEXT_RUNTIME__
++ initialize { return self; }
+#endif
@end
static int class_variable = 0;
diff --git a/gcc/testsuite/objc/execute/class-2.m b/gcc/testsuite/objc/execute/class-2.m
index cb8b47fa1a3..350a583e9b5 100644
--- a/gcc/testsuite/objc/execute/class-2.m
+++ b/gcc/testsuite/objc/execute/class-2.m
@@ -2,6 +2,8 @@
#include <objc/objc.h>
#include <objc/objc-api.h>
+#include "next_mapping.h"
+
/* Tests creating a root class and a subclass */
@interface RootClass
diff --git a/gcc/testsuite/objc/execute/class-3.m b/gcc/testsuite/objc/execute/class-3.m
index dbe68bf9037..5ce83376c46 100644
--- a/gcc/testsuite/objc/execute/class-3.m
+++ b/gcc/testsuite/objc/execute/class-3.m
@@ -2,6 +2,8 @@
#include <objc/objc.h>
#include <objc/objc-api.h>
+#include "next_mapping.h"
+
/* Tests creating a root class and a minimal subclass tree */
@interface RootClass
diff --git a/gcc/testsuite/objc/execute/class-4.m b/gcc/testsuite/objc/execute/class-4.m
index 0ae723c035b..34d414b1229 100644
--- a/gcc/testsuite/objc/execute/class-4.m
+++ b/gcc/testsuite/objc/execute/class-4.m
@@ -2,6 +2,8 @@
#include <objc/objc.h>
#include <objc/objc-api.h>
+#include "next_mapping.h"
+
/* Tests creating a root class and a subclass with an ivar and
accessor methods */
@@ -12,6 +14,9 @@
@end
@implementation RootClass
+#ifdef __NEXT_RUNTIME__
++ initialize { return self; }
+#endif
@end
@interface SubClass : RootClass
diff --git a/gcc/testsuite/objc/execute/class-5.m b/gcc/testsuite/objc/execute/class-5.m
index 5d5297f6247..e2b750ac01d 100644
--- a/gcc/testsuite/objc/execute/class-5.m
+++ b/gcc/testsuite/objc/execute/class-5.m
@@ -2,6 +2,8 @@
#include <objc/objc.h>
#include <objc/objc-api.h>
+#include "next_mapping.h"
+
/* Tests creating a root class and a subclass with an ivar and
accessor methods and a subclass overriding the superclass'
implementation */
@@ -13,6 +15,9 @@
@end
@implementation RootClass
+#ifdef __NEXT_RUNTIME__
++ initialize { return self; }
+#endif
@end
@interface SubClass : RootClass
diff --git a/gcc/testsuite/objc/execute/class-6.m b/gcc/testsuite/objc/execute/class-6.m
index f60912aa608..fb2d64b4314 100644
--- a/gcc/testsuite/objc/execute/class-6.m
+++ b/gcc/testsuite/objc/execute/class-6.m
@@ -2,6 +2,8 @@
#include <objc/objc.h>
#include <objc/objc-api.h>
+#include "next_mapping.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 */
@@ -13,6 +15,9 @@
@end
@implementation RootClass
+#ifdef __NEXT_RUNTIME__
++ initialize { return self; }
+#endif
@end
@interface SubClass : RootClass
diff --git a/gcc/testsuite/objc/execute/class-7.m b/gcc/testsuite/objc/execute/class-7.m
index 9a2fe0cff41..3fddca77065 100644
--- a/gcc/testsuite/objc/execute/class-7.m
+++ b/gcc/testsuite/objc/execute/class-7.m
@@ -2,6 +2,8 @@
#include <objc/objc.h>
#include <objc/objc-api.h>
+#include "next_mapping.h"
+
/* Tests creating a root class and a subclass with an ivar and
accessor methods; accessor methods implemented in a separate
category */
@@ -13,6 +15,9 @@
@end
@implementation RootClass
+#ifdef __NEXT_RUNTIME__
++ initialize { return self; }
+#endif
@end
@interface SubClass : RootClass
@@ -49,6 +54,13 @@ 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));
diff --git a/gcc/testsuite/objc/execute/class-8.m b/gcc/testsuite/objc/execute/class-8.m
index fa111850213..806db03687c 100644
--- a/gcc/testsuite/objc/execute/class-8.m
+++ b/gcc/testsuite/objc/execute/class-8.m
@@ -2,6 +2,8 @@
#include <objc/objc.h>
#include <objc/objc-api.h>
+#include "next_mapping.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 */
@@ -13,6 +15,9 @@
@end
@implementation RootClass
+#ifdef __NEXT_RUNTIME__
++ initialize { return self; }
+#endif
@end
@interface SubClass : RootClass
diff --git a/gcc/testsuite/objc/execute/class-9.m b/gcc/testsuite/objc/execute/class-9.m
index bb405fbc982..d32362bdd57 100644
--- a/gcc/testsuite/objc/execute/class-9.m
+++ b/gcc/testsuite/objc/execute/class-9.m
@@ -2,6 +2,8 @@
#include <objc/objc.h>
#include <objc/objc-api.h>
+#include "next_mapping.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 */
@@ -13,6 +15,9 @@
@end
@implementation RootClass
+#ifdef __NEXT_RUNTIME__
++ initialize { return self; }
+#endif
@end
@interface SubClass : RootClass
diff --git a/gcc/testsuite/objc/execute/class-tests-2.h b/gcc/testsuite/objc/execute/class-tests-2.h
index 6df91df2b6e..cc14abb4343 100644
--- a/gcc/testsuite/objc/execute/class-tests-2.h
+++ b/gcc/testsuite/objc/execute/class-tests-2.h
@@ -62,6 +62,6 @@ void test_accessor_method (TYPE_OF_OBJECT_WITH_ACCESSOR_METHOD object,
abort ();
}
}
-#endif CLASS_WITH_ACCESSOR_METHOD
+#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
index 4d4251628ea..1690f8f6bbc 100644
--- a/gcc/testsuite/objc/execute/class_self-1.m
+++ b/gcc/testsuite/objc/execute/class_self-1.m
@@ -51,6 +51,9 @@ struct d
{
return 4;
}
+#ifdef __NEXT_RUNTIME__
++ initialize { return self; }
+#endif
@end
diff --git a/gcc/testsuite/objc/execute/class_self-2.m b/gcc/testsuite/objc/execute/class_self-2.m
index e64fcf9fff4..7fa54906cce 100644
--- a/gcc/testsuite/objc/execute/class_self-2.m
+++ b/gcc/testsuite/objc/execute/class_self-2.m
@@ -32,6 +32,9 @@ struct d
return u;
}
+#ifdef __NEXT_RUNTIME__
++ initialize { return self; }
+#endif
@end
/* The second class */
@@ -54,6 +57,9 @@ struct d
}
}
+#ifdef __NEXT_RUNTIME__
++ initialize { return self; }
+#endif
@end
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 00000000000..2c8c002d9e8
--- /dev/null
+++ b/gcc/testsuite/objc/execute/function-message-1.m
@@ -0,0 +1,33 @@
+#include <objc/Object.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/many_args_method.m b/gcc/testsuite/objc/execute/many_args_method.m
index d811082cb86..6cc2e2535ed 100644
--- a/gcc/testsuite/objc/execute/many_args_method.m
+++ b/gcc/testsuite/objc/execute/many_args_method.m
@@ -30,6 +30,9 @@
{
return [self sumInteger: a withInteger: b withInteger: c];
}
+#ifdef __NEXT_RUNTIME__
++ initialize { return self; }
+#endif
@end
diff --git a/gcc/testsuite/objc/execute/nested-3.m b/gcc/testsuite/objc/execute/nested-3.m
index 94271c4e4c0..5462fd5ef7a 100644
--- a/gcc/testsuite/objc/execute/nested-3.m
+++ b/gcc/testsuite/objc/execute/nested-3.m
@@ -22,6 +22,9 @@
return test ();
}
+#ifdef __NEXT_RUNTIME__
++ initialize { return self; }
+#endif
@end
int main (void)
diff --git a/gcc/testsuite/objc/execute/next_mapping.h b/gcc/testsuite/objc/execute/next_mapping.h
new file mode 100644
index 00000000000..67c2ce34257
--- /dev/null
+++ b/gcc/testsuite/objc/execute/next_mapping.h
@@ -0,0 +1,851 @@
+/* This file "renames" various ObjC GNU runtime entry points
+ (and fakes the existence of several others)
+ if the NeXT runtime is being used. */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+
+#ifdef __NEXT_RUNTIME__
+#include <objc/objc-class.h>
+#include <ctype.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
+#define MAX(X, Y) \
+ ({ typeof (X) __x = (X), __y = (Y); \
+ (__x > __y ? __x : __y); })
+
+#undef MIN
+#define MIN(X, Y) \
+ ({ typeof (X) __x = (X), __y = (Y); \
+ (__x < __y ? __x : __y); })
+
+#undef ROUND
+#define ROUND(V, A) \
+ ({ typeof (V) __v = (V); typeof (A) __a = (A); \
+ __a * ((__v+__a - 1)/__a); })
+
+#define BITS_PER_UNIT __CHAR_BIT__
+#define STRUCTURE_SIZE_BOUNDARY (BITS_PER_UNIT * sizeof (struct{char a;}))
+
+/* 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 {
+ 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);
+
+/*
+ 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_VOID:
+ return sizeof (void);
+ 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;
+}
+
+#endif /* #ifdef __NEXT_RUNTIME__ */
diff --git a/gcc/testsuite/objc/execute/np-2.m b/gcc/testsuite/objc/execute/np-2.m
index 37cf6ddd436..85aa203ca5c 100644
--- a/gcc/testsuite/objc/execute/np-2.m
+++ b/gcc/testsuite/objc/execute/np-2.m
@@ -17,6 +17,9 @@
{
printf ("methodA\n");
}
+#ifdef __NEXT_RUNTIME__
++ initialize { return self; }
+#endif
@end
int main (void)
diff --git a/gcc/testsuite/objc/execute/object_is_class.m b/gcc/testsuite/objc/execute/object_is_class.m
index a053434fb14..87deb986497 100644
--- a/gcc/testsuite/objc/execute/object_is_class.m
+++ b/gcc/testsuite/objc/execute/object_is_class.m
@@ -3,6 +3,8 @@
#include <objc/objc-api.h>
#include <objc/Object.h>
+#include "next_mapping.h"
+
/* This test demonstrate a failure in object_is_class which was fixed */
/* Create a class whose instance variables mirror the struct used for
diff --git a/gcc/testsuite/objc/execute/object_is_meta_class.m b/gcc/testsuite/objc/execute/object_is_meta_class.m
index 90cd3a962f0..aeb129ef4e5 100644
--- a/gcc/testsuite/objc/execute/object_is_meta_class.m
+++ b/gcc/testsuite/objc/execute/object_is_meta_class.m
@@ -3,6 +3,8 @@
#include <objc/objc-api.h>
#include <objc/Object.h>
+#include "next_mapping.h"
+
/* This test demonstrate a failure in object_is_meta_class which was fixed */
@interface EvilClass : Object
diff --git a/gcc/testsuite/objc/execute/redefining_self.m b/gcc/testsuite/objc/execute/redefining_self.m
index 93659dbac8d..ddb2eb2e3d0 100644
--- a/gcc/testsuite/objc/execute/redefining_self.m
+++ b/gcc/testsuite/objc/execute/redefining_self.m
@@ -17,6 +17,9 @@
return self;
}
+#ifdef __NEXT_RUNTIME__
++ initialize { return self; }
+#endif
@end
diff --git a/gcc/testsuite/objc/execute/root_methods.m b/gcc/testsuite/objc/execute/root_methods.m
index 4f2c2fa0ee4..c18ceb07284 100644
--- a/gcc/testsuite/objc/execute/root_methods.m
+++ b/gcc/testsuite/objc/execute/root_methods.m
@@ -1,6 +1,8 @@
/* Contributed by Nicola Pero - Thu Mar 8 16:27:46 CET 2001 */
#include <objc/objc.h>
+#include "next_mapping.h"
+
/* Test that instance methods of root classes are available as class
methods to other classes as well */
@@ -16,6 +18,9 @@
{
return self;
}
+#ifdef __NEXT_RUNTIME__
++ initialize { return self; }
+#endif
@end
@interface NormalClass : RootClass
diff --git a/gcc/testsuite/objc/execute/static-1.m b/gcc/testsuite/objc/execute/static-1.m
index 761e7070271..a778b722c15 100644
--- a/gcc/testsuite/objc/execute/static-1.m
+++ b/gcc/testsuite/objc/execute/static-1.m
@@ -19,6 +19,9 @@ static int test = 1;
return test;
}
+#ifdef __NEXT_RUNTIME__
++ initialize { return self; }
+#endif
@end
int main (void)
diff --git a/gcc/testsuite/objc/execute/static-2.m b/gcc/testsuite/objc/execute/static-2.m
index 52a03a8fbd4..4d7e7449bff 100644
--- a/gcc/testsuite/objc/execute/static-2.m
+++ b/gcc/testsuite/objc/execute/static-2.m
@@ -22,6 +22,9 @@ static int test (void)
return test ();
}
+#ifdef __NEXT_RUNTIME__
++ initialize { return self; }
+#endif
@end
int main (void)
diff --git a/gcc/testsuite/objc/execute/string1.m b/gcc/testsuite/objc/execute/string1.m
index fff03c7cfa6..58a603c1f1f 100644
--- a/gcc/testsuite/objc/execute/string1.m
+++ b/gcc/testsuite/objc/execute/string1.m
@@ -2,7 +2,12 @@
#include <string.h>
#include <stdlib.h>
+
+#ifdef __NEXT_RUNTIME__
+#import <Foundation/NSString.h>
+#else
#include <objc/NXConstStr.h>
+#endif
int main(int argc, void **args)
{
diff --git a/gcc/testsuite/objc/execute/string2.m b/gcc/testsuite/objc/execute/string2.m
index 66462b3c96c..01fb85c1189 100644
--- a/gcc/testsuite/objc/execute/string2.m
+++ b/gcc/testsuite/objc/execute/string2.m
@@ -2,7 +2,12 @@
#include <string.h>
#include <stdlib.h>
+
+#ifdef __NEXT_RUNTIME__
+#import <Foundation/NSString.h>
+#else
#include <objc/NXConstStr.h>
+#endif
int main(int argc, void **args)
{
diff --git a/gcc/testsuite/objc/execute/string3.m b/gcc/testsuite/objc/execute/string3.m
index 21527dcbf15..a8d29696899 100644
--- a/gcc/testsuite/objc/execute/string3.m
+++ b/gcc/testsuite/objc/execute/string3.m
@@ -2,7 +2,12 @@
#include <string.h>
#include <stdlib.h>
+
+#ifdef __NEXT_RUNTIME__
+#import <Foundation/NSString.h>
+#else
#include <objc/NXConstStr.h>
+#endif
#define STRING "this is a string"
diff --git a/gcc/testsuite/objc/execute/string4.m b/gcc/testsuite/objc/execute/string4.m
index 54550d6f5e9..16025cbaed6 100644
--- a/gcc/testsuite/objc/execute/string4.m
+++ b/gcc/testsuite/objc/execute/string4.m
@@ -2,7 +2,12 @@
#include <string.h>
#include <stdlib.h>
+
+#ifdef __NEXT_RUNTIME__
+#import <Foundation/NSString.h>
+#else
#include <objc/NXConstStr.h>
+#endif
int main(int argc, void **args)
{
diff --git a/gcc/testsuite/objc/execute/va_method.m b/gcc/testsuite/objc/execute/va_method.m
index bcf43d272a2..51619b8d313 100644
--- a/gcc/testsuite/objc/execute/va_method.m
+++ b/gcc/testsuite/objc/execute/va_method.m
@@ -1,6 +1,7 @@
/* 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 */
@@ -31,6 +32,9 @@
return sum;
}
+#ifdef __NEXT_RUNTIME__
++ initialize { return self; }
+#endif
@end
int main (void)