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,29 +12931,23 @@ start_enum (name) ...@@ -12931,29 +12931,23 @@ 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;
/* Calculate the maximum value of any enumerator in this type. */
tree values = TYPE_VALUES (enumtype);
if (values)
{
tree pair; tree pair;
tree minnode;
tree maxnode;
tree t;
bool unsignedp;
int lowprec;
int highprec;
int precision;
for (pair = values; pair; pair = TREE_CHAIN (pair)) /* We built up the VALUES in reverse order. */
{ TYPE_VALUES (enumtype) = nreverse (TYPE_VALUES (enumtype));
tree decl;
tree value;
/* The TREE_VALUE is a CONST_DECL for this enumeration
constant. */
decl = TREE_VALUE (pair);
/* [dcl.enum] /* [dcl.enum]
...@@ -12961,27 +12955,33 @@ finish_enum (enumtype) ...@@ -12961,27 +12955,33 @@ finish_enum (enumtype)
enumerator has the type of its enumeration. Prior to the enumerator has the type of its enumeration. Prior to the
closing brace, the type of each enumerator is the type of closing brace, the type of each enumerator is the type of
its initializing value. */ its initializing value. */
TREE_TYPE (decl) = enumtype; for (pair = TYPE_VALUES (enumtype); pair; pair = TREE_CHAIN (pair))
TREE_TYPE (TREE_VALUE (pair)) = enumtype;
/* The DECL_INITIAL will be NULL if we are processing a
template declaration and this enumeration constant had no /* For a enum defined in a template, all further processing is
explicit initializer. */ postponed until the template is instantiated. */
value = DECL_INITIAL (decl); if (processing_template_decl)
if (value && !processing_template_decl) {
{ tree scope = current_scope ();
/* Set the TREE_TYPE for the VALUE as well. That's so if (scope && TREE_CODE (scope) == FUNCTION_DECL)
that when we call decl_constant_value we get an add_stmt (build_min (TAG_DEFN, enumtype));
entity of the right type (but with the constant
value). Since we shouldn't ever call return;
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 /* Figure out what the minimum and maximum values of the enumerators
TEMPLATE_PARM_INDEX or a CAST_EXPR doing so will are. */
wreak havoc on the intended type of the expression. if (TYPE_VALUES (enumtype))
{
Of course, there's also no point in trying to compute minnode = maxnode = NULL_TREE;
minimum or maximum values if we're in a template. */
TREE_TYPE (value) = enumtype; for (pair = TYPE_VALUES (enumtype);
pair;
pair = TREE_CHAIN (pair))
{
tree value;
value = DECL_INITIAL (TREE_VALUE (pair));
if (!minnode) if (!minnode)
minnode = maxnode = value; minnode = maxnode = value;
...@@ -12990,41 +12990,33 @@ finish_enum (enumtype) ...@@ -12990,41 +12990,33 @@ finish_enum (enumtype)
else if (tree_int_cst_lt (value, minnode)) else if (tree_int_cst_lt (value, minnode))
minnode = value; minnode = value;
} }
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;
}
} }
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
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);
if (processing_template_decl) /* 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
tree scope = current_scope (); with the constant value). In addition, transform the TYPE_VALUES
if (scope && TREE_CODE (scope) == FUNCTION_DECL) list to contain the values, rather than the CONST_DECLs for them. */
add_stmt (build_min (TAG_DEFN, enumtype)); for (pair = TYPE_VALUES (enumtype); pair; pair = TREE_CHAIN (pair))
}
else
{ {
int unsignedp = tree_int_cst_sgn (minnode) >= 0; tree value = DECL_INITIAL (TREE_VALUE (pair));
int lowprec = min_precision (minnode, unsignedp);
int highprec = min_precision (maxnode, unsignedp);
int precision = MAX (lowprec, highprec);
tree tem;
TYPE_SIZE (enumtype) = NULL_TREE; TREE_TYPE (value) = enumtype;
TREE_VALUE (pair) = value;
}
/* Set TYPE_MIN_VALUE and TYPE_MAX_VALUE according to `precision'. */ /* Set TYPE_MIN_VALUE and TYPE_MAX_VALUE according to `precision'. */
TYPE_SIZE (enumtype) = NULL_TREE;
TYPE_PRECISION (enumtype) = precision; TYPE_PRECISION (enumtype) = precision;
if (unsignedp) if (unsignedp)
fixup_unsigned_type (enumtype); fixup_unsigned_type (enumtype);
...@@ -13039,30 +13031,26 @@ finish_enum (enumtype) ...@@ -13039,30 +13031,26 @@ finish_enum (enumtype)
else else
TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node); TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node);
TYPE_SIZE (enumtype) = 0; TYPE_SIZE (enumtype) = NULL_TREE;
layout_type (enumtype); layout_type (enumtype);
/* Fix up all variant types of this enum type. */ /* Fix up all variant types of this enum type. */
for (tem = TYPE_MAIN_VARIANT (enumtype); tem; for (t = TYPE_MAIN_VARIANT (enumtype); t; t = TYPE_NEXT_VARIANT (t))
tem = TYPE_NEXT_VARIANT (tem))
{ {
TYPE_VALUES (tem) = TYPE_VALUES (enumtype); TYPE_VALUES (t) = TYPE_VALUES (enumtype);
TYPE_MIN_VALUE (tem) = TYPE_MIN_VALUE (enumtype); TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (enumtype);
TYPE_MAX_VALUE (tem) = TYPE_MAX_VALUE (enumtype); TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (enumtype);
TYPE_SIZE (tem) = TYPE_SIZE (enumtype); TYPE_SIZE (t) = TYPE_SIZE (enumtype);
TYPE_SIZE_UNIT (tem) = TYPE_SIZE_UNIT (enumtype); TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (enumtype);
TYPE_MODE (tem) = TYPE_MODE (enumtype); TYPE_MODE (t) = TYPE_MODE (enumtype);
TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype); TYPE_PRECISION (t) = TYPE_PRECISION (enumtype);
TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype); TYPE_ALIGN (t) = TYPE_ALIGN (enumtype);
TYPE_USER_ALIGN (tem) = TYPE_USER_ALIGN (enumtype); TYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (enumtype);
TREE_UNSIGNED (tem) = TREE_UNSIGNED (enumtype); TREE_UNSIGNED (t) = TREE_UNSIGNED (enumtype);
} }
/* Finish debugging output for this type. */ /* Finish debugging output for this type. */
rest_of_type_compilation (enumtype, namespace_bindings_p ()); rest_of_type_compilation (enumtype, namespace_bindings_p ());
}
return enumtype;
} }
/* 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