This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH to decl.c: Factor debug code


Hi,

  This is another fall out of the name-lookup performance work, when debugging.

This patches 

  1) factors out code duplicated in pushlevel and pushlevel_class;

  2) factors out code duplicated in push_namespace and
      cxx_init_decl_processing for handling global scope and
      constructing ordinary namespace.
     There were a comment in push_namespace saying that
     global_namespace is contructed elsewhere.  This patch makes that
     much more appearant in push_namespace.

  3) improves the debugging facilities for binding contours.  Now
     scopes other than class-scope or block-scope are accurately reported.

Bootstrapped and resgtested on an i686-pc-linux-gnu.

OK for mainline?
OK for branch?

-- Gaby

2003-05-30  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.
	(cxx_scope_make): New function.
	(pushlevel): Use it.
	(pushlevel_class): Likewise.
	(push_binding_level): Simplify.  Loose the last two arguments.
	(make_binding_level): Remove.
	(cxx_original_namespace_scope_push): New function.
	(push_namespace): Use it.  Simplify.
	(cxx_init_decl_processing): Likewise. 
	(declare_namespace_level): Remove.

Index: cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.776.2.20
diff -p -r1.776.2.20 cp-tree.h
*** cp-tree.h	19 May 2003 23:29:36 -0000	1.776.2.20
--- cp-tree.h	30 May 2003 00:58:34 -0000
*************** struct diagnostic_context;
*** 218,223 ****
--- 218,224 ----
    (flag_abi_version == 0 || flag_abi_version >= (N))
  
  
+ typedef struct cp_binding_level cxx_scope;
  /* 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: decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.965.2.46
diff -p -r1.965.2.46 decl.c
*** decl.c	29 May 2003 19:10:01 -0000	1.965.2.46
--- decl.c	30 May 2003 00:58:42 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 54,66 ****
  static tree grokparms				PARAMS ((tree));
  static const char *redeclaration_error_message	PARAMS ((tree, tree));
  
! static void push_binding_level PARAMS ((struct cp_binding_level *, int,
! 				      int));
  static void pop_binding_level PARAMS ((void));
  static void suspend_binding_level PARAMS ((void));
  static void resume_binding_level PARAMS ((struct cp_binding_level *));
- static struct cp_binding_level *make_binding_level PARAMS ((void));
- static void declare_namespace_level PARAMS ((void));
  static int decl_jump_unsafe PARAMS ((tree));
  static void storedecls PARAMS ((tree));
  static void require_complete_types_for_parms PARAMS ((tree));
--- 54,63 ----
  static tree grokparms				PARAMS ((tree));
  static const char *redeclaration_error_message	PARAMS ((tree, tree));
  
! static void push_binding_level (cxx_scope *);
  static void pop_binding_level PARAMS ((void));
  static void suspend_binding_level PARAMS ((void));
  static void resume_binding_level PARAMS ((struct cp_binding_level *));
  static int decl_jump_unsafe PARAMS ((tree));
  static void storedecls PARAMS ((tree));
  static void require_complete_types_for_parms PARAMS ((tree));
*************** tree cp_global_trees[CPTI_MAX];
*** 203,208 ****
--- 200,208 ----
  
  static GTY(()) tree global_type_node;
  
+ /* The node that holds the "name" of the global scope.   */
+ static GTY(()) tree global_scope_name;
+ 
  /* Expect only namespace names now.  */
  static int only_namespace_names;
  
*************** struct cp_binding_level GTY(())
*** 604,611 ****
         that were entered and exited one level down.  */
      tree blocks;
  
!     /* The _TYPE node for this level, if parm_flag == 2.  */
!     tree this_class;
  
      /* The binding level which this one is contained in (inherits from).  */
      struct cp_binding_level *level_chain;
--- 604,612 ----
         that were entered and exited one level down.  */
      tree blocks;
  
