/* Implement actions for CHILL.
   Copyright (C) 1992, 1993, 1994, 1998, 1999, 2000
   Free Software Foundation, Inc.
   Authors: Per Bothner, Bill Cox, Michael Tiemann, Michael North

This file is part of GNU CC.

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

#include "config.h"
#include "system.h"
#include "tree.h"
#include "rtl.h"
#include "expr.h"
#include "ch-tree.h"
#include "lex.h"
#include "flags.h"
#include "actions.h"
#include "obstack.h"
#include "assert.h"
#include "toplev.h"
#include "diagnostic.h"

static int id_cmp PARAMS ((tree *, tree *));
static void warn_unhandled PARAMS ((const char *));
static tree adjust_return_value PARAMS ((tree, const char *));
static tree update_else_range_for_int_const PARAMS ((tree, tree));
static tree update_else_range_for_range PARAMS ((tree, tree, tree));
static tree update_else_range_for_range_expr PARAMS ((tree, tree));
static tree update_else_range_for_type PARAMS ((tree, tree));
static tree compute_else_range PARAMS ((tree, tree, int));
static tree check_case_value PARAMS ((tree, tree));
static void chill_handle_case_label_range PARAMS ((tree, tree, tree));
static tree chill_handle_multi_case_label_range PARAMS ((tree, tree, tree));
static tree chill_handle_multi_case_else_label PARAMS ((tree));
static tree chill_handle_multi_case_label PARAMS ((tree, tree));
static tree chill_handle_multi_case_label_list PARAMS ((tree, tree));
static void print_missing_cases PARAMS ((tree, const unsigned char *, long));

#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free

/* reserved tag definitions */

#define TYPE_ID                 "id"
#define TAG_OBJECT              "chill_object"
#define TAG_CLASS               "chill_class"

extern int flag_short_enums;
extern int current_nesting_level;

extern struct obstack *expression_obstack, permanent_obstack;
extern struct obstack *current_obstack, *saveable_obstack;

/* This flag is checked throughout the non-CHILL-specific
   in the front end. */
tree chill_integer_type_node;
tree chill_unsigned_type_node;

/* Never used.  Referenced from c-typeck.c, which we use. */
int current_function_returns_value = 0;
int current_function_returns_null = 0;

/* data imported from toplev.c  */

extern char *dump_base_name;

/* set from command line parameter, to exit after 
   grant file written, generating no code. */
int grant_only_flag = 0;

const char *
lang_identify ()
{
  return "chill";
}


void
init_chill ()
{
}

void
print_lang_statistics ()
{
}


void
lang_finish ()
{
#if 0
    extern int errorcount, sorrycount;

    /* this should be the last action in compiling a module.
       If there are other actions to be performed at lang_finish
       please insert before this */

    /* FIXME: in case of a syntax error, this leaves the grant file incomplete */
    /* for the moment we print a warning in case of errors and 
       continue granting */
    if ((errorcount || sorrycount) && grant_count)
      {
	warning ("%d errors, %d sorries, do granting", errorcount, sorrycount);
	errorcount = sorrycount = 0;
      }
#endif
}

void
chill_check_decl (decl)
     tree decl;
{
  tree type = TREE_TYPE (decl);
  static int alreadyWarned = 0;

  if (TREE_CODE (type) == RECORD_TYPE) /* && TREE_STATIC_TEMPLATE (type)) */
    {
      if (!alreadyWarned)
        {
          error ("GNU compiler does not support statically allocated objects");          
          alreadyWarned = 1;
        }
      error_with_decl (decl, "`%s' cannot be statically allocated");
    }
}

/* Comparison function for sorting identifiers in RAISES lists.
   Note that because IDENTIFIER_NODEs are unique, we can sort
   them by address, saving an indirection.  */
static int
id_cmp (p1, p2)
     tree *p1, *p2;
{
  long diff = (long)TREE_VALUE (*p1) - (long)TREE_VALUE (*p2);

  return (diff < 0) ? -1 : (diff > 0);
}

/* Build the FUNCTION_TYPE or METHOD_TYPE which may raise exceptions
   listed in RAISES.  */
tree
build_exception_variant (type, raises)
     tree type, raises;
{
  int i;
  tree v = TYPE_MAIN_VARIANT (type);
  tree t, t2;
  int constp    = TYPE_READONLY (type);
  int volatilep = TYPE_VOLATILE (type);

  if (!raises)
    return build_type_variant (v, constp, volatilep);

  if (TREE_CHAIN (raises))
    { /* Sort the list */
      tree *a = (tree *)alloca ((list_length (raises)+1) * sizeof (tree));
      for (i = 0, t = raises; t; t = TREE_CHAIN (t), i++)
	a[i] = t;
      /* NULL terminator for list.  */
      a[i] = NULL_TREE;
      qsort (a, i, sizeof (tree),
	     (int (*) PARAMS ((const void*, const void*))) id_cmp);
      while (i--)
	TREE_CHAIN (a[i]) = a[i+1];
      raises = a[0];
    }

  for (v = TYPE_NEXT_VARIANT (v); v; v = TYPE_NEXT_VARIANT (v))
    {
      if (TYPE_READONLY (v) != constp
	  || TYPE_VOLATILE (v) != volatilep)
	continue;

      t = raises;
      t2 = TYPE_RAISES_EXCEPTIONS (v);
      while (t && t2)
	{
	  if (TREE_TYPE (t) == TREE_TYPE (t2))
	    {
	      t = TREE_CHAIN (t);
	      t2 = TREE_CHAIN (t2);
	    }
	  else break;
	}
      if (t || t2)
	continue;
      /* List of exceptions raised matches previously found list.

         @@ Nice to free up storage used in consing up the
	 @@ list of exceptions raised.  */
      return v;
    }

  /* Need to build a new variant.  */
  if (TREE_PERMANENT (type))
    {
      push_obstacks_nochange ();
      end_temporary_allocation ();
      v = copy_node (type);
      pop_obstacks ();
    }
  else
    v = copy_node (type);

  TYPE_NEXT_VARIANT (v) = TYPE_NEXT_VARIANT (type);
  TYPE_NEXT_VARIANT (type) = v;
  if (raises && ! TREE_PERMANENT (raises))
    {
      push_obstacks_nochange ();
      end_temporary_allocation ();
      raises = copy_list (raises);
      pop_obstacks ();
    }
  TYPE_RAISES_EXCEPTIONS (v) = raises;
  return v;
}
#if 0

tree
build_rts_call (name, type, args)
     const char *name;
     tree type, args;
{
  tree decl = lookup_name (get_identifier (name));
  tree converted_args = NULL_TREE;
  tree result, length = NULL_TREE;

  assert (decl != NULL_TREE);
  while (args)
    {
      tree arg = TREE_VALUE (args);
      if (TREE_CODE (TREE_TYPE (arg)) == SET_TYPE
	  || TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE)
	{
	  length = size_in_bytes (TREE_TYPE (arg));
	  arg = build_chill_addr_expr (arg, (char *)0);
	}
      converted_args = tree_cons (NULL_TREE, arg, converted_args);
      args = TREE_CHAIN (args);
    }
  if (length != NULL_TREE)
    converted_args = tree_cons (NULL_TREE, length, converted_args);
  converted_args = nreverse (converted_args);
  result = build_chill_function_call (decl, converted_args);
  if (TREE_CODE (type) == SET_TYPE || TREE_CODE (type) == ARRAY_TYPE)
    result = build1 (INDIRECT_REF, type, result);
  else
    result = convert (type, result);
  return result;
}
#endif

/*
 * queue name of unhandled exception
 * to avoid multiple unhandled warnings
 * in one compilation module
 */

