/* Report error messages, build initializers, and perform
   some front-end optimizations for C++ compiler.
   Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
   1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009
   Free Software Foundation, Inc.
   Hacked by Michael Tiemann (tiemann@cygnus.com)

This file is part of GCC.

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

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

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


/* This file is part of the C++ front end.
   It contains routines to build C++ expressions given their operands,
   including computing the types of the result, C and C++ specific error
   checks, and some optimization.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "cp-tree.h"
#include "flags.h"
#include "toplev.h"
#include "output.h"
#include "diagnostic.h"
#include "real.h"

static tree
process_init_constructor (tree type, tree init);


/* Print an error message stemming from an attempt to use
   BASETYPE as a base class for TYPE.  */

tree
error_not_base_type (tree basetype, tree type)
{
  if (TREE_CODE (basetype) == FUNCTION_DECL)
    basetype = DECL_CONTEXT (basetype);
  error ("type %qT is not a base type for type %qT", basetype, type);
  return error_mark_node;
}

tree
binfo_or_else (tree base, tree type)
{
  tree binfo = lookup_base (type, base, ba_unique, NULL);

  if (binfo == error_mark_node)
    return NULL_TREE;
  else if (!binfo)
    error_not_base_type (base, type);
  return binfo;
}

/* According to ARM $7.1.6, "A `const' object may be initialized, but its
   value may not be changed thereafter.  */

void
readonly_error (tree arg, const char* string)
{
  const char *fmt;

  if (TREE_CODE (arg) == COMPONENT_REF)
    {
      if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0))))
	fmt = "%s of data-member %qD in read-only structure";
      else
	fmt = "%s of read-only data-member %qD";
      error (fmt, string, TREE_OPERAND (arg, 1));
    }
  else if (TREE_CODE (arg) == VAR_DECL)
    {
      if (DECL_LANG_SPECIFIC (arg)
	  && DECL_IN_AGGR_P (arg)
	  && !TREE_STATIC (arg))
	fmt = "%s of constant field %qD";
      else
	fmt = "%s of read-only variable %qD";
      error (fmt, string, arg);
    }
  else if (TREE_CODE (arg) == PARM_DECL)
    error ("%s of read-only parameter %qD", string, arg);
  else if (TREE_CODE (arg) == INDIRECT_REF
	   && TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 0))) == REFERENCE_TYPE
	   && (TREE_CODE (TREE_OPERAND (arg, 0)) == VAR_DECL
	       || TREE_CODE (TREE_OPERAND (arg, 0)) == PARM_DECL))
    error ("%s of read-only reference %qD", string, TREE_OPERAND (arg, 0));
  else if (TREE_CODE (arg) == RESULT_DECL)
    error ("%s of read-only named return value %qD", string, arg);
  else if (TREE_CODE (arg) == FUNCTION_DECL)
    error ("%s of function %qD", string, arg);
  else
    error ("%s of read-only location %qE", string, arg);
}


/* Structure that holds information about declarations whose type was
   incomplete and we could not check whether it was abstract or not.  */

struct pending_abstract_type GTY((chain_next ("%h.next")))
{
  /* Declaration which we are checking for abstractness. It is either
     a DECL node, or an IDENTIFIER_NODE if we do not have a full
     declaration available.  */
  tree decl;

  /* Type which will be checked for abstractness.  */
  tree type;

  /* Position of the declaration. This is only needed for IDENTIFIER_NODEs,
     because DECLs already carry locus information.  */
  location_t locus;

  /* Link to the next element in list.  */
  struct pending_abstract_type* next;
};


/* Compute the hash value of the node VAL. This function is used by the
   hash table abstract_pending_vars.  */

static hashval_t
pat_calc_hash (const void* val)
{
  const struct pending_abstract_type *pat =
     (const struct pending_abstract_type *) val;
  return (hashval_t) TYPE_UID (pat->type);
}


/* Compare node VAL1 with the type VAL2. This function is used by the
   hash table abstract_pending_vars.  */

static int
pat_compare (const void* val1, const void* val2)
{
  const struct pending_abstract_type *const pat1 =
     (const struct pending_abstract_type *) val1;
  const_tree const type2 = (const_tree)val2;

  return (pat1->type == type2);
}

/* Hash table that maintains pending_abstract_type nodes, for which we still
   need to check for type abstractness.  The key of the table is the type
   of the declaration.  */
static GTY ((param_is (struct pending_abstract_type)))
htab_t abstract_pending_vars = NULL;


/* This function is called after TYPE is completed, and will check if there
   are pending declarations for which we still need to verify the abstractness
   of TYPE, and emit a diagnostic (through abstract_virtuals_error) if TYPE
   turned out to be incomplete.  */

void
complete_type_check_abstract (tree type)
{
  void **slot;
  struct pending_abstract_type *pat;
  location_t cur_loc = input_location;

  gcc_assert (COMPLETE_TYPE_P (type));

  if (!abstract_pending_vars)
    return;

  /* Retrieve the list of pending declarations for this type.  */
  slot = htab_find_slot_with_hash (abstract_pending_vars, type,
				   (hashval_t)TYPE_UID (type), NO_INSERT);
  if (!slot)
    return;
  pat = (struct pending_abstract_type*)*slot;
  gcc_assert (pat);

  /* If the type is not abstract, do not do anything.  */
  if (CLASSTYPE_PURE_VIRTUALS (type))
    {
      struct pending_abstract_type *prev = 0, *next;

      /* Reverse the list to emit the errors in top-down order.  */
      for (; pat; pat = next)
	{
	  next = pat->next;
	  pat->next = prev;
	  prev = pat;
	}
      pat = prev;

      /* Go through the list, and call abstract_virtuals_error for each
	element: it will issue a diagnostic if the type is abstract.  */
      while (pat)
	{
	  gcc_assert (type == pat->type);

	  /* Tweak input_location so that the diagnostic appears at the correct
	    location. Notice that this is only needed if the decl is an
	    IDENTIFIER_NODE.  */
	  input_location = pat->locus;
	  abstract_virtuals_error (pat->decl, pat->type);
	  pat = pat->next;
	}
    }

  htab_clear_slot (abstract_pending_vars, slot);

  input_location = cur_loc;
}


/* If TYPE has abstract virtual functions, issue an error about trying
   to create an object of that type.  DECL is the object declared, or
   NULL_TREE if the declaration is unavailable.  Returns 1 if an error
   occurred; zero if all was well.  */

