decl.c (cp_binding_level::this_entity): Rename from this_class.
authorGabriel Dos Reis <gdr@integrable-solutions.net>
Sat, 31 May 2003 12:53:41 +0000 (12:53 +0000)
committerGabriel Dos Reis <gdr@gcc.gnu.org>
Sat, 31 May 2003 12:53:41 +0000 (12:53 +0000)
* decl.c (cp_binding_level::this_entity): Rename from this_class.
(cxx_scope_descriptor): New function.
(cxx_scope_debug): Likewise.
(push_binding_level): Use it.
(pop_binding_level): Likewise.
(suspend_binding_level): Likewise.
(resume_binding_level): Likewise.
(pushlevel_class): Adjust use of this_class.
(pushtag): Likewise.
(lookup_name_real): Likewise.
(global_scope_name): New variable.
(initialize_predefined_identifiers): Initialize it.
(push_namespace): Use it.
(make_cxx_scope): New function.
(pushlevel): Use it.
(pushlevel_class): Likewise.
(push_binding_level): Simplify.  Loose the last two arguments.
(make_binding_level): Remove.
(initial_push__namespace_scope): New function.
(push_namespace): Use it.  Simplify.
(cxx_init_decl_processing): Likewise.
(declare_namespace_level): Remove.

From-SVN: r67269

gcc/cp/ChangeLog
gcc/cp/decl.c

index 33ae807..ec071ae 100644 (file)
@@ -1,3 +1,28 @@
+2003-05-31  Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+       * decl.c (cp_binding_level::this_entity): Rename from this_class.
+       (cxx_scope_descriptor): New function.
+       (cxx_scope_debug): Likewise.
+       (push_binding_level): Use it.
+       (pop_binding_level): Likewise.
+       (suspend_binding_level): Likewise.
+       (resume_binding_level): Likewise.
+       (pushlevel_class): Adjust use of this_class.
+       (pushtag): Likewise.
+       (lookup_name_real): Likewise.
+       (global_scope_name): New variable.
+       (initialize_predefined_identifiers): Initialize it.
+       (push_namespace): Use it.
+       (make_cxx_scope): New function.
+       (pushlevel): Use it.
+       (pushlevel_class): Likewise.
+       (push_binding_level): Simplify.  Loose the last two arguments.
+       (make_binding_level): Remove.
+       (initial_push__namespace_scope): New function.
+       (push_namespace): Use it.  Simplify.
+       (cxx_init_decl_processing): Likewise. 
+       (declare_namespace_level): Remove.
+
 2003-05-31  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
 
        PR c++/10956
index ec302ae..4355df5 100644 (file)
@@ -55,13 +55,10 @@ Boston, MA 02111-1307, USA.  */
 static tree grokparms (tree);
 static const char *redeclaration_error_message (tree, tree);
 
-static void push_binding_level (struct cp_binding_level *, int,
-                               int);
+static void push_binding_level (cxx_scope *);
 static void pop_binding_level (void);
 static void suspend_binding_level (void);
 static void resume_binding_level (struct cp_binding_level *);
-static struct cp_binding_level *make_binding_level (void);
-static void declare_namespace_level (void);
 static int decl_jump_unsafe (tree);
 static void storedecls (tree);
 static void require_complete_types_for_parms (tree);
@@ -203,6 +200,9 @@ tree cp_global_trees[CPTI_MAX];
 
 static GTY(()) tree global_type_node;
 
+/* The node that holds the "name" of the global scope.  */
+static GTY(()) tree global_scope_name;
+
 /* Used only for jumps to as-yet undefined labels, since jumps to
    defined labels can have their validity checked immediately.  */
 
@@ -358,8 +358,9 @@ struct cp_binding_level GTY(())
        that were entered and exited one level down.  */
     tree blocks;
 
-    /* The _TYPE node for this level, if parm_flag == 2.  */
-    tree this_class;
+    /* The entity (namespace, class, function) the scope of which this
+       binding contour corresponds to.  Otherwise NULL.  */
+    tree this_entity;
 
     /* The binding level which this one is contained in (inherits from).  */
     struct cp_binding_level *level_chain;
@@ -464,27 +465,84 @@ indent (int depth)
 
 static tree pushdecl_with_scope        (tree, struct cp_binding_level *);
 
