add @optional/@required to prto lists
authoriains <iains@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 30 Sep 2010 16:51:00 +0000 (16:51 +0000)
committeriains <iains@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 30 Sep 2010 16:51:00 +0000 (16:51 +0000)
gcc:

* c-parser.c (c_parser_objc_methodprotolist): Amend preceding comment,
parse @optional/@required and set the flags as appropriate.

gcc/c-family:

      * c-common.c: Add two new entries for @optional
       and @required keywords.

merge from FSF 'apple/trunk' branch.
2006-01-30  Fariborz Jahanian <fjahanian@apple.com>

       Radar 4386773
       * c-common.h (RID_AT_OPTIONAL, RID_AT_REQUIRED): Two new
       objective-c keywords.
       (objc_set_method_opt): New declaration.
       * stub-objc.c (objc_set_method_opt): New stub.

gcc/cp:

merge from FSF 'apple/trunk' branch.
2006-01-30  Fariborz Jahanian <fjahanian@apple.com>

Radar 4386773
* cp/parser.c (cp_parser_objc_interstitial_code): For
       @optional/@required set the optional/required flag.

gcc/objc:

merge from FSF 'apple/trunk' branch.
2006-01-30  Fariborz Jahanian <fjahanian@apple.com>

       Radar 4386773
       * objc/objc-act.c (objc_set_method_opt): New function.
       (objc_start_protocol, objc_finish_interface): Reset
       objc_method_optional_flag flag.
       (objc_add_method_declaration): Pass on the new
       flag to objc_add_method.
       (objc_add_method): Add optional methods to new chain in
       the protocol class.
       * objc/objc-act.h (CLASS_OPTIONAL_CLS_METHODS,
       CLASS_OPTIONAL_NST_METHODS): New macros accessing a protocol
       class's optional method chains.

testsuite:

merge from FSF 'apple/trunk' branch.
2006-01-30  Fariborz Jahanian <fjahanian@apple.com>

       Radar 4386773
       * objc.dg/enhanced-proto-1.m: New.
       * objc.dg/enhanced-proto-2.m: New.
       * obj-c++.dg/enhanced-proto-1.mm: New
       * obj-c++.dg/enhanced-proto-2.mm: New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@164754 138bc75d-0d04-0410-961f-82ee72b054a4

16 files changed:
gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/c-family/c-common.h
gcc/c-family/stub-objc.c
gcc/c-parser.c
gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/objc/ChangeLog
gcc/objc/objc-act.c
gcc/objc/objc-act.h
gcc/testsuite/ChangeLog
gcc/testsuite/obj-c++.dg/enhanced-proto-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/enhanced-proto-2.mm [new file with mode: 0644]
gcc/testsuite/objc.dg/enhanced-proto-1.m [new file with mode: 0644]
gcc/testsuite/objc.dg/enhanced-proto-2.m [new file with mode: 0644]

index 0a725e1..caa3d90 100644 (file)
@@ -1,3 +1,8 @@
+2010-09-30  Iain Sandoe  <iains@gcc.gnu.org>
+
+       * c-parser.c (c_parser_objc_methodprotolist): Amend preceding comment,
+       parse @optional/@required and set the flags as appropriate.
+
 2010-09-30  Nathan Froyd  <froydnj@codesourcery.com>
 
        * config/iq2000/t-iq2000 (TARGET_LIBGCC2_CFLAGS): Delete.
index ed74c28..94b71c9 100644 (file)
@@ -1,3 +1,17 @@
+2010-09-30  Iain Sandoe  <iains@gcc.gnu.org>
+
+       * c-common.c: Add two new entries for @optional
+       and @required keywords.
+
+       merge from FSF 'apple/trunk' branch.
+       2006-01-30  Fariborz Jahanian <fjahanian@apple.com>
+
+       Radar 4386773
+       * c-common.h (RID_AT_OPTIONAL, RID_AT_REQUIRED): Two new
+       objective-c keywords.
+       (objc_set_method_opt): New declaration.
+       * stub-objc.c (objc_set_method_opt): New stub.
+       
 2010-09-30  Joseph Myers  <joseph@codesourcery.com>
 
        * c-common.c (handle_optimize_attribute): Pass &global_options to
