/* Rewrite the expression tree for coarrays.
   Copyright (C) 2010-2025 Free Software Foundation, Inc.
   Contributed by Andre Vehreschild.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

/* Rewrite the expression for coarrays where needed:
   - coarray indexing operations need the indexing expression put into a
     routine callable on the remote image

   This rewriter is meant to used for non-optimisational expression tree
   rewrites.  When implementing early optimisation it is recommended to
   do this in frontend-passes.cc.
*/

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "options.h"
#include "bitmap.h"
#include "gfortran.h"

/* The code tree element that is currently processed.  */
static gfc_code **current_code;

/* Code that is inserted into the current caf_accessor at the beginning.  */
static gfc_code *caf_accessor_prepend = nullptr;

static bool caf_on_lhs = false;

static int caf_sym_cnt = 0;

static gfc_array_spec *
get_arrayspec_from_expr (gfc_expr *expr)
{
  gfc_array_spec *src_as, *dst_as = NULL;
  gfc_ref *ref;
  gfc_array_ref mod_src_ar;
  int dst_rank = 0;

  if (expr->rank == 0)
    return NULL;

  if (expr->expr_type == EXPR_FUNCTION)
    return gfc_copy_array_spec (expr->symtree->n.sym->as);

  /* Follow any component references.  */
  if (expr->expr_type == EXPR_VARIABLE || expr->expr_type == EXPR_CONSTANT)
    {
      if (expr->symtree)
	src_as = expr->symtree->n.sym->as;
      else
	src_as = NULL;

      for (ref = expr->ref; ref; ref = ref->next)
	{
	  switch (ref->type)
	    {
	    case REF_COMPONENT:
	      src_as = ref->u.c.component->as;
	      continue;

	    case REF_SUBSTRING:
	    case REF_INQUIRY:
	      continue;

	    case REF_ARRAY:
	      switch (ref->u.ar.type)
		{
		case AR_ELEMENT:
		  src_as = NULL;
		  break;
		case AR_SECTION:
		  {
		    if (!dst_as)
		      dst_as = gfc_get_array_spec ();
		    memset (&mod_src_ar, 0, sizeof (gfc_array_ref));
		    mod_src_ar = ref->u.ar;
		    for (int dim = 0; dim < src_as->rank; ++dim)
		      {
			switch (ref->u.ar.dimen_type[dim])
			  {
			  case DIMEN_ELEMENT:
			    gfc_free_expr (mod_src_ar.start[dim]);
			    mod_src_ar.start[dim] = NULL;
			    break;
			  case DIMEN_RANGE:
			    dst_as->lower[dst_rank]
			      = gfc_copy_expr (ref->u.ar.start[dim]);
			    mod_src_ar.start[dst_rank]
			      = gfc_copy_expr (ref->u.ar.start[dim]);
			    if (ref->u.ar.end[dim])
			      {
				dst_as->upper[dst_rank]
				  = gfc_copy_expr (ref->u.ar.end[dim]);
				mod_src_ar.end[dst_rank] = ref->u.ar.end[dim];
				mod_src_ar.stride[dst_rank]
				  = ref->u.ar.stride[dim];
			      }
			    else
			      dst_as->upper[dst_rank]
				= gfc_copy_expr (ref->u.ar.as->upper[dim]);
			    ++dst_rank;
			    break;
			  case DIMEN_STAR:
			    dst_as->lower[dst_rank]
			      = gfc_copy_expr (ref->u.ar.as->lower[dim]);
			    mod_src_ar.start[dst_rank]
			      = gfc_copy_expr (ref->u.ar.start[dim]);
			    if (ref->u.ar.as->upper[dim])
			      {
				dst_as->upper[dst_rank]
				  = gfc_copy_expr (ref->u.ar.as->upper[dim]);
				mod_src_ar.end[dst_rank] = ref->u.ar.end[dim];
				mod_src_ar.stride[dst_rank]
				  = ref->u.ar.stride[dim];
			      }
			    ++dst_rank;
			    break;
			  case DIMEN_VECTOR:
			    dst_as->lower[dst_rank]
			      = gfc_get_constant_expr (BT_INTEGER,
						       gfc_index_integer_kind,
						       &expr->where);
			    mpz_set_ui (dst_as->lower[dst_rank]->value.integer,
					1);
			    mod_src_ar.start[dst_rank]
			      = gfc_copy_expr (ref->u.ar.start[dim]);
			    dst_as->upper[dst_rank]
			      = gfc_get_constant_expr (BT_INTEGER,
						       gfc_index_integer_kind,
						       &expr->where);
			    mpz_set (dst_as->upper[dst_rank]->value.integer,
				     ref->u.ar.start[dim]->shape[0]);
			    ++dst_rank;
			    break;
			  case DIMEN_THIS_IMAGE:
			  case DIMEN_UNKNOWN:
			    gcc_unreachable ();
			  }
			if (ref->u.ar.dimen_type[dim] != DIMEN_ELEMENT)
			  mod_src_ar.dimen_type[dst_rank]
			    = ref->u.ar.dimen_type[dim];
		      }
		    dst_as->rank = dst_rank;
		    dst_as->type = AS_EXPLICIT;
		    ref->u.ar = mod_src_ar;
		    ref->u.ar.dimen = dst_rank;
		    break;

		  case AR_UNKNOWN:
		    src_as = NULL;
		    break;

		  case AR_FULL:
		    if (dst_as)
		      /* Prevent memory loss.  */
		      gfc_free_array_spec (dst_as);
		    dst_as = gfc_copy_array_spec (src_as);
		    break;
		  }
		  break;
		}
	    }
	}
    }
  else
    src_as = NULL;

  return dst_as;
}

static void
remove_coarray_from_derived_type (gfc_symbol *base, gfc_namespace *ns,
				  gfc_array_spec *src_as = NULL)
{
  gfc_symbol *derived;
  gfc_symbol *src_derived = base->ts.u.derived;

  if (!src_as)
    src_as = src_derived->as;
  gfc_get_symbol (src_derived->name, ns, &derived);
  derived->attr.flavor = FL_DERIVED;
  derived->attr.alloc_comp = src_derived->attr.alloc_comp;
  if (src_as && src_as->rank != 0)
    {
      base->attr.dimension = 1;
      base->as = gfc_copy_array_spec (src_as);
      base->as->corank = 0;
    }
  for (gfc_component *p = NULL, *c = src_derived->components; c; c = c->next)
    {
      gfc_component *n = gfc_get_component ();
      *n = *c;
      if (n->as)
	n->as = gfc_copy_array_spec (c->as);
      n->backend_decl = NULL;
      n->initializer = NULL;
      n->param_list = NULL;
      if (p)
	p->next = n;
      else
	derived->components = n;

      p = n;
    }
  derived->declared_at = base->declared_at;
  gfc_set_sym_referenced (derived);
  gfc_commit_symbol (derived);
  base->ts.u.derived = derived;
  gfc_commit_symbol (base);
}

static void
convert_coarray_class_to_derived_type (gfc_symbol *base, gfc_namespace *ns)
{
  gfc_symbol *src_derived = CLASS_DATA (base)->ts.u.derived;
  gfc_array_spec *src_as = CLASS_DATA (base)->as;
  const bool attr_allocatable
    = src_as && src_as->rank && src_as->type == AS_DEFERRED;

  base->ts.type = BT_DERIVED;
  base->ts.u.derived = src_derived;

  remove_coarray_from_derived_type (base, ns, src_as);

  base->attr.allocatable = attr_allocatable;
  base->attr.pointer = 0; // Ensure, that it is no pointer.
}

