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]

Re: [PATCH][C++] Fix PR29433, make C++ use a lot less time/memory


On Mon, 11 Dec 2006, Mark Mitchell wrote:

> Jason Merrill wrote:
> 
> > I guess that we were missing this diagnostic before by accident, because
> > of the different DECL_NAMEs for class template instantiations.  If we
> > want to avoid the memory usage for different DECL_NAMEs, I'd think you'd
> > have to hack around a lot to avoid giving this (correct) diagnostic here.
> 
> I don't think it would be too bad, but ...
> 
> > My inclination would be to make the change, and downgrade the error to
> > pedwarn.  There's no need for it to be a hard error.
> 
> ... that's a really good idea, since it gives users an escape hatch, but
> costs us nearly zero.
> 
> Richard, would you please make that change as part of your patch?

Ok, I'll remember.  I currently have the following, changes to debug
info and maybe diagnostics still missing.

Richard.


2006-12-11  Richard Guenther  <rguenther@suse.de>

	* pt.c (mangle_class_name_for_template): Remove.
	(classtype_mangled_name): Change to always return TYPE_IDENTIFIER.
	* class.c (note_name_declared_in_class): Make error a pedwarn.

	* g++.dg/warn/changes-meaning.C: New testcase.

Index: cp/pt.c
===================================================================
*** cp/pt.c	(revision 119733)
--- cp/pt.c	(working copy)
*************** static int push_tinst_level (tree);
*** 101,107 ****
  static void pop_tinst_level (void);
  static void reopen_tinst_level (tree);
  static tree classtype_mangled_name (tree);
- static char* mangle_class_name_for_template (const char *, tree, tree);
  static tree tsubst_initializer_list (tree, tree);
  static tree get_class_bindings (tree, tree, tree);
  static tree coerce_template_parms (tree, tree, tree, tsubst_flags_t,
--- 101,106 ----
*************** comp_template_args (tree oldargs, tree n
*** 4261,4381 ****
    return 1;
  }
  
- /* Given class template name and parameter list, produce a user-friendly name
-    for the instantiation.  */
- 
- static char *
- mangle_class_name_for_template (const char* name, tree parms, tree arglist)
- {
-   static struct obstack scratch_obstack;
-   static char *scratch_firstobj;
-   int i, nparms;
- 
-   if (!scratch_firstobj)
-     gcc_obstack_init (&scratch_obstack);
-   else
-     obstack_free (&scratch_obstack, scratch_firstobj);
-   scratch_firstobj = (char *) obstack_alloc (&scratch_obstack, 1);
- 
- #define ccat(C)	obstack_1grow (&scratch_obstack, (C));
- #define cat(S)	obstack_grow (&scratch_obstack, (S), strlen (S))
- 
-   cat (name);
-   ccat ('<');
-   nparms = TREE_VEC_LENGTH (parms);
-   arglist = INNERMOST_TEMPLATE_ARGS (arglist);
-   gcc_assert (nparms == TREE_VEC_LENGTH (arglist));
-   for (i = 0; i < nparms; i++)
-     {
-       tree parm;
-       tree arg;
- 
-       parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
-       arg = TREE_VEC_ELT (arglist, i);
- 
-       if (parm == error_mark_node)
- 	continue;
- 
-       if (i)
- 	ccat (',');
- 
-       if (TREE_CODE (parm) == TYPE_DECL)
- 	{
- 	  cat (type_as_string (arg, TFF_CHASE_TYPEDEF));
- 	  continue;
- 	}
-       else if (TREE_CODE (parm) == TEMPLATE_DECL)
- 	{
- 	  if (TREE_CODE (arg) == TEMPLATE_DECL)
- 	    {
- 	      /* Already substituted with real template.  Just output
- 		 the template name here */
- 	      tree context = DECL_CONTEXT (arg);
- 	      if (context)
- 		{
- 		  /* The template may be defined in a namespace, or
- 		     may be a member template.  */
- 		  gcc_assert (TREE_CODE (context) == NAMESPACE_DECL
- 			      || CLASS_TYPE_P (context));
- 		  cat (decl_as_string (DECL_CONTEXT (arg),
- 				      TFF_PLAIN_IDENTIFIER));
- 		  cat ("::");
- 		}
- 	      cat (IDENTIFIER_POINTER (DECL_NAME (arg)));
- 	    }
- 	  else
- 	    /* Output the parameter declaration.  */
- 	    cat (type_as_string (arg, TFF_CHASE_TYPEDEF));
- 	  continue;
- 	}
-       else
- 	gcc_assert (TREE_CODE (parm) == PARM_DECL);
- 
-       /* No need to check arglist against parmlist here; we did that
- 	 in coerce_template_parms, called from lookup_template_class.  */
-       cat (expr_as_string (arg, TFF_PLAIN_IDENTIFIER));
-     }
-   {
-     char *bufp = obstack_next_free (&scratch_obstack);
-     int offset = 0;
-     while (bufp[offset - 1] == ' ')
-       offset--;
-     obstack_blank_fast (&scratch_obstack, offset);
- 
-     /* B<C<char> >, not B<C<char>> */
-     if (bufp[offset - 1] == '>')
-       ccat (' ');
-   }
-   ccat ('>');
-   ccat ('\0');
-   return (char *) obstack_base (&scratch_obstack);
- }
- 
  static tree
  classtype_mangled_name (tree t)
  {
!   if (CLASSTYPE_TEMPLATE_INFO (t)
!       /* Specializations have already had their names set up in
! 	 lookup_template_class.  */
!       && !CLASSTYPE_TEMPLATE_SPECIALIZATION (t))
!     {
!       tree tmpl = most_general_template (CLASSTYPE_TI_TEMPLATE (t));
! 
!       /* For non-primary templates, the template parameters are
! 	 implicit from their surrounding context.  */
!       if (PRIMARY_TEMPLATE_P (tmpl))
! 	{
! 	  tree name = DECL_NAME (tmpl);
! 	  char *mangled_name = mangle_class_name_for_template
! 	    (IDENTIFIER_POINTER (name),
! 	     DECL_INNERMOST_TEMPLATE_PARMS (tmpl),
! 	     CLASSTYPE_TI_ARGS (t));
! 	  tree id = get_identifier (mangled_name);
! 	  IDENTIFIER_TEMPLATE (id) = name;
! 	  return id;
! 	}
!     }
! 
    return TYPE_IDENTIFIER (t);
  }
  
--- 4260,4269 ----
    return 1;
  }
  
  static tree
  classtype_mangled_name (tree t)
  {
!   gcc_assert (TYPE_IDENTIFIER (t));
    return TYPE_IDENTIFIER (t);
  }
  
