/* Backend support for Fortran 95 basic types and derived types.
   Copyright (C) 2002-2018 Free Software Foundation, Inc.
   Contributed by Paul Brook <paul@nowt.org>
   and Steven Bosscher <s.bosscher@student.tudelft.nl>

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

/* trans-types.c -- gfortran backend types */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "target.h"
#include "tree.h"
#include "gfortran.h"
#include "trans.h"
#include "stringpool.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "langhooks.h"	/* For iso-c-bindings.def.  */
#include "toplev.h"	/* For rest_of_decl_compilation.  */
#include "trans-types.h"
#include "trans-const.h"
#include "trans-array.h"
#include "dwarf2out.h"	/* For struct array_descr_info.  */
#include "attribs.h"


#if (GFC_MAX_DIMENSIONS < 10)
#define GFC_RANK_DIGITS 1
#define GFC_RANK_PRINTF_FORMAT "%01d"
#elif (GFC_MAX_DIMENSIONS < 100)
#define GFC_RANK_DIGITS 2
#define GFC_RANK_PRINTF_FORMAT "%02d"
#else
#error If you really need >99 dimensions, continue the sequence above...
#endif

/* array of structs so we don't have to worry about xmalloc or free */
CInteropKind_t c_interop_kinds_table[ISOCBINDING_NUMBER];

tree gfc_array_index_type;
tree gfc_array_range_type;
tree gfc_character1_type_node;
tree pvoid_type_node;
tree prvoid_type_node;
tree ppvoid_type_node;
tree pchar_type_node;
tree pfunc_type_node;

tree logical_type_node;
tree logical_true_node;
tree logical_false_node;
tree gfc_charlen_type_node;

tree gfc_float128_type_node = NULL_TREE;
tree gfc_complex_float128_type_node = NULL_TREE;

bool gfc_real16_is_float128 = false;

static GTY(()) tree gfc_desc_dim_type;
static GTY(()) tree gfc_max_array_element_size;
static GTY(()) tree gfc_array_descriptor_base[2 * (GFC_MAX_DIMENSIONS+1)];
static GTY(()) tree gfc_array_descriptor_base_caf[2 * (GFC_MAX_DIMENSIONS+1)];

/* Arrays for all integral and real kinds.  We'll fill this in at runtime
   after the target has a chance to process command-line options.  */

#define MAX_INT_KINDS 5
gfc_integer_info gfc_integer_kinds[MAX_INT_KINDS + 1];
gfc_logical_info gfc_logical_kinds[MAX_INT_KINDS + 1];
static GTY(()) tree gfc_integer_types[MAX_INT_KINDS + 1];
static GTY(()) tree gfc_logical_types[MAX_INT_KINDS + 1];

#define MAX_REAL_KINDS 5
gfc_real_info gfc_real_kinds[MAX_REAL_KINDS + 1];
static GTY(()) tree gfc_real_types[MAX_REAL_KINDS + 1];
static GTY(()) tree gfc_complex_types[MAX_REAL_KINDS + 1];

#define MAX_CHARACTER_KINDS 2
gfc_character_info gfc_character_kinds[MAX_CHARACTER_KINDS + 1];
static GTY(()) tree gfc_character_types[MAX_CHARACTER_KINDS + 1];
static GTY(()) tree gfc_pcharacter_types[MAX_CHARACTER_KINDS + 1];

static tree gfc_add_field_to_struct_1 (tree, tree, tree, tree **);

/* The integer kind to use for array indices.  This will be set to the
   proper value based on target information from the backend.  */

int gfc_index_integer_kind;

/* The default kinds of the various types.  */

int gfc_default_integer_kind;
int gfc_max_integer_kind;
int gfc_default_real_kind;
int gfc_default_double_kind;
int gfc_default_character_kind;
int gfc_default_logical_kind;
int gfc_default_complex_kind;
int gfc_c_int_kind;
int gfc_atomic_int_kind;
int gfc_atomic_logical_kind;

/* The kind size used for record offsets. If the target system supports
   kind=8, this will be set to 8, otherwise it is set to 4.  */
int gfc_intio_kind;

/* The integer kind used to store character lengths.  */
int gfc_charlen_int_kind;

/* Kind of internal integer for storing object sizes.  */
int gfc_size_kind;

/* The size of the numeric storage unit and character storage unit.  */
int gfc_numeric_storage_size;
int gfc_character_storage_size;

tree dtype_type_node = NULL_TREE;


/* Build the dtype_type_node if necessary.  */
tree get_dtype_type_node (void)
{
  tree field;
  tree dtype_node;
  tree *dtype_chain = NULL;

  if (dtype_type_node == NULL_TREE)
    {
      dtype_node = make_node (RECORD_TYPE);
      TYPE_NAME (dtype_node) = get_identifier ("dtype_type");
      TYPE_NAMELESS (dtype_node) = 1;
      field = gfc_add_field_to_struct_1 (dtype_node,
					 get_identifier ("elem_len"),
					 size_type_node, &dtype_chain);
      TREE_NO_WARNING (field) = 1;
      field = gfc_add_field_to_struct_1 (dtype_node,
					 get_identifier ("version"),
					 integer_type_node, &dtype_chain);
      TREE_NO_WARNING (field) = 1;
      field = gfc_add_field_to_struct_1 (dtype_node,
					 get_identifier ("rank"),
					 signed_char_type_node, &dtype_chain);
      TREE_NO_WARNING (field) = 1;
      field = gfc_add_field_to_struct_1 (dtype_node,
					 get_identifier ("type"),
					 signed_char_type_node, &dtype_chain);
      TREE_NO_WARNING (field) = 1;
      field = gfc_add_field_to_struct_1 (dtype_node,
					 get_identifier ("attribute"),
					 short_integer_type_node, &dtype_chain);
      TREE_NO_WARNING (field) = 1;
      gfc_finish_type (dtype_node);
      TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (dtype_node)) = 1;
      dtype_type_node = dtype_node;
    }
  return dtype_type_node;
}

bool
gfc_check_any_c_kind (gfc_typespec *ts)
{
  int i;

  for (i = 0; i < ISOCBINDING_NUMBER; i++)
    {
      /* Check for any C interoperable kind for the given type/kind in ts.
         This can be used after verify_c_interop to make sure that the
         Fortran kind being used exists in at least some form for C.  */
      if (c_interop_kinds_table[i].f90_type == ts->type &&
          c_interop_kinds_table[i].value == ts->kind)
        return true;
    }

  return false;
}


static int
get_real_kind_from_node (tree type)
{
  int i;

  for (i = 0; gfc_real_kinds[i].kind != 0; i++)
    if (gfc_real_kinds[i].mode_precision == TYPE_PRECISION (type))
      return gfc_real_kinds[i].kind;

  return -4;
}

static int
get_int_kind_from_node (tree type)
{
  int i;

  if (!type)
    return -2;

  for (i = 0; gfc_integer_kinds[i].kind != 0; i++)
    if (gfc_integer_kinds[i].bit_size == TYPE_PRECISION (type))
      return gfc_integer_kinds[i].kind;

  return -1;
}

/* Return a typenode for the "standard" C type with a given name.  */
static tree
get_typenode_from_name (const char *name)
{
  if (name == NULL || *name == '\0')
    return NULL_TREE;

  if (strcmp (name, "char") == 0)
    return char_type_node;
  if (strcmp (name, "unsigned char") == 0)
    return unsigned_char_type_node;
  if (strcmp (name, "signed char") == 0)
    return signed_char_type_node;

  if (strcmp (name, "short int") == 0)
    return short_integer_type_node;
  if (strcmp (name, "short unsigned int") == 0)
    return short_unsigned_type_node;

  if (strcmp (name, "int") == 0)
    return integer_type_node;
  if (strcmp (name, "unsigned int") == 0)
    return unsigned_type_node;

  if (strcmp (name, "long int") == 0)
    return long_integer_type_node;
  if (strcmp (name, "long unsigned int") == 0)
    return long_unsigned_type_node;

  if (strcmp (name, "long long int") == 0)
    return long_long_integer_type_node;
  if (strcmp (name, "long long unsigned int") == 0)
    return long_long_unsigned_type_node;

  gcc_unreachable ();
}

static int
get_int_kind_from_name (const char *name)
{
  return get_int_kind_from_node (get_typenode_from_name (name));
}


/* Get the kind number corresponding to an integer of given size,
   following the required return values for ISO_FORTRAN_ENV INT* constants:
   -2 is returned if we support a kind of larger size, -1 otherwise.  */
int
gfc_get_int_kind_from_width_isofortranenv (int size)
{
  int i;

  /* Look for a kind with matching storage size.  */
  for (i = 0; gfc_integer_kinds[i].kind != 0; i++)
    if (gfc_integer_kinds[i].bit_size == size)
      return gfc_integer_kinds[i].kind;

  /* Look for a kind with larger storage size.  */
  for (i = 0; gfc_integer_kinds[i].kind != 0; i++)
    if (gfc_integer_kinds[i].bit_size > size)
      return -2;

  return -1;
}


/* Get the kind number corresponding to a real of a given storage size.
   If two real's have the same storage size, then choose the real with
   the largest precision.  If a kind type is unavailable and a real
   exists with wider storage, then return -2; otherwise, return -1.  */

int
gfc_get_real_kind_from_width_isofortranenv (int size)
{
  int digits, i, kind;

  size /= 8;

  kind = -1;
  digits = 0;

  /* Look for a kind with matching storage size.  */
  for (i = 0; gfc_real_kinds[i].kind != 0; i++)
    if (int_size_in_bytes (gfc_get_real_type (gfc_real_kinds[i].kind)) == size)
      {
	if (gfc_real_kinds[i].digits > digits)
	  {
	    digits = gfc_real_kinds[i].digits;
	    kind = gfc_real_kinds[i].kind;
	  }
      }

  if (kind != -1)
    return kind;

  /* Look for a kind with larger storage size.  */
  for (i = 0; gfc_real_kinds[i].kind != 0; i++)
    if (int_size_in_bytes (gfc_get_real_type (gfc_real_kinds[i].kind)) > size)
      kind = -2;

  return kind;
}



static int
get_int_kind_from_width (int size)
{
  int i;

  for (i = 0; gfc_integer_kinds[i].kind != 0; i++)
    if (gfc_integer_kinds[i].bit_size == size)
      return gfc_integer_kinds[i].kind;

  return -2;
}

static int
get_int_kind_from_minimal_width (int size)
{
  int i;

  for (i = 0; gfc_integer_kinds[i].kind != 0; i++)
    if (gfc_integer_kinds[i].bit_size >= size)
      return gfc_integer_kinds[i].kind;

  return -2;
}


/* Generate the CInteropKind_t objects for the C interoperable
   kinds.  */

void
gfc_init_c_interop_kinds (void)
{
  int i;

  /* init all pointers in the list to NULL */
  for (i = 0; i < ISOCBINDING_NUMBER; i++)
    {
      /* Initialize the name and value fields.  */
      c_interop_kinds_table[i].name[0] = '\0';
      c_interop_kinds_table[i].value = -100;
      c_interop_kinds_table[i].f90_type = BT_UNKNOWN;
    }

#define NAMED_INTCST(a,b,c,d) \
  strncpy (c_interop_kinds_table[a].name, b, strlen(b) + 1); \
  c_interop_kinds_table[a].f90_type = BT_INTEGER; \
  c_interop_kinds_table[a].value = c;
#define NAMED_REALCST(a,b,c,d) \
  strncpy (c_interop_kinds_table[a].name, b, strlen(b) + 1); \
  c_interop_kinds_table[a].f90_type = BT_REAL; \
  c_interop_kinds_table[a].value = c;
#define NAMED_CMPXCST(a,b,c,d) \
  strncpy (c_interop_kinds_table[a].name, b, strlen(b) + 1); \
  c_interop_kinds_table[a].f90_type = BT_COMPLEX; \
  c_interop_kinds_table[a].value = c;
#define NAMED_LOGCST(a,b,c) \
  strncpy (c_interop_kinds_table[a].name, b, strlen(b) + 1); \
  c_interop_kinds_table[a].f90_type = BT_LOGICAL; \
  c_interop_kinds_table[a].value = c;
#define NAMED_CHARKNDCST(a,b,c) \
  strncpy (c_interop_kinds_table[a].name, b, strlen(b) + 1); \
  c_interop_kinds_table[a].f90_type = BT_CHARACTER; \
  c_interop_kinds_table[a].value = c;
#define NAMED_CHARCST(a,b,c) \
  strncpy (c_interop_kinds_table[a].name, b, strlen(b) + 1); \
  c_interop_kinds_table[a].f90_type = BT_CHARACTER; \
  c_interop_kinds_table[a].value = c;
#define DERIVED_TYPE(a,b,c) \
  strncpy (c_interop_kinds_table[a].name, b, strlen(b) + 1); \
  c_interop_kinds_table[a].f90_type = BT_DERIVED; \
  c_interop_kinds_table[a].value = c;
#define NAMED_FUNCTION(a,b,c,d) \
  strncpy (c_interop_kinds_table[a].name, b, strlen(b) + 1); \
  c_interop_kinds_table[a].f90_type = BT_PROCEDURE; \
  c_interop_kinds_table[a].value = c;
#define NAMED_SUBROUTINE(a,b,c,d) \
  strncpy (c_interop_kinds_table[a].name, b, strlen(b) + 1); \
  c_interop_kinds_table[a].f90_type = BT_PROCEDURE; \
  c_interop_kinds_table[a].value = c;
#include "iso-c-binding.def"
}


/* Query the target to determine which machine modes are available for
   computation.  Choose KIND numbers for them.  */