static void
move_coarray_ref (gfc_ref **from, gfc_expr *expr)
{
  int i;
  gfc_ref *to = expr->ref;
  for (; to && to->next; to = to->next)
    ;

  if (!to)
    {
      expr->ref = gfc_get_ref ();
      to = expr->ref;
      to->type = REF_ARRAY;
    }
  gcc_assert (to->type == REF_ARRAY);
  to->u.ar.as = gfc_copy_array_spec ((*from)->u.ar.as);
  to->u.ar.codimen = (*from)->u.ar.codimen;
  to->u.ar.dimen = (*from)->u.ar.dimen;
  to->u.ar.type = AR_FULL;
  to->u.ar.stat = (*from)->u.ar.stat;
  (*from)->u.ar.stat = nullptr;
  to->u.ar.team = (*from)->u.ar.team;
  (*from)->u.ar.team = nullptr;
  to->u.ar.team_type = (*from)->u.ar.team_type;
  (*from)->u.ar.team_type = TEAM_UNSET;
  for (i = 0; i < to->u.ar.dimen; ++i)
    {
      to->u.ar.start[i] = nullptr;
      to->u.ar.end[i] = nullptr;
      to->u.ar.stride[i] = nullptr;
    }
  for (i = (*from)->u.ar.dimen; i < (*from)->u.ar.dimen + (*from)->u.ar.codimen;
       ++i)
    {
      to->u.ar.dimen_type[i] = (*from)->u.ar.dimen_type[i];
      to->u.ar.start[i] = (*from)->u.ar.start[i];
      (*from)->u.ar.start[i] = nullptr;
      to->u.ar.end[i] = (*from)->u.ar.end[i];
      (*from)->u.ar.end[i] = nullptr;
      to->u.ar.stride[i] = (*from)->u.ar.stride[i];
      (*from)->u.ar.stride[i] = nullptr;
    }
  (*from)->u.ar.codimen = 0;
  if ((*from)->u.ar.dimen == 0)
    {
      gfc_ref *nref = (*from)->next;
      (*from)->next = nullptr;
      gfc_free_ref_list (*from);
      *from = nref;
    }
}

static void
fixup_comp_refs (gfc_expr *expr)
{
  bool class_ref = expr->symtree->n.sym->ts.type == BT_CLASS;
  gfc_symbol *type
    = expr->symtree->n.sym->ts.type == BT_DERIVED
	? expr->symtree->n.sym->ts.u.derived
	: (class_ref ? CLASS_DATA (expr->symtree->n.sym)->ts.u.derived
		     : nullptr);
  if (!type)
    return;
  gfc_ref **pref = &(expr->ref);
  for (gfc_ref *ref = expr->ref; ref && type;)
    {
      switch (ref->type)
	{
	case REF_COMPONENT:
	  gfc_find_component (type, ref->u.c.component->name, false, true,
			      pref);
	  if (!*pref)
	    {
	      /* This happens when there were errors previously.  Just don't
		 crash.  */
	      ref = nullptr;
	      break;
	    }
	  if (class_ref)
	    /* Link to the class type to allow for derived type resolution.  */
	    (*pref)->u.c.sym = ref->u.c.sym;
	  (*pref)->next = ref->next;
	  ref->next = NULL;
	  gfc_free_ref_list (ref);
	  ref = (*pref)->next;
	  type = (*pref)->u.c.component->ts.type == BT_DERIVED
		   ? (*pref)->u.c.component->ts.u.derived
		   : ((*pref)->u.c.component->ts.type == BT_CLASS
			? CLASS_DATA ((*pref)->u.c.component)->ts.u.derived
			: nullptr);
	  pref = &(*pref)->next;
	  break;
	case REF_ARRAY:
	  pref = &ref->next;
	  ref = ref->next;
	  break;
	default:
	  gcc_unreachable ();
	  break;
	}
    }
}

static void
split_expr_at_caf_ref (gfc_expr *expr, gfc_namespace *ns,
		       gfc_expr **post_caf_ref_expr, bool for_send)
{
  gfc_ref *caf_ref = NULL;
  gfc_symtree *st;
  gfc_symbol *base;
  gfc_typespec *caf_ts;
  bool created;

  gcc_assert (expr->expr_type == EXPR_VARIABLE);
  caf_ts = &expr->symtree->n.sym->ts;
  if (!(expr->symtree->n.sym->ts.type == BT_CLASS
	  ? CLASS_DATA (expr->symtree->n.sym)->attr.codimension
	  : expr->symtree->n.sym->attr.codimension))
    {
      /* The coarray is in some component.  Find it.  */
      caf_ref = expr->ref;
      while (caf_ref)
	{
	  if (caf_ref->type == REF_ARRAY && caf_ref->u.ar.codimen != 0)
	    break;
	  if (caf_ref->type == REF_COMPONENT)
	    caf_ts = &caf_ref->u.c.component->ts;
	  caf_ref = caf_ref->next;
	}
    }

  created = !gfc_get_sym_tree (!caf_ref ? expr->symtree->name : "base", ns, &st,
			       false);
  gcc_assert (created);
  st->n.sym->attr.flavor = FL_PARAMETER;
  st->n.sym->attr.dummy = 1;
  st->n.sym->attr.intent = INTENT_IN;
  st->n.sym->ts = *caf_ts;
  st->n.sym->declared_at = expr->where;

  *post_caf_ref_expr = gfc_get_variable_expr (st);
  (*post_caf_ref_expr)->where = expr->where;
  base = (*post_caf_ref_expr)->symtree->n.sym;

  if (!caf_ref)
    {
      (*post_caf_ref_expr)->ref = gfc_get_ref ();
      *(*post_caf_ref_expr)->ref = *expr->ref;
      expr->ref = nullptr;
      move_coarray_ref (&(*post_caf_ref_expr)->ref, expr);
      fixup_comp_refs (expr);

      if (expr->symtree->n.sym->attr.dimension)
	{
	  base->as = gfc_copy_array_spec (expr->symtree->n.sym->as);
	  base->as->corank = 0;
	  base->attr.dimension = 1;
	  base->attr.allocatable = expr->symtree->n.sym->attr.allocatable;
	  base->attr.pointer = expr->symtree->n.sym->attr.pointer
			       || expr->symtree->n.sym->attr.associate_var;
	}
    }
  else
    {
      (*post_caf_ref_expr)->ref = gfc_get_ref ();
      *(*post_caf_ref_expr)->ref = *caf_ref;
      caf_ref->next = nullptr;
      move_coarray_ref (&(*post_caf_ref_expr)->ref, expr);
      fixup_comp_refs (expr);

      if (caf_ref && caf_ref->u.ar.dimen)
	{
	  base->as = gfc_copy_array_spec (caf_ref->u.ar.as);
	  base->as->corank = 0;
	  base->attr.dimension = 1;
	  base->attr.allocatable = caf_ref->u.ar.as->type != AS_EXPLICIT;
	}
      base->ts = *caf_ts;
    }
  (*post_caf_ref_expr)->ts = expr->ts;
  if (base->ts.type == BT_CHARACTER)
    {
      base->ts.u.cl = gfc_get_charlen ();
      *base->ts.u.cl = *(caf_ts->u.cl);
      base->ts.deferred = 1;
      base->ts.u.cl->length = nullptr;
    }
  else if (base->ts.type == BT_DERIVED)
    remove_coarray_from_derived_type (base, ns);
  else if (base->ts.type == BT_CLASS)
    convert_coarray_class_to_derived_type (base, ns);

  memset (&(*post_caf_ref_expr)->ts, 0, sizeof (gfc_typespec));
  gfc_resolve_expr (*post_caf_ref_expr);
  (*post_caf_ref_expr)->corank = 0;
  gfc_expression_rank (*post_caf_ref_expr);
  if (for_send)
    gfc_expression_rank (expr);
  else
    expr->rank = (*post_caf_ref_expr)->rank;
}

