cp-tree.h (saved_scope): Remove x_previous_class_type and x_previous_class_values...
authorMark Mitchell <mark@codesourcery.com>
Thu, 8 Jul 2004 04:32:27 +0000 (04:32 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Thu, 8 Jul 2004 04:32:27 +0000 (04:32 +0000)
* cp-tree.h (saved_scope): Remove x_previous_class_type and
x_previous_class_values; add x_previous_class_level.
(previous_class_type): Remove.
(previous_class_values): Remove.
(previous_class_level): New macro.
* class.c (pushclass): Restore the identifier cache more
expeditiously.
(invalidate_class_lookup_cache): Use vector for class_shadowed and
previous_class_values.
* decl.c (poplevel): Likewise.
* name-lookup.c (cxx_binding_init): New function.
(cxx_binding_make): Use it.
(push_binding): For a binding in a class level, use a vector of
cp_class_binding nodes.
(push_binding_level): New function.
(begin_scope): Use it.
(leave_scope): Do not put class binding levels on the free list.
(print_binding_level): Adjust for the fact that class_shadowed is
a vector.
(poplevel_class): Likewise.
(clear_identifier_class_values): Likewise.
(push_class_level_binding): Likewise.
(set_class_shadows): Remove.
(store_binding): New function.
(store_class_bindings): New function.
(push_to_top_level): Use store_class_bindings as appropriate.
(pop_from_top_level): Use previous_class_level, not
previous_class_type.
* name-lookup.h (cp_class_binding): New type.
(cp_binding_level): Use a vector object for class_shadowed.
(push_binding_level): Declare.
(set_class_shadows): Remove.

From-SVN: r84259

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/name-lookup.c
gcc/cp/name-lookup.h

index 839745b3a844334ada00c4c7b427057eb652e36c..5d2aae04082eccc52194cb7c30cc20b128540ea0 100644 (file)
@@ -1,3 +1,38 @@
+2004-07-07  Mark Mitchell  <mark@codesourcery.com>
+
+       * cp-tree.h (saved_scope): Remove x_previous_class_type and
+       x_previous_class_values; add x_previous_class_level.
+       (previous_class_type): Remove.
+       (previous_class_values): Remove.
+       (previous_class_level): New macro.
+       * class.c (pushclass): Restore the identifier cache more
+       expeditiously.
+       (invalidate_class_lookup_cache): Use vector for class_shadowed and
+       previous_class_values.
+       * decl.c (poplevel): Likewise.
+       * name-lookup.c (cxx_binding_init): New function.
+       (cxx_binding_make): Use it.
+       (push_binding): For a binding in a class level, use a vector of
+       cp_class_binding nodes.
+       (push_binding_level): New function.
+       (begin_scope): Use it.
+       (leave_scope): Do not put class binding levels on the free list.
+       (print_binding_level): Adjust for the fact that class_shadowed is
+       a vector.
+       (poplevel_class): Likewise.
+       (clear_identifier_class_values): Likewise.
+       (push_class_level_binding): Likewise.
+       (set_class_shadows): Remove.
+       (store_binding): New function.
+       (store_class_bindings): New function.
+       (push_to_top_level): Use store_class_bindings as appropriate.
+       (pop_from_top_level): Use previous_class_level, not
+       previous_class_type.
+       * name-lookup.h (cp_class_binding): New type.
+       (cp_binding_level): Use a vector object for class_shadowed.
+       (push_binding_level): Declare.
+       (set_class_shadows): Remove.
+
 2004-07-07  Andrew Pinski  <apinski@apple.com>
 
        * class.c (instantiate_type): BUFFER_REF is dead.
index e41172786906c258766510ac1823d4c34e70293e..1f3b22a7ddcb8bd213da0c02f64051cbe07dede6 100644 (file)
@@ -5486,9 +5486,8 @@ pushclass (tree type)
                              ? access_private_node 
                              : access_public_node);
 
