diff options
-rw-r--r-- | gcc/cp/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 2 | ||||
-rw-r--r-- | gcc/cp/decl.c | 18 | ||||
-rw-r--r-- | gcc/cp/parse.y | 21 | ||||
-rw-r--r-- | gcc/cp/pt.c | 2 |
5 files changed, 39 insertions, 15 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d7a843f..4ecf0aa 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2001-07-11 Ben Elliston <bje@redhat.com> + + 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 <mark@codesourcery.com> * 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 66ce4fb..d27ee9f 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 5de71508..15ee0be 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 6e2ac18..6c2a6be 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -340,7 +340,7 @@ cp_parse_init () %type <ttype> init initlist maybeasm maybe_init defarg defarg1 %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers %type <ttype> maybe_attribute attributes attribute attribute_list attrib -%type <ttype> any_word +%type <ttype> any_word enum_head %type <itype> save_lineno %type <ttype> 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 '{' { $<ttype>$ = 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 = $<ttype>4; check_for_missing_semicolon ($$.t); } - | ENUM '{' + | enum_head '{' { $<ttype>$ = 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 = $<ttype>3; check_for_missing_semicolon ($$.t); } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 3d6279a..9503e3e 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)); } |