while (ffebld_op (expr) == FFEBLD_opPAREN) expr = ffebld_left (expr);
ffecom_arg_ptr_to_expr (ffebld expr, tree *length){  tree item;  tree ign_length;  ffecomConcatList_ catlist;  if (length != NULL)    *length = NULL_TREE;  if (expr == NULL)    return integer_zero_node;  switch (ffebld_op (expr))    {    case FFEBLD_opPERCENT_VAL:      if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)	return ffecom_expr (ffebld_left (expr));      {	tree temp_exp;	tree temp_length;	temp_exp = ffecom_arg_ptr_to_expr (ffebld_left (expr), &temp_length);	if (temp_exp == error_mark_node)	  return error_mark_node;	return ffecom_1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (temp_exp)),			 temp_exp);      }    case FFEBLD_opPERCENT_REF:      if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)	return ffecom_ptr_to_expr (ffebld_left (expr));      if (length != NULL)	{	  ign_length = NULL_TREE;	  length = &ign_length;	}      expr = ffebld_left (expr);      break;    case FFEBLD_opPERCENT_DESCR:      switch (ffeinfo_basictype (ffebld_info (expr)))	{#ifdef PASS_HOLLERITH_BY_DESCRIPTOR	case FFEINFO_basictypeHOLLERITH:#endif	case FFEINFO_basictypeCHARACTER:	  break;		/* Passed by descriptor anyway. */	default:	  item = ffecom_ptr_to_expr (expr);	  if (item != error_mark_node)	    *length = TYPE_SIZE (TREE_TYPE (TREE_TYPE (item)));	  break;	}      break;    default:      break;    }#ifdef PASS_HOLLERITH_BY_DESCRIPTOR  if ((ffeinfo_basictype (ffebld_info (expr)) == FFEINFO_basictypeHOLLERITH)      && (length != NULL))    {				/* Pass Hollerith by descriptor. */      ffetargetHollerith h;      assert (ffebld_op (expr) == FFEBLD_opCONTER);      h = ffebld_cu_val_hollerith (ffebld_constant_union				   (ffebld_conter (expr)));      *length	= build_int_2 (h.length, 0);      TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;    }#endif  if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)    return ffecom_ptr_to_expr (expr);  assert (ffeinfo_kindtype (ffebld_info (expr))	  == FFEINFO_kindtypeCHARACTER1);  catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE);  switch (ffecom_concat_list_count_ (catlist))    {    case 0:			/* Shouldn't happen, but in case it does... */      if (length != NULL)	{	  *length = ffecom_f2c_ftnlen_zero_node;	  TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;	}      ffecom_concat_list_kill_ (catlist);      return null_pointer_node;    case 1:			/* The (fairly) easy case. */      if (length == NULL)	ffecom_char_args_with_null_ (&item, &ign_length,				     ffecom_concat_list_expr_ (catlist, 0));      else	ffecom_char_args_ (&item, length,			   ffecom_concat_list_expr_ (catlist, 0));      ffecom_concat_list_kill_ (catlist);      assert (item != NULL_TREE);      return item;    default:			/* Must actually concatenate things. */      break;    }  {    int count = ffecom_concat_list_count_ (catlist);    int i;    tree lengths;    tree items;    tree length_array;    tree item_array;    tree citem;    tree clength;    tree temporary;    tree num;    tree known_length;    ffetargetCharacterSize sz;    sz = ffecom_concat_list_maxlen_ (catlist);    /* ~~Kludge! */    assert (sz != FFETARGET_charactersizeNONE);#ifdef HOHO    length_array      = lengths      = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node,			     FFETARGET_charactersizeNONE, count, TRUE);    item_array      = items      = ffecom_push_tempvar (ffecom_f2c_address_type_node,			     FFETARGET_charactersizeNONE, count, TRUE);    temporary = ffecom_push_tempvar (char_type_node,				     sz, -1, TRUE);#else    {      tree hook;      hook = ffebld_nonter_hook (expr);      assert (hook);      assert (TREE_CODE (hook) == TREE_VEC);      assert (TREE_VEC_LENGTH (hook) == 3);      length_array = lengths = TREE_VEC_ELT (hook, 0);      item_array = items = TREE_VEC_ELT (hook, 1);      temporary = TREE_VEC_ELT (hook, 2);    }#endif    known_length = ffecom_f2c_ftnlen_zero_node;    for (i = 0; i < count; ++i)      {	if ((i == count)	    && (length == NULL))	  ffecom_char_args_with_null_ (&citem, &clength,				       ffecom_concat_list_expr_ (catlist, i));	else	  ffecom_char_args_ (&citem, &clength,			     ffecom_concat_list_expr_ (catlist, i));	if ((citem == error_mark_node)	    || (clength == error_mark_node))	  {	    ffecom_concat_list_kill_ (catlist);	    *length = error_mark_node;	    return error_mark_node;	  }	items	  = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items),		      ffecom_modify (void_type_node,				     ffecom_2 (ARRAY_REF,		     TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))),					       item_array,					       build_int_2 (i, 0)),				     citem),		      items);	clength = ffecom_save_tree (clength);	if (length != NULL)	  known_length	    = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node,			known_length,			clength);	lengths	  = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths),		      ffecom_modify (void_type_node,				     ffecom_2 (ARRAY_REF,		   TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))),					       length_array,					       build_int_2 (i, 0)),				     clength),		      lengths);      }    temporary = ffecom_1 (ADDR_EXPR,			  build_pointer_type (TREE_TYPE (temporary)),			  temporary);    item = build_tree_list (NULL_TREE, temporary);    TREE_CHAIN (item)      = build_tree_list (NULL_TREE,			 ffecom_1 (ADDR_EXPR,				   build_pointer_type (TREE_TYPE (items)),				   items));    TREE_CHAIN (TREE_CHAIN (item))      = build_tree_list (NULL_TREE,			 ffecom_1 (ADDR_EXPR,				   build_pointer_type (TREE_TYPE (lengths)),				   lengths));    TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))      = build_tree_list	(NULL_TREE,	 ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node,		   convert (ffecom_f2c_ftnlen_type_node,			    build_int_2 (count, 0))));    num = build_int_2 (sz, 0);    TREE_TYPE (num) = ffecom_f2c_ftnlen_type_node;    TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item))))      = build_tree_list (NULL_TREE, num);    item = ffecom_call_gfrt (FFECOM_gfrtCAT, item, NULL_TREE);    TREE_SIDE_EFFECTS (item) = 1;    item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (temporary),		     item,		     temporary);    if (length != NULL)      *length = known_length;  }  ffecom_concat_list_kill_ (catlist);  assert (item != NULL_TREE);  return item;}