static void add_caf_get_from_remote (gfc_expr *e);

static gfc_component *
find_comp (gfc_symbol *type, gfc_expr *e, int *cnt, const bool is_var)
{
  char *temp_name = nullptr;
  gfc_component *comp = type->components;

  /* For variables:
     - look up same name or create new
     all else:
     - create unique new
  */
  if (is_var)
    {
      ++(*cnt);
      free (temp_name);
      temp_name = xasprintf ("caf_temp_%s_%d", e->symtree->name, *cnt);
      while (comp && strcmp (comp->name, temp_name) != 0)
	comp = comp->next;
      if (!comp)
	{
	  const bool added = gfc_add_component (type, temp_name, &comp);
	  gcc_assert (added);
	}
    }
  else
    {
      int r = -1;
      /* Components are always appended, i.e., when searching to add a unique
	 one just iterating forward is sufficient.  */
      do
	{
	  ++(*cnt);
	  free (temp_name);
	  temp_name = xasprintf ("caf_temp_%s_%d", e->symtree->name, *cnt);

	  while (comp && (r = strcmp (comp->name, temp_name)) <= 0)
	    comp = comp->next;
	}
      while (comp && r <= 0);
      {
	const bool added = gfc_add_component (type, temp_name, &comp);
	gcc_assert (added);
      }
    }

  comp->loc = e->where;
  comp->ts = e->ts;
  free (temp_name);

  return comp;
}

static void
check_add_new_comp_handle_array (gfc_expr *e, gfc_symbol *type,
				 gfc_symbol *add_data)
{
  gfc_component *comp;
  static int cnt = -1;
  gfc_symtree *caller_image;
  gfc_code *pre_code = caf_accessor_prepend;
  bool static_array_or_scalar = true;
  symbol_attribute e_attr = gfc_expr_attr (e);

  gfc_free_shape (&e->shape, e->rank);

  /* When already code to prepend into the accessor exists, go to
     the end of the chain.  */
  for (; pre_code && pre_code->next; pre_code = pre_code->next)
    ;

  comp = find_comp (type, e, &cnt,
		    e->symtree->n.sym->attr.flavor == FL_VARIABLE
		      || e->symtree->n.sym->attr.flavor == FL_PARAMETER);

  if (e->expr_type == EXPR_FUNCTION
      || (e->expr_type == EXPR_VARIABLE && e_attr.dimension
	  && e_attr.allocatable))
    {
      gfc_code *code;
      gfc_symtree *st;
      const bool created
	= !gfc_get_sym_tree (comp->name, gfc_current_ns, &st, false, &e->where);
      gcc_assert (created);

      st->n.sym->ts = e->ts;
      gfc_set_sym_referenced (st->n.sym);
      code = gfc_get_code (EXEC_ASSIGN);
      code->loc = e->where;
      code->expr1 = gfc_get_variable_expr (st);
      code->expr2 = XCNEW (gfc_expr);
      *(code->expr2) = *e;
      code->next = *current_code;
      *current_code = code;

      if (e_attr.dimension)
	{
	  gfc_array_spec *as = get_arrayspec_from_expr (e);
	  static_array_or_scalar = gfc_is_compile_time_shape (as);

	  comp->attr.dimension = 1;
	  st->n.sym->attr.dimension = 1;
	  st->n.sym->as = as;

	  if (!static_array_or_scalar)
	    {
	      comp->attr.allocatable = 1;
	      st->n.sym->attr.allocatable = 1;
	    }
	  code->expr1->rank = as->rank;
	  gfc_add_full_array_ref (code->expr1, gfc_copy_array_spec (as));
	  comp->as = gfc_copy_array_spec (as);
	}

      gfc_expression_rank (code->expr1);
      comp->initializer = gfc_get_variable_expr (st);
      gfc_commit_symbol (st->n.sym);
    }
  else
    {
      comp->initializer = gfc_copy_expr (e);
      if (e_attr.dimension && e->rank)
	{
	  comp->attr.dimension = 1;
	  comp->as = get_arrayspec_from_expr (e);
	}
    }
  comp->initializer->where = e->where;
  comp->attr.access = ACCESS_PRIVATE;
  memset (e, 0, sizeof (gfc_expr));
  e->ts = comp->initializer->ts;
  e->expr_type = EXPR_VARIABLE;
  e->where = comp->initializer->where;

  if (comp->as && comp->as->rank)
    {
      if (static_array_or_scalar)
	{
	  e->ref = gfc_get_ref ();
	  e->ref->type = REF_ARRAY;
	  e->ref->u.ar.as = gfc_copy_array_spec (add_data->as);
	  e->ref->u.ar.codimen = 1;
	  e->ref->u.ar.dimen_type[0] = DIMEN_THIS_IMAGE;
	}
      else
	{
	  gfc_code *c;
	  gfc_symtree *lv, *ad;
	  bool created = !gfc_get_sym_tree (comp->name, add_data->ns, &lv,
					    false, &e->where);
	  gcc_assert (created);

	  lv->n.sym->ts = e->ts;
	  lv->n.sym->attr.dimension = 1;
	  lv->n.sym->attr.allocatable = 1;
	  lv->n.sym->attr.flavor = FL_VARIABLE;
	  lv->n.sym->as = gfc_copy_array_spec (comp->as);
	  gfc_set_sym_referenced (lv->n.sym);
	  gfc_commit_symbol (lv->n.sym);
	  c = gfc_get_code (EXEC_ASSIGN);
	  c->loc = e->where;
	  c->expr1 = gfc_get_variable_expr (lv);
	  c->expr1->where = e->where;

	  created = !gfc_find_sym_tree (add_data->name, add_data->ns, 0, &ad);
	  gcc_assert (created);
	  c->expr2 = gfc_get_variable_expr (ad);
	  c->expr2->where = e->where;
	  c->expr2->ts = comp->initializer->ts;
	  c->expr2->ref = gfc_get_ref ();
	  c->expr2->ref->type = REF_ARRAY;
	  c->expr2->ref->u.ar.as = gfc_copy_array_spec (add_data->as);
	  c->expr2->ref->u.ar.codimen = 1;
	  c->expr2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
	  caller_image
	    = gfc_find_symtree_in_proc ("caller_image", add_data->ns);
	  gcc_assert (caller_image);
	  c->expr2->ref->u.ar.start[0] = gfc_get_variable_expr (caller_image);
	  c->expr2->ref->u.ar.start[0]->where = e->where;
	  created = gfc_find_component (ad->n.sym->ts.u.derived, comp->name,
					false, true, &c->expr2->ref->next)
		    != nullptr;
	  gcc_assert (created);
	  c->expr2->rank = comp->as->rank;
	  gfc_add_full_array_ref (c->expr2, gfc_copy_array_spec (comp->as));
	  gfc_set_sym_referenced (ad->n.sym);
	  gfc_commit_symbol (ad->n.sym);
	  if (pre_code)
	    pre_code->next = c;
	  else
	    caf_accessor_prepend = c;
	  add_caf_get_from_remote (c->expr2);

	  e->symtree = lv;
	  gfc_expression_rank (e);
	  gfc_add_full_array_ref (e, gfc_copy_array_spec (comp->as));
	}
    }
  else
    {
      e->ref = gfc_get_ref ();
      e->ref->type = REF_ARRAY;
      e->ref->u.ar.as = gfc_copy_array_spec (add_data->as);
      e->ref->u.ar.codimen = 1;
      e->ref->u.ar.dimen_type[0] = DIMEN_THIS_IMAGE;
    }

  if (static_array_or_scalar)
    {
      const bool created
	= gfc_find_component (add_data->ts.u.derived, comp->name, false, true,
			      &e->ref);
      gcc_assert (created);
      e->symtree = gfc_find_symtree (add_data->ns->sym_root, add_data->name);
      gcc_assert (e->symtree);
      if (IS_CLASS_ARRAY (e->ref->u.c.component)
	  || e->ref->u.c.component->attr.dimension)
	{
	  gfc_add_full_array_ref (e, e->ref->u.c.component->ts.type == BT_CLASS
				       ? CLASS_DATA (e->ref->u.c.component)->as
				       : e->ref->u.c.component->as);
	  e->ref->next->u.ar.dimen
	    = e->ref->u.c.component->ts.type == BT_CLASS
		? CLASS_DATA (e->ref->u.c.component)->as->rank
		: e->ref->u.c.component->as->rank;
	}
      gfc_expression_rank (e);
    }
}

