Patchwork ObjC/ObjC++: finished implementation of method parameter attributes, and cleanup of DECLs printable names

login
register
mail settings
Submitter Nicola Pero
Date Oct. 23, 2010, 11:39 p.m.
Message ID <1287877153.30568636@192.168.2.229>
Download mbox | patch
Permalink /patch/69021/
State New
Headers show

Comments

Nicola Pero - Oct. 23, 2010, 11:39 p.m.
Today's new patch does two things:

 1* it finishes the implementation of method parameter attributes for Objective-C and Objective-C++ (Iain
had done the parsing).  The implementation is really simple; I also added 4 testcases, two testing that
__attribute__((unused)) works correctly in Objective-C and Objective-C++, and two testing that invalid attributes 
(eg, __attribute__((xxxxx)) or __attribute__((noinline)) for a method parameter) produce the right warnings. 
It all works. :-)

 2* it cleans up the code for the ObjC/ObjC++ "printable name" of decls even more.  It was still messy and we had
this new objc_warn_deprecated hack where we had to replace the formatter before calling warn_deprecated to get ObjC 
method names printed in deprecation warnings.  This patch solves that.  The solution is very simple: in ObjC we 
use objc_printable_name as langhook (as we already did), while in ObjC++ we leave the default C++ cxx_printable_name 
hook in place (since replacing it didn't help with code that calls directly dump_decl, such as the deprecation warnings), 
but we added a tiny piece of code inside C++'s dump_decl so that, if it's compiling ObjC++, it will call 
objc_maybe_printable_name and use the results (if any) before going on with the C++ stuff.  That works great because 
it means all the stuff generating messages in C++ (which calls dump_decl and lots of other C++-specific functions 
directly) will now print Objc method names correctly (they all end up calling dump_decl in the end).  And we will 
now be able to implement pretty-printing of method declarations for method deprecation warnings (something I'd like to do 
at some point).  Anyway, fundamentally this rearrangement means I could get rid of objc_warn_deprecated and the associated
FIXME. :-)

By the way, I apologize for sending two unrelated changes in the same patch.  My trees 
got confused.  It won't happen again.

Ok to apply to trunk ?

Thanks

In gcc/cp/:
2010-10-24  Nicola Pero  <nicola.pero@meta-innovation.com>

        Removed Objective-C++ specific replacement of cxx_printable_name.
        * cp-objcp-common.h: Added LANG_HOOKS_DECL_PRINTABLE_NAME, set
        to cxx_printable_name for both C++ and Objective-C++.
        * cp-lang.h: Removed LANG_HOOKS_DECL_PRINTABLE_NAME.

        * error.c (dump_decl): For Objective-C++, call
        objc_maybe_printable_name here ...
        * tree.c (cxx_printable_name_internal): ... instead of here.

In gcc/objcp/:
2010-10-24  Nicola Pero  <nicola.pero@meta-innovation.com>

        * objcp-lang.c (LANG_HOOKS_DECL_PRINTABLE_NAME): Do not define.

In gcc/objc/:
2010-10-24  Nicola Pero  <nicola.pero@meta-innovation.com>

        * objc-act.c (objc_build_keyword_decl): Updated comments.  Do not
        emit a warning that method parameter attributes are unimplemented.
        Instead, store them into DECL_ATTRIBUTES of the KEYWORD_DECL.
        (start_method_def): Copy attributes from each KEYWORD_DECL into
        the corresponding PARM_DECL.
        (objc_warn_deprecated_use): Removed.
        (build_objc_method_call): Call warn_deprecated_use, not
        objc_warn_deprecated_use.
        (objc_maybe_printable_name): Do not try to get the identifier name
        of DECLs that we don't recognize.  Immediately return NULL for them.
        (objc_printable_name): Removed C++-specific case, which is no
        longer used.  Updated comments.

In gcc/testsuite/:
2010-10-24  Nicola Pero  <nicola.pero@meta-innovation.com>

        * objc.dg/attributes/method-attribute-2.m: Updated test.  Method
        parameter attributes are now supported.
        * obj-c++.dg/attributes/method-attribute-2.m: Same change.
        * objc.dg/attributes/parameter-attribute-1.m: New test.
        * objc.dg/attributes/parameter-attribute-2.m: New test.
        * obj-c++.dg/attributes/parameter-attribute-1.m: New test.
        * obj-c++.dg/attributes/parameter-attribute-2.m: New test.
Mike Stump - Oct. 24, 2010, 2:33 a.m.
On Oct 23, 2010, at 4:39 PM, Nicola Pero wrote:
> Ok to apply to trunk ?

Ok.

Patch

Index: gcc/objc/objc-act.c
===================================================================
--- gcc/objc/objc-act.c	(revision 165887)
+++ gcc/objc/objc-act.c	(working copy)
@@ -555,30 +555,6 @@  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)
 {
@@ -6546,36 +6522,44 @@  adjust_type_for_id_default (tree type)
   return type;
 }
 
-/*   Usage:
-		keyworddecl:
-			selector ':' '(' typename ')' identifier
+/* Return a KEYWORD_DECL built using the specified key_name, arg_type,
+   arg_name and attributes. (TODO: Rename KEYWORD_DECL to
+   OBJC_METHOD_PARM_DECL ?)
 
-     Purpose:
-		Transform an Objective-C keyword argument into
-		the C equivalent parameter declarator.
+   A KEYWORD_DECL is a tree representing the declaration of a
+   parameter of an Objective-C method.  It is produced when parsing a
+   fragment of Objective-C method declaration of the form
 
-     In:	key_name, an "identifier_node" (optional).
-		arg_type, a  "tree_list" (optional).
-		arg_name, an "identifier_node".
-		attributes, a optional tree containing param attributes.
+   keyworddecl:
+     selector ':' '(' typename ')' identifier
 
-     Note:	It would be really nice to strongly type the preceding
-		arguments in the function prototype; however, then I
-		could not use the "accessor" macros defined in "tree.h".
+   For example, take the Objective-C method
 
-     Out:	an instance of "keyword_decl".  */
+   -(NSString *)pathForResource:(NSString *)resource ofType:(NSString *)type; 
 
