]> gcc.gnu.org Git - gcc.git/commitdiff
hashtable.h (struct ht_identifier): Add data member "hash_value".
authorGabriel Dos Reis <gdr@integrable-solutions.net>
Sun, 18 May 2003 13:40:54 +0000 (13:40 +0000)
committerGabriel Dos Reis <gdr@gcc.gnu.org>
Sun, 18 May 2003 13:40:54 +0000 (13:40 +0000)
* hashtable.h (struct ht_identifier): Add data member "hash_value".
* hashtable.c (ht_lookup): Use it when searching, remember.
(ht_expand): Do not recompute.
* tree.h (IDENTIFIER_HASH_VALUE): New macro.

cp/
* cp-tree.h (struct lang_type_class): Replace data member tags
with hash-table nested_udts.
(CLASSTYPE_NESTED_UTDS): Rename from CLASSTYPE_TAGS.
* class.c (unreverse_member_declarations): Don't touch
CLASSTYPE_TAGS.
(pushclass): Use cxx_remember_type_decls.
* decl.c (struct cp_binding_level): Replace data member tags with
hash-table type_decls.
(pop_binding_level): Handle level->type_decls.
(kept_level_p): Adjust.
(poplevel): Remove unused local variable.
(bt_print_entry): New function.
(print_binding_level): Use it.
(push_namespace): Build current_binding_level->type_decls.
(maybe_process_template_type_declaration): Adjust.
(pushtag): Likewise.
(clear_anon_tags): Use binding_table_remove_anonymous_types.
(gettags): Remove.
(cxx_remember_type_decls):  Rename from storetags.  Adjust.
(lookup_tag): Use binding_table_find_anon_type.  Tidy.
(lookup_tag_reverse): Use binding_table_reverse_maybe_remap.
(cxx_init_decl_processing): Build global_binding_level->type_decls.
(store_parm_decls): Remove pointless code.
* name-lookup.c (free_binding_entry): New variable.
(ENTRY_INDEX): New macro.
(struct binding_table_s): New datatype.
(binding_entry_make): New function.
(binding_entry_free): Likewise.
(binding_table_construct): Likewise.
(binding_table_free): Likewise.
(binding_table_new): Likewise.
(binding_table_expand): Likewise.
(binding_table_insert): Likewise.
(binding_table_find): Likewise.
(binding_table_find_anon_type): Likewise.
(binding_table_reverse_maybe_remap): Likewise.
(binding_table_remove_anonymous_types): Likewise.
(binding_table_foreach): Likewise.
* name-lookup.h (binding_table): New type.
(binding_entry): Likewise.
(bt_foreach_proc): Likewise.
(struct binding_entry_s): New datatype.
(SCOPE_DEFAULT_HT_SIZE): New macro.
(CLASS_SCOPE_HT_SIZE): Likewise.
(NAMESPACE_ORDINARY_HT_SIZE): Likewise.
(NAMESPACE_STD_HT_SIZE): Likewise.
(GLOBAL_SCOPE_HT_SIZE): Likewise.
(binding_table_new): Declare.
(binding_table_free): Likewise.
(binding_table_insert): Likewise.
(binding_table_find_anon_type): Likewise.
(binding_table_reverse_maybe_remap): Likewise.
(binding_table_remove_anonymous_types): Likewise.
(binding_table_foreach): Likewise.
(binding_table_find): Likewise.
(cxx_remember_type_decls): Likewise.
* pt.c (bt_instantiate_type_proc): New function.
(do_type_instantiation): Use it.
* search.c (lookup_field_r): Use binding_table_find.

From-SVN: r66930

12 files changed:
gcc/ChangeLog
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
gcc/cp/pt.c
gcc/cp/search.c
gcc/hashtable.c
gcc/hashtable.h
gcc/tree.h

index 5b9436d8f1e3ceb0974415653ee5d3f58669a0a0..54b23920327ce81c6dae9b5ac16b793c9c23e6ea 100644 (file)
@@ -1,3 +1,10 @@
+2003-05-18  Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+       * hashtable.h (struct ht_identifier): Add data member "hash_value".
+       * hashtable.c (ht_lookup): Use it when searching, remember. 
+       (ht_expand): Do not recompute.
+       * tree.h (IDENTIFIER_HASH_VALUE): New macro.
+
 2003-05-18  Nathan Sidwell  <nathan@codesourcery.com>
 
        * gcov-io.c (gcov_read_bytes): Fix fread thinko.
index bf1c262afafa770c2b905d75e135720d2acf28e1..52267566d6cf1ea00b28bfeb45f470c868001926 100644 (file)
@@ -1,3 +1,65 @@
+2003-05-18  Gabriel Dos Reis  <gdr@integrable-solutions.net>
+
+       * cp-tree.h (struct lang_type_class): Replace data member tags
+       with hash-table nested_udts.
+       (CLASSTYPE_NESTED_UTDS): Rename from CLASSTYPE_TAGS.
+       * class.c (unreverse_member_declarations): Don't touch
+       CLASSTYPE_TAGS. 
+       (pushclass): Use cxx_remember_type_decls.
+       * decl.c (struct cp_binding_level): Replace data member tags with
+       hash-table type_decls.
+       (pop_binding_level): Handle level->type_decls.
+       (kept_level_p): Adjust.
+       (poplevel): Remove unused local variable.
+       (bt_print_entry): New function.
+       (print_binding_level): Use it.
+       (push_namespace): Build current_binding_level->type_decls.
+       (maybe_process_template_type_declaration): Adjust.
+       (pushtag): Likewise.
+       (clear_anon_tags): Use binding_table_remove_anonymous_types.
+       (gettags): Remove.
+       (cxx_remember_type_decls):  Rename from storetags.  Adjust.
+       (lookup_tag): Use binding_table_find_anon_type.  Tidy.
+       (lookup_tag_reverse): Use binding_table_reverse_maybe_remap.
+       (cxx_init_decl_processing): Build global_binding_level->type_decls.
+       (store_parm_decls): Remove pointless code.
+       * name-lookup.c (free_binding_entry): New variable.
+       (ENTRY_INDEX): New macro.
+       (struct binding_table_s): New datatype.
+       (binding_entry_make): New function.
+       (binding_entry_free): Likewise.
+       (binding_table_construct): Likewise.
+       (binding_table_free): Likewise.
+       (binding_table_new): Likewise.
+       (binding_table_expand): Likewise.
+       (binding_table_insert): Likewise.
+       (binding_table_find): Likewise.
+       (binding_table_find_anon_type): Likewise.
+       (binding_table_reverse_maybe_remap): Likewise.
+       (binding_table_remove_anonymous_types): Likewise.
+       (binding_table_foreach): Likewise.
+       * name-lookup.h (binding_table): New type.
+       (binding_entry): Likewise.
+       (bt_foreach_proc): Likewise.
+       (struct binding_entry_s): New datatype.
+       (SCOPE_DEFAULT_HT_SIZE): New macro.
+       (CLASS_SCOPE_HT_SIZE): Likewise.
+       (NAMESPACE_ORDINARY_HT_SIZE): Likewise.
+       (NAMESPACE_STD_HT_SIZE): Likewise.
+       (GLOBAL_SCOPE_HT_SIZE): Likewise.
+       (binding_table_new): Declare.
+       (binding_table_free): Likewise.
+       (binding_table_insert): Likewise.
+       (binding_table_find_anon_type): Likewise.
+       (binding_table_reverse_maybe_remap): Likewise.
+       (binding_table_remove_anonymous_types): Likewise.
+       (binding_table_foreach): Likewise.
+       (binding_table_find): Likewise.
+       (cxx_remember_type_decls): Likewise.
+       * pt.c (bt_instantiate_type_proc): New function.
+       (do_type_instantiation): Use it.
+       * search.c (lookup_field_r): Use binding_table_find.
+
 2003-05-18  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
 
        * semantics.c (perform_deferred_access_checks): Don't discard
index 773577d23e7b265efda4b94cda15915151a0afb9..a8a01886f88a37eda5b5f285521c333d6a42e6f4 100644 (file)
@@ -5226,7 +5226,6 @@ unreverse_member_declarations (tree t)
   /* The following lists are all in reverse order.  Put them in
      declaration order now.  */
   TYPE_METHODS (t) = nreverse (TYPE_METHODS (t));
-  CLASSTYPE_TAGS (t) = nreverse (CLASSTYPE_TAGS (t));
   CLASSTYPE_DECL_LIST (t) = nreverse (CLASSTYPE_DECL_LIST (t));
 
   /* Actually, for the TYPE_FIELDS, only the non TYPE_DECLs are in
@@ -5561,7 +5560,7 @@ pushclass (tree type, bool modify)
          unuse_fields (type);
        }
 
-      storetags (CLASSTYPE_TAGS (type));
+      cxx_remember_type_decls (CLASSTYPE_NESTED_UTDS (type));
     }
 }
 
index 6bb2e0ddc51fd6ec2b4b8c8aa1b216a102157216..0fecbea9929c5231a6e494ea5f1bb5ef67f1f1fe 100644 (file)
@@ -1098,7 +1098,7 @@ struct lang_type_class GTY(())
   tree vtables;
   tree typeinfo_var;
   tree vbases;
-  tree tags;
+  binding_table nested_udts;
   tree as_base;
   tree pure_virtuals;
   tree friend_classes;
@@ -1310,11 +1310,11 @@ struct lang_type GTY(())
 #define SET_CLASSTYPE_MARKED6(NODE)   SET_CLASSTYPE_MARKED_N (NODE, 5)
 #define CLEAR_CLASSTYPE_MARKED6(NODE) CLEAR_CLASSTYPE_MARKED_N (NODE, 5)
 
-/* A list of the nested tag-types (class, struct, union, or enum)
-   found within this class.  The TREE_PURPOSE of each node is the name
-   of the type; the TREE_VALUE is the type itself.  This list includes
-   nested member class templates.  */
-#define CLASSTYPE_TAGS(NODE)           (LANG_TYPE_CLASS_CHECK (NODE)->tags)
+/* A dictionary of the nested user-defined-types (class-types, or enums)
+   found within this class.  This table includes nested member class
+   templates.  */
+#define CLASSTYPE_NESTED_UTDS(NODE) \
+   (LANG_TYPE_CLASS_CHECK (NODE)->nested_udts)
 
 /* Nonzero if NODE has a primary base class, i.e., a base class with
    which it shares the virtual function table pointer.  */
index 4bec8a60368f1d3f521a291f3f11ec72003515ca..48f4a8cf58ea8e56f852214dbfb6cb518f1d6f1b 100644 (file)
@@ -331,15 +331,8 @@ struct cp_binding_level GTY(())
     /* A chain of VTABLE_DECL nodes.  */
     tree vtables; 
 
-    /* A list of structure, union and enum definitions, for looking up
-       tag names.
-       It is a chain of TREE_LIST nodes, each of whose TREE_PURPOSE is a name,
-       or NULL_TREE; and whose TREE_VALUE is a RECORD_TYPE, UNION_TYPE,
-       or ENUMERAL_TYPE node.
-
-       C++: the TREE_VALUE nodes can be simple types for
-       component_bindings.  */
-    tree tags;
+    /* A dictionary for looking up user-defined-types.  */
+    binding_table type_decls;
 
     /* A list of USING_DECL nodes.  */
     tree usings;
@@ -544,6 +537,10 @@ pop_binding_level (void)
     register struct cp_binding_level *level = current_binding_level;
     current_binding_level = current_binding_level->level_chain;
     level->level_chain = free_binding_level;
+    if (level->parm_flag == 2)
+      level->type_decls = NULL;
+    else
+      binding_table_free (level->type_decls);
 #if 0 /* defined(DEBUG_BINDING_LEVELS) */
     if (level->binding_depth != binding_depth)
       abort ();
@@ -678,7 +675,7 @@ kept_level_p (void)
   return (current_binding_level->blocks != NULL_TREE
          || current_binding_level->keep
          || current_binding_level->names != NULL_TREE
-         || (current_binding_level->tags != NULL_TREE
+         || (current_binding_level->type_decls != NULL
              && !current_binding_level->tag_transparent));
 }
 
@@ -1215,7 +1212,6 @@ poplevel (int keep, int reverse, int functionbody)
   tree decls;
   int tmp = functionbody;
   int real_functionbody;
-  tree tags;
   tree subblocks;
   tree block = NULL_TREE;
   tree decl;
@@ -1230,7 +1226,6 @@ poplevel (int keep, int reverse, int functionbody)
 
   real_functionbody = (current_binding_level->keep == 2
                       ? ((functionbody = 0), tmp) : functionbody);
-  tags = functionbody >= 0 ? current_binding_level->tags : 0;
   subblocks = functionbody >= 0 ? current_binding_level->blocks : 0;
 
   my_friendly_assert (!current_binding_level->class_shadowed,
@@ -1853,6 +1848,45 @@ wrapup_globals_for_namespace (tree namespace, void* data)
 static int no_print_functions = 0;
 static int no_print_builtins = 0;
 
+/* Called from print_binding_level through binding_table_foreach to
+   print the content of binding ENTRY.  DATA is a pointer to line offset
+   marker.  */
+static void
+bt_print_entry (binding_entry entry, void *data)
+{
+  int *p = (int *) data;
+  int len;
+
+  if (entry->name == NULL)
+    len = 3;
+  else if (entry->name == TYPE_IDENTIFIER (entry->type))
+    len = 2;
+  else
+    len = 4;
+    len = 4;
+
+  *p += len;
+
+  if (*p > 5)
+    {
+      fprintf (stderr, "\n\t");
+      *p = len;
+    }
+  if (entry->name == NULL)
+    {
+      print_node_brief (stderr, "<unnamed-typedef", entry->type, 0);
+      fprintf (stderr, ">");
+    }
+  else if (entry->name == TYPE_IDENTIFIER (entry->type))
+    print_node_brief (stderr, "", entry->type, 0);
+  else
+    {
+      print_node_brief (stderr, "<typedef", entry->name, 0);
+      print_node_brief (stderr, "", entry->type, 0);
+      fprintf (stderr, ">");
+    }
+}
+
 void
 print_binding_level (struct cp_binding_level* lvl)
 {
@@ -1898,38 +1932,11 @@ print_binding_level (struct cp_binding_level* lvl)
       if (i)
         fprintf (stderr, "\n");
     }
-  if (lvl->tags)
+  if (lvl->type_decls)
     {
       fprintf (stderr, " tags:\t");
       i = 0;
-      for (t = lvl->tags; t; t = TREE_CHAIN (t))
-       {
-         if (TREE_PURPOSE (t) == NULL_TREE)
-           len = 3;
-         else if (TREE_PURPOSE (t) == TYPE_IDENTIFIER (TREE_VALUE (t)))
-           len = 2;
-         else
-           len = 4;
-         i += len;
-         if (i > 5)
-           {
-             fprintf (stderr, "\n\t");
-             i = len;
-           }
-         if (TREE_PURPOSE (t) == NULL_TREE)
-           {
-             print_node_brief (stderr, "<unnamed-typedef", TREE_VALUE (t), 0);
-             fprintf (stderr, ">");
-           }
-         else if (TREE_PURPOSE (t) == TYPE_IDENTIFIER (TREE_VALUE (t)))
-           print_node_brief (stderr, "", TREE_VALUE (t), 0);
-         else
-           {
-             print_node_brief (stderr, "<typedef", TREE_PURPOSE (t), 0);
-             print_node_brief (stderr, "", TREE_VALUE (t), 0);
-             fprintf (stderr, ">");
-           }
-       }
+      binding_table_foreach (lvl->type_decls, bt_print_entry, &i);
       if (i)
        fprintf (stderr, "\n");
     }
@@ -2059,6 +2066,10 @@ push_namespace (tree name)
          pushlevel (0);
          declare_namespace_level ();
          NAMESPACE_LEVEL (d) = current_binding_level;
+          current_binding_level->type_decls =
+            binding_table_new (name == std_identifier
+                               ? NAMESPACE_STD_HT_SIZE
+                               : NAMESPACE_ORDINARY_HT_SIZE);
          VARRAY_TREE_INIT (current_binding_level->static_decls,
                            name != std_identifier ? 10 : 200,
                            "Static declarations");
@@ -2427,16 +2438,19 @@ maybe_process_template_type_declaration (tree type,
              && b->level_chain->parm_flag == 2)
            {
              finish_member_declaration (CLASSTYPE_TI_TEMPLATE (type));
-             /* Put this tag on the list of tags for the class, since
+             /* Put this UDT in the table of UDTs for the class, since
                 that won't happen below because B is not the class
                 binding level, but is instead the pseudo-global level.  */
-             b->level_chain->tags =
-               tree_cons (name, type, b->level_chain->tags);
+              if (b->level_chain->type_decls == NULL)
+                b->level_chain->type_decls =
+                  binding_table_new (SCOPE_DEFAULT_HT_SIZE);
+              binding_table_insert (b->level_chain->type_decls, name, type);
              if (!COMPLETE_TYPE_P (current_class_type))
                {
                  maybe_add_class_template_decl_list (current_class_type,
                                                      type, /*friend_p=*/0);
-                 CLASSTYPE_TAGS (current_class_type) = b->level_chain->tags;
+                 CLASSTYPE_NESTED_UTDS (current_class_type) =
+                    b->level_chain->type_decls;
                }
            }
        }
@@ -2526,7 +2540,9 @@ pushtag (tree name, tree type, int globalize)
                 || COMPLETE_TYPE_P (b->this_class))))
     b = b->level_chain;
 
-  b->tags = tree_cons (name, type, b->tags);
+  if (b->type_decls == NULL)
+    b->type_decls = binding_table_new (SCOPE_DEFAULT_HT_SIZE);
+  binding_table_insert (b->type_decls, name, type);
 
   if (name)
     {
@@ -2603,7 +2619,7 @@ pushtag (tree name, tree type, int globalize)
            {
              maybe_add_class_template_decl_list (current_class_type,
                                                  type, /*friend_p=*/0);
-             CLASSTYPE_TAGS (current_class_type) = b->tags;
+             CLASSTYPE_NESTED_UTDS (current_class_type) = b->type_decls;
            }
        }
     }
@@ -2643,14 +2659,13 @@ make_anon_name (void)
   return get_identifier (buf);
 }
 
-/* Clear the TREE_PURPOSE slot of tags which have anonymous typenames.
+/* Clear the TREE_PURPOSE slot of UTDs which have anonymous typenames.
    This keeps dbxout from getting confused.  */
 
 void
 clear_anon_tags (void)
 {
   register struct cp_binding_level *b;
-  register tree tags;
   static int last_cnt = 0;
 
   /* Fast out if no new anon names were declared.  */
@@ -2660,17 +2675,8 @@ clear_anon_tags (void)
   b = current_binding_level;
   while (b->tag_transparent)
     b = b->level_chain;
-  tags = b->tags;
-  while (tags)
-    {
-      /* A NULL purpose means we have already processed all tags
-        from here to the end of the list.  */
-      if (TREE_PURPOSE (tags) == NULL_TREE)
-       break;
-      if (ANON_AGGRNAME_P (TREE_PURPOSE (tags)))
-       TREE_PURPOSE (tags) = NULL_TREE;
-      tags = TREE_CHAIN (tags);
-    }
+  if (b->type_decls != NULL)
+    binding_table_remove_anonymous_types (b->type_decls);
   last_cnt = anon_cnt;
 }
 \f
@@ -5032,14 +5038,6 @@ getdecls (void)
   return current_binding_level->names;
 }
 
-/* Return the list of type-tags (for structs, etc) of the current level.  */
-
-tree
-gettags (void)
-{
-  return current_binding_level->tags;
-}
-
 /* Store the list of declarations of the current level.
    This is done for the parameter declarations of a function being defined,
    after they are modified in the light of any missing parameters.  */
@@ -5050,12 +5048,13 @@ storedecls (tree decls)
   current_binding_level->names = decls;
 }
 
