/* equiv.c -- Implementation File (module.c template V1.0)
   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
   Contributed by James Craig Burley.

This file is part of GNU Fortran.

GNU Fortran 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 2, or (at your option)
any later version.

GNU Fortran 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 GNU Fortran; see the file COPYING.  If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.

   Related Modules:
      None

   Description:
      Handles the EQUIVALENCE relationships in a program unit.

   Modifications:
*/

#define FFEEQUIV_DEBUG 0

/* Include files. */

#include "proj.h"
#include "equiv.h"
#include "bad.h"
#include "bld.h"
#include "com.h"
#include "data.h"
#include "global.h"
#include "lex.h"
#include "malloc.h"
#include "symbol.h"

/* Externals defined here. */


/* Simple definitions and enumerations. */


/* Internal typedefs. */


/* Private include files. */


/* Internal structure definitions. */

struct _ffeequiv_list_
  {
    ffeequiv first;
    ffeequiv last;
  };

/* Static objects accessed by functions in this module. */

static struct _ffeequiv_list_ ffeequiv_list_;

/* Static functions (internal). */

static void ffeequiv_destroy_ (ffeequiv eq);
static void ffeequiv_layout_local_ (ffeequiv eq);
static bool ffeequiv_offset_ (ffetargetOffset *offset, ffesymbol s,
			      ffebld expr, bool subtract,
			      ffetargetOffset adjust, bool no_precede);

/* Internal macros. */


static void
ffeequiv_destroy_ (ffeequiv victim)
{
  ffebld list;
  ffebld item;
  ffebld expr;

  for (list = victim->list; list != NULL; list = ffebld_trail (list))
    {
      for (item = ffebld_head (list); item != NULL; item = ffebld_trail (item))
	{
	  ffesymbol sym;

	  expr = ffebld_head (item);
	  sym = ffeequiv_symbol (expr);
	  if (sym == NULL)
	    continue;
	  if (ffesymbol_equiv (sym) != NULL)
	    ffesymbol_set_equiv (sym, NULL);
	}
    }
  ffeequiv_kill (victim);
}

/* ffeequiv_layout_local_ -- Lay out storage for local equivalenced vars

   ffeequiv eq;
   ffeequiv_layout_local_(eq);

   Makes a single master ffestorag object that contains all the vars
   in the equivalence, and makes subordinate ffestorag objects for the
   vars with the correct offsets.

   The resulting var offsets are relative not necessarily to 0 -- the
   are relative to the offset of the master area, which might be 0 or
   negative, but should never be positive.  */

static void
ffeequiv_layout_local_ (ffeequiv eq)
{
  ffestorag st;			/* Equivalence storage area. */
  ffebld list;			/* List of list of equivalences. */
  ffebld item;			/* List of equivalences. */
  ffebld root_exp;		/* Expression for root sym. */
  ffestorag root_st;		/* Storage for root. */
  ffesymbol root_sym;		/* Root itself. */
  ffebld rooted_exp;		/* Expression for rooted sym in an eqlist. */
  ffestorag rooted_st;		/* Storage for rooted. */
  ffesymbol rooted_sym;		/* Rooted symbol itself. */
  ffetargetOffset eqlist_offset;/* Offset for eqlist from rooted sym. */
  ffetargetAlign alignment;
  ffetargetAlign modulo;
  ffetargetAlign pad;
  ffetargetOffset size;
  ffetargetOffset num_elements;
  bool new_storage;		/* Established new storage info. */
  bool need_storage;		/* Have need for more storage info. */
  bool init;

  assert (eq != NULL);

  if (ffeequiv_common (eq) != NULL)
    {				/* Put in common due to programmer error. */
      ffeequiv_destroy_ (eq);
      return;
    }

  /* Find the symbol for the first valid item in the list of lists, use that
     as the root symbol.  Doesn't matter if it won't end up at the beginning
     of the list, though.  */

#if FFEEQUIV_DEBUG
  fprintf (stderr, "Equiv1:\n");
#endif

  root_sym = NULL;
  root_exp = NULL;

  for (list = ffeequiv_list (eq);
       list != NULL;
       list = ffebld_trail (list))
    {				/* For every equivalence list in the list of
				   equivs */
      for (item = ffebld_head (list);
	   item != NULL;
	   item = ffebld_trail (item))
	{			/* For every equivalence item in the list */
	  ffetargetOffset ign;	/* Ignored. */

	  root_exp = ffebld_head (item);
	  root_sym = ffeequiv_symbol (root_exp);
	  if (root_sym == NULL)
	    continue;		/* Ignore me. */

	  assert (ffesymbol_storage (root_sym) == NULL);	/* No storage yet. */

	  if (!ffeequiv_offset_ (&ign, root_sym, root_exp, FALSE, 0, FALSE))
	    {
	      /* We can't just eliminate this one symbol from the list
		 of candidates, because it might be the only one that
		 ties all these equivs together.  So just destroy the
		 whole list.  */

	      ffeequiv_destroy_ (eq);
	      return;
	    }

	  break;	/* Use first valid eqv expr for root exp/sym. */
	}
      if (root_sym != NULL)
	break;
    }

  if (root_sym == NULL)
    {
      ffeequiv_destroy_ (eq);
      return;
    }


#if FFEEQUIV_DEBUG
  fprintf (stderr, "  Root: `%s'\n", ffesymbol_text (root_sym));
#endif

  /* We've got work to do, so make the LOCAL storage object that'll hold all
     the equivalenced vars inside it. */

  st = ffestorag_new (ffestorag_list_master ());
  ffestorag_set_parent (st, NULL);	/* Initializations happen here. */
  ffestorag_set_init (st, NULL);
  ffestorag_set_accretion (st, NULL);
  ffestorag_set_offset (st, 0);		/* Assume equiv will be at root offset 0 for now. */
  ffestorag_set_alignment (st, 1);
  ffestorag_set_modulo (st, 0);
  ffestorag_set_type (st, FFESTORAG_typeLOCAL);
  ffestorag_set_basictype (st, ffesymbol_basictype (root_sym));
  ffestorag_set_kindtype (st, ffesymbol_kindtype (root_sym));
  ffestorag_set_typesymbol (st, root_sym);
  ffestorag_set_is_save (st, ffeequiv_is_save (eq));
  if (ffesymbol_is_save (root_sym))
    ffestorag_update_save (st);
  ffestorag_set_is_init (st, ffeequiv_is_init (eq));
  if (ffesymbol_is_init (root_sym))
    ffestorag_update_init (st);
  ffestorag_set_symbol (st, root_sym);	/* Assume this will be the root until
					   we know better (used only to generate
					   the internal name for the aggregate area,
					   e.g. for debugging). */

  /* Make the EQUIV storage object for the root symbol. */

  if (ffesymbol_rank (root_sym) == 0)
    num_elements = 1;
  else
    num_elements = ffebld_constant_integerdefault (ffebld_conter
						(ffesymbol_arraysize (root_sym)));
  ffetarget_layout (ffesymbol_text (root_sym), &alignment, &modulo, &size,
		    ffesymbol_basictype (root_sym), ffesymbol_kindtype (root_sym),
		    ffesymbol_size (root_sym), num_elements);
  ffestorag_set_size (st, size);	/* Set initial size of aggregate area. */

  pad = ffetarget_align (ffestorag_ptr_to_alignment (st),
			 ffestorag_ptr_to_modulo (st), 0, alignment,
			 modulo);
  assert (pad == 0);

  root_st = ffestorag_new (ffestorag_list_equivs (st));
  ffestorag_set_parent (root_st, st);	/* Initializations happen there. */
  ffestorag_set_init (root_st, NULL);
  ffestorag_set_accretion (root_st, NULL);
  ffestorag_set_symbol (root_st, root_sym);
  ffestorag_set_size (root_st, size);
  ffestorag_set_offset (root_st, 0);	/* Will not change; always 0 relative to itself! */
  ffestorag_set_alignment (root_st, alignment);
  ffestorag_set_modulo (root_st, modulo);
  ffestorag_set_type (root_st, FFESTORAG_typeEQUIV);
  ffestorag_set_basictype (root_st, ffesymbol_basictype (root_sym));
  ffestorag_set_kindtype (root_st, ffesymbol_kindtype (root_sym));
  ffestorag_set_typesymbol (root_st, root_sym);
  ffestorag_set_is_save (root_st, FALSE);	/* Assume FALSE, then... */
  if (ffestorag_is_save (st))	/* ...update to TRUE if needed. */
    ffestorag_update_save (root_st);
  ffestorag_set_is_init (root_st, FALSE);	/* Assume FALSE, then... */
  if (ffestorag_is_init (st))	/* ...update to TRUE if needed. */
    ffestorag_update_init (root_st);
  ffesymbol_set_storage (root_sym, root_st);
  ffesymbol_signal_unreported (root_sym);
  init = ffesymbol_is_init (root_sym);

  /* Now that we know the root (offset=0) symbol, revisit all the lists and
     do the actual storage allocation.	Keep doing this until we've gone
     through them all without making any new storage objects. */

  do
    {
      new_storage = FALSE;
      need_storage = FALSE;
      for (list = ffeequiv_list (eq);
	   list != NULL;
	   list = ffebld_trail (list))
	{			/* For every equivalence list in the list of
				   equivs */
	  /* Now find a "rooted" symbol in this list.  That is, find the
	     first item we can that is valid and whose symbol already
	     has a storage area, because that means we know where it
	     belongs in the equivalence area and can then allocate the
	     rest of the items in the list accordingly.  */

	  rooted_sym = NULL;
	  rooted_exp = NULL;
	  eqlist_offset = 0;

	  for (item = ffebld_head (list);
	       item != NULL;
	       item = ffebld_trail (item))
	    {			/* For every equivalence item in the list */
	      rooted_exp = ffebld_head (item);
	      rooted_sym = ffeequiv_symbol (rooted_exp);
	      if ((rooted_sym == NULL)
		  || ((rooted_st = ffesymbol_storage (rooted_sym)) == NULL))
		{
		  rooted_sym = NULL;
		  continue;	/* Ignore me. */
		}

	      need_storage = TRUE;	/* Somebody is likely to need
					   storage. */

#if FFEEQUIV_DEBUG
	      fprintf (stderr, "  Rooted: `%s' at %" ffetargetOffset_f "d\n",
		       ffesymbol_text (rooted_sym),
		       ffestorag_offset (rooted_st));
#endif

	      /* The offset of this symbol from the equiv's root symbol
		 is already known, and the size of this symbol is already
		 incorporated in the size of the equiv's aggregate area.
		 What we now determine is the offset of this equivalence
		 _list_ from the equiv's root symbol.

		 For example, if we know that A is at offset 16 from the
		 root symbol, given EQUIVALENCE (B(24),A(2)), we're looking
		 at A(2), meaning that the offset for this equivalence list
		 is 20 (4 bytes beyond the beginning of A, assuming typical
		 array types, dimensions, and type info).  */

	      if (!ffeequiv_offset_ (&eqlist_offset, rooted_sym, rooted_exp, FALSE,
				     ffestorag_offset (rooted_st), FALSE))

		{	/* Can't use this one. */
		  ffesymbol_set_equiv (rooted_sym, NULL);/* Equiv area slated for
							    death. */
		  rooted_sym = NULL;
		  continue;		/* Something's wrong with eqv expr, try another. */
		}

#if FFEEQUIV_DEBUG
	      fprintf (stderr, "  Eqlist offset: %" ffetargetOffset_f "d\n",
		       eqlist_offset);
#endif

	      break;
	    }

	  /* If no rooted symbol, it means this list has no roots -- yet.
	     So, forget this list this time around, but we'll get back
	     to it after the outer loop iterates at least one more time,
	     and, ultimately, it will have a root.  */

	  if (rooted_sym == NULL)
	    {
#if FFEEQUIV_DEBUG
	      fprintf (stderr, "No roots.\n");
#endif
	      continue;
	    }

	  /* We now have a rooted symbol/expr and the offset of this equivalence
	     list from the root symbol.  The other expressions in this
	     list all identify an initial storage unit that must have the
	     same offset. */

	  for (item = ffebld_head (list);
	       item != NULL;
	       item = ffebld_trail (item))
	    {			/* For every equivalence item in the list */
	      ffebld item_exp;			/* Expression for equivalence. */
	      ffestorag item_st;		/* Storage for var. */
	      ffesymbol item_sym;		/* Var itself. */
	      ffetargetOffset item_offset;	/* Offset for var from root. */
	      ffetargetOffset new_size;

	      item_exp = ffebld_head (item);
	      item_sym = ffeequiv_symbol (item_exp);
	      if ((item_sym == NULL)
		  || (ffesymbol_equiv (item_sym) == NULL))
		continue;	/* Ignore me. */

	      if (item_sym == rooted_sym)
		continue;	/* Rooted sym already set up. */

	      if (!ffeequiv_offset_ (&item_offset, item_sym, item_exp, TRUE,
				     eqlist_offset, FALSE))
		{
		  ffesymbol_set_equiv (item_sym, NULL);	/* Don't bother with me anymore. */
		  continue;
		}

#if FFEEQUIV_DEBUG
	      fprintf (stderr, "  Item `%s' at %" ffetargetOffset_f "d",
		       ffesymbol_text (item_sym), item_offset);
#endif

	      if (ffesymbol_rank (item_sym) == 0)
		num_elements = 1;
	      else
		num_elements = ffebld_constant_integerdefault (ffebld_conter
						(ffesymbol_arraysize (item_sym)));
	      ffetarget_layout (ffesymbol_text (item_sym), &alignment, &modulo,
				&size, ffesymbol_basictype (item_sym),
				ffesymbol_kindtype (item_sym), ffesymbol_size (item_sym),
				num_elements);
	      pad = ffetarget_align (ffestorag_ptr_to_alignment (st),
				     ffestorag_ptr_to_modulo (st),
				     item_offset, alignment, modulo);
	      if (pad != 0)
		{
		  ffebad_start (FFEBAD_EQUIV_ALIGN);
		  ffebad_string (ffesymbol_text (item_sym));
		  ffebad_finish ();
		  ffesymbol_set_equiv (item_sym, NULL);	/* Don't bother with me anymore. */
		  continue;
		}

	      /* If the variable's offset is less than the offset for the
		 aggregate storage area, it means it has to expand backwards
		 -- i.e. the new known starting point of the area precedes the
		 old one.  This can't happen with COMMON areas (the standard,
		 and common sense, disallow it), but it is normal for local
		 EQUIVALENCE areas.

		 Also handle choosing the "documented" rooted symbol for this
		 area here.  It's the symbol at the bottom (lowest offset)
		 of the aggregate area, with ties going to the name that would
		 sort to the top of the list of ties.  */

	      if (item_offset == ffestorag_offset (st))
		{
		  if ((item_sym != ffestorag_symbol (st))
		      && (strcmp (ffesymbol_text (item_sym),
				  ffesymbol_text (ffestorag_symbol (st)))
			  < 0))
		    ffestorag_set_symbol (st, item_sym);
		}
	      else if (item_offset < ffestorag_offset (st))
		{
		  /* Increase size of equiv area to start for lower offset
		     relative to root symbol.  */
		  if (! ffetarget_offset_add (&new_size,
					      ffestorag_offset (st)
					      - item_offset,
					      ffestorag_size (st)))
		    ffetarget_offset_overflow (ffesymbol_text (s));
		  else
		    ffestorag_set_size (st, new_size);

		  ffestorag_set_symbol (st, item_sym);
		  ffestorag_set_offset (st, item_offset);

#if FFEEQUIV_DEBUG
		  fprintf (stderr, " [eq offset=%" ffetargetOffset_f
			   "d, size=%" ffetargetOffset_f "d]",
			   item_offset, new_size);
#endif
		}

	      if ((item_st = ffesymbol_storage (item_sym)) == NULL)
		{		/* Create new ffestorag object, extend equiv
				   area. */
#if FFEEQUIV_DEBUG
		  fprintf (stderr, ".\n");
#endif
		  new_storage = TRUE;
		  item_st = ffestorag_new (ffestorag_list_equivs (st));
		  ffestorag_set_parent (item_st, st);	/* Initializations
							   happen there. */
		  ffestorag_set_init (item_st, NULL);
		  ffestorag_set_accretion (item_st, NULL);
		  ffestorag_set_symbol (item_st, item_sym);
		  ffestorag_set_size (item_st, size);
		  ffestorag_set_offset (item_st, item_offset);
		  ffestorag_set_alignment (item_st, alignment);
		  ffestorag_set_modulo (item_st, modulo);
		  ffestorag_set_type (item_st, FFESTORAG_typeEQUIV);
		  ffestorag_set_basictype (item_st, ffesymbol_basictype (item_sym));
		  ffestorag_set_kindtype (item_st, ffesymbol_kindtype (item_sym));
		  ffestorag_set_typesymbol (item_st, item_sym);
		  ffestorag_set_is_save (item_st, FALSE);	/* Assume FALSE... */
		  if (ffestorag_is_save (st))	/* ...update TRUE */
		    ffestorag_update_save (item_st);	/* if needed. */
		  ffestorag_set_is_init (item_st, FALSE);	/* Assume FALSE... */
		  if (ffestorag_is_init (st))	/* ...update TRUE */
		    ffestorag_update_init (item_st);	/* if needed. */
		  ffesymbol_set_storage (item_sym, item_st);
		  ffesymbol_signal_unreported (item_sym);
		  if (ffesymbol_is_init (item_sym))
		    init = TRUE;

		  /* Determine new size of equiv area, complain if overflow.  */

		  if (!ffetarget_offset_add (&size, item_offset, size)
		      || !ffetarget_offset_add (&size, -ffestorag_offset (st), size))
		    ffetarget_offset_overflow (ffesymbol_text (s));
		  else if (size > ffestorag_size (st))
		    ffestorag_set_size (st, size);
		  ffestorag_update (st, item_sym, ffesymbol_basictype (item_sym),
				    ffesymbol_kindtype (item_sym));
		}
	      else
		{
#if FFEEQUIV_DEBUG
		  fprintf (stderr, " (was %" ffetargetOffset_f "d).\n",
			   ffestorag_offset (item_st));
#endif
		  /* Make sure offset agrees with known offset. */
		  if (item_offset != ffestorag_offset (item_st))
		    {
		      char io1[40];
		      char io2[40];

		      sprintf (&io1[0], "%" ffetargetOffset_f "d", item_offset);
		      sprintf (&io2[0], "%" ffetargetOffset_f "d", ffestorag_offset (item_st));
		      ffebad_start (FFEBAD_EQUIV_MISMATCH);
		      ffebad_string (ffesymbol_text (item_sym));
		      ffebad_string (ffesymbol_text (root_sym));
		      ffebad_string (io1);
		      ffebad_string (io2);
		      ffebad_finish ();
		    }
		}
	      ffesymbol_set_equiv (item_sym, NULL);	/* Don't bother with me anymore. */
	    }			/* (For every equivalence item in the list) */
	  ffebld_set_head (list, NULL);	/* Don't do this list again. */
	}			/* (For every equivalence list in the list of
				   equivs) */
    } while (new_storage && need_storage);

  ffesymbol_set_equiv (root_sym, NULL);	/* This one has storage now. */

  ffeequiv_kill (eq);		/* Fully processed, no longer needed. */

  /* If the offset for this storage area is zero (it cannot be positive),
     that means the alignment/modulo info is already correct.  Otherwise,
     the alignment info is correct, but the modulo info reflects a
     zero offset, so fix it.  */

  if (ffestorag_offset (st) < 0)
    {
      /* Calculate the initial padding necessary to preserve
	 the alignment/modulo requirements for the storage area.
	 These requirements are themselves kept track of in the
	 record for the storage area as a whole, but really pertain
	 to offset 0 of that area, which is where the root symbol
	 was originally placed.

	 The goal here is to have the offset and size for the area
	 faithfully reflect the area itself, not extra requirements
	 like alignment.  So to meet the alignment requirements,
	 the modulo for the area should be set as if the area had an
	 alignment requirement of alignment/0 and was aligned/padded
	 downward to meet the alignment requirements of the area at
	 offset zero, the amount of padding needed being the desired
	 value for the modulo of the area.  */

      alignment = ffestorag_alignment (st);
      modulo = ffestorag_modulo (st);

      /* Since we want to move the whole area *down* (lower memory
	 addresses) as required by the alignment/modulo paid, negate
	 the offset to ffetarget_align, which assumes aligning *up*
	 is desired.  */
      pad = ffetarget_align (&alignment, &modulo,
			     - ffestorag_offset (st),
			     alignment, 0);
      ffestorag_set_modulo (st, pad);
    }

  if (init)
    ffedata_gather (st);	/* Gather subordinate inits into one init. */
}

/* ffeequiv_offset_ -- Determine offset from start of symbol

   ffetargetOffset offset;
   ffesymbol s;	 // Symbol for error reporting.
   ffebld expr;	 // opSUBSTR, opARRAYREF, opSYMTER, opANY.
   bool subtract;  // FALSE means add to adjust, TRUE means subtract from it.
   ffetargetOffset adjust;  // Helps keep answer in pos range (unsigned).
   if (!ffeequiv_offset_(&offset,s,expr,subtract,adjust))
       // error doing the calculation, message already printed

   Returns the offset represented by the SUBSTR, ARRAYREF, or SUBSTR/ARRAYREF
   combination added-to/subtracted-from the adjustment specified.  If there
   is an error of some kind, returns FALSE, else returns TRUE.	Note that
   only the first storage unit specified is considered; A(1:1) and A(1:2000)
   have the same first storage unit and so return the same offset.  */

static bool
ffeequiv_offset_ (ffetargetOffset *offset, ffesymbol s UNUSED,
		  ffebld expr, bool subtract, ffetargetOffset adjust,
		  bool no_precede)
{
  ffetargetIntegerDefault value = 0;
  ffetargetOffset cval;		/* Converted value. */
  ffesymbol sym;

  if (expr == NULL)
    return FALSE;

again:				/* :::::::::::::::::::: */

  switch (ffebld_op (expr))
    {
    case FFEBLD_opANY:
      return FALSE;

    case FFEBLD_opSYMTER:
      {
	ffetargetOffset size;	/* Size of a single unit. */
	ffetargetAlign a;	/* Ignored. */
	ffetargetAlign m;	/* Ignored. */

	sym = ffebld_symter (expr);
	if (ffesymbol_basictype (sym) == FFEINFO_basictypeANY)
	  return FALSE;

	ffetarget_layout (ffesymbol_text (sym), &a, &m, &size,
			  ffesymbol_basictype (sym),
			  ffesymbol_kindtype (sym), 1, 1);

	if (value < 0)
	  {			/* Really invalid, as in A(-2:5), but in case
				   it's wanted.... */
	    if (!ffetarget_offset (&cval, -value))
	      return FALSE;

	    if (!ffetarget_offset_multiply (&cval, cval, size))
	      return FALSE;

	    if (subtract)
	      return ffetarget_offset_add (offset, cval, adjust);

	    if (no_precede && (cval > adjust))
	      {
	      neg:		/* :::::::::::::::::::: */
		ffebad_start (FFEBAD_COMMON_NEG);
		ffebad_string (ffesymbol_text (sym));
		ffebad_finish ();
		return FALSE;
	      }
	    return ffetarget_offset_add (offset, -cval, adjust);
	  }

	if (!ffetarget_offset (&cval, value))
	  return FALSE;

	if (!ffetarget_offset_multiply (&cval, cval, size))
	  return FALSE;

	if (!subtract)
	  return ffetarget_offset_add (offset, cval, adjust);

	if (no_precede && (cval > adjust))
	  goto neg;		/* :::::::::::::::::::: */

	return ffetarget_offset_add (offset, -cval, adjust);
      }

    case FFEBLD_opARRAYREF:
      {
	ffebld symexp = ffebld_left (expr);
	ffebld subscripts = ffebld_right (expr);
	ffebld dims;
	ffetargetIntegerDefault width;
	ffetargetIntegerDefault arrayval;
	ffetargetIntegerDefault lowbound;
	ffetargetIntegerDefault highbound;
	ffebld subscript;
	ffebld dim;
	ffebld low;
	ffebld high;
	int rank = 0;

	if (ffebld_op (symexp) != FFEBLD_opSYMTER)
	  return FALSE;

	sym = ffebld_symter (symexp);
	if (ffesymbol_basictype (sym) == FFEINFO_basictypeANY)
	  return FALSE;

	if (ffesymbol_size (sym) == FFETARGET_charactersizeNONE)
	  width = 1;
	else
	  width = ffesymbol_size (sym);
	dims = ffesymbol_dims (sym);

	while (subscripts != NULL)
	  {
	    ++rank;
	    if (dims == NULL)
	      {
		ffebad_start (FFEBAD_EQUIV_MANY);
		ffebad_string (ffesymbol_text (sym));
		ffebad_finish ();
		return FALSE;
	      }

	    subscript = ffebld_head (subscripts);
	    dim = ffebld_head (dims);

	    if (ffebld_op (subscript) == FFEBLD_opANY)
	      return FALSE;

	    assert (ffebld_op (subscript) == FFEBLD_opCONTER);
	    assert (ffeinfo_basictype (ffebld_info (subscript))
		    == FFEINFO_basictypeINTEGER);
	    assert (ffeinfo_kindtype (ffebld_info (subscript))
		    == FFEINFO_kindtypeINTEGERDEFAULT);
	    arrayval = ffebld_constant_integerdefault (ffebld_conter
						       (subscript));

	    if (ffebld_op (dim) == FFEBLD_opANY)
	      return FALSE;

	    assert (ffebld_op (dim) == FFEBLD_opBOUNDS);
	    low = ffebld_left (dim);
	    high = ffebld_right (dim);

	    if (low == NULL)
	      lowbound = 1;
	    else
	      {
		if (ffebld_op (low) == FFEBLD_opANY)
		  return FALSE;

		assert (ffebld_op (low) == FFEBLD_opCONTER);
		assert (ffeinfo_basictype (ffebld_info (low))
			== FFEINFO_basictypeINTEGER);
		assert (ffeinfo_kindtype (ffebld_info (low))
			== FFEINFO_kindtypeINTEGERDEFAULT);
		lowbound
		  = ffebld_constant_integerdefault (ffebld_conter (low));
	      }

	    if (ffebld_op (high) == FFEBLD_opANY)
	      return FALSE;

	    assert (ffebld_op (high) == FFEBLD_opCONTER);
	    assert (ffeinfo_basictype (ffebld_info (high))
		    == FFEINFO_basictypeINTEGER);
	    assert (ffeinfo_kindtype (ffebld_info (high))
		    == FFEINFO_kindtypeINTEGER1);
	    highbound
	      = ffebld_constant_integerdefault (ffebld_conter (high));

	    if ((arrayval < lowbound) || (arrayval > highbound))
	      {
		char rankstr[10];

		sprintf (rankstr, "%d", rank);
		ffebad_start (FFEBAD_EQUIV_SUBSCRIPT);
		ffebad_string (ffesymbol_text (sym));
		ffebad_string (rankstr);
		ffebad_finish ();
	      }

	    subscripts = ffebld_trail (subscripts);
	    dims = ffebld_trail (dims);

	    value += width * (arrayval - lowbound);
	    if (subscripts != NULL)
	      width *= highbound - lowbound + 1;
	  }

	if (dims != NULL)
	  {
	    ffebad_start (FFEBAD_EQUIV_FEW);
	    ffebad_string (ffesymbol_text (sym));
	    ffebad_finish ();
	    return FALSE;
	  }

	expr = symexp;
      }
      goto again;		/* :::::::::::::::::::: */

    case FFEBLD_opSUBSTR:
      {
	ffebld begin = ffebld_head (ffebld_right (expr));

	expr = ffebld_left (expr);
	if (ffebld_op (expr) == FFEBLD_opANY)
	  return FALSE;
	if (ffebld_op (expr) == FFEBLD_opARRAYREF)
	  sym = ffebld_symter (ffebld_left (expr));
	else if (ffebld_op (expr) == FFEBLD_opSYMTER)
	  sym = ffebld_symter (expr);
	else
	  sym = NULL;

	if ((sym != NULL)
	    && (ffesymbol_basictype (sym) == FFEINFO_basictypeANY))
	  return FALSE;

	if (begin == NULL)
	  value = 0;
	else
	  {
	    if (ffebld_op (begin) == FFEBLD_opANY)
	      return FALSE;
	    assert (ffebld_op (begin) == FFEBLD_opCONTER);
	    assert (ffeinfo_basictype (ffebld_info (begin))
		    == FFEINFO_basictypeINTEGER);
	    assert (ffeinfo_kindtype (ffebld_info (begin))
		    == FFEINFO_kindtypeINTEGERDEFAULT);

	    value = ffebld_constant_integerdefault (ffebld_conter (begin));

	    if ((value < 1)
		|| ((sym != NULL)
		    && (value > ffesymbol_size (sym))))
	      {
		ffebad_start (FFEBAD_EQUIV_RANGE);
		ffebad_string (ffesymbol_text (sym));
		ffebad_finish ();
	      }

	    --value;
	  }
	if ((sym != NULL)
	    && (ffesymbol_basictype (sym) != FFEINFO_basictypeCHARACTER))
	  {
	    ffebad_start (FFEBAD_EQUIV_SUBSTR);
	    ffebad_string (ffesymbol_text (sym));
	    ffebad_finish ();
	    value = 0;
	  }
      }
      goto again;		/* :::::::::::::::::::: */

    default:
      assert ("bad op" == NULL);
      return FALSE;
    }

}

/* ffeequiv_add -- Add list of equivalences to list of lists for eq object

   ffeequiv eq;
   ffebld list;
   ffelexToken t;  // points to first item in equivalence list
   ffeequiv_add(eq,list,t);

   Check the list to make sure only one common symbol is involved (even
   if multiple times) and agrees with the common symbol for the equivalence
   object (or it has no common symbol until now).  Prepend (or append, it
   doesn't matter) the list to the list of lists for the equivalence object.
   Otherwise report an error and return.  */

void
ffeequiv_add (ffeequiv eq, ffebld list, ffelexToken t)
{
  ffebld item;
  ffesymbol symbol;
  ffesymbol common = ffeequiv_common (eq);

  for (item = list; item != NULL; item = ffebld_trail (item))
    {
      symbol = ffeequiv_symbol (ffebld_head (item));

      if (ffesymbol_common (symbol) != NULL)	/* Is symbol known in COMMON yet? */
	{
	  if (common == NULL)
	    common = ffesymbol_common (symbol);
	  else if (common != ffesymbol_common (symbol))
	    {
	      /* Yes, and symbol disagrees with others on the COMMON area. */
	      ffebad_start (FFEBAD_EQUIV_COMMON);
	      ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t));
	      ffebad_string (ffesymbol_text (common));
	      ffebad_string (ffesymbol_text (ffesymbol_common (symbol)));
	      ffebad_finish ();
	      return;
	    }
	}
    }

  if ((common != NULL)
      && (ffeequiv_common (eq) == NULL))	/* Is COMMON involved already? */
    ffeequiv_set_common (eq, common);	/* No, but it is now. */

  for (item = list; item != NULL; item = ffebld_trail (item))
    {
      symbol = ffeequiv_symbol (ffebld_head (item));

      if (ffesymbol_equiv (symbol) == NULL)
	ffesymbol_set_equiv (symbol, eq);
      else
	assert (ffesymbol_equiv (symbol) == eq);

      if (ffesymbol_common (symbol) == NULL)	/* Is symbol in a COMMON
						   area? */
	{			/* No (at least not yet). */
	  if (ffesymbol_is_save (symbol))
	    ffeequiv_update_save (eq);	/* EQUIVALENCE has >=1 SAVEd entity. */
	  if (ffesymbol_is_init (symbol))
	    ffeequiv_update_init (eq);	/* EQUIVALENCE has >=1 init'd entity. */
	  continue;		/* Nothing more to do here. */
	}

#if FFEGLOBAL_ENABLED
      if (ffesymbol_is_init (symbol))
	ffeglobal_init_common (ffesymbol_common (symbol), t);
#endif

      if (ffesymbol_is_save (ffesymbol_common (symbol)))
	ffeequiv_update_save (eq);	/* EQUIVALENCE is in a SAVEd COMMON block. */
      if (ffesymbol_is_init (ffesymbol_common (symbol)))
	ffeequiv_update_init (eq);	/* EQUIVALENCE is in a init'd COMMON block. */
    }

  ffeequiv_set_list (eq, ffebld_new_item (list, ffeequiv_list (eq)));
}

/* ffeequiv_exec_transition -- Do the hard work on all the equivalence objects

   ffeequiv_exec_transition();	*/

void
ffeequiv_exec_transition ()
{
  while (ffeequiv_list_.first != (ffeequiv) &ffeequiv_list_.first)
    ffeequiv_layout_local_ (ffeequiv_list_.first);
}

/* ffeequiv_init_2 -- Initialize for new program unit

   ffeequiv_init_2();

   Initializes the list of equivalences.  */

void
ffeequiv_init_2 ()
{
  ffeequiv_list_.first = (ffeequiv) &ffeequiv_list_.first;
  ffeequiv_list_.last = (ffeequiv) &ffeequiv_list_.first;
}

/* ffeequiv_kill -- Kill equivalence object after removing from list

   ffeequiv eq;
   ffeequiv_kill(eq);

   Removes equivalence object from master list, then kills it.	*/

void
ffeequiv_kill (ffeequiv victim)
{
  victim->next->previous = victim->previous;
  victim->previous->next = victim->next;
  if (ffe_is_do_internal_checks ())
    {
      ffebld list;
      ffebld item;
      ffebld expr;

      /* Assert that nobody our victim points to still points to it.  */

      assert ((victim->common == NULL)
	      || (ffesymbol_equiv (victim->common) == NULL));

      for (list = victim->list; list != NULL; list = ffebld_trail (list))
	{
	  for (item = ffebld_head (list); item != NULL; item = ffebld_trail (item))
	    {
	      ffesymbol sym;

	      expr = ffebld_head (item);
	      sym = ffeequiv_symbol (expr);
	      if (sym == NULL)
		continue;
	      assert (ffesymbol_equiv (sym) != victim);
	    }
	}
    }
  malloc_kill_ks (ffe_pool_program_unit (), victim, sizeof (*victim));
}

/* ffeequiv_layout_cblock -- Lay out storage for common area

   ffestorag st;
   if (ffeequiv_layout_cblock(st))
       // at least one equiv'd symbol has init/accretion expr.

   Now that the explicitly COMMONed variables in the common area (whose
   ffestorag object is passed) have been laid out, lay out the storage
   for all variables equivalenced into the area by making subordinate
   ffestorag objects for them.	*/

bool
ffeequiv_layout_cblock (ffestorag st)
{
  ffesymbol s = ffestorag_symbol (st);	/* CBLOCK symbol. */
  ffebld list;			/* List of explicit common vars, in order, in
				   s. */
  ffebld item;			/* List of list of equivalences in a given
				   explicit common var. */
  ffebld root;			/* Expression for (1st) explicit common var
				   in list of eqs. */
  ffestorag rst;		/* Storage for root. */
  ffetargetOffset root_offset;	/* Offset for root into common area. */
  ffesymbol sr;			/* Root itself. */
  ffeequiv seq;			/* Its equivalence object, if any. */
  ffebld var;			/* Expression for equivalence. */
  ffestorag vst;		/* Storage for var. */
  ffetargetOffset var_offset;	/* Offset for var into common area. */
  ffesymbol sv;			/* Var itself. */
  ffebld altroot;		/* Alternate root. */
  ffesymbol altrootsym;		/* Alternate root symbol. */
  ffetargetAlign alignment;
  ffetargetAlign modulo;
  ffetargetAlign pad;
  ffetargetOffset size;
  ffetargetOffset num_elements;
  bool new_storage;		/* Established new storage info. */
  bool need_storage;		/* Have need for more storage info. */
  bool ok;
  bool init = FALSE;

  assert (st != NULL);
  assert (ffestorag_type (st) == FFESTORAG_typeCBLOCK);
  assert (ffesymbol_kind (ffestorag_symbol (st)) == FFEINFO_kindCOMMON);

  for (list = ffesymbol_commonlist (ffestorag_symbol (st));
       list != NULL;
       list = ffebld_trail (list))
    {				/* For every variable in the common area */
      assert (ffebld_op (ffebld_head (list)) == FFEBLD_opSYMTER);
      sr = ffebld_symter (ffebld_head (list));
      if ((seq = ffesymbol_equiv (sr)) == NULL)
	continue;		/* No equivalences to process. */
      rst = ffesymbol_storage (sr);
      if (rst == NULL)
	{
	  assert (ffesymbol_kind (sr) == FFEINFO_kindANY);
	  continue;
	}
      ffesymbol_set_equiv (sr, NULL);	/* Cancel ref to equiv obj. */
      do
	{
	  new_storage = FALSE;
	  need_storage = FALSE;
	  for (item = ffeequiv_list (seq);	/* Get list of equivs. */
	       item != NULL;
	       item = ffebld_trail (item))
	    {			/* For every eqv list in the list of equivs
				   for the variable */
	      altroot = NULL;
	      altrootsym = NULL;
	      for (root = ffebld_head (item);
		   root != NULL;
		   root = ffebld_trail (root))
		{		/* For every equivalence item in the list */
		  sv = ffeequiv_symbol (ffebld_head (root));
		  if (sv == sr)
		    break;	/* Found first mention of "rooted" symbol. */
		  if (ffesymbol_storage (sv) != NULL)
		    {
		      altroot = root;	/* If no mention, use this guy
					   instead. */
		      altrootsym = sv;
		    }
		}
	      if (root != NULL)
		{
		  root = ffebld_head (root);	/* Lose its opITEM. */
		  ok = ffeequiv_offset_ (&root_offset, sr, root, FALSE,
					 ffestorag_offset (rst), TRUE);
		  /* Equiv point prior to start of common area? */
		}
	      else if (altroot != NULL)
		{
		  /* Equiv point prior to start of common area? */
		  root = ffebld_head (altroot);
		  ok = ffeequiv_offset_ (&root_offset, altrootsym, root,
					 FALSE,
			 ffestorag_offset (ffesymbol_storage (altrootsym)),
					 TRUE);
		  ffesymbol_set_equiv (altrootsym, NULL);
		}
	      else
		/* No rooted symbol in list of equivalences! */
		{		/* Assume this was due to opANY and ignore
				   this list for now. */
		  need_storage = TRUE;
		  continue;
		}

	      /* We now know the root symbol and the operating offset of that
		 root into the common area.  The other expressions in the
		 list all identify an initial storage unit that must have the
		 same offset. */

	      for (var = ffebld_head (item);
		   var != NULL;
		   var = ffebld_trail (var))
		{		/* For every equivalence item in the list */
		  if (ffebld_head (var) == root)
		    continue;	/* Except root, of course. */
		  sv = ffeequiv_symbol (ffebld_head (var));
		  if (sv == NULL)
		    continue;	/* Except erroneous stuff (opANY). */
		  ffesymbol_set_equiv (sv, NULL);	/* Don't need this ref
							   anymore. */
		  if (!ok
		      || !ffeequiv_offset_ (&var_offset, sv,
					    ffebld_head (var), TRUE,
					    root_offset, TRUE))
		    continue;	/* Can't do negative offset wrt COMMON. */

		  if (ffesymbol_rank (sv) == 0)
		    num_elements = 1;
		  else
		    num_elements = ffebld_constant_integerdefault
		      (ffebld_conter (ffesymbol_arraysize (sv)));
		  ffetarget_layout (ffesymbol_text (sv), &alignment,
				    &modulo, &size,
				    ffesymbol_basictype (sv),
				    ffesymbol_kindtype (sv),
				    ffesymbol_size (sv), num_elements);
		  pad = ffetarget_align (ffestorag_ptr_to_alignment (st),
					 ffestorag_ptr_to_modulo (st),
					 var_offset, alignment, modulo);
		  if (pad != 0)
		    {
		      ffebad_start (FFEBAD_EQUIV_ALIGN);
		      ffebad_string (ffesymbol_text (sv));
		      ffebad_finish ();
		      continue;
		    }

		  if ((vst = ffesymbol_storage (sv)) == NULL)
		    {		/* Create new ffestorag object, extend
				   cblock. */
		      new_storage = TRUE;
		      vst = ffestorag_new (ffestorag_list_equivs (st));
		      ffestorag_set_parent (vst, st);	/* Initializations
							   happen there. */
		      ffestorag_set_init (vst, NULL);
		      ffestorag_set_accretion (vst, NULL);
		      ffestorag_set_symbol (vst, sv);
		      ffestorag_set_size (vst, size);
		      ffestorag_set_offset (vst, var_offset);
		      ffestorag_set_alignment (vst, alignment);
		      ffestorag_set_modulo (vst, modulo);
		      ffestorag_set_type (vst, FFESTORAG_typeEQUIV);
		      ffestorag_set_basictype (vst, ffesymbol_basictype (sv));
		      ffestorag_set_kindtype (vst, ffesymbol_kindtype (sv));
		      ffestorag_set_typesymbol (vst, sv);
		      ffestorag_set_is_save (vst, FALSE);	/* Assume FALSE... */
		      if (ffestorag_is_save (st))	/* ...update TRUE */
			ffestorag_update_save (vst);	/* if needed. */
		      ffestorag_set_is_init (vst, FALSE);	/* Assume FALSE... */
		      if (ffestorag_is_init (st))	/* ...update TRUE */
			ffestorag_update_init (vst);	/* if needed. */
		      if (!ffetarget_offset_add (&size, var_offset, size))
			/* Find one size of common block, complain if
			   overflow. */
			ffetarget_offset_overflow (ffesymbol_text (s));
		      else if (size > ffestorag_size (st))
			/* Extend common. */
			ffestorag_set_size (st, size);
		      ffesymbol_set_storage (sv, vst);
		      ffesymbol_set_common (sv, s);
		      ffesymbol_signal_unreported (sv);
		      ffestorag_update (st, sv, ffesymbol_basictype (sv),
					ffesymbol_kindtype (sv));
		      if (ffesymbol_is_init (sv))
			init = TRUE;
		    }
		  else
		    {
		      /* Make sure offset agrees with known offset. */
		      if (var_offset != ffestorag_offset (vst))
			{
			  char io1[40];
			  char io2[40];

			  sprintf (&io1[0], "%" ffetargetOffset_f "d", var_offset);
			  sprintf (&io2[0], "%" ffetargetOffset_f "d", ffestorag_offset (vst));
			  ffebad_start (FFEBAD_EQUIV_MISMATCH);
			  ffebad_string (ffesymbol_text (sv));
			  ffebad_string (ffesymbol_text (s));
			  ffebad_string (io1);
			  ffebad_string (io2);
			  ffebad_finish ();
			}
		    }
		}		/* (For every equivalence item in the list) */
	    }			/* (For every eqv list in the list of equivs
				   for the variable) */
	}
      while (new_storage && need_storage);

      ffeequiv_kill (seq);	/* Kill equiv obj. */
    }				/* (For every variable in the common area) */

  return init;
}

/* ffeequiv_merge -- Merge two equivalence objects, return the merged result

   ffeequiv eq1;
   ffeequiv eq2;
   ffelexToken t;  // points to current equivalence item forcing the merge.
   eq1 = ffeequiv_merge(eq1,eq2,t);

   If the two equivalence objects can be merged, they are, all the
   ffesymbols in their lists of lists are adjusted to point to the merged
   equivalence object, and the merged object is returned.

   Otherwise, the two equivalence objects have different non-NULL common
   symbols, so the merge cannot take place.  An error message is issued and
   NULL is returned.  */

ffeequiv
ffeequiv_merge (ffeequiv eq1, ffeequiv eq2, ffelexToken t)
{
  ffebld list;
  ffebld eqs;
  ffesymbol symbol;
  ffebld last = NULL;

  /* If both equivalence objects point to different common-based symbols,
     complain.	Of course, one or both might have NULL common symbols now,
     and get COMMONed later, but the COMMON statement handler checks for
     this. */

  if ((ffeequiv_common (eq1) != NULL) && (ffeequiv_common (eq2) != NULL)
      && (ffeequiv_common (eq1) != ffeequiv_common (eq2)))
    {
      ffebad_start (FFEBAD_EQUIV_COMMON);
      ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t));
      ffebad_string (ffesymbol_text (ffeequiv_common (eq1)));
      ffebad_string (ffesymbol_text (ffeequiv_common (eq2)));
      ffebad_finish ();
      return NULL;
    }

  /* Make eq1 the new, merged object (arbitrarily). */

  if (ffeequiv_common (eq1) == NULL)
    ffeequiv_set_common (eq1, ffeequiv_common (eq2));

  /* If the victim object has any init'ed entities, so does the new object. */

  if (eq2->is_init)
    eq1->is_init = TRUE;

#if FFEGLOBAL_ENABLED
  if (eq1->is_init && (ffeequiv_common (eq1) != NULL))
    ffeglobal_init_common (ffeequiv_common (eq1), t);
#endif

  /* If the victim object has any SAVEd entities, then the new object has
     some. */

  if (ffeequiv_is_save (eq2))
    ffeequiv_update_save (eq1);

  /* If the victim object has any init'd entities, then the new object has
     some. */

  if (ffeequiv_is_init (eq2))
    ffeequiv_update_init (eq1);

  /* Adjust all the symbols in the list of lists of equivalences for the
     victim equivalence object so they point to the new merged object
     instead. */

  for (list = ffeequiv_list (eq2); list != NULL; list = ffebld_trail (list))
    {
      for (eqs = ffebld_head (list); eqs != NULL; eqs = ffebld_trail (eqs))
	{
	  symbol = ffeequiv_symbol (ffebld_head (eqs));
	  if (ffesymbol_equiv (symbol) == eq2)
	    ffesymbol_set_equiv (symbol, eq1);
	  else
	    assert (ffesymbol_equiv (symbol) == eq1);	/* Can see a sym > once. */
	}

      /* For convenience, remember where the last ITEM in the outer list is. */

      if (ffebld_trail (list) == NULL)
	{
	  last = list;
	  break;
	}
    }

  /* Append the list of lists in the new, merged object to the list of lists
     in the victim object, then use the new combined list in the new merged
     object. */

  ffebld_set_trail (last, ffeequiv_list (eq1));
  ffeequiv_set_list (eq1, ffeequiv_list (eq2));

  /* Unlink and kill the victim object. */

  ffeequiv_kill (eq2);

  return eq1;			/* Return the new merged object. */
}

/* ffeequiv_new -- Create new equivalence object, put in list

   ffeequiv eq;
   eq = ffeequiv_new();

   Creates a new equivalence object and adds it to the list of equivalence
   objects.  */

ffeequiv
ffeequiv_new ()
{
  ffeequiv eq;

  eq = malloc_new_ks (ffe_pool_program_unit (), "ffeequiv", sizeof (*eq));
  eq->next = (ffeequiv) &ffeequiv_list_.first;
  eq->previous = ffeequiv_list_.last;
  ffeequiv_set_common (eq, NULL);	/* No COMMON area yet. */
  ffeequiv_set_list (eq, NULL);	/* No list of lists of equivalences yet. */
  ffeequiv_set_is_save (eq, FALSE);
  ffeequiv_set_is_init (eq, FALSE);
  eq->next->previous = eq;
  eq->previous->next = eq;

  return eq;
}

/* ffeequiv_symbol -- Return symbol for equivalence expression

   ffesymbol symbol;
   ffebld expr;
   symbol = ffeequiv_symbol(expr);

   Finds the terminal SYMTER in an equivalence expression and returns the
   ffesymbol for it.  */

ffesymbol
ffeequiv_symbol (ffebld expr)
{
  assert (expr != NULL);

again:				/* :::::::::::::::::::: */

  switch (ffebld_op (expr))
    {
    case FFEBLD_opARRAYREF:
    case FFEBLD_opSUBSTR:
      expr = ffebld_left (expr);
      goto again;		/* :::::::::::::::::::: */

    case FFEBLD_opSYMTER:
      return ffebld_symter (expr);

    case FFEBLD_opANY:
      return NULL;

    default:
      assert ("bad eq expr" == NULL);
      return NULL;
    }
}

/* ffeequiv_update_init -- Update the INIT flag for the area to TRUE

   ffeequiv eq;
   ffeequiv_update_init(eq);

   If the INIT flag for the <eq> object is already set, return.	 Else,
   set it TRUE and call ffe*_update_init for all objects contained in
   this one.  */

void
ffeequiv_update_init (ffeequiv eq)
{
  ffebld list;			/* Current list in list of lists. */
  ffebld item;			/* Current item in current list. */
  ffebld expr;			/* Expression in head of current item. */

  if (eq->is_init)
    return;

  eq->is_init = TRUE;

  if ((eq->common != NULL)
      && !ffesymbol_is_init (eq->common))
    ffesymbol_update_init (eq->common);	/* Shouldn't be needed. */

  for (list = eq->list; list != NULL; list = ffebld_trail (list))
    {
      for (item = ffebld_head (list); item != NULL; item = ffebld_trail (item))
	{
	  expr = ffebld_head (item);

	again:			/* :::::::::::::::::::: */

	  switch (ffebld_op (expr))
	    {
	    case FFEBLD_opANY:
	      break;

	    case FFEBLD_opSYMTER:
	      if (!ffesymbol_is_init (ffebld_symter (expr)))
		ffesymbol_update_init (ffebld_symter (expr));
	      break;

	    case FFEBLD_opARRAYREF:
	      expr = ffebld_left (expr);
	      goto again;	/* :::::::::::::::::::: */

	    case FFEBLD_opSUBSTR:
	      expr = ffebld_left (expr);
	      goto again;	/* :::::::::::::::::::: */

	    default:
	      assert ("bad op for ffeequiv_update_init" == NULL);
	      break;
	    }
	}
    }
}

/* ffeequiv_update_save -- Update the SAVE flag for the area to TRUE

   ffeequiv eq;
   ffeequiv_update_save(eq);

   If the SAVE flag for the <eq> object is already set, return.	 Else,
   set it TRUE and call ffe*_update_save for all objects contained in
   this one.  */

void
ffeequiv_update_save (ffeequiv eq)
{
  ffebld list;			/* Current list in list of lists. */
  ffebld item;			/* Current item in current list. */
  ffebld expr;			/* Expression in head of current item. */

  if (eq->is_save)
    return;

  eq->is_save = TRUE;

  if ((eq->common != NULL)
      && !ffesymbol_is_save (eq->common))
    ffesymbol_update_save (eq->common);	/* Shouldn't be needed. */

  for (list = eq->list; list != NULL; list = ffebld_trail (list))
    {
      for (item = ffebld_head (list); item != NULL; item = ffebld_trail (item))
	{
	  expr = ffebld_head (item);

	again:			/* :::::::::::::::::::: */

	  switch (ffebld_op (expr))
	    {
	    case FFEBLD_opANY:
	      break;

	    case FFEBLD_opSYMTER:
	      if (!ffesymbol_is_save (ffebld_symter (expr)))
		ffesymbol_update_save (ffebld_symter (expr));
	      break;

	    case FFEBLD_opARRAYREF:
	      expr = ffebld_left (expr);
	      goto again;	/* :::::::::::::::::::: */

	    case FFEBLD_opSUBSTR:
	      expr = ffebld_left (expr);
	      goto again;	/* :::::::::::::::::::: */

	    default:
	      assert ("bad op for ffeequiv_update_save" == NULL);
	      break;
	    }
	}
    }
}