int
abstract_virtuals_error (tree decl, tree type)
{
  VEC(tree,gc) *pure;

  /* This function applies only to classes. Any other entity can never
     be abstract.  */
  if (!CLASS_TYPE_P (type))
    return 0;

  /* If the type is incomplete, we register it within a hash table,
     so that we can check again once it is completed. This makes sense
     only for objects for which we have a declaration or at least a
     name.  */
  if (!COMPLETE_TYPE_P (type))
    {
      void **slot;
      struct pending_abstract_type *pat;

      gcc_assert (!decl || DECL_P (decl)
		  || TREE_CODE (decl) == IDENTIFIER_NODE);

      if (!abstract_pending_vars)
	abstract_pending_vars = htab_create_ggc (31, &pat_calc_hash,
						&pat_compare, NULL);

      slot = htab_find_slot_with_hash (abstract_pending_vars, type,
				      (hashval_t)TYPE_UID (type), INSERT);

      pat = GGC_NEW (struct pending_abstract_type);
      pat->type = type;
      pat->decl = decl;
      pat->locus = ((decl && DECL_P (decl))
		    ? DECL_SOURCE_LOCATION (decl)
		    : input_location);

      pat->next = (struct pending_abstract_type *) *slot;
      *slot = pat;

      return 0;
    }

  if (!TYPE_SIZE (type))
    /* TYPE is being defined, and during that time
       CLASSTYPE_PURE_VIRTUALS holds the inline friends.  */
    return 0;

  pure = CLASSTYPE_PURE_VIRTUALS (type);
  if (!pure)
    return 0;

  if (decl)
    {
      if (TREE_CODE (decl) == RESULT_DECL)
	return 0;

      if (TREE_CODE (decl) == VAR_DECL)
	error ("cannot declare variable %q+D to be of abstract "
	       "type %qT", decl, type);
      else if (TREE_CODE (decl) == PARM_DECL)
	error ("cannot declare parameter %q+D to be of abstract type %qT",
	       decl, type);
      else if (TREE_CODE (decl) == FIELD_DECL)
	error ("cannot declare field %q+D to be of abstract type %qT",
	       decl, type);
      else if (TREE_CODE (decl) == FUNCTION_DECL
	       && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
	error ("invalid abstract return type for member function %q+#D", decl);
      else if (TREE_CODE (decl) == FUNCTION_DECL)
	error ("invalid abstract return type for function %q+#D", decl);
      else if (TREE_CODE (decl) == IDENTIFIER_NODE)
	/* Here we do not have location information.  */
	error ("invalid abstract type %qT for %qE", type, decl);
      else
	error ("invalid abstract type for %q+D", decl);
    }
  else
    error ("cannot allocate an object of abstract type %qT", type);

  /* Only go through this once.  */
  if (VEC_length (tree, pure))
    {
      unsigned ix;
      tree fn;

      inform (input_location, "%J  because the following virtual functions are pure "
	      "within %qT:", TYPE_MAIN_DECL (type), type);

      for (ix = 0; VEC_iterate (tree, pure, ix, fn); ix++)
	inform (input_location, "\t%+#D", fn);
      /* Now truncate the vector.  This leaves it non-null, so we know
	 there are pure virtuals, but empty so we don't list them out
	 again.  */
      VEC_truncate (tree, pure, 0);
    }
  else
    inform (input_location, "%J  since type %qT has pure virtual functions",
	    TYPE_MAIN_DECL (type), type);

  return 1;
}

/* Print an error message for invalid use of an incomplete type.
   VALUE is the expression that was used (or 0 if that isn't known)
   and TYPE is the type that was invalid.  DIAG_KIND indicates the
   type of diagnostic (see diagnostic.def).  */

void
cxx_incomplete_type_diagnostic (const_tree value, const_tree type, 
				diagnostic_t diag_kind)
{
  int decl = 0;

  gcc_assert (diag_kind == DK_WARNING 
	      || diag_kind == DK_PEDWARN 
	      || diag_kind == DK_ERROR);

  /* Avoid duplicate error message.  */
  if (TREE_CODE (type) == ERROR_MARK)
    return;

  if (value != 0 && (TREE_CODE (value) == VAR_DECL
		     || TREE_CODE (value) == PARM_DECL
		     || TREE_CODE (value) == FIELD_DECL))
    {
      emit_diagnostic (diag_kind, input_location, 0,
		       "%q+D has incomplete type", value);
      decl = 1;
    }
 retry:
  /* We must print an error message.  Be clever about what it says.  */

  switch (TREE_CODE (type))
    {
    case RECORD_TYPE:
    case UNION_TYPE:
    case ENUMERAL_TYPE:
      if (!decl)
	emit_diagnostic (diag_kind, input_location, 0,
			 "invalid use of incomplete type %q#T", type);
      if (!TYPE_TEMPLATE_INFO (type))
	emit_diagnostic (diag_kind, input_location, 0,
			 "forward declaration of %q+#T", type);
      else
	emit_diagnostic (diag_kind, input_location, 0,
			 "declaration of %q+#T", type);
      break;

    case VOID_TYPE:
      emit_diagnostic (diag_kind, input_location, 0,
		       "invalid use of %qT", type);
      break;

    case ARRAY_TYPE:
      if (TYPE_DOMAIN (type))
	{
	  type = TREE_TYPE (type);
	  goto retry;
	}
      emit_diagnostic (diag_kind, input_location, 0,
		       "invalid use of array with unspecified bounds");
      break;

    case OFFSET_TYPE:
    bad_member:
      emit_diagnostic (diag_kind, input_location, 0,
		       "invalid use of member (did you forget the %<&%> ?)");
      break;

    case TEMPLATE_TYPE_PARM:
      if (is_auto (type))
	emit_diagnostic (diag_kind, input_location, 0,
			 "invalid use of %<auto%>");
      else
	emit_diagnostic (diag_kind, input_location, 0,
			 "invalid use of template type parameter %qT", type);
      break;

    case BOUND_TEMPLATE_TEMPLATE_PARM:
      emit_diagnostic (diag_kind, input_location, 0,
		       "invalid use of template template parameter %qT",
		       TYPE_NAME (type));
      break;

    case TYPENAME_TYPE:
      emit_diagnostic (diag_kind, input_location, 0,
		       "invalid use of dependent type %qT", type);
      break;

    case UNKNOWN_TYPE:
      if (value && TREE_CODE (value) == COMPONENT_REF)
	goto bad_member;
      else if (value && TREE_CODE (value) == ADDR_EXPR)
	emit_diagnostic (diag_kind, input_location, 0,
			 "address of overloaded function with no contextual "
			 "type information");
      else if (value && TREE_CODE (value) == OVERLOAD)
	emit_diagnostic (diag_kind, input_location, 0,
			 "overloaded function with no contextual type information");
      else
	emit_diagnostic (diag_kind, input_location, 0,
			 "insufficient contextual information to determine type");
      break;

    default:
      gcc_unreachable ();
    }
}

/* Backward-compatibility interface to incomplete_type_diagnostic;
   required by ../tree.c.  */
#undef cxx_incomplete_type_error
void
cxx_incomplete_type_error (const_tree value, const_tree type)
{
  cxx_incomplete_type_diagnostic (value, type, DK_ERROR);
}


/* The recursive part of split_nonconstant_init.  DEST is an lvalue
   expression to which INIT should be assigned.  INIT is a CONSTRUCTOR.  */

static void
split_nonconstant_init_1 (tree dest, tree init)
{
  unsigned HOST_WIDE_INT idx;
  tree field_index, value;
  tree type = TREE_TYPE (dest);
  tree inner_type = NULL;
  bool array_type_p = false;

  switch (TREE_CODE (type))
    {
    case ARRAY_TYPE:
      inner_type = TREE_TYPE (type);
      array_type_p = true;
      /* FALLTHRU */

    case RECORD_TYPE:
    case UNION_TYPE:
    case QUAL_UNION_TYPE:
      FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx,
				field_index, value)
	{
	  /* The current implementation of this algorithm assumes that
	     the field was set for all the elements. This is usually done
	     by process_init_constructor.  */
	  gcc_assert (field_index);

	  if (!array_type_p)
	    inner_type = TREE_TYPE (field_index);

	  if (TREE_CODE (value) == CONSTRUCTOR)
	    {
	      tree sub;

	      if (array_type_p)
		sub = build4 (ARRAY_REF, inner_type, dest, field_index,
			      NULL_TREE, NULL_TREE);
	      else
		sub = build3 (COMPONENT_REF, inner_type, dest, field_index,
			      NULL_TREE);

	      split_nonconstant_init_1 (sub, value);
	    }
	  else if (!initializer_constant_valid_p (value, inner_type))
	    {
	      tree code;
	      tree sub;

	      /* FIXME: Ordered removal is O(1) so the whole function is
		 worst-case quadratic. This could be fixed using an aside
		 bitmap to record which elements must be removed and remove
		 them all at the same time. Or by merging
		 split_non_constant_init into process_init_constructor_array,
		 that is separating constants from non-constants while building
		 the vector.  */
	      VEC_ordered_remove (constructor_elt, CONSTRUCTOR_ELTS (init),
				  idx);
	      --idx;

	      if (array_type_p)
		sub = build4 (ARRAY_REF, inner_type, dest, field_index,
			      NULL_TREE, NULL_TREE);
	      else
		sub = build3 (COMPONENT_REF, inner_type, dest, field_index,
			      NULL_TREE);

	      code = build2 (INIT_EXPR, inner_type, sub, value);
	      code = build_stmt (EXPR_STMT, code);
	      add_stmt (code);
	      continue;
	    }
	}
      break;

    case VECTOR_TYPE:
      if (!initializer_constant_valid_p (init, type))
	{
	  tree code;
	  tree cons = copy_node (init);
	  CONSTRUCTOR_ELTS (init) = NULL;
	  code = build2 (MODIFY_EXPR, type, dest, cons);
	  code = build_stmt (EXPR_STMT, code);
	  add_stmt (code);
	}
      break;

    default:
      gcc_unreachable ();
    }

  /* The rest of the initializer is now a constant. */
  TREE_CONSTANT (init) = 1;
}

