diff mbox

[tree-type] Part 2 of type segregation in attribute processing

Message ID 5478F1A6.3080006@redhat.com
State New
Headers show

Commit Message

Andrew MacLeod Nov. 28, 2014, 10:05 p.m. UTC
Next patch for the branch.

This splits the handler function in the attribute spec structure into 
decl_handler and type_handler.

I had to adjust the attribute tables for every port and language, and 
visit each and every handler and  to see what it did and make sure the 
correct thing was being done.    Many handlers only worked on types or 
decls to start with, so those I left alone... just made sure the right 
handler field was set.   Others needed to be split into a decl and a 
type version of the handler. This part wasn't difficult for the most 
part, just tedious.

I did run into some odd inconsistencies, handlers that handled 
TREE_CODES they could never actually see (just to give warnings) , and 
others which are probably being too liberal... I fired a note to the 
mailing list about them 
(https://gcc.gnu.org/ml/gcc-patches/2014-11/msg03499.html)    The 
impossible to process codes are removed in this patch.

bootstraps on x86_64-unknown-linux-gnu, passes all regressions.  all 
targets build as well.

checked into the branch as revision

Andrew
diff mbox

Patch


	* tree-core.h (struct attribute_spec): Add type_handler field.  Rename
	handler to decl_handler.
	* attribs.c (empty_attribute_table): Add extra field.
	(finalize_type_attribute): Call type_handler.
	(type_attributes) Remove whitespace.
	(decl_attributes): Call decl_handler.
	* tree.c (handle_dll_attribute): Split into handle_dll_decl_attribute
	and handle_dll_type_attribute.
	* tree.h (handle_dll_decl_attribute, handle_dll_type_attribute): New
	prototypes.
	* ada/gcc-interface/utils.c (gnat_internal_attribute_table): Adjust
	handlers.
	* cp/tree.c (cxx_attribute_table): Adjust attribute handlers.
	(handle_java_interface_decl_attributes,
	handle_java_interface_type_attribute): Factor from
	handle_java_interface_attribute.
	(handle_com_interface_decl_attributes,
	handle_com_interface_type_attribute): Factor from
	handle_com_interface_attribute.
	(handle_abi_tag_decl_attributes, handle_abi_tag_type_attribute): Factor
	from handle_abi_tag_attribute.
	* c-family/c-common.c (c_common_attribute_table): Adjust handlers.
	(c_common_format_attribute_table): Adjust handlers.
	(handle_packed_type_attribute, handle_packed_decl_attribute): Factor
	from handle_packed_attribute.
	(handle_unused_type_attribute, handle_unused_decl_attribute): Factor
	from handle_unused_attribute.
	(handle_transparent_union_type_attribute,
	handle_transparent_union_decl_attribute): Factor from
	handle_transparent_union_attribute.
	(get_align_expr, handle_aligned_type, handle_aligned_type_attribute,
	handle_aligned_decl_attribute): Factor from handle_aligned_attribute.
	(handle_decl_visibility, handle_visibility_decl_attribute,
	handle_visibility_type_attribute): factor from
	handle_visibility_attribute.
	(handle_fnspec_attribute): No need to assert TYPE_P any longer.
	(handle_warn_unused_type_attribute, handle_warn_unused_decl_attribute):
	Factor from handle_warn_unused_attribute.
	(handle_deprecated_type_attribute, handle_deprecated_decl_attribute):
	Factored from handle_deprecated_attribute.
	* fortran/f95-lang.c (gfc_attribute_table): Adjust handlers.
	* lto/lto-lang.c (lto_attribute_table): Adjust handlers.
	* java/lang.c (java_attribute_table): Adjust handlers.
	* config/alpha/alpha.c (vms_attribute_table): Adjust handlers.
	* config/arc/arc.c (arc_attribute_table): Adjust handlers.
	* config/arm/arm.c (arm_attribute_table): Adjust handlers.
	(arm_handle_isr_decl_attribute, arm_handle_isr_type_attribute): Factor
	from arm_handle_isr_attribute.
	* config/avr/avr.c (avr_ignore_type_attribute,
	avr_warning_type_attribute): New.  Generic handlers.
	(avr_attribute_table): Adjust handlers.
	* config/bfin/bfin.c (handle_int_type_attribute,
	handle_int_decl_attribute): Factor from handle_int_attribute.
	(bfin_handle_longcall_attribute): Impossible to ever see a FIELD_DECL
	or a TYPE_DECL, so don't handle those cases.
	(bfin_attribute_table): Adjust handlers.
	* config/cr16/cr16.c (cr16_attribute_table): Adjust comments.
	* config/darwin.h (SUBTARGET_ATTRIBUTE_TABLE): Adjust handlers.
	* config/epiphany/epiphany.c (epiphany_attribute_table): Adjust
	handlers.
	* config/h8300/h8300.c (h8300_attribute_table): Adjust handlers.
	* config/i386/cygming.h (SUBTARGET_ATTRIBUTE_TABLE): Adjust handlers.
	* config/i386/i386.c (ix86_handle_cconv_attribute): Remove check for
	FIELD_DECL and TYPE_DECL since they are impossible to see.
	(ix86_handle_struct_type_attribute,ix86_handle_struct_decl_attribute):
	Factor from ix86_handle_struct_attribute.
	(ix86_attribute_table): Adjust handlers.
	* config/ia64/ia64.c (ia64_attribute_table): Adjust handlers.
	* config/m32c/m32c.c (interrupt_type_handler, interrupt_decl_handler):
	Factor from interrupt_handler.
	(m32c_attribute_table): Adjust handlers.
	* config/m32r/m32r.c (m32r_attribute_table): Adjust handlers.
	* config/m68k/m68k.c (m68k_attribute_table): Adjust handlers.
	* config/mcore/mcore.c (mcore_attribute_table): Adjust handlers.
	* config/mep/mep.c (mep_validate_type_based_tiny,
	mep_validate_decl_based_tiny): Factor from mep_validate_based_tiny.
	(mep_validate_type_near_far, mep_validate_decl_near_far): Factor
	from mep_validate_near_far.
	(mep_validate_type_disinterrupt, mep_validate_decl_disinterrupt): Factor
	from mep_validate_disinterrupt.
	(mep_validate_type_warning): Issues warning handler.
	(mep_attribute_table): Adjust handlers.
	* config/microblaze/microblaze.c: (microblaze_attribute_table): Add
	extra fields.
	* config/mips/mips.c (mips_attribute_table): Adjust handlers.
	* config/msp430/msp430.c (msp430_attribute_table): Adjust handlers.
	* config/nds32/nds32.c (nds32_attribute_table): Add extra fields.
	* config/nvptx/nvptx.c (nvptx_attribute_table): Adjust handlers.
	* config/rl78/rl78.c (r178_attribute_table): Adjust handlers.
	* config/rs6000/rs6000.c (rs600_attribute_table): Adjust handlers.
	(rs6000_handle_longcall_attribute): Remove handling of FIELD_DECL and
	TYPE_DECL since they are impossible to reach.
	(rs6000_handle_struct_type_attribute,
	rs6000_handle_struct_decl_attribute): Factor from
	rs6000_handle_struct_attribute.
	* config/rx/rx.c (rx_attribute_table): Adjust handlers.
	* config/s390/s390.c (s390_attribute_table): Adjust handlers.
	* config/sh/sh.c (sh_attribute_table): Adjust handlers.
	* config/sol2.h (SOLARIS_ATTRIBUTE_TABLE): Add extra fields.
	* config/sparc/sparc.c (sparc_attribute_table): Add extra fields.
	* config/spu/spu.c (spu_attribute_table): Adjust handlers.
	* config/stormy16/stormy16.c (xstormy16_attribute_table): Adjust
	handlers.
	(xstormy16_handle_below100_attribute): Don't handle POINTER_TYPE or
	TYPE_DECL.
	* config/v850/v850.c (v850_attribute_table): Adjust handlers.

Index: tree-core.h
===================================================================
*** tree-core.h	(revision 217983)
--- tree-core.h	(working copy)
*************** struct attribute_spec {
*** 1736,1742 ****
       otherwise the return value should be NULL_TREE.  This pointer may be
       NULL if no special handling is required beyond the checks implied
       by the rest of this structure.  */
!   tree (*handler) (tree *node, tree name, tree args,
  		   int flags, bool *no_add_attrs);
    /* Specifies if attribute affects type's identity.  */
    bool affects_type_identity;
--- 1736,1744 ----
       otherwise the return value should be NULL_TREE.  This pointer may be
       NULL if no special handling is required beyond the checks implied
       by the rest of this structure.  */
!   tree (*decl_handler) (tree *node, tree name, tree args,
! 		   int flags, bool *no_add_attrs);
!   tree (*type_handler) (tree *node, tree name, tree args,
  		   int flags, bool *no_add_attrs);
    /* Specifies if attribute affects type's identity.  */
    bool affects_type_identity;
Index: attribs.c
===================================================================
*** attribs.c	(revision 218105)
--- attribs.c	(working copy)
*************** static bool attributes_initialized = fal
*** 101,107 ****
  
  static const struct attribute_spec empty_attribute_table[] =
  {
!   { NULL, 0, 0, false, false, false, NULL, false }
  };
  
  /* Return base name of the attribute.  Ie '__attr__' is turned into 'attr'.
--- 101,107 ----
  
  static const struct attribute_spec empty_attribute_table[] =
  {
!   { NULL, 0, 0, false, false, false, NULL, NULL, false }
  };
  
  /* Return base name of the attribute.  Ie '__attr__' is turned into 'attr'.
*************** finalize_type_attribute (tree *node, con
*** 456,467 ****
        return returned_attrs;
      }
  
!   if (spec->handler != NULL)
      {
        int cxx11_flag =
  	cxx11_attribute_p (a) ? ATTR_FLAG_CXX11 : 0;
  
!       returned_attrs = chainon ((*spec->handler) (anode, name, args,
  						       flags|cxx11_flag,
  						       &no_add_attrs),
  				returned_attrs);
--- 456,467 ----
        return returned_attrs;
      }
  
!   if (spec->type_handler != NULL)
      {
        int cxx11_flag =
  	cxx11_attribute_p (a) ? ATTR_FLAG_CXX11 : 0;
  
!       returned_attrs = chainon ((*spec->type_handler) (anode, name, args,
  						       flags|cxx11_flag,
  						       &no_add_attrs),
  				returned_attrs);
*************** type_attributes (tree *node, tree attrib
*** 552,558 ****
    tree a;
    tree returned_attrs = NULL_TREE;
  
- 
    if (TREE_TYPE (*node) == error_mark_node || attributes == error_mark_node)
      return NULL_TREE;
  
--- 552,557 ----
*************** decl_attributes (tree *node, tree attrib
*** 710,720 ****
  						    node);
  	  continue;
  	}
!       if (spec->handler != NULL)
  	{
  	  int cxx11_flag =
  	    cxx11_attribute_p (a) ? ATTR_FLAG_CXX11 : 0;
! 	  returned_attrs = chainon ((*spec->handler) (anode, name, args,
  							   flags|cxx11_flag,
  							   &no_add_attrs),
  				    returned_attrs);
--- 709,719 ----
  						    node);
  	  continue;
  	}
!       if (spec->decl_handler != NULL)
  	{
  	  int cxx11_flag =
  	    cxx11_attribute_p (a) ? ATTR_FLAG_CXX11 : 0;
! 	  returned_attrs = chainon ((*spec->decl_handler) (anode, name, args,
  							   flags|cxx11_flag,
  							   &no_add_attrs),
  				    returned_attrs);
Index: tree.c
===================================================================
*** tree.c	(revision 217983)
--- tree.c	(working copy)
*************** merge_dllimport_decl_attributes (tree ol
*** 6117,6158 ****
    return a;
  }
  
! /* Handle a "dllimport" or "dllexport" attribute; arguments as in
     struct attribute_spec.handler.  */
  
  tree
! handle_dll_attribute (tree * pnode, tree name, tree args, int flags,
! 		      bool *no_add_attrs)
  {
    tree node = *pnode;
    bool is_dllimport;
  
-   /* These attributes may apply to structure and union types being created,
-      but otherwise should pass to the declaration involved.  */
-   if (!DECL_P (node))
-     {
-       if (flags & ((int) ATTR_FLAG_DECL_NEXT | (int) ATTR_FLAG_FUNCTION_NEXT
- 		   | (int) ATTR_FLAG_ARRAY_NEXT))
- 	{
- 	  *no_add_attrs = true;
- 	  return tree_cons (name, args, NULL_TREE);
- 	}
-       if (TREE_CODE (node) == RECORD_TYPE
- 	  || TREE_CODE (node) == UNION_TYPE)
- 	{
- 	  node = TYPE_NAME (node);
- 	  if (!node)
- 	    return NULL_TREE;
- 	}
-       else
- 	{
- 	  warning (OPT_Wattributes, "%qE attribute ignored",
- 		   name);
- 	  *no_add_attrs = true;
- 	  return NULL_TREE;
- 	}
-     }
- 
    if (TREE_CODE (node) != FUNCTION_DECL
        && TREE_CODE (node) != VAR_DECL
        && TREE_CODE (node) != TYPE_DECL)
--- 6117,6132 ----
    return a;
  }
  
! /* Handle a "dllimport" or "dllexport" attribute for decls; arguments as in
     struct attribute_spec.handler.  */
  
  tree
! handle_dll_decl_attribute (tree * pnode, tree name, tree args, int flags,
! 			   bool *no_add_attrs)
  {
    tree node = *pnode;
    bool is_dllimport;
  
    if (TREE_CODE (node) != FUNCTION_DECL
        && TREE_CODE (node) != VAR_DECL
        && TREE_CODE (node) != TYPE_DECL)
*************** handle_dll_attribute (tree * pnode, tree
*** 6254,6259 ****
--- 6228,6266 ----
    return NULL_TREE;
  }
  
+ 
+ /* Handle a "dllimport" or "dllexport" attribute for types; arguments as in
+    struct attribute_spec.handler.  */
+ 
+ tree
+ handle_dll_type_attribute (tree * pnode, tree name, tree args, int flags,
+ 			   bool *no_add_attrs)
+ {
+    tree node = *pnode;
+ 
+   /* These attributes may apply to structure and union types being created,
+      but otherwise should pass to the declaration involved.  */
+   if (flags & ((int) ATTR_FLAG_DECL_NEXT | (int) ATTR_FLAG_FUNCTION_NEXT
+ 	       | (int) ATTR_FLAG_ARRAY_NEXT))
+     {
+       *no_add_attrs = true;
+       return tree_cons (name, args, NULL_TREE);
+     }
+ 
+   if (TREE_CODE (node) != RECORD_TYPE && TREE_CODE (node) != UNION_TYPE)
+     {
+       warning (OPT_Wattributes, "%qE attribute ignored", name);
+       *no_add_attrs = true;
+       return NULL_TREE;
+     }
+ 
+   if (!TYPE_NAME (node))
+     return NULL_TREE;
+ 
+   return handle_dll_decl_attribute (&TYPE_NAME (node), name, args, flags,
+ 				    no_add_attrs);
+ }
+ 
  #endif /* TARGET_DLLIMPORT_DECL_ATTRIBUTES  */
  
  /* Set the type qualifiers for TYPE to TYPE_QUALS, which is a bitmask
Index: tree.h
===================================================================
*** tree.h	(revision 217983)
--- tree.h	(working copy)
*************** extern tree merge_attributes (tree, tree
*** 3865,3871 ****
  extern tree merge_dllimport_decl_attributes (tree, tree);
  
  /* Handle a "dllimport" or "dllexport" attribute.  */
! extern tree handle_dll_attribute (tree *, tree, tree, int, bool *);
  #endif
  
  /* Returns true iff unqualified CAND and BASE are equivalent.  */
--- 3865,3872 ----
  extern tree merge_dllimport_decl_attributes (tree, tree);
  
  /* Handle a "dllimport" or "dllexport" attribute.  */
! extern tree handle_dll_decl_attribute (tree *, tree, tree, int, bool *);
! extern tree handle_dll_type_attribute (tree *, tree, tree, int, bool *);
  #endif
  
  /* Returns true iff unqualified CAND and BASE are equivalent.  */
Index: ada/gcc-interface/utils.c
===================================================================
*** ada/gcc-interface/utils.c	(revision 218105)
--- ada/gcc-interface/utils.c	(working copy)
*************** static tree fake_attribute_handler
*** 122,165 ****
     this minimal set of attributes to accommodate the needs of builtins.  */
  const struct attribute_spec gnat_internal_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
!        affects_type_identity } */
    { "const",        0, 0,  true,  false, false, handle_const_attribute,
!     false },
    { "nothrow",      0, 0,  true,  false, false, handle_nothrow_attribute,
!     false },
    { "pure",         0, 0,  true,  false, false, handle_pure_attribute,
!     false },
    { "no vops",      0, 0,  true,  false, false, handle_novops_attribute,
!     false },
!   { "nonnull",      0, -1, false, true,  true,  handle_nonnull_attribute,
!     false },
!   { "sentinel",     0, 1,  false, true,  true,  handle_sentinel_attribute,
!     false },
    { "noreturn",     0, 0,  true,  false, false, handle_noreturn_attribute,
!     false },
    { "leaf",         0, 0,  true,  false, false, handle_leaf_attribute,
!     false },
    { "always_inline",0, 0,  true,  false, false, handle_always_inline_attribute,
!     false },
    { "malloc",       0, 0,  true,  false, false, handle_malloc_attribute,
!     false },
!   { "type generic", 0, 0,  false, true, true, handle_type_generic_attribute,
!     false },
  
!   { "vector_size",  1, 1,  false, true, false,  handle_vector_size_attribute,
!     false },
!   { "vector_type",  0, 0,  false, true, false,  handle_vector_type_attribute,
!     false },
!   { "may_alias",    0, 0, false, true, false, NULL, false },
  
    /* ??? format and format_arg are heavy and not supported, which actually
       prevents support for stdio builtins, which we however declare as part
       of the common builtins.def contents.  */
!   { "format",     3, 3,  false, true,  true,  fake_attribute_handler, false },
!   { "format_arg", 1, 1,  false, true,  true,  fake_attribute_handler, false },
  
!   { NULL,         0, 0, false, false, false, NULL, false }
  };
  
  /* Associates a GNAT tree node to a GCC tree node. It is used in
--- 122,167 ----
     this minimal set of attributes to accommodate the needs of builtins.  */
  const struct attribute_spec gnat_internal_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, decl_handler,
!        type_handler, affects_type_identity } */
    { "const",        0, 0,  true,  false, false, handle_const_attribute,
!     NULL, false },
    { "nothrow",      0, 0,  true,  false, false, handle_nothrow_attribute,
!     NULL, false },
    { "pure",         0, 0,  true,  false, false, handle_pure_attribute,
!     NULL, false },
    { "no vops",      0, 0,  true,  false, false, handle_novops_attribute,
!     NULL, false },
!   { "nonnull",      0, -1, false, true,  true,  NULL,
!     handle_nonnull_attribute, false },
!   { "sentinel",     0, 1,  false, true,  true,  NULL,
!     handle_sentinel_attribute, false },
    { "noreturn",     0, 0,  true,  false, false, handle_noreturn_attribute,
!     NULL, false },
    { "leaf",         0, 0,  true,  false, false, handle_leaf_attribute,
!     NULL, false },
    { "always_inline",0, 0,  true,  false, false, handle_always_inline_attribute,
!     NULL, false },
    { "malloc",       0, 0,  true,  false, false, handle_malloc_attribute,
!     NULL, false },
!   { "type generic", 0, 0,  false, true, true, NULL,
!     handle_type_generic_attribute, false },
  
!   { "vector_size",  1, 1,  false, true, false, NULL,
!     handle_vector_size_attribute, false },
!   { "vector_type",  0, 0,  false, true, false, NULL,
!     handle_vector_type_attribute, false },
!   { "may_alias",    0, 0, false, true, false, NULL, NULL, false },
  
    /* ??? format and format_arg are heavy and not supported, which actually
       prevents support for stdio builtins, which we however declare as part
       of the common builtins.def contents.  */
!   { "format",     3, 3,  false, true,  true, NULL,
!     fake_attribute_handler, false },
!   { "format_arg", 1, 1,  false, true,  true, NULL,
!     fake_attribute_handler, false },
  
!   { NULL,         0, 0, false, false, false, NULL, NULL, false }
  };
  
  /* Associates a GNAT tree node to a GCC tree node. It is used in
Index: cp/tree.c
===================================================================
*** cp/tree.c	(revision 217943)
--- cp/tree.c	(working copy)
*************** static tree count_trees_r (tree *, int *
*** 58,67 ****
  static tree verify_stmt_tree_r (tree *, int *, void *);
  static tree build_local_temp (tree);
  
! static tree handle_java_interface_attribute (tree *, tree, tree, int, bool *);
! static tree handle_com_interface_attribute (tree *, tree, tree, int, bool *);
  static tree handle_init_priority_attribute (tree *, tree, tree, int, bool *);
! static tree handle_abi_tag_attribute (tree *, tree, tree, int, bool *);
  
  /* If REF is an lvalue, returns the kind of lvalue that REF is.
     Otherwise, returns clk_none.  */
--- 58,74 ----
  static tree verify_stmt_tree_r (tree *, int *, void *);
  static tree build_local_temp (tree);
  
! static tree handle_java_interface_decl_attribute (tree *, tree, tree, int,
! 						  bool *);
! static tree handle_java_interface_type_attribute (tree *, tree, tree, int,
! 						  bool *);
! static tree handle_com_interface_decl_attribute (tree *, tree, tree, int,
! 						 bool *);
! static tree handle_com_interface_type_attribute (tree *, tree, tree, int,
! 						 bool *);
  static tree handle_init_priority_attribute (tree *, tree, tree, int, bool *);