-  if (previous_class_type != NULL_TREE
-      && (type != previous_class_type 
-         || !COMPLETE_TYPE_P (previous_class_type))
+  if (previous_class_level
+      && type != previous_class_level->this_entity
       && current_class_depth == 1)
     {
       /* Forcibly remove any old class remnants.  */
@@ -5500,10 +5499,11 @@ pushclass (tree type)
   if (current_class_depth > 1)
     clear_identifier_class_values ();
 
-  pushlevel_class ();
-
-  if (type != previous_class_type || current_class_depth > 1)
+  if (!previous_class_level 
+      || type != previous_class_level->this_entity
+      || current_class_depth > 1)
     {
+      pushlevel_class ();
       push_class_decls (type);
       if (CLASSTYPE_TEMPLATE_INFO (type) && !CLASSTYPE_USE_TEMPLATE (type))
        {
@@ -5520,22 +5520,33 @@ pushclass (tree type)
     }
   else
     {
-      tree item;
+      cp_class_binding *cb;
+      size_t i;
 
       /* We are re-entering the same class we just left, so we don't
         have to search the whole inheritance matrix to find all the
         decls to bind again.  Instead, we install the cached
         class_shadowed list, and walk through it binding names and
         setting up IDENTIFIER_TYPE_VALUEs.  */
-      set_class_shadows (previous_class_values);
-      for (item = previous_class_values; item; item = TREE_CHAIN (item))
+      push_binding_level (previous_class_level);
+      class_binding_level = previous_class_level;
+      for (i = 0; 
+          (cb = VEC_iterate (cp_class_binding, 
+                             previous_class_level->class_shadowed,
+                             i));
+          ++i)
        {
-         tree id = TREE_PURPOSE (item);
-         tree decl = TREE_TYPE (item);
-         
-         push_class_binding (id, decl);
-         if (TREE_CODE (decl) == TYPE_DECL)
-           set_identifier_type_value (id, decl);
+         tree id;
+         tree type_decl;
+
+         id = cb->identifier;
+         cb->base.previous = IDENTIFIER_BINDING (id);
+         IDENTIFIER_BINDING (id) = &cb->base;
+         type_decl = cb->base.value;
+         if (!type_decl || TREE_CODE (type_decl) != TYPE_DECL)
+           type_decl = cb->base.type;
+         if (type_decl && TREE_CODE (type_decl) == TYPE_DECL)
+           set_identifier_type_value (id, type_decl);
        }
       unuse_fields (type);
     }
@@ -5551,14 +5562,17 @@ pushclass (tree type)
 void
 invalidate_class_lookup_cache (void)
 {
-  tree t;
+  size_t i;
+  cp_class_binding *cb;
   
   /* The IDENTIFIER_CLASS_VALUEs are no longer valid.  */
-  for (t = previous_class_values; t; t = TREE_CHAIN (t))
-    IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE;
+  for (i = 0;
+       (cb = VEC_iterate (cp_class_binding, 
+                         previous_class_level->class_shadowed, i));
+       ++i)
+    IDENTIFIER_CLASS_VALUE (cb->identifier) = NULL_TREE;
 
-  previous_class_values = NULL_TREE;
-  previous_class_type = NULL_TREE;
+  previous_class_level = NULL;
 }
  
 /* Get out of the current class scope. If we were in a class scope
index 87e610eaa19c1a54fc4bf9578a069358d42118c9..15cfd8457f8de0e5e034f212423684b2eea2f48e 100644 (file)
@@ -640,8 +640,7 @@ struct saved_scope GTY(())
   varray_type lang_base;
   tree lang_name;
   tree template_parms;
-  tree x_previous_class_type;
-  tree x_previous_class_values;
+  struct cp_binding_level *x_previous_class_level;
   tree x_saved_tree;
 
   HOST_WIDE_INT x_processing_template_decl;
@@ -694,16 +693,10 @@ struct saved_scope GTY(())
 #define processing_specialization scope_chain->x_processing_specialization
 #define processing_explicit_instantiation scope_chain->x_processing_explicit_instantiation
 
-/* _TYPE: the previous type that was a class */
+/* The cached class binding level, from the most recently exited
+   class, or NULL if none.  */
 
-#define previous_class_type scope_chain->x_previous_class_type
-
-/* This is a copy of the class_shadowed list of the previous class
-   binding contour when at global scope.  It's used to reset
-   IDENTIFIER_CLASS_VALUEs when entering another class scope (i.e. a
-   cache miss).  */
-
-#define previous_class_values scope_chain->x_previous_class_values
+#define previous_class_level scope_chain->x_previous_class_level
 
 /* A list of private types mentioned, for deferred access checking.  */
 
index d8feecdbc132c94937d1d39fa7035a830f67a4ad..f17f91cc4b5d34b8143c02e8011d5f3b68eea5e3 100644 (file)
@@ -443,7 +443,8 @@ poplevel (int keep, int reverse, int functionbody)
                       ? ((functionbody = 0), tmp) : functionbody);
   subblocks = functionbody >= 0 ? current_binding_level->blocks : 0;
 
-  my_friendly_assert (!current_binding_level->class_shadowed,
+  my_friendly_assert (VEC_length(cp_class_binding, 
+                                current_binding_level->class_shadowed) == 0,
                      19990414);
 
   /* We used to use KEEP == 2 to indicate that the new block should go
index 7c44c8970d89360465ebe0ff1804f5d182722644..879d2bf6897fb075603d347fd5d36c6e33908e66 100644 (file)
@@ -328,6 +328,17 @@ binding_table_foreach (binding_table table, bt_foreach_proc proc, void *data)
 
 static GTY((deletable)) cxx_binding *free_bindings;
 
+/* Initialize VALUE and TYPE field for BINDING, and set the PREVIOUS
+   field to NULL.  */
+
+static inline void
+cxx_binding_init (cxx_binding *binding, tree value, tree type)
+{
+  binding->value = value;
+  binding->type = type;
+  binding->previous = NULL;
+}
+
 /* (GC)-allocate a binding object with VALUE and TYPE member initialized.  */
 
 static cxx_binding *
@@ -342,9 +353,7 @@ cxx_binding_make (tree value, tree type)
   else
     binding = ggc_alloc (sizeof (cxx_binding));
 
-  binding->value = value;
-  binding->type = type;
-  binding->previous = NULL;
+  cxx_binding_init (binding, value, type);
 
   return binding;
 }
@@ -365,8 +374,31 @@ cxx_binding_free (cxx_binding *binding)
 static void
 push_binding (tree id, tree decl, cxx_scope* level)
 {
-   cxx_binding *binding = cxx_binding_make (decl, NULL);
+  cxx_binding *binding;
 
+  if (level != class_binding_level)
+    binding = cxx_binding_make (decl, NULL_TREE);
+  else
+    {
+      cp_class_binding *cb;
+      size_t length;
+      size_t i;
+      bool need_fixup;
+
+      length = VEC_length (cp_class_binding, level->class_shadowed);
+      need_fixup = (length && length == level->class_shadowed->alloc);
+      cb = VEC_safe_push (cp_class_binding, level->class_shadowed, NULL);
+      cb->identifier = id;
+      binding = &cb->base;
+      cxx_binding_init (binding, decl, NULL_TREE);
+      if (need_fixup)
+       for (i = 0; i < length; ++i)
+         {
+           cb = VEC_index (cp_class_binding, level->class_shadowed, i);
+           IDENTIFIER_BINDING (cb->identifier) = &cb->base;
+         }
+    }
+                             
   /* Now, fill in the binding information.  */
   binding->previous = IDENTIFIER_BINDING (id);
   binding->scope = level;
@@ -1261,6 +1293,26 @@ namespace_scope_ht_size (tree ns)
 
 static GTY((deletable)) struct cp_binding_level *free_binding_level;
 
+/* Insert SCOPE as the innermost binding level.  */
+
+void
+push_binding_level (struct cp_binding_level *scope)
+{
+  /* Add it to the front of currently active scopes stack.  */
+  scope->level_chain = current_binding_level;
+  current_binding_level = scope;
+  keep_next_level_flag = false;
+
+  if (ENABLE_SCOPE_CHECKING)
+    {
+      scope->binding_depth = binding_depth;
+      indent (binding_depth);
+      cxx_scope_debug (scope, input_line, "push");
+      is_class_level = 0;
+      binding_depth++;
+    }
+}
+
 /* Create a new KIND scope and make it the top of the active scopes stack.
    ENTITY is the scope of the associated C++ entity (namespace, class,
    function); it is NULL otherwise.  */
@@ -1319,19 +1371,7 @@ begin_scope (scope_kind kind, tree entity)
     }
   scope->kind = kind;
 
-  /* Add it to the front of currently active scopes stack.  */
-  scope->level_chain = current_binding_level;
-  current_binding_level = scope;
-  keep_next_level_flag = false;
-
-  if (ENABLE_SCOPE_CHECKING)
-    {
-      scope->binding_depth = binding_depth;
-      indent (binding_depth);
-      cxx_scope_debug (scope, input_line, "push");
-      is_class_level = 0;
-      binding_depth++;
-    }
+  push_binding_level (scope);
 
   return scope;
 }
@@ -1366,11 +1406,13 @@ leave_scope (void)
   /* Move one nesting level up.  */
   current_binding_level = scope->level_chain;
 
-  /* Namespace-scopes are left most probably temporarily, not completely;
-     they can be reopen later, e.g. in namespace-extension or any name
-     binding activity that requires us to resume a namespace.  For other
+  /* Namespace-scopes are left most probably temporarily, not
+     completely; they can be reopen later, e.g. in namespace-extension
+     or any name binding activity that requires us to resume a
+     namespace.  For classes, we cache some binding levels.  For other
      scopes, we just make the structure available for reuse.  */
-  if (scope->kind != sk_namespace)
+  if (scope->kind != sk_namespace
+      && scope->kind != sk_class)
     {
       scope->level_chain = free_binding_level;
       if (scope->kind == sk_class)
@@ -1628,13 +1670,17 @@ print_binding_level (struct cp_binding_level* lvl)
       if (i)
        fprintf (stderr, "\n");
     }
-  if (lvl->class_shadowed)
+  if (VEC_length (cp_class_binding, lvl->class_shadowed))
     {
+      size_t i;
+      cp_class_binding *b;
       fprintf (stderr, " class-shadowed:");
-      for (t = lvl->class_shadowed; t; t = TREE_CHAIN (t))
-       {
-         fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t)));
-       }
+      for (i = 0; 
+          (b = VEC_iterate(cp_class_binding, 
+                           lvl->class_shadowed,
+                           i));
+          ++i) 
+       fprintf (stderr, " %s ", IDENTIFIER_POINTER (b->identifier));
       fprintf (stderr, "\n");
     }
   if (lvl->type_shadowed)
