aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
authorJoseph Myers <jsm28@cam.ac.uk>2001-09-21 02:27:06 +0100
committerJoseph Myers <jsm28@gcc.gnu.org>2001-09-21 02:27:06 +0100
commit91d231cb917f53b4cd34dec24227863e95fceb6f (patch)
treef30b39e86c1e124ae235fd7661bc83c06577bc32 /gcc/tree.c
parent3007d592bf05a6f1728f023c46207083cd24ca32 (diff)
downloadgcc-91d231cb917f53b4cd34dec24227863e95fceb6f.zip
gcc-91d231cb917f53b4cd34dec24227863e95fceb6f.tar.gz
gcc-91d231cb917f53b4cd34dec24227863e95fceb6f.tar.bz2
Table-driven attributes.
* c-decl.c, config/alpha/alpha.c, config/arc/arc.c, config/arm/arm.c, config/arm/pe.c, config/avr/avr.c, config/avr/avr.h, config/d30v/d30v.h, config/fr30/fr30.h, config/h8300/h8300.c, config/i386/cygwin.h, config/i386/winnt.c, config/m32r/m32r.c, config/mcore/mcore.c, config/sh/sh.c, config/stormy16/stormy16.h, config/v850/v850.c, doc/c-tree.texi, doc/tm.texi, ggc-common.c, integrate.c, print-tree.c, tree.c, tree.h: Rename DECL_MACHINE_ATTRIBUTES to DECL_ATTRIBUTES. * tree.h (struct tree_decl): Change machine_attributes to attributes. * doc/c-tree.texi: Document that all attributes are now attached to decls and types. * c-common.c (add_attribute, attrtab, attrtab_idx, default_valid_lang_attribute, valid_lang_attribute): Remove. (attribute_tables, attributes_initialized, c_common_attribute_table, default_lang_attribute_table): New variables. (handle_packed_attribute, handle_nocommon_attribute, handle_common_attribute, handle_noreturn_attribute, handle_unused_attribute, handle_const_attribute, handle_transparent_union_attribute, handle_constructor_attribute, handle_destructor_attribute, handle_mode_attribute, handle_section_attribute, handle_aligned_attribute, handle_weak_attribute, handle_alias_attribute, handle_no_instrument_function_attribute, handle_no_check_memory_usage_attribute, handle_malloc_attribute, handle_no_limit_stack_attribute, handle_pure_attribute): New functions. (init_attributes, decl_attributes): Rewrite to implement table-driven attributes. * c-common.h (enum attribute_flags): Move to tree.h. * c-format.c (decl_handle_format_attribute, decl_handle_format_arg_attribute): Rename to handle_format_attribute and handle_format_arg_attribute. Update for table-driven attributes. * c-common.h (decl_handle_format_attribute, decl_handle_format_arg_attribute): Remove prototypes. (handle_format_attribute, handle_format_arg_attribute): Add prototypes. * c-decl.c (grokdeclarator): Handle attributes nested inside declarators. * c-parse.in (setattrs, maybe_setattrs): Remove. (maybe_type_quals_setattrs): Rename to maybe_type_quals_attrs. Update to handle nested attributes properly. (maybe_resetattrs, after_type_declarator, parm_declarator_nostarttypename, notype_declarator, absdcl1_noea, absdcl1_ea, direct_absdcl1): Update to handle nested attributes properly. (make_pointer_declarator): Update to handle nested attributes properly. * doc/extend.texi: Update documentation of limits of attributes syntax. Warn about problems with attribute semantics in C++. * target.h (struct target): Remove valid_decl_attribute and valid_type_attribute. Add attribute_table and function_attribute_inlinable_p. * target-def.h (TARGET_VALID_DECL_ATTRIBUTE, TARGET_VALID_TYPE_ATTRIBUTE): Remove. (TARGET_ATTRIBUTE_TABLE, TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P): Add. (TARGET_INITIALIZER): Update. * integrate.c (FUNCTION_ATTRIBUTE_INLINABLE_P): Remove default definition. (function_attribute_inlinable_p): New function. Check for the presence of any machine attributes before using targetm.function_attribute_inlinable_p. (function_cannot_inline_p): Update. * Makefile.in (integrate.o): Update dependencies. * doc/tm.texi: Update documentation of target attributes and example definition of TARGET_VALID_TYPE_ATTRIBUTE. * tree.c (default_valid_attribute_p, valid_machine_attribute): Remove. (default_target_attribute_table, default_function_attribute_inlinable_p): New. (lookup_attribute): Update comment to clarify handling of multiple attributes with the same name. (merge_attributes, attribute_list_contained): Allow multiple attributes with the same name but different arguments to appear in the same attribute list. * tree.h (default_valid_attribute_p): Remove prototype. (struct attribute_spec): New. (default_target_attribute_table): Declare. (enum attribute_flags): Move from c-common.h. Add ATTR_FLAG_TYPE_IN_PLACE. (default_function_attribute_inlinable_p): Declare. * config/alpha/alpha.c (vms_valid_decl_attribute_p): Remove. (TARGET_VALID_DECL_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (vms_attribute_table): New. * config/arc/arc.c (arc_valid_decl_attribute): Remove. (TARGET_VALID_DECL_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (arc_attribute_table, arc_handle_interrupt_attribute): New. * config/arm/arm.c (arm_valid_type_attribute_p, arm_valid_decl_attribute_p, arm_pe_valid_decl_attribute_p): Remove. (TARGET_VALID_TYPE_ATTRIBUTE, TARGET_VALID_DECL_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (arm_attribute_table, arm_handle_fndecl_attribute, arm_handle_isr_attribute): New. * config/avr/avr.c (avr_valid_type_attribute, avr_valid_decl_attribute): Remove. (TARGET_VALID_DECL_ATTRIBUTE, TARGET_VALID_TYPE_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (avr_attribute_table, avr_handle_progmem_attribute, avr_handle_fndecl_attribute): New. * config/c4x/c4x.c (c4x_valid_type_attribute_p): Remove. (TARGET_VALID_TYPE_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (c4x_attribute_table, c4x_handle_fntype_attribute): New. * config/h8300/h8300.c (h8300_valid_decl_attribute): Remove. (TARGET_VALID_DECL_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (h8300_attribute_table, h8300_handle_fndecl_attribute, h8300_handle_eightbit_data_attribute, h8300_handle_tiny_data_attribute): New. * config/i386/i386-protos.h (ix86_valid_type_attribute_p, i386_pe_valid_decl_attribute_p, i386_pe_valid_type_attribute_p): Remove prototypes. (ix86_handle_dll_attribute, ix86_handle_shared_attribute): New declarations. * config/i386/i386.c (ix86_valid_type_attribute_p: Remove. (TARGET_VALID_TYPE_ATTRIBUTE, TARGET_VALID_DECL_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (ix86_attribute_table, ix86_handle_cdecl_attribute, ix86_handle_regparm_attribute): New. * config/i386/winnt.c (i386_pe_valid_decl_attribute_p, i386_pe_valid_type_attribute_p): Remove. (ix86_handle_dll_attribute, ix86_handle_shared_attribute): New. * config/ia64/ia64.c (ia64_valid_type_attribute): Remove. (TARGET_VALID_TYPE_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (ia64_attribute_table): New. * config/m32r/m32r.c (m32r_valid_decl_attribute, interrupt_ident1, interrupt_ident2, model_ident1, model_ident2): Remove. (TARGET_VALID_DECL_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (init_idents): Update. (m32r_attribute_table, m32r_handle_model_attribute): New. * config/m68hc11/m68hc11.c (m68hc11_valid_type_attribute_p): Remove. (TARGET_VALID_TYPE_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (m68hc11_attribute_table, m68hc11_handle_fntype_attribute): New. * config/mcore/mcore.c (mcore_valid_decl_attribute): Remove. (TARGET_VALID_DECL_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (mcore_attribute_table, mcore_handle_naked_attribute): New. * config/ns32k/ns32k.c (ns32k_valid_type_attribute_p): Remove. (TARGET_VALID_TYPE_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (ns32k_attribute_table, ns32k_handle_fntype_attribute): New. * config/rs6000/rs6000.c (rs6000_valid_type_attribute_p): Remove. (TARGET_VALID_TYPE_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (rs6000_attribute_table, rs6000_handle_longcall_attribute): New. * config/sh/sh.c (sh_valid_decl_attribute): Remove. (TARGET_VALID_DECL_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (sh_attribute_table, sh_handle_interrupt_handler_attribute, sh_handle_sp_switch_attribute, sh_handle_trap_exit_attribute): New. * config/stormy16/stormy16.c (stormy16_valid_type_attribute): Remove. (TARGET_VALID_TYPE_ATTRIBUTE): Don't define (TARGET_ATTRIBUTE_TABLE): Define. (stormy16_attribute_table, stormy16_handle_interrupt_attribute): New. * config/v850/v850.c (v850_valid_decl_attribute): Remove. (TARGET_VALID_DECL_ATTRIBUTE): Don't define. (TARGET_ATTRIBUTE_TABLE): Define. (v850_attribute_table, v850_handle_interrupt_attribute, v850_handle_data_area_attribute): New. * config/v850/v850-c.c (mark_current_function_as_interrupt): Return void. Call decl_attributes instead of valid_machine_attribute. cp: Table-driven attributes. * decl.c: Rename DECL_MACHINE_ATTRIBUTES to DECL_ATTRIBUTES. * decl2.c (cplus_decl_attributes): Only take one attributes parameter. * cp-tree.c (cplus_decl_attributes): Update prototype. * class.c (finish_struct), decl.c (start_decl, start_function), decl2.c (grokfield), friend.c (do_friend), parse.y (parse_bitfield): Update calls to cplus_decl_attributes. * decl.c (grokdeclarator): Take a pointer to a single ordinary attribute list. * decl.h (grokdeclarator): Update prototype. * decl2.c (grokfield): Take a single ordinary attribute list. * friend.c (do_friend): Likewise. * decl.c (shadow_tag, groktypename, start_decl, start_handler_parms, grokdeclarator, grokparms, start_function, start_method), decl2.c (grokfield, grokbitfield, grokoptypename), parse.y (parse_field, parse_bitfield, component_decl_1), pt.c (process_template_parm, do_decl_instantiation): Pass single ordinary attribute lists around. * decl.c (grokdeclarator): Correct handling of nested attributes. Revert the patch 1998-10-18 Jason Merrill <jason@yorick.cygnus.com> * decl.c (grokdeclarator): Embedded attrs bind to the right, not the left. . * cp-tree.h (cp_valid_lang_attribute): Remove declaration (cp_attribute_table): Declare. * decl.c (valid_lang_attribute): Don't define. (lang_attribute_table): Define. (init_decl_processing): Initialize lang_attribute_table instead of valid_lang_attribute. * tree.c (cp_valid_lang_attribute): Remove. (handle_java_interface_attribute, handle_com_interface_attribute, handle_init_priority_attribute): New functions. (cp_attribute_table): New array. * decl2.c (import_export_class): Don't use targetm.valid_type_attribute. testsuite: Table-driven attributes. * g++.dg/ext/attrib1.C: New test. From-SVN: r45718
Diffstat (limited to 'gcc/tree.c')
-rw-r--r--gcc/tree.c186
1 files changed, 48 insertions, 138 deletions
diff --git a/gcc/tree.c b/gcc/tree.c
index 731791c..1741f6a 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -2605,14 +2605,14 @@ build_expr_wfl (node, file, line, col)
return wfl;
}
-/* Return a declaration like DDECL except that its DECL_MACHINE_ATTRIBUTE
+/* Return a declaration like DDECL except that its DECL_ATTRIBUTES
is ATTRIBUTE. */
tree
build_decl_attribute_variant (ddecl, attribute)
tree ddecl, attribute;
{
- DECL_MACHINE_ATTRIBUTES (ddecl) = attribute;
+ DECL_ATTRIBUTES (ddecl) = attribute;
return ddecl;
}
@@ -2670,19 +2670,6 @@ build_type_attribute_variant (ttype, attribute)
return ttype;
}
-/* Default value of targetm.valid_decl_attribute_p and
- targetm.valid_type_attribute_p that always returns false. */
-
-int
-default_valid_attribute_p (attr_name, attr_args, decl, type)
- tree attr_name ATTRIBUTE_UNUSED;
- tree attr_args ATTRIBUTE_UNUSED;
- tree decl ATTRIBUTE_UNUSED;
- tree type ATTRIBUTE_UNUSED;
-{
- return 0;
-}
-
/* Default value of targetm.comp_type_attributes that always returns 1. */
int
@@ -2710,116 +2697,20 @@ default_insert_attributes (decl, attr_ptr)
{
}
-/* Return 1 if ATTR_NAME and ATTR_ARGS is valid for either declaration
- DECL or type TYPE and 0 otherwise. Validity is determined the
- target functions valid_decl_attribute and valid_machine_attribute. */
-
-int
-valid_machine_attribute (attr_name, attr_args, decl, type)
- tree attr_name;
- tree attr_args;
- tree decl;
- tree type;
+/* Default value of targetm.attribute_table that is empty. */
+const struct attribute_spec default_target_attribute_table[] =
{
- tree type_attrs;
-
- if (TREE_CODE (attr_name) != IDENTIFIER_NODE)
- abort ();
-
- if (decl)
- {
- tree decl_attrs = DECL_MACHINE_ATTRIBUTES (decl);
-
- if ((*targetm.valid_decl_attribute) (decl, decl_attrs, attr_name,
- attr_args))
- {
- tree attr = lookup_attribute (IDENTIFIER_POINTER (attr_name),
- decl_attrs);
-
- if (attr != NULL_TREE)
- {
- /* Override existing arguments. Declarations are unique
- so we can modify this in place. */
- TREE_VALUE (attr) = attr_args;
- }
- else
- {
- decl_attrs = tree_cons (attr_name, attr_args, decl_attrs);
- decl = build_decl_attribute_variant (decl, decl_attrs);
- }
-
- /* Don't apply the attribute to both the decl and the type. */
- return 1;
- }
- }
-
- type_attrs = TYPE_ATTRIBUTES (type);
- if ((*targetm.valid_type_attribute) (type, type_attrs, attr_name,
- attr_args))
- {
- tree attr = lookup_attribute (IDENTIFIER_POINTER (attr_name),
- type_attrs);
-
- if (attr != NULL_TREE)
- {
- /* Override existing arguments. ??? This currently
- works since attribute arguments are not included in
- `attribute_hash_list'. Something more complicated
- may be needed in the future. */
- TREE_VALUE (attr) = attr_args;
- }
- else
- {
- /* If this is part of a declaration, create a type variant,
- otherwise, this is part of a type definition, so add it
- to the base type. */
- type_attrs = tree_cons (attr_name, attr_args, type_attrs);
- if (decl != 0)
- type = build_type_attribute_variant (type, type_attrs);
- else
- TYPE_ATTRIBUTES (type) = type_attrs;
- }
-
- if (decl)
- TREE_TYPE (decl) = type;
-
- return 1;
- }
- /* Handle putting a type attribute on pointer-to-function-type
- by putting the attribute on the function type. */
- else if (POINTER_TYPE_P (type)
- && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
- && (*targetm.valid_type_attribute) (TREE_TYPE (type), type_attrs,
- attr_name, attr_args))
- {
- tree inner_type = TREE_TYPE (type);
- tree inner_attrs = TYPE_ATTRIBUTES (inner_type);
- tree attr = lookup_attribute (IDENTIFIER_POINTER (attr_name),
- type_attrs);
-
- if (attr != NULL_TREE)
- TREE_VALUE (attr) = attr_args;
- else
- {
- inner_attrs = tree_cons (attr_name, attr_args, inner_attrs);
- inner_type = build_type_attribute_variant (inner_type,
- inner_attrs);
- }
-
- if (decl)
- TREE_TYPE (decl) = build_pointer_type (inner_type);
- else
- {
- /* Clear TYPE_POINTER_TO for the old inner type, since
- `type' won't be pointing to it anymore. */
- TYPE_POINTER_TO (TREE_TYPE (type)) = NULL_TREE;
- TREE_TYPE (type) = inner_type;
- }
-
- return 1;
- }
+ { NULL, 0, 0, false, false, false, NULL }
+};
- return 0;
+/* Default value of targetm.function_attribute_inlinable_p that always
+ returns false. */
+bool
+default_function_attribute_inlinable_p (fndecl)
+ tree fndecl ATTRIBUTE_UNUSED;
+{
+ /* By default, functions with machine attributes cannot be inlined. */
+ return false;
}
/* Return non-zero if IDENT is a valid name for attribute ATTR,
@@ -2873,7 +2764,9 @@ is_attribute_p (attr, ident)
/* Given an attribute name and a list of attributes, return a pointer to the
attribute's list element if the attribute is part of the list, or NULL_TREE
- if not found. */
+ if not found. If the attribute appears more than once, this only
+ returns the first occurance; the TREE_CHAIN of the return value should
+ be passed back in if further occurances are wanted. */
tree
lookup_attribute (attr_name, list)
@@ -2915,19 +2808,29 @@ merge_attributes (a1, a2)
else
{
/* Pick the longest list, and hang on the other list. */
- /* ??? For the moment we punt on the issue of attrs with args. */
if (list_length (a1) < list_length (a2))
attributes = a2, a2 = a1;
for (; a2 != 0; a2 = TREE_CHAIN (a2))
- if (lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (a2)),
- attributes) == NULL_TREE)
- {
- a1 = copy_node (a2);
- TREE_CHAIN (a1) = attributes;
- attributes = a1;
- }
+ {
+ tree a;
+ for (a = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (a2)),
+ attributes);
+ a != NULL_TREE;
+ a = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (a2)),
+ TREE_CHAIN (a)))
+ {
+ if (simple_cst_equal (TREE_VALUE (a), TREE_VALUE (a2)) == 1)
+ break;
+ }
+ if (a == NULL_TREE)
+ {
+ a1 = copy_node (a2);
+ TREE_CHAIN (a1) = attributes;
+ attributes = a1;
+ }
+ }
}
}
return attributes;
@@ -2951,8 +2854,8 @@ tree
merge_decl_attributes (olddecl, newdecl)
tree olddecl, newdecl;
{
- return merge_attributes (DECL_MACHINE_ATTRIBUTES (olddecl),
- DECL_MACHINE_ATTRIBUTES (newdecl));
+ return merge_attributes (DECL_ATTRIBUTES (olddecl),
+ DECL_ATTRIBUTES (newdecl));
}
#ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
@@ -2974,8 +2877,8 @@ merge_dllimport_decl_attributes (old, new)
tree a;
int delete_dllimport_p;
- old = DECL_MACHINE_ATTRIBUTES (old);
- new = DECL_MACHINE_ATTRIBUTES (new);
+ old = DECL_ATTRIBUTES (old);
+ new = DECL_ATTRIBUTES (new);
/* What we need to do here is remove from `old' dllimport if it doesn't
appear in `new'. dllimport behaves like extern: if a declaration is
@@ -3345,8 +3248,15 @@ attribute_list_contained (l1, l2)
for (; t2 != 0; t2 = TREE_CHAIN (t2))
{
- tree attr
- = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (t2)), l1);
+ tree attr;
+ for (attr = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (t2)), l1);
+ attr != NULL_TREE;
+ attr = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (t2)),
+ TREE_CHAIN (attr)))
+ {
+ if (simple_cst_equal (TREE_VALUE (t2), TREE_VALUE (attr)) == 1)
+ break;
+ }
if (attr == 0)
return 0;