Index: c-family/ChangeLog =================================================================== --- c-family/ChangeLog (revision 166902) +++ c-family/ChangeLog (working copy) @@ -1,3 +1,8 @@ +2010-11-18 Nicola Pero + + * c-common.h (objc_declare_protocols): Added additional argument. + * stub-objc.c (objc_declare_protocol): Same change. + 2010-11-17 Joseph Myers * c-opts.c (c_common_parse_file): Take no arguments. Index: c-family/c-common.h =================================================================== --- c-family/c-common.h (revision 166902) +++ c-family/c-common.h (working copy) @@ -995,7 +995,7 @@ extern int objc_is_public (tree, tree); extern tree objc_is_id (tree); extern void objc_declare_alias (tree, tree); extern void objc_declare_class (tree); -extern void objc_declare_protocols (tree); +extern void objc_declare_protocols (tree, tree); extern tree objc_build_message_expr (tree); extern tree objc_finish_message_expr (tree, tree, tree); extern tree objc_build_selector_expr (location_t, tree); Index: c-family/stub-objc.c =================================================================== --- c-family/stub-objc.c (revision 166902) +++ c-family/stub-objc.c (working copy) @@ -126,7 +126,7 @@ objc_declare_class (tree ARG_UNUSED (lis } void -objc_declare_protocols (tree ARG_UNUSED (list)) +objc_declare_protocols (tree ARG_UNUSED (list), tree ARG_UNUSED (attributes)) { } Index: objc/objc-act.c =================================================================== --- objc/objc-act.c (revision 166908) +++ objc/objc-act.c (working copy) @@ -153,7 +153,7 @@ static void objc_start_function (tree, t #else static void objc_start_function (tree, tree, tree, struct c_arg_info *); #endif -static tree start_protocol (enum tree_code, tree, tree); +static tree start_protocol (enum tree_code, tree, tree, tree); static tree build_method_decl (enum tree_code, tree, tree, tree, bool); static tree objc_add_method (tree, tree, int, bool); static tree add_instance_variable (tree, objc_ivar_visibility_kind, tree); @@ -234,9 +234,9 @@ enum string_section static tree add_objc_string (tree, enum string_section); static void build_selector_table_decl (void); -/* Protocol additions. */ +/* Protocols. */ -static tree lookup_protocol (tree); +static tree lookup_protocol (tree, bool); static tree lookup_and_install_protocols (tree); /* Type encoding. */ @@ -767,17 +767,11 @@ objc_start_category_interface (tree klas void objc_start_protocol (tree name, tree protos, tree attributes) { - if (attributes) - { - if (flag_objc1_only) - error_at (input_location, "protocol attributes are not available in Objective-C 1.0"); - else - warning_at (input_location, OPT_Wattributes, - "protocol attributes are not available in this version" - " of the compiler, (ignored)"); - } + if (flag_objc1_only && attributes) + error_at (input_location, "protocol attributes are not available in Objective-C 1.0"); + objc_interface_context - = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos); + = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos, attributes); objc_method_optional_flag = false; } @@ -2866,7 +2860,7 @@ check_protocol_recursively (tree proto, tree pp = TREE_VALUE (p); if (TREE_CODE (pp) == IDENTIFIER_NODE) - pp = lookup_protocol (pp); + pp = lookup_protocol (pp, /* warn if deprecated */ false); if (pp == proto) fatal_error ("protocol %qE has circular dependency", @@ -2876,8 +2870,9 @@ check_protocol_recursively (tree proto, } } -/* Look up PROTOCOLS, and return a list of those that are found. - If none are found, return NULL. */ +/* Look up PROTOCOLS, and return a list of those that are found. If + none are found, return NULL. Note that this function will emit a + warning if a protocol is found and is deprecated. */ static tree lookup_and_install_protocols (tree protocols) @@ -2891,7 +2886,7 @@ lookup_and_install_protocols (tree proto for (proto = protocols; proto; proto = TREE_CHAIN (proto)) { tree ident = TREE_VALUE (proto); - tree p = lookup_protocol (ident); + tree p = lookup_protocol (ident, /* warn_if_deprecated */ true); if (p) return_value = chainon (return_value, @@ -8237,7 +8232,7 @@ tree objc_build_protocol_expr (tree protoname) { tree expr; - tree p = lookup_protocol (protoname); + tree p = lookup_protocol (protoname, /* warn if deprecated */ true); if (!p) { @@ -10544,14 +10539,22 @@ add_protocol (tree protocol) return protocol_chain; } +/* Looks up a protocol. If 'warn_if_deprecated' is true, a warning is + emitted if the protocol is deprecated. */ + static tree -lookup_protocol (tree ident) +lookup_protocol (tree ident, bool warn_if_deprecated) { tree chain; for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain)) if (ident == PROTOCOL_NAME (chain)) - return chain; + { + if (warn_if_deprecated && TREE_DEPRECATED (chain)) + warn_deprecated_use (chain, NULL_TREE); + + return chain; + } return NULL_TREE; } @@ -10560,9 +10563,10 @@ lookup_protocol (tree ident) they are already declared or defined, the function has no effect. */ void -objc_declare_protocols (tree names) +objc_declare_protocols (tree names, tree attributes) { tree list; + bool deprecated = false; #ifdef OBJCPLUS if (current_namespace != global_namespace) { @@ -10570,11 +10574,25 @@ objc_declare_protocols (tree names) } #endif /* OBJCPLUS */ + /* Determine if 'deprecated', the only attribute we recognize for + protocols, was used. Ignore all other attributes. */ + if (attributes) + { + tree attribute; + for (attribute = attributes; attribute; attribute = TREE_CHAIN (attribute)) + { + tree name = TREE_PURPOSE (attribute); + + if (is_attribute_p ("deprecated", name)) + deprecated = true; + } + } + for (list = names; list; list = TREE_CHAIN (list)) { tree name = TREE_VALUE (list); - if (lookup_protocol (name) == NULL_TREE) + if (lookup_protocol (name, /* warn if deprecated */ false) == NULL_TREE) { tree protocol = make_node (PROTOCOL_INTERFACE_TYPE); @@ -10585,14 +10603,22 @@ objc_declare_protocols (tree names) add_protocol (protocol); PROTOCOL_DEFINED (protocol) = 0; PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE; + + if (attributes) + { + TYPE_ATTRIBUTES (protocol) = attributes; + if (deprecated) + TREE_DEPRECATED (protocol) = 1; + } } } } static tree -start_protocol (enum tree_code code, tree name, tree list) +start_protocol (enum tree_code code, tree name, tree list, tree attributes) { tree protocol; + bool deprecated = false; #ifdef OBJCPLUS if (current_namespace != global_namespace) { @@ -10600,7 +10626,21 @@ start_protocol (enum tree_code code, tre } #endif /* OBJCPLUS */ - protocol = lookup_protocol (name); + /* Determine if 'deprecated', the only attribute we recognize for + protocols, was used. Ignore all other attributes. */ + if (attributes) + { + tree attribute; + for (attribute = attributes; attribute; attribute = TREE_CHAIN (attribute)) + { + tree name = TREE_PURPOSE (attribute); + + if (is_attribute_p ("deprecated", name)) + deprecated = true; + } + } + + protocol = lookup_protocol (name, /* warn_if_deprecated */ false); if (!protocol) { @@ -10627,6 +10667,14 @@ start_protocol (enum tree_code code, tre warning (0, "duplicate declaration for protocol %qE", name); } + + if (attributes) + { + TYPE_ATTRIBUTES (protocol) = attributes; + if (deprecated) + TREE_DEPRECATED (protocol) = 1; + } + return protocol; } Index: objc/ChangeLog =================================================================== --- objc/ChangeLog (revision 166908) +++ objc/ChangeLog (working copy) @@ -1,3 +1,22 @@ +2010-11-18 Nicola Pero + + * objc-act.c (lookup_protocol): Added 'warn_if_deprecated' + argument. If it is 'true' and the protocol is deprecated, emit a + deprecation warning. + (objc_start_protocol): Do not warn that protocol attributes are + unimplemented. Pass the attributes to start_protocol. + (start_protocol): Added attributes argument. Recognize the + 'deprecated' attribute and mark the protocols with TREE_DEPRECATED + if present. Store attributes in the protocol. + (objc_declare_protocols): Added 'attributes' argument. Recognize + the 'deprecated' attribute and mark the protocols with + TREE_DEPRECATED if present. Store attributes in the protocol. + Updated call to lookup_protocol. + (objc_build_protocol_expr): Updated call to lookup_protocol. + (check_protocol_recursively): Same change. + (lookup_and_install_protocols): Same change. + * objc-act.h: Updated comments. + 2010-11-17 Nicola Pero * objc-act.c (lookup_method_in_protocol_list): Search methods in Index: objc/objc-act.h =================================================================== --- objc/objc-act.h (revision 166908) +++ objc/objc-act.h (working copy) @@ -166,11 +166,16 @@ typedef enum objc_property_assign_semant #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) + /* For CATEGORY_INTERFACE_TYPE, CLASS_INTERFACE_TYPE or PROTOCOL_INTERFACE_TYPE */ #define CLASS_PROPERTY_DECL(CLASS) TREE_VEC_ELT (TYPE_LANG_SLOT_1 (CLASS), 6) /* For CLASS_IMPLEMENTATION_TYPE or CATEGORY_IMPLEMENTATION_TYPE. */ #define IMPL_PROPERTY_DECL(CLASS) TREE_VEC_ELT (TYPE_LANG_SLOT_1 (CLASS), 6) +/* TREE_DEPRECATED is used for a CLASS_INTERFACE_TYPE or PROTOCOL_INTERFACE_TYPE. */ + +/* TYPE_ATTRIBUTES is used for a CLASS_INTERFACE_TYPE or PROTOCOL_INTERFACE_TYPE. */ + /* ObjC-specific information pertaining to RECORD_TYPEs are stored in the LANG_SPECIFIC structures, which may itself need allocating first. */ Index: ChangeLog =================================================================== --- ChangeLog (revision 166902) +++ ChangeLog (working copy) @@ -1,3 +1,8 @@ +2010-11-18 Nicola Pero + + * c-parser.c (c_parser_objc_protocol_definition): Pass attributes + to objc_declare_protocols. + 2010-11-18 Richard Guenther PR lto/46525 Index: testsuite/ChangeLog =================================================================== --- testsuite/ChangeLog (revision 166902) +++ testsuite/ChangeLog (working copy) @@ -1,3 +1,12 @@ +2010-11-18 Nicola Pero + + * objc.dg/attributes/proto-attribute-1.m: Updated. + * objc.dg/attributes/proto-attribute-2.m: New. + * objc.dg/attributes/proto-attribute-3.m: New. + * obj-c++.dg/attributes/proto-attribute-1.mm: Updated. + * obj-c++.dg/attributes/proto-attribute-2.mm: New. + * obj-c++.dg/attributes/proto-attribute-3.mm: New. + 2010-11-17 Steve Ellcey PR middle-end/31490 Index: testsuite/objc.dg/attributes/proto-attribute-1.m =================================================================== --- testsuite/objc.dg/attributes/proto-attribute-1.m (revision 166902) +++ testsuite/objc.dg/attributes/proto-attribute-1.m (working copy) @@ -1,14 +1,13 @@ /* { dg-do compile } */ #include -#include "../../objc-obj-c++-shared/Object1.h" __attribute ((deprecated)) @protocol dep_proto -- (int) depprotomth; /* { dg-warning "protocol attributes are not available in this version" } */ +- (int) depprotomth; @end -@interface obj : Object +@interface obj /* { dg-warning "is deprecated" } */ { @public int var; @@ -20,10 +19,3 @@ __attribute ((deprecated)) - (int) mth { return var; } - (int) depprotomth { return var + 1; } @end - -int foo (void) -{ - obj *p = [obj new]; - int q = [p depprotomth]; - return [p mth]; -} Index: testsuite/objc.dg/attributes/proto-attribute-2.m =================================================================== --- testsuite/objc.dg/attributes/proto-attribute-2.m (revision 0) +++ testsuite/objc.dg/attributes/proto-attribute-2.m (revision 0) @@ -0,0 +1,45 @@ +/* Contributed by Nicola Pero , November 2010. */ +/* { dg-do compile } */ + +/* Test deprecate attribute with a forward declarations of + @protocol. */ + +#include +#include +#include + +__attribute__ ((deprecated)) +@protocol DeprecatedProtocol1; + +@protocol NonDeprecatedProtocol1; + + +@interface Class1 /* { dg-warning "is deprecated" } */ +@end + +@interface Class2 +@end + +@interface Class3 /* { dg-warning "is deprecated" } */ +@end + +@interface Class2 (Category1) /* { dg-warning "is deprecated" } */ +@end + +void function1 (id object); /* { dg-warning "is deprecated" } */ +void function2 (id object); + +@class Class4; + +void function3 (Class4 *object); /* { dg-warning "is deprecated" } */ +void function4 (Class4 *object); +void function5 (Class4 *object); /* { dg-warning "is deprecated" } */ + +int function6 (void) +{ + Protocol *p1 = @protocol (DeprecatedProtocol1); /* { dg-warning "is deprecated" } */ + Protocol *p2 = @protocol (NonDeprecatedProtocol1); + + return (p1 == p2); +} + Index: testsuite/objc.dg/attributes/proto-attribute-3.m =================================================================== --- testsuite/objc.dg/attributes/proto-attribute-3.m (revision 0) +++ testsuite/objc.dg/attributes/proto-attribute-3.m (revision 0) @@ -0,0 +1,60 @@ +/* Contributed by Nicola Pero , November 2010. */ +/* { dg-do compile } */ + +/* Test deprecate attribute with normal @protocol declarations. */ + + +#include +#include +#include + +__attribute__ ((deprecated)) +@protocol DeprecatedProtocol1 +- (void) aMethod; +@end + +@protocol NonDeprecatedProtocol1 +- (void) anotherMethod; +@end + +@protocol Protocol2 /* { dg-warning "is deprecated" } */ +- (void) someOtherMethod; +@end + +@protocol Protocol3 +- (void) someOtherMethod2; +@end + +@protocol Protocol4 /* { dg-warning "is deprecated" } */ +- (void) someOtherMethod3; +@end + + +@interface Class1 /* { dg-warning "is deprecated" } */ +@end + +@interface Class2 +@end + +@interface Class3 /* { dg-warning "is deprecated" } */ +@end + +@interface Class2 (Category1) /* { dg-warning "is deprecated" } */ +@end + +void function1 (id object); /* { dg-warning "is deprecated" } */ +void function2 (id object); + +@class Class4; + +void function3 (Class4 *object); /* { dg-warning "is deprecated" } */ +void function4 (Class4 *object); +void function5 (Class4 *object); /* { dg-warning "is deprecated" } */ + +int function6 (void) +{ + Protocol *p1 = @protocol (DeprecatedProtocol1); /* { dg-warning "is deprecated" } */ + Protocol *p2 = @protocol (NonDeprecatedProtocol1); + + return (p1 == p2); +} Index: testsuite/obj-c++.dg/attributes/proto-attribute-1.mm =================================================================== --- testsuite/obj-c++.dg/attributes/proto-attribute-1.mm (revision 166902) +++ testsuite/obj-c++.dg/attributes/proto-attribute-1.mm (working copy) @@ -1,14 +1,13 @@ /* { dg-do compile } */ #include -#include "../../objc-obj-c++-shared/Object1.h" __attribute ((deprecated)) -@protocol dep_proto /* { dg-warning "protocol attributes are not available in this version" } */ -- (int) depprotomth; +@protocol dep_proto +- (int) depprotomth; @end -@interface obj : Object +@interface obj /* { dg-warning "is deprecated" } */ { @public int var; @@ -20,10 +19,3 @@ __attribute ((deprecated)) - (int) mth { return var; } - (int) depprotomth { return var + 1; } @end - -int foo (void) -{ - obj *p = [obj new]; - int q = [p depprotomth]; - return [p mth]; -} Index: testsuite/obj-c++.dg/attributes/proto-attribute-2.mm =================================================================== --- testsuite/obj-c++.dg/attributes/proto-attribute-2.mm (revision 0) +++ testsuite/obj-c++.dg/attributes/proto-attribute-2.mm (revision 0) @@ -0,0 +1,45 @@ +/* Contributed by Nicola Pero , November 2010. */ +/* { dg-do compile } */ + +/* Test deprecate attribute with a forward declarations of + @protocol. */ + +#include +#include +#include + +__attribute__ ((deprecated)) +@protocol DeprecatedProtocol1; + +@protocol NonDeprecatedProtocol1; + + +@interface Class1 /* { dg-warning "is deprecated" } */ +@end + +@interface Class2 +@end + +@interface Class3 /* { dg-warning "is deprecated" } */ +@end + +@interface Class2 (Category1) /* { dg-warning "is deprecated" } */ +@end + +void function1 (id object); /* { dg-warning "is deprecated" } */ +void function2 (id object); + +@class Class4; + +void function3 (Class4 *object); /* { dg-warning "is deprecated" } */ +void function4 (Class4 *object); +void function5 (Class4 *object); /* { dg-warning "is deprecated" } */ + +int function6 (void) +{ + Protocol *p1 = @protocol (DeprecatedProtocol1); /* { dg-warning "is deprecated" } */ + Protocol *p2 = @protocol (NonDeprecatedProtocol1); + + return (p1 == p2); +} + Index: testsuite/obj-c++.dg/attributes/proto-attribute-3.mm =================================================================== --- testsuite/obj-c++.dg/attributes/proto-attribute-3.mm (revision 0) +++ testsuite/obj-c++.dg/attributes/proto-attribute-3.mm (revision 0) @@ -0,0 +1,60 @@ +/* Contributed by Nicola Pero , November 2010. */ +/* { dg-do compile } */ + +/* Test deprecate attribute with normal @protocol declarations. */ + + +#include +#include +#include + +__attribute__ ((deprecated)) +@protocol DeprecatedProtocol1 +- (void) aMethod; +@end + +@protocol NonDeprecatedProtocol1 +- (void) anotherMethod; +@end + +@protocol Protocol2 /* { dg-warning "is deprecated" } */ +- (void) someOtherMethod; +@end + +@protocol Protocol3 +- (void) someOtherMethod2; +@end + +@protocol Protocol4 /* { dg-warning "is deprecated" } */ +- (void) someOtherMethod3; +@end + + +@interface Class1 /* { dg-warning "is deprecated" } */ +@end + +@interface Class2 +@end + +@interface Class3 /* { dg-warning "is deprecated" } */ +@end + +@interface Class2 (Category1) /* { dg-warning "is deprecated" } */ +@end + +void function1 (id object); /* { dg-warning "is deprecated" } */ +void function2 (id object); + +@class Class4; + +void function3 (Class4 *object); /* { dg-warning "is deprecated" } */ +void function4 (Class4 *object); +void function5 (Class4 *object); /* { dg-warning "is deprecated" } */ + +int function6 (void) +{ + Protocol *p1 = @protocol (DeprecatedProtocol1); /* { dg-warning "is deprecated" } */ + Protocol *p2 = @protocol (NonDeprecatedProtocol1); + + return (p1 == p2); +} Index: cp/ChangeLog =================================================================== --- cp/ChangeLog (revision 166902) +++ cp/ChangeLog (working copy) @@ -1,3 +1,8 @@ +2010-11-18 Nicola Pero + + * parser.c (cp_parser_objc_protocol_declaration): Pass attributes + to objc_declare_protocols. + 2010-11-16 Jason Merrill * call.c (convert_like_real): Don't make a temp for copy-list-init. Index: cp/parser.c =================================================================== --- cp/parser.c (revision 166902) +++ cp/parser.c (working copy) @@ -22314,7 +22314,8 @@ cp_parser_objc_protocol_declaration (cp_ /* Try a forward declaration first. */ if (tok->type == CPP_COMMA || tok->type == CPP_SEMICOLON) { - objc_declare_protocols (cp_parser_objc_identifier_list (parser)); + objc_declare_protocols (cp_parser_objc_identifier_list (parser), + attributes); finish: cp_parser_consume_semicolon_at_end_of_statement (parser); } Index: c-parser.c =================================================================== --- c-parser.c (revision 166902) +++ c-parser.c (working copy) @@ -7046,7 +7046,7 @@ c_parser_objc_protocol_definition (c_par break; } c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); - objc_declare_protocols (list); + objc_declare_protocols (list, attributes); } else {