struct already_type
{
  struct already_type *next;
  char *name;
};

static struct already_type *already_warned = 0;

static void
warn_unhandled (ex)
     const char *ex;
{
  struct already_type *p = already_warned;

  while (p)
    {
      if (!strcmp (p->name, ex))
	return;
      p = p->next;
    }
  
  /* not yet warned */
  p = (struct already_type *)xmalloc (sizeof (struct already_type));
  p->next = already_warned;
  p->name = xstrdup (ex);
  already_warned = p;
  pedwarn ("causing unhandled exception `%s' (this is flaged only once)", ex);
}

/*
 * build a call to the following function:
 *   void   __cause_ex1 (char* ex, const char *file, 
 *                       const unsigned lineno);
 * if the exception is handled or
 *   void __unhandled_ex (char *ex, char *file, unsigned lineno)
 * if the exception is not handled.
 */
tree
build_cause_exception (exp_name, warn_if_unhandled)
     tree exp_name;
     int warn_if_unhandled;
{
  /* We don't use build_rts_call() here, because the string (array of char)
     would be followed by its length in the parameter list built by
     build_rts_call, and the runtime routine doesn't want a length parameter.*/
  tree exp_decl = build_chill_exception_decl (IDENTIFIER_POINTER (exp_name));
  tree function, fname, lineno, result;
  int handled = is_handled (exp_name);

  switch (handled)
    {
    case 0:
      /* no handler */
      if (warn_if_unhandled)
	warn_unhandled (IDENTIFIER_POINTER (exp_name));
      function = lookup_name (get_identifier ("__unhandled_ex"));
      fname = force_addr_of (get_chill_filename ());
      lineno = get_chill_linenumber ();
      break;
    case 1:
      /* local handler */
      function = lookup_name (get_identifier ("__cause_ex1"));
      fname = force_addr_of (get_chill_filename ());
      lineno = get_chill_linenumber ();
      break;
    case 2:
      /* function may propagate this exception */
      function = lookup_name (get_identifier ("__cause_ex1"));
      fname = lookup_name (get_identifier (CALLER_FILE));
      if (fname == NULL_TREE)
	fname = error_mark_node;
      lineno = lookup_name (get_identifier (CALLER_LINE));
      if (lineno == NULL_TREE)
	lineno = error_mark_node;
      break;
    default:
      abort();
    }
  result =
    build_chill_function_call (function,
      tree_cons (NULL_TREE, build_chill_addr_expr (exp_decl, (char *)0),
	tree_cons (NULL_TREE,  fname,
	  tree_cons (NULL_TREE, lineno, NULL_TREE))));
  return result;
}

void
expand_cause_exception (exp_name)
     tree exp_name;
{
  expand_expr_stmt (build_cause_exception (exp_name, 1));
}

/* If CONDITION is true, raise EXCEPTION (an IDENTIFIER_NODE);
   otherwise return EXPR. */

tree
check_expression (expr, condition, exception)
     tree expr, condition, exception;
{
  if (integer_zerop (condition))
    return expr;
  else
    return build (COMPOUND_EXPR, TREE_TYPE (expr),
		  fold (build (TRUTH_ANDIF_EXPR, boolean_type_node,
			       condition, build_cause_exception (exception, 0))),
		  expr);
}

/* Return an expression for VALUE < LO_LIMIT || VALUE > HI_LIMIT,
   somewhat optimized and with some warnings suppressed.
   If LO_LIMIT or HI_LIMIT is NULL_TREE, assume that (sub-)test passes.  */

tree
test_range (value, lo_limit, hi_limit)
     tree value, lo_limit, hi_limit;
{
  if (lo_limit || hi_limit)
    {
      int old_inhibit_warnings = inhibit_warnings;
      tree lo_check, hi_check, check;

      /* This is a hack so that `shorten_compare' doesn't warn the
	 user about useless range checks that are too much work to
	 optimize away here.  */
      inhibit_warnings = 1;

      lo_check = lo_limit ? 
	fold (build_compare_discrete_expr (LT_EXPR, value, lo_limit)) :
	  boolean_false_node;   /* fake passing the check */

      hi_check = hi_limit ? 
	fold (build_compare_discrete_expr (GT_EXPR, value, hi_limit)) :
	  boolean_false_node;   /* fake passing the check */

      if (lo_check == boolean_false_node)
	check = hi_check;
      else if (hi_check == boolean_false_node)
	check = lo_check;
      else
	check = fold (build (TRUTH_ORIF_EXPR, boolean_type_node,
			     lo_check, hi_check));

      inhibit_warnings = old_inhibit_warnings;
      return check;
    }
  else
    return boolean_false_node;
}

/* Return EXPR, except if range_checking is on, return an expression
   that also checks that value >= low_limit && value <= hi_limit.
   If LO_LIMIT or HI_LIMIT is NULL_TREE, assume that test passes.  */

tree
check_range (expr, value, lo_limit, hi_limit)
     tree expr, value, lo_limit, hi_limit;
{
  tree check = test_range (value, lo_limit, hi_limit);
  if (!integer_zerop (check))
    {
      if (current_function_decl == NULL_TREE)
	{
	  if (TREE_CODE (check) == INTEGER_CST)
	    error ("range failure (not inside function)");
	  else
	    warning ("possible range failure (not inside function)");
	}
      else
	{
	  if (TREE_CODE (check) == INTEGER_CST)
	    warning ("expression will always cause RANGEFAIL");
	  if (range_checking)
	    expr = check_expression (expr, check,
				     ridpointers[(int) RID_RANGEFAIL]);
	}
    }
  return expr;
}

/* Same as EXPR, except raise EMPTY if EXPR is NULL. */

tree
check_non_null (expr)
     tree expr;
{
  if (empty_checking)
    {
      expr = save_if_needed (expr);
      return check_expression (expr,
			       build_compare_expr (EQ_EXPR,
						   expr, null_pointer_node),
			       ridpointers[(int) RID_EMPTY]);
    }
  return expr;
}

/*  There are four conditions to generate a runtime check:
    1) assigning a longer INT to a shorter (signs irrelevant)
    2) assigning a signed to an unsigned
    3) assigning an unsigned to a signed of the same size.
    4) TYPE is a discrete subrange  */

