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>
* tree.c (cp_tree_equal): Adjust final switch formatting. Add
......
......@@ -3871,7 +3871,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 tree finish_enum PARAMS ((tree));
extern void finish_enum PARAMS ((tree));
extern void build_enumerator PARAMS ((tree, tree, tree));
extern int start_function PARAMS ((tree, tree, tree, int));
extern tree finish_function PARAMS ((int));
......
......@@ -12931,138 +12931,126 @@ start_enum (name)
/* After processing and defining all the values of an enumeration type,
install their decls in the enumeration type and finish it off.
ENUMTYPE is the type object and VALUES a list of name-value pairs.
Returns ENUMTYPE. */
ENUMTYPE is the type object and VALUES a list of name-value pairs. */
tree
void
finish_enum (enumtype)
tree enumtype;
{
register tree minnode = NULL_TREE, maxnode = NULL_TREE;
/* Calculate the maximum value of any enumerator in this type. */
tree pair;
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);
if (values)
return;
}
/* 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;
/* The TREE_VALUE is a CONST_DECL for this enumeration
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;
}
value = DECL_INITIAL (TREE_VALUE (pair));
if (processing_template_decl)
/* If this is just a template, leave the CONST_DECL
alone. That way tsubst_copy will find CONST_DECLs for
CONST_DECLs, and not INTEGER_CSTs. */
;
else
/* In the list we're building up, we want the enumeration
values, not the CONST_DECLs. */
TREE_VALUE (pair) = value;
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;
}
}
else
maxnode = minnode = integer_zero_node;
TYPE_VALUES (enumtype) = nreverse (values);
if (processing_template_decl)
{
tree scope = current_scope ();
if (scope && TREE_CODE (scope) == FUNCTION_DECL)
add_stmt (build_min (TAG_DEFN, enumtype));
}
minnode = maxnode = integer_zero_node;
/* Compute the number of bits require to represent all values of the
enumeration. We must do this before the type of MINNODE and
MAXNODE are transformed, since min_precision relies on the
TREE_TYPE of the value it is passed. */
unsignedp = tree_int_cst_sgn (minnode) >= 0;
lowprec = min_precision (minnode, unsignedp);
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
{
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;
fixup_signed_type (enumtype);
/* Set TYPE_MIN_VALUE and TYPE_MAX_VALUE according to `precision'. */
TYPE_PRECISION (enumtype) = precision;
if (unsignedp)
fixup_unsigned_type (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));
else
TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node);
TYPE_SIZE (enumtype) = 0;
layout_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));
else
TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node);
/* Fix up all variant types of this enum type. */
for (tem = TYPE_MAIN_VARIANT (enumtype); tem;
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);
}
TYPE_SIZE (enumtype) = NULL_TREE;
layout_type (enumtype);
/* Finish debugging output for this type. */
rest_of_type_compilation (enumtype, namespace_bindings_p ());
/* Fix up all variant types of this enum type. */
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
......
......@@ -2237,7 +2237,8 @@ structsp:
{ $<ttype>$ = current_enum_type;
current_enum_type = start_enum ($2); }
enumlist_opt '}'
{ $$.t = finish_enum (current_enum_type);
{ $$.t = current_enum_type;
finish_enum (current_enum_type);
$$.new_type_flag = 1;
current_enum_type = $<ttype>4;
check_for_missing_semicolon ($$.t); }
......@@ -2245,7 +2246,8 @@ structsp:
{ $<ttype>$ = current_enum_type;
current_enum_type = start_enum (make_anon_name ()); }
enumlist_opt '}'
{ $$.t = finish_enum (current_enum_type);
{ $$.t = current_enum_type;
finish_enum (current_enum_type);
$$.new_type_flag = 1;
current_enum_type = $<ttype>3;
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