!     /* 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;
*************** indent (unsigned depth)
*** 712,740 ****
      putc (' ', stderr);
  }
  
  static tree pushdecl_with_scope	PARAMS ((tree, struct cp_binding_level *));
  
  static void
! push_binding_level (newlevel, tag_transparent, keep)
!      struct cp_binding_level *newlevel;
!      int tag_transparent, keep;
  {
    /* 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, lineno);
        is_class_level = 0;
        binding_depth++;
      }
--- 713,798 ----
      putc (' ', stderr);
  }
  
+ /* 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
+ 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 *
+ cxx_scope_make (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 tree pushdecl_with_scope	PARAMS ((tree, struct cp_binding_level *));
  
  static void
! push_binding_level (cxx_scope *newlevel)
  {
    /* Add this level to the front of the chain (stack) of levels that
       are active.  */
    newlevel->level_chain = current_binding_level;
    current_binding_level = newlevel;
  
    if (ENABLE_SCOPE_CHECKING)
      {
        newlevel->binding_depth = binding_depth;
        indent (binding_depth);
!       cxx_scope_debug (newlevel, lineno, "push");
        is_class_level = 0;
        binding_depth++;
      }
*************** pop_binding_level ()
*** 766,774 ****
    if (ENABLE_SCOPE_CHECKING)
      {
        indent (--binding_depth);
!       verbatim ("pop  %s level %p line %d\n",
!                 (is_class_level) ? "class" : "block",
!                 (void *) current_binding_level, lineno);
        if (is_class_level != (current_binding_level == class_binding_level))
          {
            indent (binding_depth);
--- 824,830 ----
    if (ENABLE_SCOPE_CHECKING)
      {
        indent (--binding_depth);
!       cxx_scope_debug (current_binding_level, lineno, "pop");
        if (is_class_level != (current_binding_level == class_binding_level))
          {
            indent (binding_depth);
*************** suspend_binding_level ()
*** 804,812 ****
    if (ENABLE_SCOPE_CHECKING)
      {
        indent (--binding_depth);
!       verbatim("suspend  %s level %p line %d\n",
!                (is_class_level) ? "class" : "block",
!                (void *) current_binding_level, lineno);
        if (is_class_level != (current_binding_level == class_binding_level))
          {
            indent (binding_depth);
--- 860,866 ----
    if (ENABLE_SCOPE_CHECKING)
      {
        indent (--binding_depth);
!       cxx_scope_debug (current_binding_level, lineno, "suspend");
        if (is_class_level != (current_binding_level == class_binding_level))
          {
            indent (binding_depth);
*************** resume_binding_level (b)
*** 833,855 ****
      {
        b->binding_depth = binding_depth;
        indent (binding_depth);
!       verbatim ("resume %s level %p line %d\n",
!                 (is_class_level) ? "class" : "block", (void *) b, lineno);
        is_class_level = 0;
        binding_depth++;
      }
  }
  
- /* Create a new `struct cp_binding_level'.  */
- 
- static
- struct cp_binding_level *
- make_binding_level ()
- {
-   /* NOSTRICT */
-   return (struct cp_binding_level *) ggc_alloc (sizeof (struct cp_binding_level));
- }
- 
  /* Nonzero if we are currently in the global binding level.  */
  
  int
--- 887,898 ----
      {
        b->binding_depth = binding_depth;
        indent (binding_depth);
!       cxx_scope_debug (b, lineno, "resume");
        is_class_level = 0;
        binding_depth++;
      }
  }
  
  /* Nonzero if we are currently in the global binding level.  */
  
  int
*************** kept_level_p ()
*** 921,932 ****
  	      && !current_binding_level->tag_transparent));
  }
  
- static void
- declare_namespace_level ()
- {
-   current_binding_level->namespace_p = 1;
- }
- 
  /* Returns nonzero if this scope was created to store template
     parameters.  */
  
--- 964,969 ----
*************** void
*** 1040,1060 ****
  pushlevel (tag_transparent)
       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);
    keep_next_level_flag = 0;
  }
  
--- 1077,1086 ----
  pushlevel (tag_transparent)
       int tag_transparent;
  {
    if (cfun && !doing_semantic_analysis_p ())
      return;
  
!   push_binding_level (cxx_scope_make (tag_transparent, keep_next_level_flag));
    keep_next_level_flag = 0;
  }
  
*************** set_block (block)
*** 1865,1889 ****
  void
  pushlevel_class ()
  {
-   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);
  
    class_binding_level = current_binding_level;
    class_binding_level->parm_flag = 2;
!   class_binding_level->this_class = current_class_type;
  }
  
  /* ...and a poplevel for class declarations.  */