tree
chill_convert_for_assignment (type, expr, place)
     tree type, expr;
     const char *place; /* location description for error messages */
{
  tree ttype = type;
  tree etype = TREE_TYPE (expr);
  tree result;

  if (type == NULL_TREE || TREE_CODE (type) == ERROR_MARK)
    return error_mark_node;
  if (expr == NULL_TREE || TREE_CODE (expr) == ERROR_MARK)
    return expr;
  if (TREE_CODE (expr) == TYPE_DECL)
    {
      error ("right hand side of assignment is a mode");
      return error_mark_node;
    }

  if (! CH_COMPATIBLE (expr, type))
    {
      error ("incompatible modes in %s", place);
      return error_mark_node;
    }

  if (TREE_CODE (type) == REFERENCE_TYPE)
    ttype = TREE_TYPE (ttype);
  if (etype && TREE_CODE (etype) == REFERENCE_TYPE)
    etype = TREE_TYPE (etype);

  if (etype
      && (CH_STRING_TYPE_P (ttype)
	  || (chill_varying_type_p (ttype)
	      && CH_STRING_TYPE_P (CH_VARYING_ARRAY_TYPE (ttype))))
      && (CH_STRING_TYPE_P (etype)
	  || (chill_varying_type_p (etype)
	      && CH_STRING_TYPE_P (CH_VARYING_ARRAY_TYPE (etype)))))
    {
      tree cond;
      if (range_checking)
	expr = save_if_needed (expr);
      cond = string_assignment_condition (ttype, expr);
      if (TREE_CODE (cond) == INTEGER_CST)
	{
	  if (integer_zerop (cond))
	    {
	      error ("bad string length in %s", place);
	      return error_mark_node;
	    }
	  /* Otherwise, the condition is always true, so no runtime test. */
	}
      else if (range_checking)
	expr = check_expression (expr,
				 invert_truthvalue (cond),
				 ridpointers[(int) RID_RANGEFAIL]);
    }

  if (range_checking 
      && discrete_type_p (ttype) 
      && etype != NULL_TREE
      && discrete_type_p (etype))
    {
      int cond1 = tree_int_cst_lt (TYPE_SIZE (ttype),
				   TYPE_SIZE (etype));
      int cond2 = TREE_UNSIGNED (ttype) 
	          && (! TREE_UNSIGNED (etype));
      int cond3 = (! TREE_UNSIGNED (type))
	          && TREE_UNSIGNED (etype) 
		  && tree_int_cst_equal (TYPE_SIZE (ttype),
					 TYPE_SIZE (etype));
      int cond4 = TREE_TYPE (ttype) 
	          && discrete_type_p (TREE_TYPE (ttype));

      if (cond1 || cond2 || cond3 || cond4)
	{
	  tree type_min = TYPE_MIN_VALUE (ttype);
	  tree type_max = TYPE_MAX_VALUE (ttype);

	  expr = save_if_needed (expr);
	  if (expr && type_min && type_max)
	    expr = check_range (expr, expr, type_min, type_max);
	}
    }
  result = convert (type, expr);

  /* If the type is a array of PACK bits and the expression is an array
     constructor, then build a CONSTRUCTOR for a bitstring.  Bitstrings are
     zero based, so decrement the value of each CONSTRUCTOR element by the
     amount of the lower bound of the array.  */
  if (TREE_CODE (type) == ARRAY_TYPE && TYPE_PACKED (type)
      && TREE_CODE (result) == CONSTRUCTOR)
    {
      tree domain_min = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
      tree new_list = NULL_TREE;
      unsigned HOST_WIDE_INT index;
      tree element;

      for (element = TREE_OPERAND (result, 1);
	   element != NULL_TREE;
	   element = TREE_CHAIN (element))
	{
	  if (!tree_int_cst_equal (TREE_VALUE (element), integer_zero_node))
	    {
	      tree purpose = TREE_PURPOSE (element);
	      switch (TREE_CODE (purpose))
		{
		case INTEGER_CST:
		  new_list
		    = tree_cons (NULL_TREE,
				 fold (build (MINUS_EXPR, TREE_TYPE (purpose),
					      purpose, domain_min)),
				 new_list);
		  break;
		case RANGE_EXPR:
		  for (index = TREE_INT_CST_LOW (TREE_OPERAND (purpose, 0));
		       index <= TREE_INT_CST_LOW (TREE_OPERAND (purpose, 1));
		       index++)
		    new_list = tree_cons (NULL_TREE,
					  fold (build (MINUS_EXPR,
						       integer_type_node,
						       build_int_2 (index, 0),
						       domain_min)),
					  new_list);
		  break;
		default:
		  abort ();
		}
	    }
	}
      result = copy_node (result);
      TREE_OPERAND (result, 1) = nreverse (new_list);
      TREE_TYPE (result) = build_bitstring_type (TYPE_SIZE (type));
    }

  return result;
}

/* Check that EXPR has valid type for a RETURN or RESULT expression,
   converting to the right type.  ACTION is "RESULT" or "RETURN". */

static tree
adjust_return_value (expr, action)
     tree expr;
     const char *action;
{
  tree type = TREE_TYPE (TREE_TYPE (current_function_decl));

  if (TREE_CODE (type) == REFERENCE_TYPE)
    {
      if (CH_LOCATION_P (expr))
	{
	  if (! CH_READ_COMPATIBLE (TREE_TYPE (type), 
				    TREE_TYPE (expr)))
	    {
	      error ("mode mismatch in %s expression", action);
	      return error_mark_node;
	    }
	  return convert (type, expr);
	}
      else
	{
	  error ("%s expression must be referable", action);
	  return error_mark_node;
	}
    }
  else if (! CH_COMPATIBLE (expr, type))
    {
      error ("mode mismatch in %s expression", action);
      return error_mark_node;
    }
  return convert (type, expr);
}

void
chill_expand_result (expr, result_or_return)
     tree expr;
     int result_or_return;
{
  tree type;
  const char *action_name = result_or_return ? "RESULT" : "RETURN";
  
  if (pass == 1)
    return;

  if (expr == NULL_TREE || TREE_CODE (expr) == ERROR_MARK)
    return;

  CH_FUNCTION_SETS_RESULT (current_function_decl) = 1;

  if (chill_at_module_level || global_bindings_p ())
    error ("%s not allowed outside a PROC", action_name);

  result_never_set = 0;

  if (chill_result_decl == NULL_TREE)
    {
      error ("%s action in PROC with no declared RESULTS", action_name);
      return;
    }
  type = TREE_TYPE (chill_result_decl);

  if (TREE_CODE (type) == ERROR_MARK)
    return;

  expr = adjust_return_value (expr, action_name);

  expand_expr_stmt (build_chill_modify_expr (chill_result_decl, expr));
}

/*
 * error if EXPR not NULL and procedure doesn't
 * have a return type; 
 * warning if EXPR NULL,
 * procedure *has* a return type, and a previous
 * RESULT actions hasn't saved a return value.
 */
void
chill_expand_return (expr, implicit)
     tree expr;
     int implicit; /* 1 if an implicit return at end of function. */
{
  tree valtype;

  if (expr != NULL_TREE && TREE_CODE (expr) == ERROR_MARK)
    return;
  if (chill_at_module_level || global_bindings_p ())
    {
      error ("RETURN not allowed outside PROC");
      return;
    }

  if (pass == 1)
    return;

  result_never_set = 0;

  valtype = TREE_TYPE (TREE_TYPE (current_function_decl));
  if (TREE_CODE (valtype) == VOID_TYPE)
    {
      if (expr != NULL_TREE)
	error ("RETURN with a value, in PROC returning void");
      expand_null_return ();
    }
  else if (TREE_CODE (valtype) != ERROR_MARK)
    {
      if (expr == NULL_TREE)
	{
	  if (!CH_FUNCTION_SETS_RESULT (current_function_decl)
	      && !implicit)
	    warning ("RETURN with no value and no RESULT action in procedure");
	  expr = chill_result_decl;
	}
      else
	expr = adjust_return_value (expr, "RETURN");
      expr = build (MODIFY_EXPR, valtype,
		    DECL_RESULT (current_function_decl),
		    expr);
      TREE_SIDE_EFFECTS (expr) = 1;
      expand_return (expr);
    }
}

void
lookup_and_expand_goto (name)
     tree name;
{
  if (name == NULL_TREE ||  TREE_CODE (name) == ERROR_MARK)
    return;
  if (!ignoring)
    {
      tree decl = lookup_name (name);
      if (decl == NULL || TREE_CODE (decl) != LABEL_DECL)
	error ("no label named `%s'", IDENTIFIER_POINTER (name));
      else if (DECL_CONTEXT (decl) != current_function_decl)
	error ("cannot GOTO label `%s' outside current function",
	       IDENTIFIER_POINTER (name));
      else
	{
	  TREE_USED (decl) = 1;
	  expand_goto_except_cleanup (DECL_ACTION_NESTING_LEVEL (decl));
	  expand_goto (decl);
	}
    }
}