static void
check_add_new_component (gfc_symbol *type, gfc_expr *e, gfc_symbol *add_data)
{
  if (e)
    {
      switch (e->expr_type)
	{
	case EXPR_CONSTANT:
	case EXPR_NULL:
	  break;
	case EXPR_OP:
	  check_add_new_component (type, e->value.op.op1, add_data);
	  if (e->value.op.op2)
	    check_add_new_component (type, e->value.op.op2, add_data);
	  break;
	case EXPR_COMPCALL:
	  for (gfc_actual_arglist *actual = e->value.compcall.actual; actual;
	       actual = actual->next)
	    check_add_new_component (type, actual->expr, add_data);
	  break;
	case EXPR_FUNCTION:
	  if (!e->symtree->n.sym->attr.pure
	      && !e->symtree->n.sym->attr.elemental
	      && !(e->value.function.isym
		   && (e->value.function.isym->pure
		       || e->value.function.isym->elemental)))
	    /* Treat non-pure/non-elemental functions.  */
	    check_add_new_comp_handle_array (e, type, add_data);
	  else
	    for (gfc_actual_arglist *actual = e->value.function.actual; actual;
		 actual = actual->next)
	      check_add_new_component (type, actual->expr, add_data);
	  break;
	case EXPR_VARIABLE:
	    check_add_new_comp_handle_array (e, type, add_data);
	    break;
	case EXPR_ARRAY:
	case EXPR_PPC:
	case EXPR_STRUCTURE:
	case EXPR_SUBSTRING:
	  gcc_unreachable ();
	default:;
	}
    }
}

static gfc_symbol *
create_caf_add_data_parameter_type (gfc_expr *expr, gfc_namespace *ns,
				    gfc_symbol *add_data)
{
  static int type_cnt = 0;
  char tname[GFC_MAX_SYMBOL_LEN + 1];
  char *name;
  gfc_symbol *type;

  gcc_assert (expr->expr_type == EXPR_VARIABLE);

  strcpy (tname, expr->symtree->name);
  name = xasprintf ("@_caf_add_data_t_%s_%d", tname, ++type_cnt);
  gfc_get_symbol (name, ns, &type);

  type->attr.flavor = FL_DERIVED;
  add_data->ts.u.derived = type;
  add_data->attr.codimension = 1;
  add_data->as = gfc_get_array_spec ();
  add_data->as->corank = 1;
  add_data->as->type = AS_EXPLICIT;
  add_data->as->cotype = AS_DEFERRED;
  add_data->as->lower[0]
    = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
			     &expr->where);
  mpz_set_si (add_data->as->lower[0]->value.integer, 1);

  for (gfc_ref *ref = expr->ref; ref; ref = ref->next)
    {
      if (ref->type == REF_ARRAY)
	{
	  gfc_array_ref *ar = &ref->u.ar;
	  for (int i = 0; i < ar->dimen; ++i)
	    {
	      check_add_new_component (type, ar->start[i], add_data);
	      check_add_new_component (type, ar->end[i], add_data);
	      check_add_new_component (type, ar->stride[i], add_data);
	    }
	}
    }

  type->declared_at = expr->where;
  gfc_set_sym_referenced (type);
  gfc_commit_symbol (type);
  free (name);
  return type;
}

static void
remove_caf_ref (gfc_expr *expr, const bool conv_to_this_image_cafref = false)
{
  gfc_ref *ref = expr->ref;
  while (ref && (ref->type != REF_ARRAY || ref->u.ar.codimen == 0))
    {
      ref = ref->next;
    }
  if (ref && ref->type == REF_ARRAY && ref->u.ar.codimen != 0)
    {
      if (ref->u.ar.dimen != 0)
	{
	  ref->u.ar.codimen = 0;
	  ref = ref->next;
	}
      else
	{
	  if (conv_to_this_image_cafref)
	    {
	      for (int i = ref->u.ar.dimen;
		   i < ref->u.ar.dimen + ref->u.ar.codimen; ++i)
		ref->u.ar.dimen_type[i] = DIMEN_THIS_IMAGE;
	    }
	  else
	    {
	      expr->ref = ref->next;
	      ref->next = NULL;
	      gfc_free_ref_list (ref);
	      ref = expr->ref;
	    }
	}
    }
  fixup_comp_refs (expr);
}

