diff options
-rw-r--r-- | gcc/c-family/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/c-family/c-common.c | 3 | ||||
-rw-r--r-- | gcc/c-family/c-common.h | 1 | ||||
-rw-r--r-- | gcc/c-family/stub-objc.c | 6 | ||||
-rw-r--r-- | gcc/objc/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/objc/objc-act.c | 89 | ||||
-rw-r--r-- | gcc/objc/objc-act.h | 1 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/testsuite/obj-c++.dg/attributes/method-attribute-1.mm | 19 | ||||
-rw-r--r-- | gcc/testsuite/obj-c++.dg/attributes/method-attribute-2.mm | 24 | ||||
-rw-r--r-- | gcc/testsuite/obj-c++.dg/attributes/method-attribute-3.mm | 4 | ||||
-rw-r--r-- | gcc/testsuite/objc.dg/attributes/method-attribute-1.m | 16 | ||||
-rw-r--r-- | gcc/testsuite/objc.dg/attributes/method-attribute-2.m | 24 | ||||
-rw-r--r-- | gcc/testsuite/objc.dg/attributes/method-attribute-3.m | 4 |
14 files changed, 166 insertions, 61 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 7790895..dde5c45 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,14 @@ +2010-10-13 Iain Sandoe <iains@gcc.gnu.org> + + merge from FSF apple 'trunk' branch. + 2006-04-26 Fariborz Jahanian <fjahanian@apple.com> + + Radar 3803157 (method attributes) + * c-common.c (handle_deprecated_attribute): Recognize + objc methods as valid declarations. + * c-common.h: Declare objc_method_decl (). + * stub-objc.c (objc_method_decl): New stub. + 2010-10-08 Joseph Myers <joseph@codesourcery.com> * c-common.c (parse_optimize_options): Call diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index ff3526b..49eb510 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -7189,7 +7189,8 @@ handle_deprecated_attribute (tree *node, tree name, || TREE_CODE (decl) == PARM_DECL || TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL - || TREE_CODE (decl) == FIELD_DECL) + || TREE_CODE (decl) == FIELD_DECL + || objc_method_decl (TREE_CODE (decl))) TREE_DEPRECATED (decl) = 1; else warn = 1; diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 3236e85..71efaf9 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -1009,6 +1009,7 @@ 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); extern void objc_finish_foreach_loop (location_t, tree, tree, tree, tree, tree); +extern bool objc_method_decl (enum tree_code); /* 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 5267584..6b8c334 100644 --- a/gcc/c-family/stub-objc.c +++ b/gcc/c-family/stub-objc.c @@ -217,6 +217,12 @@ objc_finish_method_definition (tree ARG_UNUSED (fndecl)) { } +bool +objc_method_decl (enum tree_code ARG_UNUSED(opcode)) +{ + return false; +} + tree objc_build_keyword_decl (tree ARG_UNUSED (selector), tree ARG_UNUSED (type), diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog index 133141c..ed1bc2e 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -1,3 +1,18 @@ +2010-10-13 Iain Sandoe <iains@gcc.gnu.org> + + merge from FSF apple 'trunk' branch. + + 2006-04-26 Fariborz Jahanian <fjahanian@apple.com> + Radar 3803157 (method attributes) + * objc/objc-act.h (METHOD_TYPE_ATTRIBUTES): New macro. + * objc/objc-act.c (objc_decl_method_attributes): New. + (objc_add_method_declaration): Process method's attribute. + (objc_start_method_definition): Ditto. + (build_objc_method_call): Inject method attribute into + built function type. + (objc_method_decl): New. + (objc_warn_deprecated)use): New. + 2010-10-07 Andi Kleen <ak@linux.intel.com> * Make-lang.in (cc1obj-dummy): Remove. diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index 3a13519..26d490e 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -52,6 +52,9 @@ along with GCC; see the file COPYING3. If not see #include "hashtab.h" #include "langhooks-def.h" +/* For default_tree_printer (). */ +#include "tree-pretty-print.h" + /* For enum gimplify_status */ #include "gimple.h" @@ -177,6 +180,9 @@ static void build_fast_enumeration_state_template (void); static void objc_generate_cxx_cdtors (void); #endif +/* objc attribute */ +static void objc_decl_method_attributes (tree*, tree, int); +static tree build_keyword_selector (tree); static const char *synth_id_with_class_suffix (const char *, tree); /* Hash tables to manage the global pool of method prototypes. */ @@ -215,6 +221,7 @@ static void really_start_method (tree, tree); static void really_start_method (tree, struct c_arg_info *); #endif static int comp_proto_with_proto (tree, tree, int); +static tree get_arg_type_list (tree, int, int); static tree objc_decay_parm_type (tree); static void objc_push_parm (tree); #ifdef OBJCPLUS @@ -511,6 +518,30 @@ generate_struct_by_value_array (void) exit (0); } +/* FIXME: We need to intercept calls to warn_deprecated_use, since that + ultimately calls warning () with a "qD" formatter for decls. The 'D' + formatter does not handle ObjC-specific decls (in ObjC++). For now, we + interpose a switch to the default handler which simply prints the decl + identifier. + Eventually, we should handle this within the objc{,p}/ code. */ + +static void +objc_warn_deprecated_use (tree depitem, tree attr) +{ + if (DECL_P (depitem)) + { + static bool (*sav_printer) (pretty_printer *, text_info *, const char *, + int, bool, bool, bool) = NULL ; + if (sav_printer == NULL) + sav_printer = diagnostic_format_decoder (global_dc) ; + diagnostic_format_decoder (global_dc) = &default_tree_printer; + warn_deprecated_use (depitem, attr); + diagnostic_format_decoder (global_dc) = sav_printer; + } + else + warn_deprecated_use (depitem, attr); +} + bool objc_init (void) { @@ -804,11 +835,7 @@ objc_add_method_declaration (tree decl, tree attributes) fatal_error ("method declaration not in @interface context"); } - if (attributes) - warning_at (input_location, OPT_Wattributes, - "method attributes are not available in this version" - " of the compiler, (ignored)"); - + objc_decl_method_attributes (&decl, attributes, 0); objc_add_method (objc_interface_context, decl, objc_inherit_code == CLASS_METHOD_DECL, @@ -830,11 +857,6 @@ objc_start_method_definition (tree decl, tree attributes) if (decl != NULL_TREE && METHOD_SEL_NAME (decl) == error_mark_node) return false; - if (attributes) - warning_at (input_location, OPT_Wattributes, - "method attributes are not available in this version" - " of the compiler, (ignored)"); - #ifndef OBJCPLUS /* Indicate no valid break/continue context by setting these variables to some non-null, non-label value. We'll notice and emit the proper @@ -842,6 +864,7 @@ objc_start_method_definition (tree decl, tree attributes) c_break_label = c_cont_label = size_zero_node; #endif + objc_decl_method_attributes (&decl, attributes, 0); objc_add_method (objc_implementation_context, decl, objc_inherit_code == CLASS_METHOD_DECL, @@ -6154,6 +6177,32 @@ build_method_decl (enum tree_code code, tree ret_type, tree selector, #define METHOD_DEF 0 #define METHOD_REF 1 +/* This routine processes objective-c method attributes. */ + +static void +objc_decl_method_attributes (tree *node, tree attributes, int flags) +{ + tree sentinel_attr = lookup_attribute ("sentinel", attributes); + if (sentinel_attr) + { + /* hackery to make an obj method look like a function type. */ + tree rettype = TREE_TYPE (*node); + TREE_TYPE (*node) = build_function_type (TREE_VALUE (rettype), + get_arg_type_list (*node, METHOD_REF, 0)); + decl_attributes (node, attributes, flags); + METHOD_TYPE_ATTRIBUTES (*node) = TYPE_ATTRIBUTES (TREE_TYPE (*node)); + TREE_TYPE (*node) = rettype; + } + else + decl_attributes (node, attributes, flags); +} + +bool +objc_method_decl (enum tree_code opcode) +{ + return opcode == INSTANCE_METHOD_DECL || opcode == CLASS_METHOD_DECL; +} + /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return an argument list for method METH. CONTEXT is either METHOD_DEF or METHOD_REF, saying whether we are trying to define a method or call @@ -6699,14 +6748,22 @@ build_objc_method_call (location_t loc, int super_flag, tree method_prototype, = (method_prototype ? TREE_VALUE (TREE_TYPE (method_prototype)) : objc_object_type); - tree sender_cast - = build_pointer_type - (build_function_type - (ret_type, - get_arg_type_list - (method_prototype, METHOD_REF, super_flag))); + + tree method_param_types = + get_arg_type_list (method_prototype, METHOD_REF, super_flag); + tree ftype = build_function_type (ret_type, method_param_types); + tree sender_cast; tree method, t; + if (method_prototype && METHOD_TYPE_ATTRIBUTES (method_prototype)) + ftype = build_type_attribute_variant ( + ftype, METHOD_TYPE_ATTRIBUTES (method_prototype)); + + sender_cast = build_pointer_type (ftype); + + if (method_prototype && TREE_DEPRECATED (method_prototype)) + objc_warn_deprecated_use (method_prototype, NULL_TREE); + lookup_object = build_c_cast (loc, rcv_p, lookup_object); /* Use SAVE_EXPR to avoid evaluating the receiver twice. */ diff --git a/gcc/objc/objc-act.h b/gcc/objc/objc-act.h index 9f6ddca..f7a0755 100644 --- a/gcc/objc/objc-act.h +++ b/gcc/objc/objc-act.h @@ -52,6 +52,7 @@ tree objc_eh_personality (void); #define METHOD_ADD_ARGS_ELLIPSIS_P(DECL) ((DECL)->decl_common.lang_flag_0) #define METHOD_DEFINITION(DECL) ((DECL)->decl_common.initial) #define METHOD_ENCODING(DECL) ((DECL)->decl_minimal.context) +#define METHOD_TYPE_ATTRIBUTES(DECL) ((DECL)->decl_common.abstract_origin) /* CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE, CATEGORY_INTERFACE_TYPE, CATEGORY_IMPLEMENTATION_TYPE, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0c0803e..f5a2377 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2010-10-13 Iain Sandoe <iains@gcc.gnu.org> + + * objc.dg/attributes/method-attribute-1.m: Update to respond + to implemented method attributes.. + * objc.dg/attributes/method-attribute-2.m: Likewise. + * objc.dg/attributes/method-attribute-3.m: Likewise. + * obj-c++.dg/attributes/method-attribute-1.mm: Likewise. + * obj-c++.dg/attributes/method-attribute-2.mm: Likewise. + * obj-c++.dg/attributes/method-attribute-3.mm: Likewise. + 2010-10-13 Nicola Pero <nicola.pero@meta-innovation.com> PR libobjc/23214 diff --git a/gcc/testsuite/obj-c++.dg/attributes/method-attribute-1.mm b/gcc/testsuite/obj-c++.dg/attributes/method-attribute-1.mm index 2e2326c..747deab 100644 --- a/gcc/testsuite/obj-c++.dg/attributes/method-attribute-1.mm +++ b/gcc/testsuite/obj-c++.dg/attributes/method-attribute-1.mm @@ -8,13 +8,12 @@ int var; } - (int) mth; -+ (id) dep_cls_mth __attribute__((deprecated)) ;/* { dg-warning "method attributes are not available in this version" } */ -- (int) dep_ins_mth __attribute__((deprecated)) ;/* { dg-warning "method attributes are not available in this version" } */ -- (int) dep_ins_mtharg: (int) i __attribute__((deprecated)) ;/* { dg-warning "method attributes are not available in this version" } */ ++ (id) dep_cls_mth __attribute__((deprecated)) ; +- (int) dep_ins_mth __attribute__((deprecated)) ; +- (int) dep_ins_mtharg: (int) i __attribute__((deprecated)) ; - (int) dep_ins_mtharg1: (int) i __attribute__((deprecated)) add: (int) j;/* { dg-error "method attributes must be specified at the end " } */ - (int) nodef __attribute__((deprecated)) { return var-2; } ; /* { dg-error "expected ';' before '\{' token" } */ - /* { dg-warning "method attributes are not available in this version" "" { target *-*-* } 15 } */ -__attribute__((deprecated)) +__attribute__((deprecated)) - (int) bad_pref_mth; /* { dg-warning "prefix attributes are ignored for methods" } */ @end @@ -31,11 +30,11 @@ __attribute__((deprecated)) int foo (void) { obj *p = [obj new]; - id n = [obj dep_cls_mth]; + id n = [obj dep_cls_mth]; /* { dg-warning "is deprecated" } */ - [p dep_ins_mth]; - [p dep_ins_mtharg:2]; + [p dep_ins_mth]; /* { dg-warning "is deprecated" } */ + [p dep_ins_mtharg:2]; /* { dg-warning "is deprecated" } */ [p dep_ins_mtharg1:3 add:3]; - - return [p mth]; + + return [p mth]; } diff --git a/gcc/testsuite/obj-c++.dg/attributes/method-attribute-2.mm b/gcc/testsuite/obj-c++.dg/attributes/method-attribute-2.mm index f02149e..5a7b487 100644 --- a/gcc/testsuite/obj-c++.dg/attributes/method-attribute-2.mm +++ b/gcc/testsuite/obj-c++.dg/attributes/method-attribute-2.mm @@ -7,25 +7,27 @@ @public int var; } -- (int) depmtharg:(int) iarg __attribute__((deprecated)); /* { dg-warning "method attributes are not available in this version" } */ -- (int) unusedarg:(int) __attribute__((unused)) uarg ; /* { dg-warning "method parameter attributes are not available in this version" } */ -- (int) depunusedarg:(int) __attribute__((unused)) uarg __attribute__((deprecated)) ; /* { dg-warning "method attributes are not available in this version" } */ - /* { dg-warning "method parameter attributes are not available in this version" "" { target *-*-* } 12 } */ +- (int) depmth __attribute__((deprecated)); +- (int) depmtharg:(int) iarg __attribute__((deprecated)); +- (int) unusedarg:(int) __attribute__((unused)) uarg ; /* { dg-warning "method parameter attributes are not available in this version" } */ +- (int) depunusedarg:(int) __attribute__((unused)) uarg __attribute__((deprecated)) ; /* { dg-warning "method parameter attributes are not available in this version" } */ @end @implementation obj -- (int) depmtharg:(int) iarg { return var + iarg ; }; -- (int) unusedarg:(int) __attribute__((unused)) uarg { return var; } ; /* { dg-warning "method parameter attributes are not available in this version" } */ -- (int) depunusedarg:(int) __attribute__((unused)) uarg { return var; }; /* { dg-warning "method parameter attributes are not available in this version" } */ +- (int) depmth __attribute__((deprecated)) { return var; } +- (int) depmtharg:(int) iarg { return var + iarg ; } +- (int) unusedarg:(int) __attribute__((unused)) uarg { return var; } /* { dg-warning "method parameter attributes are not available in this version" } */ +- (int) depunusedarg:(int) __attribute__((unused)) uarg { return var; } /* { dg-warning "method parameter attributes are not available in this version" } */ @end int foo (void) { obj *p = [obj new]; - [p depmtharg:1]; - [p unusedarg:2]; - [p depunusedarg:3 ]; + [p depmth]; /* { dg-warning "is deprecated" } */ + [p depmtharg:1]; /* { dg-warning "is deprecated" } */ + [p unusedarg:2]; /* { dg-bogus "is deprecated" } */ + [p depunusedarg:3 ]; /* { dg-warning "is deprecated" } */ - return [p depmtharg:0]; + return [p depmtharg:0]; /* { dg-warning "is deprecated" } */ } diff --git a/gcc/testsuite/obj-c++.dg/attributes/method-attribute-3.mm b/gcc/testsuite/obj-c++.dg/attributes/method-attribute-3.mm index 05b9884..bab40d3 100644 --- a/gcc/testsuite/obj-c++.dg/attributes/method-attribute-3.mm +++ b/gcc/testsuite/obj-c++.dg/attributes/method-attribute-3.mm @@ -6,7 +6,7 @@ @public int var; } -- (int) vargsn: (int) count, ... __attribute__((deprecated)); /* { dg-warning " method attributes are not available in this version of the compiler" } */ +- (int) vargsn: (int) count, ... __attribute__((deprecated)); @end @implementation obj @@ -20,5 +20,5 @@ int foo (void) { obj *p = [obj new]; - return [p vargsn:0]; + return [p vargsn:0]; /* { dg-warning "'vargsn:' is deprecated .declared at" } */ } diff --git a/gcc/testsuite/objc.dg/attributes/method-attribute-1.m b/gcc/testsuite/objc.dg/attributes/method-attribute-1.m index 83bc1c0..ffe72e2 100644 --- a/gcc/testsuite/objc.dg/attributes/method-attribute-1.m +++ b/gcc/testsuite/objc.dg/attributes/method-attribute-1.m @@ -8,9 +8,9 @@ int var; } - (int) mth; -+ (id) dep_cls_mth __attribute__((deprecated)) ;/* { dg-warning "method attributes are not available in this version" } */ -- (int) dep_ins_mth __attribute__((deprecated)) ;/* { dg-warning "method attributes are not available in this version" } */ -- (int) dep_ins_mtharg: (int) i __attribute__((deprecated)) ;/* { dg-warning "method attributes are not available in this version" } */ ++ (id) dep_cls_mth __attribute__((deprecated)) ; +- (int) dep_ins_mth __attribute__((deprecated)) ; +- (int) dep_ins_mtharg: (int) i __attribute__((deprecated)) ; - (int) dep_ins_mtharg1: (int) i __attribute__((deprecated)) add: (int) j;/* { dg-error "expected ';' or '\{' after method attribute definition" } */ - (int) nodef __attribute__((deprecated)) { return var-2; } ; /* { dg-error "expected ';' before '\{' token" } */ __attribute__((deprecated)) @@ -30,11 +30,11 @@ __attribute__((deprecated)) int foo (void) { obj *p = [obj new]; - id n = [obj dep_cls_mth]; + id n = [obj dep_cls_mth]; /* { dg-warning "is deprecated" } */ - [p dep_ins_mth]; - [p dep_ins_mtharg:2]; + [p dep_ins_mth]; /* { dg-warning "is deprecated" } */ + [p dep_ins_mtharg:2]; /* { dg-warning "is deprecated" } */ [p dep_ins_mtharg1:3 add:3]; - - return [p mth]; + + return [p mth]; } diff --git a/gcc/testsuite/objc.dg/attributes/method-attribute-2.m b/gcc/testsuite/objc.dg/attributes/method-attribute-2.m index f02149e..5a7b487 100644 --- a/gcc/testsuite/objc.dg/attributes/method-attribute-2.m +++ b/gcc/testsuite/objc.dg/attributes/method-attribute-2.m @@ -7,25 +7,27 @@ @public int var; } -- (int) depmtharg:(int) iarg __attribute__((deprecated)); /* { dg-warning "method attributes are not available in this version" } */ -- (int) unusedarg:(int) __attribute__((unused)) uarg ; /* { dg-warning "method parameter attributes are not available in this version" } */ -- (int) depunusedarg:(int) __attribute__((unused)) uarg __attribute__((deprecated)) ; /* { dg-warning "method attributes are not available in this version" } */ - /* { dg-warning "method parameter attributes are not available in this version" "" { target *-*-* } 12 } */ +- (int) depmth __attribute__((deprecated)); +- (int) depmtharg:(int) iarg __attribute__((deprecated)); +- (int) unusedarg:(int) __attribute__((unused)) uarg ; /* { dg-warning "method parameter attributes are not available in this version" } */ +- (int) depunusedarg:(int) __attribute__((unused)) uarg __attribute__((deprecated)) ; /* { dg-warning "method parameter attributes are not available in this version" } */ @end @implementation obj -- (int) depmtharg:(int) iarg { return var + iarg ; }; -- (int) unusedarg:(int) __attribute__((unused)) uarg { return var; } ; /* { dg-warning "method parameter attributes are not available in this version" } */ -- (int) depunusedarg:(int) __attribute__((unused)) uarg { return var; }; /* { dg-warning "method parameter attributes are not available in this version" } */ +- (int) depmth __attribute__((deprecated)) { return var; } +- (int) depmtharg:(int) iarg { return var + iarg ; } +- (int) unusedarg:(int) __attribute__((unused)) uarg { return var; } /* { dg-warning "method parameter attributes are not available in this version" } */ +- (int) depunusedarg:(int) __attribute__((unused)) uarg { return var; } /* { dg-warning "method parameter attributes are not available in this version" } */ @end int foo (void) { obj *p = [obj new]; - [p depmtharg:1]; - [p unusedarg:2]; - [p depunusedarg:3 ]; + [p depmth]; /* { dg-warning "is deprecated" } */ + [p depmtharg:1]; /* { dg-warning "is deprecated" } */ + [p unusedarg:2]; /* { dg-bogus "is deprecated" } */ + [p depunusedarg:3 ]; /* { dg-warning "is deprecated" } */ - return [p depmtharg:0]; + return [p depmtharg:0]; /* { dg-warning "is deprecated" } */ } diff --git a/gcc/testsuite/objc.dg/attributes/method-attribute-3.m b/gcc/testsuite/objc.dg/attributes/method-attribute-3.m index 05b9884..de607a3 100644 --- a/gcc/testsuite/objc.dg/attributes/method-attribute-3.m +++ b/gcc/testsuite/objc.dg/attributes/method-attribute-3.m @@ -6,7 +6,7 @@ @public int var; } -- (int) vargsn: (int) count, ... __attribute__((deprecated)); /* { dg-warning " method attributes are not available in this version of the compiler" } */ +- (int) vargsn: (int) count, ... __attribute__((deprecated)); @end @implementation obj @@ -20,5 +20,5 @@ int foo (void) { obj *p = [obj new]; - return [p vargsn:0]; + return [p vargsn:0]; /* { dg-warning "'vargsn:' is deprecated .declared at " } */ } |