tree chain; for (chain = targs; chain; chain = TREE_CHAIN (chain)) TREE_VALUE (chain) = maybe_fold_nontype_arg (TREE_VALUE (chain));
if (targs && TREE_CODE (targs) == TREE_LIST) { tree chain; for (chain = targs; chain; chain = TREE_CHAIN (chain)) TREE_VALUE (chain) = maybe_fold_nontype_arg (TREE_VALUE (chain)); } else if (targs) { int i; for (i = 0; i < TREE_VEC_LENGTH (targs); ++i) TREE_VEC_ELT (targs, i) = maybe_fold_nontype_arg (TREE_VEC_ELT (targs, i)); }
tsubst_copy (t, args, complain, in_decl)     tree t, args;     int complain;     tree in_decl;{  enum tree_code code;  tree r;  if (t == NULL_TREE || t == error_mark_node)    return t;  code = TREE_CODE (t);  switch (code)    {    case PARM_DECL:      return do_identifier (DECL_NAME (t), 0, NULL_TREE);    case CONST_DECL:      {	tree enum_type;	tree v;	if (!DECL_CONTEXT (t))	  /* This is a global enumeration constant.  */	  return t;	/* Unfortunately, we cannot just call lookup_name here.	 Consider:	 template <int I> int f() {	   enum E { a = I };	   struct S { void g() { E e = a; } };	 };	 When we instantiate f<7>::S::g(), say, lookup_name is not	 clever enough to find f<7>::a.  */	enum_type 	  = tsubst_aggr_type (TREE_TYPE (t), args, complain, in_decl, 			      /*entering_scope=*/0);	for (v = TYPE_VALUES (enum_type); 	     v != NULL_TREE; 	     v = TREE_CHAIN (v))	  if (TREE_PURPOSE (v) == DECL_NAME (t))	    return TREE_VALUE (v);	  /* We didn't find the name.  That should never happen; if	     name-lookup found it during preliminary parsing, we	     should find it again here during instantiation.  */	my_friendly_abort (0);      }      return t;    case FIELD_DECL:      if (DECL_CONTEXT (t))	{	  tree ctx;	  ctx = tsubst_aggr_type (DECL_CONTEXT (t), args, complain, in_decl,				  /*entering_scope=*/1);	  if (ctx != DECL_CONTEXT (t))	    return lookup_field (ctx, DECL_NAME (t), 0, 0);	}      return t;    case VAR_DECL:    case FUNCTION_DECL:      if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t))	t = tsubst (t, args, complain, in_decl);      mark_used (t);      return t;    case TEMPLATE_DECL:      if (is_member_template (t))	return tsubst (t, args, complain, in_decl);      else	return t;    case LOOKUP_EXPR:      {	/* We must tsbust into a LOOKUP_EXPR in case the names to	   which it refers is a conversion operator; in that case the	   name will change.  We avoid making unnecessary copies,	   however.  */		tree id = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);	if (id != TREE_OPERAND (t, 0))	  {	    r = build_nt (LOOKUP_EXPR, id);	    LOOKUP_EXPR_GLOBAL (r) = LOOKUP_EXPR_GLOBAL (t);	    t = r;	  }	return t;      }    case CAST_EXPR:    case REINTERPRET_CAST_EXPR:    case CONST_CAST_EXPR:    case STATIC_CAST_EXPR:    case DYNAMIC_CAST_EXPR:    case NOP_EXPR:      return build1	(code, tsubst (TREE_TYPE (t), args, complain, in_decl),	 tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl));    case INDIRECT_REF:    case PREDECREMENT_EXPR:    case PREINCREMENT_EXPR:    case POSTDECREMENT_EXPR:    case POSTINCREMENT_EXPR:    case NEGATE_EXPR:    case TRUTH_NOT_EXPR:    case BIT_NOT_EXPR:    case ADDR_EXPR:    case CONVERT_EXPR:      /* Unary + */    case SIZEOF_EXPR:    case ALIGNOF_EXPR:    case ARROW_EXPR:    case THROW_EXPR:    case TYPEID_EXPR:      return build1	(code, tsubst (TREE_TYPE (t), args, complain, in_decl),	 tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl));    case PLUS_EXPR:    case MINUS_EXPR:    case MULT_EXPR:    case TRUNC_DIV_EXPR:    case CEIL_DIV_EXPR:    case FLOOR_DIV_EXPR:    case ROUND_DIV_EXPR:    case EXACT_DIV_EXPR:    case BIT_AND_EXPR:    case BIT_ANDTC_EXPR:    case BIT_IOR_EXPR:    case BIT_XOR_EXPR:    case TRUNC_MOD_EXPR:    case FLOOR_MOD_EXPR:    case TRUTH_ANDIF_EXPR:    case TRUTH_ORIF_EXPR:    case TRUTH_AND_EXPR:    case TRUTH_OR_EXPR:    case RSHIFT_EXPR:    case LSHIFT_EXPR:    case RROTATE_EXPR:    case LROTATE_EXPR:    case EQ_EXPR:    case NE_EXPR:    case MAX_EXPR:    case MIN_EXPR:    case LE_EXPR:    case GE_EXPR:    case LT_EXPR:    case GT_EXPR:    case COMPONENT_REF:    case ARRAY_REF:    case COMPOUND_EXPR:    case SCOPE_REF:    case DOTSTAR_EXPR:    case MEMBER_REF:      return build_nt	(code, tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),	 tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl));    case CALL_EXPR:      {	tree fn = TREE_OPERAND (t, 0);	if (is_overloaded_fn (fn))	  fn = tsubst_copy (get_first_fn (fn), args, complain, in_decl);	else	  /* Sometimes FN is a LOOKUP_EXPR.  */	  fn = tsubst_copy (fn, args, complain, in_decl);	return build_nt	  (code, fn, tsubst_copy (TREE_OPERAND (t, 1), args, complain,				  in_decl),	   NULL_TREE);      }    case METHOD_CALL_EXPR:      {	tree name = TREE_OPERAND (t, 0);	if (TREE_CODE (name) == BIT_NOT_EXPR)	  {	    name = tsubst_copy (TREE_OPERAND (name, 0), args,				complain, in_decl);	    name = build1 (BIT_NOT_EXPR, NULL_TREE, name);	  }	else if (TREE_CODE (name) == SCOPE_REF		 && TREE_CODE (TREE_OPERAND (name, 1)) == BIT_NOT_EXPR)	  {	    tree base = tsubst_copy (TREE_OPERAND (name, 0), args,				     complain, in_decl);	    name = TREE_OPERAND (name, 1);	    name = tsubst_copy (TREE_OPERAND (name, 0), args,				complain, in_decl);	    name = build1 (BIT_NOT_EXPR, NULL_TREE, name);	    name = build_nt (SCOPE_REF, base, name);	  }	else	  name = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);	return build_nt	  (code, name, tsubst_copy (TREE_OPERAND (t, 1), args,				    complain, in_decl),	   tsubst_copy (TREE_OPERAND (t, 2), args, complain, in_decl),	   NULL_TREE);      }    case BIND_EXPR:    case COND_EXPR:    case MODOP_EXPR:      {	r = build_nt	  (code, tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),	   tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl),	   tsubst_copy (TREE_OPERAND (t, 2), args, complain, in_decl));	if (code == BIND_EXPR && !processing_template_decl)	  {	    /* This processing should really occur in tsubst_expr,	       However, tsubst_expr does not recurse into expressions,	       since it assumes that there aren't any statements	       inside them.  Instead, it simply calls	       build_expr_from_tree.  So, we need to expand the	       BIND_EXPR here.  */ 	    tree rtl_expr = begin_stmt_expr ();	    tree block = tsubst_expr (TREE_OPERAND (r, 1), args,				      complain, in_decl);	    r = finish_stmt_expr (rtl_expr, block);	  }	return r;      }    case NEW_EXPR:      {	r = build_nt	(code, tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),	 tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl),	 tsubst_copy (TREE_OPERAND (t, 2), args, complain, in_decl));	NEW_EXPR_USE_GLOBAL (r) = NEW_EXPR_USE_GLOBAL (t);	return r;      }    case DELETE_EXPR:      {	r = build_nt	(code, tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),	 tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl));	DELETE_EXPR_USE_GLOBAL (r) = DELETE_EXPR_USE_GLOBAL (t);	DELETE_EXPR_USE_VEC (r) = DELETE_EXPR_USE_VEC (t);	return r;      }    case TEMPLATE_ID_EXPR:      {        /* Substituted template arguments */	tree targs = tsubst_copy (TREE_OPERAND (t, 1), args, complain,				  in_decl);	tree chain;	for (chain = targs; chain; chain = TREE_CHAIN (chain))	  TREE_VALUE (chain) = maybe_fold_nontype_arg (TREE_VALUE (chain));	return lookup_template_function	  (tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl), targs);      }    case TREE_LIST:      {	tree purpose, value, chain;	if (t == void_list_node)	  return t;	purpose = TREE_PURPOSE (t);	if (purpose)	  purpose = tsubst_copy (purpose, args, complain, in_decl);	value = TREE_VALUE (t);	if (value)	  value = tsubst_copy (value, args, complain, in_decl);	chain = TREE_CHAIN (t);	if (chain && chain != void_type_node)	  chain = tsubst_copy (chain, args, complain, in_decl);	if (purpose == TREE_PURPOSE (t)	    && value == TREE_VALUE (t)	    && chain == TREE_CHAIN (t))	  return t;	return tree_cons (purpose, value, chain);      }    case RECORD_TYPE:    case UNION_TYPE:    case ENUMERAL_TYPE:    case INTEGER_TYPE:    case TEMPLATE_TYPE_PARM:    case TEMPLATE_TEMPLATE_PARM:    case TEMPLATE_PARM_INDEX:    case POINTER_TYPE:    case REFERENCE_TYPE:    case OFFSET_TYPE:    case FUNCTION_TYPE:    case METHOD_TYPE:    case ARRAY_TYPE:    case TYPENAME_TYPE:    case TYPE_DECL:      return tsubst (t, args, complain, in_decl);    case IDENTIFIER_NODE:      if (IDENTIFIER_TYPENAME_P (t)	  /* Make sure it's not just a variable named `__opr', for instance,	     which can occur in some existing code.  */	  && TREE_TYPE (t))	return build_typename_overload	  (tsubst (TREE_TYPE (t), args, complain, in_decl));      else	return t;    case CONSTRUCTOR:      {	r = build	  (CONSTRUCTOR, tsubst (TREE_TYPE (t), args, complain, in_decl), 	   NULL_TREE, tsubst_copy (CONSTRUCTOR_ELTS (t), args,				   complain, in_decl));	TREE_HAS_CONSTRUCTOR (r) = TREE_HAS_CONSTRUCTOR (t);	return r;      }    default:      return t;    }}