void
lookup_and_handle_exit (name)
     tree name;
{
  if (name == NULL_TREE ||  TREE_CODE (name) == ERROR_MARK)
    return;
  if (!ignoring)
    {
      tree label = munge_exit_label (name);
      tree decl = lookup_name (label);
      if (decl == NULL || TREE_CODE (decl) != LABEL_DECL)
	error ("no EXITable label named `%s'", IDENTIFIER_POINTER (name));
      else if (DECL_CONTEXT (decl) != current_function_decl)
	error ("cannot EXIT label `%s' outside current function",
	       IDENTIFIER_POINTER (name));
      else
	{
	  TREE_USED (decl) = 1;
	  expand_goto_except_cleanup (DECL_ACTION_NESTING_LEVEL (decl));
	  expand_goto (decl);
	}
    }
}

/* ELSE-range handling: The else-range is a chain of trees which collectively
   represent the ranges to be tested for the (ELSE) case label. Each element in
   the chain represents a range to be tested. The boundaries of the range are
   represented by INTEGER_CST trees in the PURPOSE and VALUE fields. */

/* This function updates the else-range by removing the given integer constant. */
static tree
update_else_range_for_int_const (else_range, label)
     tree else_range, label;
{
  int  lowval = 0, highval = 0;
  int  label_value = TREE_INT_CST_LOW (label);
  tree this_range, prev_range, new_range;

  /* First, find the range element containing the integer, if it exists. */
  prev_range = NULL_TREE;
  for (this_range = else_range ;
       this_range != NULL_TREE;
       this_range = TREE_CHAIN (this_range))
    {
      lowval  = TREE_INT_CST_LOW (TREE_PURPOSE (this_range));
      highval = TREE_INT_CST_LOW (TREE_VALUE (this_range));
      if (label_value >= lowval && label_value <= highval)
	break;
      prev_range = this_range;
    }

  /* If a range element containing the integer was found, then update the range. */
  if (this_range != NULL_TREE)
    {
      tree next = TREE_CHAIN (this_range);
      if (label_value == lowval)
	{
	  /* The integer is the lower bound of the range element. If it is also the
	     upper bound, then remove this range element, otherwise update it. */
	  if (label_value == highval)
	    {
	      if (prev_range == NULL_TREE)
		else_range = next;
	      else
		TREE_CHAIN (prev_range) = next;
	    }
	  else
	    TREE_PURPOSE (this_range) = build_int_2 (label_value + 1, 0);
	}
      else if (label_value == highval)
	{
	  /* The integer is the upper bound of the range element, so ajust it. */
	  TREE_VALUE (this_range) = build_int_2 (label_value - 1, 0);
	}
      else
	{
	  /* The integer is in the middle of the range element, so split it. */
	  new_range = tree_cons (
            build_int_2 (label_value + 1, 0), TREE_VALUE (this_range), next);
	  TREE_VALUE (this_range) = build_int_2 (label_value - 1, 0);
	  TREE_CHAIN (this_range) = new_range;
	}
    }
  return else_range;
}

/* Update the else-range to remove a range of values/ */
static tree
update_else_range_for_range (else_range, low_target, high_target)
     tree else_range, low_target, high_target;
{
  tree this_range, prev_range, new_range, next_range;
  int  low_range_val = 0, high_range_val = 0;
  int  low_target_val  = TREE_INT_CST_LOW (low_target);
  int  high_target_val = TREE_INT_CST_LOW (high_target);

  /* find the first else-range element which overlaps the target range. */
  prev_range = NULL_TREE;
  for (this_range = else_range ;
       this_range != NULL_TREE;
       this_range = TREE_CHAIN (this_range))
    {
      low_range_val  = TREE_INT_CST_LOW (TREE_PURPOSE (this_range));
      high_range_val = TREE_INT_CST_LOW (TREE_VALUE (this_range));
      if ((low_target_val >= low_range_val && low_target_val <= high_range_val)
	  || (high_target_val >= low_range_val && high_target_val <= high_range_val))
	break;
      prev_range = this_range;
    }
  if (this_range == NULL_TREE)
    return else_range;

  /* This first else-range element might be truncated at the top or completely
     contain the target range. */
  if (low_range_val < low_target_val)
    {
      next_range = TREE_CHAIN (this_range);
      if (high_range_val > high_target_val)
	{
	  new_range = tree_cons (
            build_int_2 (high_target_val + 1, 0), TREE_VALUE (this_range), next_range);
	  TREE_VALUE (this_range) = build_int_2 (low_target_val - 1, 0);
	  TREE_CHAIN (this_range) = new_range;
	  return else_range;
	}

      TREE_VALUE (this_range) = build_int_2 (low_target_val - 1, 0);
      if (next_range == NULL_TREE)
	return else_range;

      prev_range = this_range;
      this_range = next_range;
      high_range_val = TREE_INT_CST_LOW (TREE_VALUE (this_range));
    }

  /* There may then follow zero or more else-range elements which are completely
     contained in the target range. */
  while (high_range_val <= high_target_val)
    {
      this_range = TREE_CHAIN (this_range);
      if (prev_range == NULL_TREE)
	else_range = this_range;
      else
	TREE_CHAIN (prev_range) = this_range;

      if (this_range == NULL_TREE)
	return else_range;
      high_range_val = TREE_INT_CST_LOW (TREE_VALUE (this_range));
    }

  /* Finally, there may be a else-range element which is truncated at the bottom. */
  low_range_val = TREE_INT_CST_LOW (TREE_PURPOSE (this_range));
  if (low_range_val <= high_target_val)
    TREE_PURPOSE (this_range) = build_int_2 (high_target_val + 1, 0);

  return else_range;
}

static tree
update_else_range_for_range_expr (else_range, label)
     tree else_range, label;
{
  if (TREE_OPERAND (label, 0) == NULL_TREE)
    {
      if (TREE_OPERAND (label, 1) == NULL_TREE)
	else_range = NULL_TREE; /* (*) -- matches everything */
    }
  else
    else_range = update_else_range_for_range (
      else_range, TREE_OPERAND (label, 0), TREE_OPERAND (label, 1));

  return else_range;
}

static tree
update_else_range_for_type (else_range, label)
     tree else_range, label;
{
  tree type = TREE_TYPE (label);
  else_range = update_else_range_for_range (
    else_range, TYPE_MIN_VALUE (type), TYPE_MAX_VALUE (type));
  return else_range;
}

static tree
compute_else_range (selector, alternatives, selector_no)
     tree selector, alternatives;
     int selector_no;
{
  /* Start with an else-range that spans the entire range of the selector type. */
  tree type = TREE_TYPE (TREE_VALUE (selector));
  tree range = tree_cons (TYPE_MIN_VALUE (type), TYPE_MAX_VALUE (type), NULL_TREE);

  /* Now remove the values represented by each case lebel specified for that
     selector. The remaining range is the else-range. */
  for ( ; alternatives != NULL_TREE; alternatives = TREE_CHAIN (alternatives))
    {
      tree label;
      tree label_list = TREE_PURPOSE (alternatives);
      int  this_selector;
      for (this_selector = 0; this_selector < selector_no ; ++this_selector)
	label_list = TREE_CHAIN (label_list);

      for (label = TREE_VALUE (label_list);
	   label != NULL_TREE;
	   label = TREE_CHAIN (label))
	{
	  tree label_value = TREE_VALUE (label);
	  if (TREE_CODE (label_value) == INTEGER_CST)
	    range = update_else_range_for_int_const (range, label_value);
	  else if (TREE_CODE (label_value) == RANGE_EXPR)
	    range = update_else_range_for_range_expr (range, label_value);
	  else if (TREE_CODE (label_value) == TYPE_DECL)
	    range = update_else_range_for_type (range, label_value);

	  if (range == NULL_TREE)
	    break;
	}
    }

  return range;
}

