
	* attribs.c (process_attribute_spec): New.  Factored from
	decl_attribute to return a valid attribute spec.
	(finalize_type_attribute): New.  Factored from decl_attribute to process
	attributes for types after error checking.
	(type_attributes): New.  Factored type specific portions of
	decl_attributes.
	(decl_attributes): Moved all type processing to other functions.
	* attribs.h (type_attributes): Export.
	* c/c-decl.c (groktypename, grokdeclarator, finish_struct,
	finish_enum): Call type_attributes.
	* c-family/c-common.c (handle_tm_attribute): Call type_attributes.
	* cp/decl.c (grokdeclarator): Call type_attributes.
	* cp/decl2.c (cplus_decl_attributes): Call type_attributes when node is
	a type.
	* ada/gcc-interface/utils.c (finish_record_type): Call type_attribute.
	(process_attributes): Call type_attribute or decl_attribute as needed.
	* config/i386/i386.c (ix86_handle_tm_regparm_attribute): Call
	type_attribute or decl_attribute as required.
	(ix86_init_tm_builtins ): Call type_attributes.

Index: attribs.c
===================================================================
*** attribs.c	(revision 217787)
--- attribs.c	(working copy)
*************** get_attribute_namespace (const_tree attr
*** 354,368 ****
    return get_identifier ("gnu");
  }
  
  
  /* Process the attributes listed in ATTRIBUTES and install them in *NODE,
!    which is either a DECL (including a TYPE_DECL) or a TYPE.  If a DECL,
!    it should be modified in place; if a TYPE, a copy should be created
!    unless ATTR_FLAG_TYPE_IN_PLACE is set in FLAGS.  FLAGS gives further
!    information, in the form of a bitwise OR of flags in enum attribute_flags
!    from tree.h.  Depending on these flags, some attributes may be
!    returned to be applied at a later stage (for example, to apply
!    a decl attribute to the declaration rather than to its type).  */
  
  tree
  decl_attributes (tree *node, tree attributes, int flags)
--- 354,622 ----
    return get_identifier ("gnu");
  }
  