index b7b445d..ddac821 100644 (file)
@@ -541,6 +541,8 @@ const struct c_common_resword c_common_reswords[] =
   { "selector",                RID_AT_SELECTOR,        D_OBJC },
   { "finally",         RID_AT_FINALLY,         D_OBJC },
   { "synchronized",    RID_AT_SYNCHRONIZED,    D_OBJC },
+  { "optional",                RID_AT_OPTIONAL,        D_OBJC },
+  { "required",                RID_AT_REQUIRED,        D_OBJC },
   /* These are recognized only in protocol-qualifier context
      (see above) */
   { "bycopy",          RID_BYCOPY,             D_OBJC },
index 27a051c..08ef3b7 100644 (file)
@@ -142,7 +142,8 @@ enum rid
   RID_AT_PRIVATE,  RID_AT_PROTECTED, RID_AT_PUBLIC,
   RID_AT_PROTOCOL, RID_AT_SELECTOR,
   RID_AT_THROW,           RID_AT_TRY,       RID_AT_CATCH,
-  RID_AT_FINALLY,  RID_AT_SYNCHRONIZED,
+  RID_AT_FINALLY,  RID_AT_SYNCHRONIZED, 
+  RID_AT_OPTIONAL, RID_AT_REQUIRED,
   RID_AT_INTERFACE,
   RID_AT_IMPLEMENTATION,
 
@@ -1007,6 +1008,7 @@ extern tree objc_build_synchronized (location_t, tree, tree);
 extern int objc_static_init_needed_p (void);
 extern tree objc_generate_static_init_call (tree);
 extern tree objc_generate_write_barrier (tree, enum tree_code, tree);
+extern void objc_set_method_opt (bool);
 
 /* The following are provided by the C and C++ front-ends, and called by
    ObjC/ObjC++.  */
index 51842eb..3f88874 100644 (file)
@@ -126,6 +126,11 @@ objc_start_protocol (tree ARG_UNUSED (proto),
 {
 }
 
+void 
+objc_set_method_opt (bool ARG_UNUSED (optional))
+{
+}
+
 void
 objc_start_class_interface (tree ARG_UNUSED (name),
                            tree ARG_UNUSED (super),
index 5640774..dc5ea8d 100644 (file)
@@ -6743,6 +6743,8 @@ c_parser_objc_method_definition (c_parser *parser)
      objc-methodprotolist objc-methodproto
      objc-methodprotolist declaration
      objc-methodprotolist ;
+     @optional
+     @required
 
    The declaration is a data definition, which may be missing
    declaration specifiers under the same rules and diagnostics as
@@ -6775,7 +6777,18 @@ c_parser_objc_methodprotolist (c_parser *parser)
        default:
          if (c_parser_next_token_is_keyword (parser, RID_AT_END))
            return;
-         c_parser_declaration_or_fndef (parser, false, false, true,
+         else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
+           {
+             objc_set_method_opt (true);
+             c_parser_consume_token (parser);
+           }
+         else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED))
+           {
+             objc_set_method_opt (false);
+             c_parser_consume_token (parser);
+           }
+         else
+           c_parser_declaration_or_fndef (parser, false, false, true,
                                         false, true);
          break;
        }
index 4b0dd12..8c201d7 100644 (file)
@@ -1,3 +1,12 @@
+2010-09-30  Iain Sandoe  <iains@gcc.gnu.org>
+
+       merge from FSF 'apple/trunk' branch.
+       2006-01-30  Fariborz Jahanian <fjahanian@apple.com>
+
+       Radar 4386773
+       * cp/parser.c (cp_parser_objc_interstitial_code): For
+       @optional/@required set the optional/required flag.
+       
 2010-09-30  Nicola Pero  <nicola.pero@meta-innovation.com>
 
        * parser.c (cp_lexer_get_preprocessor_token): Tidied up comments
