diff options
author | fabien <fabien@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-06-27 17:36:50 +0000 |
---|---|---|
committer | fabien <fabien@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-06-27 17:36:50 +0000 |
commit | 9cdd951186a3549c552f96ada38129765f32a4ff (patch) | |
tree | 02dc4e36cc1e7afb3e0d732630e32ca1de4d7ba5 | |
parent | 122a37483a484a0e4ce0335af0a405cecc078ab4 (diff) | |
download | gcc-9cdd951186a3549c552f96ada38129765f32a4ff.tar.gz |
gcc/testsuite/ChangeLog
2012-06-27 Fabien Chêne <fabien@gcc.gnu.org>
PR c++/51214
* g++.dg/cpp0x/forw_enum11.C: New.
gcc/cp/ChangeLog
2012-06-27 Fabien Chêne <fabien@gcc.gnu.org>
PR c++/51214
* cp-tree.h (insert_late_enum_def_into_classtype_sorted_fields):
Declare.
* class.c (insert_into_classtype_sorted_fields): New.
(add_enum_fields_to_record_type): New.
(count_fields): Adjust the comment.
(add_fields_to_record_type): Likewise.
(finish_struct_1): Move the code that inserts the fields for the
sorted case, into insert_into_classtype_sorted_fields, and call
it.
(insert_late_enum_def_into_classtype_sorted_fields): Define.
* decl.c (finish_enum_value_list): Call
insert_late_enum_def_into_classtype_sorted_fields if a late enum
definition is encountered.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@189021 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/cp/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/cp/class.c | 75 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/decl.c | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/forw_enum11.C | 24 |
6 files changed, 114 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3d9a2433769..dcbe6c3d8de 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,20 @@ +2012-06-27 Fabien Chêne <fabien@gcc.gnu.org> + + PR c++/51214 + * cp-tree.h (insert_late_enum_def_into_classtype_sorted_fields): + Declare. + * class.c (insert_into_classtype_sorted_fields): New. + (add_enum_fields_to_record_type): New. + (count_fields): Adjust the comment. + (add_fields_to_record_type): Likewise. + (finish_struct_1): Move the code that inserts the fields for the + sorted case, into insert_into_classtype_sorted_fields, and call + it. + (insert_late_enum_def_into_classtype_sorted_fields): Define. + * decl.c (finish_enum_value_list): Call + insert_late_enum_def_into_classtype_sorted_fields if a late enum + definition is encountered. + 2012-06-25 Jason Merrill <jason@redhat.com> PR c++/53498 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 9625c450b43..503a01e80b0 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -139,6 +139,7 @@ static void build_vtbl_initializer (tree, tree, tree, tree, int *, VEC(constructor_elt,gc) **); static int count_fields (tree); static int add_fields_to_record_type (tree, struct sorted_fields_type*, int); +static void insert_into_classtype_sorted_fields (tree, tree, int); static bool check_bitfield_decl (tree); static void check_field_decl (tree, tree, int *, int *, int *); static void check_field_decls (tree, tree *, int *, int *); @@ -2828,8 +2829,9 @@ add_implicitly_declared_members (tree t, declare_virt_assop_and_dtor (t); } -/* Subroutine of finish_struct_1. Recursively count the number of fields - in TYPE, including anonymous union members. */ +/* Subroutine of insert_into_classtype_sorted_fields. Recursively + count the number of fields in TYPE, including anonymous union + members. */ static int count_fields (tree fields) @@ -2846,8 +2848,9 @@ count_fields (tree fields) return n_fields; } -/* Subroutine of finish_struct_1. Recursively add all the fields in the - TREE_LIST FIELDS to the SORTED_FIELDS_TYPE elts, starting at offset IDX. */ +/* Subroutine of insert_into_classtype_sorted_fields. Recursively add + all the fields in the TREE_LIST FIELDS to the SORTED_FIELDS_TYPE + elts, starting at offset IDX. */ static int add_fields_to_record_type (tree fields, struct sorted_fields_type *field_vec, int idx) @@ -2863,6 +2866,20 @@ add_fields_to_record_type (tree fields, struct sorted_fields_type *field_vec, in return idx; } +/* Add all of the enum values of ENUMTYPE, to the FIELD_VEC elts, + starting at offset IDX. */ + +static int +add_enum_fields_to_record_type (tree enumtype, + struct sorted_fields_type *field_vec, + int idx) +{ + tree values; + for (values = TYPE_VALUES (enumtype); values; values = TREE_CHAIN (values)) + field_vec->elts[idx++] = TREE_VALUE (values); + return idx; +} + /* FIELD is a bit-field. We are finishing the processing for its enclosing type. Issue any appropriate messages and set appropriate flags. Returns false if an error has been diagnosed. */ @@ -5956,7 +5973,6 @@ finish_struct_1 (tree t) tree x; /* A TREE_LIST. The TREE_VALUE of each node is a FUNCTION_DECL. */ tree virtuals = NULL_TREE; - int n_fields = 0; if (COMPLETE_TYPE_P (t)) { @@ -6074,15 +6090,7 @@ finish_struct_1 (tree t) ultimately as the search bores through the inheritance hierarchy), and we want this failure to occur quickly. */ - n_fields = count_fields (TYPE_FIELDS (t)); - if (n_fields > 7) - { - struct sorted_fields_type *field_vec = sorted_fields_type_new (n_fields); - add_fields_to_record_type (TYPE_FIELDS (t), field_vec, 0); - qsort (field_vec->elts, n_fields, sizeof (tree), - field_decl_cmp); - CLASSTYPE_SORTED_FIELDS (t) = field_vec; - } + insert_into_classtype_sorted_fields (TYPE_FIELDS (t), t, 8); /* Complain if one of the field types requires lower visibility. */ constrain_class_visibility (t); @@ -6155,6 +6163,45 @@ finish_struct_1 (tree t) } } +/* Insert FIELDS into T for the sorted case if the FIELDS count is + equal to THRESHOLD or greater than THRESHOLD. */ + +static void +insert_into_classtype_sorted_fields (tree fields, tree t, int threshold) +{ + int n_fields = count_fields (fields); + if (n_fields >= threshold) + { + struct sorted_fields_type *field_vec = sorted_fields_type_new (n_fields); + add_fields_to_record_type (fields, field_vec, 0); + qsort (field_vec->elts, n_fields, sizeof (tree), field_decl_cmp); + CLASSTYPE_SORTED_FIELDS (t) = field_vec; + } +} + +/* Insert lately defined enum ENUMTYPE into T for the sorted case. */ + +void +insert_late_enum_def_into_classtype_sorted_fields (tree enumtype, tree t) +{ + struct sorted_fields_type *sorted_fields = CLASSTYPE_SORTED_FIELDS (t); + if (sorted_fields) + { + int i; + int n_fields + = list_length (TYPE_VALUES (enumtype)) + sorted_fields->len; + struct sorted_fields_type *field_vec = sorted_fields_type_new (n_fields); + + for (i = 0; i < sorted_fields->len; ++i) + field_vec->elts[i] = sorted_fields->elts[i]; + + add_enum_fields_to_record_type (enumtype, field_vec, + sorted_fields->len); + qsort (field_vec->elts, n_fields, sizeof (tree), field_decl_cmp); + CLASSTYPE_SORTED_FIELDS (t) = field_vec; + } +} + /* When T was built up, the member declarations were added in reverse order. Rearrange them to declaration order. */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index ba360d926da..951630e70f3 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4969,6 +4969,7 @@ extern void fixup_attribute_variants (tree); extern tree* decl_cloned_function_p (const_tree, bool); extern void clone_function_decl (tree, int); extern void adjust_clone_args (tree); +extern void insert_late_enum_def_into_classtype_sorted_fields (tree, tree); /* in cvt.c */ extern tree convert_to_reference (tree, tree, int, int, tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index b62f10eb1b0..6ac537dee9a 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -12347,6 +12347,12 @@ finish_enum_value_list (tree enumtype) for (t = TYPE_MAIN_VARIANT (enumtype); t; t = TYPE_NEXT_VARIANT (t)) TYPE_VALUES (t) = TYPE_VALUES (enumtype); + if (current_class_type + && COMPLETE_TYPE_P (current_class_type) + && UNSCOPED_ENUM_P (enumtype)) + insert_late_enum_def_into_classtype_sorted_fields (enumtype, + current_class_type); + /* Finish debugging output for this type. */ rest_of_type_compilation (enumtype, namespace_bindings_p ()); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d5d53460d72..35d91a93fd9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-06-27 Fabien Chêne <fabien@gcc.gnu.org> + + PR c++/51214 + * g++.dg/cpp0x/forw_enum11.C: New. + 2012-06-26 Richard Guenther <rguenther@suse.de> PR c++/53752 diff --git a/gcc/testsuite/g++.dg/cpp0x/forw_enum11.C b/gcc/testsuite/g++.dg/cpp0x/forw_enum11.C new file mode 100644 index 00000000000..dd5fd9be789 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/forw_enum11.C @@ -0,0 +1,24 @@ +// { dg-do compile } +// { dg-options "-std=c++0x -pedantic-errors" } + +enum { A = 1 }; +struct T +{ + int i1, i2, i3, i4, i5, i6, i7; + enum E2 : int; + + void f(); +}; + +enum T::E2 : int { A1 = A, A2 = 23 }; + +static_assert(int(T::A1) == 1, "error"); +static_assert(int(T::A2) == 23, "error"); + +void T::f() +{ + static_assert(int(T::A1) == 1, "error"); + static_assert(int(T::A2) == 23, "error"); + static_assert(int(A1) == 1, "error"); + static_assert(int(A2) == 23, "error"); +} |