/* OpenMP directive translation -- generate GCC trees from gfc_code.
   Copyright (C) 2005-2021 Free Software Foundation, Inc.
   Contributed by Jakub Jelinek <jakub@redhat.com>

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/>.  */


#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "options.h"
#include "tree.h"
#include "gfortran.h"
#include "gimple-expr.h"
#include "trans.h"
#include "stringpool.h"
#include "fold-const.h"
#include "gimplify.h"	/* For create_tmp_var_raw.  */
#include "trans-stmt.h"
#include "trans-types.h"
#include "trans-array.h"
#include "trans-const.h"
#include "arith.h"
#include "constructor.h"
#include "gomp-constants.h"
#include "omp-general.h"
#include "omp-low.h"
#include "memmodel.h"  /* For MEMMODEL_ enums.  */

#undef GCC_DIAG_STYLE
#define GCC_DIAG_STYLE __gcc_tdiag__
#include "diagnostic-core.h"
#undef GCC_DIAG_STYLE
#define GCC_DIAG_STYLE __gcc_gfc__
#include "attribs.h"
#include "function.h"

int ompws_flags;

/* True if OpenMP should regard this DECL as being a scalar which has Fortran's
   allocatable or pointer attribute.  */

bool
gfc_omp_is_allocatable_or_ptr (const_tree decl)
{
  return (DECL_P (decl)
	  && (GFC_DECL_GET_SCALAR_POINTER (decl)
	      || GFC_DECL_GET_SCALAR_ALLOCATABLE (decl)));
}

/* True if the argument is an optional argument; except that false is also
   returned for arguments with the value attribute (nonpointers) and for
   assumed-shape variables (decl is a local variable containing arg->data).
   Note that for 'procedure(), optional' the value false is used as that's
   always a pointer and no additional indirection is used.
   Note that pvoid_type_node is for 'type(c_ptr), value' (and c_funloc).  */

static bool
gfc_omp_is_optional_argument (const_tree decl)
{
  return (TREE_CODE (decl) == PARM_DECL
	  && DECL_LANG_SPECIFIC (decl)
	  && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
	  && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl)))
	  && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) != FUNCTION_TYPE
	  && GFC_DECL_OPTIONAL_ARGUMENT (decl));
}

/* Check whether this DECL belongs to a Fortran optional argument.
   With 'for_present_check' set to false, decls which are optional parameters
   themselve are returned as tree - or a NULL_TREE otherwise. Those decls are
   always pointers.  With 'for_present_check' set to true, the decl for checking
   whether an argument is present is returned; for arguments with value
   attribute this is the hidden argument and of BOOLEAN_TYPE.  If the decl is
   unrelated to optional arguments, NULL_TREE is returned.  */

tree
gfc_omp_check_optional_argument (tree decl, bool for_present_check)
{
  if (!for_present_check)
    return gfc_omp_is_optional_argument (decl) ? decl : NULL_TREE;

  if (!DECL_LANG_SPECIFIC (decl))
    return NULL_TREE;

  tree orig_decl = decl;

  /* For assumed-shape arrays, a local decl with arg->data is used.  */
  if (TREE_CODE (decl) != PARM_DECL
      && (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))
	  || GFC_ARRAY_TYPE_P (TREE_TYPE (decl))))
    decl = GFC_DECL_SAVED_DESCRIPTOR (decl);

  if (decl == NULL_TREE
      || TREE_CODE (decl) != PARM_DECL
      || !DECL_LANG_SPECIFIC (decl)
      || !GFC_DECL_OPTIONAL_ARGUMENT (decl))
    return NULL_TREE;

   /* Scalars with VALUE attribute which are passed by value use a hidden
      argument to denote the present status.  They are passed as nonpointer type
      with one exception: 'type(c_ptr), value' as 'void*'.  */
   /* Cf. trans-expr.c's gfc_conv_expr_present.  */
   if (TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE
       || VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
    {
      char name[GFC_MAX_SYMBOL_LEN + 2];
      tree tree_name;

      name[0] = '_';
      strcpy (&name[1], IDENTIFIER_POINTER (DECL_NAME (decl)));
      tree_name = get_identifier (name);

      /* Walk function argument list to find the hidden arg.  */
      decl = DECL_ARGUMENTS (DECL_CONTEXT (decl));
      for ( ; decl != NULL_TREE; decl = TREE_CHAIN (decl))
	if (DECL_NAME (decl) == tree_name
	    && DECL_ARTIFICIAL (decl))
	  break;

      gcc_assert (decl);
      return decl;
    }

  return fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
			  orig_decl, null_pointer_node);
}


/* Returns tree with NULL if it is not an array descriptor and with the tree to
   access the 'data' component otherwise.  With type_only = true, it returns the
   TREE_TYPE without creating a new tree.  */

tree
gfc_omp_array_data (tree decl, bool type_only)
{
  tree type = TREE_TYPE (decl);

  if (POINTER_TYPE_P (type))
    type = TREE_TYPE (type);

  if (!GFC_DESCRIPTOR_TYPE_P (type))
    return NULL_TREE;

  if (type_only)
    return GFC_TYPE_ARRAY_DATAPTR_TYPE (type);

  if (POINTER_TYPE_P (TREE_TYPE (decl)))
    decl = build_fold_indirect_ref (decl);

  decl = gfc_conv_descriptor_data_get (decl);
  STRIP_NOPS (decl);
  return decl;
}

/* True if OpenMP should privatize what this DECL points to rather
   than the DECL itself.  */

bool
gfc_omp_privatize_by_reference (const_tree decl)
{
  tree type = TREE_TYPE (decl);

  if (TREE_CODE (type) == REFERENCE_TYPE
      && (!DECL_ARTIFICIAL (decl) || TREE_CODE (decl) == PARM_DECL))
    return true;

  if (TREE_CODE (type) == POINTER_TYPE
      && gfc_omp_is_optional_argument (decl))
    return true;

  if (TREE_CODE (type) == POINTER_TYPE)
    {
      while (TREE_CODE (decl) == COMPONENT_REF)
	decl = TREE_OPERAND (decl, 1);

      /* Array POINTER/ALLOCATABLE have aggregate types, all user variables
	 that have POINTER_TYPE type and aren't scalar pointers, scalar
	 allocatables, Cray pointees or C pointers are supposed to be
	 privatized by reference.  */
      if (GFC_DECL_GET_SCALAR_POINTER (decl)
	  || GFC_DECL_GET_SCALAR_ALLOCATABLE (decl)
	  || GFC_DECL_CRAY_POINTEE (decl)
	  || GFC_DECL_ASSOCIATE_VAR_P (decl)
	  || VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
	return false;

      if (!DECL_ARTIFICIAL (decl)
	  && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)
	return true;

      /* Some arrays are expanded as DECL_ARTIFICIAL pointers
	 by the frontend.  */
      if (DECL_LANG_SPECIFIC (decl)
	  && GFC_DECL_SAVED_DESCRIPTOR (decl))
	return true;
    }

  return false;
}

/* OMP_CLAUSE_DEFAULT_UNSPECIFIED unless OpenMP sharing attribute
   of DECL is predetermined.  */

enum omp_clause_default_kind
gfc_omp_predetermined_sharing (tree decl)
{
  /* Associate names preserve the association established during ASSOCIATE.
     As they are implemented either as pointers to the selector or array
     descriptor and shouldn't really change in the ASSOCIATE region,
     this decl can be either shared or firstprivate.  If it is a pointer,
     use firstprivate, as it is cheaper that way, otherwise make it shared.  */
  if (GFC_DECL_ASSOCIATE_VAR_P (decl))
    {
      if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
	return OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
      else
	return OMP_CLAUSE_DEFAULT_SHARED;
    }

  if (DECL_ARTIFICIAL (decl)
      && ! GFC_DECL_RESULT (decl)
      && ! (DECL_LANG_SPECIFIC (decl)
	    && GFC_DECL_SAVED_DESCRIPTOR (decl)))
    return OMP_CLAUSE_DEFAULT_SHARED;

  /* Cray pointees shouldn't be listed in any clauses and should be
     gimplified to dereference of the corresponding Cray pointer.
     Make them all private, so that they are emitted in the debug
     information.  */
  if (GFC_DECL_CRAY_POINTEE (decl))
    return OMP_CLAUSE_DEFAULT_PRIVATE;

  /* Assumed-size arrays are predetermined shared.  */
  if (TREE_CODE (decl) == PARM_DECL
      && GFC_ARRAY_TYPE_P (TREE_TYPE (decl))
      && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (decl)) == GFC_ARRAY_UNKNOWN
      && GFC_TYPE_ARRAY_UBOUND (TREE_TYPE (decl),
				GFC_TYPE_ARRAY_RANK (TREE_TYPE (decl)) - 1)
	 == NULL)
    return OMP_CLAUSE_DEFAULT_SHARED;

  /* Dummy procedures aren't considered variables by OpenMP, thus are
     disallowed in OpenMP clauses.  They are represented as PARM_DECLs
     in the middle-end, so return OMP_CLAUSE_DEFAULT_FIRSTPRIVATE here
     to avoid complaining about their uses with default(none).  */
  if (TREE_CODE (decl) == PARM_DECL
      && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
      && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == FUNCTION_TYPE)
    return OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;

  /* COMMON and EQUIVALENCE decls are shared.  They
     are only referenced through DECL_VALUE_EXPR of the variables
     contained in them.  If those are privatized, they will not be
     gimplified to the COMMON or EQUIVALENCE decls.  */
  if (GFC_DECL_COMMON_OR_EQUIV (decl) && ! DECL_HAS_VALUE_EXPR_P (decl))
    return OMP_CLAUSE_DEFAULT_SHARED;

  if (GFC_DECL_RESULT (decl) && ! DECL_HAS_VALUE_EXPR_P (decl))
    return OMP_CLAUSE_DEFAULT_SHARED;

  /* These are either array or derived parameters, or vtables.
     In the former cases, the OpenMP standard doesn't consider them to be
     variables at all (they can't be redefined), but they can nevertheless appear
     in parallel/task regions and for default(none) purposes treat them as shared.
     For vtables likely the same handling is desirable.  */
  if (VAR_P (decl) && TREE_READONLY (decl)
      && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
    return OMP_CLAUSE_DEFAULT_SHARED;

  return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
}


/* OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED unless OpenMP mapping attribute
   of DECL is predetermined.  */

enum omp_clause_defaultmap_kind
gfc_omp_predetermined_mapping (tree decl)
{
  if (DECL_ARTIFICIAL (decl)
      && ! GFC_DECL_RESULT (decl)
      && ! (DECL_LANG_SPECIFIC (decl)
	    && GFC_DECL_SAVED_DESCRIPTOR (decl)))
    return OMP_CLAUSE_DEFAULTMAP_TO;

  /* These are either array or derived parameters, or vtables.  */
  if (VAR_P (decl) && TREE_READONLY (decl)
      && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
    return OMP_CLAUSE_DEFAULTMAP_TO;

  return OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
}


/* Return decl that should be used when reporting DEFAULT(NONE)
   diagnostics.  */

tree
gfc_omp_report_decl (tree decl)
{
  if (DECL_ARTIFICIAL (decl)
      && DECL_LANG_SPECIFIC (decl)
      && GFC_DECL_SAVED_DESCRIPTOR (decl))
    return GFC_DECL_SAVED_DESCRIPTOR (decl);

  return decl;
}

/* Return true if TYPE has any allocatable components.  */

static bool
gfc_has_alloc_comps (tree type, tree decl)
{
  tree field, ftype;

  if (POINTER_TYPE_P (type))
    {
      if (GFC_DECL_GET_SCALAR_ALLOCATABLE (decl))
	type = TREE_TYPE (type);
      else if (GFC_DECL_GET_SCALAR_POINTER (decl))
	return false;
    }

  if (GFC_DESCRIPTOR_TYPE_P (type)
      && (GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_POINTER
	  || GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_POINTER_CONT))
    return false;

  if (GFC_DESCRIPTOR_TYPE_P (type) || GFC_ARRAY_TYPE_P (type))
    type = gfc_get_element_type (type);

  if (TREE_CODE (type) != RECORD_TYPE)
    return false;

  for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    {
      ftype = TREE_TYPE (field);
      if (GFC_DECL_GET_SCALAR_ALLOCATABLE (field))
	return true;
      if (GFC_DESCRIPTOR_TYPE_P (ftype)
	  && GFC_TYPE_ARRAY_AKIND (ftype) == GFC_ARRAY_ALLOCATABLE)
	return true;
      if (gfc_has_alloc_comps (ftype, field))
	return true;
    }
  return false;
}

/* Return true if TYPE is polymorphic but not with pointer attribute.  */

static bool
gfc_is_polymorphic_nonptr (tree type)
{
  if (POINTER_TYPE_P (type))
    type = TREE_TYPE (type);
  return GFC_CLASS_TYPE_P (type);
}

/* Return true if TYPE is unlimited polymorphic but not with pointer attribute;
   unlimited means also intrinsic types are handled and _len is used.  */

static bool
gfc_is_unlimited_polymorphic_nonptr (tree type)
{
  if (POINTER_TYPE_P (type))
    type = TREE_TYPE (type);
  if (!GFC_CLASS_TYPE_P (type))
    return false;

  tree field = TYPE_FIELDS (type); /* _data */
  gcc_assert (field);
  field = DECL_CHAIN (field); /* _vptr */
  gcc_assert (field);
  field = DECL_CHAIN (field);
  if (!field)
    return false;
  gcc_assert (strcmp ("_len", IDENTIFIER_POINTER (DECL_NAME (field))) == 0);
  return true;
}

/* Return true if the DECL is for an allocatable array or scalar.  */

bool
gfc_omp_allocatable_p (tree decl)
{
  if (!DECL_P (decl))
    return false;

  if (GFC_DECL_GET_SCALAR_ALLOCATABLE (decl))
    return true;

  tree type = TREE_TYPE (decl);
  if (gfc_omp_privatize_by_reference (decl))
    type = TREE_TYPE (type);

  if (GFC_DESCRIPTOR_TYPE_P (type)
      && GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE)
    return true;

  return false;
}


/* Return true if DECL in private clause needs
   OMP_CLAUSE_PRIVATE_OUTER_REF on the private clause.  */
bool
gfc_omp_private_outer_ref (tree decl)
{
  tree type = TREE_TYPE (decl);

  if (gfc_omp_privatize_by_reference (decl))
    type = TREE_TYPE (type);

  if (GFC_DESCRIPTOR_TYPE_P (type)
      && GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE)
    return true;

  if (GFC_DECL_GET_SCALAR_ALLOCATABLE (decl))
    return true;

  if (gfc_has_alloc_comps (type, decl))
    return true;

  return false;
}

/* Callback for gfc_omp_unshare_expr.  */

static tree
gfc_omp_unshare_expr_r (tree *tp, int *walk_subtrees, void *)
{
  tree t = *tp;
  enum tree_code code = TREE_CODE (t);

  /* Stop at types, decls, constants like copy_tree_r.  */
  if (TREE_CODE_CLASS (code) == tcc_type
      || TREE_CODE_CLASS (code) == tcc_declaration
      || TREE_CODE_CLASS (code) == tcc_constant
      || code == BLOCK)
    *walk_subtrees = 0;
  else if (handled_component_p (t)
	   || TREE_CODE (t) == MEM_REF)
    {
      *tp = unshare_expr (t);
      *walk_subtrees = 0;
    }

  return NULL_TREE;
}

/* Unshare in expr anything that the FE which normally doesn't
   care much about tree sharing (because during gimplification
   everything is unshared) could cause problems with tree sharing
   at omp-low.c time.  */

static tree
gfc_omp_unshare_expr (tree expr)
{
  walk_tree (&expr, gfc_omp_unshare_expr_r, NULL, NULL);
  return expr;
}

enum walk_alloc_comps
{
  WALK_ALLOC_COMPS_DTOR,
  WALK_ALLOC_COMPS_DEFAULT_CTOR,
  WALK_ALLOC_COMPS_COPY_CTOR
};

/* Handle allocatable components in OpenMP clauses.  */

static tree
gfc_walk_alloc_comps (tree decl, tree dest, tree var,
		      enum walk_alloc_comps kind)
{
  stmtblock_t block, tmpblock;
  tree type = TREE_TYPE (decl), then_b, tem, field;
  gfc_init_block (&block);

  if (GFC_ARRAY_TYPE_P (type) || GFC_DESCRIPTOR_TYPE_P (type))
    {
      if (GFC_DESCRIPTOR_TYPE_P (type))
	{
	  gfc_init_block (&tmpblock);
	  tem = gfc_full_array_size (&tmpblock, decl,
				     GFC_TYPE_ARRAY_RANK (type));
	  then_b = gfc_finish_block (&tmpblock);
	  gfc_add_expr_to_block (&block, gfc_omp_unshare_expr (then_b));
	  tem = gfc_omp_unshare_expr (tem);
	  tem = fold_build2_loc (input_location, MINUS_EXPR,
				 gfc_array_index_type, tem,
				 gfc_index_one_node);
	}
      else
	{
	  bool compute_nelts = false;
	  if (!TYPE_DOMAIN (type)
	      || TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL_TREE
	      || TYPE_MIN_VALUE (TYPE_DOMAIN (type)) == error_mark_node
	      || TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == error_mark_node)
	    compute_nelts = true;
	  else if (VAR_P (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
	    {
	      tree a = DECL_ATTRIBUTES (TYPE_MAX_VALUE (TYPE_DOMAIN (type)));
	      if (lookup_attribute ("omp dummy var", a))
		compute_nelts = true;
	    }
	  if (compute_nelts)
	    {
	      tem = fold_build2 (EXACT_DIV_EXPR, sizetype,
				 TYPE_SIZE_UNIT (type),
				 TYPE_SIZE_UNIT (TREE_TYPE (type)));
	      tem = size_binop (MINUS_EXPR, tem, size_one_node);
	    }
	  else
	    tem = array_type_nelts (type);
	  tem = fold_convert (gfc_array_index_type, tem);
	}

      tree nelems = gfc_evaluate_now (tem, &block);
      tree index = gfc_create_var (gfc_array_index_type, "S");

      gfc_init_block (&tmpblock);
      tem = gfc_conv_array_data (decl);
      tree declvar = build_fold_indirect_ref_loc (input_location, tem);
      tree declvref = gfc_build_array_ref (declvar, index, NULL);
      tree destvar, destvref = NULL_TREE;
      if (dest)
	{
	  tem = gfc_conv_array_data (dest);
	  destvar = build_fold_indirect_ref_loc (input_location, tem);
	  destvref = gfc_build_array_ref (destvar, index, NULL);
	}
      gfc_add_expr_to_block (&tmpblock,
			     gfc_walk_alloc_comps (declvref, destvref,
						   var, kind));

      gfc_loopinfo loop;
      gfc_init_loopinfo (&loop);
      loop.dimen = 1;
      loop.from[0] = gfc_index_zero_node;
      loop.loopvar[0] = index;
      loop.to[0] = nelems;
      gfc_trans_scalarizing_loops (&loop, &tmpblock);
      gfc_add_block_to_block (&block, &loop.pre);
      return gfc_finish_block (&block);
    }
  else if (GFC_DECL_GET_SCALAR_ALLOCATABLE (var))
    {
      decl = build_fold_indirect_ref_loc (input_location, decl);
      if (dest)
	dest = build_fold_indirect_ref_loc (input_location, dest);
      type = TREE_TYPE (decl);
    }

  gcc_assert (TREE_CODE (type) == RECORD_TYPE);
  for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    {
      tree ftype = TREE_TYPE (field);
      tree declf, destf = NULL_TREE;
      bool has_alloc_comps = gfc_has_alloc_comps (ftype, field);
      if ((!GFC_DESCRIPTOR_TYPE_P (ftype)
	   || GFC_TYPE_ARRAY_AKIND (ftype) != GFC_ARRAY_ALLOCATABLE)
	  && !GFC_DECL_GET_SCALAR_ALLOCATABLE (field)
	  && !has_alloc_comps)
	continue;
      declf = fold_build3_loc (input_location, COMPONENT_REF, ftype,
			       decl, field, NULL_TREE);
      if (dest)
	destf = fold_build3_loc (input_location, COMPONENT_REF, ftype,
				 dest, field, NULL_TREE);

      tem = NULL_TREE;
      switch (kind)
	{
	case WALK_ALLOC_COMPS_DTOR:
	  break;
	case WALK_ALLOC_COMPS_DEFAULT_CTOR:
	  if (GFC_DESCRIPTOR_TYPE_P (ftype)
	      && GFC_TYPE_ARRAY_AKIND (ftype) == GFC_ARRAY_ALLOCATABLE)
	    {
	      gfc_add_modify (&block, unshare_expr (destf),
			      unshare_expr (declf));
	      tem = gfc_duplicate_allocatable_nocopy
					(destf, declf, ftype,
					 GFC_TYPE_ARRAY_RANK (ftype));
	    }
	  else if (GFC_DECL_GET_SCALAR_ALLOCATABLE (field))
	    tem = gfc_duplicate_allocatable_nocopy (destf, declf, ftype, 0);
	  break;
	case WALK_ALLOC_COMPS_COPY_CTOR:
	  if (GFC_DESCRIPTOR_TYPE_P (ftype)
	      && GFC_TYPE_ARRAY_AKIND (ftype) == GFC_ARRAY_ALLOCATABLE)
	    tem = gfc_duplicate_allocatable (destf, declf, ftype,
					     GFC_TYPE_ARRAY_RANK (ftype),
					     NULL_TREE);
	  else if (GFC_DECL_GET_SCALAR_ALLOCATABLE (field))
	    tem = gfc_duplicate_allocatable (destf, declf, ftype, 0,
					     NULL_TREE);
	  break;
	}
      if (tem)
	gfc_add_expr_to_block (&block, gfc_omp_unshare_expr (tem));
      if (has_alloc_comps)
	{
	  gfc_init_block (&tmpblock);
	  gfc_add_expr_to_block (&tmpblock,
				 gfc_walk_alloc_comps (declf, destf,
						       field, kind));
	  then_b = gfc_finish_block (&tmpblock);
	  if (GFC_DESCRIPTOR_TYPE_P (ftype)
	      && GFC_TYPE_ARRAY_AKIND (ftype) == GFC_ARRAY_ALLOCATABLE)
	    tem = gfc_conv_descriptor_data_get (unshare_expr (declf));
	  else if (GFC_DECL_GET_SCALAR_ALLOCATABLE (field))
	    tem = unshare_expr (declf);
	  else
	    tem = NULL_TREE;
	  if (tem)
	    {
	      tem = fold_convert (pvoid_type_node, tem);
	      tem = fold_build2_loc (input_location, NE_EXPR,
				     logical_type_node, tem,
				     null_pointer_node);
	      then_b = build3_loc (input_location, COND_EXPR, void_type_node,
				   tem, then_b,
				   build_empty_stmt (input_location));
	    }
	  gfc_add_expr_to_block (&block, then_b);
	}
      if (kind == WALK_ALLOC_COMPS_DTOR)
	{
	  if (GFC_DESCRIPTOR_TYPE_P (ftype)
	      && GFC_TYPE_ARRAY_AKIND (ftype) == GFC_ARRAY_ALLOCATABLE)
	    {
	      tem = gfc_conv_descriptor_data_get (unshare_expr (declf));
	      tem = gfc_deallocate_with_status (tem, NULL_TREE, NULL_TREE,
						NULL_TREE, NULL_TREE, true,
						NULL,
						GFC_CAF_COARRAY_NOCOARRAY);
	      gfc_add_expr_to_block (&block, gfc_omp_unshare_expr (tem));
	    }
	  else if (GFC_DECL_GET_SCALAR_ALLOCATABLE (field))
	    {
	      tem = gfc_call_free (unshare_expr (declf));
	      gfc_add_expr_to_block (&block, gfc_omp_unshare_expr (tem));
	    }
	}
    }

  return gfc_finish_block (&block);
}

/* Return code to initialize DECL with its default constructor, or
   NULL if there's nothing to do.  */

tree
gfc_omp_clause_default_ctor (tree clause, tree decl, tree outer)
{
  tree type = TREE_TYPE (decl), size, ptr, cond, then_b, else_b;
  stmtblock_t block, cond_block;

  switch (OMP_CLAUSE_CODE (clause))
    {
    case OMP_CLAUSE__LOOPTEMP_:
    case OMP_CLAUSE__REDUCTEMP_:
    case OMP_CLAUSE__CONDTEMP_:
    case OMP_CLAUSE__SCANTEMP_:
      return NULL;
    case OMP_CLAUSE_PRIVATE:
    case OMP_CLAUSE_LASTPRIVATE:
    case OMP_CLAUSE_LINEAR:
    case OMP_CLAUSE_REDUCTION:
    case OMP_CLAUSE_IN_REDUCTION:
    case OMP_CLAUSE_TASK_REDUCTION:
      break;
    default:
      gcc_unreachable ();
    }

  if ((! GFC_DESCRIPTOR_TYPE_P (type)
       || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
      && (!GFC_DECL_GET_SCALAR_ALLOCATABLE (OMP_CLAUSE_DECL (clause))
	  || !POINTER_TYPE_P (type)))
    {
      if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
	{
	  gcc_assert (outer);
	  gfc_start_block (&block);
	  tree tem = gfc_walk_alloc_comps (outer, decl,
					   OMP_CLAUSE_DECL (clause),
					   WALK_ALLOC_COMPS_DEFAULT_CTOR);
	  gfc_add_expr_to_block (&block, tem);
	  return gfc_finish_block (&block);
	}
      return NULL_TREE;
    }

  gcc_assert (outer != NULL_TREE);

  /* Allocatable arrays and scalars in PRIVATE clauses need to be set to
     "not currently allocated" allocation status if outer
     array is "not currently allocated", otherwise should be allocated.  */
  gfc_start_block (&block);

  gfc_init_block (&cond_block);

  if (GFC_DESCRIPTOR_TYPE_P (type))
    {
      gfc_add_modify (&cond_block, decl, outer);
      tree rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
      size = gfc_conv_descriptor_ubound_get (decl, rank);
      size = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
			      size,
			      gfc_conv_descriptor_lbound_get (decl, rank));
      size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
			      size, gfc_index_one_node);
      if (GFC_TYPE_ARRAY_RANK (type) > 1)
	size = fold_build2_loc (input_location, MULT_EXPR,
				gfc_array_index_type, size,
				gfc_conv_descriptor_stride_get (decl, rank));
      tree esize = fold_convert (gfc_array_index_type,
				 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
      size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
			      size, esize);
      size = unshare_expr (size);
      size = gfc_evaluate_now (fold_convert (size_type_node, size),
			       &cond_block);
    }
  else
    size = fold_convert (size_type_node, TYPE_SIZE_UNIT (TREE_TYPE (type)));
  ptr = gfc_create_var (pvoid_type_node, NULL);
  gfc_allocate_using_malloc (&cond_block, ptr, size, NULL_TREE);
  if (GFC_DESCRIPTOR_TYPE_P (type))
    gfc_conv_descriptor_data_set (&cond_block, unshare_expr (decl), ptr);
  else
    gfc_add_modify (&cond_block, unshare_expr (decl),
		    fold_convert (TREE_TYPE (decl), ptr));
  if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
    {
      tree tem = gfc_walk_alloc_comps (outer, decl,
				       OMP_CLAUSE_DECL (clause),
				       WALK_ALLOC_COMPS_DEFAULT_CTOR);
      gfc_add_expr_to_block (&cond_block, tem);
    }
  then_b = gfc_finish_block (&cond_block);

  /* Reduction clause requires allocated ALLOCATABLE.  */
  if (OMP_CLAUSE_CODE (clause) != OMP_CLAUSE_REDUCTION
      && OMP_CLAUSE_CODE (clause) != OMP_CLAUSE_IN_REDUCTION
      && OMP_CLAUSE_CODE (clause) != OMP_CLAUSE_TASK_REDUCTION)
    {
      gfc_init_block (&cond_block);
      if (GFC_DESCRIPTOR_TYPE_P (type))
	gfc_conv_descriptor_data_set (&cond_block, unshare_expr (decl),
				      null_pointer_node);
      else
	gfc_add_modify (&cond_block, unshare_expr (decl),
			build_zero_cst (TREE_TYPE (decl)));
      else_b = gfc_finish_block (&cond_block);

      tree tem = fold_convert (pvoid_type_node,
			       GFC_DESCRIPTOR_TYPE_P (type)
			       ? gfc_conv_descriptor_data_get (outer) : outer);
      tem = unshare_expr (tem);
      cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
			      tem, null_pointer_node);
      gfc_add_expr_to_block (&block,
			     build3_loc (input_location, COND_EXPR,
					 void_type_node, cond, then_b,
					 else_b));
      /* Avoid -W*uninitialized warnings.  */
      if (DECL_P (decl))
	TREE_NO_WARNING (decl) = 1;
    }
  else
    gfc_add_expr_to_block (&block, then_b);

  return gfc_finish_block (&block);
}

/* Build and return code for a copy constructor from SRC to DEST.  */

tree
gfc_omp_clause_copy_ctor (tree clause, tree dest, tree src)
{
  tree type = TREE_TYPE (dest), ptr, size, call;
  tree decl_type = TREE_TYPE (OMP_CLAUSE_DECL (clause));
  tree cond, then_b, else_b;
  stmtblock_t block, cond_block;

  gcc_assert (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_FIRSTPRIVATE
	      || OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_LINEAR);

  if (DECL_ARTIFICIAL (OMP_CLAUSE_DECL (clause))
      && DECL_LANG_SPECIFIC (OMP_CLAUSE_DECL (clause))
      && GFC_DECL_SAVED_DESCRIPTOR (OMP_CLAUSE_DECL (clause)))
    decl_type
      = TREE_TYPE (GFC_DECL_SAVED_DESCRIPTOR (OMP_CLAUSE_DECL (clause)));

  if (gfc_is_polymorphic_nonptr (decl_type))
    {
      if (POINTER_TYPE_P (decl_type))
	decl_type = TREE_TYPE (decl_type);
      decl_type = TREE_TYPE (TYPE_FIELDS (decl_type));
      if (GFC_DESCRIPTOR_TYPE_P (decl_type) || GFC_ARRAY_TYPE_P (decl_type))
	fatal_error (input_location,
		     "Sorry, polymorphic arrays not yet supported for "
		     "firstprivate");
      tree src_len;
      tree nelems = build_int_cst (size_type_node, 1);  /* Scalar.  */
      tree src_data = gfc_class_data_get (unshare_expr (src));
      tree dest_data = gfc_class_data_get (unshare_expr (dest));
      bool unlimited = gfc_is_unlimited_polymorphic_nonptr (type);

      gfc_start_block (&block);
      gfc_add_modify (&block, gfc_class_vptr_get (dest),
		      gfc_class_vptr_get (src));
      gfc_init_block (&cond_block);

      if (unlimited)
	{
	  src_len = gfc_class_len_get (src);
	  gfc_add_modify (&cond_block, gfc_class_len_get (unshare_expr (dest)), src_len);
	}

      /* Use: size = class._vtab._size * (class._len > 0 ? class._len : 1).  */
      size = fold_convert (size_type_node, gfc_class_vtab_size_get (src));
      if (unlimited)
	{
	  cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
				  unshare_expr (src_len),
				  build_zero_cst (TREE_TYPE (src_len)));
	  cond = build3_loc (input_location, COND_EXPR, size_type_node, cond,
			     fold_convert (size_type_node,
					   unshare_expr (src_len)),
			     build_int_cst (size_type_node, 1));
	  size = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
				  size, cond);
	}

      /* Malloc memory + call class->_vpt->_copy.  */
      call = builtin_decl_explicit (BUILT_IN_MALLOC);
      call = build_call_expr_loc (input_location, call, 1, size);
      gfc_add_modify (&cond_block, dest_data,
		      fold_convert (TREE_TYPE (dest_data), call));
      gfc_add_expr_to_block (&cond_block,
			     gfc_copy_class_to_class (src, dest, nelems,
						      unlimited));

      gcc_assert (TREE_CODE (dest_data) == COMPONENT_REF);
      if (!GFC_DECL_GET_SCALAR_ALLOCATABLE (TREE_OPERAND (dest_data, 1)))
	{
	  gfc_add_block_to_block (&block, &cond_block);
	}
      else
	{
	  /* Create: if (class._data != 0) <cond_block> else class._data = NULL; */
	  cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
				  src_data, null_pointer_node);
	  gfc_add_expr_to_block (&block, build3_loc (input_location, COND_EXPR,
				 void_type_node, cond,
				 gfc_finish_block (&cond_block),
				 fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
				 unshare_expr (dest_data), null_pointer_node)));
	}
      return gfc_finish_block (&block);
    }

  if ((! GFC_DESCRIPTOR_TYPE_P (type)
       || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
      && (!GFC_DECL_GET_SCALAR_ALLOCATABLE (OMP_CLAUSE_DECL (clause))
	  || !POINTER_TYPE_P (type)))
    {
      if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
	{
	  gfc_start_block (&block);
	  gfc_add_modify (&block, dest, src);
	  tree tem = gfc_walk_alloc_comps (src, dest, OMP_CLAUSE_DECL (clause),
					   WALK_ALLOC_COMPS_COPY_CTOR);
	  gfc_add_expr_to_block (&block, tem);
	  return gfc_finish_block (&block);
	}
      else
	return build2_v (MODIFY_EXPR, dest, src);
    }

  /* Allocatable arrays in FIRSTPRIVATE clauses need to be allocated
     and copied from SRC.  */
  gfc_start_block (&block);

  gfc_init_block (&cond_block);

  gfc_add_modify (&cond_block, dest, fold_convert (TREE_TYPE (dest), src));
  if (GFC_DESCRIPTOR_TYPE_P (type))
    {
      tree rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
      size = gfc_conv_descriptor_ubound_get (dest, rank);
      size = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
			      size,
			      gfc_conv_descriptor_lbound_get (dest, rank));
      size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
			      size, gfc_index_one_node);
      if (GFC_TYPE_ARRAY_RANK (type) > 1)
	size = fold_build2_loc (input_location, MULT_EXPR,
				gfc_array_index_type, size,
				gfc_conv_descriptor_stride_get (dest, rank));
      tree esize = fold_convert (gfc_array_index_type,
				 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
      size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
			      size, esize);
      size = unshare_expr (size);
      size = gfc_evaluate_now (fold_convert (size_type_node, size),
			       &cond_block);
    }
  else
    size = fold_convert (size_type_node, TYPE_SIZE_UNIT (TREE_TYPE (type)));
  ptr = gfc_create_var (pvoid_type_node, NULL);
  gfc_allocate_using_malloc (&cond_block, ptr, size, NULL_TREE);
  if (GFC_DESCRIPTOR_TYPE_P (type))
    gfc_conv_descriptor_data_set (&cond_block, unshare_expr (dest), ptr);
  else
    gfc_add_modify (&cond_block, unshare_expr (dest),
		    fold_convert (TREE_TYPE (dest), ptr));

  tree srcptr = GFC_DESCRIPTOR_TYPE_P (type)
		? gfc_conv_descriptor_data_get (src) : src;
  srcptr = unshare_expr (srcptr);
  srcptr = fold_convert (pvoid_type_node, srcptr);
  call = build_call_expr_loc (input_location,
			      builtin_decl_explicit (BUILT_IN_MEMCPY), 3, ptr,
			      srcptr, size);
  gfc_add_expr_to_block (&cond_block, fold_convert (void_type_node, call));
  if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
    {
      tree tem = gfc_walk_alloc_comps (src, dest,
				       OMP_CLAUSE_DECL (clause),
				       WALK_ALLOC_COMPS_COPY_CTOR);
      gfc_add_expr_to_block (&cond_block, tem);
    }
  then_b = gfc_finish_block (&cond_block);

  gfc_init_block (&cond_block);
  if (GFC_DESCRIPTOR_TYPE_P (type))
    gfc_conv_descriptor_data_set (&cond_block, unshare_expr (dest),
				  null_pointer_node);
  else
    gfc_add_modify (&cond_block, unshare_expr (dest),
		    build_zero_cst (TREE_TYPE (dest)));
  else_b = gfc_finish_block (&cond_block);

  cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
			  unshare_expr (srcptr), null_pointer_node);
  gfc_add_expr_to_block (&block,
			 build3_loc (input_location, COND_EXPR,
				     void_type_node, cond, then_b, else_b));
  /* Avoid -W*uninitialized warnings.  */
  if (DECL_P (dest))
    TREE_NO_WARNING (dest) = 1;

  return gfc_finish_block (&block);
}