index d9cc727..82026b1 100644 (file)
@@ -21597,6 +21597,17 @@ cp_parser_objc_interstitial_code (cp_parser* parser)
   /* Allow stray semicolons.  */
   else if (token->type == CPP_SEMICOLON)
     cp_lexer_consume_token (parser->lexer);
+  /* Mark methods as optional or required, when building protocols.  */
+  else if (token->keyword == RID_AT_OPTIONAL)
+    {
+      cp_lexer_consume_token (parser->lexer);
+      objc_set_method_opt (true);
+    }
+  else if (token->keyword == RID_AT_REQUIRED)
+    {
+      cp_lexer_consume_token (parser->lexer);
+      objc_set_method_opt (false);
+    }
   /* Finally, try to parse a block-declaration, or a function-definition.  */
   else
     cp_parser_block_declaration (parser, /*statement_p=*/false);
index 2954a5a..2f1982c 100644 (file)
@@ -1,3 +1,20 @@
+2010-09-30  Iain Sandoe  <iains@gcc.gnu.org>
+
+       merge from FSF 'apple/trunk' branch.
+       2006-01-30  Fariborz Jahanian <fjahanian@apple.com>
+
+       Radar 4386773
+       * objc/objc-act.c (objc_set_method_opt): New function.
+       (objc_start_protocol, objc_finish_interface): Reset
+       objc_method_optional_flag flag.
+       (objc_add_method_declaration): Pass on the new
+       flag to objc_add_method.
+       (objc_add_method): Add optional methods to new chain in
+       the protocol class.
+       * objc/objc-act.h (CLASS_OPTIONAL_CLS_METHODS,
+       CLASS_OPTIONAL_NST_METHODS): New macros accessing a protocol
+       class's optional method chains.
+       
 2010-09-30  Nicola Pero  <nicola.pero@meta-innovation.com>
 
        Merge from 'apple/trunk' branch on FSF servers.
index 934d78d..dffdb71 100644 (file)
@@ -146,7 +146,7 @@ static void objc_start_function (tree, tree, tree, struct c_arg_info *);
 #endif
 static tree start_protocol (enum tree_code, tree, tree);
 static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
-static tree objc_add_method (tree, tree, int);
+static tree objc_add_method (tree, tree, int, bool);
 static tree add_instance_variable (tree, int, tree);
 static tree build_ivar_reference (tree);
 static tree is_ivar (tree, tree);
@@ -352,6 +352,10 @@ int objc_public_flag;
 /* Use to generate method labels.  */
 static int method_slot = 0;
 
+/* Flag to say whether methods in a protocol are optional or
+   required.  */
+static bool objc_method_optional_flag = false;
+
 static int objc_collecting_ivars = 0;
 
 #define BUFSIZE                1024
@@ -687,6 +691,7 @@ objc_start_protocol (tree name, tree protos, tree attributes)
                " of the compiler, (ignored)");
   objc_interface_context
     = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
+  objc_method_optional_flag = false;
 }
 
 void
@@ -701,6 +706,7 @@ objc_finish_interface (void)
 {
   finish_class (objc_interface_context);
   objc_interface_context = NULL_TREE;
+  objc_method_optional_flag = false;
 }
 
 void
@@ -753,6 +759,18 @@ objc_set_visibility (int visibility)
 }
 
 void
