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:
Iain Sandoe 2020-11-04 23:52:12 +00:00
parent 49393e266a
commit b642fca1c3
7 changed files with 52 additions and 20 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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