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++/libiberty PATCH for mangling updates


As it turns out, my clever idea about using type stubs to simplify the mangling of decltype types was a bit too clever; it can create symbol collisions between function templates that can be distinguished with SFINAE. So we're back to mangling the expressions as written. This required me to set DECL_CONTEXT on the parms so I can tell what their position is in the list of parms...and then deal with updating DECL_CONTEXT when we smash decls together, which was enough of a headache before that it motivated me to come up with type stubs so that I wouldn't have to. But there it is.

This patch also adds new manglings for alignof and functional casts with 0 or more than 1 argument.

Tested x86_64-pc-linux-gnu. I'm applying now because it affects the ABI.

2009-03-17  Jason Merrill  <jason@redhat.com>

	cp/:
	* decl.c (grokfndecl): Set DECL_CONTEXT on parms.
	(duplicate_decls): Adjust DECL_CONTEXT of newdecl's parms.
	* pt.c (check_explicit_specialization): Likewise.
	(tsubst_copy) [PARM_DECL]: Return a dummy parm if we don't have a
	local specialization.
	* tree.c (cp_tree_equal) [PARM_DECL]: Check type and index, not name.
	* decl2.c (parm_index): New fn.
	* semantics.c (finish_decltype_type): Don't use describable_type.
	* mangle.c (write_expression): Likewise.  Mangle ALIGNOF_EXPR.
	Give a sorry for unsupported codes rather than crash.  Mangle
	conversions with other than 1 operand.  New mangling for PARM_DECL.
	* operators.def (ALIGNOF_EXPR): Mangle as "az".

	* include/demangle.h (enum demangle_component_type): Add
	DEMANGLE_COMPONENT_FUNCTION_PARAM.
	* libiberty/cp-demangle.c (d_make_function_param): new fn.
	(cplus_demangle_mangled_name): Work around abi v2 bug.
	(d_expr_primary): Likewise.
	(cplus_demangle_operators): Add alignof ops.
	(d_expression): Handle function parameters and conversions
	with other than 1 operand.
	(d_print_comp): Handle function parameters.  Fix bug with
	function used in type of function.

