case BOOLEAN_TYPE:
static char *build_mangled_name PROTO((tree,int,int));static void process_modifiers PROTO((tree));static void process_overload_item PROTO((tree,int));static void do_build_assign_ref PROTO((tree));static void do_build_copy_constructor PROTO((tree));static tree largest_union_member PROTO((tree));static void build_template_template_parm_names PROTO((tree));static void build_template_parm_names PROTO((tree, tree));static void build_underscore_int PROTO((int));static void start_squangling PROTO((void));static void end_squangling PROTO((void));static int check_ktype PROTO((tree, int));static int issue_ktype PROTO((tree));static void build_overload_scope_ref PROTO((tree));static void build_mangled_template_parm_index PROTO((char *, tree));#if HOST_BITS_PER_WIDE_INT >= 64static void build_mangled_C9x_name PROTO((int));#endifstatic int is_back_referenceable_type PROTO((tree));static int check_btype PROTO((tree));static void build_mangled_name_for_type PROTO((tree));static void build_mangled_name_for_type_with_Gcode PROTO((tree, int));# define OB_INIT() (scratch_firstobj ? (obstack_free (&scratch_obstack, scratch_firstobj), 0) : 0)# define OB_PUTC(C) (obstack_1grow (&scratch_obstack, (C)))# define OB_PUTC2(C1,C2)	\  (obstack_1grow (&scratch_obstack, (C1)), obstack_1grow (&scratch_obstack, (C2)))# define OB_PUTS(S) (obstack_grow (&scratch_obstack, (S), sizeof (S) - 1))# define OB_PUTID(ID)  \  (obstack_grow (&scratch_obstack, IDENTIFIER_POINTER (ID),	\		 IDENTIFIER_LENGTH (ID)))# define OB_PUTCP(S) (obstack_grow (&scratch_obstack, (S), strlen (S)))# define OB_FINISH() (obstack_1grow (&scratch_obstack, '\0'))# define OB_LAST() (obstack_next_free (&scratch_obstack)[-1])voidinit_method (){  gcc_obstack_init (&scratch_obstack);  scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0);}/* This must be large enough to hold any printed integer or floating-point   value.  */static char digit_buffer[128];/* Move inline function definitions out of structure so that they   can be processed normally.  CNAME is the name of the class   we are working from, METHOD_LIST is the list of method lists   of the structure.  We delete friend methods here, after   saving away their inline function definitions (if any).  */voiddo_inline_function_hair (type, friend_list)     tree type, friend_list;{  tree method = TYPE_METHODS (type);  if (method && TREE_CODE (method) == TREE_VEC)    {      if (TREE_VEC_ELT (method, 1))	method = TREE_VEC_ELT (method, 1);      else if (TREE_VEC_ELT (method, 0))	method = TREE_VEC_ELT (method, 0);      else	method = TREE_VEC_ELT (method, 2);    }  while (method)    {      /* Do inline member functions.  */      struct pending_inline *info = DECL_PENDING_INLINE_INFO (method);      if (info)	{	  tree args;	  my_friendly_assert (info->fndecl == method, 238);	  args = DECL_ARGUMENTS (method);	  while (args)	    {	      DECL_CONTEXT (args) = method;	      args = TREE_CHAIN (args);	    }	}      method = TREE_CHAIN (method);    }  while (friend_list)    {      tree fndecl = TREE_VALUE (friend_list);      struct pending_inline *info = DECL_PENDING_INLINE_INFO (fndecl);      if (info)	{	  tree args;	  my_friendly_assert (info->fndecl == fndecl, 239);	  args = DECL_ARGUMENTS (fndecl);	  while (args)	    {	      DECL_CONTEXT (args) = fndecl;	      args = TREE_CHAIN (args);	    }	}      friend_list = TREE_CHAIN (friend_list);    }}/* Here is where overload code starts.  *//* type tables for K and B type compression */static tree *btypelist = NULL;static tree *ktypelist = NULL;static int maxbsize = 0;static int maxksize = 0;/* number of each type seen */static int maxbtype = 0;static int maxktype = 0;/* Array of types seen so far in top-level call to `build_mangled_name'.   Allocated and deallocated by caller.  */static tree *typevec = NULL;static int  typevec_size;/* Number of types interned by `build_mangled_name' so far.  */static int maxtype = 0;/* Nonzero if we should not try folding parameter types.  */static int nofold;/* This appears to be set to true if an underscore is required to be   comcatenated before another number can be outputed. */static int numeric_output_need_bar;static __inline voidstart_squangling (){  if (flag_do_squangling)    {      nofold = 0;      maxbtype = 0;      maxktype = 0;      maxbsize = 50;      maxksize = 50;      btypelist = (tree *)xmalloc (sizeof (tree) * maxbsize);      ktypelist = (tree *)xmalloc (sizeof (tree) * maxksize);    }}static __inline voidend_squangling (){  if (flag_do_squangling)    {      if (ktypelist)        free (ktypelist);      if (btypelist)        free (btypelist);      maxbsize = 0;      maxksize = 0;      maxbtype = 0;      maxktype = 0;      ktypelist = NULL;      btypelist = NULL;    }}/* Code to concatenate an asciified integer to a string.  */static __inline voidicat (i)     HOST_WIDE_INT i;{  unsigned HOST_WIDE_INT ui;  /* Handle this case first, to go really quickly.  For many common values,     the result of ui/10 below is 1.  */  if (i == 1)    {      OB_PUTC ('1');      return;    }  if (i >= 0)    ui = i;  else    {      OB_PUTC ('m');      ui = -i;    }  if (ui >= 10)    icat (ui / 10);  OB_PUTC ('0' + (ui % 10));}static voiddicat (lo, hi)     HOST_WIDE_INT lo, hi;{  unsigned HOST_WIDE_INT ulo, uhi, qlo, qhi;  if (hi >= 0)    {      uhi = hi;      ulo = lo;    }  else    {      uhi = (lo == 0 ? -hi : -hi-1);      ulo = -lo;    }  if (uhi == 0      && ulo < ((unsigned HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT - 1)))    {      icat (ulo);      return;    }  /* Divide 2^HOST_WIDE_INT*uhi+ulo by 10. */  qhi = uhi / 10;  uhi = uhi % 10;  qlo = uhi * (((unsigned HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT - 1)) / 5);  qlo += ulo / 10;  ulo = ulo % 10;  ulo += uhi * (((unsigned HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT - 1)) % 5)	 * 2;  qlo += ulo / 10;  ulo = ulo % 10;  /* Quotient is 2^HOST_WIDE_INT*qhi+qlo, remainder is ulo. */  dicat (qlo, qhi);  OB_PUTC ('0' + ulo);}/* Returns the index of TYPE in the typevec, or -1 if it's not there.  */static __inline intold_backref_index (type)     tree type;{  int tindex = 0;  if (! is_back_referenceable_type (type))    return -1;  /* The entry for this parm is at maxtype-1, so don't look there for     something to repeat.  */  for (tindex = 0; tindex < maxtype - 1; ++tindex)    if (same_type_p (typevec[tindex], type))      break;  if (tindex == maxtype - 1)    return -1;  return tindex;}/* Old mangling style:  If TYPE has already been used in the parameter list,   emit a backward reference and return non-zero; otherwise, return 0.   NREPEATS is the number of repeats we've recorded of this type, or 0 if   this is the first time we've seen it and we're just looking to see if   it had been used before.  */static __inline intflush_repeats (nrepeats, type)     int nrepeats;     tree type;{  int tindex = old_backref_index (type);  if (tindex == -1)    {      my_friendly_assert (nrepeats == 0, 990316);      return 0;    }  if (nrepeats > 1)    {      OB_PUTC ('N');      icat (nrepeats);      if (nrepeats > 9)	OB_PUTC ('_');    }  else    OB_PUTC ('T');  icat (tindex);  if (tindex > 9)    OB_PUTC ('_');  return 1;}/* Returns nonzero iff this is a type to which we will want to make   back-references (using the `B' code).  */static intis_back_referenceable_type (type)     tree type;{  /* For some reason, the Java folks don't want back refs on these.  */  if (TYPE_FOR_JAVA (type))    return 0;  switch (TREE_CODE (type))     {    case INTEGER_TYPE:    case REAL_TYPE:    case VOID_TYPE:    case BOOLEAN_TYPE:      /* These types have single-character manglings, so there's no	 point in generating back-references.  */      return 0;             case TEMPLATE_TYPE_PARM:      /* It would be a bit complex to demangle signatures correctly if	 we generated back-references to these, and the manglings of	 type parameters are short.  */      return 0;    default:      return 1;    }}/* Issue the squangling code indicating NREPEATS repetitions of TYPE,   which was the last parameter type output.  */static voidissue_nrepeats (nrepeats, type)     int nrepeats;     tree type;{  if (nrepeats == 1 && !is_back_referenceable_type (type))    /* For types whose manglings are short, don't bother using the       repetition code if there's only one repetition, since the       repetition code will be about as long as the ordinary mangling.  */     build_mangled_name_for_type (type);  else    {      OB_PUTC ('n');      icat (nrepeats);      if (nrepeats > 9)	OB_PUTC ('_');    }}/* Check to see if a tree node has been entered into the Kcode typelist.   If not, add it.  Returns -1 if it isn't found, otherwise returns the   index.  */static intcheck_ktype (node, add)     tree node;     int add;{  int x;  tree localnode = node;  if (ktypelist == NULL)    return -1;  if (TREE_CODE (node) == TYPE_DECL)    localnode = TREE_TYPE (node);  for (x=0; x < maxktype; x++)    {      if (same_type_p (localnode, ktypelist[x]))        return x;    }  /* Didn't find it, so add it here.  */  if (add)    {      if (maxksize <= maxktype)        {          maxksize = maxksize* 3 / 2;          ktypelist = (tree *)xrealloc (ktypelist, sizeof (tree) * maxksize);        }      ktypelist[maxktype++] = localnode;    }  return -1;}static __inline intissue_ktype (decl)     tree decl;{  int kindex;  kindex = check_ktype (decl, FALSE);  if (kindex != -1)    {      OB_PUTC ('K');      icat (kindex);      if (kindex > 9)        OB_PUTC ('_');      return TRUE;    }  return FALSE;}  /* Build a representation for DECL, which may be an entity not at   global scope.  If so, a marker indicating that the name is   qualified has already been output, but the qualifying context has   not.  */static voidbuild_overload_nested_name (decl)     tree decl;{  tree context;  if (ktypelist && issue_ktype (decl))      return;  if (decl == global_namespace)    return;  context = CP_DECL_CONTEXT (decl);  /* try to issue a K type, and if we can't continue the normal path */  if (!(ktypelist && issue_ktype (context)))  {    /* For a template type parameter, we want to output an 'Xn'       rather than 'T' or some such. */    if (TREE_CODE (context) == TEMPLATE_TYPE_PARM        || TREE_CODE (context) == TEMPLATE_TEMPLATE_PARM)      build_mangled_name_for_type (context);    else    {      if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')        context = TYPE_NAME (context);      build_overload_nested_name (context);    }  }  if (TREE_CODE (decl) == FUNCTION_DECL)    {      tree name = DECL_ASSEMBLER_NAME (decl);      char *label;      ASM_FORMAT_PRIVATE_NAME (label, IDENTIFIER_POINTER (name), static_labelno);      static_labelno++;      if (numeric_output_need_bar)	OB_PUTC ('_');      icat (strlen (label));      OB_PUTCP (label);      numeric_output_need_bar = 1;    }  else if (TREE_CODE (decl) == NAMESPACE_DECL)    build_overload_identifier (DECL_NAME (decl));  else				/* TYPE_DECL */    build_overload_identifier (decl);}/* Output the decimal representation of I.  If I > 9, the decimal   representation is preceeded and followed by an underscore.  */static voidbuild_underscore_int (i)     int i;{  if (i > 9)    OB_PUTC ('_');  icat (i);  if (i > 9)    OB_PUTC ('_');}static voidbuild_overload_scope_ref (value)     tree value;{  OB_PUTC2 ('Q', '2');  numeric_output_need_bar = 0;  build_mangled_name_for_type (TREE_OPERAND (value, 0));  build_overload_identifier (TREE_OPERAND (value, 1));}/* Encoding for an INTEGER_CST value.  */static voidbuild_overload_int (value, in_template)     tree value;     int in_template;{  if (in_template && TREE_CODE (value) != INTEGER_CST)    {      if (TREE_CODE (value) == SCOPE_REF)	{	  build_overload_scope_ref (value);	  return;	}      OB_PUTC ('E');      numeric_output_need_bar = 0;      if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (value))))	{	  int i;	  int operands = tree_code_length[(int) TREE_CODE (value)];	  tree id;	  char* name;	  id = ansi_opname [(int) TREE_CODE (value)];	  my_friendly_assert (id != NULL_TREE, 0);	  name = IDENTIFIER_POINTER (id);	  if (name[0] != '_' || name[1] != '_')	    /* On some erroneous inputs, we can get here with VALUE a	       LOOKUP_EXPR.  In that case, the NAME will be the	       identifier for "<invalid operator>".  We must survive	       this routine in order to issue a sensible error	       message, so we fall through to the case below.  */	    goto bad_value;	  for (i = 0; i < operands; ++i)	    {	      tree operand;	      enum tree_code tc;	      /* We just outputted either the `E' or the name of the		 operator.  */	      numeric_output_need_bar = 0;	      if (i != 0)		/* Skip the leading underscores.  */		OB_PUTCP (name + 2);	      operand = TREE_OPERAND (value, i);	      tc = TREE_CODE (operand);	      if (TREE_CODE_CLASS (tc) == 't')		/* We can get here with sizeof, e.g.:		     		   template <class T> void f(A<sizeof(T)>);  */		build_mangled_name_for_type (operand);	      else if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (tc)))		build_overload_int (operand, in_template);	      else		build_overload_value (TREE_TYPE (operand),				      operand,				      in_template);	    }	}      else	{	  /* We don't ever want this output, but it's	     inconvenient not to be able to build the string.	     This should cause assembler errors we'll notice.  */	    	  static int n;	bad_value:	  sprintf (digit_buffer, " *%d", n++);	  OB_PUTCP (digit_buffer);	}      OB_PUTC ('W');      numeric_output_need_bar = 0;      return;    }  my_friendly_assert (TREE_CODE (value) == INTEGER_CST, 243);  if (TYPE_PRECISION (TREE_TYPE (value)) == 2 * HOST_BITS_PER_WIDE_INT)    {      if (TREE_INT_CST_HIGH (value)	  != (TREE_INT_CST_LOW (value) >> (HOST_BITS_PER_WIDE_INT - 1)))	{	  /* need to print a DImode value in decimal */	  dicat (TREE_INT_CST_LOW (value), TREE_INT_CST_HIGH (value));	  numeric_output_need_bar = 1;	  return;	}      /* else fall through to print in smaller mode */    }  /* Wordsize or smaller */  icat (TREE_INT_CST_LOW (value));  numeric_output_need_bar = 1;}/* Output S followed by a representation of the TEMPLATE_PARM_INDEX   supplied in INDEX.  */static void build_mangled_template_parm_index (s, index)     char* s;     tree index;{  OB_PUTCP (s);  build_underscore_int (TEMPLATE_PARM_IDX (index));  /* We use the LEVEL, not the ORIG_LEVEL, because the mangling is a     representation of the function from the point of view of its     type.  */  build_underscore_int (TEMPLATE_PARM_LEVEL (index));}/* Mangling for C9X integer types (and Cygnus extensions for 128-bit   and other types) is based on the letter "I" followed by the hex   representations of the bitsize for the type in question. For   encodings that result in larger than two digits, a leading and   trailing underscore is added.   Thus:   int1_t   = 001 = I01   int8_t   = 008 = I08    int16_t  = 010 = I10   int24_t  = 018 = I18   int32_t  = 020 = I20   int64_t  = 040 = I40   int80_t  = 050 = I50   int128_t = 080 = I80   int256_t = 100 = I_100_   int512_t = 200 = I_200_   Given an integer in decimal format, mangle according to this scheme. */#if HOST_BITS_PER_WIDE_INT >= 64static voidbuild_mangled_C9x_name (bits)     int bits;{  char mangled[10] = "";  if (bits > 255)    sprintf (mangled, "I_%x_", bits);  else    sprintf (mangled, "I%.2x", bits);  OB_PUTCP (mangled);}#endifstatic voidbuild_overload_value (type, value, in_template)     tree type, value;     int in_template;{  my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (type)) == 't', 0);  while (TREE_CODE (value) == NON_LVALUE_EXPR	 || TREE_CODE (value) == NOP_EXPR)    value = TREE_OPERAND (value, 0);  if (numeric_output_need_bar)    {      OB_PUTC ('_');      numeric_output_need_bar = 0;    }  if (TREE_CODE (value) == TEMPLATE_PARM_INDEX)    {      build_mangled_template_parm_index ("Y", value);      return;    }  if (TYPE_PTRMEM_P (type))    {      if (TREE_CODE (value) != PTRMEM_CST)	/* We should have already rejected this pointer to member,	   since it is not a constant.  */	my_friendly_abort (0);      /* Get the actual FIELD_DECL.  */      value = PTRMEM_CST_MEMBER (value);      my_friendly_assert (TREE_CODE (value) == FIELD_DECL, 0);      /* Output the name of the field.  */      build_overload_identifier (DECL_NAME (value));      return;    }  switch (TREE_CODE (type))    {    case INTEGER_TYPE:    case ENUMERAL_TYPE:    case BOOLEAN_TYPE:      {	build_overload_int (value, in_template);	return;      }    case REAL_TYPE:      {	REAL_VALUE_TYPE val;	char *bufp = digit_buffer;	pedwarn ("ANSI C++ forbids floating-point template arguments");	my_friendly_assert (TREE_CODE (value) == REAL_CST, 244);	val = TREE_REAL_CST (value);	if (REAL_VALUE_ISNAN (val))	  {	    sprintf (bufp, "NaN");	  }	else	  {	    if (REAL_VALUE_NEGATIVE (val))	      {		val = REAL_VALUE_NEGATE (val);		*bufp++ = 'm';	      }	    if (REAL_VALUE_ISINF (val))	      {		sprintf (bufp, "Infinity");	      }	    else	      {		REAL_VALUE_TO_DECIMAL (val, "%.20e", bufp);		bufp = (char *) index (bufp, 'e');		if (!bufp)		  strcat (digit_buffer, "e0");		else		  {		    char *p;		    bufp++;		    if (*bufp == '-')		      {			*bufp++ = 'm';		      }		    p = bufp;		    if (*p == '+')		      p++;		    while (*p == '0')		      p++;		    if (*p == 0)		      {			*bufp++ = '0';			*bufp = 0;		      }		    else if (p != bufp)		      {			while (*p)			  *bufp++ = *p++;			*bufp = 0;		      }		  }#ifdef NO_DOT_IN_LABEL		bufp = (char *) index (bufp, '.');		if (bufp)		  *bufp = '_';#endif	      }	  }	OB_PUTCP (digit_buffer);	numeric_output_need_bar = 1;	return;      }    case POINTER_TYPE:      if (TREE_CODE (value) == INTEGER_CST)	{	  build_overload_int (value, in_template);	  return;	}      else if (TREE_CODE (value) == TEMPLATE_PARM_INDEX)	{	  build_mangled_template_parm_index ("", value);	  numeric_output_need_bar = 1;	  return;	}      value = TREE_OPERAND (value, 0);      /* Fall through.  */    case REFERENCE_TYPE:      if (TREE_CODE (value) == VAR_DECL)	{	  my_friendly_assert (DECL_NAME (value) != 0, 245);	  build_overload_identifier (DECL_ASSEMBLER_NAME (value));	  return;	}      else if (TREE_CODE (value) == FUNCTION_DECL)	{	  my_friendly_assert (DECL_NAME (value) != 0, 246);	  build_overload_identifier (DECL_ASSEMBLER_NAME (value));	  return;	}      else if (TREE_CODE (value) == SCOPE_REF)	build_overload_scope_ref (value);      else	my_friendly_abort (71);      break; /* not really needed */    case RECORD_TYPE:      {	tree delta;	tree idx;	tree pfn;	tree delta2;	my_friendly_assert (TYPE_PTRMEMFUNC_P (type), 0);	/* We'll get a ADDR_EXPR of a SCOPE_REF here if we're	   mangling, an instantiation of something like:	     template <class T, void (T::*fp)()> class C {};	     template <class T> C<T, &T::f> x();  		   We mangle the return type of the function, and that	   contains template parameters.  */	if (TREE_CODE (value) == ADDR_EXPR	    && TREE_CODE (TREE_OPERAND (value, 0)) == SCOPE_REF)	  {	    build_overload_scope_ref (TREE_OPERAND (value, 0));	    break;	  }	my_friendly_assert (TREE_CODE (value) == PTRMEM_CST, 0);	expand_ptrmemfunc_cst (value, &delta, &idx, &pfn, &delta2);	build_overload_int (delta, in_template);	OB_PUTC ('_');	build_overload_int (idx, in_template);	OB_PUTC ('_');	if (pfn)	  {	    numeric_output_need_bar = 0;	    build_overload_identifier (DECL_ASSEMBLER_NAME				       (PTRMEM_CST_MEMBER (value)));	  }	else	  {	    OB_PUTC ('i');	    build_overload_int (delta2, in_template);	  }      }      break;          default:      sorry ("conversion of %s as template parameter",	     tree_code_name [(int) TREE_CODE (type)]);      my_friendly_abort (72);    }}/* Add encodings for the declaration of template template parameters.   PARMLIST must be a TREE_VEC.  */static voidbuild_template_template_parm_names (parmlist)     tree parmlist;{  int i, nparms;  my_friendly_assert (TREE_CODE (parmlist) == TREE_VEC, 246.5);  nparms = TREE_VEC_LENGTH (parmlist);  icat (nparms);  for (i = 0; i < nparms; i++)    {      tree parm = TREE_VALUE (TREE_VEC_ELT (parmlist, i));      if (TREE_CODE (parm) == TYPE_DECL)	{	  /* This parameter is a type.  */	  OB_PUTC ('Z');	}      else if (TREE_CODE (parm) == TEMPLATE_DECL)	{	  /* This parameter is a template. */	  OB_PUTC ('z');	  build_template_template_parm_names (DECL_INNERMOST_TEMPLATE_PARMS (parm));	}      else	/* It's a PARM_DECL.  */	build_mangled_name_for_type (TREE_TYPE (parm));    }}/* Add encodings for the vector of template parameters in PARMLIST,   given the vector of arguments to be substituted in ARGLIST.  */static voidbuild_template_parm_names (parmlist, arglist)     tree parmlist;     tree arglist;{  int i, nparms;  tree inner_args = innermost_args (arglist);  nparms = TREE_VEC_LENGTH (parmlist);  icat (nparms);  for (i = 0; i < nparms; i++)    {      tree parm = TREE_VALUE (TREE_VEC_ELT (parmlist, i));      tree arg = TREE_VEC_ELT (inner_args, i);      if (TREE_CODE (parm) == TYPE_DECL)	{	  /* This parameter is a type.  */	  OB_PUTC ('Z');	  build_mangled_name_for_type (arg);	}      else if (TREE_CODE (parm) == TEMPLATE_DECL)	{	  /* This parameter is a template.  */	  if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)	    /* Output parameter declaration, argument index and level.  */	    build_mangled_name_for_type (arg);	  else	    {	      /* A TEMPLATE_DECL node, output the parameter declaration 		 and template name */	      OB_PUTC ('z');	      build_template_template_parm_names		(DECL_INNERMOST_TEMPLATE_PARMS (parm));	      icat (IDENTIFIER_LENGTH (DECL_NAME (arg)));	      OB_PUTID (DECL_NAME (arg));	    }	}      else	{	  parm = tsubst (parm, arglist, /*complain=*/1, NULL_TREE);	  /* It's a PARM_DECL.  */	  build_mangled_name_for_type (TREE_TYPE (parm));	  build_overload_value (TREE_TYPE (parm), arg, 				uses_template_parms (arglist));	}    } }/* Output the representation for NAME, which is either a TYPE_DECL or   an IDENTIFIER.  */static voidbuild_overload_identifier (name)     tree name;{  if (TREE_CODE (name) == TYPE_DECL      && CLASS_TYPE_P (TREE_TYPE (name))      && CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (name))      && (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (TREE_TYPE (name)))	  || (TREE_CODE (DECL_CONTEXT (CLASSTYPE_TI_TEMPLATE 				       (TREE_TYPE (name))))	      == FUNCTION_DECL)))    {      /* NAME is the TYPE_DECL for a template specialization.  */      tree template, parmlist, arglist, tname;      template = CLASSTYPE_TI_TEMPLATE (TREE_TYPE (name));      arglist = CLASSTYPE_TI_ARGS (TREE_TYPE (name));      tname = DECL_NAME (template);      parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template);      OB_PUTC ('t');      icat (IDENTIFIER_LENGTH (tname));      OB_PUTID (tname);      build_template_parm_names (parmlist, arglist);    }  else    {      if (TREE_CODE (name) == TYPE_DECL)	name = DECL_NAME (name);      if (numeric_output_need_bar)	{	  OB_PUTC ('_');	  numeric_output_need_bar = 0;	}      icat (IDENTIFIER_LENGTH (name));      OB_PUTID (name);    }}/* Given DECL, either a class TYPE, TYPE_DECL or FUNCTION_DECL, produce   the mangling for it.  Used by build_mangled_name and build_static_name.  */static voidbuild_qualified_name (decl)     tree decl;{  tree context;  int i = 1;  if (TREE_CODE_CLASS (TREE_CODE (decl)) == 't')    decl = TYPE_NAME (decl);  /* If DECL_ASSEMBLER_NAME has been set properly, use it.  */  if (TREE_CODE (decl) == TYPE_DECL      && DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl) && !flag_do_squangling)    {      tree id = DECL_ASSEMBLER_NAME (decl);      OB_PUTID (id);      if (ISDIGIT (IDENTIFIER_POINTER (id) [IDENTIFIER_LENGTH (id) - 1]))	numeric_output_need_bar = 1;      return;    }  context = decl;  /* If we can't find a Ktype, do it the hard way.  */  if (check_ktype (context, FALSE) == -1)    {      /* Count type and namespace scopes.  */      while (1)	{	  context = CP_DECL_CONTEXT (context);	  if (context == global_namespace)	    break;	  i += 1;	  if (check_ktype (context, FALSE) != -1)	    /* Found one!  */	    break;	  if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')	    context = TYPE_NAME (context);	}    }  if (i > 1)    {      OB_PUTC ('Q');      build_underscore_int (i);      numeric_output_need_bar = 0;    }  build_overload_nested_name (decl);}/* Output the mangled representation for TYPE.  If EXTRA_GCODE is   non-zero, mangled names for structure/union types are intentionally   mangled differently from the method described in the ARM.  */static void build_mangled_name_for_type_with_Gcode (type, extra_Gcode)     tree type;     int extra_Gcode;{  if (TYPE_PTRMEMFUNC_P (type))    type = TYPE_PTRMEMFUNC_FN_TYPE (type);  process_modifiers (type);  process_overload_item (type, extra_Gcode);}/* Like build_mangled_name_for_type_with_Gcode, but never outputs the   `G'.  */static voidbuild_mangled_name_for_type (type)     tree type;{  build_mangled_name_for_type_with_Gcode (type, 0);}/* Given a list of parameters in PARMTYPES, create an unambiguous   overload string. Should distinguish any type that C (or C++) can   distinguish. I.e., pointers to functions are treated correctly.   Caller must deal with whether a final `e' goes on the end or not.   Any default conversions must take place before this function   is called.   BEGIN and END control initialization and finalization of the   obstack where we build the string.  */char *build_overload_name (parmtypes, begin, end)     tree parmtypes;     int begin, end;{  char *ret;  start_squangling ();  ret = build_mangled_name (parmtypes, begin, end);  end_squangling ();  return ret ;}/* Output the mangled representation for PARMTYPES.  If PARMTYPES is a   TREE_LIST, then it is a list of parameter types.  Otherwise,   PARMTYPES must be a single type.  */static char *build_mangled_name (parmtypes, begin, end)     tree parmtypes;     int begin, end;{  if (begin)     OB_INIT ();  if (TREE_CODE (parmtypes) != TREE_LIST)      /* There is only one type.  */    build_mangled_name_for_type (parmtypes);  else      {      /* There are several types in a parameter list.  */      int nrepeats = 0;      int old_style_repeats = !flag_do_squangling && !nofold && typevec;      tree last_type = NULL_TREE;      for (; parmtypes && parmtypes != void_list_node;	   parmtypes = TREE_CHAIN (parmtypes))	{	  /* We used to call canonical_type_variant here, but that isn't	     good enough; it doesn't handle pointers to typedef types.  So	     we can't just set TREE_USED to say we've seen a type already;	     we have to check each of the earlier types with same_type_p.  */	  tree parmtype = TREE_VALUE (parmtypes);	  if (old_style_repeats)	    {	      /* Every argument gets counted.  */	      my_friendly_assert (maxtype < typevec_size, 387);	      typevec[maxtype++] = parmtype;	    }	  if (last_type && same_type_p (parmtype, last_type))	    {	      if (flag_do_squangling 		  || (old_style_repeats		      && is_back_referenceable_type (parmtype)))		{		  /* The next type is the same as this one.  Keep		     track of the repetition, and output the repeat		     count later.  */		  nrepeats++;		  continue;		}	    }	  else if (nrepeats != 0)	    {	      /* Indicate how many times the previous parameter was		 repeated.  */	      if (old_style_repeats)		flush_repeats (nrepeats, last_type);	      else		issue_nrepeats (nrepeats, last_type);	      nrepeats = 0;	    }	  	  last_type = parmtype;	  /* Note that for bug-compatibility with 2.7.2, we can't build up	     repeats of types other than the most recent one.  So we call	     flush_repeats every round, if we get this far.  */	  if (old_style_repeats && flush_repeats (0, parmtype))	    continue;	  /* Output the PARMTYPE.  */	  build_mangled_name_for_type_with_Gcode (parmtype, 1);	}      /* Output the repeat count for the last parameter, if	 necessary.  */      if (nrepeats != 0)	{	  if (old_style_repeats)	    flush_repeats (nrepeats, last_type);	  else	    issue_nrepeats (nrepeats, last_type);	  nrepeats = 0;	}      if (!parmtypes)	/* The parameter list ends in an ellipsis.  */	OB_PUTC ('e');    }  if (end)     OB_FINISH ();  return (char *)obstack_base (&scratch_obstack);}