/* Similarly, except use an intrinsic or pointer assignment operator
   instead.  */

tree
gfc_omp_clause_assign_op (tree clause, tree dest, tree src)
{
  tree type = TREE_TYPE (dest), ptr, size, call, nonalloc;
  tree cond, then_b, else_b;
  stmtblock_t block, cond_block, cond_block2, inner_block;

  if ((! GFC_DESCRIPTOR_TYPE_P (type)
       || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
      && (!GFC_DECL_GET_SCALAR_ALLOCATABLE (OMP_CLAUSE_DECL (clause))
	  || !POINTER_TYPE_P (type)))
    {
      if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
	{
	  gfc_start_block (&block);
	  /* First dealloc any allocatable components in DEST.  */
	  tree tem = gfc_walk_alloc_comps (dest, NULL_TREE,
					   OMP_CLAUSE_DECL (clause),
					   WALK_ALLOC_COMPS_DTOR);
	  gfc_add_expr_to_block (&block, tem);
	  /* Then copy over toplevel data.  */
	  gfc_add_modify (&block, dest, src);
	  /* Finally allocate any allocatable components and copy.  */
	  tem = gfc_walk_alloc_comps (src, dest, OMP_CLAUSE_DECL (clause),
					   WALK_ALLOC_COMPS_COPY_CTOR);
	  gfc_add_expr_to_block (&block, tem);
	  return gfc_finish_block (&block);
	}
      else
	return build2_v (MODIFY_EXPR, dest, src);
    }

  gfc_start_block (&block);

  if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
    {
      then_b = gfc_walk_alloc_comps (dest, NULL_TREE, OMP_CLAUSE_DECL (clause),
				     WALK_ALLOC_COMPS_DTOR);
      tree tem = fold_convert (pvoid_type_node,
			       GFC_DESCRIPTOR_TYPE_P (type)
			       ? gfc_conv_descriptor_data_get (dest) : dest);
      tem = unshare_expr (tem);
      cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
			      tem, null_pointer_node);
      tem = build3_loc (input_location, COND_EXPR, void_type_node, cond,
			then_b, build_empty_stmt (input_location));
      gfc_add_expr_to_block (&block, tem);
    }

  gfc_init_block (&cond_block);

  if (GFC_DESCRIPTOR_TYPE_P (type))
    {
      tree rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
      size = gfc_conv_descriptor_ubound_get (src, rank);
      size = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
			      size,
			      gfc_conv_descriptor_lbound_get (src, rank));
      size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
			      size, gfc_index_one_node);
      if (GFC_TYPE_ARRAY_RANK (type) > 1)
	size = fold_build2_loc (input_location, MULT_EXPR,
				gfc_array_index_type, size,
				gfc_conv_descriptor_stride_get (src, rank));
      tree esize = fold_convert (gfc_array_index_type,
				 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
      size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
			      size, esize);
      size = unshare_expr (size);
      size = gfc_evaluate_now (fold_convert (size_type_node, size),
			       &cond_block);
    }
  else
    size = fold_convert (size_type_node, TYPE_SIZE_UNIT (TREE_TYPE (type)));
  ptr = gfc_create_var (pvoid_type_node, NULL);

  tree destptr = GFC_DESCRIPTOR_TYPE_P (type)
		 ? gfc_conv_descriptor_data_get (dest) : dest;
  destptr = unshare_expr (destptr);
  destptr = fold_convert (pvoid_type_node, destptr);
  gfc_add_modify (&cond_block, ptr, destptr);

  nonalloc = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
			      destptr, null_pointer_node);
  cond = nonalloc;
  if (GFC_DESCRIPTOR_TYPE_P (type))
    {
      int i;
      for (i = 0; i < GFC_TYPE_ARRAY_RANK (type); i++)
	{
	  tree rank = gfc_rank_cst[i];
	  tree tem = gfc_conv_descriptor_ubound_get (src, rank);
	  tem = fold_build2_loc (input_location, MINUS_EXPR,
				 gfc_array_index_type, tem,
				 gfc_conv_descriptor_lbound_get (src, rank));
	  tem = fold_build2_loc (input_location, PLUS_EXPR,
				 gfc_array_index_type, tem,
				 gfc_conv_descriptor_lbound_get (dest, rank));
	  tem = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
				 tem, gfc_conv_descriptor_ubound_get (dest,
								      rank));
	  cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
				  logical_type_node, cond, tem);
	}
    }

  gfc_init_block (&cond_block2);

  if (GFC_DESCRIPTOR_TYPE_P (type))
    {
      gfc_init_block (&inner_block);
      gfc_allocate_using_malloc (&inner_block, ptr, size, NULL_TREE);
      then_b = gfc_finish_block (&inner_block);

      gfc_init_block (&inner_block);
      gfc_add_modify (&inner_block, ptr,
		      gfc_call_realloc (&inner_block, ptr, size));
      else_b = gfc_finish_block (&inner_block);

      gfc_add_expr_to_block (&cond_block2,
			     build3_loc (input_location, COND_EXPR,
					 void_type_node,
					 unshare_expr (nonalloc),
					 then_b, else_b));
      gfc_add_modify (&cond_block2, dest, src);
      gfc_conv_descriptor_data_set (&cond_block2, unshare_expr (dest), ptr);
    }
  else
    {
      gfc_allocate_using_malloc (&cond_block2, ptr, size, NULL_TREE);
      gfc_add_modify (&cond_block2, unshare_expr (dest),
		      fold_convert (type, ptr));
    }
  then_b = gfc_finish_block (&cond_block2);
  else_b = build_empty_stmt (input_location);

  gfc_add_expr_to_block (&cond_block,
			 build3_loc (input_location, COND_EXPR,
				     void_type_node, unshare_expr (cond),
				     then_b, else_b));

  tree srcptr = GFC_DESCRIPTOR_TYPE_P (type)
		? gfc_conv_descriptor_data_get (src) : src;
  srcptr = unshare_expr (srcptr);
  srcptr = fold_convert (pvoid_type_node, srcptr);
  call = build_call_expr_loc (input_location,
			      builtin_decl_explicit (BUILT_IN_MEMCPY), 3, ptr,
			      srcptr, size);
  gfc_add_expr_to_block (&cond_block, fold_convert (void_type_node, call));
  if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
    {
      tree tem = gfc_walk_alloc_comps (src, dest,
				       OMP_CLAUSE_DECL (clause),
				       WALK_ALLOC_COMPS_COPY_CTOR);
      gfc_add_expr_to_block (&cond_block, tem);
    }
  then_b = gfc_finish_block (&cond_block);

  if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_COPYIN)
    {
      gfc_init_block (&cond_block);
      if (GFC_DESCRIPTOR_TYPE_P (type))
	{
	  tree tmp = gfc_conv_descriptor_data_get (unshare_expr (dest));
	  tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE,
					    NULL_TREE, NULL_TREE, true, NULL,
					    GFC_CAF_COARRAY_NOCOARRAY);
	  gfc_add_expr_to_block (&cond_block, tmp);
	}
      else
	{
	  destptr = gfc_evaluate_now (destptr, &cond_block);
	  gfc_add_expr_to_block (&cond_block, gfc_call_free (destptr));
	  gfc_add_modify (&cond_block, unshare_expr (dest),
			  build_zero_cst (TREE_TYPE (dest)));
	}
      else_b = gfc_finish_block (&cond_block);

      cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
			      unshare_expr (srcptr), null_pointer_node);
      gfc_add_expr_to_block (&block,
			     build3_loc (input_location, COND_EXPR,
					 void_type_node, cond,
					 then_b, else_b));
    }
  else
    gfc_add_expr_to_block (&block, then_b);

  return gfc_finish_block (&block);
}

static void
gfc_omp_linear_clause_add_loop (stmtblock_t *block, tree dest, tree src,
				tree add, tree nelems)
{
  stmtblock_t tmpblock;
  tree desta, srca, index = gfc_create_var (gfc_array_index_type, "S");
  nelems = gfc_evaluate_now (nelems, block);

  gfc_init_block (&tmpblock);
  if (TREE_CODE (TREE_TYPE (dest)) == ARRAY_TYPE)
    {
      desta = gfc_build_array_ref (dest, index, NULL);
      srca = gfc_build_array_ref (src, index, NULL);
    }
  else
    {
      gcc_assert (POINTER_TYPE_P (TREE_TYPE (dest)));
      tree idx = fold_build2 (MULT_EXPR, sizetype,
			      fold_convert (sizetype, index),
			      TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (dest))));
      desta = build_fold_indirect_ref (fold_build2 (POINTER_PLUS_EXPR,
						    TREE_TYPE (dest), dest,
						    idx));
      srca = build_fold_indirect_ref (fold_build2 (POINTER_PLUS_EXPR,
						   TREE_TYPE (src), src,
						    idx));
    }
  gfc_add_modify (&tmpblock, desta,
		  fold_build2 (PLUS_EXPR, TREE_TYPE (desta),
			       srca, add));

  gfc_loopinfo loop;
  gfc_init_loopinfo (&loop);
  loop.dimen = 1;
  loop.from[0] = gfc_index_zero_node;
  loop.loopvar[0] = index;
  loop.to[0] = nelems;
  gfc_trans_scalarizing_loops (&loop, &tmpblock);
  gfc_add_block_to_block (block, &loop.pre);
}

/* Build and return code for a constructor of DEST that initializes
   it to SRC plus ADD (ADD is scalar integer).  */

tree
gfc_omp_clause_linear_ctor (tree clause, tree dest, tree src, tree add)
{
  tree type = TREE_TYPE (dest), ptr, size, nelems = NULL_TREE;
  stmtblock_t block;

  gcc_assert (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_LINEAR);

  gfc_start_block (&block);
  add = gfc_evaluate_now (add, &block);

  if ((! GFC_DESCRIPTOR_TYPE_P (type)
       || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
      && (!GFC_DECL_GET_SCALAR_ALLOCATABLE (OMP_CLAUSE_DECL (clause))
	  || !POINTER_TYPE_P (type)))
    {
      bool compute_nelts = false;
      gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
      if (!TYPE_DOMAIN (type)
	  || TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL_TREE
	  || TYPE_MIN_VALUE (TYPE_DOMAIN (type)) == error_mark_node
	  || TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == error_mark_node)
	compute_nelts = true;
      else if (VAR_P (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
	{
	  tree a = DECL_ATTRIBUTES (TYPE_MAX_VALUE (TYPE_DOMAIN (type)));
	  if (lookup_attribute ("omp dummy var", a))
	    compute_nelts = true;
	}
      if (compute_nelts)
	{
	  nelems = fold_build2 (EXACT_DIV_EXPR, sizetype,
				TYPE_SIZE_UNIT (type),
				TYPE_SIZE_UNIT (TREE_TYPE (type)));
	  nelems = size_binop (MINUS_EXPR, nelems, size_one_node);
	}
      else
	nelems = array_type_nelts (type);
      nelems = fold_convert (gfc_array_index_type, nelems);

      gfc_omp_linear_clause_add_loop (&block, dest, src, add, nelems);
      return gfc_finish_block (&block);
    }

  /* Allocatable arrays in LINEAR clauses need to be allocated
     and copied from SRC.  */
  gfc_add_modify (&block, dest, src);
  if (GFC_DESCRIPTOR_TYPE_P (type))
    {
      tree rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
      size = gfc_conv_descriptor_ubound_get (dest, rank);
      size = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
			      size,
			      gfc_conv_descriptor_lbound_get (dest, rank));
      size = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
			      size, gfc_index_one_node);
      if (GFC_TYPE_ARRAY_RANK (type) > 1)
	size = fold_build2_loc (input_location, MULT_EXPR,
				gfc_array_index_type, size,
				gfc_conv_descriptor_stride_get (dest, rank));
      tree esize = fold_convert (gfc_array_index_type,
				 TYPE_SIZE_UNIT (gfc_get_element_type (type)));
      nelems = gfc_evaluate_now (unshare_expr (size), &block);
      size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
			      nelems, unshare_expr (esize));
      size = gfc_evaluate_now (fold_convert (size_type_node, size),
			       &block);
      nelems = fold_build2_loc (input_location, MINUS_EXPR,
				gfc_array_index_type, nelems,
				gfc_index_one_node);
    }
  else
    size = fold_convert (size_type_node, TYPE_SIZE_UNIT (TREE_TYPE (type)));
  ptr = gfc_create_var (pvoid_type_node, NULL);
  gfc_allocate_using_malloc (&block, ptr, size, NULL_TREE);
  if (GFC_DESCRIPTOR_TYPE_P (type))
    {
      gfc_conv_descriptor_data_set (&block, unshare_expr (dest), ptr);
      tree etype = gfc_get_element_type (type);
      ptr = fold_convert (build_pointer_type (etype), ptr);
      tree srcptr = gfc_conv_descriptor_data_get (unshare_expr (src));
      srcptr = fold_convert (build_pointer_type (etype), srcptr);
      gfc_omp_linear_clause_add_loop (&block, ptr, srcptr, add, nelems);
    }
  else
    {
      gfc_add_modify (&block, unshare_expr (dest),
		      fold_convert (TREE_TYPE (dest), ptr));
      ptr = fold_convert (TREE_TYPE (dest), ptr);
      tree dstm = build_fold_indirect_ref (ptr);
      tree srcm = build_fold_indirect_ref (unshare_expr (src));
      gfc_add_modify (&block, dstm,
		      fold_build2 (PLUS_EXPR, TREE_TYPE (add), srcm, add));
    }
  return gfc_finish_block (&block);
}

/* Build and return code destructing DECL.  Return NULL if nothing
   to be done.  */

tree
gfc_omp_clause_dtor (tree clause, tree decl)
{
  tree type = TREE_TYPE (decl), tem;
  tree decl_type = TREE_TYPE (OMP_CLAUSE_DECL (clause));

  if (DECL_ARTIFICIAL (OMP_CLAUSE_DECL (clause))
      && DECL_LANG_SPECIFIC (OMP_CLAUSE_DECL (clause))
      && GFC_DECL_SAVED_DESCRIPTOR (OMP_CLAUSE_DECL (clause)))
    decl_type
	= TREE_TYPE (GFC_DECL_SAVED_DESCRIPTOR (OMP_CLAUSE_DECL (clause)));
  if (gfc_is_polymorphic_nonptr (decl_type))
    {
      if (POINTER_TYPE_P (decl_type))
	decl_type = TREE_TYPE (decl_type);
      decl_type = TREE_TYPE (TYPE_FIELDS (decl_type));
      if (GFC_DESCRIPTOR_TYPE_P (decl_type) || GFC_ARRAY_TYPE_P (decl_type))
	fatal_error (input_location,
		     "Sorry, polymorphic arrays not yet supported for "
		     "firstprivate");
      stmtblock_t block, cond_block;
      gfc_start_block (&block);
      gfc_init_block (&cond_block);
      tree final = gfc_class_vtab_final_get (decl);
      tree size = fold_convert (size_type_node, gfc_class_vtab_size_get (decl));
      gfc_se se;
      gfc_init_se (&se, NULL);
      symbol_attribute attr = {};
      tree data = gfc_class_data_get (decl);
      tree desc = gfc_conv_scalar_to_descriptor (&se, data, attr);

      /* Call class->_vpt->_finalize + free.  */
      tree call = build_fold_indirect_ref (final);
      call = build_call_expr_loc (input_location, call, 3,
				  gfc_build_addr_expr (NULL, desc),
				  size, boolean_false_node);
      gfc_add_block_to_block (&cond_block, &se.pre);
      gfc_add_expr_to_block (&cond_block, fold_convert (void_type_node, call));
      gfc_add_block_to_block (&cond_block, &se.post);
      /* Create: if (_vtab && _final) <cond_block>  */
      tree cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
				   gfc_class_vptr_get (decl),
				   null_pointer_node);
      tree cond2 = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
				   final, null_pointer_node);
      cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
			      boolean_type_node, cond, cond2);
      gfc_add_expr_to_block (&block, build3_loc (input_location, COND_EXPR,
				 void_type_node, cond,
				 gfc_finish_block (&cond_block), NULL_TREE));
      call = builtin_decl_explicit (BUILT_IN_FREE);
      call = build_call_expr_loc (input_location, call, 1, data);
      gfc_add_expr_to_block (&block, fold_convert (void_type_node, call));
      return gfc_finish_block (&block);
    }

  if ((! GFC_DESCRIPTOR_TYPE_P (type)
       || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
      && (!GFC_DECL_GET_SCALAR_ALLOCATABLE (OMP_CLAUSE_DECL (clause))
	  || !POINTER_TYPE_P (type)))
    {
      if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
	return gfc_walk_alloc_comps (decl, NULL_TREE,
				     OMP_CLAUSE_DECL (clause),
				     WALK_ALLOC_COMPS_DTOR);
      return NULL_TREE;
    }

  if (GFC_DESCRIPTOR_TYPE_P (type))
    {
      /* Allocatable arrays in FIRSTPRIVATE/LASTPRIVATE etc. clauses need
	 to be deallocated if they were allocated.  */
      tem = gfc_conv_descriptor_data_get (decl);
      tem = gfc_deallocate_with_status (tem, NULL_TREE, NULL_TREE, NULL_TREE,
					NULL_TREE, true, NULL,
					GFC_CAF_COARRAY_NOCOARRAY);
    }
  else
    tem = gfc_call_free (decl);
  tem = gfc_omp_unshare_expr (tem);

  if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
    {
      stmtblock_t block;
      tree then_b;

      gfc_init_block (&block);
      gfc_add_expr_to_block (&block,
			     gfc_walk_alloc_comps (decl, NULL_TREE,
						   OMP_CLAUSE_DECL (clause),
						   WALK_ALLOC_COMPS_DTOR));
      gfc_add_expr_to_block (&block, tem);
      then_b = gfc_finish_block (&block);

      tem = fold_convert (pvoid_type_node,
			  GFC_DESCRIPTOR_TYPE_P (type)
			  ? gfc_conv_descriptor_data_get (decl) : decl);
      tem = unshare_expr (tem);
      tree cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
				   tem, null_pointer_node);
      tem = build3_loc (input_location, COND_EXPR, void_type_node, cond,
			then_b, build_empty_stmt (input_location));
    }
  return tem;
}

/* Build a conditional expression in BLOCK.  If COND_VAL is not
   null, then the block THEN_B is executed, otherwise ELSE_VAL
   is assigned to VAL.  */

static void
gfc_build_cond_assign (stmtblock_t *block, tree val, tree cond_val,
		       tree then_b, tree else_val)
{
  stmtblock_t cond_block;
  tree else_b = NULL_TREE;
  tree val_ty = TREE_TYPE (val);

  if (else_val)
    {
      gfc_init_block (&cond_block);
      gfc_add_modify (&cond_block, val, fold_convert (val_ty, else_val));
      else_b = gfc_finish_block (&cond_block);
    }
  gfc_add_expr_to_block (block,
			 build3_loc (input_location, COND_EXPR, void_type_node,
				     cond_val, then_b, else_b));
}

/* Build a conditional expression in BLOCK, returning a temporary
   variable containing the result.  If COND_VAL is not null, then
   THEN_VAL will be assigned to the variable, otherwise ELSE_VAL
   is assigned.
 */

static tree
gfc_build_cond_assign_expr (stmtblock_t *block, tree cond_val,
			    tree then_val, tree else_val)
{
  tree val;
  tree val_ty = TREE_TYPE (then_val);
  stmtblock_t cond_block;

  val = create_tmp_var (val_ty);

  gfc_init_block (&cond_block);
  gfc_add_modify (&cond_block, val, then_val);
  tree then_b = gfc_finish_block (&cond_block);

  gfc_build_cond_assign (block, val, cond_val, then_b, else_val);

  return val;
}

void
gfc_omp_finish_clause (tree c, gimple_seq *pre_p, bool openacc)
{
  if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
    return;

  tree decl = OMP_CLAUSE_DECL (c);

  /* Assumed-size arrays can't be mapped implicitly, they have to be
     mapped explicitly using array sections.  */
  if (TREE_CODE (decl) == PARM_DECL
      && GFC_ARRAY_TYPE_P (TREE_TYPE (decl))
      && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (decl)) == GFC_ARRAY_UNKNOWN
      && GFC_TYPE_ARRAY_UBOUND (TREE_TYPE (decl),
				GFC_TYPE_ARRAY_RANK (TREE_TYPE (decl)) - 1)
	 == NULL)
    {
      error_at (OMP_CLAUSE_LOCATION (c),
		"implicit mapping of assumed size array %qD", decl);
      return;
    }

  tree c2 = NULL_TREE, c3 = NULL_TREE, c4 = NULL_TREE;
  tree present = gfc_omp_check_optional_argument (decl, true);
  if (POINTER_TYPE_P (TREE_TYPE (decl)))
    {
      if (!gfc_omp_privatize_by_reference (decl)
	  && !GFC_DECL_GET_SCALAR_POINTER (decl)
	  && !GFC_DECL_GET_SCALAR_ALLOCATABLE (decl)
	  && !GFC_DECL_CRAY_POINTEE (decl)
	  && !GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
	return;
      tree orig_decl = decl;

      c4 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
      OMP_CLAUSE_SET_MAP_KIND (c4, GOMP_MAP_POINTER);
      OMP_CLAUSE_DECL (c4) = decl;
      OMP_CLAUSE_SIZE (c4) = size_int (0);
      decl = build_fold_indirect_ref (decl);
      if (present
	  && (GFC_DECL_GET_SCALAR_POINTER (orig_decl)
	      || GFC_DECL_GET_SCALAR_ALLOCATABLE (orig_decl)))
	{
	  c2 = build_omp_clause (input_location, OMP_CLAUSE_MAP);
	  OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_POINTER);
	  OMP_CLAUSE_DECL (c2) = decl;
	  OMP_CLAUSE_SIZE (c2) = size_int (0);

	  stmtblock_t block;
	  gfc_start_block (&block);
	  tree ptr = decl;
	  ptr = gfc_build_cond_assign_expr (&block, present, decl,
					    null_pointer_node);
	  gimplify_and_add (gfc_finish_block (&block), pre_p);
	  ptr = build_fold_indirect_ref (ptr);
	  OMP_CLAUSE_DECL (c) = ptr;
	  OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (ptr));
	}
      else
	{
	  OMP_CLAUSE_DECL (c) = decl;
	  OMP_CLAUSE_SIZE (c) = NULL_TREE;
	}
      if (TREE_CODE (TREE_TYPE (orig_decl)) == REFERENCE_TYPE
	  && (GFC_DECL_GET_SCALAR_POINTER (orig_decl)
	      || GFC_DECL_GET_SCALAR_ALLOCATABLE (orig_decl)))
	{
	  c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
	  OMP_CLAUSE_SET_MAP_KIND (c3, GOMP_MAP_POINTER);
	  OMP_CLAUSE_DECL (c3) = unshare_expr (decl);
	  OMP_CLAUSE_SIZE (c3) = size_int (0);
	  decl = build_fold_indirect_ref (decl);
	  OMP_CLAUSE_DECL (c) = decl;
	}
    }
  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
    {
      stmtblock_t block;
      gfc_start_block (&block);
      tree type = TREE_TYPE (decl);
      tree ptr = gfc_conv_descriptor_data_get (decl);

      /* OpenMP: automatically map pointer targets with the pointer;
	 hence, always update the descriptor/pointer itself.
	 NOTE: This also remaps the pointer for allocatable arrays with
	 'target' attribute which also don't have the 'restrict' qualifier.  */
      bool always_modifier = false;

      if (!openacc
	  && !(TYPE_QUALS (TREE_TYPE (ptr)) & TYPE_QUAL_RESTRICT))
	always_modifier = true;

      if (present)
	ptr = gfc_build_cond_assign_expr (&block, present, ptr,
					  null_pointer_node);
      ptr = fold_convert (build_pointer_type (char_type_node), ptr);
      ptr = build_fold_indirect_ref (ptr);
      OMP_CLAUSE_DECL (c) = ptr;
      c2 = build_omp_clause (input_location, OMP_CLAUSE_MAP);
      OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_TO_PSET);
      if (present)
	{
	  ptr = create_tmp_var (TREE_TYPE (TREE_OPERAND (decl, 0)));
	  gfc_add_modify (&block, ptr, TREE_OPERAND (decl, 0));

	  OMP_CLAUSE_DECL (c2) = build_fold_indirect_ref (ptr);
	}
      else
	OMP_CLAUSE_DECL (c2) = decl;
      OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (type);
      c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
      OMP_CLAUSE_SET_MAP_KIND (c3, always_modifier ? GOMP_MAP_ALWAYS_POINTER
						   : GOMP_MAP_POINTER);
      if (present)
	{
	  ptr = gfc_conv_descriptor_data_get (decl);
	  ptr = gfc_build_addr_expr (NULL, ptr);
	  ptr = gfc_build_cond_assign_expr (&block, present,
					    ptr, null_pointer_node);
	  ptr = build_fold_indirect_ref (ptr);
	  OMP_CLAUSE_DECL (c3) = ptr;
	}
      else
	OMP_CLAUSE_DECL (c3) = gfc_conv_descriptor_data_get (decl);
      OMP_CLAUSE_SIZE (c3) = size_int (0);
      tree size = create_tmp_var (gfc_array_index_type);
      tree elemsz = TYPE_SIZE_UNIT (gfc_get_element_type (type));
      elemsz = fold_convert (gfc_array_index_type, elemsz);
      if (GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_POINTER
	  || GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_POINTER_CONT)
	{
	  stmtblock_t cond_block;
	  tree tem, then_b, else_b, zero, cond;

	  gfc_init_block (&cond_block);
	  tem = gfc_full_array_size (&cond_block, decl,
				     GFC_TYPE_ARRAY_RANK (type));
	  gfc_add_modify (&cond_block, size, tem);
	  gfc_add_modify (&cond_block, size,
			  fold_build2 (MULT_EXPR, gfc_array_index_type,
				       size, elemsz));
	  then_b = gfc_finish_block (&cond_block);
	  gfc_init_block (&cond_block);
	  zero = build_int_cst (gfc_array_index_type, 0);
	  gfc_add_modify (&cond_block, size, zero);
	  else_b = gfc_finish_block (&cond_block);
	  tem = gfc_conv_descriptor_data_get (decl);
	  tem = fold_convert (pvoid_type_node, tem);
	  cond = fold_build2_loc (input_location, NE_EXPR,
				  boolean_type_node, tem, null_pointer_node);
	  if (present)
	    {
	      cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
				      boolean_type_node, present, cond);
	    }
	  gfc_add_expr_to_block (&block, build3_loc (input_location, COND_EXPR,
						     void_type_node, cond,
						     then_b, else_b));
	}
      else if (present)
	{
	  stmtblock_t cond_block;
	  tree then_b;

	  gfc_init_block (&cond_block);
	  gfc_add_modify (&cond_block, size,
			  gfc_full_array_size (&cond_block, decl,
					       GFC_TYPE_ARRAY_RANK (type)));
	  gfc_add_modify (&cond_block, size,
			  fold_build2 (MULT_EXPR, gfc_array_index_type,
				       size, elemsz));
	  then_b = gfc_finish_block (&cond_block);

	  gfc_build_cond_assign (&block, size, present, then_b,
				 build_int_cst (gfc_array_index_type, 0));
	}
      else
	{
	  gfc_add_modify (&block, size,
			  gfc_full_array_size (&block, decl,
					       GFC_TYPE_ARRAY_RANK (type)));
	  gfc_add_modify (&block, size,
			  fold_build2 (MULT_EXPR, gfc_array_index_type,
				       size, elemsz));
	}
      OMP_CLAUSE_SIZE (c) = size;
      tree stmt = gfc_finish_block (&block);
      gimplify_and_add (stmt, pre_p);
    }
  tree last = c;
  if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
    OMP_CLAUSE_SIZE (c)
      = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
		      : TYPE_SIZE_UNIT (TREE_TYPE (decl));
  if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
		     NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
    OMP_CLAUSE_SIZE (c) = size_int (0);
  if (c2)
    {
      OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (last);
      OMP_CLAUSE_CHAIN (last) = c2;
      last = c2;
    }
  if (c3)
    {
      OMP_CLAUSE_CHAIN (c3) = OMP_CLAUSE_CHAIN (last);
      OMP_CLAUSE_CHAIN (last) = c3;
      last = c3;
    }
  if (c4)
    {
      OMP_CLAUSE_CHAIN (c4) = OMP_CLAUSE_CHAIN (last);
      OMP_CLAUSE_CHAIN (last) = c4;
    }
}


/* Return true if DECL is a scalar variable (for the purpose of
   implicit firstprivatization/mapping). Only if 'ptr_alloc_ok.'
   is true, allocatables and pointers are permitted. */

bool
gfc_omp_scalar_p (tree decl, bool ptr_alloc_ok)
{
  tree type = TREE_TYPE (decl);
  if (TREE_CODE (type) == REFERENCE_TYPE)
    type = TREE_TYPE (type);
  if (TREE_CODE (type) == POINTER_TYPE)
    {
      if (GFC_DECL_GET_SCALAR_ALLOCATABLE (decl)
	  || GFC_DECL_GET_SCALAR_POINTER (decl))
	{
	  if (!ptr_alloc_ok)
	    return false;
	  type = TREE_TYPE (type);
	}
      if (GFC_ARRAY_TYPE_P (type)
	  || GFC_CLASS_TYPE_P (type))
	return false;
    }
  if ((TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == INTEGER_TYPE)
      && TYPE_STRING_FLAG (type))
    return false;
  if (INTEGRAL_TYPE_P (type)
      || SCALAR_FLOAT_TYPE_P (type)
      || COMPLEX_FLOAT_TYPE_P (type))
    return true;
  return false;
}


/* Return true if DECL is a scalar with target attribute but does not have the
   allocatable (or pointer) attribute (for the purpose of implicit mapping).  */

bool
gfc_omp_scalar_target_p (tree decl)
{
  return (DECL_P (decl) && GFC_DECL_GET_SCALAR_TARGET (decl)
	  && gfc_omp_scalar_p (decl, false));
}


/* Return true if DECL's DECL_VALUE_EXPR (if any) should be
   disregarded in OpenMP construct, because it is going to be
   remapped during OpenMP lowering.  SHARED is true if DECL
   is going to be shared, false if it is going to be privatized.  */

