summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfabien <fabien@138bc75d-0d04-0410-961f-82ee72b054a4>2012-06-27 17:36:50 +0000
committerfabien <fabien@138bc75d-0d04-0410-961f-82ee72b054a4>2012-06-27 17:36:50 +0000
commit9cdd951186a3549c552f96ada38129765f32a4ff (patch)
tree02dc4e36cc1e7afb3e0d732630e32ca1de4d7ba5
parent122a37483a484a0e4ce0335af0a405cecc078ab4 (diff)
downloadgcc-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/ChangeLog17
-rw-r--r--gcc/cp/class.c75
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/decl.c6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/forw_enum11.C24
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");
+}