Objective-C/C++ : Handle parsing @property 'class' attribute.
This attribute states that a property is one manipulated by class methods (it requires a static variable and the setter and getter must be provided explicitly, they cannot be @synthesized). gcc/c-family/ChangeLog: * c-common.h (OBJC_IS_PATTR_KEYWORD): Add class to the list of keywords accepted in @property attribute contexts. * c-objc.h (enum objc_property_attribute_group): Add OBJC_PROPATTR_GROUP_CLASS. (enum objc_property_attribute_kind): Add OBJC_PROPERTY_ATTR_CLASS. gcc/cp/ChangeLog: * parser.c (cp_parser_objc_at_property_declaration): Handle class keywords in @property attribute context. gcc/objc/ChangeLog: * objc-act.c (objc_prop_attr_kind_for_rid): Handle class attribute. (objc_add_property_declaration): Likewise. * objc-act.h (PROPERTY_CLASS): Record class attribute state. gcc/testsuite/ChangeLog: * obj-c++.dg/property/at-property-4.mm: Test handling class attributes. * objc.dg/property/at-property-4.m: Likewise.
This commit is contained in:
parent
49393e266a
commit
b642fca1c3
7 changed files with 52 additions and 20 deletions
|
@ -275,9 +275,11 @@ enum rid
|
|||
((unsigned int) (rid) >= (unsigned int) RID_FIRST_PQ && \
|
||||
(unsigned int) (rid) <= (unsigned int) RID_LAST_PQ)
|
||||
|
||||
/* Keywords permitted in an @property attribute context. */
|
||||
#define OBJC_IS_PATTR_KEYWORD(rid) \
|
||||
((unsigned int) (rid) >= (unsigned int) RID_FIRST_PATTR && \
|
||||
(unsigned int) (rid) <= (unsigned int) RID_LAST_PATTR)
|
||||
((((unsigned int) (rid) >= (unsigned int) RID_FIRST_PATTR && \
|
||||
(unsigned int) (rid) <= (unsigned int) RID_LAST_PATTR)) \
|
||||
|| rid == RID_CLASS)
|
||||
|
||||
/* OBJC_IS_CXX_KEYWORD recognizes the 'CXX_OBJC' keywords (such as
|
||||
'class') which are shared in a subtle way between Objective-C and
|
||||
|
|
|
@ -44,6 +44,7 @@ enum objc_property_attribute_group
|
|||
OBJC_PROPATTR_GROUP_READWRITE,
|
||||
OBJC_PROPATTR_GROUP_ASSIGN,
|
||||
OBJC_PROPATTR_GROUP_ATOMIC,
|
||||
OBJC_PROPATTR_GROUP_CLASS,
|
||||
OBJC_PROPATTR_GROUP_MAX
|
||||
};
|
||||
|
||||
|
@ -59,6 +60,7 @@ enum objc_property_attribute_kind
|
|||
OBJC_PROPERTY_ATTR_COPY = ( 7 << 8)|OBJC_PROPATTR_GROUP_ASSIGN,
|
||||
OBJC_PROPERTY_ATTR_ATOMIC = ( 8 << 8)|OBJC_PROPATTR_GROUP_ATOMIC,
|
||||
OBJC_PROPERTY_ATTR_NONATOMIC = ( 9 << 8)|OBJC_PROPATTR_GROUP_ATOMIC,
|
||||
OBJC_PROPERTY_ATTR_CLASS = (16 << 8)|OBJC_PROPATTR_GROUP_CLASS,
|
||||
OBJC_PROPERTY_ATTR_MAX = (255 << 8|OBJC_PROPATTR_GROUP_MAX)
|
||||
};
|
||||
|
||||
|
|
|
@ -34052,6 +34052,10 @@ cp_parser_objc_at_property_declaration (cp_parser *parser)
|
|||
enum rid keyword;
|
||||
if (token->type == CPP_NAME)
|
||||
keyword = C_RID_CODE (token->u.value);
|
||||
else if (token->type == CPP_KEYWORD
|
||||
&& token->keyword == RID_CLASS)
|
||||
/* Account for accepting the 'class' keyword in this context. */
|
||||
keyword = RID_CLASS;
|
||||
else
|
||||
keyword = RID_MAX; /* By definition, an unknown property. */
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
|
|
|
@ -825,6 +825,7 @@ objc_prop_attr_kind_for_rid (enum rid prop_rid)
|
|||
case RID_PROPATOMIC: return OBJC_PROPERTY_ATTR_ATOMIC;
|
||||
case RID_NONATOMIC: return OBJC_PROPERTY_ATTR_NONATOMIC;
|
||||
|
||||
case RID_CLASS: return OBJC_PROPERTY_ATTR_CLASS;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -986,6 +987,14 @@ objc_add_property_declaration (location_t location, tree decl,
|
|||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
/* An attribute that indicates this property manipulates a class variable.
|
||||
In this case, both the variable and the getter/setter must be provided
|
||||
by the user. */
|
||||
bool property_class = false;
|
||||
if (attrs[OBJC_PROPATTR_GROUP_CLASS])
|
||||
property_nonatomic = attrs[OBJC_PROPATTR_GROUP_CLASS]->prop_kind
|
||||
== OBJC_PROPERTY_ATTR_CLASS;
|
||||
|
||||
/* TODO: Check that the property type is an Objective-C object or a
|
||||
"POD". */
|
||||
|
||||
|
@ -1273,6 +1282,7 @@ objc_add_property_declaration (location_t location, tree decl,
|
|||
PROPERTY_SETTER_NAME (property_decl) = property_setter_ident;
|
||||
PROPERTY_READONLY (property_decl) = property_readonly;
|
||||
PROPERTY_NONATOMIC (property_decl) = property_nonatomic;
|
||||
PROPERTY_CLASS (property_decl) = property_class;
|
||||
PROPERTY_ASSIGN_SEMANTICS (property_decl) = property_assign_semantics;
|
||||
PROPERTY_IVAR_NAME (property_decl) = NULL_TREE;
|
||||
PROPERTY_DYNAMIC (property_decl) = 0;
|
||||
|
|
|
@ -137,6 +137,10 @@ enum objc_property_assign_semantics {
|
|||
#define PROPERTY_OPTIONAL(DECL) \
|
||||
DECL_LANG_FLAG_5 (PROPERTY_DECL_CHECK (DECL))
|
||||
|
||||
/* PROPERTY_CLASS can be 0 or 1. */
|
||||
#define PROPERTY_CLASS(DECL) \
|
||||
DECL_LANG_FLAG_6 (PROPERTY_DECL_CHECK (DECL))
|
||||
|
||||
/* PROPERTY_REF. A PROPERTY_REF represents an 'object.property'
|
||||
expression. It is normally used for property access, but when
|
||||
the Objective-C 2.0 "dot-syntax" (object.component) is used
|
||||
|
|
|
@ -14,17 +14,22 @@
|
|||
- (void) mySetter2: (int)property;
|
||||
|
||||
/* Test that all the new property attributes can be parsed. */
|
||||
@property (assign) id property_a;
|
||||
@property (copy) id property_b;
|
||||
@property (atomic) int property_ca;
|
||||
@property (nonatomic) int property_c;
|
||||
@property (readonly) int property_d;
|
||||
@property (readwrite) int property_e;
|
||||
@property (retain) id property_f;
|
||||
@property (release) int property_g; /* { dg-error "unknown property attribute" } */
|
||||
@property (assign) id property_as_1;
|
||||
@property (copy) id property_as_2;
|
||||
@property (retain) id property_as_3;
|
||||
|
||||
@property (getter=myGetter) int property_h;
|
||||
@property (setter=mySetter:) int property_i;
|
||||
@property (atomic) int property_at_1;
|
||||
@property (nonatomic) int property_at_2;
|
||||
|
||||
@property (readonly) int property_rw_1;
|
||||
@property (readwrite) int property_rw_2;
|
||||
|
||||
@property (class) int property_cl_1;
|
||||
|
||||
@property (release) int property_err_1; /* { dg-error "unknown property attribute" } */
|
||||
|
||||
@property (getter=myGetter) int property_g0;
|
||||
@property (setter=mySetter:) int property_s0;
|
||||
|
||||
/* Now test various problems. */
|
||||
|
||||
|
|
|
@ -14,14 +14,19 @@
|
|||
- (void) mySetter2: (int)property;
|
||||
|
||||
/* Test that all the new property attributes can be parsed. */
|
||||
@property (assign) id property_a;
|
||||
@property (copy) id property_b;
|
||||
@property (atomic) int property_ca;
|
||||
@property (nonatomic) int property_c;
|
||||
@property (readonly) int property_d;
|
||||
@property (readwrite) int property_e;
|
||||
@property (retain) id property_f;
|
||||
@property (release) int property_g; /* { dg-error "unknown property attribute" } */
|
||||
@property (assign) id property_as_1;
|
||||
@property (copy) id property_as_2;
|
||||
@property (retain) id property_as_3;
|
||||
|
||||
@property (atomic) int property_at_1;
|
||||
@property (nonatomic) int property_at_2;
|
||||
|
||||
@property (readonly) int property_rw_1;
|
||||
@property (readwrite) int property_rw_2;
|
||||
|
||||
@property (class) int property_cl_1;
|
||||
|
||||
@property (release) int property_err_1; /* { dg-error "unknown property attribute" } */
|
||||
|
||||
@property (getter=myGetter) int property_h;
|
||||
@property (setter=mySetter:) int property_i;
|
||||
|
|
Loading…
Add table
Reference in a new issue