@@ -2576,6 +2622,8 @@ void
 poplevel_class (void)
 {
   struct cp_binding_level *level = class_binding_level;
+  cp_class_binding *cb;
+  size_t i;
   tree shadowed;
 
   timevar_push (TV_NAME_LOOKUP);
@@ -2589,12 +2637,11 @@ poplevel_class (void)
   if (current_class_depth != 1)
     {
       struct cp_binding_level* b;
+      cp_class_binding* cb;
+      size_t i;
 
       /* Clear out our IDENTIFIER_CLASS_VALUEs.  */
-      for (shadowed = level->class_shadowed;
-          shadowed;
-          shadowed = TREE_CHAIN (shadowed))
-       IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed)) = NULL_TREE;
+      clear_identifier_class_values ();
 
       /* Find the next enclosing class, and recreate
         IDENTIFIER_CLASS_VALUEs appropriate for that class.  */
@@ -2603,38 +2650,36 @@ poplevel_class (void)
        b = b->level_chain;
 
       if (b)
-       for (shadowed = b->class_shadowed;
-            shadowed;
-            shadowed = TREE_CHAIN (shadowed))
+       for (i = 0;
+            (cb = VEC_iterate (cp_class_binding, 
+                               b->class_shadowed, 
+                               i));
+            ++i)
          {
            cxx_binding *binding;
             
-           binding = IDENTIFIER_BINDING (TREE_PURPOSE (shadowed));
+           binding = IDENTIFIER_BINDING (cb->identifier);
            while (binding && binding->scope != b)
              binding = binding->previous;
 
            if (binding)
-             IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed))
-               = binding->value;
+             IDENTIFIER_CLASS_VALUE (cb->identifier) = binding->value;
          }
     }
   else
     /* Remember to save what IDENTIFIER's were bound in this scope so we
        can recover from cache misses.  */