void
gfc_init_kinds (void)
{
  opt_scalar_int_mode int_mode_iter;
  opt_scalar_float_mode float_mode_iter;
  int i_index, r_index, kind;
  bool saw_i4 = false, saw_i8 = false;
  bool saw_r4 = false, saw_r8 = false, saw_r10 = false, saw_r16 = false;

  i_index = 0;
  FOR_EACH_MODE_IN_CLASS (int_mode_iter, MODE_INT)
    {
      scalar_int_mode mode = int_mode_iter.require ();
      int kind, bitsize;

      if (!targetm.scalar_mode_supported_p (mode))
	continue;

      /* The middle end doesn't support constants larger than 2*HWI.
	 Perhaps the target hook shouldn't have accepted these either,
	 but just to be safe...  */
      bitsize = GET_MODE_BITSIZE (mode);
      if (bitsize > 2*HOST_BITS_PER_WIDE_INT)
	continue;

      gcc_assert (i_index != MAX_INT_KINDS);

      /* Let the kind equal the bit size divided by 8.  This insulates the
	 programmer from the underlying byte size.  */
      kind = bitsize / 8;

      if (kind == 4)
	saw_i4 = true;
      if (kind == 8)
	saw_i8 = true;

      gfc_integer_kinds[i_index].kind = kind;
      gfc_integer_kinds[i_index].radix = 2;
      gfc_integer_kinds[i_index].digits = bitsize - 1;
      gfc_integer_kinds[i_index].bit_size = bitsize;

      gfc_logical_kinds[i_index].kind = kind;
      gfc_logical_kinds[i_index].bit_size = bitsize;

      i_index += 1;
    }

  /* Set the kind used to match GFC_INT_IO in libgfortran.  This is
     used for large file access.  */

  if (saw_i8)
    gfc_intio_kind = 8;
  else
    gfc_intio_kind = 4;

  /* If we do not at least have kind = 4, everything is pointless.  */
  gcc_assert(saw_i4);

  /* Set the maximum integer kind.  Used with at least BOZ constants.  */
  gfc_max_integer_kind = gfc_integer_kinds[i_index - 1].kind;

  r_index = 0;
  FOR_EACH_MODE_IN_CLASS (float_mode_iter, MODE_FLOAT)
    {
      scalar_float_mode mode = float_mode_iter.require ();
      const struct real_format *fmt = REAL_MODE_FORMAT (mode);
      int kind;

      if (fmt == NULL)
	continue;
      if (!targetm.scalar_mode_supported_p (mode))
	continue;

      /* Only let float, double, long double and __float128 go through.
	 Runtime support for others is not provided, so they would be
	 useless.  */
      if (!targetm.libgcc_floating_mode_supported_p (mode))
	continue;
      if (mode != TYPE_MODE (float_type_node)
	    && (mode != TYPE_MODE (double_type_node))
	    && (mode != TYPE_MODE (long_double_type_node))
#if defined(HAVE_TFmode) && defined(ENABLE_LIBQUADMATH_SUPPORT)
	    && (mode != TFmode)
#endif
	   )
	continue;

      /* Let the kind equal the precision divided by 8, rounding up.  Again,
	 this insulates the programmer from the underlying byte size.

	 Also, it effectively deals with IEEE extended formats.  There, the
	 total size of the type may equal 16, but it's got 6 bytes of padding
	 and the increased size can get in the way of a real IEEE quad format
	 which may also be supported by the target.

	 We round up so as to handle IA-64 __floatreg (RFmode), which is an
	 82 bit type.  Not to be confused with __float80 (XFmode), which is
	 an 80 bit type also supported by IA-64.  So XFmode should come out
	 to be kind=10, and RFmode should come out to be kind=11.  Egads.  */

      kind = (GET_MODE_PRECISION (mode) + 7) / 8;

      if (kind == 4)
	saw_r4 = true;
      if (kind == 8)
	saw_r8 = true;
      if (kind == 10)
	saw_r10 = true;
      if (kind == 16)
	saw_r16 = true;

      /* Careful we don't stumble a weird internal mode.  */
      gcc_assert (r_index <= 0 || gfc_real_kinds[r_index-1].kind != kind);
      /* Or have too many modes for the allocated space.  */
      gcc_assert (r_index != MAX_REAL_KINDS);

      gfc_real_kinds[r_index].kind = kind;
      gfc_real_kinds[r_index].radix = fmt->b;
      gfc_real_kinds[r_index].digits = fmt->p;
      gfc_real_kinds[r_index].min_exponent = fmt->emin;
      gfc_real_kinds[r_index].max_exponent = fmt->emax;
      if (fmt->pnan < fmt->p)
	/* This is an IBM extended double format (or the MIPS variant)
	   made up of two IEEE doubles.  The value of the long double is
	   the sum of the values of the two parts.  The most significant
	   part is required to be the value of the long double rounded
	   to the nearest double.  If we use emax of 1024 then we can't
	   represent huge(x) = (1 - b**(-p)) * b**(emax-1) * b, because
	   rounding will make the most significant part overflow.  */
	gfc_real_kinds[r_index].max_exponent = fmt->emax - 1;
      gfc_real_kinds[r_index].mode_precision = GET_MODE_PRECISION (mode);
      r_index += 1;
    }

  /* Choose the default integer kind.  We choose 4 unless the user directs us
     otherwise.  Even if the user specified that the default integer kind is 8,
     the numeric storage size is not 64 bits.  In this case, a warning will be
     issued when NUMERIC_STORAGE_SIZE is used.  Set NUMERIC_STORAGE_SIZE to 32.  */

  gfc_numeric_storage_size = 4 * 8;

  if (flag_default_integer)
    {
      if (!saw_i8)
	gfc_fatal_error ("INTEGER(KIND=8) is not available for "
			 "%<-fdefault-integer-8%> option");

      gfc_default_integer_kind = 8;

    }
  else if (flag_integer4_kind == 8)
    {
      if (!saw_i8)
	gfc_fatal_error ("INTEGER(KIND=8) is not available for "
			 "%<-finteger-4-integer-8%> option");

      gfc_default_integer_kind = 8;
    }
  else if (saw_i4)
    {
      gfc_default_integer_kind = 4;
    }
  else
    {
      gfc_default_integer_kind = gfc_integer_kinds[i_index - 1].kind;
      gfc_numeric_storage_size = gfc_integer_kinds[i_index - 1].bit_size;
    }

  /* Choose the default real kind.  Again, we choose 4 when possible.  */
  if (flag_default_real_8)
    {
      if (!saw_r8)
	gfc_fatal_error ("REAL(KIND=8) is not available for "
			 "%<-fdefault-real-8%> option");

      gfc_default_real_kind = 8;
    }
  else if (flag_default_real_10)
  {
    if (!saw_r10)
      gfc_fatal_error ("REAL(KIND=10) is not available for "
			"%<-fdefault-real-10%> option");

    gfc_default_real_kind = 10;
  }
  else if (flag_default_real_16)
  {
    if (!saw_r16)
      gfc_fatal_error ("REAL(KIND=16) is not available for "
			"%<-fdefault-real-16%> option");

    gfc_default_real_kind = 16;
  }
  else if (flag_real4_kind == 8)
  {
    if (!saw_r8)
      gfc_fatal_error ("REAL(KIND=8) is not available for %<-freal-4-real-8%> "
		       "option");

    gfc_default_real_kind = 8;
  }
  else if (flag_real4_kind == 10)
  {
    if (!saw_r10)
      gfc_fatal_error ("REAL(KIND=10) is not available for "
		       "%<-freal-4-real-10%> option");

    gfc_default_real_kind = 10;
  }
  else if (flag_real4_kind == 16)
  {
    if (!saw_r16)
      gfc_fatal_error ("REAL(KIND=16) is not available for "
		       "%<-freal-4-real-16%> option");

    gfc_default_real_kind = 16;
  }
  else if (saw_r4)
    gfc_default_real_kind = 4;
  else
    gfc_default_real_kind = gfc_real_kinds[0].kind;

  /* Choose the default double kind.  If -fdefault-real and -fdefault-double
     are specified, we use kind=8, if it's available.  If -fdefault-real is
     specified without -fdefault-double, we use kind=16, if it's available.
     Otherwise we do not change anything.  */
  if (flag_default_double && saw_r8)
    gfc_default_double_kind = 8;
  else if (flag_default_real_8 || flag_default_real_10 || flag_default_real_16)
    {
      /* Use largest available kind.  */
      if (saw_r16)
	gfc_default_double_kind = 16;
      else if (saw_r10)
	gfc_default_double_kind = 10;
      else if (saw_r8)
	gfc_default_double_kind = 8;
      else
	gfc_default_double_kind = gfc_default_real_kind;
    }
  else if (flag_real8_kind == 4)
    {
      if (!saw_r4)
	gfc_fatal_error ("REAL(KIND=4) is not available for "
			 "%<-freal-8-real-4%> option");

      gfc_default_double_kind = 4;
    }
  else if (flag_real8_kind == 10 )
    {
      if (!saw_r10)
	gfc_fatal_error ("REAL(KIND=10) is not available for "
			 "%<-freal-8-real-10%> option");

      gfc_default_double_kind = 10;
    }
  else if (flag_real8_kind == 16 )
    {
      if (!saw_r16)
	gfc_fatal_error ("REAL(KIND=10) is not available for "
			 "%<-freal-8-real-16%> option");

      gfc_default_double_kind = 16;
    }
  else if (saw_r4 && saw_r8)
    gfc_default_double_kind = 8;
  else
    {
      /* F95 14.6.3.1: A nonpointer scalar object of type double precision
	 real ... occupies two contiguous numeric storage units.

	 Therefore we must be supplied a kind twice as large as we chose
	 for single precision.  There are loopholes, in that double
	 precision must *occupy* two storage units, though it doesn't have
	 to *use* two storage units.  Which means that you can make this
	 kind artificially wide by padding it.  But at present there are
	 no GCC targets for which a two-word type does not exist, so we
	 just let gfc_validate_kind abort and tell us if something breaks.  */

      gfc_default_double_kind
	= gfc_validate_kind (BT_REAL, gfc_default_real_kind * 2, false);
    }

  /* The default logical kind is constrained to be the same as the
     default integer kind.  Similarly with complex and real.  */
  gfc_default_logical_kind = gfc_default_integer_kind;
  gfc_default_complex_kind = gfc_default_real_kind;

  /* We only have two character kinds: ASCII and UCS-4.
     ASCII corresponds to a 8-bit integer type, if one is available.
     UCS-4 corresponds to a 32-bit integer type, if one is available.  */
  i_index = 0;
  if ((kind = get_int_kind_from_width (8)) > 0)
    {
      gfc_character_kinds[i_index].kind = kind;
      gfc_character_kinds[i_index].bit_size = 8;
      gfc_character_kinds[i_index].name = "ascii";
      i_index++;
    }
  if ((kind = get_int_kind_from_width (32)) > 0)
    {
      gfc_character_kinds[i_index].kind = kind;
      gfc_character_kinds[i_index].bit_size = 32;
      gfc_character_kinds[i_index].name = "iso_10646";
      i_index++;
    }

  /* Choose the smallest integer kind for our default character.  */
  gfc_default_character_kind = gfc_character_kinds[0].kind;
  gfc_character_storage_size = gfc_default_character_kind * 8;

  gfc_index_integer_kind = get_int_kind_from_name (PTRDIFF_TYPE);

  /* Pick a kind the same size as the C "int" type.  */
  gfc_c_int_kind = INT_TYPE_SIZE / 8;

  /* Choose atomic kinds to match C's int.  */
  gfc_atomic_int_kind = gfc_c_int_kind;
  gfc_atomic_logical_kind = gfc_c_int_kind;
}


/* Make sure that a valid kind is present.  Returns an index into the
   associated kinds array, -1 if the kind is not present.  */

static int
validate_integer (int kind)
{
  int i;

  for (i = 0; gfc_integer_kinds[i].kind != 0; i++)
    if (gfc_integer_kinds[i].kind == kind)
      return i;

  return -1;
}

static int
validate_real (int kind)
{
  int i;

  for (i = 0; gfc_real_kinds[i].kind != 0; i++)
    if (gfc_real_kinds[i].kind == kind)
      return i;

  return -1;
}

static int
validate_logical (int kind)
{
  int i;

  for (i = 0; gfc_logical_kinds[i].kind; i++)
    if (gfc_logical_kinds[i].kind == kind)
      return i;

  return -1;
}

static int
validate_character (int kind)
{
  int i;

  for (i = 0; gfc_character_kinds[i].kind; i++)
    if (gfc_character_kinds[i].kind == kind)
      return i;

  return -1;
}

/* Validate a kind given a basic type.  The return value is the same
   for the child functions, with -1 indicating nonexistence of the
   type.  If MAY_FAIL is false, then -1 is never returned, and we ICE.  */

int
gfc_validate_kind (bt type, int kind, bool may_fail)
{
  int rc;

  switch (type)
    {
    case BT_REAL:		/* Fall through */
    case BT_COMPLEX:
      rc = validate_real (kind);
      break;
    case BT_INTEGER:
      rc = validate_integer (kind);
      break;
    case BT_LOGICAL:
      rc = validate_logical (kind);
      break;
    case BT_CHARACTER:
      rc = validate_character (kind);
      break;

    default:
      gfc_internal_error ("gfc_validate_kind(): Got bad type");
    }

  if (rc < 0 && !may_fail)
    gfc_internal_error ("gfc_validate_kind(): Got bad kind");

  return rc;
}


/* Four subroutines of gfc_init_types.  Create type nodes for the given kind.
   Reuse common type nodes where possible.  Recognize if the kind matches up
   with a C type.  This will be used later in determining which routines may
   be scarfed from libm.  */

static tree
gfc_build_int_type (gfc_integer_info *info)
{
  int mode_precision = info->bit_size;

  if (mode_precision == CHAR_TYPE_SIZE)
    info->c_char = 1;
  if (mode_precision == SHORT_TYPE_SIZE)
    info->c_short = 1;
  if (mode_precision == INT_TYPE_SIZE)
    info->c_int = 1;
  if (mode_precision == LONG_TYPE_SIZE)
    info->c_long = 1;
  if (mode_precision == LONG_LONG_TYPE_SIZE)
    info->c_long_long = 1;

  if (TYPE_PRECISION (intQI_type_node) == mode_precision)
    return intQI_type_node;
  if (TYPE_PRECISION (intHI_type_node) == mode_precision)
    return intHI_type_node;
  if (TYPE_PRECISION (intSI_type_node) == mode_precision)
    return intSI_type_node;
  if (TYPE_PRECISION (intDI_type_node) == mode_precision)
    return intDI_type_node;
  if (TYPE_PRECISION (intTI_type_node) == mode_precision)
    return intTI_type_node;

  return make_signed_type (mode_precision);
}

tree
gfc_build_uint_type (int size)
{
  if (size == CHAR_TYPE_SIZE)
    return unsigned_char_type_node;
  if (size == SHORT_TYPE_SIZE)
    return short_unsigned_type_node;
  if (size == INT_TYPE_SIZE)
    return unsigned_type_node;
  if (size == LONG_TYPE_SIZE)
    return long_unsigned_type_node;
  if (size == LONG_LONG_TYPE_SIZE)
    return long_long_unsigned_type_node;

  return make_unsigned_type (size);
}


static tree
gfc_build_real_type (gfc_real_info *info)
{
  int mode_precision = info->mode_precision;
  tree new_type;

  if (mode_precision == FLOAT_TYPE_SIZE)
    info->c_float = 1;
  if (mode_precision == DOUBLE_TYPE_SIZE)
    info->c_double = 1;
  if (mode_precision == LONG_DOUBLE_TYPE_SIZE)
    info->c_long_double = 1;
  if (mode_precision != LONG_DOUBLE_TYPE_SIZE && mode_precision == 128)
    {
      info->c_float128 = 1;
      gfc_real16_is_float128 = true;
    }

  if (TYPE_PRECISION (float_type_node) == mode_precision)
    return float_type_node;
  if (TYPE_PRECISION (double_type_node) == mode_precision)
    return double_type_node;
  if (TYPE_PRECISION (long_double_type_node) == mode_precision)
    return long_double_type_node;

  new_type = make_node (REAL_TYPE);
  TYPE_PRECISION (new_type) = mode_precision;
  layout_type (new_type);
  return new_type;
}

static tree
gfc_build_complex_type (tree scalar_type)
{
  tree new_type;

  if (scalar_type == NULL)
    return NULL;
  if (scalar_type == float_type_node)
    return complex_float_type_node;
  if (scalar_type == double_type_node)
    return complex_double_type_node;
  if (scalar_type == long_double_type_node)
    return complex_long_double_type_node;

  new_type = make_node (COMPLEX_TYPE);
  TREE_TYPE (new_type) = scalar_type;
  layout_type (new_type);
  return new_type;
}

static tree
gfc_build_logical_type (gfc_logical_info *info)
{
  int bit_size = info->bit_size;
  tree new_type;

  if (bit_size == BOOL_TYPE_SIZE)
    {
      info->c_bool = 1;
      return boolean_type_node;
    }

  new_type = make_unsigned_type (bit_size);
  TREE_SET_CODE (new_type, BOOLEAN_TYPE);
  TYPE_MAX_VALUE (new_type) = build_int_cst (new_type, 1);
  TYPE_PRECISION (new_type) = 1;

  return new_type;
}


/* Create the backend type nodes. We map them to their
   equivalent C type, at least for now.  We also give
   names to the types here, and we push them in the
   global binding level context.*/

