Patchwork [ObjC*] merge of apple local implementation of method attributes.

login
register
mail settings
Submitter IainS
Date Oct. 12, 2010, 8:03 p.m.
Message ID <72F24C0C-CB38-4D25-B769-B573CD20ED18@sandoe-acoustics.co.uk>
Download mbox | patch
Permalink /patch/67608/
State New
Headers show

Comments

IainS - Oct. 12, 2010, 8:03 p.m.
Whilst this almost falls within Mike's pre-approval for merges from  
the FSF apple-local branch, there is one line that is outside ObjC  
locality.

May we have approval for the following change to c-family/c-common.c?
Iain



====

complete Changelog and patches:

gcc:

	merge from FSF apple-local/trunk

	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.

gcc/objc:

	merge from FSF apple-local/trunk

	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.
Index: gcc/objc/objc-act.c
===================================================================
--- gcc/objc/objc-act.c	(revision 165375)
+++ gcc/objc/objc-act.c	(working copy)
@@ -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
 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 attri
       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 attr
   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 attr
   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_t
 #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_
     = (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.  */
Index: gcc/objc/objc-act.h
===================================================================
--- gcc/objc/objc-act.h	(revision 165375)
+++ gcc/objc/objc-act.h	(working copy)
@@ -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,
Index: gcc/c-family/c-common.c
===================================================================
--- gcc/c-family/c-common.c	(revision 165375)
+++ gcc/c-family/c-common.c	(working copy)
@@ -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;
Index: gcc/c-family/c-common.h
===================================================================
--- gcc/c-family/c-common.h	(revision 165375)
+++ gcc/c-family/c-common.h	(working copy)
@@ -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++.  */
Index: gcc/c-family/stub-objc.c
===================================================================
--- gcc/c-family/stub-objc.c	(revision 165375)
+++ gcc/c-family/stub-objc.c	(working copy)
@@ -217,6 +217,12 @@ objc_finish_method_definition (tree ARG_UNUSED (fn
 {
 }
 
+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),
testsuite:

	* 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.
Index: gcc/testsuite/obj-c++.dg/attributes/method-attribute-1.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/attributes/method-attribute-1.mm	(revision 165375)
+++ gcc/testsuite/obj-c++.dg/attributes/method-attribute-1.mm	(working copy)
@@ -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 @@
 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];
 }
Index: gcc/testsuite/obj-c++.dg/attributes/method-attribute-2.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/attributes/method-attribute-2.mm	(revision 165375)
+++ gcc/testsuite/obj-c++.dg/attributes/method-attribute-2.mm	(working copy)
@@ -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" } */   
 }
Index: gcc/testsuite/obj-c++.dg/attributes/method-attribute-3.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/attributes/method-attribute-3.mm	(revision 165375)
+++ gcc/testsuite/obj-c++.dg/attributes/method-attribute-3.mm	(working copy)
@@ -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" } */
 }
Index: gcc/testsuite/objc.dg/attributes/method-attribute-1.m
===================================================================
--- gcc/testsuite/objc.dg/attributes/method-attribute-1.m	(revision 165375)
+++ gcc/testsuite/objc.dg/attributes/method-attribute-1.m	(working copy)
@@ -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];
 }
Index: gcc/testsuite/objc.dg/attributes/method-attribute-2.m
===================================================================
--- gcc/testsuite/objc.dg/attributes/method-attribute-2.m	(revision 165375)
+++ gcc/testsuite/objc.dg/attributes/method-attribute-2.m	(working copy)
@@ -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" } */   
 }
Index: gcc/testsuite/objc.dg/attributes/method-attribute-3.m
===================================================================
--- gcc/testsuite/objc.dg/attributes/method-attribute-3.m	(revision 165375)
+++ gcc/testsuite/objc.dg/attributes/method-attribute-3.m	(working copy)
@@ -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 " } */
 }
Joseph S. Myers - Oct. 12, 2010, 8:27 p.m.
On Tue, 12 Oct 2010, IainS wrote:

> Whilst this almost falls within Mike's pre-approval for merges from the FSF
> apple-local branch, there is one line that is outside ObjC locality.
> 
> May we have approval for the following change to c-family/c-common.c?

This c-family change is OK.
IainS - Oct. 13, 2010, 8:26 a.m.
On 12 Oct 2010, at 21:27, Joseph S. Myers wrote:

> On Tue, 12 Oct 2010, IainS wrote:
>
>> Whilst this almost falls within Mike's pre-approval for merges from  
>> the FSF
>> apple-local branch, there is one line that is outside ObjC locality.
>>
>> May we have approval for the following change to c-family/c-common.c?
>
> This c-family change is OK.

thanks, committed as r165415.
Iain

Patch

Index: gcc/c-family/c-common.c
===================================================================
--- gcc/c-family/c-common.c	(revision 165375)
+++ gcc/c-family/c-common.c	(working copy)
@@ -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;


where the stub implementation of objc_method_decl () is:

Index: gcc/c-family/stub-objc.c
===================================================================
--- gcc/c-family/stub-objc.c	(revision 165375)
+++ gcc/c-family/stub-objc.c	(working copy)
@@ -217,6 +217,12 @@  objc_finish_method_definition (tree ARG_UNUSED (fn
  {
  }

+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),