static gfc_expr *
create_get_callback (gfc_expr *expr)
{
  gfc_namespace *ns;
  gfc_symbol *extproc, *proc, *buffer, *free_buffer, *base, *get_data,
    *old_buffer_data, *caller_image;
  char tname[GFC_MAX_SYMBOL_LEN + 1];
  char *name;
  const char *mname;
  gfc_expr *cb, *post_caf_ref_expr;
  gfc_code *code;
  int expr_rank = expr->rank;
  gfc_code *backup_caf_accessor_prepend = caf_accessor_prepend;
  caf_accessor_prepend = nullptr;

  /* Find the top-level namespace.  */
  for (ns = gfc_current_ns; ns->parent; ns = ns->parent)
    ;

  if (expr->expr_type == EXPR_VARIABLE)
    strcpy (tname, expr->symtree->name);
  else
    strcpy (tname, "dummy");
  if (expr->symtree->n.sym->module)
    mname = expr->symtree->n.sym->module;
  else
    mname = "main";
  name = xasprintf ("_caf_accessor_%s_%s_%d", mname, tname, ++caf_sym_cnt);
  gfc_get_symbol (name, ns, &extproc);
  extproc->declared_at = expr->where;
  gfc_set_sym_referenced (extproc);
  ++extproc->refs;
  gfc_commit_symbol (extproc);

  /* Set up namespace.  */
  gfc_namespace *sub_ns = gfc_get_namespace (ns, 0);
  sub_ns->sibling = ns->contained;
  ns->contained = sub_ns;
  sub_ns->resolved = 1;
  /* Set up procedure symbol.  */
  gfc_find_symbol (name, sub_ns, 1, &proc);
  sub_ns->proc_name = proc;
  proc->attr.if_source = IFSRC_DECL;
  proc->attr.access = ACCESS_PUBLIC;
  gfc_add_subroutine (&proc->attr, name, NULL);
  proc->attr.host_assoc = 1;
  proc->attr.always_explicit = 1;
  ++proc->refs;
  proc->declared_at = expr->where;
  gfc_commit_symbol (proc);
  free (name);

  split_expr_at_caf_ref (expr, sub_ns, &post_caf_ref_expr, false);

  if (ns->proc_name->attr.flavor == FL_MODULE)
    proc->module = ns->proc_name->name;
  gfc_set_sym_referenced (proc);
  /* Set up formal arguments.  */
  gfc_formal_arglist **argptr = &proc->formal;
#define ADD_ARG(name, nsym, stype, skind, sintent)                             \
  gfc_get_symbol (name, sub_ns, &nsym);                                        \
  nsym->ts.type = stype;                                                       \
  nsym->ts.kind = skind;                                                       \
  nsym->attr.flavor = FL_PARAMETER;                                            \
  nsym->attr.dummy = 1;                                                        \
  nsym->attr.intent = sintent;                                                 \
  nsym->declared_at = expr->where;                                             \
  gfc_set_sym_referenced (nsym);                                               \
  *argptr = gfc_get_formal_arglist ();                                         \
  (*argptr)->sym = nsym;                                                       \
  argptr = &(*argptr)->next

  name = xasprintf ("add_data_%s_%s_%d", mname, tname, caf_sym_cnt);
  ADD_ARG (name, get_data, BT_DERIVED, 0, INTENT_IN);
  gfc_commit_symbol (get_data);
  free (name);

  ADD_ARG ("caller_image", caller_image, BT_INTEGER, gfc_default_integer_kind,
	   INTENT_IN);
  gfc_commit_symbol (caller_image);

  ADD_ARG ("buffer", buffer, expr->ts.type, expr->ts.kind, INTENT_INOUT);
  buffer->ts = expr->ts;
  if (expr_rank)
    {
      buffer->as = gfc_get_array_spec ();
      buffer->as->rank = expr_rank;
      if (expr->shape)
	{
	  buffer->as->type = AS_EXPLICIT;
	  for (int d = 0; d < expr_rank; ++d)
	    {
	      buffer->as->lower[d]
		= gfc_get_constant_expr (BT_INTEGER, gfc_index_integer_kind,
					 &gfc_current_locus);
	      gfc_mpz_set_hwi (buffer->as->lower[d]->value.integer, 1);
	      buffer->as->upper[d]
		= gfc_get_constant_expr (BT_INTEGER, gfc_index_integer_kind,
					 &gfc_current_locus);
	      gfc_mpz_set_hwi (buffer->as->upper[d]->value.integer,
			       gfc_mpz_get_hwi (expr->shape[d]));
	    }
	  buffer->attr.allocatable = 1;
	}
      else
	{
	  buffer->as->type = AS_DEFERRED;
	  buffer->attr.allocatable = 1;
	}
      buffer->attr.dimension = 1;
    }
  else
    buffer->attr.pointer = 1;
  if (buffer->ts.type == BT_CHARACTER)
    {
      buffer->ts.u.cl = gfc_get_charlen ();
      *buffer->ts.u.cl = *expr->ts.u.cl;
      buffer->ts.u.cl->length = gfc_copy_expr (expr->ts.u.cl->length);
    }
  gfc_commit_symbol (buffer);

  ADD_ARG ("free_buffer", free_buffer, BT_LOGICAL, gfc_default_logical_kind,
	   INTENT_OUT);
  gfc_commit_symbol (free_buffer);

  // ADD_ARG (expr->symtree->name, base, BT_VOID, INTENT_IN);
  base = post_caf_ref_expr->symtree->n.sym;
  gfc_set_sym_referenced (base);
  gfc_commit_symbol (base);
  *argptr = gfc_get_formal_arglist ();
  (*argptr)->sym = base;
  argptr = &(*argptr)->next;
  gfc_commit_symbol (base);
#undef ADD_ARG

  /* Set up code.  */
  if (expr->rank != 0)
    {
      /* Code: old_buffer_ptr = C_LOC (buffer);  */
      code = sub_ns->code = gfc_get_code (EXEC_ASSIGN);
      gfc_get_symbol ("old_buffer_data", sub_ns, &old_buffer_data);
      old_buffer_data->ts.type = BT_VOID;
      old_buffer_data->attr.flavor = FL_VARIABLE;
      old_buffer_data->declared_at = expr->where;
      gfc_set_sym_referenced (old_buffer_data);
      gfc_commit_symbol (old_buffer_data);
      code->loc = expr->where;
      code->expr1 = gfc_lval_expr_from_sym (old_buffer_data);
      code->expr2 = gfc_build_intrinsic_call (ns, GFC_ISYM_C_LOC, "C_LOC",
					      gfc_current_locus, 1,
					      gfc_lval_expr_from_sym (buffer));
      code->next = gfc_get_code (EXEC_ASSIGN);
      code = code->next;
    }
  else
    code = sub_ns->code = gfc_get_code (EXEC_POINTER_ASSIGN);

  /* Code: buffer = expr;  */
  code->loc = expr->where;
  code->expr1 = gfc_lval_expr_from_sym (buffer);
  code->expr2 = post_caf_ref_expr;
  remove_caf_ref (post_caf_ref_expr);
  get_data->ts.u.derived
    = create_caf_add_data_parameter_type (code->expr2, ns, get_data);
  if (code->expr2->rank == 0 && code->expr2->ts.type != BT_CHARACTER)
    code->expr2 = gfc_build_intrinsic_call (ns, GFC_ISYM_C_LOC, "C_LOC",
					    gfc_current_locus, 1, code->expr2);

  /* Code: *free_buffer = old_buffer_ptr /= C_LOC (buffer); for rank != 0 or
   *       *free_buffer = 0; for rank == 0.  */
  code->next = gfc_get_code (EXEC_ASSIGN);
  code = code->next;
  code->loc = expr->where;
  code->expr1 = gfc_lval_expr_from_sym (free_buffer);
  if (expr->rank != 0)
    {
      code->expr2 = gfc_get_operator_expr (
	&gfc_current_locus, INTRINSIC_NE_OS,
	gfc_lval_expr_from_sym (old_buffer_data),
	gfc_build_intrinsic_call (ns, GFC_ISYM_C_LOC, "C_LOC",
				  gfc_current_locus, 1,
				  gfc_lval_expr_from_sym (buffer)));
      code->expr2->ts.type = BT_LOGICAL;
      code->expr2->ts.kind = gfc_default_logical_kind;
    }
  else
    {
      code->expr2 = gfc_get_logical_expr (gfc_default_logical_kind,
					  &gfc_current_locus, false);
    }

  cb = gfc_lval_expr_from_sym (extproc);
  cb->ts.interface = extproc;

  if (caf_accessor_prepend)
    {
      gfc_code *c = caf_accessor_prepend;
      /* Find last in chain.  */
      for (; c->next; c = c->next)
	;
      c->next = sub_ns->code;
      sub_ns->code = caf_accessor_prepend;
    }
  caf_accessor_prepend = backup_caf_accessor_prepend;
  return cb;
}