+objc_set_method_opt (bool optional)
+{
+  objc_method_optional_flag = optional;
+  if (!objc_interface_context 
+      || TREE_CODE (objc_interface_context) != PROTOCOL_INTERFACE_TYPE)
+    {
+      error ("@optional/@required is allowed in @protocol context only.");
+      objc_method_optional_flag = false;
+    }
+}
+
+void
 objc_set_method_type (enum tree_code type)
 {
   objc_inherit_code = (type == PLUS_EXPR
@@ -787,7 +805,8 @@ objc_add_method_declaration (tree decl, tree attributes)
 
   objc_add_method (objc_interface_context,
                   decl,
-                  objc_inherit_code == CLASS_METHOD_DECL);
+                  objc_inherit_code == CLASS_METHOD_DECL,
+                  objc_method_optional_flag);
 }
 
 /* Return 'true' if the method definition could be started, and
@@ -816,7 +835,8 @@ objc_start_method_definition (tree decl, tree attributes)
 
   objc_add_method (objc_implementation_context,
                   decl,
-                  objc_inherit_code == CLASS_METHOD_DECL);
+                  objc_inherit_code == CLASS_METHOD_DECL, 
+                  /* is optional */ false);
   start_method_def (decl);
   return true;
 }
@@ -7073,11 +7093,32 @@ add_method_to_hash_list (hash *hash_list, tree method)
 }
 
 static tree