Index: cp/class.c
===================================================================
*** cp/class.c	(revision 119733)
--- cp/class.c	(working copy)
*************** note_name_declared_in_class (tree name, 
*** 6300,6308 ****
  	 A name N used in a class S shall refer to the same declaration
  	 in its context and when re-evaluated in the completed scope of
  	 S.  */
!       error ("declaration of %q#D", decl);
!       error ("changes meaning of %qD from %q+#D",
! 	     DECL_NAME (OVL_CURRENT (decl)), (tree) n->value);
      }
  }
  
--- 6300,6308 ----
  	 A name N used in a class S shall refer to the same declaration
  	 in its context and when re-evaluated in the completed scope of
  	 S.  */
!       pedwarn ("declaration of %q#D", decl);
!       pedwarn ("changes meaning of %qD from %q+#D",
! 	       DECL_NAME (OVL_CURRENT (decl)), (tree) n->value);
      }
  }
  
Index: testsuite/g++.dg/warn/changes-meaning.C
===================================================================
*** testsuite/g++.dg/warn/changes-meaning.C	(revision 0)
--- testsuite/g++.dg/warn/changes-meaning.C	(revision 0)
***************
*** 0 ****
--- 1,11 ----
+ /* { dg-do compile } */
+ /* { dg-options "-fpermissive" } */
+ 
+ template <class _Tp> class auto_ptr {};  /* { dg-warning "changes meaning" } */
+ template <class _Tp>
+ class counted_ptr
+ {
+ public:
+   auto_ptr<_Tp> auto_ptr(); /* { dg-warning "" } */
+ };
+ 


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