Index: gcc/cp/mangle.c
===================================================================
*** gcc/cp/mangle.c	(revision 144771)
--- gcc/cp/mangle.c	(working copy)
*************** write_expression (tree expr)
*** 2143,2169 ****
  {
    enum tree_code code = TREE_CODE (expr);
  
-   /* Inside decltype we can simplify some expressions, since we're only
-      interested in the type.  */
-   if (skip_evaluation)
-     {
-       tree type = describable_type (expr);
-       if (type == NULL_TREE)
- 	;
-       else if (TREE_CODE (type) == REFERENCE_TYPE)
- 	{
- 	  write_string ("sT");
- 	  write_type (TREE_TYPE (type));
- 	  return;
- 	}
-       else
- 	{
- 	  write_string ("sR");
- 	  write_type (type);
- 	  return;
- 	}
-     }
- 
    /* Skip NOP_EXPRs.  They can occur when (say) a pointer argument
       is converted (via qualification conversions) to another
       type.  */
--- 2143,2148 ----
*************** write_expression (tree expr)
*** 2210,2219 ****
      write_template_arg_literal (expr);
    else if (code == PARM_DECL)
      {
!       /* A function parameter used under decltype in a late-specified
! 	 return type.  Represented with a type placeholder.  */
!       write_string ("sT");
!       write_type (non_reference (TREE_TYPE (expr)));
      }
    else if (DECL_P (expr))
      {
--- 2189,2200 ----
      write_template_arg_literal (expr);
    else if (code == PARM_DECL)
      {
!       /* A function parameter used in a late-specified return type.  */
!       int index = parm_index (expr);
!       write_string ("fp");
!       if (index > 1)
! 	write_unsigned_number (index - 2);
!       write_char ('_');
      }
    else if (DECL_P (expr))
      {
*************** write_expression (tree expr)
*** 2231,2236 ****
--- 2212,2223 ----
        write_string ("st");
        write_type (TREE_OPERAND (expr, 0));
      }
+   else if (TREE_CODE (expr) == ALIGNOF_EXPR
+ 	   && TYPE_P (TREE_OPERAND (expr, 0)))
+     {
+       write_string ("at");
+       write_type (TREE_OPERAND (expr, 0));
+     }
    else if (abi_version_at_least (2) && TREE_CODE (expr) == SCOPE_REF)
      {
        tree scope = TREE_OPERAND (expr, 0);
*************** write_expression (tree expr)
*** 2298,2306 ****
--- 2285,2300 ----
  	    write_template_args (template_args);
  	}
      }
+   else if (TREE_CODE (expr) == INDIRECT_REF
+ 	   && TREE_TYPE (TREE_OPERAND (expr, 0))
+ 	   && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
+     {
+       write_expression (TREE_OPERAND (expr, 0));
+     }
    else
      {
        int i;
+       const char *name;
  
        /* When we bind a variable or function to a non-type template
  	 argument with reference type, we create an ADDR_EXPR to show
*************** write_expression (tree expr)
*** 2338,2344 ****
  	}
  
        /* If it wasn't any of those, recursively expand the expression.  */
!       write_string (operator_name_info[(int) code].mangled_name);
  
        switch (code)
  	{
--- 2332,2345 ----
  	}
  
        /* If it wasn't any of those, recursively expand the expression.  */
!       name = operator_name_info[(int) code].mangled_name;
!       if (name == NULL)
! 	{
! 	  sorry ("mangling %C", code);
! 	  return;
! 	}
!       else
! 	write_string (name);	
  
        switch (code)
  	{
*************** write_expression (tree expr)
*** 2351,2373 ****
  
  	case CAST_EXPR:
  	  write_type (TREE_TYPE (expr));
! 	  /* There is no way to mangle a zero-operand cast like
! 	     "T()".  */
! 	  if (!TREE_OPERAND (expr, 0))
! 	    sorry ("zero-operand casts cannot be mangled due to a defect "
! 		   "in the C++ ABI");
! 	  else if (list_length (TREE_OPERAND (expr, 0)) > 1)
! 	    sorry ("mangling function-style cast with more than one argument");
! 	  else
  	    write_expression (TREE_VALUE (TREE_OPERAND (expr, 0)));
  	  break;
  
  	case STATIC_CAST_EXPR:
  	case CONST_CAST_EXPR:
  	  write_type (TREE_TYPE (expr));
  	  write_expression (TREE_OPERAND (expr, 0));
  	  break;
  
  	/* Handle pointers-to-members specially.  */
  	case SCOPE_REF:
  	  write_type (TREE_OPERAND (expr, 0));
--- 2352,2380 ----
  
  	case CAST_EXPR:
  	  write_type (TREE_TYPE (expr));
! 	  if (list_length (TREE_OPERAND (expr, 0)) == 1)	  
  	    write_expression (TREE_VALUE (TREE_OPERAND (expr, 0)));
+ 	  else
+ 	    {
+ 	      tree args = TREE_OPERAND (expr, 0);
+ 	      write_char ('_');
+ 	      for (; args; args = TREE_CHAIN (args))
+ 		write_expression (TREE_VALUE (args));
+ 	      write_char ('E');
+ 	    }
  	  break;
  
+ 	  /* FIXME these should have a distinct mangling.  */
  	case STATIC_CAST_EXPR:
  	case CONST_CAST_EXPR:
  	  write_type (TREE_TYPE (expr));
  	  write_expression (TREE_OPERAND (expr, 0));
  	  break;
  
+ 	case NEW_EXPR:
+ 	  sorry ("mangling new-expression");
+ 	  break;
+ 
  	/* Handle pointers-to-members specially.  */
  	case SCOPE_REF:
  	  write_type (TREE_OPERAND (expr, 0));
Index: gcc/cp/decl.c
===================================================================
*** gcc/cp/decl.c	(revision 144771)
--- gcc/cp/decl.c	(working copy)
*************** duplicate_decls (tree newdecl, tree oldd
*** 1684,1691 ****
  	    = DECL_SOURCE_LOCATION (newdecl);
  	  DECL_INITIAL (old_result) = DECL_INITIAL (new_result);
  	  if (DECL_FUNCTION_TEMPLATE_P (newdecl))
! 	    DECL_ARGUMENTS (old_result)
! 	      = DECL_ARGUMENTS (new_result);
  	}
  
        return olddecl;
--- 1684,1697 ----
  	    = DECL_SOURCE_LOCATION (newdecl);
  	  DECL_INITIAL (old_result) = DECL_INITIAL (new_result);
  	  if (DECL_FUNCTION_TEMPLATE_P (newdecl))
! 	    {
! 	      tree parm;
! 	      DECL_ARGUMENTS (old_result)
! 		= DECL_ARGUMENTS (new_result);
! 	      for (parm = DECL_ARGUMENTS (old_result); parm;
! 		   parm = TREE_CHAIN (parm))
! 		DECL_CONTEXT (parm) = old_result;
! 	    }
  	}
  
        return olddecl;
*************** duplicate_decls (tree newdecl, tree oldd
*** 1918,1923 ****
--- 1924,1931 ----
  
    if (TREE_CODE (newdecl) == FUNCTION_DECL)
      {
+       tree parm;
+ 
        if (DECL_TEMPLATE_INSTANTIATION (olddecl)
  	  && !DECL_TEMPLATE_INSTANTIATION (newdecl))
  	{
*************** duplicate_decls (tree newdecl, tree oldd
*** 1974,1979 ****
--- 1982,1992 ----
        /* Preserve abstractness on cloned [cd]tors.  */
        DECL_ABSTRACT (newdecl) = DECL_ABSTRACT (olddecl);
  
+       /* Update newdecl's parms to point at olddecl.  */
+       for (parm = DECL_ARGUMENTS (newdecl); parm;
+ 	   parm = TREE_CHAIN (parm))
+ 	DECL_CONTEXT (parm) = olddecl;
+ 
        if (! types_match)
  	{
  	  SET_DECL_LANGUAGE (olddecl, DECL_LANGUAGE (newdecl));
*************** duplicate_decls (tree newdecl, tree oldd
*** 2006,2012 ****
  	    }
  
  	  DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
! 	  /* Don't clear out the arguments if we're redefining a function.  */
  	  if (DECL_ARGUMENTS (olddecl))
  	    DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
  	}
--- 2019,2026 ----
  	    }
  
  	  DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
! 	  /* Don't clear out the arguments if we're just redeclaring a
! 	     function.  */
  	  if (DECL_ARGUMENTS (olddecl))
  	    DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
  	}
*************** grokfndecl (tree ctype,
*** 6555,6560 ****
--- 6569,6576 ----
        parms = parm;
      }
    DECL_ARGUMENTS (decl) = parms;
+   for (t = parms; t; t = TREE_CHAIN (t))
+     DECL_CONTEXT (t) = decl;
    /* Propagate volatile out from type to decl.  */
    if (TYPE_VOLATILE (type))
      TREE_THIS_VOLATILE (decl) = 1;
Index: gcc/cp/operators.def
===================================================================
*** gcc/cp/operators.def	(revision 144771)
--- gcc/cp/operators.def	(working copy)
*************** DEF_SIMPLE_OPERATOR ("++", PREINCREMENT_
*** 94,100 ****
  DEF_SIMPLE_OPERATOR ("--", PREDECREMENT_EXPR, "mm", 1)
  DEF_SIMPLE_OPERATOR ("sizeof", SIZEOF_EXPR, "sz", 1)
  /* These are extensions.  */
! DEF_SIMPLE_OPERATOR ("alignof", ALIGNOF_EXPR, "v17alignof", 1)
  DEF_SIMPLE_OPERATOR ("__imag__", IMAGPART_EXPR, "v18__imag__", 1)
  DEF_SIMPLE_OPERATOR ("__real__", REALPART_EXPR, "v18__real__", 1)
  
--- 94,100 ----
  DEF_SIMPLE_OPERATOR ("--", PREDECREMENT_EXPR, "mm", 1)
  DEF_SIMPLE_OPERATOR ("sizeof", SIZEOF_EXPR, "sz", 1)
  /* These are extensions.  */
! DEF_SIMPLE_OPERATOR ("alignof", ALIGNOF_EXPR, "az", 1)
  DEF_SIMPLE_OPERATOR ("__imag__", IMAGPART_EXPR, "v18__imag__", 1)
  DEF_SIMPLE_OPERATOR ("__real__", REALPART_EXPR, "v18__real__", 1)
  
Index: gcc/cp/tree.c
===================================================================
*** gcc/cp/tree.c	(revision 144771)
--- gcc/cp/tree.c	(working copy)
*************** cp_tree_equal (tree t1, tree t2)
*** 1881,1889 ****
      case PARM_DECL:
        /* For comparing uses of parameters in late-specified return types
  	 with an out-of-class definition of the function.  */
!       if ((!DECL_CONTEXT (t1) || !DECL_CONTEXT (t2))
! 	  && same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
! 	  && DECL_NAME (t1) == DECL_NAME (t2))
  	return true;
        else
  	return false;
--- 1881,1888 ----
      case PARM_DECL:
        /* For comparing uses of parameters in late-specified return types
  	 with an out-of-class definition of the function.  */
!       if (same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
! 	  && parm_index (t1) == parm_index (t2))
  	return true;
        else
  	return false;
Index: gcc/cp/pt.c
===================================================================
*** gcc/cp/pt.c	(revision 144771)
--- gcc/cp/pt.c	(working copy)
*************** check_explicit_specialization (tree decl
*** 2217,2233 ****
  	     the specialization of it.  */
  	  if (tsk == tsk_template)
  	    {
  	      SET_DECL_TEMPLATE_SPECIALIZATION (tmpl);
! 	      DECL_INITIAL (DECL_TEMPLATE_RESULT (tmpl)) = NULL_TREE;
  	      if (have_def)
  		{
  		  DECL_SOURCE_LOCATION (tmpl) = DECL_SOURCE_LOCATION (decl);
! 		  DECL_SOURCE_LOCATION (DECL_TEMPLATE_RESULT (tmpl))
  		    = DECL_SOURCE_LOCATION (decl);
  		  /* We want to use the argument list specified in the
  		     definition, not in the original declaration.  */
! 		  DECL_ARGUMENTS (DECL_TEMPLATE_RESULT (tmpl))
! 		    = DECL_ARGUMENTS (decl);
  		}
  	      return tmpl;
  	    }
--- 2217,2237 ----
  	     the specialization of it.  */
  	  if (tsk == tsk_template)
  	    {
+ 	      tree result = DECL_TEMPLATE_RESULT (tmpl);
  	      SET_DECL_TEMPLATE_SPECIALIZATION (tmpl);
! 	      DECL_INITIAL (result) = NULL_TREE;
  	      if (have_def)
  		{
+ 		  tree parm;
  		  DECL_SOURCE_LOCATION (tmpl) = DECL_SOURCE_LOCATION (decl);
! 		  DECL_SOURCE_LOCATION (result)
  		    = DECL_SOURCE_LOCATION (decl);
  		  /* We want to use the argument list specified in the
  		     definition, not in the original declaration.  */
! 		  DECL_ARGUMENTS (result) = DECL_ARGUMENTS (decl);
! 		  for (parm = DECL_ARGUMENTS (result); parm;
! 		       parm = TREE_CHAIN (parm))
! 		    DECL_CONTEXT (parm) = result;
  		}
  	      return tmpl;
  	    }
*************** tsubst_copy (tree t, tree args, tsubst_f
*** 9898,9913 ****
        if (r == NULL)
  	{
  	  /* This can happen for a parameter name used later in a function
! 	     declaration (such as in a late-specified return type).
! 	     Replace it with an arbitrary expression with the same type
! 	     (*(T*)0).  This should only occur in an unevaluated context
! 	     (i.e. decltype).  */
! 	  gcc_assert (skip_evaluation);
! 	  r = non_reference (TREE_TYPE (t));
! 	  r = tsubst (r, args, complain, in_decl);
! 	  r = build_pointer_type (r);
! 	  r = build_c_cast (r, null_node);
! 	  return cp_build_indirect_ref (r, NULL, tf_warning_or_error);
  	}
        
        if (TREE_CODE (r) == ARGUMENT_PACK_SELECT)
--- 9902,9915 ----
        if (r == NULL)
  	{
  	  /* This can happen for a parameter name used later in a function
! 	     declaration (such as in a late-specified return type).  Just
! 	     make a dummy decl, since it's only used for its type.  */
! 	  gcc_assert (skip_evaluation);	  
! 	  r = tsubst_decl (t, args, complain);
! 	  /* Give it the template pattern as its context; its true context
! 	     hasn't been instantiated yet and this is good enough for
! 	     mangling.  */
! 	  DECL_CONTEXT (r) = DECL_CONTEXT (t);
  	}
        
        if (TREE_CODE (r) == ARGUMENT_PACK_SELECT)
Index: gcc/cp/semantics.c
===================================================================
*** gcc/cp/semantics.c	(revision 144771)
--- gcc/cp/semantics.c	(working copy)
*************** finish_decltype_type (tree expr, bool id
*** 4585,4592 ****
  	      break;
  	    }
  	}
-       else
- 	type = describable_type (expr);
  
        if (type && !type_uses_auto (type))
  	return type;
--- 4585,4590 ----
Index: gcc/cp/decl2.c
===================================================================
*** gcc/cp/decl2.c	(revision 144771)
--- gcc/cp/decl2.c	(working copy)
*************** mark_used (tree decl)
*** 3907,3910 ****
--- 3907,3933 ----
    processing_template_decl = saved_processing_template_decl;
  }
  
+ /* Given function PARM_DECL PARM, return its index in the function's list
+    of parameters, beginning with 1.  */
+ 
+ int
+ parm_index (tree parm)
+ {
+   int index;
+   tree arg;
+ 
+   for (index = 1, arg = DECL_ARGUMENTS (DECL_CONTEXT (parm));
+        arg;
+        ++index, arg = TREE_CHAIN (arg))
+     {
+       if (DECL_NAME (parm) == DECL_NAME (arg))
+ 	break;
+       if (DECL_ARTIFICIAL (arg))
+ 	--index;
+     }
+ 
+   gcc_assert (arg);
+   return index;
+ }
+ 
  #include "gt-cp-decl2.h"
Index: gcc/cp/cp-tree.h
===================================================================
*** gcc/cp/cp-tree.h	(revision 144771)
--- gcc/cp/cp-tree.h	(working copy)
*************** extern bool decl_needed_p			(tree);
*** 4436,4441 ****
--- 4436,4442 ----
  extern void note_vague_linkage_fn		(tree);
  extern tree build_artificial_parm		(tree, tree);
  extern bool possibly_inlined_p			(tree);
+ extern int parm_index                           (tree);
  
  /* in error.c */
  extern void init_error				(void);
Index: include/demangle.h
===================================================================
*** include/demangle.h	(revision 144771)
--- include/demangle.h	(working copy)
*************** enum demangle_component_type
*** 221,226 ****
--- 221,228 ----
    /* A template parameter.  This holds a number, which is the template
       parameter index.  */
    DEMANGLE_COMPONENT_TEMPLATE_PARAM,
+   /* A function parameter.  This holds a number, which is the index.  */
+   DEMANGLE_COMPONENT_FUNCTION_PARAM,
    /* A constructor.  This holds a name and the kind of
       constructor.  */
    DEMANGLE_COMPONENT_CTOR,
*************** struct demangle_component
*** 466,475 ****
        int len;
      } s_string;
  
!     /* For DEMANGLE_COMPONENT_TEMPLATE_PARAM.  */
      struct
      {
!       /* Template parameter index.  */
        long number;
      } s_number;
  
--- 468,477 ----
        int len;
      } s_string;
  
!     /* For DEMANGLE_COMPONENT_*_PARAM.  */
      struct
      {
!       /* Parameter index.  */
        long number;
      } s_number;
  
Index: libiberty/cp-demangle.c
===================================================================
*** libiberty/cp-demangle.c	(revision 144771)
--- libiberty/cp-demangle.c	(working copy)
*************** d_make_template_param (struct d_info *di
*** 964,969 ****
--- 964,985 ----
    return p;
  }
  
+ /* Add a new function parameter.  */
+ 
+ static struct demangle_component *
+ d_make_function_param (struct d_info *di, long i)
+ {
+   struct demangle_component *p;
+ 
+   p = d_make_empty (di);
+   if (p != NULL)
+     {
+       p->type = DEMANGLE_COMPONENT_FUNCTION_PARAM;
+       p->u.s_number.number = i;
+     }
+   return p;
+ }
+ 
  /* Add a new standard substitution component.  */
  
  static struct demangle_component *
*************** CP_STATIC_IF_GLIBCPP_V3
*** 989,995 ****
  struct demangle_component *
  cplus_demangle_mangled_name (struct d_info *di, int top_level)
  {
!   if (! d_check_char (di, '_'))
      return NULL;
    if (! d_check_char (di, 'Z'))
      return NULL;
--- 1005,1015 ----
  struct demangle_component *
  cplus_demangle_mangled_name (struct d_info *di, int top_level)
  {
!   if (! d_check_char (di, '_')
!       /* Allow missing _ if not at toplevel to work around a
! 	 bug in G++ abi-version=2 mangling; see the comment in
! 	 write_template_arg.  */
!       && top_level)
      return NULL;
    if (! d_check_char (di, 'Z'))
      return NULL;
*************** const struct demangle_operator_info cplu
*** 1481,1486 ****
--- 1501,1508 ----
    { "rs", NL (">>"),        2 },
    { "st", NL ("sizeof "),   1 },
    { "sz", NL ("sizeof "),   1 },
+   { "at", NL ("alignof "),   1 },
+   { "az", NL ("alignof "),   1 },
    { NULL, NULL, 0,          0 }
  };
  
*************** d_expression (struct d_info *di)
*** 2564,2575 ****
  			    d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name,
  					 d_template_args (di)));
      }
!   else if (peek == 's'
! 	   && (d_peek_next_char (di) == 'T' || d_peek_next_char (di) == 'R'))
      {
!       /* Just demangle a parameter placeholder as its type.  */
        d_advance (di, 2);
!       return cplus_demangle_type (di);
      }
    else if (IS_DIGIT (peek))
      {
--- 2586,2610 ----
  			    d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name,
  					 d_template_args (di)));
      }