+/* Return a string describing the kind of SCOPE we have.  */
+static const char *
+cxx_scope_descriptor (cxx_scope *scope)
+{
+  const char *desc;
+
+  if (scope->namespace_p)
+    desc = "namespace-scope";
+  else if (scope->parm_flag == 1)
+    desc = "function-prototype-scope";
+  else if (scope->parm_flag == 2)
+    desc = "class-scope";
+  else if (scope->is_for_scope)
+    desc = "for-scope";
+  else if (scope->is_try_scope)
+    desc = "try-scope";
+  else if (scope->is_catch_scope)
+    desc = "catch-scope";
+  else if (scope->template_spec_p)
+    desc = "template-explicit-spec-scope";
+  else if (scope->template_parms_p)
+    desc = "template-prototype-scope";
+  else
+    desc = "block-scope";
+
+  return desc;
+}
+
+/* Output a debugging information about SCOPE when performning
+   ACTION at LINE.  */
 static void
-push_binding_level (struct cp_binding_level *newlevel, 
-                    int tag_transparent, 
-                    int keep)
+cxx_scope_debug (cxx_scope *scope, int line, const char *action)
+{
+  const char *desc = cxx_scope_descriptor (scope);
+  if (scope->this_entity)
+    verbatim ("%s %s(%E) %p %d\n", action, desc,
+              scope->this_entity, (void *) scope, line);
+  else
+    verbatim ("%s %s %p %d\n", action, desc, (void *) scope, line);
+}
+
+/* Construct a scope that may be TAG-TRANSPARENT, the sub-blocks of
+   which may be KEPT.  */
+static inline cxx_scope *
+make_cxx_scope (bool tag_transparent, int keep)
+{
+  cxx_scope *scope;
+  
+  /* Reuse or create a struct for this binding level.  */
+  if (!ENABLE_SCOPE_CHECKING && free_binding_level)
+    {
+      scope = free_binding_level;
+      free_binding_level = scope->level_chain;
+    }
+  else
+    scope = ggc_alloc (sizeof (cxx_scope));
+
+  memset (scope, 0, sizeof (cxx_scope));
+  scope->tag_transparent = tag_transparent;
+  scope->keep = keep;
+  scope->more_cleanups_ok = true;
+
+  return scope;
+}
+
+static void
+push_binding_level (cxx_scope *newlevel)
 {
   /* Add this level to the front of the chain (stack) of levels that
      are active.  */
-  memset ((char*) newlevel, 0, sizeof (struct cp_binding_level));
   newlevel->level_chain = current_binding_level;
   current_binding_level = newlevel;
-  newlevel->tag_transparent = tag_transparent;
-  newlevel->more_cleanups_ok = 1;
 
-  newlevel->keep = keep;
   if (ENABLE_SCOPE_CHECKING)
     {
       newlevel->binding_depth = binding_depth;
       indent (binding_depth);
-      verbatim ("push %s level %p line %d\n",
-                (is_class_level) ? "class" : "block",
-                (void *) newlevel, input_line);
+      cxx_scope_debug (newlevel, input_location.line, "push");
       is_class_level = 0;
       binding_depth++;
     }
@@ -516,9 +574,7 @@ pop_binding_level (void)
   if (ENABLE_SCOPE_CHECKING)
     {
       indent (--binding_depth);
-      verbatim ("pop  %s level %p line %d\n",
-                (is_class_level) ? "class" : "block",
-                (void*) current_binding_level, input_line);
+      cxx_scope_debug (current_binding_level, input_location.line, "pop");
       if (is_class_level != (current_binding_level == class_binding_level))
         {
           indent (binding_depth);
@@ -556,9 +612,7 @@ suspend_binding_level (void)
   if (ENABLE_SCOPE_CHECKING)
     {
       indent (--binding_depth);
-      verbatim ("suspend  %s level %p line %d\n",
-                (is_class_level) ? "class" : "block",
-                (void *) current_binding_level, input_line);
+      cxx_scope_debug (current_binding_level, input_location.line, "suspend");
       if (is_class_level != (current_binding_level == class_binding_level))
         {
           indent (binding_depth);
@@ -584,23 +638,12 @@ resume_binding_level (struct cp_binding_level* b)
     {
       b->binding_depth = binding_depth;
       indent (binding_depth);
-      verbatim ("resume %s level %p line %d\n",
-                (is_class_level) ? "class" : "block", b, input_line);
+      cxx_scope_debug (b, input_location.line, "resume");
       is_class_level = 0;
       binding_depth++;
     }
 }
 \f
-/* Create a new `struct cp_binding_level'.  */
-
-static
-struct cp_binding_level *
-make_binding_level (void)
-{
-  /* NOSTRICT */
-  return (struct cp_binding_level *) ggc_alloc (sizeof (struct cp_binding_level));
-}
-
 /* Nonzero if we are currently in the global binding level.  */
 
 int
@@ -671,12 +714,6 @@ kept_level_p (void)
              && !current_binding_level->tag_transparent));
 }
 
-static void
-declare_namespace_level (void)
-{
-  current_binding_level->namespace_p = 1;
-}
-
 /* Returns nonzero if this scope was created to store template
    parameters.  */
 
@@ -787,21 +824,10 @@ set_class_shadows (tree shadows)
 void
 pushlevel (int tag_transparent)
 {
-  struct cp_binding_level *newlevel;
-
   if (cfun && !doing_semantic_analysis_p ())
     return;
 
-  /* Reuse or create a struct for this binding level.  */
-  if (!ENABLE_SCOPE_CHECKING && free_binding_level)
-    {
-      newlevel = free_binding_level;
-      free_binding_level = free_binding_level->level_chain;
-    }
-  else
-    newlevel = make_binding_level ();
-
-  push_binding_level (newlevel, tag_transparent, keep_next_level_flag);
+  push_binding_level (make_cxx_scope (tag_transparent, keep_next_level_flag));
   keep_next_level_flag = 0;
 }
 
@@ -1550,25 +1576,14 @@ set_block (tree block ATTRIBUTE_UNUSED )
 void
 pushlevel_class (void)
 {
-  register struct cp_binding_level *newlevel;
-
-  /* Reuse or create a struct for this binding level.  */
-  if (!ENABLE_SCOPE_CHECKING && free_binding_level)
-    {
-      newlevel = free_binding_level;
-      free_binding_level = free_binding_level->level_chain;
-    }
-  else
-    newlevel = make_binding_level ();
-
   if (ENABLE_SCOPE_CHECKING)
     is_class_level = 1;
 
-  push_binding_level (newlevel, 0, 0);
+  push_binding_level (make_cxx_scope (false, 0));
 
   class_binding_level = current_binding_level;
   class_binding_level->parm_flag = 2;
-  class_binding_level->this_class = current_class_type;
+  class_binding_level->this_entity = current_class_type;
 }
 
 /* ...and a poplevel for class declarations.  */
@@ -1988,6 +2003,31 @@ print_binding_stack (void)
    the identifier is polymorphic, with three possible values:
    NULL_TREE, a list of "cxx_binding"s.  */
 
+
+/* Push the initial binding contour of NAMESPACE-scope.  Any subsequent
+   push of NS is actually a resume.  */
+static void
+initial_push_namespace_scope (tree ns)
+{
+  tree name = DECL_NAME (ns);
+  cxx_scope *scope;
+
+  pushlevel (0);
+  scope = current_binding_level;
+  scope->namespace_p = true;
+  scope->type_decls = binding_table_new (name == std_identifier
+                                         ? NAMESPACE_STD_HT_SIZE
+                                         : (name == global_scope_name
+                                            ? GLOBAL_SCOPE_HT_SIZE
+                                            : NAMESPACE_ORDINARY_HT_SIZE));
+  VARRAY_TREE_INIT (scope->static_decls,
+                    name == std_identifier || name == global_scope_name
+                    ? 200 : 10,
+                    "Static declarations");
+  scope->this_entity = ns;
+  NAMESPACE_LEVEL (ns) = scope;
+}
+
 /* Push into the scope of the NAME namespace.  If NAME is NULL_TREE, then we
    select a name that is unique to this compilation unit.  */
 
@@ -1997,17 +2037,16 @@ push_namespace (tree name)
   tree d = NULL_TREE;
   int need_new = 1;
   int implicit_use = 0;
-  int global = 0;
 
   timevar_push (TV_NAME_LOOKUP);
   
-  if (!global_namespace)
-    {
-      /* This must be ::.  */
-      my_friendly_assert (name == get_identifier ("::"), 377);
-      global = 1;
-    }
-  else if (!name)
+  /* We should not get here if the global_namespace is not yet constructed
+     nor if NAME designates the global namespace:  The global scope is
+     constructed elsewhere.  */
+  my_friendly_assert (global_namespace != NULL && name != global_scope_name,
+                      20030531);
+
+  if (!name)
     {
       /* The name of anonymous namespace is unique for the translation
          unit.  */
@@ -2040,23 +2079,9 @@ push_namespace (tree name)
     {
       /* Make a new namespace, binding the name to it.  */
       d = build_lang_decl (NAMESPACE_DECL, name, void_type_node);
-      /* The global namespace is not pushed, and the global binding
-        level is set elsewhere.  */
-      if (!global)
-       {
-         DECL_CONTEXT (d) = FROB_CONTEXT (current_namespace);
-         d = pushdecl (d);
-         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");
-       }
+      DECL_CONTEXT (d) = FROB_CONTEXT (current_namespace);
+      d = pushdecl (d);
+      initial_push_namespace_scope (d);
     }
   else
     resume_binding_level (NAMESPACE_LEVEL (d));
@@ -2518,7 +2543,7 @@ pushtag (tree name, tree type, int globalize)
                    of a static member variable. We allow this when
                    not pedantic, and it is particularly useful for
                    type punning via an anonymous union.  */
-                || COMPLETE_TYPE_P (b->this_class))))
+                || COMPLETE_TYPE_P (b->this_entity))))
     b = b->level_chain;
 
   if (b->type_decls == NULL)
