From patchwork Fri Feb 25 09:16:08 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicola Pero X-Patchwork-Id: 84527 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 752D0B70F3 for ; Fri, 25 Feb 2011 20:16:33 +1100 (EST) Received: (qmail 13491 invoked by alias); 25 Feb 2011 09:16:30 -0000 Received: (qmail 13475 invoked by uid 22791); 25 Feb 2011 09:16:26 -0000 X-SWARE-Spam-Status: No, hits=-1.4 required=5.0 tests=AWL, BAYES_00, TW_BJ, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from fencepost.gnu.org (HELO fencepost.gnu.org) (140.186.70.10) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 25 Feb 2011 09:16:18 +0000 Received: from eggs.gnu.org ([140.186.70.92]:54626) by fencepost.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1Pstma-0005s2-0X for gcc-patches@gnu.org; Fri, 25 Feb 2011 04:16:16 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PstmX-0003oI-Oh for gcc-patches@gnu.org; Fri, 25 Feb 2011 04:16:15 -0500 Received: from smtp111.iad.emailsrvr.com ([207.97.245.111]:38018) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PstmX-0003o3-Dd for gcc-patches@gnu.org; Fri, 25 Feb 2011 04:16:13 -0500 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp41.relay.iad1a.emailsrvr.com (SMTP Server) with ESMTP id 7A2E8290F07; Fri, 25 Feb 2011 04:16:12 -0500 (EST) Received: by smtp41.relay.iad1a.emailsrvr.com (Authenticated sender: nicola.pero-AT-meta-innovation.com) with ESMTPA id 7988C290A64; Fri, 25 Feb 2011 04:16:11 -0500 (EST) Cc: gcc-patches@gnu.org Message-Id: <3727086D-6A36-4CA0-B0E3-6376EBDF16F0@meta-innovation.com> From: Nicola Pero To: Jack Howarth In-Reply-To: <20110225022901.GA18018@bromo.med.uc.edu> Mime-Version: 1.0 (Apple Message framework v936) Subject: Re: ObjC/ObjC++: Fix property encoding on Apple Date: Fri, 25 Feb 2011 09:16:08 +0000 References: <20110225022901.GA18018@bromo.med.uc.edu> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 207.97.245.111 X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org >> PS: I tested on Apple m32. I don't have an Apple m64. I'd be >> grateful >> if someone could try out the >> patch on there before I commit to confirm that it all looks good >> there. >> Thank! :-) > > Nicola, > Can you repost the patch as an attachment? Your emailer seems to > have reformatted the patch so that it is considered as malformed by > patch and can't be applied against gcc trunk. No problem. Patch (against trunk revision 170489) is in attach. Thanks for your help! :-) Thanks Index: gcc/objc/ChangeLog =================================================================== --- gcc/objc/ChangeLog (revision 170489) +++ gcc/objc/ChangeLog (working copy) @@ -1,3 +1,7 @@ +2011-02-25 Nicola Pero + + * objc-act.c (objc_v2_encode_prop_attr): Rewritten. + 2011-02-23 Nicola Pero * objc-act.c (build_private_template): Do not copy the @@ -16,7 +20,8 @@ 2011-02-21 Mike Stump - * Make-lang.in (check_objc_parallelize): Refine for 4 processor machines. + * Make-lang.in (check_objc_parallelize): Refine for 4 processor + machines. 2011-02-20 Nicola Pero Index: gcc/objc/objc-act.c =================================================================== --- gcc/objc/objc-act.c (revision 170489) +++ gcc/objc/objc-act.c (working copy) @@ -10495,47 +10495,79 @@ kPropertyGetter = 'G', kPropertySetter = 'S', kPropertyInstanceVariable = 'V', - kPropertyType = 't', + kPropertyType = 'T', kPropertyWeak = 'W', - kPropertyStrong = 'S', + kPropertyStrong = 'P', kPropertyNonAtomic = 'N' - }; - - FIXME: Update the implementation to match. */ + }; */ tree objc_v2_encode_prop_attr (tree property) { const char *string; tree type = TREE_TYPE (property); - obstack_1grow (&util_obstack, 't'); + + obstack_1grow (&util_obstack, 'T'); encode_type (type, obstack_object_size (&util_obstack), OBJC_ENCODE_INLINE_DEFS); + if (PROPERTY_READONLY (property)) - obstack_grow (&util_obstack, ",r", 2); + obstack_grow (&util_obstack, ",R", 2); - if (PROPERTY_ASSIGN_SEMANTICS (property) == OBJC_PROPERTY_COPY) - obstack_grow (&util_obstack, ",c", 2); + switch (PROPERTY_ASSIGN_SEMANTICS (property)) + { + case OBJC_PROPERTY_COPY: + obstack_grow (&util_obstack, ",C", 2); + break; + case OBJC_PROPERTY_RETAIN: + obstack_grow (&util_obstack, ",&", 2); + break; + case OBJC_PROPERTY_ASSIGN: + default: + break; + } - if (PROPERTY_GETTER_NAME (property)) + if (PROPERTY_DYNAMIC (property)) + obstack_grow (&util_obstack, ",D", 2); + + if (PROPERTY_NONATOMIC (property)) + obstack_grow (&util_obstack, ",N", 2); + + /* Here we want to encode the getter name, but only if it's not the + standard one. */ + if (PROPERTY_GETTER_NAME (property) != PROPERTY_NAME (property)) { - obstack_grow (&util_obstack, ",g", 2); + obstack_grow (&util_obstack, ",G", 2); string = IDENTIFIER_POINTER (PROPERTY_GETTER_NAME (property)); obstack_grow (&util_obstack, string, strlen (string)); } - if (PROPERTY_SETTER_NAME (property)) + + if (!PROPERTY_READONLY (property)) { - obstack_grow (&util_obstack, ",s", 2); - string = IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (property)); - obstack_grow (&util_obstack, string, strlen (string)); + /* Here we want to encode the setter name, but only if it's not + the standard one. */ + tree standard_setter = get_identifier (objc_build_property_setter_name (PROPERTY_NAME (property))); + if (PROPERTY_SETTER_NAME (property) != standard_setter) + { + obstack_grow (&util_obstack, ",S", 2); + string = IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (property)); + obstack_grow (&util_obstack, string, strlen (string)); + } } - if (PROPERTY_IVAR_NAME (property)) + + /* TODO: Encode strong ('P'), weak ('W') for garbage collection. */ + + if (!PROPERTY_DYNAMIC (property)) { - obstack_grow (&util_obstack, ",i", 2); - string = IDENTIFIER_POINTER (PROPERTY_IVAR_NAME (property)); + obstack_grow (&util_obstack, ",V", 2); + if (PROPERTY_IVAR_NAME (property)) + string = IDENTIFIER_POINTER (PROPERTY_IVAR_NAME (property)); + else + string = IDENTIFIER_POINTER (PROPERTY_NAME (property)); obstack_grow (&util_obstack, string, strlen (string)); } - - obstack_1grow (&util_obstack, 0); /* null terminate string */ + + /* NULL-terminate string. */ + obstack_1grow (&util_obstack, 0); string = XOBFINISH (&util_obstack, char *); obstack_free (&util_obstack, util_firstobj); return get_identifier (string); Index: gcc/testsuite/ChangeLog =================================================================== --- gcc/testsuite/ChangeLog (revision 170489) +++ gcc/testsuite/ChangeLog (working copy) @@ -1,3 +1,11 @@ +2011-02-25 Nicola Pero + + * objc.dg/gnu-api-2-property.m: Added tests for property_getName() + and property_getAttributes() if __OBJC2__. + * obj-c++.dg/gnu-api-2-property.mm: Likewise. + * objc.dg/property/property-encoding-1.m: New. + * obj-c++.dg/property/property-encoding-1.mm: New. + 2011-02-24 Jason Merrill * g++.dg/parse/constant1.C: Specify C++98 mode. Index: gcc/testsuite/objc.dg/property/property-encoding-1.m =================================================================== --- gcc/testsuite/objc.dg/property/property-encoding-1.m (revision 0) +++ gcc/testsuite/objc.dg/property/property-encoding-1.m (revision 0) @@ -0,0 +1,160 @@ +/* Contributed by Nicola Pero , February 2011. */ +/* Test encoding properties. */ +/* { dg-do run } */ +/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */ + +#include +#include +#include +#include + +@interface MyRootClass +{ Class isa; } ++ alloc; +- init; ++ initialize; +@end + +@implementation MyRootClass ++ alloc { return class_createInstance (self, 0); } +- init { return self; } ++ initialize { return self; } +@end + +@interface MySubClass : MyRootClass +{ + char char_property; + short short_property; + int int_property; + long long_property; + float float_property; + double double_property; + int *int_pointer_property; + + id propertyA; + id propertyB; + id propertyC; + id propertyD; + int propertyE; + id propertyF; + + id other_variable; +} +@property char char_property; +@property short short_property; +@property int int_property; +@property long long_property; +@property float float_property; +@property double double_property; +@property int *int_pointer_property; + +@property (assign, getter=getP, setter=setP:) id propertyA; +@property (assign) id propertyB; +@property (copy) id propertyC; +@property (retain) id propertyD; +@property (nonatomic) int propertyE; +@property (nonatomic, readonly, copy) id propertyF; + +@property (assign) id propertyG; +@property (assign, readonly, getter=X) id propertyH; +@end + +@implementation MySubClass +@synthesize char_property; +@synthesize short_property; +@synthesize int_property; +@synthesize long_property; +@synthesize float_property; +@synthesize double_property; +@synthesize int_pointer_property; + +@synthesize propertyA; +@synthesize propertyB; +@synthesize propertyC; +@synthesize propertyD; +@synthesize propertyE; +@synthesize propertyF; + +@synthesize propertyG = other_variable; +@dynamic propertyH; +@end + +#ifdef __OBJC2__ +void error (objc_property_t p) +{ + printf ("Error - property_getAttributes (\"%s\") returns \"%s\"\n", + property_getName (p), + property_getAttributes (p)); + abort (); +} +#endif + +int main(int argc, void **args) +{ +#ifdef __OBJC2__ + Class c = objc_getClass ("MySubClass"); + objc_property_t p; + + p = class_getProperty (c, "char_property"); + if (strcmp ("Tc,Vchar_property", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "short_property"); + if (strcmp ("Ts,Vshort_property", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "int_property"); + if (strcmp ("Ti,Vint_property", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "long_property"); + if (strcmp ("Tl,Vlong_property", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "float_property"); + if (strcmp ("Tf,Vfloat_property", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "double_property"); + if (strcmp ("Td,Vdouble_property", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "int_pointer_property"); + if (strcmp ("T^i,Vint_pointer_property", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "propertyA"); + if (strcmp ("T@,GgetP,SsetP:,VpropertyA", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "propertyB"); + if (strcmp ("T@,VpropertyB", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "propertyC"); + if (strcmp ("T@,C,VpropertyC", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "propertyD"); + if (strcmp ("T@,&,VpropertyD", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "propertyE"); + if (strcmp ("Ti,N,VpropertyE", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "propertyF"); + if (strcmp ("T@,R,C,N,VpropertyF", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "propertyG"); + if (strcmp ("T@,Vother_variable", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "propertyH"); + if (strcmp ("T@,R,D,GX", property_getAttributes (p)) != 0) + error (p); +#endif + + return 0; +} Index: gcc/testsuite/objc.dg/gnu-api-2-property.m =================================================================== --- gcc/testsuite/objc.dg/gnu-api-2-property.m (revision 170489) +++ gcc/testsuite/objc.dg/gnu-api-2-property.m (working copy) @@ -25,23 +25,18 @@ + initialize { return self; } @end -@protocol MyProtocol -- (id) variable; +@interface MySubClass : MyRootClass +{ + id propertyA; + id propertyB; +} +@property (assign, getter=getP, setter=setP:) id propertyA; +@property (assign, nonatomic) id propertyB; @end -@protocol MySecondProtocol -- (id) setVariable: (id)value; -@end - -@interface MySubClass : MyRootClass -{ id variable_ivar; } -- (void) setVariable: (id)value; -- (id) variable; -@end - @implementation MySubClass -- (void) setVariable: (id)value { variable_ivar = value; } -- (id) variable { return variable_ivar; } +@synthesize propertyA; +@synthesize propertyB; @end @@ -49,7 +44,6 @@ { /* Functions are tested in alphabetical order. */ - /* TODO: Test new ABI (when available). */ printf ("Testing property_getAttributes () ...\n"); { /* The Apple/NeXT runtime seems to crash on the following. */ @@ -57,9 +51,26 @@ if (property_getAttributes (NULL) != NULL) abort (); #endif + + /* The GNU runtime doesn't support looking up properties at + runtime yet. */ +#ifdef __OBJC2__ + { + objc_property_t property; + + property = class_getProperty (objc_getClass ("MySubClass"), "propertyA"); + if (strcmp (property_getAttributes (property), + "T@,GgetP,SsetP:,VpropertyA") != 0) + abort (); + + property = class_getProperty (objc_getClass ("MySubClass"), "propertyB"); + if (strcmp (property_getAttributes (property), + "T@,N,VpropertyB") != 0) + abort (); + } +#endif } - /* TODO: Test new ABI (when available). */ printf ("Testing property_getName () ...\n"); { /* The Apple/NeXT runtime seems to crash on the following. */ @@ -67,6 +78,22 @@ if (property_getName (NULL) != NULL) abort (); #endif + + /* The GNU runtime doesn't support looking up properties at + runtime yet. */ +#ifdef __OBJC2__ + { + objc_property_t property; + + property = class_getProperty (objc_getClass ("MySubClass"), "propertyA"); + if (strcmp (property_getName (property), "propertyA") != 0) + abort (); + + property = class_getProperty (objc_getClass ("MySubClass"), "propertyB"); + if (strcmp (property_getName (property), "propertyB") != 0) + abort (); + } +#endif } return 0; Index: gcc/testsuite/obj-c++.dg/property/property-encoding-1.mm =================================================================== --- gcc/testsuite/obj-c++.dg/property/property-encoding-1.mm (revision 0) +++ gcc/testsuite/obj-c++.dg/property/property-encoding-1.mm (revision 0) @@ -0,0 +1,160 @@ +/* Contributed by Nicola Pero , February 2011. */ +/* Test encoding properties. */ +/* { dg-do run } */ +/* { dg-skip-if "No API#2 pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */ + +#include +#include +#include +#include + +@interface MyRootClass +{ Class isa; } ++ alloc; +- init; ++ initialize; +@end + +@implementation MyRootClass ++ alloc { return class_createInstance (self, 0); } +- init { return self; } ++ initialize { return self; } +@end + +@interface MySubClass : MyRootClass +{ + char char_property; + short short_property; + int int_property; + long long_property; + float float_property; + double double_property; + int *int_pointer_property; + + id propertyA; + id propertyB; + id propertyC; + id propertyD; + int propertyE; + id propertyF; + + id other_variable; +} +@property char char_property; +@property short short_property; +@property int int_property; +@property long long_property; +@property float float_property; +@property double double_property; +@property int *int_pointer_property; + +@property (assign, getter=getP, setter=setP:) id propertyA; +@property (assign) id propertyB; +@property (copy) id propertyC; +@property (retain) id propertyD; +@property (nonatomic) int propertyE; +@property (nonatomic, readonly, copy) id propertyF; + +@property (assign) id propertyG; +@property (assign, readonly, getter=X) id propertyH; +@end + +@implementation MySubClass +@synthesize char_property; +@synthesize short_property; +@synthesize int_property; +@synthesize long_property; +@synthesize float_property; +@synthesize double_property; +@synthesize int_pointer_property; + +@synthesize propertyA; +@synthesize propertyB; +@synthesize propertyC; +@synthesize propertyD; +@synthesize propertyE; +@synthesize propertyF; + +@synthesize propertyG = other_variable; +@dynamic propertyH; +@end + +#ifdef __OBJC2__ +void error (objc_property_t p) +{ + printf ("Error - property_getAttributes (\"%s\") returns \"%s\"\n", + property_getName (p), + property_getAttributes (p)); + abort (); +} +#endif + +int main(int argc, char **args) +{ +#ifdef __OBJC2__ + Class c = objc_getClass ("MySubClass"); + objc_property_t p; + + p = class_getProperty (c, "char_property"); + if (strcmp ("Tc,Vchar_property", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "short_property"); + if (strcmp ("Ts,Vshort_property", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "int_property"); + if (strcmp ("Ti,Vint_property", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "long_property"); + if (strcmp ("Tl,Vlong_property", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "float_property"); + if (strcmp ("Tf,Vfloat_property", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "double_property"); + if (strcmp ("Td,Vdouble_property", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "int_pointer_property"); + if (strcmp ("T^i,Vint_pointer_property", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "propertyA"); + if (strcmp ("T@,GgetP,SsetP:,VpropertyA", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "propertyB"); + if (strcmp ("T@,VpropertyB", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "propertyC"); + if (strcmp ("T@,C,VpropertyC", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "propertyD"); + if (strcmp ("T@,&,VpropertyD", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "propertyE"); + if (strcmp ("Ti,N,VpropertyE", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "propertyF"); + if (strcmp ("T@,R,C,N,VpropertyF", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "propertyG"); + if (strcmp ("T@,Vother_variable", property_getAttributes (p)) != 0) + error (p); + + p = class_getProperty (c, "propertyH"); + if (strcmp ("T@,R,D,GX", property_getAttributes (p)) != 0) + error (p); +#endif + + return 0; +} Index: gcc/testsuite/obj-c++.dg/gnu-api-2-property.mm =================================================================== --- gcc/testsuite/obj-c++.dg/gnu-api-2-property.mm (revision 170489) +++ gcc/testsuite/obj-c++.dg/gnu-api-2-property.mm (working copy) @@ -25,23 +25,18 @@ + initialize { return self; } @end -@protocol MyProtocol -- (id) variable; +@interface MySubClass : MyRootClass +{ + id propertyA; + id propertyB; +} +@property (assign, getter=getP, setter=setP:) id propertyA; +@property (assign, nonatomic) id propertyB; @end -@protocol MySecondProtocol -- (id) setVariable: (id)value; -@end - -@interface MySubClass : MyRootClass -{ id variable_ivar; } -- (void) setVariable: (id)value; -- (id) variable; -@end - @implementation MySubClass -- (void) setVariable: (id)value { variable_ivar = value; } -- (id) variable { return variable_ivar; } +@synthesize propertyA; +@synthesize propertyB; @end @@ -49,7 +44,6 @@ { /* Functions are tested in alphabetical order. */ - /* TODO: Test new ABI (when available). */ std::cout << "Testing property_getAttributes () ...\n"; { /* The Apple/NeXT runtime seems to crash on the following. */ @@ -57,9 +51,26 @@ if (property_getAttributes (NULL) != NULL) abort (); #endif + + /* The GNU runtime doesn't support looking up properties at + runtime yet. */ +#ifdef __OBJC2__ + { + objc_property_t property; + + property = class_getProperty (objc_getClass ("MySubClass"), "propertyA"); + if (std::strcmp (property_getAttributes (property), + "T@,GgetP,SsetP:,VpropertyA") != 0) + abort (); + + property = class_getProperty (objc_getClass ("MySubClass"), "propertyB"); + if (std::strcmp (property_getAttributes (property), + "T@,N,VpropertyB") != 0) + abort (); + } +#endif } - /* TODO: Test new ABI (when available). */ std::cout << "Testing property_getName () ...\n"; { /* The Apple/NeXT runtime seems to crash on the following. */ @@ -68,6 +79,22 @@ if (property_getName (NULL) != NULL) abort (); #endif + + /* The GNU runtime doesn't support looking up properties at + runtime yet. */ +#ifdef __OBJC2__ + { + objc_property_t property; + + property = class_getProperty (objc_getClass ("MySubClass"), "propertyA"); + if (std::strcmp (property_getName (property), "propertyA") != 0) + abort (); + + property = class_getProperty (objc_getClass ("MySubClass"), "propertyB"); + if (std::strcmp (property_getName (property), "propertyB") != 0) + abort (); + } +#endif } return (0);