! static tree handle_abi_tag_decl_attribute (tree *, tree, tree, int, bool *);
! static tree handle_abi_tag_type_attribute (tree *, tree, tree, int, bool *);
  
  /* If REF is an lvalue, returns the kind of lvalue that REF is.
     Otherwise, returns clk_none.  */
*************** zero_init_p (const_tree t)
*** 3312,3342 ****
  /* Table of valid C++ attributes.  */
  const struct attribute_spec cxx_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
!        affects_type_identity } */
    { "java_interface", 0, 0, false, false, false,
!     handle_java_interface_attribute, false },
    { "com_interface",  0, 0, false, false, false,
!     handle_com_interface_attribute, false },
    { "init_priority",  1, 1, true,  false, false,
!     handle_init_priority_attribute, false },
    { "abi_tag", 1, -1, false, false, false,
!     handle_abi_tag_attribute, true },
!   { NULL,	      0, 0, false, false, false, NULL, false }
  };
  
  /* Handle a "java_interface" attribute; arguments as in
     struct attribute_spec.handler.  */
  static tree
! handle_java_interface_attribute (tree* node,
! 				 tree name,
! 				 tree /*args*/,
! 				 int flags,
! 				 bool* no_add_attrs)
! {
!   if (DECL_P (*node)
!       || !CLASS_TYPE_P (*node)
!       || !TYPE_FOR_JAVA (*node))
      {
        error ("%qE attribute can only be applied to Java class definitions",
  	     name);
--- 3319,3369 ----
  /* Table of valid C++ attributes.  */
  const struct attribute_spec cxx_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, decl_handler,
!        type_handler, affects_type_identity } */
    { "java_interface", 0, 0, false, false, false,
!     handle_java_interface_decl_attribute, handle_java_interface_type_attribute,
!     false },
    { "com_interface",  0, 0, false, false, false,
!     handle_com_interface_decl_attribute, handle_com_interface_type_attribute,
!     false },
    { "init_priority",  1, 1, true,  false, false,
!     handle_init_priority_attribute, NULL, false },
    { "abi_tag", 1, -1, false, false, false,
!     handle_abi_tag_decl_attribute, handle_abi_tag_type_attribute, true },
!   { NULL,	      0, 0, false, false, false, NULL, NULL, false }
  };
  
+ 
+ static tree
+ handle_java_interface_decl_attribute (tree* /*node*/, tree name, tree /*args*/,
+ 				      int /*flags*/, bool* no_add_attrs)
+ {
+   error ("%qE attribute can only be applied to Java class definitions", name);
+   *no_add_attrs = true;
+   return NULL_TREE;
+ }
+ 
+ static tree
+ handle_com_interface_decl_attribute (tree* /*node*/, tree name, tree /*args*/,
+ 				     int /*flags*/, bool* no_add_attrs)
+ {
+   warning (OPT_Wattributes, "%qE attribute can only be applied "
+ 	   "to class definitions", name);
+   *no_add_attrs = true;
+   return NULL_TREE;
+ }
+ 
  /* Handle a "java_interface" attribute; arguments as in
     struct attribute_spec.handler.  */
  static tree
