Commit 968b956a by Mark Mitchell Committed by Mark Mitchell

cp-tree.h (finish_enum): Change prototype.

	* cp-tree.h (finish_enum): Change prototype.
	* decl.c (finish_enum): Reorganize.
	* parse.y (structsp): Adjust calls to finish_enum.

From-SVN: r41474
parent 7230e19e
2001-04-20 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (finish_enum): Change prototype.
* decl.c (finish_enum): Reorganize.
* parse.y (structsp): Adjust calls to finish_enum.
2001-04-20 Nathan Sidwell <nathan@codesourcery.com> 2001-04-20 Nathan Sidwell <nathan@codesourcery.com>
* tree.c (cp_tree_equal): Adjust final switch formatting. Add * tree.c (cp_tree_equal): Adjust final switch formatting. Add
......
...@@ -3871,7 +3871,7 @@ extern tree xref_tag PARAMS ((tree, tree, int)); ...@@ -3871,7 +3871,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 tree finish_enum PARAMS ((tree)); extern void finish_enum PARAMS ((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));
......
...@@ -12931,138 +12931,126 @@ start_enum (name) ...@@ -12931,138 +12931,126 @@ start_enum (name)
/* After processing and defining all the values of an enumeration type, /* After processing and defining all the values of an enumeration type,
install their decls in the enumeration type and finish it off. install their decls in the enumeration type and finish it off.
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. */
Returns ENUMTYPE. */
tree void
finish_enum (enumtype) finish_enum (enumtype)
tree enumtype; tree enumtype;
{ {
register tree minnode = NULL_TREE, maxnode = NULL_TREE; tree pair;
/* Calculate the maximum value of any enumerator in this type. */ tree minnode;
tree maxnode;
tree t;
bool unsignedp;
int lowprec;
int highprec;
int precision;
/* We built up the VALUES in reverse order. */
TYPE_VALUES (enumtype) = nreverse (TYPE_VALUES (enumtype));
/* [dcl.enum]
Following the closing brace of an enum-specifier, each
enumerator has the type of its enumeration. Prior to the
closing brace, the type of each enumerator is the type of
its initializing value. */
for (pair = TYPE_VALUES (enumtype); pair; pair = TREE_CHAIN (pair))
TREE_TYPE (TREE_VALUE (pair)) = enumtype;
/* For a enum defined in a template, all further processing is
postponed until the template is instantiated. */
if (processing_template_decl)
{
tree scope = current_scope ();
if (scope && TREE_CODE (scope) == FUNCTION_DECL)
add_stmt (build_min (TAG_DEFN, enumtype));
tree values = TYPE_VALUES (enumtype); return;
if (values) }
/* Figure out what the minimum and maximum values of the enumerators
are. */
if (TYPE_VALUES (enumtype))
{ {
tree pair; minnode = maxnode = NULL_TREE;
for (pair = values; pair; pair = TREE_CHAIN (pair)) for (pair = TYPE_VALUES (enumtype);
pair;
pair = TREE_CHAIN (pair))
{ {
tree decl;
tree value; tree value;
/* The TREE_VALUE is a CONST_DECL for this enumeration value = DECL_INITIAL (TREE_VALUE (pair));
constant. */
decl = TREE_VALUE (pair);
/* [dcl.enum]
Following the closing brace of an enum-specifier, each
enumerator has the type of its enumeration. Prior to the
closing brace, the type of each enumerator is the type of
its initializing value. */
TREE_TYPE (decl) = enumtype;
/* The DECL_INITIAL will be NULL if we are processing a
template declaration and this enumeration constant had no
explicit initializer. */
value = DECL_INITIAL (decl);
if (value && !processing_template_decl)
{
/* Set the TREE_TYPE for the VALUE as well. That's so
that when we call decl_constant_value we get an
entity of the right type (but with the constant
value). Since we shouldn't ever call
decl_constant_value on a template type, there's no
reason to do that when processing_template_decl.
And, if the expression is something like a
TEMPLATE_PARM_INDEX or a CAST_EXPR doing so will
wreak havoc on the intended type of the expression.
Of course, there's also no point in trying to compute
minimum or maximum values if we're in a template. */
TREE_TYPE (value) = enumtype;
if (!minnode)
minnode = maxnode = value;
else if (tree_int_cst_lt (maxnode, value))
maxnode = value;
else if (tree_int_cst_lt (value, minnode))
minnode = value;
}
if (processing_template_decl) if (!minnode)
/* If this is just a template, leave the CONST_DECL minnode = maxnode = value;
alone. That way tsubst_copy will find CONST_DECLs for else if (tree_int_cst_lt (maxnode, value))
CONST_DECLs, and not INTEGER_CSTs. */ maxnode = value;
; else if (tree_int_cst_lt (value, minnode))
else minnode = value;
/* In the list we're building up, we want the enumeration
values, not the CONST_DECLs. */
TREE_VALUE (pair) = value;
} }
} }
else else
maxnode = minnode = integer_zero_node; minnode = maxnode = integer_zero_node;
TYPE_VALUES (enumtype) = nreverse (values); /* Compute the number of bits require to represent all values of the
enumeration. We must do this before the type of MINNODE and
if (processing_template_decl) MAXNODE are transformed, since min_precision relies on the
{ TREE_TYPE of the value it is passed. */
tree scope = current_scope (); unsignedp = tree_int_cst_sgn (minnode) >= 0;
if (scope && TREE_CODE (scope) == FUNCTION_DECL) lowprec = min_precision (minnode, unsignedp);
add_stmt (build_min (TAG_DEFN, enumtype)); highprec = min_precision (maxnode, unsignedp);
} precision = MAX (lowprec, highprec);
/* Set the TREE_TYPE for the values as well. That's so that when we
call decl_constant_value we get an entity of the right type (but
with the constant value). In addition, transform the TYPE_VALUES
list to contain the values, rather than the CONST_DECLs for them. */
for (pair = TYPE_VALUES (enumtype); pair; pair = TREE_CHAIN (pair))
{
tree value = DECL_INITIAL (TREE_VALUE (pair));
TREE_TYPE (value) = enumtype;
TREE_VALUE (pair) = value;
}
/* Set TYPE_MIN_VALUE and TYPE_MAX_VALUE according to `precision'. */
TYPE_SIZE (enumtype) = NULL_TREE;
TYPE_PRECISION (enumtype) = precision;
if (unsignedp)
fixup_unsigned_type (enumtype);
else else
{ fixup_signed_type (enumtype);
int unsignedp = tree_int_cst_sgn (minnode) >= 0;
int lowprec = min_precision (minnode, unsignedp);
int highprec = min_precision (maxnode, unsignedp);
int precision = MAX (lowprec, highprec);
tree tem;
TYPE_SIZE (enumtype) = NULL_TREE;
/* Set TYPE_MIN_VALUE and TYPE_MAX_VALUE according to `precision'. */ if (flag_short_enums || (precision > TYPE_PRECISION (integer_type_node)))
/* Use the width of the narrowest normal C type which is wide
TYPE_PRECISION (enumtype) = precision; enough. */
if (unsignedp) TYPE_PRECISION (enumtype) = TYPE_PRECISION (type_for_size
fixup_unsigned_type (enumtype); (precision, 1));
else else
fixup_signed_type (enumtype); TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node);
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));
else
TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node);
TYPE_SIZE (enumtype) = 0;
layout_type (enumtype);
/* Fix up all variant types of this enum type. */ TYPE_SIZE (enumtype) = NULL_TREE;
for (tem = TYPE_MAIN_VARIANT (enumtype); tem; layout_type (enumtype);
tem = TYPE_NEXT_VARIANT (tem))
{
TYPE_VALUES (tem) = TYPE_VALUES (enumtype);
TYPE_MIN_VALUE (tem) = TYPE_MIN_VALUE (enumtype);
TYPE_MAX_VALUE (tem) = TYPE_MAX_VALUE (enumtype);
TYPE_SIZE (tem) = TYPE_SIZE (enumtype);
TYPE_SIZE_UNIT (tem) = TYPE_SIZE_UNIT (enumtype);
TYPE_MODE (tem) = TYPE_MODE (enumtype);
TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype);
TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype);
TYPE_USER_ALIGN (tem) = TYPE_USER_ALIGN (enumtype);
TREE_UNSIGNED (tem) = TREE_UNSIGNED (enumtype);
}
/* Finish debugging output for this type. */ /* Fix up all variant types of this enum type. */
rest_of_type_compilation (enumtype, namespace_bindings_p ()); for (t = TYPE_MAIN_VARIANT (enumtype); t; t = TYPE_NEXT_VARIANT (t))
{
TYPE_VALUES (t) = TYPE_VALUES (enumtype);
TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (enumtype);
TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (enumtype);
TYPE_SIZE (t) = TYPE_SIZE (enumtype);
TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (enumtype);
TYPE_MODE (t) = TYPE_MODE (enumtype);
TYPE_PRECISION (t) = TYPE_PRECISION (enumtype);
TYPE_ALIGN (t) = TYPE_ALIGN (enumtype);
TYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (enumtype);
TREE_UNSIGNED (t) = TREE_UNSIGNED (enumtype);
} }
return enumtype; /* Finish debugging output for this type. */
rest_of_type_compilation (enumtype, namespace_bindings_p ());
} }
/* Build and install a CONST_DECL for an enumeration constant of the /* Build and install a CONST_DECL for an enumeration constant of the
......
...@@ -2237,7 +2237,8 @@ structsp: ...@@ -2237,7 +2237,8 @@ structsp:
{ $<ttype>$ = current_enum_type; { $<ttype>$ = current_enum_type;
current_enum_type = start_enum ($2); } current_enum_type = start_enum ($2); }
enumlist_opt '}' enumlist_opt '}'
{ $$.t = finish_enum (current_enum_type); { $$.t = current_enum_type;
finish_enum (current_enum_type);
$$.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); }
...@@ -2245,7 +2246,8 @@ structsp: ...@@ -2245,7 +2246,8 @@ structsp:
{ $<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 '}'
{ $$.t = finish_enum (current_enum_type); { $$.t = current_enum_type;
finish_enum (current_enum_type);
$$.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); }
......
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