void
add_caf_get_from_remote (gfc_expr *e)
{
  gfc_expr *wrapper, *tmp_expr, *get_from_remote_expr,
    *get_from_remote_hash_expr;
  gfc_ref *ref;
  int n;

  for (ref = e->ref; ref; ref = ref->next)
    if (ref->type == REF_ARRAY && ref->u.ar.codimen > 0)
      break;
  if (ref == NULL)
    return;

  for (n = ref->u.ar.dimen; n < ref->u.ar.dimen + ref->u.ar.codimen; n++)
    if (ref->u.ar.dimen_type[n] != DIMEN_ELEMENT)
      return;

  tmp_expr = XCNEW (gfc_expr);
  *tmp_expr = *e;
  get_from_remote_expr = create_get_callback (tmp_expr);
  get_from_remote_hash_expr = gfc_get_expr ();
  get_from_remote_hash_expr->expr_type = EXPR_CONSTANT;
  get_from_remote_hash_expr->ts.type = BT_INTEGER;
  get_from_remote_hash_expr->ts.kind = gfc_default_integer_kind;
  get_from_remote_hash_expr->where = tmp_expr->where;
  mpz_init_set_ui (get_from_remote_hash_expr->value.integer,
		   gfc_hash_value (get_from_remote_expr->symtree->n.sym));
  wrapper = gfc_build_intrinsic_call (gfc_current_ns, GFC_ISYM_CAF_GET,
				      "caf_get", tmp_expr->where, 3, tmp_expr,
				      get_from_remote_hash_expr,
				      get_from_remote_expr);
  gfc_add_caf_accessor (get_from_remote_hash_expr, get_from_remote_expr);
  wrapper->ts = e->ts;
  wrapper->rank = e->rank;
  wrapper->corank = e->corank;
  if (e->rank)
    wrapper->shape = gfc_copy_shape (e->shape, e->rank);
  *e = *wrapper;
  free (wrapper);
}

static gfc_expr *
create_allocated_callback (gfc_expr *expr)
{
  gfc_namespace *ns;
  gfc_symbol *extproc, *proc, *result, *base, *add_data, *caller_image;
  char tname[GFC_MAX_SYMBOL_LEN + 1];
  char *name;
  const char *mname;
  gfc_expr *cb, *post_caf_ref_expr;
  gfc_code *code;
  gfc_code *backup_caf_accessor_prepend = caf_accessor_prepend;
  caf_accessor_prepend = nullptr;
  gfc_expr swp;

  /* Find the top-level namespace.  */
  for (ns = gfc_current_ns; ns->parent; ns = ns->parent)
    ;

  if (expr->value.function.actual->expr->expr_type == EXPR_VARIABLE)
    strcpy (tname, expr->value.function.actual->expr->symtree->name);
  else
    strcpy (tname, "dummy");
  if (expr->value.function.actual->expr->symtree->n.sym->module)
    mname = expr->value.function.actual->expr->symtree->n.sym->module;
  else
    mname = "main";
  name = xasprintf ("_caf_present_%s_%s_%d", mname, tname, ++caf_sym_cnt);
  gfc_get_symbol (name, ns, &extproc);
  extproc->declared_at = expr->where;
  gfc_set_sym_referenced (extproc);
  ++extproc->refs;
  gfc_commit_symbol (extproc);

  /* Set up namespace.  */
  gfc_namespace *sub_ns = gfc_get_namespace (ns, 0);
  sub_ns->sibling = ns->contained;
  ns->contained = sub_ns;
  sub_ns->resolved = 1;
  /* Set up procedure symbol.  */
  gfc_find_symbol (name, sub_ns, 1, &proc);
  sub_ns->proc_name = proc;
  proc->attr.if_source = IFSRC_DECL;
  proc->attr.access = ACCESS_PUBLIC;
  gfc_add_subroutine (&proc->attr, name, NULL);
  proc->attr.host_assoc = 1;
  proc->attr.always_explicit = 1;
  proc->declared_at = expr->where;
  ++proc->refs;
  gfc_commit_symbol (proc);
  free (name);

  split_expr_at_caf_ref (expr->value.function.actual->expr, sub_ns,
			 &post_caf_ref_expr, true);

  if (ns->proc_name->attr.flavor == FL_MODULE)
    proc->module = ns->proc_name->name;
  gfc_set_sym_referenced (proc);
  /* Set up formal arguments.  */
  gfc_formal_arglist **argptr = &proc->formal;
#define ADD_ARG(name, nsym, stype, skind, sintent)                             \
  gfc_get_symbol (name, sub_ns, &nsym);                                        \
  nsym->ts.type = stype;                                                       \
  nsym->ts.kind = skind;                                                       \
  nsym->attr.flavor = FL_PARAMETER;                                            \
  nsym->attr.dummy = 1;                                                        \
  nsym->attr.intent = sintent;                                                 \
  nsym->declared_at = expr->where;                                             \
  gfc_set_sym_referenced (nsym);                                               \
  *argptr = gfc_get_formal_arglist ();                                         \
  (*argptr)->sym = nsym;                                                       \
  argptr = &(*argptr)->next

  name = xasprintf ("add_data_%s_%s_%d", mname, tname, ++caf_sym_cnt);
  ADD_ARG (name, add_data, BT_DERIVED, 0, INTENT_IN);
  gfc_commit_symbol (add_data);
  free (name);
  ADD_ARG ("caller_image", caller_image, BT_INTEGER, gfc_default_integer_kind,
	   INTENT_IN);
  gfc_commit_symbol (caller_image);

  ADD_ARG ("result", result, BT_LOGICAL, gfc_default_logical_kind, INTENT_OUT);
  gfc_commit_symbol (result);

  // ADD_ARG (expr->symtree->name, base, BT_VOID, INTENT_IN);
  base = post_caf_ref_expr->symtree->n.sym;
  base->attr.pointer = !base->attr.dimension;
  gfc_set_sym_referenced (base);
  *argptr = gfc_get_formal_arglist ();
  (*argptr)->sym = base;
  argptr = &(*argptr)->next;
  gfc_commit_symbol (base);
#undef ADD_ARG

  /* Set up code.  */
  /* Code: result = post_caf_ref_expr;  */
  code = sub_ns->code = gfc_get_code (EXEC_ASSIGN);
  code->loc = expr->where;
  code->expr1 = gfc_lval_expr_from_sym (result);
  swp = *expr;
  *expr = *swp.value.function.actual->expr;
  swp.value.function.actual->expr = nullptr;
  code->expr2 = gfc_copy_expr (&swp);
  code->expr2->value.function.actual->expr = post_caf_ref_expr;

  remove_caf_ref (code->expr2->value.function.actual->expr, true);
  add_data->ts.u.derived
    = create_caf_add_data_parameter_type (post_caf_ref_expr, ns, add_data);

  cb = gfc_lval_expr_from_sym (extproc);
  cb->ts.interface = extproc;

  if (caf_accessor_prepend)
    {
      gfc_code *c = caf_accessor_prepend;
      /* Find last in chain.  */
      for (; c->next; c = c->next)
	;
      c->next = sub_ns->code;
      sub_ns->code = caf_accessor_prepend;
    }
  caf_accessor_prepend = backup_caf_accessor_prepend;
  return cb;
}

