In gcc/objc/: 2010-11-08 Nicola Pero <nicola.pero@meta-innovation.com>
In gcc/objc/: 2010-11-08 Nicola Pero <nicola.pero@meta-innovation.com> * objc-act.c (objc_add_dynamic_declaration_for_property): Do not search for the @property declation only in the current context, but also in inherited properties. Do not mark the original PROPERTY_DECL in the @interface or @protocol with PROPERTY_DYNAMIC. (check_methods): To check if a method is associated with a @dynamic property, search for the property in IMPL_PROPERTY_DECL. (check_accessible_methods): Same change. * objc-act.h: Updated comment. In gcc/testsuite/: 2010-11-08 Nicola Pero <nicola.pero@meta-innovation.com> * objc.dg/property/dynamic-4.m: New. * objc.dg/property/dynamic-5.m: New. * objc.dg/property/dynamic-6.m: New. * obj-c++.dg/property/dynamic-4.mm: New. * obj-c++.dg/property/dynamic-5.mm: New. * obj-c++.dg/property/dynamic-6.mm: New. 2010-11-08 Nicola Pero <nicola.pero@meta-innovation.com> * objc.dg/property/dotsyntax-13.m: New. * objc.dg/property/dotsyntax-14.m: New. * objc.dg/property/dotsyntax-15.m: New. * objc.dg/property/synthesize-7.m: New. * obj-c++.dg/property/dotsyntax-13.mm: New. * obj-c++.dg/property/dotsyntax-14.mm: New. * obj-c++.dg/property/dotsyntax-15.mm: New. * obj-c++.dg/property/synthesize-7.mm: New. From-SVN: r166457
This commit is contained in:
parent
4741888d03
commit
d36dba0739
|
@ -1,3 +1,15 @@
|
|||
2010-11-08 Nicola Pero <nicola.pero@meta-innovation.com>
|
||||
|
||||
* objc-act.c (objc_add_dynamic_declaration_for_property): Do not
|
||||
search for the @property declation only in the current context,
|
||||
but also in inherited properties. Do not mark the original
|
||||
PROPERTY_DECL in the @interface or @protocol with
|
||||
PROPERTY_DYNAMIC.
|
||||
(check_methods): To check if a method is associated with a
|
||||
@dynamic property, search for the property in IMPL_PROPERTY_DECL.
|
||||
(check_accessible_methods): Same change.
|
||||
* objc-act.h: Updated comment.
|
||||
|
||||
2010-11-08 Nicola Pero <nicola.pero@meta-innovation.com>
|
||||
|
||||
* objc-act.c (objc_add_synthesize_declaration_for_property):
|
||||
|
|
|
@ -8738,9 +8738,19 @@ check_methods (tree chain, tree implementation, int mtype)
|
|||
{
|
||||
/* If the method is associated with a dynamic property, then it
|
||||
is Ok not to have the method implementation, as it will be
|
||||
generated dynamically at runtime. */
|
||||
tree property = METHOD_PROPERTY_CONTEXT (chain);
|
||||
if (property != NULL_TREE && PROPERTY_DYNAMIC (property))
|
||||
generated dynamically at runtime. To decide if the method is
|
||||
associated with a @dynamic property, we search the list of
|
||||
@synthesize and @dynamic for this implementation, and look
|
||||
for any @dynamic property with the same setter or getter name
|
||||
as this method. */
|
||||
tree x;
|
||||
for (x = IMPL_PROPERTY_DECL (implementation); x; x = TREE_CHAIN (x))
|
||||
if (PROPERTY_DYNAMIC (x)
|
||||
&& (PROPERTY_GETTER_NAME (x) == METHOD_SEL_NAME (chain)
|
||||
|| PROPERTY_SETTER_NAME (x) == METHOD_SEL_NAME (chain)))
|
||||
break;
|
||||
|
||||
if (x != NULL_TREE)
|
||||
{
|
||||
chain = TREE_CHAIN (chain); /* next method... */
|
||||
continue;
|
||||
|
@ -8751,6 +8761,7 @@ check_methods (tree chain, tree implementation, int mtype)
|
|||
/* If the method is a property setter/getter, we'll still
|
||||
allow it to be missing if it is implemented by
|
||||
'interface' or any of its superclasses. */
|
||||
tree property = METHOD_PROPERTY_CONTEXT (chain);
|
||||
if (property)
|
||||
{
|
||||
/* Note that since this is a property getter/setter, it
|
||||
|
@ -8864,13 +8875,21 @@ check_methods_accessible (tree chain, tree context, int mtype)
|
|||
{
|
||||
/* If the method is associated with a dynamic property, then it
|
||||
is Ok not to have the method implementation, as it will be
|
||||
generated dynamically at runtime. */
|
||||
tree property = METHOD_PROPERTY_CONTEXT (chain);
|
||||
if (property != NULL_TREE && PROPERTY_DYNAMIC (property))
|
||||
generated dynamically at runtime. Search for any @dynamic
|
||||
property with the same setter or getter name as this
|
||||
method. TODO: Use a hashtable lookup. */
|
||||
tree x;
|
||||
for (x = IMPL_PROPERTY_DECL (base_context); x; x = TREE_CHAIN (x))
|
||||
if (PROPERTY_DYNAMIC (x)
|
||||
&& (PROPERTY_GETTER_NAME (x) == METHOD_SEL_NAME (chain)
|
||||
|| PROPERTY_SETTER_NAME (x) == METHOD_SEL_NAME (chain)))
|
||||
break;
|
||||
|
||||
if (x != NULL_TREE)
|
||||
{
|
||||
chain = TREE_CHAIN (chain); /* next method... */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
context = base_context;
|
||||
while (context)
|
||||
|
@ -9910,11 +9929,9 @@ objc_add_dynamic_declaration_for_property (location_t location, tree interface,
|
|||
return;
|
||||
}
|
||||
|
||||
/* Check that the property is declared in the corresponding
|
||||
interface. */
|
||||
for (property = CLASS_PROPERTY_DECL (interface); property; property = TREE_CHAIN (property))
|
||||
if (PROPERTY_NAME (property) == property_name)
|
||||
break;
|
||||
/* Check that the property is declared in the interface. It could
|
||||
also be declared in a superclass or protocol. */
|
||||
property = lookup_property (interface, property_name);
|
||||
|
||||
if (!property)
|
||||
{
|
||||
|
@ -9924,17 +9941,6 @@ objc_add_dynamic_declaration_for_property (location_t location, tree interface,
|
|||
}
|
||||
else
|
||||
{
|
||||
/* Mark the original PROPERTY_DECL as dynamic. The reason is
|
||||
that the setter and getter methods in the interface have a
|
||||
METHOD_PROPERTY_CONTEXT that points to the original
|
||||
PROPERTY_DECL; when we check that these methods have been
|
||||
implemented, we need to easily find that they are associated
|
||||
with a dynamic property. TODO: Remove this hack; it will not
|
||||
work with properties in a protocol that may be implemented by
|
||||
different classes and be @dynamic in some, and non-@dynamic
|
||||
in other ones. */
|
||||
PROPERTY_DYNAMIC (property) = 1;
|
||||
|
||||
/* We have to copy the property, because we want to chain it to
|
||||
the implementation context, and we want to store the source
|
||||
location of the @synthesize, not of the original
|
||||
|
|
|
@ -100,8 +100,7 @@ typedef enum objc_property_assign_semantics {
|
|||
#define PROPERTY_IVAR_NAME(DECL) ((DECL)->decl_common.initial)
|
||||
|
||||
/* PROPERTY_DYNAMIC can be 0 or 1. This is 1 if the PROPERTY_DECL
|
||||
represents a @dynamic (or if it is a @property for which a @dynamic
|
||||
declaration has been parsed); otherwise, it is set to 0. */
|
||||
represents a @dynamic; otherwise, it is set to 0. */
|
||||
#define PROPERTY_DYNAMIC(DECL) DECL_LANG_FLAG_2 (DECL)
|
||||
|
||||
/* PROPERTY_HAS_NO_GETTER can be 0 or 1. Normally it is 0, but if
|
||||
|
|
|
@ -1,3 +1,23 @@
|
|||
2010-11-08 Nicola Pero <nicola.pero@meta-innovation.com>
|
||||
|
||||
* objc.dg/property/dotsyntax-13.m: New.
|
||||
* objc.dg/property/dotsyntax-14.m: New.
|
||||
* objc.dg/property/dotsyntax-15.m: New.
|
||||
* objc.dg/property/synthesize-7.m: New.
|
||||
* obj-c++.dg/property/dotsyntax-13.mm: New.
|
||||
* obj-c++.dg/property/dotsyntax-14.mm: New.
|
||||
* obj-c++.dg/property/dotsyntax-15.mm: New.
|
||||
* obj-c++.dg/property/synthesize-7.mm: New.
|
||||
|
||||
2010-11-08 Nicola Pero <nicola.pero@meta-innovation.com>
|
||||
|
||||
* objc.dg/property/dynamic-4.m: New.
|
||||
* objc.dg/property/dynamic-5.m: New.
|
||||
* objc.dg/property/dynamic-6.m: New.
|
||||
* obj-c++.dg/property/dynamic-4.mm: New.
|
||||
* obj-c++.dg/property/dynamic-5.mm: New.
|
||||
* obj-c++.dg/property/dynamic-6.mm: New.
|
||||
|
||||
2010-11-08 Nicola Pero <nicola.pero@meta-innovation.com>
|
||||
|
||||
* objc.dg/property/synthesize-3.m: New.
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
|
||||
/* { dg-do run } */
|
||||
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
|
||||
|
||||
/* Test dot-syntax with a local variable. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <objc/objc.h>
|
||||
#include <objc/runtime.h>
|
||||
|
||||
@interface MyRootClass
|
||||
{
|
||||
Class isa;
|
||||
int a;
|
||||
}
|
||||
+ (id) initialize;
|
||||
+ (id) alloc;
|
||||
- (id) init;
|
||||
- (int) count;
|
||||
- (void) setCount: (int)count;
|
||||
@end
|
||||
|
||||
@implementation MyRootClass
|
||||
+ (id) initialize { return self; }
|
||||
+ (id) alloc { return class_createInstance (self, 0); }
|
||||
- (id) init { return self; }
|
||||
- (int) count
|
||||
{
|
||||
return a;
|
||||
}
|
||||
- (void) setCount: (int)count
|
||||
{
|
||||
a = count;
|
||||
}
|
||||
@end
|
||||
|
||||
int main (void)
|
||||
{
|
||||
MyRootClass *object = [[MyRootClass alloc] init];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
object.count = i;
|
||||
|
||||
if (object.count != i)
|
||||
abort ();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
|
||||
/* { dg-do compile } */
|
||||
|
||||
/* Test dot-syntax with accessors to be looked up in protocol @properties. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <objc/objc.h>
|
||||
#include <objc/runtime.h>
|
||||
|
||||
@protocol ProtocolA
|
||||
@property int countA;
|
||||
@end
|
||||
|
||||
@protocol ProtocolB
|
||||
@property int countB;
|
||||
@end
|
||||
|
||||
@protocol ProtocolC
|
||||
@property int countC;
|
||||
@end
|
||||
|
||||
@interface MyRootClass
|
||||
{
|
||||
Class isa;
|
||||
}
|
||||
+ (id) initialize;
|
||||
+ (id) alloc;
|
||||
- (id) init;
|
||||
@end
|
||||
|
||||
@interface MySubClass <ProtocolA, ProtocolB, ProtocolC>
|
||||
@end
|
||||
|
||||
int function (MySubClass *object, int x)
|
||||
{
|
||||
object.countA = x;
|
||||
object.countB = x;
|
||||
object.countC = object.countB;
|
||||
|
||||
return object.countC;
|
||||
}
|
||||
|
||||
int function2 (MyRootClass <ProtocolA, ProtocolB, ProtocolC> *object, int x)
|
||||
{
|
||||
object.countA = x;
|
||||
object.countB = x;
|
||||
object.countC = object.countB;
|
||||
|
||||
return object.countC;
|
||||
}
|
||||
|
||||
int function3 (MyRootClass <ProtocolA, ProtocolB> *object, int x)
|
||||
{
|
||||
object.countA = x;
|
||||
object.countB = x;
|
||||
object.countC = object.countB; /* { dg-error "request for member .countC. in" } */
|
||||
|
||||
return object.countC; /* { dg-error "request for member .countC. in" } */
|
||||
}
|
||||
|
||||
int function4 (id <ProtocolA, ProtocolB, ProtocolC> object, int x)
|
||||
{
|
||||
object.countA = x;
|
||||
object.countB = x;
|
||||
object.countC = object.countB;
|
||||
|
||||
return object.countC;
|
||||
}
|
||||
|
||||
int function5 (id <ProtocolA, ProtocolB> object, int x)
|
||||
{
|
||||
object.countA = x;
|
||||
object.countB = x;
|
||||
object.countC = object.countB; /* { dg-error "request for member .countC. in" } */
|
||||
|
||||
return object.countC; /* { dg-error "request for member .countC. in" } */
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
|
||||
/* { dg-do compile } */
|
||||
|
||||
/* Test dot-syntax with accessors to be looked up in protocols. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <objc/objc.h>
|
||||
#include <objc/runtime.h>
|
||||
|
||||
@protocol ProtocolA
|
||||
- (int) countA;
|
||||
- (void) setCountA: (int)aNumber;
|
||||
@end
|
||||
|
||||
@protocol ProtocolB
|
||||
- (int) countB;
|
||||
- (void) setCountB: (int)aNumber;
|
||||
@end
|
||||
|
||||
@protocol ProtocolC
|
||||
- (int) countC;
|
||||
- (void) setCountC: (int)aNumber;
|
||||
@end
|
||||
|
||||
@interface MyRootClass
|
||||
{
|
||||
Class isa;
|
||||
}
|
||||
+ (id) initialize;
|
||||
+ (id) alloc;
|
||||
- (id) init;
|
||||
@end
|
||||
|
||||
@interface MySubClass <ProtocolA, ProtocolB, ProtocolC>
|
||||
@end
|
||||
|
||||
int function (MySubClass *object, int x)
|
||||
{
|
||||
object.countA = x;
|
||||
object.countB = x;
|
||||
object.countC = object.countB;
|
||||
|
||||
return object.countC;
|
||||
}
|
||||
|
||||
int function2 (MyRootClass <ProtocolA, ProtocolB, ProtocolC> *object, int x)
|
||||
{
|
||||
object.countA = x;
|
||||
object.countB = x;
|
||||
object.countC = object.countB;
|
||||
|
||||
return object.countC;
|
||||
}
|
||||
|
||||
int function3 (MyRootClass <ProtocolA, ProtocolB> *object, int x)
|
||||
{
|
||||
object.countA = x;
|
||||
object.countB = x;
|
||||
object.countC = object.countB; /* { dg-error "request for member .countC. in" } */
|
||||
|
||||
return object.countC; /* { dg-error "request for member .countC. in" } */
|
||||
}
|
||||
|
||||
int function4 (id <ProtocolA, ProtocolB, ProtocolC> object, int x)
|
||||
{
|
||||
object.countA = x;
|
||||
object.countB = x;
|
||||
object.countC = object.countB;
|
||||
|
||||
return object.countC;
|
||||
}
|
||||
|
||||
int function5 (id <ProtocolA, ProtocolB> object, int x)
|
||||
{
|
||||
object.countA = x;
|
||||
object.countB = x;
|
||||
object.countC = object.countB; /* { dg-error "request for member .countC. in" } */
|
||||
|
||||
return object.countC; /* { dg-error "request for member .countC. in" } */
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
|
||||
/* { dg-do compile } */
|
||||
|
||||
#include <objc/objc.h>
|
||||
|
||||
@interface MyRootClass
|
||||
{
|
||||
Class isa;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation MyRootClass
|
||||
@end
|
||||
|
||||
/* Test @property/@dynamic with protocols. */
|
||||
|
||||
@protocol MyProtocol
|
||||
@property int a;
|
||||
@end
|
||||
|
||||
|
||||
/* This class is declared to conform to the protocol, but because of
|
||||
@dynamic, no warnings are issued even if the getter/setter for the
|
||||
@property are missing. */
|
||||
@interface MyClass1 : MyRootClass <MyProtocol>
|
||||
@end
|
||||
|
||||
@implementation MyClass1
|
||||
@dynamic a;
|
||||
@end
|
||||
|
||||
|
||||
/* This class is declared to conform to the protocol and warnings are
|
||||
issued because the setter for the @property is missing. */
|
||||
@interface MyClass2 : MyRootClass <MyProtocol>
|
||||
@end
|
||||
|
||||
@implementation MyClass2
|
||||
- (int) a
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@end /* { dg-warning "incomplete implementation" } */
|
||||
/* { dg-warning "method definition for .-setA:. not found" "" { target *-*-* } 43 } */
|
||||
/* { dg-warning "class .MyClass2. does not fully implement the .MyProtocol. protocol" "" { target *-*-* } 43 } */
|
|
@ -0,0 +1,53 @@
|
|||
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
|
||||
/* { dg-do run } */
|
||||
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
|
||||
|
||||
/* Test @dynamic in the real scenario where a class declares a
|
||||
@property, uses @dynamic to avoid implementing it, then subclasses
|
||||
implement it. */
|
||||
|
||||
#include <objc/objc.h>
|
||||
#include <objc/runtime.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@interface MyRootClass
|
||||
{
|
||||
Class isa;
|
||||
}
|
||||
@property int a;
|
||||
+ (id) initialize;
|
||||
+ (id) alloc;
|
||||
- (id) init;
|
||||
@end
|
||||
|
||||
@implementation MyRootClass
|
||||
+ (id) initialize { return self; }
|
||||
+ (id) alloc { return class_createInstance (self, 0); }
|
||||
- (id) init { return self; }
|
||||
@dynamic a;
|
||||
@end
|
||||
|
||||
@interface Test : MyRootClass
|
||||
{
|
||||
int v1;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation Test
|
||||
@synthesize a = v1;
|
||||
@end
|
||||
|
||||
int main (void)
|
||||
{
|
||||
/* Note how 'object' is declared to be of class 'MyRootClass', but
|
||||
actually is of the subclass which implements the property for
|
||||
real. */
|
||||
MyRootClass *object = [[Test alloc] init];
|
||||
|
||||
object.a = 40;
|
||||
|
||||
if (object.a != 40)
|
||||
abort ();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
|
||||
/* { dg-do compile } */
|
||||
|
||||
/* Test case when an accessor from a @property matches a method
|
||||
required by a protocol. If the @property is @dynamic, then no
|
||||
warning should be generated. */
|
||||
|
||||
#include <objc/objc.h>
|
||||
#include <objc/runtime.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@protocol Count
|
||||
- (int) count;
|
||||
@end
|
||||
|
||||
@interface MyRootClass <Count>
|
||||
{
|
||||
Class isa;
|
||||
}
|
||||
@property int count;
|
||||
@end
|
||||
|
||||
@implementation MyRootClass
|
||||
/* This @dynamic turns off any warnings for -count and -setCount:. */
|
||||
@dynamic count;
|
||||
@end
|
|
@ -0,0 +1,86 @@
|
|||
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
|
||||
/* { dg-do run } */
|
||||
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
|
||||
|
||||
/* Test @synthesize with protocols of protocols. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <objc/objc.h>
|
||||
#include <objc/runtime.h>
|
||||
|
||||
@protocol ProtocolA
|
||||
@property int countA;
|
||||
@end
|
||||
|
||||
@protocol ProtocolB <ProtocolA>
|
||||
@property int countB;
|
||||
@end
|
||||
|
||||
@protocol ProtocolC <ProtocolB>
|
||||
@property int countC;
|
||||
@end
|
||||
|
||||
@protocol ProtocolD
|
||||
@property int countD;
|
||||
@end
|
||||
|
||||
@interface MyRootClass <ProtocolC>
|
||||
{
|
||||
Class isa;
|
||||
int countA;
|
||||
int countB;
|
||||
int countC;
|
||||
}
|
||||
+ (id) initialize;
|
||||
+ (id) alloc;
|
||||
- (id) init;
|
||||
@end
|
||||
|
||||
@implementation MyRootClass
|
||||
+ (id) initialize { return self; }
|
||||
+ (id) alloc { return class_createInstance (self, 0); }
|
||||
- (id) init { return self; }
|
||||
@synthesize countA;
|
||||
@synthesize countB;
|
||||
@synthesize countC;
|
||||
@end
|
||||
|
||||
@interface MySubClass : MyRootClass <ProtocolD>
|
||||
{
|
||||
int countD;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation MySubClass
|
||||
@synthesize countD;
|
||||
@end
|
||||
|
||||
int main (void)
|
||||
{
|
||||
MySubClass *object = [[MySubClass alloc] init];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
object.countA += i;
|
||||
object.countB += i + 1;
|
||||
object.countC += i + 2;
|
||||
object.countD += i + 3;
|
||||
}
|
||||
|
||||
if (object.countA != 45)
|
||||
abort ();
|
||||
|
||||
if (object.countB != 55)
|
||||
abort ();
|
||||
|
||||
if (object.countC != 65)
|
||||
abort ();
|
||||
|
||||
if (object.countD != 75)
|
||||
abort ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
|
||||
/* { dg-do run } */
|
||||
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
|
||||
|
||||
/* Test dot-syntax with a local variable. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <objc/objc.h>
|
||||
#include <objc/runtime.h>
|
||||
|
||||
@interface MyRootClass
|
||||
{
|
||||
Class isa;
|
||||
int a;
|
||||
}
|
||||
+ (id) initialize;
|
||||
+ (id) alloc;
|
||||
- (id) init;
|
||||
- (int) count;
|
||||
- (void) setCount: (int)count;
|
||||
@end
|
||||
|
||||
@implementation MyRootClass
|
||||
+ (id) initialize { return self; }
|
||||
+ (id) alloc { return class_createInstance (self, 0); }
|
||||
- (id) init { return self; }
|
||||
- (int) count
|
||||
{
|
||||
return a;
|
||||
}
|
||||
- (void) setCount: (int)count
|
||||
{
|
||||
a = count;
|
||||
}
|
||||
@end
|
||||
|
||||
int main (void)
|
||||
{
|
||||
MyRootClass *object = [[MyRootClass alloc] init];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
object.count = i;
|
||||
|
||||
if (object.count != i)
|
||||
abort ();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
|
||||
/* { dg-do compile } */
|
||||
|
||||
/* Test dot-syntax with accessors to be looked up in protocol @properties. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <objc/objc.h>
|
||||
#include <objc/runtime.h>
|
||||
|
||||
@protocol ProtocolA
|
||||
@property int countA;
|
||||
@end
|
||||
|
||||
@protocol ProtocolB
|
||||
@property int countB;
|
||||
@end
|
||||
|
||||
@protocol ProtocolC
|
||||
@property int countC;
|
||||
@end
|
||||
|
||||
@interface MyRootClass
|
||||
{
|
||||
Class isa;
|
||||
}
|
||||
+ (id) initialize;
|
||||
+ (id) alloc;
|
||||
- (id) init;
|
||||
@end
|
||||
|
||||
@interface MySubClass <ProtocolA, ProtocolB, ProtocolC>
|
||||
@end
|
||||
|
||||
int function (MySubClass *object, int x)
|
||||
{
|
||||
object.countA = x;
|
||||
object.countB = x;
|
||||
object.countC = object.countB;
|
||||
|
||||
return object.countC;
|
||||
}
|
||||
|
||||
int function2 (MyRootClass <ProtocolA, ProtocolB, ProtocolC> *object, int x)
|
||||
{
|
||||
object.countA = x;
|
||||
object.countB = x;
|
||||
object.countC = object.countB;
|
||||
|
||||
return object.countC;
|
||||
}
|
||||
|
||||
int function3 (MyRootClass <ProtocolA, ProtocolB> *object, int x)
|
||||
{
|
||||
object.countA = x;
|
||||
object.countB = x;
|
||||
object.countC = object.countB; /* { dg-error "request for member .countC. in something not a structure or union" } */
|
||||
|
||||
return object.countC; /* { dg-error "request for member .countC. in something not a structure or union" } */
|
||||
}
|
||||
|
||||
int function4 (id <ProtocolA, ProtocolB, ProtocolC> object, int x)
|
||||
{
|
||||
object.countA = x;
|
||||
object.countB = x;
|
||||
object.countC = object.countB;
|
||||
|
||||
return object.countC;
|
||||
}
|
||||
|
||||
int function5 (id <ProtocolA, ProtocolB> object, int x)
|
||||
{
|
||||
object.countA = x;
|
||||
object.countB = x;
|
||||
object.countC = object.countB; /* { dg-error "request for member .countC. in something not a structure or union" } */
|
||||
|
||||
return object.countC; /* { dg-error "request for member .countC. in something not a structure or union" } */
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
|
||||
/* { dg-do compile } */
|
||||
|
||||
/* Test dot-syntax with accessors to be looked up in protocols. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <objc/objc.h>
|
||||
#include <objc/runtime.h>
|
||||
|
||||
@protocol ProtocolA
|
||||
- (int) countA;
|
||||
- (void) setCountA: (int)aNumber;
|
||||
@end
|
||||
|
||||
@protocol ProtocolB
|
||||
- (int) countB;
|
||||
- (void) setCountB: (int)aNumber;
|
||||
@end
|
||||
|
||||
@protocol ProtocolC
|
||||
- (int) countC;
|
||||
- (void) setCountC: (int)aNumber;
|
||||
@end
|
||||
|
||||
@interface MyRootClass
|
||||
{
|
||||
Class isa;
|
||||
}
|
||||
+ (id) initialize;
|
||||
+ (id) alloc;
|
||||
- (id) init;
|
||||
@end
|
||||
|
||||
@interface MySubClass <ProtocolA, ProtocolB, ProtocolC>
|
||||
@end
|
||||
|
||||
int function (MySubClass *object, int x)
|
||||
{
|
||||
object.countA = x;
|
||||
object.countB = x;
|
||||
object.countC = object.countB;
|
||||
|
||||
return object.countC;
|
||||
}
|
||||
|
||||
int function2 (MyRootClass <ProtocolA, ProtocolB, ProtocolC> *object, int x)
|
||||
{
|
||||
object.countA = x;
|
||||
object.countB = x;
|
||||
object.countC = object.countB;
|
||||
|
||||
return object.countC;
|
||||
}
|
||||
|
||||
int function3 (MyRootClass <ProtocolA, ProtocolB> *object, int x)
|
||||
{
|
||||
object.countA = x;
|
||||
object.countB = x;
|
||||
object.countC = object.countB; /* { dg-error "request for member .countC. in something not a structure or union" } */
|
||||
|
||||
return object.countC; /* { dg-error "request for member .countC. in something not a structure or union" } */
|
||||
}
|
||||
|
||||
int function4 (id <ProtocolA, ProtocolB, ProtocolC> object, int x)
|
||||
{
|
||||
object.countA = x;
|
||||
object.countB = x;
|
||||
object.countC = object.countB;
|
||||
|
||||
return object.countC;
|
||||
}
|
||||
|
||||
int function5 (id <ProtocolA, ProtocolB> object, int x)
|
||||
{
|
||||
object.countA = x;
|
||||
object.countB = x;
|
||||
object.countC = object.countB; /* { dg-error "request for member .countC. in something not a structure or union" } */
|
||||
|
||||
return object.countC; /* { dg-error "request for member .countC. in something not a structure or union" } */
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
|
||||
/* { dg-do compile } */
|
||||
|
||||
#include <objc/objc.h>
|
||||
|
||||
@interface MyRootClass
|
||||
{
|
||||
Class isa;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation MyRootClass
|
||||
@end
|
||||
|
||||
/* Test @property/@dynamic with protocols. */
|
||||
|
||||
@protocol MyProtocol
|
||||
@property int a;
|
||||
@end
|
||||
|
||||
|
||||
/* This class is declared to conform to the protocol, but because of
|
||||
@dynamic, no warnings are issued even if the getter/setter for the
|
||||
@property are missing. */
|
||||
@interface MyClass1 : MyRootClass <MyProtocol>
|
||||
@end
|
||||
|
||||
@implementation MyClass1
|
||||
@dynamic a;
|
||||
@end
|
||||
|
||||
|
||||
/* This class is declared to conform to the protocol and warnings are
|
||||
issued because the setter for the @property is missing. */
|
||||
@interface MyClass2 : MyRootClass <MyProtocol>
|
||||
@end
|
||||
|
||||
@implementation MyClass2
|
||||
- (int) a
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@end /* { dg-warning "incomplete implementation" } */
|
||||
/* { dg-warning "method definition for .-setA:. not found" "" { target *-*-* } 43 } */
|
||||
/* { dg-warning "class .MyClass2. does not fully implement the .MyProtocol. protocol" "" { target *-*-* } 43 } */
|
|
@ -0,0 +1,53 @@
|
|||
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
|
||||
/* { dg-do run } */
|
||||
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
|
||||
|
||||
/* Test @dynamic in the real scenario where a class declares a
|
||||
@property, uses @dynamic to avoid implementing it, then subclasses
|
||||
implement it. */
|
||||
|
||||
#include <objc/objc.h>
|
||||
#include <objc/runtime.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@interface MyRootClass
|
||||
{
|
||||
Class isa;
|
||||
}
|
||||
@property int a;
|
||||
+ (id) initialize;
|
||||
+ (id) alloc;
|
||||
- (id) init;
|
||||
@end
|
||||
|
||||
@implementation MyRootClass
|
||||
+ (id) initialize { return self; }
|
||||
+ (id) alloc { return class_createInstance (self, 0); }
|
||||
- (id) init { return self; }
|
||||
@dynamic a;
|
||||
@end
|
||||
|
||||
@interface Test : MyRootClass
|
||||
{
|
||||
int v1;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation Test
|
||||
@synthesize a = v1;
|
||||
@end
|
||||
|
||||
int main (void)
|
||||
{
|
||||
/* Note how 'object' is declared to be of class 'MyRootClass', but
|
||||
actually is of the subclass which implements the property for
|
||||
real. */
|
||||
MyRootClass *object = [[Test alloc] init];
|
||||
|
||||
object.a = 40;
|
||||
|
||||
if (object.a != 40)
|
||||
abort ();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
|
||||
/* { dg-do compile } */
|
||||
|
||||
/* Test case when an accessor from a @property matches a method
|
||||
required by a protocol. If the @property is @dynamic, then no
|
||||
warning should be generated. */
|
||||
|
||||
#include <objc/objc.h>
|
||||
#include <objc/runtime.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@protocol Count
|
||||
- (int) count;
|
||||
@end
|
||||
|
||||
@interface MyRootClass <Count>
|
||||
{
|
||||
Class isa;
|
||||
}
|
||||
@property int count;
|
||||
@end
|
||||
|
||||
@implementation MyRootClass
|
||||
/* This @dynamic turns off any warnings for -count and -setCount:. */
|
||||
@dynamic count;
|
||||
@end
|
|
@ -0,0 +1,86 @@
|
|||
/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010. */
|
||||
/* { dg-do run } */
|
||||
/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
|
||||
|
||||
/* Test @synthesize with protocols of protocols. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <objc/objc.h>
|
||||
#include <objc/runtime.h>
|
||||
|
||||
@protocol ProtocolA
|
||||
@property int countA;
|
||||
@end
|
||||
|
||||
@protocol ProtocolB <ProtocolA>
|
||||
@property int countB;
|
||||
@end
|
||||
|
||||
@protocol ProtocolC <ProtocolB>
|
||||
@property int countC;
|
||||
@end
|
||||
|
||||
@protocol ProtocolD
|
||||
@property int countD;
|
||||
@end
|
||||
|
||||
@interface MyRootClass <ProtocolC>
|
||||
{
|
||||
Class isa;
|
||||
int countA;
|
||||
int countB;
|
||||
int countC;
|
||||
}
|
||||
+ (id) initialize;
|
||||
+ (id) alloc;
|
||||
- (id) init;
|
||||
@end
|
||||
|
||||
@implementation MyRootClass
|
||||
+ (id) initialize { return self; }
|
||||
+ (id) alloc { return class_createInstance (self, 0); }
|
||||
- (id) init { return self; }
|
||||
@synthesize countA;
|
||||
@synthesize countB;
|
||||
@synthesize countC;
|
||||
@end
|
||||
|
||||
@interface MySubClass : MyRootClass <ProtocolD>
|
||||
{
|
||||
int countD;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation MySubClass
|
||||
@synthesize countD;
|
||||
@end
|
||||
|
||||
int main (void)
|
||||
{
|
||||
MySubClass *object = [[MySubClass alloc] init];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
object.countA += i;
|
||||
object.countB += i + 1;
|
||||
object.countC += i + 2;
|
||||
object.countD += i + 3;
|
||||
}
|
||||
|
||||
if (object.countA != 45)
|
||||
abort ();
|
||||
|
||||
if (object.countB != 55)
|
||||
abort ();
|
||||
|
||||
if (object.countC != 65)
|
||||
abort ();
|
||||
|
||||
if (object.countD != 75)
|
||||
abort ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue