Object1.h: Add copyright header, update comments.

gcc/testsuite:

	* 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.

From-SVN: r168705
This commit is contained in:
Iain Sandoe 2011-01-12 11:04:14 +00:00
parent d72ae3bf10
commit 2a6793fc09
9 changed files with 337 additions and 143 deletions

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;
}
- init {
return self;
+ (Class) class
{
return self;
}
+ class {
return object_getClass(self);
}
+ new {
return [[self alloc] init];
}
+ free {
return nil;
}
- free {
return object_dispose(self);
}
+ alloc {
return class_createInstance(self, 0);
}
- class {
return isa;
}
- superclass {
return class_getSuperclass([self class]);
}
- (const char *) name {
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;
- (BOOL)isEqual: (id)anObject
{
return self == anObject;
}
@end
#endif /* NEEDS_OBJECT_IMPLEMENTATION */
#endif /* _OBJC_OBJECT1_IMPLEMENTATION_H_ */
# 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;
}
- init
{
return self;
}
- (Class) class
{
return isa;
}
+ (Class) superclass
{
return class_getSuperclass(object_getClass(self));
}
+ new
{
return [[self alloc] init];
}
+ free
{
return nil;
}
- free
{
return object_dispose(self);
}
+ alloc
{
return class_createInstance (self, 0);
}
- (Class) superclass {
return class_getSuperclass([self class]);
}
- (const char *) name {
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;
}
#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 /* NEXT_OBJC_ABI_VERSION >= 2 */
# endif /* __NEXT_RUNTIME__ */
#endif /* _OBJC_OBJECT1_IMPLEMENTATION_H_ */

View File

@ -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__
#ifndef __NEXT_RUNTIME__
/* Case 1 = GNU. */
# include <objc/Object.h>
#else
/* 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
#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 <stdarg.h>
#import <objc/objc-runtime.h>
# include <objc/objc.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_ */

View File

@ -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"

View File

@ -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"

View File

@ -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 size; struct _XXRect *next; } XX
+ (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;

View File

@ -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;