diff options
author | Joseph Myers <jsm28@cam.ac.uk> | 2001-09-21 02:27:06 +0100 |
---|---|---|
committer | Joseph Myers <jsm28@gcc.gnu.org> | 2001-09-21 02:27:06 +0100 |
commit | 91d231cb917f53b4cd34dec24227863e95fceb6f (patch) | |
tree | f30b39e86c1e124ae235fd7661bc83c06577bc32 /gcc/cp | |
parent | 3007d592bf05a6f1728f023c46207083cd24ca32 (diff) | |
download | gcc-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/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 40 | ||||
-rw-r--r-- | gcc/cp/class.c | 2 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 4 | ||||
-rw-r--r-- | gcc/cp/decl.c | 108 | ||||
-rw-r--r-- | gcc/cp/decl.h | 2 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 27 | ||||
-rw-r--r-- | gcc/cp/friend.c | 14 | ||||
-rw-r--r-- | gcc/cp/parse.y | 15 | ||||
-rw-r--r-- | gcc/cp/pt.c | 4 | ||||
-rw-r--r-- | gcc/cp/tree.c | 219 |
10 files changed, 241 insertions, 194 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8d0498f..345cef4 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,43 @@ +2001-09-21 Joseph S. Myers <jsm28@cam.ac.uk> + + 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. + 2001-09-15 Gabriel Dos Reis <gdr@merlin.codesourcery.com> * Make-lang.in (cp/error.o): Depend on real.h diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 1526a05..0c106c3 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -5293,7 +5293,7 @@ finish_struct (t, attributes) as necessary. */ unreverse_member_declarations (t); - cplus_decl_attributes (&t, attributes, NULL_TREE, 0); + cplus_decl_attributes (&t, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE); /* Nadger the current location so that diagnostics point to the start of the struct, not the end. */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 04837da..2662356 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3734,7 +3734,7 @@ extern tree grokbitfield PARAMS ((tree, tree, tree)); 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, int)); +extern void cplus_decl_attributes PARAMS ((tree *, tree, int)); extern tree constructor_name_full PARAMS ((tree)); extern tree constructor_name PARAMS ((tree)); extern void defer_fn PARAMS ((tree)); @@ -4208,7 +4208,7 @@ extern tree walk_tree_without_duplicates PARAMS ((tree *, walk_tree_fn, void *)); extern tree copy_tree_r PARAMS ((tree *, int *, void *)); -extern int cp_valid_lang_attribute PARAMS ((tree, tree, tree, tree)); +extern const struct attribute_spec cp_attribute_table[]; extern tree make_ptrmem_cst PARAMS ((tree, tree)); extern tree cp_build_qualified_type_real PARAMS ((tree, int, int)); extern void remap_save_expr PARAMS ((tree *, splay_tree, tree, int *)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 9244272..60938a7 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -45,7 +45,7 @@ Boston, MA 02111-1307, USA. */ #include "tm_p.h" #include "target.h" -extern int (*valid_lang_attribute) PARAMS ((tree, tree, tree, tree)); +extern const struct attribute_spec *lang_attribute_table; #ifndef BOOL_TYPE_SIZE /* `bool' has size and alignment `1', on all platforms. */ @@ -3438,7 +3438,7 @@ duplicate_decls (newdecl, olddecl) /* Copy all the DECL_... slots specified in the new decl except for any that we copy here from the old type. */ - DECL_MACHINE_ATTRIBUTES (newdecl) + DECL_ATTRIBUTES (newdecl) = (*targetm.merge_decl_attributes) (olddecl, newdecl); if (TREE_CODE (newdecl) == TEMPLATE_DECL) @@ -3746,7 +3746,7 @@ duplicate_decls (newdecl, olddecl) /* NEWDECL contains the merged attribute lists. Update OLDDECL to be the same. */ - DECL_MACHINE_ATTRIBUTES (olddecl) = DECL_MACHINE_ATTRIBUTES (newdecl); + DECL_ATTRIBUTES (olddecl) = DECL_ATTRIBUTES (newdecl); return 1; } @@ -6493,7 +6493,7 @@ init_decl_processing () /* Show we use EH for cleanups. */ using_eh_for_cleanups (); - valid_lang_attribute = cp_valid_lang_attribute; + lang_attribute_table = cp_attribute_table; /* Maintain consistency. Perhaps we should just complain if they say -fwritable-strings? */ @@ -6986,7 +6986,7 @@ shadow_tag (declspecs) if (TYPE_FIELDS (t)) { tree decl = grokdeclarator (NULL_TREE, declspecs, NORMAL, 0, - NULL_TREE); + NULL); finish_anon_union (decl); } } @@ -7002,7 +7002,7 @@ groktypename (typename) return typename; return grokdeclarator (TREE_VALUE (typename), TREE_PURPOSE (typename), - TYPENAME, 0, NULL_TREE); + TYPENAME, 0, NULL); } /* Decode a declarator in an ordinary declaration or data definition. @@ -7031,7 +7031,6 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes) tree context; extern int have_extern_spec; extern int used_extern_spec; - tree attrlist; #if 0 /* See code below that used this. */ @@ -7046,13 +7045,10 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes) used_extern_spec = 1; } - if (attributes || prefix_attributes) - attrlist = build_tree_list (attributes, prefix_attributes); - else - attrlist = NULL_TREE; + attributes = chainon (attributes, prefix_attributes); decl = grokdeclarator (declarator, declspecs, NORMAL, initialized, - attrlist); + &attributes); if (decl == NULL_TREE || TREE_CODE (decl) == VOID_TYPE) return NULL_TREE; @@ -7119,7 +7115,7 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes) } /* Set attributes here so if duplicate decl, will have proper attributes. */ - cplus_decl_attributes (&decl, attributes, prefix_attributes, 0); + cplus_decl_attributes (&decl, attributes, 0); if (context && COMPLETE_TYPE_P (complete_type (context))) { @@ -8482,7 +8478,7 @@ start_handler_parms (declspecs, declarator) if (declspecs) { decl = grokdeclarator (declarator, declspecs, CATCHPARM, - 1, NULL_TREE); + 1, NULL); if (decl == NULL_TREE) error ("invalid catch parameter"); } @@ -9425,8 +9421,9 @@ check_special_function_return_type (sfk, type, optype) BITFIELD for a field with specified width. INITIALIZED is 1 if the decl has an initializer. - ATTRLIST is a TREE_LIST node with prefix attributes in TREE_VALUE and - normal attributes in TREE_PURPOSE, or NULL_TREE. + ATTRLIST is a pointer to the list of attributes, which may be NULL + if there are none; *ATTRLIST may be modified if attributes from inside + the declarator should be applied to the declaration. In the TYPENAME case, DECLARATOR is really an abstract declarator. It may also be so in the PARM case, for a prototype where the @@ -9464,7 +9461,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) tree declarator; enum decl_context decl_context; int initialized; - tree attrlist; + tree *attrlist; { RID_BIT_TYPE specbits; int nclasses = 0; @@ -9487,7 +9484,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) int bitfield = 0; #if 0 /* See the code below that used this. */ - tree decl_machine_attr = NULL_TREE; + tree decl_attr = NULL_TREE; #endif /* Set this to error_mark_node for FIELD_DECLs we could not handle properly. All FIELD_DECLs we build here have `init' put into their DECL_INITIAL. */ @@ -9506,8 +9503,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) tree raises = NULL_TREE; int template_count = 0; tree in_namespace = NULL_TREE; - tree inner_attrs; - int ignore_attrs; + tree returned_attrs = NULL_TREE; RIDBIT_RESET_ALL (specbits); if (decl_context == FUNCDEF) @@ -9598,24 +9594,22 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) cp_finish_decl so we can get the variable initialized... */ - tree attributes, prefix_attributes; + tree attributes; *next = TREE_OPERAND (decl, 0); init = CALL_DECLARATOR_PARMS (decl); if (attrlist) { - attributes = TREE_PURPOSE (attrlist); - prefix_attributes = TREE_VALUE (attrlist); + attributes = *attrlist; } else { attributes = NULL_TREE; - prefix_attributes = NULL_TREE; } decl = start_decl (declarator, declspecs, 1, - attributes, prefix_attributes); + attributes, NULL_TREE); decl_type_access_control (decl); if (decl) { @@ -9953,7 +9947,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) type = TREE_TYPE (t); #if 0 /* See the code below that used this. */ - decl_machine_attr = DECL_MACHINE_ATTRIBUTES (id); + decl_attr = DECL_ATTRIBUTES (id); #endif typedef_decl = t; } @@ -10312,9 +10306,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) Descend through it, creating more complex types, until we reach the declared identifier (or NULL_TREE, in an absolute declarator). */ - inner_attrs = NULL_TREE; - ignore_attrs = 0; - while (declarator && TREE_CODE (declarator) != IDENTIFIER_NODE && TREE_CODE (declarator) != TEMPLATE_ID_EXPR) { @@ -10363,28 +10354,30 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) } } - /* See the comment for the TREE_LIST case, below. */ - if (ignore_attrs) - ignore_attrs = 0; - else if (inner_attrs) - { - decl_attributes (&type, inner_attrs, 0); - inner_attrs = NULL_TREE; - } - switch (TREE_CODE (declarator)) { case TREE_LIST: { /* We encode a declarator with embedded attributes using - a TREE_LIST. The attributes apply to the declarator - directly inside them, so we have to skip an iteration - before applying them to the type. If the declarator just - inside is the declarator-id, we apply the attrs to the - decl itself. */ - inner_attrs = TREE_PURPOSE (declarator); - ignore_attrs = 1; + a TREE_LIST. */ + tree attrs = TREE_PURPOSE (declarator); + tree inner_decl; declarator = TREE_VALUE (declarator); + inner_decl = declarator; + while (inner_decl != NULL_TREE + && TREE_CODE (inner_decl) == TREE_LIST) + inner_decl = TREE_VALUE (inner_decl); + int attr_flags = 0; + if (inner_decl == NULL_TREE + || TREE_CODE (inner_decl) == IDENTIFIER_NODE) + attr_flags |= (int) ATTR_FLAG_DECL_NEXT; + if (TREE_CODE (inner_decl) == CALL_EXPR) + attr_flags |= (int) ATTR_FLAG_FUNCTION_NEXT; + if (TREE_CODE (inner_decl) == ARRAY_REF) + attr_flags |= (int) ATTR_FLAG_ARRAY_NEXT; + returned_attrs = decl_attributes (&type, + chainon (returned_attrs, attrs), + attr_flags); } break; @@ -10883,15 +10876,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) } } - /* See the comment for the TREE_LIST case, above. */ - if (inner_attrs) + if (returned_attrs) { - if (! ignore_attrs) - decl_attributes (&type, inner_attrs, 0); - else if (attrlist) - TREE_VALUE (attrlist) = chainon (inner_attrs, TREE_VALUE (attrlist)); + if (attrlist) + *attrlist = chainon (returned_attrs, *attrlist); else - attrlist = build_tree_list (NULL_TREE, inner_attrs); + attrlist = &returned_attrs; } /* Now TYPE has the actual type. */ @@ -11302,8 +11292,8 @@ friend declaration requires class-key, i.e. `friend %#T'", return decl; #if 0 /* This clobbers the attrs stored in `decl' from `attrlist'. */ - /* The decl and setting of decl_machine_attr is also turned off. */ - decl = build_decl_attribute_variant (decl, decl_machine_attr); + /* The decl and setting of decl_attr is also turned off. */ + decl = build_decl_attribute_variant (decl, decl_attr); #endif /* [class.conv.ctor] @@ -11401,7 +11391,7 @@ friend declaration requires class-key, i.e. `friend %#T'", } t = do_friend (ctype, declarator, decl, - last_function_parms, attrlist, flags, quals, + last_function_parms, *attrlist, flags, quals, funcdef_flag); } if (t && funcdef_flag) @@ -11838,7 +11828,7 @@ grokparms (first_parm) break; decl = grokdeclarator (TREE_VALUE (decl), TREE_PURPOSE (decl), - PARM, init != NULL_TREE, NULL_TREE); + PARM, init != NULL_TREE, NULL); if (! decl || TREE_TYPE (decl) == error_mark_node) continue; @@ -13269,7 +13259,7 @@ start_function (declspecs, declarator, attrs, flags) } else { - decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, NULL_TREE); + decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, NULL); /* If the declarator is not suitable for a function definition, cause a syntax error. */ if (decl1 == NULL_TREE || TREE_CODE (decl1) != FUNCTION_DECL) return 0; @@ -13554,7 +13544,7 @@ start_function (declspecs, declarator, attrs, flags) pushlevel (0); current_binding_level->parm_flag = 1; - cplus_decl_attributes (&decl1, NULL_TREE, attrs, 0); + cplus_decl_attributes (&decl1, attrs, 0); /* Promote the value to int before returning it. */ if (c_promoting_integer_type_p (restype)) @@ -14056,7 +14046,7 @@ start_method (declspecs, declarator, attrlist) tree declarator, declspecs, attrlist; { tree fndecl = grokdeclarator (declarator, declspecs, MEMFUNCDEF, 0, - attrlist); + &attrlist); /* Something too ugly to handle. */ if (fndecl == NULL_TREE) diff --git a/gcc/cp/decl.h b/gcc/cp/decl.h index c5417d1..6f1418a 100644 --- a/gcc/cp/decl.h +++ b/gcc/cp/decl.h @@ -31,7 +31,7 @@ enum decl_context }; /* We need this in here to get the decl_context definition. */ -extern tree grokdeclarator PARAMS ((tree, tree, enum decl_context, int, tree)); +extern tree grokdeclarator PARAMS ((tree, tree, enum decl_context, int, tree *)); /* Parsing a function declarator leaves a list of parameter names or a chain or parameter decls here. */ diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 5c62aca..28236ef 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1531,7 +1531,7 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist) && TREE_CHAIN (init) == NULL_TREE) init = NULL_TREE; - value = grokdeclarator (declarator, declspecs, FIELD, init != 0, attrlist); + value = grokdeclarator (declarator, declspecs, FIELD, init != 0, &attrlist); if (! value || value == error_mark_node) /* friend or constructor went bad. */ return value; @@ -1628,8 +1628,7 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist) value = push_template_decl (value); if (attrlist) - cplus_decl_attributes (&value, TREE_PURPOSE (attrlist), - TREE_VALUE (attrlist), 0); + cplus_decl_attributes (&value, attrlist, 0); if (TREE_CODE (value) == VAR_DECL) { @@ -1679,7 +1678,7 @@ grokbitfield (declarator, declspecs, width) tree declarator, declspecs, width; { register tree value = grokdeclarator (declarator, declspecs, BITFIELD, - 0, NULL_TREE); + 0, NULL); if (! value) return NULL_TREE; /* friends went bad. */ @@ -1735,7 +1734,7 @@ tree grokoptypename (declspecs, declarator) tree declspecs, declarator; { - tree t = grokdeclarator (declarator, declspecs, TYPENAME, 0, NULL_TREE); + tree t = grokdeclarator (declarator, declspecs, TYPENAME, 0, NULL); return mangle_conv_op_name_for_type (t); } @@ -1824,8 +1823,8 @@ grok_function_init (decl, init) } void -cplus_decl_attributes (decl, attributes, prefix_attributes, flags) - tree *decl, attributes, prefix_attributes; +cplus_decl_attributes (decl, attributes, flags) + tree *decl, attributes; int flags; { if (*decl == NULL_TREE || *decl == void_type_node) @@ -1834,7 +1833,7 @@ cplus_decl_attributes (decl, attributes, prefix_attributes, flags) if (TREE_CODE (*decl) == TEMPLATE_DECL) decl = &DECL_TEMPLATE_RESULT (*decl); - decl_attributes (decl, chainon (attributes, prefix_attributes), flags); + decl_attributes (decl, attributes, flags); if (TREE_CODE (*decl) == TYPE_DECL) SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (*decl), TREE_TYPE (*decl)); @@ -2371,17 +2370,9 @@ import_export_class (ctype) if (CLASSTYPE_INTERFACE_ONLY (ctype)) return; - if ((*targetm.valid_type_attribute) (ctype, - TYPE_ATTRIBUTES (ctype), - get_identifier ("dllimport"), - NULL_TREE) - && lookup_attribute ("dllimport", TYPE_ATTRIBUTES (ctype))) + if (lookup_attribute ("dllimport", TYPE_ATTRIBUTES (ctype))) import_export = -1; - else if ((*targetm.valid_type_attribute) (ctype, - TYPE_ATTRIBUTES (ctype), - get_identifier ("dllexport"), - NULL_TREE) - && lookup_attribute ("dllexport", TYPE_ATTRIBUTES (ctype))) + else if (lookup_attribute ("dllexport", TYPE_ATTRIBUTES (ctype))) import_export = 1; /* If we got -fno-implicit-templates, we import template classes that diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c index f7ff984..d6d720c 100644 --- a/gcc/cp/friend.c +++ b/gcc/cp/friend.c @@ -309,7 +309,6 @@ do_friend (ctype, declarator, decl, parmdecls, attrlist, int funcdef_flag; { int is_friend_template = 0; - tree prefix_attributes, attributes; /* Every decl that gets here is a friend of something. */ DECL_FRIEND_P (decl) = 1; @@ -435,19 +434,8 @@ do_friend (ctype, declarator, decl, parmdecls, attrlist, handle them in start_decl_1, but since this is a friend decl start_decl_1 never gets to see it. */ - if (attrlist) - { - attributes = TREE_PURPOSE (attrlist); - prefix_attributes = TREE_VALUE (attrlist); - } - else - { - attributes = NULL_TREE; - prefix_attributes = NULL_TREE; - } - /* Set attributes here so if duplicate decl, will have proper attributes. */ - cplus_decl_attributes (&decl, attributes, prefix_attributes, 0); + cplus_decl_attributes (&decl, attrlist, 0); return decl; } diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index 3b89022..9801c38 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -164,7 +164,7 @@ parse_field (declarator, attributes, asmspec, init) tree declarator, attributes, asmspec, init; { tree d = grokfield (declarator, current_declspecs, init, asmspec, - build_tree_list (attributes, prefix_attributes)); + chainon (attributes, prefix_attributes)); decl_type_access_control (d); return d; } @@ -182,7 +182,7 @@ parse_bitfield (declarator, attributes, width) tree declarator, attributes, width; { tree d = grokbitfield (declarator, current_declspecs, width); - cplus_decl_attributes (&d, attributes, prefix_attributes, 0); + cplus_decl_attributes (&d, chainon (attributes, prefix_attributes), 0); decl_type_access_control (d); return d; } @@ -2639,11 +2639,9 @@ component_decl_1: $$ = NULL_TREE; } | notype_declarator maybeasm maybe_attribute maybe_init - { $$ = grokfield ($$, NULL_TREE, $4, $2, - build_tree_list ($3, NULL_TREE)); } + { $$ = grokfield ($$, NULL_TREE, $4, $2, $3); } | constructor_declarator maybeasm maybe_attribute maybe_init - { $$ = grokfield ($$, NULL_TREE, $4, $2, - build_tree_list ($3, NULL_TREE)); } + { $$ = grokfield ($$, NULL_TREE, $4, $2, $3); } | ':' expr_no_commas { $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); } | error @@ -2661,10 +2659,9 @@ component_decl_1: { tree specs, attrs; split_specs_attrs ($1.t, &specs, &attrs); $$ = grokfield ($2, specs, $5, $3, - build_tree_list ($4, attrs)); } + chainon ($4, attrs)); } | component_constructor_declarator maybeasm maybe_attribute maybe_init - { $$ = grokfield ($$, NULL_TREE, $4, $2, - build_tree_list ($3, NULL_TREE)); } + { $$ = grokfield ($$, NULL_TREE, $4, $2, $3); } | using_decl { $$ = do_class_using_decl ($1); } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 05ce365..292513f 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -1929,7 +1929,7 @@ process_template_parm (list, next) my_friendly_assert (TREE_CODE (TREE_PURPOSE (parm)) == TREE_LIST, 260); /* is a const-param */ parm = grokdeclarator (TREE_VALUE (parm), TREE_PURPOSE (parm), - PARM, 0, NULL_TREE); + PARM, 0, NULL); /* [temp.param] @@ -9356,7 +9356,7 @@ void do_decl_instantiation (declspecs, declarator, storage) tree declspecs, declarator, storage; { - tree decl = grokdeclarator (declarator, declspecs, NORMAL, 0, NULL_TREE); + tree decl = grokdeclarator (declarator, declspecs, NORMAL, 0, NULL); tree result = NULL_TREE; int extern_p = 0; diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 04e8add..32783ad 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -50,6 +50,10 @@ static tree verify_stmt_tree_r PARAMS ((tree *, int *, void *)); static tree find_tree_r PARAMS ((tree *, int *, void *)); extern int cp_statement_code_p PARAMS ((enum tree_code)); +static tree handle_java_interface_attribute PARAMS ((tree *, tree, tree, int, bool *)); +static tree handle_com_interface_attribute PARAMS ((tree *, tree, tree, int, bool *)); +static tree handle_init_priority_attribute PARAMS ((tree *, tree, tree, int, bool *)); + /* If REF is an lvalue, returns the kind of lvalue that REF is. Otherwise, returns clk_none. If TREAT_CLASS_RVALUES_AS_LVALUES is non-zero, rvalues of class type are considered lvalues. */ @@ -2182,108 +2186,145 @@ pod_type_p (t) return 1; } -/* Return a 1 if ATTR_NAME and ATTR_ARGS denote a valid C++-specific - attribute for either declaration DECL or type TYPE and 0 otherwise. - Plugged into valid_lang_attribute. */ - -int -cp_valid_lang_attribute (attr_name, attr_args, decl, type) - tree attr_name; - tree attr_args ATTRIBUTE_UNUSED; - tree decl ATTRIBUTE_UNUSED; - tree type ATTRIBUTE_UNUSED; +/* Table of valid C++ attributes. */ +const struct attribute_spec cp_attribute_table[] = { - if (is_attribute_p ("java_interface", attr_name)) + /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ + { "java_interface", 0, 0, false, false, false, handle_java_interface_attribute }, + { "com_interface", 0, 0, false, false, false, handle_com_interface_attribute }, + { "init_priority", 1, 1, true, false, false, handle_init_priority_attribute }, + { NULL, 0, 0, false, false, false, NULL } +}; + +/* Handle a "java_interface" attribute; arguments as in + struct attribute_spec.handler. */ +static tree +handle_java_interface_attribute (node, name, args, flags, no_add_attrs) + tree *node; + tree name; + tree args ATTRIBUTE_UNUSED; + int flags; + bool *no_add_attrs; +{ + if (DECL_P (*node) + || !CLASS_TYPE_P (*node) + || !TYPE_FOR_JAVA (*node)) { - if (attr_args != NULL_TREE - || decl != NULL_TREE - || ! CLASS_TYPE_P (type) - || ! TYPE_FOR_JAVA (type)) - { - error ("`java_interface' attribute can only be applied to Java class definitions"); - return 0; - } - TYPE_JAVA_INTERFACE (type) = 1; - return 1; + error ("`%s' attribute can only be applied to Java class definitions", + IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + return NULL_TREE; } - if (is_attribute_p ("com_interface", attr_name)) - { - static int warned; - if (attr_args != NULL_TREE - || decl != NULL_TREE - || ! CLASS_TYPE_P (type) - || type != TYPE_MAIN_VARIANT (type)) - { - warning ("`com_interface' attribute can only be applied to class definitions"); - return 0; - } + if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) + *node = build_type_copy (*node); + TYPE_JAVA_INTERFACE (*node) = 1; - if (! warned++) - warning ("\ -`com_interface' is obsolete; g++ vtables are now COM-compatible by default"); - return 1; - } - else if (is_attribute_p ("init_priority", attr_name)) + return NULL_TREE; +} + +/* Handle a "com_interface" attribute; arguments as in + struct attribute_spec.handler. */ +static tree +handle_com_interface_attribute (node, name, args, flags, no_add_attrs) + tree *node; + tree name; + tree args ATTRIBUTE_UNUSED; + int flags ATTRIBUTE_UNUSED; + bool *no_add_attrs; +{ + static int warned; + + *no_add_attrs = true; + + if (DECL_P (*node) + || !CLASS_TYPE_P (*node) + || *node != TYPE_MAIN_VARIANT (*node)) { - tree initp_expr = (attr_args ? TREE_VALUE (attr_args): NULL_TREE); - int pri; + warning ("`%s' attribute can only be applied to class definitions", + IDENTIFIER_POINTER (name)); + return NULL_TREE; + } - if (initp_expr) - STRIP_NOPS (initp_expr); + if (!warned++) + warning ("`%s' is obsolete; g++ vtables are now COM-compatible by default", + IDENTIFIER_POINTER (name)); + + return NULL_TREE; +} + +/* Handle an "init_priority" attribute; arguments as in + struct attribute_spec.handler. */ +static tree +handle_init_priority_attribute (node, name, args, flags, no_add_attrs) + tree *node; + tree name; + tree args; + int flags ATTRIBUTE_UNUSED; + bool *no_add_attrs; +{ + tree initp_expr = TREE_VALUE (args); + tree decl = *node; + tree type = TREE_TYPE (decl); + int pri; + + STRIP_NOPS (initp_expr); - if (!initp_expr || TREE_CODE (initp_expr) != INTEGER_CST) - { - error ("requested init_priority is not an integer constant"); - return 0; - } + if (!initp_expr || TREE_CODE (initp_expr) != INTEGER_CST) + { + error ("requested init_priority is not an integer constant"); + *no_add_attrs = true; + return NULL_TREE; + } - pri = TREE_INT_CST_LOW (initp_expr); + pri = TREE_INT_CST_LOW (initp_expr); - type = strip_array_types (type); - - if (decl == NULL_TREE - || TREE_CODE (decl) != VAR_DECL - || ! TREE_STATIC (decl) - || DECL_EXTERNAL (decl) - || (TREE_CODE (type) != RECORD_TYPE - && TREE_CODE (type) != UNION_TYPE) - /* Static objects in functions are initialized the - first time control passes through that - function. This is not precise enough to pin down an - init_priority value, so don't allow it. */ - || current_function_decl) - { - error ("can only use init_priority attribute on file-scope definitions of objects of class type"); - return 0; - } - - if (pri > MAX_INIT_PRIORITY || pri <= 0) - { - error ("requested init_priority is out of range"); - return 0; - } + type = strip_array_types (type); + + if (decl == NULL_TREE + || TREE_CODE (decl) != VAR_DECL + || !TREE_STATIC (decl) + || DECL_EXTERNAL (decl) + || (TREE_CODE (type) != RECORD_TYPE + && TREE_CODE (type) != UNION_TYPE) + /* Static objects in functions are initialized the + first time control passes through that + function. This is not precise enough to pin down an + init_priority value, so don't allow it. */ + || current_function_decl) + { + error ("can only use `%s' attribute on file-scope definitions of objects of class type", + IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + return NULL_TREE; + } - /* Check for init_priorities that are reserved for - language and runtime support implementations.*/ - if (pri <= MAX_RESERVED_INIT_PRIORITY) - { - warning - ("requested init_priority is reserved for internal use"); - } + if (pri > MAX_INIT_PRIORITY || pri <= 0) + { + error ("requested init_priority is out of range"); + *no_add_attrs = true; + return NULL_TREE; + } - if (SUPPORTS_INIT_PRIORITY) - { - DECL_INIT_PRIORITY (decl) = pri; - return 1; - } - else - { - error ("init_priority attribute is not supported on this platform"); - return 0; - } + /* Check for init_priorities that are reserved for + language and runtime support implementations.*/ + if (pri <= MAX_RESERVED_INIT_PRIORITY) + { + warning + ("requested init_priority is reserved for internal use"); } - return 0; + if (SUPPORTS_INIT_PRIORITY) + { + DECL_INIT_PRIORITY (decl) = pri; + return NULL_TREE; + } + else + { + error ("`%s' attribute is not supported on this platform", + IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + return NULL_TREE; + } } /* Return a new PTRMEM_CST of the indicated TYPE. The MEMBER is the |