/* A subroutine of store_init_value.  Splits non-constant static
   initializer INIT into a constant part and generates code to
   perform the non-constant part of the initialization to DEST.
   Returns the code for the runtime init.  */

static tree
split_nonconstant_init (tree dest, tree init)
{
  tree code;

  if (TREE_CODE (init) == CONSTRUCTOR)
    {
      code = push_stmt_list ();
      split_nonconstant_init_1 (dest, init);
      code = pop_stmt_list (code);
      DECL_INITIAL (dest) = init;
      TREE_READONLY (dest) = 0;
    }
  else
    code = build2 (INIT_EXPR, TREE_TYPE (dest), dest, init);

  return code;
}

/* Perform appropriate conversions on the initial value of a variable,
   store it in the declaration DECL,
   and print any error messages that are appropriate.
   If the init is invalid, store an ERROR_MARK.

   C++: Note that INIT might be a TREE_LIST, which would mean that it is
   a base class initializer for some aggregate type, hopefully compatible
   with DECL.  If INIT is a single element, and DECL is an aggregate
   type, we silently convert INIT into a TREE_LIST, allowing a constructor
   to be called.

   If INIT is a TREE_LIST and there is no constructor, turn INIT
   into a CONSTRUCTOR and use standard initialization techniques.
   Perhaps a warning should be generated?

   Returns code to be executed if initialization could not be performed
   for static variable.  In that case, caller must emit the code.  */