+ /* Lookup the spec for attribute A using FLAGS, and issue any warnings or
+   errors as appropriate.   Return NULL or a valid spec.  */
+ 
+ static const struct attribute_spec *
+ process_attribute_spec (tree a, int flags)
+ {
+   tree name = get_attribute_name (a);
+   tree ns = get_attribute_namespace (a);
+   tree args = TREE_VALUE (a);
+   const struct attribute_spec *spec = lookup_scoped_attribute_spec (ns, name);
+ 
+   if (spec == NULL)
+     {
+       if (!(flags & (int) ATTR_FLAG_BUILT_IN))
+ 	{
+ 	  if (ns == NULL_TREE || !cxx11_attribute_p (a))
+ 	    warning (OPT_Wattributes, "%qE attribute directive ignored",
+ 		     name);
+ 	  else
+ 	    warning (OPT_Wattributes,
+ 		     "%<%E::%E%> scoped attribute directive ignored",
+ 		     ns, name);
+ 	}
+       return NULL;
+     }
+   else if (list_length (args) < spec->min_length
+ 	   || (spec->max_length >= 0
+ 	       && list_length (args) > spec->max_length))
+     {
+       error ("wrong number of arguments specified for %qE attribute",
+ 	     name);
+       return NULL;
+     }
+   gcc_assert (is_attribute_p (spec->name, name));
+   return spec;
+ }
+ 
+ /* Perform the type specific processing of type_attribute.  This is factored
+    out to allow decl_attributes() to process underlying types when necessary.
+    In those cases, DECL_NODE is passed in so the decl can have re-layout
+    called.  SPEC is the already verified attribute spec structure.  Otherwise
+    the parameters match those of type_attribute.  */
+ 
+ static tree
+ finalize_type_attribute (tree *node, const struct attribute_spec *spec,
+ 			 tree a, tree returned_attrs, int flags,
+ 			 tree *decl_node = NULL)
+ {
+   bool no_add_attrs = 0;
+   int fn_ptr_quals = 0;
+   tree fn_ptr_tmp = NULL_TREE;
+   tree name = get_attribute_name (a);
+   tree args = TREE_VALUE (a);
+   tree *anode = node;
+ 
+   gcc_checking_assert (TYPE_P (*node));
+ 
+   if (spec->function_type_required && TREE_CODE (*anode) != FUNCTION_TYPE
+       && TREE_CODE (*anode) != METHOD_TYPE)
+     {
+       if (TREE_CODE (*anode) == POINTER_TYPE
+ 	  && (TREE_CODE (TREE_TYPE (*anode)) == FUNCTION_TYPE
+ 	      || TREE_CODE (TREE_TYPE (*anode)) == METHOD_TYPE))
+ 	{
+ 	  /* OK, this is a bit convoluted.  We can't just make a copy
+ 	     of the pointer type and modify its TREE_TYPE, because if
+ 	     we change the attributes of the target type the pointer
+ 	     type needs to have a different TYPE_MAIN_VARIANT.  So we
+ 	     pull out the target type now, frob it as appropriate, and
+ 	     rebuild the pointer type later.
+ 
+ 	     This would all be simpler if attributes were part of the
+ 	     declarator, grumble grumble.  */
+ 	  fn_ptr_tmp = TREE_TYPE (*anode);
+ 	  fn_ptr_quals = TYPE_QUALS (*anode);
+ 	  anode = &fn_ptr_tmp;
+ 	  flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
+ 	}
+       else if (flags & (int) ATTR_FLAG_FUNCTION_NEXT)
+ 	{
+ 	  /* Pass on this attribute to be tried again.  */
+ 	  returned_attrs = tree_cons (name, args, returned_attrs);
+ 	  return returned_attrs;
+ 	}
+ 
+       if (TREE_CODE (*anode) != FUNCTION_TYPE
+ 	  && TREE_CODE (*anode) != METHOD_TYPE)
+ 	{
+ 	  warning (OPT_Wattributes,
+ 		   "%qE attribute only applies to function types",
+ 		   name);
+ 	  return returned_attrs;
+ 	}
+     }
+ 
+   if ((flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
+       && TYPE_SIZE (*anode) != NULL_TREE)
+     {
+       warning (OPT_Wattributes, "type attributes ignored after type is already defined");
+       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);
+     }
+ 
+   /* If there was a decl change the layout in case anything changed.  */
+   if (decl_node && spec->type_required
+       && (TREE_CODE (*decl_node) == VAR_DECL
+ 	  || TREE_CODE (*decl_node) == PARM_DECL
+ 	  || TREE_CODE (*decl_node) == RESULT_DECL))
+     relayout_decl (*decl_node);
+ 
+   if (!no_add_attrs)
+     {
+       tree old_attrs;
+       tree a;
+ 
+       old_attrs = TYPE_ATTRIBUTES (*anode);
+ 
+       for (a = lookup_attribute (spec->name, old_attrs);
+ 	   a != NULL_TREE;
+ 	   a = lookup_attribute (spec->name, TREE_CHAIN (a)))
+ 	{
+ 	  if (simple_cst_equal (TREE_VALUE (a), args) == 1)
+ 	    break;
+ 	}
+ 
+       if (a == NULL_TREE)
+ 	{
+ 	  if (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
+ 	    {
+ 	      TYPE_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
+ 	      /* If this is the main variant, also push the attributes
+ 		 out to the other variants.  */
+ 	      if (*anode == TYPE_MAIN_VARIANT (*anode))
+ 		{
+ 		  tree variant;
+ 		  for (variant = *anode; variant;
+ 		       variant = TYPE_NEXT_VARIANT (variant))
+ 		    {
+ 		      if (TYPE_ATTRIBUTES (variant) == old_attrs)
+ 			TYPE_ATTRIBUTES (variant)
+ 			  = TYPE_ATTRIBUTES (*anode);
+ 		      else if (!lookup_attribute
+ 			       (spec->name, TYPE_ATTRIBUTES (variant)))
+ 			TYPE_ATTRIBUTES (variant) = tree_cons
+ 			  (name, args, TYPE_ATTRIBUTES (variant));
+ 		    }
+ 		}
+ 	    }
+ 	  else
+ 	    *anode = build_type_attribute_variant (*anode,
+ 						   tree_cons (name, args,
+ 							      old_attrs));
+ 	}
+     }
+ 
+   if (fn_ptr_tmp)
+     {
+       /* Rebuild the function pointer type and put it in the
+ 	 appropriate place.  */
+       fn_ptr_tmp = build_pointer_type (fn_ptr_tmp);
+       if (fn_ptr_quals)
+ 	fn_ptr_tmp = build_qualified_type (fn_ptr_tmp, fn_ptr_quals);
+       if (decl_node)
+         TREE_TYPE (*decl_node) = fn_ptr_tmp;
+       else
+         {
+ 	  gcc_assert (TREE_CODE (*node) == POINTER_TYPE);
+ 	  *node = fn_ptr_tmp;
+ 	}
+     }
+   return returned_attrs;
+ 
+ }
+ 
+ /* Process the attributes listed in ATTRIBUTES and install them in *NODE,
+    which is a TYPE.  A copy should be created unless ATTR_FLAG_TYPE_IN_PLACE
+    is set in FLAGS.  FLAGS gives further information, in the form of a
+    bitwise OR of flags in enum attribute_flags from tree.h.
+    Depending on these flags, some attributes may be returned to be 
+    applied at a later stage (for example, to apply a decl attribute to the 
+    declaration rather than to its type).  */
+ 
+ tree
+ type_attributes (tree *node, tree attributes, int flags)
+ {
+   tree a;
+   tree returned_attrs = NULL_TREE;
+ 
+ 
+   if (TREE_TYPE (*node) == error_mark_node || attributes == error_mark_node)
+     return NULL_TREE;
+ 
+   gcc_checking_assert (TYPE_P (*node));
+ 
+   if (!attributes_initialized)
+     init_attributes ();
+ 
+   targetm.insert_attributes (*node, &attributes);
+ 
+   for (a = attributes; a; a = TREE_CHAIN (a))
+     {
+       tree name = get_attribute_name (a);
+       tree args = TREE_VALUE (a);
+       const struct attribute_spec *spec = process_attribute_spec (a, flags);
+ 
+       if (!spec)
+ 	continue;
+ 
+       if (cxx11_attribute_p (a) && !(flags & ATTR_FLAG_TYPE_IN_PLACE))
+ 	{
+ 	  /* This is a c++11 attribute that appertains to a
+ 	     type-specifier, outside of the definition of, a class
+ 	     type.  Ignore it.  */
+ 	  warning (OPT_Wattributes, "attribute ignored");
+ 	  inform (input_location,
+ 		  "an attribute that appertains to a type-specifier "
+ 		  "is ignored");
+ 	  continue;
+ 	}
+ 
+       if (spec->decl_required)
+ 	{
+ 	  if (flags & ((int) ATTR_FLAG_DECL_NEXT
+ 		       | (int) ATTR_FLAG_FUNCTION_NEXT
+ 		       | (int) ATTR_FLAG_ARRAY_NEXT))
+ 	    {
+ 	      /* Pass on this attribute to be tried again.  */
+ 	      returned_attrs = tree_cons (name, args, returned_attrs);
+ 	      continue;
+ 	    }
+ 	  else
+ 	    {
+ 	      warning (OPT_Wattributes, "%qE attribute does not apply to types",
+ 		       name);
+ 	      continue;
+ 	    }
+ 	}
+ 
+       returned_attrs = finalize_type_attribute (node, spec, a, returned_attrs,
+ 						flags);
+     }
+ 
+   return returned_attrs;
+ }
+ 
+ 
+ 
  
  /* Process the attributes listed in ATTRIBUTES and install them in *NODE,
!    which is a DECL (including a TYPE_DECL) it should be modified in place; 
!    FLAGS gives further information, in the form of a bitwise OR of flags in
!    enum attribute_flags from tree.h.  Depending on these flags, some
!    attributes may be returned to be applied at a later stage.  */
  
  tree
  decl_attributes (tree *node, tree attributes, int flags)
*************** decl_attributes (tree *node, tree attrib
*** 370,378 ****
--- 624,635 ----
    tree a;
    tree returned_attrs = NULL_TREE;
  
+ 
    if (TREE_TYPE (*node) == error_mark_node || attributes == error_mark_node)
      return NULL_TREE;
  
+   gcc_checking_assert (DECL_P (*node));
+ 
    if (!attributes_initialized)
      init_attributes ();
  
*************** decl_attributes (tree *node, tree attrib
*** 429,583 ****
  
    for (a = attributes; a; a = TREE_CHAIN (a))
      {
-       tree ns = get_attribute_namespace (a);
        tree name = get_attribute_name (a);
        tree args = TREE_VALUE (a);
        tree *anode = node;
-       const struct attribute_spec *spec =
- 	lookup_scoped_attribute_spec (ns, name);
        bool no_add_attrs = 0;
!       int fn_ptr_quals = 0;
!       tree fn_ptr_tmp = NULL_TREE;
  
!       if (spec == NULL)
! 	{
! 	  if (!(flags & (int) ATTR_FLAG_BUILT_IN))
! 	    {
! 	      if (ns == NULL_TREE || !cxx11_attribute_p (a))
! 		warning (OPT_Wattributes, "%qE attribute directive ignored",
! 			 name);
! 	      else
! 		warning (OPT_Wattributes,
! 			 "%<%E::%E%> scoped attribute directive ignored",
! 			 ns, name);
! 	    }
! 	  continue;
! 	}
!       else if (list_length (args) < spec->min_length
! 	       || (spec->max_length >= 0
! 		   && list_length (args) > spec->max_length))
! 	{
! 	  error ("wrong number of arguments specified for %qE attribute",
! 		 name);
! 	  continue;
! 	}
!       gcc_assert (is_attribute_p (spec->name, name));
  
!       if (TYPE_P (*node)
! 	  && cxx11_attribute_p (a)
! 	  && !(flags & ATTR_FLAG_TYPE_IN_PLACE))
! 	{
! 	  /* This is a c++11 attribute that appertains to a
! 	     type-specifier, outside of the definition of, a class
! 	     type.  Ignore it.  */
! 	  warning (OPT_Wattributes, "attribute ignored");
! 	  inform (input_location,
! 		  "an attribute that appertains to a type-specifier "
! 		  "is ignored");
! 	  continue;
! 	}
! 
!       if (spec->decl_required && !DECL_P (*anode))
! 	{
! 	  if (flags & ((int) ATTR_FLAG_DECL_NEXT
! 		       | (int) ATTR_FLAG_FUNCTION_NEXT
! 		       | (int) ATTR_FLAG_ARRAY_NEXT))
! 	    {
! 	      /* Pass on this attribute to be tried again.  */
! 	      returned_attrs = tree_cons (name, args, returned_attrs);
! 	      continue;
! 	    }
! 	  else
! 	    {
! 	      warning (OPT_Wattributes, "%qE attribute does not apply to types",
! 		       name);
! 	      continue;
! 	    }
! 	}
  
        /* If we require a type, but were passed a decl, set up to make a
  	 new type and update the one in the decl.  ATTR_FLAG_TYPE_IN_PLACE
  	 would have applied if we'd been passed a type, but we cannot modify
  	 the decl's type in place here.  */
!       if (spec->type_required && DECL_P (*anode))
  	{
  	  anode = &TREE_TYPE (*anode);
  	  flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
! 	}
! 
!       if (spec->function_type_required && TREE_CODE (*anode) != FUNCTION_TYPE
! 	  && TREE_CODE (*anode) != METHOD_TYPE)
! 	{
! 	  if (TREE_CODE (*anode) == POINTER_TYPE
! 	      && (TREE_CODE (TREE_TYPE (*anode)) == FUNCTION_TYPE
! 		  || TREE_CODE (TREE_TYPE (*anode)) == METHOD_TYPE))
! 	    {
! 	      /* OK, this is a bit convoluted.  We can't just make a copy
! 		 of the pointer type and modify its TREE_TYPE, because if
! 		 we change the attributes of the target type the pointer
! 		 type needs to have a different TYPE_MAIN_VARIANT.  So we
! 		 pull out the target type now, frob it as appropriate, and
! 		 rebuild the pointer type later.
! 
! 		 This would all be simpler if attributes were part of the
! 		 declarator, grumble grumble.  */
! 	      fn_ptr_tmp = TREE_TYPE (*anode);
! 	      fn_ptr_quals = TYPE_QUALS (*anode);
! 	      anode = &fn_ptr_tmp;
! 	      flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
! 	    }
! 	  else if (flags & (int) ATTR_FLAG_FUNCTION_NEXT)
! 	    {
! 	      /* Pass on this attribute to be tried again.  */
! 	      returned_attrs = tree_cons (name, args, returned_attrs);
! 	      continue;
! 	    }
! 
! 	  if (TREE_CODE (*anode) != FUNCTION_TYPE
! 	      && TREE_CODE (*anode) != METHOD_TYPE)
! 	    {
! 	      warning (OPT_Wattributes,
! 		       "%qE attribute only applies to function types",
! 		       name);
! 	      continue;
! 	    }
! 	}
! 
!       if (TYPE_P (*anode)
! 	  && (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
! 	  && TYPE_SIZE (*anode) != NULL_TREE)
! 	{
! 	  warning (OPT_Wattributes, "type attributes ignored after type is already defined");
  	  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);
  	}
  
-       /* Layout the decl in case anything changed.  */
-       if (spec->type_required && DECL_P (*node)
- 	  && (TREE_CODE (*node) == VAR_DECL
- 	      || TREE_CODE (*node) == PARM_DECL
- 	      || TREE_CODE (*node) == RESULT_DECL))
- 	relayout_decl (*node);
- 
        if (!no_add_attrs)
  	{
  	  tree old_attrs;
  	  tree a;
  
! 	  if (DECL_P (*anode))
! 	    old_attrs = DECL_ATTRIBUTES (*anode);
! 	  else
! 	    old_attrs = TYPE_ATTRIBUTES (*anode);
  
  	  for (a = lookup_attribute (spec->name, old_attrs);
  	       a != NULL_TREE;
--- 686,731 ----
  
    for (a = attributes; a; a = TREE_CHAIN (a))
      {
        tree name = get_attribute_name (a);
        tree args = TREE_VALUE (a);
        tree *anode = node;
        bool no_add_attrs = 0;
!       const struct attribute_spec *spec = process_attribute_spec (a, flags);
  
!       gcc_assert (DECL_P (*node));
  
!       if (!spec)
! 	continue;
  
        /* If we require a type, but were passed a decl, set up to make a
  	 new type and update the one in the decl.  ATTR_FLAG_TYPE_IN_PLACE
  	 would have applied if we'd been passed a type, but we cannot modify
  	 the decl's type in place here.  */
!       if (spec->type_required)
  	{
  	  anode = &TREE_TYPE (*anode);
  	  flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
! 	  returned_attrs = finalize_type_attribute (anode, spec, a,
! 						    returned_attrs, flags,
! 						    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);
  	}
  
        if (!no_add_attrs)
  	{
  	  tree old_attrs;
  	  tree a;
  
! 	  old_attrs = DECL_ATTRIBUTES (*anode);
  
  	  for (a = lookup_attribute (spec->name, old_attrs);
  	       a != NULL_TREE;
*************** decl_attributes (tree *node, tree attrib
*** 588,642 ****
  	    }
  
  	  if (a == NULL_TREE)
! 	    {
! 	      /* This attribute isn't already in the list.  */
! 	      if (DECL_P (*anode))
! 		DECL_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
! 	      else if (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
! 		{
! 		  TYPE_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
! 		  /* If this is the main variant, also push the attributes
! 		     out to the other variants.  */
! 		  if (*anode == TYPE_MAIN_VARIANT (*anode))
! 		    {
! 		      tree variant;
! 		      for (variant = *anode; variant;
! 			   variant = TYPE_NEXT_VARIANT (variant))
! 			{
! 			  if (TYPE_ATTRIBUTES (variant) == old_attrs)
! 			    TYPE_ATTRIBUTES (variant)
! 			      = TYPE_ATTRIBUTES (*anode);
! 			  else if (!lookup_attribute
! 				   (spec->name, TYPE_ATTRIBUTES (variant)))
! 			    TYPE_ATTRIBUTES (variant) = tree_cons
! 			      (name, args, TYPE_ATTRIBUTES (variant));
! 			}
! 		    }
! 		}
! 	      else
! 		*anode = build_type_attribute_variant (*anode,
! 						       tree_cons (name, args,
! 								  old_attrs));
! 	    }
  	}
  
-       if (fn_ptr_tmp)
- 	{
- 	  /* Rebuild the function pointer type and put it in the
- 	     appropriate place.  */
- 	  fn_ptr_tmp = build_pointer_type (fn_ptr_tmp);
- 	  if (fn_ptr_quals)
- 	    fn_ptr_tmp = build_qualified_type (fn_ptr_tmp, fn_ptr_quals);
- 	  if (DECL_P (*node))
- 	    TREE_TYPE (*node) = fn_ptr_tmp;
- 	  else
- 	    {
- 	      gcc_assert (TREE_CODE (*node) == POINTER_TYPE);
- 	      *node = fn_ptr_tmp;
- 	    }
- 	}
      }
- 
    return returned_attrs;
  }
  
--- 736,746 ----
  	    }
  
  	  if (a == NULL_TREE)
! 	    /* This attribute isn't already in the list.  */
! 	    DECL_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
  	}
  
      }
    return returned_attrs;
  }
  
*************** get_attribute_name (const_tree attr)
*** 681,685 ****
  void
  apply_tm_attr (tree fndecl, tree attr)
  {
!   decl_attributes (&TREE_TYPE (fndecl), tree_cons (attr, NULL, NULL), 0);
  }
--- 785,789 ----
  void
  apply_tm_attr (tree fndecl, tree attr)
  {
!   type_attributes (&TREE_TYPE (fndecl), tree_cons (attr, NULL, NULL), 0);
  }
Index: attribs.h
===================================================================
*** attribs.h	(revision 217787)
--- attribs.h	(working copy)
*************** extern void init_attributes (void);
*** 31,36 ****
--- 31,37 ----
     from tree.h.  Depending on these flags, some attributes may be
     returned to be applied at a later stage (for example, to apply
     a decl attribute to the declaration rather than to its type).  */
+ extern tree type_attributes (tree *, tree, int);
  extern tree decl_attributes (tree *, tree, int);
  
  extern bool cxx11_attribute_p (const_tree);
Index: c/c-decl.c
===================================================================
*** c/c-decl.c	(revision 217787)
--- c/c-decl.c	(working copy)
*************** groktypename (struct c_type_name *type_n
*** 4383,4389 ****
  			 DEPRECATED_NORMAL);
  
    /* Apply attributes.  */
!   decl_attributes (&type, attrs, 0);
  
    return type;
  }
--- 4383,4389 ----
  			 DEPRECATED_NORMAL);
  
    /* Apply attributes.  */
!   type_attributes (&type, attrs, 0);
  
    return type;
  }
