aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2001-04-21 00:04:09 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2001-04-21 00:04:09 +0000
commit968b956afbc4bc6ce30273784b4f6acf7a4ffa40 (patch)
treef9bea2e3279da3efaa324f6eccc016796be06efb /gcc/cp
parent7230e19e96550047e2ba3527886f047d20c8bdc0 (diff)
downloadgcc-968b956afbc4bc6ce30273784b4f6acf7a4ffa40.zip
gcc-968b956afbc4bc6ce30273784b4f6acf7a4ffa40.tar.gz
gcc-968b956afbc4bc6ce30273784b4f6acf7a4ffa40.tar.bz2
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
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/decl.c212
-rw-r--r--gcc/cp/parse.y6
4 files changed, 111 insertions, 115 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 8e86dbd..f0f3204 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+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
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index b1359a1..d5c358a 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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));
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index b72cf4f..85a7310 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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
diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y
index f13614b..37a2bb4 100644
--- a/gcc/cp/parse.y
+++ b/gcc/cp/parse.y
@@ -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); }