Make keyed_classes a vector.
authorNathan Sidwell <nathan@gcc.gnu.org>
Fri, 16 Jun 2017 14:33:45 +0000 (14:33 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Fri, 16 Jun 2017 14:33:45 +0000 (14:33 +0000)
* cp-tree.h (CPTI_KEYED_CLASSES, keyed_classes): Delete.
(keyed_classes): Declare as vector.
* decl.c (keyed_classes): Define.
(cxx_init_decl_processing): Allocate it.
(record_key_method_defined): Use vec_safe_push.
* class.c (finish_struct_1): Likewise.
* pt.c (instantiate_class_template_1): Likewise.
* decl2.c (c_parse_final_cleanups): Reverse iterate keyed_classes.

From-SVN: r249263

gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/pt.c

index dd1051e294b596a5733ad623bb24f657dc10ab03..ebb46fbf38c20be66904ca1833c3b82dde3976c3 100644 (file)
@@ -7189,8 +7189,8 @@ finish_struct_1 (tree t)
         in every translation unit where the class definition appears.  If
         we're devirtualizing, we can look into the vtable even if we
         aren't emitting it.  */
-      if (CLASSTYPE_KEY_METHOD (t) == NULL_TREE)
-       keyed_classes = tree_cons (NULL_TREE, t, keyed_classes);
+      if (!CLASSTYPE_KEY_METHOD (t))
+       vec_safe_push (keyed_classes, t);
     }
 
   /* Layout the class itself.  */
index 5dd6023be16d69544caae797ea6773ebbd0e0135..11250737ccb1a275e9de46b777991b09e933ac64 100644 (file)
@@ -169,8 +169,6 @@ enum cp_tree_index
     CPTI_DSO_HANDLE,
     CPTI_DCAST,
 
-    CPTI_KEYED_CLASSES,
-
     CPTI_NULLPTR,
     CPTI_NULLPTR_TYPE,
 
@@ -290,11 +288,6 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
    destructors.  */
 #define vtt_parm_type                  cp_global_trees[CPTI_VTT_PARM_TYPE]
 
-/* A TREE_LIST of the dynamic classes whose vtables may have to be
-   emitted in this translation unit.  */
-
-#define keyed_classes                  cp_global_trees[CPTI_KEYED_CLASSES]
-
 /* A node which matches any template argument.  */
 #define any_targ_node                  cp_global_trees[CPTI_ANY_TARG]
 
@@ -5107,6 +5100,10 @@ extern GTY(()) vec<tree, va_gc> *local_classes;
 /* An array of static vars & fns.  */
 extern GTY(()) vec<tree, va_gc> *static_decls;
 
+/* An array of vtable-needing types that have no key function, or have
+   an emitted key function.  */
+extern GTY(()) vec<tree, va_gc> *keyed_classes;
+
 \f
 /* Here's where we control how name mangling takes place.  */
 
index 37114761be08a1d474bfd5e27f72c918611855fa..04418a19ddfcbd0f28129932353c0003cf8a0407 100644 (file)
@@ -160,6 +160,9 @@ tree integer_two_node;
 /* vector of static decls.  */
 vec<tree, va_gc> *static_decls;
 
+/* vector of keyed classes.  */
+vec<tree, va_gc> *keyed_classes;
+
 /* Used only for jumps to as-yet undefined labels, since jumps to
    defined labels can have their validity checked immediately.  */
 
@@ -4064,6 +4067,9 @@ cxx_init_decl_processing (void)
   /* Guess at the initial static decls size.  */
   vec_alloc (static_decls, 500);
 
+  /* ... and keyed classes.  */
+  vec_alloc (keyed_classes, 100);
+
   record_builtin_type (RID_BOOL, "bool", boolean_type_node);
   truthvalue_type_node = boolean_type_node;
   truthvalue_false_node = boolean_false_node;
@@ -15438,7 +15444,7 @@ record_key_method_defined (tree fndecl)
     {
       tree fnclass = DECL_CONTEXT (fndecl);
       if (fndecl == CLASSTYPE_KEY_METHOD (fnclass))
-       keyed_classes = tree_cons (NULL_TREE, fnclass, keyed_classes);
+       vec_safe_push (keyed_classes, fnclass);
     }
 }
 
index ab32b71701821301a1a61bf9d79933d4386c9664..f9d588725c0051b96ef6e2559c0ced55a7e871de 100644 (file)
@@ -4511,37 +4511,18 @@ c_parse_final_cleanups (void)
       instantiate_pending_templates (retries);
       ggc_collect ();
 
-      /* Write out virtual tables as required.  Note that writing out
-        the virtual table for a template class may cause the
+      /* Write out virtual tables as required.  Writing out the
+        virtual table for a template class may cause the
         instantiation of members of that class.  If we write out
         vtables then we remove the class from our list so we don't
         have to look at it again.  */
-
-      while (keyed_classes != NULL_TREE
-            && maybe_emit_vtables (TREE_VALUE (keyed_classes)))
-       {
-         reconsider = true;
-         keyed_classes = TREE_CHAIN (keyed_classes);
-       }
-
-      t = keyed_classes;
-      if (t != NULL_TREE)
-       {
-         tree next = TREE_CHAIN (t);
-
-         while (next)
-           {
-             if (maybe_emit_vtables (TREE_VALUE (next)))
-               {
-                 reconsider = true;
-                 TREE_CHAIN (t) = TREE_CHAIN (next);
-               }
-             else
-               t = next;
-
-             next = TREE_CHAIN (t);
-           }
-       }
+      for (i = keyed_classes->length ();
+          keyed_classes->iterate (--i, &t);)
+       if (maybe_emit_vtables (t))
+         {
+           reconsider = true;
+           keyed_classes->unordered_remove (i);
+         }
 
       /* Write out needed type info variables.  We have to be careful
         looping through unemitted decls, because emit_tinfo_decl may
index 8a61b74a149763bc1f338910ffc22219904e45f2..91b98d4de9f7fc42ecd717dce63219cad7129bf6 100644 (file)
@@ -10864,9 +10864,9 @@ instantiate_class_template_1 (tree type)
   /* The vtable for a template class can be emitted in any translation
      unit in which the class is instantiated.  When there is no key
      method, however, finish_struct_1 will already have added TYPE to
-     the keyed_classes list.  */
+     the keyed_classes.  */
   if (TYPE_CONTAINS_VPTR_P (type) && CLASSTYPE_KEY_METHOD (type))
-    keyed_classes = tree_cons (NULL_TREE, type, keyed_classes);
+    vec_safe_push (keyed_classes, type);
 
   return type;
 }