void
compute_else_ranges (selectors, alternatives)
     tree selectors, alternatives;
{
  tree selector;
  int selector_no = 0;

  for (selector = selectors; selector != NULL_TREE; selector = TREE_CHAIN (selector))
    {
      if (ELSE_LABEL_SPECIFIED (selector))
	TREE_PURPOSE (selector) =
	  compute_else_range (selector, alternatives, selector_no);
      selector_no++;
    }
}

static tree
check_case_value (label_value, selector)
     tree label_value, selector;
{
  if (TREE_CODE (label_value) == ERROR_MARK)
    return label_value;
  if (TREE_CODE (selector) == ERROR_MARK)
    return selector;    

  /* Z.200 (6.4 Case action) says:  "The class of any discrete expression
     in the case selector list must be compatible with the corresponding
     (by position) class of the resulting list of classes of the case label
     list occurrences ...".  We don't actually construct the resulting
     list of classes, but this test should be more-or-less equivalent.
     I think... */
  if (!CH_COMPATIBLE_CLASSES (selector, label_value))
    {
      error ("case selector not compatible with label");
      return error_mark_node;
    }

  /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
  STRIP_TYPE_NOPS (label_value);

  if (TREE_CODE (label_value) != INTEGER_CST)
    {
      error ("case label does not reduce to an integer constant");
      return error_mark_node;
    }

  constant_expression_warning (label_value);
  return label_value;
}

void
chill_handle_case_default ()
{
  tree duplicate;
  register tree label = build_decl (LABEL_DECL, NULL_TREE, 
				    NULL_TREE);
  int success = pushcase (NULL_TREE, 0, label, &duplicate);

  if (success == 1)
    error ("ELSE label not within a CASE statement");
#if 0
  else if (success == 2)
    {
      error ("multiple default labels found in a CASE statement"); 
      error_with_decl (duplicate, "this is the first ELSE label");
    }
#endif
}

/* Handle cases label such as (I:J):  or (modename): */

static void
chill_handle_case_label_range (min_value, max_value, selector)
     tree min_value, max_value, selector;
{
  register tree label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
  min_value = check_case_value (min_value, selector);
  max_value = check_case_value (max_value, selector);
  if (TREE_CODE (min_value) != ERROR_MARK
      && TREE_CODE (max_value) != ERROR_MARK)
    {
      tree duplicate;
      int success = pushcase_range (min_value, max_value,
				    convert, label, &duplicate);
      if (success == 1)
	error ("label found outside of CASE statement");
      else if (success == 2)
	{
	  error ("duplicate CASE value");
	  error_with_decl (duplicate, "this is the first entry for that value");
	}
      else if (success == 3)
	error ("CASE value out of range");
      else if (success == 4)
	error ("empty range");
      else if (success == 5)
	error ("label within scope of cleanup or variable array");
    }
}

void
chill_handle_case_label (label_value, selector)
     tree label_value, selector;
{
  if (label_value == NULL_TREE 
      || TREE_CODE (label_value) == ERROR_MARK)
    return;
  if (TREE_CODE (label_value) == RANGE_EXPR)
    {
      if (TREE_OPERAND (label_value, 0) == NULL_TREE)
	chill_handle_case_default ();  /* i.e. (ELSE): or (*): */
      else
	chill_handle_case_label_range (TREE_OPERAND (label_value, 0),
				       TREE_OPERAND (label_value, 1),
				       selector);
    }
  else if (TREE_CODE (label_value) == TYPE_DECL)
    {
      tree type = TREE_TYPE (label_value);
      if (! discrete_type_p (type))
	error ("mode in label is not discrete");
      else
	chill_handle_case_label_range (TYPE_MIN_VALUE (type),
				       TYPE_MAX_VALUE (type),
				       selector);
    }
  else
    {
      register tree label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);

      label_value = check_case_value (label_value, selector);

      if (TREE_CODE (label_value) != ERROR_MARK)
	{
	  tree duplicate;
	  int success = pushcase (label_value, convert, label, &duplicate);
	  if (success == 1)
	    error ("label not within a CASE statement");
	  else if (success == 2)
	    {
	      error ("duplicate case value");
	      error_with_decl (duplicate, 
			       "this is the first entry for that value");
	    }
	  else if (success == 3)
	    error ("CASE value out of range");
	  else if (success == 4)
	    error ("empty range");
	  else if (success == 5)
	    error ("label within scope of cleanup or variable array");
        }
    }
}

int
chill_handle_single_dimension_case_label (
  selector, label_spec, expand_exit_needed, caseaction_flag
)
  tree selector, label_spec;
  int *expand_exit_needed, *caseaction_flag;
{
  tree labels, one_label;
  int  no_completeness_check = 0;

  if (*expand_exit_needed || *caseaction_flag == 1)
    {
      expand_exit_something ();
      *expand_exit_needed = 0;
    }

  for (labels = label_spec; labels != NULL_TREE; labels = TREE_CHAIN (labels))
    for (one_label = TREE_VALUE (labels); one_label != NULL_TREE;
         one_label = TREE_CHAIN (one_label))
      {
        if (TREE_VALUE (one_label) == case_else_node)
          no_completeness_check = 1;

        chill_handle_case_label (TREE_VALUE (one_label), selector);
      }

  *caseaction_flag = 1;

  return no_completeness_check;
}

static tree
chill_handle_multi_case_label_range (low, high, selector)
  tree low, high, selector;
{
  tree low_expr, high_expr, and_expr;
  tree selector_type;
  int  low_target_val, high_target_val;
  int  low_type_val, high_type_val;

  /* we can eliminate some tests is the low and/or high value in the given range
     are outside the range of the selector type. */
  low_target_val  = TREE_INT_CST_LOW (low);
  high_target_val = TREE_INT_CST_LOW (high);
  selector_type   = TREE_TYPE (selector);
  low_type_val    = TREE_INT_CST_LOW (TYPE_MIN_VALUE (selector_type));
  high_type_val   = TREE_INT_CST_LOW (TYPE_MAX_VALUE (selector_type));

  if (low_target_val > high_type_val || high_target_val < low_type_val)
    return boolean_false_node; /* selector never in range */

  if (low_type_val >= low_target_val)
    {
      if (high_type_val <= high_target_val)
	return boolean_true_node; /* always in the range */
      return build_compare_expr (LE_EXPR, selector, high);
    }

  if (high_type_val <= high_target_val)
    return build_compare_expr (GE_EXPR, selector, low);

  /* The target range in completely within the range of the selector, but we
     might be able to save a test if the upper bound is the same as the lower
     bound. */
  if (low_target_val == high_target_val)
    return build_compare_expr (EQ_EXPR, selector, low);

  /* No optimizations possible. Just generate tests against the upper and lower
     bound of the target */
  low_expr  = build_compare_expr (GE_EXPR, selector, low);
  high_expr = build_compare_expr (LE_EXPR, selector, high);
  and_expr  = build_chill_binary_op (TRUTH_ANDIF_EXPR, low_expr, high_expr);

  return and_expr;
}