tree
store_init_value (tree decl, tree init)
{
  tree value, type;

  /* If variable's type was invalidly declared, just ignore it.  */

  type = TREE_TYPE (decl);
  if (TREE_CODE (type) == ERROR_MARK)
    return NULL_TREE;

  if (MAYBE_CLASS_TYPE_P (type))
    {
      gcc_assert (TYPE_HAS_TRIVIAL_INIT_REF (type)
		  || TREE_CODE (init) == CONSTRUCTOR);

      if (TREE_CODE (init) == TREE_LIST)
	{
	  error ("constructor syntax used, but no constructor declared "
		 "for type %qT", type);
	  init = build_constructor_from_list (init_list_type_node, nreverse (init));
	}
    }
  else if (TREE_CODE (init) == TREE_LIST
	   && TREE_TYPE (init) != unknown_type_node)
    {
      if (TREE_CODE (decl) == RESULT_DECL)
	init = build_x_compound_expr_from_list (init,
						"return value initializer");
      else if (TREE_CODE (init) == TREE_LIST
	       && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
	{
	  error ("cannot initialize arrays using this syntax");
	  return NULL_TREE;
	}
      else
	/* We get here with code like `int a (2);' */
	init = build_x_compound_expr_from_list (init, "initializer");
    }

  /* End of special C++ code.  */

  /* Digest the specified initializer into an expression.  */
  value = digest_init (type, init);
  /* If the initializer is not a constant, fill in DECL_INITIAL with
     the bits that are constant, and then return an expression that
     will perform the dynamic initialization.  */
  if (value != error_mark_node
      && (TREE_SIDE_EFFECTS (value)
	   || ! initializer_constant_valid_p (value, TREE_TYPE (value))))
    return split_nonconstant_init (decl, value);
  /* If the value is a constant, just put it in DECL_INITIAL.  If DECL
     is an automatic variable, the middle end will turn this into a
     dynamic initialization later.  */
  DECL_INITIAL (decl) = value;
  return NULL_TREE;
}


/* Give errors about narrowing conversions within { }.  */

void
check_narrowing (tree type, tree init)
{
  tree ftype = unlowered_expr_type (init);
  bool ok = true;
  REAL_VALUE_TYPE d;
  bool was_decl = false;

  if (DECL_P (init))
    {
      was_decl = true;
      init = decl_constant_value (init);
    }

  if (TREE_CODE (type) == INTEGER_TYPE
      && TREE_CODE (ftype) == REAL_TYPE)
    ok = false;
  else if (INTEGRAL_OR_ENUMERATION_TYPE_P (ftype)
	   && CP_INTEGRAL_TYPE_P (type))
    {
      if (TYPE_PRECISION (type) < TYPE_PRECISION (ftype)
	  && (TREE_CODE (init) != INTEGER_CST
	      || !int_fits_type_p (init, type)))
	ok = false;
    }
  else if (TREE_CODE (ftype) == REAL_TYPE
	   && TREE_CODE (type) == REAL_TYPE)
    {
      if (TYPE_PRECISION (type) < TYPE_PRECISION (ftype))
	{
	  if (TREE_CODE (init) == REAL_CST)
	    {
	      /* Issue 703: Loss of precision is OK as long as the value is
		 within the representable range of the new type.  */
	      REAL_VALUE_TYPE r;
	      d = TREE_REAL_CST (init);
	      real_convert (&r, TYPE_MODE (type), &d);
	      if (real_isinf (&r))
		ok = false;
	    }
	  else
	    ok = false;
	}
    }
  else if (INTEGRAL_OR_ENUMERATION_TYPE_P (ftype)
	   && TREE_CODE (type) == REAL_TYPE)
    {
      ok = false;
      if (TREE_CODE (init) == INTEGER_CST)
	{
	  d = real_value_from_int_cst (0, init);
	  if (exact_real_truncate (TYPE_MODE (type), &d))
	    ok = true;
	}
    }

  if (!ok)
    permerror (input_location, "narrowing conversion of %qE from %qT to %qT inside { }",
	       init, ftype, type);
}

/* Process the initializer INIT for a variable of type TYPE, emitting
   diagnostics for invalid initializers and converting the initializer as
   appropriate.

   For aggregate types, it assumes that reshape_init has already run, thus the
   initializer will have the right shape (brace elision has been undone).

   NESTED is true iff we are being called for an element of a CONSTRUCTOR.  */

static tree
digest_init_r (tree type, tree init, bool nested)
{
  enum tree_code code = TREE_CODE (type);

  if (init == error_mark_node)
    return error_mark_node;

  gcc_assert (init);

  /* We must strip the outermost array type when completing the type,
     because the its bounds might be incomplete at the moment.  */
  if (!complete_type_or_else (TREE_CODE (type) == ARRAY_TYPE
			      ? TREE_TYPE (type) : type, NULL_TREE))
    return error_mark_node;

  /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue
     (g++.old-deja/g++.law/casts2.C).  */
  if (TREE_CODE (init) == NON_LVALUE_EXPR)
    init = TREE_OPERAND (init, 0);

  /* Initialization of an array of chars from a string constant. The initializer
     can be optionally enclosed in braces, but reshape_init has already removed
     them if they were present.  */
  if (code == ARRAY_TYPE)
    {
      tree typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type));
      if (char_type_p (typ1)
	  /*&& init */
	  && TREE_CODE (init) == STRING_CST)
	{
	  tree char_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (init)));

	  if (TYPE_PRECISION (typ1) == BITS_PER_UNIT)
	    {
	      if (char_type != char_type_node)
		{
		  error ("char-array initialized from wide string");
		  return error_mark_node;
		}
	    }
	  else
	    {
	      if (char_type == char_type_node)
		{
		  error ("int-array initialized from non-wide string");
		  return error_mark_node;
		}
	      else if (char_type != typ1)
		{
		  error ("int-array initialized from incompatible wide string");
		  return error_mark_node;
		}
	    }

	  TREE_TYPE (init) = type;
	  if (TYPE_DOMAIN (type) != 0 && TREE_CONSTANT (TYPE_SIZE (type)))
	    {
	      int size = TREE_INT_CST_LOW (TYPE_SIZE (type));
	      size = (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
	      /* In C it is ok to subtract 1 from the length of the string
		 because it's ok to ignore the terminating null char that is
		 counted in the length of the constant, but in C++ this would
		 be invalid.  */
	      if (size < TREE_STRING_LENGTH (init))
		permerror (input_location, "initializer-string for array of chars is too long");
	    }
	  return init;
	}
    }

  /* Handle scalar types (including conversions) and references.  */
  if ((TREE_CODE (type) != COMPLEX_TYPE
       || BRACE_ENCLOSED_INITIALIZER_P (init))
      && (SCALAR_TYPE_P (type) || code == REFERENCE_TYPE))
    {
      tree *exp;

      if (cxx_dialect != cxx98 && nested)
	check_narrowing (type, init);
      init = convert_for_initialization (0, type, init, LOOKUP_NORMAL,
					 "initialization", NULL_TREE, 0,
                                         tf_warning_or_error);
      exp = &init;

      /* Skip any conversions since we'll be outputting the underlying
	 constant.  */
      while (CONVERT_EXPR_P (*exp)
	     || TREE_CODE (*exp) == NON_LVALUE_EXPR)
	exp = &TREE_OPERAND (*exp, 0);

      *exp = cplus_expand_constant (*exp);

      return init;
    }

  /* Come here only for aggregates: records, arrays, unions, complex numbers
     and vectors.  */
  gcc_assert (TREE_CODE (type) == ARRAY_TYPE
	      || TREE_CODE (type) == VECTOR_TYPE
	      || TREE_CODE (type) == RECORD_TYPE
	      || TREE_CODE (type) == UNION_TYPE
	      || TREE_CODE (type) == COMPLEX_TYPE);

  if (BRACE_ENCLOSED_INITIALIZER_P (init)
      && !TYPE_NON_AGGREGATE_CLASS (type))
    return process_init_constructor (type, init);
  else
    {
      if (COMPOUND_LITERAL_P (init) && TREE_CODE (type) == ARRAY_TYPE)
	{
	  error ("cannot initialize aggregate of type %qT with "
		 "a compound literal", type);

	  return error_mark_node;
	}

      if (TREE_CODE (type) == ARRAY_TYPE
	  && TREE_CODE (init) != CONSTRUCTOR)
	{
	  error ("array must be initialized with a brace-enclosed"
		 " initializer");
	  return error_mark_node;
	}

      return convert_for_initialization (NULL_TREE, type, init,
					 LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING,
					 "initialization", NULL_TREE, 0,
                                         tf_warning_or_error);
    }
}

