From 517c3b80599a3124852717bfb6611813b8f5738b Mon Sep 17 00:00:00 2001 From: Ben Elliston Date: Wed, 11 Jul 2001 07:56:23 +0000 Subject: [PATCH] re PR c++/80 (g++ enum and attributed __packed__) 2001-07-11 Ben Elliston PR c++/80 * decl.c (finish_enum): New "attributes" argument; pass it to cplus_decl_attributes. Use a narrower type if the enum is packed. * cp-tree.h (finish_enum): Adjust prototype. * parse.y (enum_head): New non-terminal. (structsp): Use it. Enums now may be preceded or followed by optional attributes -- pass their chained tree to finish_enum(). * pt.c (tsubst_enum): Pass NULL_TREE for the new argument. From-SVN: r43929 --- gcc/cp/ChangeLog | 11 +++++++++++ gcc/cp/cp-tree.h | 2 +- gcc/cp/decl.c | 18 ++++++++++++------ gcc/cp/parse.y | 21 ++++++++++++++------- gcc/cp/pt.c | 2 +- 5 files changed, 39 insertions(+), 15 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d7a843f8ad5..4ecf0aa0bce 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2001-07-11 Ben Elliston + + PR c++/80 + * decl.c (finish_enum): New "attributes" argument; pass it to + cplus_decl_attributes. Use a narrower type if the enum is packed. + * cp-tree.h (finish_enum): Adjust prototype. + * parse.y (enum_head): New non-terminal. + (structsp): Use it. Enums now may be preceded or followed by + optional attributes -- pass their chained tree to finish_enum(). + * pt.c (tsubst_enum): Pass NULL_TREE for the new argument. + 2001-07-10 Mark Mitchell * pt.c (tsubst_decl): Set DECL_CONTEXT for namespace-scope diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 66ce4fb0d31..d27ee9fe830 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3845,7 +3845,7 @@ extern tree xref_tag PARAMS ((tree, tree, int)); extern tree xref_tag_from_type PARAMS ((tree, tree, int)); extern void xref_basetypes PARAMS ((tree, tree, tree, tree)); extern tree start_enum PARAMS ((tree)); -extern void finish_enum PARAMS ((tree)); +extern void finish_enum PARAMS ((tree, tree)); extern void build_enumerator PARAMS ((tree, tree, tree)); extern int start_function PARAMS ((tree, tree, tree, int)); extern tree finish_function PARAMS ((int)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 5de71508626..15ee0be1a39 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -12984,8 +12984,9 @@ start_enum (name) ENUMTYPE is the type object and VALUES a list of name-value pairs. */ void -finish_enum (enumtype) +finish_enum (enumtype, attributes) tree enumtype; + tree attributes; { tree pair; tree minnode; @@ -12996,6 +12997,8 @@ finish_enum (enumtype) int highprec; int precision; + cplus_decl_attributes (enumtype, attributes, NULL_TREE); + /* We built up the VALUES in reverse order. */ TYPE_VALUES (enumtype) = nreverse (TYPE_VALUES (enumtype)); @@ -13074,11 +13077,14 @@ finish_enum (enumtype) else fixup_signed_type (enumtype); - if (flag_short_enums || (precision > TYPE_PRECISION (integer_type_node))) - /* Use the width of the narrowest normal C type which is wide - enough. */ - TYPE_PRECISION (enumtype) = TYPE_PRECISION (type_for_size - (precision, 1)); + if (flag_short_enums || TYPE_PACKED (enumtype) || + (precision > TYPE_PRECISION (integer_type_node))) + { + /* Use the width of the narrowest normal C type which is wide + enough. */ + TYPE_PRECISION (enumtype) = TYPE_PRECISION (type_for_size + (precision, 1)); + } else TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node); diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index 6e2ac183ce5..6c2a6beb24b 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -340,7 +340,7 @@ cp_parse_init () %type init initlist maybeasm maybe_init defarg defarg1 %type asm_operands nonnull_asm_operands asm_operand asm_clobbers %type maybe_attribute attributes attribute attribute_list attrib -%type any_word +%type any_word enum_head %type save_lineno %type simple_stmt simple_if @@ -2240,22 +2240,29 @@ pending_defargs: { do_pending_defargs (); } ; +enum_head: + ENUM + { $$ = NULL_TREE; } + | ENUM attributes + { $$ = $2; } + ; + structsp: - ENUM identifier '{' + enum_head identifier '{' { $$ = current_enum_type; current_enum_type = start_enum ($2); } - enumlist_opt '}' + enumlist_opt '}' maybe_attribute { $$.t = current_enum_type; - finish_enum (current_enum_type); + finish_enum (current_enum_type, chainon ($1, $7)); $$.new_type_flag = 1; current_enum_type = $4; check_for_missing_semicolon ($$.t); } - | ENUM '{' + | enum_head '{' { $$ = current_enum_type; current_enum_type = start_enum (make_anon_name ()); } - enumlist_opt '}' + enumlist_opt '}' maybe_attribute { $$.t = current_enum_type; - finish_enum (current_enum_type); + finish_enum (current_enum_type, chainon ($1, $6)); $$.new_type_flag = 1; current_enum_type = $3; check_for_missing_semicolon ($$.t); } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 3d6279a8282..9503e3ec13f 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -10149,7 +10149,7 @@ tsubst_enum (tag, newtag, args) build_enumerator (TREE_PURPOSE (e), value, newtag); } - finish_enum (newtag); + finish_enum (newtag, NULL_TREE); DECL_SOURCE_LINE (TYPE_NAME (newtag)) = DECL_SOURCE_LINE (TYPE_NAME (tag)); DECL_SOURCE_FILE (TYPE_NAME (newtag)) = DECL_SOURCE_FILE (TYPE_NAME (tag)); } -- 2.30.2