--- 1891,1904 ----
  void
  pushlevel_class ()
  {
    if (ENABLE_SCOPE_CHECKING)
      is_class_level = 1;
  
!   push_binding_level (cxx_scope_make (false, 0));
  
    class_binding_level = current_binding_level;
    class_binding_level->parm_flag = 2;
!   class_binding_level->this_entity = current_class_type;
  }
  
  /* ...and a poplevel for class declarations.  */
*************** set_namespace_binding (name, scope, val)
*** 2428,2433 ****
--- 2443,2470 ----
    timevar_pop (TV_NAME_LOOKUP);
  }
  
+ static void
+ cxx_original_namespace_scope_push (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.  */
  
*************** push_namespace (name)
*** 2438,2454 ****
    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)
      {
        /* The name of anonymous namespace is unique for the translation
           unit.  */
--- 2475,2489 ----
    tree d = NULL_TREE;
    int need_new = 1;
    int implicit_use = 0;
    
    timevar_push (TV_NAME_LOOKUP);
! 
!   /* 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,
!                       20030529);
!   if (!name)
      {
        /* The name of anonymous namespace is unique for the translation
           unit.  */
*************** push_namespace (name)
*** 2481,2503 ****
      {
        /* 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");
! 	}
      }
    else
      resume_binding_level (NAMESPACE_LEVEL (d));
--- 2516,2524 ----
      {
        /* Make a new namespace, binding the name to it.  */
        d = build_lang_decl (NAMESPACE_DECL, name, void_type_node);
!       DECL_CONTEXT (d) = FROB_CONTEXT (current_namespace);
!       d = pushdecl (d);
!       cxx_original_namespace_scope_push (d);
      }
    else
      resume_binding_level (NAMESPACE_LEVEL (d));
*************** pushtag (name, type, globalize)
*** 2975,2981 ****
  		    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))))
      b = b->level_chain;
  
    if (b->type_decls == NULL)
--- 2996,3002 ----
  		    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_entity))))
      b = b->level_chain;
  
    if (b->type_decls == NULL)
*************** lookup_name_real (name, prefer_type, non
*** 6480,6486 ****
        /* Handle access control on types from enclosing or base classes.  */
        if (binding && ! yylex
  	  && BINDING_LEVEL (iter) && BINDING_LEVEL (iter)->parm_flag == 2)
! 	type_access_control (BINDING_LEVEL (iter)->this_class, binding);
  
        if (binding
  	  && (!val || !IMPLICIT_TYPENAME_TYPE_DECL_P (binding)))
--- 6501,6507 ----
        /* Handle access control on types from enclosing or base classes.  */
        if (binding && ! yylex
  	  && BINDING_LEVEL (iter) && BINDING_LEVEL (iter)->parm_flag == 2)
! 	type_access_control (BINDING_LEVEL (iter)->this_entity, binding);
  
        if (binding
  	  && (!val || !IMPLICIT_TYPENAME_TYPE_DECL_P (binding)))
*************** initialize_predefined_identifiers ()
*** 6794,6799 ****
--- 6815,6821 ----
      { 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 }
    };
*************** cxx_init_decl_processing ()
*** 6826,6835 ****
    /* Create the global variables.  */
    push_to_top_level ();
  
    /* Enter the global namespace.  */
    my_friendly_assert (global_namespace == NULL_TREE, 375);
!   push_namespace (get_identifier ("::"));
!   global_namespace = current_namespace;
    current_lang_name = NULL_TREE;
  
    /* Adjust various flags based on command-line settings.  */
--- 6848,6862 ----
    /* 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);
!   global_namespace = build_lang_decl (NAMESPACE_DECL, global_scope_name,
!                                       void_type_node);
!   cxx_original_namespace_scope_push (global_namespace);
! 
    current_lang_name = NULL_TREE;
  
    /* Adjust various flags based on command-line settings.  */
*************** cxx_init_decl_processing ()
*** 6855,6879 ****
    /* 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);
--- 6882,6891 ----


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]