-/* Similarly, store the list of tags of the current level.  */
-
+/* Set the current binding TABLE for type declarations..  This is a
+   temporary workaround of the fact that the data structure classtypes
+   does not currently carry its allocated cxx_scope structure.  */
 void
-storetags (tree tags)
+cxx_remember_type_decls (binding_table table)
 {
-  current_binding_level->tags = tags;
+  current_binding_level->type_decls = table;
 }
 \f
 /* Return the type that should be used when TYPE's name is preceded
@@ -5117,19 +5116,20 @@ lookup_tag (enum tree_code form, tree name,
   /* Nonzero if, we should look past a template parameter level, even
      if THISLEVEL_ONLY.  */
   int allow_template_parms_p = 1;
+  bool type_is_anonymous = ANON_AGGRNAME_P (name);
 
   timevar_push (TV_NAME_LOOKUP);
   for (level = binding_level; level; level = level->level_chain)
     {
       register tree tail;
-      if (ANON_AGGRNAME_P (name))
-       for (tail = level->tags; tail; tail = TREE_CHAIN (tail))
-         {
-           /* There's no need for error checking here, because
-              anon names are unique throughout the compilation.  */
-           if (TYPE_IDENTIFIER (TREE_VALUE (tail)) == name)
-             POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, TREE_VALUE (tail));
-         }
+      if (type_is_anonymous && level->type_decls != NULL)
+        {
+          tree type = binding_table_find_anon_type (level->type_decls, name);
+          /* There is no need for error checking here, because
+           anon names are unique throughout the compilation.  */
+          if (type != NULL)
+            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, type);
+        }
       else if (level->namespace_p)
        /* Do namespace lookup.  */
        for (tail = current_namespace; 1; tail = CP_DECL_CONTEXT (tail))
@@ -5171,22 +5171,22 @@ lookup_tag (enum tree_code form, tree name,
            if (thislevel_only || tail == global_namespace)
              POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
          }
-      else
-       for (tail = level->tags; tail; tail = TREE_CHAIN (tail))
-         {
-           if (TREE_PURPOSE (tail) == name)
-             {
-               enum tree_code code = TREE_CODE (TREE_VALUE (tail));
+      else if (level->type_decls != NULL)
+        {
+          binding_entry entry = binding_table_find (level->type_decls, name);
+          if (entry != NULL)
+            {
+              enum tree_code code = TREE_CODE (entry->type);
                
-               if (code != form
-                   && (form == ENUMERAL_TYPE || code == ENUMERAL_TYPE))
-                 {
-                   /* Definition isn't the kind we were looking for.  */
-                   error ("`%#D' redeclared as %C", TREE_VALUE (tail), form);
-                   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
-                 }
-               POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, TREE_VALUE (tail));
-             }
+              if (code != form
+                  && (form == ENUMERAL_TYPE || code == ENUMERAL_TYPE))
+                {
+                  /* Definition isn't the kind we were looking for.  */
+                  error ("`%#D' redeclared as %C", entry->type, form);
+                  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+                }
+              POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, entry->type);
+            }
          }
       if (thislevel_only && ! level->tag_transparent)
        {
@@ -5228,16 +5228,11 @@ lookup_tag_reverse (tree type, tree name)
   timevar_push (TV_NAME_LOOKUP);
   for (level = current_binding_level; level; level = level->level_chain)
     {
-      register tree tail;
-      for (tail = level->tags; tail; tail = TREE_CHAIN (tail))
-       {
-         if (TREE_VALUE (tail) == type)
-           {
-             if (name)
-               TREE_PURPOSE (tail) = name;
-             POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, TREE_PURPOSE (tail));
-           }
-       }
+      binding_entry entry = level->type_decls == NULL
+        ? NULL
+        : binding_table_reverse_maybe_remap (level->type_decls, type, name);
+      if (entry)
+        POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, entry->name);
     }
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
 }
@@ -6193,6 +6188,7 @@ cxx_init_decl_processing (void)
   /* Make the binding_level structure for global names.  */
   pushlevel (0);
   global_binding_level = current_binding_level;
+  global_binding_level->type_decls = binding_table_new (GLOBAL_SCOPE_HT_SIZE);
   /* The global level is the namespace level of ::.  */
   NAMESPACE_LEVEL (global_namespace) = global_binding_level;
   declare_namespace_level ();
@@ -13700,7 +13696,6 @@ store_parm_decls (tree current_function_parms)
         function.  This is all and only the PARM_DECLs that were
         pushed into scope by the loop above.  */
       DECL_ARGUMENTS (fndecl) = getdecls ();
-      storetags (gettags ());
     }
   else
     DECL_ARGUMENTS (fndecl) = NULL_TREE;
index 0e39a9ab561ec0ca4b4cef6f795f4599ee9748ee..bead072a7e2f489b2041e8598d009e31abb96ecf 100644 (file)
@@ -28,6 +28,241 @@ Boston, MA 02111-1307, USA.  */
 #include "name-lookup.h"
 #include "timevar.h"
 
