diff options
author | nicola <nicola@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-12-10 09:38:52 +0000 |
---|---|---|
committer | nicola <nicola@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-12-10 09:38:52 +0000 |
commit | e16610d055313c83e07ed3c61128785bdfb870ce (patch) | |
tree | 1455b598d50eb7e482cbb74cb6884dc439905ab7 /gcc/testsuite/obj-c++.dg | |
parent | 3ed6ea20edc4f93023f9b843ce7daa8ac8f6d197 (diff) | |
download | gcc-e16610d055313c83e07ed3c61128785bdfb870ce.tar.gz |
In gcc/:
2010-12-10 Nicola Pero <nicola.pero@meta-innovation.com>
* c-parser.c (c_parser_objc_class_definition): Recognize
Objective-C 2.0 class extensions.
In gcc/cp/:
2010-12-10 Nicola Pero <nicola.pero@meta-innovation.com>
* parser.c (cp_parser_objc_superclass_or_category): Recognize
Objective-C 2.0 class extensions. Added iface_p and
is_class_extension arguments.
(cp_parser_objc_class_interface): Updated call to
cp_parser_objc_superclass_or_category.
(cp_parser_objc_class_implementation): Same change.
In gcc/objc/:
2010-12-10 Nicola Pero <nicola.pero@meta-innovation.com>
* objc-act.c (objc_in_class_extension): New.
(objc_start_category_interface): If -fobjc-std=objc1
was specified, produce an error if a class extension is used.
(objc_finish_interface): Reset objc_in_class_extension to false.
(objc_add_property_declaration): Allow a class extension to extend
readonly properties in the main @interface to be readwrite.
(start_class): Added code to deal with class extensions. In that
case, return the existing interface after adding any additional
protocols to it and setting objc_in_class_extension to true.
(continue_class): If in a class extension, do not generate the
instance variable template.
In gcc/testsuite/:
2010-12-10 Nicola Pero <nicola.pero@meta-innovation.com>
* objc.dg/class-extension-1.m: New.
* objc.dg/class-extension-2.m: New.
* objc.dg/class-extension-3.m: New.
* objc.dg/property/at-property-26.m: New.
* objc.dg/property/at-property-27.m: New.
* objc.dg/property/at-property-28.m: New.
* obj-c++.dg/class-extension-1.mm: New.
* obj-c++.dg/class-extension-2.mm: New.
* obj-c++.dg/class-extension-3.mm: New.
* obj-c++.dg/property/at-property-26.mm: New.
* obj-c++.dg/property/at-property-27.mm: New.
* obj-c++.dg/property/at-property-28.mm: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@167680 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/testsuite/obj-c++.dg')
-rw-r--r-- | gcc/testsuite/obj-c++.dg/class-extension-1.mm | 30 | ||||
-rw-r--r-- | gcc/testsuite/obj-c++.dg/class-extension-2.mm | 56 | ||||
-rw-r--r-- | gcc/testsuite/obj-c++.dg/class-extension-3.mm | 26 | ||||
-rw-r--r-- | gcc/testsuite/obj-c++.dg/property/at-property-26.mm | 85 | ||||
-rw-r--r-- | gcc/testsuite/obj-c++.dg/property/at-property-27.mm | 66 | ||||
-rw-r--r-- | gcc/testsuite/obj-c++.dg/property/at-property-28.mm | 29 |
6 files changed, 292 insertions, 0 deletions
diff --git a/gcc/testsuite/obj-c++.dg/class-extension-1.mm b/gcc/testsuite/obj-c++.dg/class-extension-1.mm new file mode 100644 index 00000000000..eab59c4137c --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/class-extension-1.mm @@ -0,0 +1,30 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */ +/* { dg-do compile } */ + +/* This test tests the basic of class extensions. */ + +#include <objc/objc.h> + +@interface MyObject +{ + Class isa; +} +- (int) test; +@end + +@interface MyObject () +- (int) test2; +- (int) test3; +@end + +@implementation MyObject +- (int) test +{ + return 20; +} +- (int) test2 +{ + return 20; +} +@end /* { dg-warning "incomplete implementation of class .MyObject." } */ + /* { dg-warning "method definition for .-test3. not found" "" { target *-*-* } 29 } */ diff --git a/gcc/testsuite/obj-c++.dg/class-extension-2.mm b/gcc/testsuite/obj-c++.dg/class-extension-2.mm new file mode 100644 index 00000000000..79b126f529a --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/class-extension-2.mm @@ -0,0 +1,56 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */ +/* { dg-do compile } */ + +/* This test tests class extensions and protocols. */ + +#include <objc/objc.h> + +/* First, a simple test where a plain class has a protocol attached to + it in a class extension. */ +@interface MyObject +{ + Class isa; +} +@end + +@protocol MyProtocol +- (void) test; +@end + +@interface MyObject () <MyProtocol> +@end + +@implementation MyObject +@end /* { dg-warning "incomplete implementation of class .MyObject." } */ + /* { dg-warning "method definition for .-test. not found" "" { target *-*-* } 24 } */ + /* { dg-warning "class .MyObject. does not fully implement the .MyProtocol. protocol" "" { target *-*-* } 24 } */ + + + +/* Second, a more interesting test where protocols are added from the + main class and from two different class extensions. */ +@interface MyObject2 : MyObject <MyProtocol> +@end + +@protocol MyProtocol2 +- (void) test2; +@end + +@protocol MyProtocol3 +- (void) test3; +@end + +@interface MyObject2 () <MyProtocol2> +@end + +@interface MyObject2 () <MyProtocol3> +@end + +@implementation MyObject2 +@end /* { dg-warning "incomplete implementation of class .MyObject2." } */ + /* { dg-warning "method definition for .-test. not found" "" { target *-*-* } 50 } */ + /* { dg-warning "class .MyObject2. does not fully implement the .MyProtocol. protocol" "" { target *-*-* } 50 } */ + /* { dg-warning "method definition for .-test2. not found" "" { target *-*-* } 50 } */ + /* { dg-warning "class .MyObject2. does not fully implement the .MyProtocol2. protocol" "" { target *-*-* } 50 } */ + /* { dg-warning "method definition for .-test3. not found" "" { target *-*-* } 50 } */ + /* { dg-warning "class .MyObject2. does not fully implement the .MyProtocol3. protocol" "" { target *-*-* } 50 } */ diff --git a/gcc/testsuite/obj-c++.dg/class-extension-3.mm b/gcc/testsuite/obj-c++.dg/class-extension-3.mm new file mode 100644 index 00000000000..8feb5c9b6f2 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/class-extension-3.mm @@ -0,0 +1,26 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */ +/* { dg-do compile } */ + +/* This test tests warnings on class extensions. */ + +#include <objc/objc.h> + +@interface MyObject +{ + Class isa; + int count; +} +- (int) test; +@property int count; /* { dg-warning "originally specified here" } */ +@end + +@interface MyObject () +- (void) test; /* { dg-error "duplicate declaration of method .-test." } */ +@end + +@interface MyObject () +@end + +@interface MyObject () +@property int count; /* { dg-error "redeclaration of property .count." } */ +@end diff --git a/gcc/testsuite/obj-c++.dg/property/at-property-26.mm b/gcc/testsuite/obj-c++.dg/property/at-property-26.mm new file mode 100644 index 00000000000..c45757e239a --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/at-property-26.mm @@ -0,0 +1,85 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */ +/* { dg-do run } */ +/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ + +/* Test @properties in class extensions. */ + +#include <stdlib.h> +#include <objc/objc.h> +#include <objc/runtime.h> + +@interface MyRootClass +{ + Class isa; +} ++ (id) initialize; ++ (id) alloc; +- (id) init; +@end + +@implementation MyRootClass ++ (id) initialize { return self; } ++ (id) alloc { return class_createInstance (self, 0); } +- (id) init { return self; } +@end + +@protocol count4 +/* Use a different getters/setters, so that the only way to compile + object.countX is to find the actual @property. */ +@property (getter=number4, setter=setNumber4:) int count4; +@end + +@interface MySubClass : MyRootClass +{ + int count1; + int count2; + int count3; + int count4; +} +@property (getter=number1, setter=setNumber1:) int count1; +@end + +@interface MySubClass () +@property (getter=number2, setter=setNumber2:) int count2; +@end + +@interface MySubClass () <count4> +@property (getter=number3, setter=setNumber3:) int count3; +@end + +@implementation MySubClass +@synthesize count1; +@synthesize count2; +- (int) number3 +{ + return count3; +} +- (void) setNumber3: (int)value +{ + count3 = value; +} +@synthesize count4; +@end + +int main (void) +{ + MySubClass *object = [[MySubClass alloc] init]; + + object.count1 = 20; + if (object.count1 != 20) + abort (); + + object.count2 = 11; + if (object.count2 != 11) + abort (); + + object.count3 = 19; + if (object.count3 != 19) + abort (); + + object.count4 = 74; + if (object.count4 != 74) + abort (); + + return 0; +} diff --git a/gcc/testsuite/obj-c++.dg/property/at-property-27.mm b/gcc/testsuite/obj-c++.dg/property/at-property-27.mm new file mode 100644 index 00000000000..727834684fe --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/at-property-27.mm @@ -0,0 +1,66 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */ +/* { dg-do run } */ +/* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ + +/* Test overriding a readonly @property with a readwrite one in a class extension. */ + +#include <stdlib.h> +#include <objc/objc.h> +#include <objc/runtime.h> + +@interface MyRootClass +{ + Class isa; +} ++ (id) initialize; ++ (id) alloc; +- (id) init; +@end + +@implementation MyRootClass ++ (id) initialize { return self; } ++ (id) alloc { return class_createInstance (self, 0); } +- (id) init { return self; } +@end + +@protocol count2 +/* Use a different getters/setters, so that the only way to compile + object.countX is to find the actual @property. */ +@property (readonly, getter=number2) int count2; +@end + +@interface MySubClass : MyRootClass +{ + int count1; + int count2; +} +@property (readonly, getter=number1) int count1; +@end + +@interface MySubClass () +@property (readwrite, getter=number1, setter=setNumber1:) int count1; +@end + +@interface MySubClass () <count2> +@property (readwrite, getter=number2, setter=setNumber2:) int count2; +@end + +@implementation MySubClass +@synthesize count1; +@synthesize count2; +@end + +int main (void) +{ + MySubClass *object = [[MySubClass alloc] init]; + + object.count1 = 20; + if (object.count1 != 20) + abort (); + + object.count2 = 11; + if (object.count2 != 11) + abort (); + + return 0; +} diff --git a/gcc/testsuite/obj-c++.dg/property/at-property-28.mm b/gcc/testsuite/obj-c++.dg/property/at-property-28.mm new file mode 100644 index 00000000000..23b357c8505 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/at-property-28.mm @@ -0,0 +1,29 @@ +/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, December 2010. */ +/* { dg-do compile } */ + +/* Test errors when extending a property in a class extension. */ + +#include <objc/objc.h> +#include <objc/runtime.h> + +@interface MyRootClass +{ + Class isa; +} +@property (readonly, retain) id property1; /* { dg-warning "originally specified here" } */ +@property (readonly) int property2; /* { dg-warning "originally specified here" } */ +@property (readonly, getter=y) int property3; /* { dg-warning "originally specified here" } */ +@property (readonly) int property4; /* Ok */ +@property (readonly) int property5; /* { dg-warning "originally specified here" } */ +@end + +@interface MyRootClass () +@property (readwrite, copy) id property1; /* { dg-warning "assign semantics attributes of property .property1. conflict with previous declaration" } */ +@property (readwrite, nonatomic) int property2; /* { dg-warning ".nonatomic. attribute of property .property2. conflicts with previous declaration" } */ +@property (readwrite, getter=x) int property3; /* { dg-warning ".getter. attribute of property .property3. conflicts with previous declaration" } */ +@property (readwrite) int property4; /* Ok */ +@property (readwrite) float property5; /* { dg-warning "type of property .property5. conflicts with previous declaration" } */ +@end + + + |