/* Declaration statement matcher
   Copyright (C) 2002-2022 Free Software Foundation, Inc.
   Contributed by Andy Vaught

This file is part of GCC.

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

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

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

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "options.h"
#include "tree.h"
#include "gfortran.h"
#include "stringpool.h"
#include "match.h"
#include "parse.h"
#include "constructor.h"
#include "target.h"

/* Macros to access allocate memory for gfc_data_variable,
   gfc_data_value and gfc_data.  */
#define gfc_get_data_variable() XCNEW (gfc_data_variable)
#define gfc_get_data_value() XCNEW (gfc_data_value)
#define gfc_get_data() XCNEW (gfc_data)


static bool set_binding_label (const char **, const char *, int);


/* This flag is set if an old-style length selector is matched
   during a type-declaration statement.  */

static int old_char_selector;

/* When variables acquire types and attributes from a declaration
   statement, they get them from the following static variables.  The
   first part of a declaration sets these variables and the second
   part copies these into symbol structures.  */

static gfc_typespec current_ts;

static symbol_attribute current_attr;
static gfc_array_spec *current_as;
static int colon_seen;
static int attr_seen;

/* The current binding label (if any).  */
static const char* curr_binding_label;
/* Need to know how many identifiers are on the current data declaration
   line in case we're given the BIND(C) attribute with a NAME= specifier.  */
static int num_idents_on_line;
/* Need to know if a NAME= specifier was found during gfc_match_bind_c so we
   can supply a name if the curr_binding_label is nil and NAME= was not.  */
static int has_name_equals = 0;

/* Initializer of the previous enumerator.  */

static gfc_expr *last_initializer;

/* History of all the enumerators is maintained, so that
   kind values of all the enumerators could be updated depending
   upon the maximum initialized value.  */

typedef struct enumerator_history
{
  gfc_symbol *sym;
  gfc_expr *initializer;
  struct enumerator_history *next;
}
enumerator_history;

/* Header of enum history chain.  */

static enumerator_history *enum_history = NULL;

/* Pointer of enum history node containing largest initializer.  */

static enumerator_history *max_enum = NULL;

/* gfc_new_block points to the symbol of a newly matched block.  */

gfc_symbol *gfc_new_block;

bool gfc_matching_function;

/* Set upon parsing a !GCC$ unroll n directive for use in the next loop.  */
int directive_unroll = -1;

/* Set upon parsing supported !GCC$ pragmas for use in the next loop.  */
bool directive_ivdep = false;
bool directive_vector = false;
bool directive_novector = false;

/* Map of middle-end built-ins that should be vectorized.  */
hash_map<nofree_string_hash, int> *gfc_vectorized_builtins;

/* If a kind expression of a component of a parameterized derived type is
   parameterized, temporarily store the expression here.  */
static gfc_expr *saved_kind_expr = NULL;

/* Used to store the parameter list arising in a PDT declaration and
   in the typespec of a PDT variable or component.  */
static gfc_actual_arglist *decl_type_param_list;
static gfc_actual_arglist *type_param_spec_list;

/********************* DATA statement subroutines *********************/

static bool in_match_data = false;

bool
gfc_in_match_data (void)
{
  return in_match_data;
}

static void
set_in_match_data (bool set_value)
{
  in_match_data = set_value;
}

/* Free a gfc_data_variable structure and everything beneath it.  */

static void
free_variable (gfc_data_variable *p)
{
  gfc_data_variable *q;

  for (; p; p = q)
    {
      q = p->next;
      gfc_free_expr (p->expr);
      gfc_free_iterator (&p->iter, 0);
      free_variable (p->list);
      free (p);
    }
}


/* Free a gfc_data_value structure and everything beneath it.  */

static void
free_value (gfc_data_value *p)
{
  gfc_data_value *q;

  for (; p; p = q)
    {
      q = p->next;
      mpz_clear (p->repeat);
      gfc_free_expr (p->expr);
      free (p);
    }
}


/* Free a list of gfc_data structures.  */

void
gfc_free_data (gfc_data *p)
{
  gfc_data *q;

  for (; p; p = q)
    {
      q = p->next;
      free_variable (p->var);
      free_value (p->value);
      free (p);
    }
}


/* Free all data in a namespace.  */

static void
gfc_free_data_all (gfc_namespace *ns)
{
  gfc_data *d;

  for (;ns->data;)
    {
      d = ns->data->next;
      free (ns->data);
      ns->data = d;
    }
}

/* Reject data parsed since the last restore point was marked.  */

void
gfc_reject_data (gfc_namespace *ns)
{
  gfc_data *d;

  while (ns->data && ns->data != ns->old_data)
    {
      d = ns->data->next;
      free (ns->data);
      ns->data = d;
    }
}

static match var_element (gfc_data_variable *);

/* Match a list of variables terminated by an iterator and a right
   parenthesis.  */

static match
var_list (gfc_data_variable *parent)
{
  gfc_data_variable *tail, var;
  match m;

  m = var_element (&var);
  if (m == MATCH_ERROR)
    return MATCH_ERROR;
  if (m == MATCH_NO)
    goto syntax;

  tail = gfc_get_data_variable ();
  *tail = var;

  parent->list = tail;

  for (;;)
    {
      if (gfc_match_char (',') != MATCH_YES)
	goto syntax;

      m = gfc_match_iterator (&parent->iter, 1);
      if (m == MATCH_YES)
	break;
      if (m == MATCH_ERROR)
	return MATCH_ERROR;

      m = var_element (&var);
      if (m == MATCH_ERROR)
	return MATCH_ERROR;
      if (m == MATCH_NO)
	goto syntax;

      tail->next = gfc_get_data_variable ();
      tail = tail->next;

      *tail = var;
    }

  if (gfc_match_char (')') != MATCH_YES)
    goto syntax;
  return MATCH_YES;

syntax:
  gfc_syntax_error (ST_DATA);
  return MATCH_ERROR;
}


/* Match a single element in a data variable list, which can be a
   variable-iterator list.  */

static match
var_element (gfc_data_variable *new_var)
{
  match m;
  gfc_symbol *sym;

  memset (new_var, 0, sizeof (gfc_data_variable));

  if (gfc_match_char ('(') == MATCH_YES)
    return var_list (new_var);

  m = gfc_match_variable (&new_var->expr, 0);
  if (m != MATCH_YES)
    return m;

  if (new_var->expr->expr_type == EXPR_CONSTANT
      && new_var->expr->symtree == NULL)
    {
      gfc_error ("Inquiry parameter cannot appear in a "
		 "data-stmt-object-list at %C");
      return MATCH_ERROR;
    }

  sym = new_var->expr->symtree->n.sym;

  /* Symbol should already have an associated type.  */
  if (!gfc_check_symbol_typed (sym, gfc_current_ns, false, gfc_current_locus))
    return MATCH_ERROR;

  if (!sym->attr.function && gfc_current_ns->parent
      && gfc_current_ns->parent == sym->ns)
    {
      gfc_error ("Host associated variable %qs may not be in the DATA "
		 "statement at %C", sym->name);
      return MATCH_ERROR;
    }

  if (gfc_current_state () != COMP_BLOCK_DATA
      && sym->attr.in_common
      && !gfc_notify_std (GFC_STD_GNU, "initialization of "
			  "common block variable %qs in DATA statement at %C",
			  sym->name))
    return MATCH_ERROR;

  if (!gfc_add_data (&sym->attr, sym->name, &new_var->expr->where))
    return MATCH_ERROR;

  return MATCH_YES;
}


/* Match the top-level list of data variables.  */

static match
top_var_list (gfc_data *d)
{
  gfc_data_variable var, *tail, *new_var;
  match m;

  tail = NULL;

  for (;;)
    {
      m = var_element (&var);
      if (m == MATCH_NO)
	goto syntax;
      if (m == MATCH_ERROR)
	return MATCH_ERROR;

      new_var = gfc_get_data_variable ();
      *new_var = var;
      if (new_var->expr)
	new_var->expr->where = gfc_current_locus;

      if (tail == NULL)
	d->var = new_var;
      else
	tail->next = new_var;

      tail = new_var;

      if (gfc_match_char ('/') == MATCH_YES)
	break;
      if (gfc_match_char (',') != MATCH_YES)
	goto syntax;
    }

  return MATCH_YES;

syntax:
  gfc_syntax_error (ST_DATA);
  gfc_free_data_all (gfc_current_ns);
  return MATCH_ERROR;
}


static match
match_data_constant (gfc_expr **result)
{
  char name[GFC_MAX_SYMBOL_LEN + 1];
  gfc_symbol *sym, *dt_sym = NULL;
  gfc_expr *expr;
  match m;
  locus old_loc;

  m = gfc_match_literal_constant (&expr, 1);
  if (m == MATCH_YES)
    {
      *result = expr;
      return MATCH_YES;
    }

  if (m == MATCH_ERROR)
    return MATCH_ERROR;

  m = gfc_match_null (result);
  if (m != MATCH_NO)
    return m;

  old_loc = gfc_current_locus;

  /* Should this be a structure component, try to match it
     before matching a name.  */
  m = gfc_match_rvalue (result);
  if (m == MATCH_ERROR)
    return m;

  if (m == MATCH_YES && (*result)->expr_type == EXPR_STRUCTURE)
    {
      if (!gfc_simplify_expr (*result, 0))
	m = MATCH_ERROR;
      return m;
    }
  else if (m == MATCH_YES)
    {
      /* If a parameter inquiry ends up here, symtree is NULL but **result
	 contains the right constant expression.  Check here.  */
      if ((*result)->symtree == NULL
	  && (*result)->expr_type == EXPR_CONSTANT
	  && ((*result)->ts.type == BT_INTEGER
	      || (*result)->ts.type == BT_REAL))
	return m;

      /* F2018:R845 data-stmt-constant is initial-data-target.
	 A data-stmt-constant shall be ... initial-data-target if and
	 only if the corresponding data-stmt-object has the POINTER
	 attribute. ...  If data-stmt-constant is initial-data-target
	 the corresponding data statement object shall be
	 data-pointer-initialization compatible (7.5.4.6) with the initial
	 data target; the data statement object is initially associated
	 with the target.  */
      if ((*result)->symtree
	  && (*result)->symtree->n.sym->attr.save
	  && (*result)->symtree->n.sym->attr.target)
	return m;
      gfc_free_expr (*result);
    }

  gfc_current_locus = old_loc;

  m = gfc_match_name (name);
  if (m != MATCH_YES)
    return m;

  if (gfc_find_symbol (name, NULL, 1, &sym))
    return MATCH_ERROR;

  if (sym && sym->attr.generic)
    dt_sym = gfc_find_dt_in_generic (sym);

  if (sym == NULL
      || (sym->attr.flavor != FL_PARAMETER
	  && (!dt_sym || !gfc_fl_struct (dt_sym->attr.flavor))))
    {
      gfc_error ("Symbol %qs must be a PARAMETER in DATA statement at %C",
		 name);
      *result = NULL;
      return MATCH_ERROR;
    }
  else if (dt_sym && gfc_fl_struct (dt_sym->attr.flavor))
    return gfc_match_structure_constructor (dt_sym, result);

  /* Check to see if the value is an initialization array expression.  */
  if (sym->value->expr_type == EXPR_ARRAY)
    {
      gfc_current_locus = old_loc;

      m = gfc_match_init_expr (result);
      if (m == MATCH_ERROR)
	return m;

      if (m == MATCH_YES)
	{
	  if (!gfc_simplify_expr (*result, 0))
	    m = MATCH_ERROR;

	  if ((*result)->expr_type == EXPR_CONSTANT)
	    return m;
          else
	    {
	      gfc_error ("Invalid initializer %s in Data statement at %C", name);
	      return MATCH_ERROR;
	    }
	}
    }

  *result = gfc_copy_expr (sym->value);
  return MATCH_YES;
}


/* Match a list of values in a DATA statement.  The leading '/' has
   already been seen at this point.  */

static match
top_val_list (gfc_data *data)
{
  gfc_data_value *new_val, *tail;
  gfc_expr *expr;
  match m;

  tail = NULL;

  for (;;)
    {
      m = match_data_constant (&expr);
      if (m == MATCH_NO)
	goto syntax;
      if (m == MATCH_ERROR)
	return MATCH_ERROR;

      new_val = gfc_get_data_value ();
      mpz_init (new_val->repeat);

      if (tail == NULL)
	data->value = new_val;
      else
	tail->next = new_val;

      tail = new_val;

      if (expr->ts.type != BT_INTEGER || gfc_match_char ('*') != MATCH_YES)
	{
	  tail->expr = expr;
	  mpz_set_ui (tail->repeat, 1);
	}
      else
	{
	  mpz_set (tail->repeat, expr->value.integer);
	  gfc_free_expr (expr);

	  m = match_data_constant (&tail->expr);
	  if (m == MATCH_NO)
	    goto syntax;
	  if (m == MATCH_ERROR)
	    return MATCH_ERROR;
	}

      if (gfc_match_char ('/') == MATCH_YES)
	break;
      if (gfc_match_char (',') == MATCH_NO)
	goto syntax;
    }

  return MATCH_YES;

syntax:
  gfc_syntax_error (ST_DATA);
  gfc_free_data_all (gfc_current_ns);
  return MATCH_ERROR;
}


/* Matches an old style initialization.  */

static match
match_old_style_init (const char *name)
{
  match m;
  gfc_symtree *st;
  gfc_symbol *sym;
  gfc_data *newdata, *nd;

  /* Set up data structure to hold initializers.  */
  gfc_find_sym_tree (name, NULL, 0, &st);
  sym = st->n.sym;

  newdata = gfc_get_data ();
  newdata->var = gfc_get_data_variable ();
  newdata->var->expr = gfc_get_variable_expr (st);
  newdata->var->expr->where = sym->declared_at;
  newdata->where = gfc_current_locus;

  /* Match initial value list. This also eats the terminal '/'.  */
  m = top_val_list (newdata);
  if (m != MATCH_YES)
    {
      free (newdata);
      return m;
    }

  /* Check that a BOZ did not creep into an old-style initialization.  */
  for (nd = newdata; nd; nd = nd->next)
    {
      if (nd->value->expr->ts.type == BT_BOZ
	  && gfc_invalid_boz (G_("BOZ at %L cannot appear in an old-style "
			      "initialization"), &nd->value->expr->where))
	return MATCH_ERROR;

      if (nd->var->expr->ts.type != BT_INTEGER
	  && nd->var->expr->ts.type != BT_REAL
	  && nd->value->expr->ts.type == BT_BOZ)
	{
	  gfc_error (G_("BOZ literal constant near %L cannot be assigned to "
		     "a %qs variable in an old-style initialization"),
		     &nd->value->expr->where,
		     gfc_typename (&nd->value->expr->ts));
	  return MATCH_ERROR;
	}
    }

  if (gfc_pure (NULL))
    {
      gfc_error ("Initialization at %C is not allowed in a PURE procedure");
      free (newdata);
      return MATCH_ERROR;
    }
  gfc_unset_implicit_pure (gfc_current_ns->proc_name);

  /* Mark the variable as having appeared in a data statement.  */
  if (!gfc_add_data (&sym->attr, sym->name, &sym->declared_at))
    {
      free (newdata);
      return MATCH_ERROR;
    }

  /* Chain in namespace list of DATA initializers.  */
  newdata->next = gfc_current_ns->data;
  gfc_current_ns->data = newdata;

  return m;
}


/* Match the stuff following a DATA statement. If ERROR_FLAG is set,
   we are matching a DATA statement and are therefore issuing an error
   if we encounter something unexpected, if not, we're trying to match
   an old-style initialization expression of the form INTEGER I /2/.  */

match
gfc_match_data (void)
{
  gfc_data *new_data;
  gfc_expr *e;
  gfc_ref *ref;
  match m;
  char c;

  /* DATA has been matched.  In free form source code, the next character
     needs to be whitespace or '(' from an implied do-loop.  Check that
     here.  */
  c = gfc_peek_ascii_char ();
  if (gfc_current_form == FORM_FREE && !gfc_is_whitespace (c) && c != '(')
    return MATCH_NO;

  /* Before parsing the rest of a DATA statement, check F2008:c1206.  */
  if ((gfc_current_state () == COMP_FUNCTION
       || gfc_current_state () == COMP_SUBROUTINE)
      && gfc_state_stack->previous->state == COMP_INTERFACE)
    {
      gfc_error ("DATA statement at %C cannot appear within an INTERFACE");
      return MATCH_ERROR;
    }

  set_in_match_data (true);

  for (;;)
    {
      new_data = gfc_get_data ();
      new_data->where = gfc_current_locus;

      m = top_var_list (new_data);
      if (m != MATCH_YES)
	goto cleanup;

      if (new_data->var->iter.var
	  && new_data->var->iter.var->ts.type == BT_INTEGER
	  && new_data->var->iter.var->symtree->n.sym->attr.implied_index == 1
	  && new_data->var->list
	  && new_data->var->list->expr
	  && new_data->var->list->expr->ts.type == BT_CHARACTER
	  && new_data->var->list->expr->ref
	  && new_data->var->list->expr->ref->type == REF_SUBSTRING)
	{
	  gfc_error ("Invalid substring in data-implied-do at %L in DATA "
		     "statement", &new_data->var->list->expr->where);
	  goto cleanup;
	}

      /* Check for an entity with an allocatable component, which is not
	 allowed.  */
      e = new_data->var->expr;
      if (e)
	{
	  bool invalid;

	  invalid = false;
	  for (ref = e->ref; ref; ref = ref->next)
	    if ((ref->type == REF_COMPONENT
		 && ref->u.c.component->attr.allocatable)
		|| (ref->type == REF_ARRAY
		    && e->symtree->n.sym->attr.pointer != 1
		    && ref->u.ar.as && ref->u.ar.as->type == AS_DEFERRED))
	      invalid = true;

	  if (invalid)
	    {
	      gfc_error ("Allocatable component or deferred-shaped array "
			 "near %C in DATA statement");
	      goto cleanup;
	    }

	  /* F2008:C567 (R536) A data-i-do-object or a variable that appears
	     as a data-stmt-object shall not be an object designator in which
	     a pointer appears other than as the entire rightmost part-ref.  */
	  if (!e->ref && e->ts.type == BT_DERIVED
	      && e->symtree->n.sym->attr.pointer)
	    goto partref;

	  ref = e->ref;
	  if (e->symtree->n.sym->ts.type == BT_DERIVED
	      && e->symtree->n.sym->attr.pointer
	      && ref->type == REF_COMPONENT)
	    goto partref;

	  for (; ref; ref = ref->next)
	    if (ref->type == REF_COMPONENT
		&& ref->u.c.component->attr.pointer
		&& ref->next)
	      goto partref;
	}

      m = top_val_list (new_data);
      if (m != MATCH_YES)
	goto cleanup;

      new_data->next = gfc_current_ns->data;
      gfc_current_ns->data = new_data;

      /* A BOZ literal constant cannot appear in a structure constructor.
	 Check for that here for a data statement value.  */
      if (new_data->value->expr->ts.type == BT_DERIVED
	  && new_data->value->expr->value.constructor)
	{
	  gfc_constructor *c;
	  c = gfc_constructor_first (new_data->value->expr->value.constructor);
	  for (; c; c = gfc_constructor_next (c))
	    if (c->expr && c->expr->ts.type == BT_BOZ)
	      {
		gfc_error ("BOZ literal constant at %L cannot appear in a "
			   "structure constructor", &c->expr->where);
		return MATCH_ERROR;
	      }
	}

      if (gfc_match_eos () == MATCH_YES)
	break;

      gfc_match_char (',');	/* Optional comma */
    }

  set_in_match_data (false);

  if (gfc_pure (NULL))
    {
      gfc_error ("DATA statement at %C is not allowed in a PURE procedure");
      return MATCH_ERROR;
    }
  gfc_unset_implicit_pure (gfc_current_ns->proc_name);

  return MATCH_YES;

partref:

  gfc_error ("part-ref with pointer attribute near %L is not "
	     "rightmost part-ref of data-stmt-object",
	     &e->where);

cleanup:
  set_in_match_data (false);
  gfc_free_data (new_data);
  return MATCH_ERROR;
}


/************************ Declaration statements *********************/


/* Like gfc_match_init_expr, but matches a 'clist' (old-style initialization
   list). The difference here is the expression is a list of constants
   and is surrounded by '/'.
   The typespec ts must match the typespec of the variable which the
   clist is initializing.
   The arrayspec tells whether this should match a list of constants
   corresponding to array elements or a scalar (as == NULL).  */

static match
match_clist_expr (gfc_expr **result, gfc_typespec *ts, gfc_array_spec *as)
{
  gfc_constructor_base array_head = NULL;
  gfc_expr *expr = NULL;
  match m = MATCH_ERROR;
  locus where;
  mpz_t repeat, cons_size, as_size;
  bool scalar;
  int cmp;

  gcc_assert (ts);

  /* We have already matched '/' - now look for a constant list, as with
     top_val_list from decl.cc, but append the result to an array.  */
  if (gfc_match ("/") == MATCH_YES)
    {
      gfc_error ("Empty old style initializer list at %C");
      return MATCH_ERROR;
    }

  where = gfc_current_locus;
  scalar = !as || !as->rank;

  if (!scalar && !spec_size (as, &as_size))
    {
      gfc_error ("Array in initializer list at %L must have an explicit shape",
		 as->type == AS_EXPLICIT ? &as->upper[0]->where : &where);
      /* Nothing to cleanup yet.  */
      return MATCH_ERROR;
    }

  mpz_init_set_ui (repeat, 0);

  for (;;)
    {
      m = match_data_constant (&expr);
      if (m != MATCH_YES)
        expr = NULL; /* match_data_constant may set expr to garbage */
      if (m == MATCH_NO)
        goto syntax;
      if (m == MATCH_ERROR)
        goto cleanup;

      /* Found r in repeat spec r*c; look for the constant to repeat.  */
      if ( gfc_match_char ('*') == MATCH_YES)
        {
          if (scalar)
            {
              gfc_error ("Repeat spec invalid in scalar initializer at %C");
              goto cleanup;
            }
          if (expr->ts.type != BT_INTEGER)
            {
              gfc_error ("Repeat spec must be an integer at %C");
              goto cleanup;
            }
          mpz_set (repeat, expr->value.integer);
          gfc_free_expr (expr);
          expr = NULL;

          m = match_data_constant (&expr);
          if (m == MATCH_NO)
	    {
	      m = MATCH_ERROR;
	      gfc_error ("Expected data constant after repeat spec at %C");
	    }
          if (m != MATCH_YES)
            goto cleanup;
        }
      /* No repeat spec, we matched the data constant itself. */
      else
        mpz_set_ui (repeat, 1);

      if (!scalar)
        {
          /* Add the constant initializer as many times as repeated. */
          for (; mpz_cmp_ui (repeat, 0) > 0; mpz_sub_ui (repeat, repeat, 1))
            {
              /* Make sure types of elements match */
              if(ts && !gfc_compare_types (&expr->ts, ts)
                    && !gfc_convert_type (expr, ts, 1))
                goto cleanup;

              gfc_constructor_append_expr (&array_head,
                  gfc_copy_expr (expr), &gfc_current_locus);
            }

          gfc_free_expr (expr);
          expr = NULL;
        }

      /* For scalar initializers quit after one element.  */
      else
        {
          if(gfc_match_char ('/') != MATCH_YES)
            {
              gfc_error ("End of scalar initializer expected at %C");
              goto cleanup;
            }
          break;
        }

      if (gfc_match_char ('/') == MATCH_YES)
        break;
      if (gfc_match_char (',') == MATCH_NO)
        goto syntax;
    }

  /* If we break early from here out, we encountered an error.  */
  m = MATCH_ERROR;

  /* Set up expr as an array constructor. */
  if (!scalar)
    {
      expr = gfc_get_array_expr (ts->type, ts->kind, &where);
      expr->ts = *ts;
      expr->value.constructor = array_head;

      /* Validate sizes.  We built expr ourselves, so cons_size will be
	 constant (we fail above for non-constant expressions).
	 We still need to verify that the sizes match.  */
      gcc_assert (gfc_array_size (expr, &cons_size));
      cmp = mpz_cmp (cons_size, as_size);
      if (cmp < 0)
	gfc_error ("Not enough elements in array initializer at %C");
      else if (cmp > 0)
	gfc_error ("Too many elements in array initializer at %C");
      mpz_clear (cons_size);
      if (cmp)
	goto cleanup;

      /* Set the rank/shape to match the LHS as auto-reshape is implied. */
      expr->rank = as->rank;
      expr->shape = gfc_get_shape (as->rank);
      for (int i = 0; i < as->rank; ++i)
	spec_dimen_size (as, i, &expr->shape[i]);
    }

  /* Make sure scalar types match. */
  else if (!gfc_compare_types (&expr->ts, ts)
           && !gfc_convert_type (expr, ts, 1))
    goto cleanup;

  if (expr->ts.u.cl)
    expr->ts.u.cl->length_from_typespec = 1;

  *result = expr;
  m = MATCH_YES;
  goto done;

syntax:
  m = MATCH_ERROR;
  gfc_error ("Syntax error in old style initializer list at %C");

cleanup:
  if (expr)
    expr->value.constructor = NULL;
  gfc_free_expr (expr);
  gfc_constructor_free (array_head);

done:
  mpz_clear (repeat);
  if (!scalar)
    mpz_clear (as_size);
  return m;
}


/* Auxiliary function to merge DIMENSION and CODIMENSION array specs.  */

static bool
merge_array_spec (gfc_array_spec *from, gfc_array_spec *to, bool copy)
{
  if ((from->type == AS_ASSUMED_RANK && to->corank)
      || (to->type == AS_ASSUMED_RANK && from->corank))
    {
      gfc_error ("The assumed-rank array at %C shall not have a codimension");
      return false;
    }

  if (to->rank == 0 && from->rank > 0)
    {
      to->rank = from->rank;
      to->type = from->type;
      to->cray_pointee = from->cray_pointee;
      to->cp_was_assumed = from->cp_was_assumed;

      for (int i = to->corank - 1; i >= 0; i--)
	{
	  /* Do not exceed the limits on lower[] and upper[].  gfortran
	     cleans up elsewhere.  */
	  int j = from->rank + i;
	  if (j >= GFC_MAX_DIMENSIONS)
	    break;

	  to->lower[j] = to->lower[i];
	  to->upper[j] = to->upper[i];
	}
      for (int i = 0; i < from->rank; i++)
	{
	  if (copy)
	    {
	      to->lower[i] = gfc_copy_expr (from->lower[i]);
	      to->upper[i] = gfc_copy_expr (from->upper[i]);
	    }
	  else
	    {
	      to->lower[i] = from->lower[i];
	      to->upper[i] = from->upper[i];
	    }
	}
    }
  else if (to->corank == 0 && from->corank > 0)
    {
      to->corank = from->corank;
      to->cotype = from->cotype;

      for (int i = 0; i < from->corank; i++)
	{
	  /* Do not exceed the limits on lower[] and upper[].  gfortran
	     cleans up elsewhere.  */
	  int k = from->rank + i;
	  int j = to->rank + i;
	  if (j >= GFC_MAX_DIMENSIONS)
	    break;

	  if (copy)
	    {
	      to->lower[j] = gfc_copy_expr (from->lower[k]);
	      to->upper[j] = gfc_copy_expr (from->upper[k]);
	    }
	  else
	    {
	      to->lower[j] = from->lower[k];
	      to->upper[j] = from->upper[k];
	    }
	}
    }

  if (to->rank + to->corank > GFC_MAX_DIMENSIONS)
    {
      gfc_error ("Sum of array rank %d and corank %d at %C exceeds maximum "
		 "allowed dimensions of %d",
		 to->rank, to->corank, GFC_MAX_DIMENSIONS);
      to->corank = GFC_MAX_DIMENSIONS - to->rank;
      return false;
    }
  return true;
}


/* Match an intent specification.  Since this can only happen after an
   INTENT word, a legal intent-spec must follow.  */

static sym_intent
match_intent_spec (void)
{

  if (gfc_match (" ( in out )") == MATCH_YES)
    return INTENT_INOUT;
  if (gfc_match (" ( in )") == MATCH_YES)
    return INTENT_IN;
  if (gfc_match (" ( out )") == MATCH_YES)
    return INTENT_OUT;

  gfc_error ("Bad INTENT specification at %C");
  return INTENT_UNKNOWN;
}


/* Matches a character length specification, which is either a
   specification expression, '*', or ':'.  */

static match
char_len_param_value (gfc_expr **expr, bool *deferred)
{
  match m;

  *expr = NULL;
  *deferred = false;

  if (gfc_match_char ('*') == MATCH_YES)
    return MATCH_YES;

  if (gfc_match_char (':') == MATCH_YES)
    {
      if (!gfc_notify_std (GFC_STD_F2003, "deferred type parameter at %C"))
	return MATCH_ERROR;

      *deferred = true;

      return MATCH_YES;
    }

  m = gfc_match_expr (expr);

  if (m == MATCH_NO || m == MATCH_ERROR)
    return m;

  if (!gfc_expr_check_typed (*expr, gfc_current_ns, false))
    return MATCH_ERROR;

  /* If gfortran gets an EXPR_OP, try to simplifiy it.  This catches things
     like CHARACTER(([1])).   */
  if ((*expr)->expr_type == EXPR_OP)
    gfc_simplify_expr (*expr, 1);

  if ((*expr)->expr_type == EXPR_FUNCTION)
    {
      if ((*expr)->ts.type == BT_INTEGER
	  || ((*expr)->ts.type == BT_UNKNOWN
	      && strcmp((*expr)->symtree->name, "null") != 0))
	return MATCH_YES;

      goto syntax;
    }
  else if ((*expr)->expr_type == EXPR_CONSTANT)
    {
      /* F2008, 4.4.3.1:  The length is a type parameter; its kind is
	 processor dependent and its value is greater than or equal to zero.
	 F2008, 4.4.3.2:  If the character length parameter value evaluates
	 to a negative value, the length of character entities declared
	 is zero.  */

      if ((*expr)->ts.type == BT_INTEGER)
	{
	  if (mpz_cmp_si ((*expr)->value.integer, 0) < 0)
	    mpz_set_si ((*expr)->value.integer, 0);
	}
      else
	goto syntax;
    }
  else if ((*expr)->expr_type == EXPR_ARRAY)
    goto syntax;
  else if ((*expr)->expr_type == EXPR_VARIABLE)
    {
      bool t;
      gfc_expr *e;

      e = gfc_copy_expr (*expr);

      /* This catches the invalid code "[character(m(2:3)) :: 'x', 'y']",
	 which causes an ICE if gfc_reduce_init_expr() is called.  */
      if (e->ref && e->ref->type == REF_ARRAY
	  && e->ref->u.ar.type == AR_UNKNOWN
	  && e->ref->u.ar.dimen_type[0] == DIMEN_RANGE)
	goto syntax;

      t = gfc_reduce_init_expr (e);

      if (!t && e->ts.type == BT_UNKNOWN
	  && e->symtree->n.sym->attr.untyped == 1
	  && (flag_implicit_none
	      || e->symtree->n.sym->ns->seen_implicit_none == 1
	      || e->symtree->n.sym->ns->parent->seen_implicit_none == 1))
	{
	  gfc_free_expr (e);
	  goto syntax;
	}

      if ((e->ref && e->ref->type == REF_ARRAY
	   && e->ref->u.ar.type != AR_ELEMENT)
	  || (!e->ref && e->expr_type == EXPR_ARRAY))
	{
	  gfc_free_expr (e);
	  goto syntax;
	}

      gfc_free_expr (e);
    }

  if (gfc_seen_div0)
    m = MATCH_ERROR;

  return m;

syntax:
  gfc_error ("Scalar INTEGER expression expected at %L", &(*expr)->where);
  return MATCH_ERROR;
}


/* A character length is a '*' followed by a literal integer or a
   char_len_param_value in parenthesis.  */

static match
match_char_length (gfc_expr **expr, bool *deferred, bool obsolescent_check)
{
  int length;
  match m;

  *deferred = false;
  m = gfc_match_char ('*');
  if (m != MATCH_YES)
    return m;

  m = gfc_match_small_literal_int (&length, NULL);
  if (m == MATCH_ERROR)
    return m;

  if (m == MATCH_YES)
    {
      if (obsolescent_check
	  && !gfc_notify_std (GFC_STD_F95_OBS, "Old-style character length at %C"))
	return MATCH_ERROR;
      *expr = gfc_get_int_expr (gfc_charlen_int_kind, NULL, length);
      return m;
    }

  if (gfc_match_char ('(') == MATCH_NO)
    goto syntax;

  m = char_len_param_value (expr, deferred);
  if (m != MATCH_YES && gfc_matching_function)
    {
      gfc_undo_symbols ();
      m = MATCH_YES;
    }

  if (m == MATCH_ERROR)
    return m;
  if (m == MATCH_NO)
    goto syntax;

  if (gfc_match_char (')') == MATCH_NO)
    {
      gfc_free_expr (*expr);
      *expr = NULL;
      goto syntax;
    }

  return MATCH_YES;

syntax:
  gfc_error ("Syntax error in character length specification at %C");
  return MATCH_ERROR;
}


/* Special subroutine for finding a symbol.  Check if the name is found
   in the current name space.  If not, and we're compiling a function or
   subroutine and the parent compilation unit is an interface, then check
   to see if the name we've been given is the name of the interface
   (located in another namespace).  */

static int
find_special (const char *name, gfc_symbol **result, bool allow_subroutine)
{
  gfc_state_data *s;
  gfc_symtree *st;
  int i;

  i = gfc_get_sym_tree (name, NULL, &st, allow_subroutine);
  if (i == 0)
    {
      *result = st ? st->n.sym : NULL;
      goto end;
    }

  if (gfc_current_state () != COMP_SUBROUTINE
      && gfc_current_state () != COMP_FUNCTION)
    goto end;

  s = gfc_state_stack->previous;
  if (s == NULL)
    goto end;

  if (s->state != COMP_INTERFACE)
    goto end;
  if (s->sym == NULL)
    goto end;		  /* Nameless interface.  */

  if (strcmp (name, s->sym->name) == 0)
    {
      *result = s->sym;
      return 0;
    }

end:
  return i;
}


/* Special subroutine for getting a symbol node associated with a
   procedure name, used in SUBROUTINE and FUNCTION statements.  The
   symbol is created in the parent using with symtree node in the
   child unit pointing to the symbol.  If the current namespace has no
   parent, then the symbol is just created in the current unit.  */

static int
get_proc_name (const char *name, gfc_symbol **result, bool module_fcn_entry)
{
  gfc_symtree *st;
  gfc_symbol *sym;
  int rc = 0;

  /* Module functions have to be left in their own namespace because
     they have potentially (almost certainly!) already been referenced.
     In this sense, they are rather like external functions.  This is
     fixed up in resolve.cc(resolve_entries), where the symbol name-
     space is set to point to the master function, so that the fake
     result mechanism can work.  */
  if (module_fcn_entry)
    {
      /* Present if entry is declared to be a module procedure.  */
      rc = gfc_find_symbol (name, gfc_current_ns->parent, 0, result);

      if (*result == NULL)
	rc = gfc_get_symbol (name, NULL, result);
      else if (!gfc_get_symbol (name, NULL, &sym) && sym
		 && (*result)->ts.type == BT_UNKNOWN
		 && sym->attr.flavor == FL_UNKNOWN)
	/* Pick up the typespec for the entry, if declared in the function
	   body.  Note that this symbol is FL_UNKNOWN because it will
	   only have appeared in a type declaration.  The local symtree
	   is set to point to the module symbol and a unique symtree
	   to the local version.  This latter ensures a correct clearing
	   of the symbols.  */
	{
	  /* If the ENTRY proceeds its specification, we need to ensure
	     that this does not raise a "has no IMPLICIT type" error.  */
	  if (sym->ts.type == BT_UNKNOWN)
	    sym->attr.untyped = 1;

	  (*result)->ts = sym->ts;

	  /* Put the symbol in the procedure namespace so that, should
	     the ENTRY precede its specification, the specification
	     can be applied.  */
	  (*result)->ns = gfc_current_ns;

	  gfc_find_sym_tree (name, gfc_current_ns, 0, &st);
	  st->n.sym = *result;
	  st = gfc_get_unique_symtree (gfc_current_ns);
	  sym->refs++;
	  st->n.sym = sym;
	}
    }
  else
    rc = gfc_get_symbol (name, gfc_current_ns->parent, result);

  if (rc)
    return rc;

  sym = *result;
  if (sym->attr.proc == PROC_ST_FUNCTION)
    return rc;

  if (sym->attr.module_procedure && sym->attr.if_source == IFSRC_IFBODY)
    {
      /* Create a partially populated interface symbol to carry the
	 characteristics of the procedure and the result.  */
      sym->tlink = gfc_new_symbol (name, sym->ns);
      gfc_add_type (sym->tlink, &(sym->ts), &gfc_current_locus);
      gfc_copy_attr (&sym->tlink->attr, &sym->attr, NULL);
      if (sym->attr.dimension)
	sym->tlink->as = gfc_copy_array_spec (sym->as);

      /* Ideally, at this point, a copy would be made of the formal
	 arguments and their namespace. However, this does not appear
	 to be necessary, albeit at the expense of not being able to
	 use gfc_compare_interfaces directly.  */

      if (sym->result && sym->result != sym)
	{
	  sym->tlink->result = sym->result;
	  sym->result = NULL;
	}
      else if (sym->result)
	{
	  sym->tlink->result = sym->tlink;
	}
    }
  else if (sym && !sym->gfc_new
	   && gfc_current_state () != COMP_INTERFACE)
    {
      /* Trap another encompassed procedure with the same name.  All
	 these conditions are necessary to avoid picking up an entry
	 whose name clashes with that of the encompassing procedure;
	 this is handled using gsymbols to register unique, globally
	 accessible names.  */
      if (sym->attr.flavor != 0
	  && sym->attr.proc != 0
	  && (sym->attr.subroutine || sym->attr.function || sym->attr.entry)
	  && sym->attr.if_source != IFSRC_UNKNOWN)
	{
	  gfc_error_now ("Procedure %qs at %C is already defined at %L",
			 name, &sym->declared_at);
	  return true;
	}
      if (sym->attr.flavor != 0
	  && sym->attr.entry && sym->attr.if_source != IFSRC_UNKNOWN)
	{
	  gfc_error_now ("Procedure %qs at %C is already defined at %L",
			 name, &sym->declared_at);
	  return true;
	}

      if (sym->attr.external && sym->attr.procedure
	  && gfc_current_state () == COMP_CONTAINS)
	{
	  gfc_error_now ("Contained procedure %qs at %C clashes with "
			 "procedure defined at %L",
			 name, &sym->declared_at);
	  return true;
	}

      /* Trap a procedure with a name the same as interface in the
	 encompassing scope.  */
      if (sym->attr.generic != 0
	  && (sym->attr.subroutine || sym->attr.function)
	  && !sym->attr.mod_proc)
	{
	  gfc_error_now ("Name %qs at %C is already defined"
			 " as a generic interface at %L",
			 name, &sym->declared_at);
	  return true;
	}

      /* Trap declarations of attributes in encompassing scope.  The
	 signature for this is that ts.kind is nonzero for no-CLASS
	 entity.  For a CLASS entity, ts.kind is zero.  */
      if ((sym->ts.kind != 0 || sym->ts.type == BT_CLASS)
	  && !sym->attr.implicit_type
	  && sym->attr.proc == 0
	  && gfc_current_ns->parent != NULL
	  && sym->attr.access == 0
	  && !module_fcn_entry)
	{
	  gfc_error_now ("Procedure %qs at %C has an explicit interface "
		       "from a previous declaration",  name);
	  return true;
	}
    }

  /* C1246 (R1225) MODULE shall appear only in the function-stmt or
     subroutine-stmt of a module subprogram or of a nonabstract interface
     body that is declared in the scoping unit of a module or submodule.  */
  if (sym->attr.external
      && (sym->attr.subroutine || sym->attr.function)
      && sym->attr.if_source == IFSRC_IFBODY
      && !current_attr.module_procedure
      && sym->attr.proc == PROC_MODULE
      && gfc_state_stack->state == COMP_CONTAINS)
    {
      gfc_error_now ("Procedure %qs defined in interface body at %L "
		     "clashes with internal procedure defined at %C",
		     name, &sym->declared_at);
      return true;
    }

  if (sym && !sym->gfc_new
      && sym->attr.flavor != FL_UNKNOWN
      && sym->attr.referenced == 0 && sym->attr.subroutine == 1
      && gfc_state_stack->state == COMP_CONTAINS
      && gfc_state_stack->previous->state == COMP_SUBROUTINE)
    {
      gfc_error_now ("Procedure %qs at %C is already defined at %L",
		     name, &sym->declared_at);
      return true;
    }

  if (gfc_current_ns->parent == NULL || *result == NULL)
    return rc;

  /* Module function entries will already have a symtree in
     the current namespace but will need one at module level.  */
  if (module_fcn_entry)
    {
      /* Present if entry is declared to be a module procedure.  */
      rc = gfc_find_sym_tree (name, gfc_current_ns->parent, 0, &st);
      if (st == NULL)
	st = gfc_new_symtree (&gfc_current_ns->parent->sym_root, name);
    }
  else
    st = gfc_new_symtree (&gfc_current_ns->sym_root, name);

  st->n.sym = sym;
  sym->refs++;

  /* See if the procedure should be a module procedure.  */

  if (((sym->ns->proc_name != NULL
	&& sym->ns->proc_name->attr.flavor == FL_MODULE
	&& sym->attr.proc != PROC_MODULE)
       || (module_fcn_entry && sym->attr.proc != PROC_MODULE))
      && !gfc_add_procedure (&sym->attr, PROC_MODULE, sym->name, NULL))
    rc = 2;

  return rc;
}


/* Verify that the given symbol representing a parameter is C
   interoperable, by checking to see if it was marked as such after
   its declaration.  If the given symbol is not interoperable, a
   warning is reported, thus removing the need to return the status to
   the calling function.  The standard does not require the user use
   one of the iso_c_binding named constants to declare an
   interoperable parameter, but we can't be sure if the param is C
   interop or not if the user doesn't.  For example, integer(4) may be
   legal Fortran, but doesn't have meaning in C.  It may interop with
   a number of the C types, which causes a problem because the
   compiler can't know which one.  This code is almost certainly not
   portable, and the user will get what they deserve if the C type
   across platforms isn't always interoperable with integer(4).  If
   the user had used something like integer(c_int) or integer(c_long),
   the compiler could have automatically handled the varying sizes
   across platforms.  */

bool
gfc_verify_c_interop_param (gfc_symbol *sym)
{
  int is_c_interop = 0;
  bool retval = true;

  /* We check implicitly typed variables in symbol.cc:gfc_set_default_type().
     Don't repeat the checks here.  */
  if (sym->attr.implicit_type)
    return true;

  /* For subroutines or functions that are passed to a BIND(C) procedure,
     they're interoperable if they're BIND(C) and their params are all
     interoperable.  */
  if (sym->attr.flavor == FL_PROCEDURE)
    {
      if (sym->attr.is_bind_c == 0)
        {
          gfc_error_now ("Procedure %qs at %L must have the BIND(C) "
			 "attribute to be C interoperable", sym->name,
			 &(sym->declared_at));
          return false;
        }
      else
        {
          if (sym->attr.is_c_interop == 1)
            /* We've already checked this procedure; don't check it again.  */
            return true;
          else
            return verify_bind_c_sym (sym, &(sym->ts), sym->attr.in_common,
                                      sym->common_block);
        }
    }

  /* See if we've stored a reference to a procedure that owns sym.  */
  if (sym->ns != NULL && sym->ns->proc_name != NULL)
    {
      if (sym->ns->proc_name->attr.is_bind_c == 1)
	{
	  is_c_interop = (gfc_verify_c_interop(&(sym->ts)) ? 1 : 0);

	  if (is_c_interop != 1)
	    {
	      /* Make personalized messages to give better feedback.  */
	      if (sym->ts.type == BT_DERIVED)
		gfc_error ("Variable %qs at %L is a dummy argument to the "
			   "BIND(C) procedure %qs but is not C interoperable "
			   "because derived type %qs is not C interoperable",
			   sym->name, &(sym->declared_at),
			   sym->ns->proc_name->name,
			   sym->ts.u.derived->name);
	      else if (sym->ts.type == BT_CLASS)
		gfc_error ("Variable %qs at %L is a dummy argument to the "
			   "BIND(C) procedure %qs but is not C interoperable "
			   "because it is polymorphic",
			   sym->name, &(sym->declared_at),
			   sym->ns->proc_name->name);
	      else if (warn_c_binding_type)
		gfc_warning (OPT_Wc_binding_type,
			     "Variable %qs at %L is a dummy argument of the "
			     "BIND(C) procedure %qs but may not be C "
			     "interoperable",
			     sym->name, &(sym->declared_at),
			     sym->ns->proc_name->name);
	    }

	  /* Per F2018, 18.3.6 (5), pointer + contiguous is not permitted.  */
	  if (sym->attr.pointer && sym->attr.contiguous)
	    gfc_error ("Dummy argument %qs at %L may not be a pointer with "
		       "CONTIGUOUS attribute as procedure %qs is BIND(C)",
		       sym->name, &sym->declared_at, sym->ns->proc_name->name);

	  /* Per F2018, C1557, pointer/allocatable dummies to a bind(c)
	     procedure that are default-initialized are not permitted.  */
	  if ((sym->attr.pointer || sym->attr.allocatable)
	      && sym->ts.type == BT_DERIVED
	      && gfc_has_default_initializer (sym->ts.u.derived))
	    {
	      gfc_error ("Default-initialized %s dummy argument %qs "
			 "at %L is not permitted in BIND(C) procedure %qs",
			 (sym->attr.pointer ? "pointer" : "allocatable"),
			 sym->name, &sym->declared_at,
			 sym->ns->proc_name->name);
	      retval = false;
	    }

          /* Character strings are only C interoperable if they have a
	     length of 1.  However, as an argument they are also iteroperable
	     when passed as descriptor (which requires len=: or len=*).  */
	  if (sym->ts.type == BT_CHARACTER)
	    {
	      gfc_charlen *cl = sym->ts.u.cl;

	      if (sym->attr.allocatable || sym->attr.pointer)
		{
		  /* F2018, 18.3.6 (6).  */
		  if (!sym->ts.deferred)
		    {
		      if (sym->attr.allocatable)
			gfc_error ("Allocatable character dummy argument %qs "
				   "at %L must have deferred length as "
				   "procedure %qs is BIND(C)", sym->name,
				   &sym->declared_at, sym->ns->proc_name->name);
		      else
			gfc_error ("Pointer character dummy argument %qs at %L "
				   "must have deferred length as procedure %qs "
				   "is BIND(C)", sym->name, &sym->declared_at,
				   sym->ns->proc_name->name);
		      retval = false;
		    }
		  else if (!gfc_notify_std (GFC_STD_F2018,
					    "Deferred-length character dummy "
					    "argument %qs at %L of procedure "
					    "%qs with BIND(C) attribute",
					    sym->name, &sym->declared_at,
					    sym->ns->proc_name->name))
		    retval = false;
		}
	      else if (sym->attr.value
		       && (!cl || !cl->length
			   || cl->length->expr_type != EXPR_CONSTANT
			   || mpz_cmp_si (cl->length->value.integer, 1) != 0))
		{
		  gfc_error ("Character dummy argument %qs at %L must be "
			     "of length 1 as it has the VALUE attribute",
			     sym->name, &sym->declared_at);
		  retval = false;
		}
	      else if (!cl || !cl->length)
		{
		  /* Assumed length; F2018, 18.3.6 (5)(2).
		     Uses the CFI array descriptor - also for scalars and
		     explicit-size/assumed-size arrays.  */
		  if (!gfc_notify_std (GFC_STD_F2018,
				      "Assumed-length character dummy argument "
				      "%qs at %L of procedure %qs with BIND(C) "
				      "attribute", sym->name, &sym->declared_at,
				      sym->ns->proc_name->name))
		    retval = false;
		}
	      else if (cl->length->expr_type != EXPR_CONSTANT
		       || mpz_cmp_si (cl->length->value.integer, 1) != 0)
		{
		  /* F2018, 18.3.6, (5), item 4.  */
		  if (!sym->attr.dimension
		      || sym->as->type == AS_ASSUMED_SIZE
		      || sym->as->type == AS_EXPLICIT)
		    {
		      gfc_error ("Character dummy argument %qs at %L must be "
				 "of constant length of one or assumed length, "
				 "unless it has assumed shape or assumed rank, "
				 "as procedure %qs has the BIND(C) attribute",
				 sym->name, &sym->declared_at,
				 sym->ns->proc_name->name);
		      retval = false;
		    }
		  /* else: valid only since F2018 - and an assumed-shape/rank
		     array; however, gfc_notify_std is already called when
		     those array types are used. Thus, silently accept F200x. */
		}
	    }

	  /* We have to make sure that any param to a bind(c) routine does
	     not have the allocatable, pointer, or optional attributes,
	     according to J3/04-007, section 5.1.  */
	  if (sym->attr.allocatable == 1
	      && !gfc_notify_std (GFC_STD_F2018, "Variable %qs at %L with "
				  "ALLOCATABLE attribute in procedure %qs "
				  "with BIND(C)", sym->name,
				  &(sym->declared_at),
				  sym->ns->proc_name->name))
	    retval = false;

	  if (sym->attr.pointer == 1
	      && !gfc_notify_std (GFC_STD_F2018, "Variable %qs at %L with "
				  "POINTER attribute in procedure %qs "
				  "with BIND(C)", sym->name,
				  &(sym->declared_at),
				  sym->ns->proc_name->name))
	    retval = false;

	  if (sym->attr.optional == 1 && sym->attr.value)
	    {
	      gfc_error ("Variable %qs at %L cannot have both the OPTIONAL "
			 "and the VALUE attribute because procedure %qs "
			 "is BIND(C)", sym->name, &(sym->declared_at),
			 sym->ns->proc_name->name);
	      retval = false;
	    }
	  else if (sym->attr.optional == 1
		   && !gfc_notify_std (GFC_STD_F2018, "Variable %qs "
				       "at %L with OPTIONAL attribute in "
				       "procedure %qs which is BIND(C)",
				       sym->name, &(sym->declared_at),
				       sym->ns->proc_name->name))
	    retval = false;

          /* Make sure that if it has the dimension attribute, that it is
	     either assumed size or explicit shape. Deferred shape is already
	     covered by the pointer/allocatable attribute.  */
	  if (sym->as != NULL && sym->as->type == AS_ASSUMED_SHAPE
	      && !gfc_notify_std (GFC_STD_F2018, "Assumed-shape array %qs "
				  "at %L as dummy argument to the BIND(C) "
				  "procedure %qs at %L", sym->name,
				  &(sym->declared_at),
				  sym->ns->proc_name->name,
				  &(sym->ns->proc_name->declared_at)))
	    retval = false;
	}
    }

  return retval;
}



/* Function called by variable_decl() that adds a name to the symbol table.  */

static bool
build_sym (const char *name, gfc_charlen *cl, bool cl_deferred,
	   gfc_array_spec **as, locus *var_locus)
{
  symbol_attribute attr;
  gfc_symbol *sym;
  int upper;
  gfc_symtree *st;

  /* Symbols in a submodule are host associated from the parent module or
     submodules. Therefore, they can be overridden by declarations in the
     submodule scope. Deal with this by attaching the existing symbol to
     a new symtree and recycling the old symtree with a new symbol...  */
  st = gfc_find_symtree (gfc_current_ns->sym_root, name);
  if (st != NULL && gfc_state_stack->state == COMP_SUBMODULE
      && st->n.sym != NULL
      && st->n.sym->attr.host_assoc && st->n.sym->attr.used_in_submodule)
    {
      gfc_symtree *s = gfc_get_unique_symtree (gfc_current_ns);
      s->n.sym = st->n.sym;
      sym = gfc_new_symbol (name, gfc_current_ns);


      st->n.sym = sym;
      sym->refs++;
      gfc_set_sym_referenced (sym);
    }
  /* ...Otherwise generate a new symtree and new symbol.  */
  else if (gfc_get_symbol (name, NULL, &sym))
    return false;

  /* Check if the name has already been defined as a type.  The
     first letter of the symtree will be in upper case then.  Of
     course, this is only necessary if the upper case letter is
     actually different.  */

  upper = TOUPPER(name[0]);
  if (upper != name[0])
    {
      char u_name[GFC_MAX_SYMBOL_LEN + 1];
      gfc_symtree *st;

      gcc_assert (strlen(name) <= GFC_MAX_SYMBOL_LEN);
      strcpy (u_name, name);
      u_name[0] = upper;

      st = gfc_find_symtree (gfc_current_ns->sym_root, u_name);

      /* STRUCTURE types can alias symbol names */
      if (st != 0 && st->n.sym->attr.flavor != FL_STRUCT)
	{
	  gfc_error ("Symbol %qs at %C also declared as a type at %L", name,
		     &st->n.sym->declared_at);
	  return false;
	}
    }

  /* Start updating the symbol table.  Add basic type attribute if present.  */
  if (current_ts.type != BT_UNKNOWN
      && (sym->attr.implicit_type == 0
	  || !gfc_compare_types (&sym->ts, &current_ts))
      && !gfc_add_type (sym, &current_ts, var_locus))
    return false;

  if (sym->ts.type == BT_CHARACTER)
    {
      sym->ts.u.cl = cl;
      sym->ts.deferred = cl_deferred;
    }

  /* Add dimension attribute if present.  */
  if (!gfc_set_array_spec (sym, *as, var_locus))
    return false;
  *as = NULL;

  /* Add attribute to symbol.  The copy is so that we can reset the
     dimension attribute.  */
  attr = current_attr;
  attr.dimension = 0;
  attr.codimension = 0;

  if (!gfc_copy_attr (&sym->attr, &attr, var_locus))
    return false;

  /* Finish any work that may need to be done for the binding label,
     if it's a bind(c).  The bind(c) attr is found before the symbol
     is made, and before the symbol name (for data decls), so the
     current_ts is holding the binding label, or nothing if the
     name= attr wasn't given.  Therefore, test here if we're dealing
     with a bind(c) and make sure the binding label is set correctly.  */
  if (sym->attr.is_bind_c == 1)
    {
      if (!sym->binding_label)
        {
	  /* Set the binding label and verify that if a NAME= was specified
	     then only one identifier was in the entity-decl-list.  */
	  if (!set_binding_label (&sym->binding_label, sym->name,
				  num_idents_on_line))
            return false;
        }
    }

  /* See if we know we're in a common block, and if it's a bind(c)
     common then we need to make sure we're an interoperable type.  */
  if (sym->attr.in_common == 1)
    {
      /* Test the common block object.  */
      if (sym->common_block != NULL && sym->common_block->is_bind_c == 1
          && sym->ts.is_c_interop != 1)
        {
          gfc_error_now ("Variable %qs in common block %qs at %C "
                         "must be declared with a C interoperable "
                         "kind since common block %qs is BIND(C)",
                         sym->name, sym->common_block->name,
                         sym->common_block->name);
          gfc_clear_error ();
        }
    }

  sym->attr.implied_index = 0;

  /* Use the parameter expressions for a parameterized derived type.  */
  if ((sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS)
      && sym->ts.u.derived->attr.pdt_type && type_param_spec_list)
    sym->param_list = gfc_copy_actual_arglist (type_param_spec_list);

  if (sym->ts.type == BT_CLASS)
    return gfc_build_class_symbol (&sym->ts, &sym->attr, &sym->as);

  return true;
}


/* Set character constant to the given length. The constant will be padded or
   truncated.  If we're inside an array constructor without a typespec, we
   additionally check that all elements have the same length; check_len -1
   means no checking.  */

void
gfc_set_constant_character_len (gfc_charlen_t len, gfc_expr *expr,
				gfc_charlen_t check_len)
{
  gfc_char_t *s;
  gfc_charlen_t slen;

  if (expr->ts.type != BT_CHARACTER)
    return;

  if (expr->expr_type != EXPR_CONSTANT)
    {
      gfc_error_now ("CHARACTER length must be a constant at %L", &expr->where);
      return;
    }

  slen = expr->value.character.length;
  if (len != slen)
    {
      s = gfc_get_wide_string (len + 1);
      memcpy (s, expr->value.character.string,
	      MIN (len, slen) * sizeof (gfc_char_t));
      if (len > slen)
	gfc_wide_memset (&s[slen], ' ', len - slen);

      if (warn_character_truncation && slen > len)
	gfc_warning_now (OPT_Wcharacter_truncation,
			 "CHARACTER expression at %L is being truncated "
			 "(%ld/%ld)", &expr->where,
			 (long) slen, (long) len);

      /* Apply the standard by 'hand' otherwise it gets cleared for
	 initializers.  */
      if (check_len != -1 && slen != check_len
          && !(gfc_option.allow_std & GFC_STD_GNU))
	gfc_error_now ("The CHARACTER elements of the array constructor "
		       "at %L must have the same length (%ld/%ld)",
		       &expr->where, (long) slen,
		       (long) check_len);

      s[len] = '\0';
      free (expr->value.character.string);
      expr->value.character.string = s;
      expr->value.character.length = len;
      /* If explicit representation was given, clear it
	 as it is no longer needed after padding.  */
      if (expr->representation.length)
	{
	  expr->representation.length = 0;
	  free (expr->representation.string);
	  expr->representation.string = NULL;
	}
    }
}


/* Function to create and update the enumerator history
   using the information passed as arguments.
   Pointer "max_enum" is also updated, to point to
   enum history node containing largest initializer.

   SYM points to the symbol node of enumerator.
   INIT points to its enumerator value.  */

static void
create_enum_history (gfc_symbol *sym, gfc_expr *init)
{
  enumerator_history *new_enum_history;
  gcc_assert (sym != NULL && init != NULL);

  new_enum_history = XCNEW (enumerator_history);

  new_enum_history->sym = sym;
  new_enum_history->initializer = init;
  new_enum_history->next = NULL;

  if (enum_history == NULL)
    {
      enum_history = new_enum_history;
      max_enum = enum_history;
    }
  else
    {
      new_enum_history->next = enum_history;
      enum_history = new_enum_history;

      if (mpz_cmp (max_enum->initializer->value.integer,
		   new_enum_history->initializer->value.integer) < 0)
	max_enum = new_enum_history;
    }
}


/* Function to free enum kind history.  */

void
gfc_free_enum_history (void)
{
  enumerator_history *current = enum_history;
  enumerator_history *next;

  while (current != NULL)
    {
      next = current->next;
      free (current);
      current = next;
    }
  max_enum = NULL;
  enum_history = NULL;
}


/* Function called by variable_decl() that adds an initialization
   expression to a symbol.  */

static bool
add_init_expr_to_sym (const char *name, gfc_expr **initp, locus *var_locus)
{
  symbol_attribute attr;
  gfc_symbol *sym;
  gfc_expr *init;

  init = *initp;
  if (find_special (name, &sym, false))
    return false;

  attr = sym->attr;

  /* If this symbol is confirming an implicit parameter type,
     then an initialization expression is not allowed.  */
  if (attr.flavor == FL_PARAMETER && sym->value != NULL)
    {
      if (*initp != NULL)
	{
	  gfc_error ("Initializer not allowed for PARAMETER %qs at %C",
		     sym->name);
	  return false;
	}
      else
	return true;
    }

  if (init == NULL)
    {
      /* An initializer is required for PARAMETER declarations.  */
      if (attr.flavor == FL_PARAMETER)
	{
	  gfc_error ("PARAMETER at %L is missing an initializer", var_locus);
	  return false;
	}
    }
  else
    {
      /* If a variable appears in a DATA block, it cannot have an
	 initializer.  */
      if (sym->attr.data)
	{
	  gfc_error ("Variable %qs at %C with an initializer already "
		     "appears in a DATA statement", sym->name);
	  return false;
	}

      /* Check if the assignment can happen. This has to be put off
	 until later for derived type variables and procedure pointers.  */
      if (!gfc_bt_struct (sym->ts.type) && !gfc_bt_struct (init->ts.type)
	  && sym->ts.type != BT_CLASS && init->ts.type != BT_CLASS
	  && !sym->attr.proc_pointer
	  && !gfc_check_assign_symbol (sym, NULL, init))
	return false;

      if (sym->ts.type == BT_CHARACTER && sym->ts.u.cl
	    && init->ts.type == BT_CHARACTER)
	{
	  /* Update symbol character length according initializer.  */
	  if (!gfc_check_assign_symbol (sym, NULL, init))
	    return false;

	  if (sym->ts.u.cl->length == NULL)
	    {
	      gfc_charlen_t clen;
	      /* If there are multiple CHARACTER variables declared on the
		 same line, we don't want them to share the same length.  */
	      sym->ts.u.cl = gfc_new_charlen (gfc_current_ns, NULL);

	      if (sym->attr.flavor == FL_PARAMETER)
		{
		  if (init->expr_type == EXPR_CONSTANT)
		    {
		      clen = init->value.character.length;
		      sym->ts.u.cl->length
				= gfc_get_int_expr (gfc_charlen_int_kind,
						    NULL, clen);
		    }
		  else if (init->expr_type == EXPR_ARRAY)
		    {
		      if (init->ts.u.cl && init->ts.u.cl->length)
			{
			  const gfc_expr *length = init->ts.u.cl->length;
			  if (length->expr_type != EXPR_CONSTANT)
			    {
			      gfc_error ("Cannot initialize parameter array "
					 "at %L "
					 "with variable length elements",
					 &sym->declared_at);
			      return false;
			    }
			  clen = mpz_get_si (length->value.integer);
			}
		      else if (init->value.constructor)
			{
			  gfc_constructor *c;
	                  c = gfc_constructor_first (init->value.constructor);
	                  clen = c->expr->value.character.length;
			}
		      else
			  gcc_unreachable ();
		      sym->ts.u.cl->length
				= gfc_get_int_expr (gfc_charlen_int_kind,
						    NULL, clen);
		    }
		  else if (init->ts.u.cl && init->ts.u.cl->length)
		    sym->ts.u.cl->length =
				gfc_copy_expr (init->ts.u.cl->length);
		}
	    }
	  /* Update initializer character length according symbol.  */
	  else if (sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
	    {
	      if (!gfc_specification_expr (sym->ts.u.cl->length))
		return false;

	      int k = gfc_validate_kind (BT_INTEGER, gfc_charlen_int_kind,
					 false);
	      /* resolve_charlen will complain later on if the length
		 is too large.  Just skeep the initialization in that case.  */
	      if (mpz_cmp (sym->ts.u.cl->length->value.integer,
			   gfc_integer_kinds[k].huge) <= 0)
		{
		  HOST_WIDE_INT len
		    = gfc_mpz_get_hwi (sym->ts.u.cl->length->value.integer);

		  if (init->expr_type == EXPR_CONSTANT)
		    gfc_set_constant_character_len (len, init, -1);
		  else if (init->expr_type == EXPR_ARRAY)
		    {
		      gfc_constructor *c;

		      /* Build a new charlen to prevent simplification from
			 deleting the length before it is resolved.  */
		      init->ts.u.cl = gfc_new_charlen (gfc_current_ns, NULL);
		      init->ts.u.cl->length
			= gfc_copy_expr (sym->ts.u.cl->length);

		      for (c = gfc_constructor_first (init->value.constructor);
			   c; c = gfc_constructor_next (c))
			gfc_set_constant_character_len (len, c->expr, -1);
		    }
		}
	    }
	}

      if (sym->attr.flavor == FL_PARAMETER && sym->attr.dimension && sym->as
	  && sym->as->rank && init->rank && init->rank != sym->as->rank)
	{
	  gfc_error ("Rank mismatch of array at %L and its initializer "
		     "(%d/%d)", &sym->declared_at, sym->as->rank, init->rank);
	  return false;
	}

      /* If sym is implied-shape, set its upper bounds from init.  */
      if (sym->attr.flavor == FL_PARAMETER && sym->attr.dimension
	  && sym->as->type == AS_IMPLIED_SHAPE)
	{
	  int dim;

	  if (init->rank == 0)
	    {
	      gfc_error ("Cannot initialize implied-shape array at %L"
			 " with scalar", &sym->declared_at);
	      return false;
	    }

	  /* The shape may be NULL for EXPR_ARRAY, set it.  */
	  if (init->shape == NULL)
	    {
	      if (init->expr_type != EXPR_ARRAY)
		{
		  gfc_error ("Bad shape of initializer at %L", &init->where);
		  return false;
		}

	      init->shape = gfc_get_shape (1);
	      if (!gfc_array_size (init, &init->shape[0]))
		{
		  gfc_error ("Cannot determine shape of initializer at %L",
			     &init->where);
		  free (init->shape);
		  init->shape = NULL;
		  return false;
		}
	    }

	  for (dim = 0; dim < sym->as->rank; ++dim)
	    {
	      int k;
	      gfc_expr *e, *lower;

	      lower = sym->as->lower[dim];

	      /* If the lower bound is an array element from another
		 parameterized array, then it is marked with EXPR_VARIABLE and
		 is an initialization expression.  Try to reduce it.  */
	      if (lower->expr_type == EXPR_VARIABLE)
		gfc_reduce_init_expr (lower);

	      if (lower->expr_type == EXPR_CONSTANT)
		{
		  /* All dimensions must be without upper bound.  */
		  gcc_assert (!sym->as->upper[dim]);

		  k = lower->ts.kind;
		  e = gfc_get_constant_expr (BT_INTEGER, k, &sym->declared_at);
		  mpz_add (e->value.integer, lower->value.integer,
			   init->shape[dim]);
		  mpz_sub_ui (e->value.integer, e->value.integer, 1);
		  sym->as->upper[dim] = e;
		}
	      else
		{
		  gfc_error ("Non-constant lower bound in implied-shape"
			     " declaration at %L", &lower->where);
		  return false;
		}
	    }

	  sym->as->type = AS_EXPLICIT;
	}

      /* Ensure that explicit bounds are simplified.  */
      if (sym->attr.flavor == FL_PARAMETER && sym->attr.dimension
	  && sym->as->type == AS_EXPLICIT)
	{
	  for (int dim = 0; dim < sym->as->rank; ++dim)
	    {
	      gfc_expr *e;

	      e = sym->as->lower[dim];
	      if (e->expr_type != EXPR_CONSTANT)
		gfc_reduce_init_expr (e);

	      e = sym->as->upper[dim];
	      if (e->expr_type != EXPR_CONSTANT)
		gfc_reduce_init_expr (e);
	    }
	}

      /* Need to check if the expression we initialized this
	 to was one of the iso_c_binding named constants.  If so,
	 and we're a parameter (constant), let it be iso_c.
	 For example:
	 integer(c_int), parameter :: my_int = c_int
	 integer(my_int) :: my_int_2
	 If we mark my_int as iso_c (since we can see it's value
	 is equal to one of the named constants), then my_int_2
	 will be considered C interoperable.  */
      if (sym->ts.type != BT_CHARACTER && !gfc_bt_struct (sym->ts.type))
	{
	  sym->ts.is_iso_c |= init->ts.is_iso_c;
	  sym->ts.is_c_interop |= init->ts.is_c_interop;
	  /* attr bits needed for module files.  */
	  sym->attr.is_iso_c |= init->ts.is_iso_c;
	  sym->attr.is_c_interop |= init->ts.is_c_interop;
	  if (init->ts.is_iso_c)
	    sym->ts.f90_type = init->ts.f90_type;
	}

      /* Add initializer.  Make sure we keep the ranks sane.  */
      if (sym->attr.dimension && init->rank == 0)
	{
	  mpz_t size;
	  gfc_expr *array;
	  int n;
	  if (sym->attr.flavor == FL_PARAMETER
	      && gfc_is_constant_expr (init)
	      && (init->expr_type == EXPR_CONSTANT
		  || init->expr_type == EXPR_STRUCTURE)
	      && spec_size (sym->as, &size)
	      && mpz_cmp_si (size, 0) > 0)
	    {
	      array = gfc_get_array_expr (init->ts.type, init->ts.kind,
					  &init->where);
	      if (init->ts.type == BT_DERIVED)
		array->ts.u.derived = init->ts.u.derived;
	      for (n = 0; n < (int)mpz_get_si (size); n++)
		gfc_constructor_append_expr (&array->value.constructor,
					     n == 0
						? init
						: gfc_copy_expr (init),
					     &init->where);

	      array->shape = gfc_get_shape (sym->as->rank);
	      for (n = 0; n < sym->as->rank; n++)
		spec_dimen_size (sym->as, n, &array->shape[n]);

	      init = array;
	      mpz_clear (size);
	    }
	  init->rank = sym->as->rank;
	}

      sym->value = init;
      if (sym->attr.save == SAVE_NONE)
	sym->attr.save = SAVE_IMPLICIT;
      *initp = NULL;
    }

  return true;
}


/* Function called by variable_decl() that adds a name to a structure
   being built.  */

static bool
build_struct (const char *name, gfc_charlen *cl, gfc_expr **init,
	      gfc_array_spec **as)
{
  gfc_state_data *s;
  gfc_component *c;

  /* F03:C438/C439. If the current symbol is of the same derived type that we're
     constructing, it must have the pointer attribute.  */
  if ((current_ts.type == BT_DERIVED || current_ts.type == BT_CLASS)
      && current_ts.u.derived == gfc_current_block ()
      && current_attr.pointer == 0)
    {
      if (current_attr.allocatable
	  && !gfc_notify_std(GFC_STD_F2008, "Component at %C "
			     "must have the POINTER attribute"))
	{
	  return false;
	}
      else if (current_attr.allocatable == 0)
	{
	  gfc_error ("Component at %C must have the POINTER attribute");
	  return false;
	}
    }

  /* F03:C437.  */
  if (current_ts.type == BT_CLASS
      && !(current_attr.pointer || current_attr.allocatable))
    {
      gfc_error ("Component %qs with CLASS at %C must be allocatable "
                 "or pointer", name);
      return false;
    }

  if (gfc_current_block ()->attr.pointer && (*as)->rank != 0)
    {
      if ((*as)->type != AS_DEFERRED && (*as)->type != AS_EXPLICIT)
	{
	  gfc_error ("Array component of structure at %C must have explicit "
		     "or deferred shape");
	  return false;
	}
    }

  /* If we are in a nested union/map definition, gfc_add_component will not
     properly find repeated components because:
       (i) gfc_add_component does a flat search, where components of unions
           and maps are implicity chained so nested components may conflict.
      (ii) Unions and maps are not linked as components of their parent
           structures until after they are parsed.
     For (i) we use gfc_find_component which searches recursively, and for (ii)
     we search each block directly from the parse stack until we find the top
     level structure.  */

  s = gfc_state_stack;
  if (s->state == COMP_UNION || s->state == COMP_MAP)
    {
      while (s->state == COMP_UNION || gfc_comp_struct (s->state))
        {
          c = gfc_find_component (s->sym, name, true, true, NULL);
          if (c != NULL)
            {
              gfc_error_now ("Component %qs at %C already declared at %L",
                             name, &c->loc);
              return false;
            }
          /* Break after we've searched the entire chain.  */
          if (s->state == COMP_DERIVED || s->state == COMP_STRUCTURE)
            break;
          s = s->previous;
        }
    }

  if (!gfc_add_component (gfc_current_block(), name, &c))
    return false;

  c->ts = current_ts;
  if (c->ts.type == BT_CHARACTER)
    c->ts.u.cl = cl;

  if (c->ts.type != BT_CLASS && c->ts.type != BT_DERIVED
      && (c->ts.kind == 0 || c->ts.type == BT_CHARACTER)
      && saved_kind_expr != NULL)
    c->kind_expr = gfc_copy_expr (saved_kind_expr);

  c->attr = current_attr;

  c->initializer = *init;
  *init = NULL;

  c->as = *as;
  if (c->as != NULL)
    {
      if (c->as->corank)
	c->attr.codimension = 1;
      if (c->as->rank)
	c->attr.dimension = 1;
    }
  *as = NULL;

  gfc_apply_init (&c->ts, &c->attr, c->initializer);

  /* Check array components.  */
  if (!c->attr.dimension)
    goto scalar;

  if (c->attr.pointer)
    {
      if (c->as->type != AS_DEFERRED)
	{
	  gfc_error ("Pointer array component of structure at %C must have a "
		     "deferred shape");
	  return false;
	}
    }
  else if (c->attr.allocatable)
    {
      if (c->as->type != AS_DEFERRED)
	{
	  gfc_error ("Allocatable component of structure at %C must have a "
		     "deferred shape");
	  return false;
	}
    }
  else
    {
      if (c->as->type != AS_EXPLICIT)
	{
	  gfc_error ("Array component of structure at %C must have an "
		     "explicit shape");
	  return false;
	}
    }

scalar:
  if (c->ts.type == BT_CLASS)
    return gfc_build_class_symbol (&c->ts, &c->attr, &c->as);

  if (c->attr.pdt_kind || c->attr.pdt_len)
    {
      gfc_symbol *sym;
      gfc_find_symbol (c->name, gfc_current_block ()->f2k_derived,
		       0, &sym);
      if (sym == NULL)
	{
	  gfc_error ("Type parameter %qs at %C has no corresponding entry "
		     "in the type parameter name list at %L",
		     c->name, &gfc_current_block ()->declared_at);
	  return false;
	}
      sym->ts = c->ts;
      sym->attr.pdt_kind = c->attr.pdt_kind;
      sym->attr.pdt_len = c->attr.pdt_len;
      if (c->initializer)
	sym->value = gfc_copy_expr (c->initializer);
      sym->attr.flavor = FL_VARIABLE;
    }

  if ((c->ts.type == BT_DERIVED || c->ts.type == BT_CLASS)
      && c->ts.u.derived && c->ts.u.derived->attr.pdt_template
      && decl_type_param_list)
    c->param_list = gfc_copy_actual_arglist (decl_type_param_list);

  return true;
}


/* Match a 'NULL()', and possibly take care of some side effects.  */

match
gfc_match_null (gfc_expr **result)
{
  gfc_symbol *sym;
  match m, m2 = MATCH_NO;

  if ((m = gfc_match (" null ( )")) == MATCH_ERROR)
    return MATCH_ERROR;

  if (m == MATCH_NO)
    {
      locus old_loc;
      char name[GFC_MAX_SYMBOL_LEN + 1];

      if ((m2 = gfc_match (" null (")) != MATCH_YES)
	return m2;

      old_loc = gfc_current_locus;
      if ((m2 = gfc_match (" %n ) ", name)) == MATCH_ERROR)
	return MATCH_ERROR;
      if (m2 != MATCH_YES
	  && ((m2 = gfc_match (" mold = %n )", name)) == MATCH_ERROR))
	return MATCH_ERROR;
      if (m2 == MATCH_NO)
	{
	  gfc_current_locus = old_loc;
	  return MATCH_NO;
	}
    }

  /* The NULL symbol now has to be/become an intrinsic function.  */
  if (gfc_get_symbol ("null", NULL, &sym))
    {
      gfc_error ("NULL() initialization at %C is ambiguous");
      return MATCH_ERROR;
    }

  gfc_intrinsic_symbol (sym);

  if (sym->attr.proc != PROC_INTRINSIC
      && !(sym->attr.use_assoc && sym->attr.intrinsic)
      && (!gfc_add_procedure(&sym->attr, PROC_INTRINSIC, sym->name, NULL)
	  || !gfc_add_function (&sym->attr, sym->name, NULL)))
    return MATCH_ERROR;

  *result = gfc_get_null_expr (&gfc_current_locus);

  /* Invalid per F2008, C512.  */
  if (m2 == MATCH_YES)
    {
      gfc_error ("NULL() initialization at %C may not have MOLD");
      return MATCH_ERROR;
    }

  return MATCH_YES;
}


/* Match the initialization expr for a data pointer or procedure pointer.  */

static match
match_pointer_init (gfc_expr **init, int procptr)
{
  match m;

  if (gfc_pure (NULL) && !gfc_comp_struct (gfc_state_stack->state))
    {
      gfc_error ("Initialization of pointer at %C is not allowed in "
		 "a PURE procedure");
      return MATCH_ERROR;
    }
  gfc_unset_implicit_pure (gfc_current_ns->proc_name);

  /* Match NULL() initialization.  */
  m = gfc_match_null (init);
  if (m != MATCH_NO)
    return m;

  /* Match non-NULL initialization.  */
  gfc_matching_ptr_assignment = !procptr;
  gfc_matching_procptr_assignment = procptr;
  m = gfc_match_rvalue (init);
  gfc_matching_ptr_assignment = 0;
  gfc_matching_procptr_assignment = 0;
  if (m == MATCH_ERROR)
    return MATCH_ERROR;
  else if (m == MATCH_NO)
    {
      gfc_error ("Error in pointer initialization at %C");
      return MATCH_ERROR;
    }

  if (!procptr && !gfc_resolve_expr (*init))
    return MATCH_ERROR;

  if (!gfc_notify_std (GFC_STD_F2008, "non-NULL pointer "
		       "initialization at %C"))
    return MATCH_ERROR;

  return MATCH_YES;
}


static bool
check_function_name (char *name)
{
  /* In functions that have a RESULT variable defined, the function name always
     refers to function calls.  Therefore, the name is not allowed to appear in
     specification statements. When checking this, be careful about
     'hidden' procedure pointer results ('ppr@').  */

  if (gfc_current_state () == COMP_FUNCTION)
    {
      gfc_symbol *block = gfc_current_block ();
      if (block && block->result && block->result != block
	  && strcmp (block->result->name, "ppr@") != 0
	  && strcmp (block->name, name) == 0)
	{
	  gfc_error ("RESULT variable %qs at %L prohibits FUNCTION name %qs at %C "
		     "from appearing in a specification statement",
		     block->result->name, &block->result->declared_at, name);
	  return false;
	}
    }

  return true;
}


/* Match a variable name with an optional initializer.  When this
   subroutine is called, a variable is expected to be parsed next.
   Depending on what is happening at the moment, updates either the
   symbol table or the current interface.  */

static match
variable_decl (int elem)
{
  char name[GFC_MAX_SYMBOL_LEN + 1];
  static unsigned int fill_id = 0;
  gfc_expr *initializer, *char_len;
  gfc_array_spec *as;
  gfc_array_spec *cp_as; /* Extra copy for Cray Pointees.  */
  gfc_charlen *cl;
  bool cl_deferred;
  locus var_locus;
  match m;
  bool t;
  gfc_symbol *sym;
  char c;

  initializer = NULL;
  as = NULL;
  cp_as = NULL;

  /* When we get here, we've just matched a list of attributes and
     maybe a type and a double colon.  The next thing we expect to see
     is the name of the symbol.  */

  /* If we are parsing a structure with legacy support, we allow the symbol
     name to be '%FILL' which gives it an anonymous (inaccessible) name.  */
  m = MATCH_NO;
  gfc_gobble_whitespace ();
  c = gfc_peek_ascii_char ();
  if (c == '%')
    {
      gfc_next_ascii_char ();	/* Burn % character.  */
      m = gfc_match ("fill");
      if (m == MATCH_YES)
	{
	  if (gfc_current_state () != COMP_STRUCTURE)
	    {
	      if (flag_dec_structure)
		gfc_error ("%qs not allowed outside STRUCTURE at %C", "%FILL");
	      else
		gfc_error ("%qs at %C is a DEC extension, enable with "
		       "%<-fdec-structure%>", "%FILL");
	      m = MATCH_ERROR;
	      goto cleanup;
	    }

	  if (attr_seen)
	    {
	      gfc_error ("%qs entity cannot have attributes at %C", "%FILL");
	      m = MATCH_ERROR;
	      goto cleanup;
	    }

	  /* %FILL components are given invalid fortran names.  */
	  snprintf (name, GFC_MAX_SYMBOL_LEN + 1, "%%FILL%u", fill_id++);
	}
      else
	{
	  gfc_error ("Invalid character %qc in variable name at %C", c);
	  return MATCH_ERROR;
	}
    }
  else
    {
      m = gfc_match_name (name);
      if (m != MATCH_YES)
	goto cleanup;
    }

  var_locus = gfc_current_locus;

  /* Now we could see the optional array spec. or character length.  */
  m = gfc_match_array_spec (&as, true, true);
  if (m == MATCH_ERROR)
    goto cleanup;

  if (m == MATCH_NO)
    as = gfc_copy_array_spec (current_as);
  else if (current_as
	   && !merge_array_spec (current_as, as, true))
    {
      m = MATCH_ERROR;
      goto cleanup;
    }

  if (flag_cray_pointer)
    cp_as = gfc_copy_array_spec (as);

  /* At this point, we know for sure if the symbol is PARAMETER and can thus
     determine (and check) whether it can be implied-shape.  If it
     was parsed as assumed-size, change it because PARAMETERs cannot
     be assumed-size.

     An explicit-shape-array cannot appear under several conditions.
     That check is done here as well.  */
  if (as)
    {
      if (as->type == AS_IMPLIED_SHAPE && current_attr.flavor != FL_PARAMETER)
	{
	  m = MATCH_ERROR;
	  gfc_error ("Non-PARAMETER symbol %qs at %L cannot be implied-shape",
		     name, &var_locus);
	  goto cleanup;
	}

      if (as->type == AS_ASSUMED_SIZE && as->rank == 1
	  && current_attr.flavor == FL_PARAMETER)
	as->type = AS_IMPLIED_SHAPE;

      if (as->type == AS_IMPLIED_SHAPE
	  && !gfc_notify_std (GFC_STD_F2008, "Implied-shape array at %L",
			      &var_locus))
	{
	  m = MATCH_ERROR;
	  goto cleanup;
	}

      gfc_seen_div0 = false;
      
      /* F2018:C830 (R816) An explicit-shape-spec whose bounds are not
	 constant expressions shall appear only in a subprogram, derived
	 type definition, BLOCK construct, or interface body.  */
      if (as->type == AS_EXPLICIT
	  && gfc_current_state () != COMP_BLOCK
	  && gfc_current_state () != COMP_DERIVED
	  && gfc_current_state () != COMP_FUNCTION
	  && gfc_current_state () != COMP_INTERFACE
	  && gfc_current_state () != COMP_SUBROUTINE)
	{
	  gfc_expr *e;
	  bool not_constant = false;

	  for (int i = 0; i < as->rank; i++)
	    {
	      e = gfc_copy_expr (as->lower[i]);
	      if (!gfc_resolve_expr (e) && gfc_seen_div0)
		{
		  m = MATCH_ERROR;
		  goto cleanup;
		}

	      gfc_simplify_expr (e, 0);
	      if (e && (e->expr_type != EXPR_CONSTANT))
		{
		  not_constant = true;
		  break;
		}
	      gfc_free_expr (e);

	      e = gfc_copy_expr (as->upper[i]);
	      if (!gfc_resolve_expr (e)  && gfc_seen_div0)
		{
		  m = MATCH_ERROR;
		  goto cleanup;
		}

	      gfc_simplify_expr (e, 0);
	      if (e && (e->expr_type != EXPR_CONSTANT))
		{
		  not_constant = true;
		  break;
		}
	      gfc_free_expr (e);
	    }

	  if (not_constant && e->ts.type != BT_INTEGER)
	    {
	      gfc_error ("Explicit array shape at %C must be constant of "
			 "INTEGER type and not %s type",
			 gfc_basic_typename (e->ts.type));
	      m = MATCH_ERROR;
	      goto cleanup;
	    }
	  if (not_constant)
	    {
	      gfc_error ("Explicit shaped array with nonconstant bounds at %C");
	      m = MATCH_ERROR;
	      goto cleanup;
	    }
	}
      if (as->type == AS_EXPLICIT)
	{
	  for (int i = 0; i < as->rank; i++)
	    {
	      gfc_expr *e, *n;
	      e = as->lower[i];
	      if (e->expr_type != EXPR_CONSTANT)
		{
		  n = gfc_copy_expr (e);
		  if (!gfc_simplify_expr (n, 1)  && gfc_seen_div0) 
		    {
		      m = MATCH_ERROR;
		      goto cleanup;
		    }

		  if (n->expr_type == EXPR_CONSTANT)
		    gfc_replace_expr (e, n);
		  else
		    gfc_free_expr (n);
		}
	      e = as->upper[i];
	      if (e->expr_type != EXPR_CONSTANT)
		{
		  n = gfc_copy_expr (e);
		  if (!gfc_simplify_expr (n, 1)  && gfc_seen_div0) 
		    {
		      m = MATCH_ERROR;
		      goto cleanup;
		    }
		  
		  if (n->expr_type == EXPR_CONSTANT)
		    gfc_replace_expr (e, n);
		  else
		    gfc_free_expr (n);
		}
	      /* For an explicit-shape spec with constant bounds, ensure
		 that the effective upper bound is not lower than the
		 respective lower bound minus one.  Otherwise adjust it so
		 that the extent is trivially derived to be zero.  */
	      if (as->lower[i]->expr_type == EXPR_CONSTANT
		  && as->upper[i]->expr_type == EXPR_CONSTANT
		  && as->lower[i]->ts.type == BT_INTEGER
		  && as->upper[i]->ts.type == BT_INTEGER
		  && mpz_cmp (as->upper[i]->value.integer,
			      as->lower[i]->value.integer) < 0)
		mpz_sub_ui (as->upper[i]->value.integer,
			    as->lower[i]->value.integer, 1);
	    }
	}
    }

  char_len = NULL;
  cl = NULL;
  cl_deferred = false;

  if (current_ts.type == BT_CHARACTER)
    {
      switch (match_char_length (&char_len, &cl_deferred, false))
	{
	case MATCH_YES:
	  cl = gfc_new_charlen (gfc_current_ns, NULL);

	  cl->length = char_len;
	  break;

	/* Non-constant lengths need to be copied after the first
	   element.  Also copy assumed lengths.  */
	case MATCH_NO:
	  if (elem > 1
	      && (current_ts.u.cl->length == NULL
		  || current_ts.u.cl->length->expr_type != EXPR_CONSTANT))
	    {
	      cl = gfc_new_charlen (gfc_current_ns, NULL);
	      cl->length = gfc_copy_expr (current_ts.u.cl->length);
	    }
	  else
	    cl = current_ts.u.cl;

	  cl_deferred = current_ts.deferred;

	  break;

	case MATCH_ERROR:
	  goto cleanup;
	}
    }

  /* The dummy arguments and result of the abreviated form of MODULE
     PROCEDUREs, used in SUBMODULES should not be redefined.  */
  if (gfc_current_ns->proc_name
      && gfc_current_ns->proc_name->abr_modproc_decl)
    {
      gfc_find_symbol (name, gfc_current_ns, 1, &sym);
      if (sym != NULL && (sym->attr.dummy || sym->attr.result))
	{
	  m = MATCH_ERROR;
	  gfc_error ("%qs at %C is a redefinition of the declaration "
		     "in the corresponding interface for MODULE "
		     "PROCEDURE %qs", sym->name,
		     gfc_current_ns->proc_name->name);
	  goto cleanup;
	}
    }

  /* %FILL components may not have initializers.  */
  if (startswith (name, "%FILL") && gfc_match_eos () != MATCH_YES)
    {
      gfc_error ("%qs entity cannot have an initializer at %C", "%FILL");
      m = MATCH_ERROR;
      goto cleanup;
    }

  /*  If this symbol has already shown up in a Cray Pointer declaration,
      and this is not a component declaration,
      then we want to set the type & bail out.  */
  if (flag_cray_pointer && !gfc_comp_struct (gfc_current_state ()))
    {
      gfc_find_symbol (name, gfc_current_ns, 0, &sym);
      if (sym != NULL && sym->attr.cray_pointee)
	{
	  m = MATCH_YES;
	  if (!gfc_add_type (sym, &current_ts, &gfc_current_locus))
	    {
	      m = MATCH_ERROR;
	      goto cleanup;
	    }

	  /* Check to see if we have an array specification.  */
	  if (cp_as != NULL)
	    {
	      if (sym->as != NULL)
		{
		  gfc_error ("Duplicate array spec for Cray pointee at %C");
		  gfc_free_array_spec (cp_as);
		  m = MATCH_ERROR;
		  goto cleanup;
		}
	      else
		{
		  if (!gfc_set_array_spec (sym, cp_as, &var_locus))
		    gfc_internal_error ("Cannot set pointee array spec.");

		  /* Fix the array spec.  */
		  m = gfc_mod_pointee_as (sym->as);
		  if (m == MATCH_ERROR)
		    goto cleanup;
		}
	    }
	  goto cleanup;
	}
      else
	{
	  gfc_free_array_spec (cp_as);
	}
    }

  /* Procedure pointer as function result.  */
  if (gfc_current_state () == COMP_FUNCTION
      && strcmp ("ppr@", gfc_current_block ()->name) == 0
      && strcmp (name, gfc_current_block ()->ns->proc_name->name) == 0)
    strcpy (name, "ppr@");

  if (gfc_current_state () == COMP_FUNCTION
      && strcmp (name, gfc_current_block ()->name) == 0
      && gfc_current_block ()->result
      && strcmp ("ppr@", gfc_current_block ()->result->name) == 0)
    strcpy (name, "ppr@");

  /* OK, we've successfully matched the declaration.  Now put the
     symbol in the current namespace, because it might be used in the
     optional initialization expression for this symbol, e.g. this is
     perfectly legal:

     integer, parameter :: i = huge(i)

     This is only true for parameters or variables of a basic type.
     For components of derived types, it is not true, so we don't
     create a symbol for those yet.  If we fail to create the symbol,
     bail out.  */
  if (!gfc_comp_struct (gfc_current_state ())
      && !build_sym (name, cl, cl_deferred, &as, &var_locus))
    {
      m = MATCH_ERROR;
      goto cleanup;
    }

  if (!check_function_name (name))
    {
      m = MATCH_ERROR;
      goto cleanup;
    }

  /* We allow old-style initializations of the form
       integer i /2/, j(4) /3*3, 1/
     (if no colon has been seen). These are different from data
     statements in that initializers are only allowed to apply to the
     variable immediately preceding, i.e.
       integer i, j /1, 2/
     is not allowed. Therefore we have to do some work manually, that
     could otherwise be left to the matchers for DATA statements.  */

  if (!colon_seen && gfc_match (" /") == MATCH_YES)
    {
      if (!gfc_notify_std (GFC_STD_GNU, "Old-style "
			   "initialization at %C"))
	return MATCH_ERROR;

      /* Allow old style initializations for components of STRUCTUREs and MAPs
         but not components of derived types.  */
      else if (gfc_current_state () == COMP_DERIVED)
	{
	  gfc_error ("Invalid old style initialization for derived type "
		     "component at %C");
	  m = MATCH_ERROR;
	  goto cleanup;
	}

      /* For structure components, read the initializer as a special
         expression and let the rest of this function apply the initializer
         as usual.  */
      else if (gfc_comp_struct (gfc_current_state ()))
        {
          m = match_clist_expr (&initializer, &current_ts, as);
          if (m == MATCH_NO)
            gfc_error ("Syntax error in old style initialization of %s at %C",
                       name);
          if (m != MATCH_YES)
            goto cleanup;
        }

      /* Otherwise we treat the old style initialization just like a
         DATA declaration for the current variable.  */
      else
        return match_old_style_init (name);
    }

  /* The double colon must be present in order to have initializers.
     Otherwise the statement is ambiguous with an assignment statement.  */
  if (colon_seen)
    {
      if (gfc_match (" =>") == MATCH_YES)
	{
	  if (!current_attr.pointer)
	    {
	      gfc_error ("Initialization at %C isn't for a pointer variable");
	      m = MATCH_ERROR;
	      goto cleanup;
	    }

	  m = match_pointer_init (&initializer, 0);
	  if (m != MATCH_YES)
	    goto cleanup;

	  /* The target of a pointer initialization must have the SAVE
	     attribute.  A variable in PROGRAM, MODULE, or SUBMODULE scope
	     is implicit SAVEd.  Explicitly, set the SAVE_IMPLICIT value.  */
	  if (initializer->expr_type == EXPR_VARIABLE
	      && initializer->symtree->n.sym->attr.save == SAVE_NONE
	      && (gfc_current_state () == COMP_PROGRAM
		  || gfc_current_state () == COMP_MODULE
		  || gfc_current_state () == COMP_SUBMODULE))
	    initializer->symtree->n.sym->attr.save = SAVE_IMPLICIT;
	}
      else if (gfc_match_char ('=') == MATCH_YES)
	{
	  if (current_attr.pointer)
	    {
	      gfc_error ("Pointer initialization at %C requires %<=>%>, "
			 "not %<=%>");
	      m = MATCH_ERROR;
	      goto cleanup;
	    }

	  m = gfc_match_init_expr (&initializer);
	  if (m == MATCH_NO)
	    {
	      gfc_error ("Expected an initialization expression at %C");
	      m = MATCH_ERROR;
	    }

	  if (current_attr.flavor != FL_PARAMETER && gfc_pure (NULL)
	      && !gfc_comp_struct (gfc_state_stack->state))
	    {
	      gfc_error ("Initialization of variable at %C is not allowed in "
			 "a PURE procedure");
	      m = MATCH_ERROR;
	    }

	  if (current_attr.flavor != FL_PARAMETER
	      && !gfc_comp_struct (gfc_state_stack->state))
	    gfc_unset_implicit_pure (gfc_current_ns->proc_name);

	  if (m != MATCH_YES)
	    goto cleanup;
	}
    }

  if (initializer != NULL && current_attr.allocatable
	&& gfc_comp_struct (gfc_current_state ()))
    {
      gfc_error ("Initialization of allocatable component at %C is not "
		 "allowed");
      m = MATCH_ERROR;
      goto cleanup;
    }

  if (gfc_current_state () == COMP_DERIVED
      && initializer && initializer->ts.type == BT_HOLLERITH)
    {
      gfc_error ("Initialization of structure component with a HOLLERITH "
		 "constant at %L is not allowed", &initializer->where);
      m = MATCH_ERROR;
      goto cleanup;
    }

  if (gfc_current_state () == COMP_DERIVED
      && gfc_current_block ()->attr.pdt_template)
    {
      gfc_symbol *param;
      gfc_find_symbol (name, gfc_current_block ()->f2k_derived,
		       0, &param);
      if (!param && (current_attr.pdt_kind || current_attr.pdt_len))
	{
	  gfc_error ("The component with KIND or LEN attribute at %C does not "
		     "not appear in the type parameter list at %L",
		     &gfc_current_block ()->declared_at);
	  m = MATCH_ERROR;
	  goto cleanup;
	}
      else if (param && !(current_attr.pdt_kind || current_attr.pdt_len))
	{
	  gfc_error ("The component at %C that appears in the type parameter "
		     "list at %L has neither the KIND nor LEN attribute",
		     &gfc_current_block ()->declared_at);
	  m = MATCH_ERROR;
	  goto cleanup;
	}
      else if (as && (current_attr.pdt_kind || current_attr.pdt_len))
	{
	  gfc_error ("The component at %C which is a type parameter must be "
		     "a scalar");
	  m = MATCH_ERROR;
	  goto cleanup;
	}
      else if (param && initializer)
	{
	  if (initializer->ts.type == BT_BOZ)
	    {
	      gfc_error ("BOZ literal constant at %L cannot appear as an "
			 "initializer", &initializer->where);
	      m = MATCH_ERROR;
      	      goto cleanup;
	    }
	  param->value = gfc_copy_expr (initializer);
	}
    }

  /* Before adding a possible initilizer, do a simple check for compatibility
     of lhs and rhs types.  Assigning a REAL value to a derived type is not a
     good thing.  */
  if (current_ts.type == BT_DERIVED && initializer
      && (gfc_numeric_ts (&initializer->ts)
	  || initializer->ts.type == BT_LOGICAL
	  || initializer->ts.type == BT_CHARACTER))
    {
      gfc_error ("Incompatible initialization between a derived type "
		 "entity and an entity with %qs type at %C",
		  gfc_typename (initializer));
      m = MATCH_ERROR;
      goto cleanup;
    }


  /* Add the initializer.  Note that it is fine if initializer is
     NULL here, because we sometimes also need to check if a
     declaration *must* have an initialization expression.  */
  if (!gfc_comp_struct (gfc_current_state ()))
    t = add_init_expr_to_sym (name, &initializer, &var_locus);
  else
    {
      if (current_ts.type == BT_DERIVED
	  && !current_attr.pointer && !initializer)
	initializer = gfc_default_initializer (&current_ts);
      t = build_struct (name, cl, &initializer, &as);

      /* If we match a nested structure definition we expect to see the
       * body even if the variable declarations blow up, so we need to keep
       * the structure declaration around.  */
      if (gfc_new_block && gfc_new_block->attr.flavor == FL_STRUCT)
        gfc_commit_symbol (gfc_new_block);
    }

  m = (t) ? MATCH_YES : MATCH_ERROR;

cleanup:
  /* Free stuff up and return.  */
  gfc_seen_div0 = false;
  gfc_free_expr (initializer);
  gfc_free_array_spec (as);

  return m;
}


/* Match an extended-f77 "TYPESPEC*bytesize"-style kind specification.
   This assumes that the byte size is equal to the kind number for
   non-COMPLEX types, and equal to twice the kind number for COMPLEX.  */

static match
gfc_match_old_kind_spec (gfc_typespec *ts)
{
  match m;
  int original_kind;

  if (gfc_match_char ('*') != MATCH_YES)
    return MATCH_NO;

  m = gfc_match_small_literal_int (&ts->kind, NULL);
  if (m != MATCH_YES)
    return MATCH_ERROR;

  original_kind = ts->kind;

  /* Massage the kind numbers for complex types.  */
  if (ts->type == BT_COMPLEX)
    {
      if (ts->kind % 2)
	{
	  gfc_error ("Old-style type declaration %s*%d not supported at %C",
		     gfc_basic_typename (ts->type), original_kind);
	  return MATCH_ERROR;
	}
      ts->kind /= 2;

    }

  if (ts->type == BT_INTEGER && ts->kind == 4 && flag_integer4_kind == 8)
    ts->kind = 8;

  if (ts->type == BT_REAL || ts->type == BT_COMPLEX)
    {
      if (ts->kind == 4)
	{
	  if (flag_real4_kind == 8)
	    ts->kind =  8;
	  if (flag_real4_kind == 10)
	    ts->kind = 10;
	  if (flag_real4_kind == 16)
	    ts->kind = 16;
	}
      else if (ts->kind == 8)
	{
	  if (flag_real8_kind == 4)
	    ts->kind = 4;
	  if (flag_real8_kind == 10)
	    ts->kind = 10;
	  if (flag_real8_kind == 16)
	    ts->kind = 16;
	}
    }

  if (gfc_validate_kind (ts->type, ts->kind, true) < 0)
    {
      gfc_error ("Old-style type declaration %s*%d not supported at %C",
		 gfc_basic_typename (ts->type), original_kind);
      return MATCH_ERROR;
    }

  if (!gfc_notify_std (GFC_STD_GNU,
		       "Nonstandard type declaration %s*%d at %C",
		       gfc_basic_typename(ts->type), original_kind))
    return MATCH_ERROR;

  return MATCH_YES;
}


/* Match a kind specification.  Since kinds are generally optional, we
   usually return MATCH_NO if something goes wrong.  If a "kind="
   string is found, then we know we have an error.  */

match
gfc_match_kind_spec (gfc_typespec *ts, bool kind_expr_only)
{
  locus where, loc;
  gfc_expr *e;
  match m, n;
  char c;

  m = MATCH_NO;
  n = MATCH_YES;
  e = NULL;
  saved_kind_expr = NULL;

  where = loc = gfc_current_locus;

  if (kind_expr_only)
    goto kind_expr;

  if (gfc_match_char ('(') == MATCH_NO)
    return MATCH_NO;

  /* Also gobbles optional text.  */
  if (gfc_match (" kind = ") == MATCH_YES)
    m = MATCH_ERROR;

  loc = gfc_current_locus;

kind_expr:

  n = gfc_match_init_expr (&e);

  if (gfc_derived_parameter_expr (e))
    {
      ts->kind = 0;
      saved_kind_expr = gfc_copy_expr (e);
      goto close_brackets;
    }

  if (n != MATCH_YES)
    {
      if (gfc_matching_function)
	{
	  /* The function kind expression might include use associated or
	     imported parameters and try again after the specification
	     expressions.....  */
	  if (gfc_match_char (')') != MATCH_YES)
	    {
	      gfc_error ("Missing right parenthesis at %C");
	      m = MATCH_ERROR;
	      goto no_match;
	    }

	  gfc_free_expr (e);
	  gfc_undo_symbols ();
	  return MATCH_YES;
	}
      else
	{
	  /* ....or else, the match is real.  */
	  if (n == MATCH_NO)
	    gfc_error ("Expected initialization expression at %C");
	  if (n != MATCH_YES)
	    return MATCH_ERROR;
	}
    }

  if (e->rank != 0)
    {
      gfc_error ("Expected scalar initialization expression at %C");
      m = MATCH_ERROR;
      goto no_match;
    }

  if (gfc_extract_int (e, &ts->kind, 1))
    {
      m = MATCH_ERROR;
      goto no_match;
    }

  /* Before throwing away the expression, let's see if we had a
     C interoperable kind (and store the fact).	 */
  if (e->ts.is_c_interop == 1)
    {
      /* Mark this as C interoperable if being declared with one
	 of the named constants from iso_c_binding.  */
      ts->is_c_interop = e->ts.is_iso_c;
      ts->f90_type = e->ts.f90_type;
      if (e->symtree)
	ts->interop_kind = e->symtree->n.sym;
    }

  gfc_free_expr (e);
  e = NULL;

  /* Ignore errors to this point, if we've gotten here.  This means
     we ignore the m=MATCH_ERROR from above.  */
  if (gfc_validate_kind (ts->type, ts->kind, true) < 0)
    {
      gfc_error ("Kind %d not supported for type %s at %C", ts->kind,
		 gfc_basic_typename (ts->type));
      gfc_current_locus = where;
      return MATCH_ERROR;
    }

  /* Warn if, e.g., c_int is used for a REAL variable, but not
     if, e.g., c_double is used for COMPLEX as the standard
     explicitly says that the kind type parameter for complex and real
     variable is the same, i.e. c_float == c_float_complex.  */
  if (ts->f90_type != BT_UNKNOWN && ts->f90_type != ts->type
      && !((ts->f90_type == BT_REAL && ts->type == BT_COMPLEX)
	   || (ts->f90_type == BT_COMPLEX && ts->type == BT_REAL)))
    gfc_warning_now (0, "C kind type parameter is for type %s but type at %L "
		     "is %s", gfc_basic_typename (ts->f90_type), &where,
		     gfc_basic_typename (ts->type));

close_brackets:

  gfc_gobble_whitespace ();
  if ((c = gfc_next_ascii_char ()) != ')'
      && (ts->type != BT_CHARACTER || c != ','))
    {
      if (ts->type == BT_CHARACTER)
	gfc_error ("Missing right parenthesis or comma at %C");
      else
	gfc_error ("Missing right parenthesis at %C");
      m = MATCH_ERROR;
    }
  else
     /* All tests passed.  */
     m = MATCH_YES;

  if(m == MATCH_ERROR)
     gfc_current_locus = where;

  if (ts->type == BT_INTEGER && ts->kind == 4 && flag_integer4_kind == 8)
    ts->kind =  8;

  if (ts->type == BT_REAL || ts->type == BT_COMPLEX)
    {
      if (ts->kind == 4)
	{
	  if (flag_real4_kind == 8)
	    ts->kind =  8;
	  if (flag_real4_kind == 10)
	    ts->kind = 10;
	  if (flag_real4_kind == 16)
	    ts->kind = 16;
	}
      else if (ts->kind == 8)
	{
	  if (flag_real8_kind == 4)
	    ts->kind = 4;
	  if (flag_real8_kind == 10)
	    ts->kind = 10;
	  if (flag_real8_kind == 16)
	    ts->kind = 16;
	}
    }

  /* Return what we know from the test(s).  */
  return m;

no_match:
  gfc_free_expr (e);
  gfc_current_locus = where;
  return m;
}


static match
match_char_kind (int * kind, int * is_iso_c)
{
  locus where;
  gfc_expr *e;
  match m, n;
  bool fail;

  m = MATCH_NO;
  e = NULL;
  where = gfc_current_locus;

  n = gfc_match_init_expr (&e);

  if (n != MATCH_YES && gfc_matching_function)
    {
      /* The expression might include use-associated or imported
	 parameters and try again after the specification
	 expressions.  */
      gfc_free_expr (e);
      gfc_undo_symbols ();
      return MATCH_YES;
    }

  if (n == MATCH_NO)
    gfc_error ("Expected initialization expression at %C");
  if (n != MATCH_YES)
    return MATCH_ERROR;

  if (e->rank != 0)
    {
      gfc_error ("Expected scalar initialization expression at %C");
      m = MATCH_ERROR;
      goto no_match;
    }

  if (gfc_derived_parameter_expr (e))
    {
      saved_kind_expr = e;
      *kind = 0;
      return MATCH_YES;
    }

  fail = gfc_extract_int (e, kind, 1);
  *is_iso_c = e->ts.is_iso_c;
  if (fail)
    {
      m = MATCH_ERROR;
      goto no_match;
    }

  gfc_free_expr (e);

  /* Ignore errors to this point, if we've gotten here.  This means
     we ignore the m=MATCH_ERROR from above.  */
  if (gfc_validate_kind (BT_CHARACTER, *kind, true) < 0)
    {
      gfc_error ("Kind %d is not supported for CHARACTER at %C", *kind);
      m = MATCH_ERROR;
    }
  else
     /* All tests passed.  */
     m = MATCH_YES;

  if (m == MATCH_ERROR)
     gfc_current_locus = where;

  /* Return what we know from the test(s).  */
  return m;

no_match:
  gfc_free_expr (e);
  gfc_current_locus = where;
  return m;
}


/* Match the various kind/length specifications in a CHARACTER
   declaration.  We don't return MATCH_NO.  */

match
gfc_match_char_spec (gfc_typespec *ts)
{
  int kind, seen_length, is_iso_c;
  gfc_charlen *cl;
  gfc_expr *len;
  match m;
  bool deferred;

  len = NULL;
  seen_length = 0;
  kind = 0;
  is_iso_c = 0;
  deferred = false;

  /* Try the old-style specification first.  */
  old_char_selector = 0;

  m = match_char_length (&len, &deferred, true);
  if (m != MATCH_NO)
    {
      if (m == MATCH_YES)
	old_char_selector = 1;
      seen_length = 1;
      goto done;
    }

  m = gfc_match_char ('(');
  if (m != MATCH_YES)
    {
      m = MATCH_YES;	/* Character without length is a single char.  */
      goto done;
    }

  /* Try the weird case:  ( KIND = <int> [ , LEN = <len-param> ] ).  */
  if (gfc_match (" kind =") == MATCH_YES)
    {
      m = match_char_kind (&kind, &is_iso_c);

      if (m == MATCH_ERROR)
	goto done;
      if (m == MATCH_NO)
	goto syntax;

      if (gfc_match (" , len =") == MATCH_NO)
	goto rparen;

      m = char_len_param_value (&len, &deferred);
      if (m == MATCH_NO)
	goto syntax;
      if (m == MATCH_ERROR)
	goto done;
      seen_length = 1;

      goto rparen;
    }

  /* Try to match "LEN = <len-param>" or "LEN = <len-param>, KIND = <int>".  */
  if (gfc_match (" len =") == MATCH_YES)
    {
      m = char_len_param_value (&len, &deferred);
      if (m == MATCH_NO)
	goto syntax;
      if (m == MATCH_ERROR)
	goto done;
      seen_length = 1;

      if (gfc_match_char (')') == MATCH_YES)
	goto done;

      if (gfc_match (" , kind =") != MATCH_YES)
	goto syntax;

      if (match_char_kind (&kind, &is_iso_c) == MATCH_ERROR)
	goto done;

      goto rparen;
    }

  /* Try to match ( <len-param> ) or ( <len-param> , [ KIND = ] <int> ).  */
  m = char_len_param_value (&len, &deferred);
  if (m == MATCH_NO)
    goto syntax;
  if (m == MATCH_ERROR)
    goto done;
  seen_length = 1;

  m = gfc_match_char (')');
  if (m == MATCH_YES)
    goto done;

  if (gfc_match_char (',') != MATCH_YES)
    goto syntax;

  gfc_match (" kind =");	/* Gobble optional text.  */

  m = match_char_kind (&kind, &is_iso_c);
  if (m == MATCH_ERROR)
    goto done;
  if (m == MATCH_NO)
    goto syntax;

rparen:
  /* Require a right-paren at this point.  */
  m = gfc_match_char (')');
  if (m == MATCH_YES)
    goto done;

syntax:
  gfc_error ("Syntax error in CHARACTER declaration at %C");
  m = MATCH_ERROR;
  gfc_free_expr (len);
  return m;

done:
  /* Deal with character functions after USE and IMPORT statements.  */
  if (gfc_matching_function)
    {
      gfc_free_expr (len);
      gfc_undo_symbols ();
      return MATCH_YES;
    }

  if (m != MATCH_YES)
    {
      gfc_free_expr (len);
      return m;
    }

  /* Do some final massaging of the length values.  */
  cl = gfc_new_charlen (gfc_current_ns, NULL);

  if (seen_length == 0)
    cl->length = gfc_get_int_expr (gfc_charlen_int_kind, NULL, 1);
  else
    {
      /* If gfortran ends up here, then len may be reducible to a constant.
	 Try to do that here.  If it does not reduce, simply assign len to
	 charlen.  A complication occurs with user-defined generic functions,
	 which are not resolved.  Use a private namespace to deal with
	 generic functions.  */

      if (len && len->expr_type != EXPR_CONSTANT)
	{
	  gfc_namespace *old_ns;
	  gfc_expr *e;

	  old_ns = gfc_current_ns;
	  gfc_current_ns = gfc_get_namespace (NULL, 0);

	  e = gfc_copy_expr (len);
	  gfc_push_suppress_errors ();
	  gfc_reduce_init_expr (e);
	  gfc_pop_suppress_errors ();
	  if (e->expr_type == EXPR_CONSTANT)
	    {
	      gfc_replace_expr (len, e);
	      if (mpz_cmp_si (len->value.integer, 0) < 0)
		mpz_set_ui (len->value.integer, 0);
	    }
	  else
	    gfc_free_expr (e);

	  gfc_free_namespace (gfc_current_ns);
	  gfc_current_ns = old_ns;
	}

      cl->length = len;
    }

  ts->u.cl = cl;
  ts->kind = kind == 0 ? gfc_default_character_kind : kind;
  ts->deferred = deferred;

  /* We have to know if it was a C interoperable kind so we can
     do accurate type checking of bind(c) procs, etc.  */
  if (kind != 0)
    /* Mark this as C interoperable if being declared with one
       of the named constants from iso_c_binding.  */
    ts->is_c_interop = is_iso_c;
  else if (len != NULL)
    /* Here, we might have parsed something such as: character(c_char)
       In this case, the parsing code above grabs the c_char when
       looking for the length (line 1690, roughly).  it's the last
       testcase for parsing the kind params of a character variable.
       However, it's not actually the length.	 this seems like it
       could be an error.
       To see if the user used a C interop kind, test the expr
       of the so called length, and see if it's C interoperable.  */
    ts->is_c_interop = len->ts.is_iso_c;

  return MATCH_YES;
}


/* Matches a RECORD declaration. */

static match
match_record_decl (char *name)
{
    locus old_loc;
    old_loc = gfc_current_locus;
    match m;

    m = gfc_match (" record /");
    if (m == MATCH_YES)
      {
          if (!flag_dec_structure)
            {
                gfc_current_locus = old_loc;
                gfc_error ("RECORD at %C is an extension, enable it with "
			   "%<-fdec-structure%>");
                return MATCH_ERROR;
            }
          m = gfc_match (" %n/", name);
          if (m == MATCH_YES)
            return MATCH_YES;
      }

  gfc_current_locus = old_loc;
  if (flag_dec_structure
      && (gfc_match (" record% ") == MATCH_YES
          || gfc_match (" record%t") == MATCH_YES))
    gfc_error ("Structure name expected after RECORD at %C");
  if (m == MATCH_NO)
    return MATCH_NO;

  return MATCH_ERROR;
}


/* This function uses the gfc_actual_arglist 'type_param_spec_list' as a source
   of expressions to substitute into the possibly parameterized expression
   'e'. Using a list is inefficient but should not be too bad since the
   number of type parameters is not likely to be large.  */
static bool
insert_parameter_exprs (gfc_expr* e, gfc_symbol* sym ATTRIBUTE_UNUSED,
			int* f)
{
  gfc_actual_arglist *param;
  gfc_expr *copy;

  if (e->expr_type != EXPR_VARIABLE)
    return false;

  gcc_assert (e->symtree);
  if (e->symtree->n.sym->attr.pdt_kind
      || (*f != 0 && e->symtree->n.sym->attr.pdt_len))
    {
      for (param = type_param_spec_list; param; param = param->next)
	if (strcmp (e->symtree->n.sym->name, param->name) == 0)
	  break;

      if (param)
	{
	  copy = gfc_copy_expr (param->expr);
	  *e = *copy;
	  free (copy);
	}
    }

  return false;
}


static bool
gfc_insert_kind_parameter_exprs (gfc_expr *e)
{
  return gfc_traverse_expr (e, NULL, &insert_parameter_exprs, 0);
}


bool
gfc_insert_parameter_exprs (gfc_expr *e, gfc_actual_arglist *param_list)
{
  gfc_actual_arglist *old_param_spec_list = type_param_spec_list;
  type_param_spec_list = param_list;
  bool res = gfc_traverse_expr (e, NULL, &insert_parameter_exprs, 1);
  type_param_spec_list = old_param_spec_list;
  return res;
}

/* Determines the instance of a parameterized derived type to be used by
   matching determining the values of the kind parameters and using them
   in the name of the instance. If the instance exists, it is used, otherwise
   a new derived type is created.  */
match
gfc_get_pdt_instance (gfc_actual_arglist *param_list, gfc_symbol **sym,
		      gfc_actual_arglist **ext_param_list)
{
  /* The PDT template symbol.  */
  gfc_symbol *pdt = *sym;
  /* The symbol for the parameter in the template f2k_namespace.  */
  gfc_symbol *param;
  /* The hoped for instance of the PDT.  */
  gfc_symbol *instance;
  /* The list of parameters appearing in the PDT declaration.  */
  gfc_formal_arglist *type_param_name_list;
  /* Used to store the parameter specification list during recursive calls.  */
  gfc_actual_arglist *old_param_spec_list;
  /* Pointers to the parameter specification being used.  */
  gfc_actual_arglist *actual_param;
  gfc_actual_arglist *tail = NULL;
  /* Used to build up the name of the PDT instance. The prefix uses 4
     characters and each KIND parameter 2 more.  Allow 8 of the latter. */
  char name[GFC_MAX_SYMBOL_LEN + 21];

  bool name_seen = (param_list == NULL);
  bool assumed_seen = false;
  bool deferred_seen = false;
  bool spec_error = false;
  int kind_value, i;
  gfc_expr *kind_expr;
  gfc_component *c1, *c2;
  match m;

  type_param_spec_list = NULL;

  type_param_name_list = pdt->formal;
  actual_param = param_list;
  sprintf (name, "Pdt%s", pdt->name);

  /* Run through the parameter name list and pick up the actual
     parameter values or use the default values in the PDT declaration.  */
  for (; type_param_name_list;
       type_param_name_list = type_param_name_list->next)
    {
      if (actual_param && actual_param->spec_type != SPEC_EXPLICIT)
	{
	  if (actual_param->spec_type == SPEC_ASSUMED)
	    spec_error = deferred_seen;
	  else
	    spec_error = assumed_seen;

	  if (spec_error)
	    {
	      gfc_error ("The type parameter spec list at %C cannot contain "
			 "both ASSUMED and DEFERRED parameters");
	      goto error_return;
	    }
	}

      if (actual_param && actual_param->name)
	name_seen = true;
      param = type_param_name_list->sym;

      if (!param || !param->name)
	continue;

      c1 = gfc_find_component (pdt, param->name, false, true, NULL);
      /* An error should already have been thrown in resolve.cc
	 (resolve_fl_derived0).  */
      if (!pdt->attr.use_assoc && !c1)
	goto error_return;

      kind_expr = NULL;
      if (!name_seen)
	{
	  if (!actual_param && !(c1 && c1->initializer))
	    {
	      gfc_error ("The type parameter spec list at %C does not contain "
			 "enough parameter expressions");
	      goto error_return;
	    }
	  else if (!actual_param && c1 && c1->initializer)
	    kind_expr = gfc_copy_expr (c1->initializer);
	  else if (actual_param && actual_param->spec_type == SPEC_EXPLICIT)
	    kind_expr = gfc_copy_expr (actual_param->expr);
	}
      else
	{
	  actual_param = param_list;
	  for (;actual_param; actual_param = actual_param->next)
	    if (actual_param->name
	        && strcmp (actual_param->name, param->name) == 0)
	      break;
	  if (actual_param && actual_param->spec_type == SPEC_EXPLICIT)
	    kind_expr = gfc_copy_expr (actual_param->expr);
	  else
	    {
	      if (c1->initializer)
		kind_expr = gfc_copy_expr (c1->initializer);
	      else if (!(actual_param && param->attr.pdt_len))
		{
		  gfc_error ("The derived parameter %qs at %C does not "
			     "have a default value", param->name);
		  goto error_return;
		}
	    }
	}

      /* Store the current parameter expressions in a temporary actual
	 arglist 'list' so that they can be substituted in the corresponding
	 expressions in the PDT instance.  */
      if (type_param_spec_list == NULL)
	{
	  type_param_spec_list = gfc_get_actual_arglist ();
	  tail = type_param_spec_list;
	}
      else
	{
	  tail->next = gfc_get_actual_arglist ();
	  tail = tail->next;
	}
      tail->name = param->name;

      if (kind_expr)
	{
	  /* Try simplification even for LEN expressions.  */
	  bool ok;
	  gfc_resolve_expr (kind_expr);
	  ok = gfc_simplify_expr (kind_expr, 1);
	  /* Variable expressions seem to default to BT_PROCEDURE.
	     TODO find out why this is and fix it.  */
	  if (kind_expr->ts.type != BT_INTEGER
	      && kind_expr->ts.type != BT_PROCEDURE)
	    {
	      gfc_error ("The parameter expression at %C must be of "
		         "INTEGER type and not %s type",
			 gfc_basic_typename (kind_expr->ts.type));
	      goto error_return;
	    }
	  if (kind_expr->ts.type == BT_INTEGER && !ok)
	    {
	      gfc_error ("The parameter expression at %C does not "
			 "simplify to an INTEGER constant");
	      goto error_return;
	    }

	  tail->expr = gfc_copy_expr (kind_expr);
	}

      if (actual_param)
	tail->spec_type = actual_param->spec_type;

      if (!param->attr.pdt_kind)
	{
	  if (!name_seen && actual_param)
	    actual_param = actual_param->next;
	  if (kind_expr)
	    {
	      gfc_free_expr (kind_expr);
	      kind_expr = NULL;
	    }
	  continue;
	}

      if (actual_param
	  && (actual_param->spec_type == SPEC_ASSUMED
	      || actual_param->spec_type == SPEC_DEFERRED))
	{
	  gfc_error ("The KIND parameter %qs at %C cannot either be "
		     "ASSUMED or DEFERRED", param->name);
	  goto error_return;
	}

      if (!kind_expr || !gfc_is_constant_expr (kind_expr))
	{
	  gfc_error ("The value for the KIND parameter %qs at %C does not "
		     "reduce to a constant expression", param->name);
	  goto error_return;
	}

      gfc_extract_int (kind_expr, &kind_value);
      sprintf (name + strlen (name), "_%d", kind_value);

      if (!name_seen && actual_param)
	actual_param = actual_param->next;
      gfc_free_expr (kind_expr);
    }

  if (!name_seen && actual_param)
    {
      gfc_error ("The type parameter spec list at %C contains too many "
		 "parameter expressions");
      goto error_return;
    }

  /* Now we search for the PDT instance 'name'. If it doesn't exist, we
     build it, using 'pdt' as a template.  */
  if (gfc_get_symbol (name, pdt->ns, &instance))
    {
      gfc_error ("Parameterized derived type at %C is ambiguous");
      goto error_return;
    }

  m = MATCH_YES;

  if (instance->attr.flavor == FL_DERIVED
      && instance->attr.pdt_type)
    {
      instance->refs++;
      if (ext_param_list)
        *ext_param_list = type_param_spec_list;
      *sym = instance;
      gfc_commit_symbols ();
      return m;
    }

  /* Start building the new instance of the parameterized type.  */
  gfc_copy_attr (&instance->attr, &pdt->attr, &pdt->declared_at);
  instance->attr.pdt_template = 0;
  instance->attr.pdt_type = 1;
  instance->declared_at = gfc_current_locus;

  /* Add the components, replacing the parameters in all expressions
     with the expressions for their values in 'type_param_spec_list'.  */
  c1 = pdt->components;
  tail = type_param_spec_list;
  for (; c1; c1 = c1->next)
    {
      gfc_add_component (instance, c1->name, &c2);

      c2->ts = c1->ts;
      c2->attr = c1->attr;

      /* The order of declaration of the type_specs might not be the
	 same as that of the components.  */
      if (c1->attr.pdt_kind || c1->attr.pdt_len)
	{
	  for (tail = type_param_spec_list; tail; tail = tail->next)
	    if (strcmp (c1->name, tail->name) == 0)
	      break;
	}

      /* Deal with type extension by recursively calling this function
	 to obtain the instance of the extended type.  */
      if (gfc_current_state () != COMP_DERIVED
	  && c1 == pdt->components
	  && (c1->ts.type == BT_DERIVED || c1->ts.type == BT_CLASS)
	  && c1->ts.u.derived && c1->ts.u.derived->attr.pdt_template
	  && gfc_get_derived_super_type (*sym) == c2->ts.u.derived)
	{
	  gfc_formal_arglist *f;

	  old_param_spec_list = type_param_spec_list;

	  /* Obtain a spec list appropriate to the extended type..*/
	  actual_param = gfc_copy_actual_arglist (type_param_spec_list);
	  type_param_spec_list = actual_param;
	  for (f = c1->ts.u.derived->formal; f && f->next; f = f->next)
	    actual_param = actual_param->next;
	  if (actual_param)
	    {
	      gfc_free_actual_arglist (actual_param->next);
	      actual_param->next = NULL;
	    }

	  /* Now obtain the PDT instance for the extended type.  */
	  c2->param_list = type_param_spec_list;
	  m = gfc_get_pdt_instance (type_param_spec_list, &c2->ts.u.derived,
				    NULL);
	  type_param_spec_list = old_param_spec_list;

	  c2->ts.u.derived->refs++;
	  gfc_set_sym_referenced (c2->ts.u.derived);

	  /* Set extension level.  */
	  if (c2->ts.u.derived->attr.extension == 255)
	    {
	      /* Since the extension field is 8 bit wide, we can only have
		 up to 255 extension levels.  */
	      gfc_error ("Maximum extension level reached with type %qs at %L",
			 c2->ts.u.derived->name,
			 &c2->ts.u.derived->declared_at);
	      goto error_return;
	    }
	  instance->attr.extension = c2->ts.u.derived->attr.extension + 1;

	  continue;
	}

      /* Set the component kind using the parameterized expression.  */
      if ((c1->ts.kind == 0 || c1->ts.type == BT_CHARACTER)
	   && c1->kind_expr != NULL)
	{
	  gfc_expr *e = gfc_copy_expr (c1->kind_expr);
	  gfc_insert_kind_parameter_exprs (e);
	  gfc_simplify_expr (e, 1);
	  gfc_extract_int (e, &c2->ts.kind);
	  gfc_free_expr (e);
	  if (gfc_validate_kind (c2->ts.type, c2->ts.kind, true) < 0)
	    {
	      gfc_error ("Kind %d not supported for type %s at %C",
			 c2->ts.kind, gfc_basic_typename (c2->ts.type));
	      goto error_return;
	    }
	}

      /* Similarly, set the string length if parameterized.  */
      if (c1->ts.type == BT_CHARACTER
	  && c1->ts.u.cl->length
	  && gfc_derived_parameter_expr (c1->ts.u.cl->length))
	{
	  gfc_expr *e;
	  e = gfc_copy_expr (c1->ts.u.cl->length);
	  gfc_insert_kind_parameter_exprs (e);
	  gfc_simplify_expr (e, 1);
	  c2->ts.u.cl = gfc_new_charlen (gfc_current_ns, NULL);
	  c2->ts.u.cl->length = e;
	  c2->attr.pdt_string = 1;
	}

      /* Set up either the KIND/LEN initializer, if constant,
	 or the parameterized expression. Use the template
	 initializer if one is not already set in this instance.  */
      if (c2->attr.pdt_kind || c2->attr.pdt_len)
	{
	  if (tail && tail->expr && gfc_is_constant_expr (tail->expr))
	    c2->initializer = gfc_copy_expr (tail->expr);
	  else if (tail && tail->expr)
	    {
	      c2->param_list = gfc_get_actual_arglist ();
	      c2->param_list->name = tail->name;
	      c2->param_list->expr = gfc_copy_expr (tail->expr);
	      c2->param_list->next = NULL;
	    }

	  if (!c2->initializer && c1->initializer)
	    c2->initializer = gfc_copy_expr (c1->initializer);
	}

      /* Copy the array spec.  */
      c2->as = gfc_copy_array_spec (c1->as);
      if (c1->ts.type == BT_CLASS)
	CLASS_DATA (c2)->as = gfc_copy_array_spec (CLASS_DATA (c1)->as);

      /* Determine if an array spec is parameterized. If so, substitute
	 in the parameter expressions for the bounds and set the pdt_array
	 attribute. Notice that this attribute must be unconditionally set
	 if this is an array of parameterized character length.  */
      if (c1->as && c1->as->type == AS_EXPLICIT)
	{
	  bool pdt_array = false;

	  /* Are the bounds of the array parameterized?  */
	  for (i = 0; i < c1->as->rank; i++)
	    {
	      if (gfc_derived_parameter_expr (c1->as->lower[i]))
		pdt_array = true;
	      if (gfc_derived_parameter_expr (c1->as->upper[i]))
		pdt_array = true;
	    }

	  /* If they are, free the expressions for the bounds and
	     replace them with the template expressions with substitute
	     values.  */
	  for (i = 0; pdt_array && i < c1->as->rank; i++)
	    {
	      gfc_expr *e;
	      e = gfc_copy_expr (c1->as->lower[i]);
	      gfc_insert_kind_parameter_exprs (e);
	      gfc_simplify_expr (e, 1);
	      gfc_free_expr (c2->as->lower[i]);
	      c2->as->lower[i] = e;
	      e = gfc_copy_expr (c1->as->upper[i]);
	      gfc_insert_kind_parameter_exprs (e);
	      gfc_simplify_expr (e, 1);
	      gfc_free_expr (c2->as->upper[i]);
	      c2->as->upper[i] = e;
	    }
	  c2->attr.pdt_array = pdt_array ? 1 : c2->attr.pdt_string;
	  if (c1->initializer)
	    {
	      c2->initializer = gfc_copy_expr (c1->initializer);
	      gfc_insert_kind_parameter_exprs (c2->initializer);
	      gfc_simplify_expr (c2->initializer, 1);
	    }
	}

      /* Recurse into this function for PDT components.  */
      if ((c1->ts.type == BT_DERIVED || c1->ts.type == BT_CLASS)
	  && c1->ts.u.derived && c1->ts.u.derived->attr.pdt_template)
	{
	  gfc_actual_arglist *params;
	  /* The component in the template has a list of specification
	     expressions derived from its declaration.  */
	  params = gfc_copy_actual_arglist (c1->param_list);
	  actual_param = params;
	  /* Substitute the template parameters with the expressions
	     from the specification list.  */
	  for (;actual_param; actual_param = actual_param->next)
	    gfc_insert_parameter_exprs (actual_param->expr,
					type_param_spec_list);

	  /* Now obtain the PDT instance for the component.  */
	  old_param_spec_list = type_param_spec_list;
	  m = gfc_get_pdt_instance (params, &c2->ts.u.derived, NULL);
	  type_param_spec_list = old_param_spec_list;

	  c2->param_list = params;
	  if (!(c2->attr.pointer || c2->attr.allocatable))
	    c2->initializer = gfc_default_initializer (&c2->ts);

	  if (c2->attr.allocatable)
	    instance->attr.alloc_comp = 1;
	}
    }

  gfc_commit_symbol (instance);
  if (ext_param_list)
    *ext_param_list = type_param_spec_list;
  *sym = instance;
  return m;

error_return:
  gfc_free_actual_arglist (type_param_spec_list);
  return MATCH_ERROR;
}


/* Match a legacy nonstandard BYTE type-spec.  */

static match
match_byte_typespec (gfc_typespec *ts)
{
  if (gfc_match (" byte") == MATCH_YES)
    {
      if (!gfc_notify_std (GFC_STD_GNU, "BYTE type at %C"))
	return MATCH_ERROR;

      if (gfc_current_form == FORM_FREE)
	{
	  char c = gfc_peek_ascii_char ();
	  if (!gfc_is_whitespace (c) && c != ',')
	    return MATCH_NO;
	}

      if (gfc_validate_kind (BT_INTEGER, 1, true) < 0)
	{
	  gfc_error ("BYTE type used at %C "
		     "is not available on the target machine");
	  return MATCH_ERROR;
	}

      ts->type = BT_INTEGER;
      ts->kind = 1;
      return MATCH_YES;
    }
  return MATCH_NO;
}


/* Matches a declaration-type-spec (F03:R502).  If successful, sets the ts
   structure to the matched specification.  This is necessary for FUNCTION and
   IMPLICIT statements.

   If implicit_flag is nonzero, then we don't check for the optional
   kind specification.  Not doing so is needed for matching an IMPLICIT
   statement correctly.  */

match
gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag)
{
  /* Provide sufficient space to hold "pdtsymbol".  */
  char *name = XALLOCAVEC (char, GFC_MAX_SYMBOL_LEN + 1);
  gfc_symbol *sym, *dt_sym;
  match m;
  char c;
  bool seen_deferred_kind, matched_type;
  const char *dt_name;

  decl_type_param_list = NULL;

  /* A belt and braces check that the typespec is correctly being treated
     as a deferred characteristic association.  */
  seen_deferred_kind = (gfc_current_state () == COMP_FUNCTION)
			  && (gfc_current_block ()->result->ts.kind == -1)
			  && (ts->kind == -1);
  gfc_clear_ts (ts);
  if (seen_deferred_kind)
    ts->kind = -1;

  /* Clear the current binding label, in case one is given.  */
  curr_binding_label = NULL;

  /* Match BYTE type-spec.  */
  m = match_byte_typespec (ts);
  if (m != MATCH_NO)
    return m;

  m = gfc_match (" type (");
  matched_type = (m == MATCH_YES);
  if (matched_type)
    {
      gfc_gobble_whitespace ();
      if (gfc_peek_ascii_char () == '*')
	{
	  if ((m = gfc_match ("* ) ")) != MATCH_YES)
	    return m;
	  if (gfc_comp_struct (gfc_current_state ()))
	    {
	      gfc_error ("Assumed type at %C is not allowed for components");
	      return MATCH_ERROR;
	    }
	  if (!gfc_notify_std (GFC_STD_F2018, "Assumed type at %C"))
	    return MATCH_ERROR;
	  ts->type = BT_ASSUMED;
	  return MATCH_YES;
	}

      m = gfc_match ("%n", name);
      matched_type = (m == MATCH_YES);
    }

  if ((matched_type && strcmp ("integer", name) == 0)
      || (!matched_type && gfc_match (" integer") == MATCH_YES))
    {
      ts->type = BT_INTEGER;
      ts->kind = gfc_default_integer_kind;
      goto get_kind;
    }

  if ((matched_type && strcmp ("character", name) == 0)
      || (!matched_type && gfc_match (" character") == MATCH_YES))
    {
      if (matched_type
	  && !gfc_notify_std (GFC_STD_F2008, "TYPE with "
			      "intrinsic-type-spec at %C"))
	return MATCH_ERROR;

      ts->type = BT_CHARACTER;
      if (implicit_flag == 0)
	m = gfc_match_char_spec (ts);
      else
	m = MATCH_YES;

      if (matched_type && m == MATCH_YES && gfc_match_char (')') != MATCH_YES)
	{
	  gfc_error ("Malformed type-spec at %C");
	  return MATCH_ERROR;
	}

      return m;
    }

  if ((matched_type && strcmp ("real", name) == 0)
      || (!matched_type && gfc_match (" real") == MATCH_YES))
    {
      ts->type = BT_REAL;
      ts->kind = gfc_default_real_kind;
      goto get_kind;
    }

  if ((matched_type
       && (strcmp ("doubleprecision", name) == 0
	   || (strcmp ("double", name) == 0
	       && gfc_match (" precision") == MATCH_YES)))
      || (!matched_type && gfc_match (" double precision") == MATCH_YES))
    {
      if (matched_type
	  && !gfc_notify_std (GFC_STD_F2008, "TYPE with "
			      "intrinsic-type-spec at %C"))
	return MATCH_ERROR;

      if (matched_type && gfc_match_char (')') != MATCH_YES)
	{
	  gfc_error ("Malformed type-spec at %C");
	  return MATCH_ERROR;
	}

      ts->type = BT_REAL;
      ts->kind = gfc_default_double_kind;
      return MATCH_YES;
    }

  if ((matched_type && strcmp ("complex", name) == 0)
      || (!matched_type && gfc_match (" complex") == MATCH_YES))
    {
      ts->type = BT_COMPLEX;
      ts->kind = gfc_default_complex_kind;
      goto get_kind;
    }

  if ((matched_type
       && (strcmp ("doublecomplex", name) == 0
	   || (strcmp ("double", name) == 0
	       && gfc_match (" complex") == MATCH_YES)))
      || (!matched_type && gfc_match (" double complex") == MATCH_YES))
    {
      if (!gfc_notify_std (GFC_STD_GNU, "DOUBLE COMPLEX at %C"))
	return MATCH_ERROR;

      if (matched_type
	  && !gfc_notify_std (GFC_STD_F2008, "TYPE with "
			      "intrinsic-type-spec at %C"))
	return MATCH_ERROR;

      if (matched_type && gfc_match_char (')') != MATCH_YES)
	{
	  gfc_error ("Malformed type-spec at %C");
	  return MATCH_ERROR;
	}

      ts->type = BT_COMPLEX;
      ts->kind = gfc_default_double_kind;
      return MATCH_YES;
    }

  if ((matched_type && strcmp ("logical", name) == 0)
      || (!matched_type && gfc_match (" logical") == MATCH_YES))
    {
      ts->type = BT_LOGICAL;
      ts->kind = gfc_default_logical_kind;
      goto get_kind;
    }

  if (matched_type)
    {
      m = gfc_match_actual_arglist (1, &decl_type_param_list, true);
      if (m == MATCH_ERROR)
	return m;

      gfc_gobble_whitespace ();
      if (gfc_peek_ascii_char () != ')')
	{
	  gfc_error ("Malformed type-spec at %C");
	  return MATCH_ERROR;
	}
      m = gfc_match_char (')'); /* Burn closing ')'.  */
    }

  if (m != MATCH_YES)
    m = match_record_decl (name);

  if (matched_type || m == MATCH_YES)
    {
      ts->type = BT_DERIVED;
      /* We accept record/s/ or type(s) where s is a structure, but we
       * don't need all the extra derived-type stuff for structures.  */
      if (gfc_find_symbol (gfc_dt_upper_string (name), NULL, 1, &sym))
        {
          gfc_error ("Type name %qs at %C is ambiguous", name);
          return MATCH_ERROR;
        }

      if (sym && sym->attr.flavor == FL_DERIVED
	  && sym->attr.pdt_template
	  && gfc_current_state () != COMP_DERIVED)
	{
	  m = gfc_get_pdt_instance (decl_type_param_list, &sym,  NULL);
	  if (m != MATCH_YES)
	    return m;
	  gcc_assert (!sym->attr.pdt_template && sym->attr.pdt_type);
	  ts->u.derived = sym;
	  const char* lower = gfc_dt_lower_string (sym->name);
	  size_t len = strlen (lower);
	  /* Reallocate with sufficient size.  */
	  if (len > GFC_MAX_SYMBOL_LEN)
	    name = XALLOCAVEC (char, len + 1);
	  memcpy (name, lower, len);
	  name[len] = '\0';
	}

      if (sym && sym->attr.flavor == FL_STRUCT)
        {
          ts->u.derived = sym;
          return MATCH_YES;
        }
      /* Actually a derived type.  */
    }

  else
    {
      /* Match nested STRUCTURE declarations; only valid within another
	 structure declaration.  */
      if (flag_dec_structure
	  && (gfc_current_state () == COMP_STRUCTURE
	      || gfc_current_state () == COMP_MAP))
	{
	  m = gfc_match (" structure");
	  if (m == MATCH_YES)
	    {
	      m = gfc_match_structure_decl ();
	      if (m == MATCH_YES)
		{
		  /* gfc_new_block is updated by match_structure_decl.  */
		  ts->type = BT_DERIVED;
		  ts->u.derived = gfc_new_block;
		  return MATCH_YES;
		}
	    }
	  if (m == MATCH_ERROR)
	    return MATCH_ERROR;
	}

      /* Match CLASS declarations.  */
      m = gfc_match (" class ( * )");
      if (m == MATCH_ERROR)
	return MATCH_ERROR;
      else if (m == MATCH_YES)
	{
	  gfc_symbol *upe;
	  gfc_symtree *st;
	  ts->type = BT_CLASS;
	  gfc_find_symbol ("STAR", gfc_current_ns, 1, &upe);
	  if (upe == NULL)
	    {
	      upe = gfc_new_symbol ("STAR", gfc_current_ns);
	      st = gfc_new_symtree (&gfc_current_ns->sym_root, "STAR");
	      st->n.sym = upe;
	      gfc_set_sym_referenced (upe);
	      upe->refs++;
	      upe->ts.type = BT_VOID;
	      upe->attr.unlimited_polymorphic = 1;
	      /* This is essential to force the construction of
		 unlimited polymorphic component class containers.  */
	      upe->attr.zero_comp = 1;
	      if (!gfc_add_flavor (&upe->attr, FL_DERIVED, NULL,
				   &gfc_current_locus))
	      return MATCH_ERROR;
	    }
	  else
	    {
	      st = gfc_get_tbp_symtree (&gfc_current_ns->sym_root, "STAR");
	      st->n.sym = upe;
	      upe->refs++;
	    }
	  ts->u.derived = upe;
	  return m;
	}

      m = gfc_match (" class (");

      if (m == MATCH_YES)
	m = gfc_match ("%n", name);
      else
	return m;

      if (m != MATCH_YES)
	return m;
      ts->type = BT_CLASS;

      if (!gfc_notify_std (GFC_STD_F2003, "CLASS statement at %C"))
	return MATCH_ERROR;

      m = gfc_match_actual_arglist (1, &decl_type_param_list, true);
      if (m == MATCH_ERROR)
	return m;

      m = gfc_match_char (')');
      if (m != MATCH_YES)
	return m;
    }

  /* Defer association of the derived type until the end of the
     specification block.  However, if the derived type can be
     found, add it to the typespec.  */
  if (gfc_matching_function)
    {
      ts->u.derived = NULL;
      if (gfc_current_state () != COMP_INTERFACE
	    && !gfc_find_symbol (name, NULL, 1, &sym) && sym)
	{
	  sym = gfc_find_dt_in_generic (sym);
	  ts->u.derived = sym;
	}
      return MATCH_YES;
    }

  /* Search for the name but allow the components to be defined later.  If
     type = -1, this typespec has been seen in a function declaration but
     the type could not be accessed at that point.  The actual derived type is
     stored in a symtree with the first letter of the name capitalized; the
     symtree with the all lower-case name contains the associated
     generic function.  */
  dt_name = gfc_dt_upper_string (name);
  sym = NULL;
  dt_sym = NULL;
  if (ts->kind != -1)
    {
      gfc_get_ha_symbol (name, &sym);
      if (sym->generic && gfc_find_symbol (dt_name, NULL, 0, &dt_sym))
	{
	  gfc_error ("Type name %qs at %C is ambiguous", name);
	  return MATCH_ERROR;
	}
      if (sym->generic && !dt_sym)
	dt_sym = gfc_find_dt_in_generic (sym);

      /* Host associated PDTs can get confused with their constructors
	 because they ar instantiated in the template's namespace.  */
      if (!dt_sym)
	{
	  if (gfc_find_symbol (dt_name, NULL, 1, &dt_sym))
	    {
	      gfc_error ("Type name %qs at %C is ambiguous", name);
	      return MATCH_ERROR;
	    }
	  if (dt_sym && !dt_sym->attr.pdt_type)
	    dt_sym = NULL;
	}
    }
  else if (ts->kind == -1)
    {
      int iface = gfc_state_stack->previous->state != COMP_INTERFACE
		    || gfc_current_ns->has_import_set;
      gfc_find_symbol (name, NULL, iface, &sym);
      if (sym && sym->generic && gfc_find_symbol (dt_name, NULL, 1, &dt_sym))
	{
	  gfc_error ("Type name %qs at %C is ambiguous", name);
	  return MATCH_ERROR;
	}
      if (sym && sym->generic && !dt_sym)
	dt_sym = gfc_find_dt_in_generic (sym);

      ts->kind = 0;
      if (sym == NULL)
	return MATCH_NO;
    }

  if ((sym->attr.flavor != FL_UNKNOWN && sym->attr.flavor != FL_STRUCT
       && !(sym->attr.flavor == FL_PROCEDURE && sym->attr.generic))
      || sym->attr.subroutine)
    {
      gfc_error ("Type name %qs at %C conflicts with previously declared "
		 "entity at %L, which has the same name", name,
		 &sym->declared_at);
      return MATCH_ERROR;
    }

  if (sym && sym->attr.flavor == FL_DERIVED
      && sym->attr.pdt_template
      && gfc_current_state () != COMP_DERIVED)
    {
      m = gfc_get_pdt_instance (decl_type_param_list, &sym, NULL);
      if (m != MATCH_YES)
	return m;
      gcc_assert (!sym->attr.pdt_template && sym->attr.pdt_type);
      ts->u.derived = sym;
      strcpy (name, gfc_dt_lower_string (sym->name));
    }

  gfc_save_symbol_data (sym);
  gfc_set_sym_referenced (sym);
  if (!sym->attr.generic
      && !gfc_add_generic (&sym->attr, sym->name, NULL))
    return MATCH_ERROR;

  if (!sym->attr.function
      && !gfc_add_function (&sym->attr, sym->name, NULL))
    return MATCH_ERROR;

  if (dt_sym && dt_sym->attr.flavor == FL_DERIVED
      && dt_sym->attr.pdt_template
      && gfc_current_state () != COMP_DERIVED)
    {
      m = gfc_get_pdt_instance (decl_type_param_list, &dt_sym, NULL);
      if (m != MATCH_YES)
	return m;
      gcc_assert (!dt_sym->attr.pdt_template && dt_sym->attr.pdt_type);
    }

  if (!dt_sym)
    {
      gfc_interface *intr, *head;

      /* Use upper case to save the actual derived-type symbol.  */
      gfc_get_symbol (dt_name, NULL, &dt_sym);
      dt_sym->name = gfc_get_string ("%s", sym->name);
      head = sym->generic;
      intr = gfc_get_interface ();
      intr->sym = dt_sym;
      intr->where = gfc_current_locus;
      intr->next = head;
      sym->generic = intr;
      sym->attr.if_source = IFSRC_DECL;
    }
  else
    gfc_save_symbol_data (dt_sym);

  gfc_set_sym_referenced (dt_sym);

  if (dt_sym->attr.flavor != FL_DERIVED && dt_sym->attr.flavor != FL_STRUCT
      && !gfc_add_flavor (&dt_sym->attr, FL_DERIVED, sym->name, NULL))
    return MATCH_ERROR;

  ts->u.derived = dt_sym;

  return MATCH_YES;

get_kind:
  if (matched_type
      && !gfc_notify_std (GFC_STD_F2008, "TYPE with "
			  "intrinsic-type-spec at %C"))
    return MATCH_ERROR;

  /* For all types except double, derived and character, look for an
     optional kind specifier.  MATCH_NO is actually OK at this point.  */
  if (implicit_flag == 1)
    {
	if (matched_type && gfc_match_char (')') != MATCH_YES)
	  return MATCH_ERROR;

	return MATCH_YES;
    }

  if (gfc_current_form == FORM_FREE)
    {
      c = gfc_peek_ascii_char ();
      if (!gfc_is_whitespace (c) && c != '*' && c != '('
	  && c != ':' && c != ',')
        {
	  if (matched_type && c == ')')
	    {
	      gfc_next_ascii_char ();
	      return MATCH_YES;
	    }
	  gfc_error ("Malformed type-spec at %C");
	  return MATCH_NO;
	}
    }

  m = gfc_match_kind_spec (ts, false);
  if (m == MATCH_NO && ts->type != BT_CHARACTER)
    {
      m = gfc_match_old_kind_spec (ts);
      if (gfc_validate_kind (ts->type, ts->kind, true) == -1)
         return MATCH_ERROR;
    }

  if (matched_type && gfc_match_char (')') != MATCH_YES)
    {
      gfc_error ("Malformed type-spec at %C");
      return MATCH_ERROR;
    }

  /* Defer association of the KIND expression of function results
     until after USE and IMPORT statements.  */
  if ((gfc_current_state () == COMP_NONE && gfc_error_flag_test ())
	 || gfc_matching_function)
    return MATCH_YES;

  if (m == MATCH_NO)
    m = MATCH_YES;		/* No kind specifier found.  */

  return m;
}


/* Match an IMPLICIT NONE statement.  Actually, this statement is
   already matched in parse.cc, or we would not end up here in the
   first place.  So the only thing we need to check, is if there is
   trailing garbage.  If not, the match is successful.  */

match
gfc_match_implicit_none (void)
{
  char c;
  match m;
  char name[GFC_MAX_SYMBOL_LEN + 1];
  bool type = false;
  bool external = false;
  locus cur_loc = gfc_current_locus;

  if (gfc_current_ns->seen_implicit_none
      || gfc_current_ns->has_implicit_none_export)
    {
      gfc_error ("Duplicate IMPLICIT NONE statement at %C");
      return MATCH_ERROR;
    }

  gfc_gobble_whitespace ();
  c = gfc_peek_ascii_char ();
  if (c == '(')
    {
      (void) gfc_next_ascii_char ();
      if (!gfc_notify_std (GFC_STD_F2018, "IMPLICIT NONE with spec list at %C"))
	return MATCH_ERROR;

      gfc_gobble_whitespace ();
      if (gfc_peek_ascii_char () == ')')
	{
	  (void) gfc_next_ascii_char ();
	  type = true;
	}
      else
	for(;;)
	  {
	    m = gfc_match (" %n", name);
	    if (m != MATCH_YES)
	      return MATCH_ERROR;

	    if (strcmp (name, "type") == 0)
	      type = true;
	    else if (strcmp (name, "external") == 0)
	      external = true;
	    else
	      return MATCH_ERROR;

	    gfc_gobble_whitespace ();
	    c = gfc_next_ascii_char ();
	    if (c == ',')
	      continue;
	    if (c == ')')
	      break;
	    return MATCH_ERROR;
	  }
    }
  else
    type = true;

  if (gfc_match_eos () != MATCH_YES)
    return MATCH_ERROR;

  gfc_set_implicit_none (type, external, &cur_loc);

  return MATCH_YES;
}


/* Match the letter range(s) of an IMPLICIT statement.  */

static match
match_implicit_range (void)
{
  char c, c1, c2;
  int inner;
  locus cur_loc;

  cur_loc = gfc_current_locus;

  gfc_gobble_whitespace ();
  c = gfc_next_ascii_char ();
  if (c != '(')
    {
      gfc_error ("Missing character range in IMPLICIT at %C");
      goto bad;
    }

  inner = 1;
  while (inner)
    {
      gfc_gobble_whitespace ();
      c1 = gfc_next_ascii_char ();
      if (!ISALPHA (c1))
	goto bad;

      gfc_gobble_whitespace ();
      c = gfc_next_ascii_char ();

      switch (c)
	{
	case ')':
	  inner = 0;		/* Fall through.  */

	case ',':
	  c2 = c1;
	  break;

	case '-':
	  gfc_gobble_whitespace ();
	  c2 = gfc_next_ascii_char ();
	  if (!ISALPHA (c2))
	    goto bad;

	  gfc_gobble_whitespace ();
	  c = gfc_next_ascii_char ();

	  if ((c != ',') && (c != ')'))
	    goto bad;
	  if (c == ')')
	    inner = 0;

	  break;

	default:
	  goto bad;
	}

      if (c1 > c2)
	{
	  gfc_error ("Letters must be in alphabetic order in "
		     "IMPLICIT statement at %C");
	  goto bad;
	}

      /* See if we can add the newly matched range to the pending
	 implicits from this IMPLICIT statement.  We do not check for
	 conflicts with whatever earlier IMPLICIT statements may have
	 set.  This is done when we've successfully finished matching
	 the current one.  */
      if (!gfc_add_new_implicit_range (c1, c2))
	goto bad;
    }

  return MATCH_YES;

bad:
  gfc_syntax_error (ST_IMPLICIT);

  gfc_current_locus = cur_loc;
  return MATCH_ERROR;
}


/* Match an IMPLICIT statement, storing the types for
   gfc_set_implicit() if the statement is accepted by the parser.
   There is a strange looking, but legal syntactic construction
   possible.  It looks like:

     IMPLICIT INTEGER (a-b) (c-d)

   This is legal if "a-b" is a constant expression that happens to
   equal one of the legal kinds for integers.  The real problem
   happens with an implicit specification that looks like:

     IMPLICIT INTEGER (a-b)

   In this case, a typespec matcher that is "greedy" (as most of the
   matchers are) gobbles the character range as a kindspec, leaving
   nothing left.  We therefore have to go a bit more slowly in the
   matching process by inhibiting the kindspec checking during
   typespec matching and checking for a kind later.  */

match
gfc_match_implicit (void)
{
  gfc_typespec ts;
  locus cur_loc;
  char c;
  match m;

  if (gfc_current_ns->seen_implicit_none)
    {
      gfc_error ("IMPLICIT statement at %C following an IMPLICIT NONE (type) "
		 "statement");
      return MATCH_ERROR;
    }

  gfc_clear_ts (&ts);

  /* We don't allow empty implicit statements.  */
  if (gfc_match_eos () == MATCH_YES)
    {
      gfc_error ("Empty IMPLICIT statement at %C");
      return MATCH_ERROR;
    }

  do
    {
      /* First cleanup.  */
      gfc_clear_new_implicit ();

      /* A basic type is mandatory here.  */
      m = gfc_match_decl_type_spec (&ts, 1);
      if (m == MATCH_ERROR)
	goto error;
      if (m == MATCH_NO)
	goto syntax;

      cur_loc = gfc_current_locus;
      m = match_implicit_range ();

      if (m == MATCH_YES)
	{
	  /* We may have <TYPE> (<RANGE>).  */
	  gfc_gobble_whitespace ();
          c = gfc_peek_ascii_char ();
	  if (c == ',' || c == '\n' || c == ';' || c == '!')
	    {
	      /* Check for CHARACTER with no length parameter.  */
	      if (ts.type == BT_CHARACTER && !ts.u.cl)
		{
		  ts.kind = gfc_default_character_kind;
		  ts.u.cl = gfc_new_charlen (gfc_current_ns, NULL);
		  ts.u.cl->length = gfc_get_int_expr (gfc_charlen_int_kind,
						      NULL, 1);
		}

	      /* Record the Successful match.  */
	      if (!gfc_merge_new_implicit (&ts))
		return MATCH_ERROR;
	      if (c == ',')
		c = gfc_next_ascii_char ();
	      else if (gfc_match_eos () == MATCH_ERROR)
		goto error;
	      continue;
	    }

	  gfc_current_locus = cur_loc;
	}

      /* Discard the (incorrectly) matched range.  */
      gfc_clear_new_implicit ();

      /* Last chance -- check <TYPE> <SELECTOR> (<RANGE>).  */
      if (ts.type == BT_CHARACTER)
	m = gfc_match_char_spec (&ts);
      else if (gfc_numeric_ts(&ts) || ts.type == BT_LOGICAL)
	{
	  m = gfc_match_kind_spec (&ts, false);
	  if (m == MATCH_NO)
	    {
	      m = gfc_match_old_kind_spec (&ts);
	      if (m == MATCH_ERROR)
		goto error;
	      if (m == MATCH_NO)
		goto syntax;
	    }
	}
      if (m == MATCH_ERROR)
	goto error;

      m = match_implicit_range ();
      if (m == MATCH_ERROR)
	goto error;
      if (m == MATCH_NO)
	goto syntax;

      gfc_gobble_whitespace ();
      c = gfc_next_ascii_char ();
      if (c != ',' && gfc_match_eos () != MATCH_YES)
	goto syntax;

      if (!gfc_merge_new_implicit (&ts))
	return MATCH_ERROR;
    }
  while (c == ',');

  return MATCH_YES;

syntax:
  gfc_syntax_error (ST_IMPLICIT);

error:
  return MATCH_ERROR;
}


match
gfc_match_import (void)
{
  char name[GFC_MAX_SYMBOL_LEN + 1];
  match m;
  gfc_symbol *sym;
  gfc_symtree *st;

  if (gfc_current_ns->proc_name == NULL
      || gfc_current_ns->proc_name->attr.if_source != IFSRC_IFBODY)
    {
      gfc_error ("IMPORT statement at %C only permitted in "
		 "an INTERFACE body");
      return MATCH_ERROR;
    }

  if (gfc_current_ns->proc_name->attr.module_procedure)
    {
      gfc_error ("F2008: C1210 IMPORT statement at %C is not permitted "
		 "in a module procedure interface body");
      return MATCH_ERROR;
    }

  if (!gfc_notify_std (GFC_STD_F2003, "IMPORT statement at %C"))
    return MATCH_ERROR;

  if (gfc_match_eos () == MATCH_YES)
    {
      /* All host variables should be imported.  */
      gfc_current_ns->has_import_set = 1;
      return MATCH_YES;
    }

  if (gfc_match (" ::") == MATCH_YES)
    {
      if (gfc_match_eos () == MATCH_YES)
	{
	   gfc_error ("Expecting list of named entities at %C");
	   return MATCH_ERROR;
	}
    }

  for(;;)
    {
      sym = NULL;
      m = gfc_match (" %n", name);
      switch (m)
	{
	case MATCH_YES:
	  if (gfc_current_ns->parent !=  NULL
	      && gfc_find_symbol (name, gfc_current_ns->parent, 1, &sym))
	    {
	       gfc_error ("Type name %qs at %C is ambiguous", name);
	       return MATCH_ERROR;
	    }
	  else if (!sym && gfc_current_ns->proc_name->ns->parent !=  NULL
		   && gfc_find_symbol (name,
				       gfc_current_ns->proc_name->ns->parent,
				       1, &sym))
	    {
	       gfc_error ("Type name %qs at %C is ambiguous", name);
	       return MATCH_ERROR;
	    }

	  if (sym == NULL)
	    {
	      gfc_error ("Cannot IMPORT %qs from host scoping unit "
			 "at %C - does not exist.", name);
	      return MATCH_ERROR;
	    }

	  if (gfc_find_symtree (gfc_current_ns->sym_root, name))
	    {
	      gfc_warning (0, "%qs is already IMPORTed from host scoping unit "
			   "at %C", name);
	      goto next_item;
	    }

	  st = gfc_new_symtree (&gfc_current_ns->sym_root, name);
	  st->n.sym = sym;
	  sym->refs++;
	  sym->attr.imported = 1;

	  if (sym->attr.generic && (sym = gfc_find_dt_in_generic (sym)))
	    {
	      /* The actual derived type is stored in a symtree with the first
		 letter of the name capitalized; the symtree with the all
		 lower-case name contains the associated generic function.  */
	      st = gfc_new_symtree (&gfc_current_ns->sym_root,
                                    gfc_dt_upper_string (name));
	      st->n.sym = sym;
	      sym->refs++;
	      sym->attr.imported = 1;
	    }

	  goto next_item;

	case MATCH_NO:
	  break;

	case MATCH_ERROR:
	  return MATCH_ERROR;
	}

    next_item:
      if (gfc_match_eos () == MATCH_YES)
	break;
      if (gfc_match_char (',') != MATCH_YES)
	goto syntax;
    }

  return MATCH_YES;

syntax:
  gfc_error ("Syntax error in IMPORT statement at %C");
  return MATCH_ERROR;
}


/* A minimal implementation of gfc_match without whitespace, escape
   characters or variable arguments.  Returns true if the next
   characters match the TARGET template exactly.  */

static bool
match_string_p (const char *target)
{
  const char *p;

  for (p = target; *p; p++)
    if ((char) gfc_next_ascii_char () != *p)
      return false;
  return true;
}

/* Matches an attribute specification including array specs.  If
   successful, leaves the variables current_attr and current_as
   holding the specification.  Also sets the colon_seen variable for
   later use by matchers associated with initializations.

   This subroutine is a little tricky in the sense that we don't know
   if we really have an attr-spec until we hit the double colon.
   Until that time, we can only return MATCH_NO.  This forces us to
   check for duplicate specification at this level.  */

static match
match_attr_spec (void)
{
  /* Modifiers that can exist in a type statement.  */
  enum
  { GFC_DECL_BEGIN = 0, DECL_ALLOCATABLE = GFC_DECL_BEGIN,
    DECL_IN = INTENT_IN, DECL_OUT = INTENT_OUT, DECL_INOUT = INTENT_INOUT,
    DECL_DIMENSION, DECL_EXTERNAL,
    DECL_INTRINSIC, DECL_OPTIONAL,
    DECL_PARAMETER, DECL_POINTER, DECL_PROTECTED, DECL_PRIVATE,
    DECL_STATIC, DECL_AUTOMATIC,
    DECL_PUBLIC, DECL_SAVE, DECL_TARGET, DECL_VALUE, DECL_VOLATILE,
    DECL_IS_BIND_C, DECL_CODIMENSION, DECL_ASYNCHRONOUS, DECL_CONTIGUOUS,
    DECL_LEN, DECL_KIND, DECL_NONE, GFC_DECL_END /* Sentinel */
  };

/* GFC_DECL_END is the sentinel, index starts at 0.  */
#define NUM_DECL GFC_DECL_END

  /* Make sure that values from sym_intent are safe to be used here.  */
  gcc_assert (INTENT_IN > 0);

  locus start, seen_at[NUM_DECL];
  int seen[NUM_DECL];
  unsigned int d;
  const char *attr;
  match m;
  bool t;

  gfc_clear_attr (&current_attr);
  start = gfc_current_locus;

  current_as = NULL;
  colon_seen = 0;
  attr_seen = 0;

  /* See if we get all of the keywords up to the final double colon.  */
  for (d = GFC_DECL_BEGIN; d != GFC_DECL_END; d++)
    seen[d] = 0;

  for (;;)
    {
      char ch;

      d = DECL_NONE;
      gfc_gobble_whitespace ();

      ch = gfc_next_ascii_char ();
      if (ch == ':')
	{
	  /* This is the successful exit condition for the loop.  */
	  if (gfc_next_ascii_char () == ':')
	    break;
	}
      else if (ch == ',')
	{
	  gfc_gobble_whitespace ();
	  switch (gfc_peek_ascii_char ())
	    {
	    case 'a':
	      gfc_next_ascii_char ();
	      switch (gfc_next_ascii_char ())
		{
		case 'l':
		  if (match_string_p ("locatable"))
		    {
		      /* Matched "allocatable".  */
		      d = DECL_ALLOCATABLE;
		    }
		  break;

		case 's':
		  if (match_string_p ("ynchronous"))
		    {
		      /* Matched "asynchronous".  */
		      d = DECL_ASYNCHRONOUS;
		    }
		  break;

		case 'u':
		  if (match_string_p ("tomatic"))
		    {
		      /* Matched "automatic".  */
		      d = DECL_AUTOMATIC;
		    }
		  break;
		}
	      break;

	    case 'b':
	      /* Try and match the bind(c).  */
	      m = gfc_match_bind_c (NULL, true);
	      if (m == MATCH_YES)
		d = DECL_IS_BIND_C;
	      else if (m == MATCH_ERROR)
		goto cleanup;
	      break;

	    case 'c':
	      gfc_next_ascii_char ();
	      if ('o' != gfc_next_ascii_char ())
		break;
	      switch (gfc_next_ascii_char ())
		{
		case 'd':
		  if (match_string_p ("imension"))
		    {
		      d = DECL_CODIMENSION;
		      break;
		    }
		  /* FALLTHRU */
		case 'n':
		  if (match_string_p ("tiguous"))
		    {
		      d = DECL_CONTIGUOUS;
		      break;
		    }
		}
	      break;

	    case 'd':
	      if (match_string_p ("dimension"))
		d = DECL_DIMENSION;
	      break;

	    case 'e':
	      if (match_string_p ("external"))
		d = DECL_EXTERNAL;
	      break;

	    case 'i':
	      if (match_string_p ("int"))
		{
		  ch = gfc_next_ascii_char ();
		  if (ch == 'e')
		    {
		      if (match_string_p ("nt"))
			{
			  /* Matched "intent".  */
			  d = match_intent_spec ();
			  if (d == INTENT_UNKNOWN)
			    {
			      m = MATCH_ERROR;
			      goto cleanup;
			    }
			}
		    }
		  else if (ch == 'r')
		    {
		      if (match_string_p ("insic"))
			{
			  /* Matched "intrinsic".  */
			  d = DECL_INTRINSIC;
			}
		    }
		}
	      break;

	    case 'k':
	      if (match_string_p ("kind"))
		d = DECL_KIND;
	      break;

	    case 'l':
	      if (match_string_p ("len"))
		d = DECL_LEN;
	      break;

	    case 'o':
	      if (match_string_p ("optional"))
		d = DECL_OPTIONAL;
	      break;

	    case 'p':
	      gfc_next_ascii_char ();
	      switch (gfc_next_ascii_char ())
		{
		case 'a':
		  if (match_string_p ("rameter"))
		    {
		      /* Matched "parameter".  */
		      d = DECL_PARAMETER;
		    }
		  break;

		case 'o':
		  if (match_string_p ("inter"))
		    {
		      /* Matched "pointer".  */
		      d = DECL_POINTER;
		    }
		  break;

		case 'r':
		  ch = gfc_next_ascii_char ();
		  if (ch == 'i')
		    {
		      if (match_string_p ("vate"))
			{
			  /* Matched "private".  */
			  d = DECL_PRIVATE;
			}
		    }
		  else if (ch == 'o')
		    {
		      if (match_string_p ("tected"))
			{
			  /* Matched "protected".  */
			  d = DECL_PROTECTED;
			}
		    }
		  break;

		case 'u':
		  if (match_string_p ("blic"))
		    {
		      /* Matched "public".  */
		      d = DECL_PUBLIC;
		    }
		  break;
		}
	      break;

	    case 's':
	      gfc_next_ascii_char ();
	      switch (gfc_next_ascii_char ())
		{
		  case 'a':
		    if (match_string_p ("ve"))
		      {
			/* Matched "save".  */
			d = DECL_SAVE;
		      }
		    break;

		  case 't':
		    if (match_string_p ("atic"))
		      {
			/* Matched "static".  */
			d = DECL_STATIC;
		      }
		    break;
		}
	      break;

	    case 't':
	      if (match_string_p ("target"))
		d = DECL_TARGET;
	      break;

	    case 'v':
	      gfc_next_ascii_char ();
	      ch = gfc_next_ascii_char ();
	      if (ch == 'a')
		{
		  if (match_string_p ("lue"))
		    {
		      /* Matched "value".  */
		      d = DECL_VALUE;
		    }
		}
	      else if (ch == 'o')
		{
		  if (match_string_p ("latile"))
		    {
		      /* Matched "volatile".  */
		      d = DECL_VOLATILE;
		    }
		}
	      break;
	    }
	}

      /* No double colon and no recognizable decl_type, so assume that
	 we've been looking at something else the whole time.  */
      if (d == DECL_NONE)
	{
	  m = MATCH_NO;
	  goto cleanup;
	}

      /* Check to make sure any parens are paired up correctly.  */
      if (gfc_match_parens () == MATCH_ERROR)
	{
	  m = MATCH_ERROR;
	  goto cleanup;
	}

      seen[d]++;
      seen_at[d] = gfc_current_locus;

      if (d == DECL_DIMENSION || d == DECL_CODIMENSION)
	{
	  gfc_array_spec *as = NULL;

	  m = gfc_match_array_spec (&as, d == DECL_DIMENSION,
				    d == DECL_CODIMENSION);

	  if (current_as == NULL)
	    current_as = as;
	  else if (m == MATCH_YES)
	    {
	      if (!merge_array_spec (as, current_as, false))
		m = MATCH_ERROR;
	      free (as);
	    }

	  if (m == MATCH_NO)
	    {
	      if (d == DECL_CODIMENSION)
		gfc_error ("Missing codimension specification at %C");
	      else
		gfc_error ("Missing dimension specification at %C");
	      m = MATCH_ERROR;
	    }

	  if (m == MATCH_ERROR)
	    goto cleanup;
	}
    }

  /* Since we've seen a double colon, we have to be looking at an
     attr-spec.  This means that we can now issue errors.  */
  for (d = GFC_DECL_BEGIN; d != GFC_DECL_END; d++)
    if (seen[d] > 1)
      {
	switch (d)
	  {
	  case DECL_ALLOCATABLE:
	    attr = "ALLOCATABLE";
	    break;
	  case DECL_ASYNCHRONOUS:
	    attr = "ASYNCHRONOUS";
	    break;
	  case DECL_CODIMENSION:
	    attr = "CODIMENSION";
	    break;
	  case DECL_CONTIGUOUS:
	    attr = "CONTIGUOUS";
	    break;
	  case DECL_DIMENSION:
	    attr = "DIMENSION";
	    break;
	  case DECL_EXTERNAL:
	    attr = "EXTERNAL";
	    break;
	  case DECL_IN:
	    attr = "INTENT (IN)";
	    break;
	  case DECL_OUT:
	    attr = "INTENT (OUT)";
	    break;
	  case DECL_INOUT:
	    attr = "INTENT (IN OUT)";
	    break;
	  case DECL_INTRINSIC:
	    attr = "INTRINSIC";
	    break;
	  case DECL_OPTIONAL:
	    attr = "OPTIONAL";
	    break;
	  case DECL_KIND:
	    attr = "KIND";
	    break;
	  case DECL_LEN:
	    attr = "LEN";
	    break;
	  case DECL_PARAMETER:
	    attr = "PARAMETER";
	    break;
	  case DECL_POINTER:
	    attr = "POINTER";
	    break;
	  case DECL_PROTECTED:
	    attr = "PROTECTED";
	    break;
	  case DECL_PRIVATE:
	    attr = "PRIVATE";
	    break;
	  case DECL_PUBLIC:
	    attr = "PUBLIC";
	    break;
	  case DECL_SAVE:
	    attr = "SAVE";
	    break;
	  case DECL_STATIC:
	    attr = "STATIC";
	    break;
	  case DECL_AUTOMATIC:
	    attr = "AUTOMATIC";
	    break;
	  case DECL_TARGET:
	    attr = "TARGET";
	    break;
          case DECL_IS_BIND_C:
            attr = "IS_BIND_C";
            break;
          case DECL_VALUE:
            attr = "VALUE";
            break;
	  case DECL_VOLATILE:
	    attr = "VOLATILE";
	    break;
	  default:
	    attr = NULL;	/* This shouldn't happen.  */
	  }

	gfc_error ("Duplicate %s attribute at %L", attr, &seen_at[d]);
	m = MATCH_ERROR;
	goto cleanup;
      }

  /* Now that we've dealt with duplicate attributes, add the attributes
     to the current attribute.  */
  for (d = GFC_DECL_BEGIN; d != GFC_DECL_END; d++)
    {
      if (seen[d] == 0)
	continue;
      else
        attr_seen = 1;

      if ((d == DECL_STATIC || d == DECL_AUTOMATIC)
	  && !flag_dec_static)
	{
	  gfc_error ("%s at %L is a DEC extension, enable with "
		     "%<-fdec-static%>",
		     d == DECL_STATIC ? "STATIC" : "AUTOMATIC", &seen_at[d]);
	  m = MATCH_ERROR;
	  goto cleanup;
	}
      /* Allow SAVE with STATIC, but don't complain.  */
      if (d == DECL_STATIC && seen[DECL_SAVE])
	continue;

      if (gfc_comp_struct (gfc_current_state ())
	  && d != DECL_DIMENSION && d != DECL_CODIMENSION
	  && d != DECL_POINTER   && d != DECL_PRIVATE
	  && d != DECL_PUBLIC && d != DECL_CONTIGUOUS && d != DECL_NONE)
	{
	  bool is_derived = gfc_current_state () == COMP_DERIVED;
	  if (d == DECL_ALLOCATABLE)
	    {
	      if (!gfc_notify_std (GFC_STD_F2003, is_derived
				   ? G_("ALLOCATABLE attribute at %C in a "
					"TYPE definition")
				   : G_("ALLOCATABLE attribute at %C in a "
					"STRUCTURE definition")))
		{
		  m = MATCH_ERROR;
		  goto cleanup;
		}
	    }
	  else if (d == DECL_KIND)
	    {
	      if (!gfc_notify_std (GFC_STD_F2003, is_derived
				   ? G_("KIND attribute at %C in a "
					"TYPE definition")
				   : G_("KIND attribute at %C in a "
					"STRUCTURE definition")))
		{
		  m = MATCH_ERROR;
		  goto cleanup;
		}
	      if (current_ts.type != BT_INTEGER)
		{
		  gfc_error ("Component with KIND attribute at %C must be "
			     "INTEGER");
		  m = MATCH_ERROR;
		  goto cleanup;
		}
	    }
	  else if (d == DECL_LEN)
	    {
	      if (!gfc_notify_std (GFC_STD_F2003, is_derived
				   ? G_("LEN attribute at %C in a "
					"TYPE definition")
				   : G_("LEN attribute at %C in a "
					"STRUCTURE definition")))
		{
		  m = MATCH_ERROR;
		  goto cleanup;
		}
	      if (current_ts.type != BT_INTEGER)
		{
		  gfc_error ("Component with LEN attribute at %C must be "
			     "INTEGER");
		  m = MATCH_ERROR;
		  goto cleanup;
		}
	    }
	  else
	    {
	      gfc_error (is_derived ? G_("Attribute at %L is not allowed in a "
					 "TYPE definition")
				    : G_("Attribute at %L is not allowed in a "
					 "STRUCTURE definition"), &seen_at[d]);
	      m = MATCH_ERROR;
	      goto cleanup;
	    }
	}

      if ((d == DECL_PRIVATE || d == DECL_PUBLIC)
	  && gfc_current_state () != COMP_MODULE)
	{
	  if (d == DECL_PRIVATE)
	    attr = "PRIVATE";
	  else
	    attr = "PUBLIC";
	  if (gfc_current_state () == COMP_DERIVED
	      && gfc_state_stack->previous
	      && gfc_state_stack->previous->state == COMP_MODULE)
	    {
	      if (!gfc_notify_std (GFC_STD_F2003, "Attribute %s "
				   "at %L in a TYPE definition", attr,
				   &seen_at[d]))
		{
		  m = MATCH_ERROR;
		  goto cleanup;
		}
	    }
	  else
	    {
	      gfc_error ("%s attribute at %L is not allowed outside of the "
			 "specification part of a module", attr, &seen_at[d]);
	      m = MATCH_ERROR;
	      goto cleanup;
	    }
	}

      if (gfc_current_state () != COMP_DERIVED
	  && (d == DECL_KIND || d == DECL_LEN))
	{
	  gfc_error ("Attribute at %L is not allowed outside a TYPE "
		     "definition", &seen_at[d]);
	  m = MATCH_ERROR;
	  goto cleanup;
	}

      switch (d)
	{
	case DECL_ALLOCATABLE:
	  t = gfc_add_allocatable (&current_attr, &seen_at[d]);
	  break;

	case DECL_ASYNCHRONOUS:
	  if (!gfc_notify_std (GFC_STD_F2003, "ASYNCHRONOUS attribute at %C"))
	    t = false;
	  else
	    t = gfc_add_asynchronous (&current_attr, NULL, &seen_at[d]);
	  break;

	case DECL_CODIMENSION:
	  t = gfc_add_codimension (&current_attr, NULL, &seen_at[d]);
	  break;

	case DECL_CONTIGUOUS:
	  if (!gfc_notify_std (GFC_STD_F2008, "CONTIGUOUS attribute at %C"))
	    t = false;
	  else
	    t = gfc_add_contiguous (&current_attr, NULL, &seen_at[d]);
	  break;

	case DECL_DIMENSION:
	  t = gfc_add_dimension (&current_attr, NULL, &seen_at[d]);
	  break;

	case DECL_EXTERNAL:
	  t = gfc_add_external (&current_attr, &seen_at[d]);
	  break;

	case DECL_IN:
	  t = gfc_add_intent (&current_attr, INTENT_IN, &seen_at[d]);
	  break;

	case DECL_OUT:
	  t = gfc_add_intent (&current_attr, INTENT_OUT, &seen_at[d]);
	  break;

	case DECL_INOUT:
	  t = gfc_add_intent (&current_attr, INTENT_INOUT, &seen_at[d]);
	  break;

	case DECL_INTRINSIC:
	  t = gfc_add_intrinsic (&current_attr, &seen_at[d]);
	  break;

	case DECL_OPTIONAL:
	  t = gfc_add_optional (&current_attr, &seen_at[d]);
	  break;

	case DECL_KIND:
	  t = gfc_add_kind (&current_attr, &seen_at[d]);
	  break;

	case DECL_LEN:
	  t = gfc_add_len (&current_attr, &seen_at[d]);
	  break;

	case DECL_PARAMETER:
	  t = gfc_add_flavor (&current_attr, FL_PARAMETER, NULL, &seen_at[d]);
	  break;

	case DECL_POINTER:
	  t = gfc_add_pointer (&current_attr, &seen_at[d]);
	  break;

	case DECL_PROTECTED:
	  if (gfc_current_state () != COMP_MODULE
	      || (gfc_current_ns->proc_name
		  && gfc_current_ns->proc_name->attr.flavor != FL_MODULE))
	    {
	       gfc_error ("PROTECTED at %C only allowed in specification "
			  "part of a module");
	       t = false;
	       break;
	    }

	  if (!gfc_notify_std (GFC_STD_F2003, "PROTECTED attribute at %C"))
	    t = false;
	  else
	    t = gfc_add_protected (&current_attr, NULL, &seen_at[d]);
	  break;

	case DECL_PRIVATE:
	  t = gfc_add_access (&current_attr, ACCESS_PRIVATE, NULL,
			      &seen_at[d]);
	  break;

	case DECL_PUBLIC:
	  t = gfc_add_access (&current_attr, ACCESS_PUBLIC, NULL,
			      &seen_at[d]);
	  break;

	case DECL_STATIC:
	case DECL_SAVE:
	  t = gfc_add_save (&current_attr, SAVE_EXPLICIT, NULL, &seen_at[d]);
	  break;

	case DECL_AUTOMATIC:
	  t = gfc_add_automatic (&current_attr, NULL, &seen_at[d]);
	  break;

	case DECL_TARGET:
	  t = gfc_add_target (&current_attr, &seen_at[d]);
	  break;

        case DECL_IS_BIND_C:
           t = gfc_add_is_bind_c(&current_attr, NULL, &seen_at[d], 0);
           break;

	case DECL_VALUE:
	  if (!gfc_notify_std (GFC_STD_F2003, "VALUE attribute at %C"))
	    t = false;
	  else
	    t = gfc_add_value (&current_attr, NULL, &seen_at[d]);
	  break;

	case DECL_VOLATILE:
	  if (!gfc_notify_std (GFC_STD_F2003, "VOLATILE attribute at %C"))
	    t = false;
	  else
	    t = gfc_add_volatile (&current_attr, NULL, &seen_at[d]);
	  break;

	default:
	  gfc_internal_error ("match_attr_spec(): Bad attribute");
	}

      if (!t)
	{
	  m = MATCH_ERROR;
	  goto cleanup;
	}
    }

  /* Since Fortran 2008 module variables implicitly have the SAVE attribute.  */
  if ((gfc_current_state () == COMP_MODULE
       || gfc_current_state () == COMP_SUBMODULE)
      && !current_attr.save
      && (gfc_option.allow_std & GFC_STD_F2008) != 0)
    current_attr.save = SAVE_IMPLICIT;

  colon_seen = 1;
  return MATCH_YES;

cleanup:
  gfc_current_locus = start;
  gfc_free_array_spec (current_as);
  current_as = NULL;
  attr_seen = 0;
  return m;
}


/* Set the binding label, dest_label, either with the binding label
   stored in the given gfc_typespec, ts, or if none was provided, it
   will be the symbol name in all lower case, as required by the draft
   (J3/04-007, section 15.4.1).  If a binding label was given and
   there is more than one argument (num_idents), it is an error.  */

static bool
set_binding_label (const char **dest_label, const char *sym_name,
		   int num_idents)
{
  if (num_idents > 1 && has_name_equals)
    {
      gfc_error ("Multiple identifiers provided with "
		 "single NAME= specifier at %C");
      return false;
    }

  if (curr_binding_label)
    /* Binding label given; store in temp holder till have sym.  */
    *dest_label = curr_binding_label;
  else
    {
      /* No binding label given, and the NAME= specifier did not exist,
         which means there was no NAME="".  */
      if (sym_name != NULL && has_name_equals == 0)
        *dest_label = IDENTIFIER_POINTER (get_identifier (sym_name));
    }

  return true;
}


/* Set the status of the given common block as being BIND(C) or not,
   depending on the given parameter, is_bind_c.  */

static void
set_com_block_bind_c (gfc_common_head *com_block, int is_bind_c)
{
  com_block->is_bind_c = is_bind_c;
  return;
}


/* Verify that the given gfc_typespec is for a C interoperable type.  */

bool
gfc_verify_c_interop (gfc_typespec *ts)
{
  if (ts->type == BT_DERIVED && ts->u.derived != NULL)
    return (ts->u.derived->ts.is_c_interop || ts->u.derived->attr.is_bind_c)
	   ? true : false;
  else if (ts->type == BT_CLASS)
    return false;
  else if (ts->is_c_interop != 1 && ts->type != BT_ASSUMED)
    return false;

  return true;
}


/* Verify that the variables of a given common block, which has been
   defined with the attribute specifier bind(c), to be of a C
   interoperable type.  Errors will be reported here, if
   encountered.  */

bool
verify_com_block_vars_c_interop (gfc_common_head *com_block)
{
  gfc_symbol *curr_sym = NULL;
  bool retval = true;

  curr_sym = com_block->head;

  /* Make sure we have at least one symbol.  */
  if (curr_sym == NULL)
    return retval;

  /* Here we know we have a symbol, so we'll execute this loop
     at least once.  */
  do
    {
      /* The second to last param, 1, says this is in a common block.  */
      retval = verify_bind_c_sym (curr_sym, &(curr_sym->ts), 1, com_block);
      curr_sym = curr_sym->common_next;
    } while (curr_sym != NULL);

  return retval;
}


/* Verify that a given BIND(C) symbol is C interoperable.  If it is not,
   an appropriate error message is reported.  */

bool
verify_bind_c_sym (gfc_symbol *tmp_sym, gfc_typespec *ts,
                   int is_in_common, gfc_common_head *com_block)
{
  bool bind_c_function = false;
  bool retval = true;

  if (tmp_sym->attr.function && tmp_sym->attr.is_bind_c)
    bind_c_function = true;

  if (tmp_sym->attr.function && tmp_sym->result != NULL)
    {
      tmp_sym = tmp_sym->result;
      /* Make sure it wasn't an implicitly typed result.  */
      if (tmp_sym->attr.implicit_type && warn_c_binding_type)
	{
	  gfc_warning (OPT_Wc_binding_type,
		       "Implicitly declared BIND(C) function %qs at "
                       "%L may not be C interoperable", tmp_sym->name,
                       &tmp_sym->declared_at);
	  tmp_sym->ts.f90_type = tmp_sym->ts.type;
	  /* Mark it as C interoperable to prevent duplicate warnings.	*/
	  tmp_sym->ts.is_c_interop = 1;
	  tmp_sym->attr.is_c_interop = 1;
	}
    }

  /* Here, we know we have the bind(c) attribute, so if we have
     enough type info, then verify that it's a C interop kind.
     The info could be in the symbol already, or possibly still in
     the given ts (current_ts), so look in both.  */
  if (tmp_sym->ts.type != BT_UNKNOWN || ts->type != BT_UNKNOWN)
    {
      if (!gfc_verify_c_interop (&(tmp_sym->ts)))
	{
	  /* See if we're dealing with a sym in a common block or not.	*/
	  if (is_in_common == 1 && warn_c_binding_type)
	    {
	      gfc_warning (OPT_Wc_binding_type,
			   "Variable %qs in common block %qs at %L "
                           "may not be a C interoperable "
                           "kind though common block %qs is BIND(C)",
                           tmp_sym->name, com_block->name,
                           &(tmp_sym->declared_at), com_block->name);
	    }
	  else
	    {
              if (tmp_sym->ts.type == BT_DERIVED || ts->type == BT_DERIVED)
                gfc_error ("Type declaration %qs at %L is not C "
                           "interoperable but it is BIND(C)",
                           tmp_sym->name, &(tmp_sym->declared_at));
              else if (warn_c_binding_type)
                gfc_warning (OPT_Wc_binding_type, "Variable %qs at %L "
                             "may not be a C interoperable "
                             "kind but it is BIND(C)",
                             tmp_sym->name, &(tmp_sym->declared_at));
	    }
	}

      /* Variables declared w/in a common block can't be bind(c)
	 since there's no way for C to see these variables, so there's
	 semantically no reason for the attribute.  */
      if (is_in_common == 1 && tmp_sym->attr.is_bind_c == 1)
	{
	  gfc_error ("Variable %qs in common block %qs at "
		     "%L cannot be declared with BIND(C) "
		     "since it is not a global",
		     tmp_sym->name, com_block->name,
		     &(tmp_sym->declared_at));
	  retval = false;
	}

      /* Scalar variables that are bind(c) cannot have the pointer
	 or allocatable attributes.  */
      if (tmp_sym->attr.is_bind_c == 1)
	{
	  if (tmp_sym->attr.pointer == 1)
	    {
	      gfc_error ("Variable %qs at %L cannot have both the "
			 "POINTER and BIND(C) attributes",
			 tmp_sym->name, &(tmp_sym->declared_at));
	      retval = false;
	    }

	  if (tmp_sym->attr.allocatable == 1)
	    {
	      gfc_error ("Variable %qs at %L cannot have both the "
			 "ALLOCATABLE and BIND(C) attributes",
			 tmp_sym->name, &(tmp_sym->declared_at));
	      retval = false;
	    }

        }

      /* If it is a BIND(C) function, make sure the return value is a
	 scalar value.  The previous tests in this function made sure
	 the type is interoperable.  */
      if (bind_c_function && tmp_sym->as != NULL)
	gfc_error ("Return type of BIND(C) function %qs at %L cannot "
		   "be an array", tmp_sym->name, &(tmp_sym->declared_at));

      /* BIND(C) functions cannot return a character string.  */
      if (bind_c_function && tmp_sym->ts.type == BT_CHARACTER)
	if (tmp_sym->ts.u.cl == NULL || tmp_sym->ts.u.cl->length == NULL
	    || tmp_sym->ts.u.cl->length->expr_type != EXPR_CONSTANT
	    || mpz_cmp_si (tmp_sym->ts.u.cl->length->value.integer, 1) != 0)
	  gfc_error ("Return type of BIND(C) function %qs of character "
		     "type at %L must have length 1", tmp_sym->name,
			 &(tmp_sym->declared_at));
    }

  /* See if the symbol has been marked as private.  If it has, make sure
     there is no binding label and warn the user if there is one.  */
  if (tmp_sym->attr.access == ACCESS_PRIVATE
      && tmp_sym->binding_label)
      /* Use gfc_warning_now because we won't say that the symbol fails
	 just because of this.	*/
      gfc_warning_now (0, "Symbol %qs at %L is marked PRIVATE but has been "
		       "given the binding label %qs", tmp_sym->name,
		       &(tmp_sym->declared_at), tmp_sym->binding_label);

  return retval;
}


/* Set the appropriate fields for a symbol that's been declared as
   BIND(C) (the is_bind_c flag and the binding label), and verify that
   the type is C interoperable.  Errors are reported by the functions
   used to set/test these fields.  */

static bool
set_verify_bind_c_sym (gfc_symbol *tmp_sym, int num_idents)
{
  bool retval = true;

  /* TODO: Do we need to make sure the vars aren't marked private?  */

  /* Set the is_bind_c bit in symbol_attribute.  */
  gfc_add_is_bind_c (&(tmp_sym->attr), tmp_sym->name, &gfc_current_locus, 0);

  if (!set_binding_label (&tmp_sym->binding_label, tmp_sym->name, num_idents))
    return false;

  return retval;
}


/* Set the fields marking the given common block as BIND(C), including
   a binding label, and report any errors encountered.  */

static bool
set_verify_bind_c_com_block (gfc_common_head *com_block, int num_idents)
{
  bool retval = true;

  /* destLabel, common name, typespec (which may have binding label).  */
  if (!set_binding_label (&com_block->binding_label, com_block->name,
			  num_idents))
    return false;

  /* Set the given common block (com_block) to being bind(c) (1).  */
  set_com_block_bind_c (com_block, 1);

  return retval;
}


/* Retrieve the list of one or more identifiers that the given bind(c)
   attribute applies to.  */

static bool
get_bind_c_idents (void)
{
  char name[GFC_MAX_SYMBOL_LEN + 1];
  int num_idents = 0;
  gfc_symbol *tmp_sym = NULL;
  match found_id;
  gfc_common_head *com_block = NULL;

  if (gfc_match_name (name) == MATCH_YES)
    {
      found_id = MATCH_YES;
      gfc_get_ha_symbol (name, &tmp_sym);
    }
  else if (gfc_match_common_name (name) == MATCH_YES)
    {
      found_id = MATCH_YES;
      com_block = gfc_get_common (name, 0);
    }
  else
    {
      gfc_error ("Need either entity or common block name for "
		 "attribute specification statement at %C");
      return false;
    }

  /* Save the current identifier and look for more.  */
  do
    {
      /* Increment the number of identifiers found for this spec stmt.  */
      num_idents++;

      /* Make sure we have a sym or com block, and verify that it can
	 be bind(c).  Set the appropriate field(s) and look for more
	 identifiers.  */
      if (tmp_sym != NULL || com_block != NULL)
        {
	  if (tmp_sym != NULL)
	    {
	      if (!set_verify_bind_c_sym (tmp_sym, num_idents))
		return false;
	    }
	  else
	    {
	      if (!set_verify_bind_c_com_block (com_block, num_idents))
		return false;
	    }

	  /* Look to see if we have another identifier.  */
	  tmp_sym = NULL;
	  if (gfc_match_eos () == MATCH_YES)
	    found_id = MATCH_NO;
	  else if (gfc_match_char (',') != MATCH_YES)
	    found_id = MATCH_NO;
	  else if (gfc_match_name (name) == MATCH_YES)
	    {
	      found_id = MATCH_YES;
	      gfc_get_ha_symbol (name, &tmp_sym);
	    }
	  else if (gfc_match_common_name (name) == MATCH_YES)
	    {
	      found_id = MATCH_YES;
	      com_block = gfc_get_common (name, 0);
	    }
	  else
	    {
	      gfc_error ("Missing entity or common block name for "
			 "attribute specification statement at %C");
	      return false;
	    }
	}
      else
	{
	  gfc_internal_error ("Missing symbol");
	}
    } while (found_id == MATCH_YES);

  /* if we get here we were successful */
  return true;
}


/* Try and match a BIND(C) attribute specification statement.  */

match
gfc_match_bind_c_stmt (void)
{
  match found_match = MATCH_NO;
  gfc_typespec *ts;

  ts = &current_ts;

  /* This may not be necessary.  */
  gfc_clear_ts (ts);
  /* Clear the temporary binding label holder.  */
  curr_binding_label = NULL;

  /* Look for the bind(c).  */
  found_match = gfc_match_bind_c (NULL, true);

  if (found_match == MATCH_YES)
    {
      if (!gfc_notify_std (GFC_STD_F2003, "BIND(C) statement at %C"))
	return MATCH_ERROR;

      /* Look for the :: now, but it is not required.  */
      gfc_match (" :: ");

      /* Get the identifier(s) that needs to be updated.  This may need to
	 change to hand the flag(s) for the attr specified so all identifiers
	 found can have all appropriate parts updated (assuming that the same
	 spec stmt can have multiple attrs, such as both bind(c) and
	 allocatable...).  */
      if (!get_bind_c_idents ())
	/* Error message should have printed already.  */
	return MATCH_ERROR;
    }

  return found_match;
}


/* Match a data declaration statement.  */

match
gfc_match_data_decl (void)
{
  gfc_symbol *sym;
  match m;
  int elem;

  type_param_spec_list = NULL;
  decl_type_param_list = NULL;

  num_idents_on_line = 0;

  m = gfc_match_decl_type_spec (&current_ts, 0);
  if (m != MATCH_YES)
    return m;

  if ((current_ts.type == BT_DERIVED || current_ts.type == BT_CLASS)
	&& !gfc_comp_struct (gfc_current_state ()))
    {
      sym = gfc_use_derived (current_ts.u.derived);

      if (sym == NULL)
	{
	  m = MATCH_ERROR;
	  goto cleanup;
	}

      current_ts.u.derived = sym;
    }

  m = match_attr_spec ();
  if (m == MATCH_ERROR)
    {
      m = MATCH_NO;
      goto cleanup;
    }

  /* F2018:C708.  */
  if (current_ts.type == BT_CLASS && current_attr.flavor == FL_PARAMETER)
    {
      gfc_error ("CLASS entity at %C cannot have the PARAMETER attribute");
      m = MATCH_ERROR;
      goto cleanup;
    }

  if (current_ts.type == BT_CLASS
	&& current_ts.u.derived->attr.unlimited_polymorphic)
    goto ok;

  if ((current_ts.type == BT_DERIVED || current_ts.type == BT_CLASS)
      && current_ts.u.derived->components == NULL
      && !current_ts.u.derived->attr.zero_comp)
    {

      if (current_attr.pointer && gfc_comp_struct (gfc_current_state ()))
	goto ok;

      if (current_attr.allocatable && gfc_current_state () == COMP_DERIVED)
	goto ok;

      gfc_find_symbol (current_ts.u.derived->name,
		       current_ts.u.derived->ns, 1, &sym);

      /* Any symbol that we find had better be a type definition
	 which has its components defined, or be a structure definition
         actively being parsed.  */
      if (sym != NULL && gfc_fl_struct (sym->attr.flavor)
	  && (current_ts.u.derived->components != NULL
	      || current_ts.u.derived->attr.zero_comp
	      || current_ts.u.derived == gfc_new_block))
	goto ok;

      gfc_error ("Derived type at %C has not been previously defined "
		 "and so cannot appear in a derived type definition");
      m = MATCH_ERROR;
      goto cleanup;
    }

ok:
  /* If we have an old-style character declaration, and no new-style
     attribute specifications, then there a comma is optional between
     the type specification and the variable list.  */
  if (m == MATCH_NO && current_ts.type == BT_CHARACTER && old_char_selector)
    gfc_match_char (',');

  /* Give the types/attributes to symbols that follow. Give the element
     a number so that repeat character length expressions can be copied.  */
  elem = 1;
  for (;;)
    {
      num_idents_on_line++;
      m = variable_decl (elem++);
      if (m == MATCH_ERROR)
	goto cleanup;
      if (m == MATCH_NO)
	break;

      if (gfc_match_eos () == MATCH_YES)
	goto cleanup;
      if (gfc_match_char (',') != MATCH_YES)
	break;
    }

  if (!gfc_error_flag_test ())
    {
      /* An anonymous structure declaration is unambiguous; if we matched one
	 according to gfc_match_structure_decl, we need to return MATCH_YES
	 here to avoid confusing the remaining matchers, even if there was an
	 error during variable_decl.  We must flush any such errors.  Note this
	 causes the parser to gracefully continue parsing the remaining input
	 as a structure body, which likely follows.  */
      if (current_ts.type == BT_DERIVED && current_ts.u.derived
	  && gfc_fl_struct (current_ts.u.derived->attr.flavor))
	{
	  gfc_error_now ("Syntax error in anonymous structure declaration"
			 " at %C");
	  /* Skip the bad variable_decl and line up for the start of the
	     structure body.  */
	  gfc_error_recovery ();
	  m = MATCH_YES;
	  goto cleanup;
	}

      gfc_error ("Syntax error in data declaration at %C");
    }

  m = MATCH_ERROR;

  gfc_free_data_all (gfc_current_ns);

cleanup:
  if (saved_kind_expr)
    gfc_free_expr (saved_kind_expr);
  if (type_param_spec_list)
    gfc_free_actual_arglist (type_param_spec_list);
  if (decl_type_param_list)
    gfc_free_actual_arglist (decl_type_param_list);
  saved_kind_expr = NULL;
  gfc_free_array_spec (current_as);
  current_as = NULL;
  return m;
}

static bool
in_module_or_interface(void)
{
  if (gfc_current_state () == COMP_MODULE
      || gfc_current_state () == COMP_SUBMODULE
      || gfc_current_state () == COMP_INTERFACE)
    return true;

  if (gfc_state_stack->state == COMP_CONTAINS
      || gfc_state_stack->state == COMP_FUNCTION
      || gfc_state_stack->state == COMP_SUBROUTINE)
    {
      gfc_state_data *p;
      for (p = gfc_state_stack->previous; p ; p = p->previous)
	{
	  if (p->state == COMP_MODULE || p->state == COMP_SUBMODULE
	      || p->state == COMP_INTERFACE)
	    return true;
	}
    }
    return false;
}

/* Match a prefix associated with a function or subroutine
   declaration.  If the typespec pointer is nonnull, then a typespec
   can be matched.  Note that if nothing matches, MATCH_YES is
   returned (the null string was matched).  */

match
gfc_match_prefix (gfc_typespec *ts)
{
  bool seen_type;
  bool seen_impure;
  bool found_prefix;

  gfc_clear_attr (&current_attr);
  seen_type = false;
  seen_impure = false;

  gcc_assert (!gfc_matching_prefix);
  gfc_matching_prefix = true;

  do
    {
      found_prefix = false;

      /* MODULE is a prefix like PURE, ELEMENTAL, etc., having a
	 corresponding attribute seems natural and distinguishes these
	 procedures from procedure types of PROC_MODULE, which these are
	 as well.  */
      if (gfc_match ("module% ") == MATCH_YES)
	{
	  if (!gfc_notify_std (GFC_STD_F2008, "MODULE prefix at %C"))
	    goto error;

	  if (!in_module_or_interface ())
	    {
	      gfc_error ("MODULE prefix at %C found outside of a module, "
			 "submodule, or interface");
	      goto error;
	    }

	  current_attr.module_procedure = 1;
	  found_prefix = true;
	}

      if (!seen_type && ts != NULL)
	{
	  match m;
	  m = gfc_match_decl_type_spec (ts, 0);
	  if (m == MATCH_ERROR)
	    goto error;
	  if (m == MATCH_YES && gfc_match_space () == MATCH_YES)
	    {
	      seen_type = true;
	      found_prefix = true;
	    }
	}

      if (gfc_match ("elemental% ") == MATCH_YES)
	{
	  if (!gfc_add_elemental (&current_attr, NULL))
	    goto error;

	  found_prefix = true;
	}

      if (gfc_match ("pure% ") == MATCH_YES)
	{
	  if (!gfc_add_pure (&current_attr, NULL))
	    goto error;

	  found_prefix = true;
	}

      if (gfc_match ("recursive% ") == MATCH_YES)
	{
	  if (!gfc_add_recursive (&current_attr, NULL))
	    goto error;

	  found_prefix = true;
	}

      /* IMPURE is a somewhat special case, as it needs not set an actual
	 attribute but rather only prevents ELEMENTAL routines from being
	 automatically PURE.  */
      if (gfc_match ("impure% ") == MATCH_YES)
	{
	  if (!gfc_notify_std (GFC_STD_F2008, "IMPURE procedure at %C"))
	    goto error;

	  seen_impure = true;
	  found_prefix = true;
	}
    }
  while (found_prefix);

  /* IMPURE and PURE must not both appear, of course.  */
  if (seen_impure && current_attr.pure)
    {
      gfc_error ("PURE and IMPURE must not appear both at %C");
      goto error;
    }

  /* If IMPURE it not seen but the procedure is ELEMENTAL, mark it as PURE.  */
  if (!seen_impure && current_attr.elemental && !current_attr.pure)
    {
      if (!gfc_add_pure (&current_attr, NULL))
	goto error;
    }

  /* At this point, the next item is not a prefix.  */
  gcc_assert (gfc_matching_prefix);

  gfc_matching_prefix = false;
  return MATCH_YES;

error:
  gcc_assert (gfc_matching_prefix);
  gfc_matching_prefix = false;
  return MATCH_ERROR;
}


/* Copy attributes matched by gfc_match_prefix() to attributes on a symbol.  */

static bool
copy_prefix (symbol_attribute *dest, locus *where)
{
  if (dest->module_procedure)
    {
      if (current_attr.elemental)
	dest->elemental = 1;

      if (current_attr.pure)
	dest->pure = 1;

      if (current_attr.recursive)
	dest->recursive = 1;

      /* Module procedures are unusual in that the 'dest' is copied from
	 the interface declaration. However, this is an oportunity to
	 check that the submodule declaration is compliant with the
	 interface.  */
      if (dest->elemental && !current_attr.elemental)
	{
	  gfc_error ("ELEMENTAL prefix in MODULE PROCEDURE interface is "
		     "missing at %L", where);
	  return false;
	}

      if (dest->pure && !current_attr.pure)
	{
	  gfc_error ("PURE prefix in MODULE PROCEDURE interface is "
		     "missing at %L", where);
	  return false;
	}

      if (dest->recursive && !current_attr.recursive)
	{
	  gfc_error ("RECURSIVE prefix in MODULE PROCEDURE interface is "
		     "missing at %L", where);
	  return false;
	}

      return true;
    }

  if (current_attr.elemental && !gfc_add_elemental (dest, where))
    return false;

  if (current_attr.pure && !gfc_add_pure (dest, where))
    return false;

  if (current_attr.recursive && !gfc_add_recursive (dest, where))
    return false;

  return true;
}


/* Match a formal argument list or, if typeparam is true, a
   type_param_name_list.  */

match
gfc_match_formal_arglist (gfc_symbol *progname, int st_flag,
			  int null_flag, bool typeparam)
{
  gfc_formal_arglist *head, *tail, *p, *q;
  char name[GFC_MAX_SYMBOL_LEN + 1];
  gfc_symbol *sym;
  match m;
  gfc_formal_arglist *formal = NULL;

  head = tail = NULL;

  /* Keep the interface formal argument list and null it so that the
     matching for the new declaration can be done.  The numbers and
     names of the arguments are checked here. The interface formal
     arguments are retained in formal_arglist and the characteristics
     are compared in resolve.cc(resolve_fl_procedure).  See the remark
     in get_proc_name about the eventual need to copy the formal_arglist
     and populate the formal namespace of the interface symbol.  */
  if (progname->attr.module_procedure
      && progname->attr.host_assoc)
    {
      formal = progname->formal;
      progname->formal = NULL;
    }

  if (gfc_match_char ('(') != MATCH_YES)
    {
      if (null_flag)
	goto ok;
      return MATCH_NO;
    }

  if (gfc_match_char (')') == MATCH_YES)
  {
    if (typeparam)
      {
	gfc_error_now ("A type parameter list is required at %C");
	m = MATCH_ERROR;
	goto cleanup;
      }
    else
      goto ok;
  }

  for (;;)
    {
      if (gfc_match_char ('*') == MATCH_YES)
	{
	  sym = NULL;
	  if (!typeparam && !gfc_notify_std (GFC_STD_F95_OBS,
			     "Alternate-return argument at %C"))
	    {
	      m = MATCH_ERROR;
	      goto cleanup;
	    }
	  else if (typeparam)
	    gfc_error_now ("A parameter name is required at %C");
	}
      else
	{
	  m = gfc_match_name (name);
	  if (m != MATCH_YES)
	    {
	      if(typeparam)
		gfc_error_now ("A parameter name is required at %C");
	      goto cleanup;
	    }

	  if (!typeparam && gfc_get_symbol (name, NULL, &sym))
	    goto cleanup;
	  else if (typeparam
		   && gfc_get_symbol (name, progname->f2k_derived, &sym))
	    goto cleanup;
	}

      p = gfc_get_formal_arglist ();

      if (head == NULL)
	head = tail = p;
      else
	{
	  tail->next = p;
	  tail = p;
	}

      tail->sym = sym;

      /* We don't add the VARIABLE flavor because the name could be a
	 dummy procedure.  We don't apply these attributes to formal
	 arguments of statement functions.  */
      if (sym != NULL && !st_flag
	  && (!gfc_add_dummy(&sym->attr, sym->name, NULL)
	      || !gfc_missing_attr (&sym->attr, NULL)))
	{
	  m = MATCH_ERROR;
	  goto cleanup;
	}

      /* The name of a program unit can be in a different namespace,
	 so check for it explicitly.  After the statement is accepted,
	 the name is checked for especially in gfc_get_symbol().  */
      if (gfc_new_block != NULL && sym != NULL && !typeparam
	  && strcmp (sym->name, gfc_new_block->name) == 0)
	{
	  gfc_error ("Name %qs at %C is the name of the procedure",
		     sym->name);
	  m = MATCH_ERROR;
	  goto cleanup;
	}

      if (gfc_match_char (')') == MATCH_YES)
	goto ok;

      m = gfc_match_char (',');
      if (m != MATCH_YES)
	{
	  if (typeparam)
	    gfc_error_now ("Expected parameter list in type declaration "
			   "at %C");
	  else
	    gfc_error ("Unexpected junk in formal argument list at %C");
	  goto cleanup;
	}
    }

ok:
  /* Check for duplicate symbols in the formal argument list.  */
  if (head != NULL)
    {
      for (p = head; p->next; p = p->next)
	{
	  if (p->sym == NULL)
	    continue;

	  for (q = p->next; q; q = q->next)
	    if (p->sym == q->sym)
	      {
		if (typeparam)
		  gfc_error_now ("Duplicate name %qs in parameter "
				 "list at %C", p->sym->name);
		else
		  gfc_error ("Duplicate symbol %qs in formal argument "
			     "list at %C", p->sym->name);

		m = MATCH_ERROR;
		goto cleanup;
	      }
	}
    }

  if (!gfc_add_explicit_interface (progname, IFSRC_DECL, head, NULL))
    {
      m = MATCH_ERROR;
      goto cleanup;
    }

  /* gfc_error_now used in following and return with MATCH_YES because
     doing otherwise results in a cascade of extraneous errors and in
     some cases an ICE in symbol.cc(gfc_release_symbol).  */
  if (progname->attr.module_procedure && progname->attr.host_assoc)
    {
      bool arg_count_mismatch = false;

      if (!formal && head)
	arg_count_mismatch = true;

      /* Abbreviated module procedure declaration is not meant to have any
	 formal arguments!  */
      if (!progname->abr_modproc_decl && formal && !head)
	arg_count_mismatch = true;

      for (p = formal, q = head; p && q; p = p->next, q = q->next)
	{
	  if ((p->next != NULL && q->next == NULL)
	      || (p->next == NULL && q->next != NULL))
	    arg_count_mismatch = true;
	  else if ((p->sym == NULL && q->sym == NULL)
		    || strcmp (p->sym->name, q->sym->name) == 0)
	    continue;
	  else
	    gfc_error_now ("Mismatch in MODULE PROCEDURE formal "
			   "argument names (%s/%s) at %C",
			   p->sym->name, q->sym->name);
	}

      if (arg_count_mismatch)
	gfc_error_now ("Mismatch in number of MODULE PROCEDURE "
		       "formal arguments at %C");
    }

  return MATCH_YES;

cleanup:
  gfc_free_formal_arglist (head);
  return m;
}


/* Match a RESULT specification following a function declaration or
   ENTRY statement.  Also matches the end-of-statement.  */

static match
match_result (gfc_symbol *function, gfc_symbol **result)
{
  char name[GFC_MAX_SYMBOL_LEN + 1];
  gfc_symbol *r;
  match m;

  if (gfc_match (" result (") != MATCH_YES)
    return MATCH_NO;

  m = gfc_match_name (name);
  if (m != MATCH_YES)
    return m;

  /* Get the right paren, and that's it because there could be the
     bind(c) attribute after the result clause.  */
  if (gfc_match_char (')') != MATCH_YES)
    {
     /* TODO: should report the missing right paren here.  */
      return MATCH_ERROR;
    }

  if (strcmp (function->name, name) == 0)
    {
      gfc_error ("RESULT variable at %C must be different than function name");
      return MATCH_ERROR;
    }

  if (gfc_get_symbol (name, NULL, &r))
    return MATCH_ERROR;

  if (!gfc_add_result (&r->attr, r->name, NULL))
    return MATCH_ERROR;

  *result = r;

  return MATCH_YES;
}


/* Match a function suffix, which could be a combination of a result
   clause and BIND(C), either one, or neither.  The draft does not
   require them to come in a specific order.  */

static match
gfc_match_suffix (gfc_symbol *sym, gfc_symbol **result)
{
  match is_bind_c;   /* Found bind(c).  */
  match is_result;   /* Found result clause.  */
  match found_match; /* Status of whether we've found a good match.  */
  char peek_char;    /* Character we're going to peek at.  */
  bool allow_binding_name;

  /* Initialize to having found nothing.  */
  found_match = MATCH_NO;
  is_bind_c = MATCH_NO;
  is_result = MATCH_NO;

  /* Get the next char to narrow between result and bind(c).  */
  gfc_gobble_whitespace ();
  peek_char = gfc_peek_ascii_char ();

  /* C binding names are not allowed for internal procedures.  */
  if (gfc_current_state () == COMP_CONTAINS
      && sym->ns->proc_name->attr.flavor != FL_MODULE)
    allow_binding_name = false;
  else
    allow_binding_name = true;

  switch (peek_char)
    {
    case 'r':
      /* Look for result clause.  */
      is_result = match_result (sym, result);
      if (is_result == MATCH_YES)
	{
	  /* Now see if there is a bind(c) after it.  */
	  is_bind_c = gfc_match_bind_c (sym, allow_binding_name);
	  /* We've found the result clause and possibly bind(c).  */
	  found_match = MATCH_YES;
	}
      else
	/* This should only be MATCH_ERROR.  */
	found_match = is_result;
      break;
    case 'b':
      /* Look for bind(c) first.  */
      is_bind_c = gfc_match_bind_c (sym, allow_binding_name);
      if (is_bind_c == MATCH_YES)
	{
	  /* Now see if a result clause followed it.  */
	  is_result = match_result (sym, result);
	  found_match = MATCH_YES;
	}
      else
	{
	  /* Should only be a MATCH_ERROR if we get here after seeing 'b'.  */
	  found_match = MATCH_ERROR;
	}
      break;
    default:
      gfc_error ("Unexpected junk after function declaration at %C");
      found_match = MATCH_ERROR;
      break;
    }

  if (is_bind_c == MATCH_YES)
    {
      /* Fortran 2008 draft allows BIND(C) for internal procedures.  */
      if (gfc_current_state () == COMP_CONTAINS
	  && sym->ns->proc_name->attr.flavor != FL_MODULE
	  && !gfc_notify_std (GFC_STD_F2008, "BIND(C) attribute "
			      "at %L may not be specified for an internal "
			      "procedure", &gfc_current_locus))
	return MATCH_ERROR;

      if (!gfc_add_is_bind_c (&(sym->attr), sym->name, &gfc_current_locus, 1))
     	return MATCH_ERROR;
    }

  return found_match;
}


/* Procedure pointer return value without RESULT statement:
   Add "hidden" result variable named "ppr@".  */

static bool
add_hidden_procptr_result (gfc_symbol *sym)
{
  bool case1,case2;

  if (gfc_notification_std (GFC_STD_F2003) == ERROR)
    return false;

  /* First usage case: PROCEDURE and EXTERNAL statements.  */
  case1 = gfc_current_state () == COMP_FUNCTION && gfc_current_block ()
	  && strcmp (gfc_current_block ()->name, sym->name) == 0
	  && sym->attr.external;
  /* Second usage case: INTERFACE statements.  */
  case2 = gfc_current_state () == COMP_INTERFACE && gfc_state_stack->previous
	  && gfc_state_stack->previous->state == COMP_FUNCTION
	  && strcmp (gfc_state_stack->previous->sym->name, sym->name) == 0;

  if (case1 || case2)
    {
      gfc_symtree *stree;
      if (case1)
	gfc_get_sym_tree ("ppr@", gfc_current_ns, &stree, false);
      else
	{
	  gfc_symtree *st2;
	  gfc_get_sym_tree ("ppr@", gfc_current_ns->parent, &stree, false);
	  st2 = gfc_new_symtree (&gfc_current_ns->sym_root, "ppr@");
	  st2->n.sym = stree->n.sym;
	  stree->n.sym->refs++;
	}
      sym->result = stree->n.sym;

      sym->result->attr.proc_pointer = sym->attr.proc_pointer;
      sym->result->attr.pointer = sym->attr.pointer;
      sym->result->attr.external = sym->attr.external;
      sym->result->attr.referenced = sym->attr.referenced;
      sym->result->ts = sym->ts;
      sym->attr.proc_pointer = 0;
      sym->attr.pointer = 0;
      sym->attr.external = 0;
      if (sym->result->attr.external && sym->result->attr.pointer)
	{
	  sym->result->attr.pointer = 0;
	  sym->result->attr.proc_pointer = 1;
	}

      return gfc_add_result (&sym->result->attr, sym->result->name, NULL);
    }
  /* POINTER after PROCEDURE/EXTERNAL/INTERFACE statement.  */
  else if (sym->attr.function && !sym->attr.external && sym->attr.pointer
	   && sym->result && sym->result != sym && sym->result->attr.external
	   && sym == gfc_current_ns->proc_name
	   && sym == sym->result->ns->proc_name
	   && strcmp ("ppr@", sym->result->name) == 0)
    {
      sym->result->attr.proc_pointer = 1;
      sym->attr.pointer = 0;
      return true;
    }
  else
    return false;
}


/* Match the interface for a PROCEDURE declaration,
   including brackets (R1212).  */

static match
match_procedure_interface (gfc_symbol **proc_if)
{
  match m;
  gfc_symtree *st;
  locus old_loc, entry_loc;
  gfc_namespace *old_ns = gfc_current_ns;
  char name[GFC_MAX_SYMBOL_LEN + 1];

  old_loc = entry_loc = gfc_current_locus;
  gfc_clear_ts (&current_ts);

  if (gfc_match (" (") != MATCH_YES)
    {
      gfc_current_locus = entry_loc;
      return MATCH_NO;
    }

  /* Get the type spec. for the procedure interface.  */
  old_loc = gfc_current_locus;
  m = gfc_match_decl_type_spec (&current_ts, 0);
  gfc_gobble_whitespace ();
  if (m == MATCH_YES || (m == MATCH_NO && gfc_peek_ascii_char () == ')'))
    goto got_ts;

  if (m == MATCH_ERROR)
    return m;

  /* Procedure interface is itself a procedure.  */
  gfc_current_locus = old_loc;
  m = gfc_match_name (name);

  /* First look to see if it is already accessible in the current
     namespace because it is use associated or contained.  */
  st = NULL;
  if (gfc_find_sym_tree (name, NULL, 0, &st))
    return MATCH_ERROR;

  /* If it is still not found, then try the parent namespace, if it
     exists and create the symbol there if it is still not found.  */
  if (gfc_current_ns->parent)
    gfc_current_ns = gfc_current_ns->parent;
  if (st == NULL && gfc_get_ha_sym_tree (name, &st))
    return MATCH_ERROR;

  gfc_current_ns = old_ns;
  *proc_if = st->n.sym;

  if (*proc_if)
    {
      (*proc_if)->refs++;
      /* Resolve interface if possible. That way, attr.procedure is only set
	 if it is declared by a later procedure-declaration-stmt, which is
	 invalid per F08:C1216 (cf. resolve_procedure_interface).  */
      while ((*proc_if)->ts.interface
	     && *proc_if != (*proc_if)->ts.interface)
	*proc_if = (*proc_if)->ts.interface;

      if ((*proc_if)->attr.flavor == FL_UNKNOWN
	  && (*proc_if)->ts.type == BT_UNKNOWN
	  && !gfc_add_flavor (&(*proc_if)->attr, FL_PROCEDURE,
			      (*proc_if)->name, NULL))
	return MATCH_ERROR;
    }

got_ts:
  if (gfc_match (" )") != MATCH_YES)
    {
      gfc_current_locus = entry_loc;
      return MATCH_NO;
    }

  return MATCH_YES;
}


/* Match a PROCEDURE declaration (R1211).  */

static match
match_procedure_decl (void)
{
  match m;
  gfc_symbol *sym, *proc_if = NULL;
  int num;
  gfc_expr *initializer = NULL;

  /* Parse interface (with brackets).  */
  m = match_procedure_interface (&proc_if);
  if (m != MATCH_YES)
    return m;

  /* Parse attributes (with colons).  */
  m = match_attr_spec();
  if (m == MATCH_ERROR)
    return MATCH_ERROR;

  if (proc_if && proc_if->attr.is_bind_c && !current_attr.is_bind_c)
    {
      current_attr.is_bind_c = 1;
      has_name_equals = 0;
      curr_binding_label = NULL;
    }

  /* Get procedure symbols.  */
  for(num=1;;num++)
    {
      m = gfc_match_symbol (&sym, 0);
      if (m == MATCH_NO)
	goto syntax;
      else if (m == MATCH_ERROR)
	return m;

      /* Add current_attr to the symbol attributes.  */
      if (!gfc_copy_attr (&sym->attr, &current_attr, NULL))
	return MATCH_ERROR;

      if (sym->attr.is_bind_c)
	{
	  /* Check for C1218.  */
	  if (!proc_if || !proc_if->attr.is_bind_c)
	    {
	      gfc_error ("BIND(C) attribute at %C requires "
			"an interface with BIND(C)");
	      return MATCH_ERROR;
	    }
	  /* Check for C1217.  */
	  if (has_name_equals && sym->attr.pointer)
	    {
	      gfc_error ("BIND(C) procedure with NAME may not have "
			"POINTER attribute at %C");
	      return MATCH_ERROR;
	    }
	  if (has_name_equals && sym->attr.dummy)
	    {
	      gfc_error ("Dummy procedure at %C may not have "
			"BIND(C) attribute with NAME");
	      return MATCH_ERROR;
	    }
	  /* Set binding label for BIND(C).  */
	  if (!set_binding_label (&sym->binding_label, sym->name, num))
	    return MATCH_ERROR;
	}

      if (!gfc_add_external (&sym->attr, NULL))
	return MATCH_ERROR;

      if (add_hidden_procptr_result (sym))
	sym = sym->result;

      if (!gfc_add_proc (&sym->attr, sym->name, NULL))
	return MATCH_ERROR;

      /* Set interface.  */
      if (proc_if != NULL)
	{
          if (sym->ts.type != BT_UNKNOWN)
	    {
	      gfc_error ("Procedure %qs at %L already has basic type of %s",
			 sym->name, &gfc_current_locus,
			 gfc_basic_typename (sym->ts.type));
	      return MATCH_ERROR;
	    }
	  sym->ts.interface = proc_if;
	  sym->attr.untyped = 1;
	  sym->attr.if_source = IFSRC_IFBODY;
	}
      else if (current_ts.type != BT_UNKNOWN)
	{
	  if (!gfc_add_type (sym, &current_ts, &gfc_current_locus))
	    return MATCH_ERROR;
	  sym->ts.interface = gfc_new_symbol ("", gfc_current_ns);
	  sym->ts.interface->ts = current_ts;
	  sym->ts.interface->attr.flavor = FL_PROCEDURE;
	  sym->ts.interface->attr.function = 1;
	  sym->attr.function = 1;
	  sym->attr.if_source = IFSRC_UNKNOWN;
	}

      if (gfc_match (" =>") == MATCH_YES)
	{
	  if (!current_attr.pointer)
	    {
	      gfc_error ("Initialization at %C isn't for a pointer variable");
	      m = MATCH_ERROR;
	      goto cleanup;
	    }

	  m = match_pointer_init (&initializer, 1);
	  if (m != MATCH_YES)
	    goto cleanup;

	  if (!add_init_expr_to_sym (sym->name, &initializer, &gfc_current_locus))
	    goto cleanup;

	}

      if (gfc_match_eos () == MATCH_YES)
	return MATCH_YES;
      if (gfc_match_char (',') != MATCH_YES)
	goto syntax;
    }

syntax:
  gfc_error ("Syntax error in PROCEDURE statement at %C");
  return MATCH_ERROR;

cleanup:
  /* Free stuff up and return.  */
  gfc_free_expr (initializer);
  return m;
}


static match
match_binding_attributes (gfc_typebound_proc* ba, bool generic, bool ppc);


/* Match a procedure pointer component declaration (R445).  */

static match
match_ppc_decl (void)
{
  match m;
  gfc_symbol *proc_if = NULL;
  gfc_typespec ts;
  int num;
  gfc_component *c;
  gfc_expr *initializer = NULL;
  gfc_typebound_proc* tb;
  char name[GFC_MAX_SYMBOL_LEN + 1];

  /* Parse interface (with brackets).  */
  m = match_procedure_interface (&proc_if);
  if (m != MATCH_YES)
    goto syntax;

  /* Parse attributes.  */
  tb = XCNEW (gfc_typebound_proc);
  tb->where = gfc_current_locus;
  m = match_binding_attributes (tb, false, true);
  if (m == MATCH_ERROR)
    return m;

  gfc_clear_attr (&current_attr);
  current_attr.procedure = 1;
  current_attr.proc_pointer = 1;
  current_attr.access = tb->access;
  current_attr.flavor = FL_PROCEDURE;

  /* Match the colons (required).  */
  if (gfc_match (" ::") != MATCH_YES)
    {
      gfc_error ("Expected %<::%> after binding-attributes at %C");
      return MATCH_ERROR;
    }

  /* Check for C450.  */
  if (!tb->nopass && proc_if == NULL)
    {
      gfc_error("NOPASS or explicit interface required at %C");
      return MATCH_ERROR;
    }

  if (!gfc_notify_std (GFC_STD_F2003, "Procedure pointer component at %C"))
    return MATCH_ERROR;

  /* Match PPC names.  */
  ts = current_ts;
  for(num=1;;num++)
    {
      m = gfc_match_name (name);
      if (m == MATCH_NO)
	goto syntax;
      else if (m == MATCH_ERROR)
	return m;

      if (!gfc_add_component (gfc_current_block(), name, &c))
	return MATCH_ERROR;

      /* Add current_attr to the symbol attributes.  */
      if (!gfc_copy_attr (&c->attr, &current_attr, NULL))
	return MATCH_ERROR;

      if (!gfc_add_external (&c->attr, NULL))
	return MATCH_ERROR;

      if (!gfc_add_proc (&c->attr, name, NULL))
	return MATCH_ERROR;

      if (num == 1)
	c->tb = tb;
      else
	{
	  c->tb = XCNEW (gfc_typebound_proc);
	  c->tb->where = gfc_current_locus;
	  *c->tb = *tb;
	}

      /* Set interface.  */
      if (proc_if != NULL)
	{
	  c->ts.interface = proc_if;
	  c->attr.untyped = 1;
	  c->attr.if_source = IFSRC_IFBODY;
	}
      else if (ts.type != BT_UNKNOWN)
	{
	  c->ts = ts;
	  c->ts.interface = gfc_new_symbol ("", gfc_current_ns);
	  c->ts.interface->result = c->ts.interface;
	  c->ts.interface->ts = ts;
	  c->ts.interface->attr.flavor = FL_PROCEDURE;
	  c->ts.interface->attr.function = 1;
	  c->attr.function = 1;
	  c->attr.if_source = IFSRC_UNKNOWN;
	}

      if (gfc_match (" =>") == MATCH_YES)
	{
	  m = match_pointer_init (&initializer, 1);
	  if (m != MATCH_YES)
	    {
	      gfc_free_expr (initializer);
	      return m;
	    }
	  c->initializer = initializer;
	}

      if (gfc_match_eos () == MATCH_YES)
	return MATCH_YES;
      if (gfc_match_char (',') != MATCH_YES)
	goto syntax;
    }

syntax:
  gfc_error ("Syntax error in procedure pointer component at %C");
  return MATCH_ERROR;
}


/* Match a PROCEDURE declaration inside an interface (R1206).  */

static match
match_procedure_in_interface (void)
{
  match m;
  gfc_symbol *sym;
  char name[GFC_MAX_SYMBOL_LEN + 1];
  locus old_locus;

  if (current_interface.type == INTERFACE_NAMELESS
      || current_interface.type == INTERFACE_ABSTRACT)
    {
      gfc_error ("PROCEDURE at %C must be in a generic interface");
      return MATCH_ERROR;
    }

  /* Check if the F2008 optional double colon appears.  */
  gfc_gobble_whitespace ();
  old_locus = gfc_current_locus;
  if (gfc_match ("::") == MATCH_YES)
    {
      if (!gfc_notify_std (GFC_STD_F2008, "double colon in "
			   "MODULE PROCEDURE statement at %L", &old_locus))
	return MATCH_ERROR;
    }
  else
    gfc_current_locus = old_locus;

  for(;;)
    {
      m = gfc_match_name (name);
      if (m == MATCH_NO)
	goto syntax;
      else if (m == MATCH_ERROR)
	return m;
      if (gfc_get_symbol (name, gfc_current_ns->parent, &sym))
	return MATCH_ERROR;

      if (!gfc_add_interface (sym))
	return MATCH_ERROR;

      if (gfc_match_eos () == MATCH_YES)
	break;
      if (gfc_match_char (',') != MATCH_YES)
	goto syntax;
    }

  return MATCH_YES;

syntax:
  gfc_error ("Syntax error in PROCEDURE statement at %C");
  return MATCH_ERROR;
}


/* General matcher for PROCEDURE declarations.  */

static match match_procedure_in_type (void);

match
gfc_match_procedure (void)
{
  match m;

  switch (gfc_current_state ())
    {
    case COMP_NONE:
    case COMP_PROGRAM:
    case COMP_MODULE:
    case COMP_SUBMODULE:
    case COMP_SUBROUTINE:
    case COMP_FUNCTION:
    case COMP_BLOCK:
      m = match_procedure_decl ();
      break;
    case COMP_INTERFACE:
      m = match_procedure_in_interface ();
      break;
    case COMP_DERIVED:
      m = match_ppc_decl ();
      break;
    case COMP_DERIVED_CONTAINS:
      m = match_procedure_in_type ();
      break;
    default:
      return MATCH_NO;
    }

  if (m != MATCH_YES)
    return m;

  if (!gfc_notify_std (GFC_STD_F2003, "PROCEDURE statement at %C"))
    return MATCH_ERROR;

  return m;
}


/* Warn if a matched procedure has the same name as an intrinsic; this is
   simply a wrapper around gfc_warn_intrinsic_shadow that interprets the current
   parser-state-stack to find out whether we're in a module.  */

static void
do_warn_intrinsic_shadow (const gfc_symbol* sym, bool func)
{
  bool in_module;

  in_module = (gfc_state_stack->previous
	       && (gfc_state_stack->previous->state == COMP_MODULE
		   || gfc_state_stack->previous->state == COMP_SUBMODULE));

  gfc_warn_intrinsic_shadow (sym, in_module, func);
}


/* Match a function declaration.  */

match
gfc_match_function_decl (void)
{
  char name[GFC_MAX_SYMBOL_LEN + 1];
  gfc_symbol *sym, *result;
  locus old_loc;
  match m;
  match suffix_match;
  match found_match; /* Status returned by match func.  */

  if (gfc_current_state () != COMP_NONE
      && gfc_current_state () != COMP_INTERFACE
      && gfc_current_state () != COMP_CONTAINS)
    return MATCH_NO;

  gfc_clear_ts (&current_ts);

  old_loc = gfc_current_locus;

  m = gfc_match_prefix (&current_ts);
  if (m != MATCH_YES)
    {
      gfc_current_locus = old_loc;
      return m;
    }

  if (gfc_match ("function% %n", name) != MATCH_YES)
    {
      gfc_current_locus = old_loc;
      return MATCH_NO;
    }

  if (get_proc_name (name, &sym, false))
    return MATCH_ERROR;

  if (add_hidden_procptr_result (sym))
    sym = sym->result;

  if (current_attr.module_procedure)
    sym->attr.module_procedure = 1;

  gfc_new_block = sym;

  m = gfc_match_formal_arglist (sym, 0, 0);
  if (m == MATCH_NO)
    {
      gfc_error ("Expected formal argument list in function "
		 "definition at %C");
      m = MATCH_ERROR;
      goto cleanup;
    }
  else if (m == MATCH_ERROR)
    goto cleanup;

  result = NULL;

  /* According to the draft, the bind(c) and result clause can
     come in either order after the formal_arg_list (i.e., either
     can be first, both can exist together or by themselves or neither
     one).  Therefore, the match_result can't match the end of the
     string, and check for the bind(c) or result clause in either order.  */
  found_match = gfc_match_eos ();

  /* Make sure that it isn't already declared as BIND(C).  If it is, it
     must have been marked BIND(C) with a BIND(C) attribute and that is
     not allowed for procedures.  */
  if (sym->attr.is_bind_c == 1)
    {
      sym->attr.is_bind_c = 0;

      if (gfc_state_stack->previous
	  && gfc_state_stack->previous->state != COMP_SUBMODULE)
	{
	  locus loc;
	  loc = sym->old_symbol != NULL
	    ? sym->old_symbol->declared_at : gfc_current_locus;
	  gfc_error_now ("BIND(C) attribute at %L can only be used for "
			 "variables or common blocks", &loc);
	}
    }

  if (found_match != MATCH_YES)
    {
      /* If we haven't found the end-of-statement, look for a suffix.  */
      suffix_match = gfc_match_suffix (sym, &result);
      if (suffix_match == MATCH_YES)
        /* Need to get the eos now.  */
        found_match = gfc_match_eos ();
      else
	found_match = suffix_match;
    }

  /* F2018 C1550 (R1526) If MODULE appears in the prefix of a module
     subprogram and a binding label is specified, it shall be the
     same as the binding label specified in the corresponding module
     procedure interface body.  */
    if (sym->attr.is_bind_c && sym->attr.module_procedure && sym->old_symbol
  	&& strcmp (sym->name, sym->old_symbol->name) == 0
	&& sym->binding_label && sym->old_symbol->binding_label
	&& strcmp (sym->binding_label, sym->old_symbol->binding_label) != 0)
      {
	  const char *null = "NULL", *s1, *s2;
	  s1 = sym->binding_label;
	  if (!s1) s1 = null;
	  s2 = sym->old_symbol->binding_label;
	  if (!s2) s2 = null;
          gfc_error ("Mismatch in BIND(C) names (%qs/%qs) at %C", s1, s2);
	  sym->refs++;	/* Needed to avoid an ICE in gfc_release_symbol */
	  return MATCH_ERROR;
      }

  if(found_match != MATCH_YES)
    m = MATCH_ERROR;
  else
    {
      /* Make changes to the symbol.  */
      m = MATCH_ERROR;

      if (!gfc_add_function (&sym->attr, sym->name, NULL))
	goto cleanup;

      if (!gfc_missing_attr (&sym->attr, NULL))
	goto cleanup;

      if (!copy_prefix (&sym->attr, &sym->declared_at))
	{
	  if(!sym->attr.module_procedure)
	goto cleanup;
	  else
	    gfc_error_check ();
	}

      /* Delay matching the function characteristics until after the
	 specification block by signalling kind=-1.  */
      sym->declared_at = old_loc;
      if (current_ts.type != BT_UNKNOWN)
	current_ts.kind = -1;
      else
	current_ts.kind = 0;

      if (result == NULL)
	{
          if (current_ts.type != BT_UNKNOWN
	      && !gfc_add_type (sym, &current_ts, &gfc_current_locus))
	    goto cleanup;
	  sym->result = sym;
	}
      else
	{
          if (current_ts.type != BT_UNKNOWN
	      && !gfc_add_type (result, &current_ts, &gfc_current_locus))
	    goto cleanup;
	  sym->result = result;
	}

      /* Warn if this procedure has the same name as an intrinsic.  */
      do_warn_intrinsic_shadow (sym, true);

      return MATCH_YES;
    }

cleanup:
  gfc_current_locus = old_loc;
  return m;
}


/* This is mostly a copy of parse.cc(add_global_procedure) but modified to
   pass the name of the entry, rather than the gfc_current_block name, and
   to return false upon finding an existing global entry.  */

static bool
add_global_entry (const char *name, const char *binding_label, bool sub,
		  locus *where)
{
  gfc_gsymbol *s;
  enum gfc_symbol_type type;

  type = sub ? GSYM_SUBROUTINE : GSYM_FUNCTION;

  /* Only in Fortran 2003: For procedures with a binding label also the Fortran
     name is a global identifier.  */
  if (!binding_label || gfc_notification_std (GFC_STD_F2008))
    {
      s = gfc_get_gsymbol (name, false);

      if (s->defined || (s->type != GSYM_UNKNOWN && s->type != type))
	{
	  gfc_global_used (s, where);
	  return false;
	}
      else
	{
	  s->type = type;
	  s->sym_name = name;
	  s->where = *where;
	  s->defined = 1;
	  s->ns = gfc_current_ns;
	}
    }

  /* Don't add the symbol multiple times.  */
  if (binding_label
      && (!gfc_notification_std (GFC_STD_F2008)
	  || strcmp (name, binding_label) != 0))
    {
      s = gfc_get_gsymbol (binding_label, true);

      if (s->defined || (s->type != GSYM_UNKNOWN && s->type != type))
	{
	  gfc_global_used (s, where);
	  return false;
	}
      else
	{
	  s->type = type;
	  s->sym_name = name;
	  s->binding_label = binding_label;
	  s->where = *where;
	  s->defined = 1;
	  s->ns = gfc_current_ns;
	}
    }

  return true;
}


/* Match an ENTRY statement.  */

match
gfc_match_entry (void)
{
  gfc_symbol *proc;
  gfc_symbol *result;
  gfc_symbol *entry;
  char name[GFC_MAX_SYMBOL_LEN + 1];
  gfc_compile_state state;
  match m;
  gfc_entry_list *el;
  locus old_loc;
  bool module_procedure;
  char peek_char;
  match is_bind_c;

  m = gfc_match_name (name);
  if (m != MATCH_YES)
    return m;

  if (!gfc_notify_std (GFC_STD_F2008_OBS, "ENTRY statement at %C"))
    return MATCH_ERROR;

  state = gfc_current_state ();
  if (state != COMP_SUBROUTINE && state != COMP_FUNCTION)
    {
      switch (state)
	{
	  case COMP_PROGRAM:
	    gfc_error ("ENTRY statement at %C cannot appear within a PROGRAM");
	    break;
	  case COMP_MODULE:
	    gfc_error ("ENTRY statement at %C cannot appear within a MODULE");
	    break;
	  case COMP_SUBMODULE:
	    gfc_error ("ENTRY statement at %C cannot appear within a SUBMODULE");
	    break;
	  case COMP_BLOCK_DATA:
	    gfc_error ("ENTRY statement at %C cannot appear within "
		       "a BLOCK DATA");
	    break;
	  case COMP_INTERFACE:
	    gfc_error ("ENTRY statement at %C cannot appear within "
		       "an INTERFACE");
	    break;
          case COMP_STRUCTURE:
            gfc_error ("ENTRY statement at %C cannot appear within "
                       "a STRUCTURE block");
            break;
	  case COMP_DERIVED:
	    gfc_error ("ENTRY statement at %C cannot appear within "
		       "a DERIVED TYPE block");
	    break;
	  case COMP_IF:
	    gfc_error ("ENTRY statement at %C cannot appear within "
		       "an IF-THEN block");
	    break;
	  case COMP_DO:
	  case COMP_DO_CONCURRENT:
	    gfc_error ("ENTRY statement at %C cannot appear within "
		       "a DO block");
	    break;
	  case COMP_SELECT:
	    gfc_error ("ENTRY statement at %C cannot appear within "
		       "a SELECT block");
	    break;
	  case COMP_FORALL:
	    gfc_error ("ENTRY statement at %C cannot appear within "
		       "a FORALL block");
	    break;
	  case COMP_WHERE:
	    gfc_error ("ENTRY statement at %C cannot appear within "
		       "a WHERE block");
	    break;
	  case COMP_CONTAINS:
	    gfc_error ("ENTRY statement at %C cannot appear within "
		       "a contained subprogram");
	    break;
	  default:
	    gfc_error ("Unexpected ENTRY statement at %C");
	}
      return MATCH_ERROR;
    }

  if ((state == COMP_SUBROUTINE || state == COMP_FUNCTION)
      && gfc_state_stack->previous->state == COMP_INTERFACE)
    {
      gfc_error ("ENTRY statement at %C cannot appear within an INTERFACE");
      return MATCH_ERROR;
    }

  module_procedure = gfc_current_ns->parent != NULL
		   && gfc_current_ns->parent->proc_name
		   && gfc_current_ns->parent->proc_name->attr.flavor
		      == FL_MODULE;

  if (gfc_current_ns->parent != NULL
      && gfc_current_ns->parent->proc_name
      && !module_procedure)
    {
      gfc_error("ENTRY statement at %C cannot appear in a "
		"contained procedure");
      return MATCH_ERROR;
    }

  /* Module function entries need special care in get_proc_name
     because previous references within the function will have
     created symbols attached to the current namespace.  */
  if (get_proc_name (name, &entry,
		     gfc_current_ns->parent != NULL
		     && module_procedure))
    return MATCH_ERROR;

  proc = gfc_current_block ();

  /* Make sure that it isn't already declared as BIND(C).  If it is, it
     must have been marked BIND(C) with a BIND(C) attribute and that is
     not allowed for procedures.  */
  if (entry->attr.is_bind_c == 1)
    {
      locus loc;

      entry->attr.is_bind_c = 0;

      loc = entry->old_symbol != NULL
	? entry->old_symbol->declared_at : gfc_current_locus;
      gfc_error_now ("BIND(C) attribute at %L can only be used for "
		     "variables or common blocks", &loc);
     }

  /* Check what next non-whitespace character is so we can tell if there
     is the required parens if we have a BIND(C).  */
  old_loc = gfc_current_locus;
  gfc_gobble_whitespace ();
  peek_char = gfc_peek_ascii_char ();

  if (state == COMP_SUBROUTINE)
    {
      m = gfc_match_formal_arglist (entry, 0, 1);
      if (m != MATCH_YES)
	return MATCH_ERROR;

      /* Call gfc_match_bind_c with allow_binding_name = true as ENTRY can
	 never be an internal procedure.  */
      is_bind_c = gfc_match_bind_c (entry, true);
      if (is_bind_c == MATCH_ERROR)
	return MATCH_ERROR;
      if (is_bind_c == MATCH_YES)
	{
	  if (peek_char != '(')
	    {
	      gfc_error ("Missing required parentheses before BIND(C) at %C");
	      return MATCH_ERROR;
	    }

	  if (!gfc_add_is_bind_c (&(entry->attr), entry->name,
				  &(entry->declared_at), 1))
	    return MATCH_ERROR;

	}

      if (!gfc_current_ns->parent
	  && !add_global_entry (name, entry->binding_label, true,
				&old_loc))
	return MATCH_ERROR;

      /* An entry in a subroutine.  */
      if (!gfc_add_entry (&entry->attr, entry->name, NULL)
	  || !gfc_add_subroutine (&entry->attr, entry->name, NULL))
	return MATCH_ERROR;
    }
  else
    {
      /* An entry in a function.
	 We need to take special care because writing
	    ENTRY f()
	 as
	    ENTRY f
	 is allowed, whereas
	    ENTRY f() RESULT (r)
	 can't be written as
	    ENTRY f RESULT (r).  */
      if (gfc_match_eos () == MATCH_YES)
	{
	  gfc_current_locus = old_loc;
	  /* Match the empty argument list, and add the interface to
	     the symbol.  */
	  m = gfc_match_formal_arglist (entry, 0, 1);
	}
      else
	m = gfc_match_formal_arglist (entry, 0, 0);

      if (m != MATCH_YES)
	return MATCH_ERROR;

      result = NULL;

      if (gfc_match_eos () == MATCH_YES)
	{
	  if (!gfc_add_entry (&entry->attr, entry->name, NULL)
	      || !gfc_add_function (&entry->attr, entry->name, NULL))
	    return MATCH_ERROR;

	  entry->result = entry;
	}
      else
	{
	  m = gfc_match_suffix (entry, &result);
	  if (m == MATCH_NO)
	    gfc_syntax_error (ST_ENTRY);
	  if (m != MATCH_YES)
	    return MATCH_ERROR;

          if (result)
	    {
	      if (!gfc_add_result (&result->attr, result->name, NULL)
		  || !gfc_add_entry (&entry->attr, result->name, NULL)
		  || !gfc_add_function (&entry->attr, result->name, NULL))
	        return MATCH_ERROR;
	      entry->result = result;
	    }
	  else
	    {
	      if (!gfc_add_entry (&entry->attr, entry->name, NULL)
		  || !gfc_add_function (&entry->attr, entry->name, NULL))
		return MATCH_ERROR;
	      entry->result = entry;
	    }
	}

      if (!gfc_current_ns->parent
	  && !add_global_entry (name, entry->binding_label, false,
				&old_loc))
	return MATCH_ERROR;
    }

  if (gfc_match_eos () != MATCH_YES)
    {
      gfc_syntax_error (ST_ENTRY);
      return MATCH_ERROR;
    }

  /* F2018:C1546 An elemental procedure shall not have the BIND attribute.  */
  if (proc->attr.elemental && entry->attr.is_bind_c)
    {
      gfc_error ("ENTRY statement at %L with BIND(C) prohibited in an "
		 "elemental procedure", &entry->declared_at);
      return MATCH_ERROR;
    }

  entry->attr.recursive = proc->attr.recursive;
  entry->attr.elemental = proc->attr.elemental;
  entry->attr.pure = proc->attr.pure;

  el = gfc_get_entry_list ();
  el->sym = entry;
  el->next = gfc_current_ns->entries;
  gfc_current_ns->entries = el;
  if (el->next)
    el->id = el->next->id + 1;
  else
    el->id = 1;

  new_st.op = EXEC_ENTRY;
  new_st.ext.entry = el;

  return MATCH_YES;
}


/* Match a subroutine statement, including optional prefixes.  */

match
gfc_match_subroutine (void)
{
  char name[GFC_MAX_SYMBOL_LEN + 1];
  gfc_symbol *sym;
  match m;
  match is_bind_c;
  char peek_char;
  bool allow_binding_name;
  locus loc;

  if (gfc_current_state () != COMP_NONE
      && gfc_current_state () != COMP_INTERFACE
      && gfc_current_state () != COMP_CONTAINS)
    return MATCH_NO;

  m = gfc_match_prefix (NULL);
  if (m != MATCH_YES)
    return m;

  m = gfc_match ("subroutine% %n", name);
  if (m != MATCH_YES)
    return m;

  if (get_proc_name (name, &sym, false))
    return MATCH_ERROR;

  /* Set declared_at as it might point to, e.g., a PUBLIC statement, if
     the symbol existed before.  */
  sym->declared_at = gfc_current_locus;

  if (current_attr.module_procedure)
    sym->attr.module_procedure = 1;

  if (add_hidden_procptr_result (sym))
    sym = sym->result;

  gfc_new_block = sym;

  /* Check what next non-whitespace character is so we can tell if there
     is the required parens if we have a BIND(C).  */
  gfc_gobble_whitespace ();
  peek_char = gfc_peek_ascii_char ();

  if (!gfc_add_subroutine (&sym->attr, sym->name, NULL))
    return MATCH_ERROR;

  if (gfc_match_formal_arglist (sym, 0, 1) != MATCH_YES)
    return MATCH_ERROR;

  /* Make sure that it isn't already declared as BIND(C).  If it is, it
     must have been marked BIND(C) with a BIND(C) attribute and that is
     not allowed for procedures.  */
  if (sym->attr.is_bind_c == 1)
    {
      sym->attr.is_bind_c = 0;

      if (gfc_state_stack->previous
	  && gfc_state_stack->previous->state != COMP_SUBMODULE)
	{
	  locus loc;
	  loc = sym->old_symbol != NULL
	    ? sym->old_symbol->declared_at : gfc_current_locus;
	  gfc_error_now ("BIND(C) attribute at %L can only be used for "
			 "variables or common blocks", &loc);
	}
    }

  /* C binding names are not allowed for internal procedures.  */
  if (gfc_current_state () == COMP_CONTAINS
      && sym->ns->proc_name->attr.flavor != FL_MODULE)
    allow_binding_name = false;
  else
    allow_binding_name = true;

  /* Here, we are just checking if it has the bind(c) attribute, and if
     so, then we need to make sure it's all correct.  If it doesn't,
     we still need to continue matching the rest of the subroutine line.  */
  gfc_gobble_whitespace ();
  loc = gfc_current_locus;
  is_bind_c = gfc_match_bind_c (sym, allow_binding_name);
  if (is_bind_c == MATCH_ERROR)
    {
      /* There was an attempt at the bind(c), but it was wrong.	 An
	 error message should have been printed w/in the gfc_match_bind_c
	 so here we'll just return the MATCH_ERROR.  */
      return MATCH_ERROR;
    }

  if (is_bind_c == MATCH_YES)
    {
      gfc_formal_arglist *arg;

      /* The following is allowed in the Fortran 2008 draft.  */
      if (gfc_current_state () == COMP_CONTAINS
	  && sym->ns->proc_name->attr.flavor != FL_MODULE
	  && !gfc_notify_std (GFC_STD_F2008, "BIND(C) attribute "
			      "at %L may not be specified for an internal "
			      "procedure", &gfc_current_locus))
	return MATCH_ERROR;

      if (peek_char != '(')
        {
          gfc_error ("Missing required parentheses before BIND(C) at %C");
          return MATCH_ERROR;
        }

      /* F2018 C1550 (R1526) If MODULE appears in the prefix of a module
	 subprogram and a binding label is specified, it shall be the
	 same as the binding label specified in the corresponding module
	 procedure interface body.  */
      if (sym->attr.module_procedure && sym->old_symbol
  	  && strcmp (sym->name, sym->old_symbol->name) == 0
	  && sym->binding_label && sym->old_symbol->binding_label
	  && strcmp (sym->binding_label, sym->old_symbol->binding_label) != 0)
	{
	  const char *null = "NULL", *s1, *s2;
	  s1 = sym->binding_label;
	  if (!s1) s1 = null;
	  s2 = sym->old_symbol->binding_label;
	  if (!s2) s2 = null;
          gfc_error ("Mismatch in BIND(C) names (%qs/%qs) at %C", s1, s2);
	  sym->refs++;	/* Needed to avoid an ICE in gfc_release_symbol */
	  return MATCH_ERROR;
	}

      /* Scan the dummy arguments for an alternate return.  */
      for (arg = sym->formal; arg; arg = arg->next)
	if (!arg->sym)
	  {
	    gfc_error ("Alternate return dummy argument cannot appear in a "
		       "SUBROUTINE with the BIND(C) attribute at %L", &loc);
	    return MATCH_ERROR;
	  }

      if (!gfc_add_is_bind_c (&(sym->attr), sym->name, &(sym->declared_at), 1))
        return MATCH_ERROR;
    }

  if (gfc_match_eos () != MATCH_YES)
    {
      gfc_syntax_error (ST_SUBROUTINE);
      return MATCH_ERROR;
    }

  if (!copy_prefix (&sym->attr, &sym->declared_at))
    {
      if(!sym->attr.module_procedure)
	return MATCH_ERROR;
      else
	gfc_error_check ();
    }

  /* Warn if it has the same name as an intrinsic.  */
  do_warn_intrinsic_shadow (sym, false);

  return MATCH_YES;
}


/* Check that the NAME identifier in a BIND attribute or statement
   is conform to C identifier rules.  */

match
check_bind_name_identifier (char **name)
{
  char *n = *name, *p;

  /* Remove leading spaces.  */
  while (*n == ' ')
    n++;

  /* On an empty string, free memory and set name to NULL.  */
  if (*n == '\0')
    {
      free (*name);
      *name = NULL;
      return MATCH_YES;
    }

  /* Remove trailing spaces.  */
  p = n + strlen(n) - 1;
  while (*p == ' ')
    *(p--) = '\0';

  /* Insert the identifier into the symbol table.  */
  p = xstrdup (n);
  free (*name);
  *name = p;

  /* Now check that identifier is valid under C rules.  */
  if (ISDIGIT (*p))
    {
      gfc_error ("Invalid C identifier in NAME= specifier at %C");
      return MATCH_ERROR;
    }

  for (; *p; p++)
    if (!(ISALNUM (*p) || *p == '_' || *p == '$'))
      {
        gfc_error ("Invalid C identifier in NAME= specifier at %C");
	return MATCH_ERROR;
      }

  return MATCH_YES;
}


/* Match a BIND(C) specifier, with the optional 'name=' specifier if
   given, and set the binding label in either the given symbol (if not
   NULL), or in the current_ts.  The symbol may be NULL because we may
   encounter the BIND(C) before the declaration itself.  Return
   MATCH_NO if what we're looking at isn't a BIND(C) specifier,
   MATCH_ERROR if it is a BIND(C) clause but an error was encountered,
   or MATCH_YES if the specifier was correct and the binding label and
   bind(c) fields were set correctly for the given symbol or the
   current_ts. If allow_binding_name is false, no binding name may be
   given.  */

match
gfc_match_bind_c (gfc_symbol *sym, bool allow_binding_name)
{
  char *binding_label = NULL;
  gfc_expr *e = NULL;

  /* Initialize the flag that specifies whether we encountered a NAME=
     specifier or not.  */
  has_name_equals = 0;

  /* This much we have to be able to match, in this order, if
     there is a bind(c) label.	*/
  if (gfc_match (" bind ( c ") != MATCH_YES)
    return MATCH_NO;

  /* Now see if there is a binding label, or if we've reached the
     end of the bind(c) attribute without one.	*/
  if (gfc_match_char (',') == MATCH_YES)
    {
      if (gfc_match (" name = ") != MATCH_YES)
        {
          gfc_error ("Syntax error in NAME= specifier for binding label "
                     "at %C");
          /* should give an error message here */
          return MATCH_ERROR;
        }

      has_name_equals = 1;

      if (gfc_match_init_expr (&e) != MATCH_YES)
	{
	  gfc_free_expr (e);
	  return MATCH_ERROR;
	}

      if (!gfc_simplify_expr(e, 0))
	{
	  gfc_error ("NAME= specifier at %C should be a constant expression");
	  gfc_free_expr (e);
	  return MATCH_ERROR;
	}

      if (e->expr_type != EXPR_CONSTANT || e->ts.type != BT_CHARACTER
	  || e->ts.kind != gfc_default_character_kind || e->rank != 0)
	{
	  gfc_error ("NAME= specifier at %C should be a scalar of "
	             "default character kind");
	  gfc_free_expr(e);
	  return MATCH_ERROR;
	}

      // Get a C string from the Fortran string constant
      binding_label = gfc_widechar_to_char (e->value.character.string,
					    e->value.character.length);
      gfc_free_expr(e);

      // Check that it is valid (old gfc_match_name_C)
      if (check_bind_name_identifier (&binding_label) != MATCH_YES)
	return MATCH_ERROR;
    }

  /* Get the required right paren.  */
  if (gfc_match_char (')') != MATCH_YES)
    {
      gfc_error ("Missing closing paren for binding label at %C");
      return MATCH_ERROR;
    }

  if (has_name_equals && !allow_binding_name)
    {
      gfc_error ("No binding name is allowed in BIND(C) at %C");
      return MATCH_ERROR;
    }

  if (has_name_equals && sym != NULL && sym->attr.dummy)
    {
      gfc_error ("For dummy procedure %s, no binding name is "
		 "allowed in BIND(C) at %C", sym->name);
      return MATCH_ERROR;
    }


  /* Save the binding label to the symbol.  If sym is null, we're
     probably matching the typespec attributes of a declaration and
     haven't gotten the name yet, and therefore, no symbol yet.	 */
  if (binding_label)
    {
      if (sym != NULL)
	sym->binding_label = binding_label;
      else
	curr_binding_label = binding_label;
    }
  else if (allow_binding_name)
    {
      /* No binding label, but if symbol isn't null, we
	 can set the label for it here.
	 If name="" or allow_binding_name is false, no C binding name is
	 created.  */
      if (sym != NULL && sym->name != NULL && has_name_equals == 0)
	sym->binding_label = IDENTIFIER_POINTER (get_identifier (sym->name));
    }

  if (has_name_equals && gfc_current_state () == COMP_INTERFACE
      && current_interface.type == INTERFACE_ABSTRACT)
    {
      gfc_error ("NAME not allowed on BIND(C) for ABSTRACT INTERFACE at %C");
      return MATCH_ERROR;
    }

  return MATCH_YES;
}


/* Return nonzero if we're currently compiling a contained procedure.  */

static int
contained_procedure (void)
{
  gfc_state_data *s = gfc_state_stack;

  if ((s->state == COMP_SUBROUTINE || s->state == COMP_FUNCTION)
      && s->previous != NULL && s->previous->state == COMP_CONTAINS)
    return 1;

  return 0;
}

/* Set the kind of each enumerator.  The kind is selected such that it is
   interoperable with the corresponding C enumeration type, making
   sure that -fshort-enums is honored.  */

static void
set_enum_kind(void)
{
  enumerator_history *current_history = NULL;
  int kind;
  int i;

  if (max_enum == NULL || enum_history == NULL)
    return;

  if (!flag_short_enums)
    return;

  i = 0;
  do
    {
      kind = gfc_integer_kinds[i++].kind;
    }
  while (kind < gfc_c_int_kind
	 && gfc_check_integer_range (max_enum->initializer->value.integer,
				     kind) != ARITH_OK);

  current_history = enum_history;
  while (current_history != NULL)
    {
      current_history->sym->ts.kind = kind;
      current_history = current_history->next;
    }
}


/* Match any of the various end-block statements.  Returns the type of
   END to the caller.  The END INTERFACE, END IF, END DO, END SELECT
   and END BLOCK statements cannot be replaced by a single END statement.  */

match
gfc_match_end (gfc_statement *st)
{
  char name[GFC_MAX_SYMBOL_LEN + 1];
  gfc_compile_state state;
  locus old_loc;
  const char *block_name;
  const char *target;
  int eos_ok;
  match m;
  gfc_namespace *parent_ns, *ns, *prev_ns;
  gfc_namespace **nsp;
  bool abreviated_modproc_decl = false;
  bool got_matching_end = false;

  old_loc = gfc_current_locus;
  if (gfc_match ("end") != MATCH_YES)
    return MATCH_NO;

  state = gfc_current_state ();
  block_name = gfc_current_block () == NULL
	     ? NULL : gfc_current_block ()->name;

  switch (state)
    {
    case COMP_ASSOCIATE:
    case COMP_BLOCK:
      if (startswith (block_name, "block@"))
	block_name = NULL;
      break;

    case COMP_CONTAINS:
    case COMP_DERIVED_CONTAINS:
      state = gfc_state_stack->previous->state;
      block_name = gfc_state_stack->previous->sym == NULL
		 ? NULL : gfc_state_stack->previous->sym->name;
      abreviated_modproc_decl = gfc_state_stack->previous->sym
		&& gfc_state_stack->previous->sym->abr_modproc_decl;
      break;

    default:
      break;
    }

  if (!abreviated_modproc_decl)
    abreviated_modproc_decl = gfc_current_block ()
			      && gfc_current_block ()->abr_modproc_decl;

  switch (state)
    {
    case COMP_NONE:
    case COMP_PROGRAM:
      *st = ST_END_PROGRAM;
      target = " program";
      eos_ok = 1;
      break;

    case COMP_SUBROUTINE:
      *st = ST_END_SUBROUTINE;
      if (!abreviated_modproc_decl)
      target = " subroutine";
      else
	target = " procedure";
      eos_ok = !contained_procedure ();
      break;

    case COMP_FUNCTION:
      *st = ST_END_FUNCTION;
      if (!abreviated_modproc_decl)
      target = " function";
      else
	target = " procedure";
      eos_ok = !contained_procedure ();
      break;

    case COMP_BLOCK_DATA:
      *st = ST_END_BLOCK_DATA;
      target = " block data";
      eos_ok = 1;
      break;

    case COMP_MODULE:
      *st = ST_END_MODULE;
      target = " module";
      eos_ok = 1;
      break;

    case COMP_SUBMODULE:
      *st = ST_END_SUBMODULE;
      target = " submodule";
      eos_ok = 1;
      break;

    case COMP_INTERFACE:
      *st = ST_END_INTERFACE;
      target = " interface";
      eos_ok = 0;
      break;

    case COMP_MAP:
      *st = ST_END_MAP;
      target = " map";
      eos_ok = 0;
      break;

    case COMP_UNION:
      *st = ST_END_UNION;
      target = " union";
      eos_ok = 0;
      break;

    case COMP_STRUCTURE:
      *st = ST_END_STRUCTURE;
      target = " structure";
      eos_ok = 0;
      break;

    case COMP_DERIVED:
    case COMP_DERIVED_CONTAINS:
      *st = ST_END_TYPE;
      target = " type";
      eos_ok = 0;
      break;

    case COMP_ASSOCIATE:
      *st = ST_END_ASSOCIATE;
      target = " associate";
      eos_ok = 0;
      break;

    case COMP_BLOCK:
    case COMP_OMP_STRICTLY_STRUCTURED_BLOCK:
      *st = ST_END_BLOCK;
      target = " block";
      eos_ok = 0;
      break;

    case COMP_IF:
      *st = ST_ENDIF;
      target = " if";
      eos_ok = 0;
      break;

    case COMP_DO:
    case COMP_DO_CONCURRENT:
      *st = ST_ENDDO;
      target = " do";
      eos_ok = 0;
      break;

    case COMP_CRITICAL:
      *st = ST_END_CRITICAL;
      target = " critical";
      eos_ok = 0;
      break;

    case COMP_SELECT:
    case COMP_SELECT_TYPE:
    case COMP_SELECT_RANK:
      *st = ST_END_SELECT;
      target = " select";
      eos_ok = 0;
      break;

    case COMP_FORALL:
      *st = ST_END_FORALL;
      target = " forall";
      eos_ok = 0;
      break;

    case COMP_WHERE:
      *st = ST_END_WHERE;
      target = " where";
      eos_ok = 0;
      break;

    case COMP_ENUM:
      *st = ST_END_ENUM;
      target = " enum";
      eos_ok = 0;
      last_initializer = NULL;
      set_enum_kind ();
      gfc_free_enum_history ();
      break;

    default:
      gfc_error ("Unexpected END statement at %C");
      goto cleanup;
    }

  old_loc = gfc_current_locus;
  if (gfc_match_eos () == MATCH_YES)
    {
      if (!eos_ok && (*st == ST_END_SUBROUTINE || *st == ST_END_FUNCTION))
	{
	  if (!gfc_notify_std (GFC_STD_F2008, "END statement "
			       "instead of %s statement at %L",
			       abreviated_modproc_decl ? "END PROCEDURE"
			       : gfc_ascii_statement(*st), &old_loc))
	    goto cleanup;
	}
      else if (!eos_ok)
	{
	  /* We would have required END [something].  */
	  gfc_error ("%s statement expected at %L",
		     gfc_ascii_statement (*st), &old_loc);
	  goto cleanup;
	}

      return MATCH_YES;
    }

  /* Verify that we've got the sort of end-block that we're expecting.  */
  if (gfc_match (target) != MATCH_YES)
    {
      gfc_error ("Expecting %s statement at %L", abreviated_modproc_decl
		 ? "END PROCEDURE" : gfc_ascii_statement(*st), &old_loc);
      goto cleanup;
    }
  else
    got_matching_end = true;

  old_loc = gfc_current_locus;
  /* If we're at the end, make sure a block name wasn't required.  */
  if (gfc_match_eos () == MATCH_YES)
    {

      if (*st != ST_ENDDO && *st != ST_ENDIF && *st != ST_END_SELECT
	  && *st != ST_END_FORALL && *st != ST_END_WHERE && *st != ST_END_BLOCK
	  && *st != ST_END_ASSOCIATE && *st != ST_END_CRITICAL)
	return MATCH_YES;

      if (!block_name)
	return MATCH_YES;

      gfc_error ("Expected block name of %qs in %s statement at %L",
		 block_name, gfc_ascii_statement (*st), &old_loc);

      return MATCH_ERROR;
    }

  /* END INTERFACE has a special handler for its several possible endings.  */
  if (*st == ST_END_INTERFACE)
    return gfc_match_end_interface ();

  /* We haven't hit the end of statement, so what is left must be an
     end-name.  */
  m = gfc_match_space ();
  if (m == MATCH_YES)
    m = gfc_match_name (name);

  if (m == MATCH_NO)
    gfc_error ("Expected terminating name at %C");
  if (m != MATCH_YES)
    goto cleanup;

  if (block_name == NULL)
    goto syntax;

  /* We have to pick out the declared submodule name from the composite
     required by F2008:11.2.3 para 2, which ends in the declared name.  */
  if (state == COMP_SUBMODULE)
    block_name = strchr (block_name, '.') + 1;

  if (strcmp (name, block_name) != 0 && strcmp (block_name, "ppr@") != 0)
    {
      gfc_error ("Expected label %qs for %s statement at %C", block_name,
		 gfc_ascii_statement (*st));
      goto cleanup;
    }
  /* Procedure pointer as function result.  */
  else if (strcmp (block_name, "ppr@") == 0
	   && strcmp (name, gfc_current_block ()->ns->proc_name->name) != 0)
    {
      gfc_error ("Expected label %qs for %s statement at %C",
		 gfc_current_block ()->ns->proc_name->name,
		 gfc_ascii_statement (*st));
      goto cleanup;
    }

  if (gfc_match_eos () == MATCH_YES)
    return MATCH_YES;

syntax:
  gfc_syntax_error (*st);

cleanup:
  gfc_current_locus = old_loc;

  /* If we are missing an END BLOCK, we created a half-ready namespace.
     Remove it from the parent namespace's sibling list.  */

  while (state == COMP_BLOCK && !got_matching_end)
    {
      parent_ns = gfc_current_ns->parent;

      nsp = &(gfc_state_stack->previous->tail->ext.block.ns);

      prev_ns = NULL;
      ns = *nsp;
      while (ns)
	{
	  if (ns == gfc_current_ns)
	    {
	      if (prev_ns == NULL)
		*nsp = NULL;
	      else
		prev_ns->sibling = ns->sibling;
	    }
	  prev_ns = ns;
	  ns = ns->sibling;
	}

      gfc_free_namespace (gfc_current_ns);
      gfc_current_ns = parent_ns;
      gfc_state_stack = gfc_state_stack->previous;
      state = gfc_current_state ();
    }

  return MATCH_ERROR;
}



/***************** Attribute declaration statements ****************/

/* Set the attribute of a single variable.  */

static match
attr_decl1 (void)
{
  char name[GFC_MAX_SYMBOL_LEN + 1];
  gfc_array_spec *as;

  /* Workaround -Wmaybe-uninitialized false positive during
     profiledbootstrap by initializing them.  */
  gfc_symbol *sym = NULL;
  locus var_locus;
  match m;

  as = NULL;

  m = gfc_match_name (name);
  if (m != MATCH_YES)
    goto cleanup;

  if (find_special (name, &sym, false))
    return MATCH_ERROR;

  if (!check_function_name (name))
    {
      m = MATCH_ERROR;
      goto cleanup;
    }

  var_locus = gfc_current_locus;

  /* Deal with possible array specification for certain attributes.  */
  if (current_attr.dimension
      || current_attr.codimension
      || current_attr.allocatable
      || current_attr.pointer
      || current_attr.target)
    {
      m = gfc_match_array_spec (&as, !current_attr.codimension,
				!current_attr.dimension
				&& !current_attr.pointer
				&& !current_attr.target);
      if (m == MATCH_ERROR)
	goto cleanup;

      if (current_attr.dimension && m == MATCH_NO)
	{
	  gfc_error ("Missing array specification at %L in DIMENSION "
		     "statement", &var_locus);
	  m = MATCH_ERROR;
	  goto cleanup;
	}

      if (current_attr.dimension && sym->value)
	{
	  gfc_error ("Dimensions specified for %s at %L after its "
		     "initialization", sym->name, &var_locus);
	  m = MATCH_ERROR;
	  goto cleanup;
	}

      if (current_attr.codimension && m == MATCH_NO)
	{
	  gfc_error ("Missing array specification at %L in CODIMENSION "
		     "statement", &var_locus);
	  m = MATCH_ERROR;
	  goto cleanup;
	}

      if ((current_attr.allocatable || current_attr.pointer)
	  && (m == MATCH_YES) && (as->type != AS_DEFERRED))
	{
	  gfc_error ("Array specification must be deferred at %L", &var_locus);
	  m = MATCH_ERROR;
	  goto cleanup;
	}
    }

  /* Update symbol table.  DIMENSION attribute is set in
     gfc_set_array_spec().  For CLASS variables, this must be applied
     to the first component, or '_data' field.  */
  if (sym->ts.type == BT_CLASS && sym->ts.u.derived->attr.is_class)
    {
      /* gfc_set_array_spec sets sym->attr not CLASS_DATA(sym)->attr.  Check
	 for duplicate attribute here.  */
      if (CLASS_DATA(sym)->attr.dimension == 1 && as)
	{
	  gfc_error ("Duplicate DIMENSION attribute at %C");
	  m = MATCH_ERROR;
	  goto cleanup;
	}

      if (!gfc_copy_attr (&CLASS_DATA(sym)->attr, &current_attr, &var_locus))
	{
	  m = MATCH_ERROR;
	  goto cleanup;
	}
    }
  else
    {
      if (current_attr.dimension == 0 && current_attr.codimension == 0
	  && !gfc_copy_attr (&sym->attr, &current_attr, &var_locus))
	{
	  m = MATCH_ERROR;
	  goto cleanup;
	}
    }

  if (sym->ts.type == BT_CLASS
      && !gfc_build_class_symbol (&sym->ts, &sym->attr, &sym->as))
    {
      m = MATCH_ERROR;
      goto cleanup;
    }

  if (!gfc_set_array_spec (sym, as, &var_locus))
    {
      m = MATCH_ERROR;
      goto cleanup;
    }

  if (sym->attr.cray_pointee && sym->as != NULL)
    {
      /* Fix the array spec.  */
      m = gfc_mod_pointee_as (sym->as);
      if (m == MATCH_ERROR)
	goto cleanup;
    }

  if (!gfc_add_attribute (&sym->attr, &var_locus))
    {
      m = MATCH_ERROR;
      goto cleanup;
    }

  if ((current_attr.external || current_attr.intrinsic)
      && sym->attr.flavor != FL_PROCEDURE
      && !gfc_add_flavor (&sym->attr, FL_PROCEDURE, sym->name, NULL))
    {
      m = MATCH_ERROR;
      goto cleanup;
    }

  add_hidden_procptr_result (sym);

  return MATCH_YES;

cleanup:
  gfc_free_array_spec (as);
  return m;
}


/* Generic attribute declaration subroutine.  Used for attributes that
   just have a list of names.  */

static match
attr_decl (void)
{
  match m;

  /* Gobble the optional double colon, by simply ignoring the result
     of gfc_match().  */
  gfc_match (" ::");

  for (;;)
    {
      m = attr_decl1 ();
      if (m != MATCH_YES)
	break;

      if (gfc_match_eos () == MATCH_YES)
	{
	  m = MATCH_YES;
	  break;
	}

      if (gfc_match_char (',') != MATCH_YES)
	{
	  gfc_error ("Unexpected character in variable list at %C");
	  m = MATCH_ERROR;
	  break;
	}
    }

  return m;
}


/* This routine matches Cray Pointer declarations of the form:
   pointer ( <pointer>, <pointee> )
   or
   pointer ( <pointer1>, <pointee1> ), ( <pointer2>, <pointee2> ), ...
   The pointer, if already declared, should be an integer.  Otherwise, we
   set it as BT_INTEGER with kind gfc_index_integer_kind.  The pointee may
   be either a scalar, or an array declaration.  No space is allocated for
   the pointee.  For the statement
   pointer (ipt, ar(10))
   any subsequent uses of ar will be translated (in C-notation) as
   ar(i) => ((<type> *) ipt)(i)
   After gimplification, pointee variable will disappear in the code.  */

static match
cray_pointer_decl (void)
{
  match m;
  gfc_array_spec *as = NULL;
  gfc_symbol *cptr; /* Pointer symbol.  */
  gfc_symbol *cpte; /* Pointee symbol.  */
  locus var_locus;
  bool done = false;

  while (!done)
    {
      if (gfc_match_char ('(') != MATCH_YES)
	{
	  gfc_error ("Expected %<(%> at %C");
	  return MATCH_ERROR;
	}

      /* Match pointer.  */
      var_locus = gfc_current_locus;
      gfc_clear_attr (&current_attr);
      gfc_add_cray_pointer (&current_attr, &var_locus);
      current_ts.type = BT_INTEGER;
      current_ts.kind = gfc_index_integer_kind;

      m = gfc_match_symbol (&cptr, 0);
      if (m != MATCH_YES)
	{
	  gfc_error ("Expected variable name at %C");
	  return m;
	}

      if (!gfc_add_cray_pointer (&cptr->attr, &var_locus))
	return MATCH_ERROR;

      gfc_set_sym_referenced (cptr);

      if (cptr->ts.type == BT_UNKNOWN) /* Override the type, if necessary.  */
	{
	  cptr->ts.type = BT_INTEGER;
	  cptr->ts.kind = gfc_index_integer_kind;
	}
      else if (cptr->ts.type != BT_INTEGER)
	{
	  gfc_error ("Cray pointer at %C must be an integer");
	  return MATCH_ERROR;
	}
      else if (cptr->ts.kind < gfc_index_integer_kind)
	gfc_warning (0, "Cray pointer at %C has %d bytes of precision;"
		     " memory addresses require %d bytes",
		     cptr->ts.kind, gfc_index_integer_kind);

      if (gfc_match_char (',') != MATCH_YES)
	{
	  gfc_error ("Expected \",\" at %C");
	  return MATCH_ERROR;
	}

      /* Match Pointee.  */
      var_locus = gfc_current_locus;
      gfc_clear_attr (&current_attr);
      gfc_add_cray_pointee (&current_attr, &var_locus);
      current_ts.type = BT_UNKNOWN;
      current_ts.kind = 0;

      m = gfc_match_symbol (&cpte, 0);
      if (m != MATCH_YES)
	{
	  gfc_error ("Expected variable name at %C");
	  return m;
	}

      /* Check for an optional array spec.  */
      m = gfc_match_array_spec (&as, true, false);
      if (m == MATCH_ERROR)
	{
	  gfc_free_array_spec (as);
	  return m;
	}
      else if (m == MATCH_NO)
	{
	  gfc_free_array_spec (as);
	  as = NULL;
	}

      if (!gfc_add_cray_pointee (&cpte->attr, &var_locus))
	return MATCH_ERROR;

      gfc_set_sym_referenced (cpte);

      if (cpte->as == NULL)
	{
	  if (!gfc_set_array_spec (cpte, as, &var_locus))
	    gfc_internal_error ("Cannot set Cray pointee array spec.");
	}
      else if (as != NULL)
	{
	  gfc_error ("Duplicate array spec for Cray pointee at %C");
	  gfc_free_array_spec (as);
	  return MATCH_ERROR;
	}

      as = NULL;

      if (cpte->as != NULL)
	{
	  /* Fix array spec.  */
	  m = gfc_mod_pointee_as (cpte->as);
	  if (m == MATCH_ERROR)
	    return m;
	}

      /* Point the Pointee at the Pointer.  */
      cpte->cp_pointer = cptr;

      if (gfc_match_char (')') != MATCH_YES)
	{
	  gfc_error ("Expected \")\" at %C");
	  return MATCH_ERROR;
	}
      m = gfc_match_char (',');
      if (m != MATCH_YES)
	done = true; /* Stop searching for more declarations.  */

    }

  if (m == MATCH_ERROR /* Failed when trying to find ',' above.  */
      || gfc_match_eos () != MATCH_YES)
    {
      gfc_error ("Expected %<,%> or end of statement at %C");
      return MATCH_ERROR;
    }
  return MATCH_YES;
}


match
gfc_match_external (void)
{

  gfc_clear_attr (&current_attr);
  current_attr.external = 1;

  return attr_decl ();
}


match
gfc_match_intent (void)
{
  sym_intent intent;

  /* This is not allowed within a BLOCK construct!  */
  if (gfc_current_state () == COMP_BLOCK)
    {
      gfc_error ("INTENT is not allowed inside of BLOCK at %C");
      return MATCH_ERROR;
    }

  intent = match_intent_spec ();
  if (intent == INTENT_UNKNOWN)
    return MATCH_ERROR;

  gfc_clear_attr (&current_attr);
  current_attr.intent = intent;

  return attr_decl ();
}


match
gfc_match_intrinsic (void)
{

  gfc_clear_attr (&current_attr);
  current_attr.intrinsic = 1;

  return attr_decl ();
}


match
gfc_match_optional (void)
{
  /* This is not allowed within a BLOCK construct!  */
  if (gfc_current_state () == COMP_BLOCK)
    {
      gfc_error ("OPTIONAL is not allowed inside of BLOCK at %C");
      return MATCH_ERROR;
    }

  gfc_clear_attr (&current_attr);
  current_attr.optional = 1;

  return attr_decl ();
}


match
gfc_match_pointer (void)
{
  gfc_gobble_whitespace ();
  if (gfc_peek_ascii_char () == '(')
    {
      if (!flag_cray_pointer)
	{
	  gfc_error ("Cray pointer declaration at %C requires "
		     "%<-fcray-pointer%> flag");
	  return MATCH_ERROR;
	}
      return cray_pointer_decl ();
    }
  else
    {
      gfc_clear_attr (&current_attr);
      current_attr.pointer = 1;

      return attr_decl ();
    }
}


match
gfc_match_allocatable (void)
{
  gfc_clear_attr (&current_attr);
  current_attr.allocatable = 1;

  return attr_decl ();
}


match
gfc_match_codimension (void)
{
  gfc_clear_attr (&current_attr);
  current_attr.codimension = 1;

  return attr_decl ();
}


match
gfc_match_contiguous (void)
{
  if (!gfc_notify_std (GFC_STD_F2008, "CONTIGUOUS statement at %C"))
    return MATCH_ERROR;

  gfc_clear_attr (&current_attr);
  current_attr.contiguous = 1;

  return attr_decl ();
}


match
gfc_match_dimension (void)
{
  gfc_clear_attr (&current_attr);
  current_attr.dimension = 1;

  return attr_decl ();
}


match
gfc_match_target (void)
{
  gfc_clear_attr (&current_attr);
  current_attr.target = 1;

  return attr_decl ();
}


/* Match the list of entities being specified in a PUBLIC or PRIVATE
   statement.  */

static match
access_attr_decl (gfc_statement st)
{
  char name[GFC_MAX_SYMBOL_LEN + 1];
  interface_type type;
  gfc_user_op *uop;
  gfc_symbol *sym, *dt_sym;
  gfc_intrinsic_op op;
  match m;
  gfc_access access = (st == ST_PUBLIC) ? ACCESS_PUBLIC : ACCESS_PRIVATE;

  if (gfc_match (" ::") == MATCH_NO && gfc_match_space () == MATCH_NO)
    goto done;

  for (;;)
    {
      m = gfc_match_generic_spec (&type, name, &op);
      if (m == MATCH_NO)
	goto syntax;
      if (m == MATCH_ERROR)
	goto done;

      switch (type)
	{
	case INTERFACE_NAMELESS:
	case INTERFACE_ABSTRACT:
	  goto syntax;

	case INTERFACE_GENERIC:
	case INTERFACE_DTIO:

	  if (gfc_get_symbol (name, NULL, &sym))
	    goto done;

	  if (type == INTERFACE_DTIO
	      && gfc_current_ns->proc_name
	      && gfc_current_ns->proc_name->attr.flavor == FL_MODULE
	      && sym->attr.flavor == FL_UNKNOWN)
	    sym->attr.flavor = FL_PROCEDURE;

	  if (!gfc_add_access (&sym->attr, access, sym->name, NULL))
	    goto done;

	  if (sym->attr.generic && (dt_sym = gfc_find_dt_in_generic (sym))
	      && !gfc_add_access (&dt_sym->attr, access, sym->name, NULL))
	    goto done;

	  break;

	case INTERFACE_INTRINSIC_OP:
	  if (gfc_current_ns->operator_access[op] == ACCESS_UNKNOWN)
	    {
	      gfc_intrinsic_op other_op;

	      gfc_current_ns->operator_access[op] = access;

	      /* Handle the case if there is another op with the same
		 function, for INTRINSIC_EQ vs. INTRINSIC_EQ_OS and so on.  */
	      other_op = gfc_equivalent_op (op);

	      if (other_op != INTRINSIC_NONE)
		gfc_current_ns->operator_access[other_op] = access;
	    }
	  else
	    {
	      gfc_error ("Access specification of the %s operator at %C has "
			 "already been specified", gfc_op2string (op));
	      goto done;
	    }

	  break;

	case INTERFACE_USER_OP:
	  uop = gfc_get_uop (name);

	  if (uop->access == ACCESS_UNKNOWN)
	    {
	      uop->access = access;
	    }
	  else
	    {
	      gfc_error ("Access specification of the .%s. operator at %C "
			 "has already been specified", uop->name);
	      goto done;
	    }

	  break;
	}

      if (gfc_match_char (',') == MATCH_NO)
	break;
    }

  if (gfc_match_eos () != MATCH_YES)
    goto syntax;
  return MATCH_YES;

syntax:
  gfc_syntax_error (st);

done:
  return MATCH_ERROR;
}


match
gfc_match_protected (void)
{
  gfc_symbol *sym;
  match m;
  char c;

  /* PROTECTED has already been seen, but must be followed by whitespace
     or ::.  */
  c = gfc_peek_ascii_char ();
  if (!gfc_is_whitespace (c) && c != ':')
    return MATCH_NO;

  if (!gfc_current_ns->proc_name
      || gfc_current_ns->proc_name->attr.flavor != FL_MODULE)
    {
       gfc_error ("PROTECTED at %C only allowed in specification "
		  "part of a module");
       return MATCH_ERROR;

    }

  gfc_match (" ::");

  if (!gfc_notify_std (GFC_STD_F2003, "PROTECTED statement at %C"))
    return MATCH_ERROR;

  /* PROTECTED has an entity-list.  */
  if (gfc_match_eos () == MATCH_YES)
    goto syntax;

  for(;;)
    {
      m = gfc_match_symbol (&sym, 0);
      switch (m)
	{
	case MATCH_YES:
	  if (!gfc_add_protected (&sym->attr, sym->name, &gfc_current_locus))
	    return MATCH_ERROR;
	  goto next_item;

	case MATCH_NO:
	  break;

	case MATCH_ERROR:
	  return MATCH_ERROR;
	}

    next_item:
      if (gfc_match_eos () == MATCH_YES)
	break;
      if (gfc_match_char (',') != MATCH_YES)
	goto syntax;
    }

  return MATCH_YES;

syntax:
  gfc_error ("Syntax error in PROTECTED statement at %C");
  return MATCH_ERROR;
}


/* The PRIVATE statement is a bit weird in that it can be an attribute
   declaration, but also works as a standalone statement inside of a
   type declaration or a module.  */

match
gfc_match_private (gfc_statement *st)
{
  gfc_state_data *prev;

  if (gfc_match ("private") != MATCH_YES)
    return MATCH_NO;

  /* Try matching PRIVATE without an access-list.  */
  if (gfc_match_eos () == MATCH_YES)
    {
      prev = gfc_state_stack->previous;
      if (gfc_current_state () != COMP_MODULE
	  && !(gfc_current_state () == COMP_DERIVED
		&& prev && prev->state == COMP_MODULE)
	  && !(gfc_current_state () == COMP_DERIVED_CONTAINS
		&& prev->previous && prev->previous->state == COMP_MODULE))
	{
	  gfc_error ("PRIVATE statement at %C is only allowed in the "
		     "specification part of a module");
	  return MATCH_ERROR;
	}

      *st = ST_PRIVATE;
      return MATCH_YES;
    }

  /* At this point in free-form source code, PRIVATE must be followed
     by whitespace or ::.  */
  if (gfc_current_form == FORM_FREE)
    {
      char c = gfc_peek_ascii_char ();
      if (!gfc_is_whitespace (c) && c != ':')
	return MATCH_NO;
    }

  prev = gfc_state_stack->previous;
  if (gfc_current_state () != COMP_MODULE
      && !(gfc_current_state () == COMP_DERIVED
	   && prev && prev->state == COMP_MODULE)
      && !(gfc_current_state () == COMP_DERIVED_CONTAINS
	   && prev->previous && prev->previous->state == COMP_MODULE))
    {
      gfc_error ("PRIVATE statement at %C is only allowed in the "
		 "specification part of a module");
      return MATCH_ERROR;
    }

  *st = ST_ATTR_DECL;
  return access_attr_decl (ST_PRIVATE);
}


match
gfc_match_public (gfc_statement *st)
{
  if (gfc_match ("public") != MATCH_YES)
    return MATCH_NO;

  /* Try matching PUBLIC without an access-list.  */
  if (gfc_match_eos () == MATCH_YES)
    {
      if (gfc_current_state () != COMP_MODULE)
	{
	  gfc_error ("PUBLIC statement at %C is only allowed in the "
		     "specification part of a module");
	  return MATCH_ERROR;
	}

      *st = ST_PUBLIC;
      return MATCH_YES;
    }

  /* At this point in free-form source code, PUBLIC must be followed
     by whitespace or ::.  */
  if (gfc_current_form == FORM_FREE)
    {
      char c = gfc_peek_ascii_char ();
      if (!gfc_is_whitespace (c) && c != ':')
	return MATCH_NO;
    }

  if (gfc_current_state () != COMP_MODULE)
    {
      gfc_error ("PUBLIC statement at %C is only allowed in the "
		 "specification part of a module");
      return MATCH_ERROR;
    }

  *st = ST_ATTR_DECL;
  return access_attr_decl (ST_PUBLIC);
}


/* Workhorse for gfc_match_parameter.  */

static match
do_parm (void)
{
  gfc_symbol *sym;
  gfc_expr *init;
  match m;
  bool t;

  m = gfc_match_symbol (&sym, 0);
  if (m == MATCH_NO)
    gfc_error ("Expected variable name at %C in PARAMETER statement");

  if (m != MATCH_YES)
    return m;

  if (gfc_match_char ('=') == MATCH_NO)
    {
      gfc_error ("Expected = sign in PARAMETER statement at %C");
      return MATCH_ERROR;
    }

  m = gfc_match_init_expr (&init);
  if (m == MATCH_NO)
    gfc_error ("Expected expression at %C in PARAMETER statement");
  if (m != MATCH_YES)
    return m;

  if (sym->ts.type == BT_UNKNOWN
      && !gfc_set_default_type (sym, 1, NULL))
    {
      m = MATCH_ERROR;
      goto cleanup;
    }

  if (!gfc_check_assign_symbol (sym, NULL, init)
      || !gfc_add_flavor (&sym->attr, FL_PARAMETER, sym->name, NULL))
    {
      m = MATCH_ERROR;
      goto cleanup;
    }

  if (sym->value)
    {
      gfc_error ("Initializing already initialized variable at %C");
      m = MATCH_ERROR;
      goto cleanup;
    }

  t = add_init_expr_to_sym (sym->name, &init, &gfc_current_locus);
  return (t) ? MATCH_YES : MATCH_ERROR;

cleanup:
  gfc_free_expr (init);
  return m;
}


/* Match a parameter statement, with the weird syntax that these have.  */

match
gfc_match_parameter (void)
{
  const char *term = " )%t";
  match m;

  if (gfc_match_char ('(') == MATCH_NO)
    {
      /* With legacy PARAMETER statements, don't expect a terminating ')'.  */
      if (!gfc_notify_std (GFC_STD_LEGACY, "PARAMETER without '()' at %C"))
	return MATCH_NO;
      term = " %t";
    }

  for (;;)
    {
      m = do_parm ();
      if (m != MATCH_YES)
	break;

      if (gfc_match (term) == MATCH_YES)
	break;

      if (gfc_match_char (',') != MATCH_YES)
	{
	  gfc_error ("Unexpected characters in PARAMETER statement at %C");
	  m = MATCH_ERROR;
	  break;
	}
    }

  return m;
}


match
gfc_match_automatic (void)
{
  gfc_symbol *sym;
  match m;
  bool seen_symbol = false;

  if (!flag_dec_static)
    {
      gfc_error ("%s at %C is a DEC extension, enable with "
		 "%<-fdec-static%>",
		 "AUTOMATIC"
		 );
      return MATCH_ERROR;
    }

  gfc_match (" ::");

  for (;;)
    {
      m = gfc_match_symbol (&sym, 0);
      switch (m)
      {
      case MATCH_NO:
        break;

      case MATCH_ERROR:
	return MATCH_ERROR;

      case MATCH_YES:
	if (!gfc_add_automatic (&sym->attr, sym->name, &gfc_current_locus))
	  return MATCH_ERROR;
	seen_symbol = true;
	break;
      }

      if (gfc_match_eos () == MATCH_YES)
	break;
      if (gfc_match_char (',') != MATCH_YES)
	goto syntax;
    }

  if (!seen_symbol)
    {
      gfc_error ("Expected entity-list in AUTOMATIC statement at %C");
      return MATCH_ERROR;
    }

  return MATCH_YES;

syntax:
  gfc_error ("Syntax error in AUTOMATIC statement at %C");
  return MATCH_ERROR;
}


match
gfc_match_static (void)
{
  gfc_symbol *sym;
  match m;
  bool seen_symbol = false;

  if (!flag_dec_static)
    {
      gfc_error ("%s at %C is a DEC extension, enable with "
		 "%<-fdec-static%>",
		 "STATIC");
      return MATCH_ERROR;
    }

  gfc_match (" ::");

  for (;;)
    {
      m = gfc_match_symbol (&sym, 0);
      switch (m)
      {
      case MATCH_NO:
        break;

      case MATCH_ERROR:
	return MATCH_ERROR;

      case MATCH_YES:
	if (!gfc_add_save (&sym->attr, SAVE_EXPLICIT, sym->name,
			  &gfc_current_locus))
	  return MATCH_ERROR;
	seen_symbol = true;
	break;
      }

      if (gfc_match_eos () == MATCH_YES)
	break;
      if (gfc_match_char (',') != MATCH_YES)
	goto syntax;
    }

  if (!seen_symbol)
    {
      gfc_error ("Expected entity-list in STATIC statement at %C");
      return MATCH_ERROR;
    }

  return MATCH_YES;

syntax:
  gfc_error ("Syntax error in STATIC statement at %C");
  return MATCH_ERROR;
}


/* Save statements have a special syntax.  */

match
gfc_match_save (void)
{
  char n[GFC_MAX_SYMBOL_LEN+1];
  gfc_common_head *c;
  gfc_symbol *sym;
  match m;

  if (gfc_match_eos () == MATCH_YES)
    {
      if (gfc_current_ns->seen_save)
	{
	  if (!gfc_notify_std (GFC_STD_LEGACY, "Blanket SAVE statement at %C "
			       "follows previous SAVE statement"))
	    return MATCH_ERROR;
	}

      gfc_current_ns->save_all = gfc_current_ns->seen_save = 1;
      return MATCH_YES;
    }

  if (gfc_current_ns->save_all)
    {
      if (!gfc_notify_std (GFC_STD_LEGACY, "SAVE statement at %C follows "
			   "blanket SAVE statement"))
	return MATCH_ERROR;
    }

  gfc_match (" ::");

  for (;;)
    {
      m = gfc_match_symbol (&sym, 0);
      switch (m)
	{
	case MATCH_YES:
	  if (!gfc_add_save (&sym->attr, SAVE_EXPLICIT, sym->name,
			     &gfc_current_locus))
	    return MATCH_ERROR;
	  goto next_item;

	case MATCH_NO:
	  break;

	case MATCH_ERROR:
	  return MATCH_ERROR;
	}

      m = gfc_match (" / %n /", &n);
      if (m == MATCH_ERROR)
	return MATCH_ERROR;
      if (m == MATCH_NO)
	goto syntax;

      c = gfc_get_common (n, 0);
      c->saved = 1;

      gfc_current_ns->seen_save = 1;

    next_item:
      if (gfc_match_eos () == MATCH_YES)
	break;
      if (gfc_match_char (',') != MATCH_YES)
	goto syntax;
    }

  return MATCH_YES;

syntax:
  if (gfc_current_ns->seen_save)
    {
      gfc_error ("Syntax error in SAVE statement at %C");
      return MATCH_ERROR;
    }
  else
      return MATCH_NO;
}


match
gfc_match_value (void)
{
  gfc_symbol *sym;
  match m;

  /* This is not allowed within a BLOCK construct!  */
  if (gfc_current_state () == COMP_BLOCK)
    {
      gfc_error ("VALUE is not allowed inside of BLOCK at %C");
      return MATCH_ERROR;
    }

  if (!gfc_notify_std (GFC_STD_F2003, "VALUE statement at %C"))
    return MATCH_ERROR;

  if (gfc_match (" ::") == MATCH_NO && gfc_match_space () == MATCH_NO)
    {
      return MATCH_ERROR;
    }

  if (gfc_match_eos () == MATCH_YES)
    goto syntax;

  for(;;)
    {
      m = gfc_match_symbol (&sym, 0);
      switch (m)
	{
	case MATCH_YES:
	  if (!gfc_add_value (&sym->attr, sym->name, &gfc_current_locus))
	    return MATCH_ERROR;
	  goto next_item;

	case MATCH_NO:
	  break;

	case MATCH_ERROR:
	  return MATCH_ERROR;
	}

    next_item:
      if (gfc_match_eos () == MATCH_YES)
	break;
      if (gfc_match_char (',') != MATCH_YES)
	goto syntax;
    }

  return MATCH_YES;

syntax:
  gfc_error ("Syntax error in VALUE statement at %C");
  return MATCH_ERROR;
}


match
gfc_match_volatile (void)
{
  gfc_symbol *sym;
  char *name;
  match m;

  if (!gfc_notify_std (GFC_STD_F2003, "VOLATILE statement at %C"))
    return MATCH_ERROR;

  if (gfc_match (" ::") == MATCH_NO && gfc_match_space () == MATCH_NO)
    {
      return MATCH_ERROR;
    }

  if (gfc_match_eos () == MATCH_YES)
    goto syntax;

  for(;;)
    {
      /* VOLATILE is special because it can be added to host-associated
	 symbols locally.  Except for coarrays.  */
      m = gfc_match_symbol (&sym, 1);
      switch (m)
	{
	case MATCH_YES:
	  name = XCNEWVAR (char, strlen (sym->name) + 1);
	  strcpy (name, sym->name);
	  if (!check_function_name (name))
	    return MATCH_ERROR;
	  /* F2008, C560+C561. VOLATILE for host-/use-associated variable or
	     for variable in a BLOCK which is defined outside of the BLOCK.  */
	  if (sym->ns != gfc_current_ns && sym->attr.codimension)
	    {
	      gfc_error ("Specifying VOLATILE for coarray variable %qs at "
			 "%C, which is use-/host-associated", sym->name);
	      return MATCH_ERROR;
	    }
	  if (!gfc_add_volatile (&sym->attr, sym->name, &gfc_current_locus))
	    return MATCH_ERROR;
	  goto next_item;

	case MATCH_NO:
	  break;

	case MATCH_ERROR:
	  return MATCH_ERROR;
	}

    next_item:
      if (gfc_match_eos () == MATCH_YES)
	break;
      if (gfc_match_char (',') != MATCH_YES)
	goto syntax;
    }

  return MATCH_YES;

syntax:
  gfc_error ("Syntax error in VOLATILE statement at %C");
  return MATCH_ERROR;
}


match
gfc_match_asynchronous (void)
{
  gfc_symbol *sym;
  char *name;
  match m;

  if (!gfc_notify_std (GFC_STD_F2003, "ASYNCHRONOUS statement at %C"))
    return MATCH_ERROR;

  if (gfc_match (" ::") == MATCH_NO && gfc_match_space () == MATCH_NO)
    {
      return MATCH_ERROR;
    }

  if (gfc_match_eos () == MATCH_YES)
    goto syntax;

  for(;;)
    {
      /* ASYNCHRONOUS is special because it can be added to host-associated
	 symbols locally.  */
      m = gfc_match_symbol (&sym, 1);
      switch (m)
	{
	case MATCH_YES:
	  name = XCNEWVAR (char, strlen (sym->name) + 1);
	  strcpy (name, sym->name);
	  if (!check_function_name (name))
	    return MATCH_ERROR;
	  if (!gfc_add_asynchronous (&sym->attr, sym->name, &gfc_current_locus))
	    return MATCH_ERROR;
	  goto next_item;

	case MATCH_NO:
	  break;

	case MATCH_ERROR:
	  return MATCH_ERROR;
	}

    next_item:
      if (gfc_match_eos () == MATCH_YES)
	break;
      if (gfc_match_char (',') != MATCH_YES)
	goto syntax;
    }

  return MATCH_YES;

syntax:
  gfc_error ("Syntax error in ASYNCHRONOUS statement at %C");
  return MATCH_ERROR;
}


/* Match a module procedure statement in a submodule.  */

match
gfc_match_submod_proc (void)
{
  char name[GFC_MAX_SYMBOL_LEN + 1];
  gfc_symbol *sym, *fsym;
  match m;
  gfc_formal_arglist *formal, *head, *tail;

  if (gfc_current_state () != COMP_CONTAINS
      || !(gfc_state_stack->previous
	   && (gfc_state_stack->previous->state == COMP_SUBMODULE
	       || gfc_state_stack->previous->state == COMP_MODULE)))
    return MATCH_NO;

  m = gfc_match (" module% procedure% %n", name);
  if (m != MATCH_YES)
    return m;

  if (!gfc_notify_std (GFC_STD_F2008, "MODULE PROCEDURE declaration "
				      "at %C"))
    return MATCH_ERROR;

  if (get_proc_name (name, &sym, false))
    return MATCH_ERROR;

  /* Make sure that the result field is appropriately filled.  */
  if (sym->tlink && sym->tlink->attr.function)
    {
      if (sym->tlink->result && sym->tlink->result != sym->tlink)
	{
	  sym->result = sym->tlink->result;
	  if (!sym->result->attr.use_assoc)
	    {
	      gfc_symtree *st = gfc_new_symtree (&gfc_current_ns->sym_root,
						 sym->result->name);
	      st->n.sym = sym->result;
	      sym->result->refs++;
	    }
	}
      else
	sym->result = sym;
    }

  /* Set declared_at as it might point to, e.g., a PUBLIC statement, if
     the symbol existed before.  */
  sym->declared_at = gfc_current_locus;

  if (!sym->attr.module_procedure)
    return MATCH_ERROR;

  /* Signal match_end to expect "end procedure".  */
  sym->abr_modproc_decl = 1;

  /* Change from IFSRC_IFBODY coming from the interface declaration.  */
  sym->attr.if_source = IFSRC_DECL;

  gfc_new_block = sym;

  /* Make a new formal arglist with the symbols in the procedure
      namespace.  */
  head = tail = NULL;
  for (formal = sym->formal; formal && formal->sym; formal = formal->next)
    {
      if (formal == sym->formal)
	head = tail = gfc_get_formal_arglist ();
      else
	{
	  tail->next = gfc_get_formal_arglist ();
	  tail = tail->next;
	}

      if (gfc_copy_dummy_sym (&fsym, formal->sym, 0))
	goto cleanup;

      tail->sym = fsym;
      gfc_set_sym_referenced (fsym);
    }

  /* The dummy symbols get cleaned up, when the formal_namespace of the
     interface declaration is cleared.  This allows us to add the
     explicit interface as is done for other type of procedure.  */
  if (!gfc_add_explicit_interface (sym, IFSRC_DECL, head,
				   &gfc_current_locus))
    return MATCH_ERROR;

  if (gfc_match_eos () != MATCH_YES)
    {
      /* Unset st->n.sym. Note: in reject_statement (), the symbol changes are
	 undone, such that the st->n.sym->formal points to the original symbol;
	 if now this namespace is finalized, the formal namespace is freed,
	 but it might be still needed in the parent namespace.  */
      gfc_symtree *st = gfc_find_symtree (gfc_current_ns->sym_root, sym->name);
      st->n.sym = NULL;
      gfc_free_symbol (sym->tlink);
      sym->tlink = NULL;
      sym->refs--;
      gfc_syntax_error (ST_MODULE_PROC);
      return MATCH_ERROR;
    }

  return MATCH_YES;

cleanup:
  gfc_free_formal_arglist (head);
  return MATCH_ERROR;
}


/* Match a module procedure statement.  Note that we have to modify
   symbols in the parent's namespace because the current one was there
   to receive symbols that are in an interface's formal argument list.  */

match
gfc_match_modproc (void)
{
  char name[GFC_MAX_SYMBOL_LEN + 1];
  gfc_symbol *sym;
  match m;
  locus old_locus;
  gfc_namespace *module_ns;
  gfc_interface *old_interface_head, *interface;

  if ((gfc_state_stack->state != COMP_INTERFACE
       && gfc_state_stack->state != COMP_CONTAINS)
      || gfc_state_stack->previous == NULL
      || current_interface.type == INTERFACE_NAMELESS
      || current_interface.type == INTERFACE_ABSTRACT)
    {
      gfc_error ("MODULE PROCEDURE at %C must be in a generic module "
		 "interface");
      return MATCH_ERROR;
    }

  module_ns = gfc_current_ns->parent;
  for (; module_ns; module_ns = module_ns->parent)
    if (module_ns->proc_name->attr.flavor == FL_MODULE
	|| module_ns->proc_name->attr.flavor == FL_PROGRAM
	|| (module_ns->proc_name->attr.flavor == FL_PROCEDURE
	    && !module_ns->proc_name->attr.contained))
      break;

  if (module_ns == NULL)
    return MATCH_ERROR;

  /* Store the current state of the interface. We will need it if we
     end up with a syntax error and need to recover.  */
  old_interface_head = gfc_current_interface_head ();

  /* Check if the F2008 optional double colon appears.  */
  gfc_gobble_whitespace ();
  old_locus = gfc_current_locus;
  if (gfc_match ("::") == MATCH_YES)
    {
      if (!gfc_notify_std (GFC_STD_F2008, "double colon in "
			   "MODULE PROCEDURE statement at %L", &old_locus))
	return MATCH_ERROR;
    }
  else
    gfc_current_locus = old_locus;

  for (;;)
    {
      bool last = false;
      old_locus = gfc_current_locus;

      m = gfc_match_name (name);
      if (m == MATCH_NO)
	goto syntax;
      if (m != MATCH_YES)
	return MATCH_ERROR;

      /* Check for syntax error before starting to add symbols to the
	 current namespace.  */
      if (gfc_match_eos () == MATCH_YES)
	last = true;

      if (!last && gfc_match_char (',') != MATCH_YES)
	goto syntax;

      /* Now we're sure the syntax is valid, we process this item
	 further.  */
      if (gfc_get_symbol (name, module_ns, &sym))
	return MATCH_ERROR;

      if (sym->attr.intrinsic)
	{
	  gfc_error ("Intrinsic procedure at %L cannot be a MODULE "
		     "PROCEDURE", &old_locus);
	  return MATCH_ERROR;
	}

      if (sym->attr.proc != PROC_MODULE
	  && !gfc_add_procedure (&sym->attr, PROC_MODULE, sym->name, NULL))
	return MATCH_ERROR;

      if (!gfc_add_interface (sym))
	return MATCH_ERROR;

      sym->attr.mod_proc = 1;
      sym->declared_at = old_locus;

      if (last)
	break;
    }

  return MATCH_YES;

syntax:
  /* Restore the previous state of the interface.  */
  interface = gfc_current_interface_head ();
  gfc_set_current_interface_head (old_interface_head);

  /* Free the new interfaces.  */
  while (interface != old_interface_head)
  {
    gfc_interface *i = interface->next;
    free (interface);
    interface = i;
  }

  /* And issue a syntax error.  */
  gfc_syntax_error (ST_MODULE_PROC);
  return MATCH_ERROR;
}


/* Check a derived type that is being extended.  */

static gfc_symbol*
check_extended_derived_type (char *name)
{
  gfc_symbol *extended;

  if (gfc_find_symbol (name, gfc_current_ns, 1, &extended))
    {
      gfc_error ("Ambiguous symbol in TYPE definition at %C");
      return NULL;
    }

  extended = gfc_find_dt_in_generic (extended);

  /* F08:C428.  */
  if (!extended)
    {
      gfc_error ("Symbol %qs at %C has not been previously defined", name);
      return NULL;
    }

  if (extended->attr.flavor != FL_DERIVED)
    {
      gfc_error ("%qs in EXTENDS expression at %C is not a "
		 "derived type", name);
      return NULL;
    }

  if (extended->attr.is_bind_c)
    {
      gfc_error ("%qs cannot be extended at %C because it "
		 "is BIND(C)", extended->name);
      return NULL;
    }

  if (extended->attr.sequence)
    {
      gfc_error ("%qs cannot be extended at %C because it "
		 "is a SEQUENCE type", extended->name);
      return NULL;
    }

  return extended;
}


/* Match the optional attribute specifiers for a type declaration.
   Return MATCH_ERROR if an error is encountered in one of the handled
   attributes (public, private, bind(c)), MATCH_NO if what's found is
   not a handled attribute, and MATCH_YES otherwise.  TODO: More error
   checking on attribute conflicts needs to be done.  */

static match
gfc_get_type_attr_spec (symbol_attribute *attr, char *name)
{
  /* See if the derived type is marked as private.  */
  if (gfc_match (" , private") == MATCH_YES)
    {
      if (gfc_current_state () != COMP_MODULE)
	{
	  gfc_error ("Derived type at %C can only be PRIVATE in the "
		     "specification part of a module");
	  return MATCH_ERROR;
	}

      if (!gfc_add_access (attr, ACCESS_PRIVATE, NULL, NULL))
	return MATCH_ERROR;
    }
  else if (gfc_match (" , public") == MATCH_YES)
    {
      if (gfc_current_state () != COMP_MODULE)
	{
	  gfc_error ("Derived type at %C can only be PUBLIC in the "
		     "specification part of a module");
	  return MATCH_ERROR;
	}

      if (!gfc_add_access (attr, ACCESS_PUBLIC, NULL, NULL))
	return MATCH_ERROR;
    }
  else if (gfc_match (" , bind ( c )") == MATCH_YES)
    {
      /* If the type is defined to be bind(c) it then needs to make
	 sure that all fields are interoperable.  This will
	 need to be a semantic check on the finished derived type.
	 See 15.2.3 (lines 9-12) of F2003 draft.  */
      if (!gfc_add_is_bind_c (attr, NULL, &gfc_current_locus, 0))
	return MATCH_ERROR;

      /* TODO: attr conflicts need to be checked, probably in symbol.cc.  */
    }
  else if (gfc_match (" , abstract") == MATCH_YES)
    {
      if (!gfc_notify_std (GFC_STD_F2003, "ABSTRACT type at %C"))
	return MATCH_ERROR;

      if (!gfc_add_abstract (attr, &gfc_current_locus))
	return MATCH_ERROR;
    }
  else if (name && gfc_match (" , extends ( %n )", name) == MATCH_YES)
    {
      if (!gfc_add_extension (attr, &gfc_current_locus))
	return MATCH_ERROR;
    }
  else
    return MATCH_NO;

  /* If we get here, something matched.  */
  return MATCH_YES;
}


/* Common function for type declaration blocks similar to derived types, such
   as STRUCTURES and MAPs. Unlike derived types, a structure type
   does NOT have a generic symbol matching the name given by the user.
   STRUCTUREs can share names with variables and PARAMETERs so we must allow
   for the creation of an independent symbol.
   Other parameters are a message to prefix errors with, the name of the new
   type to be created, and the flavor to add to the resulting symbol. */

static bool
get_struct_decl (const char *name, sym_flavor fl, locus *decl,
                 gfc_symbol **result)
{
  gfc_symbol *sym;
  locus where;

  gcc_assert (name[0] == (char) TOUPPER (name[0]));

  if (decl)
    where = *decl;
  else
    where = gfc_current_locus;

  if (gfc_get_symbol (name, NULL, &sym))
    return false;

  if (!sym)
    {
      gfc_internal_error ("Failed to create structure type '%s' at %C", name);
      return false;
    }

  if (sym->components != NULL || sym->attr.zero_comp)
    {
      gfc_error ("Type definition of %qs at %C was already defined at %L",
                 sym->name, &sym->declared_at);
      return false;
    }

  sym->declared_at = where;

  if (sym->attr.flavor != fl
      && !gfc_add_flavor (&sym->attr, fl, sym->name, NULL))
    return false;

  if (!sym->hash_value)
      /* Set the hash for the compound name for this type.  */
    sym->hash_value = gfc_hash_value (sym);

  /* Normally the type is expected to have been completely parsed by the time
     a field declaration with this type is seen. For unions, maps, and nested
     structure declarations, we need to indicate that it is okay that we
     haven't seen any components yet. This will be updated after the structure
     is fully parsed. */
  sym->attr.zero_comp = 0;

  /* Structures always act like derived-types with the SEQUENCE attribute */
  gfc_add_sequence (&sym->attr, sym->name, NULL);

  if (result) *result = sym;

  return true;
}


/* Match the opening of a MAP block. Like a struct within a union in C;
   behaves identical to STRUCTURE blocks.  */

match
gfc_match_map (void)
{
  /* Counter used to give unique internal names to map structures. */
  static unsigned int gfc_map_id = 0;
  char name[GFC_MAX_SYMBOL_LEN + 1];
  gfc_symbol *sym;
  locus old_loc;

  old_loc = gfc_current_locus;

  if (gfc_match_eos () != MATCH_YES)
    {
	gfc_error ("Junk after MAP statement at %C");
	gfc_current_locus = old_loc;
	return MATCH_ERROR;
    }

  /* Map blocks are anonymous so we make up unique names for the symbol table
     which are invalid Fortran identifiers.  */
  snprintf (name, GFC_MAX_SYMBOL_LEN + 1, "MM$%u", gfc_map_id++);

  if (!get_struct_decl (name, FL_STRUCT, &old_loc, &sym))
    return MATCH_ERROR;

  gfc_new_block = sym;

  return MATCH_YES;
}


/* Match the opening of a UNION block.  */

match
gfc_match_union (void)
{
  /* Counter used to give unique internal names to union types. */
  static unsigned int gfc_union_id = 0;
  char name[GFC_MAX_SYMBOL_LEN + 1];
  gfc_symbol *sym;
  locus old_loc;

  old_loc = gfc_current_locus;

  if (gfc_match_eos () != MATCH_YES)
    {
	gfc_error ("Junk after UNION statement at %C");
	gfc_current_locus = old_loc;
	return MATCH_ERROR;
    }

  /* Unions are anonymous so we make up unique names for the symbol table
     which are invalid Fortran identifiers.  */
  snprintf (name, GFC_MAX_SYMBOL_LEN + 1, "UU$%u", gfc_union_id++);

  if (!get_struct_decl (name, FL_UNION, &old_loc, &sym))
    return MATCH_ERROR;

  gfc_new_block = sym;

  return MATCH_YES;
}


/* Match the beginning of a STRUCTURE declaration. This is similar to
   matching the beginning of a derived type declaration with a few
   twists. The resulting type symbol has no access control or other
   interesting attributes.  */

match
gfc_match_structure_decl (void)
{
  /* Counter used to give unique internal names to anonymous structures.  */
  static unsigned int gfc_structure_id = 0;
  char name[GFC_MAX_SYMBOL_LEN + 1];
  gfc_symbol *sym;
  match m;
  locus where;

  if (!flag_dec_structure)
    {
      gfc_error ("%s at %C is a DEC extension, enable with "
		 "%<-fdec-structure%>",
		 "STRUCTURE");
      return MATCH_ERROR;
    }

  name[0] = '\0';

  m = gfc_match (" /%n/", name);
  if (m != MATCH_YES)
    {
      /* Non-nested structure declarations require a structure name.  */
      if (!gfc_comp_struct (gfc_current_state ()))
	{
	    gfc_error ("Structure name expected in non-nested structure "
		       "declaration at %C");
	    return MATCH_ERROR;
	}
      /* This is an anonymous structure; make up a unique name for it
	 (upper-case letters never make it to symbol names from the source).
	 The important thing is initializing the type variable
	 and setting gfc_new_symbol, which is immediately used by
	 parse_structure () and variable_decl () to add components of
	 this type.  */
      snprintf (name, GFC_MAX_SYMBOL_LEN + 1, "SS$%u", gfc_structure_id++);
    }

  where = gfc_current_locus;
  /* No field list allowed after non-nested structure declaration.  */
  if (!gfc_comp_struct (gfc_current_state ())
      && gfc_match_eos () != MATCH_YES)
    {
      gfc_error ("Junk after non-nested STRUCTURE statement at %C");
      return MATCH_ERROR;
    }

  /* Make sure the name is not the name of an intrinsic type.  */
  if (gfc_is_intrinsic_typename (name))
    {
      gfc_error ("Structure name %qs at %C cannot be the same as an"
		 " intrinsic type", name);
      return MATCH_ERROR;
    }

  /* Store the actual type symbol for the structure with an upper-case first
     letter (an invalid Fortran identifier).  */

  if (!get_struct_decl (gfc_dt_upper_string (name), FL_STRUCT, &where, &sym))
    return MATCH_ERROR;

  gfc_new_block = sym;
  return MATCH_YES;
}


/* This function does some work to determine which matcher should be used to
 * match a statement beginning with "TYPE".  This is used to disambiguate TYPE
 * as an alias for PRINT from derived type declarations, TYPE IS statements,
 * and [parameterized] derived type declarations.  */

match
gfc_match_type (gfc_statement *st)
{
  char name[GFC_MAX_SYMBOL_LEN + 1];
  match m;
  locus old_loc;

  /* Requires -fdec.  */
  if (!flag_dec)
    return MATCH_NO;

  m = gfc_match ("type");
  if (m != MATCH_YES)
    return m;
  /* If we already have an error in the buffer, it is probably from failing to
   * match a derived type data declaration. Let it happen.  */
  else if (gfc_error_flag_test ())
    return MATCH_NO;

  old_loc = gfc_current_locus;
  *st = ST_NONE;

  /* If we see an attribute list before anything else it's definitely a derived
   * type declaration.  */
  if (gfc_match (" ,") == MATCH_YES || gfc_match (" ::") == MATCH_YES)
    goto derived;

  /* By now "TYPE" has already been matched. If we do not see a name, this may
   * be something like "TYPE *" or "TYPE <fmt>".  */
  m = gfc_match_name (name);
  if (m != MATCH_YES)
    {
      /* Let print match if it can, otherwise throw an error from
       * gfc_match_derived_decl.  */
      gfc_current_locus = old_loc;
      if (gfc_match_print () == MATCH_YES)
	{
	  *st = ST_WRITE;
	  return MATCH_YES;
	}
      goto derived;
    }

  /* Check for EOS.  */
  if (gfc_match_eos () == MATCH_YES)
    {
      /* By now we have "TYPE <name> <EOS>". Check first if the name is an
       * intrinsic typename - if so let gfc_match_derived_decl dump an error.
       * Otherwise if gfc_match_derived_decl fails it's probably an existing
       * symbol which can be printed.  */
      gfc_current_locus = old_loc;
      m = gfc_match_derived_decl ();
      if (gfc_is_intrinsic_typename (name) || m == MATCH_YES)
	{
	  *st = ST_DERIVED_DECL;
	  return m;
	}
    }
  else
    {
      /* Here we have "TYPE <name>". Check for <TYPE IS (> or a PDT declaration
	 like <type name(parameter)>.  */
      gfc_gobble_whitespace ();
      bool paren = gfc_peek_ascii_char () == '(';
      if (paren)
	{
	  if (strcmp ("is", name) == 0)
	    goto typeis;
	  else
	    goto derived;
	}
    }

  /* Treat TYPE... like PRINT...  */
  gfc_current_locus = old_loc;
  *st = ST_WRITE;
  return gfc_match_print ();

derived:
  gfc_current_locus = old_loc;
  *st = ST_DERIVED_DECL;
  return gfc_match_derived_decl ();

typeis:
  gfc_current_locus = old_loc;
  *st = ST_TYPE_IS;
  return gfc_match_type_is ();
}


/* Match the beginning of a derived type declaration.  If a type name
   was the result of a function, then it is possible to have a symbol
   already to be known as a derived type yet have no components.  */

match
gfc_match_derived_decl (void)
{
  char name[GFC_MAX_SYMBOL_LEN + 1];
  char parent[GFC_MAX_SYMBOL_LEN + 1];
  symbol_attribute attr;
  gfc_symbol *sym, *gensym;
  gfc_symbol *extended;
  match m;
  match is_type_attr_spec = MATCH_NO;
  bool seen_attr = false;
  gfc_interface *intr = NULL, *head;
  bool parameterized_type = false;
  bool seen_colons = false;

  if (gfc_comp_struct (gfc_current_state ()))
    return MATCH_NO;

  name[0] = '\0';
  parent[0] = '\0';
  gfc_clear_attr (&attr);
  extended = NULL;

  do
    {
      is_type_attr_spec = gfc_get_type_attr_spec (&attr, parent);
      if (is_type_attr_spec == MATCH_ERROR)
	return MATCH_ERROR;
      if (is_type_attr_spec == MATCH_YES)
	seen_attr = true;
    } while (is_type_attr_spec == MATCH_YES);

  /* Deal with derived type extensions.  The extension attribute has
     been added to 'attr' but now the parent type must be found and
     checked.  */
  if (parent[0])
    extended = check_extended_derived_type (parent);

  if (parent[0] && !extended)
    return MATCH_ERROR;

  m = gfc_match (" ::");
  if (m == MATCH_YES)
    {
      seen_colons = true;
    }
  else if (seen_attr)
    {
      gfc_error ("Expected :: in TYPE definition at %C");
      return MATCH_ERROR;
    }

  /*  In free source form, need to check for TYPE XXX as oppose to TYPEXXX.
      But, we need to simply return for TYPE(.  */
  if (m == MATCH_NO && gfc_current_form == FORM_FREE)
    {
      char c = gfc_peek_ascii_char ();
      if (c == '(')
	return m;
      if (!gfc_is_whitespace (c))
	{
	  gfc_error ("Mangled derived type definition at %C");
	  return MATCH_NO;
	}
    }

  m = gfc_match (" %n ", name);
  if (m != MATCH_YES)
    return m;

  /* Make sure that we don't identify TYPE IS (...) as a parameterized
     derived type named 'is'.
     TODO Expand the check, when 'name' = "is" by matching " (tname) "
     and checking if this is a(n intrinsic) typename.  This picks up
     misplaced TYPE IS statements such as in select_type_1.f03.  */
  if (gfc_peek_ascii_char () == '(')
    {
      if (gfc_current_state () == COMP_SELECT_TYPE
	  || (!seen_colons && !strcmp (name, "is")))
	return MATCH_NO;
      parameterized_type = true;
    }

  m = gfc_match_eos ();
  if (m != MATCH_YES && !parameterized_type)
    return m;

  /* Make sure the name is not the name of an intrinsic type.  */
  if (gfc_is_intrinsic_typename (name))
    {
      gfc_error ("Type name %qs at %C cannot be the same as an intrinsic "
		 "type", name);
      return MATCH_ERROR;
    }

  if (gfc_get_symbol (name, NULL, &gensym))
    return MATCH_ERROR;

  if (!gensym->attr.generic && gensym->ts.type != BT_UNKNOWN)
    {
      if (gensym->ts.u.derived)
	gfc_error ("Derived type name %qs at %C already has a basic type "
		   "of %s", gensym->name, gfc_typename (&gensym->ts));
      else
	gfc_error ("Derived type name %qs at %C already has a basic type",
		   gensym->name);
      return MATCH_ERROR;
    }

  if (!gensym->attr.generic
      && !gfc_add_generic (&gensym->attr, gensym->name, NULL))
    return MATCH_ERROR;

  if (!gensym->attr.function
      && !gfc_add_function (&gensym->attr, gensym->name, NULL))
    return MATCH_ERROR;

  if (gensym->attr.dummy)
    {
      gfc_error ("Dummy argument %qs at %L cannot be a derived type at %C",
		 name, &gensym->declared_at);
      return MATCH_ERROR;
    }

  sym = gfc_find_dt_in_generic (gensym);

  if (sym && (sym->components != NULL || sym->attr.zero_comp))
    {
      gfc_error ("Derived type definition of %qs at %C has already been "
                 "defined", sym->name);
      return MATCH_ERROR;
    }

  if (!sym)
    {
      /* Use upper case to save the actual derived-type symbol.  */
      gfc_get_symbol (gfc_dt_upper_string (gensym->name), NULL, &sym);
      sym->name = gfc_get_string ("%s", gensym->name);
      head = gensym->generic;
      intr = gfc_get_interface ();
      intr->sym = sym;
      intr->where = gfc_current_locus;
      intr->sym->declared_at = gfc_current_locus;
      intr->next = head;
      gensym->generic = intr;
      gensym->attr.if_source = IFSRC_DECL;
    }

  /* The symbol may already have the derived attribute without the
     components.  The ways this can happen is via a function
     definition, an INTRINSIC statement or a subtype in another
     derived type that is a pointer.  The first part of the AND clause
     is true if the symbol is not the return value of a function.  */
  if (sym->attr.flavor != FL_DERIVED
      && !gfc_add_flavor (&sym->attr, FL_DERIVED, sym->name, NULL))
    return MATCH_ERROR;

  if (attr.access != ACCESS_UNKNOWN
      && !gfc_add_access (&sym->attr, attr.access, sym->name, NULL))
    return MATCH_ERROR;
  else if (sym->attr.access == ACCESS_UNKNOWN
	   && gensym->attr.access != ACCESS_UNKNOWN
	   && !gfc_add_access (&sym->attr, gensym->attr.access,
			       sym->name, NULL))
    return MATCH_ERROR;

  if (sym->attr.access != ACCESS_UNKNOWN
      && gensym->attr.access == ACCESS_UNKNOWN)
    gensym->attr.access = sym->attr.access;

  /* See if the derived type was labeled as bind(c).  */
  if (attr.is_bind_c != 0)
    sym->attr.is_bind_c = attr.is_bind_c;

  /* Construct the f2k_derived namespace if it is not yet there.  */
  if (!sym->f2k_derived)
    sym->f2k_derived = gfc_get_namespace (NULL, 0);

  if (parameterized_type)
    {
      /* Ignore error or mismatches by going to the end of the statement
	 in order to avoid the component declarations causing problems.  */
      m = gfc_match_formal_arglist (sym, 0, 0, true);
      if (m != MATCH_YES)
	gfc_error_recovery ();
      else
	sym->attr.pdt_template = 1;
      m = gfc_match_eos ();
      if (m != MATCH_YES)
	{
	  gfc_error_recovery ();
	  gfc_error_now ("Garbage after PARAMETERIZED TYPE declaration at %C");
	}
    }

  if (extended && !sym->components)
    {
      gfc_component *p;
      gfc_formal_arglist *f, *g, *h;

      /* Add the extended derived type as the first component.  */
      gfc_add_component (sym, parent, &p);
      extended->refs++;
      gfc_set_sym_referenced (extended);

      p->ts.type = BT_DERIVED;
      p->ts.u.derived = extended;
      p->initializer = gfc_default_initializer (&p->ts);

      /* Set extension level.  */
      if (extended->attr.extension == 255)
	{
	  /* Since the extension field is 8 bit wide, we can only have
	     up to 255 extension levels.  */
	  gfc_error ("Maximum extension level reached with type %qs at %L",
		     extended->name, &extended->declared_at);
	  return MATCH_ERROR;
	}
      sym->attr.extension = extended->attr.extension + 1;

      /* Provide the links between the extended type and its extension.  */
      if (!extended->f2k_derived)
	extended->f2k_derived = gfc_get_namespace (NULL, 0);

      /* Copy the extended type-param-name-list from the extended type,
	 append those of the extension and add the whole lot to the
	 extension.  */
      if (extended->attr.pdt_template)
	{
	  g = h = NULL;
	  sym->attr.pdt_template = 1;
	  for (f = extended->formal; f; f = f->next)
	    {
	      if (f == extended->formal)
		{
		  g = gfc_get_formal_arglist ();
		  h = g;
		}
	      else
		{
		  g->next = gfc_get_formal_arglist ();
		  g = g->next;
		}
	      g->sym = f->sym;
	    }
	  g->next = sym->formal;
	  sym->formal = h;
	}
    }

  if (!sym->hash_value)
    /* Set the hash for the compound name for this type.  */
    sym->hash_value = gfc_hash_value (sym);

  /* Take over the ABSTRACT attribute.  */
  sym->attr.abstract = attr.abstract;

  gfc_new_block = sym;

  return MATCH_YES;
}


/* Cray Pointees can be declared as:
      pointer (ipt, a (n,m,...,*))  */

match
gfc_mod_pointee_as (gfc_array_spec *as)
{
  as->cray_pointee = true; /* This will be useful to know later.  */
  if (as->type == AS_ASSUMED_SIZE)
    as->cp_was_assumed = true;
  else if (as->type == AS_ASSUMED_SHAPE)
    {
      gfc_error ("Cray Pointee at %C cannot be assumed shape array");
      return MATCH_ERROR;
    }
  return MATCH_YES;
}


/* Match the enum definition statement, here we are trying to match
   the first line of enum definition statement.
   Returns MATCH_YES if match is found.  */

match
gfc_match_enum (void)
{
  match m;

  m = gfc_match_eos ();
  if (m != MATCH_YES)
    return m;

  if (!gfc_notify_std (GFC_STD_F2003, "ENUM and ENUMERATOR at %C"))
    return MATCH_ERROR;

  return MATCH_YES;
}


/* Returns an initializer whose value is one higher than the value of the
   LAST_INITIALIZER argument.  If the argument is NULL, the
   initializers value will be set to zero.  The initializer's kind
   will be set to gfc_c_int_kind.

   If -fshort-enums is given, the appropriate kind will be selected
   later after all enumerators have been parsed.  A warning is issued
   here if an initializer exceeds gfc_c_int_kind.  */

static gfc_expr *
enum_initializer (gfc_expr *last_initializer, locus where)
{
  gfc_expr *result;
  result = gfc_get_constant_expr (BT_INTEGER, gfc_c_int_kind, &where);

  mpz_init (result->value.integer);

  if (last_initializer != NULL)
    {
      mpz_add_ui (result->value.integer, last_initializer->value.integer, 1);
      result->where = last_initializer->where;

      if (gfc_check_integer_range (result->value.integer,
	     gfc_c_int_kind) != ARITH_OK)
	{
	  gfc_error ("Enumerator exceeds the C integer type at %C");
	  return NULL;
	}
    }
  else
    {
      /* Control comes here, if it's the very first enumerator and no
	 initializer has been given.  It will be initialized to zero.  */
      mpz_set_si (result->value.integer, 0);
    }

  return result;
}


/* Match a variable name with an optional initializer.  When this
   subroutine is called, a variable is expected to be parsed next.
   Depending on what is happening at the moment, updates either the
   symbol table or the current interface.  */

static match
enumerator_decl (void)
{
  char name[GFC_MAX_SYMBOL_LEN + 1];
  gfc_expr *initializer;
  gfc_array_spec *as = NULL;
  gfc_symbol *sym;
  locus var_locus;
  match m;
  bool t;
  locus old_locus;

  initializer = NULL;
  old_locus = gfc_current_locus;

  /* When we get here, we've just matched a list of attributes and
     maybe a type and a double colon.  The next thing we expect to see
     is the name of the symbol.  */
  m = gfc_match_name (name);
  if (m != MATCH_YES)
    goto cleanup;

  var_locus = gfc_current_locus;

  /* OK, we've successfully matched the declaration.  Now put the
     symbol in the current namespace. If we fail to create the symbol,
     bail out.  */
  if (!build_sym (name, NULL, false, &as, &var_locus))
    {
      m = MATCH_ERROR;
      goto cleanup;
    }

  /* The double colon must be present in order to have initializers.
     Otherwise the statement is ambiguous with an assignment statement.  */
  if (colon_seen)
    {
      if (gfc_match_char ('=') == MATCH_YES)
	{
	  m = gfc_match_init_expr (&initializer);
	  if (m == MATCH_NO)
	    {
	      gfc_error ("Expected an initialization expression at %C");
	      m = MATCH_ERROR;
	    }

	  if (m != MATCH_YES)
	    goto cleanup;
	}
    }

  /* If we do not have an initializer, the initialization value of the
     previous enumerator (stored in last_initializer) is incremented
     by 1 and is used to initialize the current enumerator.  */
  if (initializer == NULL)
    initializer = enum_initializer (last_initializer, old_locus);

  if (initializer == NULL || initializer->ts.type != BT_INTEGER)
    {
      gfc_error ("ENUMERATOR %L not initialized with integer expression",
		 &var_locus);
      m = MATCH_ERROR;
      goto cleanup;
    }

  /* Store this current initializer, for the next enumerator variable
     to be parsed.  add_init_expr_to_sym() zeros initializer, so we
     use last_initializer below.  */
  last_initializer = initializer;
  t = add_init_expr_to_sym (name, &initializer, &var_locus);

  /* Maintain enumerator history.  */
  gfc_find_symbol (name, NULL, 0, &sym);
  create_enum_history (sym, last_initializer);

  return (t) ? MATCH_YES : MATCH_ERROR;

cleanup:
  /* Free stuff up and return.  */
  gfc_free_expr (initializer);

  return m;
}


/* Match the enumerator definition statement.  */

match
gfc_match_enumerator_def (void)
{
  match m;
  bool t;

  gfc_clear_ts (&current_ts);

  m = gfc_match (" enumerator");
  if (m != MATCH_YES)
    return m;

  m = gfc_match (" :: ");
  if (m == MATCH_ERROR)
    return m;

  colon_seen = (m == MATCH_YES);

  if (gfc_current_state () != COMP_ENUM)
    {
      gfc_error ("ENUM definition statement expected before %C");
      gfc_free_enum_history ();
      return MATCH_ERROR;
    }

  (&current_ts)->type = BT_INTEGER;
  (&current_ts)->kind = gfc_c_int_kind;

  gfc_clear_attr (&current_attr);
  t = gfc_add_flavor (&current_attr, FL_PARAMETER, NULL, NULL);
  if (!t)
    {
      m = MATCH_ERROR;
      goto cleanup;
    }

  for (;;)
    {
      m = enumerator_decl ();
      if (m == MATCH_ERROR)
	{
	  gfc_free_enum_history ();
	  goto cleanup;
	}
      if (m == MATCH_NO)
	break;

      if (gfc_match_eos () == MATCH_YES)
	goto cleanup;
      if (gfc_match_char (',') != MATCH_YES)
	break;
    }

  if (gfc_current_state () == COMP_ENUM)
    {
      gfc_free_enum_history ();
      gfc_error ("Syntax error in ENUMERATOR definition at %C");
      m = MATCH_ERROR;
    }

cleanup:
  gfc_free_array_spec (current_as);
  current_as = NULL;
  return m;

}


/* Match binding attributes.  */

static match
match_binding_attributes (gfc_typebound_proc* ba, bool generic, bool ppc)
{
  bool found_passing = false;
  bool seen_ptr = false;
  match m = MATCH_YES;

  /* Initialize to defaults.  Do so even before the MATCH_NO check so that in
     this case the defaults are in there.  */
  ba->access = ACCESS_UNKNOWN;
  ba->pass_arg = NULL;
  ba->pass_arg_num = 0;
  ba->nopass = 0;
  ba->non_overridable = 0;
  ba->deferred = 0;
  ba->ppc = ppc;

  /* If we find a comma, we believe there are binding attributes.  */
  m = gfc_match_char (',');
  if (m == MATCH_NO)
    goto done;

  do
    {
      /* Access specifier.  */

      m = gfc_match (" public");
      if (m == MATCH_ERROR)
	goto error;
      if (m == MATCH_YES)
	{
	  if (ba->access != ACCESS_UNKNOWN)
	    {
	      gfc_error ("Duplicate access-specifier at %C");
	      goto error;
	    }

	  ba->access = ACCESS_PUBLIC;
	  continue;
	}

      m = gfc_match (" private");
      if (m == MATCH_ERROR)
	goto error;
      if (m == MATCH_YES)
	{
	  if (ba->access != ACCESS_UNKNOWN)
	    {
	      gfc_error ("Duplicate access-specifier at %C");
	      goto error;
	    }

	  ba->access = ACCESS_PRIVATE;
	  continue;
	}

      /* If inside GENERIC, the following is not allowed.  */
      if (!generic)
	{

	  /* NOPASS flag.  */
	  m = gfc_match (" nopass");
	  if (m == MATCH_ERROR)
	    goto error;
	  if (m == MATCH_YES)
	    {
	      if (found_passing)
		{
		  gfc_error ("Binding attributes already specify passing,"
			     " illegal NOPASS at %C");
		  goto error;
		}

	      found_passing = true;
	      ba->nopass = 1;
	      continue;
	    }

	  /* PASS possibly including argument.  */
	  m = gfc_match (" pass");
	  if (m == MATCH_ERROR)
	    goto error;
	  if (m == MATCH_YES)
	    {
	      char arg[GFC_MAX_SYMBOL_LEN + 1];

	      if (found_passing)
		{
		  gfc_error ("Binding attributes already specify passing,"
			     " illegal PASS at %C");
		  goto error;
		}

	      m = gfc_match (" ( %n )", arg);
	      if (m == MATCH_ERROR)
		goto error;
	      if (m == MATCH_YES)
		ba->pass_arg = gfc_get_string ("%s", arg);
	      gcc_assert ((m == MATCH_YES) == (ba->pass_arg != NULL));

	      found_passing = true;
	      ba->nopass = 0;
	      continue;
	    }

	  if (ppc)
	    {
	      /* POINTER flag.  */
	      m = gfc_match (" pointer");
	      if (m == MATCH_ERROR)
		goto error;
	      if (m == MATCH_YES)
		{
		  if (seen_ptr)
		    {
		      gfc_error ("Duplicate POINTER attribute at %C");
		      goto error;
		    }

		  seen_ptr = true;
        	  continue;
		}
	    }
	  else
	    {
	      /* NON_OVERRIDABLE flag.  */
	      m = gfc_match (" non_overridable");
	      if (m == MATCH_ERROR)
		goto error;
	      if (m == MATCH_YES)
		{
		  if (ba->non_overridable)
		    {
		      gfc_error ("Duplicate NON_OVERRIDABLE at %C");
		      goto error;
		    }

		  ba->non_overridable = 1;
		  continue;
		}

	      /* DEFERRED flag.  */
	      m = gfc_match (" deferred");
	      if (m == MATCH_ERROR)
		goto error;
	      if (m == MATCH_YES)
		{
		  if (ba->deferred)
		    {
		      gfc_error ("Duplicate DEFERRED at %C");
		      goto error;
		    }

		  ba->deferred = 1;
		  continue;
		}
	    }

	}

      /* Nothing matching found.  */
      if (generic)
	gfc_error ("Expected access-specifier at %C");
      else
	gfc_error ("Expected binding attribute at %C");
      goto error;
    }
  while (gfc_match_char (',') == MATCH_YES);

  /* NON_OVERRIDABLE and DEFERRED exclude themselves.  */
  if (ba->non_overridable && ba->deferred)
    {
      gfc_error ("NON_OVERRIDABLE and DEFERRED cannot both appear at %C");
      goto error;
    }

  m = MATCH_YES;

done:
  if (ba->access == ACCESS_UNKNOWN)
    ba->access = ppc ? gfc_current_block()->component_access
                     : gfc_typebound_default_access;

  if (ppc && !seen_ptr)
    {
      gfc_error ("POINTER attribute is required for procedure pointer component"
                 " at %C");
      goto error;
    }

  return m;

error:
  return MATCH_ERROR;
}


/* Match a PROCEDURE specific binding inside a derived type.  */

static match
match_procedure_in_type (void)
{
  char name[GFC_MAX_SYMBOL_LEN + 1];
  char target_buf[GFC_MAX_SYMBOL_LEN + 1];
  char* target = NULL, *ifc = NULL;
  gfc_typebound_proc tb;
  bool seen_colons;
  bool seen_attrs;
  match m;
  gfc_symtree* stree;
  gfc_namespace* ns;
  gfc_symbol* block;
  int num;

  /* Check current state.  */
  gcc_assert (gfc_state_stack->state == COMP_DERIVED_CONTAINS);
  block = gfc_state_stack->previous->sym;
  gcc_assert (block);

  /* Try to match PROCEDURE(interface).  */
  if (gfc_match (" (") == MATCH_YES)
    {
      m = gfc_match_name (target_buf);
      if (m == MATCH_ERROR)
	return m;
      if (m != MATCH_YES)
	{
	  gfc_error ("Interface-name expected after %<(%> at %C");
	  return MATCH_ERROR;
	}

      if (gfc_match (" )") != MATCH_YES)
	{
	  gfc_error ("%<)%> expected at %C");
	  return MATCH_ERROR;
	}

      ifc = target_buf;
    }

  /* Construct the data structure.  */
  memset (&tb, 0, sizeof (tb));
  tb.where = gfc_current_locus;

  /* Match binding attributes.  */
  m = match_binding_attributes (&tb, false, false);
  if (m == MATCH_ERROR)
    return m;
  seen_attrs = (m == MATCH_YES);

  /* Check that attribute DEFERRED is given if an interface is specified.  */
  if (tb.deferred && !ifc)
    {
      gfc_error ("Interface must be specified for DEFERRED binding at %C");
      return MATCH_ERROR;
    }
  if (ifc && !tb.deferred)
    {
      gfc_error ("PROCEDURE(interface) at %C should be declared DEFERRED");
      return MATCH_ERROR;
    }

  /* Match the colons.  */
  m = gfc_match (" ::");
  if (m == MATCH_ERROR)
    return m;
  seen_colons = (m == MATCH_YES);
  if (seen_attrs && !seen_colons)
    {
      gfc_error ("Expected %<::%> after binding-attributes at %C");
      return MATCH_ERROR;
    }

  /* Match the binding names.  */
  for(num=1;;num++)
    {
      m = gfc_match_name (name);
      if (m == MATCH_ERROR)
	return m;
      if (m == MATCH_NO)
	{
	  gfc_error ("Expected binding name at %C");
	  return MATCH_ERROR;
	}

      if (num>1 && !gfc_notify_std (GFC_STD_F2008, "PROCEDURE list at %C"))
	return MATCH_ERROR;

      /* Try to match the '=> target', if it's there.  */
      target = ifc;
      m = gfc_match (" =>");
      if (m == MATCH_ERROR)
	return m;
      if (m == MATCH_YES)
	{
	  if (tb.deferred)
	    {
	      gfc_error ("%<=> target%> is invalid for DEFERRED binding at %C");
	      return MATCH_ERROR;
	    }

	  if (!seen_colons)
	    {
	      gfc_error ("%<::%> needed in PROCEDURE binding with explicit target"
			 " at %C");
	      return MATCH_ERROR;
	    }

	  m = gfc_match_name (target_buf);
	  if (m == MATCH_ERROR)
	    return m;
	  if (m == MATCH_NO)
	    {
	      gfc_error ("Expected binding target after %<=>%> at %C");
	      return MATCH_ERROR;
	    }
	  target = target_buf;
	}

      /* If no target was found, it has the same name as the binding.  */
      if (!target)
	target = name;

      /* Get the namespace to insert the symbols into.  */
      ns = block->f2k_derived;
      gcc_assert (ns);

      /* If the binding is DEFERRED, check that the containing type is ABSTRACT.  */
      if (tb.deferred && !block->attr.abstract)
	{
	  gfc_error ("Type %qs containing DEFERRED binding at %C "
		     "is not ABSTRACT", block->name);
	  return MATCH_ERROR;
	}

      /* See if we already have a binding with this name in the symtree which
	 would be an error.  If a GENERIC already targeted this binding, it may
	 be already there but then typebound is still NULL.  */
      stree = gfc_find_symtree (ns->tb_sym_root, name);
      if (stree && stree->n.tb)
	{
	  gfc_error ("There is already a procedure with binding name %qs for "
		     "the derived type %qs at %C", name, block->name);
	  return MATCH_ERROR;
	}

      /* Insert it and set attributes.  */

      if (!stree)
	{
	  stree = gfc_new_symtree (&ns->tb_sym_root, name);
	  gcc_assert (stree);
	}
      stree->n.tb = gfc_get_typebound_proc (&tb);

      if (gfc_get_sym_tree (target, gfc_current_ns, &stree->n.tb->u.specific,
			    false))
	return MATCH_ERROR;
      gfc_set_sym_referenced (stree->n.tb->u.specific->n.sym);
      gfc_add_flavor(&stree->n.tb->u.specific->n.sym->attr, FL_PROCEDURE,
		     target, &stree->n.tb->u.specific->n.sym->declared_at);

      if (gfc_match_eos () == MATCH_YES)
	return MATCH_YES;
      if (gfc_match_char (',') != MATCH_YES)
	goto syntax;
    }

syntax:
  gfc_error ("Syntax error in PROCEDURE statement at %C");
  return MATCH_ERROR;
}


/* Match a GENERIC procedure binding inside a derived type.  */

match
gfc_match_generic (void)
{
  char name[GFC_MAX_SYMBOL_LEN + 1];
  char bind_name[GFC_MAX_SYMBOL_LEN + 16]; /* Allow space for OPERATOR(...).  */
  gfc_symbol* block;
  gfc_typebound_proc tbattr; /* Used for match_binding_attributes.  */
  gfc_typebound_proc* tb;
  gfc_namespace* ns;
  interface_type op_type;
  gfc_intrinsic_op op;
  match m;

  /* Check current state.  */
  if (gfc_current_state () == COMP_DERIVED)
    {
      gfc_error ("GENERIC at %C must be inside a derived-type CONTAINS");
      return MATCH_ERROR;
    }
  if (gfc_current_state () != COMP_DERIVED_CONTAINS)
    return MATCH_NO;
  block = gfc_state_stack->previous->sym;
  ns = block->f2k_derived;
  gcc_assert (block && ns);

  memset (&tbattr, 0, sizeof (tbattr));
  tbattr.where = gfc_current_locus;

  /* See if we get an access-specifier.  */
  m = match_binding_attributes (&tbattr, true, false);
  if (m == MATCH_ERROR)
    goto error;

  /* Now the colons, those are required.  */
  if (gfc_match (" ::") != MATCH_YES)
    {
      gfc_error ("Expected %<::%> at %C");
      goto error;
    }

  /* Match the binding name; depending on type (operator / generic) format
     it for future error messages into bind_name.  */

  m = gfc_match_generic_spec (&op_type, name, &op);
  if (m == MATCH_ERROR)
    return MATCH_ERROR;
  if (m == MATCH_NO)
    {
      gfc_error ("Expected generic name or operator descriptor at %C");
      goto error;
    }

  switch (op_type)
    {
    case INTERFACE_GENERIC:
    case INTERFACE_DTIO:
      snprintf (bind_name, sizeof (bind_name), "%s", name);
      break;

    case INTERFACE_USER_OP:
      snprintf (bind_name, sizeof (bind_name), "OPERATOR(.%s.)", name);
      break;

    case INTERFACE_INTRINSIC_OP:
      snprintf (bind_name, sizeof (bind_name), "OPERATOR(%s)",
		gfc_op2string (op));
      break;

    case INTERFACE_NAMELESS:
      gfc_error ("Malformed GENERIC statement at %C");
      goto error;
      break;

    default:
      gcc_unreachable ();
    }

  /* Match the required =>.  */
  if (gfc_match (" =>") != MATCH_YES)
    {
      gfc_error ("Expected %<=>%> at %C");
      goto error;
    }

  /* Try to find existing GENERIC binding with this name / for this operator;
     if there is something, check that it is another GENERIC and then extend
     it rather than building a new node.  Otherwise, create it and put it
     at the right position.  */

  switch (op_type)
    {
    case INTERFACE_DTIO:
    case INTERFACE_USER_OP:
    case INTERFACE_GENERIC:
      {
	const bool is_op = (op_type == INTERFACE_USER_OP);
	gfc_symtree* st;

	st = gfc_find_symtree (is_op ? ns->tb_uop_root : ns->tb_sym_root, name);
	tb = st ? st->n.tb : NULL;
	break;
      }

    case INTERFACE_INTRINSIC_OP:
      tb = ns->tb_op[op];
      break;

    default:
      gcc_unreachable ();
    }

  if (tb)
    {
      if (!tb->is_generic)
	{
	  gcc_assert (op_type == INTERFACE_GENERIC);
	  gfc_error ("There's already a non-generic procedure with binding name"
		     " %qs for the derived type %qs at %C",
		     bind_name, block->name);
	  goto error;
	}

      if (tb->access != tbattr.access)
	{
	  gfc_error ("Binding at %C must have the same access as already"
		     " defined binding %qs", bind_name);
	  goto error;
	}
    }
  else
    {
      tb = gfc_get_typebound_proc (NULL);
      tb->where = gfc_current_locus;
      tb->access = tbattr.access;
      tb->is_generic = 1;
      tb->u.generic = NULL;

      switch (op_type)
	{
	case INTERFACE_DTIO:
	case INTERFACE_GENERIC:
	case INTERFACE_USER_OP:
	  {
	    const bool is_op = (op_type == INTERFACE_USER_OP);
	    gfc_symtree* st = gfc_get_tbp_symtree (is_op ? &ns->tb_uop_root :
						   &ns->tb_sym_root, name);
	    gcc_assert (st);
	    st->n.tb = tb;

	    break;
	  }

	case INTERFACE_INTRINSIC_OP:
	  ns->tb_op[op] = tb;
	  break;

	default:
	  gcc_unreachable ();
	}
    }

  /* Now, match all following names as specific targets.  */
  do
    {
      gfc_symtree* target_st;
      gfc_tbp_generic* target;

      m = gfc_match_name (name);
      if (m == MATCH_ERROR)
	goto error;
      if (m == MATCH_NO)
	{
	  gfc_error ("Expected specific binding name at %C");
	  goto error;
	}

      target_st = gfc_get_tbp_symtree (&ns->tb_sym_root, name);

      /* See if this is a duplicate specification.  */
      for (target = tb->u.generic; target; target = target->next)
	if (target_st == target->specific_st)
	  {
	    gfc_error ("%qs already defined as specific binding for the"
		       " generic %qs at %C", name, bind_name);
	    goto error;
	  }

      target = gfc_get_tbp_generic ();
      target->specific_st = target_st;
      target->specific = NULL;
      target->next = tb->u.generic;
      target->is_operator = ((op_type == INTERFACE_USER_OP)
			     || (op_type == INTERFACE_INTRINSIC_OP));
      tb->u.generic = target;
    }
  while (gfc_match (" ,") == MATCH_YES);

  /* Here should be the end.  */
  if (gfc_match_eos () != MATCH_YES)
    {
      gfc_error ("Junk after GENERIC binding at %C");
      goto error;
    }

  return MATCH_YES;

error:
  return MATCH_ERROR;
}


/* Match a FINAL declaration inside a derived type.  */

match
gfc_match_final_decl (void)
{
  char name[GFC_MAX_SYMBOL_LEN + 1];
  gfc_symbol* sym;
  match m;
  gfc_namespace* module_ns;
  bool first, last;
  gfc_symbol* block;

  if (gfc_current_form == FORM_FREE)
    {
      char c = gfc_peek_ascii_char ();
      if (!gfc_is_whitespace (c) && c != ':')
	return MATCH_NO;
    }

  if (gfc_state_stack->state != COMP_DERIVED_CONTAINS)
    {
      if (gfc_current_form == FORM_FIXED)
	return MATCH_NO;

      gfc_error ("FINAL declaration at %C must be inside a derived type "
		 "CONTAINS section");
      return MATCH_ERROR;
    }

  block = gfc_state_stack->previous->sym;
  gcc_assert (block);

  if (!gfc_state_stack->previous || !gfc_state_stack->previous->previous
      || gfc_state_stack->previous->previous->state != COMP_MODULE)
    {
      gfc_error ("Derived type declaration with FINAL at %C must be in the"
		 " specification part of a MODULE");
      return MATCH_ERROR;
    }

  module_ns = gfc_current_ns;
  gcc_assert (module_ns);
  gcc_assert (module_ns->proc_name->attr.flavor == FL_MODULE);

  /* Match optional ::, don't care about MATCH_YES or MATCH_NO.  */
  if (gfc_match (" ::") == MATCH_ERROR)
    return MATCH_ERROR;

  /* Match the sequence of procedure names.  */
  first = true;
  last = false;
  do
    {
      gfc_finalizer* f;

      if (first && gfc_match_eos () == MATCH_YES)
	{
	  gfc_error ("Empty FINAL at %C");
	  return MATCH_ERROR;
	}

      m = gfc_match_name (name);
      if (m == MATCH_NO)
	{
	  gfc_error ("Expected module procedure name at %C");
	  return MATCH_ERROR;
	}
      else if (m != MATCH_YES)
	return MATCH_ERROR;

      if (gfc_match_eos () == MATCH_YES)
	last = true;
      if (!last && gfc_match_char (',') != MATCH_YES)
	{
	  gfc_error ("Expected %<,%> at %C");
	  return MATCH_ERROR;
	}

      if (gfc_get_symbol (name, module_ns, &sym))
	{
	  gfc_error ("Unknown procedure name %qs at %C", name);
	  return MATCH_ERROR;
	}

      /* Mark the symbol as module procedure.  */
      if (sym->attr.proc != PROC_MODULE
	  && !gfc_add_procedure (&sym->attr, PROC_MODULE, sym->name, NULL))
	return MATCH_ERROR;

      /* Check if we already have this symbol in the list, this is an error.  */
      for (f = block->f2k_derived->finalizers; f; f = f->next)
	if (f->proc_sym == sym)
	  {
	    gfc_error ("%qs at %C is already defined as FINAL procedure",
		       name);
	    return MATCH_ERROR;
	  }

      /* Add this symbol to the list of finalizers.  */
      gcc_assert (block->f2k_derived);
      sym->refs++;
      f = XCNEW (gfc_finalizer);
      f->proc_sym = sym;
      f->proc_tree = NULL;
      f->where = gfc_current_locus;
      f->next = block->f2k_derived->finalizers;
      block->f2k_derived->finalizers = f;

      first = false;
    }
  while (!last);

  return MATCH_YES;
}


const ext_attr_t ext_attr_list[] = {
  { "dllimport",    EXT_ATTR_DLLIMPORT,    "dllimport" },
  { "dllexport",    EXT_ATTR_DLLEXPORT,    "dllexport" },
  { "cdecl",        EXT_ATTR_CDECL,        "cdecl"     },
  { "stdcall",      EXT_ATTR_STDCALL,      "stdcall"   },
  { "fastcall",     EXT_ATTR_FASTCALL,     "fastcall"  },
  { "no_arg_check", EXT_ATTR_NO_ARG_CHECK, NULL        },
  { "deprecated",   EXT_ATTR_DEPRECATED,   NULL	       },
  { NULL,           EXT_ATTR_LAST,         NULL        }
};

/* Match a !GCC$ ATTRIBUTES statement of the form:
      !GCC$ ATTRIBUTES attribute-list :: var-name [, var-name] ...
   When we come here, we have already matched the !GCC$ ATTRIBUTES string.

   TODO: We should support all GCC attributes using the same syntax for
   the attribute list, i.e. the list in C
      __attributes(( attribute-list ))
   matches then
      !GCC$ ATTRIBUTES attribute-list ::
   Cf. c-parser.cc's c_parser_attributes; the data can then directly be
   saved into a TREE.

   As there is absolutely no risk of confusion, we should never return
   MATCH_NO.  */
match
gfc_match_gcc_attributes (void)
{
  symbol_attribute attr;
  char name[GFC_MAX_SYMBOL_LEN + 1];
  unsigned id;
  gfc_symbol *sym;
  match m;

  gfc_clear_attr (&attr);
  for(;;)
    {
      char ch;

      if (gfc_match_name (name) != MATCH_YES)
	return MATCH_ERROR;

      for (id = 0; id < EXT_ATTR_LAST; id++)
	if (strcmp (name, ext_attr_list[id].name) == 0)
	  break;

      if (id == EXT_ATTR_LAST)
	{
	  gfc_error ("Unknown attribute in !GCC$ ATTRIBUTES statement at %C");
	  return MATCH_ERROR;
	}

      if (!gfc_add_ext_attribute (&attr, (ext_attr_id_t)id, &gfc_current_locus))
	return MATCH_ERROR;

      gfc_gobble_whitespace ();
      ch = gfc_next_ascii_char ();
      if (ch == ':')
        {
          /* This is the successful exit condition for the loop.  */
          if (gfc_next_ascii_char () == ':')
            break;
        }

      if (ch == ',')
	continue;

      goto syntax;
    }

  if (gfc_match_eos () == MATCH_YES)
    goto syntax;

  for(;;)
    {
      m = gfc_match_name (name);
      if (m != MATCH_YES)
	return m;

      if (find_special (name, &sym, true))
	return MATCH_ERROR;

      sym->attr.ext_attr |= attr.ext_attr;

      if (gfc_match_eos () == MATCH_YES)
	break;

      if (gfc_match_char (',') != MATCH_YES)
	goto syntax;
    }

  return MATCH_YES;

syntax:
  gfc_error ("Syntax error in !GCC$ ATTRIBUTES statement at %C");
  return MATCH_ERROR;
}


/* Match a !GCC$ UNROLL statement of the form:
      !GCC$ UNROLL n

   The parameter n is the number of times we are supposed to unroll.

   When we come here, we have already matched the !GCC$ UNROLL string.  */
match
gfc_match_gcc_unroll (void)
{
  int value;

  /* FIXME: use gfc_match_small_literal_int instead, delete small_int  */
  if (gfc_match_small_int (&value) == MATCH_YES)
    {
      if (value < 0 || value > USHRT_MAX)
	{
	  gfc_error ("%<GCC unroll%> directive requires a"
	      " non-negative integral constant"
	      " less than or equal to %u at %C",
	      USHRT_MAX
	  );
	  return MATCH_ERROR;
	}
      if (gfc_match_eos () == MATCH_YES)
	{
	  directive_unroll = value == 0 ? 1 : value;
	  return MATCH_YES;
	}
    }

  gfc_error ("Syntax error in !GCC$ UNROLL directive at %C");
  return MATCH_ERROR;
}

/* Match a !GCC$ builtin (b) attributes simd flags if('target') form:

   The parameter b is name of a middle-end built-in.
   FLAGS is optional and must be one of:
     - (inbranch)
     - (notinbranch)

   IF('target') is optional and TARGET is a name of a multilib ABI.

   When we come here, we have already matched the !GCC$ builtin string.  */

match
gfc_match_gcc_builtin (void)
{
  char builtin[GFC_MAX_SYMBOL_LEN + 1];
  char target[GFC_MAX_SYMBOL_LEN + 1];

  if (gfc_match (" ( %n ) attributes simd", builtin) != MATCH_YES)
    return MATCH_ERROR;

  gfc_simd_clause clause = SIMD_NONE;
  if (gfc_match (" ( notinbranch ) ") == MATCH_YES)
    clause = SIMD_NOTINBRANCH;
  else if (gfc_match (" ( inbranch ) ") == MATCH_YES)
    clause = SIMD_INBRANCH;

  if (gfc_match (" if ( '%n' ) ", target) == MATCH_YES)
    {
      const char *abi = targetm.get_multilib_abi_name ();
      if (abi == NULL || strcmp (abi, target) != 0)
	return MATCH_YES;
    }

  if (gfc_vectorized_builtins == NULL)
    gfc_vectorized_builtins = new hash_map<nofree_string_hash, int> ();

  char *r = XNEWVEC (char, strlen (builtin) + 32);
  sprintf (r, "__builtin_%s", builtin);

  bool existed;
  int &value = gfc_vectorized_builtins->get_or_insert (r, &existed);
  value |= clause;
  if (existed)
    free (r);

  return MATCH_YES;
}

/* Match an !GCC$ IVDEP statement.
   When we come here, we have already matched the !GCC$ IVDEP string.  */

match
gfc_match_gcc_ivdep (void)
{
  if (gfc_match_eos () == MATCH_YES)
    {
      directive_ivdep = true;
      return MATCH_YES;
    }

  gfc_error ("Syntax error in !GCC$ IVDEP directive at %C");
  return MATCH_ERROR;
}

/* Match an !GCC$ VECTOR statement.
   When we come here, we have already matched the !GCC$ VECTOR string.  */

match
gfc_match_gcc_vector (void)
{
  if (gfc_match_eos () == MATCH_YES)
    {
      directive_vector = true;
      directive_novector = false;
      return MATCH_YES;
    }

  gfc_error ("Syntax error in !GCC$ VECTOR directive at %C");
  return MATCH_ERROR;
}

/* Match an !GCC$ NOVECTOR statement.
   When we come here, we have already matched the !GCC$ NOVECTOR string.  */

match
gfc_match_gcc_novector (void)
{
  if (gfc_match_eos () == MATCH_YES)
    {
      directive_novector = true;
      directive_vector = false;
      return MATCH_YES;
    }

  gfc_error ("Syntax error in !GCC$ NOVECTOR directive at %C");
  return MATCH_ERROR;
}