+/* Compute the chain index of a binding_entry given the HASH value of its
+   name and the total COUNT of chains.  COUNT is assumed to be a power
+   of 2.  */
+#define ENTRY_INDEX(HASH, COUNT) (((HASH) >> 3) & ((COUNT) - 1))
+
+/* A free list of "binding_entry"s awaiting for re-use.  */
+static binding_entry GTY((deletable(""))) free_binding_entry;
+
+/* Create a binding_entry object for (NAME, TYPE).  */
+static inline binding_entry
+binding_entry_make (tree name, tree type)
+{
+  binding_entry entry;
+
+  if (free_binding_entry)
+    {
+      entry = free_binding_entry;
+      free_binding_entry = entry->chain;
+    }
+  else
+    entry = ggc_alloc (sizeof (struct binding_entry_s));
+
+  entry->name = name;
+  entry->type = type;
+
+  return entry;
+}
+
+/* Put ENTRY back on the free list.  */
+static inline void
+binding_entry_free (binding_entry entry)
+{
+  entry->chain = free_binding_entry;
+  free_binding_entry = entry;
+}
+
+/* The datatype used to implement the mapping from names to types at
+   a given scope.  */
+struct binding_table_s GTY(())
+{
+  /* Array of chains of "binding_entry"s  */
+  binding_entry * GTY((length ("%h.chain_count"))) chain;
+
+  /* The number of chains in this table.  This is the length of the
+     the member "chaiin" considered as an array.  */
+  size_t chain_count;
+
+  /* Number of "binding_entry"s in this table.  */
+  size_t entry_count;
+};
+
+/* Construct TABLE with an initial CHAIN_COUNT.  */
+static inline void
+binding_table_construct (binding_table table, size_t chain_count)
+{
+  table->chain_count = chain_count;
+  table->entry_count = 0;
+  table->chain = ggc_alloc_cleared
+    (table->chain_count * sizeof (binding_entry));
+}
+
+/* Free TABLE by making its entries ready for reuse. */
+void
+binding_table_free (binding_table table)
+{
+  size_t i;
+  if (table == NULL)
+    return;
+
+  for (i = 0; i < table->chain_count; ++i)
+    {
+      while (table->chain[i] != NULL)
+        {
+          binding_entry entry = table->chain[i];
+          table->chain[i] = entry->chain;
+          binding_entry_free (entry);
+        }
+    }
+  table->entry_count = 0;
+}
+
+/* Allocate a table with CHAIN_COUNT, assumed to be a power of two.  */
+binding_table
+binding_table_new (size_t chain_count)
+{
+  binding_table table = ggc_alloc (sizeof (struct binding_table_s));
+  binding_table_construct (table, chain_count);
+  return table;
+}
+
+/* Expand TABLE to twice its current chain_count.  */
+static void
+binding_table_expand (binding_table table)
+{
+  const size_t old_chain_count = table->chain_count;
+  const size_t old_entry_count = table->entry_count;
+  const size_t new_chain_count = 2 * old_chain_count;
+  binding_entry *old_chains = table->chain;
+  size_t i;
+
+  binding_table_construct (table, new_chain_count);
+  for (i = 0; i < old_chain_count; ++i)
+    {
+      binding_entry entry = old_chains[i];
+      for (; entry != NULL; entry = old_chains[i])
+        {
+          const unsigned int hash = IDENTIFIER_HASH_VALUE (entry->name);
+          const size_t j = ENTRY_INDEX (hash, new_chain_count);
+
+          old_chains[i] = entry->chain;
+          entry->chain = table->chain[j];
+          table->chain[j] = entry;
+        }
+    }
+  table->entry_count = old_entry_count;
+}
+
+/* Insert a binding for NAME to TYPe into TABLE.  */
+void
+binding_table_insert (binding_table table, tree name, tree type)
+{
+  const unsigned int hash = IDENTIFIER_HASH_VALUE (name);
+  const size_t i = ENTRY_INDEX (hash, table->chain_count);
+  binding_entry entry = binding_entry_make (name, type);
+
+  entry->chain = table->chain[i];
+  table->chain[i] = entry;
+  ++table->entry_count;
+
+  if (3 * table->chain_count < 5 * table->entry_count)
+    binding_table_expand (table);
+}
+
+/* Return the binding_entry, if any, that maps NAME.  */
+binding_entry
+binding_table_find (binding_table table, tree name)
+{
+  const unsigned int hash = IDENTIFIER_HASH_VALUE (name);
+  binding_entry entry = table->chain[ENTRY_INDEX (hash, table->chain_count)];
+
+  while (entry != NULL && entry->name != name)
+    entry = entry->chain;
+
+  return entry;
+}
+
+/* Return the binding_entry, if any, that maps name to an anonymous type.  */
+tree
+binding_table_find_anon_type (binding_table table, tree name)
+{
+  const unsigned int hash = IDENTIFIER_HASH_VALUE (name);
+  binding_entry entry = table->chain[ENTRY_INDEX (hash, table->chain_count)];
+
+  while (entry != NULL && TYPE_IDENTIFIER (entry->type) != name)
+    entry = entry->chain;
+
+  return entry ? entry->type : NULL;
+}
+
+/* Return the binding_entry, if any, that has TYPE as target.  If NAME
+   is non-null, then set the domain and rehash that entry.  */
+binding_entry
+binding_table_reverse_maybe_remap (binding_table table, tree type, tree name)
+{
+  const size_t chain_count = table->chain_count;
+  binding_entry entry = NULL;
+  binding_entry *p = NULL;
+  size_t i;
+
+  for (i = 0; i < chain_count && entry == NULL; ++i)
+    {
+      p = &table->chain[i];
+      while (*p != NULL && entry == NULL)
+        if ((*p)->type == type)
+          entry = *p;
+        else
+          p = &(*p)->chain;
+    }
+
+  if (entry != NULL && name != NULL && entry->name != name)
+    {
+      /* Remove the bucket from the previous chain.  */
+      *p = (*p)->chain;
+
+      /* Remap the name type to type.  */
+      i = ENTRY_INDEX (IDENTIFIER_HASH_VALUE (name), chain_count);
+      entry->chain = table->chain[i];
+      entry->name = name;
+      table->chain[i] = entry;
+    }
+
+  return entry;
+}
+
+/* Remove from TABLE all entries that map to anonymous enums or
+   class-types.  */
+void
+binding_table_remove_anonymous_types (binding_table table)
+{
+  const size_t chain_count = table->chain_count;
+  size_t i;
+
+  for (i = 0; i < chain_count; ++i)
+    {
+      binding_entry *p = &table->chain[i];
+
+      while (*p != NULL)
+        if (ANON_AGGRNAME_P ((*p)->name))
+          {
+            binding_entry e = *p;
+            *p = (*p)->chain;
+            --table->entry_count;
+            binding_entry_free (e);
+          }
+        else
+          p = &(*p)->chain;
+    }
+}
+
+/* Apply PROC -- with DATA -- to all entries in TABLE.  */
+void
+binding_table_foreach (binding_table table, bt_foreach_proc proc, void *data)
+{
+  const size_t chain_count = table->chain_count;
+  size_t i;
+
+  for (i = 0; i < chain_count; ++i)
+    {
+      binding_entry entry = table->chain[i];
+      for (; entry != NULL; entry = entry->chain)
+        proc (entry, data);
+    }
+}
+\f
+
 /* A free list of "cxx_binding"s, connected by their PREVIOUS.  */
 static GTY((deletable (""))) cxx_binding *free_bindings;
 