static tree
chill_handle_multi_case_else_label (selector)
     tree selector;
{
  tree else_range, selector_value, selector_type;
  tree low, high, larg;

  else_range = TREE_PURPOSE (selector);
  if (else_range == NULL_TREE)
    return boolean_false_node; /* no values in ELSE range */

  /* Test each of the ranges in the else-range chain */
  selector_value = TREE_VALUE (selector);
  selector_type  = TREE_TYPE (selector_value);
  low  = convert (selector_type, TREE_PURPOSE (else_range));
  high = convert (selector_type, TREE_VALUE (else_range));
  larg = chill_handle_multi_case_label_range (low, high, selector_value);

  for (else_range = TREE_CHAIN (else_range);
       else_range != NULL_TREE;
       else_range = TREE_CHAIN (else_range))
    {
      tree rarg;
      low  = convert (selector_type, TREE_PURPOSE (else_range));
      high = convert (selector_type, TREE_VALUE (else_range));
      rarg = chill_handle_multi_case_label_range (low, high, selector_value);
      larg = build_chill_binary_op (TRUTH_ORIF_EXPR, larg, rarg);
    }

  return larg;
}

static tree
chill_handle_multi_case_label (selector, label)
  tree selector, label;
{
  tree expr = NULL_TREE;

  if (label == NULL_TREE || TREE_CODE (label) == ERROR_MARK)
    return NULL_TREE;

  if (TREE_CODE (label) == INTEGER_CST)
    {
      int  target_val = TREE_INT_CST_LOW (label);
      tree selector_type = TREE_TYPE (TREE_VALUE (selector));
      int  low_type_val  = TREE_INT_CST_LOW (TYPE_MIN_VALUE (selector_type));
      int  high_type_val = TREE_INT_CST_LOW (TYPE_MAX_VALUE (selector_type));
      if (target_val < low_type_val || target_val > high_type_val)
	expr = boolean_false_node;
      else
	expr = build_compare_expr (EQ_EXPR, TREE_VALUE (selector), label);
    }
  else if (TREE_CODE (label) == RANGE_EXPR)
    {
      if (TREE_OPERAND (label, 0) == NULL_TREE)
	{
	  if (TREE_OPERAND (label, 1) == NULL_TREE)
	    expr = boolean_true_node; /* (*) -- matches everything */
	  else
	    expr = chill_handle_multi_case_else_label (selector);
	}
      else
	{
	  tree low = TREE_OPERAND (label, 0);
	  tree high = TREE_OPERAND (label, 1);
	  if (TREE_CODE (low) != INTEGER_CST)
	    {
	      error ("lower bound of range must be a discrete literal expression");
	      expr = error_mark_node;
	    }
	  if (TREE_CODE (high) != INTEGER_CST)
	    {
	      error ("upper bound of range must be a discrete literal expression");
	      expr = error_mark_node;
	    }
	  if (expr != error_mark_node)
	    {
	      expr = chill_handle_multi_case_label_range (
                       low, high, TREE_VALUE (selector));
	    }
	}
    }
  else if (TREE_CODE (label) == TYPE_DECL)
    {
      tree type = TREE_TYPE (label);
      if (! discrete_type_p (type))
	{
	  error ("mode in label is not discrete");
	  expr = error_mark_node;
	}
      else
	expr = chill_handle_multi_case_label_range (
		 TYPE_MIN_VALUE (type), TYPE_MAX_VALUE (type), TREE_VALUE (selector));
    }
  else
    {
      error ("CASE label is not valid");
      expr = error_mark_node;
    }

  return expr;
}

static tree
chill_handle_multi_case_label_list (selector, labels)
  tree selector, labels;
{
  tree one_label, larg, rarg;

  one_label = TREE_VALUE (labels);
  larg = chill_handle_multi_case_label (selector, TREE_VALUE (one_label));

  for (one_label = TREE_CHAIN (one_label);
       one_label != NULL_TREE;
       one_label = TREE_CHAIN (one_label))
    {
      rarg = chill_handle_multi_case_label (selector, TREE_VALUE (one_label));
      larg = build_chill_binary_op (TRUTH_ORIF_EXPR, larg, rarg);
    }

  return larg;
}

tree
build_multi_case_selector_expression (selector_list, label_spec)
  tree selector_list, label_spec;
{
  tree labels, selector, larg, rarg;

  labels   = label_spec;
  selector = selector_list;
  larg = chill_handle_multi_case_label_list(selector, labels);

  for (labels = TREE_CHAIN (labels), selector = TREE_CHAIN (selector);
       labels != NULL_TREE && selector != NULL_TREE;
       labels = TREE_CHAIN (labels), selector = TREE_CHAIN (selector))
    {
      rarg = chill_handle_multi_case_label_list(selector, labels);
      larg = build_chill_binary_op (TRUTH_ANDIF_EXPR, larg, rarg);
    }

  if (labels != NULL_TREE || selector != NULL_TREE)
    error ("number of CASE selectors does not match the number of CASE label lists");

  return larg;
}

#define BITARRAY_TEST(ARRAY, INDEX) \
  ((ARRAY)[(unsigned)(INDEX) / HOST_BITS_PER_CHAR]\
			  & (1 << ((unsigned)(INDEX) % HOST_BITS_PER_CHAR)))
#define BITARRAY_SET(ARRAY, INDEX) \
  ((ARRAY)[(unsigned)(INDEX) / HOST_BITS_PER_CHAR]\
			  |= 1 << ((unsigned)(INDEX) % HOST_BITS_PER_CHAR))

/* CASES_SEEN is a set (bitarray) of length COUNT.
   For each element that is zero, print an error message,
   assume the element have the given TYPE. */

static void
print_missing_cases (type, cases_seen, count)
     tree type;
     const unsigned char *cases_seen;
     long count;
{
  long i;
  for (i = 0;  i < count; i++)
    {
      if (BITARRAY_TEST(cases_seen, i) == 0)
	{
	  char buf[20];
	  long x = i;
	  long j;
	  tree t = type;
	  const char *err_val_name = "???";
	  if (TYPE_MIN_VALUE (t)
	      && TREE_CODE (TYPE_MIN_VALUE (t)) == INTEGER_CST)
	    x += TREE_INT_CST_LOW (TYPE_MIN_VALUE (t));
	  while (TREE_TYPE (t) != NULL_TREE)
	    t = TREE_TYPE (t);
	  switch (TREE_CODE (t))
	    {
	      tree v;
	    case BOOLEAN_TYPE:
	      err_val_name = x ? "TRUE" : "FALSE";
	      break;
	    case CHAR_TYPE:
	      {
		char *bufptr;
		if ((x >= ' ' && x < 127) && x != '\'' && x != '^')
		  sprintf (buf, "'%c'", (char)x);
		else
		  sprintf (buf, "'^(%ld)'", x);
		bufptr = buf;
		j = i;
		while (j < count && !BITARRAY_TEST(cases_seen, j))
		  j++;
		if (j > i + 1)
		  {
		    long y = x+j-i-1;
		    bufptr += strlen (bufptr);
		    if ((y >= ' ' && y < 127) && y != '\'' && y != '^')
		      sprintf (bufptr, "%s:'%c'", buf, (char)y);
		    else
		      sprintf (bufptr, "%s:'^(%ld)'", buf, y);
		    i = j - 1;      
		  }
		err_val_name = bufptr;
	      }
	      break;
	    case ENUMERAL_TYPE:
	      for (v = TYPE_VALUES (t);  v && x;  v = TREE_CHAIN (v))
		x--;
	      if (v)
		err_val_name = IDENTIFIER_POINTER (TREE_PURPOSE (v));
	      break;
	    default:
	      j = i;
	      while (j < count && !BITARRAY_TEST(cases_seen, j))
		j++;
	      if (j == i + 1)
		sprintf (buf, "%ld", x);
	      else
		sprintf (buf, "%ld:%ld", x, x+j-i-1);
	      i = j - 1;      
	      err_val_name = buf;
	      break;
	    }
	  error ("incomplete CASE - %s not handled", err_val_name);
	}
    }
}