-    {
-      previous_class_type = current_class_type;
-      previous_class_values = class_binding_level->class_shadowed;
-    }
+    previous_class_level = level;
   for (shadowed = level->type_shadowed;
        shadowed;
        shadowed = TREE_CHAIN (shadowed))
     SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (shadowed), TREE_VALUE (shadowed));
 
   /* Remove the bindings for all of the class-level declarations.  */
-  for (shadowed = level->class_shadowed;
-       shadowed;
-       shadowed = TREE_CHAIN (shadowed))
-    pop_binding (TREE_PURPOSE (shadowed), TREE_TYPE (shadowed));
+  for (i = 0;
+       (cb = VEC_iterate (cp_class_binding, level->class_shadowed, i));
+       ++i)
+    IDENTIFIER_BINDING (cb->identifier) = cb->base.previous;
 
   /* Now, pop out of the binding level which we created up in the
      `pushlevel_class' routine.  */
@@ -2707,15 +2752,16 @@ push_class_binding (tree id, tree decl)
 void
 clear_identifier_class_values (void)
 {
-  tree t;
-
-  if (!class_binding_level)
-    return;
+  size_t i;
+  cp_class_binding *cb;
 
-  for (t = class_binding_level->class_shadowed;
-       t;
-       t = TREE_CHAIN (t))
-    IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE;
+  if (class_binding_level)
+    for (i = 0;
+        (cb = VEC_iterate (cp_class_binding, 
+                           class_binding_level->class_shadowed, 
+                           i));
+        ++i)
+      IDENTIFIER_CLASS_VALUE (cb->identifier) = NULL_TREE;
 }
 
 /* Make the declaration of X appear in CLASS scope.  */
