From 069761fbf4b005ff86f4e2bc2b53e70efaf5b89f Mon Sep 17 00:00:00 2001 From: iains Date: Thu, 30 Sep 2010 16:51:00 +0000 Subject: [PATCH] add @optional/@required to prto lists 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 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 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 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 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 --- gcc/ChangeLog | 5 +++ gcc/c-family/ChangeLog | 14 ++++++++ gcc/c-family/c-common.c | 2 ++ gcc/c-family/c-common.h | 4 ++- gcc/c-family/stub-objc.c | 5 +++ gcc/c-parser.c | 15 +++++++- gcc/cp/ChangeLog | 9 +++++ gcc/cp/parser.c | 11 ++++++ gcc/objc/ChangeLog | 17 +++++++++ gcc/objc/objc-act.c | 54 ++++++++++++++++++++++++---- gcc/objc/objc-act.h | 4 ++- gcc/testsuite/ChangeLog | 11 ++++++ gcc/testsuite/obj-c++.dg/enhanced-proto-1.mm | 18 ++++++++++ gcc/testsuite/obj-c++.dg/enhanced-proto-2.mm | 23 ++++++++++++ gcc/testsuite/objc.dg/enhanced-proto-1.m | 19 ++++++++++ gcc/testsuite/objc.dg/enhanced-proto-2.m | 24 +++++++++++++ 16 files changed, 226 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/obj-c++.dg/enhanced-proto-1.mm create mode 100644 gcc/testsuite/obj-c++.dg/enhanced-proto-2.mm create mode 100644 gcc/testsuite/objc.dg/enhanced-proto-1.m create mode 100644 gcc/testsuite/objc.dg/enhanced-proto-2.m diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0a725e1..caa3d90 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2010-09-30 Iain Sandoe + + * c-parser.c (c_parser_objc_methodprotolist): Amend preceding comment, + parse @optional/@required and set the flags as appropriate. + 2010-09-30 Nathan Froyd * config/iq2000/t-iq2000 (TARGET_LIBGCC2_CFLAGS): Delete. diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index ed74c28..94b71c9 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,17 @@ +2010-09-30 Iain Sandoe + + * c-common.c: Add two new entries for @optional + and @required keywords. + + merge from FSF 'apple/trunk' branch. + 2006-01-30 Fariborz Jahanian + + 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 * c-common.c (handle_optimize_attribute): Pass &global_options to diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index b7b445d..ddac821 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -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 }, diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 27a051c..08ef3b7 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -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++. */ diff --git a/gcc/c-family/stub-objc.c b/gcc/c-family/stub-objc.c index 51842eb..3f88874 100644 --- a/gcc/c-family/stub-objc.c +++ b/gcc/c-family/stub-objc.c @@ -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), diff --git a/gcc/c-parser.c b/gcc/c-parser.c index 5640774..dc5ea8d 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -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; } diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4b0dd12..8c201d7 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2010-09-30 Iain Sandoe + + merge from FSF 'apple/trunk' branch. + 2006-01-30 Fariborz Jahanian + + Radar 4386773 + * cp/parser.c (cp_parser_objc_interstitial_code): For + @optional/@required set the optional/required flag. + 2010-09-30 Nicola Pero * parser.c (cp_lexer_get_preprocessor_token): Tidied up comments diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index d9cc727..82026b1 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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); diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog index 2954a5a..2f1982c 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -1,3 +1,20 @@ +2010-09-30 Iain Sandoe + + merge from FSF 'apple/trunk' branch. + 2006-01-30 Fariborz Jahanian + + 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 Merge from 'apple/trunk' branch on FSF servers. diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index 934d78d..dffdb71 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -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); } } } diff --git a/gcc/objc/objc-act.h b/gcc/objc/objc-act.h index c8edd64..61312e9 100644 --- a/gcc/objc/objc-act.h +++ b/gcc/objc/objc-act.h @@ -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. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1ee38b7..7afca7e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2010-09-30 Iain Sandoe + + merge from FSF 'apple/trunk' branch. + 2006-01-30 Fariborz Jahanian + + 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 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 index 0000000..97e1420 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/enhanced-proto-1.mm @@ -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 +- (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 index 0000000..4aacbda --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/enhanced-proto-2.mm @@ -0,0 +1,23 @@ +/* { dg-do compile } */ + +@protocol MyProto1 +@optional +- (void) FOO; +@optional +- (void) FOO; +@optional +- (void) REQ; +@optional +@end + +@interface MyProto2 +@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 index 0000000..fef4c97 --- /dev/null +++ b/gcc/testsuite/objc.dg/enhanced-proto-1.m @@ -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 +- (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 index 0000000..6944ec8 --- /dev/null +++ b/gcc/testsuite/objc.dg/enhanced-proto-2.m @@ -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 +@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 -- 2.7.4