===================================================================
@@ -1,3 +1,20 @@
+2011-01-12 Iain Sandoe <iains@gcc.gnu.org>
+
+ * objc-obj-c++-shared/Object1.h: Add copyright header, update
+ comments. Add a TEST_SUITE_ADDITIONS category for GNU runtime.
+ Amend NeXT version to declare a TEST_SUITE_ADDITIONS carrying the
+ methods missing from the OBJC2 Object.
+ * objc-obj-c++-shared/Object1-implementation.h: Add copyright header.
+ Amend implementation to use a TEST_SUITE_ADDITIONS category for both GNU
+ and NeXT runtimes.
+ * objc-obj-c++-shared/Object1.mm: Remove redundant header, update
+ comments.
+ * objc-obj-c++-shared/Object1.m: Likewise.
+ * objc.dg/encode-3.m: Update header use. Amend to be API2 compatible.
+ * objc.dg/proto-qual-1.m: Likewise.
+ * obj-c++.dg/proto-lossage-3.mm: Likewise.
+ * obj-c++.dg/proto-qual-1.mm: Likewise.
+
2011-01-12 Eric Botcazou <ebotcazou@adacore.com>
PR testsuite/33033
===================================================================
@@ -3,9 +3,10 @@
Problem report and original fix by richard@brainstorm.co.uk. */
/* { dg-do run } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
+/* { dg-additional-sources "../objc-obj-c++-shared/Object1.mm" } */
+
+#include "../objc-obj-c++-shared/next-mapping.h"
#include "../objc-obj-c++-shared/Protocol1.h"
-#include <objc/objc.h>
-#include <objc/Object.h>
@protocol NoInstanceMethods
+ testMethod;
===================================================================
@@ -3,12 +3,14 @@
/* { dg-do run } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
-#include "../objc-obj-c++-shared/Protocol1.h"
+
+#include <stdio.h>
+#include <stdlib.h>
#ifndef __NEXT_RUNTIME__
#include <objc/objc-api.h>
#endif
-#include <stdio.h>
-#include <stdlib.h>
+#include "../objc-obj-c++-shared/next-mapping.h"
+#include <objc/Protocol.h>
/* The encoded parameter sizes will be rounded up to match pointer alignment. */
#define ROUND(s,a) (a * ((s + a - 1) / a))
@@ -30,8 +32,11 @@
- (bycopy) address:(byref inout id)location with:(out short unsigned **)arg2 { return nil; }
@end
-Protocol *proto = @protocol(Retain);
+Protocol *proto;
struct objc_method_description *meth;
+#ifdef NEXT_OBJC_USE_NEW_INTERFACE
+struct objc_method_description meth_object;
+#endif
unsigned totsize, offs0, offs1, offs2, offs3, offs4, offs5, offs6, offs7;
static void scan_initial(const char *pattern) {
@@ -42,10 +47,23 @@ static void scan_initial(const char *pattern) {
}
int main(void) {
+ proto = @protocol(Retain);
+#ifdef NEXT_OBJC_USE_NEW_INTERFACE
+ meth_object = protocol_getMethodDescription (proto, @selector(address:with:),
+ YES, YES);
+ meth = &meth_object;
+#else
meth = [proto descriptionForInstanceMethod: @selector(address:with:)];
+#endif
scan_initial("O@%u@%u:%uNR@%uo^^S%u");
CHECK_IF(offs3 == offs2 + aligned_sizeof(id) && totsize == offs3 + aligned_sizeof(unsigned));
+#ifdef NEXT_OBJC_USE_NEW_INTERFACE
+ meth_object = protocol_getMethodDescription (proto, @selector(retainArgument:with:),
+ YES, NO);
+ meth = &meth_object;
+#else
meth = [proto descriptionForClassMethod: @selector(retainArgument:with:)];
+#endif
scan_initial("Vv%u@%u:%uOo@%un^*%u");
CHECK_IF(offs3 == offs2 + aligned_sizeof(id) && totsize == offs3 + aligned_sizeof(char **));
return 0;
===================================================================
@@ -1,11 +1,4 @@
-#import "Object1.h"
-/* This will generate the code if required - as determined by
- the headr above. It is kept like this to keep one code file
- shared between dg-xxxx tests that can ask for an extra source
- and the objc/{compile,execute}/xxx tests that have to include
- the implementation explicitly.
-
- For cases/targets that don't require the generation of the
- Object implementation, this should result in an empty object.
+/* This will generate compatibility code for the test-suite provided as a
+ category on Object.
*/
#import "Object1-implementation.h"
===================================================================
@@ -1,62 +1,169 @@
-/* This provides a minimal implementation of the Object root class.
- * It is split from the definition so that it can be placed
- * at the end of source files that require it. This reduces
- * clutter in .s and other internmediate code while debugging.
-*/
+/* Compatibility code between APIs and ABIs for the objc test suite.
+ Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+ Contributed by Iain Sandoe
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/*
+ * Implementation of a compatibility layer for the ObjC* test-suite.
+ *
+ * Four cases:
+ * GNU
+ * Uses the 'old' Object with API and ABI = 0.
+ * Compatibility methods are added.
+ * NeXT pre-Darwin9
+ * Uses the 'old' Object with API and ABI = 0.
+ * NeXT Darwin >= 9 with no implementation of ABI 2
+ * Uses API 2 and ABI 0 for m32, uses the 'old' Object'
+ * Uses API 2 for m64 but only compile tests can be expected to work.
+ * NeXT Darwin >= 9 with __OBJC2__
+ * Uses API 2 and ABI 0 for m32, uses the 'old' Object'
+ * Uses API 2 and ABI 2 - the libobjc implementation of Object is very
+ * basic, and we add a category to expand this for test-suite use.
+ */
+
#ifndef _OBJC_OBJECT1_IMPLEMENTATION_H_
#define _OBJC_OBJECT1_IMPLEMENTATION_H_
-#ifdef DO_NEXT_M64_OBJECT_IMPLEMENTATION
+
+#include "Object1.h"
+
+#ifndef __NEXT_RUNTIME__
+
+/* Save us from repeating this. */
+@implementation Object (TEST_SUITE_ADDITIONS)
++ initialize
+{
+ return self;
+}
+@end
+
+#else
+
+/* For NeXT pre-Darwin 9 or m32 we need do nothing. */
+
+# if NEXT_OBJC_ABI_VERSION >= 2
+
+/* Pick up the API=2 header. */
+# include <objc/runtime.h>
+
+# ifndef __OBJC2__
+
+/* On a Darwin system >= 9 when there is no __OBJC2__ compiler, the testcases
+ will not link. So we provide a dummy Object for this purpose. */
+
@implementation Object
-+ initialize {
- return self;
++ (Class) class
+{
+ return self;
}
-- init {
- return self;
+
+- (BOOL)isEqual: (id)anObject
+{
+ return self == anObject;
}
-+ class {
- return object_getClass(self);
+@end
+# endif /* __OBJC2__ */
+
+/* In any case, since the library does not provide a complete (enough)
+ implementation we need to provide the additions. */
+
+@implementation Object (TEST_SUITE_ADDITIONS)
+
++ initialize
+{
+ return self;
}
-+ new {
- return [[self alloc] init];
+- init
+{
+ return self;
}
-+ free {
- return nil;
+- (Class) class
+{
+ return isa;
}
-- free {
- return object_dispose(self);
++ (Class) superclass
+{
+ return class_getSuperclass(object_getClass(self));
}
-+ alloc {
- return class_createInstance(self, 0);
++ new
+{
+ return [[self alloc] init];
}
++ free
+{
+ return nil;
+}
-- class {
- return isa;
+- free
+{
+ return object_dispose(self);
}
++ alloc
+{
+ return class_createInstance (self, 0);
+}
-- superclass {
- return class_getSuperclass([self class]);
+- (Class) superclass {
+ return class_getSuperclass([self class]);
}
- (const char *) name {
- return class_getName([self class]);
+ return class_getName([self class]);
}
-(BOOL)conformsTo:(Protocol *)protocol {
- Class cls;
- for (cls = [self class]; cls; cls = [cls superclass]) {
- if (class_conformsToProtocol(cls, protocol)) return YES;
- }
- return NO;
+ Class cls;
+ for (cls = [self class]; cls; cls = [cls superclass])
+ {
+ if (class_conformsToProtocol(cls, protocol))
+ return YES;
+ }
+ return NO;
}
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int printf (const char *, ...);
+extern void abort (void);
+#ifdef __cplusplus
+}
+#endif
+
+/* This is a helper to catch cases where we need to add more functionality
+ to our test-suite category - more informative than fail with 'does not
+ respond to forward:' */
+- forward: (SEL)sel : (marg_list)args
+{
+ const char * onam = object_getClassName (self);
+ const char * snam = sel_getName (sel);
+ printf ("%s: tried to forward: %s\n", onam, snam);
+ abort ();
+}
@end
-#endif /* NEEDS_OBJECT_IMPLEMENTATION */
-#endif /* _OBJC_OBJECT1_IMPLEMENTATION_H_ */
\ No newline at end of file
+
+# endif /* NEXT_OBJC_ABI_VERSION >= 2 */
+# endif /* __NEXT_RUNTIME__ */
+#endif /* _OBJC_OBJECT1_IMPLEMENTATION_H_ */
===================================================================
@@ -1,11 +1,4 @@
-#import "Object1.h"
-/* This will generate the code if required - as determined by
- the headr above. It is kept like this to keep one code file
- shared between dg-xxxx tests that can ask for an extra source
- and the objc/{compile,execute}/xxx tests that have to include
- the implementation explicitly.
-
- For cases/targets that don't require the generation of the
- Object implementation, this should result in an empty object.
+/* This will generate compatibility code for the test-suite provided as a
+ category on Object.
*/
-#import "Object1-implementation.h"
+#include "Object1-implementation.h"
===================================================================
@@ -1,56 +1,88 @@
-/* Object definition taken from <objc/Object.h>
+/* Compatibility code between APIs and ABIs for the objc test suite.
+ Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+ Contributed by Iain Sandoe
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/*
+ * Compatibility header.
+ *
+ * Four cases:
+ * GNU
+ * Uses the 'old' Object with API and ABI = 0.
+ * Compatibility methods are added.
+ * NeXT pre-Darwin9
+ * Uses the 'old' Object with API and ABI = 0.
+ * NeXT Darwin >= 9 with no implementation of ABI 2
+ * Uses API 2 and ABI 0 for m32, uses the 'old' Object'
+ * Uses API 2 for m64 but only compile tests can be expected to work.
+ * NeXT Darwin >= 9 with __OBJC2__
+ * Uses API 2 and ABI 0 for m32, uses the 'old' Object'
+ * Uses API 2 and ABI 2 - the libobjc implementation of Object is very
+ * basic, and we add a category to expand this for test-suite use.
*/
#ifndef _OBJC_OBJECT1_H_
#define _OBJC_OBJECT1_H_
-#undef DO_NEXT_M64_OBJECT_IMPLEMENTATION
+#ifndef __NEXT_RUNTIME__
+/* Case 1 = GNU. */
+# include <objc/Object.h>
+/* NeXT requires a +initialize (or forward:) method, and it makes testcases more
+ readable if the conditional code can be reduced, so we add one to the GNU tests
+ too. This saves us from having to introduce it every time. */
+@interface Object (TEST_SUITE_ADDITIONS)
++ initialize;
+@end
-#ifndef __NEXT_RUNTIME__
-# include <objc/Object.h>
-#else
+#else /* NeXT */
+
# include "next-abi.h"
-# ifndef NEXT_OBJC_USE_NEW_INTERFACE
-/* We are on a next system, or version, that is happy to compile V0 ABI */
+# if !defined(NEXT_OBJC_ABI_VERSION) || (NEXT_OBJC_ABI_VERSION < 2)
+/* Cases 2, Case 3/m32 and 4/m32 are handled as default. */
# include <objc/Object.h>
# else
-# if (NEXT_OBJC_ABI_VERSION==0)
-/* We are on a system that has V0 ABI implementation in libobjc.dylib.
- * However, we need to use the new accessors and pretend that the
- * structures are opaque to avoid 'deprecated' warnings
- */
-# include <objc/Object.h>
-# else
-/* We are on a system that includes a V2 ABI Object in libobjc.dylib.
-*/
-# ifdef __OBJC2__
-/* ... and we have a V2 ABI compiler .. */
-# include <objc/Object.h>
-# else
-/* We can't access the Object definition in libobjc.dylib because
- * we can't yet generate OBJC2 code.
- *
- * So we'll roll our own Object - purely for the sake of compile
- * checks - the code is unlikely to run...
-*/
-# ifndef _OBJC_OBJECT_H_
-# define _OBJC_OBJECT_H_
+# include <objc/objc.h>
-#include <stdarg.h>
-#import <objc/objc-runtime.h>
-
/* This is a cut-down Object with only the methods currently required
- by the testsuite declared.
-
- For those executables that require an implementation (to link) this
- can be provided in a given test by placing:
- #include "path/to/objc-c++shared/Object1-implementation.h"
- at the end of the source for the test.
+ by the testsuite declared. The implementation is provided in
+ Object1-implementation.h
*/
-@interface Object
+/* The m64 libobjc implementation of Object provides only the 'class' and
+ isEqual: methods.
+
+ We add the others required as a test-suite category.
+
+ Please leave the unimplemented methods as comments - so that they can
+ be inserted as required by future tests. */
+
+@interface Object
{
- Class isa; /* A pointer to the instance's class structure */
+ Class isa;
}
++ (Class) class;
+- (BOOL)isEqual: (id)anObject;
+@end
+
+/* Dummy definition. */
+typedef void * marg_list;
+
+@interface Object (TEST_SUITE_ADDITIONS)
+
+ initialize;
- init;
@@ -63,16 +95,14 @@
//- copyFromZone:(void *)zone;
//- (void *)zone;
-+ class;
-//+ superclass;
+- (Class) class;
++ (Class) superclass;
//+ (const char *) name;
-- class;
-- superclass;
+//- superclass;
- (const char *) name;
//- self;
//- (unsigned int) hash;
-//-(BOOL) isEqual:anObject;
/* Testing inheritance relationships */
@@ -135,16 +165,11 @@
/* Forwarding */
-//- forward: (SEL)sel : (marg_list)args;
+- forward: (SEL)sel : (marg_list)args;
//- performv: (SEL)sel : (marg_list)args;
@end
-#define DO_NEXT_M64_OBJECT_IMPLEMENTATION
-
-# endif /* _OBJC_OBJECT_H_ */
-# endif /* __OBJC2__ */
-# endif /* ABI=0 */
-# endif /* NEXT_OBJC_USE_NEW_INTERFACE */
-# endif /* __NEXT_RUNTIME__ */
+# endif /* NeXT case 3 & 4 m64 */
+# endif /* NEXT */
#endif /* _OBJC_OBJECT1_H_ */
===================================================================
@@ -3,19 +3,15 @@
/* { dg-do run } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
-#include "../objc-obj-c++-shared/Protocol1.h"
#include <stdio.h>
#include <stdlib.h>
-#ifdef __cplusplus
-#define ProtoBool bool
-#else
-#define ProtoBool _Bool
-#endif
-
#ifndef __NEXT_RUNTIME__
-#include <objc/objc-api.h>
+# include <objc/objc-api.h>
#endif
+#include "../objc-obj-c++-shared/objc-test-suite-types.h"
+#include "../objc-obj-c++-shared/next-mapping.h"
+#include <objc/Protocol.h>
extern int sscanf(const char *str, const char *format, ...);
extern void abort(void);
@@ -38,8 +34,11 @@ typedef struct _XXRect { XXPoint origin; XXSize si
+ (ProtoBool **)getBool:(ObjCBool **)b;
@end
-Protocol *proto = @protocol(Proto);
+Protocol *proto;
struct objc_method_description *meth;
+#ifdef NEXT_OBJC_USE_NEW_INTERFACE
+struct objc_method_description meth_object;
+#endif
unsigned totsize, offs0, offs1, offs2, offs3, offs4, offs5, offs6, offs7;
static void scan_initial(const char *pattern) {
@@ -51,8 +50,14 @@ static void scan_initial(const char *pattern) {
int main(void) {
const char *string;
-
+ proto = @protocol(Proto);
+#ifdef NEXT_OBJC_USE_NEW_INTERFACE
+ meth_object = protocol_getMethodDescription (proto,
+ @selector(char:float:double:unsigned:short:long:), YES, YES);
+ meth = &meth_object;
+#else
meth = [proto descriptionForInstanceMethod: @selector(char:float:double:unsigned:short:long:)];
+#endif
if (sizeof (long) == 8)
string = "v%u@%u:%uc%uf%ud%uI%us%uq%u";
else
@@ -61,11 +66,23 @@ int main(void) {
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));
+#ifdef NEXT_OBJC_USE_NEW_INTERFACE
+ meth_object = protocol_getMethodDescription (proto,
+ @selector(setRect:withBool:withInt:), YES, YES);
+ meth = &meth_object;
+#else
meth = [proto descriptionForInstanceMethod: @selector(setRect:withBool:withInt:)];
+#endif
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));
+#ifdef NEXT_OBJC_USE_NEW_INTERFACE
+ meth_object = protocol_getMethodDescription (proto,
+ @selector(getEnum:enum:bool:), YES, NO);
+ meth = &meth_object;
+#else
meth = [proto descriptionForClassMethod: @selector(getEnum:enum:bool:)];
+#endif
/* Here we have the complication that 'enum Enum' could be encoded
as 'i' on __NEXT_RUNTIME_, and (most likely) as 'I' on the GNU
@@ -83,7 +100,13 @@ int main(void) {
CHECK_IF(offs3 == offs2 + sizeof(XXPoint *) && offs4 == offs3 + sizeof(enum Enum));
CHECK_IF(totsize == offs4 + sizeof(int)); /* 'ObjCBool' is really 'char' */
+#ifdef NEXT_OBJC_USE_NEW_INTERFACE
+ meth_object = protocol_getMethodDescription (proto,
+ @selector(getBool:), YES, NO);
+ meth = &meth_object;
+#else
meth = [proto descriptionForClassMethod: @selector(getBool:)];
+#endif
scan_initial("^^B%u@%u:%u^*%u");
CHECK_IF(totsize == offs2 + sizeof(ObjCBool **));
return 0;
===================================================================
@@ -1,13 +1,14 @@
/* Check that protocol qualifiers are compiled and encoded properly. */
/* Author: Ziemowit Laski <zlaski@apple.com> */
-/* { dg-options "" } */
+
/* { dg-do run } */
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
-#include "../objc-obj-c++-shared/Protocol1.h"
+#include <objc/Protocol.h>
#ifndef __NEXT_RUNTIME__
#include <objc/objc-api.h>
#endif
+#include "../objc-obj-c++-shared/next-mapping.h"
/* The encoded parameter sizes will be rounded up to match pointer alignment. */
#define ROUND(s,a) (a * ((s + a - 1) / a))
@@ -31,8 +32,11 @@ extern void abort(void);
- (bycopy) address:(byref inout id)location with:(out short unsigned **)arg2 { return nil; }
@end
-Protocol *proto = @protocol(Retain);
+Protocol *proto;
struct objc_method_description *meth;
+#ifdef NEXT_OBJC_USE_NEW_INTERFACE
+struct objc_method_description meth_object;
+#endif
unsigned totsize, offs0, offs1, offs2, offs3, offs4, offs5, offs6, offs7;
static void scan_initial(const char *pattern) {
@@ -43,10 +47,23 @@ static void scan_initial(const char *pattern) {
}
int main(void) {
+ proto = @protocol(Retain);
+#ifdef NEXT_OBJC_USE_NEW_INTERFACE
+ meth_object = protocol_getMethodDescription (proto,
+ @selector(address:with:), YES, YES);
+ meth = &meth_object;
+#else
meth = [proto descriptionForInstanceMethod: @selector(address:with:)];
+#endif
scan_initial("O@%u@%u:%uNR@%uo^^S%u");
CHECK_IF(offs3 == offs2 + aligned_sizeof(id) && totsize == offs3 + aligned_sizeof(unsigned));
+#ifdef NEXT_OBJC_USE_NEW_INTERFACE
+ meth_object = protocol_getMethodDescription (proto,
+ @selector(retainArgument:with:), YES, NO);
+ meth = &meth_object;
+#else
meth = [proto descriptionForClassMethod: @selector(retainArgument:with:)];
+#endif
scan_initial("Vv%u@%u:%uOo@%un^*%u");
CHECK_IF(offs3 == offs2 + aligned_sizeof(id) && totsize == offs3 + aligned_sizeof(char **));
return 0;