-objc_add_method (tree klass, tree method, int is_class)
+objc_add_method (tree klass, tree method, int is_class, bool is_optional)
 {
   tree mth;
 
-  if (!(mth = lookup_method (is_class
+  /* @optional methods are added to protocol's OPTIONAL list */
+  if (is_optional)
+    {
+      gcc_assert (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE);
+      if (!(mth = lookup_method (is_class
+                               ? PROTOCOL_OPTIONAL_CLS_METHODS (klass)
+                               : PROTOCOL_OPTIONAL_NST_METHODS (klass), 
+                                                               method)))
+       {
+         if (is_class)
+           {
+             TREE_CHAIN (method) = PROTOCOL_OPTIONAL_CLS_METHODS (klass);
+             PROTOCOL_OPTIONAL_CLS_METHODS (klass) = method;
+           }
+         else
+           {
+             TREE_CHAIN (method) = PROTOCOL_OPTIONAL_NST_METHODS (klass);
+             PROTOCOL_OPTIONAL_NST_METHODS (klass) = method;
+           }
+       }
+    }
+  else if (!(mth = lookup_method (is_class
                             ? CLASS_CLS_METHODS (klass)
                             : CLASS_NST_METHODS (klass), method)))
     {
@@ -9064,7 +9105,8 @@ really_start_method (tree method,
 
          if (interface)
            objc_add_method (interface, copy_node (method),
-                            TREE_CODE (method) == CLASS_METHOD_DECL);
+                            TREE_CODE (method) == CLASS_METHOD_DECL, 
+                            /* is_optional= */ false);
        }
     }
 }
index c8edd64..61312e9 100644 (file)
@@ -38,7 +38,7 @@ tree objc_eh_personality (void);
 /* Objective-C structures */
 
 #define CLASS_LANG_SLOT_ELTS           5
-#define PROTOCOL_LANG_SLOT_ELTS                2
+#define PROTOCOL_LANG_SLOT_ELTS                4
 #define OBJC_INFO_SLOT_ELTS            2
 
 /* KEYWORD_DECL */
@@ -71,6 +71,8 @@ tree objc_eh_personality (void);
 #define PROTOCOL_CLS_METHODS(CLASS) ((CLASS)->type.maxval)
 #define PROTOCOL_FORWARD_DECL(CLASS) TREE_VEC_ELT (TYPE_LANG_SLOT_1 (CLASS), 1)
 #define PROTOCOL_DEFINED(CLASS) TREE_USED (CLASS)
+#define PROTOCOL_OPTIONAL_CLS_METHODS(CLASS) TREE_VEC_ELT (TYPE_LANG_SLOT_1 (CLASS), 2)
+#define PROTOCOL_OPTIONAL_NST_METHODS(CLASS) TREE_VEC_ELT (TYPE_LANG_SLOT_1 (CLASS), 3)
 
 /* ObjC-specific information pertaining to RECORD_TYPEs are stored in
    the LANG_SPECIFIC structures, which may itself need allocating first.  */
index 1ee38b7..7afca7e 100644 (file)
@@ -1,3 +1,14 @@
+2010-09-30  Iain Sandoe  <iains@gcc.gnu.org>
+
+       merge from FSF 'apple/trunk' branch.
+       2006-01-30  Fariborz Jahanian <fjahanian@apple.com>
+
+       Radar 4386773
+       * objc.dg/enhanced-proto-1.m: New.
+       * objc.dg/enhanced-proto-2.m: New.
+       * obj-c++.dg/enhanced-proto-1.mm: New
+       * obj-c++.dg/enhanced-proto-2.mm: New.
+
 2010-09-30  Richard Guenther  <rguenther@suse.de>
 
        PR testsuite/45702
diff --git a/gcc/testsuite/obj-c++.dg/enhanced-proto-1.mm b/gcc/testsuite/obj-c++.dg/enhanced-proto-1.mm
new file mode 100644 (file)
index 0000000..97e1420
--- /dev/null
@@ -0,0 +1,18 @@
+/* Test use of @optional/@required keywords in @protocol class. */
+/* { dg-do compile } */
+
+@protocol MyProto1 
+@optional
+- (void) FOO;
+@optional
+- (void) FOO;
+@required 
+- (void) REQ;
+@optional
+@end
+
+@protocol  MyProto2 <MyProto1>
+- (void) FOO2;
+@optional
+- (void) FOO3;
+@end
diff --git a/gcc/testsuite/obj-c++.dg/enhanced-proto-2.mm b/gcc/testsuite/obj-c++.dg/enhanced-proto-2.mm
new file mode 100644 (file)
index 0000000..4aacbda
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+
+@protocol MyProto1 
+@optional
+- (void) FOO;
+@optional
+- (void) FOO;
+@optional 
+- (void) REQ;
+@optional
+@end
+
+@interface  MyProto2 <MyProto1>
+@required              /* { dg-error "@optional/@required is allowed in @protocol context only" }  */
+- (void) FOO2;
+@optional              /* { dg-error "@optional/@required is allowed in @protocol context only" }  */
+- (void) FOO3;
+@end
+
+@implementation MyProto2
+- (void) FOO2{}
+- (void) FOO3{}
+@end
diff --git a/gcc/testsuite/objc.dg/enhanced-proto-1.m b/gcc/testsuite/objc.dg/enhanced-proto-1.m
new file mode 100644 (file)
index 0000000..fef4c97
--- /dev/null
@@ -0,0 +1,19 @@
+/* APPLE LOCAL file C* language */
+/* Test use of @optional/@required keywords in @protocol class. */
+/* { dg-do compile } */
+
+@protocol MyProto1 
+@optional
+- (void) FOO;
+@optional
+- (void) FOO;
+@required 
+- (void) REQ;
+@optional
+@end
+
+@protocol  MyProto2 <MyProto1>
+- (void) FOO2;
+@optional
+- (void) FOO3;
+@end
diff --git a/gcc/testsuite/objc.dg/enhanced-proto-2.m b/gcc/testsuite/objc.dg/enhanced-proto-2.m
new file mode 100644 (file)
index 0000000..6944ec8
--- /dev/null
@@ -0,0 +1,24 @@
+/* Test use of @optional/@required keywords in @protocol class. */
+/* { dg-do compile } */
+
+@protocol MyProto1 
+@optional
+- (void) FOO;
+@optional
+- (void) FOO;
+@optional 
+- (void) REQ;
+@optional
+@end
+
+@interface  MyProto2 <MyProto1>
+@required              /* { dg-error "@optional/@required is allowed in @protocol context only" }  */
+- (void) FOO2;
+@optional              /* { dg-error "@optional/@required is allowed in @protocol context only" }  */
+- (void) FOO3;
+@end
+
+@implementation MyProto2
+- (void) FOO2{}
+- (void) FOO3{}
+@end