diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1ac0d6a1ca7..5c380f3a102 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2007-09-12 Richard Sandiford + + * c-tree.h (grokfield): Add a "tree *" argument. + * c-decl.c (grokdeclarator): Take a pointer to the decl's attributes. + Chain nested decl attributes to it. Don't call decl_attributes here. + (groktypename): Pass grokdeclarator a pointer to the attribute list. + (start_decl, grokparm, push_parm_decl, start_function): Likewise. + (grokfield): Take a pointer to the decl's attributes and pass + it to grokdeclarator. + * c-parser.c (c_parser_struct_declaration): Update the calls to + grokfield. Call decl_attributes for anonymous struct and union + fields. + 2007-09-12 Jan Hubicka * c-objc-common.h (LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION): Kill. diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 83fc7b9e161..719c2897397 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -407,7 +407,7 @@ static tree lookup_name_in_scope (tree, struct c_scope *); static tree c_make_fname_decl (tree, int); static tree grokdeclarator (const struct c_declarator *, struct c_declspecs *, - enum decl_context, bool, tree *, + enum decl_context, bool, tree *, tree *, enum deprecated_states); static tree grokparms (struct c_arg_info *, bool); static void layout_array_type (tree); @@ -3141,7 +3141,7 @@ groktypename (struct c_type_name *type_name) type_name->specs->attrs = NULL_TREE; type = grokdeclarator (type_name->declarator, type_name->specs, TYPENAME, - false, NULL, DEPRECATED_NORMAL); + false, NULL, &attrs, DEPRECATED_NORMAL); /* Apply attributes. */ decl_attributes (&type, attrs, 0); @@ -3178,7 +3178,7 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs, deprecated_state = DEPRECATED_SUPPRESS; decl = grokdeclarator (declarator, declspecs, - NORMAL, initialized, NULL, + NORMAL, initialized, NULL, &attributes, deprecated_state); if (!decl) return 0; @@ -3667,10 +3667,11 @@ finish_decl (tree decl, tree init, tree asmspec_tree) tree grokparm (const struct c_parm *parm) { + tree attrs = parm->attrs; tree decl = grokdeclarator (parm->declarator, parm->specs, PARM, false, - NULL, DEPRECATED_NORMAL); + NULL, &attrs, DEPRECATED_NORMAL); - decl_attributes (&decl, parm->attrs, 0); + decl_attributes (&decl, attrs, 0); return decl; } @@ -3681,11 +3682,12 @@ grokparm (const struct c_parm *parm) void push_parm_decl (const struct c_parm *parm) { + tree attrs = parm->attrs; tree decl; decl = grokdeclarator (parm->declarator, parm->specs, PARM, false, NULL, - DEPRECATED_NORMAL); - decl_attributes (&decl, parm->attrs, 0); + &attrs, DEPRECATED_NORMAL); + decl_attributes (&decl, attrs, 0); decl = pushdecl (decl); @@ -3957,6 +3959,9 @@ warn_variable_length_array (const char *name, tree size) INITIALIZED is true if the decl has an initializer. WIDTH is non-NULL for bit-fields, and is a pointer to an INTEGER_CST node representing the width of the bit-field. + DECL_ATTRS points to the list of attributes that should be added to this + decl. Any nested attributes that belong on the decl itself will be + added to this list. DEPRECATED_STATE is a deprecated_states value indicating whether deprecation warnings should be suppressed. @@ -3971,7 +3976,7 @@ static tree grokdeclarator (const struct c_declarator *declarator, struct c_declspecs *declspecs, enum decl_context decl_context, bool initialized, tree *width, - enum deprecated_states deprecated_state) + tree *decl_attrs, enum deprecated_states deprecated_state) { tree type = declspecs->type; bool threadp = declspecs->thread_p; @@ -4615,6 +4620,7 @@ grokdeclarator (const struct c_declarator *declarator, gcc_unreachable (); } } + *decl_attrs = chainon (returned_attrs, *decl_attrs); /* Now TYPE has the actual type, apart from any qualifiers in TYPE_QUALS. */ @@ -4649,7 +4655,6 @@ grokdeclarator (const struct c_declarator *declarator, decl = build_decl (TYPE_DECL, declarator->u.id, type); if (declspecs->explicit_signed_p) C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1; - decl_attributes (&decl, returned_attrs, 0); if (declspecs->inline_p) pedwarn ("typedef %q+D declared %", decl); return decl; @@ -4669,7 +4674,6 @@ grokdeclarator (const struct c_declarator *declarator, pedwarn ("ISO C forbids const or volatile function types"); if (type_quals) type = c_build_qualified_type (type, type_quals); - decl_attributes (&type, returned_attrs, 0); return type; } @@ -4987,8 +4991,6 @@ grokdeclarator (const struct c_declarator *declarator, name of a variable. Thus, if it's known before this, die horribly. */ gcc_assert (!DECL_ASSEMBLER_NAME_SET_P (decl)); - decl_attributes (&decl, returned_attrs, 0); - return decl; } } @@ -5390,6 +5392,7 @@ start_struct (enum tree_code code, tree name) /* Process the specs, declarator and width (NULL if omitted) of a structure component, returning a FIELD_DECL node. WIDTH is non-NULL for bit-fields only, and is an INTEGER_CST node. + DECL_ATTRS is as for grokdeclarator. This is done during the parsing of the struct declaration. The FIELD_DECL nodes are chained together and the lot of them @@ -5397,7 +5400,7 @@ start_struct (enum tree_code code, tree name) tree grokfield (struct c_declarator *declarator, struct c_declspecs *declspecs, - tree width) + tree width, tree *decl_attrs) { tree value; @@ -5450,7 +5453,8 @@ grokfield (struct c_declarator *declarator, struct c_declspecs *declspecs, } value = grokdeclarator (declarator, declspecs, FIELD, false, - width ? &width : NULL, DEPRECATED_NORMAL); + width ? &width : NULL, decl_attrs, + DEPRECATED_NORMAL); finish_decl (value, NULL_TREE, NULL_TREE); DECL_INITIAL (value) = width; @@ -6091,7 +6095,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator, c_break_label = c_cont_label = size_zero_node; decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, true, NULL, - DEPRECATED_NORMAL); + &attributes, DEPRECATED_NORMAL); /* If the declarator is not suitable for a function definition, cause a syntax error. */ diff --git a/gcc/c-parser.c b/gcc/c-parser.c index 4cd9479bada..4bbc39d32d8 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -2030,7 +2030,10 @@ c_parser_struct_declaration (c_parser *parser) /* Support for unnamed structs or unions as members of structs or unions (which is [a] useful and [b] supports MS P-SDK). */ - ret = grokfield (build_id_declarator (NULL_TREE), specs, NULL_TREE); + tree attrs = NULL; + ret = grokfield (build_id_declarator (NULL_TREE), specs, + NULL_TREE, &attrs); + decl_attributes (&ret, attrs, 0); } return ret; } @@ -2070,7 +2073,7 @@ c_parser_struct_declaration (c_parser *parser) } if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) postfix_attrs = c_parser_attributes (parser); - d = grokfield (declarator, specs, width); + d = grokfield (declarator, specs, width, &all_prefix_attrs); decl_attributes (&d, chainon (postfix_attrs, all_prefix_attrs), 0); TREE_CHAIN (d) = decls; diff --git a/gcc/c-tree.h b/gcc/c-tree.h index 57b19f69857..9fd696b925d 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -476,7 +476,8 @@ extern tree finish_enum (tree, tree, tree); extern void finish_function (void); extern tree finish_struct (tree, tree, tree); extern struct c_arg_info *get_parm_info (bool); -extern tree grokfield (struct c_declarator *, struct c_declspecs *, tree); +extern tree grokfield (struct c_declarator *, struct c_declspecs *, + tree, tree *); extern tree groktypename (struct c_type_name *); extern tree grokparm (const struct c_parm *); extern tree implicitly_declare (tree);