aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeoffrey Keating <geoffk@apple.com>2004-10-11 19:05:45 +0000
committerGeoffrey Keating <geoffk@apple.com>2004-10-11 19:05:45 +0000
commita115ee12372f1ea829d46683291784e4916b3d46 (patch)
tree3719802a87c58c145203b891b6c7c558705cb619
parent6a92b0981a94d2a175f0e4f26d31ad01977998ee (diff)
2004-10-11 Geoffrey Keating <geoffk@apple.com>static-tree-branch
* c-aux-info.c (gen_type): Update for change to TYPE_VALUES. * c-common.c (c_type_hash): Likewise. (match_case_to_enum): Likewise. (c_do_switch_warnings): Likewise. * c-decl.c (start_enum): Use NULL not 0. (finish_enum): Build TYPE_VALUES as a vector. * c-pretty-print.c (pp_c_enumeration_constant): Update for change to TYPE_VALUES. * c-typeck.c (tagged_types_tu_compatible_p): Likewise. * dbxout.c (dbxout_type): Likewise. * dwarf2out.c (gen_enumeration_type_die): Likewise. * fold-const.c (fold_checksum_tree): Don't checksum TYPE_VALUES. * print-tree.c (print_node): Update for change to TYPE_VALUES. * sdbout.c (sdbout_one_type): Likewise. * tree-browser.c (browse_tree): Don't try to browse into TYPE_VALUES. * tree-dump.c (dequeue_and_dump): Update for change to TYPE_VALUES. * tree.c (type_hash_eq): Compare TYPE_VALUES by value. * tree.def: Update comment for ENUMERAL_TYPE. * tree.h (TYPE_VALUES): Update for change to type.values. (TYPE_DOMAIN): Likewise. (TYPE_FIELDS): Likewise. (TYPE_CACHED_VALUES): Likewise. (TYPE_ARG_TYPES): Likewise. (TYPE_DEBUG_REPRESENTATION_TYPE): Likewise. (struct tree_type): Make field 'values' a union holding either a tree or a pointer to a vector of trees. * doc/c-tree.texi (ENUMERAL_TYPE): Update for change to TYPE_VALUES. Index: ada/ChangeLog 2004-10-07 Geoffrey Keating <geoffk@apple.com> * decl.c (gnat_to_gnu_entity): Update for change to TYPE_VALUES. Index: cp/ChangeLog 2004-10-07 Geoffrey Keating <geoffk@apple.com> * cp-tree.h (TYPENAME_TYPE_FULLNAME): Update for change to tree_type.values. (TYPEOF_TYPE_EXPR): Likewise. (TEMPLATE_TYPE_PARM_INDEX): Likewise. (finish_enum): Update prototype. (build_enumerator): Update prototype. * decl.c (start_enum): Use NULL for TYPE_VALUES, not NULL_TREE. (finish_enum): Update for change to TYPE_VALUES. (build_enumerator): Change arguments, return built type. * parser.c (struct enumeration_builder_data): New. (cp_parser_enum_specifier): Update for changes to TYPE_VALUES. (cp_parser_enumerator_list): Likewise. (cp_parser_enumerator_definition): Update to match change to build_enumerator. * pt.c (tsubst_enum): Update for changes to TYPE_VALUES. (tsubst_copy): Likewise. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/static-tree-branch@88899 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog30
-rw-r--r--gcc/ada/ChangeLog4
-rw-r--r--gcc/ada/decl.c13
-rw-r--r--gcc/c-aux-info.c11
-rw-r--r--gcc/c-common.c34
-rw-r--r--gcc/c-decl.c15
-rw-r--r--gcc/c-pretty-print.c25
-rw-r--r--gcc/c-typeck.c53
-rw-r--r--gcc/cp/ChangeLog19
-rw-r--r--gcc/cp/cp-tree.h11
-rw-r--r--gcc/cp/decl.c66
-rw-r--r--gcc/cp/parser.c77
-rw-r--r--gcc/cp/pt.c33
-rw-r--r--gcc/dbxout.c38
-rw-r--r--gcc/doc/c-tree.texi9
-rw-r--r--gcc/dwarf2out.c8
-rw-r--r--gcc/fold-const.c2
-rw-r--r--gcc/print-tree.c10
-rw-r--r--gcc/sdbout.c9
-rw-r--r--gcc/tree-browser.c5
-rw-r--r--gcc/tree-dump.c11
-rw-r--r--gcc/tree.c9
-rw-r--r--gcc/tree.def4
-rw-r--r--gcc/tree.h21
24 files changed, 320 insertions, 197 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 98896f030a8..b7c9874ca1a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,33 @@
+2004-10-11 Geoffrey Keating <geoffk@apple.com>
+
+ * c-aux-info.c (gen_type): Update for change to TYPE_VALUES.
+ * c-common.c (c_type_hash): Likewise.
+ (match_case_to_enum): Likewise.
+ (c_do_switch_warnings): Likewise.
+ * c-decl.c (start_enum): Use NULL not 0.
+ (finish_enum): Build TYPE_VALUES as a vector.
+ * c-pretty-print.c (pp_c_enumeration_constant): Update for change
+ to TYPE_VALUES.
+ * c-typeck.c (tagged_types_tu_compatible_p): Likewise.
+ * dbxout.c (dbxout_type): Likewise.
+ * dwarf2out.c (gen_enumeration_type_die): Likewise.
+ * fold-const.c (fold_checksum_tree): Don't checksum TYPE_VALUES.
+ * print-tree.c (print_node): Update for change to TYPE_VALUES.
+ * sdbout.c (sdbout_one_type): Likewise.
+ * tree-browser.c (browse_tree): Don't try to browse into TYPE_VALUES.
+ * tree-dump.c (dequeue_and_dump): Update for change to TYPE_VALUES.
+ * tree.c (type_hash_eq): Compare TYPE_VALUES by value.
+ * tree.def: Update comment for ENUMERAL_TYPE.
+ * tree.h (TYPE_VALUES): Update for change to type.values.
+ (TYPE_DOMAIN): Likewise.
+ (TYPE_FIELDS): Likewise.
+ (TYPE_CACHED_VALUES): Likewise.
+ (TYPE_ARG_TYPES): Likewise.
+ (TYPE_DEBUG_REPRESENTATION_TYPE): Likewise.
+ (struct tree_type): Make field 'values' a union holding either a tree
+ or a pointer to a vector of trees.
+ * doc/c-tree.texi (ENUMERAL_TYPE): Update for change to TYPE_VALUES.
+
2004-10-04 Geoffrey Keating <geoffk@apple.com>
* c-decl.c (get_parm_info): Don't save b->id in the TREE_PURPOSE
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 2acfd826c86..8920026f4ab 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,7 @@
+2004-10-07 Geoffrey Keating <geoffk@apple.com>
+
+ * decl.c (gnat_to_gnu_entity): Update for change to TYPE_VALUES.
+
2004-09-30 Geoffrey Keating <geoffk@apple.com>
* gigi.h (builtin_function): Update parameters.
diff --git a/gcc/ada/decl.c b/gcc/ada/decl.c
index 369f8d248d8..fd3f268663c 100644
--- a/gcc/ada/decl.c
+++ b/gcc/ada/decl.c
@@ -1148,17 +1148,15 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
/* Normal case of non-character type, or non-Standard character type */
{
/* Here we have a list of enumeral constants in First_Literal.
- We make a CONST_DECL for each and build into GNU_LITERAL_LIST
- the list to be places into TYPE_FIELDS. Each node in the list
- is a TREE_LIST node whose TREE_VALUE is the literal name
- and whose TREE_PURPOSE is the value of the literal.
+ We make a CONST_DECL for each and build a list of them
+ into GNU_LITERAL_LIST to be placed in the TYPE_VALUES field.
Esize contains the number of bits needed to represent the enumeral
type, Type_Low_Bound also points to the first literal and
Type_High_Bound points to the last literal. */
Entity_Id gnat_literal;
- tree gnu_literal_list = NULL_TREE;
+ VEC (tree) * gnu_literal_list = VEC_alloc (tree, -1);
if (Is_Unsigned_Type (gnat_entity))
gnu_type = make_unsigned_type (esize);
@@ -1179,11 +1177,10 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
false, NULL, gnat_literal);
save_gnu_tree (gnat_literal, gnu_literal, false);
- gnu_literal_list = tree_cons (DECL_NAME (gnu_literal),
- gnu_value, gnu_literal_list);
+ VEC_push (tree, gnu_literal_list, gnu_lititeral);
}
- TYPE_VALUES (gnu_type) = nreverse (gnu_literal_list);
+ TYPE_VALUES (gnu_type) = gnu_literal_list;
/* Note that the bounds are updated at the end of this function
because to avoid an infinite recursion when we get the bounds of
diff --git a/gcc/c-aux-info.c b/gcc/c-aux-info.c
index b42adce9a80..83b376ecba9 100644
--- a/gcc/c-aux-info.c
+++ b/gcc/c-aux-info.c
@@ -407,14 +407,15 @@ gen_type (const char *ret_val, tree t, formals_style style)
data_type = IDENTIFIER_POINTER (TYPE_NAME (t));
else
{
+ VEC (tree) * values = TYPE_VALUES (t);
+ unsigned i;
data_type = "";
- chain_p = TYPE_VALUES (t);
- while (chain_p)
+
+ for (i = 0; VEC_iterate (tree, values, i, chain_p); i++)
{
data_type = concat (data_type,
- IDENTIFIER_POINTER (TREE_PURPOSE (chain_p)), NULL);
- chain_p = TREE_CHAIN (chain_p);
- if (chain_p)
+ IDENTIFIER_POINTER (DECL_NAME (chain_p)), NULL);
+ if (i < VEC_length (tree, values) - 1)
data_type = concat (data_type, ", ", NULL);
}
data_type = concat ("{ ", data_type, " }", NULL);
diff --git a/gcc/c-common.c b/gcc/c-common.c
index b61222806fe..ec198d86a6c 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -2563,7 +2563,7 @@ c_apply_type_quals_to_decl (int type_quals, tree decl)
static hashval_t
c_type_hash (const void *p)
{
- int i = 0;
+ int i;
int shift, size;
tree t = (tree)p;
tree t2;
@@ -2574,9 +2574,7 @@ c_type_hash (const void *p)
return c_type_hash (TREE_TYPE (t)) ^ 0x3003003;
/* Hash on number of elements and total size. */
case ENUMERAL_TYPE:
- shift = 3;
- t2 = TYPE_VALUES (t);
- break;
+ return VEC_length (tree, TYPE_VALUES (t)) << 3;
case RECORD_TYPE:
shift = 0;
t2 = TYPE_FIELDS (t);
@@ -2592,8 +2590,7 @@ c_type_hash (const void *p)
default:
gcc_unreachable ();
}
- for (; t2; t2 = TREE_CHAIN (t2))
- i++;
+ i = list_length (t2);
size = TREE_INT_CST_LOW (TYPE_SIZE (t));
return ((size << 24) | (i << shift));
}
@@ -3702,13 +3699,13 @@ match_case_to_enum (splay_tree_node node, void *data)
the range either, just the endpoints. */
if (CASE_HIGH (label))
{
- tree chain, key = CASE_HIGH (label);
-
- for (chain = TYPE_VALUES (type);
- chain && !tree_int_cst_equal (key, TREE_VALUE (chain));
- chain = TREE_CHAIN (chain))
- continue;
- if (!chain)
+ tree decl, key = CASE_HIGH (label);
+ unsigned i;
+
+ for (i = 0; VEC_iterate (tree, TYPE_VALUES (type), i, decl); i++)
+ if (tree_int_cst_equal (key, DECL_INITIAL (decl)))
+ break;
+ if (i == VEC_length (tree, TYPE_VALUES (type)))
match_case_to_enum_1 (key, type, label);
}
@@ -3753,17 +3750,18 @@ c_do_switch_warnings (splay_tree cases, tree switch_stmt)
&& type && TREE_CODE (type) == ENUMERAL_TYPE
&& TREE_CODE (SWITCH_COND (switch_stmt)) != INTEGER_CST)
{
- tree chain;
+ tree decl;
+ unsigned i;
/* The time complexity here is O(N*lg(N)) worst case, but for the
common case of monotonically increasing enumerators, it is
O(N), since the nature of the splay tree will keep the next
element adjacent to the root at all times. */
- for (chain = TYPE_VALUES (type); chain; chain = TREE_CHAIN (chain))
+ for (i = 0; VEC_iterate (tree, TYPE_VALUES (type), i, decl); i++)
{
splay_tree_node node
- = splay_tree_lookup (cases, (splay_tree_key) TREE_VALUE (chain));
+ = splay_tree_lookup (cases, (splay_tree_key) DECL_INITIAL (decl));
if (node)
{
@@ -3777,8 +3775,8 @@ c_do_switch_warnings (splay_tree cases, tree switch_stmt)
{
/* Warn if there are enumerators that don't correspond to
case expressions. */
- warning ("%Henumeration value %qE not handled in switch",
- &switch_location, TREE_PURPOSE (chain));
+ warning ("%Henumeration value %qD not handled in switch",
+ &switch_location, decl);
}
}
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index d88024e6d81..efe55718744 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -5368,7 +5368,7 @@ start_enum (tree name)
C_TYPE_BEING_DEFINED (enumtype) = 1;
- if (TYPE_VALUES (enumtype) != 0)
+ if (TYPE_VALUES (enumtype) != NULL)
{
/* This enum is a named one that has been declared already. */
error ("redeclaration of %<enum %s%>", IDENTIFIER_POINTER (name));
@@ -5401,6 +5401,7 @@ finish_enum (tree enumtype, tree values, attribute_list attributes)
int precision, unsign;
bool toplevel = (file_scope == current_scope);
struct lang_type *lt;
+ size_t veclen = 1;
decl_attributes (&enumtype, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);
@@ -5418,6 +5419,7 @@ finish_enum (tree enumtype, tree values, attribute_list attributes)
maxnode = value;
if (tree_int_cst_lt (value, minnode))
minnode = value;
+ veclen++;
}
}
@@ -5460,13 +5462,17 @@ finish_enum (tree enumtype, tree values, attribute_list attributes)
if (values != error_mark_node)
{
+ VEC (tree) * vec_values;
+
+ vec_values = VEC_alloc (tree, veclen);
+
/* Change the type of the enumerators to be the enum type. We
need to do this irrespective of the size of the enum, for
proper type checking. Replace the DECL_INITIALs of the
enumerators, and the value slots of the list, with copies
that have the enum type; they cannot be modified in place
because they may be shared (e.g. integer_zero_node) Finally,
- change the purpose slots to point to the names of the decls. */
+ put the decls into a VEC. */
for (pair = values; pair; pair = TREE_CHAIN (pair))
{
tree enu = TREE_PURPOSE (pair);
@@ -5488,11 +5494,10 @@ finish_enum (tree enumtype, tree values, attribute_list attributes)
ini = convert (tem, ini);
DECL_INITIAL (enu) = ini;
- TREE_PURPOSE (pair) = DECL_NAME (enu);
- TREE_VALUE (pair) = ini;
+ VEC_quick_push (tree, vec_values, enu);
}
- TYPE_VALUES (enumtype) = values;
+ TYPE_VALUES (enumtype) = vec_values;
}
/* Record the min/max values so that we can warn about bit-field
diff --git a/gcc/c-pretty-print.c b/gcc/c-pretty-print.c
index 7b741244bbf..50a52cdd713 100644
--- a/gcc/c-pretty-print.c
+++ b/gcc/c-pretty-print.c
@@ -858,26 +858,21 @@ pp_c_bool_constant (c_pretty_printer *pp, tree b)
static bool
pp_c_enumeration_constant (c_pretty_printer *pp, tree e)
{
- bool value_is_named = true;
tree type = TREE_TYPE (e);
tree value;
+ unsigned i;
/* Find the name of this constant. */
- for (value = TYPE_VALUES (type);
- value != NULL_TREE && !tree_int_cst_equal (TREE_VALUE (value), e);
- value = TREE_CHAIN (value))
- ;
-
- if (value != NULL_TREE)
- pp_id_expression (pp, TREE_PURPOSE (value));
- else
- {
- /* Value must have been cast. */
- pp_c_type_cast (pp, type);
- value_is_named = false;
- }
+ for (i = 0; VEC_iterate (tree, TYPE_VALUES (type), i, value); i++)
+ if (tree_int_cst_equal (DECL_INITIAL (value), e))
+ {
+ pp_id_expression (pp, DECL_NAME (value));
+ return true;
+ }
- return value_is_named;
+ /* Value must have been cast. */
+ pp_c_type_cast (pp, type);
+ return false;
}
/* Print out a REAL value as a decimal-floating-constant. */
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index 5a8dc4c4788..cfb6563ec9a 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -846,35 +846,46 @@ tagged_types_tu_compatible_p (tree t1, tree t2)
{
case ENUMERAL_TYPE:
{
+ size_t i, len;
- /* Speed up the case where the type values are in the same order. */
- tree tv1 = TYPE_VALUES (t1);
- tree tv2 = TYPE_VALUES (t2);
+ VEC (tree) * tv1 = TYPE_VALUES (t1);
+ VEC (tree) * tv2 = TYPE_VALUES (t2);
if (tv1 == tv2)
return 1;
- for (;tv1 && tv2; tv1 = TREE_CHAIN (tv1), tv2 = TREE_CHAIN (tv2))
- {
- if (TREE_PURPOSE (tv1) != TREE_PURPOSE (tv2))
- break;
- if (simple_cst_equal (TREE_VALUE (tv1), TREE_VALUE (tv2)) != 1)
- return 0;
- }
-
- if (tv1 == NULL_TREE && tv2 == NULL_TREE)
- return 1;
- if (tv1 == NULL_TREE || tv2 == NULL_TREE)
- return 0;
-
- if (list_length (TYPE_VALUES (t1)) != list_length (TYPE_VALUES (t2)))
+ len = VEC_length (tree, tv1);
+ if (len != VEC_length (tree, tv2))
return 0;
- for (s1 = TYPE_VALUES (t1); s1; s1 = TREE_CHAIN (s1))
+ /* Speed up the case where the type values are in the same order. */
+ for (i = 0; i < len; i++)
+ {
+ tree v1 = VEC_index (tree, tv1, i);
+ tree v2 = VEC_index (tree, tv2, i);
+
+ if (DECL_NAME (v1) != DECL_NAME (v2))
+ break;
+ if (simple_cst_equal (DECL_INITIAL (v1), DECL_INITIAL (v2)) != 1)
+ return 0;
+ }
+ for (; i < len; i++)
{
- s2 = purpose_member (TREE_PURPOSE (s1), TYPE_VALUES (t2));
- if (s2 == NULL
- || simple_cst_equal (TREE_VALUE (s1), TREE_VALUE (s2)) != 1)
+ tree v1 = VEC_index (tree, tv1, i);
+ size_t i2;
+ for (i2 = 0; i2 < len; i2++)
+ {
+ tree v2 = VEC_index (tree, tv2, i);
+ if (DECL_NAME (v1) == DECL_NAME (v2))
+ {
+ if (simple_cst_equal (DECL_INITIAL (v1), DECL_INITIAL (v2))
+ != 1)
+ return 0;
+ else
+ continue;
+ }
+ }
+ if (i2 == len)
return 0;
}
return 1;
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 36ce4d62ae8..019c85797ee 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,22 @@
+2004-10-07 Geoffrey Keating <geoffk@apple.com>
+
+ * cp-tree.h (TYPENAME_TYPE_FULLNAME): Update for change to
+ tree_type.values.
+ (TYPEOF_TYPE_EXPR): Likewise.
+ (TEMPLATE_TYPE_PARM_INDEX): Likewise.
+ (finish_enum): Update prototype.
+ (build_enumerator): Update prototype.
+ * decl.c (start_enum): Use NULL for TYPE_VALUES, not NULL_TREE.
+ (finish_enum): Update for change to TYPE_VALUES.
+ (build_enumerator): Change arguments, return built type.
+ * parser.c (struct enumeration_builder_data): New.
+ (cp_parser_enum_specifier): Update for changes to TYPE_VALUES.
+ (cp_parser_enumerator_list): Likewise.
+ (cp_parser_enumerator_definition): Update to match change to
+ build_enumerator.
+ * pt.c (tsubst_enum): Update for changes to TYPE_VALUES.
+ (tsubst_copy): Likewise.
+
2004-09-30 Geoffrey Keating <geoffk@apple.com>
General changes that apply to every file listed:
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 9ce8b0ee58a..194a934e4e4 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -2221,7 +2221,8 @@ struct lang_decl GTY(())
this is an IDENTIFIER_NODE, and the same as the DECL_NAME on the
corresponding TYPE_DECL. However, this may also be a
TEMPLATE_ID_EXPR if we had something like `typename X::Y<T>'. */
-#define TYPENAME_TYPE_FULLNAME(NODE) (TYPENAME_TYPE_CHECK (NODE))->type.values
+#define TYPENAME_TYPE_FULLNAME(NODE) \
+ (TYPENAME_TYPE_CHECK (NODE))->type.values.t
/* Nonzero in INTEGER_CST means that this int is negative by dint of
using a twos-complement negated operand. */
@@ -2477,7 +2478,7 @@ struct lang_decl GTY(())
#define PTRMEM_CST_MEMBER(NODE) (((ptrmem_cst_t)PTRMEM_CST_CHECK (NODE))->member)
/* The expression in question for a TYPEOF_TYPE. */
-#define TYPEOF_TYPE_EXPR(NODE) (TYPEOF_TYPE_CHECK (NODE))->type.values
+#define TYPEOF_TYPE_EXPR(NODE) (TYPEOF_TYPE_CHECK (NODE))->type.values.t
/* Nonzero for VAR_DECL and FUNCTION_DECL node means that `extern' was
specified in its declaration. This can also be set for an
@@ -3309,7 +3310,7 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
TEMPLATE_TEMPLATE_PARM and BOUND_TEMPLATE_TEMPLATE_PARM nodes. */
#define TEMPLATE_TYPE_PARM_INDEX(NODE) \
(TREE_CHECK3 ((NODE), TEMPLATE_TYPE_PARM, TEMPLATE_TEMPLATE_PARM, \
- BOUND_TEMPLATE_TEMPLATE_PARM))->type.values
+ BOUND_TEMPLATE_TEMPLATE_PARM))->type.values.t
#define TEMPLATE_TYPE_IDX(NODE) \
(TEMPLATE_PARM_IDX (TEMPLATE_TYPE_PARM_INDEX (NODE)))
#define TEMPLATE_TYPE_LEVEL(NODE) \
@@ -3708,8 +3709,8 @@ extern tree xref_tag (enum tag_types, tree, bool, bool);
extern tree xref_tag_from_type (tree, tree, int);
extern void xref_basetypes (tree, tree);
extern tree start_enum (tree);
-extern void finish_enum (tree);
-extern void build_enumerator (tree, tree, tree);
+extern void finish_enum (tree, VEC (tree) *);
+extern tree build_enumerator (tree, tree, tree);
extern void start_preparsed_function (tree, attribute_list, int);
extern int start_function (cp_decl_specifier_seq *, const cp_declarator *, attribute_list);
extern tree begin_function_body (void);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 7d508efa6b0..42d91f6cac6 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -9419,7 +9419,7 @@ start_enum (tree name)
error ("multiple definition of `%#T'", enumtype);
error ("%Jprevious definition here", TYPE_MAIN_DECL (enumtype));
/* Clear out TYPE_VALUES, and start again. */
- TYPE_VALUES (enumtype) = NULL_TREE;
+ TYPE_VALUES (enumtype) = NULL;
}
else
{
@@ -9432,13 +9432,11 @@ start_enum (tree 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. */
+ ENUMTYPE is the type object and VALUES the CONST_DECLs. */
void
-finish_enum (tree enumtype)
+finish_enum (tree enumtype, VEC (tree) * values)
{
- tree values;
- tree decl;
tree value;
tree minnode;
tree maxnode;
@@ -9449,44 +9447,40 @@ finish_enum (tree enumtype)
int precision;
integer_type_kind itk;
tree underlying_type = NULL_TREE;
+ size_t i;
+ size_t numvalues = VEC_length (tree, values);
- /* We built up the VALUES in reverse order. */
- TYPE_VALUES (enumtype) = nreverse (TYPE_VALUES (enumtype));
-
+ /* List the CONST_DECLs in TYPE_VALUES of the type. */
+ TYPE_VALUES (enumtype) = values;
+
/* 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 (values = TYPE_VALUES (enumtype);
- values;
- values = TREE_CHAIN (values))
- TREE_TYPE (TREE_VALUE (values)) = enumtype;
+ for (i = 0; i < numvalues; i++)
+ TREE_TYPE (VEC_index (tree, values, i)) = enumtype;
if (at_function_scope_p ())
add_stmt (build_min (TAG_DEFN, enumtype));
return;
}
/* Determine the minimum and maximum values of the enumerators. */
- if (TYPE_VALUES (enumtype))
+ if (numvalues > 0)
{
minnode = maxnode = NULL_TREE;
- for (values = TYPE_VALUES (enumtype);
- values;
- values = TREE_CHAIN (values))
+ for (i = 0; i < numvalues; i++)
{
- decl = TREE_VALUE (values);
-
/* [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;
+ TREE_TYPE (VEC_index (tree, values, i)) = enumtype;
/* Update the minimum and maximum values, if appropriate. */
- value = DECL_INITIAL (decl);
+ value = DECL_INITIAL (VEC_index (tree, values, i));
/* Figure out what the minimum and maximum values of the
enumerators are. */
if (!minnode)
@@ -9581,18 +9575,18 @@ finish_enum (tree enumtype)
/* Convert each of the enumerators to the type of the underlying
type of the enumeration. */
- for (values = TYPE_VALUES (enumtype); values; values = TREE_CHAIN (values))
+ for (i = 0; i < numvalues; i++)
{
- decl = TREE_VALUE (values);
value = perform_implicit_conversion (underlying_type,
- DECL_INITIAL (decl));
+ DECL_INITIAL (VEC_index (tree,
+ values,
+ i)));
/* Do not clobber shared ints. */
value = copy_node (value);
TREE_TYPE (value) = enumtype;
- DECL_INITIAL (decl) = value;
- TREE_VALUE (values) = value;
+ DECL_INITIAL (VEC_index (tree, values, i)) = value;
}
/* Fix up all variant types of this enum type. */
@@ -9614,12 +9608,12 @@ finish_enum (tree enumtype)
rest_of_type_compilation (enumtype, namespace_bindings_p ());
}
-/* Build and install a CONST_DECL for an enumeration constant of the
+/* Build and return a CONST_DECL for an enumeration constant of the
enumeration type ENUMTYPE whose NAME and VALUE (if any) are provided.
Assignment of sequential values by default is handled here. */
-void
-build_enumerator (tree name, tree value, tree enumtype)
+tree
+build_enumerator (tree name, tree value, tree lastvalue)
{
tree decl;
tree context;
@@ -9651,23 +9645,21 @@ build_enumerator (tree name, tree value, tree enumtype)
/* Default based on previous value. */
if (value == NULL_TREE)
{
- if (TYPE_VALUES (enumtype))
+ if (lastvalue)
{
HOST_WIDE_INT hi;
unsigned HOST_WIDE_INT lo;
- tree prev_value;
bool overflowed;
/* The next value is the previous value plus one. We can
safely assume that the previous value is an INTEGER_CST.
add_double doesn't know the type of the target expression,
so we must check with int_fits_type_p as well. */
- prev_value = DECL_INITIAL (TREE_VALUE (TYPE_VALUES (enumtype)));
- overflowed = add_double (TREE_INT_CST_LOW (prev_value),
- TREE_INT_CST_HIGH (prev_value),
+ overflowed = add_double (TREE_INT_CST_LOW (lastvalue),
+ TREE_INT_CST_HIGH (lastvalue),
1, 0, &lo, &hi);
- value = build_int_cst_wide (TREE_TYPE (prev_value), lo, hi);
- overflowed |= !int_fits_type_p (value, TREE_TYPE (prev_value));
+ value = build_int_cst_wide (TREE_TYPE (lastvalue), lo, hi);
+ overflowed |= !int_fits_type_p (value, TREE_TYPE (lastvalue));
if (overflowed)
error ("overflow in enumeration values at `%D'", name);
@@ -9722,9 +9714,7 @@ build_enumerator (tree name, tree value, tree enumtype)
finish_member_declaration (decl);
else
pushdecl (decl);
-
- /* Add this enumeration constant to the list for this type. */
- TYPE_VALUES (enumtype) = tree_cons (name, decl, TYPE_VALUES (enumtype));
+ return decl;
}
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 14b4e76a485..4c66824690c 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -1515,9 +1515,10 @@ static tree cp_parser_elaborated_type_specifier
(cp_parser *, bool, bool);
static tree cp_parser_enum_specifier
(cp_parser *);
+struct enumeration_builder_data;
static void cp_parser_enumerator_list
- (cp_parser *, tree);
-static void cp_parser_enumerator_definition
+ (cp_parser *, struct enumeration_builder_data *);
+static tree cp_parser_enumerator_definition
(cp_parser *, tree);
static tree cp_parser_namespace_name
(cp_parser *);
@@ -9829,6 +9830,24 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
return type;
}
+/* This is used to construct the array of enumeration CONST_DECLs. We
+ expect that most of the time, there will be less (much less!) than
+ 125 constants. USED holds the number of entries in *ENUMS that
+ have been used, SIZE holds the maximum number of entries in *ENUMS.
+ If SIZE is insufficient, ENUMS must be enlarged by using xrealloc,
+ or using xmemdup if ENUMS points to INIT_ENUMS.
+
+ Although this does cause an extra copy, compared to using a
+ VEC (tree) directly, it's faster because it saves on allocation and
+ garbage generation. */
+struct enumeration_builder_data {
+ tree lastvalue;
+ tree *enums;
+ size_t size;
+ size_t used;
+ tree init_enums[125];
+};
+
/* Parse an enum-specifier.
enum-specifier:
@@ -9839,8 +9858,10 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
static tree
cp_parser_enum_specifier (cp_parser* parser)
{
+ struct enumeration_builder_data ebd;
tree identifier;
tree type;
+ VEC (tree) * decls;
/* Caller guarantees that the current token is 'enum', an identifier
possibly follows, and the token after that is an opening brace.
@@ -9861,18 +9882,31 @@ cp_parser_enum_specifier (cp_parser* parser)
'enum' keyword, if there is no tag). */
type = start_enum (identifier);
+ /* Set up the builder structure. */
+ ebd.lastvalue = NULL_TREE;
+ ebd.enums = ebd.init_enums;
+ ebd.size = ARRAY_SIZE (ebd.init_enums);
+ ebd.used = 0;
+
/* Consume the opening brace. */
cp_lexer_consume_token (parser->lexer);
/* If the next token is not '}', then there are some enumerators. */
if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_BRACE))
- cp_parser_enumerator_list (parser, type);
+ cp_parser_enumerator_list (parser, &ebd);
/* Consume the final '}'. */
cp_parser_require (parser, CPP_CLOSE_BRACE, "`}'");
+ /* Build the vector of enumeration constants. */
+ decls = VEC_alloc (tree, ebd.used);
+ memcpy (VEC_address (tree, decls), ebd.enums, ebd.used * sizeof (tree));
+ decls->num = ebd.used;
+ if (ebd.enums != ebd.init_enums)
+ free (ebd.enums);
+
/* Finish up the enumeration. */
- finish_enum (type);
+ finish_enum (type, decls);
return type;
}
@@ -9885,12 +9919,33 @@ cp_parser_enum_specifier (cp_parser* parser)
enumerator-list , enumerator-definition */
static void
-cp_parser_enumerator_list (cp_parser* parser, tree type)
+cp_parser_enumerator_list (cp_parser* parser,
+ struct enumeration_builder_data * ebd)
{
while (true)
{
+ tree decl;
+
/* Parse an enumerator-definition. */
- cp_parser_enumerator_definition (parser, type);
+ decl = cp_parser_enumerator_definition (parser, ebd->lastvalue);
+
+ /* Insert it into the list. */
+ if (decl)
+ {
+ ebd->lastvalue = DECL_INITIAL (decl);
+ /* Make room for more enumerators if necessary. */
+ if (ebd->size == ebd->used)
+ {
+ ebd->size *= 2;
+ if (ebd->enums == ebd->init_enums)
+ ebd->enums = xmemdup (ebd->enums,
+ ebd->used * sizeof (tree),
+ ebd->size * sizeof (tree));
+ else
+ ebd->enums = xrealloc (ebd->enums, ebd->size * sizeof (tree));
+ }
+ ebd->enums[ebd->used++] = decl;
+ }
/* If the next token is not a ',', we've reached the end of
the list. */
@@ -9909,7 +9964,7 @@ cp_parser_enumerator_list (cp_parser* parser, tree type)
}
/* Parse an enumerator-definition. The enumerator has the indicated
- TYPE.
+ TYPE. Returns the resulting CONST_DECL.
enumerator-definition:
enumerator
@@ -9918,8 +9973,8 @@ cp_parser_enumerator_list (cp_parser* parser, tree type)
enumerator:
identifier */
-static void
-cp_parser_enumerator_definition (cp_parser* parser, tree type)
+static tree
+cp_parser_enumerator_definition (cp_parser* parser, tree lastvalue)
{
tree identifier;
tree value;
@@ -9927,7 +9982,7 @@ cp_parser_enumerator_definition (cp_parser* parser, tree type)
/* Look for the identifier. */
identifier = cp_parser_identifier (parser);
if (identifier == error_mark_node)
- return;
+ return NULL_TREE;
/* If the next token is an '=', then there is an explicit value. */
if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
@@ -9943,7 +9998,7 @@ cp_parser_enumerator_definition (cp_parser* parser, tree type)
value = NULL_TREE;
/* Create the enumerator. */
- build_enumerator (identifier, value, type);
+ return build_enumerator (identifier, value, lastvalue);
}
/* Parse a namespace-name.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 7adb1698acf..173ccda23d8 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -7469,6 +7469,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
tree enum_type;
tree v;
+ unsigned i;
if (DECL_TEMPLATE_PARM_P (t))
return tsubst_copy (DECL_INITIAL (t), args, complain, in_decl);
@@ -7494,11 +7495,9 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
= tsubst_aggr_type (TREE_TYPE (t), args, complain, in_decl,
/*entering_scope=*/0);
- for (v = TYPE_VALUES (enum_type);
- v != NULL_TREE;
- v = TREE_CHAIN (v))
- if (TREE_PURPOSE (v) == DECL_NAME (t))
- return TREE_VALUE (v);
+ for (i = 0; VEC_iterate (tree, TYPE_VALUES (enum_type), i, v); i++)
+ if (DECL_NAME (v) == DECL_NAME (t))
+ return decl_constant_value (v);
/* We didn't find the name. That should never happen; if
name-lookup found it during preliminary parsing, we
@@ -11386,14 +11385,24 @@ set_current_access_from_decl (tree decl)
static void
tsubst_enum (tree tag, tree newtag, tree args)
{
- tree e;
+ tree decl;
+ unsigned i;
+ VEC (tree) * values;
+ unsigned len = VEC_length (tree, TYPE_VALUES (tag));
+ tree prev_value = NULL_TREE;
+
+ values = VEC_alloc (tree, len);
- for (e = TYPE_VALUES (tag); e; e = TREE_CHAIN (e))
+ /* Because tsubst_copy can't call lookup_name and has to look up
+ names in the partially-created enum type, the type needs to refer
+ to the decls created so far. */
+ TYPE_VALUES (newtag) = values;
+
+ for (i = 0; VEC_iterate (tree, TYPE_VALUES (tag), i, decl); i++)
{
tree value;
- tree decl;
+ tree enu;
- decl = TREE_VALUE (e);
/* Note that in a template enum, the TREE_VALUE is the
CONST_DECL, not the corresponding INTEGER_CST. */
value = tsubst_expr (DECL_INITIAL (decl),
@@ -11404,10 +11413,12 @@ tsubst_enum (tree tag, tree newtag, tree args)
set_current_access_from_decl (decl);
/* Actually build the enumerator itself. */
- build_enumerator (DECL_NAME (decl), value, newtag);
+ enu = build_enumerator (DECL_NAME (decl), value, prev_value);
+ VEC_quick_push (tree, values, enu);
+ prev_value = DECL_INITIAL (enu);
}
- finish_enum (newtag);
+ finish_enum (newtag, values);
DECL_SOURCE_LOCATION (TYPE_NAME (newtag))
= DECL_SOURCE_LOCATION (TYPE_NAME (tag));
}
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index 8dd153e151a..6d9869906f5 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -1872,23 +1872,27 @@ dbxout_type (tree type, int full)
putc ('e', asmfile);
CHARS (1);
- for (tem = TYPE_VALUES (type); tem; tem = TREE_CHAIN (tem))
- {
- fprintf (asmfile, "%s:", IDENTIFIER_POINTER (TREE_PURPOSE (tem)));
- CHARS (IDENTIFIER_LENGTH (TREE_PURPOSE (tem)) + 1);
- if (TREE_INT_CST_HIGH (TREE_VALUE (tem)) == 0)
- print_wide_int (TREE_INT_CST_LOW (TREE_VALUE (tem)));
- else if (TREE_INT_CST_HIGH (TREE_VALUE (tem)) == -1
- && (HOST_WIDE_INT) TREE_INT_CST_LOW (TREE_VALUE (tem)) < 0)
- print_wide_int (TREE_INT_CST_LOW (TREE_VALUE (tem)));
- else
- print_int_cst_octal (TREE_VALUE (tem));
-
- putc (',', asmfile);
- CHARS (1);
- if (TREE_CHAIN (tem) != 0)
- CONTIN;
- }
+ {
+ unsigned i;
+ for (i = 0; VEC_iterate (tree, TYPE_VALUES (type), i, tem); i++)
+ {
+ fprintf (asmfile, "%s:", IDENTIFIER_POINTER (DECL_NAME (tem)));
+ CHARS (IDENTIFIER_LENGTH (DECL_NAME (tem)) + 1);
+ if (TREE_INT_CST_HIGH (DECL_INITIAL (tem)) == 0)
+ print_wide_int (TREE_INT_CST_LOW (DECL_INITIAL (tem)));
+ else if (TREE_INT_CST_HIGH (DECL_INITIAL (tem)) == -1
+ && ((HOST_WIDE_INT) TREE_INT_CST_LOW (DECL_INITIAL (tem))
+ < 0))
+ print_wide_int (TREE_INT_CST_LOW (DECL_INITIAL (tem)));
+ else
+ print_int_cst_octal (DECL_INITIAL (tem));
+
+ putc (',', asmfile);
+ CHARS (1);
+ if (i < VEC_length (tree, TYPE_VALUES (type)) - 1)
+ CONTIN;
+ }
+ }
putc (';', asmfile);
CHARS (1);
diff --git a/gcc/doc/c-tree.texi b/gcc/doc/c-tree.texi
index 653eb09874e..83e820e11bc 100644
--- a/gcc/doc/c-tree.texi
+++ b/gcc/doc/c-tree.texi
@@ -463,13 +463,8 @@ with @code{TYPE_MIN_VALUE} and @code{TYPE_MAX_VALUE}, respectively; each
of these macros returns an @code{INTEGER_CST}.
The actual enumeration constants themselves may be obtained by looking
-at the @code{TYPE_VALUES}. This macro will return a @code{TREE_LIST},
-containing the constants. The @code{TREE_PURPOSE} of each node will be
-an @code{IDENTIFIER_NODE} giving the name of the constant; the
-@code{TREE_VALUE} will be an @code{INTEGER_CST} giving the value
-assigned to that constant. These constants will appear in the order in
-which they were declared. The @code{TREE_TYPE} of each of these
-constants will be the type of enumeration type itself.
+at the @code{TYPE_VALUES}, a vector of the corresponding
+@code{CONST_DECL}s.
@item BOOLEAN_TYPE
Used to represent the @code{bool} type.
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 3992c83189b..b337291afbe 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -10860,6 +10860,7 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die)
if (TYPE_SIZE (type))
{
tree link;
+ unsigned i;
TREE_ASM_WRITTEN (type) = 1;
add_byte_size_attribute (type_die, type);
@@ -10871,14 +10872,13 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die)
if (type_die->die_parent == NULL)
add_child_die (scope_die_for (type, context_die), type_die);
- for (link = TYPE_VALUES (type);
- link != NULL; link = TREE_CHAIN (link))
+ for (i = 0; VEC_iterate (tree, TYPE_VALUES (type), i, link); i++)
{
dw_die_ref enum_die = new_die (DW_TAG_enumerator, type_die, link);
- tree value = TREE_VALUE (link);
+ tree value = DECL_INITIAL (link);
add_name_attribute (enum_die,
- IDENTIFIER_POINTER (TREE_PURPOSE (link)));
+ IDENTIFIER_POINTER (DECL_NAME (link)));
if (host_integerp (value, TYPE_UNSIGNED (TREE_TYPE (value))))
/* DWARF2 does not provide a way of indicating whether or
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 2d229739db5..f83e4fb3e95 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -9134,8 +9134,6 @@ fold_checksum_tree (tree expr, struct md5_ctx *ctx, htab_t ht)
fold_checksum_tree (DECL_VINDEX (expr), ctx, ht);
break;
case tcc_type:
- if (TREE_CODE (expr) == ENUMERAL_TYPE)
- fold_checksum_tree (TYPE_VALUES (expr), ctx, ht);
fold_checksum_tree (TYPE_SIZE (expr), ctx, ht);
fold_checksum_tree (TYPE_SIZE_UNIT (expr), ctx, ht);
fold_checksum_tree (TYPE_ATTRIBUTES (expr), ctx, ht);
diff --git a/gcc/print-tree.c b/gcc/print-tree.c
index 02344f13b88..58e28661670 100644
--- a/gcc/print-tree.c
+++ b/gcc/print-tree.c
@@ -554,7 +554,15 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
}
if (TREE_CODE (node) == ENUMERAL_TYPE)
- print_node (file, "values", TYPE_VALUES (node), indent + 4);
+ {
+ unsigned i;
+ tree t;
+ fputs (" values <", file);
+ if (TYPE_VALUES (node))
+ for (i = 0; VEC_iterate (tree, TYPE_VALUES (node), i, t); i++)
+ print_node_brief (file, "", t, indent + 4);
+ fputc ('>', file);
+ }
else if (TREE_CODE (node) == ARRAY_TYPE || TREE_CODE (node) == SET_TYPE)
print_node (file, "domain", TYPE_DOMAIN (node), indent + 4);
else if (TREE_CODE (node) == VECTOR_TYPE)
diff --git a/gcc/sdbout.c b/gcc/sdbout.c
index 8689cc09be4..0f5efd9a5ab 100644
--- a/gcc/sdbout.c
+++ b/gcc/sdbout.c
@@ -1184,11 +1184,12 @@ sdbout_one_type (tree type)
if (TREE_CODE (type) == ENUMERAL_TYPE)
{
- for (tem = TYPE_VALUES (type); tem; tem = TREE_CHAIN (tem))
- if (host_integerp (TREE_VALUE (tem), 0))
+ unsigned i;
+ for (i = 0; VEC_iterate (tree, TYPE_VALUES (type), i, tem); i++)
+ if (host_integerp (DECL_INITIAL (tem), 0))
{
- PUT_SDB_DEF (IDENTIFIER_POINTER (TREE_PURPOSE (tem)));
- PUT_SDB_INT_VAL (tree_low_cst (TREE_VALUE (tem), 0));
+ PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_NAME (tem)));
+ PUT_SDB_INT_VAL (tree_low_cst (DECL_INITIAL (tem), 0));
PUT_SDB_SCL (C_MOE);
PUT_SDB_TYPE (T_MOE);
PUT_SDB_ENDEF;
diff --git a/gcc/tree-browser.c b/gcc/tree-browser.c
index 1f41a42ad07..c7683c15f2b 100644
--- a/gcc/tree-browser.c
+++ b/gcc/tree-browser.c
@@ -319,10 +319,7 @@ browse_tree (tree begin)
break;
case TB_VALUES:
- if (head && TREE_CODE (head) == ENUMERAL_TYPE)
- TB_SET_HEAD (TYPE_VALUES (head));
- else
- TB_WF;
+ TB_WF;
break;
case TB_ARG_TYPE_AS_WRITTEN:
diff --git a/gcc/tree-dump.c b/gcc/tree-dump.c
index fed3bfc4a09..1b8cbe11cd0 100644
--- a/gcc/tree-dump.c
+++ b/gcc/tree-dump.c
@@ -430,7 +430,16 @@ dequeue_and_dump (dump_info_p di)
dump_child ("max", TYPE_MAX_VALUE (t));
if (code == ENUMERAL_TYPE)
- dump_child ("csts", TYPE_VALUES (t));
+ {
+ unsigned i;
+ tree t;
+ for (i = 0; VEC_iterate (tree, TYPE_VALUES (t), i, t); i++)
+ {
+ char buffer[16];
+ sprintf (buffer, "cst%u", i);
+ dump_child (buffer, t);
+ }
+ }
break;
case REAL_TYPE:
diff --git a/gcc/tree.c b/gcc/tree.c
index f0ae4277bf9..86a3be76e20 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -3418,14 +3418,7 @@ type_hash_eq (const void *va, const void *vb)
return 1;
case ENUMERAL_TYPE:
- if (TYPE_VALUES (a->type) != TYPE_VALUES (b->type)
- && !(TYPE_VALUES (a->type)
- && TREE_CODE (TYPE_VALUES (a->type)) == TREE_LIST
- && TYPE_VALUES (b->type)
- && TREE_CODE (TYPE_VALUES (b->type)) == TREE_LIST
- && type_list_equal (TYPE_VALUES (a->type),
- TYPE_VALUES (b->type))))
- return 0;
+ return TYPE_VALUES (a->type) == TYPE_VALUES (b->type);
/* ... fall through ... */
diff --git a/gcc/tree.def b/gcc/tree.def
index 11469b1d1a5..e769df5e9dc 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -146,9 +146,7 @@ DEFTREECODE (VECTOR_TYPE, "vector_type", tcc_type, 0)
/* C enums. The type node looks just like an INTEGER_TYPE node.
The symbols for the values of the enum type are defined by
- CONST_DECL nodes, but the type does not point to them;
- however, the TYPE_VALUES is a list in which each element's TREE_PURPOSE
- is a name and the TREE_VALUE is the value (an INTEGER_CST node). */
+ CONST_DECL nodes, which are listed in the TYPE_VALUES field. */
/* A forward reference `enum foo' when no enum named foo is defined yet
has zero (a null pointer) in its TYPE_SIZE. The tag name is in
the TYPE_NAME field. If the type is later defined, the normal
diff --git a/gcc/tree.h b/gcc/tree.h
index 123235ffeba..f5ba921a139 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1506,16 +1506,16 @@ struct tree_block GTY(())
#define TYPE_SIZE(NODE) (TYPE_CHECK (NODE)->type.size)
#define TYPE_SIZE_UNIT(NODE) (TYPE_CHECK (NODE)->type.size_unit)
#define TYPE_MODE(NODE) (TYPE_CHECK (NODE)->type.mode)
-#define TYPE_VALUES(NODE) (ENUMERAL_TYPE_CHECK (NODE)->type.values)
-#define TYPE_DOMAIN(NODE) (SET_OR_ARRAY_CHECK (NODE)->type.values)
-#define TYPE_FIELDS(NODE) (RECORD_OR_UNION_CHECK (NODE)->type.values)
-#define TYPE_CACHED_VALUES(NODE) (TYPE_CHECK(NODE)->type.values)
+#define TYPE_VALUES(NODE) (ENUMERAL_TYPE_CHECK (NODE)->type.values.enum_values)
+#define TYPE_DOMAIN(NODE) (SET_OR_ARRAY_CHECK (NODE)->type.values.t)
+#define TYPE_FIELDS(NODE) (RECORD_OR_UNION_CHECK (NODE)->type.values.t)
+#define TYPE_CACHED_VALUES(NODE) (TYPE_CHECK(NODE)->type.values.t)
#define TYPE_ORIG_SIZE_TYPE(NODE) \
- (INTEGER_TYPE_CHECK (NODE)->type.values \
- ? TREE_TYPE ((NODE)->type.values) : NULL_TREE)
+ (INTEGER_TYPE_CHECK (NODE)->type.values.t \
+ ? TREE_TYPE ((NODE)->type.values.t) : NULL_TREE)
#define TYPE_METHODS(NODE) (RECORD_OR_UNION_CHECK (NODE)->type.maxval)
#define TYPE_VFIELD(NODE) (RECORD_OR_UNION_CHECK (NODE)->type.minval)
-#define TYPE_ARG_TYPES(NODE) (FUNC_OR_METHOD_CHECK (NODE)->type.values)
+#define TYPE_ARG_TYPES(NODE) (FUNC_OR_METHOD_CHECK (NODE)->type.values.t)
#define TYPE_METHOD_BASETYPE(NODE) (FUNC_OR_METHOD_CHECK (NODE)->type.maxval)
#define TYPE_OFFSET_BASETYPE(NODE) (OFFSET_TYPE_CHECK (NODE)->type.maxval)
#define TYPE_POINTER_TO(NODE) (TYPE_CHECK (NODE)->type.pointer_to)
@@ -1537,7 +1537,7 @@ struct tree_block GTY(())
/* For a VECTOR_TYPE node, this describes a different type which is emitted
in the debugging output. We use this to describe a vector as a
structure containing an array. */
-#define TYPE_DEBUG_REPRESENTATION_TYPE(NODE) (VECTOR_TYPE_CHECK (NODE)->type.values)
+#define TYPE_DEBUG_REPRESENTATION_TYPE(NODE) (VECTOR_TYPE_CHECK (NODE)->type.values.t)
/* For record and union types, information about this type, as a base type
for itself. */
@@ -1685,7 +1685,10 @@ struct die_struct;
struct tree_type GTY(())
{
struct tree_common common;
- tree values;
+ union tree_type_values {
+ tree GTY ((tag ("0"))) t;
+ VEC (tree) * GTY ((tag ("1"))) enum_values;
+ } GTY ((desc ("TREE_CODE ((tree) &%0) == ENUMERAL_TYPE"))) values;
tree size;
tree size_unit;
attribute_list attributes;