void
check_missing_cases (type)
     tree type;
{
  int is_sparse;
  /* For each possible selector value. a one iff it has been matched
     by a case value alternative. */
  unsigned char *cases_seen;
  /* The number of possible selector values. */
  HOST_WIDE_INT size = all_cases_count (type, &is_sparse);
  HOST_WIDE_INT bytes_needed
    = (size + HOST_BITS_PER_CHAR) / HOST_BITS_PER_CHAR;

  if (size == -1)
    warning ("CASE selector with variable range");
  else if (size < 0 || size > 600000
	   /* We deliberately use malloc here - not xmalloc. */
	   || (cases_seen = (char*) malloc (bytes_needed)) == NULL)
    warning ("too many cases to do CASE completeness testing");
  else
    {
      memset (cases_seen, 0, bytes_needed);
      mark_seen_cases (type, cases_seen, size, is_sparse);
      print_missing_cases (type, cases_seen, size);
      free (cases_seen);
    }
}

/*
 * We build an expression tree here because, in many contexts,
 * we don't know the type of result that's desired.  By the
 * time we get to expanding the tree, we do know.
 */
tree
build_chill_case_expr (exprlist, casealtlist_expr,
		       optelsecase_expr)
     tree exprlist, casealtlist_expr, optelsecase_expr;
{
  return build (CASE_EXPR, NULL_TREE, exprlist,
		optelsecase_expr ?
		  tree_cons (NULL_TREE,
			     optelsecase_expr,
			     casealtlist_expr) :
		  casealtlist_expr);
}

/* This function transforms the selector_list and alternatives into a COND_EXPR. */
tree
build_chill_multi_dimension_case_expr (selector_list, alternatives, else_expr)
  tree selector_list, alternatives, else_expr;
{
  tree expr;

  selector_list = check_case_selector_list (selector_list);

  if (alternatives == NULL_TREE)
    return NULL_TREE;

  alternatives = nreverse (alternatives);
  /* alternatives represents the CASE label specifications and resulting values in
     the reverse order in which they appeared.
     If there is an ELSE expression, then use it. If there is no
     ELSE expression, make the last alternative (which is the first in the list)
     into the ELSE expression. This is safe because, if the CASE is complete
     (as required), then the last condition need not be checked anyway. */
  if (else_expr != NULL_TREE)
    expr = else_expr;
  else
    {
      expr = TREE_VALUE (alternatives);
      alternatives = TREE_CHAIN (alternatives);
    }

  for ( ; alternatives != NULL_TREE; alternatives = TREE_CHAIN (alternatives))
    { 
      tree value  = TREE_VALUE (alternatives);
      tree labels = TREE_PURPOSE (alternatives);
      tree cond   = build_multi_case_selector_expression(selector_list, labels);
      expr = build_nt (COND_EXPR, cond, value, expr);
    }

  return expr;
}


/* This is called with the assumption that RHS has been stabilized.  
   It has one purpose:  to iterate through the CHILL list of LHS's */
void
expand_assignment_action (loclist, modifycode, rhs)
     tree loclist;
     enum chill_tree_code modifycode;
     tree rhs;
{
  if (loclist == NULL_TREE || TREE_CODE (loclist) == ERROR_MARK
      || rhs == NULL_TREE  || TREE_CODE (rhs) == ERROR_MARK)
    return;

  if (TREE_CHAIN (loclist) != NULL_TREE)
    { /* Multiple assignment */
      tree target;
      if (TREE_TYPE (rhs) != NULL_TREE)
	rhs = save_expr (rhs);
      else if (TREE_CODE (rhs) == CONSTRUCTOR)
	error ("type of tuple cannot be implicit in multiple assignent");
      else if (TREE_CODE (rhs) == CASE_EXPR || TREE_CODE (rhs) == COND_EXPR)
	error ("conditional expression cannot be used in multiple assignent");
      else
	error ("internal error - unknown type in multiple assignment");

      if (modifycode != NOP_EXPR)
	{
	  error ("no operator allowed in multiple assignment,");
	  modifycode = NOP_EXPR;
	}

      for (target = TREE_CHAIN (loclist); target; target = TREE_CHAIN (target))
	{
	  if (!CH_EQUIVALENT (TREE_TYPE (TREE_VALUE (target)),
			      TREE_TYPE (TREE_VALUE (loclist))))
	    {
	      error
		("location modes in multiple assignment are not equivalent");
	      break;
	    }
	}
    }
  for ( ; loclist != NULL_TREE; loclist = TREE_CHAIN (loclist))
    chill_expand_assignment (TREE_VALUE (loclist), modifycode, rhs);
}