@@ -2859,22 +2905,25 @@ push_class_level_binding (tree name, tree x)
        old_decl = bval;
       else if (TREE_CODE (bval) == USING_DECL && is_overloaded_fn (x))
        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
-      
+
       if (old_decl)
        {
-         tree shadow;
-         
+         cp_class_binding *cb;
+         size_t i;
+
          /* Find the previous binding of name on the class-shadowed
              list, and update it.  */
-         for (shadow = class_binding_level->class_shadowed;
-              shadow;
-              shadow = TREE_CHAIN (shadow))
-           if (TREE_PURPOSE (shadow) == name
-               && TREE_TYPE (shadow) == old_decl)
+         for (i = 0; 
+              (cb = VEC_iterate (cp_class_binding,
+                                 class_binding_level->class_shadowed,
+                                 i));
+              ++i)
+           if (cb->identifier == name
+               && (cb->base.value == old_decl
+                   || cb->base.type == old_decl))
              {
                binding->value = x;
                INHERITED_VALUE_BINDING_P (binding) = 0;
-               TREE_TYPE (shadow) = x;
                IDENTIFIER_CLASS_VALUE (name) = x;
                POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
              }
@@ -2884,15 +2933,7 @@ push_class_level_binding (tree name, tree x)
   /* If we didn't replace an existing binding, put the binding on the
      stack of bindings for the identifier, and update the shadowed list.  */
   if (push_class_binding (name, x))
-    {
-      class_binding_level->class_shadowed
-       = tree_cons (name, NULL,
-                    class_binding_level->class_shadowed);
-      /* Record the value we are binding NAME to so that we can know
-        what to pop later.  */
-      TREE_TYPE (class_binding_level->class_shadowed) = x;
-      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
-    }
+    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
 
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);
 }
