Commit 517c3b80 by Ben Elliston Committed by Ben Elliston

re PR c++/80 (g++ enum and attributed __packed__)

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.

From-SVN: r43929
parent 6fbce318
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> 2001-07-10 Mark Mitchell <mark@codesourcery.com>
* pt.c (tsubst_decl): Set DECL_CONTEXT for namespace-scope * pt.c (tsubst_decl): Set DECL_CONTEXT for namespace-scope
......
...@@ -3845,7 +3845,7 @@ extern tree xref_tag PARAMS ((tree, tree, int)); ...@@ -3845,7 +3845,7 @@ extern tree xref_tag PARAMS ((tree, tree, int));
extern tree xref_tag_from_type PARAMS ((tree, tree, int)); extern tree xref_tag_from_type PARAMS ((tree, tree, int));
extern void xref_basetypes PARAMS ((tree, tree, tree, tree)); extern void xref_basetypes PARAMS ((tree, tree, tree, tree));
extern tree start_enum PARAMS ((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 void build_enumerator PARAMS ((tree, tree, tree));
extern int start_function PARAMS ((tree, tree, tree, int)); extern int start_function PARAMS ((tree, tree, tree, int));
extern tree finish_function PARAMS ((int)); extern tree finish_function PARAMS ((int));
......
...@@ -12984,8 +12984,9 @@ start_enum (name) ...@@ -12984,8 +12984,9 @@ start_enum (name)
ENUMTYPE is the type object and VALUES a list of name-value pairs. */ ENUMTYPE is the type object and VALUES a list of name-value pairs. */
void void
finish_enum (enumtype) finish_enum (enumtype, attributes)
tree enumtype; tree enumtype;
tree attributes;
{ {
tree pair; tree pair;
tree minnode; tree minnode;
...@@ -12996,6 +12997,8 @@ finish_enum (enumtype) ...@@ -12996,6 +12997,8 @@ finish_enum (enumtype)
int highprec; int highprec;
int precision; int precision;
cplus_decl_attributes (enumtype, attributes, NULL_TREE);
/* We built up the VALUES in reverse order. */ /* We built up the VALUES in reverse order. */
TYPE_VALUES (enumtype) = nreverse (TYPE_VALUES (enumtype)); TYPE_VALUES (enumtype) = nreverse (TYPE_VALUES (enumtype));
...@@ -13074,11 +13077,14 @@ finish_enum (enumtype) ...@@ -13074,11 +13077,14 @@ finish_enum (enumtype)
else else
fixup_signed_type (enumtype); fixup_signed_type (enumtype);
if (flag_short_enums || (precision > TYPE_PRECISION (integer_type_node))) if (flag_short_enums || TYPE_PACKED (enumtype) ||
/* Use the width of the narrowest normal C type which is wide (precision > TYPE_PRECISION (integer_type_node)))
enough. */ {
TYPE_PRECISION (enumtype) = TYPE_PRECISION (type_for_size /* Use the width of the narrowest normal C type which is wide
(precision, 1)); enough. */
TYPE_PRECISION (enumtype) = TYPE_PRECISION (type_for_size
(precision, 1));
}
else else
TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node); TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node);
......
...@@ -340,7 +340,7 @@ cp_parse_init () ...@@ -340,7 +340,7 @@ cp_parse_init ()
%type <ttype> init initlist maybeasm maybe_init defarg defarg1 %type <ttype> init initlist maybeasm maybe_init defarg defarg1
%type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
%type <ttype> maybe_attribute attributes attribute attribute_list attrib %type <ttype> maybe_attribute attributes attribute attribute_list attrib
%type <ttype> any_word %type <ttype> any_word enum_head
%type <itype> save_lineno %type <itype> save_lineno
%type <ttype> simple_stmt simple_if %type <ttype> simple_stmt simple_if
...@@ -2240,22 +2240,29 @@ pending_defargs: ...@@ -2240,22 +2240,29 @@ pending_defargs:
{ do_pending_defargs (); } { do_pending_defargs (); }
; ;
enum_head:
ENUM
{ $$ = NULL_TREE; }
| ENUM attributes
{ $$ = $2; }
;
structsp: structsp:
ENUM identifier '{' enum_head identifier '{'
{ $<ttype>$ = current_enum_type; { $<ttype>$ = current_enum_type;
current_enum_type = start_enum ($2); } current_enum_type = start_enum ($2); }
enumlist_opt '}' enumlist_opt '}' maybe_attribute
{ $$.t = current_enum_type; { $$.t = current_enum_type;
finish_enum (current_enum_type); finish_enum (current_enum_type, chainon ($1, $7));
$$.new_type_flag = 1; $$.new_type_flag = 1;
current_enum_type = $<ttype>4; current_enum_type = $<ttype>4;
check_for_missing_semicolon ($$.t); } check_for_missing_semicolon ($$.t); }
| ENUM '{' | enum_head '{'
{ $<ttype>$ = current_enum_type; { $<ttype>$ = current_enum_type;
current_enum_type = start_enum (make_anon_name ()); } current_enum_type = start_enum (make_anon_name ()); }
enumlist_opt '}' enumlist_opt '}' maybe_attribute
{ $$.t = current_enum_type; { $$.t = current_enum_type;
finish_enum (current_enum_type); finish_enum (current_enum_type, chainon ($1, $6));
$$.new_type_flag = 1; $$.new_type_flag = 1;
current_enum_type = $<ttype>3; current_enum_type = $<ttype>3;
check_for_missing_semicolon ($$.t); } check_for_missing_semicolon ($$.t); }
......
...@@ -10149,7 +10149,7 @@ tsubst_enum (tag, newtag, args) ...@@ -10149,7 +10149,7 @@ tsubst_enum (tag, newtag, args)
build_enumerator (TREE_PURPOSE (e), value, newtag); 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_LINE (TYPE_NAME (newtag)) = DECL_SOURCE_LINE (TYPE_NAME (tag));
DECL_SOURCE_FILE (TYPE_NAME (newtag)) = DECL_SOURCE_FILE (TYPE_NAME (tag)); DECL_SOURCE_FILE (TYPE_NAME (newtag)) = DECL_SOURCE_FILE (TYPE_NAME (tag));
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment