/* Declaration statement matcher
   Copyright (C) 2002-2021 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->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.c, 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.c(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.c: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 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)
	    {
	      gcc_assert (init->expr_type == EXPR_ARRAY);
	      init->shape = gfc_get_shape (1);
	      if (!gfc_array_size (init, &init->shape[0]))
		  gfc_internal_error ("gfc_array_size failed");
	    }

	  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);
		}
	    }
	}
    }

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

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_reduce_init_expr (e);
	  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;
}


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;
  return gfc_traverse_expr (e, NULL, &insert_parameter_exprs, 1);
  type_param_spec_list = NULL;
  type_param_spec_list = old_param_spec_list;
}

/* 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.c
	 (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.c, 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, "IMPORT 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.  */

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

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

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

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;
    }

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

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

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.c.  */
    }
  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.c'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;

  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;
}