*************** grokdeclarator (const struct c_declarato
*** 5691,5697 ****
  	      attr_flags |= (int) ATTR_FLAG_FUNCTION_NEXT;
  	    else if (inner_decl->kind == cdk_array)
  	      attr_flags |= (int) ATTR_FLAG_ARRAY_NEXT;
! 	    returned_attrs = decl_attributes (&type,
  					      chainon (returned_attrs, attrs),
  					      attr_flags);
  	    break;
--- 5691,5697 ----
  	      attr_flags |= (int) ATTR_FLAG_FUNCTION_NEXT;
  	    else if (inner_decl->kind == cdk_array)
  	      attr_flags |= (int) ATTR_FLAG_ARRAY_NEXT;
! 	    returned_attrs = type_attributes (&type,
  					      chainon (returned_attrs, attrs),
  					      attr_flags);
  	    break;
*************** finish_struct (location_t loc, tree t, t
*** 7576,7582 ****
  
    TYPE_SIZE (t) = 0;
  
!   decl_attributes (&t, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);
  
    if (pedantic)
      {
--- 7576,7582 ----
  
    TYPE_SIZE (t) = 0;
  
!   type_attributes (&t, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);
  
    if (pedantic)
      {
*************** finish_enum (tree enumtype, tree values,
*** 7949,7955 ****
    bool toplevel = (file_scope == current_scope);
    struct lang_type *lt;
  
!   decl_attributes (&enumtype, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);
  
    /* Calculate the maximum value of any enumerator in this type.  */
  
--- 7949,7955 ----
    bool toplevel = (file_scope == current_scope);
    struct lang_type *lt;
  
!   type_attributes (&enumtype, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);
  
    /* Calculate the maximum value of any enumerator in this type.  */
  
Index: c-family/c-common.c
===================================================================
*** c-family/c-common.c	(revision 217787)
--- c-family/c-common.c	(working copy)
*************** handle_tm_attribute (tree *node, tree na
*** 8574,8580 ****
  	if (subcode == FUNCTION_TYPE || subcode == METHOD_TYPE)
  	  {
  	    tree fn_tmp = TREE_TYPE (*node);
! 	    decl_attributes (&fn_tmp, tree_cons (name, args, NULL), 0);
  	    *node = build_pointer_type (fn_tmp);
  	    break;
  	  }
--- 8574,8580 ----
  	if (subcode == FUNCTION_TYPE || subcode == METHOD_TYPE)
  	  {
  	    tree fn_tmp = TREE_TYPE (*node);
! 	    type_attributes (&fn_tmp, tree_cons (name, args, NULL), 0);
  	    *node = build_pointer_type (fn_tmp);
  	    break;
  	  }
Index: cp/decl.c
===================================================================
*** cp/decl.c	(revision 217787)
--- cp/decl.c	(working copy)
*************** grokdeclarator (const cp_declarator *dec
*** 9581,9587 ****
      {
        /* Apply the c++11 attributes to the type preceding them.  */
        input_location = declspecs->locations[ds_std_attribute];
!       decl_attributes (&type, declspecs->std_attributes, 0);
        input_location = saved_loc;
      }
  
--- 9581,9587 ----
      {
        /* Apply the c++11 attributes to the type preceding them.  */
        input_location = declspecs->locations[ds_std_attribute];
!       type_attributes (&type, declspecs->std_attributes, 0);
        input_location = saved_loc;
      }
  
*************** grokdeclarator (const cp_declarator *dec
*** 9607,9613 ****
  	    attr_flags |= (int) ATTR_FLAG_FUNCTION_NEXT;
  	  if (declarator->kind == cdk_array)
  	    attr_flags |= (int) ATTR_FLAG_ARRAY_NEXT;
! 	  returned_attrs = decl_attributes (&type,
  					    chainon (returned_attrs, attrs),
  					    attr_flags);
  	}
--- 9607,9613 ----
  	    attr_flags |= (int) ATTR_FLAG_FUNCTION_NEXT;
  	  if (declarator->kind == cdk_array)
  	    attr_flags |= (int) ATTR_FLAG_ARRAY_NEXT;
! 	  returned_attrs = type_attributes (&type,
  					    chainon (returned_attrs, attrs),
  					    attr_flags);
  	}
*************** grokdeclarator (const cp_declarator *dec
*** 9853,9859 ****
  
  		 The optional attribute-specifier-seq appertains to
  		 the function type.  */
! 	      decl_attributes (&type, declarator->std_attributes,
  			       0);
  	  }
  	  break;
--- 9853,9859 ----
  
  		 The optional attribute-specifier-seq appertains to
  		 the function type.  */
! 	      type_attributes (&type, declarator->std_attributes,
  			       0);
  	  }
  	  break;
*************** grokdeclarator (const cp_declarator *dec
*** 10034,10040 ****
  		 [the optional attribute-specifier-seq (7.6.1) appertains
  		  to the pointer and not to the object pointed to].  */
  	  if (declarator->std_attributes)
! 	    decl_attributes (&type, declarator->std_attributes,
  			     0);
  
  	  ctype = NULL_TREE;
--- 10034,10040 ----
  		 [the optional attribute-specifier-seq (7.6.1) appertains
  		  to the pointer and not to the object pointed to].  */
  	  if (declarator->std_attributes)
! 	    type_attributes (&type, declarator->std_attributes,
  			     0);
  
  	  ctype = NULL_TREE;
Index: cp/decl2.c
===================================================================
*** cp/decl2.c	(revision 217787)
--- cp/decl2.c	(working copy)
*************** cplus_decl_attributes (tree *decl, tree
*** 1472,1484 ****
  
    if (TREE_TYPE (*decl) && TYPE_PTRMEMFUNC_P (TREE_TYPE (*decl)))
      {
!       attributes
! 	= decl_attributes (decl, attributes, flags | ATTR_FLAG_FUNCTION_NEXT);
!       decl_attributes (&TYPE_PTRMEMFUNC_FN_TYPE_RAW (TREE_TYPE (*decl)),
  		       attributes, flags);
      }
    else
!     decl_attributes (decl, attributes, flags);
  
    if (TREE_CODE (*decl) == TYPE_DECL)
      SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (*decl), TREE_TYPE (*decl));
--- 1472,1491 ----
  
    if (TREE_TYPE (*decl) && TYPE_PTRMEMFUNC_P (TREE_TYPE (*decl)))
      {
!       if (TYPE_P (*decl))
! 	attributes
! 	  = type_attributes (decl, attributes, flags | ATTR_FLAG_FUNCTION_NEXT);
!       else
! 	attributes
! 	  = decl_attributes (decl, attributes, flags | ATTR_FLAG_FUNCTION_NEXT);
!       type_attributes (&TYPE_PTRMEMFUNC_FN_TYPE_RAW (TREE_TYPE (*decl)),
  		       attributes, flags);
      }
    else
!     if (TYPE_P (*decl))
!       type_attributes (decl, attributes, flags);
!     else
!       decl_attributes (decl, attributes, flags);
  
    if (TREE_CODE (*decl) == TYPE_DECL)
      SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (*decl), TREE_TYPE (*decl));
Index: ada/gcc-interface/utils.c
===================================================================
*** ada/gcc-interface/utils.c	(revision 217787)
--- ada/gcc-interface/utils.c	(working copy)
*************** finish_record_type (tree record_type, tr
*** 1629,1635 ****
  	 efficient packing in almost all cases.  */
  #ifdef TARGET_MS_BITFIELD_LAYOUT
        if (TARGET_MS_BITFIELD_LAYOUT && TYPE_PACKED (record_type))
! 	decl_attributes (&record_type,
  			 tree_cons (get_identifier ("gcc_struct"),
  				    NULL_TREE, NULL_TREE),
  			 ATTR_FLAG_TYPE_IN_PLACE);
--- 1629,1635 ----
  	 efficient packing in almost all cases.  */
  #ifdef TARGET_MS_BITFIELD_LAYOUT
        if (TARGET_MS_BITFIELD_LAYOUT && TYPE_PACKED (record_type))
! 	type_attributes (&record_type,
  			 tree_cons (get_identifier ("gcc_struct"),
  				    NULL_TREE, NULL_TREE),
  			 ATTR_FLAG_TYPE_IN_PLACE);
*************** process_attributes (tree *node, struct a
*** 2650,2657 ****
        {
        case ATTR_MACHINE_ATTRIBUTE:
  	Sloc_to_locus (Sloc (gnat_node), &input_location);
! 	decl_attributes (node, tree_cons (attr->name, attr->args, NULL_TREE),
! 			 in_place ? ATTR_FLAG_TYPE_IN_PLACE : 0);
  	break;
  
        case ATTR_LINK_ALIAS:
--- 2650,2661 ----
        {
        case ATTR_MACHINE_ATTRIBUTE:
  	Sloc_to_locus (Sloc (gnat_node), &input_location);
! 	if (TYPE_P (*node))
! 	  type_attributes (node, tree_cons (attr->name, attr->args, NULL_TREE),
! 			   in_place ? ATTR_FLAG_TYPE_IN_PLACE : 0);
! 	else
! 	  decl_attributes (node, tree_cons (attr->name, attr->args, NULL_TREE),
! 			   in_place ? ATTR_FLAG_TYPE_IN_PLACE : 0);
  	break;
  
        case ATTR_LINK_ALIAS:
Index: config/i386/i386.c
===================================================================
*** config/i386/i386.c	(revision 217787)
--- config/i386/i386.c	(working copy)
*************** ix86_handle_tm_regparm_attribute (tree *
*** 5614,5620 ****
        alt = tree_cons (NULL, build_int_cst (NULL, 2), NULL);
        alt = tree_cons (get_identifier ("regparm"), alt, NULL);
      }
!   decl_attributes (node, alt, flags);
  
    return NULL_TREE;
  }
--- 5614,5623 ----
        alt = tree_cons (NULL, build_int_cst (NULL, 2), NULL);
        alt = tree_cons (get_identifier ("regparm"), alt, NULL);
      }
!   if (TYPE_P (*node))
!     type_attributes (node, alt, flags);
!   else
!     decl_attributes (node, alt, flags);
  
    return NULL_TREE;
  }
*************** ix86_init_tm_builtins (void)
*** 33294,33300 ****
  				       attrs);
  	  /* add_builtin_function() will set the DECL_ATTRIBUTES, now
  	     set the TYPE_ATTRIBUTES.  */
! 	  decl_attributes (&TREE_TYPE (decl), attrs_type, ATTR_FLAG_BUILT_IN);
  
  	  set_builtin_decl (code, decl, false);
  	}
--- 33297,33303 ----
  				       attrs);
  	  /* add_builtin_function() will set the DECL_ATTRIBUTES, now
  	     set the TYPE_ATTRIBUTES.  */
! 	  type_attributes (&TREE_TYPE (decl), attrs_type, ATTR_FLAG_BUILT_IN);
  
  	  set_builtin_decl (code, decl, false);
  	}