bool
gfc_omp_disregard_value_expr (tree decl, bool shared)
{
  if (GFC_DECL_COMMON_OR_EQUIV (decl)
      && DECL_HAS_VALUE_EXPR_P (decl))
    {
      tree value = DECL_VALUE_EXPR (decl);

      if (TREE_CODE (value) == COMPONENT_REF
	  && VAR_P (TREE_OPERAND (value, 0))
	  && GFC_DECL_COMMON_OR_EQUIV (TREE_OPERAND (value, 0)))
	{
	  /* If variable in COMMON or EQUIVALENCE is privatized, return
	     true, as just that variable is supposed to be privatized,
	     not the whole COMMON or whole EQUIVALENCE.
	     For shared variables in COMMON or EQUIVALENCE, let them be
	     gimplified to DECL_VALUE_EXPR, so that for multiple shared vars
	     from the same COMMON or EQUIVALENCE just one sharing of the
	     whole COMMON or EQUIVALENCE is enough.  */
	  return ! shared;
	}
    }

  if (GFC_DECL_RESULT (decl) && DECL_HAS_VALUE_EXPR_P (decl))
    return ! shared;

  return false;
}

/* Return true if DECL that is shared iff SHARED is true should
   be put into OMP_CLAUSE_PRIVATE with OMP_CLAUSE_PRIVATE_DEBUG
   flag set.  */

bool
gfc_omp_private_debug_clause (tree decl, bool shared)
{
  if (GFC_DECL_CRAY_POINTEE (decl))
    return true;

  if (GFC_DECL_COMMON_OR_EQUIV (decl)
      && DECL_HAS_VALUE_EXPR_P (decl))
    {
      tree value = DECL_VALUE_EXPR (decl);

      if (TREE_CODE (value) == COMPONENT_REF
	  && VAR_P (TREE_OPERAND (value, 0))
	  && GFC_DECL_COMMON_OR_EQUIV (TREE_OPERAND (value, 0)))
	return shared;
    }

  return false;
}

/* Register language specific type size variables as potentially OpenMP
   firstprivate variables.  */

void
gfc_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
{
  if (GFC_ARRAY_TYPE_P (type) || GFC_DESCRIPTOR_TYPE_P (type))
    {
      int r;

      gcc_assert (TYPE_LANG_SPECIFIC (type) != NULL);
      for (r = 0; r < GFC_TYPE_ARRAY_RANK (type); r++)
	{
	  omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_LBOUND (type, r));
	  omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_UBOUND (type, r));
	  omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_STRIDE (type, r));
	}
      omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_SIZE (type));
      omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_OFFSET (type));
    }
}


static inline tree
gfc_trans_add_clause (tree node, tree tail)
{
  OMP_CLAUSE_CHAIN (node) = tail;
  return node;
}

static tree
gfc_trans_omp_variable (gfc_symbol *sym, bool declare_simd)
{
  if (declare_simd)
    {
      int cnt = 0;
      gfc_symbol *proc_sym;
      gfc_formal_arglist *f;

      gcc_assert (sym->attr.dummy);
      proc_sym = sym->ns->proc_name;
      if (proc_sym->attr.entry_master)
	++cnt;
      if (gfc_return_by_reference (proc_sym))
	{
	  ++cnt;
	  if (proc_sym->ts.type == BT_CHARACTER)
	    ++cnt;
	}
      for (f = gfc_sym_get_dummy_args (proc_sym); f; f = f->next)
	if (f->sym == sym)
	  break;
	else if (f->sym)
	  ++cnt;
      gcc_assert (f);
      return build_int_cst (integer_type_node, cnt);
    }

  tree t = gfc_get_symbol_decl (sym);
  tree parent_decl;
  int parent_flag;
  bool return_value;
  bool alternate_entry;
  bool entry_master;

  return_value = sym->attr.function && sym->result == sym;
  alternate_entry = sym->attr.function && sym->attr.entry
		    && sym->result == sym;
  entry_master = sym->attr.result
		 && sym->ns->proc_name->attr.entry_master
		 && !gfc_return_by_reference (sym->ns->proc_name);
  parent_decl = current_function_decl
		? DECL_CONTEXT (current_function_decl) : NULL_TREE;

  if ((t == parent_decl && return_value)
       || (sym->ns && sym->ns->proc_name
	   && sym->ns->proc_name->backend_decl == parent_decl
	   && (alternate_entry || entry_master)))
    parent_flag = 1;
  else
    parent_flag = 0;

  /* Special case for assigning the return value of a function.
     Self recursive functions must have an explicit return value.  */
  if (return_value && (t == current_function_decl || parent_flag))
    t = gfc_get_fake_result_decl (sym, parent_flag);

  /* Similarly for alternate entry points.  */
  else if (alternate_entry
	   && (sym->ns->proc_name->backend_decl == current_function_decl
	       || parent_flag))
    {
      gfc_entry_list *el = NULL;

      for (el = sym->ns->entries; el; el = el->next)
	if (sym == el->sym)
	  {
	    t = gfc_get_fake_result_decl (sym, parent_flag);
	    break;
	  }
    }

  else if (entry_master
	   && (sym->ns->proc_name->backend_decl == current_function_decl
	       || parent_flag))
    t = gfc_get_fake_result_decl (sym, parent_flag);

  return t;
}

static tree
gfc_trans_omp_variable_list (enum omp_clause_code code,
			     gfc_omp_namelist *namelist, tree list,
			     bool declare_simd)
{
  for (; namelist != NULL; namelist = namelist->next)
    if (namelist->sym->attr.referenced || declare_simd)
      {
	tree t = gfc_trans_omp_variable (namelist->sym, declare_simd);
	if (t != error_mark_node)
	  {
	    tree node = build_omp_clause (input_location, code);
	    OMP_CLAUSE_DECL (node) = t;
	    list = gfc_trans_add_clause (node, list);

	    if (code == OMP_CLAUSE_LASTPRIVATE
		&& namelist->u.lastprivate_conditional)
	      OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (node) = 1;
	  }
      }
  return list;
}

struct omp_udr_find_orig_data
{
  gfc_omp_udr *omp_udr;
  bool omp_orig_seen;
};

static int
omp_udr_find_orig (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
		   void *data)
{
  struct omp_udr_find_orig_data *cd = (struct omp_udr_find_orig_data *) data;
  if ((*e)->expr_type == EXPR_VARIABLE
      && (*e)->symtree->n.sym == cd->omp_udr->omp_orig)
    cd->omp_orig_seen = true;

  return 0;
}

static void
gfc_trans_omp_array_reduction_or_udr (tree c, gfc_omp_namelist *n, locus where)
{
  gfc_symbol *sym = n->sym;
  gfc_symtree *root1 = NULL, *root2 = NULL, *root3 = NULL, *root4 = NULL;
  gfc_symtree *symtree1, *symtree2, *symtree3, *symtree4 = NULL;
  gfc_symbol init_val_sym, outer_sym, intrinsic_sym;
  gfc_symbol omp_var_copy[4];
  gfc_expr *e1, *e2, *e3, *e4;
  gfc_ref *ref;
  tree decl, backend_decl, stmt, type, outer_decl;
  locus old_loc = gfc_current_locus;
  const char *iname;
  bool t;
  gfc_omp_udr *udr = n->u2.udr ? n->u2.udr->udr : NULL;

  decl = OMP_CLAUSE_DECL (c);
  gfc_current_locus = where;
  type = TREE_TYPE (decl);
  outer_decl = create_tmp_var_raw (type);
  if (TREE_CODE (decl) == PARM_DECL
      && TREE_CODE (type) == REFERENCE_TYPE
      && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (type))
      && GFC_TYPE_ARRAY_AKIND (TREE_TYPE (type)) == GFC_ARRAY_ALLOCATABLE)
    {
      decl = build_fold_indirect_ref (decl);
      type = TREE_TYPE (type);
    }

  /* Create a fake symbol for init value.  */
  memset (&init_val_sym, 0, sizeof (init_val_sym));
  init_val_sym.ns = sym->ns;
  init_val_sym.name = sym->name;
  init_val_sym.ts = sym->ts;
  init_val_sym.attr.referenced = 1;
  init_val_sym.declared_at = where;
  init_val_sym.attr.flavor = FL_VARIABLE;
  if (OMP_CLAUSE_REDUCTION_CODE (c) != ERROR_MARK)
    backend_decl = omp_reduction_init (c, gfc_sym_type (&init_val_sym));
  else if (udr->initializer_ns)
    backend_decl = NULL;
  else
    switch (sym->ts.type)
      {
      case BT_LOGICAL:
      case BT_INTEGER:
      case BT_REAL:
      case BT_COMPLEX:
	backend_decl = build_zero_cst (gfc_sym_type (&init_val_sym));
	break;
      default:
	backend_decl = NULL_TREE;
	break;
      }
  init_val_sym.backend_decl = backend_decl;

  /* Create a fake symbol for the outer array reference.  */
  outer_sym = *sym;
  if (sym->as)
    outer_sym.as = gfc_copy_array_spec (sym->as);
  outer_sym.attr.dummy = 0;
  outer_sym.attr.result = 0;
  outer_sym.attr.flavor = FL_VARIABLE;
  outer_sym.backend_decl = outer_decl;
  if (decl != OMP_CLAUSE_DECL (c))
    outer_sym.backend_decl = build_fold_indirect_ref (outer_decl);

  /* Create fake symtrees for it.  */
  symtree1 = gfc_new_symtree (&root1, sym->name);
  symtree1->n.sym = sym;
  gcc_assert (symtree1 == root1);

  symtree2 = gfc_new_symtree (&root2, sym->name);
  symtree2->n.sym = &init_val_sym;
  gcc_assert (symtree2 == root2);

  symtree3 = gfc_new_symtree (&root3, sym->name);
  symtree3->n.sym = &outer_sym;
  gcc_assert (symtree3 == root3);

  memset (omp_var_copy, 0, sizeof omp_var_copy);
  if (udr)
    {
      omp_var_copy[0] = *udr->omp_out;
      omp_var_copy[1] = *udr->omp_in;
      *udr->omp_out = outer_sym;
      *udr->omp_in = *sym;
      if (udr->initializer_ns)
	{
	  omp_var_copy[2] = *udr->omp_priv;
	  omp_var_copy[3] = *udr->omp_orig;
	  *udr->omp_priv = *sym;
	  *udr->omp_orig = outer_sym;
	}
    }

  /* Create expressions.  */
  e1 = gfc_get_expr ();
  e1->expr_type = EXPR_VARIABLE;
  e1->where = where;
  e1->symtree = symtree1;
  e1->ts = sym->ts;
  if (sym->attr.dimension)
    {
      e1->ref = ref = gfc_get_ref ();
      ref->type = REF_ARRAY;
      ref->u.ar.where = where;
      ref->u.ar.as = sym->as;
      ref->u.ar.type = AR_FULL;
      ref->u.ar.dimen = 0;
    }
  t = gfc_resolve_expr (e1);
  gcc_assert (t);

  e2 = NULL;
  if (backend_decl != NULL_TREE)
    {
      e2 = gfc_get_expr ();
      e2->expr_type = EXPR_VARIABLE;
      e2->where = where;
      e2->symtree = symtree2;
      e2->ts = sym->ts;
      t = gfc_resolve_expr (e2);
      gcc_assert (t);
    }
  else if (udr->initializer_ns == NULL)
    {
      gcc_assert (sym->ts.type == BT_DERIVED);
      e2 = gfc_default_initializer (&sym->ts);
      gcc_assert (e2);
      t = gfc_resolve_expr (e2);
      gcc_assert (t);
    }
  else if (n->u2.udr->initializer->op == EXEC_ASSIGN)
    {
      e2 = gfc_copy_expr (n->u2.udr->initializer->expr2);
      t = gfc_resolve_expr (e2);
      gcc_assert (t);
    }
  if (udr && udr->initializer_ns)
    {
      struct omp_udr_find_orig_data cd;
      cd.omp_udr = udr;
      cd.omp_orig_seen = false;
      gfc_code_walker (&n->u2.udr->initializer,
		       gfc_dummy_code_callback, omp_udr_find_orig, &cd);
      if (cd.omp_orig_seen)
	OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c) = 1;
    }

  e3 = gfc_copy_expr (e1);
  e3->symtree = symtree3;
  t = gfc_resolve_expr (e3);
  gcc_assert (t);

  iname = NULL;
  e4 = NULL;
  switch (OMP_CLAUSE_REDUCTION_CODE (c))
    {
    case PLUS_EXPR:
    case MINUS_EXPR:
      e4 = gfc_add (e3, e1);
      break;
    case MULT_EXPR:
      e4 = gfc_multiply (e3, e1);
      break;
    case TRUTH_ANDIF_EXPR:
      e4 = gfc_and (e3, e1);
      break;
    case TRUTH_ORIF_EXPR:
      e4 = gfc_or (e3, e1);
      break;
    case EQ_EXPR:
      e4 = gfc_eqv (e3, e1);
      break;
    case NE_EXPR:
      e4 = gfc_neqv (e3, e1);
      break;
    case MIN_EXPR:
      iname = "min";
      break;
    case MAX_EXPR:
      iname = "max";
      break;
    case BIT_AND_EXPR:
      iname = "iand";
      break;
    case BIT_IOR_EXPR:
      iname = "ior";
      break;
    case BIT_XOR_EXPR:
      iname = "ieor";
      break;
    case ERROR_MARK:
      if (n->u2.udr->combiner->op == EXEC_ASSIGN)
	{
	  gfc_free_expr (e3);
	  e3 = gfc_copy_expr (n->u2.udr->combiner->expr1);
	  e4 = gfc_copy_expr (n->u2.udr->combiner->expr2);
	  t = gfc_resolve_expr (e3);
	  gcc_assert (t);
	  t = gfc_resolve_expr (e4);
	  gcc_assert (t);
	}
      break;
    default:
      gcc_unreachable ();
    }
  if (iname != NULL)
    {
      memset (&intrinsic_sym, 0, sizeof (intrinsic_sym));
      intrinsic_sym.ns = sym->ns;
      intrinsic_sym.name = iname;
      intrinsic_sym.ts = sym->ts;
      intrinsic_sym.attr.referenced = 1;
      intrinsic_sym.attr.intrinsic = 1;
      intrinsic_sym.attr.function = 1;
      intrinsic_sym.attr.implicit_type = 1;
      intrinsic_sym.result = &intrinsic_sym;
      intrinsic_sym.declared_at = where;

      symtree4 = gfc_new_symtree (&root4, iname);
      symtree4->n.sym = &intrinsic_sym;
      gcc_assert (symtree4 == root4);

      e4 = gfc_get_expr ();
      e4->expr_type = EXPR_FUNCTION;
      e4->where = where;
      e4->symtree = symtree4;
      e4->value.function.actual = gfc_get_actual_arglist ();
      e4->value.function.actual->expr = e3;
      e4->value.function.actual->next = gfc_get_actual_arglist ();
      e4->value.function.actual->next->expr = e1;
    }
  if (OMP_CLAUSE_REDUCTION_CODE (c) != ERROR_MARK)
    {
      /* e1 and e3 have been stored as arguments of e4, avoid sharing.  */
      e1 = gfc_copy_expr (e1);
      e3 = gfc_copy_expr (e3);
      t = gfc_resolve_expr (e4);
      gcc_assert (t);
    }

  /* Create the init statement list.  */
  pushlevel ();
  if (e2)
    stmt = gfc_trans_assignment (e1, e2, false, false);
  else
    stmt = gfc_trans_call (n->u2.udr->initializer, false,
			   NULL_TREE, NULL_TREE, false);
  if (TREE_CODE (stmt) != BIND_EXPR)
    stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
  else
    poplevel (0, 0);
  OMP_CLAUSE_REDUCTION_INIT (c) = stmt;

  /* Create the merge statement list.  */
  pushlevel ();
  if (e4)
    stmt = gfc_trans_assignment (e3, e4, false, true);
  else
    stmt = gfc_trans_call (n->u2.udr->combiner, false,
			   NULL_TREE, NULL_TREE, false);
  if (TREE_CODE (stmt) != BIND_EXPR)
    stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
  else
    poplevel (0, 0);
  OMP_CLAUSE_REDUCTION_MERGE (c) = stmt;

  /* And stick the placeholder VAR_DECL into the clause as well.  */
  OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = outer_decl;

  gfc_current_locus = old_loc;

  gfc_free_expr (e1);
  if (e2)
    gfc_free_expr (e2);
  gfc_free_expr (e3);
  if (e4)
    gfc_free_expr (e4);
  free (symtree1);
  free (symtree2);
  free (symtree3);
  free (symtree4);
  if (outer_sym.as)
    gfc_free_array_spec (outer_sym.as);

  if (udr)
    {
      *udr->omp_out = omp_var_copy[0];
      *udr->omp_in = omp_var_copy[1];
      if (udr->initializer_ns)
	{
	  *udr->omp_priv = omp_var_copy[2];
	  *udr->omp_orig = omp_var_copy[3];
	}
    }
}

static tree
gfc_trans_omp_reduction_list (int kind, gfc_omp_namelist *namelist, tree list,
			      locus where, bool mark_addressable)
{
  omp_clause_code clause = OMP_CLAUSE_REDUCTION;
  switch (kind)
    {
    case OMP_LIST_REDUCTION:
    case OMP_LIST_REDUCTION_INSCAN:
    case OMP_LIST_REDUCTION_TASK:
      break;
    case OMP_LIST_IN_REDUCTION:
      clause = OMP_CLAUSE_IN_REDUCTION;
      break;
    case OMP_LIST_TASK_REDUCTION:
      clause = OMP_CLAUSE_TASK_REDUCTION;
      break;
    default:
      gcc_unreachable ();
    }
  for (; namelist != NULL; namelist = namelist->next)
    if (namelist->sym->attr.referenced)
      {
	tree t = gfc_trans_omp_variable (namelist->sym, false);
	if (t != error_mark_node)
	  {
	    tree node = build_omp_clause (gfc_get_location (&namelist->where),
					  clause);
	    OMP_CLAUSE_DECL (node) = t;
	    if (mark_addressable)
	      TREE_ADDRESSABLE (t) = 1;
	    if (kind == OMP_LIST_REDUCTION_INSCAN)
	      OMP_CLAUSE_REDUCTION_INSCAN (node) = 1;
	    if (kind == OMP_LIST_REDUCTION_TASK)
	      OMP_CLAUSE_REDUCTION_TASK (node) = 1;
	    switch (namelist->u.reduction_op)
	      {
	      case OMP_REDUCTION_PLUS:
		OMP_CLAUSE_REDUCTION_CODE (node) = PLUS_EXPR;
		break;
	      case OMP_REDUCTION_MINUS:
		OMP_CLAUSE_REDUCTION_CODE (node) = MINUS_EXPR;
		break;
	      case OMP_REDUCTION_TIMES:
		OMP_CLAUSE_REDUCTION_CODE (node) = MULT_EXPR;
		break;
	      case OMP_REDUCTION_AND:
		OMP_CLAUSE_REDUCTION_CODE (node) = TRUTH_ANDIF_EXPR;
		break;
	      case OMP_REDUCTION_OR:
		OMP_CLAUSE_REDUCTION_CODE (node) = TRUTH_ORIF_EXPR;
		break;
	      case OMP_REDUCTION_EQV:
		OMP_CLAUSE_REDUCTION_CODE (node) = EQ_EXPR;
		break;
	      case OMP_REDUCTION_NEQV:
		OMP_CLAUSE_REDUCTION_CODE (node) = NE_EXPR;
		break;
	      case OMP_REDUCTION_MAX:
		OMP_CLAUSE_REDUCTION_CODE (node) = MAX_EXPR;
		break;
	      case OMP_REDUCTION_MIN:
		OMP_CLAUSE_REDUCTION_CODE (node) = MIN_EXPR;
		break;
 	      case OMP_REDUCTION_IAND:
		OMP_CLAUSE_REDUCTION_CODE (node) = BIT_AND_EXPR;
		break;
 	      case OMP_REDUCTION_IOR:
		OMP_CLAUSE_REDUCTION_CODE (node) = BIT_IOR_EXPR;
		break;
 	      case OMP_REDUCTION_IEOR:
		OMP_CLAUSE_REDUCTION_CODE (node) = BIT_XOR_EXPR;
		break;
	      case OMP_REDUCTION_USER:
		OMP_CLAUSE_REDUCTION_CODE (node) = ERROR_MARK;
		break;
	      default:
		gcc_unreachable ();
	      }
	    if (namelist->sym->attr.dimension
		|| namelist->u.reduction_op == OMP_REDUCTION_USER
		|| namelist->sym->attr.allocatable)
	      gfc_trans_omp_array_reduction_or_udr (node, namelist, where);
	    list = gfc_trans_add_clause (node, list);
	  }
      }
  return list;
}

static inline tree
gfc_convert_expr_to_tree (stmtblock_t *block, gfc_expr *expr)
{
  gfc_se se;
  tree result;

  gfc_init_se (&se, NULL );
  gfc_conv_expr (&se, expr);
  gfc_add_block_to_block (block, &se.pre);
  result = gfc_evaluate_now (se.expr, block);
  gfc_add_block_to_block (block, &se.post);

  return result;
}

static vec<tree, va_heap, vl_embed> *doacross_steps;


/* Translate an array section or array element.  */

static void
gfc_trans_omp_array_section (stmtblock_t *block, gfc_omp_namelist *n,
			     tree decl, bool element, gomp_map_kind ptr_kind,
			     tree &node, tree &node2, tree &node3, tree &node4)
{
  gfc_se se;
  tree ptr, ptr2;
  tree elemsz = NULL_TREE;

  gfc_init_se (&se, NULL);

  if (element)
    {
      gfc_conv_expr_reference (&se, n->expr);
      gfc_add_block_to_block (block, &se.pre);
      ptr = se.expr;
      OMP_CLAUSE_SIZE (node) = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ptr)));
      elemsz = OMP_CLAUSE_SIZE (node);
    }
  else
    {
      gfc_conv_expr_descriptor (&se, n->expr);
      ptr = gfc_conv_array_data (se.expr);
      tree type = TREE_TYPE (se.expr);
      gfc_add_block_to_block (block, &se.pre);
      OMP_CLAUSE_SIZE (node) = gfc_full_array_size (block, se.expr,
						    GFC_TYPE_ARRAY_RANK (type));
      elemsz = TYPE_SIZE_UNIT (gfc_get_element_type (type));
      elemsz = fold_convert (gfc_array_index_type, elemsz);
      OMP_CLAUSE_SIZE (node) = fold_build2 (MULT_EXPR, gfc_array_index_type,
					    OMP_CLAUSE_SIZE (node), elemsz);
    }
  gcc_assert (se.post.head == NULL_TREE);
  ptr = fold_convert (build_pointer_type (char_type_node), ptr);
  OMP_CLAUSE_DECL (node) = build_fold_indirect_ref (ptr);
  ptr = fold_convert (ptrdiff_type_node, ptr);

  if (POINTER_TYPE_P (TREE_TYPE (decl))
      && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (decl)))
      && ptr_kind == GOMP_MAP_POINTER)
    {
      node4 = build_omp_clause (input_location,
				OMP_CLAUSE_MAP);
      OMP_CLAUSE_SET_MAP_KIND (node4, GOMP_MAP_POINTER);
      OMP_CLAUSE_DECL (node4) = decl;
      OMP_CLAUSE_SIZE (node4) = size_int (0);
      decl = build_fold_indirect_ref (decl);
    }
  else if (ptr_kind == GOMP_MAP_ALWAYS_POINTER
	   && n->expr->ts.type == BT_CHARACTER
	   && n->expr->ts.deferred)
    {
      gomp_map_kind map_kind;
      if (GOMP_MAP_COPY_TO_P (OMP_CLAUSE_MAP_KIND (node)))
	map_kind = GOMP_MAP_TO;
      else if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_RELEASE
	       || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_DELETE)
	map_kind = OMP_CLAUSE_MAP_KIND (node);
      else
	map_kind = GOMP_MAP_ALLOC;
      gcc_assert (se.string_length);
      node4 = build_omp_clause (input_location, OMP_CLAUSE_MAP);
      OMP_CLAUSE_SET_MAP_KIND (node4, map_kind);
      OMP_CLAUSE_DECL (node4) = se.string_length;
      OMP_CLAUSE_SIZE (node4) = TYPE_SIZE_UNIT (gfc_charlen_type_node);
    }
  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
    {
      tree desc_node;
      tree type = TREE_TYPE (decl);
      ptr2 = gfc_conv_descriptor_data_get (decl);
      desc_node = build_omp_clause (input_location, OMP_CLAUSE_MAP);
      OMP_CLAUSE_DECL (desc_node) = decl;
      OMP_CLAUSE_SIZE (desc_node) = TYPE_SIZE_UNIT (type);
      if (ptr_kind == GOMP_MAP_ALWAYS_POINTER)
	{
	  OMP_CLAUSE_SET_MAP_KIND (desc_node, GOMP_MAP_TO);
	  node2 = node;
	  node = desc_node;  /* Needs to come first.  */
	}
      else
	{
	  OMP_CLAUSE_SET_MAP_KIND (desc_node, GOMP_MAP_TO_PSET);
	  node2 = desc_node;
	}
      node3 = build_omp_clause (input_location,
				OMP_CLAUSE_MAP);
      OMP_CLAUSE_SET_MAP_KIND (node3, ptr_kind);
      OMP_CLAUSE_DECL (node3)
	= gfc_conv_descriptor_data_get (decl);
      /* This purposely does not include GOMP_MAP_ALWAYS_POINTER.  The extra
	 cast prevents gimplify.c from recognising it as being part of the
	 struct – and adding an 'alloc: for the 'desc.data' pointer, which
	 would break as the 'desc' (the descriptor) is also mapped
	 (see node4 above).  */
      if (ptr_kind == GOMP_MAP_ATTACH_DETACH)
	STRIP_NOPS (OMP_CLAUSE_DECL (node3));
    }
  else
    {
      if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
	{
	  tree offset;
	  ptr2 = build_fold_addr_expr (decl);
	  offset = fold_build2 (MINUS_EXPR, ptrdiff_type_node, ptr,
				fold_convert (ptrdiff_type_node, ptr2));
	  offset = build2 (TRUNC_DIV_EXPR, ptrdiff_type_node,
			   offset, fold_convert (ptrdiff_type_node, elemsz));
	  offset = build4_loc (input_location, ARRAY_REF,
			       TREE_TYPE (TREE_TYPE (decl)),
			       decl, offset, NULL_TREE, NULL_TREE);
	  OMP_CLAUSE_DECL (node) = offset;
	}
      else
	{
	  gcc_assert (POINTER_TYPE_P (TREE_TYPE (decl)));
	  ptr2 = decl;
	}
      node3 = build_omp_clause (input_location,
				OMP_CLAUSE_MAP);
      OMP_CLAUSE_SET_MAP_KIND (node3, ptr_kind);
      OMP_CLAUSE_DECL (node3) = decl;
    }
  ptr2 = fold_convert (ptrdiff_type_node, ptr2);
  OMP_CLAUSE_SIZE (node3) = fold_build2 (MINUS_EXPR, ptrdiff_type_node,
					 ptr, ptr2);
}

static tree
handle_iterator (gfc_namespace *ns, stmtblock_t *iter_block, tree block)
{
  tree list = NULL_TREE;
  for (gfc_symbol *sym = ns->proc_name; sym; sym = sym->tlink)
    {
      gfc_constructor *c;
      gfc_se se;

      tree last = make_tree_vec (6);
      tree iter_var = gfc_get_symbol_decl (sym);
      tree type = TREE_TYPE (iter_var);
      TREE_VEC_ELT (last, 0) = iter_var;
      DECL_CHAIN (iter_var) = BLOCK_VARS (block);
      BLOCK_VARS (block) = iter_var;

      /* begin */
      c = gfc_constructor_first (sym->value->value.constructor);
      gfc_init_se (&se, NULL);
      gfc_conv_expr (&se, c->expr);
      gfc_add_block_to_block (iter_block, &se.pre);
      gfc_add_block_to_block (iter_block, &se.post);
      TREE_VEC_ELT (last, 1) = fold_convert (type,
					     gfc_evaluate_now (se.expr,
							       iter_block));
      /* end */
      c = gfc_constructor_next (c);
      gfc_init_se (&se, NULL);
      gfc_conv_expr (&se, c->expr);
      gfc_add_block_to_block (iter_block, &se.pre);
      gfc_add_block_to_block (iter_block, &se.post);
      TREE_VEC_ELT (last, 2) = fold_convert (type,
					     gfc_evaluate_now (se.expr,
							       iter_block));
      /* step */
      c = gfc_constructor_next (c);
      tree step;
      if (c)
	{
	  gfc_init_se (&se, NULL);
	  gfc_conv_expr (&se, c->expr);
	  gfc_add_block_to_block (iter_block, &se.pre);
	  gfc_add_block_to_block (iter_block, &se.post);
	  gfc_conv_expr (&se, c->expr);
	  step = fold_convert (type,
			       gfc_evaluate_now (se.expr,
						 iter_block));
	}
      else
	step = build_int_cst (type, 1);
      TREE_VEC_ELT (last, 3) = step;
      /* orig_step */
      TREE_VEC_ELT (last, 4) = save_expr (step);
      TREE_CHAIN (last) = list;
      list = last;
    }
  return list;
}

