[pushed] Objective-C/C++ : Handle parsing @property 'class' attribute.

Message ID D45AF8C7-36D2-43B9-9E1F-362258AAE428@sandoe.co.uk
State New
Headers show
Series
  • [pushed] Objective-C/C++ : Handle parsing @property 'class' attribute.
Related show

Commit Message

Iain Sandoe Nov. 8, 2020, 11:33 a.m.
Hi

(this change reused the existing ‘class’ keyword and RID, so only
 needed Objective-C context modifications).

tested on x86_64-darwin, x86_64-linux-gnu,
pushed to master,
thanks
Iain

-- 
2.24.1

Patch

====

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.
---
 gcc/c-family/c-common.h                       |  6 +++--
 gcc/c-family/c-objc.h                         |  2 ++
 gcc/cp/parser.c                               |  4 +++
 gcc/objc/objc-act.c                           | 10 +++++++
 gcc/objc/objc-act.h                           |  4 +++
 .../obj-c++.dg/property/at-property-4.mm      | 27 +++++++++++--------
 .../objc.dg/property/at-property-4.m          | 21 +++++++++------
 7 files changed, 53 insertions(+), 21 deletions(-)

diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 7e2cd5342aa..bfcc279609c 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -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
diff --git a/gcc/c-family/c-objc.h b/gcc/c-family/c-objc.h
index a2ca112dcc6..6e96731882b 100644
--- a/gcc/c-family/c-objc.h
+++ b/gcc/c-family/c-objc.h
@@ -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)
 };
 
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index c4c672efa09..323d7424a83 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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);
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index 2dad46aa77e..b9ed32d51d0 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -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;
diff --git a/gcc/objc/objc-act.h b/gcc/objc/objc-act.h
index db71b6a265e..5b0433ff0ee 100644
--- a/gcc/objc/objc-act.h
+++ b/gcc/objc/objc-act.h
@@ -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
diff --git a/gcc/testsuite/obj-c++.dg/property/at-property-4.mm b/gcc/testsuite/obj-c++.dg/property/at-property-4.mm
index 31f2eb4336a..f73d70639b6 100644
--- a/gcc/testsuite/obj-c++.dg/property/at-property-4.mm
+++ b/gcc/testsuite/obj-c++.dg/property/at-property-4.mm
@@ -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 (getter=myGetter)  int property_h;
-@property (setter=mySetter:) int property_i;
+@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_g0;
+@property (setter=mySetter:) int property_s0;
 
 /* Now test various problems.  */
 
diff --git a/gcc/testsuite/objc.dg/property/at-property-4.m b/gcc/testsuite/objc.dg/property/at-property-4.m
index 31f2eb4336a..0e905db0eb4 100644
--- a/gcc/testsuite/objc.dg/property/at-property-4.m
+++ b/gcc/testsuite/objc.dg/property/at-property-4.m
@@ -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;