!   else if (peek == 'f' && d_peek_next_char (di) == 'p')
      {
!       /* Function parameter used in a late-specified return type.  */
!       int index;
        d_advance (di, 2);
!       if (d_peek_char (di) == '_')
! 	index = 1;
!       else
! 	{
! 	  index = d_number (di);
! 	  if (index < 0)
! 	    return NULL;
! 	  index += 2;
! 	}
! 
!       if (! d_check_char (di, '_'))
! 	return NULL;
! 
!       return d_make_function_param (di, index);
      }
    else if (IS_DIGIT (peek))
      {
*************** d_expression (struct d_info *di)
*** 2619,2626 ****
        switch (args)
  	{
  	case 1:
! 	  return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
! 			      d_expression (di));
  	case 2:
  	  {
  	    struct demangle_component *left;
--- 2654,2669 ----
        switch (args)
  	{
  	case 1:
! 	  {
! 	    struct demangle_component *operand;
! 	    if (op->type == DEMANGLE_COMPONENT_CAST
! 		&& d_check_char (di, '_'))
! 	      operand = d_exprlist (di);
! 	    else
! 	      operand = d_expression (di);
! 	    return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
! 				operand);
! 	  }
  	case 2:
  	  {
  	    struct demangle_component *left;
*************** d_expr_primary (struct d_info *di)
*** 2671,2677 ****
  
    if (! d_check_char (di, 'L'))
      return NULL;
!   if (d_peek_char (di) == '_')
      ret = cplus_demangle_mangled_name (di, 0);
    else
      {
--- 2714,2722 ----
  
    if (! d_check_char (di, 'L'))
      return NULL;
!   if (d_peek_char (di) == '_'
!       /* Workaround for G++ bug; see comment in write_template_arg.  */
!       || d_peek_char (di) == 'Z')
      ret = cplus_demangle_mangled_name (di, 0);
    else
      {
*************** d_print_comp (struct d_print_info *dpi,
*** 3293,3298 ****
--- 3338,3344 ----
  	   the right place for the type.  We also have to pass down
  	   any CV-qualifiers, which apply to the this parameter.  */
  	hold_modifiers = dpi->modifiers;
+ 	dpi->modifiers = 0;
  	i = 0;
  	typed_name = d_left (dc);
  	while (typed_name != NULL)
*************** d_print_comp (struct d_print_info *dpi,
*** 3981,3986 ****
--- 4027,4041 ----
        }
        return;
  
+     case DEMANGLE_COMPONENT_FUNCTION_PARAM:
+       {
+ 	char buf[25];
+ 	d_append_string (dpi, "parm#");
+ 	sprintf(buf,"%ld", dc->u.s_number.number);
+ 	d_append_string (dpi, buf);
+ 	return;
+       }
+ 
      default:
        d_print_error (dpi);
        return;
Index: gcc/testsuite/g++.dg/cpp0x/auto6.C
===================================================================
*** gcc/testsuite/g++.dg/cpp0x/auto6.C	(revision 144771)
--- gcc/testsuite/g++.dg/cpp0x/auto6.C	(working copy)
*************** A<int> a, *p;
*** 95,115 ****
  
  int main()
  {
!   // { dg-final { scan-assembler  "_Z3addIidEDTplsTT_sTT0_ES0_S1_" } }
    auto i = add(1, 2.0);
!   // { dg-final { scan-assembler "_Z4add4IidEDTplsTT_sTT0_ES0_S1_" } }
    auto i4 = add4(1, 2.0);
!   // { dg-final { scan-assembler "_Z4add2IidEDTplsRT_sRT0_ES0_S1_" } }
    auto i2 = add2(1, 2.0);
!   // { dg-final { scan-assembler "_Z4add3IidEDTclL_Z2agEsTT_sTT0_EES0_S1_" } }
    auto i3 = add3(1, 2.0);
!   // { dg-final { scan-assembler "_Z1fI1AIiEEDTclptsTPT_1fEES3_" } }
    f(p);
!   // { dg-final { scan-assembler "_Z1gI1AIiEEDTcldtsTT_1fEES2_" } }
    g(a);
!   // { dg-final { scan-assembler "_Z1hI1AIiEdEDTcldtsTT_1gIT0_EEES2_S3_" } }
    h(a,1.0);
!   // { dg-final { scan-assembler "_Z1kI1C1AIiE1DEDtdtsTT_srNT0_1BIT1_EE3MEMES4_S5_S7_" } }
    k( C(), A<int>(), D() );
    // { dg-final { scan-assembler "_Z1lIiET_S0_" } }
    l(1);
--- 95,115 ----
  
  int main()
  {
!   // { dg-final { scan-assembler  "_Z3addIidEDTplfp_fp0_ET_T0_" } }
    auto i = add(1, 2.0);
!   // { dg-final { scan-assembler "_Z4add4IidEDTpldecvPT_Li0EdecvPT0_Li0EES0_S2_" } }
    auto i4 = add4(1, 2.0);
!   // { dg-final { scan-assembler "_Z4add2IidEDTplcvT__EcvT0__EES0_S1_" } }
    auto i2 = add2(1, 2.0);
!   // { dg-final { scan-assembler "_Z4add3IidEDTclL_Z2agEfp_fp0_EET_T0_" } }
    auto i3 = add3(1, 2.0);
!   // { dg-final { scan-assembler "_Z1fI1AIiEEDTclptfp_1fEEPT_" } }
    f(p);
!   // { dg-final { scan-assembler "_Z1gI1AIiEEDTcldtfp_1fEET_" } }
    g(a);
!   // { dg-final { scan-assembler "_Z1hI1AIiEdEDTcldtfp_1gIT0_EEET_S2_" } }
    h(a,1.0);
!   // { dg-final { scan-assembler "_Z1kI1C1AIiE1DEDtdtfp_srNT0_1BIT1_EE3MEMET_S4_S6_" } }
    k( C(), A<int>(), D() );
    // { dg-final { scan-assembler "_Z1lIiET_S0_" } }
    l(1);
Index: gcc/testsuite/g++.dg/cpp0x/auto12.C
===================================================================
*** gcc/testsuite/g++.dg/cpp0x/auto12.C	(revision 144771)
--- gcc/testsuite/g++.dg/cpp0x/auto12.C	(working copy)
*************** auto A<T>::f(U u) -> decltype (u + i)
*** 37,52 ****
  
  int main()
  {
!   // { dg-final { scan-assembler  "_ZN1AIiE1fIiEEDTplsTT_sTiES2_" } }
    A<int>().f(1);
!   // { dg-final { scan-assembler  "_ZN1AIiE2frIiEEDTplsTT_sTiES2_" } }
    A<int>().fr(1);
!   // { dg-final { scan-assembler  "_ZN1AIiE3frrIiEEDTplsTT_sTiES2_" } }
    A<int>().frr(1);
!   // { dg-final { scan-assembler  "_ZN1AIiE1gIiEEDTplsTT_sR.ES2_" } }
    A<int>().g(1);
!   // { dg-final { scan-assembler  "_ZN1AIiE1hIiEEDTplsTT_sr1BIS2_E1iES2_" } }
    A<int>().h(1);
!   // { dg-final { scan-assembler  "_ZN1AIiE1jIiEEDTplsTT_sRiES2_" } }
    A<int>().j(1);
  }
--- 37,52 ----
  
  int main()
  {
!   // { dg-final { scan-assembler  "_ZN1AIiE1fIiEEDTplfp_L_ZNS0_1iEEET_" } }
    A<int>().f(1);
!   // { dg-final { scan-assembler  "_ZN1AIiE2frIiEEDTplfp_L_ZNS0_2irEEET_" } }
    A<int>().fr(1);
!   // { dg-final { scan-assembler  "_ZN1AIiE3frrIiEEDTplfp_L_ZNS0_3irrEEET_" } }
    A<int>().frr(1);
!   // { dg-final { scan-assembler  "_ZN1AIiE1gIiEEDTplfp_szL_ZNS0_1iEEET_" } }
    A<int>().g(1);
!   // { dg-final { scan-assembler  "_ZN1AIiE1hIiEEDTplfp_sr1BIT_E1iES3_" } }
    A<int>().h(1);
!   // { dg-final { scan-assembler  "_ZN1AIiE1jIiEEDTplfp_clL_Z1xvEEET_" } }
    A<int>().j(1);
  }
Index: libiberty/testsuite/demangle-expected
===================================================================
*** libiberty/testsuite/demangle-expected	(revision 144771)
--- libiberty/testsuite/demangle-expected	(working copy)
*************** foo<int (*) [3]>
*** 3723,3729 ****
  # This used to crash the demangler--PR 16240
  --format=gnu-v3 --no-params
  _ZN13PatternDriver23StringScalarDeleteValueC1ERKNS_25ConflateStringScalarValueERKNS_25AbstractStringScalarValueERKNS_12TemplateEnumINS_12pdcomplementELZNS_16complement_namesEELZNS_14COMPLEMENTENUMEEEE
! _ZN13PatternDriver23StringScalarDeleteValueC1ERKNS_25ConflateStringScalarValueERKNS_25AbstractStringScalarValueERKNS_12TemplateEnumINS_12pdcomplementELZNS_16complement_namesEELZNS_14COMPLEMENTENUMEEEE
  PatternDriver::StringScalarDeleteValue::StringScalarDeleteValue
  #
  # This used to cause the demangler to walk into undefined memory--PR 22268
--- 3723,3729 ----
  # This used to crash the demangler--PR 16240
  --format=gnu-v3 --no-params
  _ZN13PatternDriver23StringScalarDeleteValueC1ERKNS_25ConflateStringScalarValueERKNS_25AbstractStringScalarValueERKNS_12TemplateEnumINS_12pdcomplementELZNS_16complement_namesEELZNS_14COMPLEMENTENUMEEEE
! PatternDriver::StringScalarDeleteValue::StringScalarDeleteValue(PatternDriver::ConflateStringScalarValue const&, PatternDriver::AbstractStringScalarValue const&, PatternDriver::TemplateEnum<PatternDriver::pdcomplement, PatternDriver::complement_names, PatternDriver::COMPLEMENTENUM> const&)
  PatternDriver::StringScalarDeleteValue::StringScalarDeleteValue
  #
  # This used to cause the demangler to walk into undefined memory--PR 22268
*************** _ZGr32_java$Sutil$Siso4217$_properties
*** 3884,3895 ****
  java resource java/util/iso4217.properties
  # decltype/param placeholder test
  --format=gnu-v3
! _Z3addIidEDTplsTT_sTT0_ES0_S1_
! decltype ((int)+(double)) add<int, double>(int, double)
  # decltype/fn call test
  --format=gnu-v3
! _Z4add3IidEDTclL_Z1gEsTT_sTT0_EES0_S1_
! decltype (g(int, double)) add3<int, double>(int, double)
  # new (2008) built in types test
  --format=gnu-v3
  _Z1fDfDdDeDhDsDi
--- 3884,3895 ----
  java resource java/util/iso4217.properties
  # decltype/param placeholder test
  --format=gnu-v3
! _Z3addIidEDTplfp_fp0_ET_T0_
! decltype ((parm#1)+(parm#2)) add<int, double>(int, double)
  # decltype/fn call test
  --format=gnu-v3
! _Z4add3IidEDTclL_Z1gEfp_fp0_EET_T0_
! decltype (g(parm#1, parm#2)) add3<int, double>(int, double)
  # new (2008) built in types test
  --format=gnu-v3
  _Z1fDfDdDeDhDsDi
*************** _Z1fIIPiPfPdEEvDpT_
*** 3900,3904 ****
  void f<int*, float*, double*>(int*, float*, double*)
  # '.' test
  --format=gnu-v3
! _Z1hI1AIiEdEDTcldtsTT_1gIT0_EEES2_S3_
! decltype (((A<int>).(g<double>))()) h<A<int>, double>(A<int>, double)
--- 3900,3908 ----
  void f<int*, float*, double*>(int*, float*, double*)
  # '.' test
  --format=gnu-v3
! _Z1hI1AIiEdEDTcldtfp_1gIT0_EEET_S2_
! decltype (((parm#1).(g<double>))()) h<A<int>, double>(A<int>, double)
! # test for typed function in decltype
! --format=gnu-v3
! _ZN1AIiE1jIiEEDTplfp_clL_Z1xvEEET_
! decltype ((parm#1)+((x())())) A<int>::j<int>(int)

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