+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
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));
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;
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));
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);
%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
{ 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); }
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));
}