! handle_java_interface_type_attribute (tree* node,
! 				      tree name,
! 				      tree /*args*/,
! 				      int flags,
! 				      bool* no_add_attrs)
! {
!   if (!CLASS_TYPE_P (*node) || !TYPE_FOR_JAVA (*node))
      {
        error ("%qE attribute can only be applied to Java class definitions",
  	     name);
*************** handle_java_interface_attribute (tree* n
*** 3353,3371 ****
  /* Handle a "com_interface" attribute; arguments as in
     struct attribute_spec.handler.  */
  static tree
! handle_com_interface_attribute (tree* node,
! 				tree name,
! 				tree /*args*/,
! 				int /*flags*/,
! 				bool* no_add_attrs)
  {
    static int warned;
  
    *no_add_attrs = true;
  
!   if (DECL_P (*node)
!       || !CLASS_TYPE_P (*node)
!       || *node != TYPE_MAIN_VARIANT (*node))
      {
        warning (OPT_Wattributes, "%qE attribute can only be applied "
  	       "to class definitions", name);
--- 3380,3396 ----
  /* Handle a "com_interface" attribute; arguments as in
     struct attribute_spec.handler.  */
  static tree
! handle_com_interface_type_attribute (tree* node,
! 				     tree name,
! 				     tree /*args*/,
! 				     int /*flags*/,
! 				     bool* no_add_attrs)
  {
    static int warned;
  
    *no_add_attrs = true;
  
!   if (!CLASS_TYPE_P (*node) || *node != TYPE_MAIN_VARIANT (*node))
      {
        warning (OPT_Wattributes, "%qE attribute can only be applied "
  	       "to class definitions", name);
*************** check_abi_tag_redeclaration (const_tree
*** 3491,3526 ****
     struct attribute_spec.handler.  */
  
  static tree
! handle_abi_tag_attribute (tree* node, tree name, tree args,
! 			  int flags, bool* no_add_attrs)
  {
!   if (TYPE_P (*node))
      {
!       if (!OVERLOAD_TYPE_P (*node))
! 	{
! 	  error ("%qE attribute applied to non-class, non-enum type %qT",
! 		 name, *node);
! 	  goto fail;
! 	}
!       else if (!(flags & (int)ATTR_FLAG_TYPE_IN_PLACE))
! 	{
! 	  error ("%qE attribute applied to %qT after its definition",
! 		 name, *node);
! 	  goto fail;
! 	}
!       else if (CLASSTYPE_TEMPLATE_INSTANTIATION (*node))
! 	{
! 	  warning (OPT_Wattributes, "ignoring %qE attribute applied to "
! 		   "template instantiation %qT", name, *node);
! 	  goto fail;
! 	}
!       else if (CLASSTYPE_TEMPLATE_SPECIALIZATION (*node))
! 	{
! 	  warning (OPT_Wattributes, "ignoring %qE attribute applied to "
! 		   "template specialization %qT", name, *node);
! 	  goto fail;
! 	}
  
        tree attributes = TYPE_ATTRIBUTES (*node);
        tree decl = TYPE_NAME (*node);
  
--- 3516,3570 ----
     struct attribute_spec.handler.  */
  
  static tree
! handle_abi_tag_decl_attribute (tree* node, tree name, tree /*args*/,
! 			       int /*flags*/, bool* no_add_attrs)
  {
!   if (TREE_CODE (*node) != FUNCTION_DECL)
      {
!       error ("%qE attribute applied to non-function %qD", name, *node);
!       *no_add_attrs = true;
!     }
!   else if (DECL_LANGUAGE (*node) == lang_c)
!     {
!       error ("%qE attribute applied to extern \"C\" function %qD",
! 	     name, *node);
!       *no_add_attrs = true;
!     }
  
+   return NULL_TREE;
+ }
+ 
+ 
+ static tree
+ handle_abi_tag_type_attribute (tree* node, tree name, tree args,
+ 			  int flags, bool* no_add_attrs)
+ {
+   if (!OVERLOAD_TYPE_P (*node))
+     {
+       error ("%qE attribute applied to non-class, non-enum type %qT",
+ 	     name, *node);
+       *no_add_attrs = true;
+     }
+   else if (!(flags & (int)ATTR_FLAG_TYPE_IN_PLACE))
+     {
+       error ("%qE attribute applied to %qT after its definition",
+ 	     name, *node);
+       *no_add_attrs = true;
+     }
+   else if (CLASSTYPE_TEMPLATE_INSTANTIATION (*node))
+     {
+       warning (OPT_Wattributes, "ignoring %qE attribute applied to "
+ 	       "template instantiation %qT", name, *node);
+       *no_add_attrs = true;
+     }
+   else if (CLASSTYPE_TEMPLATE_SPECIALIZATION (*node))
+     {
+       warning (OPT_Wattributes, "ignoring %qE attribute applied to "
+ 	       "template specialization %qT", name, *node);
+       *no_add_attrs = true;
+     }
+   else
+     {
        tree attributes = TYPE_ATTRIBUTES (*node);
        tree decl = TYPE_NAME (*node);
  
*************** handle_abi_tag_attribute (tree* node, tr
*** 3531,3559 ****
  					    lookup_attribute ("abi_tag",
  							      attributes),
  					    args))
! 	    goto fail;
  	}
!     }
!   else
!     {
!       if (TREE_CODE (*node) != FUNCTION_DECL)
! 	{
! 	  error ("%qE attribute applied to non-function %qD", name, *node);
! 	  goto fail;
! 	}
!       else if (DECL_LANGUAGE (*node) == lang_c)
! 	{
! 	  error ("%qE attribute applied to extern \"C\" function %qD",
! 		 name, *node);
! 	  goto fail;
! 	}
!     }
  
    return NULL_TREE;
- 
-  fail:
-   *no_add_attrs = true;
-   return NULL_TREE;
  }
  
  /* Return a new PTRMEM_CST of the indicated TYPE.  The MEMBER is the
--- 3575,3585 ----
  					    lookup_attribute ("abi_tag",
  							      attributes),
  					    args))
! 	    *no_add_attrs = true;
  	}
!      }
  
    return NULL_TREE;
  }
  
  /* Return a new PTRMEM_CST of the indicated TYPE.  The MEMBER is the
Index: c-family/c-common.c
===================================================================
*** c-family/c-common.c	(revision 218105)
--- c-family/c-common.c	(working copy)
*************** static tree c_fully_fold_internal (tree
*** 312,318 ****
  static tree check_case_value (location_t, tree);
  static bool check_case_bounds (location_t, tree, tree, tree *, tree *);
  
! static tree handle_packed_attribute (tree *, tree, tree, int, bool *);
  static tree handle_nocommon_attribute (tree *, tree, tree, int, bool *);
  static tree handle_common_attribute (tree *, tree, tree, int, bool *);
  static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
--- 312,319 ----
  static tree check_case_value (location_t, tree);
  static bool check_case_bounds (location_t, tree, tree, tree *, tree *);
  
! static tree handle_packed_decl_attribute (tree *, tree, tree, int, bool *);
! static tree handle_packed_type_attribute (tree *, tree, tree, int, bool *);
  static tree handle_nocommon_attribute (tree *, tree, tree, int, bool *);
  static tree handle_common_attribute (tree *, tree, tree, int, bool *);
  static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
*************** static tree handle_artificial_attribute
*** 334,359 ****
  static tree handle_flatten_attribute (tree *, tree, tree, int, bool *);
  static tree handle_error_attribute (tree *, tree, tree, int, bool *);
  static tree handle_used_attribute (tree *, tree, tree, int, bool *);
! static tree handle_unused_attribute (tree *, tree, tree, int, bool *);
  static tree handle_externally_visible_attribute (tree *, tree, tree, int,
  						 bool *);
  static tree handle_no_reorder_attribute (tree *, tree, tree, int,
  						 bool *);
  static tree handle_const_attribute (tree *, tree, tree, int, bool *);
! static tree handle_transparent_union_attribute (tree *, tree, tree,
! 						int, bool *);
  static tree handle_constructor_attribute (tree *, tree, tree, int, bool *);
  static tree handle_destructor_attribute (tree *, tree, tree, int, bool *);
  static tree handle_mode_attribute (tree *, tree, tree, int, bool *);
  static tree handle_section_attribute (tree *, tree, tree, int, bool *);
! static tree handle_aligned_attribute (tree *, tree, tree, int, bool *);
  static tree handle_weak_attribute (tree *, tree, tree, int, bool *) ;
  static tree handle_alias_ifunc_attribute (bool, tree *, tree, tree, bool *);
  static tree handle_ifunc_attribute (tree *, tree, tree, int, bool *);
  static tree handle_alias_attribute (tree *, tree, tree, int, bool *);
  static tree handle_weakref_attribute (tree *, tree, tree, int, bool *) ;
! static tree handle_visibility_attribute (tree *, tree, tree, int,
! 					 bool *);
  static tree handle_tls_model_attribute (tree *, tree, tree, int,
  					bool *);
  static tree handle_no_instrument_function_attribute (tree *, tree,
--- 335,366 ----
  static tree handle_flatten_attribute (tree *, tree, tree, int, bool *);
  static tree handle_error_attribute (tree *, tree, tree, int, bool *);
  static tree handle_used_attribute (tree *, tree, tree, int, bool *);
! static tree handle_unused_decl_attribute (tree *, tree, tree, int, bool *);
! static tree handle_unused_type_attribute (tree *, tree, tree, int, bool *);
  static tree handle_externally_visible_attribute (tree *, tree, tree, int,
  						 bool *);
  static tree handle_no_reorder_attribute (tree *, tree, tree, int,
  						 bool *);
  static tree handle_const_attribute (tree *, tree, tree, int, bool *);
! static tree handle_transparent_union_decl_attribute (tree *, tree, tree,
! 						     int, bool *);
! static tree handle_transparent_union_type_attribute (tree *, tree, tree,
! 						     int, bool *);
  static tree handle_constructor_attribute (tree *, tree, tree, int, bool *);
  static tree handle_destructor_attribute (tree *, tree, tree, int, bool *);
  static tree handle_mode_attribute (tree *, tree, tree, int, bool *);
  static tree handle_section_attribute (tree *, tree, tree, int, bool *);
! static tree handle_aligned_type_attribute (tree *, tree, tree, int, bool *);
! static tree handle_aligned_decl_attribute (tree *, tree, tree, int, bool *);
  static tree handle_weak_attribute (tree *, tree, tree, int, bool *) ;
  static tree handle_alias_ifunc_attribute (bool, tree *, tree, tree, bool *);
  static tree handle_ifunc_attribute (tree *, tree, tree, int, bool *);
  static tree handle_alias_attribute (tree *, tree, tree, int, bool *);
  static tree handle_weakref_attribute (tree *, tree, tree, int, bool *) ;
! static tree handle_visibility_decl_attribute (tree *, tree, tree, int,
! 					      bool *);
! static tree handle_visibility_type_attribute (tree *, tree, tree, int,
! 					      bool *);
  static tree handle_tls_model_attribute (tree *, tree, tree, int,
  					bool *);
  static tree handle_no_instrument_function_attribute (tree *, tree,
*************** static tree handle_pure_attribute (tree
*** 366,373 ****
  static tree handle_tm_attribute (tree *, tree, tree, int, bool *);
  static tree handle_tm_wrap_attribute (tree *, tree, tree, int, bool *);
  static tree handle_novops_attribute (tree *, tree, tree, int, bool *);
! static tree handle_deprecated_attribute (tree *, tree, tree, int,
! 					 bool *);
  static tree handle_vector_size_attribute (tree *, tree, tree, int,
  					  bool *);
  static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);
--- 373,382 ----
  static tree handle_tm_attribute (tree *, tree, tree, int, bool *);
  static tree handle_tm_wrap_attribute (tree *, tree, tree, int, bool *);
  static tree handle_novops_attribute (tree *, tree, tree, int, bool *);
! static tree handle_deprecated_type_attribute (tree *, tree, tree, int,
! 					      bool *);
! static tree handle_deprecated_decl_attribute (tree *, tree, tree, int,
! 					      bool *);
  static tree handle_vector_size_attribute (tree *, tree, tree, int,
  					  bool *);
  static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);
*************** static tree handle_optimize_attribute (t
*** 385,391 ****
  static tree ignore_attribute (tree *, tree, tree, int, bool *);
  static tree handle_no_split_stack_attribute (tree *, tree, tree, int, bool *);
  static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *);
! static tree handle_warn_unused_attribute (tree *, tree, tree, int, bool *);
  static tree handle_returns_nonnull_attribute (tree *, tree, tree, int, bool *);
  static tree handle_omp_declare_simd_attribute (tree *, tree, tree, int,
  					       bool *);
--- 394,401 ----
  static tree ignore_attribute (tree *, tree, tree, int, bool *);
  static tree handle_no_split_stack_attribute (tree *, tree, tree, int, bool *);
  static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *);
! static tree handle_warn_unused_decl_attribute (tree *, tree, tree, int, bool *);
! static tree handle_warn_unused_type_attribute (tree *, tree, tree, int, bool *);
  static tree handle_returns_nonnull_attribute (tree *, tree, tree, int, bool *);
  static tree handle_omp_declare_simd_attribute (tree *, tree, tree, int,
  					       bool *);
*************** const unsigned int num_c_common_reswords
*** 637,813 ****
     Current list of processed common attributes: nonnull.  */
  const struct attribute_spec c_common_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
!        affects_type_identity } */
    { "packed",                 0, 0, false, false, false,
! 			      handle_packed_attribute , false},
    { "nocommon",               0, 0, true,  false, false,
! 			      handle_nocommon_attribute, false},
    { "common",                 0, 0, true,  false, false,
! 			      handle_common_attribute, false },
    /* FIXME: logically, noreturn attributes should be listed as
       "false, true, true" and apply to function types.  But implementing this
       would require all the places in the compiler that use TREE_THIS_VOLATILE
       on a decl to identify non-returning functions to be located and fixed
       to check the function type instead.  */
    { "noreturn",               0, 0, true,  false, false,
! 			      handle_noreturn_attribute, false },
    { "volatile",               0, 0, true,  false, false,
! 			      handle_noreturn_attribute, false },
    { "noinline",               0, 0, true,  false, false,
! 			      handle_noinline_attribute, false },
    { "noclone",                0, 0, true,  false, false,
! 			      handle_noclone_attribute, false },
    { "leaf",                   0, 0, true,  false, false,
! 			      handle_leaf_attribute, false },
    { "always_inline",          0, 0, true,  false, false,
! 			      handle_always_inline_attribute, false },
    { "gnu_inline",             0, 0, true,  false, false,
! 			      handle_gnu_inline_attribute, false },
    { "artificial",             0, 0, true,  false, false,
! 			      handle_artificial_attribute, false },
    { "flatten",                0, 0, true,  false, false,
! 			      handle_flatten_attribute, false },
    { "used",                   0, 0, true,  false, false,
! 			      handle_used_attribute, false },
    { "unused",                 0, 0, false, false, false,
! 			      handle_unused_attribute, false },
    { "externally_visible",     0, 0, true,  false, false,
! 			      handle_externally_visible_attribute, false },
    { "no_reorder",	      0, 0, true, false, false,
!                               handle_no_reorder_attribute, false },
    /* The same comments as for noreturn attributes apply to const ones.  */
    { "const",                  0, 0, true,  false, false,
! 			      handle_const_attribute, false },
    { "transparent_union",      0, 0, false, false, false,
! 			      handle_transparent_union_attribute, false },
    { "constructor",            0, 1, true,  false, false,
! 			      handle_constructor_attribute, false },
    { "destructor",             0, 1, true,  false, false,
! 			      handle_destructor_attribute, false },
!   { "mode",                   1, 1, false,  true, false,
  			      handle_mode_attribute, false },
    { "section",                1, 1, true,  false, false,
! 			      handle_section_attribute, false },
    { "aligned",                0, 1, false, false, false,
! 			      handle_aligned_attribute, false },
    { "weak",                   0, 0, true,  false, false,
! 			      handle_weak_attribute, false },
    { "ifunc",                  1, 1, true,  false, false,
! 			      handle_ifunc_attribute, false },
    { "alias",                  1, 1, true,  false, false,
! 			      handle_alias_attribute, false },
    { "weakref",                0, 1, true,  false, false,
! 			      handle_weakref_attribute, false },
    { "no_instrument_function", 0, 0, true,  false, false,
  			      handle_no_instrument_function_attribute,
! 			      false },
    { "malloc",                 0, 0, true,  false, false,
! 			      handle_malloc_attribute, false },
    { "returns_twice",          0, 0, true,  false, false,
! 			      handle_returns_twice_attribute, false },
    { "no_stack_limit",         0, 0, true,  false, false,
! 			      handle_no_limit_stack_attribute, false },
    { "pure",                   0, 0, true,  false, false,
! 			      handle_pure_attribute, false },
!   { "transaction_callable",   0, 0, false, true,  false,
  			      handle_tm_attribute, false },
    { "transaction_unsafe",     0, 0, false, true,  false,
! 			      handle_tm_attribute, false },
    { "transaction_safe",       0, 0, false, true,  false,
! 			      handle_tm_attribute, false },
    { "transaction_may_cancel_outer", 0, 0, false, true, false,
! 			      handle_tm_attribute, false },
    /* ??? These two attributes didn't make the transition from the
       Intel language document to the multi-vendor language document.  */
    { "transaction_pure",       0, 0, false, true,  false,
! 			      handle_tm_attribute, false },
    { "transaction_wrap",       1, 1, true,  false,  false,
! 			     handle_tm_wrap_attribute, false },
    /* For internal use (marking of builtins) only.  The name contains space
       to prevent its usage in source code.  */
    { "no vops",                0, 0, true,  false, false,
! 			      handle_novops_attribute, false },
    { "deprecated",             0, 1, false, false, false,
! 			      handle_deprecated_attribute, false },
    { "vector_size",	      1, 1, false, true, false,
! 			      handle_vector_size_attribute, false },
    { "visibility",	      1, 1, false, false, false,
! 			      handle_visibility_attribute, false },
    { "tls_model",	      1, 1, true,  false, false,
! 			      handle_tls_model_attribute, false },
    { "nonnull",                0, -1, false, true, true,
! 			      handle_nonnull_attribute, false },
    { "nothrow",                0, 0, true,  false, false,
! 			      handle_nothrow_attribute, false },
!   { "may_alias",	      0, 0, false, true, false, NULL, false },
    { "cleanup",		      1, 1, true, false, false,
! 			      handle_cleanup_attribute, false },
!   { "warn_unused_result",     0, 0, false, true, true,
  			      handle_warn_unused_result_attribute, false },
    { "sentinel",               0, 1, false, true, true,
! 			      handle_sentinel_attribute, false },
    /* For internal use (marking of builtins) only.  The name contains space
       to prevent its usage in source code.  */
    { "type generic",           0, 0, false, true, true,
! 			      handle_type_generic_attribute, false },
    { "alloc_size",	      1, 2, false, true, true,
! 			      handle_alloc_size_attribute, false },
    { "cold",                   0, 0, true,  false, false,
! 			      handle_cold_attribute, false },
    { "hot",                    0, 0, true,  false, false,
! 			      handle_hot_attribute, false },
    { "no_address_safety_analysis",
  			      0, 0, true, false, false,
  			      handle_no_address_safety_analysis_attribute,
! 			      false },
    { "no_sanitize_address",    0, 0, true, false, false,
  			      handle_no_sanitize_address_attribute,
! 			      false },
    { "no_sanitize_undefined",  0, 0, true, false, false,
  			      handle_no_sanitize_undefined_attribute,
! 			      false },
    { "warning",		      1, 1, true,  false, false,
! 			      handle_error_attribute, false },
    { "error",		      1, 1, true,  false, false,
! 			      handle_error_attribute, false },
    { "target",                 1, -1, true, false, false,
! 			      handle_target_attribute, false },
    { "optimize",               1, -1, true, false, false,
! 			      handle_optimize_attribute, false },
    /* For internal use only.  The leading '*' both prevents its usage in
       source code and signals that it may be overridden by machine tables.  */
    { "*tm regparm",            0, 0, false, true, true,
! 			      ignore_attribute, false },
    { "no_split_stack",	      0, 0, true,  false, false,
! 			      handle_no_split_stack_attribute, false },
    /* For internal use (marking of builtins and runtime functions) only.
       The name contains space to prevent its usage in source code.  */
    { "fn spec",	 	      1, 1, false, true, true,
! 			      handle_fnspec_attribute, false },
    { "warn_unused",            0, 0, false, false, false,
! 			      handle_warn_unused_attribute, false },
    { "returns_nonnull",        0, 0, false, true, true,
! 			      handle_returns_nonnull_attribute, false },
    { "omp declare simd",       0, -1, true,  false, false,
! 			      handle_omp_declare_simd_attribute, false },
    { "cilk simd function",     0, -1, true,  false, false,
! 			      handle_omp_declare_simd_attribute, false },
    { "omp declare target",     0, 0, true, false, false,
! 			      handle_omp_declare_target_attribute, false },
    { "alloc_align",	      1, 1, false, true, true,
! 			      handle_alloc_align_attribute, false },
    { "assume_aligned",	      1, 2, false, true, true,
! 			      handle_assume_aligned_attribute, false },
    { "designated_init",        0, 0, false, true, false,
! 			      handle_designated_init_attribute, false },
    { "bnd_variable_size",      0, 0, true,  false, false,
! 			      handle_bnd_variable_size_attribute, false },
    { "bnd_legacy",             0, 0, true, false, false,
! 			      handle_bnd_legacy, false },
    { "bnd_instrument",         0, 0, true, false, false,
! 			      handle_bnd_instrument, false },
!   { NULL,                     0, 0, false, false, false, NULL, false }
  };
  
  /* Give the specifications for the format attributes, used by C and all
--- 647,832 ----
     Current list of processed common attributes: nonnull.  */
  const struct attribute_spec c_common_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, decl_handler,
!        type_handler, affects_type_identity } */
    { "packed",                 0, 0, false, false, false,
! 			      handle_packed_decl_attribute,
! 			      handle_packed_type_attribute, false},
    { "nocommon",               0, 0, true,  false, false,
! 			      handle_nocommon_attribute, NULL, false},
    { "common",                 0, 0, true,  false, false,
! 			      handle_common_attribute, NULL, false },
    /* FIXME: logically, noreturn attributes should be listed as
       "false, true, true" and apply to function types.  But implementing this
       would require all the places in the compiler that use TREE_THIS_VOLATILE
       on a decl to identify non-returning functions to be located and fixed
       to check the function type instead.  */
    { "noreturn",               0, 0, true,  false, false,
! 			      handle_noreturn_attribute, NULL, false },
    { "volatile",               0, 0, true,  false, false,
! 			      handle_noreturn_attribute, NULL, false },
    { "noinline",               0, 0, true,  false, false,
! 			      handle_noinline_attribute, NULL, false },
    { "noclone",                0, 0, true,  false, false,
! 			      handle_noclone_attribute, NULL, false },
    { "leaf",                   0, 0, true,  false, false,
! 			      handle_leaf_attribute, NULL, false },
    { "always_inline",          0, 0, true,  false, false,
! 			      handle_always_inline_attribute, NULL, false },
    { "gnu_inline",             0, 0, true,  false, false,
! 			      handle_gnu_inline_attribute, NULL, false },
    { "artificial",             0, 0, true,  false, false,
! 			      handle_artificial_attribute, NULL, false },
    { "flatten",                0, 0, true,  false, false,
! 			      handle_flatten_attribute, NULL, false },
    { "used",                   0, 0, true,  false, false,
! 			      handle_used_attribute, NULL, false },
    { "unused",                 0, 0, false, false, false,
! 			      handle_unused_decl_attribute,
! 			      handle_unused_type_attribute, false },
    { "externally_visible",     0, 0, true,  false, false,
! 			      handle_externally_visible_attribute, NULL,
! 			      false },
    { "no_reorder",	      0, 0, true, false, false,
!                               handle_no_reorder_attribute, NULL, false },
    /* The same comments as for noreturn attributes apply to const ones.  */
    { "const",                  0, 0, true,  false, false,
! 			      handle_const_attribute, NULL, false },
    { "transparent_union",      0, 0, false, false, false,
! 			      handle_transparent_union_decl_attribute,
! 			      handle_transparent_union_type_attribute, false },
    { "constructor",            0, 1, true,  false, false,
! 			      handle_constructor_attribute, NULL, false },
    { "destructor",             0, 1, true,  false, false,
! 			      handle_destructor_attribute, NULL, false },
!   { "mode",                   1, 1, false,  true, false, NULL,
  			      handle_mode_attribute, false },
    { "section",                1, 1, true,  false, false,
! 			      handle_section_attribute, NULL, false },
    { "aligned",                0, 1, false, false, false,
! 			      handle_aligned_decl_attribute,
! 			      handle_aligned_type_attribute, false },
    { "weak",                   0, 0, true,  false, false,
! 			      handle_weak_attribute, NULL, false },
    { "ifunc",                  1, 1, true,  false, false,
! 			      handle_ifunc_attribute, NULL, false },
    { "alias",                  1, 1, true,  false, false,
! 			      handle_alias_attribute, NULL, false },
    { "weakref",                0, 1, true,  false, false,
! 			      handle_weakref_attribute, NULL, false },
    { "no_instrument_function", 0, 0, true,  false, false,
  			      handle_no_instrument_function_attribute,
! 			      NULL, false },
    { "malloc",                 0, 0, true,  false, false,
! 			      handle_malloc_attribute, NULL, false },
    { "returns_twice",          0, 0, true,  false, false,
! 			      handle_returns_twice_attribute, NULL, false },
    { "no_stack_limit",         0, 0, true,  false, false,
! 			      handle_no_limit_stack_attribute, NULL, false },
    { "pure",                   0, 0, true,  false, false,
! 			      handle_pure_attribute, NULL, false },
!   { "transaction_callable",   0, 0, false, true,  false, NULL, 
  			      handle_tm_attribute, false },
    { "transaction_unsafe",     0, 0, false, true,  false,
! 			      NULL, handle_tm_attribute, false },
    { "transaction_safe",       0, 0, false, true,  false,
! 			      NULL, handle_tm_attribute, false },
    { "transaction_may_cancel_outer", 0, 0, false, true, false,
! 			      NULL, handle_tm_attribute, false },
    /* ??? These two attributes didn't make the transition from the
       Intel language document to the multi-vendor language document.  */
    { "transaction_pure",       0, 0, false, true,  false,
! 			      NULL, handle_tm_attribute, false },
    { "transaction_wrap",       1, 1, true,  false,  false,
! 			      handle_tm_wrap_attribute, NULL, false },
    /* For internal use (marking of builtins) only.  The name contains space
       to prevent its usage in source code.  */
    { "no vops",                0, 0, true,  false, false,
! 			      handle_novops_attribute, NULL, false },
    { "deprecated",             0, 1, false, false, false,
! 			      handle_deprecated_decl_attribute,
! 			      handle_deprecated_type_attribute, false },
    { "vector_size",	      1, 1, false, true, false,
! 			      NULL, handle_vector_size_attribute, false },
    { "visibility",	      1, 1, false, false, false,
! 			      handle_visibility_decl_attribute,
! 			      handle_visibility_type_attribute, false },
    { "tls_model",	      1, 1, true,  false, false,
! 			      handle_tls_model_attribute, NULL, false },
    { "nonnull",                0, -1, false, true, true,
! 			      NULL, handle_nonnull_attribute, false },
    { "nothrow",                0, 0, true,  false, false,
! 			      handle_nothrow_attribute, NULL, false },
!   { "may_alias",	      0, 0, false, true, false, NULL, NULL, false },
    { "cleanup",		      1, 1, true, false, false,
! 			      handle_cleanup_attribute, NULL, false },
!   { "warn_unused_result",     0, 0, false, true, true, NULL,
  			      handle_warn_unused_result_attribute, false },
    { "sentinel",               0, 1, false, true, true,
! 			      NULL, handle_sentinel_attribute, false },
    /* For internal use (marking of builtins) only.  The name contains space
       to prevent its usage in source code.  */
    { "type generic",           0, 0, false, true, true,
! 			      NULL, handle_type_generic_attribute, false },
    { "alloc_size",	      1, 2, false, true, true,
! 			      NULL, handle_alloc_size_attribute, false },
    { "cold",                   0, 0, true,  false, false,
! 			      handle_cold_attribute, NULL, false },
    { "hot",                    0, 0, true,  false, false,
! 			      handle_hot_attribute, NULL, false },
    { "no_address_safety_analysis",
  			      0, 0, true, false, false,
  			      handle_no_address_safety_analysis_attribute,
! 			      NULL, false },
    { "no_sanitize_address",    0, 0, true, false, false,
  			      handle_no_sanitize_address_attribute,
! 			      NULL, false },
    { "no_sanitize_undefined",  0, 0, true, false, false,
  			      handle_no_sanitize_undefined_attribute,
! 			      NULL, false },
    { "warning",		      1, 1, true,  false, false,
! 			      handle_error_attribute, NULL, false },
    { "error",		      1, 1, true,  false, false,
! 			      handle_error_attribute, NULL, false },
    { "target",                 1, -1, true, false, false,
! 			      handle_target_attribute, NULL, false },
    { "optimize",               1, -1, true, false, false,
! 			      handle_optimize_attribute, NULL, false },
    /* For internal use only.  The leading '*' both prevents its usage in
       source code and signals that it may be overridden by machine tables.  */
    { "*tm regparm",            0, 0, false, true, true,
! 			      NULL, ignore_attribute, false },
    { "no_split_stack",	      0, 0, true,  false, false,
! 			      handle_no_split_stack_attribute, NULL, false },
    /* For internal use (marking of builtins and runtime functions) only.
       The name contains space to prevent its usage in source code.  */
    { "fn spec",	 	      1, 1, false, true, true,
! 			      NULL, handle_fnspec_attribute, false },
    { "warn_unused",            0, 0, false, false, false,
! 			      handle_warn_unused_decl_attribute,
! 			      handle_warn_unused_type_attribute, false },
    { "returns_nonnull",        0, 0, false, true, true,
! 			      NULL, handle_returns_nonnull_attribute, false },
    { "omp declare simd",       0, -1, true,  false, false,
! 			      handle_omp_declare_simd_attribute, NULL, false },
    { "cilk simd function",     0, -1, true,  false, false,
! 			      handle_omp_declare_simd_attribute, NULL, false },
    { "omp declare target",     0, 0, true, false, false,
! 			      handle_omp_declare_target_attribute, NULL,
! 			      false },
    { "alloc_align",	      1, 1, false, true, true,
! 			      NULL, handle_alloc_align_attribute, false },
    { "assume_aligned",	      1, 2, false, true, true,
! 			      NULL, handle_assume_aligned_attribute, false },
    { "designated_init",        0, 0, false, true, false,
! 			      NULL, handle_designated_init_attribute, false },
    { "bnd_variable_size",      0, 0, true,  false, false,
! 			      handle_bnd_variable_size_attribute, NULL, false },
    { "bnd_legacy",             0, 0, true, false, false,
! 			      handle_bnd_legacy, NULL, false },
    { "bnd_instrument",         0, 0, true, false, false,
! 			      handle_bnd_instrument, NULL, false },
!   { NULL,                     0, 0, false, false, false, NULL, NULL, false }
  };
  
  /* Give the specifications for the format attributes, used by C and all
*************** const struct attribute_spec c_common_for
*** 822,831 ****
    /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
         affects_type_identity } */
    { "format",                 3, 3, false, true,  true,
! 			      handle_format_attribute, false },
    { "format_arg",             1, 1, false, true,  true,
! 			      handle_format_arg_attribute, false },
!   { NULL,                     0, 0, false, false, false, NULL, false }
  };
  
  /* Return identifier for address space AS.  */
--- 841,850 ----
    /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
         affects_type_identity } */
    { "format",                 3, 3, false, true,  true,
! 			      NULL, handle_format_attribute, false },
    { "format_arg",             1, 1, false, true,  true,
! 			      NULL, handle_format_arg_attribute, false },
!   { NULL,                     0, 0, false, false, false, NULL, NULL, false }
  };
  
  /* Return identifier for address space AS.  */
*************** attribute_takes_identifier_p (const_tree
*** 6547,6562 ****
     struct attribute_spec.handler.  */
  
  static tree
! handle_packed_attribute (tree *node, tree name, tree ARG_UNUSED (args),
! 			 int flags, bool *no_add_attrs)
  {
!   if (TYPE_P (*node))
!     {
!       if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
! 	*node = build_variant_type_copy (*node);
!       TYPE_PACKED (*node) = 1;
!     }
!   else if (TREE_CODE (*node) == FIELD_DECL)
      {
        if (TYPE_ALIGN (TREE_TYPE (*node)) <= BITS_PER_UNIT
  	  /* Still pack bitfields.  */
--- 6566,6575 ----
     struct attribute_spec.handler.  */
  
  static tree
! handle_packed_decl_attribute (tree *node, tree name, tree ARG_UNUSED (args),
! 			      int ARG_UNUSED (flags), bool *no_add_attrs)
  {
!   if (TREE_CODE (*node) == FIELD_DECL)
      {
        if (TYPE_ALIGN (TREE_TYPE (*node)) <= BITS_PER_UNIT
  	  /* Still pack bitfields.  */
*************** handle_packed_attribute (tree *node, tre
*** 6580,6585 ****
--- 6593,6610 ----
    return NULL_TREE;
  }
  
+ static tree
+ handle_packed_type_attribute (tree *node, tree ARG_UNUSED (name),
+ 			      tree ARG_UNUSED (args),
+ 			      int flags, bool *ARG_UNUSED (no_add_attrs))
+ {
+   if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
+     *node = build_variant_type_copy (*node);
+   TYPE_PACKED (*node) = 1;
+ 
+   return NULL_TREE;
+ }
+ 
  /* Handle a "nocommon" attribute; arguments as in
     struct attribute_spec.handler.  */
  
*************** handle_used_attribute (tree *pnode, tree
*** 6967,7004 ****
  
  /* Handle a "unused" attribute; arguments as in
     struct attribute_spec.handler.  */
- 
  static tree
! handle_unused_attribute (tree *node, tree name, tree ARG_UNUSED (args),
! 			 int flags, bool *no_add_attrs)
  {
!   if (DECL_P (*node))
!     {
!       tree decl = *node;
  
!       if (TREE_CODE (decl) == PARM_DECL
! 	  || TREE_CODE (decl) == VAR_DECL
! 	  || TREE_CODE (decl) == FUNCTION_DECL
! 	  || TREE_CODE (decl) == LABEL_DECL
! 	  || TREE_CODE (decl) == TYPE_DECL)
! 	{
! 	  TREE_USED (decl) = 1;
! 	  if (TREE_CODE (decl) == VAR_DECL
! 	      || TREE_CODE (decl) == PARM_DECL)
! 	    DECL_READ_P (decl) = 1;
! 	}
!       else
! 	{
! 	  warning (OPT_Wattributes, "%qE attribute ignored", name);
! 	  *no_add_attrs = true;
! 	}
      }
    else
      {
!       if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
! 	*node = build_variant_type_copy (*node);
!       TREE_USED (*node) = 1;
      }
  
    return NULL_TREE;
  }
--- 6992,7031 ----
  
  /* Handle a "unused" attribute; arguments as in
     struct attribute_spec.handler.  */
  static tree
! handle_unused_decl_attribute (tree *node, tree name, tree ARG_UNUSED (args),
! 			      int ARG_UNUSED (flags), bool *no_add_attrs)
  {
!   tree decl = *node;
  
!   if (TREE_CODE (decl) == PARM_DECL
!       || TREE_CODE (decl) == VAR_DECL
!       || TREE_CODE (decl) == FUNCTION_DECL
!       || TREE_CODE (decl) == LABEL_DECL
!       || TREE_CODE (decl) == TYPE_DECL)
!     {
!       TREE_USED (decl) = 1;
!       if (TREE_CODE (decl) == VAR_DECL
! 	  || TREE_CODE (decl) == PARM_DECL)
! 	DECL_READ_P (decl) = 1;
      }
    else
      {
!       warning (OPT_Wattributes, "%qE attribute ignored", name);
!       *no_add_attrs = true;
      }
+   return NULL_TREE;
+ }
+ 
+ 
+ static tree
+ handle_unused_type_attribute (tree *node, tree ARG_UNUSED (name),
+ 			      tree ARG_UNUSED (args), int flags,
+ 			      bool *ARG_UNUSED (no_add_attrs))
+ {
+   if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
+     *node = build_variant_type_copy (*node);
+   TREE_USED (*node) = 1;
  
    return NULL_TREE;
  }
*************** handle_const_attribute (tree *node, tree
*** 7090,7109 ****
     struct attribute_spec.handler.  */
  
  static tree
! handle_transparent_union_attribute (tree *node, tree name,
! 				    tree ARG_UNUSED (args), int flags,
! 				    bool *no_add_attrs)
  {
!   tree type;
! 
    *no_add_attrs = true;
  
- 
-   if (TREE_CODE (*node) == TYPE_DECL
-       && ! (flags & ATTR_FLAG_CXX11))
-     node = &TREE_TYPE (*node);
-   type = *node;
- 
    if (TREE_CODE (type) == UNION_TYPE)
      {
        /* Make sure that the first field will work for a transparent union.
--- 7117,7129 ----
     struct attribute_spec.handler.  */
  
  static tree
! handle_transparent_union_type_attribute (tree *node, tree name,
! 					 tree ARG_UNUSED (args), int flags,
! 					 bool *no_add_attrs)
  {
!   tree type = *node;
    *no_add_attrs = true;
  
    if (TREE_CODE (type) == UNION_TYPE)
      {
        /* Make sure that the first field will work for a transparent union.
*************** handle_transparent_union_attribute (tree
*** 7143,7148 ****
--- 7163,7183 ----
    return NULL_TREE;
  }
  
+ 
+ static tree
+ handle_transparent_union_decl_attribute (tree *node, tree name, tree args,
+ 					 int flags, bool *no_add_attrs)
+ {
+   *no_add_attrs = true;
+ 
+   if (TREE_CODE (*node) == TYPE_DECL && !(flags & ATTR_FLAG_CXX11))
+     return handle_transparent_union_type_attribute (&TREE_TYPE (*node), name,
+ 						    args, flags, no_add_attrs);
+ 
+   warning (OPT_Wattributes, "%qE attribute ignored", name);
+   return NULL_TREE;
+ }
+ 
  /* Subroutine of handle_{con,de}structor_attribute.  Evaluate ARGS to
     get the requested priority for a constructor or destructor,
     possibly issuing diagnostics for invalid or reserved
*************** check_cxx_fundamental_alignment_constrai
*** 7663,7680 ****
    return !alignment_too_large_p;
  }
  
! /* Handle a "aligned" attribute; arguments as in
!    struct attribute_spec.handler.  */
  
  static tree
! handle_aligned_attribute (tree *node, tree ARG_UNUSED (name), tree args,
! 			  int flags, bool *no_add_attrs)
  {
-   tree decl = NULL_TREE;
-   tree *type = NULL;
-   int is_type = 0;
    tree align_expr;
-   int i;
  
    if (args)
      {
--- 7698,7709 ----
    return !alignment_too_large_p;
  }
  
! /* Return the alignment expression from tree_list element ARGS.  */
  
  static tree
! get_align_expr (tree args)
  {
    tree align_expr;
  
    if (args)
      {
*************** handle_aligned_attribute (tree *node, tr
*** 7686,7725 ****
    else
      align_expr = size_int (ATTRIBUTE_ALIGNED_VALUE / BITS_PER_UNIT);
  
!   if (DECL_P (*node))
!     {
!       decl = *node;
!       type = &TREE_TYPE (decl);
!       is_type = TREE_CODE (*node) == TYPE_DECL;
!     }
!   else if (TYPE_P (*node))
!     type = node, is_type = 1;
  
    if ((i = check_user_alignment (align_expr, false)) == -1
        || !check_cxx_fundamental_alignment_constraints (*node, i, flags))
      *no_add_attrs = true;
!   else if (is_type)
!     {
!       if ((flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
! 	/* OK, modify the type in place.  */;
!       /* If we have a TYPE_DECL, then copy the type, so that we
! 	 don't accidentally modify a builtin type.  See pushdecl.  */
!       else if (decl && TREE_TYPE (decl) != error_mark_node
! 	       && DECL_ORIGINAL_TYPE (decl) == NULL_TREE)
! 	{
! 	  tree tt = TREE_TYPE (decl);
! 	  *type = build_variant_type_copy (*type);
! 	  DECL_ORIGINAL_TYPE (decl) = tt;
! 	  TYPE_NAME (*type) = decl;
! 	  TREE_USED (*type) = TREE_USED (decl);
! 	  TREE_TYPE (decl) = *type;
! 	}
!       else
! 	*type = build_variant_type_copy (*type);
  
!       TYPE_ALIGN (*type) = (1U << i) * BITS_PER_UNIT;
!       TYPE_USER_ALIGN (*type) = 1;
      }
    else if (! VAR_OR_FUNCTION_DECL_P (decl)
  	   && TREE_CODE (decl) != FIELD_DECL)
      {
--- 7715,7774 ----
    else
      align_expr = size_int (ATTRIBUTE_ALIGNED_VALUE / BITS_PER_UNIT);
  
!   return align_expr;
! }
! 
! /* Set the type alignment fields of NODE, based on FLAGS to I.  */
! 
! static void
! handle_aligned_type (tree *node, int flags, int i)
! {
!   if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
!     *node = build_variant_type_copy (*node);
! 
!   TYPE_ALIGN (*node) = (1U << i) * BITS_PER_UNIT;
!   TYPE_USER_ALIGN (*node) = 1;
! }
! 
! /* Handle a "aligned" attribute; arguments as in
!    struct attribute_spec.handler.  */
! 
! static tree
! handle_aligned_type_attribute (tree *node, tree ARG_UNUSED (name), tree args,
! 			  int flags, bool *no_add_attrs)
! {
!   tree align_expr;
!   int i;
! 
!   align_expr = get_align_expr (args);
  
    if ((i = check_user_alignment (align_expr, false)) == -1
        || !check_cxx_fundamental_alignment_constraints (*node, i, flags))
      *no_add_attrs = true;
!   else 
!     handle_aligned_type (node, flags, i);
! 
!   return NULL_TREE;
! }
! 
! 
! static tree
! handle_aligned_decl_attribute (tree *node, tree ARG_UNUSED (name), tree args,
! 			       int flags, bool *no_add_attrs)
! {
!   tree align_expr;
!   tree decl = *node;
!   int i;
  
!   align_expr = get_align_expr (args);
! 
!   if ((i = check_user_alignment (align_expr, false)) == -1
!       || !check_cxx_fundamental_alignment_constraints (*node, i, flags))
!     {
!       *no_add_attrs = true;
      }
+   else if (TREE_CODE (*node) == TYPE_DECL)
+     handle_aligned_type (&TREE_TYPE (*node), flags, i);
    else if (! VAR_OR_FUNCTION_DECL_P (decl)
  	   && TREE_CODE (decl) != FIELD_DECL)
      {
*************** handle_weakref_attribute (tree *node, tr
*** 7960,8020 ****
    return NULL_TREE;
  }
  
! /* Handle an "visibility" attribute; arguments as in
!    struct attribute_spec.handler.  */
  
! static tree
! handle_visibility_attribute (tree *node, tree name, tree args,
! 			     int ARG_UNUSED (flags),
! 			     bool *ARG_UNUSED (no_add_attrs))
  {
-   tree decl = *node;
-   tree id = TREE_VALUE (args);
    enum symbol_visibility vis;
  
-   if (TYPE_P (*node))
-     {
-       if (TREE_CODE (*node) == ENUMERAL_TYPE)
- 	/* OK */;
-       else if (TREE_CODE (*node) != RECORD_TYPE && TREE_CODE (*node) != UNION_TYPE)
- 	{
- 	  warning (OPT_Wattributes, "%qE attribute ignored on non-class types",
- 		   name);
- 	  return NULL_TREE;
- 	}
-       else if (TYPE_FIELDS (*node))
- 	{
- 	  error ("%qE attribute ignored because %qT is already defined",
- 		 name, *node);
- 	  return NULL_TREE;
- 	}
-     }
-   else if (decl_function_context (decl) != 0 || !TREE_PUBLIC (decl))
-     {
-       warning (OPT_Wattributes, "%qE attribute ignored", name);
-       return NULL_TREE;
-     }
- 
-   if (TREE_CODE (id) != STRING_CST)
-     {
-       error ("visibility argument not a string");
-       return NULL_TREE;
-     }
- 
-   /*  If this is a type, set the visibility on the type decl.  */
-   if (TYPE_P (decl))
-     {
-       decl = TYPE_NAME (decl);
-       if (!decl)
- 	return NULL_TREE;
-       if (TREE_CODE (decl) == IDENTIFIER_NODE)
- 	{
- 	   warning (OPT_Wattributes, "%qE attribute ignored on types",
- 		    name);
- 	   return NULL_TREE;
- 	}
-     }
- 
    if (strcmp (TREE_STRING_POINTER (id), "default") == 0)
      vis = VISIBILITY_DEFAULT;
    else if (strcmp (TREE_STRING_POINTER (id), "internal") == 0)
--- 8009,8021 ----
    return NULL_TREE;
  }
  
! /* Process the DECL common parts of handle_visibility_attribute.  */
  
! static void
! handle_decl_visibility (tree decl, tree id, tree attributes)
  {
    enum symbol_visibility vis;
  
    if (strcmp (TREE_STRING_POINTER (id), "default") == 0)
      vis = VISIBILITY_DEFAULT;
    else if (strcmp (TREE_STRING_POINTER (id), "internal") == 0)
*************** handle_visibility_attribute (tree *node,
*** 8032,8040 ****
    if (DECL_VISIBILITY_SPECIFIED (decl)
        && vis != DECL_VISIBILITY (decl))
      {
-       tree attributes = (TYPE_P (*node)
- 			 ? TYPE_ATTRIBUTES (*node)
- 			 : DECL_ATTRIBUTES (decl));
        if (lookup_attribute ("visibility", attributes))
  	error ("%qD redeclared with different visibility", decl);
        else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
--- 8033,8038 ----
*************** handle_visibility_attribute (tree *node,
*** 8049,8054 ****
--- 8047,8127 ----
  
    DECL_VISIBILITY (decl) = vis;
    DECL_VISIBILITY_SPECIFIED (decl) = 1;
+ }
+ 
+ /* Handle an "visibility" attribute; arguments as in
+    struct attribute_spec.handler.  */
+ static tree
+ handle_visibility_decl_attribute (tree *node, tree name, tree args,
+ 				  int ARG_UNUSED (flags),
+ 				  bool *ARG_UNUSED (no_add_attrs))
+ {
+   tree decl = *node;
+   tree id = TREE_VALUE (args);
+ 
+   if (decl_function_context (decl) != 0 || !TREE_PUBLIC (decl))
+     {
+       warning (OPT_Wattributes, "%qE attribute ignored", name);
+       return NULL_TREE;
+     }
+ 
+   if (TREE_CODE (id) != STRING_CST)
+     {
+       error ("visibility argument not a string");
+       return NULL_TREE;
+     }
+ 
+   handle_decl_visibility (decl, id, DECL_ATTRIBUTES (decl));
+   /* Go ahead and attach the attribute to the node as well.  This is needed
+      so we can determine whether we have VISIBILITY_DEFAULT because the
+      visibility was not specified, or because it was explicitly overridden
+      from the containing scope.  */
+ 
+   return NULL_TREE;
+ }
+ 
+ 
+ static tree
+ handle_visibility_type_attribute (tree *node, tree name, tree args,
+ 				  int ARG_UNUSED (flags),
+ 				  bool *ARG_UNUSED (no_add_attrs))
+ {
+   tree decl;
+   tree id = TREE_VALUE (args);
+ 
+   if (TREE_CODE (*node) == ENUMERAL_TYPE)
+     /* OK */;
+   else if (TREE_CODE (*node) != RECORD_TYPE && TREE_CODE (*node) != UNION_TYPE)
+     {
+       warning (OPT_Wattributes, "%qE attribute ignored on non-class types",
+ 	       name);
+       return NULL_TREE;
+     }
+   else if (TYPE_FIELDS (*node))
+     {
+       error ("%qE attribute ignored because %qT is already defined",
+ 	     name, *node);
+       return NULL_TREE;
+     }
+ 
+   if (TREE_CODE (id) != STRING_CST)
+     {
+       error ("visibility argument not a string");
+       return NULL_TREE;
+     }
+ 
+   decl = TYPE_NAME (*node);
+   if (!decl)
+     return NULL_TREE;
+ 
+   if (TREE_CODE (decl) == IDENTIFIER_NODE)
+     {
+        warning (OPT_Wattributes, "%qE attribute ignored on types",
+ 		name);
+        return NULL_TREE;
+     }
+ 
+   handle_decl_visibility (decl, id, TYPE_ATTRIBUTES (*node));
  
    /* Go ahead and attach the attribute to the node as well.  This is needed
       so we can determine whether we have VISIBILITY_DEFAULT because the
*************** handle_fnspec_attribute (tree *node ATTR
*** 8273,8279 ****
  			 tree args, int ARG_UNUSED (flags),
  			 bool *no_add_attrs ATTRIBUTE_UNUSED)
  {
!   gcc_assert (args
  	      && TREE_CODE (TREE_VALUE (args)) == STRING_CST
  	      && !TREE_CHAIN (args));
    return NULL_TREE;
--- 8346,8352 ----
  			 tree args, int ARG_UNUSED (flags),
  			 bool *no_add_attrs ATTRIBUTE_UNUSED)
  {
!   gcc_assert (TYPE_P (*node) && args
  	      && TREE_CODE (TREE_VALUE (args)) == STRING_CST
  	      && !TREE_CHAIN (args));
    return NULL_TREE;
*************** handle_bnd_instrument (tree *node, tree
*** 8331,8350 ****
     struct attribute_spec.handler.  */
  
  static tree
! handle_warn_unused_attribute (tree *node, tree name,
! 			      tree args ATTRIBUTE_UNUSED,
! 			      int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
  {
!   if (TYPE_P (*node))
!     /* Do nothing else, just set the attribute.  We'll get at
!        it later with lookup_attribute.  */
!     ;
!   else
!     {
!       warning (OPT_Wattributes, "%qE attribute ignored", name);
!       *no_add_attrs = true;
!     }
  
    return NULL_TREE;
  }
  
--- 8404,8429 ----
     struct attribute_spec.handler.  */
  
  static tree
! handle_warn_unused_type_attribute (tree *node ATTRIBUTE_UNUSED,
! 				   tree name ATTRIBUTE_UNUSED,
! 				   tree args ATTRIBUTE_UNUSED,
! 				   int flags ATTRIBUTE_UNUSED,
! 				   bool *no_add_attrs ATTRIBUTE_UNUSED)
  {
!   /* Do nothing else, just set the attribute.  We'll get at
!      it later with lookup_attribute.  */
!   return NULL_TREE;
! }
  
+ static tree
+ handle_warn_unused_decl_attribute (tree *node ATTRIBUTE_UNUSED,
+ 				   tree name ATTRIBUTE_UNUSED,
+ 				   tree args ATTRIBUTE_UNUSED,
+ 				   int flags ATTRIBUTE_UNUSED,
+ 				   bool *no_add_attrs ATTRIBUTE_UNUSED)
+ {
+   /* Do nothing else, just set the attribute.  We'll get at
+      it later with lookup_attribute.  */
    return NULL_TREE;
  }
  
*************** handle_novops_attribute (tree *node, tre
*** 8668,8681 ****
     struct attribute_spec.handler.  */
  
  static tree
! handle_deprecated_attribute (tree *node, tree name,
! 			     tree args, int flags,
! 			     bool *no_add_attrs)
  {
-   tree type = NULL_TREE;
-   int warn = 0;
-   tree what = NULL_TREE;
- 
    if (!args)
      *no_add_attrs = true;
    else if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
--- 8747,8756 ----
     struct attribute_spec.handler.  */
  
  static tree
! handle_deprecated_type_attribute (tree *node, tree ARG_UNUSED (name),
! 				  tree args, int flags,
! 				  bool *no_add_attrs)
  {
    if (!args)
      *no_add_attrs = true;
    else if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
*************** handle_deprecated_attribute (tree *node,
*** 8684,8716 ****
        *no_add_attrs = true;
      }
  
!   if (DECL_P (*node))
!     {
!       tree decl = *node;
!       type = TREE_TYPE (decl);
  
!       if (TREE_CODE (decl) == TYPE_DECL
! 	  || TREE_CODE (decl) == PARM_DECL
! 	  || TREE_CODE (decl) == VAR_DECL
! 	  || TREE_CODE (decl) == FUNCTION_DECL
! 	  || TREE_CODE (decl) == FIELD_DECL
! 	  || objc_method_decl (TREE_CODE (decl)))
! 	TREE_DEPRECATED (decl) = 1;
!       else
! 	warn = 1;
!     }
!   else if (TYPE_P (*node))
      {
!       if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
! 	*node = build_variant_type_copy (*node);
!       TREE_DEPRECATED (*node) = 1;
!       type = *node;
      }
-   else
-     warn = 1;
  
!   if (warn)
      {
        *no_add_attrs = true;
        if (type && TYPE_NAME (type))
  	{
--- 8759,8798 ----
        *no_add_attrs = true;
      }
  
!   if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
!     *node = build_variant_type_copy (*node);
!   TREE_DEPRECATED (*node) = 1;
  
!   return NULL_TREE;
! }
! 
! 
! static tree
! handle_deprecated_decl_attribute (tree *node, tree name,
! 				  tree args, int ARG_UNUSED (flags),
! 				  bool *no_add_attrs)
! {
!   tree decl = *node;
!   tree what = NULL_TREE;
! 
!   if (!args)
!     *no_add_attrs = true;
!   else if (TREE_CODE (TREE_VALUE (args)) != STRING_CST)
      {
!       error ("deprecated message is not a string");
!       *no_add_attrs = true;
      }
  
!   if (TREE_CODE (decl) == TYPE_DECL
!       || TREE_CODE (decl) == PARM_DECL
!       || TREE_CODE (decl) == VAR_DECL
!       || TREE_CODE (decl) == FUNCTION_DECL
!       || TREE_CODE (decl) == FIELD_DECL
!       || objc_method_decl (TREE_CODE (decl)))
!     TREE_DEPRECATED (decl) = 1;
!   else
      {
+       tree type = TREE_TYPE (decl);
        *no_add_attrs = true;
        if (type && TYPE_NAME (type))
  	{
Index: fortran/f95-lang.c
===================================================================
*** fortran/f95-lang.c	(revision 217943)
--- fortran/f95-lang.c	(working copy)
*************** gfc_handle_omp_declare_target_attribute
*** 108,118 ****
  /* Table of valid Fortran attributes.  */
  static const struct attribute_spec gfc_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
!        affects_type_identity } */
    { "omp declare target", 0, 0, true,  false, false,
!     gfc_handle_omp_declare_target_attribute, false },
!   { NULL,		  0, 0, false, false, false, NULL, false }
  };
  
  #undef LANG_HOOKS_NAME
--- 108,118 ----
  /* Table of valid Fortran attributes.  */
  static const struct attribute_spec gfc_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, decl_handler,
!        type_handler, affects_type_identity } */
    { "omp declare target", 0, 0, true,  false, false,
!     gfc_handle_omp_declare_target_attribute, NULL, false },
!   { NULL,		  0, 0, false, false, false, NULL, NULL, false }
  };
  
  #undef LANG_HOOKS_NAME
Index: java/lang.c
===================================================================
*** java/lang.c	(revision 217943)
--- java/lang.c	(working copy)
*************** static tree java_eh_personality (void);
*** 72,80 ****
  /* Table of machine-independent attributes.  */
  const struct attribute_spec java_attribute_table[] =
  {
!  { "nonnull",                0, -1, false, true, true,
! 			      NULL, false },
!   { NULL,                     0, 0, false, false, false, NULL, false }
  };
  
  /* Used to avoid printing error messages with bogus function
--- 72,79 ----
  /* Table of machine-independent attributes.  */
  const struct attribute_spec java_attribute_table[] =
  {
!  { "nonnull",                0, -1, false, true, true, NULL, NULL, false },
!   { NULL,                     0, 0, false, false, false, NULL, NULL, false }
  };
  
  /* Used to avoid printing error messages with bogus function
Index: lto/lto-lang.c
===================================================================
*** lto/lto-lang.c	(revision 217943)
--- lto/lto-lang.c	(working copy)
*************** const struct attribute_spec lto_attribut
*** 82,118 ****
    /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
         do_diagnostic } */
    { "noreturn",               0, 0, true,  false, false,
! 			      handle_noreturn_attribute, false },
    { "leaf",		      0, 0, true,  false, false,
! 			      handle_leaf_attribute, false },
    /* The same comments as for noreturn attributes apply to const ones.  */
    { "const",                  0, 0, true,  false, false,
! 			      handle_const_attribute, false },
    { "malloc",                 0, 0, true,  false, false,
! 			      handle_malloc_attribute, false },
    { "pure",                   0, 0, true,  false, false,
! 			      handle_pure_attribute, false },
    { "no vops",                0, 0, true,  false, false,
! 			      handle_novops_attribute, false },
    { "nonnull",                0, -1, false, true, true,
! 			      handle_nonnull_attribute, false },
    { "nothrow",                0, 0, true,  false, false,
! 			      handle_nothrow_attribute, false },
    { "returns_twice",          0, 0, true,  false, false,
! 			      handle_returns_twice_attribute, false },
    { "sentinel",               0, 1, false, true, true,
! 			      handle_sentinel_attribute, false },
    { "type generic",           0, 0, false, true, true,
! 			      handle_type_generic_attribute, false },
    { "fn spec",	 	      1, 1, false, true, true,
! 			      handle_fnspec_attribute, false },
    { "transaction_pure",	      0, 0, false, true, true,
! 			      handle_transaction_pure_attribute, false },
    /* For internal use only.  The leading '*' both prevents its usage in
       source code and signals that it may be overridden by machine tables.  */
    { "*tm regparm",            0, 0, false, true, true,
! 			      ignore_attribute, false },
!   { NULL,                     0, 0, false, false, false, NULL, false }
  };
  
  /* Give the specifications for the format attributes, used by C and all
--- 82,119 ----
    /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
         do_diagnostic } */
    { "noreturn",               0, 0, true,  false, false,
! 			      handle_noreturn_attribute, NULL, false },
    { "leaf",		      0, 0, true,  false, false,
! 			      handle_leaf_attribute, NULL, false },
    /* The same comments as for noreturn attributes apply to const ones.  */
    { "const",                  0, 0, true,  false, false,
! 			      handle_const_attribute, NULL, false },
    { "malloc",                 0, 0, true,  false, false,
! 			      handle_malloc_attribute, NULL, false },
    { "pure",                   0, 0, true,  false, false,
! 			      handle_pure_attribute, NULL, false },
    { "no vops",                0, 0, true,  false, false,
! 			      handle_novops_attribute, NULL, false },
    { "nonnull",                0, -1, false, true, true,
! 			      NULL, handle_nonnull_attribute, false },
    { "nothrow",                0, 0, true,  false, false,
! 			      handle_nothrow_attribute, NULL, false },
    { "returns_twice",          0, 0, true,  false, false,
! 			      handle_returns_twice_attribute, NULL, false },
    { "sentinel",               0, 1, false, true, true,
! 			      NULL, handle_sentinel_attribute, false },
    { "type generic",           0, 0, false, true, true,
! 			      NULL, handle_type_generic_attribute, false },
    { "fn spec",	 	      1, 1, false, true, true,
! 			      NULL, handle_fnspec_attribute, false },
    { "transaction_pure",	      0, 0, false, true, true,
! 			      NULL, handle_transaction_pure_attribute, false },
    /* For internal use only.  The leading '*' both prevents its usage in
       source code and signals that it may be overridden by machine tables.  */
    { "*tm regparm",            0, 0, false, true, true,
! 			      NULL, ignore_attribute,
! 			      false },
!   { NULL,                     0, 0, false, false, false, NULL, NULL, false }
  };
  
  /* Give the specifications for the format attributes, used by C and all
*************** const struct attribute_spec lto_format_a
*** 123,132 ****
    /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
         affects_type_identity } */
    { "format",                 3, 3, false, true,  true,
  			      handle_format_attribute, false },
    { "format_arg",             1, 1, false, true,  true,
  			      handle_format_arg_attribute, false },
!   { NULL,                     0, 0, false, false, false, NULL, false }
  };
  
  enum built_in_attribute
--- 124,135 ----
    /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
         affects_type_identity } */
    { "format",                 3, 3, false, true,  true,
+ 			      NULL,
  			      handle_format_attribute, false },
    { "format_arg",             1, 1, false, true,  true,
+ 			      NULL,
  			      handle_format_arg_attribute, false },
!   { NULL,                     0, 0, false, false, false, NULL, NULL, false }
  };
  
  enum built_in_attribute
Index: config/alpha/alpha.c
===================================================================
*** config/alpha/alpha.c	(revision 217943)
--- config/alpha/alpha.c	(working copy)
*************** common_object_handler (tree *node, tree
*** 7542,7551 ****
  
  static const struct attribute_spec vms_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
!        affects_type_identity } */
!   { COMMON_OBJECT,   0, 1, true,  false, false, common_object_handler, false },
!   { NULL,            0, 0, false, false, false, NULL, false }
  };
  
  void
--- 7542,7552 ----
  
  static const struct attribute_spec vms_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, decl_handler,
!        type_handler, affects_type_identity } */
!   { COMMON_OBJECT,   0, 1, true,  false, false, common_object_handler, NULL,
!     false },
!   { NULL,            0, 0, false, false, false, NULL, NULL, false }
  };
  
  void
Index: config/arc/arc.c
===================================================================
*** config/arc/arc.c	(revision 217943)
--- config/arc/arc.c	(working copy)
*************** static tree arc_handle_interrupt_attribu
*** 366,385 ****
     machine specific supported attributes.  */
  const struct attribute_spec arc_attribute_table[] =
  {
!  /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
!       affects_type_identity } */
!   { "interrupt", 1, 1, true, false, false, arc_handle_interrupt_attribute, true },
    /* Function calls made to this symbol must be done indirectly, because
       it may lie outside of the 21/25 bit addressing range of a normal function
       call.  */
!   { "long_call",    0, 0, false, true,  true,  NULL, false },
    /* Whereas these functions are always known to reside within the 25 bit
       addressing range of unconditionalized bl.  */
!   { "medium_call",   0, 0, false, true,  true,  NULL, false },
    /* And these functions are always known to reside within the 21 bit
       addressing range of blcc.  */
!   { "short_call",   0, 0, false, true,  true,  NULL, false },
!   { NULL, 0, 0, false, false, false, NULL, false }
  };
  static int arc_comp_type_attributes (const_tree, const_tree);
  static void arc_file_start (void);
--- 366,386 ----
     machine specific supported attributes.  */
  const struct attribute_spec arc_attribute_table[] =
  {
!  /* { name, min_len, max_len, decl_req, type_req, fn_type_req, decl_handler,
!       type_handler, affects_type_identity } */
!   { "interrupt", 1, 1, true, false, false, arc_handle_interrupt_attribute,
!     NULL, true },
    /* Function calls made to this symbol must be done indirectly, because
       it may lie outside of the 21/25 bit addressing range of a normal function
       call.  */
!   { "long_call",    0, 0, false, true,  true,  NULL, NULL, false },
    /* Whereas these functions are always known to reside within the 25 bit
       addressing range of unconditionalized bl.  */
!   { "medium_call",   0, 0, false, true,  true,  NULL, NULL, false },
    /* And these functions are always known to reside within the 21 bit
       addressing range of blcc.  */
!   { "short_call",   0, 0, false, true,  true,  NULL, NULL, false },
!   { NULL, 0, 0, false, false, false, NULL, NULL, false }
  };
  static int arc_comp_type_attributes (const_tree, const_tree);
  static void arc_file_start (void);
Index: config/arm/arm.c
===================================================================
*** config/arm/arm.c	(revision 217943)
--- config/arm/arm.c	(working copy)
*************** static unsigned long arm_isr_value (tree
*** 149,155 ****
  static unsigned long arm_compute_func_type (void);
  static tree arm_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
  static tree arm_handle_pcs_attribute (tree *, tree, tree, int, bool *);
! static tree arm_handle_isr_attribute (tree *, tree, tree, int, bool *);
  #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
  static tree arm_handle_notshared_attribute (tree *, tree, tree, int, bool *);
  #endif
--- 149,156 ----
  static unsigned long arm_compute_func_type (void);
  static tree arm_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
  static tree arm_handle_pcs_attribute (tree *, tree, tree, int, bool *);
! static tree arm_handle_isr_decl_attribute (tree *, tree, tree, int, bool *);
! static tree arm_handle_isr_type_attribute (tree *, tree, tree, int, bool *);
  #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
  static tree arm_handle_notshared_attribute (tree *, tree, tree, int, bool *);
  #endif
*************** static void arm_sched_fusion_priority (r
*** 309,333 ****
  /* Table of machine attributes.  */
  static const struct attribute_spec arm_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
!        affects_type_identity } */
    /* Function calls made to this symbol must be done indirectly, because
       it may lie outside of the 26 bit addressing range of a normal function
       call.  */
!   { "long_call",    0, 0, false, true,  true,  NULL, false },
    /* Whereas these functions are always known to reside within the 26 bit
       addressing range.  */
!   { "short_call",   0, 0, false, true,  true,  NULL, false },
    /* Specify the procedure call conventions for a function.  */
!   { "pcs",          1, 1, false, true,  true,  arm_handle_pcs_attribute,
      false },
    /* Interrupt Service Routines have special prologue and epilogue requirements.  */
!   { "isr",          0, 1, false, false, false, arm_handle_isr_attribute,
!     false },
!   { "interrupt",    0, 1, false, false, false, arm_handle_isr_attribute,
      false },
    { "naked",        0, 0, true,  false, false, arm_handle_fndecl_attribute,
!     false },
  #ifdef ARM_PE
    /* ARM/PE has three new attributes:
       interfacearm - ?
--- 310,335 ----
  /* Table of machine attributes.  */
  static const struct attribute_spec arm_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, decl_handler,
!        type_handle, affects_type_identity } */
    /* Function calls made to this symbol must be done indirectly, because
       it may lie outside of the 26 bit addressing range of a normal function
       call.  */
!   { "long_call",    0, 0, false, true,  true,  NULL, NULL, false },
    /* Whereas these functions are always known to reside within the 26 bit
       addressing range.  */
!   { "short_call",   0, 0, false, true,  true,  NULL, NULL, false },
    /* Specify the procedure call conventions for a function.  */
!   { "pcs",          1, 1, false, true,  true, NULL, arm_handle_pcs_attribute, 
      false },
    /* Interrupt Service Routines have special prologue and epilogue requirements.  */
!   { "isr",          0, 1, false, false, false, arm_handle_isr_decl_attribute,
!     arm_handle_isr_type_attribute, false },
!   { "interrupt",    0, 1, false, false, false, arm_handle_isr_decl_attribute,
!     arm_handle_isr_type_attribute, 
      false },
    { "naked",        0, 0, true,  false, false, arm_handle_fndecl_attribute,
!     NULL, false },
  #ifdef ARM_PE
    /* ARM/PE has three new attributes:
       interfacearm - ?
*************** static const struct attribute_spec arm_a
*** 338,354 ****
       them with spaces.  We do NOT support this.  Instead, use __declspec
       multiple times.
    */
!   { "dllimport",    0, 0, true,  false, false, NULL, false },
!   { "dllexport",    0, 0, true,  false, false, NULL, false },
    { "interfacearm", 0, 0, true,  false, false, arm_handle_fndecl_attribute,
!     false },
  #elif TARGET_DLLIMPORT_DECL_ATTRIBUTES
!   { "dllimport",    0, 0, false, false, false, handle_dll_attribute, false },
!   { "dllexport",    0, 0, false, false, false, handle_dll_attribute, false },
!   { "notshared",    0, 0, false, true, false, arm_handle_notshared_attribute,
!     false },
  #endif
!   { NULL,           0, 0, false, false, false, NULL, false }
  };
  
  /* Initialize the GCC target structure.  */
--- 340,358 ----
       them with spaces.  We do NOT support this.  Instead, use __declspec
       multiple times.
    */
!   { "dllimport",    0, 0, true,  false, false, NULL, NULL, false },
!   { "dllexport",    0, 0, true,  false, false, NULL, NULL, false },
    { "interfacearm", 0, 0, true,  false, false, arm_handle_fndecl_attribute,
!     NULL, false },
  #elif TARGET_DLLIMPORT_DECL_ATTRIBUTES
!   { "dllimport",    0, 0, false, false, false, handle_dll_decl_attribute,
!     handle_dll_type_attribute, false },
!   { "dllexport",    0, 0, false, false, false, handle_dll_decl_attribute,
!     handle_dll_type_attribute, false },
!   { "notshared",    0, 0, false, true, false, NULL,
!     arm_handle_notshared_attribute, false },
  #endif
!   { NULL,           0, 0, false, false, false, NULL, NULL, false }
  };
  
  /* Initialize the GCC target structure.  */
*************** arm_handle_fndecl_attribute (tree *node,
*** 6104,6161 ****
  /* Handle an "interrupt" or "isr" attribute;
     arguments as in struct attribute_spec.handler.  */
  static tree
! arm_handle_isr_attribute (tree *node, tree name, tree args, int flags,
! 			  bool *no_add_attrs)
  {
!   if (DECL_P (*node))
      {
!       if (TREE_CODE (*node) != FUNCTION_DECL)
  	{
! 	  warning (OPT_Wattributes, "%qE attribute only applies to functions",
  		   name);
  	  *no_add_attrs = true;
  	}
!       /* FIXME: the argument if any is checked for type attributes;
! 	 should it be checked for decl ones?  */
      }
    else
      {
!       if (TREE_CODE (*node) == FUNCTION_TYPE
! 	  || TREE_CODE (*node) == METHOD_TYPE)
  	{
- 	  if (arm_isr_value (args) == ARM_FT_UNKNOWN)
- 	    {
- 	      warning (OPT_Wattributes, "%qE attribute ignored",
- 		       name);
- 	      *no_add_attrs = true;
- 	    }
- 	}
-       else if (TREE_CODE (*node) == POINTER_TYPE
- 	       && (TREE_CODE (TREE_TYPE (*node)) == FUNCTION_TYPE
- 		   || TREE_CODE (TREE_TYPE (*node)) == METHOD_TYPE)
- 	       && arm_isr_value (args) != ARM_FT_UNKNOWN)
- 	{
- 	  *node = build_variant_type_copy (*node);
- 	  TREE_TYPE (*node) = build_type_attribute_variant
- 	    (TREE_TYPE (*node),
- 	     tree_cons (name, args, TYPE_ATTRIBUTES (TREE_TYPE (*node))));
  	  *no_add_attrs = true;
  	}
        else
  	{
! 	  /* Possibly pass this attribute on from the type to a decl.  */
! 	  if (flags & ((int) ATTR_FLAG_DECL_NEXT
! 		       | (int) ATTR_FLAG_FUNCTION_NEXT
! 		       | (int) ATTR_FLAG_ARRAY_NEXT))
! 	    {
! 	      *no_add_attrs = true;
! 	      return tree_cons (name, args, NULL_TREE);
! 	    }
! 	  else
! 	    {
! 	      warning (OPT_Wattributes, "%qE attribute ignored",
! 		       name);
! 	    }
  	}
      }
  
--- 6108,6167 ----
  /* Handle an "interrupt" or "isr" attribute;
     arguments as in struct attribute_spec.handler.  */
  static tree
! arm_handle_isr_decl_attribute (tree *node, tree name, tree args, int flags,
! 			       bool *no_add_attrs)
  {
!   if (TREE_CODE (*node) != FUNCTION_DECL)
      {
!       warning (OPT_Wattributes, "%qE attribute only applies to functions",
! 	       name);
!       *no_add_attrs = true;
!     }
!   /* FIXME: the argument if any is checked for type attributes;
!      should it be checked for decl ones?  */
! 
!   return NULL_TREE;
! }
! 
! static tree
! arm_handle_isr_type_attribute (tree *node, tree name, tree args, int flags,
! 			       bool *no_add_attrs)
! {
!   if (TREE_CODE (*node) == FUNCTION_TYPE
!       || TREE_CODE (*node) == METHOD_TYPE)
!     {
!       if (arm_isr_value (args) == ARM_FT_UNKNOWN)
  	{
! 	  warning (OPT_Wattributes, "%qE attribute ignored",
  		   name);
  	  *no_add_attrs = true;
  	}
!     }
!   else if (TREE_CODE (*node) == POINTER_TYPE
! 	   && (TREE_CODE (TREE_TYPE (*node)) == FUNCTION_TYPE
! 	       || TREE_CODE (TREE_TYPE (*node)) == METHOD_TYPE)
! 	   && arm_isr_value (args) != ARM_FT_UNKNOWN)
!     {
!       *node = build_variant_type_copy (*node);
!       TREE_TYPE (*node) = build_type_attribute_variant
! 	(TREE_TYPE (*node),
! 	 tree_cons (name, args, TYPE_ATTRIBUTES (TREE_TYPE (*node))));
!       *no_add_attrs = true;
      }
    else
      {
!       /* Possibly pass this attribute on from the type to a decl.  */
!       if (flags & ((int) ATTR_FLAG_DECL_NEXT
! 		   | (int) ATTR_FLAG_FUNCTION_NEXT
! 		   | (int) ATTR_FLAG_ARRAY_NEXT))
  	{
  	  *no_add_attrs = true;
+ 	  return tree_cons (name, args, NULL_TREE);
  	}
        else
  	{
! 	  warning (OPT_Wattributes, "%qE attribute ignored",
! 		   name);
  	}
      }
  
Index: config/avr/avr.c
===================================================================
*** config/avr/avr.c	(revision 217943)
--- config/avr/avr.c	(working copy)
*************** avr_class_likely_spilled_p (reg_class_t
*** 8867,8872 ****
--- 8867,8891 ----
     naked     -  Don't generate function prologue/epilogue and RET
                  instruction.  */
  
+ static tree
+ avr_ignore_type_attribute (tree *node ATTRIBUTE_UNUSED,
+ 			   tree name ATTRIBUTE_UNUSED,
+ 			   tree args ATTRIBUTE_UNUSED,
+ 			   int flags ATTRIBUTE_UNUSED,
+ 			   bool *no_add_attrs ATTRIBUTE_UNUSED)
+ {
+   return NULL_TREE;
+ }
+ 
+ static tree
+ avr_warning_type_attribute (tree *node ATTRIBUTE_UNUSED, tree name,
+ 			   tree args ATTRIBUTE_UNUSED,
+ 			   int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
+ {
+   warning (OPT_Wattributes, "%qE attribute does not apply to types",
+ 	   name);
+   *no_add_attrs = true;
+ }
  /* Handle a "progmem" attribute; arguments as in
     struct attribute_spec.handler.  */
  
*************** avr_eval_addr_attrib (rtx x)
*** 9026,9052 ****
  static const struct attribute_spec
  avr_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
!        affects_type_identity } */
!   { "progmem",   0, 0, false, false, false,  avr_handle_progmem_attribute,
!     false },
!   { "signal",    0, 0, true,  false, false,  avr_handle_fndecl_attribute,
!     false },
!   { "interrupt", 0, 0, true,  false, false,  avr_handle_fndecl_attribute,
!     false },
!   { "naked",     0, 0, false, true,  true,   avr_handle_fntype_attribute,
!     false },
!   { "OS_task",   0, 0, false, true,  true,   avr_handle_fntype_attribute,
!     false },
!   { "OS_main",   0, 0, false, true,  true,   avr_handle_fntype_attribute,
!     false },
!   { "io",        0, 1, false, false, false,  avr_handle_addr_attribute,
!     false },
!   { "io_low",    0, 1, false, false, false,  avr_handle_addr_attribute,
!     false },
!   { "address",   1, 1, false, false, false,  avr_handle_addr_attribute,
!     false },
!   { NULL,        0, 0, false, false, false, NULL, false }
  };
  
  
--- 9045,9073 ----
  static const struct attribute_spec
  avr_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, decl_handler,
!        type_handler, affects_type_identity } */
!   { "progmem",   0, 0, false, false, false, avr_handle_progmem_attribute,
!     avr_ignore_type_attribute, 
!     false },
!   { "signal",    0, 0, true,  false, false, avr_handle_fndecl_attribute,
!     avr_warning_type_attribute, false },
!   { "interrupt", 0, 0, true,  false, false, avr_handle_fndecl_attribute,
!     avr_warning_type_attribute, false },
!   { "naked",     0, 0, false, true,  true,  NULL, avr_handle_fntype_attribute, 
!     false },
!   { "OS_task",   0, 0, false, true,  true,  NULL, avr_handle_fntype_attribute, 
!     false },
!   { "OS_main",   0, 0, false, true,  true,  NULL, avr_handle_fntype_attribute, 
!     false },
!   { "io",        0, 1, false, false, false, avr_handle_addr_attribute,
!     avr_warning_type_attribute, false },
!   { "io_low",    0, 1, false, false, false, avr_handle_addr_attribute,
!     avr_warning_type_attribute, 
!     false },
!   { "address",   1, 1, false, false, false, avr_handle_addr_attribute,
!     avr_warning_type_attribute, false },
!   { NULL,        0, 0, false, false, false, NULL, NULL, false }
  };
  
  
Index: config/bfin/bfin.c
===================================================================
*** config/bfin/bfin.c	(revision 217943)
--- config/bfin/bfin.c	(working copy)
*************** bfin_reorg (void)
*** 4671,4685 ****
     attributes; arguments as in struct attribute_spec.handler.  */
  
  static tree
! handle_int_attribute (tree *node, tree name,
! 		      tree args ATTRIBUTE_UNUSED,
! 		      int flags ATTRIBUTE_UNUSED,
! 		      bool *no_add_attrs)
  {
    tree x = *node;
-   if (TREE_CODE (x) == FUNCTION_DECL)
-     x = TREE_TYPE (x);
- 
    if (TREE_CODE (x) != FUNCTION_TYPE)
      {
        warning (OPT_Wattributes, "%qE attribute only applies to functions",
--- 4671,4682 ----
     attributes; arguments as in struct attribute_spec.handler.  */
  
  static tree
! handle_int_type_attribute (tree *node, tree name,
! 			   tree args ATTRIBUTE_UNUSED,
! 			   int flags ATTRIBUTE_UNUSED,
! 			   bool *no_add_attrs)
  {
    tree x = *node;
    if (TREE_CODE (x) != FUNCTION_TYPE)
      {
        warning (OPT_Wattributes, "%qE attribute only applies to functions",
*************** handle_int_attribute (tree *node, tree n
*** 4692,4697 ****
--- 4689,4709 ----
    return NULL_TREE;
  }
  
+ static tree
+ handle_int_decl_attribute (tree *node, tree name, tree args, int flags,
+ 			   bool *no_add_attrs)
+ {
+   tree x = *node;
+   if (TREE_CODE (x) == FUNCTION_DECL)
+     return handle_int_type_attribute (&TREE_TYPE(x), name, args, flags,
+ 				      no_add_attrs);
+ 
+   warning (OPT_Wattributes, "%qE attribute only applies to functions", name);
+   *no_add_attrs = true;
+ 
+   return NULL_TREE;
+ }
+ 
  /* Return 0 if the attributes for two types are incompatible, 1 if they
     are compatible, and 2 if they are nearly compatible (which causes a
     warning to be generated).  */
*************** bfin_handle_longcall_attribute (tree *no
*** 4739,4747 ****
  				int flags ATTRIBUTE_UNUSED, 
  				bool *no_add_attrs)
  {
!   if (TREE_CODE (*node) != FUNCTION_TYPE
!       && TREE_CODE (*node) != FIELD_DECL
!       && TREE_CODE (*node) != TYPE_DECL)
      {
        warning (OPT_Wattributes, "%qE attribute only applies to functions",
  	       name);
--- 4751,4757 ----
  				int flags ATTRIBUTE_UNUSED, 
  				bool *no_add_attrs)
  {
!   if (TREE_CODE (*node) != FUNCTION_TYPE)
      {
        warning (OPT_Wattributes, "%qE attribute only applies to functions",
  	       name);
*************** static const struct attribute_spec bfin_
*** 4889,4916 ****
  {
    /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
         affects_type_identity } */
!   { "interrupt_handler", 0, 0, false, true,  true, handle_int_attribute,
!     false },
!   { "exception_handler", 0, 0, false, true,  true, handle_int_attribute,
!     false },
!   { "nmi_handler", 0, 0, false, true,  true, handle_int_attribute, false },
!   { "nesting", 0, 0, false, true,  true, NULL, false },
!   { "kspisusp", 0, 0, false, true,  true, NULL, false },
!   { "saveall", 0, 0, false, true,  true, NULL, false },
!   { "longcall",  0, 0, false, true,  true,  bfin_handle_longcall_attribute,
!     false },
!   { "shortcall", 0, 0, false, true,  true,  bfin_handle_longcall_attribute,
!     false },
!   { "l1_text", 0, 0, true, false, false,  bfin_handle_l1_text_attribute,
      false },
!   { "l1_data", 0, 0, true, false, false,  bfin_handle_l1_data_attribute,
      false },
!   { "l1_data_A", 0, 0, true, false, false, bfin_handle_l1_data_attribute,
      false },
!   { "l1_data_B", 0, 0, true, false, false,  bfin_handle_l1_data_attribute,
      false },
!   { "l2", 0, 0, true, false, false,  bfin_handle_l2_attribute, false },
!   { NULL, 0, 0, false, false, false, NULL, false }
  };
  
  /* Implementation of TARGET_ASM_INTEGER.  When using FD-PIC, we need to
--- 4899,4927 ----
  {
    /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
         affects_type_identity } */
!   { "interrupt_handler", 0, 0, false, true,  true, handle_int_decl_attribute,
!     handle_int_type_attribute, false },
!   { "exception_handler", 0, 0, false, true,  true, handle_int_decl_attribute,
!     handle_int_type_attribute, false },
!   { "nmi_handler", 0, 0, false, true,  true, handle_int_decl_attribute,
!     handle_int_type_attribute, false },
!   { "nesting", 0, 0, false, true,  true, NULL, NULL, false },
!   { "kspisusp", 0, 0, false, true,  true, NULL, NULL, false },
!   { "saveall", 0, 0, false, true,  true, NULL, NULL, false },
!   { "longcall",  0, 0, false, true,  true,  NULL,
!     bfin_handle_longcall_attribute, false },
!   { "shortcall", 0, 0, false, true,  true,  NULL,
!     bfin_handle_longcall_attribute, false },
!   { "l1_text", 0, 0, true, false, false, bfin_handle_l1_text_attribute, NULL,
      false },
!   { "l1_data", 0, 0, true, false, false, bfin_handle_l1_data_attribute, NULL,
      false },
!   { "l1_data_A", 0, 0, true, false, false, bfin_handle_l1_data_attribute, NULL,
      false },
!   { "l1_data_B", 0, 0, true, false, false, bfin_handle_l1_data_attribute, NULL,
      false },
!   { "l2", 0, 0, true, false, false,  bfin_handle_l2_attribute, NULL, false },
!   { NULL, 0, 0, false, false, false, NULL, NULL, false }
  };
  
  /* Implementation of TARGET_ASM_INTEGER.  When using FD-PIC, we need to
Index: config/cr16/cr16.c
===================================================================
*** config/cr16/cr16.c	(revision 217943)
--- config/cr16/cr16.c	(working copy)
*************** static void cr16_print_operand_address (
*** 217,226 ****
  /* Table of machine attributes.  */
  static const struct attribute_spec cr16_attribute_table[] = {
    /* ISRs have special prologue and epilogue requirements.  */
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
!        affects_type_identity }.  */
!   {"interrupt", 0, 0, false, true, true, NULL, false},
!   {NULL, 0, 0, false, false, false, NULL, false}
  };
  
  /* TARGET_ASM_UNALIGNED_xx_OP generates .?byte directive
--- 217,226 ----
  /* Table of machine attributes.  */
  static const struct attribute_spec cr16_attribute_table[] = {
    /* ISRs have special prologue and epilogue requirements.  */
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, decl_handler,
!        type_handler, affects_type_identity }.  */
!   {"interrupt", 0, 0, false, true, true, NULL, NULL, false},
!   {NULL, 0, 0, false, false, false, NULL, NULL, false}
  };
  
  /* TARGET_ASM_UNALIGNED_xx_OP generates .?byte directive
Index: config/darwin.h
===================================================================
*** config/darwin.h	(revision 217943)
--- config/darwin.h	(working copy)
*************** extern GTY(()) section * darwin_sections
*** 705,713 ****
    /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,     \
         affects_type_identity } */						     \
    { "apple_kext_compatibility", 0, 0, false, true, false,		     \
!     darwin_handle_kext_attribute, false },				     \
    { "weak_import", 0, 0, true, false, false,				     \
!     darwin_handle_weak_import_attribute, false }
  
  #undef ASM_GENERATE_INTERNAL_LABEL
  #define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM)	\
--- 705,713 ----
    /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,     \
         affects_type_identity } */						     \
    { "apple_kext_compatibility", 0, 0, false, true, false,		     \
!     NULL, darwin_handle_kext_attribute, false },     \
    { "weak_import", 0, 0, true, false, false,				     \
!     darwin_handle_weak_import_attribute, NULL, false }
  
  #undef ASM_GENERATE_INTERNAL_LABEL
  #define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM)	\
Index: config/epiphany/epiphany.c
===================================================================
*** config/epiphany/epiphany.c	(revision 217943)
--- config/epiphany/epiphany.c	(working copy)
*************** epiphany_init_reg_tables (void)
*** 469,481 ****
  
  static const struct attribute_spec epiphany_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
!   { "interrupt",  0, 9, true,  false, false, epiphany_handle_interrupt_attribute, true },
!   { "forwarder_section", 1, 1, true, false, false, epiphany_handle_forwarder_attribute, false },
!   { "long_call",  0, 0, false, true, true, NULL, false },
!   { "short_call", 0, 0, false, true, true, NULL, false },
!   { "disinterrupt", 0, 0, false, true, true, NULL, true },
!   { NULL,         0, 0, false, false, false, NULL, false }
  };
  
  /* Handle an "interrupt" attribute; arguments as in
--- 469,483 ----
  
  static const struct attribute_spec epiphany_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, decl_handler,
!        type_handler } */
!   { "interrupt",  0, 9, true,  false, false,
!     epiphany_handle_interrupt_attribute, NULL, true },
!   { "forwarder_section", 1, 1, true, false, false, epiphany_handle_forwarder_attribute, NULL, false },
!   { "long_call",  0, 0, false, true, true, NULL, NULL, false },
!   { "short_call", 0, 0, false, true, true, NULL, NULL, false },
!   { "disinterrupt", 0, 0, false, true, true, NULL, NULL, true },
!   { NULL,         0, 0, false, false, false, NULL, NULL, false }
  };
  
  /* Handle an "interrupt" attribute; arguments as in
Index: config/h8300/h8300.c
===================================================================
*** config/h8300/h8300.c	(revision 217943)
--- config/h8300/h8300.c	(working copy)
*************** static const struct attribute_spec h8300
*** 5430,5449 ****
    /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
         affects_type_identity } */
    { "interrupt_handler", 0, 0, true,  false, false,
!     h8300_handle_fndecl_attribute, false },
    { "saveall",           0, 0, true,  false, false,
!     h8300_handle_fndecl_attribute, false },
    { "OS_Task",           0, 0, true,  false, false,
!     h8300_handle_fndecl_attribute, false },
    { "monitor",           0, 0, true,  false, false,
!     h8300_handle_fndecl_attribute, false },
    { "function_vector",   0, 0, true,  false, false,
!     h8300_handle_fndecl_attribute, false },
    { "eightbit_data",     0, 0, true,  false, false,
!     h8300_handle_eightbit_data_attribute, false },
    { "tiny_data",         0, 0, true,  false, false,
!     h8300_handle_tiny_data_attribute, false },
!   { NULL,                0, 0, false, false, false, NULL, false }
  };
  
  
--- 5430,5449 ----
    /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
         affects_type_identity } */
    { "interrupt_handler", 0, 0, true,  false, false,
!     h8300_handle_fndecl_attribute, NULL, false },
    { "saveall",           0, 0, true,  false, false,
!     h8300_handle_fndecl_attribute, NULL, false },
    { "OS_Task",           0, 0, true,  false, false,
!     h8300_handle_fndecl_attribute, NULL, false },
    { "monitor",           0, 0, true,  false, false,
!     h8300_handle_fndecl_attribute, NULL, false },
    { "function_vector",   0, 0, true,  false, false,
!     h8300_handle_fndecl_attribute, NULL, false },
    { "eightbit_data",     0, 0, true,  false, false,
!     h8300_handle_eightbit_data_attribute, NULL, false },
    { "tiny_data",         0, 0, true,  false, false,
!     h8300_handle_tiny_data_attribute, NULL, false },
!   { NULL,                0, 0, false, false, false, NULL, NULL, false }
  };
  
  
Index: config/i386/cygming.h
===================================================================
*** config/i386/cygming.h	(revision 217943)
--- config/i386/cygming.h	(working copy)
*************** do {						\
*** 459,467 ****
  
  #define SUBTARGET_ATTRIBUTE_TABLE \
    { "selectany", 0, 0, true, false, false, ix86_handle_selectany_attribute, \
!     false }
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
!        affects_type_identity } */
  
  /*  mcount() does not need a counter variable.  */
  #undef NO_PROFILE_COUNTERS
--- 459,467 ----
  
  #define SUBTARGET_ATTRIBUTE_TABLE \
    { "selectany", 0, 0, true, false, false, ix86_handle_selectany_attribute, \
!     NULL, false }
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, decl_handler,
!        type_handler, affects_type_identity } */
  
  /*  mcount() does not need a counter variable.  */
  #undef NO_PROFILE_COUNTERS
Index: config/i386/i386.c
===================================================================
*** config/i386/i386.c	(revision 218105)
--- config/i386/i386.c	(working copy)
*************** ix86_handle_cconv_attribute (tree *node,
*** 5483,5491 ****
  				   bool *no_add_attrs)
  {
    if (TREE_CODE (*node) != FUNCTION_TYPE
!       && TREE_CODE (*node) != METHOD_TYPE
!       && TREE_CODE (*node) != FIELD_DECL
!       && TREE_CODE (*node) != TYPE_DECL)
      {
        warning (OPT_Wattributes, "%qE attribute only applies to functions",
  	       name);
--- 5483,5489 ----
  				   bool *no_add_attrs)
  {
    if (TREE_CODE (*node) != FUNCTION_TYPE
!       && TREE_CODE (*node) != METHOD_TYPE)
      {
        warning (OPT_Wattributes, "%qE attribute only applies to functions",
  	       name);
*************** ix86_handle_abi_attribute (tree *node, t
*** 42578,42599 ****
  /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
     struct attribute_spec.handler.  */
  static tree
! ix86_handle_struct_attribute (tree *node, tree name, tree, int,
! 			      bool *no_add_attrs)
  {
!   tree *type = NULL;
!   if (DECL_P (*node))
!     {
!       if (TREE_CODE (*node) == TYPE_DECL)
! 	type = &TREE_TYPE (*node);
!     }
!   else
!     type = node;
! 
!   if (!(type && RECORD_OR_UNION_TYPE_P (*type)))
      {
!       warning (OPT_Wattributes, "%qE attribute ignored",
! 	       name);
        *no_add_attrs = true;
      }
  
--- 42576,42587 ----
  /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
     struct attribute_spec.handler.  */
  static tree
! ix86_handle_struct_type_attribute (tree *type, tree name, tree, int,
! 				   bool *no_add_attrs)
  {
!   if (!(RECORD_OR_UNION_TYPE_P (*type)))
      {
!       warning (OPT_Wattributes, "%qE attribute ignored", name);
        *no_add_attrs = true;
      }
  
*************** ix86_handle_struct_attribute (tree *node
*** 42611,42616 ****
--- 42599,42618 ----
  }
  
  static tree
+ ix86_handle_struct_decl_attribute (tree *node, tree name, tree arg, int flags,
+ 				   bool *no_add_attrs)
+ {
+   if (TREE_CODE (*node) == TYPE_DECL)
+     return ix86_handle_struct_type_attribute (&(TREE_TYPE (*node)), name, arg,
+ 					      flags, no_add_attrs);
+ 
+   warning (OPT_Wattributes, "%qE attribute ignored", name);
+   *no_add_attrs = true;
+ 
+   return NULL_TREE;
+ }
+ 
+ static tree
  ix86_handle_fndecl_attribute (tree *node, tree name, tree, int,
  			      bool *no_add_attrs)
  {
*************** ix86_expand_round_sse4 (rtx op0, rtx op1
*** 46467,46527 ****
  /* Table of valid machine attributes.  */
  static const struct attribute_spec ix86_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
!        affects_type_identity } */
    /* Stdcall attribute says callee is responsible for popping arguments
       if they are not variable.  */
!   { "stdcall",   0, 0, false, true,  true,  ix86_handle_cconv_attribute,
      true },
    /* Fastcall attribute says callee is responsible for popping arguments
       if they are not variable.  */
!   { "fastcall",  0, 0, false, true,  true,  ix86_handle_cconv_attribute,
      true },
    /* Thiscall attribute says callee is responsible for popping arguments
       if they are not variable.  */
!   { "thiscall",  0, 0, false, true,  true,  ix86_handle_cconv_attribute,
      true },
    /* Cdecl attribute says the callee is a normal C declaration */
!   { "cdecl",     0, 0, false, true,  true,  ix86_handle_cconv_attribute,
      true },
    /* Regparm attribute specifies how many integer arguments are to be
       passed in registers.  */
!   { "regparm",   1, 1, false, true,  true,  ix86_handle_cconv_attribute,
      true },
    /* Sseregparm attribute says we are using x86_64 calling conventions
       for FP arguments.  */
!   { "sseregparm", 0, 0, false, true, true, ix86_handle_cconv_attribute,
      true },
    /* The transactional memory builtins are implicitly regparm or fastcall
       depending on the ABI.  Override the generic do-nothing attribute that
       these builtins were declared with.  */
!   { "*tm regparm", 0, 0, false, true, true, ix86_handle_tm_regparm_attribute,
!     true },
    /* force_align_arg_pointer says this function realigns the stack at entry.  */
    { (const char *)&ix86_force_align_arg_pointer_string, 0, 0,
!     false, true,  true, ix86_handle_cconv_attribute, false },
  #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
!   { "dllimport", 0, 0, false, false, false, handle_dll_attribute, false },
!   { "dllexport", 0, 0, false, false, false, handle_dll_attribute, false },
!   { "shared",    0, 0, true,  false, false, ix86_handle_shared_attribute,
      false },
  #endif
!   { "ms_struct", 0, 0, false, false,  false, ix86_handle_struct_attribute,
!     false },
!   { "gcc_struct", 0, 0, false, false,  false, ix86_handle_struct_attribute,
!     false },
  #ifdef SUBTARGET_ATTRIBUTE_TABLE
    SUBTARGET_ATTRIBUTE_TABLE,
  #endif
    /* ms_abi and sysv_abi calling convention function attributes.  */
!   { "ms_abi", 0, 0, false, true, true, ix86_handle_abi_attribute, true },
!   { "sysv_abi", 0, 0, false, true, true, ix86_handle_abi_attribute, true },
    { "ms_hook_prologue", 0, 0, true, false, false, ix86_handle_fndecl_attribute,
!     false },
!   { "callee_pop_aggregate_return", 1, 1, false, true, true,
      ix86_handle_callee_pop_aggregate_return, true },
    /* End element.  */
!   { NULL,        0, 0, false, false, false, NULL, false }
  };
  
  /* Implement targetm.vectorize.builtin_vectorization_cost.  */
--- 46469,46532 ----
  /* Table of valid machine attributes.  */
  static const struct attribute_spec ix86_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, decl_handler,
!        type_handler, affects_type_identity } */
    /* Stdcall attribute says callee is responsible for popping arguments
       if they are not variable.  */
!   { "stdcall",   0, 0, false, true,  true,  NULL, ix86_handle_cconv_attribute,
      true },
    /* Fastcall attribute says callee is responsible for popping arguments
       if they are not variable.  */
!   { "fastcall",  0, 0, false, true,  true,  NULL, ix86_handle_cconv_attribute,
      true },
    /* Thiscall attribute says callee is responsible for popping arguments
       if they are not variable.  */
!   { "thiscall",  0, 0, false, true,  true,  NULL, ix86_handle_cconv_attribute,
      true },
    /* Cdecl attribute says the callee is a normal C declaration */
!   { "cdecl",     0, 0, false, true,  true,  NULL, ix86_handle_cconv_attribute,
      true },
    /* Regparm attribute specifies how many integer arguments are to be
       passed in registers.  */
!   { "regparm",   1, 1, false, true,  true,  NULL, ix86_handle_cconv_attribute,
      true },
    /* Sseregparm attribute says we are using x86_64 calling conventions
       for FP arguments.  */
!   { "sseregparm", 0, 0, false, true, true, NULL, ix86_handle_cconv_attribute,
      true },
    /* The transactional memory builtins are implicitly regparm or fastcall
       depending on the ABI.  Override the generic do-nothing attribute that
       these builtins were declared with.  */
!   { "*tm regparm", 0, 0, false, true, true, NULL,
!     ix86_handle_tm_regparm_attribute, true },
    /* force_align_arg_pointer says this function realigns the stack at entry.  */
    { (const char *)&ix86_force_align_arg_pointer_string, 0, 0,
!     false, true,  true, NULL, ix86_handle_cconv_attribute, false },
  #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
!   { "dllimport", 0, 0, false, false, false, handle_dll_decl_attribute,
!     handle_dll_type_attribute, false },
!   { "dllexport", 0, 0, false, false, false, handle_dll_decl_attribute,
!     handle_dll_type_attribute, false },
!   { "shared",    0, 0, true,  false, false, ix86_handle_shared_attribute, NULL,
      false },
  #endif
!   { "ms_struct", 0, 0, false, false,  false, ix86_handle_struct_decl_attribute,
!     ix86_handle_struct_type_attribute, false },
!   { "gcc_struct", 0, 0, false, false,  false, ix86_handle_struct_decl_attribute,
!     ix86_handle_struct_type_attribute, false },
  #ifdef SUBTARGET_ATTRIBUTE_TABLE
    SUBTARGET_ATTRIBUTE_TABLE,
  #endif
    /* ms_abi and sysv_abi calling convention function attributes.  */
!   { "ms_abi", 0, 0, false, true, true, NULL, ix86_handle_abi_attribute, true },
!   { "sysv_abi", 0, 0, false, true, true, NULL, ix86_handle_abi_attribute,
!     true },
    { "ms_hook_prologue", 0, 0, true, false, false, ix86_handle_fndecl_attribute,
!     NULL, false },
!   { "callee_pop_aggregate_return", 1, 1, false, true, true, NULL,
      ix86_handle_callee_pop_aggregate_return, true },
    /* End element.  */
!   { NULL,        0, 0, false, false, false, NULL, NULL, false }
  };
  
  /* Implement targetm.vectorize.builtin_vectorization_cost.  */
Index: config/ia64/ia64.c
===================================================================
*** config/ia64/ia64.c	(revision 217943)
--- config/ia64/ia64.c	(working copy)
*************** static bool ia64_expand_vec_perm_const_1
*** 373,390 ****
  /* Table of valid machine attributes.  */
  static const struct attribute_spec ia64_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
!        affects_type_identity } */
!   { "syscall_linkage", 0, 0, false, true,  true,  NULL, false },
    { "model",	       1, 1, true, false, false, ia64_handle_model_attribute,
!     false },
  #if TARGET_ABI_OPEN_VMS
    { "common_object",   1, 1, true, false, false,
!     ia64_vms_common_object_attribute, false },
  #endif
    { "version_id",      1, 1, true, false, false,
!     ia64_handle_version_id_attribute, false },
!   { NULL,	       0, 0, false, false, false, NULL, false }
  };
  
  /* Initialize the GCC target structure.  */
--- 373,390 ----
  /* Table of valid machine attributes.  */
  static const struct attribute_spec ia64_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, decl_handler,
!        type_handler, affects_type_identity } */
!   { "syscall_linkage", 0, 0, false, true,  true,  NULL, NULL, false },
    { "model",	       1, 1, true, false, false, ia64_handle_model_attribute,
!     NULL, false },
  #if TARGET_ABI_OPEN_VMS
    { "common_object",   1, 1, true, false, false,
!     ia64_vms_common_object_attribute, NULL, false },
  #endif
    { "version_id",      1, 1, true, false, false,
!     ia64_handle_version_id_attribute, NULL, false },
!   { NULL,	       0, 0, false, false, false, NULL, NULL, false }
  };
  
  /* Initialize the GCC target structure.  */
Index: config/m32c/m32c.c
===================================================================
*** config/m32c/m32c.c	(revision 217943)
--- config/m32c/m32c.c	(working copy)
*************** typedef enum
*** 86,92 ****
  } Push_Pop_Type;
  
  static bool m32c_function_needs_enter (void);
! static tree interrupt_handler (tree *, tree, tree, int, bool *);
  static tree function_vector_handler (tree *, tree, tree, int, bool *);
  static int interrupt_p (tree node);
  static int bank_switch_p (tree node);
--- 86,93 ----
  } Push_Pop_Type;
  
  static bool m32c_function_needs_enter (void);
! static tree interrupt_decl_handler (tree *, tree, tree, int, bool *);
! static tree interrupt_type_handler (tree *, tree, tree, int, bool *);
  static tree function_vector_handler (tree *, tree, tree, int, bool *);
  static int interrupt_p (tree node);
  static int bank_switch_p (tree node);
*************** fast_interrupt_p (tree node ATTRIBUTE_UN
*** 2904,2910 ****
  }
  
  static tree
! interrupt_handler (tree * node ATTRIBUTE_UNUSED,
  		   tree name ATTRIBUTE_UNUSED,
  		   tree args ATTRIBUTE_UNUSED,
  		   int flags ATTRIBUTE_UNUSED,
--- 2905,2911 ----
  }
  
  static tree
! interrupt_decl_handler (tree * node ATTRIBUTE_UNUSED,
  		   tree name ATTRIBUTE_UNUSED,
  		   tree args ATTRIBUTE_UNUSED,
  		   int flags ATTRIBUTE_UNUSED,
*************** interrupt_handler (tree * node ATTRIBUTE
*** 2913,2918 ****
--- 2914,2928 ----
    return NULL_TREE;
  }
  
+ static tree
+ interrupt_type_handler (tree * node ATTRIBUTE_UNUSED,
+ 		   tree name ATTRIBUTE_UNUSED,
+ 		   tree args ATTRIBUTE_UNUSED,
+ 		   int flags ATTRIBUTE_UNUSED,
+ 		   bool * no_add_attrs ATTRIBUTE_UNUSED)
+ {
+   return NULL_TREE;
+ }
  /* Returns TRUE if given tree has the "function_vector" attribute. */
  int
  m32c_special_page_vector_p (tree func)
*************** current_function_special_page_vector (rt
*** 3012,3023 ****
  #undef TARGET_ATTRIBUTE_TABLE
  #define TARGET_ATTRIBUTE_TABLE m32c_attribute_table
  static const struct attribute_spec m32c_attribute_table[] = {
!   {"interrupt", 0, 0, false, false, false, interrupt_handler, false},
!   {"bank_switch", 0, 0, false, false, false, interrupt_handler, false},
!   {"fast_interrupt", 0, 0, false, false, false, interrupt_handler, false},
!   {"function_vector", 1, 1, true,  false, false, function_vector_handler,
     false},
!   {0, 0, 0, 0, 0, 0, 0, false}
  };
  
  #undef TARGET_COMP_TYPE_ATTRIBUTES
--- 3022,3036 ----
  #undef TARGET_ATTRIBUTE_TABLE
  #define TARGET_ATTRIBUTE_TABLE m32c_attribute_table
  static const struct attribute_spec m32c_attribute_table[] = {
!   {"interrupt", 0, 0, false, false, false, interrupt_decl_handler,
!     interrupt_type_handler, false},
!   {"bank_switch", 0, 0, false, false, false, interrupt_decl_handler,
!     interrupt_type_handler, false},
!   {"fast_interrupt", 0, 0, false, false, false, interrupt_decl_handler,
!     interrupt_type_handler, false},
!   {"function_vector", 1, 1, true,  false, false,function_vector_handler, NULL, 
     false},
!   {0, 0, 0, 0, 0, 0, 0, 0, false}
  };
  
  #undef TARGET_COMP_TYPE_ATTRIBUTES
Index: config/m32r/m32r.c
===================================================================
*** config/m32r/m32r.c	(revision 217943)
--- config/m32r/m32r.c	(working copy)
*************** static bool m32r_legitimate_constant_p (
*** 121,132 ****
  
  static const struct attribute_spec m32r_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
!        affects_type_identity } */
!   { "interrupt", 0, 0, true,  false, false, NULL, false },
!   { "model",     1, 1, true,  false, false, m32r_handle_model_attribute,
      false },
!   { NULL,        0, 0, false, false, false, NULL, false }
  };
  
  /* Initialize the GCC target structure.  */
--- 121,132 ----
  
  static const struct attribute_spec m32r_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, decl_handler,
!        type_handler, affects_type_identity } */
!   { "interrupt", 0, 0, true,  false, false, NULL, NULL, false },
!   { "model",     1, 1, true,  false, false, m32r_handle_model_attribute, NULL, 
      false },
!   { NULL,        0, 0, false, false, false, NULL, NULL, false }
  };
  
  /* Initialize the GCC target structure.  */
Index: config/m68k/m68k.c
===================================================================
*** config/m68k/m68k.c	(revision 217943)
--- config/m68k/m68k.c	(working copy)
*************** static const struct attribute_spec m68k_
*** 328,340 ****
  {
    /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
         affects_type_identity } */
!   { "interrupt", 0, 0, true,  false, false, m68k_handle_fndecl_attribute,
      false },
    { "interrupt_handler", 0, 0, true,  false, false,
!     m68k_handle_fndecl_attribute, false },
    { "interrupt_thread", 0, 0, true,  false, false,
!     m68k_handle_fndecl_attribute, false },
!   { NULL,                0, 0, false, false, false, NULL, false }
  };
  
  struct gcc_target targetm = TARGET_INITIALIZER;
--- 328,340 ----
  {
    /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
         affects_type_identity } */
!   { "interrupt", 0, 0, true,  false, false, m68k_handle_fndecl_attribute, NULL,
      false },
    { "interrupt_handler", 0, 0, true,  false, false,
!     m68k_handle_fndecl_attribute, NULL, false },
    { "interrupt_thread", 0, 0, true,  false, false,
!     m68k_handle_fndecl_attribute, NULL, false },
!   { NULL,                0, 0, false, false, false, NULL, NULL, false }
  };
  
  struct gcc_target targetm = TARGET_INITIALIZER;
Index: config/mcore/mcore.c
===================================================================
*** config/mcore/mcore.c	(revision 217943)
--- config/mcore/mcore.c	(working copy)
*************** static const struct attribute_spec mcore
*** 166,176 ****
  {
    /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
         affects_type_identity } */
!   { "dllexport", 0, 0, true,  false, false, NULL, false },
!   { "dllimport", 0, 0, true,  false, false, NULL, false },
!   { "naked",     0, 0, true,  false, false, mcore_handle_naked_attribute,
      false },
!   { NULL,        0, 0, false, false, false, NULL, false }
  };
  
  /* Initialize the GCC target structure.  */
--- 166,176 ----
  {
    /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
         affects_type_identity } */
!   { "dllexport", 0, 0, true,  false, false, NULL, NULL, false },
!   { "dllimport", 0, 0, true,  false, false, NULL, NULL, false },
!   { "naked",     0, 0, true,  false, false, mcore_handle_naked_attribute, NULL, 
      false },
!   { NULL,        0, 0, false, false, false, NULL, NULL, false }
  };
  
  /* Initialize the GCC target structure.  */
Index: config/mep/mep.c
===================================================================
*** config/mep/mep.c	(revision 217943)
--- config/mep/mep.c	(working copy)
*************** static bool mep_function_ok_for_sibcall
*** 194,202 ****
  static int unique_bit_in (HOST_WIDE_INT);
  static int bit_size_for_clip (HOST_WIDE_INT);
  static int bytesize (const_tree, machine_mode);
! static tree mep_validate_based_tiny (tree *, tree, tree, int, bool *);
! static tree mep_validate_near_far (tree *, tree, tree, int, bool *);
! static tree mep_validate_disinterrupt (tree *, tree, tree, int, bool *);
  static tree mep_validate_interrupt (tree *, tree, tree, int, bool *);
  static tree mep_validate_io_cb (tree *, tree, tree, int, bool *);
  static tree mep_validate_vliw (tree *, tree, tree, int, bool *);
--- 194,206 ----
  static int unique_bit_in (HOST_WIDE_INT);
  static int bit_size_for_clip (HOST_WIDE_INT);
  static int bytesize (const_tree, machine_mode);
! static tree mep_validate_type_based_tiny (tree *, tree, tree, int, bool *);
! static tree mep_validate_decl_based_tiny (tree *, tree, tree, int, bool *);
! static tree mep_validate_type_near_far (tree *, tree, tree, int, bool *);
! static tree mep_validate_decl_near_far (tree *, tree, tree, int, bool *);
! static tree mep_validate_type_disinterrupt (tree *, tree, tree, int, bool *);
! static tree mep_validate_decl_disinterrupt (tree *, tree, tree, int, bool *);
! static tree mep_validate_type_warning(tree *, tree, tree, int, bool *);
  static tree mep_validate_interrupt (tree *, tree, tree, int, bool *);
  static tree mep_validate_io_cb (tree *, tree, tree, int, bool *);
  static tree mep_validate_vliw (tree *, tree, tree, int, bool *);
*************** mep_asm_output_opcode (FILE *file, const
*** 3810,3820 ****
  /* Handle attributes.  */
  
  static tree
! mep_validate_based_tiny (tree *node, tree name, tree args,
  			 int flags ATTRIBUTE_UNUSED, bool *no_add)
  {
    if (TREE_CODE (*node) != VAR_DECL
-       && TREE_CODE (*node) != POINTER_TYPE
        && TREE_CODE (*node) != TYPE_DECL)
      {
        warning (0, "%qE attribute only applies to variables", name);
--- 3814,3836 ----
  /* Handle attributes.  */
  
  static tree
! mep_validate_type_based_tiny (tree *node, tree name, tree args,
! 			      int flags ATTRIBUTE_UNUSED, bool *no_add)
! {
!   if (TREE_CODE (*node) != POINTER_TYPE)
!     {
!       warning (0, "%qE attribute only applies to variables", name);
!       *no_add = true;
!     }
!   
!   return NULL_TREE;
! }
! 
! static tree
! mep_validate_decl_based_tiny (tree *node, tree name, tree args,
  			 int flags ATTRIBUTE_UNUSED, bool *no_add)
  {
    if (TREE_CODE (*node) != VAR_DECL
        && TREE_CODE (*node) != TYPE_DECL)
      {
        warning (0, "%qE attribute only applies to variables", name);
*************** mep_multiple_address_regions (tree list,
*** 3870,3882 ****
  		  : TYPE_ATTRIBUTES (TREE_TYPE (decl))
  
  static tree
! mep_validate_near_far (tree *node, tree name, tree args,
  		       int flags ATTRIBUTE_UNUSED, bool *no_add)
  {
    if (TREE_CODE (*node) != VAR_DECL
        && TREE_CODE (*node) != FUNCTION_DECL
-       && TREE_CODE (*node) != METHOD_TYPE
-       && TREE_CODE (*node) != POINTER_TYPE
        && TREE_CODE (*node) != TYPE_DECL)
      {
        warning (0, "%qE attribute only applies to variables and functions",
--- 3886,3914 ----
  		  : TYPE_ATTRIBUTES (TREE_TYPE (decl))
  
  static tree
! mep_validate_type_near_far (tree *node, tree name, tree args,
! 		       int flags ATTRIBUTE_UNUSED, bool *no_add)
! {
!   if (TREE_CODE (*node) != METHOD_TYPE && TREE_CODE (*node) != POINTER_TYPE)
!     {
!       warning (0, "%qE attribute only applies to variables and functions",
! 	       name);
!       *no_add = true;
!     }
!   else if (mep_multiple_address_regions (MEP_ATTRIBUTES (*node), false) > 0)
!     {
!       warning (0, "duplicate address region attribute %qE", name);
!       TYPE_ATTRIBUTES (*node) = NULL_TREE;
!     }
!   return NULL_TREE;
! }
! 
! static tree
! mep_validate_decl_near_far (tree *node, tree name, tree args,
  		       int flags ATTRIBUTE_UNUSED, bool *no_add)
  {
    if (TREE_CODE (*node) != VAR_DECL
        && TREE_CODE (*node) != FUNCTION_DECL
        && TREE_CODE (*node) != TYPE_DECL)
      {
        warning (0, "%qE attribute only applies to variables and functions",
*************** mep_validate_near_far (tree *node, tree
*** 3907,3917 ****
  }
  
  static tree
! mep_validate_disinterrupt (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
! 			   int flags ATTRIBUTE_UNUSED, bool *no_add)
  {
!   if (TREE_CODE (*node) != FUNCTION_DECL
!       && TREE_CODE (*node) != METHOD_TYPE)
      {
        warning (0, "%qE attribute only applies to functions", name);
        *no_add = true;
--- 3939,3962 ----
  }
  
  static tree
! mep_validate_type_disinterrupt (tree *node, tree name,
! 				tree args ATTRIBUTE_UNUSED,
! 			        int flags ATTRIBUTE_UNUSED, bool *no_add)
! {
!   if (TREE_CODE (*node) != METHOD_TYPE)
!     {
!       warning (0, "%qE attribute only applies to functions", name);
!       *no_add = true;
!     }
!   return NULL_TREE;
! }
! 
! static tree
! mep_validate_decl_disinterrupt (tree *node, tree name,
! 				tree args ATTRIBUTE_UNUSED,
! 			        int flags ATTRIBUTE_UNUSED, bool *no_add)
  {
!   if (TREE_CODE (*node) != FUNCTION_DECL)
      {
        warning (0, "%qE attribute only applies to functions", name);
        *no_add = true;
*************** mep_validate_disinterrupt (tree *node, t
*** 3920,3925 ****
--- 3965,3981 ----
  }
  
  static tree
+ mep_validate_type_warning (tree *node ATTRIBUTE_UNUSED, tree name,
+ 			     tree args ATTRIBUTE_UNUSED,
+ 			     int flags ATTRIBUTE_UNUSED, bool *no_add)
+ {
+   warning (0, "%qE attribute only applies to functions", name);
+   *no_add = true;
+   return NULL_TREE;
+ }
+ 
+ 
+ static tree
  mep_validate_interrupt (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
  			int flags ATTRIBUTE_UNUSED, bool *no_add)
  {
*************** static const struct attribute_spec mep_a
*** 4032,4048 ****
  {
    /* name         min max decl   type   func   handler
       affects_type_identity */
!   { "based",        0, 0, false, false, false, mep_validate_based_tiny, false },
!   { "tiny",         0, 0, false, false, false, mep_validate_based_tiny, false },
!   { "near",         0, 0, false, false, false, mep_validate_near_far, false },
!   { "far",          0, 0, false, false, false, mep_validate_near_far, false },
!   { "disinterrupt", 0, 0, false, false, false, mep_validate_disinterrupt,
!     false },
!   { "interrupt",    0, 0, false, false, false, mep_validate_interrupt, false },
!   { "io",           0, 1, false, false, false, mep_validate_io_cb, false },
!   { "cb",           0, 1, false, false, false, mep_validate_io_cb, false },
!   { "vliw",         0, 0, false, true,  false, mep_validate_vliw, false },
!   { NULL,           0, 0, false, false, false, NULL, false }
  };
  
  static bool
--- 4088,4111 ----
  {
    /* name         min max decl   type   func   handler
       affects_type_identity */
!   { "based",        0, 0, false, false, false, mep_validate_decl_based_tiny,
!     mep_validate_type_based_tiny, false },
!   { "tiny",         0, 0, false, false, false, mep_validate_decl_based_tiny,
!     mep_validate_type_based_tiny, false },
!   { "near",         0, 0, false, false, false, mep_validate_decl_near_far,
!     mep_validate_type_near_far, false },
!   { "far",          0, 0, false, false, false, mep_validate_decl_near_far,
!     mep_validate_type_near_far, false },
!   { "disinterrupt", 0, 0, false, false, false, mep_validate_decl_disinterrupt,
!     mep_validate_type_disinterrupt, false },
!   { "interrupt",    0, 0, false, false, false, mep_validate_interrupt,
!     mep_validate_type_warning, false },
!   { "io",           0, 1, false, false, false, mep_validate_io_cb,
!     mep_validate_type_warning, false },
!   { "cb",           0, 1, false, false, false, mep_validate_io_cb,
!     mep_validate_type_warning, false },
!   { "vliw",         0, 0, false, true,  false, NULL, mep_validate_vliw, false },
!   { NULL,           0, 0, false, false, false, NULL, NULL, false }
  };
  
  static bool
Index: config/microblaze/microblaze.c
===================================================================
*** config/microblaze/microblaze.c	(revision 217943)
--- config/microblaze/microblaze.c	(working copy)
*************** int fast_interrupt;
*** 234,251 ****
  int save_volatiles;
  
  const struct attribute_spec microblaze_attribute_table[] = {
!   /* name         min_len, max_len, decl_req, type_req, fn_type, req_handler,
!      affects_type_identity */
!   {"interrupt_handler", 0,       0,     true,    false,   false,        NULL,
!     false },
    {"break_handler",     0,       0,     true,    false,   false,        NULL,
!     false },
    {"fast_interrupt",    0,       0,     true,    false,   false,        NULL,
!     false },
    {"save_volatiles"   , 0,       0,     true,    false,   false,        NULL,
!     false },
    { NULL,        	0,       0,    false,    false,   false,        NULL,
!     false }
  };
  
  static int microblaze_interrupt_function_p (tree);
--- 234,251 ----
  int save_volatiles;
  
  const struct attribute_spec microblaze_attribute_table[] = {
!   /* name         min_len, max_len, decl_req, type_req, fn_type, decl_handler,
!      type_handler, affects_type_identity */
!   {"interrupt_handler", 0,       0,     true,    false,   false,	NULL,
!     NULL,	false },
    {"break_handler",     0,       0,     true,    false,   false,        NULL,
!     NULL,	false },
    {"fast_interrupt",    0,       0,     true,    false,   false,        NULL,
!     NULL,	false },
    {"save_volatiles"   , 0,       0,     true,    false,   false,        NULL,
!     NULL,	false },
    { NULL,        	0,       0,    false,    false,   false,        NULL,
!     NULL,	false }
  };
  
  static int microblaze_interrupt_function_p (tree);
Index: config/mips/mips.c
===================================================================
*** config/mips/mips.c	(revision 217943)
--- config/mips/mips.c	(working copy)
*************** const enum reg_class mips_regno_to_class
*** 724,749 ****
  
  /* The value of TARGET_ATTRIBUTE_TABLE.  */
  static const struct attribute_spec mips_attribute_table[] = {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
!        om_diagnostic } */
!   { "long_call",   0, 0, false, true,  true,  NULL, false },
!   { "far",     	   0, 0, false, true,  true,  NULL, false },
!   { "near",        0, 0, false, true,  true,  NULL, false },
    /* We would really like to treat "mips16" and "nomips16" as type
       attributes, but GCC doesn't provide the hooks we need to support
       the right conversion rules.  As declaration attributes, they affect
       code generation but don't carry other semantics.  */
!   { "mips16", 	   0, 0, true,  false, false, NULL, false },
!   { "nomips16",    0, 0, true,  false, false, NULL, false },
!   { "micromips",   0, 0, true,  false, false, NULL, false },
!   { "nomicromips", 0, 0, true,  false, false, NULL, false },
!   { "nocompression", 0, 0, true,  false, false, NULL, false },
    /* Allow functions to be specified as interrupt handlers */
!   { "interrupt",   0, 0, false, true,  true, NULL, false },
!   { "use_shadow_register_set",	0, 0, false, true,  true, NULL, false },
!   { "keep_interrupts_masked",	0, 0, false, true,  true, NULL, false },
!   { "use_debug_exception_return", 0, 0, false, true,  true, NULL, false },
!   { NULL,	   0, 0, false, false, false, NULL, false }
  };
  
  /* A table describing all the processors GCC knows about; see
--- 724,749 ----
  
  /* The value of TARGET_ATTRIBUTE_TABLE.  */
  static const struct attribute_spec mips_attribute_table[] = {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, decl_handler,
!        type_handler, om_diagnostic } */
!   { "long_call",   0, 0, false, true,  true,  NULL, NULL, false },
!   { "far",     	   0, 0, false, true,  true,  NULL, NULL, false },
!   { "near",        0, 0, false, true,  true,  NULL, NULL, false },
    /* We would really like to treat "mips16" and "nomips16" as type
       attributes, but GCC doesn't provide the hooks we need to support
       the right conversion rules.  As declaration attributes, they affect
       code generation but don't carry other semantics.  */
!   { "mips16", 	   0, 0, true,  false, false, NULL, NULL, false },
!   { "nomips16",    0, 0, true,  false, false, NULL, NULL, false },
!   { "micromips",   0, 0, true,  false, false, NULL, NULL, false },
!   { "nomicromips", 0, 0, true,  false, false, NULL, NULL, false },
!   { "nocompression", 0, 0, true,  false, false, NULL, NULL, false },
    /* Allow functions to be specified as interrupt handlers */
!   { "interrupt",   0, 0, false, true,  true, NULL, NULL, false },
!   { "use_shadow_register_set",	0, 0, false, true,  true, NULL, NULL, false },
!   { "keep_interrupts_masked",	0, 0, false, true,  true, NULL, NULL, false },
!   { "use_debug_exception_return", 0, 0, false, true,  true, NULL, NULL, false },
!   { NULL,	   0, 0, false, false, false, NULL, NULL, false }
  };
  
  /* A table describing all the processors GCC knows about; see
Index: config/msp430/msp430.c
===================================================================
*** config/msp430/msp430.c	(revision 217943)
--- config/msp430/msp430.c	(working copy)
*************** msp430_attr (tree * node,
*** 1315,1327 ****
  const struct attribute_spec msp430_attribute_table[] =
  {
    /* Name          min_len  decl_req,    fn_type_req,    affects_type_identity
!                        max_len,  type_req,        handler.  */
!   { "interrupt",      0, 1, true,  false, false, msp430_attr, false },
!   { "naked",          0, 0, true,  false, false, msp430_attr, false },
!   { "reentrant",      0, 0, true,  false, false, msp430_attr, false },
!   { "critical",       0, 0, true,  false, false, msp430_attr, false },
!   { "wakeup",         0, 0, true,  false, false, msp430_attr, false },
!   { NULL,             0, 0, false, false, false, NULL,        false }
  };
  
  void
--- 1315,1327 ----
  const struct attribute_spec msp430_attribute_table[] =
  {
    /* Name          min_len  decl_req,    fn_type_req,    affects_type_identity
!                        max_len,  type_req, decl_handler, type_handler.  */
!   { "interrupt",      0, 1, true,  false, false, msp430_attr, NULL, false },
!   { "naked",          0, 0, true,  false, false, msp430_attr, NULL, false },
!   { "reentrant",      0, 0, true,  false, false, msp430_attr, NULL, false },
!   { "critical",       0, 0, true,  false, false, msp430_attr, NULL, false },
!   { "wakeup",         0, 0, true,  false, false, msp430_attr, NULL, false },
!   { NULL,             0, 0, false, false, false, NULL,        NULL, false }
  };
  
  void
Index: config/nds32/nds32.c
===================================================================
*** config/nds32/nds32.c	(revision 217943)
--- config/nds32/nds32.c	(working copy)
*************** static const char * const nds32_intrinsi
*** 100,132 ****
  static const struct attribute_spec nds32_attribute_table[] =
  {
    /* Syntax: { name, min_len, max_len, decl_required, type_required,
!                function_type_required, handler, affects_type_identity } */
  
    /* The interrupt vid: [0-63]+ (actual vector number starts from 9 to 72).  */
!   { "interrupt",    1, 64, false, false, false, NULL, false },
    /* The exception vid: [1-8]+  (actual vector number starts from 1 to 8).  */
!   { "exception",    1,  8, false, false, false, NULL, false },
    /* Argument is user's interrupt numbers.  The vector number is always 0.  */
!   { "reset",        1,  1, false, false, false, NULL, false },
  
    /* The attributes describing isr nested type.  */
!   { "nested",       0,  0, false, false, false, NULL, false },
!   { "not_nested",   0,  0, false, false, false, NULL, false },
!   { "nested_ready", 0,  0, false, false, false, NULL, false },
  
    /* The attributes describing isr register save scheme.  */
!   { "save_all",     0,  0, false, false, false, NULL, false },
!   { "partial_save", 0,  0, false, false, false, NULL, false },
  
    /* The attributes used by reset attribute.  */
!   { "nmi",          1,  1, false, false, false, NULL, false },
!   { "warm",         1,  1, false, false, false, NULL, false },
  
    /* The attribute telling no prologue/epilogue.  */
!   { "naked",        0,  0, false, false, false, NULL, false },
  
    /* The last attribute spec is set to be NULL.  */
!   { NULL,           0,  0, false, false, false, NULL, false }
  };
  
  
--- 100,133 ----
  static const struct attribute_spec nds32_attribute_table[] =
  {
    /* Syntax: { name, min_len, max_len, decl_required, type_required,
!                function_type_required, decl_handler, type_handler,
! 	       affects_type_identity } */
  
    /* The interrupt vid: [0-63]+ (actual vector number starts from 9 to 72).  */
!   { "interrupt",    1, 64, false, false, false, NULL, NULL, false },
    /* The exception vid: [1-8]+  (actual vector number starts from 1 to 8).  */
!   { "exception",    1,  8, false, false, false, NULL, NULL, false },
    /* Argument is user's interrupt numbers.  The vector number is always 0.  */
!   { "reset",        1,  1, false, false, false, NULL, NULL, false },
  
    /* The attributes describing isr nested type.  */
!   { "nested",       0,  0, false, false, false, NULL, NULL, false },
!   { "not_nested",   0,  0, false, false, false, NULL, NULL, false },
!   { "nested_ready", 0,  0, false, false, false, NULL, NULL, false },
  
    /* The attributes describing isr register save scheme.  */
!   { "save_all",     0,  0, false, false, false, NULL, NULL, false },
!   { "partial_save", 0,  0, false, false, false, NULL, NULL, false },
  
    /* The attributes used by reset attribute.  */
!   { "nmi",          1,  1, false, false, false, NULL, NULL, false },
!   { "warm",         1,  1, false, false, false, NULL, NULL, false },
  
    /* The attribute telling no prologue/epilogue.  */
!   { "naked",        0,  0, false, false, false, NULL, NULL, false },
  
    /* The last attribute spec is set to be NULL.  */
!   { NULL,           0,  0, false, false, false, NULL, NULL, false }
  };
  
  
Index: config/nvptx/nvptx.c
===================================================================
*** config/nvptx/nvptx.c	(revision 217943)
--- config/nvptx/nvptx.c	(working copy)
*************** nvptx_handle_kernel_attribute (tree *nod
*** 1983,1992 ****
  /* Table of valid machine attributes.  */
  static const struct attribute_spec nvptx_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
!        affects_type_identity } */
!   { "kernel", 0, 0, true, false,  false, nvptx_handle_kernel_attribute, false },
!   { NULL, 0, 0, false, false, false, NULL, false }
  };
  
  /* Limit vector alignments to BIGGEST_ALIGNMENT.  */
--- 1983,1993 ----
  /* Table of valid machine attributes.  */
  static const struct attribute_spec nvptx_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, decl_handler,
!        type_handler, affects_type_identity } */
!   { "kernel", 0, 0, true, false,  false, nvptx_handle_kernel_attribute, NULL,
!     false },
!   { NULL, 0, 0, false, false, false, NULL, NULL, false }
  };
  
  /* Limit vector alignments to BIGGEST_ALIGNMENT.  */
Index: config/rl78/rl78.c
===================================================================
*** config/rl78/rl78.c	(revision 217943)
--- config/rl78/rl78.c	(working copy)
*************** rl78_handle_func_attribute (tree * node,
*** 687,701 ****
  /* Table of RL78-specific attributes.  */
  const struct attribute_spec rl78_attribute_table[] =
  {
!   /* Name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
!      affects_type_identity.  */
    { "interrupt",      0, 0, true, false, false, rl78_handle_func_attribute,
!     false },
    { "brk_interrupt",  0, 0, true, false, false, rl78_handle_func_attribute,
!     false },
    { "naked",          0, 0, true, false, false, rl78_handle_func_attribute,
!     false },
!   { NULL,             0, 0, false, false, false, NULL, false }
  };
  
  
--- 687,701 ----
  /* Table of RL78-specific attributes.  */
  const struct attribute_spec rl78_attribute_table[] =
  {
!   /* Name, min_len, max_len, decl_req, type_req, fn_type_req, decl_handler,
!      type_handler, affects_type_identity.  */
    { "interrupt",      0, 0, true, false, false, rl78_handle_func_attribute,
!     NULL, false },
    { "brk_interrupt",  0, 0, true, false, false, rl78_handle_func_attribute,
!     NULL, false },
    { "naked",          0, 0, true, false, false, rl78_handle_func_attribute,
!     NULL, false },
!   { NULL,             0, 0, false, false, false, NULL, NULL, false }
  };
  
  
Index: config/rs6000/rs6000.c
===================================================================
*** config/rs6000/rs6000.c	(revision 217943)
--- config/rs6000/rs6000.c	(working copy)
*************** static struct machine_function * rs6000_
*** 1083,1089 ****
  static int rs6000_ra_ever_killed (void);
  static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
  static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
! static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
  static tree rs6000_builtin_vectorized_libmass (tree, tree, tree);
  static void rs6000_emit_set_long_const (rtx, HOST_WIDE_INT);
  static int rs6000_memory_move_cost (machine_mode, reg_class_t, bool);
--- 1083,1092 ----
  static int rs6000_ra_ever_killed (void);
  static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
  static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
! static tree rs6000_handle_struct_decl_attribute (tree *, tree, tree, int,
! 						 bool *);
! static tree rs6000_handle_struct_type_attribute (tree *, tree, tree, int,
! 						 bool *);
  static tree rs6000_builtin_vectorized_libmass (tree, tree, tree);
  static void rs6000_emit_set_long_const (rtx, HOST_WIDE_INT);
  static int rs6000_memory_move_cost (machine_mode, reg_class_t, bool);
*************** static const char alt_reg_names[][8] =
*** 1295,1316 ****
  
  static const struct attribute_spec rs6000_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
!        affects_type_identity } */
!   { "altivec",   1, 1, false, true,  false, rs6000_handle_altivec_attribute,
!     false },
!   { "longcall",  0, 0, false, true,  true,  rs6000_handle_longcall_attribute,
!     false },
!   { "shortcall", 0, 0, false, true,  true,  rs6000_handle_longcall_attribute,
!     false },
!   { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute,
!     false },
!   { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute,
      false },
  #ifdef SUBTARGET_ATTRIBUTE_TABLE
    SUBTARGET_ATTRIBUTE_TABLE,
  #endif
!   { NULL,        0, 0, false, false, false, NULL, false }
  };
  
  #ifndef TARGET_PROFILE_KERNEL
--- 1298,1320 ----
  
  static const struct attribute_spec rs6000_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, decl_handler,
!        type_handler, affects_type_identity } */
!   { "altivec",   1, 1, false, true,  false, NULL,
!     rs6000_handle_altivec_attribute, false },
!   { "longcall",  0, 0, false, true,  true,  NULL,
!     rs6000_handle_longcall_attribute, false },
!   { "shortcall", 0, 0, false, true,  true,  NULL,
!     rs6000_handle_longcall_attribute, false },
!   { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_decl_attribute,
!     rs6000_handle_struct_type_attribute, false },
!   { "gcc_struct", 0, 0, false, false, false,
!     rs6000_handle_struct_decl_attribute, rs6000_handle_struct_type_attribute,
      false },
  #ifdef SUBTARGET_ATTRIBUTE_TABLE
    SUBTARGET_ATTRIBUTE_TABLE,
  #endif
!   { NULL,        0, 0, false, false, false, NULL, NULL, false }
  };
  
  #ifndef TARGET_PROFILE_KERNEL
*************** rs6000_handle_longcall_attribute (tree *
*** 28745,28753 ****
  				  int flags ATTRIBUTE_UNUSED,
  				  bool *no_add_attrs)
  {
!   if (TREE_CODE (*node) != FUNCTION_TYPE
!       && TREE_CODE (*node) != FIELD_DECL
!       && TREE_CODE (*node) != TYPE_DECL)
      {
        warning (OPT_Wattributes, "%qE attribute only applies to functions",
  	       name);
--- 28749,28755 ----
  				  int flags ATTRIBUTE_UNUSED,
  				  bool *no_add_attrs)
  {
!   if (TREE_CODE (*node) != FUNCTION_TYPE)
      {
        warning (OPT_Wattributes, "%qE attribute only applies to functions",
  	       name);
*************** rs6000_longcall_ref (rtx call_ref)
*** 28806,28824 ****
  
  /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
     struct attribute_spec.handler.  */
  static tree
! rs6000_handle_struct_attribute (tree *node, tree name,
! 				tree args ATTRIBUTE_UNUSED,
! 				int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
  {
!   tree *type = NULL;
!   if (DECL_P (*node))
!     {
!       if (TREE_CODE (*node) == TYPE_DECL)
!         type = &TREE_TYPE (*node);
!     }
!   else
!     type = node;
  
    if (!(type && (TREE_CODE (*type) == RECORD_TYPE
                   || TREE_CODE (*type) == UNION_TYPE)))
--- 28808,28821 ----
  
  /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
     struct attribute_spec.handler.  */
+ 
  static tree
! rs6000_handle_struct_type_attribute (tree *node, tree name,
! 				     tree args ATTRIBUTE_UNUSED,
! 				     int flags ATTRIBUTE_UNUSED,
! 				     bool *no_add_attrs)
  {
!   tree *type = node;
  
    if (!(type && (TREE_CODE (*type) == RECORD_TYPE
                   || TREE_CODE (*type) == UNION_TYPE)))
*************** rs6000_handle_struct_attribute (tree *no
*** 28840,28845 ****
--- 28837,28855 ----
    return NULL_TREE;
  }
  
+ static tree
+ rs6000_handle_struct_decl_attribute (tree *node, tree name, tree args,
+ 				     int flags, bool *no_add_attrs)
+ {
+   if (TREE_CODE (*node) == TYPE_DECL)
+     return rs6000_handle_struct_type_attribute (&TREE_TYPE (*node), name, args,
+ 						flags, no_add_attrs);
+ 
+   warning (OPT_Wattributes, "%qE attribute ignored", name);
+   *no_add_attrs = true;
+   return NULL_TREE;
+ }
+ 
  static bool
  rs6000_ms_bitfield_layout_p (const_tree record_type)
  {
Index: config/rx/rx.c
===================================================================
*** config/rx/rx.c	(revision 217943)
--- config/rx/rx.c	(working copy)
*************** rx_handle_vector_attribute (tree * node,
*** 2717,2733 ****
  /* Table of RX specific attributes.  */
  const struct attribute_spec rx_attribute_table[] =
  {
!   /* Name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
!      affects_type_identity.  */
!   { "fast_interrupt", 0, 0, true, false, false, rx_handle_func_attribute,
      false },
!   { "interrupt",      0, -1, true, false, false, rx_handle_func_attribute,
      false },
!   { "naked",          0, 0, true, false, false, rx_handle_func_attribute,
      false },
    { "vector",         1, -1, true, false, false, rx_handle_vector_attribute,
!     false },
!   { NULL,             0, 0, false, false, false, NULL, false }
  };
  
  /* Implement TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE.  */
--- 2717,2733 ----
  /* Table of RX specific attributes.  */
  const struct attribute_spec rx_attribute_table[] =
  {
!   /* Name, min_len, max_len, decl_req, type_req, fn_type_req, decl_handler,
!      type_handler, affects_type_identity.  */
!   { "fast_interrupt", 0, 0, true, false, false, rx_handle_func_attribute, NULL,
      false },
!   { "interrupt",      0, -1, true, false, false, rx_handle_func_attribute, NULL,
      false },
!   { "naked",          0, 0, true, false, false, rx_handle_func_attribute, NULL,
      false },
    { "vector",         1, -1, true, false, false, rx_handle_vector_attribute,
!     NULL, false },
!   { NULL,             0, 0, false, false, false, NULL, NULL, false }
  };
  
  /* Implement TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE.  */
Index: config/s390/s390.c
===================================================================
*** config/s390/s390.c	(revision 217943)
--- config/s390/s390.c	(working copy)
*************** s390_handle_hotpatch_attribute (tree *no
*** 497,506 ****
  }
  
  static const struct attribute_spec s390_attribute_table[] = {
!   { "hotpatch", 0, 1, true, false, false, s390_handle_hotpatch_attribute, false
    },
    /* End element.  */
!   { NULL,        0, 0, false, false, false, NULL, false }
  };
  
  /* Return the alignment for LABEL.  We default to the -falign-labels
--- 497,507 ----
  }
  
  static const struct attribute_spec s390_attribute_table[] = {
!   { "hotpatch", 0, 1, true, false, false, s390_handle_hotpatch_attribute, NULL,
!     false
    },
    /* End element.  */
!   { NULL,        0, 0, false, false, false, NULL, NULL, false }
  };
  
  /* Return the alignment for LABEL.  We default to the -falign-labels
Index: config/sh/sh.c
===================================================================
*** config/sh/sh.c	(revision 217943)
--- config/sh/sh.c	(working copy)
*************** static void sh_init_sync_libfuncs (void)
*** 352,376 ****
  
  static const struct attribute_spec sh_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
!        affects_type_identity } */
    { "interrupt_handler", 0, 0, true,  false, false,
!     sh_handle_interrupt_handler_attribute, false },
    { "sp_switch",         1, 1, true,  false, false,
!      sh_handle_sp_switch_attribute, false },
    { "trap_exit",         1, 1, true,  false, false,
!     sh_handle_trap_exit_attribute, false },
!   { "renesas",           0, 0, false, true, false,
      sh_handle_renesas_attribute, false },
    { "trapa_handler",     0, 0, true,  false, false,
!     sh_handle_interrupt_handler_attribute, false },
    { "nosave_low_regs",   0, 0, true,  false, false,
!     sh_handle_interrupt_handler_attribute, false },
    { "resbank",           0, 0, true,  false, false,
!     sh_handle_resbank_handler_attribute, false },
    { "function_vector",   1, 1, true,  false, false,
!     sh2a_handle_function_vector_handler_attribute, false },
!   { NULL,                0, 0, false, false, false, NULL, false }
  };
  
  /* Initialize the GCC target structure.  */
--- 352,376 ----
  
  static const struct attribute_spec sh_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, decl_handler,
!        type_handler, affects_type_identity } */
    { "interrupt_handler", 0, 0, true,  false, false,
!     sh_handle_interrupt_handler_attribute, NULL, false },
    { "sp_switch",         1, 1, true,  false, false,
!      sh_handle_sp_switch_attribute, NULL, false },
    { "trap_exit",         1, 1, true,  false, false,
!     sh_handle_trap_exit_attribute, NULL, false },
!   { "renesas",           0, 0, false, true, false, NULL,
      sh_handle_renesas_attribute, false },
    { "trapa_handler",     0, 0, true,  false, false,
!     sh_handle_interrupt_handler_attribute, NULL, false },
    { "nosave_low_regs",   0, 0, true,  false, false,
!     sh_handle_interrupt_handler_attribute, NULL, false },
    { "resbank",           0, 0, true,  false, false,
!     sh_handle_resbank_handler_attribute, NULL, false },
    { "function_vector",   1, 1, true,  false, false,
!     sh2a_handle_function_vector_handler_attribute, NULL, false },
!   { NULL,                0, 0, false, false, false, NULL, NULL, false }
  };
  
  /* Initialize the GCC target structure.  */
Index: config/sol2.h
===================================================================
*** config/sol2.h	(revision 217943)
--- config/sol2.h	(working copy)
*************** along with GCC; see the file COPYING3.
*** 316,323 ****
  /* #pragma init and #pragma fini are implemented on top of init and
     fini attributes.  */
  #define SOLARIS_ATTRIBUTE_TABLE						\
!   { "init",      0, 0, true,  false,  false, NULL, false },		\
!   { "fini",      0, 0, true,  false,  false, NULL, false }
  
  /* Solaris-specific #pragmas are implemented on top of attributes.  Hook in
     the bits from config/sol2.c.  */
--- 316,323 ----
  /* #pragma init and #pragma fini are implemented on top of init and
     fini attributes.  */
  #define SOLARIS_ATTRIBUTE_TABLE						\
!   { "init",      0, 0, true,  false,  false, NULL, NULL, false },	\
!   { "fini",      0, 0, true,  false,  false, NULL, NULL, false }
  
  /* Solaris-specific #pragmas are implemented on top of attributes.  Hook in
     the bits from config/sol2.c.  */
Index: config/sparc/sparc.c
===================================================================
*** config/sparc/sparc.c	(revision 217943)
--- config/sparc/sparc.c	(working copy)
*************** static void sparc_atomic_assign_expand_f
*** 653,662 ****
  /* Table of valid machine attributes.  */
  static const struct attribute_spec sparc_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
!        do_diagnostic } */
    SUBTARGET_ATTRIBUTE_TABLE,
!   { NULL,        0, 0, false, false, false, NULL, false }
  };
  #endif
  
--- 653,662 ----
  /* Table of valid machine attributes.  */
  static const struct attribute_spec sparc_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, decl_handler,
!        type_handler, do_diagnostic } */
    SUBTARGET_ATTRIBUTE_TABLE,
!   { NULL,        0, 0, false, false, false, NULL, NULL, false }
  };
  #endif
  
Index: config/spu/spu.c
===================================================================
*** config/spu/spu.c	(revision 217983)
--- config/spu/spu.c	(working copy)
*************** spu_canonicalize_comparison (int *code,
*** 7146,7158 ****
  /*  Table of machine attributes.  */
  static const struct attribute_spec spu_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
!        affects_type_identity } */
    { "naked",          0, 0, true,  false, false, spu_handle_fndecl_attribute,
!     false },
!   { "spu_vector",     0, 0, false, true,  false, spu_handle_vector_attribute,
!     false },
!   { NULL,             0, 0, false, false, false, NULL, false }
  };
  
  /*  TARGET overrides.  */
--- 7146,7158 ----
  /*  Table of machine attributes.  */
  static const struct attribute_spec spu_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, decl_handler,
!        type_handler, affects_type_identity } */
    { "naked",          0, 0, true,  false, false, spu_handle_fndecl_attribute,
!     NULL, false },
!   { "spu_vector",     0, 0, false, true,  false, NULL,
!     spu_handle_vector_attribute, false },
!   { NULL,             0, 0, false, false, false, NULL, NULL, false }
  };
  
  /*  TARGET overrides.  */
Index: config/stormy16/stormy16.c
===================================================================
*** config/stormy16/stormy16.c	(revision 217943)
--- config/stormy16/stormy16.c	(working copy)
*************** static tree xstormy16_handle_below100_at
*** 2212,2226 ****
  
  static const struct attribute_spec xstormy16_attribute_table[] =
  {
!   /* name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
!      affects_type_identity.  */
!   { "interrupt", 0, 0, false, true,  true,
!     xstormy16_handle_interrupt_attribute , false },
!   { "BELOW100",  0, 0, false, false, false,
!     xstormy16_handle_below100_attribute, false },
!   { "below100",  0, 0, false, false, false,
!     xstormy16_handle_below100_attribute, false },
!   { NULL,        0, 0, false, false, false, NULL, false }
  };
  
  /* Handle an "interrupt" attribute;
--- 2212,2226 ----
  
  static const struct attribute_spec xstormy16_attribute_table[] =
  {
!   /* name, min_len, max_len, decl_req, type_req, fn_type_req, decl_handler,
!      type_handler, affects_type_identity.  */
!   { "interrupt", 0, 0, false, true,  true, NULL,
!   xstormy16_handle_interrupt_attribute , false },
!   { "BELOW100",  0, 0, true, false, false,
!     xstormy16_handle_below100_attribute, NULL, false },
!   { "below100",  0, 0, true, false, false,
!     xstormy16_handle_below100_attribute, NULL, false },
!   { NULL,        0, 0, false, false, false, NULL, NULL, false }
  };
  
  /* Handle an "interrupt" attribute;
*************** xstormy16_handle_below100_attribute (tre
*** 2252,2266 ****
  				     int flags ATTRIBUTE_UNUSED,
  				     bool *no_add_attrs)
  {
!   if (TREE_CODE (*node) != VAR_DECL
!       && TREE_CODE (*node) != POINTER_TYPE
!       && TREE_CODE (*node) != TYPE_DECL)
      {
        warning (OPT_Wattributes,
  	       "%<__BELOW100__%> attribute only applies to variables");
        *no_add_attrs = true;
      }
!   else if (args == NULL_TREE && TREE_CODE (*node) == VAR_DECL)
      {
        if (! (TREE_PUBLIC (*node) || TREE_STATIC (*node)))
  	{
--- 2252,2264 ----
  				     int flags ATTRIBUTE_UNUSED,
  				     bool *no_add_attrs)
  {
!   if (TREE_CODE (*node) != VAR_DECL)
      {
        warning (OPT_Wattributes,
  	       "%<__BELOW100__%> attribute only applies to variables");
        *no_add_attrs = true;
      }
!   else if (args == NULL_TREE)
      {
        if (! (TREE_PUBLIC (*node) || TREE_STATIC (*node)))
  	{
Index: config/v850/v850.c
===================================================================
*** config/v850/v850.c	(revision 217943)
--- config/v850/v850.c	(working copy)
*************** v850_adjust_insn_length (rtx_insn *insn,
*** 3138,3156 ****
  
  static const struct attribute_spec v850_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
!        affects_type_identity } */
    { "interrupt_handler", 0, 0, true,  false, false,
!     v850_handle_interrupt_attribute, false },
    { "interrupt",         0, 0, true,  false, false,
!     v850_handle_interrupt_attribute, false },
    { "sda",               0, 0, true,  false, false,
!     v850_handle_data_area_attribute, false },
    { "tda",               0, 0, true,  false, false,
!     v850_handle_data_area_attribute, false },
    { "zda",               0, 0, true,  false, false,
!     v850_handle_data_area_attribute, false },
!   { NULL,                0, 0, false, false, false, NULL, false }
  };
  
  static void
--- 3138,3156 ----
  
  static const struct attribute_spec v850_attribute_table[] =
  {
!   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, decl_handler,
!        type_handler, affects_type_identity } */
    { "interrupt_handler", 0, 0, true,  false, false,
!     v850_handle_interrupt_attribute, NULL, false },
    { "interrupt",         0, 0, true,  false, false,
!     v850_handle_interrupt_attribute, NULL, false },
    { "sda",               0, 0, true,  false, false,
!     v850_handle_data_area_attribute, NULL, false },
    { "tda",               0, 0, true,  false, false,
!     v850_handle_data_area_attribute, NULL, false },
    { "zda",               0, 0, true,  false, false,
!     v850_handle_data_area_attribute, NULL, false },
!   { NULL,                0, 0, false, false, false, NULL, NULL, false }
  };
  
  static void