void
gfc_init_types (void)
{
  char name_buf[26];
  int index;
  tree type;
  unsigned n;

  /* Create and name the types.  */
#define PUSH_TYPE(name, node) \
  pushdecl (build_decl (input_location, \
			TYPE_DECL, get_identifier (name), node))

  for (index = 0; gfc_integer_kinds[index].kind != 0; ++index)
    {
      type = gfc_build_int_type (&gfc_integer_kinds[index]);
      /* Ensure integer(kind=1) doesn't have TYPE_STRING_FLAG set.  */
      if (TYPE_STRING_FLAG (type))
	type = make_signed_type (gfc_integer_kinds[index].bit_size);
      gfc_integer_types[index] = type;
      snprintf (name_buf, sizeof(name_buf), "integer(kind=%d)",
		gfc_integer_kinds[index].kind);
      PUSH_TYPE (name_buf, type);
    }

  for (index = 0; gfc_logical_kinds[index].kind != 0; ++index)
    {
      type = gfc_build_logical_type (&gfc_logical_kinds[index]);
      gfc_logical_types[index] = type;
      snprintf (name_buf, sizeof(name_buf), "logical(kind=%d)",
		gfc_logical_kinds[index].kind);
      PUSH_TYPE (name_buf, type);
    }

  for (index = 0; gfc_real_kinds[index].kind != 0; index++)
    {
      type = gfc_build_real_type (&gfc_real_kinds[index]);
      gfc_real_types[index] = type;
      snprintf (name_buf, sizeof(name_buf), "real(kind=%d)",
		gfc_real_kinds[index].kind);
      PUSH_TYPE (name_buf, type);

      if (gfc_real_kinds[index].c_float128)
	gfc_float128_type_node = type;

      type = gfc_build_complex_type (type);
      gfc_complex_types[index] = type;
      snprintf (name_buf, sizeof(name_buf), "complex(kind=%d)",
		gfc_real_kinds[index].kind);
      PUSH_TYPE (name_buf, type);

      if (gfc_real_kinds[index].c_float128)
	gfc_complex_float128_type_node = type;
    }

  for (index = 0; gfc_character_kinds[index].kind != 0; ++index)
    {
      type = gfc_build_uint_type (gfc_character_kinds[index].bit_size);
      type = build_qualified_type (type, TYPE_UNQUALIFIED);
      snprintf (name_buf, sizeof(name_buf), "character(kind=%d)",
		gfc_character_kinds[index].kind);
      PUSH_TYPE (name_buf, type);
      gfc_character_types[index] = type;
      gfc_pcharacter_types[index] = build_pointer_type (type);
    }
  gfc_character1_type_node = gfc_character_types[0];

  PUSH_TYPE ("byte", unsigned_char_type_node);
  PUSH_TYPE ("void", void_type_node);

  /* DBX debugging output gets upset if these aren't set.  */
  if (!TYPE_NAME (integer_type_node))
    PUSH_TYPE ("c_integer", integer_type_node);
  if (!TYPE_NAME (char_type_node))
    PUSH_TYPE ("c_char", char_type_node);

#undef PUSH_TYPE

  pvoid_type_node = build_pointer_type (void_type_node);
  prvoid_type_node = build_qualified_type (pvoid_type_node, TYPE_QUAL_RESTRICT);
  ppvoid_type_node = build_pointer_type (pvoid_type_node);
  pchar_type_node = build_pointer_type (gfc_character1_type_node);
  pfunc_type_node
    = build_pointer_type (build_function_type_list (void_type_node, NULL_TREE));

  gfc_array_index_type = gfc_get_int_type (gfc_index_integer_kind);
  /* We cannot use gfc_index_zero_node in definition of gfc_array_range_type,
     since this function is called before gfc_init_constants.  */
  gfc_array_range_type
	  = build_range_type (gfc_array_index_type,
			      build_int_cst (gfc_array_index_type, 0),
			      NULL_TREE);

  /* The maximum array element size that can be handled is determined
     by the number of bits available to store this field in the array
     descriptor.  */

  n = TYPE_PRECISION (size_type_node);
  gfc_max_array_element_size
    = wide_int_to_tree (size_type_node,
			wi::mask (n, UNSIGNED,
				  TYPE_PRECISION (size_type_node)));

  logical_type_node = gfc_get_logical_type (gfc_default_logical_kind);
  logical_true_node = build_int_cst (logical_type_node, 1);
  logical_false_node = build_int_cst (logical_type_node, 0);

  /* Character lengths are of type size_t, except signed.  */
  gfc_charlen_int_kind = get_int_kind_from_node (size_type_node);
  gfc_charlen_type_node = gfc_get_int_type (gfc_charlen_int_kind);

  /* Fortran kind number of size_type_node (size_t). This is used for
     the _size member in vtables.  */
  gfc_size_kind = get_int_kind_from_node (size_type_node);
}

/* Get the type node for the given type and kind.  */

tree
gfc_get_int_type (int kind)
{
  int index = gfc_validate_kind (BT_INTEGER, kind, true);
  return index < 0 ? 0 : gfc_integer_types[index];
}

tree
gfc_get_real_type (int kind)
{
  int index = gfc_validate_kind (BT_REAL, kind, true);
  return index < 0 ? 0 : gfc_real_types[index];
}

tree
gfc_get_complex_type (int kind)
{
  int index = gfc_validate_kind (BT_COMPLEX, kind, true);
  return index < 0 ? 0 : gfc_complex_types[index];
}

tree
gfc_get_logical_type (int kind)
{
  int index = gfc_validate_kind (BT_LOGICAL, kind, true);
  return index < 0 ? 0 : gfc_logical_types[index];
}

tree
gfc_get_char_type (int kind)
{
  int index = gfc_validate_kind (BT_CHARACTER, kind, true);
  return index < 0 ? 0 : gfc_character_types[index];
}

tree
gfc_get_pchar_type (int kind)
{
  int index = gfc_validate_kind (BT_CHARACTER, kind, true);
  return index < 0 ? 0 : gfc_pcharacter_types[index];
}


/* Create a character type with the given kind and length.  */

tree
gfc_get_character_type_len_for_eltype (tree eltype, tree len)
{
  tree bounds, type;

  bounds = build_range_type (gfc_charlen_type_node, gfc_index_one_node, len);
  type = build_array_type (eltype, bounds);
  TYPE_STRING_FLAG (type) = 1;

  return type;
}

tree
gfc_get_character_type_len (int kind, tree len)
{
  gfc_validate_kind (BT_CHARACTER, kind, false);
  return gfc_get_character_type_len_for_eltype (gfc_get_char_type (kind), len);
}


/* Get a type node for a character kind.  */

tree
gfc_get_character_type (int kind, gfc_charlen * cl)
{
  tree len;

  len = (cl == NULL) ? NULL_TREE : cl->backend_decl;
  if (len && POINTER_TYPE_P (TREE_TYPE (len)))
    len = build_fold_indirect_ref (len);

  return gfc_get_character_type_len (kind, len);
}

/* Convert a basic type.  This will be an array for character types.  */

tree
gfc_typenode_for_spec (gfc_typespec * spec, int codim)
{
  tree basetype;

  switch (spec->type)
    {
    case BT_UNKNOWN:
      gcc_unreachable ();

    case BT_INTEGER:
      /* We use INTEGER(c_intptr_t) for C_PTR and C_FUNPTR once the symbol
         has been resolved.  This is done so we can convert C_PTR and
         C_FUNPTR to simple variables that get translated to (void *).  */
      if (spec->f90_type == BT_VOID)
	{
	  if (spec->u.derived
	      && spec->u.derived->intmod_sym_id == ISOCBINDING_PTR)
	    basetype = ptr_type_node;
	  else
	    basetype = pfunc_type_node;
	}
      else
        basetype = gfc_get_int_type (spec->kind);
      break;

    case BT_REAL:
      basetype = gfc_get_real_type (spec->kind);
      break;

    case BT_COMPLEX:
      basetype = gfc_get_complex_type (spec->kind);
      break;

    case BT_LOGICAL:
      basetype = gfc_get_logical_type (spec->kind);
      break;

    case BT_CHARACTER:
      basetype = gfc_get_character_type (spec->kind, spec->u.cl);
      break;

    case BT_HOLLERITH:
      /* Since this cannot be used, return a length one character.  */
      basetype = gfc_get_character_type_len (gfc_default_character_kind,
					     gfc_index_one_node);
      break;

    case BT_UNION:
      basetype = gfc_get_union_type (spec->u.derived);
      break;

    case BT_DERIVED:
    case BT_CLASS:
      basetype = gfc_get_derived_type (spec->u.derived, codim);

      if (spec->type == BT_CLASS)
	GFC_CLASS_TYPE_P (basetype) = 1;

      /* If we're dealing with either C_PTR or C_FUNPTR, we modified the
         type and kind to fit a (void *) and the basetype returned was a
         ptr_type_node.  We need to pass up this new information to the
         symbol that was declared of type C_PTR or C_FUNPTR.  */
      if (spec->u.derived->ts.f90_type == BT_VOID)
        {
          spec->type = BT_INTEGER;
          spec->kind = gfc_index_integer_kind;
          spec->f90_type = BT_VOID;
        }
      break;
    case BT_VOID:
    case BT_ASSUMED:
      /* This is for the second arg to c_f_pointer and c_f_procpointer
         of the iso_c_binding module, to accept any ptr type.  */
      basetype = ptr_type_node;
      if (spec->f90_type == BT_VOID)
	{
	  if (spec->u.derived
	      && spec->u.derived->intmod_sym_id == ISOCBINDING_PTR)
	    basetype = ptr_type_node;
	  else
	    basetype = pfunc_type_node;
	}
       break;
    default:
      gcc_unreachable ();
    }
  return basetype;
}

/* Build an INT_CST for constant expressions, otherwise return NULL_TREE.  */

static tree
gfc_conv_array_bound (gfc_expr * expr)
{
  /* If expr is an integer constant, return that.  */
  if (expr != NULL && expr->expr_type == EXPR_CONSTANT)
    return gfc_conv_mpz_to_tree (expr->value.integer, gfc_index_integer_kind);

  /* Otherwise return NULL.  */
  return NULL_TREE;
}

/* Return the type of an element of the array.  Note that scalar coarrays
   are special.  In particular, for GFC_ARRAY_TYPE_P, the original argument
   (with POINTER_TYPE stripped) is returned.  */

tree
gfc_get_element_type (tree type)
{
  tree element;

  if (GFC_ARRAY_TYPE_P (type))
    {
      if (TREE_CODE (type) == POINTER_TYPE)
        type = TREE_TYPE (type);
      if (GFC_TYPE_ARRAY_RANK (type) == 0)
	{
	  gcc_assert (GFC_TYPE_ARRAY_CORANK (type) > 0);
	  element = type;
	}
      else
	{
	  gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
	  element = TREE_TYPE (type);
	}
    }
  else
    {
      gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
      element = GFC_TYPE_ARRAY_DATAPTR_TYPE (type);

      gcc_assert (TREE_CODE (element) == POINTER_TYPE);
      element = TREE_TYPE (element);

      /* For arrays, which are not scalar coarrays.  */
      if (TREE_CODE (element) == ARRAY_TYPE && !TYPE_STRING_FLAG (element))
	element = TREE_TYPE (element);
    }

  return element;
}

/* Build an array.  This function is called from gfc_sym_type().
   Actually returns array descriptor type.

   Format of array descriptors is as follows:

    struct gfc_array_descriptor
    {
      array *data;
      index offset;
      struct dtype_type dtype;
      struct descriptor_dimension dimension[N_DIM];
    }

    struct dtype_type
    {
      size_t elem_len;
      int version;
      signed char rank;
      signed char type;
      signed short attribute;
    }

    struct descriptor_dimension
    {
      index stride;
      index lbound;
      index ubound;
    }

   Translation code should use gfc_conv_descriptor_* rather than
   accessing the descriptor directly.  Any changes to the array
   descriptor type will require changes in gfc_conv_descriptor_* and
   gfc_build_array_initializer.

   This is represented internally as a RECORD_TYPE. The index nodes
   are gfc_array_index_type and the data node is a pointer to the
   data.  See below for the handling of character types.

   I originally used nested ARRAY_TYPE nodes to represent arrays, but
   this generated poor code for assumed/deferred size arrays.  These
   require use of PLACEHOLDER_EXPR/WITH_RECORD_EXPR, which isn't part
   of the GENERIC grammar.  Also, there is no way to explicitly set
   the array stride, so all data must be packed(1).  I've tried to
   mark all the functions which would require modification with a GCC
   ARRAYS comment.

   The data component points to the first element in the array.  The
   offset field is the position of the origin of the array (i.e. element
   (0, 0 ...)).  This may be outside the bounds of the array.

   An element is accessed by
    data[offset + index0*stride0 + index1*stride1 + index2*stride2]
   This gives good performance as the computation does not involve the
   bounds of the array.  For packed arrays, this is optimized further
   by substituting the known strides.

   This system has one problem: all array bounds must be within 2^31
   elements of the origin (2^63 on 64-bit machines).  For example
    integer, dimension (80000:90000, 80000:90000, 2) :: array
   may not work properly on 32-bit machines because 80000*80000 >
   2^31, so the calculation for stride2 would overflow.  This may
   still work, but I haven't checked, and it relies on the overflow
   doing the right thing.

   The way to fix this problem is to access elements as follows:
    data[(index0-lbound0)*stride0 + (index1-lbound1)*stride1]
   Obviously this is much slower.  I will make this a compile time
   option, something like -fsmall-array-offsets.  Mixing code compiled
   with and without this switch will work.

   (1) This can be worked around by modifying the upper bound of the
   previous dimension.  This requires extra fields in the descriptor
   (both real_ubound and fake_ubound).  */


/* Returns true if the array sym does not require a descriptor.  */

int
gfc_is_nodesc_array (gfc_symbol * sym)
{
  symbol_attribute *array_attr;
  gfc_array_spec *as;
  bool is_classarray = IS_CLASS_ARRAY (sym);

  array_attr = is_classarray ? &CLASS_DATA (sym)->attr : &sym->attr;
  as = is_classarray ? CLASS_DATA (sym)->as : sym->as;

  gcc_assert (array_attr->dimension || array_attr->codimension);

  /* We only want local arrays.  */
  if ((sym->ts.type != BT_CLASS && sym->attr.pointer)
      || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.class_pointer)
      || array_attr->allocatable)
    return 0;

  /* We want a descriptor for associate-name arrays that do not have an
	 explicitly known shape already.  */
  if (sym->assoc && as->type != AS_EXPLICIT)
    return 0;

  /* The dummy is stored in sym and not in the component.  */
  if (sym->attr.dummy)
    return as->type != AS_ASSUMED_SHAPE
	&& as->type != AS_ASSUMED_RANK;

  if (sym->attr.result || sym->attr.function)
    return 0;

  gcc_assert (as->type == AS_EXPLICIT || as->cp_was_assumed);

  return 1;
}


/* Create an array descriptor type.  */