index f6a4131fe5b657ee3c65053f2640f28823a32ab5..1222f5e4a612cd9ebf9a4adb42482b56a3e5360f 100644 (file)
@@ -24,6 +24,39 @@ Boston, MA 02111-1307, USA.  */
 
 #include "c-common.h"
 
+/* The type of dictionary used to map names to types declared at
+   a given scope.  */
+typedef struct binding_table_s *binding_table;
+typedef struct binding_entry_s *binding_entry;
+
+/* The type of a routine repeatedly called by binding_table_foreach.  */
+typedef void (*bt_foreach_proc) (binding_entry, void *);
+
+struct binding_entry_s GTY(())
+{
+  binding_entry chain;
+  tree name;
+  tree type;
+};
+
+/* These macros indicate the initial chains count for binding_table.  */
+#define SCOPE_DEFAULT_HT_SIZE                        (1 << 3)
+#define CLASS_SCOPE_HT_SIZE                          (1 << 3)
+#define NAMESPACE_ORDINARY_HT_SIZE                   (1 << 5)
+#define NAMESPACE_STD_HT_SIZE                        (1 << 8)
+#define GLOBAL_SCOPE_HT_SIZE                         (1 << 8)
+
+extern binding_table binding_table_new (size_t);
+extern void binding_table_free (binding_table);
+extern void binding_table_insert (binding_table, tree, tree);
+extern tree binding_table_find_anon_type (binding_table, tree);
+extern binding_entry binding_table_reverse_maybe_remap (binding_table,
+                                                        tree, tree);
+extern void binding_table_remove_anonymous_types (binding_table);
+extern void binding_table_foreach (binding_table, bt_foreach_proc, void *);
+extern binding_entry binding_table_find (binding_table, tree);
+extern void cxx_remember_type_decls (binding_table);
+\f
 /* Datatype used to temporarily save C++ bindings (for implicit
    instantiations purposes and like).  Implemented in decl.c.  */
 typedef struct cxx_saved_binding cxx_saved_binding;
index efc37740b0c76f9fd5d9640da5ee0bf35e3f3d60..e7feab6de05cd00993307abde5fc2bd111d6e6a6 100644 (file)
@@ -5393,7 +5393,7 @@ instantiate_class_template (type)
        {
          if (TYPE_P (t))
            {
-             /* Build new CLASSTYPE_TAGS.  */
+             /* Build new CLASSTYPE_NESTED_UTDS.  */
 
              tree tag = t;
              tree name = TYPE_IDENTIFIER (tag);
@@ -5486,7 +5486,7 @@ instantiate_class_template (type)
                  /* If it is a TYPE_DECL for a class-scoped ENUMERAL_TYPE,
                     such a thing will already have been added to the field
                     list by tsubst_enum in finish_member_declaration in the
-                    CLASSTYPE_TAGS case above.  */
+                    CLASSTYPE_NESTED_UTDS case above.  */
                  if (!(TREE_CODE (r) == TYPE_DECL
                        && TREE_CODE (TREE_TYPE (r)) == ENUMERAL_TYPE
                        && TYPE_CONTEXT (TREE_TYPE (r)) == type))
@@ -10470,6 +10470,18 @@ mark_class_instantiated (t, extern_p)
     }
 }     
 