tree
digest_init (tree type, tree init)
{
  return digest_init_r (type, init, false);
}

/* Set of flags used within process_init_constructor to describe the
   initializers.  */
#define PICFLAG_ERRONEOUS 1
#define PICFLAG_NOT_ALL_CONSTANT 2
#define PICFLAG_NOT_ALL_SIMPLE 4

/* Given an initializer INIT, return the flag (PICFLAG_*) which better
   describe it.  */

static int
picflag_from_initializer (tree init)
{
  if (init == error_mark_node)
    return PICFLAG_ERRONEOUS;
  else if (!TREE_CONSTANT (init))
    return PICFLAG_NOT_ALL_CONSTANT;
  else if (!initializer_constant_valid_p (init, TREE_TYPE (init)))
    return PICFLAG_NOT_ALL_SIMPLE;
  return 0;
}

/* Subroutine of process_init_constructor, which will process an initializer
   INIT for an array or vector of type TYPE. Returns the flags (PICFLAG_*)
   which describe the initializers.  */

static int
process_init_constructor_array (tree type, tree init)
{
  unsigned HOST_WIDE_INT i, len = 0;
  int flags = 0;
  bool unbounded = false;
  constructor_elt *ce;
  VEC(constructor_elt,gc) *v = CONSTRUCTOR_ELTS (init);

  gcc_assert (TREE_CODE (type) == ARRAY_TYPE
	      || TREE_CODE (type) == VECTOR_TYPE);

  if (TREE_CODE (type) == ARRAY_TYPE)
    {
      tree domain = TYPE_DOMAIN (type);
      if (domain)
	len = (TREE_INT_CST_LOW (TYPE_MAX_VALUE (domain))
	      - TREE_INT_CST_LOW (TYPE_MIN_VALUE (domain))
	      + 1);
      else
	unbounded = true;  /* Take as many as there are.  */
    }
  else
    /* Vectors are like simple fixed-size arrays.  */
    len = TYPE_VECTOR_SUBPARTS (type);

  /* There cannot be more initializers than needed as otherwise
     reshape_init would have already rejected the initializer.  */
  if (!unbounded)
    gcc_assert (VEC_length (constructor_elt, v) <= len);

  for (i = 0; VEC_iterate (constructor_elt, v, i, ce); ++i)
    {
      if (ce->index)
	{
	  gcc_assert (TREE_CODE (ce->index) == INTEGER_CST);
	  if (compare_tree_int (ce->index, i) != 0)
	    {
	      ce->value = error_mark_node;
	      sorry ("non-trivial designated initializers not supported");
	    }
	}
      else
	ce->index = size_int (i);
      gcc_assert (ce->value);
      ce->value = digest_init_r (TREE_TYPE (type), ce->value, true);

      if (ce->value != error_mark_node)
	gcc_assert (same_type_ignoring_top_level_qualifiers_p
		      (TREE_TYPE (type), TREE_TYPE (ce->value)));

      flags |= picflag_from_initializer (ce->value);
    }

  /* No more initializers. If the array is unbounded, we are done. Otherwise,
     we must add initializers ourselves.  */
  if (!unbounded)
    for (; i < len; ++i)
      {
	tree next;

	if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (type)))
	  {
	    /* If this type needs constructors run for default-initialization,
	      we can't rely on the back end to do it for us, so build up
	      TARGET_EXPRs.  If the type in question is a class, just build
	      one up; if it's an array, recurse.  */
	    if (MAYBE_CLASS_TYPE_P (TREE_TYPE (type)))
              next = build_functional_cast (TREE_TYPE (type), NULL_TREE,
                                            tf_warning_or_error);
	    else
	      next = build_constructor (init_list_type_node, NULL);
	    next = digest_init (TREE_TYPE (type), next);
	  }
	else if (!zero_init_p (TREE_TYPE (type)))
	  next = build_zero_init (TREE_TYPE (type),
				  /*nelts=*/NULL_TREE,
				  /*static_storage_p=*/false);
	else
	  /* The default zero-initialization is fine for us; don't
	     add anything to the CONSTRUCTOR.  */
	  break;

	flags |= picflag_from_initializer (next);
	CONSTRUCTOR_APPEND_ELT (v, size_int (i), next);
      }

  CONSTRUCTOR_ELTS (init) = v;
  return flags;
}

/* Subroutine of process_init_constructor, which will process an initializer
   INIT for a class of type TYPE. Returns the flags (PICFLAG_*) which describe
   the initializers.  */