static tree
gfc_build_array_type (tree type, gfc_array_spec * as,
		      enum gfc_array_kind akind, bool restricted,
		      bool contiguous, int codim)
{
  tree lbound[GFC_MAX_DIMENSIONS];
  tree ubound[GFC_MAX_DIMENSIONS];
  int n, corank;

  /* Assumed-shape arrays do not have codimension information stored in the
     descriptor.  */
  corank = MAX (as->corank, codim);
  if (as->type == AS_ASSUMED_SHAPE ||
      (as->type == AS_ASSUMED_RANK && akind == GFC_ARRAY_ALLOCATABLE))
    corank = codim;

  if (as->type == AS_ASSUMED_RANK)
    for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
      {
	lbound[n] = NULL_TREE;
	ubound[n] = NULL_TREE;
      }

  for (n = 0; n < as->rank; n++)
    {
      /* Create expressions for the known bounds of the array.  */
      if (as->type == AS_ASSUMED_SHAPE && as->lower[n] == NULL)
        lbound[n] = gfc_index_one_node;
      else
        lbound[n] = gfc_conv_array_bound (as->lower[n]);
      ubound[n] = gfc_conv_array_bound (as->upper[n]);
    }

  for (n = as->rank; n < as->rank + corank; n++)
    {
      if (as->type != AS_DEFERRED && as->lower[n] == NULL)
        lbound[n] = gfc_index_one_node;
      else
        lbound[n] = gfc_conv_array_bound (as->lower[n]);

      if (n < as->rank + corank - 1)
	ubound[n] = gfc_conv_array_bound (as->upper[n]);
    }

  if (as->type == AS_ASSUMED_SHAPE)
    akind = contiguous ? GFC_ARRAY_ASSUMED_SHAPE_CONT
		       : GFC_ARRAY_ASSUMED_SHAPE;
  else if (as->type == AS_ASSUMED_RANK)
    akind = contiguous ? GFC_ARRAY_ASSUMED_RANK_CONT
		       : GFC_ARRAY_ASSUMED_RANK;
  return gfc_get_array_type_bounds (type, as->rank == -1
					  ? GFC_MAX_DIMENSIONS : as->rank,
				    corank, lbound, ubound, 0, akind,
				    restricted);
}

/* Returns the struct descriptor_dimension type.  */

static tree
gfc_get_desc_dim_type (void)
{
  tree type;
  tree decl, *chain = NULL;

  if (gfc_desc_dim_type)
    return gfc_desc_dim_type;

  /* Build the type node.  */
  type = make_node (RECORD_TYPE);

  TYPE_NAME (type) = get_identifier ("descriptor_dimension");
  TYPE_PACKED (type) = 1;

  /* Consists of the stride, lbound and ubound members.  */
  decl = gfc_add_field_to_struct_1 (type,
				    get_identifier ("stride"),
				    gfc_array_index_type, &chain);
  TREE_NO_WARNING (decl) = 1;

  decl = gfc_add_field_to_struct_1 (type,
				    get_identifier ("lbound"),
				    gfc_array_index_type, &chain);
  TREE_NO_WARNING (decl) = 1;

  decl = gfc_add_field_to_struct_1 (type,
				    get_identifier ("ubound"),
				    gfc_array_index_type, &chain);
  TREE_NO_WARNING (decl) = 1;

  /* Finish off the type.  */
  gfc_finish_type (type);
  TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (type)) = 1;

  gfc_desc_dim_type = type;
  return type;
}


/* Return the DTYPE for an array.  This describes the type and type parameters
   of the array.  */
/* TODO: Only call this when the value is actually used, and make all the
   unknown cases abort.  */

tree
gfc_get_dtype_rank_type (int rank, tree etype)
{
  tree size;
  int n;
  tree tmp;
  tree dtype;
  tree field;
  vec<constructor_elt, va_gc> *v = NULL;

  size = TYPE_SIZE_UNIT (etype);

  switch (TREE_CODE (etype))
    {
    case INTEGER_TYPE:
      n = BT_INTEGER;
      break;

    case BOOLEAN_TYPE:
      n = BT_LOGICAL;
      break;

    case REAL_TYPE:
      n = BT_REAL;
      break;

    case COMPLEX_TYPE:
      n = BT_COMPLEX;
      break;

    case RECORD_TYPE:
      if (GFC_CLASS_TYPE_P (etype))
	n = BT_CLASS;
      else
	n = BT_DERIVED;
      break;

    /* We will never have arrays of arrays.  */
    case ARRAY_TYPE:
      n = BT_CHARACTER;
      if (size == NULL_TREE)
	size = TYPE_SIZE_UNIT (TREE_TYPE (etype));
      break;

    case POINTER_TYPE:
      n = BT_ASSUMED;
      if (TREE_CODE (TREE_TYPE (etype)) != VOID_TYPE)
	size = TYPE_SIZE_UNIT (TREE_TYPE (etype));
      else
	size = build_int_cst (size_type_node, 0);
    break;

    default:
      /* TODO: Don't do dtype for temporary descriptorless arrays.  */
      /* We can encounter strange array types for temporary arrays.  */
      return gfc_index_zero_node;
    }

  tmp = get_dtype_type_node ();
  field = gfc_advance_chain (TYPE_FIELDS (tmp),
			     GFC_DTYPE_ELEM_LEN);
  CONSTRUCTOR_APPEND_ELT (v, field,
			  fold_convert (TREE_TYPE (field), size));

  field = gfc_advance_chain (TYPE_FIELDS (dtype_type_node),
			     GFC_DTYPE_RANK);
  CONSTRUCTOR_APPEND_ELT (v, field,
			  build_int_cst (TREE_TYPE (field), rank));

  field = gfc_advance_chain (TYPE_FIELDS (dtype_type_node),
			     GFC_DTYPE_TYPE);
  CONSTRUCTOR_APPEND_ELT (v, field,
			  build_int_cst (TREE_TYPE (field), n));

  dtype = build_constructor (tmp, v);

  return dtype;
}


tree
gfc_get_dtype (tree type)
{
  tree dtype;
  tree etype;
  int rank;

  gcc_assert (GFC_DESCRIPTOR_TYPE_P (type) || GFC_ARRAY_TYPE_P (type));

  rank = GFC_TYPE_ARRAY_RANK (type);
  etype = gfc_get_element_type (type);
  dtype = gfc_get_dtype_rank_type (rank, etype);

  GFC_TYPE_ARRAY_DTYPE (type) = dtype;
  return dtype;
}


/* Build an array type for use without a descriptor, packed according
   to the value of PACKED.  */

tree
gfc_get_nodesc_array_type (tree etype, gfc_array_spec * as, gfc_packed packed,
			   bool restricted)
{
  tree range;
  tree type;
  tree tmp;
  int n;
  int known_stride;
  int known_offset;
  mpz_t offset;
  mpz_t stride;
  mpz_t delta;
  gfc_expr *expr;

  mpz_init_set_ui (offset, 0);
  mpz_init_set_ui (stride, 1);
  mpz_init (delta);

  /* We don't use build_array_type because this does not include include
     lang-specific information (i.e. the bounds of the array) when checking
     for duplicates.  */
  if (as->rank)
    type = make_node (ARRAY_TYPE);
  else
    type = build_variant_type_copy (etype);

  GFC_ARRAY_TYPE_P (type) = 1;
  TYPE_LANG_SPECIFIC (type) = ggc_cleared_alloc<struct lang_type> ();

  known_stride = (packed != PACKED_NO);
  known_offset = 1;
  for (n = 0; n < as->rank; n++)
    {
      /* Fill in the stride and bound components of the type.  */
      if (known_stride)
	tmp = gfc_conv_mpz_to_tree (stride, gfc_index_integer_kind);
      else
        tmp = NULL_TREE;
      GFC_TYPE_ARRAY_STRIDE (type, n) = tmp;

      expr = as->lower[n];
      if (expr->expr_type == EXPR_CONSTANT)
        {
          tmp = gfc_conv_mpz_to_tree (expr->value.integer,
				      gfc_index_integer_kind);
        }
      else
        {
          known_stride = 0;
          tmp = NULL_TREE;
        }
      GFC_TYPE_ARRAY_LBOUND (type, n) = tmp;

      if (known_stride)
	{
          /* Calculate the offset.  */
          mpz_mul (delta, stride, as->lower[n]->value.integer);
          mpz_sub (offset, offset, delta);
	}
      else
	known_offset = 0;

      expr = as->upper[n];
      if (expr && expr->expr_type == EXPR_CONSTANT)
        {
	  tmp = gfc_conv_mpz_to_tree (expr->value.integer,
			          gfc_index_integer_kind);
        }
      else
        {
          tmp = NULL_TREE;
          known_stride = 0;
        }
      GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;

      if (known_stride)
        {
          /* Calculate the stride.  */
          mpz_sub (delta, as->upper[n]->value.integer,
	           as->lower[n]->value.integer);
          mpz_add_ui (delta, delta, 1);
          mpz_mul (stride, stride, delta);
        }

      /* Only the first stride is known for partial packed arrays.  */
      if (packed == PACKED_NO || packed == PACKED_PARTIAL)
        known_stride = 0;
    }
  for (n = as->rank; n < as->rank + as->corank; n++)
    {
      expr = as->lower[n];
      if (expr->expr_type == EXPR_CONSTANT)
	tmp = gfc_conv_mpz_to_tree (expr->value.integer,
				    gfc_index_integer_kind);
      else
      	tmp = NULL_TREE;
      GFC_TYPE_ARRAY_LBOUND (type, n) = tmp;

      expr = as->upper[n];
      if (expr && expr->expr_type == EXPR_CONSTANT)
	tmp = gfc_conv_mpz_to_tree (expr->value.integer,
				    gfc_index_integer_kind);
      else
 	tmp = NULL_TREE;
      if (n < as->rank + as->corank - 1)
      GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
    }

  if (known_offset)
    {
      GFC_TYPE_ARRAY_OFFSET (type) =
        gfc_conv_mpz_to_tree (offset, gfc_index_integer_kind);
    }
  else
    GFC_TYPE_ARRAY_OFFSET (type) = NULL_TREE;

  if (known_stride)
    {
      GFC_TYPE_ARRAY_SIZE (type) =
        gfc_conv_mpz_to_tree (stride, gfc_index_integer_kind);
    }
  else
    GFC_TYPE_ARRAY_SIZE (type) = NULL_TREE;

  GFC_TYPE_ARRAY_RANK (type) = as->rank;
  GFC_TYPE_ARRAY_CORANK (type) = as->corank;
  GFC_TYPE_ARRAY_DTYPE (type) = NULL_TREE;
  range = build_range_type (gfc_array_index_type, gfc_index_zero_node,
			    NULL_TREE);
  /* TODO: use main type if it is unbounded.  */
  GFC_TYPE_ARRAY_DATAPTR_TYPE (type) =
    build_pointer_type (build_array_type (etype, range));
  if (restricted)
    GFC_TYPE_ARRAY_DATAPTR_TYPE (type) =
      build_qualified_type (GFC_TYPE_ARRAY_DATAPTR_TYPE (type),
			    TYPE_QUAL_RESTRICT);

  if (as->rank == 0)
    {
      if (packed != PACKED_STATIC  || flag_coarray == GFC_FCOARRAY_LIB)
	{
	  type = build_pointer_type (type);

	  if (restricted)
	    type = build_qualified_type (type, TYPE_QUAL_RESTRICT);

	  GFC_ARRAY_TYPE_P (type) = 1;
	  TYPE_LANG_SPECIFIC (type) = TYPE_LANG_SPECIFIC (TREE_TYPE (type));
	}

      return type;
    }

  if (known_stride)
    {
      mpz_sub_ui (stride, stride, 1);
      range = gfc_conv_mpz_to_tree (stride, gfc_index_integer_kind);
    }
  else
    range = NULL_TREE;

  range = build_range_type (gfc_array_index_type, gfc_index_zero_node, range);
  TYPE_DOMAIN (type) = range;

  build_pointer_type (etype);
  TREE_TYPE (type) = etype;

  layout_type (type);

  mpz_clear (offset);
  mpz_clear (stride);
  mpz_clear (delta);

  /* Represent packed arrays as multi-dimensional if they have rank >
     1 and with proper bounds, instead of flat arrays.  This makes for
     better debug info.  */
  if (known_offset)
    {
      tree gtype = etype, rtype, type_decl;

      for (n = as->rank - 1; n >= 0; n--)
	{
	  rtype = build_range_type (gfc_array_index_type,
				    GFC_TYPE_ARRAY_LBOUND (type, n),
				    GFC_TYPE_ARRAY_UBOUND (type, n));
	  gtype = build_array_type (gtype, rtype);
	}
      TYPE_NAME (type) = type_decl = build_decl (input_location,
						 TYPE_DECL, NULL, gtype);
      DECL_ORIGINAL_TYPE (type_decl) = gtype;
    }

  if (packed != PACKED_STATIC || !known_stride
      || (as->corank && flag_coarray == GFC_FCOARRAY_LIB))
    {
      /* For dummy arrays and automatic (heap allocated) arrays we
	 want a pointer to the array.  */
      type = build_pointer_type (type);
      if (restricted)
	type = build_qualified_type (type, TYPE_QUAL_RESTRICT);
      GFC_ARRAY_TYPE_P (type) = 1;
      TYPE_LANG_SPECIFIC (type) = TYPE_LANG_SPECIFIC (TREE_TYPE (type));
    }
  return type;
}


/* Return or create the base type for an array descriptor.  */

static tree
gfc_get_array_descriptor_base (int dimen, int codimen, bool restricted)
{
  tree fat_type, decl, arraytype, *chain = NULL;
  char name[16 + 2*GFC_RANK_DIGITS + 1 + 1];
  int idx;

  /* Assumed-rank array.  */
  if (dimen == -1)
    dimen = GFC_MAX_DIMENSIONS;

  idx = 2 * (codimen + dimen) + restricted;

  gcc_assert (codimen + dimen >= 0 && codimen + dimen <= GFC_MAX_DIMENSIONS);

  if (flag_coarray == GFC_FCOARRAY_LIB && codimen)
    {
      if (gfc_array_descriptor_base_caf[idx])
	return gfc_array_descriptor_base_caf[idx];
    }
  else if (gfc_array_descriptor_base[idx])
    return gfc_array_descriptor_base[idx];

  /* Build the type node.  */
  fat_type = make_node (RECORD_TYPE);

  sprintf (name, "array_descriptor" GFC_RANK_PRINTF_FORMAT, dimen + codimen);
  TYPE_NAME (fat_type) = get_identifier (name);
  TYPE_NAMELESS (fat_type) = 1;

  /* Add the data member as the first element of the descriptor.  */
  decl = gfc_add_field_to_struct_1 (fat_type,
				    get_identifier ("data"),
				    (restricted
				     ? prvoid_type_node
				     : ptr_type_node), &chain);

  /* Add the base component.  */
  decl = gfc_add_field_to_struct_1 (fat_type,
				    get_identifier ("offset"),
				    gfc_array_index_type, &chain);
  TREE_NO_WARNING (decl) = 1;

  /* Add the dtype component.  */
  decl = gfc_add_field_to_struct_1 (fat_type,
				    get_identifier ("dtype"),
				    get_dtype_type_node (), &chain);
  TREE_NO_WARNING (decl) = 1;

  /* Add the span component.  */
  decl = gfc_add_field_to_struct_1 (fat_type,
				    get_identifier ("span"),
				    gfc_array_index_type, &chain);
  TREE_NO_WARNING (decl) = 1;

  /* Build the array type for the stride and bound components.  */
  if (dimen + codimen > 0)
    {
      arraytype =
	build_array_type (gfc_get_desc_dim_type (),
			  build_range_type (gfc_array_index_type,
					    gfc_index_zero_node,
					    gfc_rank_cst[codimen + dimen - 1]));

      decl = gfc_add_field_to_struct_1 (fat_type, get_identifier ("dim"),
					arraytype, &chain);
      TREE_NO_WARNING (decl) = 1;
    }

  if (flag_coarray == GFC_FCOARRAY_LIB)
    {
      decl = gfc_add_field_to_struct_1 (fat_type,
					get_identifier ("token"),
					prvoid_type_node, &chain);
      TREE_NO_WARNING (decl) = 1;
    }

  /* Finish off the type.  */
  gfc_finish_type (fat_type);
  TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (fat_type)) = 1;

  if (flag_coarray == GFC_FCOARRAY_LIB && codimen)
    gfc_array_descriptor_base_caf[idx] = fat_type;
  else
    gfc_array_descriptor_base[idx] = fat_type;

  return fat_type;
}