static tree
gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
		       locus where, bool declare_simd = false,
		       bool openacc = false)
{
  tree omp_clauses = NULL_TREE, prev_clauses, chunk_size, c;
  tree iterator = NULL_TREE;
  tree tree_block = NULL_TREE;
  stmtblock_t iter_block;
  int list, ifc;
  enum omp_clause_code clause_code;
  gfc_omp_namelist *prev = NULL;
  gfc_se se;

  if (clauses == NULL)
    return NULL_TREE;

  for (list = 0; list < OMP_LIST_NUM; list++)
    {
      gfc_omp_namelist *n = clauses->lists[list];

      if (n == NULL)
	continue;
      switch (list)
	{
	case OMP_LIST_REDUCTION:
	case OMP_LIST_REDUCTION_INSCAN:
	case OMP_LIST_REDUCTION_TASK:
	case OMP_LIST_IN_REDUCTION:
	case OMP_LIST_TASK_REDUCTION:
	  /* An OpenACC async clause indicates the need to set reduction
	     arguments addressable, to allow asynchronous copy-out.  */
	  omp_clauses = gfc_trans_omp_reduction_list (list, n, omp_clauses,
						      where, clauses->async);
	  break;
	case OMP_LIST_PRIVATE:
	  clause_code = OMP_CLAUSE_PRIVATE;
	  goto add_clause;
	case OMP_LIST_SHARED:
	  clause_code = OMP_CLAUSE_SHARED;
	  goto add_clause;
	case OMP_LIST_FIRSTPRIVATE:
	  clause_code = OMP_CLAUSE_FIRSTPRIVATE;
	  goto add_clause;
	case OMP_LIST_LASTPRIVATE:
	  clause_code = OMP_CLAUSE_LASTPRIVATE;
	  goto add_clause;
	case OMP_LIST_COPYIN:
	  clause_code = OMP_CLAUSE_COPYIN;
	  goto add_clause;
	case OMP_LIST_COPYPRIVATE:
	  clause_code = OMP_CLAUSE_COPYPRIVATE;
	  goto add_clause;
	case OMP_LIST_UNIFORM:
	  clause_code = OMP_CLAUSE_UNIFORM;
	  goto add_clause;
	case OMP_LIST_USE_DEVICE:
	case OMP_LIST_USE_DEVICE_PTR:
	  clause_code = OMP_CLAUSE_USE_DEVICE_PTR;
	  goto add_clause;
	case OMP_LIST_USE_DEVICE_ADDR:
	  clause_code = OMP_CLAUSE_USE_DEVICE_ADDR;
	  goto add_clause;
	case OMP_LIST_IS_DEVICE_PTR:
	  clause_code = OMP_CLAUSE_IS_DEVICE_PTR;
	  goto add_clause;
	case OMP_LIST_NONTEMPORAL:
	  clause_code = OMP_CLAUSE_NONTEMPORAL;
	  goto add_clause;
	case OMP_LIST_SCAN_IN:
	  clause_code = OMP_CLAUSE_INCLUSIVE;
	  goto add_clause;
	case OMP_LIST_SCAN_EX:
	  clause_code = OMP_CLAUSE_EXCLUSIVE;
	  goto add_clause;

	add_clause:
	  omp_clauses
	    = gfc_trans_omp_variable_list (clause_code, n, omp_clauses,
					   declare_simd);
	  break;
	case OMP_LIST_ALIGNED:
	  for (; n != NULL; n = n->next)
	    if (n->sym->attr.referenced || declare_simd)
	      {
		tree t = gfc_trans_omp_variable (n->sym, declare_simd);
		if (t != error_mark_node)
		  {
		    tree node = build_omp_clause (input_location,
						  OMP_CLAUSE_ALIGNED);
		    OMP_CLAUSE_DECL (node) = t;
		    if (n->expr)
		      {
			tree alignment_var;

			if (declare_simd)
			  alignment_var = gfc_conv_constant_to_tree (n->expr);
			else
			  {
			    gfc_init_se (&se, NULL);
			    gfc_conv_expr (&se, n->expr);
			    gfc_add_block_to_block (block, &se.pre);
			    alignment_var = gfc_evaluate_now (se.expr, block);
			    gfc_add_block_to_block (block, &se.post);
			  }
			OMP_CLAUSE_ALIGNED_ALIGNMENT (node) = alignment_var;
		      }
		    omp_clauses = gfc_trans_add_clause (node, omp_clauses);
		  }
	      }
	  break;
	case OMP_LIST_LINEAR:
	  {
	    gfc_expr *last_step_expr = NULL;
	    tree last_step = NULL_TREE;
	    bool last_step_parm = false;

	    for (; n != NULL; n = n->next)
	      {
		if (n->expr)
		  {
		    last_step_expr = n->expr;
		    last_step = NULL_TREE;
		    last_step_parm = false;
		  }
		if (n->sym->attr.referenced || declare_simd)
		  {
		    tree t = gfc_trans_omp_variable (n->sym, declare_simd);
		    if (t != error_mark_node)
		      {
			tree node = build_omp_clause (input_location,
						      OMP_CLAUSE_LINEAR);
			OMP_CLAUSE_DECL (node) = t;
			omp_clause_linear_kind kind;
			switch (n->u.linear_op)
			  {
			  case OMP_LINEAR_DEFAULT:
			    kind = OMP_CLAUSE_LINEAR_DEFAULT;
			    break;
			  case OMP_LINEAR_REF:
			    kind = OMP_CLAUSE_LINEAR_REF;
			    break;
			  case OMP_LINEAR_VAL:
			    kind = OMP_CLAUSE_LINEAR_VAL;
			    break;
			  case OMP_LINEAR_UVAL:
			    kind = OMP_CLAUSE_LINEAR_UVAL;
			    break;
			  default:
			    gcc_unreachable ();
			  }
			OMP_CLAUSE_LINEAR_KIND (node) = kind;
			if (last_step_expr && last_step == NULL_TREE)
			  {
			    if (!declare_simd)
			      {
				gfc_init_se (&se, NULL);
				gfc_conv_expr (&se, last_step_expr);
				gfc_add_block_to_block (block, &se.pre);
				last_step = gfc_evaluate_now (se.expr, block);
				gfc_add_block_to_block (block, &se.post);
			      }
			    else if (last_step_expr->expr_type == EXPR_VARIABLE)
			      {
				gfc_symbol *s = last_step_expr->symtree->n.sym;
				last_step = gfc_trans_omp_variable (s, true);
				last_step_parm = true;
			      }
			    else
			      last_step
				= gfc_conv_constant_to_tree (last_step_expr);
			  }
			if (last_step_parm)
			  {
			    OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (node) = 1;
			    OMP_CLAUSE_LINEAR_STEP (node) = last_step;
			  }
			else
			  {
			    if (kind == OMP_CLAUSE_LINEAR_REF)
			      {
				tree type;
				if (n->sym->attr.flavor == FL_PROCEDURE)
				  {
				    type = gfc_get_function_type (n->sym);
				    type = build_pointer_type (type);
				  }
				else
				  type = gfc_sym_type (n->sym);
				if (POINTER_TYPE_P (type))
				  type = TREE_TYPE (type);
				/* Otherwise to be determined what exactly
				   should be done.  */
				tree t = fold_convert (sizetype, last_step);
				t = size_binop (MULT_EXPR, t,
						TYPE_SIZE_UNIT (type));
				OMP_CLAUSE_LINEAR_STEP (node) = t;
			      }
			    else
			      {
				tree type
				  = gfc_typenode_for_spec (&n->sym->ts);
				OMP_CLAUSE_LINEAR_STEP (node)
				  = fold_convert (type, last_step);
			      }
			  }
			if (n->sym->attr.dimension || n->sym->attr.allocatable)
			  OMP_CLAUSE_LINEAR_ARRAY (node) = 1;
			omp_clauses = gfc_trans_add_clause (node, omp_clauses);
		      }
		  }
	      }
	  }
	  break;
	case OMP_LIST_AFFINITY:
	case OMP_LIST_DEPEND:
	  iterator = NULL_TREE;
	  prev = NULL;
	  prev_clauses = omp_clauses;
	  for (; n != NULL; n = n->next)
	    {
	      if (iterator && prev->u2.ns != n->u2.ns)
		{ 
		  BLOCK_SUBBLOCKS (tree_block) = gfc_finish_block (&iter_block);
		  TREE_VEC_ELT (iterator, 5) = tree_block;
		  for (tree c = omp_clauses; c != prev_clauses;
		       c = OMP_CLAUSE_CHAIN (c))
		    OMP_CLAUSE_DECL (c) = build_tree_list (iterator,
							   OMP_CLAUSE_DECL (c));
		  prev_clauses = omp_clauses;
		  iterator = NULL_TREE;
		}
	      if (n->u2.ns && (!prev || prev->u2.ns != n->u2.ns))
		{
		  gfc_init_block (&iter_block);
		  tree_block = make_node (BLOCK);
		  TREE_USED (tree_block) = 1;
		  BLOCK_VARS (tree_block) = NULL_TREE;
		  iterator = handle_iterator (n->u2.ns, block,
					      tree_block);
		}
	      if (!iterator)
		gfc_init_block (&iter_block);
	      prev = n;
	      if (list == OMP_LIST_DEPEND
		  && n->u.depend_op == OMP_DEPEND_SINK_FIRST)
		{
		  tree vec = NULL_TREE;
		  unsigned int i;
		  for (i = 0; ; i++)
		    {
		      tree addend = integer_zero_node, t;
		      bool neg = false;
		      if (n->expr)
			{
			  addend = gfc_conv_constant_to_tree (n->expr);
			  if (TREE_CODE (addend) == INTEGER_CST
			      && tree_int_cst_sgn (addend) == -1)
			    {
			      neg = true;
			      addend = const_unop (NEGATE_EXPR,
						   TREE_TYPE (addend), addend);
			    }
			}
		      t = gfc_trans_omp_variable (n->sym, false);
		      if (t != error_mark_node)
			{
			  if (i < vec_safe_length (doacross_steps)
			      && !integer_zerop (addend)
			      && (*doacross_steps)[i])
			    {
			      tree step = (*doacross_steps)[i];
			      addend = fold_convert (TREE_TYPE (step), addend);
			      addend = build2 (TRUNC_DIV_EXPR,
					       TREE_TYPE (step), addend, step);
			    }
			  vec = tree_cons (addend, t, vec);
			  if (neg)
			    OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1;
			}
		      if (n->next == NULL
			  || n->next->u.depend_op != OMP_DEPEND_SINK)
			break;
		      n = n->next;
		    }
		  if (vec == NULL_TREE)
		    continue;

		  tree node = build_omp_clause (input_location,
						OMP_CLAUSE_DEPEND);
		  OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_SINK;
		  OMP_CLAUSE_DECL (node) = nreverse (vec);
		  omp_clauses = gfc_trans_add_clause (node, omp_clauses);
		  continue;
		}

	      if (!n->sym->attr.referenced)
		continue;

	      tree node = build_omp_clause (input_location,
					    list == OMP_LIST_DEPEND
					    ? OMP_CLAUSE_DEPEND
					    : OMP_CLAUSE_AFFINITY);
	      if (n->expr == NULL || n->expr->ref->u.ar.type == AR_FULL)
		{
		  tree decl = gfc_trans_omp_variable (n->sym, false);
		  if (gfc_omp_privatize_by_reference (decl))
		    decl = build_fold_indirect_ref (decl);
		  if (n->u.depend_op == OMP_DEPEND_DEPOBJ
		      && POINTER_TYPE_P (TREE_TYPE (decl)))
		    decl = build_fold_indirect_ref (decl);
		  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
		    {
		      decl = gfc_conv_descriptor_data_get (decl);
		      decl = fold_convert (build_pointer_type (char_type_node),
					   decl);
		      decl = build_fold_indirect_ref (decl);
		    }
		  else if (DECL_P (decl))
		    TREE_ADDRESSABLE (decl) = 1;
		  OMP_CLAUSE_DECL (node) = decl;
		}
	      else
		{
		  tree ptr;
		  gfc_init_se (&se, NULL);
		  if (n->expr->ref->u.ar.type == AR_ELEMENT)
		    {
		      gfc_conv_expr_reference (&se, n->expr);
		      ptr = se.expr;
		    }
		  else
		    {
		      gfc_conv_expr_descriptor (&se, n->expr);
		      ptr = gfc_conv_array_data (se.expr);
		    }
		  gfc_add_block_to_block (&iter_block, &se.pre);
		  gfc_add_block_to_block (&iter_block, &se.post);
		  ptr = fold_convert (build_pointer_type (char_type_node),
				      ptr);
		  OMP_CLAUSE_DECL (node) = build_fold_indirect_ref (ptr);
		}
	      if (list == OMP_LIST_DEPEND)
		switch (n->u.depend_op)
		  {
		  case OMP_DEPEND_IN:
		    OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_IN;
		    break;
		  case OMP_DEPEND_OUT:
		    OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_OUT;
		    break;
		  case OMP_DEPEND_INOUT:
		    OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_INOUT;
		    break;
		  case OMP_DEPEND_MUTEXINOUTSET:
		    OMP_CLAUSE_DEPEND_KIND (node)
		      = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
		    break;
		  case OMP_DEPEND_DEPOBJ:
		    OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_DEPOBJ;
		    break;
		  default:
		    gcc_unreachable ();
		  }
	      if (!iterator)
		gfc_add_block_to_block (block, &iter_block);
	      omp_clauses = gfc_trans_add_clause (node, omp_clauses);
	    }
	  if (iterator)
	    { 
	      BLOCK_SUBBLOCKS (tree_block) = gfc_finish_block (&iter_block);
	      TREE_VEC_ELT (iterator, 5) = tree_block;
	      for (tree c = omp_clauses; c != prev_clauses;
		   c = OMP_CLAUSE_CHAIN (c))
		OMP_CLAUSE_DECL (c) = build_tree_list (iterator,
						       OMP_CLAUSE_DECL (c));
	    }
	  break;
	case OMP_LIST_MAP:
	  for (; n != NULL; n = n->next)
	    {
	      if (!n->sym->attr.referenced)
		continue;

	      bool always_modifier = false;
	      tree node = build_omp_clause (input_location, OMP_CLAUSE_MAP);
	      tree node2 = NULL_TREE;
	      tree node3 = NULL_TREE;
	      tree node4 = NULL_TREE;

	      /* OpenMP: automatically map pointer targets with the pointer;
		 hence, always update the descriptor/pointer itself.  */
	      if (!openacc
		  && ((n->expr == NULL && n->sym->attr.pointer)
		      || (n->expr && gfc_expr_attr (n->expr).pointer)))
		always_modifier = true;

	      switch (n->u.map_op)
		{
		case OMP_MAP_ALLOC:
		  OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_ALLOC);
		  break;
		case OMP_MAP_IF_PRESENT:
		  OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_IF_PRESENT);
		  break;
		case OMP_MAP_ATTACH:
		  OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_ATTACH);
		  break;
		case OMP_MAP_TO:
		  OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_TO);
		  break;
		case OMP_MAP_FROM:
		  OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FROM);
		  break;
		case OMP_MAP_TOFROM:
		  OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_TOFROM);
		  break;
		case OMP_MAP_ALWAYS_TO:
		  always_modifier = true;
		  OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_ALWAYS_TO);
		  break;
		case OMP_MAP_ALWAYS_FROM:
		  always_modifier = true;
		  OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_ALWAYS_FROM);
		  break;
		case OMP_MAP_ALWAYS_TOFROM:
		  always_modifier = true;
		  OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_ALWAYS_TOFROM);
		  break;
		case OMP_MAP_RELEASE:
		  OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_RELEASE);
		  break;
		case OMP_MAP_DELETE:
		  OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_DELETE);
		  break;
		case OMP_MAP_DETACH:
		  OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_DETACH);
		  break;
		case OMP_MAP_FORCE_ALLOC:
		  OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FORCE_ALLOC);
		  break;
		case OMP_MAP_FORCE_TO:
		  OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FORCE_TO);
		  break;
		case OMP_MAP_FORCE_FROM:
		  OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FORCE_FROM);
		  break;
		case OMP_MAP_FORCE_TOFROM:
		  OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FORCE_TOFROM);
		  break;
		case OMP_MAP_FORCE_PRESENT:
		  OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FORCE_PRESENT);
		  break;
		case OMP_MAP_FORCE_DEVICEPTR:
		  OMP_CLAUSE_SET_MAP_KIND (node, GOMP_MAP_FORCE_DEVICEPTR);
		  break;
		default:
		  gcc_unreachable ();
		}

	      tree decl = gfc_trans_omp_variable (n->sym, false);
	      if (DECL_P (decl))
		TREE_ADDRESSABLE (decl) = 1;

	      gfc_ref *lastref = NULL;

	      if (n->expr)
		for (gfc_ref *ref = n->expr->ref; ref; ref = ref->next)
		  if (ref->type == REF_COMPONENT || ref->type == REF_ARRAY)
		    lastref = ref;

	      bool allocatable = false, pointer = false;

	      if (lastref && lastref->type == REF_COMPONENT)
		{
		  gfc_component *c = lastref->u.c.component;

		  if (c->ts.type == BT_CLASS)
		    {
		      pointer = CLASS_DATA (c)->attr.class_pointer;
		      allocatable = CLASS_DATA (c)->attr.allocatable;
		    }
		  else
		    {
		      pointer = c->attr.pointer;
		      allocatable = c->attr.allocatable;
		    }
		}

	      if (n->expr == NULL
		  || (n->expr->ref->type == REF_ARRAY
		      && n->expr->ref->u.ar.type == AR_FULL))
		{
		  tree present = gfc_omp_check_optional_argument (decl, true);
		  if (openacc && n->sym->ts.type == BT_CLASS)
		    {
		      tree type = TREE_TYPE (decl);
		      if (n->sym->attr.optional)
			sorry ("optional class parameter");
		      if (POINTER_TYPE_P (type))
			{
			  node4 = build_omp_clause (input_location,
						    OMP_CLAUSE_MAP);
			  OMP_CLAUSE_SET_MAP_KIND (node4, GOMP_MAP_POINTER);
			  OMP_CLAUSE_DECL (node4) = decl;
			  OMP_CLAUSE_SIZE (node4) = size_int (0);
			  decl = build_fold_indirect_ref (decl);
			}
		      tree ptr = gfc_class_data_get (decl);
		      ptr = build_fold_indirect_ref (ptr);
		      OMP_CLAUSE_DECL (node) = ptr;
		      OMP_CLAUSE_SIZE (node) = gfc_class_vtab_size_get (decl);
		      node2 = build_omp_clause (input_location, OMP_CLAUSE_MAP);
		      OMP_CLAUSE_SET_MAP_KIND (node2, GOMP_MAP_TO_PSET);
		      OMP_CLAUSE_DECL (node2) = decl;
		      OMP_CLAUSE_SIZE (node2) = TYPE_SIZE_UNIT (type);
		      node3 = build_omp_clause (input_location, OMP_CLAUSE_MAP);
		      OMP_CLAUSE_SET_MAP_KIND (node3, GOMP_MAP_ATTACH_DETACH);
		      OMP_CLAUSE_DECL (node3) = gfc_class_data_get (decl);
		      OMP_CLAUSE_SIZE (node3) = size_int (0);
		      goto finalize_map_clause;
		    }
		  else if (POINTER_TYPE_P (TREE_TYPE (decl))
			   && (gfc_omp_privatize_by_reference (decl)
			       || GFC_DECL_GET_SCALAR_POINTER (decl)
			       || GFC_DECL_GET_SCALAR_ALLOCATABLE (decl)
			       || GFC_DECL_CRAY_POINTEE (decl)
			       || GFC_DESCRIPTOR_TYPE_P
					     (TREE_TYPE (TREE_TYPE (decl)))
			       || n->sym->ts.type == BT_DERIVED))
		    {
		      tree orig_decl = decl;

		      /* For nonallocatable, nonpointer arrays, a temporary
			 variable is generated, but this one is only defined if
			 the variable is present; hence, we now set it to NULL
			 to avoid accessing undefined variables.  We cannot use
			 a temporary variable here as otherwise the replacement
			 of the variables in omp-low.c will not work.  */
		      if (present && GFC_ARRAY_TYPE_P (TREE_TYPE (decl)))
			{
			  tree tmp = fold_build2_loc (input_location,
						      MODIFY_EXPR,
						      void_type_node, decl,
						      null_pointer_node);
			  tree cond = fold_build1_loc (input_location,
						       TRUTH_NOT_EXPR,
						       boolean_type_node,
						       present);
			  gfc_add_expr_to_block (block,
						 build3_loc (input_location,
							     COND_EXPR,
							     void_type_node,
							     cond, tmp,
							     NULL_TREE));
			}
		      node4 = build_omp_clause (input_location,
						OMP_CLAUSE_MAP);
		      OMP_CLAUSE_SET_MAP_KIND (node4, GOMP_MAP_POINTER);
		      OMP_CLAUSE_DECL (node4) = decl;
		      OMP_CLAUSE_SIZE (node4) = size_int (0);
		      decl = build_fold_indirect_ref (decl);
		      if ((TREE_CODE (TREE_TYPE (orig_decl)) == REFERENCE_TYPE
			   || gfc_omp_is_optional_argument (orig_decl))
			  && (GFC_DECL_GET_SCALAR_POINTER (orig_decl)
			      || GFC_DECL_GET_SCALAR_ALLOCATABLE (orig_decl)))
			{
			  node3 = build_omp_clause (input_location,
						    OMP_CLAUSE_MAP);
			  OMP_CLAUSE_SET_MAP_KIND (node3, GOMP_MAP_POINTER);
			  OMP_CLAUSE_DECL (node3) = decl;
			  OMP_CLAUSE_SIZE (node3) = size_int (0);
			  decl = build_fold_indirect_ref (decl);
			}
		    }
		  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
		    {
		      tree type = TREE_TYPE (decl);
		      tree ptr = gfc_conv_descriptor_data_get (decl);
		      if (present)
			ptr = gfc_build_cond_assign_expr (block, present, ptr,
							  null_pointer_node);
		      ptr = fold_convert (build_pointer_type (char_type_node),
					  ptr);
		      ptr = build_fold_indirect_ref (ptr);
		      OMP_CLAUSE_DECL (node) = ptr;
		      node2 = build_omp_clause (input_location,
						OMP_CLAUSE_MAP);
		      OMP_CLAUSE_SET_MAP_KIND (node2, GOMP_MAP_TO_PSET);
		      OMP_CLAUSE_DECL (node2) = decl;
		      OMP_CLAUSE_SIZE (node2) = TYPE_SIZE_UNIT (type);
		      node3 = build_omp_clause (input_location,
						OMP_CLAUSE_MAP);
		      if (present)
			{
			  ptr = gfc_conv_descriptor_data_get (decl);
			  ptr = gfc_build_addr_expr (NULL, ptr);
			  ptr = gfc_build_cond_assign_expr (block, present, ptr,
							    null_pointer_node);
			  ptr = build_fold_indirect_ref (ptr);
			  OMP_CLAUSE_DECL (node3) = ptr;
			}
		      else
			OMP_CLAUSE_DECL (node3)
			  = gfc_conv_descriptor_data_get (decl);
		      OMP_CLAUSE_SIZE (node3) = size_int (0);
		      if (n->u.map_op == OMP_MAP_ATTACH)
			{
			  /* Standalone attach clauses used with arrays with
			     descriptors must copy the descriptor to the target,
			     else they won't have anything to perform the
			     attachment onto (see OpenACC 2.6, "2.6.3. Data
			     Structures with Pointers").  */
			  OMP_CLAUSE_SET_MAP_KIND (node3, GOMP_MAP_ATTACH);
			  /* We don't want to map PTR at all in this case, so
			     delete its node and shuffle the others down.  */
			  node = node2;
			  node2 = node3;
			  node3 = NULL;
			  goto finalize_map_clause;
			}
		      else if (n->u.map_op == OMP_MAP_DETACH)
			{
			  OMP_CLAUSE_SET_MAP_KIND (node3, GOMP_MAP_DETACH);
			  /* Similarly to above, we don't want to unmap PTR
			     here.  */
			  node = node2;
			  node2 = node3;
			  node3 = NULL;
			  goto finalize_map_clause;
			}
		      else
			OMP_CLAUSE_SET_MAP_KIND (node3,
						 always_modifier
						 ? GOMP_MAP_ALWAYS_POINTER
						 : GOMP_MAP_POINTER);

		      /* We have to check for n->sym->attr.dimension because
			 of scalar coarrays.  */
		      if (n->sym->attr.pointer && n->sym->attr.dimension)
			{
			  stmtblock_t cond_block;
			  tree size
			    = gfc_create_var (gfc_array_index_type, NULL);
			  tree tem, then_b, else_b, zero, cond;

			  gfc_init_block (&cond_block);
			  tem
			    = gfc_full_array_size (&cond_block, decl,
						   GFC_TYPE_ARRAY_RANK (type));
			  gfc_add_modify (&cond_block, size, tem);
			  then_b = gfc_finish_block (&cond_block);
			  gfc_init_block (&cond_block);
			  zero = build_int_cst (gfc_array_index_type, 0);
			  gfc_add_modify (&cond_block, size, zero);
			  else_b = gfc_finish_block (&cond_block);
			  tem = gfc_conv_descriptor_data_get (decl);
			  tem = fold_convert (pvoid_type_node, tem);
			  cond = fold_build2_loc (input_location, NE_EXPR,
						  boolean_type_node,
						  tem, null_pointer_node);
			  if (present)
			    cond = fold_build2_loc (input_location,
						    TRUTH_ANDIF_EXPR,
						    boolean_type_node,
						    present, cond);
			  gfc_add_expr_to_block (block,
						 build3_loc (input_location,
							     COND_EXPR,
							     void_type_node,
							     cond, then_b,
							     else_b));
			  OMP_CLAUSE_SIZE (node) = size;
			}
		      else if (n->sym->attr.dimension)
			{
			  stmtblock_t cond_block;
			  gfc_init_block (&cond_block);
			  tree size = gfc_full_array_size (&cond_block, decl,
					GFC_TYPE_ARRAY_RANK (type));
			  if (present)
			    {
			      tree var = gfc_create_var (gfc_array_index_type,
							 NULL);
			      gfc_add_modify (&cond_block, var, size);
			      tree cond_body = gfc_finish_block (&cond_block);
			      tree cond = build3_loc (input_location, COND_EXPR,
						      void_type_node, present,
						      cond_body, NULL_TREE);
			      gfc_add_expr_to_block (block, cond);
			      OMP_CLAUSE_SIZE (node) = var;
			    }
			  else
			    {
			      gfc_add_block_to_block (block, &cond_block);
			      OMP_CLAUSE_SIZE (node) = size;
			    }
			}
		      if (n->sym->attr.dimension)
			{
			  tree elemsz
			    = TYPE_SIZE_UNIT (gfc_get_element_type (type));
			  elemsz = fold_convert (gfc_array_index_type, elemsz);
			  OMP_CLAUSE_SIZE (node)
			    = fold_build2 (MULT_EXPR, gfc_array_index_type,
					   OMP_CLAUSE_SIZE (node), elemsz);
			}
		    }
		  else if (present
			   && TREE_CODE (decl) == INDIRECT_REF
			   && (TREE_CODE (TREE_OPERAND (decl, 0))
			       == INDIRECT_REF))
		    {
		      /* A single indirectref is handled by the middle end.  */
		      gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
		      decl = TREE_OPERAND (decl, 0);
		      decl = gfc_build_cond_assign_expr (block, present, decl,
							 null_pointer_node);
		      OMP_CLAUSE_DECL (node) = build_fold_indirect_ref (decl);
		    }
		  else
		    OMP_CLAUSE_DECL (node) = decl;
		}
	      else if (n->expr
		       && n->expr->expr_type == EXPR_VARIABLE
		       && n->expr->ref->type == REF_ARRAY
		       && !n->expr->ref->next)
		{
		  /* An array element or array section which is not part of a
		     derived type, etc.  */
		  bool element = n->expr->ref->u.ar.type == AR_ELEMENT;
		  gfc_trans_omp_array_section (block, n, decl, element,
					       GOMP_MAP_POINTER, node, node2,
					       node3, node4);
		}
	      else if (n->expr
		       && n->expr->expr_type == EXPR_VARIABLE
		       && (n->expr->ref->type == REF_COMPONENT
			   || n->expr->ref->type == REF_ARRAY)
		       && lastref
		       && lastref->type == REF_COMPONENT
		       && lastref->u.c.component->ts.type != BT_CLASS
		       && lastref->u.c.component->ts.type != BT_DERIVED
		       && !lastref->u.c.component->attr.dimension)
		{
		  /* Derived type access with last component being a scalar.  */
		  gfc_init_se (&se, NULL);

		  gfc_conv_expr (&se, n->expr);
		  gfc_add_block_to_block (block, &se.pre);
		  /* For BT_CHARACTER a pointer is returned.  */
		  OMP_CLAUSE_DECL (node)
		    = POINTER_TYPE_P (TREE_TYPE (se.expr))
		      ? build_fold_indirect_ref (se.expr) : se.expr;
		  gfc_add_block_to_block (block, &se.post);
		  if (pointer || allocatable)
		    {
		      node2 = build_omp_clause (input_location,
						OMP_CLAUSE_MAP);
		      gomp_map_kind kind
			= (openacc ? GOMP_MAP_ATTACH_DETACH
				   : GOMP_MAP_ALWAYS_POINTER);
		      OMP_CLAUSE_SET_MAP_KIND (node2, kind);
		      OMP_CLAUSE_DECL (node2)
			= POINTER_TYPE_P (TREE_TYPE (se.expr))
			  ? se.expr
			  : gfc_build_addr_expr (NULL, se.expr);
		      OMP_CLAUSE_SIZE (node2) = size_int (0);
		      if (!openacc
			  && n->expr->ts.type == BT_CHARACTER
			  && n->expr->ts.deferred)
			{
			  gcc_assert (se.string_length);
			  tree tmp
			    = gfc_get_char_type (n->expr->ts.kind);
			  OMP_CLAUSE_SIZE (node)
			    = fold_build2 (MULT_EXPR, size_type_node,
					   fold_convert (size_type_node,
					       se.string_length),
					   TYPE_SIZE_UNIT (tmp));
			  node3 = build_omp_clause (input_location,
						    OMP_CLAUSE_MAP);
			  OMP_CLAUSE_SET_MAP_KIND (node3, GOMP_MAP_TO);
			  OMP_CLAUSE_DECL (node3) = se.string_length;
			  OMP_CLAUSE_SIZE (node3)
			    = TYPE_SIZE_UNIT (gfc_charlen_type_node);
			}
		    }
		}
	      else if (n->expr
		       && n->expr->expr_type == EXPR_VARIABLE
		       && (n->expr->ref->type == REF_COMPONENT
			   || n->expr->ref->type == REF_ARRAY))
		{
		  gfc_init_se (&se, NULL);
		  se.expr = gfc_maybe_dereference_var (n->sym, decl);

		  for (gfc_ref *ref = n->expr->ref; ref; ref = ref->next)
		    {
		      if (ref->type == REF_COMPONENT)
			{
			  if (ref->u.c.sym->attr.extension)
			    conv_parent_component_references (&se, ref);

			  gfc_conv_component_ref (&se, ref);
			}
		      else if (ref->type == REF_ARRAY)
			{
			  if (ref->u.ar.type == AR_ELEMENT && ref->next)
			    gfc_conv_array_ref (&se, &ref->u.ar, n->expr,
						&n->expr->where);
			  else
			    gcc_assert (!ref->next);
			}
		      else
			sorry ("unhandled expression type");
		    }

		  tree inner = se.expr;

		  /* Last component is a derived type or class pointer.  */
		  if (lastref->type == REF_COMPONENT
		      && (lastref->u.c.component->ts.type == BT_DERIVED
			  || lastref->u.c.component->ts.type == BT_CLASS))
		    {
		      if (pointer || (openacc && allocatable))
			{
			  tree data, size;

			  if (lastref->u.c.component->ts.type == BT_CLASS)
			    {
			      data = gfc_class_data_get (inner);
			      gcc_assert (POINTER_TYPE_P (TREE_TYPE (data)));
			      data = build_fold_indirect_ref (data);
			      size = gfc_class_vtab_size_get (inner);
			    }
			  else  /* BT_DERIVED.  */
			    {
			      data = inner;
			      size = TYPE_SIZE_UNIT (TREE_TYPE (inner));
			    }

			  OMP_CLAUSE_DECL (node) = data;
			  OMP_CLAUSE_SIZE (node) = size;
			  node2 = build_omp_clause (input_location,
						    OMP_CLAUSE_MAP);
			  OMP_CLAUSE_SET_MAP_KIND (node2,
						   openacc
						   ? GOMP_MAP_ATTACH_DETACH
						   : GOMP_MAP_ALWAYS_POINTER);
			  OMP_CLAUSE_DECL (node2) = build_fold_addr_expr (data);
			  OMP_CLAUSE_SIZE (node2) = size_int (0);
			}
		      else
			{
			  OMP_CLAUSE_DECL (node) = inner;
			  OMP_CLAUSE_SIZE (node)
			    = TYPE_SIZE_UNIT (TREE_TYPE (inner));
			}
		    }
		  else if (lastref->type == REF_ARRAY
			   && lastref->u.ar.type == AR_FULL)
		    {
		      /* Just pass the (auto-dereferenced) decl through for
			 bare attach and detach clauses.  */
		      if (n->u.map_op == OMP_MAP_ATTACH
			  || n->u.map_op == OMP_MAP_DETACH)
			{
			  OMP_CLAUSE_DECL (node) = inner;
			  OMP_CLAUSE_SIZE (node) = size_zero_node;
			  goto finalize_map_clause;
			}

		      if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (inner)))
			{
			  gomp_map_kind map_kind;
			  tree desc_node;
			  tree type = TREE_TYPE (inner);
			  tree ptr = gfc_conv_descriptor_data_get (inner);
			  ptr = build_fold_indirect_ref (ptr);
			  OMP_CLAUSE_DECL (node) = ptr;
			  int rank = GFC_TYPE_ARRAY_RANK (type);
			  OMP_CLAUSE_SIZE (node)
			    = gfc_full_array_size (block, inner, rank);
			  tree elemsz
			    = TYPE_SIZE_UNIT (gfc_get_element_type (type));
			  if (GOMP_MAP_COPY_TO_P (OMP_CLAUSE_MAP_KIND (node)))
			    map_kind = GOMP_MAP_TO;
			  else if (n->u.map_op == OMP_MAP_RELEASE
				   || n->u.map_op == OMP_MAP_DELETE)
			    map_kind = OMP_CLAUSE_MAP_KIND (node);
			  else
			    map_kind = GOMP_MAP_ALLOC;
			  if (!openacc
			      && n->expr->ts.type == BT_CHARACTER
			      && n->expr->ts.deferred)
			    {
			      gcc_assert (se.string_length);
			      tree len = fold_convert (size_type_node,
						       se.string_length);
			      elemsz = gfc_get_char_type (n->expr->ts.kind);
			      elemsz = TYPE_SIZE_UNIT (elemsz);
			      elemsz = fold_build2 (MULT_EXPR, size_type_node,
						    len, elemsz);
			      node4 = build_omp_clause (input_location,
							OMP_CLAUSE_MAP);
			      OMP_CLAUSE_SET_MAP_KIND (node4, map_kind);
			      OMP_CLAUSE_DECL (node4) = se.string_length;
			      OMP_CLAUSE_SIZE (node4)
				= TYPE_SIZE_UNIT (gfc_charlen_type_node);
			    }
			  elemsz = fold_convert (gfc_array_index_type, elemsz);
			  OMP_CLAUSE_SIZE (node)
			    = fold_build2 (MULT_EXPR, gfc_array_index_type,
					   OMP_CLAUSE_SIZE (node), elemsz);
			  desc_node = build_omp_clause (input_location,
							OMP_CLAUSE_MAP);
			  if (openacc)
			    OMP_CLAUSE_SET_MAP_KIND (desc_node,
						     GOMP_MAP_TO_PSET);
			  else
			    OMP_CLAUSE_SET_MAP_KIND (desc_node, map_kind);
			  OMP_CLAUSE_DECL (desc_node) = inner;
			  OMP_CLAUSE_SIZE (desc_node) = TYPE_SIZE_UNIT (type);
			  if (openacc)
			    node2 = desc_node;
			  else
			    {
			      node2 = node;
			      node = desc_node;  /* Put first.  */
			    }
			  node3 = build_omp_clause (input_location,
						    OMP_CLAUSE_MAP);
			  OMP_CLAUSE_SET_MAP_KIND (node3,
						   openacc
						   ? GOMP_MAP_ATTACH_DETACH
						   : GOMP_MAP_ALWAYS_POINTER);
			  OMP_CLAUSE_DECL (node3)
			    = gfc_conv_descriptor_data_get (inner);
			  /* Similar to gfc_trans_omp_array_section (details
			     there), we add/keep the cast for OpenMP to prevent
			     that an 'alloc:' gets added for node3 ('desc.data')
			     as that is part of the whole descriptor (node3).
			     TODO: Remove once the ME handles this properly.  */
			  if (!openacc)
			    OMP_CLAUSE_DECL (node3)
				= fold_convert (TREE_TYPE (TREE_OPERAND(ptr, 0)),
						OMP_CLAUSE_DECL (node3));
			  else
			    STRIP_NOPS (OMP_CLAUSE_DECL (node3));
			  OMP_CLAUSE_SIZE (node3) = size_int (0);
			}
		      else
			OMP_CLAUSE_DECL (node) = inner;
		    }
		  else if (lastref->type == REF_ARRAY)
		    {
		      /* An array element or section.  */
		      bool element = lastref->u.ar.type == AR_ELEMENT;
		      gomp_map_kind kind = (openacc ? GOMP_MAP_ATTACH_DETACH
						    : GOMP_MAP_ALWAYS_POINTER);
		      gfc_trans_omp_array_section (block, n, inner, element,
						   kind, node, node2, node3,
						   node4);
		    }
		  else
		    gcc_unreachable ();
		}
	      else
		sorry ("unhandled expression");

	      finalize_map_clause:

	      omp_clauses = gfc_trans_add_clause (node, omp_clauses);
	      if (node2)
		omp_clauses = gfc_trans_add_clause (node2, omp_clauses);
	      if (node3)
		omp_clauses = gfc_trans_add_clause (node3, omp_clauses);
	      if (node4)
		omp_clauses = gfc_trans_add_clause (node4, omp_clauses);
	    }
	  break;
	case OMP_LIST_TO:
	case OMP_LIST_FROM:
	case OMP_LIST_CACHE:
	  for (; n != NULL; n = n->next)
	    {
	      if (!n->sym->attr.referenced)
		continue;

	      switch (list)
		{
		case OMP_LIST_TO:
		  clause_code = OMP_CLAUSE_TO;
		  break;
		case OMP_LIST_FROM:
		  clause_code = OMP_CLAUSE_FROM;
		  break;
		case OMP_LIST_CACHE:
		  clause_code = OMP_CLAUSE__CACHE_;
		  break;
		default:
		  gcc_unreachable ();
		}
	      tree node = build_omp_clause (input_location, clause_code);
	      if (n->expr == NULL || n->expr->ref->u.ar.type == AR_FULL)
		{
		  tree decl = gfc_trans_omp_variable (n->sym, false);
		  if (gfc_omp_privatize_by_reference (decl))
		    {
		      if (gfc_omp_is_allocatable_or_ptr (decl))
			decl = build_fold_indirect_ref (decl);
		      decl = build_fold_indirect_ref (decl);
		    }
		  else if (DECL_P (decl))
		    TREE_ADDRESSABLE (decl) = 1;
		  if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl)))
		    {
		      tree type = TREE_TYPE (decl);
		      tree ptr = gfc_conv_descriptor_data_get (decl);
		      ptr = fold_convert (build_pointer_type (char_type_node),
					  ptr);
		      ptr = build_fold_indirect_ref (ptr);
		      OMP_CLAUSE_DECL (node) = ptr;
		      OMP_CLAUSE_SIZE (node)
			= gfc_full_array_size (block, decl,
					       GFC_TYPE_ARRAY_RANK (type));
		      tree elemsz
			= TYPE_SIZE_UNIT (gfc_get_element_type (type));
		      elemsz = fold_convert (gfc_array_index_type, elemsz);
		      OMP_CLAUSE_SIZE (node)
			= fold_build2 (MULT_EXPR, gfc_array_index_type,
				       OMP_CLAUSE_SIZE (node), elemsz);
		    }
		  else
		    {
		      OMP_CLAUSE_DECL (node) = decl;
		      if (gfc_omp_is_allocatable_or_ptr (decl))
			OMP_CLAUSE_SIZE (node)
				= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
		    }
		}
	      else
		{
		  tree ptr;
		  gfc_init_se (&se, NULL);
		  if (n->expr->ref->u.ar.type == AR_ELEMENT)
		    {
		      gfc_conv_expr_reference (&se, n->expr);
		      ptr = se.expr;
		      gfc_add_block_to_block (block, &se.pre);
		      OMP_CLAUSE_SIZE (node)
			= TYPE_SIZE_UNIT (TREE_TYPE (ptr));
		    }
		  else
		    {
		      gfc_conv_expr_descriptor (&se, n->expr);
		      ptr = gfc_conv_array_data (se.expr);
		      tree type = TREE_TYPE (se.expr);
		      gfc_add_block_to_block (block, &se.pre);
		      OMP_CLAUSE_SIZE (node)
			= gfc_full_array_size (block, se.expr,
					       GFC_TYPE_ARRAY_RANK (type));
		      tree elemsz
			= TYPE_SIZE_UNIT (gfc_get_element_type (type));
		      elemsz = fold_convert (gfc_array_index_type, elemsz);
		      OMP_CLAUSE_SIZE (node)
			= fold_build2 (MULT_EXPR, gfc_array_index_type,
				       OMP_CLAUSE_SIZE (node), elemsz);
		    }
		  gfc_add_block_to_block (block, &se.post);
		  ptr = fold_convert (build_pointer_type (char_type_node),
				      ptr);
		  OMP_CLAUSE_DECL (node) = build_fold_indirect_ref (ptr);
		}
	      omp_clauses = gfc_trans_add_clause (node, omp_clauses);
	    }
	  break;
	default:
	  break;
	}
    }

  if (clauses->if_expr)
    {
      tree if_var;

      gfc_init_se (&se, NULL);
      gfc_conv_expr (&se, clauses->if_expr);
      gfc_add_block_to_block (block, &se.pre);
      if_var = gfc_evaluate_now (se.expr, block);
      gfc_add_block_to_block (block, &se.post);

      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_IF);
      OMP_CLAUSE_IF_MODIFIER (c) = ERROR_MARK;
      OMP_CLAUSE_IF_EXPR (c) = if_var;
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }
  for (ifc = 0; ifc < OMP_IF_LAST; ifc++)
    if (clauses->if_exprs[ifc])
      {
	tree if_var;

	gfc_init_se (&se, NULL);
	gfc_conv_expr (&se, clauses->if_exprs[ifc]);
	gfc_add_block_to_block (block, &se.pre);
	if_var = gfc_evaluate_now (se.expr, block);
	gfc_add_block_to_block (block, &se.post);

	c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_IF);
	switch (ifc)
	  {
	  case OMP_IF_CANCEL:
	    OMP_CLAUSE_IF_MODIFIER (c) = VOID_CST;
	    break;
	  case OMP_IF_PARALLEL:
	    OMP_CLAUSE_IF_MODIFIER (c) = OMP_PARALLEL;
	    break;
	  case OMP_IF_SIMD:
	    OMP_CLAUSE_IF_MODIFIER (c) = OMP_SIMD;
	    break;
	  case OMP_IF_TASK:
	    OMP_CLAUSE_IF_MODIFIER (c) = OMP_TASK;
	    break;
	  case OMP_IF_TASKLOOP:
	    OMP_CLAUSE_IF_MODIFIER (c) = OMP_TASKLOOP;
	    break;
	  case OMP_IF_TARGET:
	    OMP_CLAUSE_IF_MODIFIER (c) = OMP_TARGET;
	    break;
	  case OMP_IF_TARGET_DATA:
	    OMP_CLAUSE_IF_MODIFIER (c) = OMP_TARGET_DATA;
	    break;
	  case OMP_IF_TARGET_UPDATE:
	    OMP_CLAUSE_IF_MODIFIER (c) = OMP_TARGET_UPDATE;
	    break;
	  case OMP_IF_TARGET_ENTER_DATA:
	    OMP_CLAUSE_IF_MODIFIER (c) = OMP_TARGET_ENTER_DATA;
	    break;
	  case OMP_IF_TARGET_EXIT_DATA:
	    OMP_CLAUSE_IF_MODIFIER (c) = OMP_TARGET_EXIT_DATA;
	    break;
	  default:
	    gcc_unreachable ();
	  }
	OMP_CLAUSE_IF_EXPR (c) = if_var;
	omp_clauses = gfc_trans_add_clause (c, omp_clauses);
      }

  if (clauses->final_expr)
    {
      tree final_var;

      gfc_init_se (&se, NULL);
      gfc_conv_expr (&se, clauses->final_expr);
      gfc_add_block_to_block (block, &se.pre);
      final_var = gfc_evaluate_now (se.expr, block);
      gfc_add_block_to_block (block, &se.post);

      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_FINAL);
      OMP_CLAUSE_FINAL_EXPR (c) = final_var;
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }

  if (clauses->num_threads)
    {
      tree num_threads;

      gfc_init_se (&se, NULL);
      gfc_conv_expr (&se, clauses->num_threads);
      gfc_add_block_to_block (block, &se.pre);
      num_threads = gfc_evaluate_now (se.expr, block);
      gfc_add_block_to_block (block, &se.post);

      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_NUM_THREADS);
      OMP_CLAUSE_NUM_THREADS_EXPR (c) = num_threads;
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }

  chunk_size = NULL_TREE;
  if (clauses->chunk_size)
    {
      gfc_init_se (&se, NULL);
      gfc_conv_expr (&se, clauses->chunk_size);
      gfc_add_block_to_block (block, &se.pre);
      chunk_size = gfc_evaluate_now (se.expr, block);
      gfc_add_block_to_block (block, &se.post);
    }

  if (clauses->sched_kind != OMP_SCHED_NONE)
    {
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_SCHEDULE);
      OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = chunk_size;
      switch (clauses->sched_kind)
	{
	case OMP_SCHED_STATIC:
	  OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
	  break;
	case OMP_SCHED_DYNAMIC:
	  OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
	  break;
	case OMP_SCHED_GUIDED:
	  OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
	  break;
	case OMP_SCHED_RUNTIME:
	  OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
	  break;
	case OMP_SCHED_AUTO:
	  OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
	  break;
	default:
	  gcc_unreachable ();
	}
      if (clauses->sched_monotonic)
	OMP_CLAUSE_SCHEDULE_KIND (c)
	  = (omp_clause_schedule_kind) (OMP_CLAUSE_SCHEDULE_KIND (c)
					| OMP_CLAUSE_SCHEDULE_MONOTONIC);
      else if (clauses->sched_nonmonotonic)
	OMP_CLAUSE_SCHEDULE_KIND (c)
	  = (omp_clause_schedule_kind) (OMP_CLAUSE_SCHEDULE_KIND (c)
					| OMP_CLAUSE_SCHEDULE_NONMONOTONIC);
      if (clauses->sched_simd)
	OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }

  if (clauses->default_sharing != OMP_DEFAULT_UNKNOWN)
    {
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_DEFAULT);
      switch (clauses->default_sharing)
	{
	case OMP_DEFAULT_NONE:
	  OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_NONE;
	  break;
	case OMP_DEFAULT_SHARED:
	  OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_SHARED;
	  break;
	case OMP_DEFAULT_PRIVATE:
	  OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_PRIVATE;
	  break;
	case OMP_DEFAULT_FIRSTPRIVATE:
	  OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
	  break;
	case OMP_DEFAULT_PRESENT:
	  OMP_CLAUSE_DEFAULT_KIND (c) = OMP_CLAUSE_DEFAULT_PRESENT;
	  break;
	default:
	  gcc_unreachable ();
	}
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }

  if (clauses->nowait)
    {
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_NOWAIT);
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }

  if (clauses->ordered)
    {
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_ORDERED);
      OMP_CLAUSE_ORDERED_EXPR (c)
	= clauses->orderedc ? build_int_cst (integer_type_node,
					     clauses->orderedc) : NULL_TREE;
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }

  if (clauses->order_concurrent)
    {
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_ORDER);
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }

  if (clauses->untied)
    {
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_UNTIED);
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }

  if (clauses->mergeable)
    {
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_MERGEABLE);
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }

  if (clauses->collapse)
    {
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_COLLAPSE);
      OMP_CLAUSE_COLLAPSE_EXPR (c)
	= build_int_cst (integer_type_node, clauses->collapse);
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }

  if (clauses->inbranch)
    {
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_INBRANCH);
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }

  if (clauses->notinbranch)
    {
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_NOTINBRANCH);
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }

  switch (clauses->cancel)
    {
    case OMP_CANCEL_UNKNOWN:
      break;
    case OMP_CANCEL_PARALLEL:
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_PARALLEL);
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
      break;
    case OMP_CANCEL_SECTIONS:
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_SECTIONS);
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
      break;
    case OMP_CANCEL_DO:
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_FOR);
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
      break;
    case OMP_CANCEL_TASKGROUP:
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_TASKGROUP);
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
      break;
    }

  if (clauses->proc_bind != OMP_PROC_BIND_UNKNOWN)
    {
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_PROC_BIND);
      switch (clauses->proc_bind)
	{
	case OMP_PROC_BIND_MASTER:
	  OMP_CLAUSE_PROC_BIND_KIND (c) = OMP_CLAUSE_PROC_BIND_MASTER;
	  break;
	case OMP_PROC_BIND_SPREAD:
	  OMP_CLAUSE_PROC_BIND_KIND (c) = OMP_CLAUSE_PROC_BIND_SPREAD;
	  break;
	case OMP_PROC_BIND_CLOSE:
	  OMP_CLAUSE_PROC_BIND_KIND (c) = OMP_CLAUSE_PROC_BIND_CLOSE;
	  break;
	default:
	  gcc_unreachable ();
	}
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }

  if (clauses->safelen_expr)
    {
      tree safelen_var;

      gfc_init_se (&se, NULL);
      gfc_conv_expr (&se, clauses->safelen_expr);
      gfc_add_block_to_block (block, &se.pre);
      safelen_var = gfc_evaluate_now (se.expr, block);
      gfc_add_block_to_block (block, &se.post);

      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_SAFELEN);
      OMP_CLAUSE_SAFELEN_EXPR (c) = safelen_var;
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }

  if (clauses->simdlen_expr)
    {
      if (declare_simd)
	{
	  c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_SIMDLEN);
	  OMP_CLAUSE_SIMDLEN_EXPR (c)
	    = gfc_conv_constant_to_tree (clauses->simdlen_expr);
	  omp_clauses = gfc_trans_add_clause (c, omp_clauses);
	}
      else
	{
	  tree simdlen_var;

	  gfc_init_se (&se, NULL);
	  gfc_conv_expr (&se, clauses->simdlen_expr);
	  gfc_add_block_to_block (block, &se.pre);
	  simdlen_var = gfc_evaluate_now (se.expr, block);
	  gfc_add_block_to_block (block, &se.post);

	  c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_SIMDLEN);
	  OMP_CLAUSE_SIMDLEN_EXPR (c) = simdlen_var;
	  omp_clauses = gfc_trans_add_clause (c, omp_clauses);
	}
    }

  if (clauses->num_teams)
    {
      tree num_teams;

      gfc_init_se (&se, NULL);
      gfc_conv_expr (&se, clauses->num_teams);
      gfc_add_block_to_block (block, &se.pre);
      num_teams = gfc_evaluate_now (se.expr, block);
      gfc_add_block_to_block (block, &se.post);

      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_NUM_TEAMS);
      OMP_CLAUSE_NUM_TEAMS_EXPR (c) = num_teams;
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }

  if (clauses->device)
    {
      tree device;

      gfc_init_se (&se, NULL);
      gfc_conv_expr (&se, clauses->device);
      gfc_add_block_to_block (block, &se.pre);
      device = gfc_evaluate_now (se.expr, block);
      gfc_add_block_to_block (block, &se.post);

      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_DEVICE);
      OMP_CLAUSE_DEVICE_ID (c) = device;
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }

  if (clauses->thread_limit)
    {
      tree thread_limit;

      gfc_init_se (&se, NULL);
      gfc_conv_expr (&se, clauses->thread_limit);
      gfc_add_block_to_block (block, &se.pre);
      thread_limit = gfc_evaluate_now (se.expr, block);
      gfc_add_block_to_block (block, &se.post);

      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_THREAD_LIMIT);
      OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }

  chunk_size = NULL_TREE;
  if (clauses->dist_chunk_size)
    {
      gfc_init_se (&se, NULL);
      gfc_conv_expr (&se, clauses->dist_chunk_size);
      gfc_add_block_to_block (block, &se.pre);
      chunk_size = gfc_evaluate_now (se.expr, block);
      gfc_add_block_to_block (block, &se.post);
    }

  if (clauses->dist_sched_kind != OMP_SCHED_NONE)
    {
      c = build_omp_clause (gfc_get_location (&where),
			    OMP_CLAUSE_DIST_SCHEDULE);
      OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = chunk_size;
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }

  if (clauses->grainsize)
    {
      tree grainsize;

      gfc_init_se (&se, NULL);
      gfc_conv_expr (&se, clauses->grainsize);
      gfc_add_block_to_block (block, &se.pre);
      grainsize = gfc_evaluate_now (se.expr, block);
      gfc_add_block_to_block (block, &se.post);

      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_GRAINSIZE);
      OMP_CLAUSE_GRAINSIZE_EXPR (c) = grainsize;
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }

  if (clauses->num_tasks)
    {
      tree num_tasks;

      gfc_init_se (&se, NULL);
      gfc_conv_expr (&se, clauses->num_tasks);
      gfc_add_block_to_block (block, &se.pre);
      num_tasks = gfc_evaluate_now (se.expr, block);
      gfc_add_block_to_block (block, &se.post);

      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_NUM_TASKS);
      OMP_CLAUSE_NUM_TASKS_EXPR (c) = num_tasks;
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }

  if (clauses->priority)
    {
      tree priority;

      gfc_init_se (&se, NULL);
      gfc_conv_expr (&se, clauses->priority);
      gfc_add_block_to_block (block, &se.pre);
      priority = gfc_evaluate_now (se.expr, block);
      gfc_add_block_to_block (block, &se.post);

      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_PRIORITY);
      OMP_CLAUSE_PRIORITY_EXPR (c) = priority;
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }

  if (clauses->detach)
    {
      tree detach;

      gfc_init_se (&se, NULL);
      gfc_conv_expr (&se, clauses->detach);
      gfc_add_block_to_block (block, &se.pre);
      detach = se.expr;
      gfc_add_block_to_block (block, &se.post);

      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_DETACH);
      TREE_ADDRESSABLE (detach) = 1;
      OMP_CLAUSE_DECL (c) = detach;
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }

  if (clauses->hint)
    {
      tree hint;

      gfc_init_se (&se, NULL);
      gfc_conv_expr (&se, clauses->hint);
      gfc_add_block_to_block (block, &se.pre);
      hint = gfc_evaluate_now (se.expr, block);
      gfc_add_block_to_block (block, &se.post);

      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_HINT);
      OMP_CLAUSE_HINT_EXPR (c) = hint;
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }

  if (clauses->simd)
    {
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_SIMD);
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }
  if (clauses->threads)
    {
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_THREADS);
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }
  if (clauses->nogroup)
    {
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_NOGROUP);
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }

  for (int i = 0; i < OMP_DEFAULTMAP_CAT_NUM; i++)
    {
      if (clauses->defaultmap[i] == OMP_DEFAULTMAP_UNSET)
       continue;
      enum omp_clause_defaultmap_kind behavior, category;
      switch ((gfc_omp_defaultmap_category) i)
	{
	case OMP_DEFAULTMAP_CAT_UNCATEGORIZED:
	  category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
	  break;
	case OMP_DEFAULTMAP_CAT_SCALAR:
	  category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR;
	  break;
	case OMP_DEFAULTMAP_CAT_AGGREGATE:
	  category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
	  break;
	case OMP_DEFAULTMAP_CAT_ALLOCATABLE:
	  category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE;
	  break;
	case OMP_DEFAULTMAP_CAT_POINTER:
	  category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER;
	  break;
	default: gcc_unreachable ();
	}
      switch (clauses->defaultmap[i])
	{
	case OMP_DEFAULTMAP_ALLOC:
	  behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC;
	  break;
	case OMP_DEFAULTMAP_TO: behavior = OMP_CLAUSE_DEFAULTMAP_TO; break;
	case OMP_DEFAULTMAP_FROM: behavior = OMP_CLAUSE_DEFAULTMAP_FROM; break;
	case OMP_DEFAULTMAP_TOFROM:
	  behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM;
	  break;
	case OMP_DEFAULTMAP_FIRSTPRIVATE:
	  behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
	  break;
	case OMP_DEFAULTMAP_NONE: behavior = OMP_CLAUSE_DEFAULTMAP_NONE; break;
	case OMP_DEFAULTMAP_DEFAULT:
	  behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
	  break;
	default: gcc_unreachable ();
	}
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_DEFAULTMAP);
      OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category);
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }

  if (clauses->depend_source)
    {
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_DEPEND);
      OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_SOURCE;
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }

  if (clauses->async)
    {
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_ASYNC);
      if (clauses->async_expr)
	OMP_CLAUSE_ASYNC_EXPR (c)
	  = gfc_convert_expr_to_tree (block, clauses->async_expr);
      else
	OMP_CLAUSE_ASYNC_EXPR (c) = NULL;
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }
  if (clauses->seq)
    {
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_SEQ);
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }
  if (clauses->par_auto)
    {
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_AUTO);
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }
  if (clauses->if_present)
    {
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_IF_PRESENT);
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }
  if (clauses->finalize)
    {
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_FINALIZE);
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }
  if (clauses->independent)
    {
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_INDEPENDENT);
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }
  if (clauses->wait_list)
    {
      gfc_expr_list *el;

      for (el = clauses->wait_list; el; el = el->next)
	{
	  c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_WAIT);
	  OMP_CLAUSE_DECL (c) = gfc_convert_expr_to_tree (block, el->expr);
	  OMP_CLAUSE_CHAIN (c) = omp_clauses;
	  omp_clauses = c;
	}
    }
  if (clauses->num_gangs_expr)
    {
      tree num_gangs_var
	= gfc_convert_expr_to_tree (block, clauses->num_gangs_expr);
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_NUM_GANGS);
      OMP_CLAUSE_NUM_GANGS_EXPR (c) = num_gangs_var;
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }
  if (clauses->num_workers_expr)
    {
      tree num_workers_var
	= gfc_convert_expr_to_tree (block, clauses->num_workers_expr);
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_NUM_WORKERS);
      OMP_CLAUSE_NUM_WORKERS_EXPR (c) = num_workers_var;
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }
  if (clauses->vector_length_expr)
    {
      tree vector_length_var
	= gfc_convert_expr_to_tree (block, clauses->vector_length_expr);
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_VECTOR_LENGTH);
      OMP_CLAUSE_VECTOR_LENGTH_EXPR (c) = vector_length_var;
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
    }
  if (clauses->tile_list)
    {
      vec<tree, va_gc> *tvec;
      gfc_expr_list *el;

      vec_alloc (tvec, 4);

      for (el = clauses->tile_list; el; el = el->next)
	vec_safe_push (tvec, gfc_convert_expr_to_tree (block, el->expr));

      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_TILE);
      OMP_CLAUSE_TILE_LIST (c) = build_tree_list_vec (tvec);
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
      tvec->truncate (0);
    }
  if (clauses->vector)
    {
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_VECTOR);
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);

      if (clauses->vector_expr)
	{
	  tree vector_var
	    = gfc_convert_expr_to_tree (block, clauses->vector_expr);
	  OMP_CLAUSE_VECTOR_EXPR (c) = vector_var;

	  /* TODO: We're not capturing location information for individual
	     clauses.  However, if we have an expression attached to the
	     clause, that one provides better location information.  */
	  OMP_CLAUSE_LOCATION (c)
	    = gfc_get_location (&clauses->vector_expr->where);
	}
    }
  if (clauses->worker)
    {
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_WORKER);
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);

      if (clauses->worker_expr)
	{
	  tree worker_var
	    = gfc_convert_expr_to_tree (block, clauses->worker_expr);
	  OMP_CLAUSE_WORKER_EXPR (c) = worker_var;

	  /* TODO: We're not capturing location information for individual
	     clauses.  However, if we have an expression attached to the
	     clause, that one provides better location information.  */
	  OMP_CLAUSE_LOCATION (c)
	    = gfc_get_location (&clauses->worker_expr->where);
	}
    }
  if (clauses->gang)
    {
      tree arg;
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_GANG);
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);

      if (clauses->gang_num_expr)
	{
	  arg = gfc_convert_expr_to_tree (block, clauses->gang_num_expr);
	  OMP_CLAUSE_GANG_EXPR (c) = arg;

	  /* TODO: We're not capturing location information for individual
	     clauses.  However, if we have an expression attached to the
	     clause, that one provides better location information.  */
	  OMP_CLAUSE_LOCATION (c)
	    = gfc_get_location (&clauses->gang_num_expr->where);
	}

      if (clauses->gang_static)
	{
	  arg = clauses->gang_static_expr
	    ? gfc_convert_expr_to_tree (block, clauses->gang_static_expr)
	    : integer_minus_one_node;
	  OMP_CLAUSE_GANG_STATIC_EXPR (c) = arg;
	}
    }
  if (clauses->bind != OMP_BIND_UNSET)
    {
      c = build_omp_clause (gfc_get_location (&where), OMP_CLAUSE_BIND);
      omp_clauses = gfc_trans_add_clause (c, omp_clauses);
      switch (clauses->bind)
	{
	case OMP_BIND_TEAMS:
	  OMP_CLAUSE_BIND_KIND (c) = OMP_CLAUSE_BIND_TEAMS;
	  break;
	case OMP_BIND_PARALLEL:
	  OMP_CLAUSE_BIND_KIND (c) = OMP_CLAUSE_BIND_PARALLEL;
	  break;
	case OMP_BIND_THREAD:
	  OMP_CLAUSE_BIND_KIND (c) = OMP_CLAUSE_BIND_THREAD;
	  break;
	default:
	  gcc_unreachable ();
	}
    }

  return nreverse (omp_clauses);
}

