]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
name-lookup.c (store_binding_p): New predicate, split out from ...
authorRichard Guenther <rguenther@suse.de>
Mon, 20 Aug 2012 10:27:37 +0000 (10:27 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 20 Aug 2012 10:27:37 +0000 (10:27 +0000)
2012-08-20  Richard Guenther  <rguenther@suse.de>

* name-lookup.c (store_binding_p): New predicate, split out from ...
(store_binding): ... here.  Always store binding and require
target vector with enough space.
(store_bindings): Collect to store bindings and reserve space
for them, then store them.
(store_class_bindings): Likewise.

From-SVN: r190529

gcc/cp/ChangeLog
gcc/cp/name-lookup.c

index e64bbdf1f1005ab06f18c5817b0621647b488974..b5961554d8b246589b1116672d9dad9bc95be862 100644 (file)
@@ -1,3 +1,12 @@
+2012-08-20  Richard Guenther  <rguenther@suse.de>
+
+       * name-lookup.c (store_binding_p): New predicate, split out from ...
+       (store_binding): ... here.  Always store binding and require
+       target vector with enough space.
+       (store_bindings): Collect to store bindings and reserve space
+       for them, then store them.
+       (store_class_bindings): Likewise.
+
 2012-08-19  Mikael Morin  <mikael@gcc.gnu.org>
 
        * Make-lang.in: Fix typo.
index 97581d914a2c5f234d1754e321c49f576b928bde..f8dbfa1b628504973cf8d0efbee9da51c7e77b9d 100644 (file)
@@ -5855,23 +5855,33 @@ pushtag (tree name, tree type, tag_scope scope)
    scope isn't enough, because more binding levels may be pushed.  */
 struct saved_scope *scope_chain;
 
-/* If ID has not already been marked, add an appropriate binding to
-   *OLD_BINDINGS.  */
+/* Return true if ID has not already been marked.  */
+
+static inline bool
+store_binding_p (tree id)
+{
+  if (!id || !IDENTIFIER_BINDING (id))
+    return false;
+
+  if (IDENTIFIER_MARKED (id))
+    return false;
+
+  return true;
+}
+
+/* Add an appropriate binding to *OLD_BINDINGS which needs to already
+   have enough space reserved.  */
 
 static void
 store_binding (tree id, VEC(cxx_saved_binding,gc) **old_bindings)
 {
   cxx_saved_binding *saved;
 
-  if (!id || !IDENTIFIER_BINDING (id))
-    return;
-
-  if (IDENTIFIER_MARKED (id))
-    return;
+  gcc_checking_assert (store_binding_p (id));
 
   IDENTIFIER_MARKED (id) = 1;
 
-  saved = VEC_safe_push (cxx_saved_binding, gc, *old_bindings, NULL);
+  saved = VEC_quick_push (cxx_saved_binding, *old_bindings, NULL);
   saved->identifier = id;
   saved->binding = IDENTIFIER_BINDING (id);
   saved->real_type_value = REAL_IDENTIFIER_TYPE_VALUE (id);
@@ -5881,19 +5891,32 @@ store_binding (tree id, VEC(cxx_saved_binding,gc) **old_bindings)
 static void
 store_bindings (tree names, VEC(cxx_saved_binding,gc) **old_bindings)
 {
-  tree t;
+  static VEC(tree,heap) *bindings_need_stored = NULL;
+  tree t, id;
+  size_t i;
 
   bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
   for (t = names; t; t = TREE_CHAIN (t))
     {
-      tree id;
-
       if (TREE_CODE (t) == TREE_LIST)
        id = TREE_PURPOSE (t);
       else
        id = DECL_NAME (t);
 
-      store_binding (id, old_bindings);
+      if (store_binding_p (id))
+       VEC_safe_push(tree, heap, bindings_need_stored, id);
+    }
+  if (!VEC_empty (tree, bindings_need_stored))
+    {
+      VEC_reserve_exact (cxx_saved_binding, gc, *old_bindings,
+                        VEC_length (tree, bindings_need_stored));
+      for (i = 0; VEC_iterate(tree, bindings_need_stored, i, id); ++i)
+       {
+         /* We can appearantly have duplicates in NAMES.  */
+         if (store_binding_p (id))
+           store_binding (id, old_bindings);
+       }
+      VEC_truncate (tree, bindings_need_stored, 0);
     }
   timevar_cond_stop (TV_NAME_LOOKUP, subtime);
 }
@@ -5905,12 +5928,23 @@ static void
 store_class_bindings (VEC(cp_class_binding,gc) *names,
                      VEC(cxx_saved_binding,gc) **old_bindings)
 {
+  static VEC(tree,heap) *bindings_need_stored = NULL;
   size_t i;
   cp_class_binding *cb;
 
   bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
   for (i = 0; VEC_iterate(cp_class_binding, names, i, cb); ++i)
-    store_binding (cb->identifier, old_bindings);
+    if (store_binding_p (cb->identifier))
+      VEC_safe_push (tree, heap, bindings_need_stored, cb->identifier);
+  if (!VEC_empty (tree, bindings_need_stored))
+    {
+      tree id;
+      VEC_reserve_exact (cxx_saved_binding, gc, *old_bindings,
+                        VEC_length (tree, bindings_need_stored));
+      for (i = 0; VEC_iterate(tree, bindings_need_stored, i, id); ++i)
+       store_binding (id, old_bindings);
+      VEC_truncate (tree, bindings_need_stored, 0);
+    }
   timevar_cond_stop (TV_NAME_LOOKUP, subtime);
 }