/* Build an array (descriptor) type with given bounds.  */

tree
gfc_get_array_type_bounds (tree etype, int dimen, int codimen, tree * lbound,
			   tree * ubound, int packed,
			   enum gfc_array_kind akind, bool restricted)
{
  char name[8 + 2*GFC_RANK_DIGITS + 1 + GFC_MAX_SYMBOL_LEN];
  tree fat_type, base_type, arraytype, lower, upper, stride, tmp, rtype;
  const char *type_name;
  int n;

  base_type = gfc_get_array_descriptor_base (dimen, codimen, restricted);
  fat_type = build_distinct_type_copy (base_type);
  /* Make sure that nontarget and target array type have the same canonical
     type (and same stub decl for debug info).  */
  base_type = gfc_get_array_descriptor_base (dimen, codimen, false);
  TYPE_CANONICAL (fat_type) = base_type;
  TYPE_STUB_DECL (fat_type) = TYPE_STUB_DECL (base_type);

  tmp = TYPE_NAME (etype);
  if (tmp && TREE_CODE (tmp) == TYPE_DECL)
    tmp = DECL_NAME (tmp);
  if (tmp)
    type_name = IDENTIFIER_POINTER (tmp);
  else
    type_name = "unknown";
  sprintf (name, "array" GFC_RANK_PRINTF_FORMAT "_%.*s", dimen + codimen,
	   GFC_MAX_SYMBOL_LEN, type_name);
  TYPE_NAME (fat_type) = get_identifier (name);
  TYPE_NAMELESS (fat_type) = 1;

  GFC_DESCRIPTOR_TYPE_P (fat_type) = 1;
  TYPE_LANG_SPECIFIC (fat_type) = ggc_cleared_alloc<struct lang_type> ();

  GFC_TYPE_ARRAY_RANK (fat_type) = dimen;
  GFC_TYPE_ARRAY_CORANK (fat_type) = codimen;
  GFC_TYPE_ARRAY_DTYPE (fat_type) = NULL_TREE;
  GFC_TYPE_ARRAY_AKIND (fat_type) = akind;

  /* Build an array descriptor record type.  */
  if (packed != 0)
    stride = gfc_index_one_node;
  else
    stride = NULL_TREE;
  for (n = 0; n < dimen + codimen; n++)
    {
      if (n < dimen)
	GFC_TYPE_ARRAY_STRIDE (fat_type, n) = stride;

      if (lbound)
	lower = lbound[n];
      else
	lower = NULL_TREE;

      if (lower != NULL_TREE)
	{
	  if (INTEGER_CST_P (lower))
	    GFC_TYPE_ARRAY_LBOUND (fat_type, n) = lower;
	  else
	    lower = NULL_TREE;
	}

      if (codimen && n == dimen + codimen - 1)
	break;

      upper = ubound[n];
      if (upper != NULL_TREE)
	{
	  if (INTEGER_CST_P (upper))
	    GFC_TYPE_ARRAY_UBOUND (fat_type, n) = upper;
	  else
	    upper = NULL_TREE;
	}

      if (n >= dimen)
	continue;

      if (upper != NULL_TREE && lower != NULL_TREE && stride != NULL_TREE)
	{
	  tmp = fold_build2_loc (input_location, MINUS_EXPR,
				 gfc_array_index_type, upper, lower);
	  tmp = fold_build2_loc (input_location, PLUS_EXPR,
				 gfc_array_index_type, tmp,
				 gfc_index_one_node);
	  stride = fold_build2_loc (input_location, MULT_EXPR,
				    gfc_array_index_type, tmp, stride);
	  /* Check the folding worked.  */
	  gcc_assert (INTEGER_CST_P (stride));
	}
      else
	stride = NULL_TREE;
    }
  GFC_TYPE_ARRAY_SIZE (fat_type) = stride;

  /* TODO: known offsets for descriptors.  */
  GFC_TYPE_ARRAY_OFFSET (fat_type) = NULL_TREE;

  if (dimen == 0)
    {
      arraytype =  build_pointer_type (etype);
      if (restricted)
	arraytype = build_qualified_type (arraytype, TYPE_QUAL_RESTRICT);

      GFC_TYPE_ARRAY_DATAPTR_TYPE (fat_type) = arraytype;
      return fat_type;
    }

  /* We define data as an array with the correct size if possible.
     Much better than doing pointer arithmetic.  */
  if (stride)
    rtype = build_range_type (gfc_array_index_type, gfc_index_zero_node,
			      int_const_binop (MINUS_EXPR, stride,
					       build_int_cst (TREE_TYPE (stride), 1)));
  else
    rtype = gfc_array_range_type;
  arraytype = build_array_type (etype, rtype);
  arraytype = build_pointer_type (arraytype);
  if (restricted)
    arraytype = build_qualified_type (arraytype, TYPE_QUAL_RESTRICT);
  GFC_TYPE_ARRAY_DATAPTR_TYPE (fat_type) = arraytype;

  /* This will generate the base declarations we need to emit debug
     information for this type.  FIXME: there must be a better way to
     avoid divergence between compilations with and without debug
     information.  */
  {
    struct array_descr_info info;
    gfc_get_array_descr_info (fat_type, &info);
    gfc_get_array_descr_info (build_pointer_type (fat_type), &info);
  }

  return fat_type;
}

/* Build a pointer type. This function is called from gfc_sym_type().  */

static tree
gfc_build_pointer_type (gfc_symbol * sym, tree type)
{
  /* Array pointer types aren't actually pointers.  */
  if (sym->attr.dimension)
    return type;
  else
    return build_pointer_type (type);
}

static tree gfc_nonrestricted_type (tree t);
/* Given two record or union type nodes TO and FROM, ensure
   that all fields in FROM have a corresponding field in TO,
   their type being nonrestrict variants.  This accepts a TO
   node that already has a prefix of the fields in FROM.  */
static void
mirror_fields (tree to, tree from)
{
  tree fto, ffrom;
  tree *chain;

  /* Forward to the end of TOs fields.  */
  fto = TYPE_FIELDS (to);
  ffrom = TYPE_FIELDS (from);
  chain = &TYPE_FIELDS (to);
  while (fto)
    {
      gcc_assert (ffrom && DECL_NAME (fto) == DECL_NAME (ffrom));
      chain = &DECL_CHAIN (fto);
      fto = DECL_CHAIN (fto);
      ffrom = DECL_CHAIN (ffrom);
    }

  /* Now add all fields remaining in FROM (starting with ffrom).  */
  for (; ffrom; ffrom = DECL_CHAIN (ffrom))
    {
      tree newfield = copy_node (ffrom);
      DECL_CONTEXT (newfield) = to;
      /* The store to DECL_CHAIN might seem redundant with the
	 stores to *chain, but not clearing it here would mean
	 leaving a chain into the old fields.  If ever
	 our called functions would look at them confusion
	 will arise.  */
      DECL_CHAIN (newfield) = NULL_TREE;
      *chain = newfield;
      chain = &DECL_CHAIN (newfield);

      if (TREE_CODE (ffrom) == FIELD_DECL)
	{
	  tree elemtype = gfc_nonrestricted_type (TREE_TYPE (ffrom));
	  TREE_TYPE (newfield) = elemtype;
	}
    }
  *chain = NULL_TREE;
}

/* Given a type T, returns a different type of the same structure,
   except that all types it refers to (recursively) are always
   non-restrict qualified types.  */
static tree
gfc_nonrestricted_type (tree t)
{
  tree ret = t;

  /* If the type isn't laid out yet, don't copy it.  If something
     needs it for real it should wait until the type got finished.  */
  if (!TYPE_SIZE (t))
    return t;

  if (!TYPE_LANG_SPECIFIC (t))
    TYPE_LANG_SPECIFIC (t) = ggc_cleared_alloc<struct lang_type> ();
  /* If we're dealing with this very node already further up
     the call chain (recursion via pointers and struct members)
     we haven't yet determined if we really need a new type node.
     Assume we don't, return T itself.  */
  if (TYPE_LANG_SPECIFIC (t)->nonrestricted_type == error_mark_node)
    return t;

  /* If we have calculated this all already, just return it.  */
  if (TYPE_LANG_SPECIFIC (t)->nonrestricted_type)
    return TYPE_LANG_SPECIFIC (t)->nonrestricted_type;

  /* Mark this type.  */
  TYPE_LANG_SPECIFIC (t)->nonrestricted_type = error_mark_node;

  switch (TREE_CODE (t))
    {
      default:
	break;

      case POINTER_TYPE:
      case REFERENCE_TYPE:
	{
	  tree totype = gfc_nonrestricted_type (TREE_TYPE (t));
	  if (totype == TREE_TYPE (t))
	    ret = t;
	  else if (TREE_CODE (t) == POINTER_TYPE)
	    ret = build_pointer_type (totype);
	  else
	    ret = build_reference_type (totype);
	  ret = build_qualified_type (ret,
				      TYPE_QUALS (t) & ~TYPE_QUAL_RESTRICT);
	}
	break;

      case ARRAY_TYPE:
	{
	  tree elemtype = gfc_nonrestricted_type (TREE_TYPE (t));
	  if (elemtype == TREE_TYPE (t))
	    ret = t;
	  else
	    {
	      ret = build_variant_type_copy (t);
	      TREE_TYPE (ret) = elemtype;
	      if (TYPE_LANG_SPECIFIC (t)
		  && GFC_TYPE_ARRAY_DATAPTR_TYPE (t))
		{
		  tree dataptr_type = GFC_TYPE_ARRAY_DATAPTR_TYPE (t);
		  dataptr_type = gfc_nonrestricted_type (dataptr_type);
		  if (dataptr_type != GFC_TYPE_ARRAY_DATAPTR_TYPE (t))
		    {
		      TYPE_LANG_SPECIFIC (ret)
			= ggc_cleared_alloc<struct lang_type> ();
		      *TYPE_LANG_SPECIFIC (ret) = *TYPE_LANG_SPECIFIC (t);
		      GFC_TYPE_ARRAY_DATAPTR_TYPE (ret) = dataptr_type;
		    }
		}
	    }
	}
	break;

      case RECORD_TYPE:
      case UNION_TYPE:
      case QUAL_UNION_TYPE:
	{
	  tree field;
	  /* First determine if we need a new type at all.
	     Careful, the two calls to gfc_nonrestricted_type per field
	     might return different values.  That happens exactly when
	     one of the fields reaches back to this very record type
	     (via pointers).  The first calls will assume that we don't
	     need to copy T (see the error_mark_node marking).  If there
	     are any reasons for copying T apart from having to copy T,
	     we'll indeed copy it, and the second calls to
	     gfc_nonrestricted_type will use that new node if they
	     reach back to T.  */
	  for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
	    if (TREE_CODE (field) == FIELD_DECL)
	      {
		tree elemtype = gfc_nonrestricted_type (TREE_TYPE (field));
		if (elemtype != TREE_TYPE (field))
		  break;
	      }
	  if (!field)
	    break;
	  ret = build_variant_type_copy (t);
	  TYPE_FIELDS (ret) = NULL_TREE;

	  /* Here we make sure that as soon as we know we have to copy
	     T, that also fields reaching back to us will use the new
	     copy.  It's okay if that copy still contains the old fields,
	     we won't look at them.  */
	  TYPE_LANG_SPECIFIC (t)->nonrestricted_type = ret;
	  mirror_fields (ret, t);
	}
        break;
    }

  TYPE_LANG_SPECIFIC (t)->nonrestricted_type = ret;
  return ret;
}


/* Return the type for a symbol.  Special handling is required for character
   types to get the correct level of indirection.
   For functions return the return type.
   For subroutines return void_type_node.
   Calling this multiple times for the same symbol should be avoided,
   especially for character and array types.  */

tree
gfc_sym_type (gfc_symbol * sym)
{
  tree type;
  int byref;
  bool restricted;

  /* Procedure Pointers inside COMMON blocks.  */
  if (sym->attr.proc_pointer && sym->attr.in_common)
    {
      /* Unset proc_pointer as gfc_get_function_type calls gfc_sym_type.  */
      sym->attr.proc_pointer = 0;
      type = build_pointer_type (gfc_get_function_type (sym));
      sym->attr.proc_pointer = 1;
      return type;
    }

  if (sym->attr.flavor == FL_PROCEDURE && !sym->attr.function)
    return void_type_node;

  /* In the case of a function the fake result variable may have a
     type different from the function type, so don't return early in
     that case.  */
  if (sym->backend_decl && !sym->attr.function)
    return TREE_TYPE (sym->backend_decl);

  if (sym->attr.result
      && sym->ts.type == BT_CHARACTER
      && sym->ts.u.cl->backend_decl == NULL_TREE
      && sym->ns->proc_name
      && sym->ns->proc_name->ts.u.cl
      && sym->ns->proc_name->ts.u.cl->backend_decl != NULL_TREE)
    sym->ts.u.cl->backend_decl = sym->ns->proc_name->ts.u.cl->backend_decl;

  if (sym->ts.type == BT_CHARACTER
      && ((sym->attr.function && sym->attr.is_bind_c)
	  || (sym->attr.result
	      && sym->ns->proc_name
	      && sym->ns->proc_name->attr.is_bind_c)
	  || (sym->ts.deferred && (!sym->ts.u.cl
				   || !sym->ts.u.cl->backend_decl))))
    type = gfc_character1_type_node;
  else
    type = gfc_typenode_for_spec (&sym->ts, sym->attr.codimension);

  if (sym->attr.dummy && !sym->attr.function && !sym->attr.value)
    byref = 1;
  else
    byref = 0;

  restricted = !sym->attr.target && !sym->attr.pointer
               && !sym->attr.proc_pointer && !sym->attr.cray_pointee;
  if (!restricted)
    type = gfc_nonrestricted_type (type);

  if (sym->attr.dimension || sym->attr.codimension)
    {
      if (gfc_is_nodesc_array (sym))
        {
	  /* If this is a character argument of unknown length, just use the
	     base type.  */
	  if (sym->ts.type != BT_CHARACTER
	      || !(sym->attr.dummy || sym->attr.function)
	      || sym->ts.u.cl->backend_decl)
	    {
	      type = gfc_get_nodesc_array_type (type, sym->as,
						byref ? PACKED_FULL
						      : PACKED_STATIC,
						restricted);
	      byref = 0;
	    }
        }
      else
	{
	  enum gfc_array_kind akind = GFC_ARRAY_UNKNOWN;
	  if (sym->attr.pointer)
	    akind = sym->attr.contiguous ? GFC_ARRAY_POINTER_CONT
					 : GFC_ARRAY_POINTER;
	  else if (sym->attr.allocatable)
	    akind = GFC_ARRAY_ALLOCATABLE;
	  type = gfc_build_array_type (type, sym->as, akind, restricted,
				       sym->attr.contiguous, false);
	}
    }
  else
    {
      if (sym->attr.allocatable || sym->attr.pointer
	  || gfc_is_associate_pointer (sym))
	type = gfc_build_pointer_type (sym, type);
    }

  /* We currently pass all parameters by reference.
     See f95_get_function_decl.  For dummy function parameters return the
     function type.  */
  if (byref)
    {
      /* We must use pointer types for potentially absent variables.  The
	 optimizers assume a reference type argument is never NULL.  */
      if (sym->attr.optional
	  || (sym->ns->proc_name && sym->ns->proc_name->attr.entry_master))
	type = build_pointer_type (type);
      else
	{
	  type = build_reference_type (type);
	  if (restricted)
	    type = build_qualified_type (type, TYPE_QUAL_RESTRICT);
	}
    }

  return (type);
}

/* Layout and output debug info for a record type.  */