+   the two fragments "pathForResource:(NSString *)resource" and
+   "ofType:(NSString *)type" will generate a KEYWORD_DECL each.  The
+   KEYWORD_DECL stores the 'key_name' (eg, identifier for
+   "pathForResource"), the 'arg_type' (eg, tree representing a
+   NSString *), the 'arg_name' (eg identifier for "resource") and
+   potentially some attributes (for example, a tree representing
+   __attribute__ ((unused)) if such an attribute was attached to a
+   certain parameter).  You can access this information using the
+   TREE_TYPE (for arg_type), KEYWORD_ARG_NAME (for arg_name),
+   KEYWORD_KEY_NAME (for key_name), DECL_ATTRIBUTES (for attributes).
+
+   'key_name' is an identifier node (and is optional as you can omit
+   it in Objective-C methods).
+   'arg_type' is a tree list (and is optional too if no parameter type
+   was specified).
+   'arg_name' is an identifier node and is required.
+   'attributes' is an optional tree containing parameter attributes.  */
 tree
 objc_build_keyword_decl (tree key_name, tree arg_type, 
 			 tree arg_name, tree attributes)
 {
   tree keyword_decl;
 
-  if (attributes)
-    warning_at (input_location, OPT_Wattributes, 
-		"method parameter attributes are not available in this "
-		"version of the compiler, (ignored)");
-
   /* If no type is specified, default to "id".  */
   arg_type = adjust_type_for_id_default (arg_type);
 
@@ -6584,6 +6568,7 @@  objc_build_keyword_decl (tree key_name, tree arg_t
   TREE_TYPE (keyword_decl) = arg_type;
   KEYWORD_ARG_NAME (keyword_decl) = arg_name;
   KEYWORD_KEY_NAME (keyword_decl) = key_name;
+  DECL_ATTRIBUTES (keyword_decl) = attributes;
 
   return keyword_decl;
 }
@@ -7278,7 +7263,7 @@  build_objc_method_call (location_t loc, int super_
   sender_cast = build_pointer_type (ftype);
 
   if (method_prototype && TREE_DEPRECATED (method_prototype))
-    objc_warn_deprecated_use (method_prototype, NULL_TREE);
+    warn_deprecated_use (method_prototype, NULL_TREE);
 
   lookup_object = build_c_cast (loc, rcv_p, lookup_object);
 
@@ -9918,10 +9903,13 @@  start_method_def (tree method)
   parmlist = METHOD_SEL_ARGS (method);
   while (parmlist)
     {
-      tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
+      /* parmlist is a KEYWORD_DECL.  */
+      tree type = TREE_VALUE (TREE_TYPE (parmlist));
+      tree parm;
 
       parm = build_decl (input_location,
 			 PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
+      decl_attributes (&parm, DECL_ATTRIBUTES (parmlist), 0);
       objc_push_parm (parm);
       parmlist = DECL_CHAIN (parmlist);
     }
@@ -10083,7 +10071,6 @@  objc_start_function (tree name, tree type, tree at
 #else
   current_function_returns_value = 0;  /* Assume, until we see it does.  */
   current_function_returns_null = 0;
-
   decl_attributes (&fndecl, attrs, 0);
   announce_function (fndecl);
   DECL_INITIAL (fndecl) = error_mark_node;
@@ -10766,26 +10753,25 @@  objc_demangle (const char *mangled)
 const char *
 objc_maybe_printable_name (tree decl, int v ATTRIBUTE_UNUSED)
 {
-  const char *decl_name = IDENTIFIER_POINTER (DECL_NAME (decl));  
-
   switch (TREE_CODE (decl))
     {
     case FUNCTION_DECL:
-      return objc_demangle (decl_name);
+      return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
       break;
-      /* This unusual case (INSTANCE_METHOD_DECL and
-	 CLASS_METHOD_DECL) seems to happen only in ObjC++ and to be a
-	 by-product of the method attribute changes.  It would be nice
-	 to be able to print "-[NSObject autorelease] is deprecated",
-	 but to do that, we'd need to store the class and method name
-	 in the method decl, which we currently don't do.  For now,
-	 just return the name of the method.  We don't return NULL,
-	 because that may trigger further attempts to pretty-print the
-	 decl in C/C++, but they wouldn't know how to pretty-print
-	 it.  */
+
+      /* The following happens when we are printing a deprecation
+	 warning for a method.  The warn_deprecation() will end up
+	 trying to print the decl for INSTANCE_METHOD_DECL or
+	 CLASS_METHOD_DECL.  It would be nice to be able to print
+	 "-[NSObject autorelease] is deprecated", but to do that, we'd
+	 need to store the class and method name in the method decl,
+	 which we currently don't do.  For now, just return the name
+	 of the method.  We don't return NULL, because that may
+	 trigger further attempts to pretty-print the decl in C/C++,
+	 but they wouldn't know how to pretty-print it.  */
     case INSTANCE_METHOD_DECL:
     case CLASS_METHOD_DECL:
-      return decl_name;
+      return IDENTIFIER_POINTER (DECL_NAME (decl));
       break;
     default:
       return NULL;
@@ -10794,9 +10780,12 @@  objc_maybe_printable_name (tree decl, int v ATTRIB
 }
 
 /* Return a printable name for 'decl'.  This first tries
-   objc_maybe_printable_name(), and if that fails, it hands it back to
-   C/C++.  'v' is the verbosity level, as this is a
-   LANG_HOOKS_DECL_PRINTABLE_NAME.  */
+   objc_maybe_printable_name(), and if that fails, it returns the name
+   in the decl.  This is used as LANG_HOOKS_DECL_PRINTABLE_NAME for
+   Objective-C; in Objective-C++, setting the hook is not enough
+   because lots of C++ Front-End code calls cxx_printable_name,
+   dump_decl and other C++ functions directly.  So instead we have
+   modified dump_decl to call objc_maybe_printable_name directly.  */
 const char *
 objc_printable_name (tree decl, int v)
 {
@@ -10805,13 +10794,7 @@  objc_printable_name (tree decl, int v)
   if (demangled_name != NULL)
     return demangled_name;
   else
-    {
-#ifdef OBJCPLUS
-      return cxx_printable_name (decl, v);
-#else
-      return IDENTIFIER_POINTER (DECL_NAME (decl));
-#endif
-    }
+    return IDENTIFIER_POINTER (DECL_NAME (decl));
 }
 
 static void
Index: gcc/objc/ChangeLog
===================================================================
--- gcc/objc/ChangeLog	(revision 165887)
+++ gcc/objc/ChangeLog	(working copy)
@@ -1,3 +1,18 @@ 
+2010-10-24  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+	* objc-act.c (objc_build_keyword_decl): Updated comments.  Do not
+	emit a warning that method parameter attributes are unimplemented.
+	Instead, store them into DECL_ATTRIBUTES of the KEYWORD_DECL.
+	(start_method_def): Copy attributes from each KEYWORD_DECL into
+	the corresponding PARM_DECL.
+	(objc_warn_deprecated_use): Removed.
+	(build_objc_method_call): Call warn_deprecated_use, not
+	objc_warn_deprecated_use.
+	(objc_maybe_printable_name): Do not try to get the identifier name
+	of DECLs that we don't recognize.  Immediately return NULL for them.
+	(objc_printable_name): Removed C++-specific case, which is no
+	longer used.  Updated comments.
+	
 2010-10-23  Nicola Pero  <nicola.pero@meta-innovation.com>
 
 	* objc-act.c (OBJC_GEN_METHOD_LABEL): Updated comments.
Index: gcc/testsuite/ChangeLog
===================================================================
--- gcc/testsuite/ChangeLog	(revision 165887)
+++ gcc/testsuite/ChangeLog	(working copy)
@@ -1,3 +1,13 @@ 
+2010-10-24  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+	* objc.dg/attributes/method-attribute-2.m: Updated test.  Method
+	parameter attributes are now supported.
+	* obj-c++.dg/attributes/method-attribute-2.m: Same change.
+	* objc.dg/attributes/parameter-attribute-1.m: New test.
+	* objc.dg/attributes/parameter-attribute-2.m: New test.	
+	* obj-c++.dg/attributes/parameter-attribute-1.m: New test.
+	* obj-c++.dg/attributes/parameter-attribute-2.m: New test.	
+	
 2010-10-23  Nicola Pero  <nicola.pero@meta-innovation.com>
 
 	* objc.dg/demangle-1.m: New test.
Index: gcc/testsuite/objc.dg/attributes/parameter-attribute-1.m
===================================================================
--- gcc/testsuite/objc.dg/attributes/parameter-attribute-1.m	(revision 0)
+++ gcc/testsuite/objc.dg/attributes/parameter-attribute-1.m	(revision 0)
@@ -0,0 +1,45 @@ 
+/* Test __attribute__((unused)) for an Objective-C method parameter.  */
+/* { dg-do compile } */
+/* { dg-options "-Wunused-parameter" } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+  Class isa;
+}
+- (id) method1: (id) argument1;
+- (id) method2: (id) __attribute__((unused)) argument1;
+- (id) method3: (id) __attribute__((unused)) argument1
+   andArgument: (id) argument2;
+- (id) method4: (id) __attribute__((unused)) argument1
+   andArgument: (id) __attribute__((unused)) argument2;
+- (id) method5: (id) argument1
+   andArgument: (id) __attribute__ ((unused)) argument2;
+@end
+
+@implementation MyRootClass
+- (id) method1: (id) argument1
+{ /* { dg-warning "unused parameter .argument1." } */
+  return nil;
+}
+- (id) method2: (id) __attribute__((unused)) argument1
+{
+  return nil;
+}
+- (id) method3: (id) __attribute__((unused)) argument1
+   andArgument: (id) argument2
+{ /* { dg-warning "unused parameter .argument2." } */
+  return nil;
+}
+- (id) method4: (id) __attribute__((unused)) argument1
+   andArgument: (id) __attribute__((unused)) argument2
+{
+  return nil;
+}
+- (id) method5: (id) argument1
+   andArgument: (id) __attribute__ ((unused)) argument2
+{ /* { dg-warning "unused parameter .argument1." } */
+  return nil;
+}
+@end
Index: gcc/testsuite/objc.dg/attributes/method-attribute-2.m
===================================================================
--- gcc/testsuite/objc.dg/attributes/method-attribute-2.m	(revision 165885)
+++ gcc/testsuite/objc.dg/attributes/method-attribute-2.m	(working copy)
@@ -9,15 +9,15 @@ 
 } 
 - (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" } */
+- (int) unusedarg:(int) __attribute__((unused)) uarg ;
+- (int) depunusedarg:(int) __attribute__((unused)) uarg __attribute__((deprecated)) ;
 @end
 
 @implementation obj
 - (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" } */
+- (int) unusedarg:(int) __attribute__((unused)) uarg { return var; }
+- (int) depunusedarg:(int) __attribute__((unused)) uarg { return var; }
 @end 
 
 int foo (void)
Index: gcc/testsuite/objc.dg/attributes/parameter-attribute-2.m
===================================================================
--- gcc/testsuite/objc.dg/attributes/parameter-attribute-2.m	(revision 0)
+++ gcc/testsuite/objc.dg/attributes/parameter-attribute-2.m	(revision 0)
@@ -0,0 +1,25 @@ 
+/* Test that we get warnings for unrecognized attributes.  */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+  Class isa;
+}
+/* TODO: Emit warnings in the @interface as well.  Currently we only emit
+   them in @implementation.  */
++ (id) method1: (id) __attribute__ ((xxxxx)) argument1;
++ (id) method2: (id) __attribute__ ((noinline)) argument1;
+@end
+
+@implementation MyRootClass
++ (id) method1: (id) __attribute__ ((xxxxx)) argument1
+{  /* { dg-warning ".xxxxx. attribute directive ignored" } */
+  return argument1;
+}
++ (id) method2: (id) __attribute__ ((noinline)) argument1
+{ /* { dg-warning ".noinline. attribute ignored" } */
+  return argument1;
+}
+@end
Index: gcc/testsuite/obj-c++.dg/attributes/unused-parameter-1.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/attributes/unused-parameter-1.mm	(revision 0)
+++ gcc/testsuite/obj-c++.dg/attributes/unused-parameter-1.mm	(revision 0)
@@ -0,0 +1,50 @@ 
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+  Class isa;
+}
+- (id) method1: (id) argument1;
+- (id) method2: (id) __attribute__((unused)) argument1;
+- (id) method3: (id) __attribute__((unused)) argument1
+   andArgument: (id) argument2;
+- (id) method4: (id) __attribute__((unused)) argument1
+   andArgument: (id) __attribute__((unused)) argument2;
+- (id) method5: (id) argument1
+   andArgument: (id) __attribute__ ((unused)) argument2;
+- (id) method6: (id) argument1
+   andArgument: (id) argument2;
+@end
+
+@implementation MyRootClass
+- (id) method1: (id) argument1
+{
+  return nil;
+}
+- (id) method2: (id) __attribute__((unused)) argument1
+{
+  return nil;
+}
+- (id) method3: (id) __attribute__((unused)) argument1
+   andArgument: (id) argument2
+{
+  return nil;
+}
+- (id) method4: (id) __attribute__((unused)) argument1
+   andArgument: (id) __attribute__((unused)) argument2
+{
+  return nil;
+}
+- (id) method5: (id) argument1
+   andArgument: (id) __attribute__ ((unused)) argument2
+{
+  return nil;
+}
+- (id) method6: (id) argument1
+   andArgument: (id) argument2
+{
+  return nil;
+}
+@end
Index: gcc/testsuite/obj-c++.dg/attributes/parameter-attribute-1.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/attributes/parameter-attribute-1.mm	(revision 0)
+++ gcc/testsuite/obj-c++.dg/attributes/parameter-attribute-1.mm	(revision 0)
@@ -0,0 +1,45 @@ 
+/* Test __attribute__((unused)) for an Objective-C method parameter.  */
+/* { dg-do compile } */
+/* { dg-options "-Wunused-parameter" } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+  Class isa;
+}
+- (id) method1: (id) argument1;
+- (id) method2: (id) __attribute__((unused)) argument1;
+- (id) method3: (id) __attribute__((unused)) argument1
+   andArgument: (id) argument2;
+- (id) method4: (id) __attribute__((unused)) argument1
+   andArgument: (id) __attribute__((unused)) argument2;
+- (id) method5: (id) argument1
+   andArgument: (id) __attribute__ ((unused)) argument2;
+@end
+
+@implementation MyRootClass
+- (id) method1: (id) argument1  /* { dg-warning "unused parameter .argument1." } */
+{
+  return nil;
+}
+- (id) method2: (id) __attribute__((unused)) argument1
+{
+  return nil;
+}
+- (id) method3: (id) __attribute__((unused)) argument1
+   andArgument: (id) argument2 /* { dg-warning "unused parameter .argument2." } */
+{
+  return nil;
+}
+- (id) method4: (id) __attribute__((unused)) argument1
+   andArgument: (id) __attribute__((unused)) argument2
+{
+  return nil;
+}
+- (id) method5: (id) argument1
+   andArgument: (id) __attribute__ ((unused)) argument2 /* { dg-warning "unused parameter .argument1." } */
+{
+  return nil;
+}
+@end
Index: gcc/testsuite/obj-c++.dg/attributes/method-attribute-2.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/attributes/method-attribute-2.mm	(revision 165885)
+++ gcc/testsuite/obj-c++.dg/attributes/method-attribute-2.mm	(working copy)
@@ -9,15 +9,15 @@ 
 } 
 - (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" } */
+- (int) unusedarg:(int) __attribute__((unused)) uarg ;
+- (int) depunusedarg:(int) __attribute__((unused)) uarg __attribute__((deprecated)) ;
 @end
 
 @implementation obj
 - (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" } */
+- (int) unusedarg:(int) __attribute__((unused)) uarg { return var; }
+- (int) depunusedarg:(int) __attribute__((unused)) uarg { return var; }
 @end 
 
 int foo (void)
Index: gcc/testsuite/obj-c++.dg/attributes/parameter-attribute-2.mm
===================================================================
--- gcc/testsuite/obj-c++.dg/attributes/parameter-attribute-2.mm	(revision 0)
+++ gcc/testsuite/obj-c++.dg/attributes/parameter-attribute-2.mm	(revision 0)
@@ -0,0 +1,25 @@ 
+/* Test that we get warnings for unrecognized attributes.  */
+/* { dg-do compile } */
+
+#include <objc/objc.h>
+
+@interface MyRootClass
+{
+  Class isa;
+}
+/* TODO: Emit warnings in the @interface as well.  Currently we only emit
+   them in @implementation.  */
++ (id) method1: (id) __attribute__ ((xxxxx)) argument1;
++ (id) method2: (id) __attribute__ ((noinline)) argument1;
+@end
+
+@implementation MyRootClass
++ (id) method1: (id) __attribute__ ((xxxxx)) argument1  /* { dg-warning ".xxxxx. attribute directive ignored" } */
+{
+  return argument1;
+}
++ (id) method2: (id) __attribute__ ((noinline)) argument1 /* { dg-warning ".noinline. attribute ignored" } */
+{
+  return argument1;
+}
+@end
Index: gcc/objcp/ChangeLog
===================================================================
--- gcc/objcp/ChangeLog	(revision 165885)
+++ gcc/objcp/ChangeLog	(working copy)
@@ -1,3 +1,7 @@ 
+2010-10-24  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+	* objcp-lang.c (LANG_HOOKS_DECL_PRINTABLE_NAME): Do not define.
+
 2010-10-20  Nicola Pero  <nicola.pero@meta-innovation.com>
 
 	* objcp-lang.c (finish_file): Removed.
Index: gcc/objcp/objcp-lang.c
===================================================================
--- gcc/objcp/objcp-lang.c	(revision 165885)
+++ gcc/objcp/objcp-lang.c	(working copy)
@@ -43,8 +43,6 @@  static tree objcxx_eh_personality (void);
 #define LANG_HOOKS_NAME "GNU Objective-C++"
 #undef LANG_HOOKS_INIT
 #define LANG_HOOKS_INIT objc_init
-#undef LANG_HOOKS_DECL_PRINTABLE_NAME
-#define LANG_HOOKS_DECL_PRINTABLE_NAME	objc_printable_name
 #undef LANG_HOOKS_GIMPLIFY_EXPR 
 #define LANG_HOOKS_GIMPLIFY_EXPR objc_gimplify_expr
 #undef LANG_HOOKS_INIT_TS
Index: gcc/cp/error.c
===================================================================
--- gcc/cp/error.c	(revision 165885)
+++ gcc/cp/error.c	(working copy)
@@ -896,6 +896,18 @@  dump_decl (tree t, int flags)
   if (t == NULL_TREE)
     return;
 
+  /* If doing Objective-C++, give Objective-C a chance to demangle
+     Objective-C method names.  */
+  if (c_dialect_objc ())
+    {
+      const char *demangled = objc_maybe_printable_name (t, flags);
+      if (demangled)
+	{
+	  pp_string (cxx_pp, demangled);
+	  return;
+	}
+    }
+
   switch (TREE_CODE (t))
     {
     case TYPE_DECL:
Index: gcc/cp/tree.c
===================================================================
--- gcc/cp/tree.c	(revision 165887)
+++ gcc/cp/tree.c	(working copy)
@@ -1409,15 +1409,6 @@  cxx_printable_name_internal (tree decl, int v, boo
   static int ring_counter;
   int i;
 
-  /* If doing Objective-C++, give Objective-C a chance to demangle
-     Objective-C method names.  */
-  if (c_dialect_objc ())
-    {
-      const char *demangled = objc_maybe_printable_name (decl, v);
-      if (demangled)
-	return demangled;
-    }
-
   /* Only cache functions.  */
   if (v < 2
       || TREE_CODE (decl) != FUNCTION_DECL
Index: gcc/cp/ChangeLog
===================================================================
--- gcc/cp/ChangeLog	(revision 165887)
+++ gcc/cp/ChangeLog	(working copy)
@@ -1,3 +1,14 @@ 
+2010-10-24  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+	Removed Objective-C++ specific replacement of cxx_printable_name.
+	* cp-objcp-common.h: Added LANG_HOOKS_DECL_PRINTABLE_NAME, set
+	to cxx_printable_name for both C++ and Objective-C++.
+	* cp-lang.h: Removed LANG_HOOKS_DECL_PRINTABLE_NAME.
+
+	* error.c (dump_decl): For Objective-C++, call
+	objc_maybe_printable_name here ...
+	* tree.c (cxx_printable_name_internal): ... instead of here.
+	
 2010-10-23  Nicola Pero  <nicola.pero@meta-innovation.com>
 
 	* tree.c (cxx_printable_name_internal): In Objective-C++, call
Index: gcc/cp/cp-lang.c
===================================================================
--- gcc/cp/cp-lang.c	(revision 165885)
+++ gcc/cp/cp-lang.c	(working copy)
@@ -72,8 +72,6 @@  static tree cp_eh_personality (void);
 	function_parameter_expanded_from_pack_p
 #undef LANG_HOOKS_GET_GENERIC_FUNCTION_DECL
 #define LANG_HOOKS_GET_GENERIC_FUNCTION_DECL get_function_template_decl
-#undef LANG_HOOKS_DECL_PRINTABLE_NAME
-#define LANG_HOOKS_DECL_PRINTABLE_NAME	cxx_printable_name
 #undef LANG_HOOKS_DWARF_NAME
 #define LANG_HOOKS_DWARF_NAME cxx_dwarf_name
 #undef LANG_HOOKS_INIT_TS
Index: gcc/cp/cp-objcp-common.h
===================================================================
--- gcc/cp/cp-objcp-common.h	(revision 165885)
+++ gcc/cp/cp-objcp-common.h	(working copy)
@@ -69,6 +69,8 @@  extern bool cp_function_decl_explicit_p (tree decl
 #define LANG_HOOKS_PRINT_STATISTICS cxx_print_statistics
 #undef LANG_HOOKS_PRINT_XNODE
 #define LANG_HOOKS_PRINT_XNODE cxx_print_xnode
+#undef LANG_HOOKS_DECL_PRINTABLE_NAME
+#define LANG_HOOKS_DECL_PRINTABLE_NAME	cxx_printable_name
 #undef LANG_HOOKS_PRINT_DECL
 #define LANG_HOOKS_PRINT_DECL cxx_print_decl
 #undef LANG_HOOKS_PRINT_TYPE