static void
rewrite_caf_allocated (gfc_expr **e)
{
  gfc_expr *present_fn_expr, *present_hash_expr, *wrapper;

  present_fn_expr = create_allocated_callback (*e);

  present_hash_expr = gfc_get_expr ();
  present_hash_expr->expr_type = EXPR_CONSTANT;
  present_hash_expr->ts.type = BT_INTEGER;
  present_hash_expr->ts.kind = gfc_default_integer_kind;
  present_hash_expr->where = (*e)->where;
  mpz_init_set_ui (present_hash_expr->value.integer,
		   gfc_hash_value (present_fn_expr->symtree->n.sym));
  wrapper
    = gfc_build_intrinsic_call (gfc_current_ns,
				GFC_ISYM_CAF_IS_PRESENT_ON_REMOTE,
				"caf_is_present_on_remote", (*e)->where, 3, *e,
				present_hash_expr, present_fn_expr);
  gfc_add_caf_accessor (present_hash_expr, present_fn_expr);
  *e = wrapper;
}

static gfc_expr *
create_send_callback (gfc_expr *expr, gfc_expr *rhs)
{
  gfc_namespace *ns;
  gfc_symbol *extproc, *proc, *buffer, *base, *send_data, *caller_image;
  char tname[GFC_MAX_SYMBOL_LEN + 1];
  char *name;
  const char *mname;
  gfc_expr *cb, *post_caf_ref_expr;
  gfc_code *code;
  gfc_code *backup_caf_accessor_prepend = caf_accessor_prepend;
  caf_accessor_prepend = nullptr;

  /* Find the top-level namespace.  */
  for (ns = gfc_current_ns; ns->parent; ns = ns->parent)
    ;

  if (expr->expr_type == EXPR_VARIABLE)
    strcpy (tname, expr->symtree->name);
  else
    strcpy (tname, "dummy");
  if (expr->symtree->n.sym->module)
    mname = expr->symtree->n.sym->module;
  else
    mname = "main";
  name = xasprintf ("_caf_accessor_%s_%s_%d", mname, tname, ++caf_sym_cnt);
  gfc_get_symbol (name, ns, &extproc);
  extproc->declared_at = expr->where;
  gfc_set_sym_referenced (extproc);
  ++extproc->refs;
  gfc_commit_symbol (extproc);

  /* Set up namespace.  */
  gfc_namespace *sub_ns = gfc_get_namespace (ns, 0);
  sub_ns->sibling = ns->contained;
  ns->contained = sub_ns;
  sub_ns->resolved = 1;
  /* Set up procedure symbol.  */
  gfc_find_symbol (name, sub_ns, 1, &proc);
  sub_ns->proc_name = proc;
  proc->attr.if_source = IFSRC_DECL;
  proc->attr.access = ACCESS_PUBLIC;
  gfc_add_subroutine (&proc->attr, name, NULL);
  proc->attr.host_assoc = 1;
  proc->attr.always_explicit = 1;
  ++proc->refs;
  proc->declared_at = expr->where;
  gfc_commit_symbol (proc);
  free (name);

  split_expr_at_caf_ref (expr, sub_ns, &post_caf_ref_expr, true);

  if (ns->proc_name->attr.flavor == FL_MODULE)
    proc->module = ns->proc_name->name;
  gfc_set_sym_referenced (proc);
  /* Set up formal arguments.  */
  gfc_formal_arglist **argptr = &proc->formal;
#define ADD_ARG(name, nsym, stype, skind, sintent)                             \
  gfc_get_symbol (name, sub_ns, &nsym);                                        \
  nsym->ts.type = stype;                                                       \
  nsym->ts.kind = skind;                                                       \
  nsym->attr.flavor = FL_PARAMETER;                                            \
  nsym->attr.dummy = 1;                                                        \
  nsym->attr.intent = sintent;                                                 \
  nsym->declared_at = expr->where;                                             \
  gfc_set_sym_referenced (nsym);                                               \
  *argptr = gfc_get_formal_arglist ();                                         \
  (*argptr)->sym = nsym;                                                       \
  argptr = &(*argptr)->next

  name = xasprintf ("add_send_data_%s_%s_%d", mname, tname, caf_sym_cnt);
  ADD_ARG (name, send_data, BT_DERIVED, 0, INTENT_IN);
  gfc_commit_symbol (send_data);
  free (name);

  ADD_ARG ("caller_image", caller_image, BT_INTEGER, gfc_default_integer_kind,
	   INTENT_IN);
  gfc_commit_symbol (caller_image);

  // ADD_ARG (expr->symtree->name, base, BT_VOID, INTENT_IN);
  base = post_caf_ref_expr->symtree->n.sym;
  base->attr.intent = INTENT_INOUT;
  gfc_set_sym_referenced (base);
  gfc_commit_symbol (base);
  *argptr = gfc_get_formal_arglist ();
  (*argptr)->sym = base;
  argptr = &(*argptr)->next;
  gfc_commit_symbol (base);

  ADD_ARG ("buffer", buffer, rhs->ts.type, rhs->ts.kind, INTENT_IN);
  buffer->ts = rhs->ts;
  if (rhs->rank)
    {
      buffer->as = gfc_get_array_spec ();
      buffer->as->rank = rhs->rank;
      buffer->as->type = AS_DEFERRED;
      buffer->attr.allocatable = 1;
      buffer->attr.dimension = 1;
    }
  if (buffer->ts.type == BT_CHARACTER)
    {
      buffer->ts.u.cl = gfc_get_charlen ();
      *buffer->ts.u.cl = *rhs->ts.u.cl;
      buffer->ts.deferred = 1;
      buffer->ts.u.cl->length = gfc_copy_expr (rhs->ts.u.cl->length);
    }
  gfc_commit_symbol (buffer);
#undef ADD_ARG

  /* Set up code.  */
  /* Code: base = buffer;  */
  code = sub_ns->code = gfc_get_code (EXEC_ASSIGN);
  code->loc = expr->where;
  code->expr1 = post_caf_ref_expr;
  if (code->expr1->ts.type == BT_CHARACTER
      && code->expr1->ts.kind != buffer->ts.kind)
    {
      bool converted;
      code->expr2 = gfc_lval_expr_from_sym (buffer);
      converted = gfc_convert_chartype (code->expr2, &code->expr1->ts);
      gcc_assert (converted);
    }
  else if (code->expr1->ts.type != buffer->ts.type)
    {
      bool converted;
      code->expr2 = gfc_lval_expr_from_sym (buffer);
      converted = gfc_convert_type_warn (code->expr2, &code->expr1->ts, 0, 0,
					 buffer->attr.dimension);
      gcc_assert (converted);
    }
  else
    code->expr2 = gfc_lval_expr_from_sym (buffer);
  remove_caf_ref (post_caf_ref_expr);
  send_data->ts.u.derived
    = create_caf_add_data_parameter_type (code->expr1, ns, send_data);

  cb = gfc_lval_expr_from_sym (extproc);
  cb->ts.interface = extproc;

  if (caf_accessor_prepend)
    {
      gfc_code *c = caf_accessor_prepend;
      /* Find last in chain.  */
      for (; c->next; c = c->next)
	;
      c->next = sub_ns->code;
      sub_ns->code = caf_accessor_prepend;
    }
  caf_accessor_prepend = backup_caf_accessor_prepend;
  return cb;
}