static int
process_init_constructor_record (tree type, tree init)
{
  VEC(constructor_elt,gc) *v = NULL;
  int flags = 0;
  tree field;
  unsigned HOST_WIDE_INT idx = 0;

  gcc_assert (TREE_CODE (type) == RECORD_TYPE);
  gcc_assert (!CLASSTYPE_VBASECLASSES (type));
  gcc_assert (!TYPE_BINFO (type)
	      || !BINFO_N_BASE_BINFOS (TYPE_BINFO (type)));
  gcc_assert (!TYPE_POLYMORPHIC_P (type));

  /* Generally, we will always have an index for each initializer (which is
     a FIELD_DECL, put by reshape_init), but compound literals don't go trough
     reshape_init. So we need to handle both cases.  */
  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
    {
      tree next;
      tree type;

      if (!DECL_NAME (field) && DECL_C_BIT_FIELD (field))
	{
	  flags |= picflag_from_initializer (integer_zero_node);
	  CONSTRUCTOR_APPEND_ELT (v, field, integer_zero_node);
	  continue;
	}

      if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field))
	continue;

      /* If this is a bitfield, first convert to the declared type.  */
      type = TREE_TYPE (field);
      if (DECL_BIT_FIELD_TYPE (field))
	type = DECL_BIT_FIELD_TYPE (field);

      if (idx < VEC_length (constructor_elt, CONSTRUCTOR_ELTS (init)))
	{
	  constructor_elt *ce = VEC_index (constructor_elt,
					   CONSTRUCTOR_ELTS (init), idx);
	  if (ce->index)
	    {
	      /* We can have either a FIELD_DECL or an IDENTIFIER_NODE. The
		 latter case can happen in templates where lookup has to be
		 deferred.  */
	      gcc_assert (TREE_CODE (ce->index) == FIELD_DECL
			  || TREE_CODE (ce->index) == IDENTIFIER_NODE);
	      if (ce->index != field
		  && ce->index != DECL_NAME (field))
		{
		  ce->value = error_mark_node;
		  sorry ("non-trivial designated initializers not supported");
		}
	    }

	  gcc_assert (ce->value);
	  next = digest_init_r (type, ce->value, true);
	  ++idx;
	}
      else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (field)))
	{
	  /* If this type needs constructors run for
	     default-initialization, we can't rely on the back end to do it
	     for us, so build up TARGET_EXPRs.  If the type in question is
	     a class, just build one up; if it's an array, recurse.  */
	  if (MAYBE_CLASS_TYPE_P (TREE_TYPE (field)))
	    next = build_functional_cast (TREE_TYPE (field), NULL_TREE,
                                          tf_warning_or_error);
	  else
	    next = build_constructor (init_list_type_node, NULL);

	  next = digest_init_r (TREE_TYPE (field), next, true);

	  /* Warn when some struct elements are implicitly initialized.  */
	  warning (OPT_Wmissing_field_initializers,
		   "missing initializer for member %qD", field);
	}
      else
	{
	  if (TREE_READONLY (field))
	    error ("uninitialized const member %qD", field);
	  else if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (TREE_TYPE (field)))
	    error ("member %qD with uninitialized const fields", field);
	  else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE)
	    error ("member %qD is uninitialized reference", field);

	  /* Warn when some struct elements are implicitly initialized
	     to zero.  */
	  warning (OPT_Wmissing_field_initializers,
		   "missing initializer for member %qD", field);

	  if (!zero_init_p (TREE_TYPE (field)))
	    next = build_zero_init (TREE_TYPE (field), /*nelts=*/NULL_TREE,
				    /*static_storage_p=*/false);
	  else
	    /* The default zero-initialization is fine for us; don't
	    add anything to the CONSTRUCTOR.  */
	    continue;
	}

      /* If this is a bitfield, now convert to the lowered type.  */
      if (type != TREE_TYPE (field))
	next = cp_convert_and_check (TREE_TYPE (field), next);
      flags |= picflag_from_initializer (next);
      CONSTRUCTOR_APPEND_ELT (v, field, next);
    }

  if (idx < VEC_length (constructor_elt, CONSTRUCTOR_ELTS (init)))
    error ("too many initializers for %qT", type);
    
  CONSTRUCTOR_ELTS (init) = v;
  return flags;
}

/* Subroutine of process_init_constructor, which will process a single
   initializer INIT for a union of type TYPE. Returns the flags (PICFLAG_*)
   which describe the initializer.  */

static int
process_init_constructor_union (tree type, tree init)
{
  constructor_elt *ce;
  int len;

  /* If the initializer was empty, use default zero initialization.  */
  if (VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (init)))
    return 0;

  len = VEC_length (constructor_elt, CONSTRUCTOR_ELTS (init));
  if (len > 1)
    {
      error ("too many initializers for %qT", type);
      VEC_block_remove (constructor_elt, CONSTRUCTOR_ELTS (init), 1, len-1);
    }

  ce = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (init), 0);

  /* If this element specifies a field, initialize via that field.  */
  if (ce->index)
    {
      if (TREE_CODE (ce->index) == FIELD_DECL)
	;
      else if (TREE_CODE (ce->index) == IDENTIFIER_NODE)
	{
	  /* This can happen within a cast, see g++.dg/opt/cse2.C.  */
	  tree name = ce->index;
	  tree field;
	  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
	    if (DECL_NAME (field) == name)
	      break;
	  if (!field)
	    {
	      error ("no field %qD found in union being initialized", field);
	      ce->value = error_mark_node;
	    }
	  ce->index = field;
	}
      else
	{
	  gcc_assert (TREE_CODE (ce->index) == INTEGER_CST
		      || TREE_CODE (ce->index) == RANGE_EXPR);
	  error ("index value instead of field name in union initializer");
	  ce->value = error_mark_node;
	}
    }
  else
    {
      /* Find the first named field.  ANSI decided in September 1990
	 that only named fields count here.  */
      tree field = TYPE_FIELDS (type);
      while (field && (!DECL_NAME (field) || TREE_CODE (field) != FIELD_DECL))
	field = TREE_CHAIN (field);
      if (field == NULL_TREE)
	{
	  error ("too many initializers for %qT", type);
	  ce->value = error_mark_node;
	}
      ce->index = field;
    }

  if (ce->value && ce->value != error_mark_node)
    ce->value = digest_init_r (TREE_TYPE (ce->index), ce->value, true);

  return picflag_from_initializer (ce->value);
}

/* Process INIT, a constructor for a variable of aggregate type TYPE. The
   constructor is a brace-enclosed initializer, and will be modified in-place.

   Each element is converted to the right type through digest_init, and
   missing initializers are added following the language rules (zero-padding,
   etc.).

   After the execution, the initializer will have TREE_CONSTANT if all elts are
   constant, and TREE_STATIC set if, in addition, all elts are simple enough
   constants that the assembler and linker can compute them.

   The function returns the initializer itself, or error_mark_node in case
   of error.  */

static tree
process_init_constructor (tree type, tree init)
{
  int flags;

  gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init));

  if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == VECTOR_TYPE)
    flags = process_init_constructor_array (type, init);
  else if (TREE_CODE (type) == RECORD_TYPE)
    flags = process_init_constructor_record (type, init);
  else if (TREE_CODE (type) == UNION_TYPE)
    flags = process_init_constructor_union (type, init);
  else
    gcc_unreachable ();

  if (flags & PICFLAG_ERRONEOUS)
    return error_mark_node;

  TREE_TYPE (init) = type;
  if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == NULL_TREE)
    cp_complete_array_type (&TREE_TYPE (init), init, /*do_default=*/0);
  if (!(flags & PICFLAG_NOT_ALL_CONSTANT))
    {
      TREE_CONSTANT (init) = 1;
      if (!(flags & PICFLAG_NOT_ALL_SIMPLE))
	TREE_STATIC (init) = 1;
    }
  return init;
}