+/* Called from do_type_instantiation through binding_table_foreach to
+   do recursive instantiation for the type bound in ENTRY.   */
+static void
+bt_instantiate_type_proc (binding_entry entry, void *data)
+{
+  tree storage = *(tree *) data;
+
+  if (IS_AGGR_TYPE (entry->type)
+      && !uses_template_parms (CLASSTYPE_TI_ARGS (entry->type)))
+    do_type_instantiation (TYPE_MAIN_DECL (entry->type), storage, 0);
+}
+
 /* Perform an explicit instantiation of template class T.  STORAGE, if
    non-null, is the RID for extern, inline or static.  COMPLAIN is
    nonzero if this is called from the parser, zero if called recursively,
@@ -10610,10 +10622,9 @@ do_type_instantiation (t, storage, complain)
            instantiate_decl (tmp, /*defer_ok=*/1);
        }
 
-    for (tmp = CLASSTYPE_TAGS (t); tmp; tmp = TREE_CHAIN (tmp))
-      if (IS_AGGR_TYPE (TREE_VALUE (tmp))
-         && !uses_template_parms (CLASSTYPE_TI_ARGS (TREE_VALUE (tmp))))
-       do_type_instantiation (TYPE_MAIN_DECL (TREE_VALUE (tmp)), storage, 0);
+    if (CLASSTYPE_NESTED_UTDS (t))
+      binding_table_foreach (CLASSTYPE_NESTED_UTDS (t),
+                             bt_instantiate_type_proc, &storage);
   }
 }
 
index f9fa16641edce9102d41a4ec417344bcc1efde72..7bab0b1e0ba2c857af9d752b5492097214026c52 100644 (file)
@@ -1117,11 +1117,12 @@ lookup_field_r (tree binfo, void *data)
        }
       else
        nval = NULL_TREE;
-      if (!nval)
+      if (!nval && CLASSTYPE_NESTED_UTDS (type) != NULL)
        {
-         nval = purpose_member (lfi->name, CLASSTYPE_TAGS (type));
-         if (nval)
-           nval = TYPE_MAIN_DECL (TREE_VALUE (nval));
+          binding_entry e = binding_table_find (CLASSTYPE_NESTED_UTDS (type),
+                                                lfi->name);
+         if (e != NULL)
+           nval = TYPE_MAIN_DECL (e->type);
          else 
            return NULL_TREE;
        }
index 63df6ff96a062eaaf0fc8328af479edcb009cf58..b3f6404ba33a5414119313c1d93af171f286f381 100644 (file)
@@ -121,7 +121,8 @@ ht_lookup (table, str, len, insert)
       if (node == NULL)
        break;
 
-      if (HT_LEN (node) == len && !memcmp (HT_STR (node), str, len))
+      if (node->hash_value == hash && HT_LEN (node) == len
+          && !memcmp (HT_STR (node), str, len))
        {
          if (insert == HT_ALLOCED)
            /* The string we search for was placed at the end of the
@@ -141,6 +142,7 @@ ht_lookup (table, str, len, insert)
   table->entries[index] = node;
 
   HT_LEN (node) = len;
+  node->hash_value = hash;
   if (insert == HT_ALLOC)
     HT_STR (node) = obstack_copy0 (&table->stack, str, len);
   else
@@ -173,7 +175,7 @@ ht_expand (table)
       {
        unsigned int index, hash, hash2;
 
-       hash = calc_hash (HT_STR (*p), HT_LEN (*p));
+       hash = (*p)->hash_value;
        hash2 = ((hash * 17) & sizemask) | 1;
        index = hash & sizemask;
 
index 20445d7d321cc065f751bfa00901e758ffc26bb2..11e9893287dbf95cf45b509b3bdd9160f77c930e 100644 (file)
@@ -27,6 +27,7 @@ struct ht_identifier GTY(())
 {
   const unsigned char *str;
   unsigned int len;
+  unsigned int hash_value;
 };
 
 #define HT_LEN(NODE) ((NODE)->len)
index 060ecd1118911e719d24850c498209196b193baf..9b18558753db405226a84354db0d0425878401f3 100644 (file)
@@ -813,6 +813,8 @@ struct tree_vector GTY(())
   (IDENTIFIER_NODE_CHECK (NODE)->identifier.id.len)
 #define IDENTIFIER_POINTER(NODE) \
   ((const char *) IDENTIFIER_NODE_CHECK (NODE)->identifier.id.str)
+#define IDENTIFIER_HASH_VALUE(NODE) \
+  (IDENTIFIER_NODE_CHECK (NODE)->identifier.id.hash_value)
 
 /* Translate a hash table identifier pointer to a tree_identifier
    pointer, and vice versa.  */
This page took 0.125655 seconds and 5 git commands to generate.