@@ -2945,11 +2986,6 @@ do_class_using_decl (tree decl)
   return value;
 }
 
-void
-set_class_shadows (tree shadows)
-{
-  class_binding_level->class_shadowed = shadows;
-}
 \f
 /* Return the binding value for name in scope.  */
 
@@ -4796,6 +4832,41 @@ struct cxx_saved_binding GTY(())
    scope isn't enough, because more binding levels may be pushed.  */
 struct saved_scope *scope_chain;
 
+/* If ID is not already in the SEARCH_BINDINGS, prepend its binding
+   information to OLD_BINDINGS.  Returns the new OLD_BINDINGS
+   list.  */
+
+static cxx_saved_binding *
+store_binding (tree id,
+              cxx_saved_binding *old_bindings,
+              cxx_saved_binding *search_bindings)
+{
+  cxx_saved_binding *saved;
+  cxx_saved_binding *t1;
+
+  if (!id
+      /* Note that we may have an IDENTIFIER_CLASS_VALUE even when
+        we have no IDENTIFIER_BINDING if we have left the class
+        scope, but cached the class-level declarations.  */
+      || !(IDENTIFIER_BINDING (id) || IDENTIFIER_CLASS_VALUE (id)))
+     return old_bindings;
+
+  for (t1 = search_bindings; t1; t1 = t1->previous)
+    if (t1->identifier == id)
+     return old_bindings;
+
+  my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135);
+  saved = cxx_saved_binding_make ();
+  saved->previous = old_bindings;
+  saved->identifier = id;
+  saved->binding = IDENTIFIER_BINDING (id);
+  saved->class_value = IDENTIFIER_CLASS_VALUE (id);;
+  saved->real_type_value = REAL_IDENTIFIER_TYPE_VALUE (id);
+  IDENTIFIER_BINDING (id) = NULL;
+  IDENTIFIER_CLASS_VALUE (id) = NULL_TREE;
+  return saved;
+}
+
 static cxx_saved_binding *
 store_bindings (tree names, cxx_saved_binding *old_bindings)
 {
@@ -4806,41 +4877,38 @@ store_bindings (tree names, cxx_saved_binding *old_bindings)
   for (t = names; t; t = TREE_CHAIN (t))
     {
       tree id;
-      cxx_saved_binding *saved;
-      cxx_saved_binding *t1;
 
       if (TREE_CODE (t) == TREE_LIST)
        id = TREE_PURPOSE (t);
       else
        id = DECL_NAME (t);
 
-      if (!id
-         /* Note that we may have an IDENTIFIER_CLASS_VALUE even when
-            we have no IDENTIFIER_BINDING if we have left the class
-            scope, but cached the class-level declarations.  */
-         || !(IDENTIFIER_BINDING (id) || IDENTIFIER_CLASS_VALUE (id)))
-       continue;
-
-      for (t1 = search_bindings; t1; t1 = t1->previous)
-       if (t1->identifier == id)
-         goto skip_it;
-
-      my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135);
-      saved = cxx_saved_binding_make ();
-      saved->previous = old_bindings;
-      saved->identifier = id;
-      saved->binding = IDENTIFIER_BINDING (id);
-      saved->class_value = IDENTIFIER_CLASS_VALUE (id);;
-      saved->real_type_value = REAL_IDENTIFIER_TYPE_VALUE (id);
-      IDENTIFIER_BINDING (id) = NULL;
-      IDENTIFIER_CLASS_VALUE (id) = NULL_TREE;
-      old_bindings = saved;
-    skip_it:
-      ;
+      old_bindings 
+       = store_binding (id, old_bindings, search_bindings);
     }
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, old_bindings);
 }
 
