+2001-07-13 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * c-common.c (decl_attributes): Take a pointer to the node to
+ which attributes are to be attached, and a flags argument.
+ * c-common.h (enum attribute_flags): New.
+ (decl_attributes): Update prototype.
+ * c-decl.c (start_decl, push_parm_decl, finish_struct,
+ finish_enum, start_function): Update calls to decl_attributes.
+ * c-parse.in (component_declarator, component_notype_declarator,
+ label): Update calls to decl_attributes.
+
Fri Jul 13 23:04:00 2001 Denis Chertykov <denisc@overta.ru>
* config/avr/avr.md (strlenhi): PARALLEL keyword removed.
int (*valid_lang_attribute) PARAMS ((tree, tree, tree, tree))
= default_valid_lang_attribute;
-/* Process the attributes listed in ATTRIBUTES and install them in NODE,
- which is either a DECL (including a TYPE_DECL) or a TYPE. */
+/* 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.
+ FLAGS gives further information, in the form of a bitwise OR of flags
+ in enum attribute_flags from c-common.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). */
-void
-decl_attributes (node, attributes)
- tree node, attributes;
+tree
+decl_attributes (node, attributes, flags)
+ tree *node, attributes;
+ int flags ATTRIBUTE_UNUSED;
{
tree decl = 0, type = 0;
int is_type = 0;
if (attrtab_idx == 0)
init_attributes ();
- if (DECL_P (node))
+ if (DECL_P (*node))
{
- decl = node;
+ decl = *node;
type = TREE_TYPE (decl);
- is_type = TREE_CODE (node) == TYPE_DECL;
+ is_type = TREE_CODE (*node) == TYPE_DECL;
}
- else if (TYPE_P (node))
- type = node, is_type = 1;
+ else if (TYPE_P (*node))
+ type = *node, is_type = 1;
- (*targetm.insert_attributes) (node, &attributes);
+ (*targetm.insert_attributes) (*node, &attributes);
for (a = attributes; a; a = TREE_CHAIN (a))
{
else if (DECL_SECTION_NAME (decl) != NULL_TREE
&& strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)),
TREE_STRING_POINTER (TREE_VALUE (args))) != 0)
- error_with_decl (node,
+ error_with_decl (*node,
"section of `%s' conflicts with previous declaration");
else
DECL_SECTION_NAME (decl) = TREE_VALUE (args);
}
else
- error_with_decl (node,
+ error_with_decl (*node,
"section attribute not allowed for `%s'");
#else
- error_with_decl (node,
+ error_with_decl (*node,
"section attributes are not supported for this target");
#endif
break;
break;
}
}
+ return NULL_TREE;
}
/* Split SPECS_ATTRS, a list of declspecs and prefix attributes, into two
extern const char *fname_as_string PARAMS ((int));
extern tree fname_decl PARAMS ((unsigned, tree));
extern const char *fname_string PARAMS ((unsigned));
-extern void decl_attributes PARAMS ((tree, tree));
+
+/* Flags that may be passed in the third argument of decl_attributes. */
+enum attribute_flags
+{
+ /* The type passed in is the type of a DECL, and any attributes that
+ should be passed in again to be applied to the DECL rather than the
+ type should be returned. */
+ ATTR_FLAG_DECL_NEXT = 1,
+ /* The type passed in is a function return type, and any attributes that
+ should be passed in again to be applied to the function type rather
+ than the return type should be returned. */
+ ATTR_FLAG_FUNCTION_NEXT = 2,
+ /* The type passed in is an array element type, and any attributes that
+ should be passed in again to be applied to the array type rather
+ than the element type should be returned. */
+ ATTR_FLAG_ARRAY_NEXT = 4
+};
+
+extern tree decl_attributes PARAMS ((tree *, tree, int));
extern void init_function_format_info PARAMS ((void));
extern void check_function_format PARAMS ((int *, tree, tree, tree));
extern void set_Wformat PARAMS ((int));
int initialized;
tree attributes;
{
- register tree decl = grokdeclarator (declarator, declspecs,
- NORMAL, initialized);
+ tree decl = grokdeclarator (declarator, declspecs,
+ NORMAL, initialized);
register tree tem;
if (warn_main > 0 && TREE_CODE (decl) != FUNCTION_DECL
DECL_COMMON (decl) = 1;
/* Set attributes here so if duplicate decl, will have proper attributes. */
- decl_attributes (decl, attributes);
+ decl_attributes (&decl, attributes, 0);
/* Add this decl to the current binding level.
TEM may equal DECL or it may be a previous decl of the same name. */
decl = grokdeclarator (TREE_VALUE (TREE_PURPOSE (parm)),
TREE_PURPOSE (TREE_PURPOSE (parm)), PARM, 0);
- decl_attributes (decl, TREE_VALUE (parm));
+ decl_attributes (&decl, TREE_VALUE (parm), 0);
#if 0
if (DECL_NAME (decl))
TYPE_SIZE (t) = 0;
- decl_attributes (t, attributes);
+ decl_attributes (&t, attributes, 0);
/* Nameless union parm types are useful as GCC extension. */
if (! (TREE_CODE (t) == UNION_TYPE && TYPE_NAME (t) == 0) && !pedantic)
if (in_parm_level_p ())
warning ("enum defined inside parms");
- decl_attributes (enumtype, attributes);
+ decl_attributes (&enumtype, attributes, 0);
/* Calculate the maximum value of any enumerator in this type. */
return 0;
}
- decl_attributes (decl1, attributes);
+ decl_attributes (&decl1, attributes, 0);
announce_function (decl1);
component_declarator:
save_filename save_lineno declarator maybe_attribute
{ $$ = grokfield ($1, $2, $3, current_declspecs, NULL_TREE);
- decl_attributes ($$, chainon ($4, prefix_attributes)); }
+ decl_attributes (&$$, chainon ($4, prefix_attributes), 0); }
| save_filename save_lineno
declarator ':' expr_no_commas maybe_attribute
{ $$ = grokfield ($1, $2, $3, current_declspecs, $5);
- decl_attributes ($$, chainon ($6, prefix_attributes)); }
+ decl_attributes (&$$, chainon ($6, prefix_attributes), 0); }
| save_filename save_lineno ':' expr_no_commas maybe_attribute
{ $$ = grokfield ($1, $2, NULL_TREE, current_declspecs, $4);
- decl_attributes ($$, chainon ($5, prefix_attributes)); }
+ decl_attributes (&$$, chainon ($5, prefix_attributes), 0); }
;
component_notype_declarator:
save_filename save_lineno notype_declarator maybe_attribute
{ $$ = grokfield ($1, $2, $3, current_declspecs, NULL_TREE);
- decl_attributes ($$, chainon ($4, prefix_attributes)); }
+ decl_attributes (&$$, chainon ($4, prefix_attributes), 0); }
| save_filename save_lineno
notype_declarator ':' expr_no_commas maybe_attribute
{ $$ = grokfield ($1, $2, $3, current_declspecs, $5);
- decl_attributes ($$, chainon ($6, prefix_attributes)); }
+ decl_attributes (&$$, chainon ($6, prefix_attributes), 0); }
| save_filename save_lineno ':' expr_no_commas maybe_attribute
{ $$ = grokfield ($1, $2, NULL_TREE, current_declspecs, $4);
- decl_attributes ($$, chainon ($5, prefix_attributes)); }
+ decl_attributes (&$$, chainon ($5, prefix_attributes), 0); }
;
/* We chain the enumerators in reverse order.
stmt_count++;
if (label)
{
- decl_attributes (label, $5);
+ decl_attributes (&label, $5, 0);
$$ = add_stmt (build_stmt (LABEL_STMT, label));
}
else
+2001-07-13 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl2.c (cplus_decl_attributes): Take a pointer to the node to
+ which attributes are to be attached, and a flags argument. Update
+ call to decl_attributes.
+ (grokfield): Update call to decl_attributes.
+ * class.c (finish_struct): Update call to cplus_decl_attributes.
+ * cp-tree.h (cplus_decl_attributes): Update prototype.
+ * decl.c (start_decl, grokdeclarator, start_function): Update
+ calls to decl_attributes and cplus_decl_attributes.
+ * friend.c (do_friend): Update call to cplus_decl_attributes.
+ * parse.y (parse_bitfield): Update call to cplus_decl_attributes.
+
2001-07-12 Mark Mitchell <mark@codesourcery.com>
* decl.c (make_rtl_for_nonlocal_decl): Set DECL_C_HARD_REGISTER
as necessary. */
unreverse_member_declarations (t);
- cplus_decl_attributes (t, attributes, NULL_TREE);
+ cplus_decl_attributes (&t, attributes, NULL_TREE, 0);
/* Nadger the current location so that diagnostics point to the start of
the struct, not the end. */
extern tree groktypefield PARAMS ((tree, tree));
extern tree grokoptypename PARAMS ((tree, tree));
extern int copy_assignment_arg_p PARAMS ((tree, int));
-extern void cplus_decl_attributes PARAMS ((tree, tree, tree));
+extern void cplus_decl_attributes PARAMS ((tree *, tree, tree, int));
extern tree constructor_name_full PARAMS ((tree));
extern tree constructor_name PARAMS ((tree));
extern void defer_fn PARAMS ((tree));
int initialized;
tree attributes, prefix_attributes;
{
- register tree decl;
+ tree decl;
register tree type, tem;
tree context;
extern int have_extern_spec;
}
/* Set attributes here so if duplicate decl, will have proper attributes. */
- cplus_decl_attributes (decl, attributes, prefix_attributes);
+ cplus_decl_attributes (&decl, attributes, prefix_attributes, 0);
if (context && COMPLETE_TYPE_P (complete_type (context)))
{
ignore_attrs = 0;
else if (inner_attrs)
{
- decl_attributes (type, inner_attrs);
+ decl_attributes (&type, inner_attrs, 0);
inner_attrs = NULL_TREE;
}
if (inner_attrs)
{
if (! ignore_attrs)
- decl_attributes (type, inner_attrs);
+ decl_attributes (&type, inner_attrs, 0);
else if (attrlist)
TREE_VALUE (attrlist) = chainon (inner_attrs, TREE_VALUE (attrlist));
else
pushlevel (0);
current_binding_level->parm_flag = 1;
- cplus_decl_attributes (decl1, NULL_TREE, attrs);
+ cplus_decl_attributes (&decl1, NULL_TREE, attrs, 0);
/* Promote the value to int before returning it. */
if (c_promoting_integer_type_p (restype))
grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
tree declarator, declspecs, init, asmspec_tree, attrlist;
{
- register tree value;
+ tree value;
const char *asmspec = 0;
int flags = LOOKUP_ONLYCONVERTING;
value = push_template_decl (value);
if (attrlist)
- cplus_decl_attributes (value, TREE_PURPOSE (attrlist),
- TREE_VALUE (attrlist));
+ cplus_decl_attributes (&value, TREE_PURPOSE (attrlist),
+ TREE_VALUE (attrlist), 0);
if (TREE_CODE (value) == VAR_DECL)
{
}
\f
void
-cplus_decl_attributes (decl, attributes, prefix_attributes)
- tree decl, attributes, prefix_attributes;
+cplus_decl_attributes (decl, attributes, prefix_attributes, flags)
+ tree *decl, attributes, prefix_attributes;
+ int flags;
{
- if (decl == NULL_TREE || decl == void_type_node)
+ if (*decl == NULL_TREE || *decl == void_type_node)
return;
- if (TREE_CODE (decl) == TEMPLATE_DECL)
- decl = DECL_TEMPLATE_RESULT (decl);
+ if (TREE_CODE (*decl) == TEMPLATE_DECL)
+ decl = &DECL_TEMPLATE_RESULT (*decl);
- decl_attributes (decl, chainon (attributes, prefix_attributes));
+ decl_attributes (decl, chainon (attributes, prefix_attributes), flags);
- if (TREE_CODE (decl) == TYPE_DECL)
- SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (decl), TREE_TYPE (decl));
+ if (TREE_CODE (*decl) == TYPE_DECL)
+ SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (*decl), TREE_TYPE (*decl));
}
\f
/* CONSTRUCTOR_NAME:
}
/* Set attributes here so if duplicate decl, will have proper attributes. */
- cplus_decl_attributes (decl, attributes, prefix_attributes);
+ cplus_decl_attributes (&decl, attributes, prefix_attributes, 0);
return decl;
}
tree declarator, attributes, width;
{
tree d = grokbitfield (declarator, current_declspecs, width);
- cplus_decl_attributes (d, attributes, prefix_attributes);
+ cplus_decl_attributes (&d, attributes, prefix_attributes, 0);
decl_type_access_control (d);
return d;
}