/* Given a structure or union value DATUM, construct and return
   the structure or union component which results from narrowing
   that value to the base specified in BASETYPE.  For example, given the
   hierarchy

   class L { int ii; };
   class A : L { ... };
   class B : L { ... };
   class C : A, B { ... };

   and the declaration

   C x;

   then the expression

   x.A::ii refers to the ii member of the L part of
   the A part of the C object named by X.  In this case,
   DATUM would be x, and BASETYPE would be A.

   I used to think that this was nonconformant, that the standard specified
   that first we look up ii in A, then convert x to an L& and pull out the
   ii part.  But in fact, it does say that we convert x to an A&; A here
   is known as the "naming class".  (jason 2000-12-19)

   BINFO_P points to a variable initialized either to NULL_TREE or to the
   binfo for the specific base subobject we want to convert to.  */

tree
build_scoped_ref (tree datum, tree basetype, tree* binfo_p)
{
  tree binfo;

  if (datum == error_mark_node)
    return error_mark_node;
  if (*binfo_p)
    binfo = *binfo_p;
  else
    binfo = lookup_base (TREE_TYPE (datum), basetype, ba_check, NULL);

  if (!binfo || binfo == error_mark_node)
    {
      *binfo_p = NULL_TREE;
      if (!binfo)
	error_not_base_type (basetype, TREE_TYPE (datum));
      return error_mark_node;
    }

  *binfo_p = binfo;
  return build_base_path (PLUS_EXPR, datum, binfo, 1);
}

/* Build a reference to an object specified by the C++ `->' operator.
   Usually this just involves dereferencing the object, but if the
   `->' operator is overloaded, then such overloads must be
   performed until an object which does not have the `->' operator
   overloaded is found.  An error is reported when circular pointer
   delegation is detected.  */

tree
build_x_arrow (tree expr)
{
  tree orig_expr = expr;
  tree types_memoized = NULL_TREE;
  tree type = TREE_TYPE (expr);
  tree last_rval = NULL_TREE;

  if (type == error_mark_node)
    return error_mark_node;

  if (processing_template_decl)
    {
      if (type_dependent_expression_p (expr))
	return build_min_nt (ARROW_EXPR, expr);
      expr = build_non_dependent_expr (expr);
    }

  if (MAYBE_CLASS_TYPE_P (type))
    {
      while ((expr = build_new_op (COMPONENT_REF, LOOKUP_NORMAL, expr,
				   NULL_TREE, NULL_TREE,
				   /*overloaded_p=*/NULL, 
				   tf_warning_or_error)))
	{
	  if (expr == error_mark_node)
	    return error_mark_node;

	  if (value_member (TREE_TYPE (expr), types_memoized))
	    {
	      error ("circular pointer delegation detected");
	      return error_mark_node;
	    }
	  else
	    {
	      types_memoized = tree_cons (NULL_TREE, TREE_TYPE (expr),
					  types_memoized);
	    }
	  last_rval = expr;
	}

      if (last_rval == NULL_TREE)
	{
	  error ("base operand of %<->%> has non-pointer type %qT", type);
	  return error_mark_node;
	}

      if (TREE_CODE (TREE_TYPE (last_rval)) == REFERENCE_TYPE)
	last_rval = convert_from_reference (last_rval);
    }
  else
    last_rval = decay_conversion (expr);

  if (TREE_CODE (TREE_TYPE (last_rval)) == POINTER_TYPE)
    {
      if (processing_template_decl)
	{
	  expr = build_min_non_dep (ARROW_EXPR, last_rval, orig_expr);
	  /* It will be dereferenced.  */
	  TREE_TYPE (expr) = TREE_TYPE (TREE_TYPE (last_rval));
	  return expr;
	}

      return cp_build_indirect_ref (last_rval, NULL, tf_warning_or_error);
    }

  if (types_memoized)
    error ("result of %<operator->()%> yields non-pointer result");
  else
    error ("base operand of %<->%> is not a pointer");
  return error_mark_node;
}

/* Return an expression for "DATUM .* COMPONENT".  DATUM has not
   already been checked out to be of aggregate type.  */

tree
build_m_component_ref (tree datum, tree component)
{
  tree ptrmem_type;
  tree objtype;
  tree type;
  tree binfo;
  tree ctype;

  if (error_operand_p (datum) || error_operand_p (component))
    return error_mark_node;

  ptrmem_type = TREE_TYPE (component);
  if (!TYPE_PTR_TO_MEMBER_P (ptrmem_type))
    {
      error ("%qE cannot be used as a member pointer, since it is of "
	     "type %qT",
	     component, ptrmem_type);
      return error_mark_node;
    }

  objtype = TYPE_MAIN_VARIANT (TREE_TYPE (datum));
  if (! MAYBE_CLASS_TYPE_P (objtype))
    {
      error ("cannot apply member pointer %qE to %qE, which is of "
	     "non-class type %qT",
	     component, datum, objtype);
      return error_mark_node;
    }

  type = TYPE_PTRMEM_POINTED_TO_TYPE (ptrmem_type);
  ctype = complete_type (TYPE_PTRMEM_CLASS_TYPE (ptrmem_type));

  if (!COMPLETE_TYPE_P (ctype))
    {
      if (!same_type_p (ctype, objtype))
	goto mismatch;
      binfo = NULL;
    }
  else
    {
      binfo = lookup_base (objtype, ctype, ba_check, NULL);

      if (!binfo)
	{
	mismatch:
	  error ("pointer to member type %qT incompatible with object "
		 "type %qT",
		 type, objtype);
	  return error_mark_node;
	}
      else if (binfo == error_mark_node)
	return error_mark_node;
    }

  if (TYPE_PTRMEM_P (ptrmem_type))
    {
      tree ptype;

      /* Compute the type of the field, as described in [expr.ref].
	 There's no such thing as a mutable pointer-to-member, so
	 things are not as complex as they are for references to
	 non-static data members.  */
      type = cp_build_qualified_type (type,
				      (cp_type_quals (type)
				       | cp_type_quals (TREE_TYPE (datum))));

      datum = build_address (datum);

      /* Convert object to the correct base.  */
      if (binfo)
	datum = build_base_path (PLUS_EXPR, datum, binfo, 1);

      /* Build an expression for "object + offset" where offset is the
	 value stored in the pointer-to-data-member.  */
      ptype = build_pointer_type (type);
      datum = build2 (POINTER_PLUS_EXPR, ptype,
		      fold_convert (ptype, datum),
		      build_nop (sizetype, component));
      return cp_build_indirect_ref (datum, 0, tf_warning_or_error);
    }
  else
    return build2 (OFFSET_REF, type, datum, component);
}