static void
rewrite_caf_send (gfc_code *c)
{
  gfc_expr *send_to_remote_expr, *send_to_remote_hash_expr, *lhs, *rhs;
  gfc_actual_arglist *arg = c->ext.actual;

  lhs = arg->expr;
  arg = arg->next;
  rhs = arg->expr;
  /* Detect an already rewritten caf_send.  */
  if (arg->next && arg->next->expr->expr_type == EXPR_CONSTANT
      && arg->next->next && arg->next->next->expr->expr_type == EXPR_VARIABLE)
    return;

  send_to_remote_expr = create_send_callback (lhs, rhs);
  send_to_remote_hash_expr = gfc_get_expr ();
  send_to_remote_hash_expr->expr_type = EXPR_CONSTANT;
  send_to_remote_hash_expr->ts.type = BT_INTEGER;
  send_to_remote_hash_expr->ts.kind = gfc_default_integer_kind;
  send_to_remote_hash_expr->where = lhs->where;
  mpz_init_set_ui (send_to_remote_hash_expr->value.integer,
		   gfc_hash_value (send_to_remote_expr->symtree->n.sym));
  arg->next = gfc_get_actual_arglist ();
  arg = arg->next;
  arg->expr = send_to_remote_hash_expr;
  arg->next = gfc_get_actual_arglist ();
  arg = arg->next;
  arg->expr = send_to_remote_expr;
  gfc_add_caf_accessor (send_to_remote_hash_expr, send_to_remote_expr);

  if (gfc_is_coindexed (rhs))
    {
      gfc_expr *get_from_remote_expr, *get_from_remote_hash_expr;

      c->resolved_isym = gfc_intrinsic_subroutine_by_id (GFC_ISYM_CAF_SENDGET);
      get_from_remote_expr = create_get_callback (rhs);
      get_from_remote_hash_expr = gfc_get_expr ();
      get_from_remote_hash_expr->expr_type = EXPR_CONSTANT;
      get_from_remote_hash_expr->ts.type = BT_INTEGER;
      get_from_remote_hash_expr->ts.kind = gfc_default_integer_kind;
      get_from_remote_hash_expr->where = rhs->where;
      mpz_init_set_ui (get_from_remote_hash_expr->value.integer,
		       gfc_hash_value (get_from_remote_expr->symtree->n.sym));
      arg->next = gfc_get_actual_arglist ();
      arg = arg->next;
      arg->expr = get_from_remote_hash_expr;
      arg->next = gfc_get_actual_arglist ();
      arg = arg->next;
      arg->expr = get_from_remote_expr;
      gfc_add_caf_accessor (get_from_remote_hash_expr, get_from_remote_expr);
    }
}

static int
coindexed_expr_callback (gfc_expr **e, int *walk_subtrees,
			 void *data ATTRIBUTE_UNUSED)
{
  *walk_subtrees = 1;

  switch ((*e)->expr_type)
    {
    case EXPR_VARIABLE:
      if (!caf_on_lhs && gfc_is_coindexed (*e))
	{
	  add_caf_get_from_remote (*e);
	  *walk_subtrees = 0;
	}
      /* Clear the flag to rewrite caf_gets in sub expressions of the lhs.  */
      caf_on_lhs = false;
      break;
    case EXPR_FUNCTION:
      if ((*e)->value.function.isym)
	switch ((*e)->value.function.isym->id)
	  {
	  case GFC_ISYM_ALLOCATED:
	    if ((*e)->value.function.actual->expr
		&& (gfc_is_coarray ((*e)->value.function.actual->expr)
		    || gfc_is_coindexed ((*e)->value.function.actual->expr)))
	      {
		rewrite_caf_allocated (e);
		*walk_subtrees = 0;
	      }
	    break;
	  case GFC_ISYM_CAF_GET:
	  case GFC_ISYM_CAF_IS_PRESENT_ON_REMOTE:
	    *walk_subtrees = 0;
	    break;
	  default:
	    break;
	  }
    default:
      break;
    }

  return 0;
}

static int
coindexed_code_callback (gfc_code **c, int *walk_subtrees,
			 void *data ATTRIBUTE_UNUSED)
{
  int ws = 1;
  current_code = c;

  switch ((*c)->op)
    {
    case EXEC_ASSIGN:
    case EXEC_POINTER_ASSIGN:
      caf_on_lhs = true;
      coindexed_expr_callback (&((*c)->expr1), &ws, NULL);
      caf_on_lhs = false;
      ws = 1;
      coindexed_expr_callback (&((*c)->expr2), &ws, NULL);
      *walk_subtrees = ws;
      break;
    case EXEC_LOCK:
    case EXEC_UNLOCK:
    case EXEC_EVENT_POST:
    case EXEC_EVENT_WAIT:
      *walk_subtrees = 0;
      break;
    case EXEC_CALL:
      *walk_subtrees = 1;
      if ((*c)->resolved_isym)
	switch ((*c)->resolved_isym->id)
	  {
	  case GFC_ISYM_CAF_SEND:
	    rewrite_caf_send (*c);
	    *walk_subtrees = 0;
	    break;
	  case GFC_ISYM_CAF_SENDGET:
	    /* Seldomly this routine is called again with the symbol already
	       changed to CAF_SENDGET.  Do not process the subtree again.  The
	       rewrite has already been done by rewrite_caf_send ().  */
	    *walk_subtrees = 0;
	    break;
	  case GFC_ISYM_ATOMIC_ADD:
	  case GFC_ISYM_ATOMIC_AND:
	  case GFC_ISYM_ATOMIC_CAS:
	  case GFC_ISYM_ATOMIC_DEF:
	  case GFC_ISYM_ATOMIC_FETCH_ADD:
	  case GFC_ISYM_ATOMIC_FETCH_AND:
	  case GFC_ISYM_ATOMIC_FETCH_OR:
	  case GFC_ISYM_ATOMIC_FETCH_XOR:
	  case GFC_ISYM_ATOMIC_OR:
	  case GFC_ISYM_ATOMIC_REF:
	  case GFC_ISYM_ATOMIC_XOR:
	    *walk_subtrees = 0;
	    break;
	  default:
	    break;
	  }
      break;
    default:
      *walk_subtrees = 1;
      break;
    }
  return 0;
}

void
gfc_coarray_rewrite (gfc_namespace *ns)
{
  gfc_namespace *saved_ns = gfc_current_ns;
  gfc_current_ns = ns;

  if (flag_coarray == GFC_FCOARRAY_LIB)
    {
      gfc_code_walker (&ns->code, coindexed_code_callback,
		       coindexed_expr_callback, NULL);

      for (gfc_namespace *cns = ns->contained; cns; cns = cns->sibling)
	gfc_coarray_rewrite (cns);
    }

  gfc_current_ns = saved_ns;
}