/* Like gfc_trans_code, but force creation of a BIND_EXPR around it.  */

static tree
gfc_trans_omp_code (gfc_code *code, bool force_empty)
{
  tree stmt;

  pushlevel ();
  stmt = gfc_trans_code (code);
  if (TREE_CODE (stmt) != BIND_EXPR)
    {
      if (!IS_EMPTY_STMT (stmt) || force_empty)
	{
	  tree block = poplevel (1, 0);
	  stmt = build3_v (BIND_EXPR, NULL, stmt, block);
	}
      else
	poplevel (0, 0);
    }
  else
    poplevel (0, 0);
  return stmt;
}

/* Translate OpenACC 'parallel', 'kernels', 'serial', 'data', 'host_data'
   construct. */

static tree
gfc_trans_oacc_construct (gfc_code *code)
{
  stmtblock_t block;
  tree stmt, oacc_clauses;
  enum tree_code construct_code;

  switch (code->op)
    {
      case EXEC_OACC_PARALLEL:
	construct_code = OACC_PARALLEL;
	break;
      case EXEC_OACC_KERNELS:
	construct_code = OACC_KERNELS;
	break;
      case EXEC_OACC_SERIAL:
	construct_code = OACC_SERIAL;
	break;
      case EXEC_OACC_DATA:
	construct_code = OACC_DATA;
	break;
      case EXEC_OACC_HOST_DATA:
	construct_code = OACC_HOST_DATA;
	break;
      default:
	gcc_unreachable ();
    }

  gfc_start_block (&block);
  oacc_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
					code->loc, false, true);
  stmt = gfc_trans_omp_code (code->block->next, true);
  stmt = build2_loc (gfc_get_location (&code->loc), construct_code,
		     void_type_node, stmt, oacc_clauses);
  gfc_add_expr_to_block (&block, stmt);
  return gfc_finish_block (&block);
}

/* update, enter_data, exit_data, cache. */
static tree 
gfc_trans_oacc_executable_directive (gfc_code *code)
{
  stmtblock_t block;
  tree stmt, oacc_clauses;
  enum tree_code construct_code;

  switch (code->op)
    {
      case EXEC_OACC_UPDATE:
	construct_code = OACC_UPDATE;
	break;
      case EXEC_OACC_ENTER_DATA:
	construct_code = OACC_ENTER_DATA;
	break;
      case EXEC_OACC_EXIT_DATA:
	construct_code = OACC_EXIT_DATA;
	break;
      case EXEC_OACC_CACHE:
	construct_code = OACC_CACHE;
	break;
      default:
	gcc_unreachable ();
    }

  gfc_start_block (&block);
  oacc_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
					code->loc, false, true);
  stmt = build1_loc (input_location, construct_code, void_type_node, 
		     oacc_clauses);
  gfc_add_expr_to_block (&block, stmt);
  return gfc_finish_block (&block);
}

static tree
gfc_trans_oacc_wait_directive (gfc_code *code)
{
  stmtblock_t block;
  tree stmt, t;
  vec<tree, va_gc> *args;
  int nparms = 0;
  gfc_expr_list *el;
  gfc_omp_clauses *clauses = code->ext.omp_clauses;
  location_t loc = input_location;

  for (el = clauses->wait_list; el; el = el->next)
    nparms++;

  vec_alloc (args, nparms + 2);
  stmt = builtin_decl_explicit (BUILT_IN_GOACC_WAIT);

  gfc_start_block (&block);

  if (clauses->async_expr)
    t = gfc_convert_expr_to_tree (&block, clauses->async_expr);
  else
    t = build_int_cst (integer_type_node, -2);

  args->quick_push (t);
  args->quick_push (build_int_cst (integer_type_node, nparms));

  for (el = clauses->wait_list; el; el = el->next)
    args->quick_push (gfc_convert_expr_to_tree (&block, el->expr));

  stmt = build_call_expr_loc_vec (loc, stmt, args);
  gfc_add_expr_to_block (&block, stmt);

  vec_free (args);

  return gfc_finish_block (&block);
}

static tree gfc_trans_omp_sections (gfc_code *, gfc_omp_clauses *);
static tree gfc_trans_omp_workshare (gfc_code *, gfc_omp_clauses *);