@@ -5829,7 +5854,7 @@ lookup_name_real (tree name, int prefer_type, int nonclass,
            continue;
          
          /* Lookup the conversion operator in the class.  */
-         class_type = level->this_class;
+         class_type = level->this_entity;
          operators = lookup_fnfields (class_type, name, /*protect=*/0);
          if (operators)
            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, operators);
@@ -6104,6 +6129,7 @@ initialize_predefined_identifiers (void)
     { VTABLE_PFN_NAME, &pfn_identifier, 0 },
     { "_vptr", &vptr_identifier, 0 },
     { "__vtt_parm", &vtt_parm_identifier, 0 },
+    { "::", &global_scope_name, 0 },
     { "std", &std_identifier, 0 },
     { NULL, NULL, 0 }
   };
@@ -6136,10 +6162,15 @@ cxx_init_decl_processing (void)
   /* Create the global variables.  */
   push_to_top_level ();
 
+  current_function_decl = NULL_TREE;
+  current_binding_level = NULL_BINDING_LEVEL;
+  free_binding_level = NULL_BINDING_LEVEL;
   /* Enter the global namespace.  */
   my_friendly_assert (global_namespace == NULL_TREE, 375);
-  push_namespace (get_identifier ("::"));
-  global_namespace = current_namespace;
+  global_namespace = build_lang_decl (NAMESPACE_DECL, global_scope_name,
+                                      void_type_node);
+  initial_push_namespace_scope (global_namespace);
+
   current_lang_name = NULL_TREE;
 
   /* Adjust various flags based on command-line settings.  */
@@ -6165,26 +6196,11 @@ cxx_init_decl_processing (void)
   /* Initially, C.  */
   current_lang_name = lang_name_c;
 
-  current_function_decl = NULL_TREE;
-  current_binding_level = NULL_BINDING_LEVEL;
-  free_binding_level = NULL_BINDING_LEVEL;
-
   build_common_tree_nodes (flag_signed_char);
 
   error_mark_list = build_tree_list (error_mark_node, error_mark_node);
   TREE_TYPE (error_mark_list) = error_mark_node;
 
-  /* Make the binding_level structure for global names.  */
-  pushlevel (0);
-  current_binding_level->type_decls = binding_table_new (GLOBAL_SCOPE_HT_SIZE);
-  /* The global level is the namespace level of ::.  */
-  NAMESPACE_LEVEL (global_namespace) = current_binding_level;
-  declare_namespace_level ();
-
-  VARRAY_TREE_INIT (current_binding_level->static_decls,
-                   200,
-                   "Static declarations");
-
   /* Create the `std' namespace.  */
   push_namespace (std_identifier);
   std_node = current_namespace;