From f5d70cc0249ddd1745846c62ec171f0cfbeb7673 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 3 Mar 2003 20:13:38 -0500 Subject: [PATCH] decl.c (finish_enum): Do set the type in a template. * decl.c (finish_enum): Do set the type in a template. Simplify. * pt.c (tsubst_enum, tsubst_copy): Revert last patch. From-SVN: r63754 --- gcc/cp/ChangeLog | 5 ++++ gcc/cp/decl.c | 82 ++++++++++++++++++++++++-------------------------------- gcc/cp/pt.c | 11 +------- 3 files changed, 41 insertions(+), 57 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c769429..7b0a807 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2003-03-03 Jason Merrill + + * decl.c (finish_enum): Do set the type in a template. Simplify. + * pt.c (tsubst_enum, tsubst_copy): Revert last patch. + 2003-03-03 Mark Mitchell PR c++/9878 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 63072d3..0bed8e9 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -13072,10 +13072,14 @@ finish_enum (tree enumtype) /* We built up the VALUES in reverse order. */ TYPE_VALUES (enumtype) = nreverse (TYPE_VALUES (enumtype)); - /* For an enum defined in a template, all further processing is - postponed until the template is instantiated. */ + /* For an enum defined in a template, just set the type of the values; + all further processing is postponed until the template is + instantiated. We need to set the type so that tsubst of a CONST_DECL + works. */ if (processing_template_decl) { + for (pair = TYPE_VALUES (enumtype); pair; pair = TREE_CHAIN (pair)) + TREE_TYPE (TREE_VALUE (pair)) = enumtype; if (at_function_scope_p ()) add_stmt (build_min (TAG_DEFN, enumtype)); return; @@ -13083,49 +13087,46 @@ finish_enum (tree enumtype) if (TYPE_VALUES (enumtype)) { - /* Initialize min and max values and figure out actual values in - following 'for' loop. */ minnode = maxnode = NULL_TREE; - /* [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 value; - - /* If we are going to reset type then copy node first. - It cannot be shared now. */ - if (TREE_TYPE (TREE_VALUE (pair)) != enumtype) + tree decl = TREE_VALUE (pair); + tree value = DECL_INITIAL (decl); + + /* [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; + + /* Figure out what the minimum and maximum values of the + enumerators are. */ + 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; + + /* 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). But first make a copy so we + don't clobber shared INTEGER_CSTs. */ + if (TREE_TYPE (value) != enumtype) { - if (DECL_INITIAL (TREE_VALUE (pair))) - DECL_INITIAL (TREE_VALUE (pair)) = - copy_node (DECL_INITIAL (TREE_VALUE (pair))); - TREE_TYPE (TREE_VALUE (pair)) = enumtype; + value = DECL_INITIAL (decl) = copy_node (value); + TREE_TYPE (value) = enumtype; } - if (!processing_template_decl) - { - /* Adjust min and max value. */ - value = DECL_INITIAL (TREE_VALUE (pair)); - - 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; - } + /* In addition, transform the TYPE_VALUES list to contain the + values, rather than the CONST_DECLs for them. */ + TREE_VALUE (pair) = value; } } else 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 @@ -13135,18 +13136,6 @@ finish_enum (tree 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; @@ -13241,8 +13230,7 @@ build_enumerator (tree name, tree value, tree enumtype) } /* Remove no-op casts from the value. */ - if (value) - STRIP_TYPE_NOPS (value); + STRIP_TYPE_NOPS (value); } /* C++ associates enums with global, function, or class declarations. */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index ac5e4e1..a058978 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -7143,10 +7143,6 @@ tsubst_copy (t, args, complain, in_decl) = tsubst_aggr_type (TREE_TYPE (t), args, complain, in_decl, /*entering_scope=*/0); - /* Not yet available. */ - if (!enum_type || enum_type == (TREE_TYPE (t))) - return t; - for (v = TYPE_VALUES (enum_type); v != NULL_TREE; v = TREE_CHAIN (v)) @@ -11073,12 +11069,7 @@ tsubst_enum (tag, newtag, args) for (e = TYPE_VALUES (tag); e; e = TREE_CHAIN (e)) { tree value; - - /* Copy node and set type */ - if (DECL_INITIAL (TREE_VALUE (e))) - DECL_INITIAL (TREE_VALUE (e)) = copy_node (DECL_INITIAL (TREE_VALUE (e))); - TREE_TYPE (TREE_VALUE (e)) = tag; - + /* Note that in a template enum, the TREE_VALUE is the CONST_DECL, not the corresponding INTEGER_CST. */ value = tsubst_expr (DECL_INITIAL (TREE_VALUE (e)), -- 2.7.4