+/* Like store_bindings, but NAMES is a vector of cp_class_binding
+   objects, rather than a TREE_LIST.  */
+
+static cxx_saved_binding *
+store_class_bindings (VEC(cp_class_binding) *names, 
+                     cxx_saved_binding *old_bindings)
+{
+  size_t i;
+  cp_class_binding *cb;
+  cxx_saved_binding *search_bindings = old_bindings;
+
+  timevar_push (TV_NAME_LOOKUP);
+  for (i = 0; 
+       (cb = VEC_iterate(cp_class_binding, names, i));
+       ++i)
+    old_bindings 
+      = store_binding (cb->identifier, old_bindings, search_bindings);
+  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, old_bindings);
+}
+
 void
 push_to_top_level (void)
 {
@@ -4864,8 +4932,9 @@ push_to_top_level (void)
     need_pop = 0;
 
   old_bindings = NULL;
-  if (scope_chain && previous_class_type)
-    old_bindings = store_bindings (previous_class_values, old_bindings);
+  if (scope_chain && previous_class_level)
+    old_bindings = store_class_bindings (previous_class_level->class_shadowed,
+                                        old_bindings);
 
   /* Have to include the global scope, because class-scope decls
      aren't listed anywhere useful.  */
@@ -4884,7 +4953,7 @@ push_to_top_level (void)
       /* We also need to check class_shadowed to save class-level type
         bindings, since pushclass doesn't fill in b->names.  */
       if (b->kind == sk_class)
-       old_bindings = store_bindings (b->class_shadowed, old_bindings);
+       old_bindings = store_class_bindings (b->class_shadowed, old_bindings);
 
       /* Unwind type-value slots back to top level.  */
       for (t = b->type_shadowed; t; t = TREE_CHAIN (t))
@@ -4912,7 +4981,7 @@ pop_from_top_level (void)
 
   timevar_push (TV_NAME_LOOKUP); 
   /* Clear out class-level bindings cache.  */
-  if (previous_class_type)
+  if (previous_class_level)
     invalidate_class_lookup_cache ();
 
   current_lang_base = 0;
index 49046e893fe552410e078c961806bde4c4bb0447..1d1f09f789d5b35b1aa6ef64ab6d00657baf50c1 100644 (file)
@@ -117,6 +117,15 @@ typedef enum scope_kind {
                        "template <>", this scope is always empty.  */
 } scope_kind;
 
+typedef struct cp_class_binding GTY(())
+{
+  cxx_binding base;
+  /* The bound name.  */
+  tree identifier;
+} cp_class_binding;
+
+DEF_VEC_O(cp_class_binding);
+
 /* For each binding contour we allocate a binding_level structure
    which records the names defined in that contour.
    Contours include:
@@ -175,7 +184,7 @@ struct cp_binding_level GTY(())
        class_shadowed is a TREE_LIST.  The TREE_PURPOSE of each node
        is the name of an entity bound in the class.  The TREE_TYPE is
        the DECL bound by this name in the class.  */
-    tree class_shadowed;
+    VEC(cp_class_binding) *class_shadowed;
 
     /* Similar to class_shadowed, but for IDENTIFIER_TYPE_VALUE, and
        is used for all binding levels. In addition the TREE_VALUE is the
@@ -273,6 +282,7 @@ extern void keep_next_level (bool);
 extern bool is_ancestor (tree, tree);
 extern bool push_scope (tree);
 extern void pop_scope (tree);
+extern void push_binding_level (struct cp_binding_level *);
 \f
 extern void push_namespace (tree);
 extern void pop_namespace (void);
@@ -299,7 +309,6 @@ extern bool push_class_level_binding (tree, tree);
 extern void storetags (tree);
 extern tree getdecls (void);
 extern tree cp_namespace_decls (tree);
-extern void set_class_shadows (tree);
 extern void set_decl_namespace (tree, tree, bool);
 extern tree current_decl_namespace (void);
 extern void push_decl_namespace (tree);