static tree
gfc_trans_omp_atomic (gfc_code *code)
{
  gfc_code *atomic_code = code->block;
  gfc_se lse;
  gfc_se rse;
  gfc_se vse;
  gfc_expr *expr2, *e;
  gfc_symbol *var;
  stmtblock_t block;
  tree lhsaddr, type, rhs, x;
  enum tree_code op = ERROR_MARK;
  enum tree_code aop = OMP_ATOMIC;
  bool var_on_left = false;
  enum omp_memory_order mo;
  switch (atomic_code->ext.omp_clauses->memorder)
    {
    case OMP_MEMORDER_UNSET: mo = OMP_MEMORY_ORDER_UNSPECIFIED; break;
    case OMP_MEMORDER_ACQ_REL: mo = OMP_MEMORY_ORDER_ACQ_REL; break;
    case OMP_MEMORDER_ACQUIRE: mo = OMP_MEMORY_ORDER_ACQUIRE; break;
    case OMP_MEMORDER_RELAXED: mo = OMP_MEMORY_ORDER_RELAXED; break;
    case OMP_MEMORDER_RELEASE: mo = OMP_MEMORY_ORDER_RELEASE; break;
    case OMP_MEMORDER_SEQ_CST: mo = OMP_MEMORY_ORDER_SEQ_CST; break;
    default: gcc_unreachable ();
    }

  code = code->block->next;
  gcc_assert (code->op == EXEC_ASSIGN);
  var = code->expr1->symtree->n.sym;

  gfc_init_se (&lse, NULL);
  gfc_init_se (&rse, NULL);
  gfc_init_se (&vse, NULL);
  gfc_start_block (&block);

  expr2 = code->expr2;
  if (((atomic_code->ext.omp_clauses->atomic_op & GFC_OMP_ATOMIC_MASK)
       != GFC_OMP_ATOMIC_WRITE)
      && expr2->expr_type == EXPR_FUNCTION
      && expr2->value.function.isym
      && expr2->value.function.isym->id == GFC_ISYM_CONVERSION)
    expr2 = expr2->value.function.actual->expr;

  if ((atomic_code->ext.omp_clauses->atomic_op & GFC_OMP_ATOMIC_MASK)
      == GFC_OMP_ATOMIC_READ)
    {
      gfc_conv_expr (&vse, code->expr1);
      gfc_add_block_to_block (&block, &vse.pre);

      gfc_conv_expr (&lse, expr2);
      gfc_add_block_to_block (&block, &lse.pre);
      type = TREE_TYPE (lse.expr);
      lhsaddr = gfc_build_addr_expr (NULL, lse.expr);

      x = build1 (OMP_ATOMIC_READ, type, lhsaddr);
      OMP_ATOMIC_MEMORY_ORDER (x) = mo;
      x = convert (TREE_TYPE (vse.expr), x);
      gfc_add_modify (&block, vse.expr, x);

      gfc_add_block_to_block (&block, &lse.pre);
      gfc_add_block_to_block (&block, &rse.pre);

      return gfc_finish_block (&block);
    }
  if (atomic_code->ext.omp_clauses->capture)
    {
      aop = OMP_ATOMIC_CAPTURE_NEW;
      if (expr2->expr_type == EXPR_VARIABLE)
	{
	  aop = OMP_ATOMIC_CAPTURE_OLD;
	  gfc_conv_expr (&vse, code->expr1);
	  gfc_add_block_to_block (&block, &vse.pre);

	  gfc_conv_expr (&lse, expr2);
	  gfc_add_block_to_block (&block, &lse.pre);
	  gfc_init_se (&lse, NULL);
	  code = code->next;
	  var = code->expr1->symtree->n.sym;
	  expr2 = code->expr2;
	  if (expr2->expr_type == EXPR_FUNCTION
	      && expr2->value.function.isym
	      && expr2->value.function.isym->id == GFC_ISYM_CONVERSION)
	    expr2 = expr2->value.function.actual->expr;
	}
    }

  gfc_conv_expr (&lse, code->expr1);
  gfc_add_block_to_block (&block, &lse.pre);
  type = TREE_TYPE (lse.expr);
  lhsaddr = gfc_build_addr_expr (NULL, lse.expr);

  if (((atomic_code->ext.omp_clauses->atomic_op & GFC_OMP_ATOMIC_MASK)
       == GFC_OMP_ATOMIC_WRITE)
      || (atomic_code->ext.omp_clauses->atomic_op & GFC_OMP_ATOMIC_SWAP))
    {
      gfc_conv_expr (&rse, expr2);
      gfc_add_block_to_block (&block, &rse.pre);
    }
  else if (expr2->expr_type == EXPR_OP)
    {
      gfc_expr *e;
      switch (expr2->value.op.op)
	{
	case INTRINSIC_PLUS:
	  op = PLUS_EXPR;
	  break;
	case INTRINSIC_TIMES:
	  op = MULT_EXPR;
	  break;
	case INTRINSIC_MINUS:
	  op = MINUS_EXPR;
	  break;
	case INTRINSIC_DIVIDE:
	  if (expr2->ts.type == BT_INTEGER)
	    op = TRUNC_DIV_EXPR;
	  else
	    op = RDIV_EXPR;
	  break;
	case INTRINSIC_AND:
	  op = TRUTH_ANDIF_EXPR;
	  break;
	case INTRINSIC_OR:
	  op = TRUTH_ORIF_EXPR;
	  break;
	case INTRINSIC_EQV:
	  op = EQ_EXPR;
	  break;
	case INTRINSIC_NEQV:
	  op = NE_EXPR;
	  break;
	default:
	  gcc_unreachable ();
	}
      e = expr2->value.op.op1;
      if (e->expr_type == EXPR_FUNCTION
	  && e->value.function.isym
	  && e->value.function.isym->id == GFC_ISYM_CONVERSION)
	e = e->value.function.actual->expr;
      if (e->expr_type == EXPR_VARIABLE
	  && e->symtree != NULL
	  && e->symtree->n.sym == var)
	{
	  expr2 = expr2->value.op.op2;
	  var_on_left = true;
	}
      else
	{
	  e = expr2->value.op.op2;
	  if (e->expr_type == EXPR_FUNCTION
	      && e->value.function.isym
	      && e->value.function.isym->id == GFC_ISYM_CONVERSION)
	    e = e->value.function.actual->expr;
	  gcc_assert (e->expr_type == EXPR_VARIABLE
		      && e->symtree != NULL
		      && e->symtree->n.sym == var);
	  expr2 = expr2->value.op.op1;
	  var_on_left = false;
	}
      gfc_conv_expr (&rse, expr2);
      gfc_add_block_to_block (&block, &rse.pre);
    }
  else
    {
      gcc_assert (expr2->expr_type == EXPR_FUNCTION);
      switch (expr2->value.function.isym->id)
	{
	case GFC_ISYM_MIN:
	  op = MIN_EXPR;
	  break;
	case GFC_ISYM_MAX:
	  op = MAX_EXPR;
	  break;
	case GFC_ISYM_IAND:
	  op = BIT_AND_EXPR;
	  break;
	case GFC_ISYM_IOR:
	  op = BIT_IOR_EXPR;
	  break;
	case GFC_ISYM_IEOR:
	  op = BIT_XOR_EXPR;
	  break;
	default:
	  gcc_unreachable ();
	}
      e = expr2->value.function.actual->expr;
      gcc_assert (e->expr_type == EXPR_VARIABLE
		  && e->symtree != NULL
		  && e->symtree->n.sym == var);

      gfc_conv_expr (&rse, expr2->value.function.actual->next->expr);
      gfc_add_block_to_block (&block, &rse.pre);
      if (expr2->value.function.actual->next->next != NULL)
	{
	  tree accum = gfc_create_var (TREE_TYPE (rse.expr), NULL);
	  gfc_actual_arglist *arg;

	  gfc_add_modify (&block, accum, rse.expr);
	  for (arg = expr2->value.function.actual->next->next; arg;
	       arg = arg->next)
	    {
	      gfc_init_block (&rse.pre);
	      gfc_conv_expr (&rse, arg->expr);
	      gfc_add_block_to_block (&block, &rse.pre);
	      x = fold_build2_loc (input_location, op, TREE_TYPE (accum),
				   accum, rse.expr);
	      gfc_add_modify (&block, accum, x);
	    }

	  rse.expr = accum;
	}

      expr2 = expr2->value.function.actual->next->expr;
    }

  lhsaddr = save_expr (lhsaddr);
  if (TREE_CODE (lhsaddr) != SAVE_EXPR
      && (TREE_CODE (lhsaddr) != ADDR_EXPR
	  || !VAR_P (TREE_OPERAND (lhsaddr, 0))))
    {
      /* Make sure LHS is simple enough so that goa_lhs_expr_p can recognize
	 it even after unsharing function body.  */
      tree var = create_tmp_var_raw (TREE_TYPE (lhsaddr));
      DECL_CONTEXT (var) = current_function_decl;
      lhsaddr = build4 (TARGET_EXPR, TREE_TYPE (lhsaddr), var, lhsaddr,
			NULL_TREE, NULL_TREE);
    }

  rhs = gfc_evaluate_now (rse.expr, &block);

  if (((atomic_code->ext.omp_clauses->atomic_op & GFC_OMP_ATOMIC_MASK)
       == GFC_OMP_ATOMIC_WRITE)
      || (atomic_code->ext.omp_clauses->atomic_op & GFC_OMP_ATOMIC_SWAP))
    x = rhs;
  else
    {
      x = convert (TREE_TYPE (rhs),
		   build_fold_indirect_ref_loc (input_location, lhsaddr));
      if (var_on_left)
	x = fold_build2_loc (input_location, op, TREE_TYPE (rhs), x, rhs);
      else
	x = fold_build2_loc (input_location, op, TREE_TYPE (rhs), rhs, x);
    }

  if (TREE_CODE (TREE_TYPE (rhs)) == COMPLEX_TYPE
      && TREE_CODE (type) != COMPLEX_TYPE)
    x = fold_build1_loc (input_location, REALPART_EXPR,
			 TREE_TYPE (TREE_TYPE (rhs)), x);

  gfc_add_block_to_block (&block, &lse.pre);
  gfc_add_block_to_block (&block, &rse.pre);

  if (aop == OMP_ATOMIC)
    {
      x = build2_v (OMP_ATOMIC, lhsaddr, convert (type, x));
      OMP_ATOMIC_MEMORY_ORDER (x) = mo;
      gfc_add_expr_to_block (&block, x);
    }
  else
    {
      if (aop == OMP_ATOMIC_CAPTURE_NEW)
	{
	  code = code->next;
	  expr2 = code->expr2;
	  if (expr2->expr_type == EXPR_FUNCTION
	      && expr2->value.function.isym
	      && expr2->value.function.isym->id == GFC_ISYM_CONVERSION)
	    expr2 = expr2->value.function.actual->expr;

	  gcc_assert (expr2->expr_type == EXPR_VARIABLE);
	  gfc_conv_expr (&vse, code->expr1);
	  gfc_add_block_to_block (&block, &vse.pre);

	  gfc_init_se (&lse, NULL);
	  gfc_conv_expr (&lse, expr2);
	  gfc_add_block_to_block (&block, &lse.pre);
	}
      x = build2 (aop, type, lhsaddr, convert (type, x));
      OMP_ATOMIC_MEMORY_ORDER (x) = mo;
      x = convert (TREE_TYPE (vse.expr), x);
      gfc_add_modify (&block, vse.expr, x);
    }

  return gfc_finish_block (&block);
}

static tree
gfc_trans_omp_barrier (void)
{
  tree decl = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER);
  return build_call_expr_loc (input_location, decl, 0);
}

static tree
gfc_trans_omp_cancel (gfc_code *code)
{
  int mask = 0;
  tree ifc = boolean_true_node;
  stmtblock_t block;
  switch (code->ext.omp_clauses->cancel)
    {
    case OMP_CANCEL_PARALLEL: mask = 1; break;
    case OMP_CANCEL_DO: mask = 2; break;
    case OMP_CANCEL_SECTIONS: mask = 4; break;
    case OMP_CANCEL_TASKGROUP: mask = 8; break;
    default: gcc_unreachable ();
    }
  gfc_start_block (&block);
  if (code->ext.omp_clauses->if_expr
      || code->ext.omp_clauses->if_exprs[OMP_IF_CANCEL])
    {
      gfc_se se;
      tree if_var;

      gcc_assert ((code->ext.omp_clauses->if_expr == NULL)
		  ^ (code->ext.omp_clauses->if_exprs[OMP_IF_CANCEL] == NULL));
      gfc_init_se (&se, NULL);
      gfc_conv_expr (&se, code->ext.omp_clauses->if_expr != NULL
			  ? code->ext.omp_clauses->if_expr
			  : code->ext.omp_clauses->if_exprs[OMP_IF_CANCEL]);
      gfc_add_block_to_block (&block, &se.pre);
      if_var = gfc_evaluate_now (se.expr, &block);
      gfc_add_block_to_block (&block, &se.post);
      tree type = TREE_TYPE (if_var);
      ifc = fold_build2_loc (input_location, NE_EXPR,
			     boolean_type_node, if_var,
			     build_zero_cst (type));
    }
  tree decl = builtin_decl_explicit (BUILT_IN_GOMP_CANCEL);
  tree c_bool_type = TREE_TYPE (TREE_TYPE (decl));
  ifc = fold_convert (c_bool_type, ifc);
  gfc_add_expr_to_block (&block,
			 build_call_expr_loc (input_location, decl, 2,
					      build_int_cst (integer_type_node,
							     mask), ifc));
  return gfc_finish_block (&block);
}

static tree
gfc_trans_omp_cancellation_point (gfc_code *code)
{
  int mask = 0;
  switch (code->ext.omp_clauses->cancel)
    {
    case OMP_CANCEL_PARALLEL: mask = 1; break;
    case OMP_CANCEL_DO: mask = 2; break;
    case OMP_CANCEL_SECTIONS: mask = 4; break;
    case OMP_CANCEL_TASKGROUP: mask = 8; break;
    default: gcc_unreachable ();
    }
  tree decl = builtin_decl_explicit (BUILT_IN_GOMP_CANCELLATION_POINT);
  return build_call_expr_loc (input_location, decl, 1,
			      build_int_cst (integer_type_node, mask));
}

static tree
gfc_trans_omp_critical (gfc_code *code)
{
  stmtblock_t block;
  tree stmt, name = NULL_TREE;
  if (code->ext.omp_clauses->critical_name != NULL)
    name = get_identifier (code->ext.omp_clauses->critical_name);
  gfc_start_block (&block);
  stmt = make_node (OMP_CRITICAL);
  TREE_TYPE (stmt) = void_type_node;
  OMP_CRITICAL_BODY (stmt) = gfc_trans_code (code->block->next);
  OMP_CRITICAL_NAME (stmt) = name;
  OMP_CRITICAL_CLAUSES (stmt) = gfc_trans_omp_clauses (&block,
						       code->ext.omp_clauses,
						       code->loc);
  gfc_add_expr_to_block (&block, stmt);
  return gfc_finish_block (&block);
}

typedef struct dovar_init_d {
  tree var;
  tree init;
} dovar_init;


static tree
gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock,
		  gfc_omp_clauses *do_clauses, tree par_clauses)
{
  gfc_se se;
  tree dovar, stmt, from, to, step, type, init, cond, incr, orig_decls;
  tree count = NULL_TREE, cycle_label, tmp, omp_clauses;
  stmtblock_t block;
  stmtblock_t body;
  gfc_omp_clauses *clauses = code->ext.omp_clauses;
  int i, collapse = clauses->collapse;
  vec<dovar_init> inits = vNULL;
  dovar_init *di;
  unsigned ix;
  vec<tree, va_heap, vl_embed> *saved_doacross_steps = doacross_steps;
  gfc_expr_list *tile = do_clauses ? do_clauses->tile_list : clauses->tile_list;

  /* Both collapsed and tiled loops are lowered the same way.  In
     OpenACC, those clauses are not compatible, so prioritize the tile
     clause, if present.  */
  if (tile)
    {
      collapse = 0;
      for (gfc_expr_list *el = tile; el; el = el->next)
	collapse++;
    }

  doacross_steps = NULL;
  if (clauses->orderedc)
    collapse = clauses->orderedc;
  if (collapse <= 0)
    collapse = 1;

  code = code->block->next;
  gcc_assert (code->op == EXEC_DO);

  init = make_tree_vec (collapse);
  cond = make_tree_vec (collapse);
  incr = make_tree_vec (collapse);
  orig_decls = clauses->orderedc ? make_tree_vec (collapse) : NULL_TREE;

  if (pblock == NULL)
    {
      gfc_start_block (&block);
      pblock = &block;
    }

  /* simd schedule modifier is only useful for composite do simd and other
     constructs including that, where gfc_trans_omp_do is only called
     on the simd construct and DO's clauses are translated elsewhere.  */
  do_clauses->sched_simd = false;

  omp_clauses = gfc_trans_omp_clauses (pblock, do_clauses, code->loc);

  for (i = 0; i < collapse; i++)
    {
      int simple = 0;
      int dovar_found = 0;
      tree dovar_decl;

      if (clauses)
	{
	  gfc_omp_namelist *n = NULL;
	  if (op == EXEC_OMP_SIMD && collapse == 1)
	    for (n = clauses->lists[OMP_LIST_LINEAR];
		 n != NULL; n = n->next)
	      if (code->ext.iterator->var->symtree->n.sym == n->sym)
		{
		  dovar_found = 3;
		  break;
		}
	  if (n == NULL && op != EXEC_OMP_DISTRIBUTE)
	    for (n = clauses->lists[OMP_LIST_LASTPRIVATE];
		 n != NULL; n = n->next)
	      if (code->ext.iterator->var->symtree->n.sym == n->sym)
		{
		  dovar_found = 2;
		  break;
		}
	  if (n == NULL)
	    for (n = clauses->lists[OMP_LIST_PRIVATE]; n != NULL; n = n->next)
	      if (code->ext.iterator->var->symtree->n.sym == n->sym)
		{
		  dovar_found = 1;
		  break;
		}
	}

      /* Evaluate all the expressions in the iterator.  */
      gfc_init_se (&se, NULL);
      gfc_conv_expr_lhs (&se, code->ext.iterator->var);
      gfc_add_block_to_block (pblock, &se.pre);
      dovar = se.expr;
      type = TREE_TYPE (dovar);
      gcc_assert (TREE_CODE (type) == INTEGER_TYPE);

      gfc_init_se (&se, NULL);
      gfc_conv_expr_val (&se, code->ext.iterator->start);
      gfc_add_block_to_block (pblock, &se.pre);
      from = gfc_evaluate_now (se.expr, pblock);

      gfc_init_se (&se, NULL);
      gfc_conv_expr_val (&se, code->ext.iterator->end);
      gfc_add_block_to_block (pblock, &se.pre);
      to = gfc_evaluate_now (se.expr, pblock);

      gfc_init_se (&se, NULL);
      gfc_conv_expr_val (&se, code->ext.iterator->step);
      gfc_add_block_to_block (pblock, &se.pre);
      step = gfc_evaluate_now (se.expr, pblock);
      dovar_decl = dovar;

      /* Special case simple loops.  */
      if (VAR_P (dovar))
	{
	  if (integer_onep (step))
	    simple = 1;
	  else if (tree_int_cst_equal (step, integer_minus_one_node))
	    simple = -1;
	}
      else
	dovar_decl
	  = gfc_trans_omp_variable (code->ext.iterator->var->symtree->n.sym,
				    false);

      /* Loop body.  */
      if (simple)
	{
	  TREE_VEC_ELT (init, i) = build2_v (MODIFY_EXPR, dovar, from);
	  /* The condition should not be folded.  */
	  TREE_VEC_ELT (cond, i) = build2_loc (input_location, simple > 0
					       ? LE_EXPR : GE_EXPR,
					       logical_type_node, dovar, to);
	  TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location, PLUS_EXPR,
						    type, dovar, step);
	  TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location,
						    MODIFY_EXPR,
						    type, dovar,
						    TREE_VEC_ELT (incr, i));
	}
      else
	{
	  /* STEP is not 1 or -1.  Use:
	     for (count = 0; count < (to + step - from) / step; count++)
	       {
		 dovar = from + count * step;
		 body;
	       cycle_label:;
	       }  */
	  tmp = fold_build2_loc (input_location, MINUS_EXPR, type, step, from);
	  tmp = fold_build2_loc (input_location, PLUS_EXPR, type, to, tmp);
	  tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, type, tmp,
				 step);
	  tmp = gfc_evaluate_now (tmp, pblock);
	  count = gfc_create_var (type, "count");
	  TREE_VEC_ELT (init, i) = build2_v (MODIFY_EXPR, count,
					     build_int_cst (type, 0));
	  /* The condition should not be folded.  */
	  TREE_VEC_ELT (cond, i) = build2_loc (input_location, LT_EXPR,
					       logical_type_node,
					       count, tmp);
	  TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location, PLUS_EXPR,
						    type, count,
						    build_int_cst (type, 1));
	  TREE_VEC_ELT (incr, i) = fold_build2_loc (input_location,
						    MODIFY_EXPR, type, count,
						    TREE_VEC_ELT (incr, i));

	  /* Initialize DOVAR.  */
	  tmp = fold_build2_loc (input_location, MULT_EXPR, type, count, step);
	  tmp = fold_build2_loc (input_location, PLUS_EXPR, type, from, tmp);
	  dovar_init e = {dovar, tmp};
	  inits.safe_push (e);
	  if (clauses->orderedc)
	    {
	      if (doacross_steps == NULL)
		vec_safe_grow_cleared (doacross_steps, clauses->orderedc, true);
	      (*doacross_steps)[i] = step;
	    }
	}
      if (orig_decls)
	TREE_VEC_ELT (orig_decls, i) = dovar_decl;

      if (dovar_found == 3
	  && op == EXEC_OMP_SIMD
	  && collapse == 1
	  && !simple)
	{
	  for (tmp = omp_clauses; tmp; tmp = OMP_CLAUSE_CHAIN (tmp))
	    if (OMP_CLAUSE_CODE (tmp) == OMP_CLAUSE_LINEAR
		&& OMP_CLAUSE_DECL (tmp) == dovar)
	      {
		OMP_CLAUSE_LINEAR_NO_COPYIN (tmp) = 1;
		break;
	      }
	}
      if (!dovar_found && op == EXEC_OMP_SIMD)
	{
	  if (collapse == 1)
	    {
	      tmp = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
	      OMP_CLAUSE_LINEAR_STEP (tmp) = step;
	      OMP_CLAUSE_LINEAR_NO_COPYIN (tmp) = 1;
	      OMP_CLAUSE_DECL (tmp) = dovar_decl;
	      omp_clauses = gfc_trans_add_clause (tmp, omp_clauses);
	    }
	  if (!simple)
	    dovar_found = 3;
	}
      else if (!dovar_found && !simple)
	{
	  tmp = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
	  OMP_CLAUSE_DECL (tmp) = dovar_decl;
	  omp_clauses = gfc_trans_add_clause (tmp, omp_clauses);
	}
      if (dovar_found > 1)
	{
	  tree c = NULL;

	  tmp = NULL;
	  if (!simple)
	    {
	      /* If dovar is lastprivate, but different counter is used,
		 dovar += step needs to be added to
		 OMP_CLAUSE_LASTPRIVATE_STMT, otherwise the copied dovar
		 will have the value on entry of the last loop, rather
		 than value after iterator increment.  */
	      if (clauses->orderedc)
		{
		  if (clauses->collapse <= 1 || i >= clauses->collapse)
		    tmp = count;
		  else
		    tmp = fold_build2_loc (input_location, PLUS_EXPR,
					   type, count, build_one_cst (type));
		  tmp = fold_build2_loc (input_location, MULT_EXPR, type,
					 tmp, step);
		  tmp = fold_build2_loc (input_location, PLUS_EXPR, type,
					 from, tmp);
		}
	      else
		{
		  tmp = gfc_evaluate_now (step, pblock);
		  tmp = fold_build2_loc (input_location, PLUS_EXPR, type,
					 dovar, tmp);
		}
	      tmp = fold_build2_loc (input_location, MODIFY_EXPR, type,
				     dovar, tmp);
	      for (c = omp_clauses; c ; c = OMP_CLAUSE_CHAIN (c))
		if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
		    && OMP_CLAUSE_DECL (c) == dovar_decl)
		  {
		    OMP_CLAUSE_LASTPRIVATE_STMT (c) = tmp;
		    break;
		  }
		else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
			 && OMP_CLAUSE_DECL (c) == dovar_decl)
		  {
		    OMP_CLAUSE_LINEAR_STMT (c) = tmp;
		    break;
		  }
	    }
	  if (c == NULL && op == EXEC_OMP_DO && par_clauses != NULL)
	    {
	      for (c = par_clauses; c ; c = OMP_CLAUSE_CHAIN (c))
		if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
		    && OMP_CLAUSE_DECL (c) == dovar_decl)
		  {
		    tree l = build_omp_clause (input_location,
					       OMP_CLAUSE_LASTPRIVATE);
		    if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
		      OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (l) = 1;
		    OMP_CLAUSE_DECL (l) = dovar_decl;
		    OMP_CLAUSE_CHAIN (l) = omp_clauses;
		    OMP_CLAUSE_LASTPRIVATE_STMT (l) = tmp;
		    omp_clauses = l;
		    OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_SHARED);
		    break;
		  }
	    }
	  gcc_assert (simple || c != NULL);
	}
      if (!simple)
	{
	  if (op != EXEC_OMP_SIMD || dovar_found == 1)
	    tmp = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
	  else if (collapse == 1)
	    {
	      tmp = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
	      OMP_CLAUSE_LINEAR_STEP (tmp) = build_int_cst (type, 1);
	      OMP_CLAUSE_LINEAR_NO_COPYIN (tmp) = 1;
	      OMP_CLAUSE_LINEAR_NO_COPYOUT (tmp) = 1;
	    }
	  else
	    tmp = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
	  OMP_CLAUSE_DECL (tmp) = count;
	  omp_clauses = gfc_trans_add_clause (tmp, omp_clauses);
	}

      if (i + 1 < collapse)
	code = code->block->next;
    }

  if (pblock != &block)
    {
      pushlevel ();
      gfc_start_block (&block);
    }

  gfc_start_block (&body);

  FOR_EACH_VEC_ELT (inits, ix, di)
    gfc_add_modify (&body, di->var, di->init);
  inits.release ();

  /* Cycle statement is implemented with a goto.  Exit statement must not be
     present for this loop.  */
  cycle_label = gfc_build_label_decl (NULL_TREE);

  /* Put these labels where they can be found later.  */

  code->cycle_label = cycle_label;
  code->exit_label = NULL_TREE;

  /* Main loop body.  */
  if (clauses->lists[OMP_LIST_REDUCTION_INSCAN])
    {
      gcc_assert (code->block->next->next->op == EXEC_OMP_SCAN);
      gcc_assert (code->block->next->next->next->next == NULL);
      locus *cloc = &code->block->next->next->loc;
      location_t loc = gfc_get_location (cloc);

      gfc_code code2 = *code->block->next;
      code2.next = NULL;
      tmp = gfc_trans_code (&code2);
      tmp = build2 (OMP_SCAN, void_type_node, tmp, NULL_TREE);
      SET_EXPR_LOCATION (tmp, loc);
      gfc_add_expr_to_block (&body, tmp);
      input_location = loc;
      tree c = gfc_trans_omp_clauses (&body,
				      code->block->next->next->ext.omp_clauses,
				      *cloc);
      code2 = *code->block->next->next->next;
      code2.next = NULL;
      tmp = gfc_trans_code (&code2);
      tmp = build2 (OMP_SCAN, void_type_node, tmp, c);
      SET_EXPR_LOCATION (tmp, loc);
    }
  else
    tmp = gfc_trans_omp_code (code->block->next, true);
  gfc_add_expr_to_block (&body, tmp);

  /* Label for cycle statements (if needed).  */
  if (TREE_USED (cycle_label))
    {
      tmp = build1_v (LABEL_EXPR, cycle_label);
      gfc_add_expr_to_block (&body, tmp);
    }

  /* End of loop body.  */
  switch (op)
    {
    case EXEC_OMP_SIMD: stmt = make_node (OMP_SIMD); break;
    case EXEC_OMP_DO: stmt = make_node (OMP_FOR); break;
    case EXEC_OMP_DISTRIBUTE: stmt = make_node (OMP_DISTRIBUTE); break;
    case EXEC_OMP_LOOP: stmt = make_node (OMP_LOOP); break;
    case EXEC_OMP_TASKLOOP: stmt = make_node (OMP_TASKLOOP); break;
    case EXEC_OACC_LOOP: stmt = make_node (OACC_LOOP); break;
    default: gcc_unreachable ();
    }

  TREE_TYPE (stmt) = void_type_node;
  OMP_FOR_BODY (stmt) = gfc_finish_block (&body);
  OMP_FOR_CLAUSES (stmt) = omp_clauses;
  OMP_FOR_INIT (stmt) = init;
  OMP_FOR_COND (stmt) = cond;
  OMP_FOR_INCR (stmt) = incr;
  if (orig_decls)
    OMP_FOR_ORIG_DECLS (stmt) = orig_decls;
  gfc_add_expr_to_block (&block, stmt);

  vec_free (doacross_steps);
  doacross_steps = saved_doacross_steps;

  return gfc_finish_block (&block);
}

/* Translate combined OpenACC 'parallel loop', 'kernels loop', 'serial loop'
   construct. */

static tree
gfc_trans_oacc_combined_directive (gfc_code *code)
{
  stmtblock_t block, *pblock = NULL;
  gfc_omp_clauses construct_clauses, loop_clauses;
  tree stmt, oacc_clauses = NULL_TREE;
  enum tree_code construct_code;
  location_t loc = input_location;

  switch (code->op)
    {
      case EXEC_OACC_PARALLEL_LOOP:
	construct_code = OACC_PARALLEL;
	break;
      case EXEC_OACC_KERNELS_LOOP:
	construct_code = OACC_KERNELS;
	break;
      case EXEC_OACC_SERIAL_LOOP:
	construct_code = OACC_SERIAL;
	break;
      default:
	gcc_unreachable ();
    }

  gfc_start_block (&block);

  memset (&loop_clauses, 0, sizeof (loop_clauses));
  if (code->ext.omp_clauses != NULL)
    {
      memcpy (&construct_clauses, code->ext.omp_clauses,
	      sizeof (construct_clauses));
      loop_clauses.collapse = construct_clauses.collapse;
      loop_clauses.gang = construct_clauses.gang;
      loop_clauses.gang_static = construct_clauses.gang_static;
      loop_clauses.gang_num_expr = construct_clauses.gang_num_expr;
      loop_clauses.gang_static_expr = construct_clauses.gang_static_expr;
      loop_clauses.vector = construct_clauses.vector;
      loop_clauses.vector_expr = construct_clauses.vector_expr;
      loop_clauses.worker = construct_clauses.worker;
      loop_clauses.worker_expr = construct_clauses.worker_expr;
      loop_clauses.seq = construct_clauses.seq;
      loop_clauses.par_auto = construct_clauses.par_auto;
      loop_clauses.independent = construct_clauses.independent;
      loop_clauses.tile_list = construct_clauses.tile_list;
      loop_clauses.lists[OMP_LIST_PRIVATE]
	= construct_clauses.lists[OMP_LIST_PRIVATE];
      loop_clauses.lists[OMP_LIST_REDUCTION]
	= construct_clauses.lists[OMP_LIST_REDUCTION];
      construct_clauses.gang = false;
      construct_clauses.gang_static = false;
      construct_clauses.gang_num_expr = NULL;
      construct_clauses.gang_static_expr = NULL;
      construct_clauses.vector = false;
      construct_clauses.vector_expr = NULL;
      construct_clauses.worker = false;
      construct_clauses.worker_expr = NULL;
      construct_clauses.seq = false;
      construct_clauses.par_auto = false;
      construct_clauses.independent = false;
      construct_clauses.independent = false;
      construct_clauses.tile_list = NULL;
      construct_clauses.lists[OMP_LIST_PRIVATE] = NULL;
      if (construct_code == OACC_KERNELS)
	construct_clauses.lists[OMP_LIST_REDUCTION] = NULL;
      oacc_clauses = gfc_trans_omp_clauses (&block, &construct_clauses,
					    code->loc, false, true);
    }
  if (!loop_clauses.seq)
    pblock = &block;
  else
    pushlevel ();
  stmt = gfc_trans_omp_do (code, EXEC_OACC_LOOP, pblock, &loop_clauses, NULL);
  protected_set_expr_location (stmt, loc);
  if (TREE_CODE (stmt) != BIND_EXPR)
    stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
  else
    poplevel (0, 0);
  stmt = build2_loc (loc, construct_code, void_type_node, stmt, oacc_clauses);
  gfc_add_expr_to_block (&block, stmt);
  return gfc_finish_block (&block);
}

static tree
gfc_trans_omp_depobj (gfc_code *code)
{
  stmtblock_t block;
  gfc_se se;
  gfc_init_se (&se, NULL);
  gfc_init_block (&block);
  gfc_conv_expr (&se, code->ext.omp_clauses->depobj);
  gcc_assert (se.pre.head == NULL && se.post.head == NULL);
  tree depobj = se.expr;
  location_t loc = EXPR_LOCATION (depobj);
  if (!POINTER_TYPE_P (TREE_TYPE (depobj)))
    depobj = gfc_build_addr_expr (NULL, depobj);
  depobj = fold_convert (build_pointer_type_for_mode (ptr_type_node,
						      TYPE_MODE (ptr_type_node),
						      true), depobj);
  gfc_omp_namelist *n = code->ext.omp_clauses->lists[OMP_LIST_DEPEND];
  if (n)
    {
      tree var;
      if (n->expr)
        var = gfc_convert_expr_to_tree (&block, n->expr);
      else
	var = gfc_get_symbol_decl (n->sym);
      if (!POINTER_TYPE_P (TREE_TYPE (var)))
        var = gfc_build_addr_expr (NULL, var);
      depobj = save_expr (depobj);
      tree r = build_fold_indirect_ref_loc (loc, depobj);
      gfc_add_expr_to_block (&block,
			     build2 (MODIFY_EXPR, void_type_node, r, var));
    }

  /* Only one may be set. */
  gcc_assert (((int)(n != NULL) + (int)(code->ext.omp_clauses->destroy)
	      + (int)(code->ext.omp_clauses->depobj_update != OMP_DEPEND_UNSET))
	      == 1);
  int k = -1; /* omp_clauses->destroy */
  if (!code->ext.omp_clauses->destroy)
    switch (code->ext.omp_clauses->depobj_update != OMP_DEPEND_UNSET
	    ? code->ext.omp_clauses->depobj_update : n->u.depend_op)
      {
      case OMP_DEPEND_IN: k = GOMP_DEPEND_IN; break;
      case OMP_DEPEND_OUT: k = GOMP_DEPEND_OUT; break;
      case OMP_DEPEND_INOUT: k = GOMP_DEPEND_INOUT; break;
      case OMP_DEPEND_MUTEXINOUTSET: k = GOMP_DEPEND_MUTEXINOUTSET; break;
      default: gcc_unreachable ();
      }
  tree t = build_int_cst (ptr_type_node, k);
  depobj = build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (depobj), depobj,
                       TYPE_SIZE_UNIT (ptr_type_node));
  depobj = build_fold_indirect_ref_loc (loc, depobj);
  gfc_add_expr_to_block (&block, build2 (MODIFY_EXPR, void_type_node, depobj, t));

  return gfc_finish_block (&block);
}

static tree
gfc_trans_omp_flush (gfc_code *code)
{
  tree call;
  if (!code->ext.omp_clauses
      || code->ext.omp_clauses->memorder == OMP_MEMORDER_UNSET)
    {
      call = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE);
      call = build_call_expr_loc (input_location, call, 0);
    }
  else
    {
      enum memmodel mo = MEMMODEL_LAST;
      switch (code->ext.omp_clauses->memorder)
	{
	case OMP_MEMORDER_ACQ_REL: mo = MEMMODEL_ACQ_REL; break;
	case OMP_MEMORDER_RELEASE: mo = MEMMODEL_RELEASE; break;
	case OMP_MEMORDER_ACQUIRE: mo = MEMMODEL_ACQUIRE; break;
	default: gcc_unreachable (); break;
	}
      call = builtin_decl_explicit (BUILT_IN_ATOMIC_THREAD_FENCE);
      call = build_call_expr_loc (input_location, call, 1,
				  build_int_cst (integer_type_node, mo));
    }
  return call;
}

static tree
gfc_trans_omp_master (gfc_code *code)
{
  tree stmt = gfc_trans_code (code->block->next);
  if (IS_EMPTY_STMT (stmt))
    return stmt;
  return build1_v (OMP_MASTER, stmt);
}

static tree
gfc_trans_omp_ordered (gfc_code *code)
{
  if (!flag_openmp)
    {
      if (!code->ext.omp_clauses->simd)
	return gfc_trans_code (code->block ? code->block->next : NULL);
      code->ext.omp_clauses->threads = 0;
    }
  tree omp_clauses = gfc_trans_omp_clauses (NULL, code->ext.omp_clauses,
					    code->loc);
  return build2_loc (input_location, OMP_ORDERED, void_type_node,
		     code->block ? gfc_trans_code (code->block->next)
		     : NULL_TREE, omp_clauses);
}

static tree
gfc_trans_omp_parallel (gfc_code *code)
{
  stmtblock_t block;
  tree stmt, omp_clauses;

  gfc_start_block (&block);
  omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
				       code->loc);
  pushlevel ();
  stmt = gfc_trans_omp_code (code->block->next, true);
  stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
  stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
		     omp_clauses);
  gfc_add_expr_to_block (&block, stmt);
  return gfc_finish_block (&block);
}