/* Return a tree node for the expression TYPENAME '(' PARMS ')'.  */

tree
build_functional_cast (tree exp, tree parms, tsubst_flags_t complain)
{
  /* This is either a call to a constructor,
     or a C cast in C++'s `functional' notation.  */

  /* The type to which we are casting.  */
  tree type;

  if (exp == error_mark_node || parms == error_mark_node)
    return error_mark_node;

  if (TREE_CODE (exp) == TYPE_DECL)
    type = TREE_TYPE (exp);
  else
    type = exp;

  if (TREE_CODE (type) == REFERENCE_TYPE && !parms)
    {
      error ("invalid value-initialization of reference types");
      return error_mark_node;
    }

  if (processing_template_decl)
    {
      tree t = build_min (CAST_EXPR, type, parms);
      /* We don't know if it will or will not have side effects.  */
      TREE_SIDE_EFFECTS (t) = 1;
      return t;
    }

  if (! MAYBE_CLASS_TYPE_P (type))
    {
      if (parms == NULL_TREE)
	return cp_convert (type, integer_zero_node);

      /* This must build a C cast.  */
      parms = build_x_compound_expr_from_list (parms, "functional cast");
      return cp_build_c_cast (type, parms, complain);
    }

  /* Prepare to evaluate as a call to a constructor.  If this expression
     is actually used, for example,

     return X (arg1, arg2, ...);

     then the slot being initialized will be filled in.  */

  if (!complete_type_or_else (type, NULL_TREE))
    return error_mark_node;
  if (abstract_virtuals_error (NULL_TREE, type))
    return error_mark_node;

  /* [expr.type.conv]

     If the expression list is a single-expression, the type
     conversion is equivalent (in definedness, and if defined in
     meaning) to the corresponding cast expression.  */
  if (parms && TREE_CHAIN (parms) == NULL_TREE)
    return cp_build_c_cast (type, TREE_VALUE (parms), complain);

  /* [expr.type.conv]

     The expression T(), where T is a simple-type-specifier for a
     non-array complete object type or the (possibly cv-qualified)
     void type, creates an rvalue of the specified type, which is
     value-initialized.  */

  if (parms == NULL_TREE
      /* If there's a user-defined constructor, value-initialization is
	 just calling the constructor, so fall through.  */
      && !TYPE_HAS_USER_CONSTRUCTOR (type))
    {
      exp = build_value_init (type);
      return get_target_expr (exp);
    }

  /* Call the constructor.  */
  exp = build_special_member_call (NULL_TREE, complete_ctor_identifier, parms,
				   type, LOOKUP_NORMAL, complain);

  if (exp == error_mark_node)
    return error_mark_node;

  return build_cplus_new (type, exp);
}


/* Add new exception specifier SPEC, to the LIST we currently have.
   If it's already in LIST then do nothing.
   Moan if it's bad and we're allowed to. COMPLAIN < 0 means we
   know what we're doing.  */

tree
add_exception_specifier (tree list, tree spec, int complain)
{
  bool ok;
  tree core = spec;
  bool is_ptr;
  diagnostic_t diag_type = DK_UNSPECIFIED; /* none */

  if (spec == error_mark_node)
    return list;

  gcc_assert (spec && (!list || TREE_VALUE (list)));

  /* [except.spec] 1, type in an exception specifier shall not be
     incomplete, or pointer or ref to incomplete other than pointer
     to cv void.  */
  is_ptr = TREE_CODE (core) == POINTER_TYPE;
  if (is_ptr || TREE_CODE (core) == REFERENCE_TYPE)
    core = TREE_TYPE (core);
  if (complain < 0)
    ok = true;
  else if (VOID_TYPE_P (core))
    ok = is_ptr;
  else if (TREE_CODE (core) == TEMPLATE_TYPE_PARM)
    ok = true;
  else if (processing_template_decl)
    ok = true;
  else
    {
      ok = true;
      /* 15.4/1 says that types in an exception specifier must be complete,
	 but it seems more reasonable to only require this on definitions
	 and calls.  So just give a pedwarn at this point; we will give an
	 error later if we hit one of those two cases.  */
      if (!COMPLETE_TYPE_P (complete_type (core)))
	diag_type = DK_PEDWARN; /* pedwarn */
    }

  if (ok)
    {
      tree probe;

      for (probe = list; probe; probe = TREE_CHAIN (probe))
	if (same_type_p (TREE_VALUE (probe), spec))
	  break;
      if (!probe)
	list = tree_cons (NULL_TREE, spec, list);
    }
  else
    diag_type = DK_ERROR; /* error */

  if (diag_type != DK_UNSPECIFIED && complain)
    cxx_incomplete_type_diagnostic (NULL_TREE, core, diag_type);

  return list;
}

/* Combine the two exceptions specifier lists LIST and ADD, and return
   their union.  */

tree
merge_exception_specifiers (tree list, tree add)
{
  if (!list || !add)
    return NULL_TREE;
  else if (!TREE_VALUE (list))
    return add;
  else if (!TREE_VALUE (add))
    return list;
  else
    {
      tree orig_list = list;

      for (; add; add = TREE_CHAIN (add))
	{
	  tree spec = TREE_VALUE (add);
	  tree probe;

	  for (probe = orig_list; probe; probe = TREE_CHAIN (probe))
	    if (same_type_p (TREE_VALUE (probe), spec))
	      break;
	  if (!probe)
	    {
	      spec = build_tree_list (NULL_TREE, spec);
	      TREE_CHAIN (spec) = list;
	      list = spec;
	    }
	}
    }
  return list;
}

/* Subroutine of build_call.  Ensure that each of the types in the
   exception specification is complete.  Technically, 15.4/1 says that
   they need to be complete when we see a declaration of the function,
   but we should be able to get away with only requiring this when the
   function is defined or called.  See also add_exception_specifier.  */

void
require_complete_eh_spec_types (tree fntype, tree decl)
{
  tree raises;
  /* Don't complain about calls to op new.  */
  if (decl && DECL_ARTIFICIAL (decl))
    return;
  for (raises = TYPE_RAISES_EXCEPTIONS (fntype); raises;
       raises = TREE_CHAIN (raises))
    {
      tree type = TREE_VALUE (raises);
      if (type && !COMPLETE_TYPE_P (type))
	{
	  if (decl)
	    error
	      ("call to function %qD which throws incomplete type %q#T",
	       decl, type);
	  else
	    error ("call to function which throws incomplete type %q#T",
		   decl);
	}
    }
}


#include "gt-cp-typeck2.h"