void
gfc_finish_type (tree type)
{
  tree decl;

  decl = build_decl (input_location,
		     TYPE_DECL, NULL_TREE, type);
  TYPE_STUB_DECL (type) = decl;
  layout_type (type);
  rest_of_type_compilation (type, 1);
  rest_of_decl_compilation (decl, 1, 0);
}

/* Add a field of given NAME and TYPE to the context of a UNION_TYPE
   or RECORD_TYPE pointed to by CONTEXT.  The new field is chained
   to the end of the field list pointed to by *CHAIN.

   Returns a pointer to the new field.  */

static tree
gfc_add_field_to_struct_1 (tree context, tree name, tree type, tree **chain)
{
  tree decl = build_decl (input_location, FIELD_DECL, name, type);

  DECL_CONTEXT (decl) = context;
  DECL_CHAIN (decl) = NULL_TREE;
  if (TYPE_FIELDS (context) == NULL_TREE)
    TYPE_FIELDS (context) = decl;
  if (chain != NULL)
    {
      if (*chain != NULL)
	**chain = decl;
      *chain = &DECL_CHAIN (decl);
    }

  return decl;
}

/* Like `gfc_add_field_to_struct_1', but adds alignment
   information.  */

tree
gfc_add_field_to_struct (tree context, tree name, tree type, tree **chain)
{
  tree decl = gfc_add_field_to_struct_1 (context, name, type, chain);

  DECL_INITIAL (decl) = 0;
  SET_DECL_ALIGN (decl, 0);
  DECL_USER_ALIGN (decl) = 0;

  return decl;
}


/* Copy the backend_decl and component backend_decls if
   the two derived type symbols are "equal", as described
   in 4.4.2 and resolved by gfc_compare_derived_types.  */

int
gfc_copy_dt_decls_ifequal (gfc_symbol *from, gfc_symbol *to,
			   bool from_gsym)
{
  gfc_component *to_cm;
  gfc_component *from_cm;

  if (from == to)
    return 1;

  if (from->backend_decl == NULL
	|| !gfc_compare_derived_types (from, to))
    return 0;

  to->backend_decl = from->backend_decl;

  to_cm = to->components;
  from_cm = from->components;

  /* Copy the component declarations.  If a component is itself
     a derived type, we need a copy of its component declarations.
     This is done by recursing into gfc_get_derived_type and
     ensures that the component's component declarations have
     been built.  If it is a character, we need the character
     length, as well.  */
  for (; to_cm; to_cm = to_cm->next, from_cm = from_cm->next)
    {
      to_cm->backend_decl = from_cm->backend_decl;
      to_cm->caf_token = from_cm->caf_token;
      if (from_cm->ts.type == BT_UNION)
        gfc_get_union_type (to_cm->ts.u.derived);
      else if (from_cm->ts.type == BT_DERIVED
	  && (!from_cm->attr.pointer || from_gsym))
	gfc_get_derived_type (to_cm->ts.u.derived);
      else if (from_cm->ts.type == BT_CLASS
	       && (!CLASS_DATA (from_cm)->attr.class_pointer || from_gsym))
	gfc_get_derived_type (to_cm->ts.u.derived);
      else if (from_cm->ts.type == BT_CHARACTER)
	to_cm->ts.u.cl->backend_decl = from_cm->ts.u.cl->backend_decl;
    }

  return 1;
}


/* Build a tree node for a procedure pointer component.  */

tree
gfc_get_ppc_type (gfc_component* c)
{
  tree t;

  /* Explicit interface.  */
  if (c->attr.if_source != IFSRC_UNKNOWN && c->ts.interface)
    return build_pointer_type (gfc_get_function_type (c->ts.interface));

  /* Implicit interface (only return value may be known).  */
  if (c->attr.function && !c->attr.dimension && c->ts.type != BT_CHARACTER)
    t = gfc_typenode_for_spec (&c->ts);
  else
    t = void_type_node;

  return build_pointer_type (build_function_type_list (t, NULL_TREE));
}


/* Build a tree node for a union type. Requires building each map
   structure which is an element of the union. */

tree
gfc_get_union_type (gfc_symbol *un)
{
    gfc_component *map = NULL;
    tree typenode = NULL, map_type = NULL, map_field = NULL;
    tree *chain = NULL;

    if (un->backend_decl)
      {
        if (TYPE_FIELDS (un->backend_decl) || un->attr.proc_pointer_comp)
          return un->backend_decl;
        else
          typenode = un->backend_decl;
      }
    else
      {
        typenode = make_node (UNION_TYPE);
        TYPE_NAME (typenode) = get_identifier (un->name);
      }

    /* Add each contained MAP as a field. */
    for (map = un->components; map; map = map->next)
      {
        gcc_assert (map->ts.type == BT_DERIVED);

        /* The map's type node, which is defined within this union's context. */
        map_type = gfc_get_derived_type (map->ts.u.derived);
        TYPE_CONTEXT (map_type) = typenode;

        /* The map field's declaration. */
        map_field = gfc_add_field_to_struct(typenode, get_identifier(map->name),
                                            map_type, &chain);
        if (map->loc.lb)
          gfc_set_decl_location (map_field, &map->loc);
        else if (un->declared_at.lb)
          gfc_set_decl_location (map_field, &un->declared_at);

        DECL_PACKED (map_field) |= TYPE_PACKED (typenode);
        DECL_NAMELESS(map_field) = true;

        /* We should never clobber another backend declaration for this map,
           because each map component is unique. */
        if (!map->backend_decl)
          map->backend_decl = map_field;
      }

    un->backend_decl = typenode;
    gfc_finish_type (typenode);

    return typenode;
}


/* Build a tree node for a derived type.  If there are equal
   derived types, with different local names, these are built
   at the same time.  If an equal derived type has been built
   in a parent namespace, this is used.  */

tree
gfc_get_derived_type (gfc_symbol * derived, int codimen)
{
  tree typenode = NULL, field = NULL, field_type = NULL;
  tree canonical = NULL_TREE;
  tree *chain = NULL;
  bool got_canonical = false;
  bool unlimited_entity = false;
  gfc_component *c;
  gfc_dt_list *dt;
  gfc_namespace *ns;
  tree tmp;
  bool coarray_flag;

  coarray_flag = flag_coarray == GFC_FCOARRAY_LIB
		 && derived->module && !derived->attr.vtype;

  gcc_assert (!derived->attr.pdt_template);

  if (derived->attr.unlimited_polymorphic
      || (flag_coarray == GFC_FCOARRAY_LIB
	  && derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
	  && (derived->intmod_sym_id == ISOFORTRAN_LOCK_TYPE
	      || derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE
	      || derived->intmod_sym_id == ISOFORTRAN_TEAM_TYPE)))
    return ptr_type_node;

  if (flag_coarray != GFC_FCOARRAY_LIB
      && derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
      && (derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE
	  || derived->intmod_sym_id == ISOFORTRAN_TEAM_TYPE))
    return gfc_get_int_type (gfc_default_integer_kind);

  if (derived && derived->attr.flavor == FL_PROCEDURE
      && derived->attr.generic)
    derived = gfc_find_dt_in_generic (derived);

  /* See if it's one of the iso_c_binding derived types.  */
  if (derived->attr.is_iso_c == 1 || derived->ts.f90_type == BT_VOID)
    {
      if (derived->backend_decl)
	return derived->backend_decl;

      if (derived->intmod_sym_id == ISOCBINDING_PTR)
	derived->backend_decl = ptr_type_node;
      else
	derived->backend_decl = pfunc_type_node;

      derived->ts.kind = gfc_index_integer_kind;
      derived->ts.type = BT_INTEGER;
      /* Set the f90_type to BT_VOID as a way to recognize something of type
         BT_INTEGER that needs to fit a void * for the purpose of the
         iso_c_binding derived types.  */
      derived->ts.f90_type = BT_VOID;

      return derived->backend_decl;
    }

  /* If use associated, use the module type for this one.  */
  if (derived->backend_decl == NULL
      && derived->attr.use_assoc
      && derived->module
      && gfc_get_module_backend_decl (derived))
    goto copy_derived_types;

  /* The derived types from an earlier namespace can be used as the
     canonical type.  */
  if (derived->backend_decl == NULL && !derived->attr.use_assoc
      && gfc_global_ns_list)
    {
      for (ns = gfc_global_ns_list;
	   ns->translated && !got_canonical;
	   ns = ns->sibling)
	{
	  dt = ns->derived_types;
	  for (; dt && !canonical; dt = dt->next)
	    {
	      gfc_copy_dt_decls_ifequal (dt->derived, derived, true);
	      if (derived->backend_decl)
		got_canonical = true;
	    }
	}
    }

  /* Store up the canonical type to be added to this one.  */
  if (got_canonical)
    {
      if (TYPE_CANONICAL (derived->backend_decl))
	canonical = TYPE_CANONICAL (derived->backend_decl);
      else
	canonical = derived->backend_decl;

      derived->backend_decl = NULL_TREE;
    }

  /* derived->backend_decl != 0 means we saw it before, but its
     components' backend_decl may have not been built.  */
  if (derived->backend_decl)
    {
      /* Its components' backend_decl have been built or we are
	 seeing recursion through the formal arglist of a procedure
	 pointer component.  */
      if (TYPE_FIELDS (derived->backend_decl))
        return derived->backend_decl;
      else if (derived->attr.abstract
	       && derived->attr.proc_pointer_comp)
	{
	  /* If an abstract derived type with procedure pointer
	     components has no other type of component, return the
	     backend_decl. Otherwise build the components if any of the
	     non-procedure pointer components have no backend_decl.  */
	  for (c = derived->components; c; c = c->next)
	    {
	      bool same_alloc_type = c->attr.allocatable
				     && derived == c->ts.u.derived;
	      if (!c->attr.proc_pointer
		  && !same_alloc_type
		  && c->backend_decl == NULL)
		break;
	      else if (c->next == NULL)
		return derived->backend_decl;
	    }
	  typenode = derived->backend_decl;
	}
      else
        typenode = derived->backend_decl;
    }
  else
    {
      /* We see this derived type first time, so build the type node.  */
      typenode = make_node (RECORD_TYPE);
      TYPE_NAME (typenode) = get_identifier (derived->name);
      TYPE_PACKED (typenode) = flag_pack_derived;
      derived->backend_decl = typenode;
    }

  if (derived->components
	&& derived->components->ts.type == BT_DERIVED
	&& strcmp (derived->components->name, "_data") == 0
	&& derived->components->ts.u.derived->attr.unlimited_polymorphic)
    unlimited_entity = true;

  /* Go through the derived type components, building them as
     necessary. The reason for doing this now is that it is
     possible to recurse back to this derived type through a
     pointer component (PR24092). If this happens, the fields
     will be built and so we can return the type.  */
  for (c = derived->components; c; c = c->next)
    {
      bool same_alloc_type = c->attr.allocatable
			     && derived == c->ts.u.derived;

      if (c->ts.type == BT_UNION && c->ts.u.derived->backend_decl == NULL)
        c->ts.u.derived->backend_decl = gfc_get_union_type (c->ts.u.derived);

      if (c->ts.type != BT_DERIVED && c->ts.type != BT_CLASS)
	continue;

      if ((!c->attr.pointer && !c->attr.proc_pointer
	  && !same_alloc_type)
	  || c->ts.u.derived->backend_decl == NULL)
	{
	  int local_codim = c->attr.codimension ? c->as->corank: codimen;
	  c->ts.u.derived->backend_decl = gfc_get_derived_type (c->ts.u.derived,
								local_codim);
	}

      if (c->ts.u.derived->attr.is_iso_c)
        {
          /* Need to copy the modified ts from the derived type.  The
             typespec was modified because C_PTR/C_FUNPTR are translated
             into (void *) from derived types.  */
          c->ts.type = c->ts.u.derived->ts.type;
          c->ts.kind = c->ts.u.derived->ts.kind;
          c->ts.f90_type = c->ts.u.derived->ts.f90_type;
	  if (c->initializer)
	    {
	      c->initializer->ts.type = c->ts.type;
	      c->initializer->ts.kind = c->ts.kind;
	      c->initializer->ts.f90_type = c->ts.f90_type;
	      c->initializer->expr_type = EXPR_NULL;
	    }
        }
    }

  if (TYPE_FIELDS (derived->backend_decl))
    return derived->backend_decl;

  /* Build the type member list. Install the newly created RECORD_TYPE
     node as DECL_CONTEXT of each FIELD_DECL. In this case we must go
     through only the top-level linked list of components so we correctly
     build UNION_TYPE nodes for BT_UNION components. MAPs and other nested
     types are built as part of gfc_get_union_type.  */
  for (c = derived->components; c; c = c->next)
    {
      bool same_alloc_type = c->attr.allocatable
			     && derived == c->ts.u.derived;
      /* Prevent infinite recursion, when the procedure pointer type is
	 the same as derived, by forcing the procedure pointer component to
	 be built as if the explicit interface does not exist.  */
      if (c->attr.proc_pointer
	  && (c->ts.type != BT_DERIVED || (c->ts.u.derived
		    && !gfc_compare_derived_types (derived, c->ts.u.derived)))
	  && (c->ts.type != BT_CLASS || (CLASS_DATA (c)->ts.u.derived
		    && !gfc_compare_derived_types (derived, CLASS_DATA (c)->ts.u.derived))))
	field_type = gfc_get_ppc_type (c);
      else if (c->attr.proc_pointer && derived->backend_decl)
	{
	  tmp = build_function_type_list (derived->backend_decl, NULL_TREE);
	  field_type = build_pointer_type (tmp);
	}
      else if (c->ts.type == BT_DERIVED || c->ts.type == BT_CLASS)
	field_type = c->ts.u.derived->backend_decl;
      else if (c->attr.caf_token)
	field_type = pvoid_type_node;
      else
	{
	  if (c->ts.type == BT_CHARACTER
	      && !c->ts.deferred && !c->attr.pdt_string)
	    {
	      /* Evaluate the string length.  */
	      gfc_conv_const_charlen (c->ts.u.cl);
	      gcc_assert (c->ts.u.cl->backend_decl);
	    }
	  else if (c->ts.type == BT_CHARACTER)
	    c->ts.u.cl->backend_decl
			= build_int_cst (gfc_charlen_type_node, 0);

	  field_type = gfc_typenode_for_spec (&c->ts, codimen);
	}

      /* This returns an array descriptor type.  Initialization may be
         required.  */
      if ((c->attr.dimension || c->attr.codimension) && !c->attr.proc_pointer )
	{
	  if (c->attr.pointer || c->attr.allocatable || c->attr.pdt_array)
	    {
	      enum gfc_array_kind akind;
	      if (c->attr.pointer)
		akind = c->attr.contiguous ? GFC_ARRAY_POINTER_CONT
					   : GFC_ARRAY_POINTER;
	      else
		akind = GFC_ARRAY_ALLOCATABLE;
	      /* Pointers to arrays aren't actually pointer types.  The
	         descriptors are separate, but the data is common.  */
	      field_type = gfc_build_array_type (field_type, c->as, akind,
						 !c->attr.target
						 && !c->attr.pointer,
						 c->attr.contiguous,
						 codimen);
	    }
	  else
	    field_type = gfc_get_nodesc_array_type (field_type, c->as,
						    PACKED_STATIC,
						    !c->attr.target);
	}
      else if ((c->attr.pointer || c->attr.allocatable || c->attr.pdt_string)
	       && !c->attr.proc_pointer
	       && !(unlimited_entity && c == derived->components))
	field_type = build_pointer_type (field_type);

      if (c->attr.pointer || same_alloc_type)
	field_type = gfc_nonrestricted_type (field_type);

      /* vtype fields can point to different types to the base type.  */
      if (c->ts.type == BT_DERIVED
	    && c->ts.u.derived && c->ts.u.derived->attr.vtype)
	  field_type = build_pointer_type_for_mode (TREE_TYPE (field_type),
						    ptr_mode, true);

      /* Ensure that the CLASS language specific flag is set.  */
      if (c->ts.type == BT_CLASS)
	{
	  if (POINTER_TYPE_P (field_type))
	    GFC_CLASS_TYPE_P (TREE_TYPE (field_type)) = 1;
	  else
	    GFC_CLASS_TYPE_P (field_type) = 1;
	}

      field = gfc_add_field_to_struct (typenode,
				       get_identifier (c->name),
				       field_type, &chain);
      if (c->loc.lb)
	gfc_set_decl_location (field, &c->loc);
      else if (derived->declared_at.lb)
	gfc_set_decl_location (field, &derived->declared_at);

      gfc_finish_decl_attrs (field, &c->attr);

      DECL_PACKED (field) |= TYPE_PACKED (typenode);

      gcc_assert (field);
      if (!c->backend_decl)
	c->backend_decl = field;

      if (c->attr.pointer && c->attr.dimension
	  && !(c->ts.type == BT_DERIVED
	       && strcmp (c->name, "_data") == 0))
	GFC_DECL_PTR_ARRAY_P (c->backend_decl) = 1;
    }

  /* Now lay out the derived type, including the fields.  */
  if (canonical)
    TYPE_CANONICAL (typenode) = canonical;

  gfc_finish_type (typenode);
  gfc_set_decl_location (TYPE_STUB_DECL (typenode), &derived->declared_at);
  if (derived->module && derived->ns->proc_name
      && derived->ns->proc_name->attr.flavor == FL_MODULE)
    {
      if (derived->ns->proc_name->backend_decl
	  && TREE_CODE (derived->ns->proc_name->backend_decl)
	     == NAMESPACE_DECL)
	{
	  TYPE_CONTEXT (typenode) = derived->ns->proc_name->backend_decl;
	  DECL_CONTEXT (TYPE_STUB_DECL (typenode))
	    = derived->ns->proc_name->backend_decl;
	}
    }

  derived->backend_decl = typenode;

copy_derived_types:

  for (c = derived->components; c; c = c->next)
    {
      /* Do not add a caf_token field for class container components.  */
      if ((codimen || coarray_flag)
	  && !c->attr.dimension && !c->attr.codimension
	  && (c->attr.allocatable || c->attr.pointer)
	  && !derived->attr.is_class)
	{
	  char caf_name[GFC_MAX_SYMBOL_LEN];
	  gfc_component *token;
	  snprintf (caf_name, GFC_MAX_SYMBOL_LEN, "_caf_%s", c->name);
	  token = gfc_find_component (derived, caf_name, true, true, NULL);
	  gcc_assert (token);
	  c->caf_token = token->backend_decl;
	  TREE_NO_WARNING (c->caf_token) = 1;
	}
    }

  for (dt = gfc_derived_types; dt; dt = dt->next)
    gfc_copy_dt_decls_ifequal (derived, dt->derived, false);

  return derived->backend_decl;
}