void
chill_expand_assignment (lhs, modifycode, rhs)
     tree lhs;
     enum chill_tree_code modifycode;
     tree rhs;
{
  tree loc;

  while (TREE_CODE (lhs) == COMPOUND_EXPR)
    {
      expand_expr (TREE_OPERAND (lhs, 0), const0_rtx, VOIDmode, 0);
      emit_queue ();
      lhs = TREE_OPERAND (lhs, 1);
    }

  if (TREE_CODE (lhs) == ERROR_MARK)
    return;

  /* errors for assignment to BUFFER, EVENT locations.
     what about SIGNALs? FIXME: Need similar test in
     build_chill_function_call. */
  if (TREE_CODE (lhs) == IDENTIFIER_NODE)
    {
      tree decl = lookup_name (lhs);
      if (decl)
	{
	  tree type = TREE_TYPE (decl);
	  if (CH_IS_BUFFER_MODE (type) || CH_IS_EVENT_MODE (type))
	    {
	      error ("you may not assign a value to a BUFFER or EVENT location");
	      return;
	    }
	}
    }

  if (TYPE_READONLY_PROPERTY (TREE_TYPE (lhs)) || TREE_READONLY (lhs))
    {
      error ("can't assign value to READonly location");
      return;
    }
  if (CH_TYPE_NONVALUE_P (TREE_TYPE (lhs)))
    {
      error ("cannot assign to location with non-value property");
      return;
    }

  if (TREE_CODE (TREE_TYPE (lhs)) == REFERENCE_TYPE)
    lhs = convert_from_reference (lhs);

  /* check for lhs is a location */
  loc = lhs;
  while (1)
    {
      if (TREE_CODE (loc) == SLICE_EXPR)
	loc = TREE_OPERAND (loc, 0);
      else if (TREE_CODE (loc) == SET_IN_EXPR)
	loc = TREE_OPERAND (loc, 1);
      else
	break;
    }
  if (! CH_LOCATION_P (loc))
    {
      error ("lefthand side of assignment is not a location");
      return;
    }

  /* If a binary op has been requested, combine the old LHS value with
     the RHS producing the value we should actually store into the LHS. */

  if (modifycode != NOP_EXPR)
    {
      lhs = stabilize_reference (lhs);
      /* This is to handle border-line cases such
	 as: LHS OR := [I].  This seems to be permitted
	 by the letter of Z.200, though it violates
	 its spirit, since LHS:=LHS OR [I] is
	 *not* legal. */
      if (TREE_TYPE (rhs) == NULL_TREE)
	rhs = convert (TREE_TYPE (lhs), rhs);
      rhs = build_chill_binary_op (modifycode, lhs, rhs);
    }

  rhs = chill_convert_for_assignment (TREE_TYPE (lhs), rhs, "assignment");

  /* handle the LENGTH (vary_array) := expr action */
  loc = lhs;
  if (TREE_CODE (loc) == NOP_EXPR)
    loc = TREE_OPERAND (loc, 0);
  if (TREE_CODE (loc) == COMPONENT_REF
      && chill_varying_type_p (TREE_TYPE (TREE_OPERAND (loc, 0)))
      && DECL_NAME (TREE_OPERAND (loc, 1)) == var_length_id)
    {
      expand_varying_length_assignment (TREE_OPERAND (loc, 0), rhs);
    }
  else if (TREE_CODE (lhs) == SLICE_EXPR)
    {
      tree func = lookup_name (get_identifier ("__pscpy"));
      tree dst = TREE_OPERAND (lhs, 0);
      tree dst_offset = TREE_OPERAND (lhs, 1);
      tree length = TREE_OPERAND (lhs, 2);
      tree src, src_offset;
      if (TREE_CODE (rhs) == SLICE_EXPR)
	{
	  src = TREE_OPERAND (rhs, 0);
	  /* Should check that the TREE_OPERAND (src, 0) is
	     the same as length and powerserlen (src).  FIXME */
	  src_offset = TREE_OPERAND (rhs, 1);
	}
      else
	{
	  src = rhs;
	  src_offset = integer_zero_node;
	}
      expand_expr_stmt (build_chill_function_call (func,
	tree_cons (NULL_TREE, force_addr_of (dst),
	  tree_cons (NULL_TREE, powersetlen (dst),
	    tree_cons (NULL_TREE, convert (long_unsigned_type_node, dst_offset),
	      tree_cons (NULL_TREE, force_addr_of (src),
		tree_cons (NULL_TREE, powersetlen (src),
		  tree_cons (NULL_TREE, convert (long_unsigned_type_node, src_offset),
		    tree_cons (NULL_TREE, convert (long_unsigned_type_node, length),
		       NULL_TREE)))))))));
    }

  else if (TREE_CODE (lhs) == SET_IN_EXPR)
    {
      tree from_pos = save_expr (TREE_OPERAND (lhs, 0));
      tree set = TREE_OPERAND (lhs, 1);
      tree domain = TYPE_DOMAIN (TREE_TYPE (set));
      tree set_length
	= fold (build (PLUS_EXPR, integer_type_node,
		       fold (build (MINUS_EXPR, integer_type_node,
				    TYPE_MAX_VALUE (domain),
				    TYPE_MIN_VALUE (domain))),
		       integer_one_node));
      tree filename = force_addr_of (get_chill_filename());
      
      if (TREE_CODE (TREE_TYPE (lhs)) != BOOLEAN_TYPE)
	sorry("bitstring slice");
      expand_expr_stmt (
	build_chill_function_call (lookup_name (
	  get_identifier ("__setbitpowerset")),
	      tree_cons (NULL_TREE, build_chill_addr_expr (set, "powerset"),
		  tree_cons (NULL_TREE, set_length,
		    tree_cons (NULL_TREE, TYPE_MIN_VALUE (domain),
		      tree_cons (NULL_TREE, convert (long_integer_type_node, from_pos),
			tree_cons (NULL_TREE, rhs,
			  tree_cons (NULL_TREE, filename,
			    tree_cons (NULL_TREE, get_chill_linenumber(),
  			      NULL_TREE)))))))));
    }

  /* Handle arrays of packed bitfields. Currently, this is limited to bitfields
     which are 1 bit wide, so use the powerset runtime function. */
  else if (TREE_CODE (lhs) == PACKED_ARRAY_REF)
    {
      tree from_pos = save_expr (TREE_OPERAND (lhs, 1));
      tree array = TREE_OPERAND (lhs, 0);
      tree domain = TYPE_DOMAIN (TREE_TYPE (array));
      tree array_length = powersetlen (array);
      tree filename = force_addr_of (get_chill_filename());
      expand_expr_stmt (
	build_chill_function_call (lookup_name (
	  get_identifier ("__setbitpowerset")),
            tree_cons (NULL_TREE, build_chill_addr_expr (array, "packed bitfield array"),
		tree_cons (NULL_TREE, convert (long_unsigned_type_node, array_length),
		  tree_cons (NULL_TREE, convert (long_integer_type_node,
						 TYPE_MIN_VALUE (domain)),
		    tree_cons (NULL_TREE, convert (long_integer_type_node, from_pos),
		      tree_cons (NULL_TREE, build1 (CONVERT_EXPR, boolean_type_node, rhs),
			tree_cons (NULL_TREE, filename,
			  tree_cons (NULL_TREE, get_chill_linenumber(),
  			    NULL_TREE)))))))));
    }

  /* The following is probably superseded by the
     above code for SET_IN_EXPR. FIXME! */
  else if (TREE_CODE (lhs) == BIT_FIELD_REF)
    {
      tree set = TREE_OPERAND (lhs, 0);
      tree numbits = TREE_OPERAND (lhs, 1);
      tree from_pos = save_expr (TREE_OPERAND (lhs, 2));
      tree domain = TYPE_DOMAIN (TREE_TYPE (set));
      tree set_length
	= fold (build (PLUS_EXPR, integer_type_node,
		       fold (build (MINUS_EXPR, integer_type_node,
				    TYPE_MAX_VALUE (domain),
				    TYPE_MIN_VALUE (domain))),
		       integer_one_node));
      tree filename = force_addr_of (get_chill_filename());
      tree to_pos;

      switch (TREE_CODE (TREE_TYPE (rhs)))
	{
	case SET_TYPE:
	  to_pos = fold (build (MINUS_EXPR, integer_type_node,
				fold (build (PLUS_EXPR, integer_type_node,
					     from_pos, numbits)),
				integer_one_node));
	  break;
	case BOOLEAN_TYPE:
	  to_pos = from_pos;
	  break;
	default:
	  abort ();
	}
      
      if (TREE_CODE (TREE_TYPE (lhs)) != BOOLEAN_TYPE)
	sorry("bitstring slice");
      expand_expr_stmt (
	  build_chill_function_call( lookup_name (
	      get_identifier ("__setbitpowerset")),
		tree_cons (NULL_TREE, build_chill_addr_expr (set, "powerset"),
		  tree_cons (NULL_TREE, set_length,
		    tree_cons (NULL_TREE, TYPE_MIN_VALUE (domain),
		      tree_cons (NULL_TREE, from_pos,
			tree_cons (NULL_TREE, rhs,
			  tree_cons (NULL_TREE, filename,
			    tree_cons (NULL_TREE, get_chill_linenumber(),
	  		      NULL_TREE)))))))));
    }

  else
    expand_expr_stmt (build_chill_modify_expr (lhs, rhs));
}

/* Also assumes that rhs has been stabilized */
void
expand_varying_length_assignment (lhs, rhs)
     tree lhs, rhs;
{
  tree base_array, min_domain_val;

  pedwarn ("LENGTH on left-hand-side is non-portable");
      
  if (! CH_LOCATION_P (lhs))
    {
      error ("can only set LENGTH of array location");
      return;
    }

  /* cause a RANGE exception if rhs would cause a 'hole' in the array. */
  rhs = valid_array_index_p (lhs, rhs, "new array length too large", 1);

  base_array     = CH_VARYING_ARRAY_TYPE (TREE_TYPE (lhs));
  min_domain_val = TYPE_MIN_VALUE (TYPE_DOMAIN (base_array));

  lhs = build_component_ref (lhs, var_length_id);
  rhs = fold (build (MINUS_EXPR, TREE_TYPE (rhs), rhs, min_domain_val));

  expand_expr_stmt (build_chill_modify_expr (lhs, rhs));
}

void
push_action ()
{
  push_handler ();
  if (ignoring)
    return;
  emit_line_note (input_filename, lineno);
}
