From patchwork Wed Nov 26 23:59:52 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew MacLeod X-Patchwork-Id: 415346 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id C9F941401D0 for ; Thu, 27 Nov 2014 11:00:07 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:subject:content-type; q= dns; s=default; b=eY5Y+/9KGjUgmgXXZ2w2KvUkZlIjXAar4Jaf9ffNTiTkhO 3aFH8ZzCbsgfXzXqd5kxUKEFuKYuKod34yi90i3yVEK2nF2O1m29syTez0pF06wp GsdwkX0ycQjCDATQI9vqt5NUEGz9hjP8fYakur6E7PXZzGy3QI2cYrSVNQAsY= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:subject:content-type; s= default; bh=1yBiQ8Xk6qOvBQHGEWds4bjgNNc=; b=taSY60AZ+tJ3nBWM3Qv6 KOyIc/k95CBcb7lNYDF4amLXD9nyIFr28E3GbhOjEoSE55mjhwsiPqXg8qDNY+N2 M+1852n4p+vqQGI+v/+eLX7kISgomPjL4vm1yJalVDIIQsJyCi9PogPVyDBbbA4M udR28r4vWtdhjr4Nw9aeqMI= Received: (qmail 21722 invoked by alias); 26 Nov 2014 23:59:59 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 21711 invoked by uid 89); 26 Nov 2014 23:59:58 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.8 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Wed, 26 Nov 2014 23:59:55 +0000 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id sAQNxsOt007510 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Wed, 26 Nov 2014 18:59:54 -0500 Received: from [10.10.54.196] (vpn-54-196.rdu2.redhat.com [10.10.54.196]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id sAQNxqY1017657 for ; Wed, 26 Nov 2014 18:59:53 -0500 Message-ID: <54766978.2070908@redhat.com> Date: Wed, 26 Nov 2014 18:59:52 -0500 From: Andrew MacLeod User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.2.0 MIME-Version: 1.0 To: gcc-patches Subject: [tree-type] Split decl_attribute into type and decl specific versions. X-IsSubscribed: yes First independent infrastructure patch for the branch. These sort of patches I will commit to the branch without any tree-type specific changes so I can maintain it as a patch to submit in stage 1 independent of the overall larger change. I'll make the tree-type specific changes last. decl_attribute can be applied to either a type or a decl. This separates that function into decl_attributes() and type_attributes() (adding checking asserts for good measure), and changes the calling locations. It was not an enjoyable function to split. ugg. Hope the rest aren't like this :-) Bootstraps, passes regression testing and build all targets. The next part will change the attribute_spec structure to have a separate handler for types and for decls and change all the locations as handlers as need be. Easier to test by keeping these changes apart from each other. checked into tree-type branch as revision 218105 Andrew * 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); }