int
gfc_return_by_reference (gfc_symbol * sym)
{
  if (!sym->attr.function)
    return 0;

  if (sym->attr.dimension)
    return 1;

  if (sym->ts.type == BT_CHARACTER
      && !sym->attr.is_bind_c
      && (!sym->attr.result
	  || !sym->ns->proc_name
	  || !sym->ns->proc_name->attr.is_bind_c))
    return 1;

  /* Possibly return complex numbers by reference for g77 compatibility.
     We don't do this for calls to intrinsics (as the library uses the
     -fno-f2c calling convention), nor for calls to functions which always
     require an explicit interface, as no compatibility problems can
     arise there.  */
  if (flag_f2c && sym->ts.type == BT_COMPLEX
      && !sym->attr.intrinsic && !sym->attr.always_explicit)
    return 1;

  return 0;
}

static tree
gfc_get_mixed_entry_union (gfc_namespace *ns)
{
  tree type;
  tree *chain = NULL;
  char name[GFC_MAX_SYMBOL_LEN + 1];
  gfc_entry_list *el, *el2;

  gcc_assert (ns->proc_name->attr.mixed_entry_master);
  gcc_assert (memcmp (ns->proc_name->name, "master.", 7) == 0);

  snprintf (name, GFC_MAX_SYMBOL_LEN, "munion.%s", ns->proc_name->name + 7);

  /* Build the type node.  */
  type = make_node (UNION_TYPE);

  TYPE_NAME (type) = get_identifier (name);

  for (el = ns->entries; el; el = el->next)
    {
      /* Search for duplicates.  */
      for (el2 = ns->entries; el2 != el; el2 = el2->next)
	if (el2->sym->result == el->sym->result)
	  break;

      if (el == el2)
	gfc_add_field_to_struct_1 (type,
				   get_identifier (el->sym->result->name),
				   gfc_sym_type (el->sym->result), &chain);
    }

  /* Finish off the type.  */
  gfc_finish_type (type);
  TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (type)) = 1;
  return type;
}

/* Create a "fn spec" based on the formal arguments;
   cf. create_function_arglist.  */

static tree
create_fn_spec (gfc_symbol *sym, tree fntype)
{
  char spec[150];
  size_t spec_len;
  gfc_formal_arglist *f;
  tree tmp;

  memset (&spec, 0, sizeof (spec));
  spec[0] = '.';
  spec_len = 1;

  if (sym->attr.entry_master)
    spec[spec_len++] = 'R';
  if (gfc_return_by_reference (sym))
    {
      gfc_symbol *result = sym->result ? sym->result : sym;

      if (result->attr.pointer || sym->attr.proc_pointer)
	spec[spec_len++] = '.';
      else
	spec[spec_len++] = 'w';
      if (sym->ts.type == BT_CHARACTER)
	spec[spec_len++] = 'R';
    }

  for (f = gfc_sym_get_dummy_args (sym); f; f = f->next)
    if (spec_len < sizeof (spec))
      {
	if (!f->sym || f->sym->attr.pointer || f->sym->attr.target
	    || f->sym->attr.external || f->sym->attr.cray_pointer
	    || (f->sym->ts.type == BT_DERIVED
		&& (f->sym->ts.u.derived->attr.proc_pointer_comp
		    || f->sym->ts.u.derived->attr.pointer_comp))
	    || (f->sym->ts.type == BT_CLASS
		&& (CLASS_DATA (f->sym)->ts.u.derived->attr.proc_pointer_comp
		    || CLASS_DATA (f->sym)->ts.u.derived->attr.pointer_comp)))
	  spec[spec_len++] = '.';
	else if (f->sym->attr.intent == INTENT_IN)
	  spec[spec_len++] = 'r';
	else if (f->sym)
	  spec[spec_len++] = 'w';
      }

  tmp = build_tree_list (NULL_TREE, build_string (spec_len, spec));
  tmp = tree_cons (get_identifier ("fn spec"), tmp, TYPE_ATTRIBUTES (fntype));
  return build_type_attribute_variant (fntype, tmp);
}


tree
gfc_get_function_type (gfc_symbol * sym)
{
  tree type;
  vec<tree, va_gc> *typelist = NULL;
  gfc_formal_arglist *f;
  gfc_symbol *arg;
  int alternate_return = 0;
  bool is_varargs = true;

  /* Make sure this symbol is a function, a subroutine or the main
     program.  */
  gcc_assert (sym->attr.flavor == FL_PROCEDURE
	      || sym->attr.flavor == FL_PROGRAM);

  /* To avoid recursing infinitely on recursive types, we use error_mark_node
     so that they can be detected here and handled further down.  */
  if (sym->backend_decl == NULL)
    sym->backend_decl = error_mark_node;
  else if (sym->backend_decl == error_mark_node)
    goto arg_type_list_done;
  else if (sym->attr.proc_pointer)
    return TREE_TYPE (TREE_TYPE (sym->backend_decl));
  else
    return TREE_TYPE (sym->backend_decl);

  if (sym->attr.entry_master)
    /* Additional parameter for selecting an entry point.  */
    vec_safe_push (typelist, gfc_array_index_type);

  if (sym->result)
    arg = sym->result;
  else
    arg = sym;

  if (arg->ts.type == BT_CHARACTER)
    gfc_conv_const_charlen (arg->ts.u.cl);

  /* Some functions we use an extra parameter for the return value.  */
  if (gfc_return_by_reference (sym))
    {
      type = gfc_sym_type (arg);
      if (arg->ts.type == BT_COMPLEX
	  || arg->attr.dimension
	  || arg->ts.type == BT_CHARACTER)
	type = build_reference_type (type);

      vec_safe_push (typelist, type);
      if (arg->ts.type == BT_CHARACTER)
	{
	  if (!arg->ts.deferred)
	    /* Transfer by value.  */
	    vec_safe_push (typelist, gfc_charlen_type_node);
	  else
	    /* Deferred character lengths are transferred by reference
	       so that the value can be returned.  */
	    vec_safe_push (typelist, build_pointer_type(gfc_charlen_type_node));
	}
    }

  /* Build the argument types for the function.  */
  for (f = gfc_sym_get_dummy_args (sym); f; f = f->next)
    {
      arg = f->sym;
      if (arg)
	{
	  /* Evaluate constant character lengths here so that they can be
	     included in the type.  */
	  if (arg->ts.type == BT_CHARACTER)
	    gfc_conv_const_charlen (arg->ts.u.cl);

	  if (arg->attr.flavor == FL_PROCEDURE)
	    {
	      type = gfc_get_function_type (arg);
	      type = build_pointer_type (type);
	    }
	  else
	    type = gfc_sym_type (arg);

	  /* Parameter Passing Convention

	     We currently pass all parameters by reference.
	     Parameters with INTENT(IN) could be passed by value.
	     The problem arises if a function is called via an implicit
	     prototype. In this situation the INTENT is not known.
	     For this reason all parameters to global functions must be
	     passed by reference.  Passing by value would potentially
	     generate bad code.  Worse there would be no way of telling that
	     this code was bad, except that it would give incorrect results.

	     Contained procedures could pass by value as these are never
	     used without an explicit interface, and cannot be passed as
	     actual parameters for a dummy procedure.  */

	  vec_safe_push (typelist, type);
	}
      else
        {
          if (sym->attr.subroutine)
            alternate_return = 1;
        }
    }

  /* Add hidden string length parameters.  */
  for (f = gfc_sym_get_dummy_args (sym); f; f = f->next)
    {
      arg = f->sym;
      if (arg && arg->ts.type == BT_CHARACTER && !sym->attr.is_bind_c)
	{
	  if (!arg->ts.deferred)
	    /* Transfer by value.  */
	    type = gfc_charlen_type_node;
	  else
	    /* Deferred character lengths are transferred by reference
	       so that the value can be returned.  */
	    type = build_pointer_type (gfc_charlen_type_node);

	  vec_safe_push (typelist, type);
	}
    }

  if (!vec_safe_is_empty (typelist)
      || sym->attr.is_main_program
      || sym->attr.if_source != IFSRC_UNKNOWN)
    is_varargs = false;

  if (sym->backend_decl == error_mark_node)
    sym->backend_decl = NULL_TREE;

arg_type_list_done:

  if (alternate_return)
    type = integer_type_node;
  else if (!sym->attr.function || gfc_return_by_reference (sym))
    type = void_type_node;
  else if (sym->attr.mixed_entry_master)
    type = gfc_get_mixed_entry_union (sym->ns);
  else if (flag_f2c && sym->ts.type == BT_REAL
	   && sym->ts.kind == gfc_default_real_kind
	   && !sym->attr.always_explicit)
    {
      /* Special case: f2c calling conventions require that (scalar)
	 default REAL functions return the C type double instead.  f2c
	 compatibility is only an issue with functions that don't
	 require an explicit interface, as only these could be
	 implemented in Fortran 77.  */
      sym->ts.kind = gfc_default_double_kind;
      type = gfc_typenode_for_spec (&sym->ts);
      sym->ts.kind = gfc_default_real_kind;
    }
  else if (sym->result && sym->result->attr.proc_pointer)
    /* Procedure pointer return values.  */
    {
      if (sym->result->attr.result && strcmp (sym->name,"ppr@") != 0)
	{
	  /* Unset proc_pointer as gfc_get_function_type
	     is called recursively.  */
	  sym->result->attr.proc_pointer = 0;
	  type = build_pointer_type (gfc_get_function_type (sym->result));
	  sym->result->attr.proc_pointer = 1;
	}
      else
       type = gfc_sym_type (sym->result);
    }
  else
    type = gfc_sym_type (sym);

  if (is_varargs)
    type = build_varargs_function_type_vec (type, typelist);
  else
    type = build_function_type_vec (type, typelist);
  type = create_fn_spec (sym, type);

  return type;
}

/* Language hooks for middle-end access to type nodes.  */

/* Return an integer type with BITS bits of precision,
   that is unsigned if UNSIGNEDP is nonzero, otherwise signed.  */

tree
gfc_type_for_size (unsigned bits, int unsignedp)
{
  if (!unsignedp)
    {
      int i;
      for (i = 0; i <= MAX_INT_KINDS; ++i)
	{
	  tree type = gfc_integer_types[i];
	  if (type && bits == TYPE_PRECISION (type))
	    return type;
	}

      /* Handle TImode as a special case because it is used by some backends
         (e.g. ARM) even though it is not available for normal use.  */
#if HOST_BITS_PER_WIDE_INT >= 64
      if (bits == TYPE_PRECISION (intTI_type_node))
	return intTI_type_node;
#endif

      if (bits <= TYPE_PRECISION (intQI_type_node))
	return intQI_type_node;
      if (bits <= TYPE_PRECISION (intHI_type_node))
	return intHI_type_node;
      if (bits <= TYPE_PRECISION (intSI_type_node))
	return intSI_type_node;
      if (bits <= TYPE_PRECISION (intDI_type_node))
	return intDI_type_node;
      if (bits <= TYPE_PRECISION (intTI_type_node))
	return intTI_type_node;
    }
  else
    {
      if (bits <= TYPE_PRECISION (unsigned_intQI_type_node))
        return unsigned_intQI_type_node;
      if (bits <= TYPE_PRECISION (unsigned_intHI_type_node))
	return unsigned_intHI_type_node;
      if (bits <= TYPE_PRECISION (unsigned_intSI_type_node))
	return unsigned_intSI_type_node;
      if (bits <= TYPE_PRECISION (unsigned_intDI_type_node))
	return unsigned_intDI_type_node;
      if (bits <= TYPE_PRECISION (unsigned_intTI_type_node))
	return unsigned_intTI_type_node;
    }

  return NULL_TREE;
}

/* Return a data type that has machine mode MODE.  If the mode is an
   integer, then UNSIGNEDP selects between signed and unsigned types.  */

tree
gfc_type_for_mode (machine_mode mode, int unsignedp)
{
  int i;
  tree *base;
  scalar_int_mode int_mode;

  if (GET_MODE_CLASS (mode) == MODE_FLOAT)
    base = gfc_real_types;
  else if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
    base = gfc_complex_types;
  else if (is_a <scalar_int_mode> (mode, &int_mode))
    {
      tree type = gfc_type_for_size (GET_MODE_PRECISION (int_mode), unsignedp);
      return type != NULL_TREE && mode == TYPE_MODE (type) ? type : NULL_TREE;
    }
  else if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL
	   && valid_vector_subparts_p (GET_MODE_NUNITS (mode)))
    {
      unsigned int elem_bits = vector_element_size (GET_MODE_BITSIZE (mode),
						    GET_MODE_NUNITS (mode));
      tree bool_type = build_nonstandard_boolean_type (elem_bits);
      return build_vector_type_for_mode (bool_type, mode);
    }
  else if (VECTOR_MODE_P (mode)
	   && valid_vector_subparts_p (GET_MODE_NUNITS (mode)))
    {
      machine_mode inner_mode = GET_MODE_INNER (mode);
      tree inner_type = gfc_type_for_mode (inner_mode, unsignedp);
      if (inner_type != NULL_TREE)
        return build_vector_type_for_mode (inner_type, mode);
      return NULL_TREE;
    }
  else
    return NULL_TREE;

  for (i = 0; i <= MAX_REAL_KINDS; ++i)
    {
      tree type = base[i];
      if (type && mode == TYPE_MODE (type))
	return type;
    }

  return NULL_TREE;
}

