OSDN Git Service

gcc/testsuite/ChangeLog
authorfabien <fabien@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 27 Jun 2012 17:36:50 +0000 (17:36 +0000)
committerfabien <fabien@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 27 Jun 2012 17:36:50 +0000 (17:36 +0000)
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

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/forw_enum11.C [new file with mode: 0644]

index 3d9a243..dcbe6c3 100644 (file)
@@ -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
index 9625c45..503a01e 100644 (file)
@@ -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.  */
 
index ba360d9..951630e 100644 (file)
@@ -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);
index b62f10e..6ac537d 100644 (file)
@@ -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 ());
 }
index d5d5346..35d91a9 100644 (file)
@@ -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 (file)
index 0000000..dd5fd9b
--- /dev/null
@@ -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");
+}