enum
{
  GFC_OMP_SPLIT_SIMD,
  GFC_OMP_SPLIT_DO,
  GFC_OMP_SPLIT_PARALLEL,
  GFC_OMP_SPLIT_DISTRIBUTE,
  GFC_OMP_SPLIT_TEAMS,
  GFC_OMP_SPLIT_TARGET,
  GFC_OMP_SPLIT_TASKLOOP,
  GFC_OMP_SPLIT_NUM
};

enum
{
  GFC_OMP_MASK_SIMD = (1 << GFC_OMP_SPLIT_SIMD),
  GFC_OMP_MASK_DO = (1 << GFC_OMP_SPLIT_DO),
  GFC_OMP_MASK_PARALLEL = (1 << GFC_OMP_SPLIT_PARALLEL),
  GFC_OMP_MASK_DISTRIBUTE = (1 << GFC_OMP_SPLIT_DISTRIBUTE),
  GFC_OMP_MASK_TEAMS = (1 << GFC_OMP_SPLIT_TEAMS),
  GFC_OMP_MASK_TARGET = (1 << GFC_OMP_SPLIT_TARGET),
  GFC_OMP_MASK_TASKLOOP = (1 << GFC_OMP_SPLIT_TASKLOOP)
};

/* If a var is in lastprivate/firstprivate/reduction but not in a
   data mapping/sharing clause, add it to 'map(tofrom:' if is_target
   and to 'shared' otherwise.  */
static void
gfc_add_clause_implicitly (gfc_omp_clauses *clauses_out,
			   gfc_omp_clauses *clauses_in,
			   bool is_target, bool is_parallel_do)
{
  int clauselist_to_add = is_target ? OMP_LIST_MAP : OMP_LIST_SHARED;
  gfc_omp_namelist *tail = NULL;
  for (int i = 0; i < 5; ++i)
    {
      gfc_omp_namelist *n;
      switch (i)
	{
	case 0: n = clauses_in->lists[OMP_LIST_FIRSTPRIVATE]; break;
	case 1: n = clauses_in->lists[OMP_LIST_LASTPRIVATE]; break;
	case 2: n = clauses_in->lists[OMP_LIST_REDUCTION]; break;
	case 3: n = clauses_in->lists[OMP_LIST_REDUCTION_INSCAN]; break;
	case 4: n = clauses_in->lists[OMP_LIST_REDUCTION_TASK]; break;
	default: gcc_unreachable ();
	}
      for (; n != NULL; n = n->next)
	{
	  gfc_omp_namelist *n2, **n_firstp = NULL, **n_lastp = NULL;
	  for (int j = 0; j < 6; ++j)
	    {
	      gfc_omp_namelist **n2ref = NULL, *prev2 = NULL;
	      switch (j)
		{
		case 0:
		  n2ref = &clauses_out->lists[clauselist_to_add];
		  break;
		case 1:
		  n2ref = &clauses_out->lists[OMP_LIST_FIRSTPRIVATE];
		  break;
		case 2:
		  if (is_target)
		    n2ref = &clauses_in->lists[OMP_LIST_LASTPRIVATE];
		  else
		    n2ref = &clauses_out->lists[OMP_LIST_LASTPRIVATE];
		  break;
		case 3: n2ref = &clauses_out->lists[OMP_LIST_REDUCTION]; break;
		case 4:
		  n2ref = &clauses_out->lists[OMP_LIST_REDUCTION_INSCAN];
		  break;
		case 5:
		  n2ref = &clauses_out->lists[OMP_LIST_REDUCTION_TASK];
		  break;
		default: gcc_unreachable ();
		}
	      for (n2 = *n2ref; n2 != NULL; prev2 = n2, n2 = n2->next)
		if (n2->sym == n->sym)
		  break;
	      if (n2)
		{
		  if (j == 0 /* clauselist_to_add */)
		    break;  /* Already present.  */
		  if (j == 1 /* OMP_LIST_FIRSTPRIVATE */)
		    {
		      n_firstp = prev2 ? &prev2->next : n2ref;
		      continue;
		    }
		  if (j == 2 /* OMP_LIST_LASTPRIVATE */)
		    {
		      n_lastp = prev2 ? &prev2->next : n2ref;
		      continue;
		    }
		  break;
		}
	    }
	  if (n_firstp && n_lastp)
	    {
	      /* For parallel do, GCC puts firstprivatee/lastprivate
		 on the parallel.  */
	      if (is_parallel_do)
		continue;
	      *n_firstp = (*n_firstp)->next;
	      if (!is_target)
		*n_lastp = (*n_lastp)->next;
	    }
	  else if (is_target && n_lastp)
	    ;
	  else if (n2 || n_firstp || n_lastp)
	    continue;
	  if (clauses_out->lists[clauselist_to_add]
	      && (clauses_out->lists[clauselist_to_add]
		  == clauses_in->lists[clauselist_to_add]))
	    {
	      gfc_omp_namelist *p = NULL;
	      for (n2 = clauses_in->lists[clauselist_to_add]; n2; n2 = n2->next)
		{
		  if (p)
		    {
		      p->next = gfc_get_omp_namelist ();
		      p = p->next;
		    }
		  else
		    {
		      p = gfc_get_omp_namelist ();
		      clauses_out->lists[clauselist_to_add] = p;
		    }
		  *p = *n2;
		}
	    }
	  if (!tail)
	    {
	      tail = clauses_out->lists[clauselist_to_add];
	      for (; tail && tail->next; tail = tail->next)
		;
	    }
	  n2 = gfc_get_omp_namelist ();
	  n2->where = n->where;
	  n2->sym = n->sym;
	  if (is_target)
	    n2->u.map_op = OMP_MAP_TOFROM;
	  if (tail)
	    {
	      tail->next = n2;
	      tail = n2;
	    }
	  else
	    clauses_out->lists[clauselist_to_add] = n2;
	}
    }
}

static void
gfc_free_split_omp_clauses (gfc_code *code, gfc_omp_clauses *clausesa)
{
  for (int i = 0; i < GFC_OMP_SPLIT_NUM; ++i)
    for (int j = 0; j < OMP_LIST_NUM; ++j)
      if (clausesa[i].lists[j] && clausesa[i].lists[j] != code->ext.omp_clauses->lists[j])
	for (gfc_omp_namelist *n = clausesa[i].lists[j]; n;)
	  {
	    gfc_omp_namelist *p = n;
	    n = n->next;
	    free (p);
	  }
}

static void
gfc_split_omp_clauses (gfc_code *code,
		       gfc_omp_clauses clausesa[GFC_OMP_SPLIT_NUM])
{
  int mask = 0, innermost = 0;
  bool is_loop = false;
  memset (clausesa, 0, GFC_OMP_SPLIT_NUM * sizeof (gfc_omp_clauses));
  switch (code->op)
    {
    case EXEC_OMP_DISTRIBUTE:
      innermost = GFC_OMP_SPLIT_DISTRIBUTE;
      break;
    case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
      mask = GFC_OMP_MASK_DISTRIBUTE | GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO;
      innermost = GFC_OMP_SPLIT_DO;
      break;
    case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
      mask = GFC_OMP_MASK_DISTRIBUTE | GFC_OMP_MASK_PARALLEL
	     | GFC_OMP_MASK_DO | GFC_OMP_MASK_SIMD;
      innermost = GFC_OMP_SPLIT_SIMD;
      break;
    case EXEC_OMP_DISTRIBUTE_SIMD:
      mask = GFC_OMP_MASK_DISTRIBUTE | GFC_OMP_MASK_SIMD;
      innermost = GFC_OMP_SPLIT_SIMD;
      break;
    case EXEC_OMP_DO:
    case EXEC_OMP_LOOP:
      innermost = GFC_OMP_SPLIT_DO;
      break;
    case EXEC_OMP_DO_SIMD:
      mask = GFC_OMP_MASK_DO | GFC_OMP_MASK_SIMD;
      innermost = GFC_OMP_SPLIT_SIMD;
      break;
    case EXEC_OMP_PARALLEL:
      innermost = GFC_OMP_SPLIT_PARALLEL;
      break;
    case EXEC_OMP_PARALLEL_DO:
    case EXEC_OMP_PARALLEL_LOOP:
      mask = GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO;
      innermost = GFC_OMP_SPLIT_DO;
      break;
    case EXEC_OMP_PARALLEL_DO_SIMD:
      mask = GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO | GFC_OMP_MASK_SIMD;
      innermost = GFC_OMP_SPLIT_SIMD;
      break;
    case EXEC_OMP_PARALLEL_MASTER_TASKLOOP:
      mask = GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_TASKLOOP | GFC_OMP_MASK_SIMD;
      innermost = GFC_OMP_SPLIT_TASKLOOP;
      break;
    case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD:
      mask = GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_TASKLOOP | GFC_OMP_MASK_SIMD;
      innermost = GFC_OMP_SPLIT_SIMD;
      break;
    case EXEC_OMP_SIMD:
      innermost = GFC_OMP_SPLIT_SIMD;
      break;
    case EXEC_OMP_TARGET:
      innermost = GFC_OMP_SPLIT_TARGET;
      break;
    case EXEC_OMP_TARGET_PARALLEL:
      mask = GFC_OMP_MASK_TARGET | GFC_OMP_MASK_PARALLEL;
      innermost = GFC_OMP_SPLIT_PARALLEL;
      break;
    case EXEC_OMP_TARGET_PARALLEL_DO:
    case EXEC_OMP_TARGET_PARALLEL_LOOP:
      mask = GFC_OMP_MASK_TARGET | GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO;
      innermost = GFC_OMP_SPLIT_DO;
      break;
    case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
      mask = GFC_OMP_MASK_TARGET | GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO
	     | GFC_OMP_MASK_SIMD;
      innermost = GFC_OMP_SPLIT_SIMD;
      break;
    case EXEC_OMP_TARGET_SIMD:
      mask = GFC_OMP_MASK_TARGET | GFC_OMP_MASK_SIMD;
      innermost = GFC_OMP_SPLIT_SIMD;
      break;
    case EXEC_OMP_TARGET_TEAMS:
      mask = GFC_OMP_MASK_TARGET | GFC_OMP_MASK_TEAMS;
      innermost = GFC_OMP_SPLIT_TEAMS;
      break;
    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
      mask = GFC_OMP_MASK_TARGET | GFC_OMP_MASK_TEAMS
	     | GFC_OMP_MASK_DISTRIBUTE;
      innermost = GFC_OMP_SPLIT_DISTRIBUTE;
      break;
    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
      mask = GFC_OMP_MASK_TARGET | GFC_OMP_MASK_TEAMS | GFC_OMP_MASK_DISTRIBUTE
	     | GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO;
      innermost = GFC_OMP_SPLIT_DO;
      break;
    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
      mask = GFC_OMP_MASK_TARGET | GFC_OMP_MASK_TEAMS | GFC_OMP_MASK_DISTRIBUTE
	     | GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO | GFC_OMP_MASK_SIMD;
      innermost = GFC_OMP_SPLIT_SIMD;
      break;
    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
      mask = GFC_OMP_MASK_TARGET | GFC_OMP_MASK_TEAMS
	     | GFC_OMP_MASK_DISTRIBUTE | GFC_OMP_MASK_SIMD;
      innermost = GFC_OMP_SPLIT_SIMD;
      break;
    case EXEC_OMP_TARGET_TEAMS_LOOP:
      mask = GFC_OMP_MASK_TARGET | GFC_OMP_MASK_TEAMS | GFC_OMP_MASK_DO;
      innermost = GFC_OMP_SPLIT_DO;
      break;
    case EXEC_OMP_MASTER_TASKLOOP:
    case EXEC_OMP_TASKLOOP:
      innermost = GFC_OMP_SPLIT_TASKLOOP;
      break;
    case EXEC_OMP_MASTER_TASKLOOP_SIMD:
    case EXEC_OMP_TASKLOOP_SIMD:
      mask = GFC_OMP_MASK_TASKLOOP | GFC_OMP_MASK_SIMD;
      innermost = GFC_OMP_SPLIT_SIMD;
      break;
    case EXEC_OMP_TEAMS:
      innermost = GFC_OMP_SPLIT_TEAMS;
      break;
    case EXEC_OMP_TEAMS_DISTRIBUTE:
      mask = GFC_OMP_MASK_TEAMS | GFC_OMP_MASK_DISTRIBUTE;
      innermost = GFC_OMP_SPLIT_DISTRIBUTE;
      break;
    case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
      mask = GFC_OMP_MASK_TEAMS | GFC_OMP_MASK_DISTRIBUTE
	     | GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO;
      innermost = GFC_OMP_SPLIT_DO;
      break;
    case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
      mask = GFC_OMP_MASK_TEAMS | GFC_OMP_MASK_DISTRIBUTE
	     | GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO | GFC_OMP_MASK_SIMD;
      innermost = GFC_OMP_SPLIT_SIMD;
      break;
    case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
      mask = GFC_OMP_MASK_TEAMS | GFC_OMP_MASK_DISTRIBUTE | GFC_OMP_MASK_SIMD;
      innermost = GFC_OMP_SPLIT_SIMD;
      break;
    case EXEC_OMP_TEAMS_LOOP:
      mask = GFC_OMP_MASK_TEAMS | GFC_OMP_MASK_DO;
      innermost = GFC_OMP_SPLIT_DO;
      break;
    default:
      gcc_unreachable ();
    }
  if (mask == 0)
    {
      clausesa[innermost] = *code->ext.omp_clauses;
      return;
    }
  /* Loops are similar to DO but still a bit different.  */
  switch (code->op)
    {
    case EXEC_OMP_LOOP:
    case EXEC_OMP_PARALLEL_LOOP:
    case EXEC_OMP_TEAMS_LOOP:
    case EXEC_OMP_TARGET_PARALLEL_LOOP:
    case EXEC_OMP_TARGET_TEAMS_LOOP:
      is_loop = true;
    default:
      break;
    }
  if (code->ext.omp_clauses != NULL)
    {
      if (mask & GFC_OMP_MASK_TARGET)
	{
	  /* First the clauses that are unique to some constructs.  */
	  clausesa[GFC_OMP_SPLIT_TARGET].lists[OMP_LIST_MAP]
	    = code->ext.omp_clauses->lists[OMP_LIST_MAP];
	  clausesa[GFC_OMP_SPLIT_TARGET].lists[OMP_LIST_IS_DEVICE_PTR]
	    = code->ext.omp_clauses->lists[OMP_LIST_IS_DEVICE_PTR];
	  clausesa[GFC_OMP_SPLIT_TARGET].device
	    = code->ext.omp_clauses->device;
	  for (int i = 0; i < OMP_DEFAULTMAP_CAT_NUM; i++)
	    clausesa[GFC_OMP_SPLIT_TARGET].defaultmap[i]
	      = code->ext.omp_clauses->defaultmap[i];
	  clausesa[GFC_OMP_SPLIT_TARGET].if_exprs[OMP_IF_TARGET]
	    = code->ext.omp_clauses->if_exprs[OMP_IF_TARGET];
	  /* And this is copied to all.  */
	  clausesa[GFC_OMP_SPLIT_TARGET].if_expr
	    = code->ext.omp_clauses->if_expr;
	}
      if (mask & GFC_OMP_MASK_TEAMS)
	{
	  /* First the clauses that are unique to some constructs.  */
	  clausesa[GFC_OMP_SPLIT_TEAMS].num_teams
	    = code->ext.omp_clauses->num_teams;
	  clausesa[GFC_OMP_SPLIT_TEAMS].thread_limit
	    = code->ext.omp_clauses->thread_limit;
	  /* Shared and default clauses are allowed on parallel, teams
	     and taskloop.  */
	  clausesa[GFC_OMP_SPLIT_TEAMS].lists[OMP_LIST_SHARED]
	    = code->ext.omp_clauses->lists[OMP_LIST_SHARED];
	  clausesa[GFC_OMP_SPLIT_TEAMS].default_sharing
	    = code->ext.omp_clauses->default_sharing;
	}
      if (mask & GFC_OMP_MASK_DISTRIBUTE)
	{
	  /* First the clauses that are unique to some constructs.  */
	  clausesa[GFC_OMP_SPLIT_DISTRIBUTE].dist_sched_kind
	    = code->ext.omp_clauses->dist_sched_kind;
	  clausesa[GFC_OMP_SPLIT_DISTRIBUTE].dist_chunk_size
	    = code->ext.omp_clauses->dist_chunk_size;
	  /* Duplicate collapse.  */
	  clausesa[GFC_OMP_SPLIT_DISTRIBUTE].collapse
	    = code->ext.omp_clauses->collapse;
	  clausesa[GFC_OMP_SPLIT_DISTRIBUTE].order_concurrent
	    = code->ext.omp_clauses->order_concurrent;
	}
      if (mask & GFC_OMP_MASK_PARALLEL)
	{
	  /* First the clauses that are unique to some constructs.  */
	  clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_COPYIN]
	    = code->ext.omp_clauses->lists[OMP_LIST_COPYIN];
	  clausesa[GFC_OMP_SPLIT_PARALLEL].num_threads
	    = code->ext.omp_clauses->num_threads;
	  clausesa[GFC_OMP_SPLIT_PARALLEL].proc_bind
	    = code->ext.omp_clauses->proc_bind;
	  /* Shared and default clauses are allowed on parallel, teams
	     and taskloop.  */
	  clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_SHARED]
	    = code->ext.omp_clauses->lists[OMP_LIST_SHARED];
	  clausesa[GFC_OMP_SPLIT_PARALLEL].default_sharing
	    = code->ext.omp_clauses->default_sharing;
	  clausesa[GFC_OMP_SPLIT_PARALLEL].if_exprs[OMP_IF_PARALLEL]
	    = code->ext.omp_clauses->if_exprs[OMP_IF_PARALLEL];
	  /* And this is copied to all.  */
	  clausesa[GFC_OMP_SPLIT_PARALLEL].if_expr
	    = code->ext.omp_clauses->if_expr;
	}
      if ((mask & GFC_OMP_MASK_DO) && !is_loop)
	{
	  /* First the clauses that are unique to some constructs.  */
	  clausesa[GFC_OMP_SPLIT_DO].ordered
	    = code->ext.omp_clauses->ordered;
	  clausesa[GFC_OMP_SPLIT_DO].orderedc
	    = code->ext.omp_clauses->orderedc;
	  clausesa[GFC_OMP_SPLIT_DO].sched_kind
	    = code->ext.omp_clauses->sched_kind;
	  if (innermost == GFC_OMP_SPLIT_SIMD)
	    clausesa[GFC_OMP_SPLIT_DO].sched_simd
	      = code->ext.omp_clauses->sched_simd;
	  clausesa[GFC_OMP_SPLIT_DO].sched_monotonic
	    = code->ext.omp_clauses->sched_monotonic;
	  clausesa[GFC_OMP_SPLIT_DO].sched_nonmonotonic
	    = code->ext.omp_clauses->sched_nonmonotonic;
	  clausesa[GFC_OMP_SPLIT_DO].chunk_size
	    = code->ext.omp_clauses->chunk_size;
	  clausesa[GFC_OMP_SPLIT_DO].nowait
	    = code->ext.omp_clauses->nowait;
	}
      if (mask & GFC_OMP_MASK_DO)
	{
	  clausesa[GFC_OMP_SPLIT_DO].bind
	    = code->ext.omp_clauses->bind;
	  /* Duplicate collapse.  */
	  clausesa[GFC_OMP_SPLIT_DO].collapse
	    = code->ext.omp_clauses->collapse;
	  clausesa[GFC_OMP_SPLIT_DO].order_concurrent
	    = code->ext.omp_clauses->order_concurrent;
	}
      if (mask & GFC_OMP_MASK_SIMD)
	{
	  clausesa[GFC_OMP_SPLIT_SIMD].safelen_expr
	    = code->ext.omp_clauses->safelen_expr;
	  clausesa[GFC_OMP_SPLIT_SIMD].simdlen_expr
	    = code->ext.omp_clauses->simdlen_expr;
	  clausesa[GFC_OMP_SPLIT_SIMD].lists[OMP_LIST_ALIGNED]
	    = code->ext.omp_clauses->lists[OMP_LIST_ALIGNED];
	  /* Duplicate collapse.  */
	  clausesa[GFC_OMP_SPLIT_SIMD].collapse
	    = code->ext.omp_clauses->collapse;
	  clausesa[GFC_OMP_SPLIT_SIMD].if_exprs[OMP_IF_SIMD]
	    = code->ext.omp_clauses->if_exprs[OMP_IF_SIMD];
	  clausesa[GFC_OMP_SPLIT_SIMD].order_concurrent
	    = code->ext.omp_clauses->order_concurrent;
	  /* And this is copied to all.  */
	  clausesa[GFC_OMP_SPLIT_SIMD].if_expr
	    = code->ext.omp_clauses->if_expr;
	}
      if (mask & GFC_OMP_MASK_TASKLOOP)
	{
	  /* First the clauses that are unique to some constructs.  */
	  clausesa[GFC_OMP_SPLIT_TASKLOOP].nogroup
	    = code->ext.omp_clauses->nogroup;
	  clausesa[GFC_OMP_SPLIT_TASKLOOP].grainsize
	    = code->ext.omp_clauses->grainsize;
	  clausesa[GFC_OMP_SPLIT_TASKLOOP].num_tasks
	    = code->ext.omp_clauses->num_tasks;
	  clausesa[GFC_OMP_SPLIT_TASKLOOP].priority
	    = code->ext.omp_clauses->priority;
	  clausesa[GFC_OMP_SPLIT_TASKLOOP].final_expr
	    = code->ext.omp_clauses->final_expr;
	  clausesa[GFC_OMP_SPLIT_TASKLOOP].untied
	    = code->ext.omp_clauses->untied;
	  clausesa[GFC_OMP_SPLIT_TASKLOOP].mergeable
	    = code->ext.omp_clauses->mergeable;
	  clausesa[GFC_OMP_SPLIT_TASKLOOP].if_exprs[OMP_IF_TASKLOOP]
	    = code->ext.omp_clauses->if_exprs[OMP_IF_TASKLOOP];
	  /* And this is copied to all.  */
	  clausesa[GFC_OMP_SPLIT_TASKLOOP].if_expr
	    = code->ext.omp_clauses->if_expr;
	  /* Shared and default clauses are allowed on parallel, teams
	     and taskloop.  */
	  clausesa[GFC_OMP_SPLIT_TASKLOOP].lists[OMP_LIST_SHARED]
	    = code->ext.omp_clauses->lists[OMP_LIST_SHARED];
	  clausesa[GFC_OMP_SPLIT_TASKLOOP].default_sharing
	    = code->ext.omp_clauses->default_sharing;
	  /* Duplicate collapse.  */
	  clausesa[GFC_OMP_SPLIT_TASKLOOP].collapse
	    = code->ext.omp_clauses->collapse;
	}
      /* Private clause is supported on all constructs,
	 it is enough to put it on the innermost one.  For
	 !$ omp parallel do put it on parallel though,
	 as that's what we did for OpenMP 3.1.  */
      clausesa[innermost == GFC_OMP_SPLIT_DO && !is_loop
	       ? (int) GFC_OMP_SPLIT_PARALLEL
	       : innermost].lists[OMP_LIST_PRIVATE]
	= code->ext.omp_clauses->lists[OMP_LIST_PRIVATE];
      /* Firstprivate clause is supported on all constructs but
	 simd.  Put it on the outermost of those and duplicate
	 on parallel and teams.  */
      if (mask & GFC_OMP_MASK_TARGET)
	clausesa[GFC_OMP_SPLIT_TARGET].lists[OMP_LIST_FIRSTPRIVATE]
	  = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE];
      if (mask & GFC_OMP_MASK_TEAMS)
	clausesa[GFC_OMP_SPLIT_TEAMS].lists[OMP_LIST_FIRSTPRIVATE]
	  = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE];
      else if (mask & GFC_OMP_MASK_DISTRIBUTE)
	clausesa[GFC_OMP_SPLIT_DISTRIBUTE].lists[OMP_LIST_FIRSTPRIVATE]
	  = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE];
      if (mask & GFC_OMP_MASK_TASKLOOP)
	clausesa[GFC_OMP_SPLIT_TASKLOOP].lists[OMP_LIST_FIRSTPRIVATE]
	  = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE];
      if ((mask & GFC_OMP_MASK_PARALLEL)
	  && !(mask & GFC_OMP_MASK_TASKLOOP))
	clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_FIRSTPRIVATE]
	  = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE];
      else if ((mask & GFC_OMP_MASK_DO) && !is_loop)
	clausesa[GFC_OMP_SPLIT_DO].lists[OMP_LIST_FIRSTPRIVATE]
	  = code->ext.omp_clauses->lists[OMP_LIST_FIRSTPRIVATE];
      /* Lastprivate is allowed on distribute, do, simd, taskloop and loop.
         In parallel do{, simd} we actually want to put it on
	 parallel rather than do.  */
      if (mask & GFC_OMP_MASK_DISTRIBUTE)
	clausesa[GFC_OMP_SPLIT_DISTRIBUTE].lists[OMP_LIST_LASTPRIVATE]
	  = code->ext.omp_clauses->lists[OMP_LIST_LASTPRIVATE];
      if (mask & GFC_OMP_MASK_TASKLOOP)
	clausesa[GFC_OMP_SPLIT_TASKLOOP].lists[OMP_LIST_LASTPRIVATE]
	  = code->ext.omp_clauses->lists[OMP_LIST_LASTPRIVATE];
      if ((mask & GFC_OMP_MASK_PARALLEL) && !is_loop
	  && !(mask & GFC_OMP_MASK_TASKLOOP))
	clausesa[GFC_OMP_SPLIT_PARALLEL].lists[OMP_LIST_LASTPRIVATE]
	  = code->ext.omp_clauses->lists[OMP_LIST_LASTPRIVATE];
      else if (mask & GFC_OMP_MASK_DO)
	clausesa[GFC_OMP_SPLIT_DO].lists[OMP_LIST_LASTPRIVATE]
	  = code->ext.omp_clauses->lists[OMP_LIST_LASTPRIVATE];
      if (mask & GFC_OMP_MASK_SIMD)
	clausesa[GFC_OMP_SPLIT_SIMD].lists[OMP_LIST_LASTPRIVATE]
	  = code->ext.omp_clauses->lists[OMP_LIST_LASTPRIVATE];
      /* Reduction is allowed on simd, do, parallel, teams, taskloop, and loop.
	 Duplicate it on all of them, but
	 - omit on do if parallel is present;
	 - omit on task and parallel if loop is present;
	 additionally, inscan applies to do/simd only.  */
      for (int i = OMP_LIST_REDUCTION; i <= OMP_LIST_REDUCTION_TASK; i++)
	{
	  if (mask & GFC_OMP_MASK_TASKLOOP
	      && i != OMP_LIST_REDUCTION_INSCAN)
	    clausesa[GFC_OMP_SPLIT_TASKLOOP].lists[i]
	      = code->ext.omp_clauses->lists[i];
	  if (mask & GFC_OMP_MASK_TEAMS
	      && i != OMP_LIST_REDUCTION_INSCAN
	      && !is_loop)
	    clausesa[GFC_OMP_SPLIT_TEAMS].lists[i]
	      = code->ext.omp_clauses->lists[i];
	  if (mask & GFC_OMP_MASK_PARALLEL
	      && i != OMP_LIST_REDUCTION_INSCAN
	      && !(mask & GFC_OMP_MASK_TASKLOOP)
	      && !is_loop)
	    clausesa[GFC_OMP_SPLIT_PARALLEL].lists[i]
	      = code->ext.omp_clauses->lists[i];
	  else if (mask & GFC_OMP_MASK_DO)
	    clausesa[GFC_OMP_SPLIT_DO].lists[i]
	      = code->ext.omp_clauses->lists[i];
	  if (mask & GFC_OMP_MASK_SIMD)
	    clausesa[GFC_OMP_SPLIT_SIMD].lists[i]
	      = code->ext.omp_clauses->lists[i];
	}
      if (mask & GFC_OMP_MASK_TARGET)
	clausesa[GFC_OMP_SPLIT_TARGET].lists[OMP_LIST_IN_REDUCTION]
	  = code->ext.omp_clauses->lists[OMP_LIST_IN_REDUCTION];
      if (mask & GFC_OMP_MASK_TASKLOOP)
	clausesa[GFC_OMP_SPLIT_TASKLOOP].lists[OMP_LIST_IN_REDUCTION]
	  = code->ext.omp_clauses->lists[OMP_LIST_IN_REDUCTION];
      /* Linear clause is supported on do and simd,
	 put it on the innermost one.  */
      clausesa[innermost].lists[OMP_LIST_LINEAR]
	= code->ext.omp_clauses->lists[OMP_LIST_LINEAR];
    }
   /* Propagate firstprivate/lastprivate/reduction vars to
      shared (parallel, teams) and map-tofrom (target).  */
   if (mask & GFC_OMP_MASK_TARGET)
     gfc_add_clause_implicitly (&clausesa[GFC_OMP_SPLIT_TARGET],
				code->ext.omp_clauses, true, false);
   if ((mask & GFC_OMP_MASK_PARALLEL) && innermost != GFC_OMP_MASK_PARALLEL)
     gfc_add_clause_implicitly (&clausesa[GFC_OMP_SPLIT_PARALLEL],
				code->ext.omp_clauses, false,
				mask & GFC_OMP_MASK_DO);
   if (mask & GFC_OMP_MASK_TEAMS && innermost != GFC_OMP_MASK_TEAMS)
     gfc_add_clause_implicitly (&clausesa[GFC_OMP_SPLIT_TEAMS],
				code->ext.omp_clauses, false, false);
   if (((mask & (GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO))
	== (GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO))
       && !is_loop)
    clausesa[GFC_OMP_SPLIT_DO].nowait = true;
}

static tree
gfc_trans_omp_do_simd (gfc_code *code, stmtblock_t *pblock,
		       gfc_omp_clauses *clausesa, tree omp_clauses)
{
  stmtblock_t block;
  gfc_omp_clauses clausesa_buf[GFC_OMP_SPLIT_NUM];
  tree stmt, body, omp_do_clauses = NULL_TREE;
  bool free_clausesa = false;

  if (pblock == NULL)
    gfc_start_block (&block);
  else
    gfc_init_block (&block);

  if (clausesa == NULL)
    {
      clausesa = clausesa_buf;
      gfc_split_omp_clauses (code, clausesa);
      free_clausesa = true;
    }
  if (flag_openmp)
    omp_do_clauses
      = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_DO], code->loc);
  body = gfc_trans_omp_do (code, EXEC_OMP_SIMD, pblock ? pblock : &block,
			   &clausesa[GFC_OMP_SPLIT_SIMD], omp_clauses);
  if (pblock == NULL)
    {
      if (TREE_CODE (body) != BIND_EXPR)
	body = build3_v (BIND_EXPR, NULL, body, poplevel (1, 0));
      else
	poplevel (0, 0);
    }
  else if (TREE_CODE (body) != BIND_EXPR)
    body = build3_v (BIND_EXPR, NULL, body, NULL_TREE);
  if (flag_openmp)
    {
      stmt = make_node (OMP_FOR);
      TREE_TYPE (stmt) = void_type_node;
      OMP_FOR_BODY (stmt) = body;
      OMP_FOR_CLAUSES (stmt) = omp_do_clauses;
    }
  else
    stmt = body;
  gfc_add_expr_to_block (&block, stmt);
  if (free_clausesa)
    gfc_free_split_omp_clauses (code, clausesa);
  return gfc_finish_block (&block);
}

static tree
gfc_trans_omp_parallel_do (gfc_code *code, bool is_loop, stmtblock_t *pblock,
			   gfc_omp_clauses *clausesa)
{
  stmtblock_t block, *new_pblock = pblock;
  gfc_omp_clauses clausesa_buf[GFC_OMP_SPLIT_NUM];
  tree stmt, omp_clauses = NULL_TREE;
  bool free_clausesa = false;

  if (pblock == NULL)
    gfc_start_block (&block);
  else
    gfc_init_block (&block);

  if (clausesa == NULL)
    {
      clausesa = clausesa_buf;
      gfc_split_omp_clauses (code, clausesa);
      free_clausesa = true;
    }
  omp_clauses
    = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_PARALLEL],
			     code->loc);
  if (pblock == NULL)
    {
      if (!clausesa[GFC_OMP_SPLIT_DO].ordered
	  && clausesa[GFC_OMP_SPLIT_DO].sched_kind != OMP_SCHED_STATIC)
	new_pblock = &block;
      else
	pushlevel ();
    }
  stmt = gfc_trans_omp_do (code, is_loop ? EXEC_OMP_LOOP : EXEC_OMP_DO,
			   new_pblock, &clausesa[GFC_OMP_SPLIT_DO],
			   omp_clauses);
  if (pblock == NULL)
    {
      if (TREE_CODE (stmt) != BIND_EXPR)
	stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
      else
	poplevel (0, 0);
    }
  else if (TREE_CODE (stmt) != BIND_EXPR)
    stmt = build3_v (BIND_EXPR, NULL, stmt, NULL_TREE);
  stmt = build2_loc (gfc_get_location (&code->loc), OMP_PARALLEL,
		     void_type_node, stmt, omp_clauses);
  OMP_PARALLEL_COMBINED (stmt) = 1;
  gfc_add_expr_to_block (&block, stmt);
  if (free_clausesa)
    gfc_free_split_omp_clauses (code, clausesa);
  return gfc_finish_block (&block);
}