/* Return TRUE if TYPE is a type with a hidden descriptor, fill in INFO
   in that case.  */

bool
gfc_get_array_descr_info (const_tree type, struct array_descr_info *info)
{
  int rank, dim;
  bool indirect = false;
  tree etype, ptype, t, base_decl;
  tree data_off, dim_off, dtype_off, dim_size, elem_size;
  tree lower_suboff, upper_suboff, stride_suboff;
  tree dtype, field, rank_off;

  if (! GFC_DESCRIPTOR_TYPE_P (type))
    {
      if (! POINTER_TYPE_P (type))
	return false;
      type = TREE_TYPE (type);
      if (! GFC_DESCRIPTOR_TYPE_P (type))
	return false;
      indirect = true;
    }

  rank = GFC_TYPE_ARRAY_RANK (type);
  if (rank >= (int) (sizeof (info->dimen) / sizeof (info->dimen[0])))
    return false;

  etype = GFC_TYPE_ARRAY_DATAPTR_TYPE (type);
  gcc_assert (POINTER_TYPE_P (etype));
  etype = TREE_TYPE (etype);

  /* If the type is not a scalar coarray.  */
  if (TREE_CODE (etype) == ARRAY_TYPE)
    etype = TREE_TYPE (etype);

  /* Can't handle variable sized elements yet.  */
  if (int_size_in_bytes (etype) <= 0)
    return false;
  /* Nor non-constant lower bounds in assumed shape arrays.  */
  if (GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ASSUMED_SHAPE
      || GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ASSUMED_SHAPE_CONT)
    {
      for (dim = 0; dim < rank; dim++)
	if (GFC_TYPE_ARRAY_LBOUND (type, dim) == NULL_TREE
	    || TREE_CODE (GFC_TYPE_ARRAY_LBOUND (type, dim)) != INTEGER_CST)
	  return false;
    }

  memset (info, '\0', sizeof (*info));
  info->ndimensions = rank;
  info->ordering = array_descr_ordering_column_major;
  info->element_type = etype;
  ptype = build_pointer_type (gfc_array_index_type);
  base_decl = GFC_TYPE_ARRAY_BASE_DECL (type, indirect);
  if (!base_decl)
    {
      base_decl = make_node (DEBUG_EXPR_DECL);
      DECL_ARTIFICIAL (base_decl) = 1;
      TREE_TYPE (base_decl) = indirect ? build_pointer_type (ptype) : ptype;
      SET_DECL_MODE (base_decl, TYPE_MODE (TREE_TYPE (base_decl)));
      GFC_TYPE_ARRAY_BASE_DECL (type, indirect) = base_decl;
    }
  info->base_decl = base_decl;
  if (indirect)
    base_decl = build1 (INDIRECT_REF, ptype, base_decl);

  elem_size = fold_convert (gfc_array_index_type, TYPE_SIZE_UNIT (etype));

  gfc_get_descriptor_offsets_for_info (type, &data_off, &dtype_off, &dim_off,
				       &dim_size, &stride_suboff,
				       &lower_suboff, &upper_suboff);

  t = base_decl;
  if (!integer_zerop (data_off))
    t = fold_build_pointer_plus (t, data_off);
  t = build1 (NOP_EXPR, build_pointer_type (ptr_type_node), t);
  info->data_location = build1 (INDIRECT_REF, ptr_type_node, t);
  if (GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE)
    info->allocated = build2 (NE_EXPR, logical_type_node,
			      info->data_location, null_pointer_node);
  else if (GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_POINTER
	   || GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_POINTER_CONT)
    info->associated = build2 (NE_EXPR, logical_type_node,
			       info->data_location, null_pointer_node);
  if ((GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ASSUMED_RANK
       || GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ASSUMED_RANK_CONT)
      && dwarf_version >= 5)
    {
      rank = 1;
      info->ndimensions = 1;
      t = base_decl;
      if (!integer_zerop (dtype_off))
	t = fold_build_pointer_plus (t, dtype_off);
      dtype = TYPE_MAIN_VARIANT (get_dtype_type_node ());
      field = gfc_advance_chain (TYPE_FIELDS (dtype), GFC_DTYPE_RANK);
      rank_off = byte_position (field);
      if (!integer_zerop (dtype_off))
	t = fold_build_pointer_plus (t, rank_off);

      t = build1 (NOP_EXPR, build_pointer_type (gfc_array_index_type), t);
      t = build1 (INDIRECT_REF, gfc_array_index_type, t);
      info->rank = t;
      t = build0 (PLACEHOLDER_EXPR, TREE_TYPE (dim_off));
      t = size_binop (MULT_EXPR, t, dim_size);
      dim_off = build2 (PLUS_EXPR, TREE_TYPE (dim_off), t, dim_off);
    }

  for (dim = 0; dim < rank; dim++)
    {
      t = fold_build_pointer_plus (base_decl,
				   size_binop (PLUS_EXPR,
					       dim_off, lower_suboff));
      t = build1 (INDIRECT_REF, gfc_array_index_type, t);
      info->dimen[dim].lower_bound = t;
      t = fold_build_pointer_plus (base_decl,
				   size_binop (PLUS_EXPR,
					       dim_off, upper_suboff));
      t = build1 (INDIRECT_REF, gfc_array_index_type, t);
      info->dimen[dim].upper_bound = t;
      if (GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ASSUMED_SHAPE
	  || GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ASSUMED_SHAPE_CONT)
	{
	  /* Assumed shape arrays have known lower bounds.  */
	  info->dimen[dim].upper_bound
	    = build2 (MINUS_EXPR, gfc_array_index_type,
		      info->dimen[dim].upper_bound,
		      info->dimen[dim].lower_bound);
	  info->dimen[dim].lower_bound
	    = fold_convert (gfc_array_index_type,
			    GFC_TYPE_ARRAY_LBOUND (type, dim));
	  info->dimen[dim].upper_bound
	    = build2 (PLUS_EXPR, gfc_array_index_type,
		      info->dimen[dim].lower_bound,
		      info->dimen[dim].upper_bound);
	}
      t = fold_build_pointer_plus (base_decl,
				   size_binop (PLUS_EXPR,
					       dim_off, stride_suboff));
      t = build1 (INDIRECT_REF, gfc_array_index_type, t);
      t = build2 (MULT_EXPR, gfc_array_index_type, t, elem_size);
      info->dimen[dim].stride = t;
      if (dim + 1 < rank)
	dim_off = size_binop (PLUS_EXPR, dim_off, dim_size);
    }

  return true;
}


/* Create a type to handle vector subscripts for coarray library calls. It
   has the form:
     struct caf_vector_t {
       size_t nvec;  // size of the vector
       union {
         struct {
           void *vector;
           int kind;
         } v;
         struct {
           ptrdiff_t lower_bound;
           ptrdiff_t upper_bound;
           ptrdiff_t stride;
         } triplet;
       } u;
     }
   where nvec == 0 for DIMEN_ELEMENT or DIMEN_RANGE and nvec being the vector
   size in case of DIMEN_VECTOR, where kind is the integer type of the vector.  */

tree
gfc_get_caf_vector_type (int dim)
{
  static tree vector_types[GFC_MAX_DIMENSIONS];
  static tree vec_type = NULL_TREE;
  tree triplet_struct_type, vect_struct_type, union_type, tmp, *chain;

  if (vector_types[dim-1] != NULL_TREE)
    return vector_types[dim-1];

  if (vec_type == NULL_TREE)
    {
      chain = 0;
      vect_struct_type = make_node (RECORD_TYPE);
      tmp = gfc_add_field_to_struct_1 (vect_struct_type,
				       get_identifier ("vector"),
				       pvoid_type_node, &chain);
      TREE_NO_WARNING (tmp) = 1;
      tmp = gfc_add_field_to_struct_1 (vect_struct_type,
				       get_identifier ("kind"),
				       integer_type_node, &chain);
      TREE_NO_WARNING (tmp) = 1;
      gfc_finish_type (vect_struct_type);

      chain = 0;
      triplet_struct_type = make_node (RECORD_TYPE);
      tmp = gfc_add_field_to_struct_1 (triplet_struct_type,
				       get_identifier ("lower_bound"),
				       gfc_array_index_type, &chain);
      TREE_NO_WARNING (tmp) = 1;
      tmp = gfc_add_field_to_struct_1 (triplet_struct_type,
				       get_identifier ("upper_bound"),
				       gfc_array_index_type, &chain);
      TREE_NO_WARNING (tmp) = 1;
      tmp = gfc_add_field_to_struct_1 (triplet_struct_type, get_identifier ("stride"),
				       gfc_array_index_type, &chain);
      TREE_NO_WARNING (tmp) = 1;
      gfc_finish_type (triplet_struct_type);

      chain = 0;
      union_type = make_node (UNION_TYPE);
      tmp = gfc_add_field_to_struct_1 (union_type, get_identifier ("v"),
                                       vect_struct_type, &chain);
      TREE_NO_WARNING (tmp) = 1;
      tmp = gfc_add_field_to_struct_1 (union_type, get_identifier ("triplet"),
				       triplet_struct_type, &chain);
      TREE_NO_WARNING (tmp) = 1;
      gfc_finish_type (union_type);

      chain = 0;
      vec_type = make_node (RECORD_TYPE);
      tmp = gfc_add_field_to_struct_1 (vec_type, get_identifier ("nvec"),
				       size_type_node, &chain);
      TREE_NO_WARNING (tmp) = 1;
      tmp = gfc_add_field_to_struct_1 (vec_type, get_identifier ("u"),
				       union_type, &chain);
      TREE_NO_WARNING (tmp) = 1;
      gfc_finish_type (vec_type);
      TYPE_NAME (vec_type) = get_identifier ("caf_vector_t");
    }

  tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node,
			  gfc_rank_cst[dim-1]);
  vector_types[dim-1] = build_array_type (vec_type, tmp);
  return vector_types[dim-1];
}


tree
gfc_get_caf_reference_type ()
{
  static tree reference_type = NULL_TREE;
  tree c_struct_type, s_struct_type, v_struct_type, union_type, dim_union_type,
      a_struct_type, u_union_type, tmp, *chain;

  if (reference_type != NULL_TREE)
    return reference_type;

  chain = 0;
  c_struct_type = make_node (RECORD_TYPE);
  tmp = gfc_add_field_to_struct_1 (c_struct_type,
				   get_identifier ("offset"),
				   gfc_array_index_type, &chain);
  TREE_NO_WARNING (tmp) = 1;
  tmp = gfc_add_field_to_struct_1 (c_struct_type,
				   get_identifier ("caf_token_offset"),
				   gfc_array_index_type, &chain);
  TREE_NO_WARNING (tmp) = 1;
  gfc_finish_type (c_struct_type);

  chain = 0;
  s_struct_type = make_node (RECORD_TYPE);
  tmp = gfc_add_field_to_struct_1 (s_struct_type,
				   get_identifier ("start"),
				   gfc_array_index_type, &chain);
  TREE_NO_WARNING (tmp) = 1;
  tmp = gfc_add_field_to_struct_1 (s_struct_type,
				   get_identifier ("end"),
				   gfc_array_index_type, &chain);
  TREE_NO_WARNING (tmp) = 1;
  tmp = gfc_add_field_to_struct_1 (s_struct_type,
				   get_identifier ("stride"),
				   gfc_array_index_type, &chain);
  TREE_NO_WARNING (tmp) = 1;
  gfc_finish_type (s_struct_type);

  chain = 0;
  v_struct_type = make_node (RECORD_TYPE);
  tmp = gfc_add_field_to_struct_1 (v_struct_type,
				   get_identifier ("vector"),
				   pvoid_type_node, &chain);
  TREE_NO_WARNING (tmp) = 1;
  tmp = gfc_add_field_to_struct_1 (v_struct_type,
				   get_identifier ("nvec"),
				   size_type_node, &chain);
  TREE_NO_WARNING (tmp) = 1;
  tmp = gfc_add_field_to_struct_1 (v_struct_type,
				   get_identifier ("kind"),
				   integer_type_node, &chain);
  TREE_NO_WARNING (tmp) = 1;
  gfc_finish_type (v_struct_type);

  chain = 0;
  union_type = make_node (UNION_TYPE);
  tmp = gfc_add_field_to_struct_1 (union_type, get_identifier ("s"),
				   s_struct_type, &chain);
  TREE_NO_WARNING (tmp) = 1;
  tmp = gfc_add_field_to_struct_1 (union_type, get_identifier ("v"),
				   v_struct_type, &chain);
  TREE_NO_WARNING (tmp) = 1;
  gfc_finish_type (union_type);

  tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node,
			  gfc_rank_cst[GFC_MAX_DIMENSIONS - 1]);
  dim_union_type = build_array_type (union_type, tmp);

  chain = 0;
  a_struct_type = make_node (RECORD_TYPE);
  tmp = gfc_add_field_to_struct_1 (a_struct_type, get_identifier ("mode"),
		build_array_type (unsigned_char_type_node,
				  build_range_type (gfc_array_index_type,
						    gfc_index_zero_node,
					 gfc_rank_cst[GFC_MAX_DIMENSIONS - 1])),
		&chain);
  TREE_NO_WARNING (tmp) = 1;
  tmp = gfc_add_field_to_struct_1 (a_struct_type,
				   get_identifier ("static_array_type"),
				   integer_type_node, &chain);
  TREE_NO_WARNING (tmp) = 1;
  tmp = gfc_add_field_to_struct_1 (a_struct_type, get_identifier ("dim"),
				   dim_union_type, &chain);
  TREE_NO_WARNING (tmp) = 1;
  gfc_finish_type (a_struct_type);

  chain = 0;
  u_union_type = make_node (UNION_TYPE);
  tmp = gfc_add_field_to_struct_1 (u_union_type, get_identifier ("c"),
				   c_struct_type, &chain);
  TREE_NO_WARNING (tmp) = 1;
  tmp = gfc_add_field_to_struct_1 (u_union_type, get_identifier ("a"),
				   a_struct_type, &chain);
  TREE_NO_WARNING (tmp) = 1;
  gfc_finish_type (u_union_type);

  chain = 0;
  reference_type = make_node (RECORD_TYPE);
  tmp = gfc_add_field_to_struct_1 (reference_type, get_identifier ("next"),
				   build_pointer_type (reference_type), &chain);
  TREE_NO_WARNING (tmp) = 1;
  tmp = gfc_add_field_to_struct_1 (reference_type, get_identifier ("type"),
				   integer_type_node, &chain);
  TREE_NO_WARNING (tmp) = 1;
  tmp = gfc_add_field_to_struct_1 (reference_type, get_identifier ("item_size"),
				   size_type_node, &chain);
  TREE_NO_WARNING (tmp) = 1;
  tmp = gfc_add_field_to_struct_1 (reference_type, get_identifier ("u"),
				   u_union_type, &chain);
  TREE_NO_WARNING (tmp) = 1;
  gfc_finish_type (reference_type);
  TYPE_NAME (reference_type) = get_identifier ("caf_reference_t");

  return reference_type;
}

#include "gt-fortran-trans-types.h"