static tree
gfc_trans_omp_parallel_do_simd (gfc_code *code, stmtblock_t *pblock,
				gfc_omp_clauses *clausesa)
{
  stmtblock_t block;
  gfc_omp_clauses clausesa_buf[GFC_OMP_SPLIT_NUM];
  tree stmt, omp_clauses = NULL_TREE;
  bool free_clausesa = false;

  if (pblock == NULL)
    gfc_start_block (&block);
  else
    gfc_init_block (&block);

  if (clausesa == NULL)
    {
      clausesa = clausesa_buf;
      gfc_split_omp_clauses (code, clausesa);
      free_clausesa = true;
    }
  if (flag_openmp)
    omp_clauses
      = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_PARALLEL],
			       code->loc);
  if (pblock == NULL)
    pushlevel ();
  stmt = gfc_trans_omp_do_simd (code, pblock, clausesa, omp_clauses);
  if (pblock == NULL)
    {
      if (TREE_CODE (stmt) != BIND_EXPR)
	stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
      else
	poplevel (0, 0);
    }
  else if (TREE_CODE (stmt) != BIND_EXPR)
    stmt = build3_v (BIND_EXPR, NULL, stmt, NULL_TREE);
  if (flag_openmp)
    {
      stmt = build2_loc (gfc_get_location (&code->loc), OMP_PARALLEL,
			 void_type_node, stmt, omp_clauses);
      OMP_PARALLEL_COMBINED (stmt) = 1;
    }
  gfc_add_expr_to_block (&block, stmt);
  if (free_clausesa)
    gfc_free_split_omp_clauses (code, clausesa);
  return gfc_finish_block (&block);
}

static tree
gfc_trans_omp_parallel_sections (gfc_code *code)
{
  stmtblock_t block;
  gfc_omp_clauses section_clauses;
  tree stmt, omp_clauses;

  memset (&section_clauses, 0, sizeof (section_clauses));
  section_clauses.nowait = true;

  gfc_start_block (&block);
  omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
				       code->loc);
  pushlevel ();
  stmt = gfc_trans_omp_sections (code, &section_clauses);
  if (TREE_CODE (stmt) != BIND_EXPR)
    stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
  else
    poplevel (0, 0);
  stmt = build2_loc (gfc_get_location (&code->loc), OMP_PARALLEL,
		     void_type_node, stmt, omp_clauses);
  OMP_PARALLEL_COMBINED (stmt) = 1;
  gfc_add_expr_to_block (&block, stmt);
  return gfc_finish_block (&block);
}

static tree
gfc_trans_omp_parallel_workshare (gfc_code *code)
{
  stmtblock_t block;
  gfc_omp_clauses workshare_clauses;
  tree stmt, omp_clauses;

  memset (&workshare_clauses, 0, sizeof (workshare_clauses));
  workshare_clauses.nowait = true;

  gfc_start_block (&block);
  omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
				       code->loc);
  pushlevel ();
  stmt = gfc_trans_omp_workshare (code, &workshare_clauses);
  stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
  stmt = build2_loc (gfc_get_location (&code->loc), OMP_PARALLEL,
		     void_type_node, stmt, omp_clauses);
  OMP_PARALLEL_COMBINED (stmt) = 1;
  gfc_add_expr_to_block (&block, stmt);
  return gfc_finish_block (&block);
}

static tree
gfc_trans_omp_sections (gfc_code *code, gfc_omp_clauses *clauses)
{
  stmtblock_t block, body;
  tree omp_clauses, stmt;
  bool has_lastprivate = clauses->lists[OMP_LIST_LASTPRIVATE] != NULL;
  location_t loc = gfc_get_location (&code->loc);

  gfc_start_block (&block);

  omp_clauses = gfc_trans_omp_clauses (&block, clauses, code->loc);

  gfc_init_block (&body);
  for (code = code->block; code; code = code->block)
    {
      /* Last section is special because of lastprivate, so even if it
	 is empty, chain it in.  */
      stmt = gfc_trans_omp_code (code->next,
				 has_lastprivate && code->block == NULL);
      if (! IS_EMPTY_STMT (stmt))
	{
	  stmt = build1_v (OMP_SECTION, stmt);
	  gfc_add_expr_to_block (&body, stmt);
	}
    }
  stmt = gfc_finish_block (&body);

  stmt = build2_loc (loc, OMP_SECTIONS, void_type_node, stmt, omp_clauses);
  gfc_add_expr_to_block (&block, stmt);

  return gfc_finish_block (&block);
}

static tree
gfc_trans_omp_single (gfc_code *code, gfc_omp_clauses *clauses)
{
  tree omp_clauses = gfc_trans_omp_clauses (NULL, clauses, code->loc);
  tree stmt = gfc_trans_omp_code (code->block->next, true);
  stmt = build2_loc (gfc_get_location (&code->loc), OMP_SINGLE, void_type_node,
		     stmt, omp_clauses);
  return stmt;
}

static tree
gfc_trans_omp_task (gfc_code *code)
{
  stmtblock_t block;
  tree stmt, omp_clauses;

  gfc_start_block (&block);
  omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
				       code->loc);
  pushlevel ();
  stmt = gfc_trans_omp_code (code->block->next, true);
  stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
  stmt = build2_loc (gfc_get_location (&code->loc), OMP_TASK, void_type_node,
		     stmt, omp_clauses);
  gfc_add_expr_to_block (&block, stmt);
  return gfc_finish_block (&block);
}

static tree
gfc_trans_omp_taskgroup (gfc_code *code)
{
  tree body = gfc_trans_code (code->block->next);
  tree stmt = make_node (OMP_TASKGROUP);
  TREE_TYPE (stmt) = void_type_node;
  OMP_TASKGROUP_BODY (stmt) = body;
  OMP_TASKGROUP_CLAUSES (stmt) = NULL_TREE;
  return stmt;
}

static tree
gfc_trans_omp_taskwait (gfc_code *code)
{
  if (!code->ext.omp_clauses)
    {
      tree decl = builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT);
      return build_call_expr_loc (input_location, decl, 0);
    }
  stmtblock_t block;
  gfc_start_block (&block);
  tree stmt = make_node (OMP_TASK);
  TREE_TYPE (stmt) = void_type_node;
  OMP_TASK_BODY (stmt) = NULL_TREE;
  OMP_TASK_CLAUSES (stmt) = gfc_trans_omp_clauses (&block,
						   code->ext.omp_clauses,
						   code->loc);
  gfc_add_expr_to_block (&block, stmt);
  return gfc_finish_block (&block);
}

static tree
gfc_trans_omp_taskyield (void)
{
  tree decl = builtin_decl_explicit (BUILT_IN_GOMP_TASKYIELD);
  return build_call_expr_loc (input_location, decl, 0);
}

static tree
gfc_trans_omp_distribute (gfc_code *code, gfc_omp_clauses *clausesa)
{
  stmtblock_t block;
  gfc_omp_clauses clausesa_buf[GFC_OMP_SPLIT_NUM];
  tree stmt, omp_clauses = NULL_TREE;
  bool free_clausesa = false;

  gfc_start_block (&block);
  if (clausesa == NULL)
    {
      clausesa = clausesa_buf;
      gfc_split_omp_clauses (code, clausesa);
      free_clausesa = true;
    }
  if (flag_openmp)
    omp_clauses
      = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_DISTRIBUTE],
			       code->loc);
  switch (code->op)
    {
    case EXEC_OMP_DISTRIBUTE:
    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
    case EXEC_OMP_TEAMS_DISTRIBUTE:
      /* This is handled in gfc_trans_omp_do.  */
      gcc_unreachable ();
      break;
    case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
    case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
      stmt = gfc_trans_omp_parallel_do (code, false, &block, clausesa);
      if (TREE_CODE (stmt) != BIND_EXPR)
	stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
      else
	poplevel (0, 0);
      break;
    case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
    case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
      stmt = gfc_trans_omp_parallel_do_simd (code, &block, clausesa);
      if (TREE_CODE (stmt) != BIND_EXPR)
	stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
      else
	poplevel (0, 0);
      break;
    case EXEC_OMP_DISTRIBUTE_SIMD:
    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
    case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
      stmt = gfc_trans_omp_do (code, EXEC_OMP_SIMD, &block,
			       &clausesa[GFC_OMP_SPLIT_SIMD], NULL_TREE);
      if (TREE_CODE (stmt) != BIND_EXPR)
	stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
      else
	poplevel (0, 0);
      break;
    default:
      gcc_unreachable ();
    }
  if (flag_openmp)
    {
      tree distribute = make_node (OMP_DISTRIBUTE);
      TREE_TYPE (distribute) = void_type_node;
      OMP_FOR_BODY (distribute) = stmt;
      OMP_FOR_CLAUSES (distribute) = omp_clauses;
      stmt = distribute;
    }
  gfc_add_expr_to_block (&block, stmt);
  if (free_clausesa)
    gfc_free_split_omp_clauses (code, clausesa);
  return gfc_finish_block (&block);
}

static tree
gfc_trans_omp_teams (gfc_code *code, gfc_omp_clauses *clausesa,
		     tree omp_clauses)
{
  stmtblock_t block;
  gfc_omp_clauses clausesa_buf[GFC_OMP_SPLIT_NUM];
  tree stmt;
  bool combined = true, free_clausesa = false;

  gfc_start_block (&block);
  if (clausesa == NULL)
    {
      clausesa = clausesa_buf;
      gfc_split_omp_clauses (code, clausesa);
      free_clausesa = true;
    }
  if (flag_openmp)
    {
      omp_clauses
	= chainon (omp_clauses,
		   gfc_trans_omp_clauses (&block,
					  &clausesa[GFC_OMP_SPLIT_TEAMS],
					  code->loc));
      pushlevel ();
    }
  switch (code->op)
    {
    case EXEC_OMP_TARGET_TEAMS:
    case EXEC_OMP_TEAMS:
      stmt = gfc_trans_omp_code (code->block->next, true);
      combined = false;
      break;
    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
    case EXEC_OMP_TEAMS_DISTRIBUTE:
      stmt = gfc_trans_omp_do (code, EXEC_OMP_DISTRIBUTE, NULL,
			       &clausesa[GFC_OMP_SPLIT_DISTRIBUTE],
			       NULL);
      break;
    case EXEC_OMP_TARGET_TEAMS_LOOP:
    case EXEC_OMP_TEAMS_LOOP:
      stmt = gfc_trans_omp_do (code, EXEC_OMP_LOOP, NULL,
			       &clausesa[GFC_OMP_SPLIT_DO],
			       NULL);
      break;
    default:
      stmt = gfc_trans_omp_distribute (code, clausesa);
      break;
    }
  if (flag_openmp)
    {
      stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
      stmt = build2_loc (gfc_get_location (&code->loc), OMP_TEAMS,
			 void_type_node, stmt, omp_clauses);
      if (combined)
	OMP_TEAMS_COMBINED (stmt) = 1;
    }
  gfc_add_expr_to_block (&block, stmt);
  if (free_clausesa)
    gfc_free_split_omp_clauses (code, clausesa);
  return gfc_finish_block (&block);
}

static tree
gfc_trans_omp_target (gfc_code *code)
{
  stmtblock_t block;
  gfc_omp_clauses clausesa[GFC_OMP_SPLIT_NUM];
  tree stmt, omp_clauses = NULL_TREE;

  gfc_start_block (&block);
  gfc_split_omp_clauses (code, clausesa);
  if (flag_openmp)
    omp_clauses
      = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_TARGET],
			       code->loc);
  switch (code->op)
    {
    case EXEC_OMP_TARGET:
      pushlevel ();
      stmt = gfc_trans_omp_code (code->block->next, true);
      stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
      break;
    case EXEC_OMP_TARGET_PARALLEL:
      {
	stmtblock_t iblock;

	pushlevel ();
	gfc_start_block (&iblock);
	tree inner_clauses
	  = gfc_trans_omp_clauses (&iblock, &clausesa[GFC_OMP_SPLIT_PARALLEL],
				   code->loc);
	stmt = gfc_trans_omp_code (code->block->next, true);
	stmt = build2_loc (input_location, OMP_PARALLEL, void_type_node, stmt,
			   inner_clauses);
	gfc_add_expr_to_block (&iblock, stmt);
	stmt = gfc_finish_block (&iblock);
	if (TREE_CODE (stmt) != BIND_EXPR)
	  stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
	else
	  poplevel (0, 0);
      }
      break;
    case EXEC_OMP_TARGET_PARALLEL_DO:
    case EXEC_OMP_TARGET_PARALLEL_LOOP:
      stmt = gfc_trans_omp_parallel_do (code,
					(code->op
					 == EXEC_OMP_TARGET_PARALLEL_LOOP),
					&block, clausesa);
      if (TREE_CODE (stmt) != BIND_EXPR)
	stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
      else
	poplevel (0, 0);
      break;
    case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
      stmt = gfc_trans_omp_parallel_do_simd (code, &block, clausesa);
      if (TREE_CODE (stmt) != BIND_EXPR)
	stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
      else
	poplevel (0, 0);
      break;
    case EXEC_OMP_TARGET_SIMD:
      stmt = gfc_trans_omp_do (code, EXEC_OMP_SIMD, &block,
			       &clausesa[GFC_OMP_SPLIT_SIMD], NULL_TREE);
      if (TREE_CODE (stmt) != BIND_EXPR)
	stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
      else
	poplevel (0, 0);
      break;
    default:
      if (flag_openmp
	  && (clausesa[GFC_OMP_SPLIT_TEAMS].num_teams
	      || clausesa[GFC_OMP_SPLIT_TEAMS].thread_limit))
	{
	  gfc_omp_clauses clausesb;
	  tree teams_clauses;
	  /* For combined !$omp target teams, the num_teams and
	     thread_limit clauses are evaluated before entering the
	     target construct.  */
	  memset (&clausesb, '\0', sizeof (clausesb));
	  clausesb.num_teams = clausesa[GFC_OMP_SPLIT_TEAMS].num_teams;
	  clausesb.thread_limit = clausesa[GFC_OMP_SPLIT_TEAMS].thread_limit;
	  clausesa[GFC_OMP_SPLIT_TEAMS].num_teams = NULL;
	  clausesa[GFC_OMP_SPLIT_TEAMS].thread_limit = NULL;
	  teams_clauses
	    = gfc_trans_omp_clauses (&block, &clausesb, code->loc);
	  pushlevel ();
	  stmt = gfc_trans_omp_teams (code, clausesa, teams_clauses);
	}
      else
	{
	  pushlevel ();
	  stmt = gfc_trans_omp_teams (code, clausesa, NULL_TREE);
	}
      if (TREE_CODE (stmt) != BIND_EXPR)
	stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
      else
	poplevel (0, 0);
      break;
    }
  if (flag_openmp)
    {
      stmt = build2_loc (gfc_get_location (&code->loc), OMP_TARGET,
			 void_type_node, stmt, omp_clauses);
      if (code->op != EXEC_OMP_TARGET)
	OMP_TARGET_COMBINED (stmt) = 1;
      cfun->has_omp_target = true;
    }
  gfc_add_expr_to_block (&block, stmt);
  gfc_free_split_omp_clauses (code, clausesa);
  return gfc_finish_block (&block);
}

static tree
gfc_trans_omp_taskloop (gfc_code *code, gfc_exec_op op)
{
  stmtblock_t block;
  gfc_omp_clauses clausesa[GFC_OMP_SPLIT_NUM];
  tree stmt, omp_clauses = NULL_TREE;

  gfc_start_block (&block);
  gfc_split_omp_clauses (code, clausesa);
  if (flag_openmp)
    omp_clauses
      = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_TASKLOOP],
			       code->loc);
  switch (op)
    {
    case EXEC_OMP_TASKLOOP:
      /* This is handled in gfc_trans_omp_do.  */
      gcc_unreachable ();
      break;
    case EXEC_OMP_TASKLOOP_SIMD:
      stmt = gfc_trans_omp_do (code, EXEC_OMP_SIMD, &block,
			       &clausesa[GFC_OMP_SPLIT_SIMD], NULL_TREE);
      if (TREE_CODE (stmt) != BIND_EXPR)
	stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
      else
	poplevel (0, 0);
      break;
    default:
      gcc_unreachable ();
    }
  if (flag_openmp)
    {
      tree taskloop = make_node (OMP_TASKLOOP);
      TREE_TYPE (taskloop) = void_type_node;
      OMP_FOR_BODY (taskloop) = stmt;
      OMP_FOR_CLAUSES (taskloop) = omp_clauses;
      stmt = taskloop;
    }
  gfc_add_expr_to_block (&block, stmt);
  gfc_free_split_omp_clauses (code, clausesa);
  return gfc_finish_block (&block);
}

static tree
gfc_trans_omp_master_taskloop (gfc_code *code, gfc_exec_op op)
{
  stmtblock_t block;
  tree stmt;

  gfc_start_block (&block);
  pushlevel ();
  if (op == EXEC_OMP_MASTER_TASKLOOP_SIMD)
    stmt = gfc_trans_omp_taskloop (code, EXEC_OMP_TASKLOOP_SIMD);
  else
    {
      gfc_omp_clauses clausesa[GFC_OMP_SPLIT_NUM];
      gcc_assert (op == EXEC_OMP_MASTER_TASKLOOP);
      if (op != code->op)
	gfc_split_omp_clauses (code, clausesa);
      stmt = gfc_trans_omp_do (code, EXEC_OMP_TASKLOOP, NULL,
			       op != code->op
			       ? &clausesa[GFC_OMP_SPLIT_TASKLOOP]
			       : code->ext.omp_clauses, NULL);
      if (op != code->op)
	gfc_free_split_omp_clauses (code, clausesa);
    }
  if (TREE_CODE (stmt) != BIND_EXPR)
    stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
  else
    poplevel (0, 0);
  stmt = build1_v (OMP_MASTER, stmt);
  gfc_add_expr_to_block (&block, stmt);
  return gfc_finish_block (&block);
}

static tree
gfc_trans_omp_parallel_master (gfc_code *code)
{
  stmtblock_t block;
  tree stmt, omp_clauses;
  gfc_omp_clauses clausesa[GFC_OMP_SPLIT_NUM];

  if (code->op != EXEC_OMP_PARALLEL_MASTER)
    gfc_split_omp_clauses (code, clausesa);

  gfc_start_block (&block);
  omp_clauses = gfc_trans_omp_clauses (&block,
				       code->op == EXEC_OMP_PARALLEL_MASTER
				       ? code->ext.omp_clauses
				       : &clausesa[GFC_OMP_SPLIT_PARALLEL],
				       code->loc);
  if (code->op != EXEC_OMP_PARALLEL_MASTER)
    gfc_free_split_omp_clauses (code, clausesa);
  pushlevel ();
  if (code->op == EXEC_OMP_PARALLEL_MASTER)
    stmt = gfc_trans_omp_master (code);
  else
    {
      gcc_assert (code->op == EXEC_OMP_PARALLEL_MASTER_TASKLOOP
		  || code->op == EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD);
      gfc_exec_op op = (code->op == EXEC_OMP_PARALLEL_MASTER_TASKLOOP
			? EXEC_OMP_MASTER_TASKLOOP
			: EXEC_OMP_MASTER_TASKLOOP_SIMD);
      stmt = gfc_trans_omp_master_taskloop (code, op);
    }
  if (TREE_CODE (stmt) != BIND_EXPR)
    stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
  else
    poplevel (0, 0);
  stmt = build2_loc (gfc_get_location (&code->loc), OMP_PARALLEL,
		     void_type_node, stmt, omp_clauses);
  OMP_PARALLEL_COMBINED (stmt) = 1;
  gfc_add_expr_to_block (&block, stmt);
  return gfc_finish_block (&block);
}

static tree
gfc_trans_omp_target_data (gfc_code *code)
{
  stmtblock_t block;
  tree stmt, omp_clauses;

  gfc_start_block (&block);
  omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
				       code->loc);
  stmt = gfc_trans_omp_code (code->block->next, true);
  stmt = build2_loc (gfc_get_location (&code->loc), OMP_TARGET_DATA,
		     void_type_node, stmt, omp_clauses);
  gfc_add_expr_to_block (&block, stmt);
  return gfc_finish_block (&block);
}

static tree
gfc_trans_omp_target_enter_data (gfc_code *code)
{
  stmtblock_t block;
  tree stmt, omp_clauses;

  gfc_start_block (&block);
  omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
				       code->loc);
  stmt = build1_loc (input_location, OMP_TARGET_ENTER_DATA, void_type_node,
		     omp_clauses);
  gfc_add_expr_to_block (&block, stmt);
  return gfc_finish_block (&block);
}

static tree
gfc_trans_omp_target_exit_data (gfc_code *code)
{
  stmtblock_t block;
  tree stmt, omp_clauses;

  gfc_start_block (&block);
  omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
				       code->loc);
  stmt = build1_loc (input_location, OMP_TARGET_EXIT_DATA, void_type_node,
		     omp_clauses);
  gfc_add_expr_to_block (&block, stmt);
  return gfc_finish_block (&block);
}

static tree
gfc_trans_omp_target_update (gfc_code *code)
{
  stmtblock_t block;
  tree stmt, omp_clauses;

  gfc_start_block (&block);
  omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
				       code->loc);
  stmt = build1_loc (input_location, OMP_TARGET_UPDATE, void_type_node,
		     omp_clauses);
  gfc_add_expr_to_block (&block, stmt);
  return gfc_finish_block (&block);
}

static tree
gfc_trans_omp_workshare (gfc_code *code, gfc_omp_clauses *clauses)
{
  tree res, tmp, stmt;
  stmtblock_t block, *pblock = NULL;
  stmtblock_t singleblock;
  int saved_ompws_flags;
  bool singleblock_in_progress = false;
  /* True if previous gfc_code in workshare construct is not workshared.  */
  bool prev_singleunit;
  location_t loc = gfc_get_location (&code->loc);

  code = code->block->next;

  pushlevel ();

  gfc_start_block (&block);
  pblock = &block;

  ompws_flags = OMPWS_WORKSHARE_FLAG;
  prev_singleunit = false;

  /* Translate statements one by one to trees until we reach
     the end of the workshare construct.  Adjacent gfc_codes that
     are a single unit of work are clustered and encapsulated in a
     single OMP_SINGLE construct.  */
  for (; code; code = code->next)
    {
      if (code->here != 0)
	{
	  res = gfc_trans_label_here (code);
	  gfc_add_expr_to_block (pblock, res);
	}

      /* No dependence analysis, use for clauses with wait.
	 If this is the last gfc_code, use default omp_clauses.  */
      if (code->next == NULL && clauses->nowait)
	ompws_flags |= OMPWS_NOWAIT;

      /* By default, every gfc_code is a single unit of work.  */
      ompws_flags |= OMPWS_CURR_SINGLEUNIT;
      ompws_flags &= ~(OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY);

      switch (code->op)
	{
	case EXEC_NOP:
	  res = NULL_TREE;
	  break;

	case EXEC_ASSIGN:
	  res = gfc_trans_assign (code);
	  break;

	case EXEC_POINTER_ASSIGN:
	  res = gfc_trans_pointer_assign (code);
	  break;

	case EXEC_INIT_ASSIGN:
	  res = gfc_trans_init_assign (code);
	  break;

	case EXEC_FORALL:
	  res = gfc_trans_forall (code);
	  break;

	case EXEC_WHERE:
	  res = gfc_trans_where (code);
	  break;

	case EXEC_OMP_ATOMIC:
	  res = gfc_trans_omp_directive (code);
	  break;

	case EXEC_OMP_PARALLEL:
	case EXEC_OMP_PARALLEL_DO:
	case EXEC_OMP_PARALLEL_MASTER:
	case EXEC_OMP_PARALLEL_SECTIONS:
	case EXEC_OMP_PARALLEL_WORKSHARE:
	case EXEC_OMP_CRITICAL:
	  saved_ompws_flags = ompws_flags;
	  ompws_flags = 0;
	  res = gfc_trans_omp_directive (code);
	  ompws_flags = saved_ompws_flags;
	  break;
	
	default:
	  gfc_internal_error ("gfc_trans_omp_workshare(): Bad statement code");
	}

      gfc_set_backend_locus (&code->loc);

      if (res != NULL_TREE && ! IS_EMPTY_STMT (res))
	{
	  if (prev_singleunit)
	    {
	      if (ompws_flags & OMPWS_CURR_SINGLEUNIT)
		/* Add current gfc_code to single block.  */
		gfc_add_expr_to_block (&singleblock, res);
	      else
		{
		  /* Finish single block and add it to pblock.  */
		  tmp = gfc_finish_block (&singleblock);
		  tmp = build2_loc (loc, OMP_SINGLE,
				    void_type_node, tmp, NULL_TREE);
		  gfc_add_expr_to_block (pblock, tmp);
		  /* Add current gfc_code to pblock.  */
		  gfc_add_expr_to_block (pblock, res);
		  singleblock_in_progress = false;
		}
	    }
	  else
	    {
	      if (ompws_flags & OMPWS_CURR_SINGLEUNIT)
		{
		  /* Start single block.  */
		  gfc_init_block (&singleblock);
		  gfc_add_expr_to_block (&singleblock, res);
		  singleblock_in_progress = true;
		  loc = gfc_get_location (&code->loc);
		}
	      else
		/* Add the new statement to the block.  */
		gfc_add_expr_to_block (pblock, res);
	    }
	  prev_singleunit = (ompws_flags & OMPWS_CURR_SINGLEUNIT) != 0;
	}
    }

  /* Finish remaining SINGLE block, if we were in the middle of one.  */
  if (singleblock_in_progress)
    {
      /* Finish single block and add it to pblock.  */
      tmp = gfc_finish_block (&singleblock);
      tmp = build2_loc (loc, OMP_SINGLE, void_type_node, tmp,
			clauses->nowait
			? build_omp_clause (input_location, OMP_CLAUSE_NOWAIT)
			: NULL_TREE);
      gfc_add_expr_to_block (pblock, tmp);
    }

  stmt = gfc_finish_block (pblock);
  if (TREE_CODE (stmt) != BIND_EXPR)
    {
      if (!IS_EMPTY_STMT (stmt))
	{
	  tree bindblock = poplevel (1, 0);
	  stmt = build3_v (BIND_EXPR, NULL, stmt, bindblock);
	}
      else
	poplevel (0, 0);
    }
  else
    poplevel (0, 0);

  if (IS_EMPTY_STMT (stmt) && !clauses->nowait)
    stmt = gfc_trans_omp_barrier ();

  ompws_flags = 0;
  return stmt;
}

tree
gfc_trans_oacc_declare (gfc_code *code)
{
  stmtblock_t block;
  tree stmt, oacc_clauses;
  enum tree_code construct_code;

  construct_code = OACC_DATA;

  gfc_start_block (&block);

  oacc_clauses = gfc_trans_omp_clauses (&block, code->ext.oacc_declare->clauses,
					code->loc, false, true);
  stmt = gfc_trans_omp_code (code->block->next, true);
  stmt = build2_loc (input_location, construct_code, void_type_node, stmt,
		     oacc_clauses);
  gfc_add_expr_to_block (&block, stmt);

  return gfc_finish_block (&block);
}

tree
gfc_trans_oacc_directive (gfc_code *code)
{
  switch (code->op)
    {
    case EXEC_OACC_PARALLEL_LOOP:
    case EXEC_OACC_KERNELS_LOOP:
    case EXEC_OACC_SERIAL_LOOP:
      return gfc_trans_oacc_combined_directive (code);
    case EXEC_OACC_PARALLEL:
    case EXEC_OACC_KERNELS:
    case EXEC_OACC_SERIAL:
    case EXEC_OACC_DATA:
    case EXEC_OACC_HOST_DATA:
      return gfc_trans_oacc_construct (code);
    case EXEC_OACC_LOOP:
      return gfc_trans_omp_do (code, code->op, NULL, code->ext.omp_clauses,
			       NULL);
    case EXEC_OACC_UPDATE:
    case EXEC_OACC_CACHE:
    case EXEC_OACC_ENTER_DATA:
    case EXEC_OACC_EXIT_DATA:
      return gfc_trans_oacc_executable_directive (code);
    case EXEC_OACC_WAIT:
      return gfc_trans_oacc_wait_directive (code);
    case EXEC_OACC_ATOMIC:
      return gfc_trans_omp_atomic (code);
    case EXEC_OACC_DECLARE:
      return gfc_trans_oacc_declare (code);
    default:
      gcc_unreachable ();
    }
}

tree
gfc_trans_omp_directive (gfc_code *code)
{
  switch (code->op)
    {
    case EXEC_OMP_ATOMIC:
      return gfc_trans_omp_atomic (code);
    case EXEC_OMP_BARRIER:
      return gfc_trans_omp_barrier ();
    case EXEC_OMP_CANCEL:
      return gfc_trans_omp_cancel (code);
    case EXEC_OMP_CANCELLATION_POINT:
      return gfc_trans_omp_cancellation_point (code);
    case EXEC_OMP_CRITICAL:
      return gfc_trans_omp_critical (code);
    case EXEC_OMP_DEPOBJ:
      return gfc_trans_omp_depobj (code);
    case EXEC_OMP_DISTRIBUTE:
    case EXEC_OMP_DO:
    case EXEC_OMP_LOOP:
    case EXEC_OMP_SIMD:
    case EXEC_OMP_TASKLOOP:
      return gfc_trans_omp_do (code, code->op, NULL, code->ext.omp_clauses,
			       NULL);
    case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
    case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
    case EXEC_OMP_DISTRIBUTE_SIMD:
      return gfc_trans_omp_distribute (code, NULL);
    case EXEC_OMP_DO_SIMD:
      return gfc_trans_omp_do_simd (code, NULL, NULL, NULL_TREE);
    case EXEC_OMP_FLUSH:
      return gfc_trans_omp_flush (code);
    case EXEC_OMP_MASTER:
      return gfc_trans_omp_master (code);
    case EXEC_OMP_MASTER_TASKLOOP:
    case EXEC_OMP_MASTER_TASKLOOP_SIMD:
      return gfc_trans_omp_master_taskloop (code, code->op);
    case EXEC_OMP_ORDERED:
      return gfc_trans_omp_ordered (code);
    case EXEC_OMP_PARALLEL:
      return gfc_trans_omp_parallel (code);
    case EXEC_OMP_PARALLEL_DO:
      return gfc_trans_omp_parallel_do (code, false, NULL, NULL);
    case EXEC_OMP_PARALLEL_LOOP:
      return gfc_trans_omp_parallel_do (code, true, NULL, NULL);
    case EXEC_OMP_PARALLEL_DO_SIMD:
      return gfc_trans_omp_parallel_do_simd (code, NULL, NULL);
    case EXEC_OMP_PARALLEL_MASTER:
    case EXEC_OMP_PARALLEL_MASTER_TASKLOOP:
    case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD:
      return gfc_trans_omp_parallel_master (code);
    case EXEC_OMP_PARALLEL_SECTIONS:
      return gfc_trans_omp_parallel_sections (code);
    case EXEC_OMP_PARALLEL_WORKSHARE:
      return gfc_trans_omp_parallel_workshare (code);
    case EXEC_OMP_SECTIONS:
      return gfc_trans_omp_sections (code, code->ext.omp_clauses);
    case EXEC_OMP_SINGLE:
      return gfc_trans_omp_single (code, code->ext.omp_clauses);
    case EXEC_OMP_TARGET:
    case EXEC_OMP_TARGET_PARALLEL:
    case EXEC_OMP_TARGET_PARALLEL_DO:
    case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
    case EXEC_OMP_TARGET_PARALLEL_LOOP:
    case EXEC_OMP_TARGET_SIMD:
    case EXEC_OMP_TARGET_TEAMS:
    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
    case EXEC_OMP_TARGET_TEAMS_LOOP:
      return gfc_trans_omp_target (code);
    case EXEC_OMP_TARGET_DATA:
      return gfc_trans_omp_target_data (code);
    case EXEC_OMP_TARGET_ENTER_DATA:
      return gfc_trans_omp_target_enter_data (code);
    case EXEC_OMP_TARGET_EXIT_DATA:
      return gfc_trans_omp_target_exit_data (code);
    case EXEC_OMP_TARGET_UPDATE:
      return gfc_trans_omp_target_update (code);
    case EXEC_OMP_TASK:
      return gfc_trans_omp_task (code);
    case EXEC_OMP_TASKGROUP:
      return gfc_trans_omp_taskgroup (code);
    case EXEC_OMP_TASKLOOP_SIMD:
      return gfc_trans_omp_taskloop (code, code->op);
    case EXEC_OMP_TASKWAIT:
      return gfc_trans_omp_taskwait (code);
    case EXEC_OMP_TASKYIELD:
      return gfc_trans_omp_taskyield ();
    case EXEC_OMP_TEAMS:
    case EXEC_OMP_TEAMS_DISTRIBUTE:
    case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
    case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
    case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
    case EXEC_OMP_TEAMS_LOOP:
      return gfc_trans_omp_teams (code, NULL, NULL_TREE);
    case EXEC_OMP_WORKSHARE:
      return gfc_trans_omp_workshare (code, code->ext.omp_clauses);
    default:
      gcc_unreachable ();
    }
}

void
gfc_trans_omp_declare_simd (gfc_namespace *ns)
{
  if (ns->entries)
    return;

  gfc_omp_declare_simd *ods;
  for (ods = ns->omp_declare_simd; ods; ods = ods->next)
    {
      tree c = gfc_trans_omp_clauses (NULL, ods->clauses, ods->where, true);
      tree fndecl = ns->proc_name->backend_decl;
      if (c != NULL_TREE)
	c = tree_cons (NULL_TREE, c, NULL_TREE);
      c = build_tree_list (get_identifier ("omp declare simd"), c);
      TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
      DECL_ATTRIBUTES (fndecl) = c;
    }
}
