c-typeck.c revision 52750
118334Speter/* Build expressions with type checking for C compiler.
250397Sobrien   Copyright (C) 1987, 88, 91-97, 1998 Free Software Foundation, Inc.
318334Speter
418334SpeterThis file is part of GNU CC.
518334Speter
618334SpeterGNU CC is free software; you can redistribute it and/or modify
718334Speterit under the terms of the GNU General Public License as published by
818334Speterthe Free Software Foundation; either version 2, or (at your option)
918334Speterany later version.
1018334Speter
1118334SpeterGNU CC is distributed in the hope that it will be useful,
1218334Speterbut WITHOUT ANY WARRANTY; without even the implied warranty of
1318334SpeterMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1418334SpeterGNU General Public License for more details.
1518334Speter
1618334SpeterYou should have received a copy of the GNU General Public License
1718334Speteralong with GNU CC; see the file COPYING.  If not, write to
1818334Speterthe Free Software Foundation, 59 Temple Place - Suite 330,
1918334SpeterBoston, MA 02111-1307, USA.  */
2018334Speter
2118334Speter
2218334Speter/* This file is part of the C front end.
2318334Speter   It contains routines to build C expressions given their operands,
2418334Speter   including computing the types of the result, C-specific error checks,
2518334Speter   and some optimization.
2618334Speter
2718334Speter   There are also routines to build RETURN_STMT nodes and CASE_STMT nodes,
2818334Speter   and to process initializations in declarations (since they work
2918334Speter   like a strange sort of assignment).  */
3018334Speter
3118334Speter#include "config.h"
3250397Sobrien#include "system.h"
3318334Speter#include "tree.h"
3418334Speter#include "c-tree.h"
3518334Speter#include "flags.h"
3618334Speter#include "output.h"
3750397Sobrien#include "rtl.h"
3850397Sobrien#include "expr.h"
3950397Sobrien#include "toplev.h"
4052284Sobrien#include "intl.h"
4118334Speter
4218334Speter/* Nonzero if we've already printed a "missing braces around initializer"
4318334Speter   message within this initializer.  */
4418334Speterstatic int missing_braces_mentioned;
4518334Speter
4650397Sobrienstatic tree qualify_type		PROTO((tree, tree));
4718334Speterstatic int comp_target_types		PROTO((tree, tree));
4818334Speterstatic int function_types_compatible_p	PROTO((tree, tree));
4918334Speterstatic int type_lists_compatible_p	PROTO((tree, tree));
5018334Speterstatic int self_promoting_type_p	PROTO((tree));
5118334Speterstatic tree decl_constant_value		PROTO((tree));
5218334Speterstatic tree lookup_field		PROTO((tree, tree, tree *));
5318334Speterstatic tree convert_arguments		PROTO((tree, tree, tree, tree));
5418334Speterstatic tree pointer_int_sum		PROTO((enum tree_code, tree, tree));
5518334Speterstatic tree pointer_diff		PROTO((tree, tree));
5618334Speterstatic tree unary_complex_lvalue	PROTO((enum tree_code, tree));
5718334Speterstatic void pedantic_lvalue_warning	PROTO((enum tree_code));
5818334Speterstatic tree internal_build_compound_expr PROTO((tree, int));
5952284Sobrienstatic tree convert_for_assignment	PROTO((tree, tree, const char *, tree,
6018334Speter					       tree, int));
6152284Sobrienstatic void warn_for_assignment		PROTO((const char *, const char *,
6252284Sobrien					       tree, int));
6318334Speterstatic tree valid_compound_expr_initializer PROTO((tree, tree));
6452284Sobrienstatic void push_string			PROTO((const char *));
6518334Speterstatic void push_member_name		PROTO((tree));
6618334Speterstatic void push_array_bounds		PROTO((int));
6718334Speterstatic int spelling_length		PROTO((void));
6818334Speterstatic char *print_spelling		PROTO((char *));
6952284Sobrienstatic void warning_init		PROTO((const char *));
7018334Speterstatic tree digest_init			PROTO((tree, tree, int, int));
7118334Speterstatic void check_init_type_bitfields	PROTO((tree));
7218334Speterstatic void output_init_element		PROTO((tree, tree, tree, int));
7318334Speterstatic void output_pending_init_elements PROTO((int));
7450397Sobrienstatic void add_pending_init		PROTO((tree, tree));
7550397Sobrienstatic int pending_init_member		PROTO((tree));
7618334Speter
7718334Speter/* Do `exp = require_complete_type (exp);' to make sure exp
7818334Speter   does not have an incomplete type.  (That includes void types.)  */
7918334Speter
8018334Spetertree
8118334Speterrequire_complete_type (value)
8218334Speter     tree value;
8318334Speter{
8418334Speter  tree type = TREE_TYPE (value);
8518334Speter
8652284Sobrien  if (TREE_CODE (value) == ERROR_MARK)
8752284Sobrien    return error_mark_node;
8852284Sobrien
8918334Speter  /* First, detect a valid value with a complete type.  */
9018334Speter  if (TYPE_SIZE (type) != 0
9118334Speter      && type != void_type_node)
9218334Speter    return value;
9318334Speter
9418334Speter  incomplete_type_error (value, type);
9518334Speter  return error_mark_node;
9618334Speter}
9718334Speter
9818334Speter/* Print an error message for invalid use of an incomplete type.
9918334Speter   VALUE is the expression that was used (or 0 if that isn't known)
10018334Speter   and TYPE is the type that was invalid.  */
10118334Speter
10218334Spetervoid
10318334Speterincomplete_type_error (value, type)
10418334Speter     tree value;
10518334Speter     tree type;
10618334Speter{
10752284Sobrien  const char *type_code_string;
10818334Speter
10918334Speter  /* Avoid duplicate error message.  */
11018334Speter  if (TREE_CODE (type) == ERROR_MARK)
11118334Speter    return;
11218334Speter
11318334Speter  if (value != 0 && (TREE_CODE (value) == VAR_DECL
11418334Speter		     || TREE_CODE (value) == PARM_DECL))
11518334Speter    error ("`%s' has an incomplete type",
11618334Speter	   IDENTIFIER_POINTER (DECL_NAME (value)));
11718334Speter  else
11818334Speter    {
11918334Speter    retry:
12018334Speter      /* We must print an error message.  Be clever about what it says.  */
12118334Speter
12218334Speter      switch (TREE_CODE (type))
12318334Speter	{
12418334Speter	case RECORD_TYPE:
12552284Sobrien	  type_code_string = "struct";
12618334Speter	  break;
12718334Speter
12818334Speter	case UNION_TYPE:
12952284Sobrien	  type_code_string = "union";
13018334Speter	  break;
13118334Speter
13218334Speter	case ENUMERAL_TYPE:
13352284Sobrien	  type_code_string = "enum";
13418334Speter	  break;
13518334Speter
13618334Speter	case VOID_TYPE:
13718334Speter	  error ("invalid use of void expression");
13818334Speter	  return;
13918334Speter
14018334Speter	case ARRAY_TYPE:
14118334Speter	  if (TYPE_DOMAIN (type))
14218334Speter	    {
14318334Speter	      type = TREE_TYPE (type);
14418334Speter	      goto retry;
14518334Speter	    }
14618334Speter	  error ("invalid use of array with unspecified bounds");
14718334Speter	  return;
14818334Speter
14918334Speter	default:
15018334Speter	  abort ();
15118334Speter	}
15218334Speter
15318334Speter      if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
15452284Sobrien	error ("invalid use of undefined type `%s %s'",
15552284Sobrien	       type_code_string, IDENTIFIER_POINTER (TYPE_NAME (type)));
15618334Speter      else
15718334Speter	/* If this type has a typedef-name, the TYPE_NAME is a TYPE_DECL.  */
15818334Speter	error ("invalid use of incomplete typedef `%s'",
15918334Speter	       IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
16018334Speter    }
16118334Speter}
16218334Speter
16318334Speter/* Return a variant of TYPE which has all the type qualifiers of LIKE
16418334Speter   as well as those of TYPE.  */
16518334Speter
16618334Speterstatic tree
16718334Speterqualify_type (type, like)
16818334Speter     tree type, like;
16918334Speter{
17052750Sobrien  return c_build_qualified_type (type,
17152750Sobrien				 TYPE_QUALS (type) | TYPE_QUALS (like));
17218334Speter}
17318334Speter
17418334Speter/* Return the common type of two types.
17518334Speter   We assume that comptypes has already been done and returned 1;
17618334Speter   if that isn't so, this may crash.  In particular, we assume that qualifiers
17718334Speter   match.
17818334Speter
17918334Speter   This is the type for the result of most arithmetic operations
18018334Speter   if the operands have the given two types.  */
18118334Speter
18218334Spetertree
18318334Spetercommon_type (t1, t2)
18418334Speter     tree t1, t2;
18518334Speter{
18618334Speter  register enum tree_code code1;
18718334Speter  register enum tree_code code2;
18818334Speter  tree attributes;
18918334Speter
19018334Speter  /* Save time if the two types are the same.  */
19118334Speter
19218334Speter  if (t1 == t2) return t1;
19318334Speter
19418334Speter  /* If one type is nonsense, use the other.  */
19518334Speter  if (t1 == error_mark_node)
19618334Speter    return t2;
19718334Speter  if (t2 == error_mark_node)
19818334Speter    return t1;
19918334Speter
20050397Sobrien  /* Merge the attributes.  */
20150397Sobrien  attributes = merge_machine_type_attributes (t1, t2);
20218334Speter
20318334Speter  /* Treat an enum type as the unsigned integer type of the same width.  */
20418334Speter
20518334Speter  if (TREE_CODE (t1) == ENUMERAL_TYPE)
20618334Speter    t1 = type_for_size (TYPE_PRECISION (t1), 1);
20718334Speter  if (TREE_CODE (t2) == ENUMERAL_TYPE)
20818334Speter    t2 = type_for_size (TYPE_PRECISION (t2), 1);
20918334Speter
21018334Speter  code1 = TREE_CODE (t1);
21118334Speter  code2 = TREE_CODE (t2);
21218334Speter
21318334Speter  /* If one type is complex, form the common type of the non-complex
21418334Speter     components, then make that complex.  Use T1 or T2 if it is the
21518334Speter     required type.  */
21618334Speter  if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
21718334Speter    {
21818334Speter      tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
21918334Speter      tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
22018334Speter      tree subtype = common_type (subtype1, subtype2);
22118334Speter
22218334Speter      if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
22318334Speter	return build_type_attribute_variant (t1, attributes);
22418334Speter      else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype)
22518334Speter	return build_type_attribute_variant (t2, attributes);
22618334Speter      else
22718334Speter	return build_type_attribute_variant (build_complex_type (subtype),
22818334Speter					     attributes);
22918334Speter    }
23018334Speter
23118334Speter  switch (code1)
23218334Speter    {
23318334Speter    case INTEGER_TYPE:
23418334Speter    case REAL_TYPE:
23518334Speter      /* If only one is real, use it as the result.  */
23618334Speter
23718334Speter      if (code1 == REAL_TYPE && code2 != REAL_TYPE)
23818334Speter	return build_type_attribute_variant (t1, attributes);
23918334Speter
24018334Speter      if (code2 == REAL_TYPE && code1 != REAL_TYPE)
24118334Speter	return build_type_attribute_variant (t2, attributes);
24218334Speter
24318334Speter      /* Both real or both integers; use the one with greater precision.  */
24418334Speter
24518334Speter      if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))
24618334Speter	return build_type_attribute_variant (t1, attributes);
24718334Speter      else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1))
24818334Speter	return build_type_attribute_variant (t2, attributes);
24918334Speter
25018334Speter      /* Same precision.  Prefer longs to ints even when same size.  */
25118334Speter
25218334Speter      if (TYPE_MAIN_VARIANT (t1) == long_unsigned_type_node
25318334Speter	  || TYPE_MAIN_VARIANT (t2) == long_unsigned_type_node)
25418334Speter	return build_type_attribute_variant (long_unsigned_type_node,
25518334Speter					     attributes);
25618334Speter
25718334Speter      if (TYPE_MAIN_VARIANT (t1) == long_integer_type_node
25818334Speter	  || TYPE_MAIN_VARIANT (t2) == long_integer_type_node)
25918334Speter	{
26018334Speter	  /* But preserve unsignedness from the other type,
26118334Speter	     since long cannot hold all the values of an unsigned int.  */
26218334Speter	  if (TREE_UNSIGNED (t1) || TREE_UNSIGNED (t2))
26318334Speter	     t1 = long_unsigned_type_node;
26418334Speter	  else
26518334Speter	     t1 = long_integer_type_node;
26618334Speter	  return build_type_attribute_variant (t1, attributes);
26718334Speter	}
26818334Speter
26950397Sobrien      /* Likewise, prefer long double to double even if same size.  */
27050397Sobrien      if (TYPE_MAIN_VARIANT (t1) == long_double_type_node
27150397Sobrien	  || TYPE_MAIN_VARIANT (t2) == long_double_type_node)
27250397Sobrien	return build_type_attribute_variant (long_double_type_node,
27350397Sobrien					     attributes);
27450397Sobrien
27518334Speter      /* Otherwise prefer the unsigned one.  */
27618334Speter
27718334Speter      if (TREE_UNSIGNED (t1))
27818334Speter	return build_type_attribute_variant (t1, attributes);
27918334Speter      else
28018334Speter	return build_type_attribute_variant (t2, attributes);
28118334Speter
28218334Speter    case POINTER_TYPE:
28318334Speter      /* For two pointers, do this recursively on the target type,
28418334Speter	 and combine the qualifiers of the two types' targets.  */
28518334Speter      /* This code was turned off; I don't know why.
28618334Speter	 But ANSI C specifies doing this with the qualifiers.
28718334Speter	 So I turned it on again.  */
28818334Speter      {
28952284Sobrien	tree pointed_to_1 = TREE_TYPE (t1);
29052284Sobrien	tree pointed_to_2 = TREE_TYPE (t2);
29152284Sobrien	tree target = common_type (TYPE_MAIN_VARIANT (pointed_to_1),
29252284Sobrien				   TYPE_MAIN_VARIANT (pointed_to_2));
29352284Sobrien	t1 = build_pointer_type (c_build_qualified_type
29452284Sobrien				 (target,
29552284Sobrien				  TYPE_QUALS (pointed_to_1) |
29652284Sobrien				  TYPE_QUALS (pointed_to_2)));
29718334Speter	return build_type_attribute_variant (t1, attributes);
29818334Speter      }
29918334Speter#if 0
30018334Speter      t1 = build_pointer_type (common_type (TREE_TYPE (t1), TREE_TYPE (t2)));
30118334Speter      return build_type_attribute_variant (t1, attributes);
30218334Speter#endif
30318334Speter
30418334Speter    case ARRAY_TYPE:
30518334Speter      {
30618334Speter	tree elt = common_type (TREE_TYPE (t1), TREE_TYPE (t2));
30718334Speter	/* Save space: see if the result is identical to one of the args.  */
30818334Speter	if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1))
30918334Speter	  return build_type_attribute_variant (t1, attributes);
31018334Speter	if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2))
31118334Speter	  return build_type_attribute_variant (t2, attributes);
31218334Speter	/* Merge the element types, and have a size if either arg has one.  */
31318334Speter	t1 = build_array_type (elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2));
31418334Speter	return build_type_attribute_variant (t1, attributes);
31518334Speter      }
31618334Speter
31718334Speter    case FUNCTION_TYPE:
31818334Speter      /* Function types: prefer the one that specified arg types.
31918334Speter	 If both do, merge the arg types.  Also merge the return types.  */
32018334Speter      {
32118334Speter	tree valtype = common_type (TREE_TYPE (t1), TREE_TYPE (t2));
32218334Speter	tree p1 = TYPE_ARG_TYPES (t1);
32318334Speter	tree p2 = TYPE_ARG_TYPES (t2);
32418334Speter	int len;
32518334Speter	tree newargs, n;
32618334Speter	int i;
32718334Speter
32818334Speter	/* Save space: see if the result is identical to one of the args.  */
32918334Speter	if (valtype == TREE_TYPE (t1) && ! TYPE_ARG_TYPES (t2))
33018334Speter	  return build_type_attribute_variant (t1, attributes);
33118334Speter	if (valtype == TREE_TYPE (t2) && ! TYPE_ARG_TYPES (t1))
33218334Speter	  return build_type_attribute_variant (t2, attributes);
33318334Speter
33418334Speter	/* Simple way if one arg fails to specify argument types.  */
33518334Speter	if (TYPE_ARG_TYPES (t1) == 0)
33618334Speter	 {
33718334Speter	   t1 = build_function_type (valtype, TYPE_ARG_TYPES (t2));
33818334Speter	   return build_type_attribute_variant (t1, attributes);
33918334Speter	 }
34018334Speter	if (TYPE_ARG_TYPES (t2) == 0)
34118334Speter	 {
34218334Speter	   t1 = build_function_type (valtype, TYPE_ARG_TYPES (t1));
34318334Speter	   return build_type_attribute_variant (t1, attributes);
34418334Speter	 }
34518334Speter
34618334Speter	/* If both args specify argument types, we must merge the two
34718334Speter	   lists, argument by argument.  */
34818334Speter
34918334Speter	len = list_length (p1);
35018334Speter	newargs = 0;
35118334Speter
35218334Speter	for (i = 0; i < len; i++)
35318334Speter	  newargs = tree_cons (NULL_TREE, NULL_TREE, newargs);
35418334Speter
35518334Speter	n = newargs;
35618334Speter
35718334Speter	for (; p1;
35818334Speter	     p1 = TREE_CHAIN (p1), p2 = TREE_CHAIN (p2), n = TREE_CHAIN (n))
35918334Speter	  {
36018334Speter	    /* A null type means arg type is not specified.
36118334Speter	       Take whatever the other function type has.  */
36218334Speter	    if (TREE_VALUE (p1) == 0)
36318334Speter	      {
36418334Speter		TREE_VALUE (n) = TREE_VALUE (p2);
36518334Speter		goto parm_done;
36618334Speter	      }
36718334Speter	    if (TREE_VALUE (p2) == 0)
36818334Speter	      {
36918334Speter		TREE_VALUE (n) = TREE_VALUE (p1);
37018334Speter		goto parm_done;
37118334Speter	      }
37218334Speter
37318334Speter	    /* Given  wait (union {union wait *u; int *i} *)
37418334Speter	       and  wait (union wait *),
37518334Speter	       prefer  union wait *  as type of parm.  */
37618334Speter	    if (TREE_CODE (TREE_VALUE (p1)) == UNION_TYPE
37718334Speter		&& TREE_VALUE (p1) != TREE_VALUE (p2))
37818334Speter	      {
37918334Speter		tree memb;
38018334Speter		for (memb = TYPE_FIELDS (TREE_VALUE (p1));
38118334Speter		     memb; memb = TREE_CHAIN (memb))
38218334Speter		  if (comptypes (TREE_TYPE (memb), TREE_VALUE (p2)))
38318334Speter		    {
38418334Speter		      TREE_VALUE (n) = TREE_VALUE (p2);
38518334Speter		      if (pedantic)
38618334Speter			pedwarn ("function types not truly compatible in ANSI C");
38718334Speter		      goto parm_done;
38818334Speter		    }
38918334Speter	      }
39018334Speter	    if (TREE_CODE (TREE_VALUE (p2)) == UNION_TYPE
39118334Speter		&& TREE_VALUE (p2) != TREE_VALUE (p1))
39218334Speter	      {
39318334Speter		tree memb;
39418334Speter		for (memb = TYPE_FIELDS (TREE_VALUE (p2));
39518334Speter		     memb; memb = TREE_CHAIN (memb))
39618334Speter		  if (comptypes (TREE_TYPE (memb), TREE_VALUE (p1)))
39718334Speter		    {
39818334Speter		      TREE_VALUE (n) = TREE_VALUE (p1);
39918334Speter		      if (pedantic)
40018334Speter			pedwarn ("function types not truly compatible in ANSI C");
40118334Speter		      goto parm_done;
40218334Speter		    }
40318334Speter	      }
40418334Speter	    TREE_VALUE (n) = common_type (TREE_VALUE (p1), TREE_VALUE (p2));
40518334Speter	  parm_done: ;
40618334Speter	  }
40718334Speter
40818334Speter	t1 = build_function_type (valtype, newargs);
40950397Sobrien	/* ... falls through ...  */
41018334Speter      }
41118334Speter
41218334Speter    default:
41318334Speter      return build_type_attribute_variant (t1, attributes);
41418334Speter    }
41518334Speter
41618334Speter}
41718334Speter
41818334Speter/* Return 1 if TYPE1 and TYPE2 are compatible types for assignment
41918334Speter   or various other operations.  Return 2 if they are compatible
42018334Speter   but a warning may be needed if you use them together.  */
42118334Speter
42218334Speterint
42318334Spetercomptypes (type1, type2)
42418334Speter     tree type1, type2;
42518334Speter{
42618334Speter  register tree t1 = type1;
42718334Speter  register tree t2 = type2;
42818334Speter  int attrval, val;
42918334Speter
43018334Speter  /* Suppress errors caused by previously reported errors.  */
43118334Speter
43250397Sobrien  if (t1 == t2 || !t1 || !t2
43350397Sobrien      || TREE_CODE (t1) == ERROR_MARK || TREE_CODE (t2) == ERROR_MARK)
43418334Speter    return 1;
43518334Speter
43618334Speter  /* Treat an enum type as the integer type of the same width and
43718334Speter     signedness.  */
43818334Speter
43918334Speter  if (TREE_CODE (t1) == ENUMERAL_TYPE)
44018334Speter    t1 = type_for_size (TYPE_PRECISION (t1), TREE_UNSIGNED (t1));
44118334Speter  if (TREE_CODE (t2) == ENUMERAL_TYPE)
44218334Speter    t2 = type_for_size (TYPE_PRECISION (t2), TREE_UNSIGNED (t2));
44318334Speter
44418334Speter  if (t1 == t2)
44518334Speter    return 1;
44618334Speter
44718334Speter  /* Different classes of types can't be compatible.  */
44818334Speter
44918334Speter  if (TREE_CODE (t1) != TREE_CODE (t2)) return 0;
45018334Speter
45118334Speter  /* Qualifiers must match.  */
45218334Speter
45352284Sobrien  if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
45418334Speter    return 0;
45518334Speter
45618334Speter  /* Allow for two different type nodes which have essentially the same
45718334Speter     definition.  Note that we already checked for equality of the type
45850397Sobrien     qualifiers (just above).  */
45918334Speter
46018334Speter  if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
46118334Speter    return 1;
46218334Speter
46318334Speter#ifndef COMP_TYPE_ATTRIBUTES
46418334Speter#define COMP_TYPE_ATTRIBUTES(t1,t2)	1
46518334Speter#endif
46618334Speter
46718334Speter  /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
46818334Speter  if (! (attrval = COMP_TYPE_ATTRIBUTES (t1, t2)))
46918334Speter     return 0;
47018334Speter
47118334Speter  /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
47218334Speter  val = 0;
47318334Speter
47418334Speter  switch (TREE_CODE (t1))
47518334Speter    {
47618334Speter    case POINTER_TYPE:
47718334Speter      val = (TREE_TYPE (t1) == TREE_TYPE (t2)
47818334Speter	      ? 1 : comptypes (TREE_TYPE (t1), TREE_TYPE (t2)));
47918334Speter      break;
48018334Speter
48118334Speter    case FUNCTION_TYPE:
48218334Speter      val = function_types_compatible_p (t1, t2);
48318334Speter      break;
48418334Speter
48518334Speter    case ARRAY_TYPE:
48618334Speter      {
48718334Speter	tree d1 = TYPE_DOMAIN (t1);
48818334Speter	tree d2 = TYPE_DOMAIN (t2);
48918334Speter	val = 1;
49018334Speter
49118334Speter	/* Target types must match incl. qualifiers.  */
49218334Speter	if (TREE_TYPE (t1) != TREE_TYPE (t2)
49318334Speter	    && 0 == (val = comptypes (TREE_TYPE (t1), TREE_TYPE (t2))))
49418334Speter	  return 0;
49518334Speter
49618334Speter	/* Sizes must match unless one is missing or variable.  */
49718334Speter	if (d1 == 0 || d2 == 0 || d1 == d2
49818334Speter	    || TREE_CODE (TYPE_MIN_VALUE (d1)) != INTEGER_CST
49918334Speter	    || TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST
50018334Speter	    || TREE_CODE (TYPE_MAX_VALUE (d1)) != INTEGER_CST
50118334Speter	    || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST)
50218334Speter	  break;
50318334Speter
50418334Speter	if (! ((TREE_INT_CST_LOW (TYPE_MIN_VALUE (d1))
50518334Speter		  == TREE_INT_CST_LOW (TYPE_MIN_VALUE (d2)))
50618334Speter		 && (TREE_INT_CST_HIGH (TYPE_MIN_VALUE (d1))
50718334Speter		     == TREE_INT_CST_HIGH (TYPE_MIN_VALUE (d2)))
50818334Speter		 && (TREE_INT_CST_LOW (TYPE_MAX_VALUE (d1))
50918334Speter		     == TREE_INT_CST_LOW (TYPE_MAX_VALUE (d2)))
51018334Speter		 && (TREE_INT_CST_HIGH (TYPE_MAX_VALUE (d1))
51118334Speter		     == TREE_INT_CST_HIGH (TYPE_MAX_VALUE (d2)))))
51218334Speter	   val = 0;
51318334Speter        break;
51418334Speter      }
51518334Speter
51618334Speter    case RECORD_TYPE:
51718334Speter      if (maybe_objc_comptypes (t1, t2, 0) == 1)
51818334Speter	val = 1;
51918334Speter      break;
52050397Sobrien
52150397Sobrien    default:
52250397Sobrien      break;
52318334Speter    }
52418334Speter  return attrval == 2 && val == 1 ? 2 : val;
52518334Speter}
52618334Speter
52718334Speter/* Return 1 if TTL and TTR are pointers to types that are equivalent,
52818334Speter   ignoring their qualifiers.  */
52918334Speter
53018334Speterstatic int
53118334Spetercomp_target_types (ttl, ttr)
53218334Speter     tree ttl, ttr;
53318334Speter{
53418334Speter  int val;
53518334Speter
53618334Speter  /* Give maybe_objc_comptypes a crack at letting these types through.  */
53750397Sobrien  if ((val = maybe_objc_comptypes (ttl, ttr, 1)) >= 0)
53818334Speter    return val;
53918334Speter
54018334Speter  val = comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (ttl)),
54118334Speter		   TYPE_MAIN_VARIANT (TREE_TYPE (ttr)));
54218334Speter
54318334Speter  if (val == 2 && pedantic)
54418334Speter    pedwarn ("types are not quite compatible");
54518334Speter  return val;
54618334Speter}
54718334Speter
54818334Speter/* Subroutines of `comptypes'.  */
54918334Speter
55018334Speter/* Return 1 if two function types F1 and F2 are compatible.
55118334Speter   If either type specifies no argument types,
55218334Speter   the other must specify a fixed number of self-promoting arg types.
55318334Speter   Otherwise, if one type specifies only the number of arguments,
55418334Speter   the other must specify that number of self-promoting arg types.
55518334Speter   Otherwise, the argument types must match.  */
55618334Speter
55718334Speterstatic int
55818334Speterfunction_types_compatible_p (f1, f2)
55918334Speter     tree f1, f2;
56018334Speter{
56118334Speter  tree args1, args2;
56218334Speter  /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
56318334Speter  int val = 1;
56418334Speter  int val1;
56518334Speter
56618334Speter  if (!(TREE_TYPE (f1) == TREE_TYPE (f2)
56718334Speter	|| (val = comptypes (TREE_TYPE (f1), TREE_TYPE (f2)))))
56818334Speter    return 0;
56918334Speter
57018334Speter  args1 = TYPE_ARG_TYPES (f1);
57118334Speter  args2 = TYPE_ARG_TYPES (f2);
57218334Speter
57318334Speter  /* An unspecified parmlist matches any specified parmlist
57418334Speter     whose argument types don't need default promotions.  */
57518334Speter
57618334Speter  if (args1 == 0)
57718334Speter    {
57818334Speter      if (!self_promoting_args_p (args2))
57918334Speter	return 0;
58018334Speter      /* If one of these types comes from a non-prototype fn definition,
58118334Speter	 compare that with the other type's arglist.
58218334Speter	 If they don't match, ask for a warning (but no error).  */
58318334Speter      if (TYPE_ACTUAL_ARG_TYPES (f1)
58418334Speter	  && 1 != type_lists_compatible_p (args2, TYPE_ACTUAL_ARG_TYPES (f1)))
58518334Speter	val = 2;
58618334Speter      return val;
58718334Speter    }
58818334Speter  if (args2 == 0)
58918334Speter    {
59018334Speter      if (!self_promoting_args_p (args1))
59118334Speter	return 0;
59218334Speter      if (TYPE_ACTUAL_ARG_TYPES (f2)
59318334Speter	  && 1 != type_lists_compatible_p (args1, TYPE_ACTUAL_ARG_TYPES (f2)))
59418334Speter	val = 2;
59518334Speter      return val;
59618334Speter    }
59718334Speter
59818334Speter  /* Both types have argument lists: compare them and propagate results.  */
59918334Speter  val1 = type_lists_compatible_p (args1, args2);
60018334Speter  return val1 != 1 ? val1 : val;
60118334Speter}
60218334Speter
60318334Speter/* Check two lists of types for compatibility,
60418334Speter   returning 0 for incompatible, 1 for compatible,
60518334Speter   or 2 for compatible with warning.  */
60618334Speter
60718334Speterstatic int
60818334Spetertype_lists_compatible_p (args1, args2)
60918334Speter     tree args1, args2;
61018334Speter{
61118334Speter  /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
61218334Speter  int val = 1;
61318334Speter  int newval = 0;
61418334Speter
61518334Speter  while (1)
61618334Speter    {
61718334Speter      if (args1 == 0 && args2 == 0)
61818334Speter	return val;
61918334Speter      /* If one list is shorter than the other,
62018334Speter	 they fail to match.  */
62118334Speter      if (args1 == 0 || args2 == 0)
62218334Speter	return 0;
62318334Speter      /* A null pointer instead of a type
62418334Speter	 means there is supposed to be an argument
62518334Speter	 but nothing is specified about what type it has.
62618334Speter	 So match anything that self-promotes.  */
62718334Speter      if (TREE_VALUE (args1) == 0)
62818334Speter	{
62918334Speter	  if (! self_promoting_type_p (TREE_VALUE (args2)))
63018334Speter	    return 0;
63118334Speter	}
63218334Speter      else if (TREE_VALUE (args2) == 0)
63318334Speter	{
63418334Speter	  if (! self_promoting_type_p (TREE_VALUE (args1)))
63518334Speter	    return 0;
63618334Speter	}
63718334Speter      else if (! (newval = comptypes (TREE_VALUE (args1), TREE_VALUE (args2))))
63818334Speter	{
63918334Speter	  /* Allow  wait (union {union wait *u; int *i} *)
64018334Speter	     and  wait (union wait *)  to be compatible.  */
64118334Speter	  if (TREE_CODE (TREE_VALUE (args1)) == UNION_TYPE
64218334Speter	      && (TYPE_NAME (TREE_VALUE (args1)) == 0
64318334Speter		  || TYPE_TRANSPARENT_UNION (TREE_VALUE (args1)))
64418334Speter	      && TREE_CODE (TYPE_SIZE (TREE_VALUE (args1))) == INTEGER_CST
64518334Speter	      && tree_int_cst_equal (TYPE_SIZE (TREE_VALUE (args1)),
64618334Speter				     TYPE_SIZE (TREE_VALUE (args2))))
64718334Speter	    {
64818334Speter	      tree memb;
64918334Speter	      for (memb = TYPE_FIELDS (TREE_VALUE (args1));
65018334Speter		   memb; memb = TREE_CHAIN (memb))
65118334Speter		if (comptypes (TREE_TYPE (memb), TREE_VALUE (args2)))
65218334Speter		  break;
65318334Speter	      if (memb == 0)
65418334Speter		return 0;
65518334Speter	    }
65618334Speter	  else if (TREE_CODE (TREE_VALUE (args2)) == UNION_TYPE
65718334Speter		   && (TYPE_NAME (TREE_VALUE (args2)) == 0
65818334Speter		       || TYPE_TRANSPARENT_UNION (TREE_VALUE (args2)))
65918334Speter		   && TREE_CODE (TYPE_SIZE (TREE_VALUE (args2))) == INTEGER_CST
66018334Speter		   && tree_int_cst_equal (TYPE_SIZE (TREE_VALUE (args2)),
66118334Speter					  TYPE_SIZE (TREE_VALUE (args1))))
66218334Speter	    {
66318334Speter	      tree memb;
66418334Speter	      for (memb = TYPE_FIELDS (TREE_VALUE (args2));
66518334Speter		   memb; memb = TREE_CHAIN (memb))
66618334Speter		if (comptypes (TREE_TYPE (memb), TREE_VALUE (args1)))
66718334Speter		  break;
66818334Speter	      if (memb == 0)
66918334Speter		return 0;
67018334Speter	    }
67118334Speter	  else
67218334Speter	    return 0;
67318334Speter	}
67418334Speter
67518334Speter      /* comptypes said ok, but record if it said to warn.  */
67618334Speter      if (newval > val)
67718334Speter	val = newval;
67818334Speter
67918334Speter      args1 = TREE_CHAIN (args1);
68018334Speter      args2 = TREE_CHAIN (args2);
68118334Speter    }
68218334Speter}
68318334Speter
68418334Speter/* Return 1 if PARMS specifies a fixed number of parameters
68518334Speter   and none of their types is affected by default promotions.  */
68618334Speter
68718334Speterint
68818334Speterself_promoting_args_p (parms)
68918334Speter     tree parms;
69018334Speter{
69118334Speter  register tree t;
69218334Speter  for (t = parms; t; t = TREE_CHAIN (t))
69318334Speter    {
69418334Speter      register tree type = TREE_VALUE (t);
69518334Speter
69618334Speter      if (TREE_CHAIN (t) == 0 && type != void_type_node)
69718334Speter	return 0;
69818334Speter
69918334Speter      if (type == 0)
70018334Speter	return 0;
70118334Speter
70218334Speter      if (TYPE_MAIN_VARIANT (type) == float_type_node)
70318334Speter	return 0;
70418334Speter
70518334Speter      if (C_PROMOTING_INTEGER_TYPE_P (type))
70618334Speter	return 0;
70718334Speter    }
70818334Speter  return 1;
70918334Speter}
71018334Speter
71118334Speter/* Return 1 if TYPE is not affected by default promotions.  */
71218334Speter
71318334Speterstatic int
71418334Speterself_promoting_type_p (type)
71518334Speter     tree type;
71618334Speter{
71718334Speter  if (TYPE_MAIN_VARIANT (type) == float_type_node)
71818334Speter    return 0;
71918334Speter
72018334Speter  if (C_PROMOTING_INTEGER_TYPE_P (type))
72118334Speter    return 0;
72218334Speter
72318334Speter  return 1;
72418334Speter}
72518334Speter
72618334Speter/* Return an unsigned type the same as TYPE in other respects.  */
72718334Speter
72818334Spetertree
72918334Speterunsigned_type (type)
73018334Speter     tree type;
73118334Speter{
73218334Speter  tree type1 = TYPE_MAIN_VARIANT (type);
73318334Speter  if (type1 == signed_char_type_node || type1 == char_type_node)
73418334Speter    return unsigned_char_type_node;
73518334Speter  if (type1 == integer_type_node)
73618334Speter    return unsigned_type_node;
73718334Speter  if (type1 == short_integer_type_node)
73818334Speter    return short_unsigned_type_node;
73918334Speter  if (type1 == long_integer_type_node)
74018334Speter    return long_unsigned_type_node;
74118334Speter  if (type1 == long_long_integer_type_node)
74218334Speter    return long_long_unsigned_type_node;
74318334Speter  if (type1 == intDI_type_node)
74418334Speter    return unsigned_intDI_type_node;
74518334Speter  if (type1 == intSI_type_node)
74618334Speter    return unsigned_intSI_type_node;
74718334Speter  if (type1 == intHI_type_node)
74818334Speter    return unsigned_intHI_type_node;
74918334Speter  if (type1 == intQI_type_node)
75018334Speter    return unsigned_intQI_type_node;
75150397Sobrien
75250397Sobrien  return signed_or_unsigned_type (1, type);
75318334Speter}
75418334Speter
75518334Speter/* Return a signed type the same as TYPE in other respects.  */
75618334Speter
75718334Spetertree
75818334Spetersigned_type (type)
75918334Speter     tree type;
76018334Speter{
76118334Speter  tree type1 = TYPE_MAIN_VARIANT (type);
76218334Speter  if (type1 == unsigned_char_type_node || type1 == char_type_node)
76318334Speter    return signed_char_type_node;
76418334Speter  if (type1 == unsigned_type_node)
76518334Speter    return integer_type_node;
76618334Speter  if (type1 == short_unsigned_type_node)
76718334Speter    return short_integer_type_node;
76818334Speter  if (type1 == long_unsigned_type_node)
76918334Speter    return long_integer_type_node;
77018334Speter  if (type1 == long_long_unsigned_type_node)
77118334Speter    return long_long_integer_type_node;
77218334Speter  if (type1 == unsigned_intDI_type_node)
77318334Speter    return intDI_type_node;
77418334Speter  if (type1 == unsigned_intSI_type_node)
77518334Speter    return intSI_type_node;
77618334Speter  if (type1 == unsigned_intHI_type_node)
77718334Speter    return intHI_type_node;
77818334Speter  if (type1 == unsigned_intQI_type_node)
77918334Speter    return intQI_type_node;
78050397Sobrien
78150397Sobrien  return signed_or_unsigned_type (0, type);
78218334Speter}
78318334Speter
78418334Speter/* Return a type the same as TYPE except unsigned or
78518334Speter   signed according to UNSIGNEDP.  */
78618334Speter
78718334Spetertree
78818334Spetersigned_or_unsigned_type (unsignedp, type)
78918334Speter     int unsignedp;
79018334Speter     tree type;
79118334Speter{
79250397Sobrien  if ((! INTEGRAL_TYPE_P (type) && ! POINTER_TYPE_P (type))
79350397Sobrien      || TREE_UNSIGNED (type) == unsignedp)
79418334Speter    return type;
79518334Speter  if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
79618334Speter    return unsignedp ? unsigned_char_type_node : signed_char_type_node;
79718334Speter  if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
79818334Speter    return unsignedp ? unsigned_type_node : integer_type_node;
79918334Speter  if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))
80018334Speter    return unsignedp ? short_unsigned_type_node : short_integer_type_node;
80118334Speter  if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))
80218334Speter    return unsignedp ? long_unsigned_type_node : long_integer_type_node;
80318334Speter  if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))
80418334Speter    return (unsignedp ? long_long_unsigned_type_node
80518334Speter	    : long_long_integer_type_node);
80618334Speter  return type;
80718334Speter}
80818334Speter
80918334Speter/* Compute the value of the `sizeof' operator.  */
81018334Speter
81118334Spetertree
81218334Speterc_sizeof (type)
81318334Speter     tree type;
81418334Speter{
81518334Speter  enum tree_code code = TREE_CODE (type);
81618334Speter  tree t;
81718334Speter
81818334Speter  if (code == FUNCTION_TYPE)
81918334Speter    {
82018334Speter      if (pedantic || warn_pointer_arith)
82118334Speter	pedwarn ("sizeof applied to a function type");
82218334Speter      return size_int (1);
82318334Speter    }
82418334Speter  if (code == VOID_TYPE)
82518334Speter    {
82618334Speter      if (pedantic || warn_pointer_arith)
82718334Speter	pedwarn ("sizeof applied to a void type");
82818334Speter      return size_int (1);
82918334Speter    }
83018334Speter  if (code == ERROR_MARK)
83118334Speter    return size_int (1);
83218334Speter  if (TYPE_SIZE (type) == 0)
83318334Speter    {
83418334Speter      error ("sizeof applied to an incomplete type");
83518334Speter      return size_int (0);
83618334Speter    }
83718334Speter
83818334Speter  /* Convert in case a char is more than one unit.  */
83918334Speter  t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
84018334Speter		  size_int (TYPE_PRECISION (char_type_node)));
84150397Sobrien  t = convert (sizetype, t);
84218334Speter  /* size_binop does not put the constant in range, so do it now.  */
84318334Speter  if (TREE_CODE (t) == INTEGER_CST && force_fit_type (t, 0))
84418334Speter    TREE_CONSTANT_OVERFLOW (t) = TREE_OVERFLOW (t) = 1;
84518334Speter  return t;
84618334Speter}
84718334Speter
84818334Spetertree
84918334Speterc_sizeof_nowarn (type)
85018334Speter     tree type;
85118334Speter{
85218334Speter  enum tree_code code = TREE_CODE (type);
85318334Speter  tree t;
85418334Speter
85518334Speter  if (code == FUNCTION_TYPE
85618334Speter      || code == VOID_TYPE
85718334Speter      || code == ERROR_MARK)
85818334Speter    return size_int (1);
85918334Speter  if (TYPE_SIZE (type) == 0)
86018334Speter    return size_int (0);
86118334Speter
86218334Speter  /* Convert in case a char is more than one unit.  */
86318334Speter  t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
86418334Speter		  size_int (TYPE_PRECISION (char_type_node)));
86550397Sobrien  t = convert (sizetype, t);
86618334Speter  force_fit_type (t, 0);
86718334Speter  return t;
86818334Speter}
86918334Speter
87018334Speter/* Compute the size to increment a pointer by.  */
87118334Speter
87218334Spetertree
87318334Speterc_size_in_bytes (type)
87418334Speter     tree type;
87518334Speter{
87618334Speter  enum tree_code code = TREE_CODE (type);
87718334Speter  tree t;
87818334Speter
87918334Speter  if (code == FUNCTION_TYPE)
88018334Speter    return size_int (1);
88118334Speter  if (code == VOID_TYPE)
88218334Speter    return size_int (1);
88318334Speter  if (code == ERROR_MARK)
88418334Speter    return size_int (1);
88518334Speter  if (TYPE_SIZE (type) == 0)
88618334Speter    {
88718334Speter      error ("arithmetic on pointer to an incomplete type");
88818334Speter      return size_int (1);
88918334Speter    }
89018334Speter
89118334Speter  /* Convert in case a char is more than one unit.  */
89218334Speter  t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
89318334Speter		     size_int (BITS_PER_UNIT));
89450397Sobrien  t = convert (sizetype, t);
89518334Speter  force_fit_type (t, 0);
89618334Speter  return t;
89718334Speter}
89818334Speter
89918334Speter/* Implement the __alignof keyword: Return the minimum required
90018334Speter   alignment of TYPE, measured in bytes.  */
90118334Speter
90218334Spetertree
90318334Speterc_alignof (type)
90418334Speter     tree type;
90518334Speter{
90618334Speter  enum tree_code code = TREE_CODE (type);
90718334Speter
90818334Speter  if (code == FUNCTION_TYPE)
90918334Speter    return size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT);
91018334Speter
91118334Speter  if (code == VOID_TYPE || code == ERROR_MARK)
91218334Speter    return size_int (1);
91318334Speter
91418334Speter  return size_int (TYPE_ALIGN (type) / BITS_PER_UNIT);
91518334Speter}
91618334Speter
91718334Speter/* Implement the __alignof keyword: Return the minimum required
91818334Speter   alignment of EXPR, measured in bytes.  For VAR_DECL's and
91918334Speter   FIELD_DECL's return DECL_ALIGN (which can be set from an
92018334Speter   "aligned" __attribute__ specification).  */
92118334Speter
92218334Spetertree
92318334Speterc_alignof_expr (expr)
92418334Speter     tree expr;
92518334Speter{
92618334Speter  if (TREE_CODE (expr) == VAR_DECL)
92718334Speter    return size_int (DECL_ALIGN (expr) / BITS_PER_UNIT);
92818334Speter
92918334Speter  if (TREE_CODE (expr) == COMPONENT_REF
93050397Sobrien      && DECL_C_BIT_FIELD (TREE_OPERAND (expr, 1)))
93118334Speter    {
93218334Speter      error ("`__alignof' applied to a bit-field");
93318334Speter      return size_int (1);
93418334Speter    }
93518334Speter  else if (TREE_CODE (expr) == COMPONENT_REF
93618334Speter      && TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL)
93718334Speter    return size_int (DECL_ALIGN (TREE_OPERAND (expr, 1)) / BITS_PER_UNIT);
93818334Speter
93918334Speter  if (TREE_CODE (expr) == INDIRECT_REF)
94018334Speter    {
94118334Speter      tree t = TREE_OPERAND (expr, 0);
94218334Speter      tree best = t;
94318334Speter      int bestalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));
94418334Speter
94518334Speter      while (TREE_CODE (t) == NOP_EXPR
94618334Speter	      && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == POINTER_TYPE)
94718334Speter	{
94818334Speter	  int thisalign;
94918334Speter
95018334Speter	  t = TREE_OPERAND (t, 0);
95118334Speter	  thisalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));
95218334Speter	  if (thisalign > bestalign)
95318334Speter	    best = t, bestalign = thisalign;
95418334Speter	}
95518334Speter      return c_alignof (TREE_TYPE (TREE_TYPE (best)));
95618334Speter    }
95718334Speter  else
95818334Speter    return c_alignof (TREE_TYPE (expr));
95918334Speter}
96050397Sobrien
96118334Speter/* Return either DECL or its known constant value (if it has one).  */
96218334Speter
96318334Speterstatic tree
96418334Speterdecl_constant_value (decl)
96518334Speter     tree decl;
96618334Speter{
96750397Sobrien  if (/* Don't change a variable array bound or initial value to a constant
96818334Speter	 in a place where a variable is invalid.  */
96950397Sobrien      current_function_decl != 0
97018334Speter      && ! pedantic
97118334Speter      && ! TREE_THIS_VOLATILE (decl)
97218334Speter      && TREE_READONLY (decl) && ! ITERATOR_P (decl)
97318334Speter      && DECL_INITIAL (decl) != 0
97418334Speter      && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK
97518334Speter      /* This is invalid if initial value is not constant.
97618334Speter	 If it has either a function call, a memory reference,
97718334Speter	 or a variable, then re-evaluating it could give different results.  */
97818334Speter      && TREE_CONSTANT (DECL_INITIAL (decl))
97918334Speter      /* Check for cases where this is sub-optimal, even though valid.  */
98018334Speter      && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR
98118334Speter      && DECL_MODE (decl) != BLKmode)
98218334Speter    return DECL_INITIAL (decl);
98318334Speter  return decl;
98418334Speter}
98518334Speter
98618334Speter/* Perform default promotions for C data used in expressions.
98718334Speter   Arrays and functions are converted to pointers;
98818334Speter   enumeral types or short or char, to int.
98918334Speter   In addition, manifest constants symbols are replaced by their values.  */
99018334Speter
99118334Spetertree
99218334Speterdefault_conversion (exp)
99318334Speter     tree exp;
99418334Speter{
99518334Speter  register tree type = TREE_TYPE (exp);
99618334Speter  register enum tree_code code = TREE_CODE (type);
99718334Speter
99818334Speter  /* Constants can be used directly unless they're not loadable.  */
99918334Speter  if (TREE_CODE (exp) == CONST_DECL)
100018334Speter    exp = DECL_INITIAL (exp);
100118334Speter
100218334Speter  /* Replace a nonvolatile const static variable with its value unless
100318334Speter     it is an array, in which case we must be sure that taking the
100418334Speter     address of the array produces consistent results.  */
100518334Speter  else if (optimize && TREE_CODE (exp) == VAR_DECL && code != ARRAY_TYPE)
100618334Speter    {
100718334Speter      exp = decl_constant_value (exp);
100818334Speter      type = TREE_TYPE (exp);
100918334Speter    }
101018334Speter
101118334Speter  /* Strip NON_LVALUE_EXPRs and no-op conversions, since we aren't using as
101218334Speter     an lvalue.  */
101318334Speter  /* Do not use STRIP_NOPS here!  It will remove conversions from pointer
101418334Speter     to integer and cause infinite recursion.  */
101518334Speter  while (TREE_CODE (exp) == NON_LVALUE_EXPR
101618334Speter	 || (TREE_CODE (exp) == NOP_EXPR
101718334Speter	     && TREE_TYPE (TREE_OPERAND (exp, 0)) == TREE_TYPE (exp)))
101818334Speter    exp = TREE_OPERAND (exp, 0);
101918334Speter
102018334Speter  /* Normally convert enums to int,
102118334Speter     but convert wide enums to something wider.  */
102218334Speter  if (code == ENUMERAL_TYPE)
102318334Speter    {
102418334Speter      type = type_for_size (MAX (TYPE_PRECISION (type),
102518334Speter				 TYPE_PRECISION (integer_type_node)),
102618334Speter			    ((flag_traditional
102750397Sobrien			      || (TYPE_PRECISION (type)
102850397Sobrien				  >= TYPE_PRECISION (integer_type_node)))
102918334Speter			     && TREE_UNSIGNED (type)));
103018334Speter      return convert (type, exp);
103118334Speter    }
103218334Speter
103350397Sobrien  if (TREE_CODE (exp) == COMPONENT_REF
103450397Sobrien      && DECL_C_BIT_FIELD (TREE_OPERAND (exp, 1)))
103550397Sobrien    {
103650397Sobrien      tree width = DECL_SIZE (TREE_OPERAND (exp, 1));
103750397Sobrien      HOST_WIDE_INT low = TREE_INT_CST_LOW (width);
103850397Sobrien
103950397Sobrien      /* If it's thinner than an int, promote it like a
104050397Sobrien	 C_PROMOTING_INTEGER_TYPE_P, otherwise leave it alone.  */
104150397Sobrien
104250397Sobrien      if (low < TYPE_PRECISION (integer_type_node))
104350397Sobrien	{
104450397Sobrien	  if (flag_traditional && TREE_UNSIGNED (type))
104550397Sobrien	    return convert (unsigned_type_node, exp);
104650397Sobrien	  else
104750397Sobrien	    return convert (integer_type_node, exp);
104850397Sobrien	}
104950397Sobrien    }
105050397Sobrien
105118334Speter  if (C_PROMOTING_INTEGER_TYPE_P (type))
105218334Speter    {
105318334Speter      /* Traditionally, unsignedness is preserved in default promotions.
105418334Speter         Also preserve unsignedness if not really getting any wider.  */
105518334Speter      if (TREE_UNSIGNED (type)
105618334Speter	  && (flag_traditional
105718334Speter	      || TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)))
105818334Speter	return convert (unsigned_type_node, exp);
105918334Speter      return convert (integer_type_node, exp);
106018334Speter    }
106118334Speter  if (flag_traditional && !flag_allow_single_precision
106218334Speter      && TYPE_MAIN_VARIANT (type) == float_type_node)
106318334Speter    return convert (double_type_node, exp);
106418334Speter  if (code == VOID_TYPE)
106518334Speter    {
106618334Speter      error ("void value not ignored as it ought to be");
106718334Speter      return error_mark_node;
106818334Speter    }
106918334Speter  if (code == FUNCTION_TYPE)
107018334Speter    {
107118334Speter      return build_unary_op (ADDR_EXPR, exp, 0);
107218334Speter    }
107318334Speter  if (code == ARRAY_TYPE)
107418334Speter    {
107518334Speter      register tree adr;
107618334Speter      tree restype = TREE_TYPE (type);
107718334Speter      tree ptrtype;
107818334Speter      int constp = 0;
107918334Speter      int volatilep = 0;
108018334Speter
108118334Speter      if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'r'
108218334Speter	  || TREE_CODE_CLASS (TREE_CODE (exp)) == 'd')
108318334Speter	{
108418334Speter	  constp = TREE_READONLY (exp);
108518334Speter	  volatilep = TREE_THIS_VOLATILE (exp);
108618334Speter	}
108718334Speter
108852284Sobrien      if (TYPE_QUALS (type) || constp || volatilep)
108952284Sobrien	restype
109052284Sobrien	  = c_build_qualified_type (restype,
109152284Sobrien				    TYPE_QUALS (type)
109252284Sobrien				    | (constp * TYPE_QUAL_CONST)
109352284Sobrien				    | (volatilep * TYPE_QUAL_VOLATILE));
109418334Speter
109518334Speter      if (TREE_CODE (exp) == INDIRECT_REF)
109618334Speter	return convert (TYPE_POINTER_TO (restype),
109718334Speter			TREE_OPERAND (exp, 0));
109818334Speter
109918334Speter      if (TREE_CODE (exp) == COMPOUND_EXPR)
110018334Speter	{
110118334Speter	  tree op1 = default_conversion (TREE_OPERAND (exp, 1));
110218334Speter	  return build (COMPOUND_EXPR, TREE_TYPE (op1),
110318334Speter			TREE_OPERAND (exp, 0), op1);
110418334Speter	}
110518334Speter
110650397Sobrien      if (! lvalue_p (exp)
110718334Speter	  && ! (TREE_CODE (exp) == CONSTRUCTOR && TREE_STATIC (exp)))
110818334Speter	{
110918334Speter	  error ("invalid use of non-lvalue array");
111018334Speter	  return error_mark_node;
111118334Speter	}
111218334Speter
111318334Speter      ptrtype = build_pointer_type (restype);
111418334Speter
111518334Speter      if (TREE_CODE (exp) == VAR_DECL)
111618334Speter	{
111718334Speter	  /* ??? This is not really quite correct
111818334Speter	     in that the type of the operand of ADDR_EXPR
111918334Speter	     is not the target type of the type of the ADDR_EXPR itself.
112018334Speter	     Question is, can this lossage be avoided?  */
112118334Speter	  adr = build1 (ADDR_EXPR, ptrtype, exp);
112218334Speter	  if (mark_addressable (exp) == 0)
112318334Speter	    return error_mark_node;
112418334Speter	  TREE_CONSTANT (adr) = staticp (exp);
112518334Speter	  TREE_SIDE_EFFECTS (adr) = 0;   /* Default would be, same as EXP.  */
112618334Speter	  return adr;
112718334Speter	}
112818334Speter      /* This way is better for a COMPONENT_REF since it can
112918334Speter	 simplify the offset for a component.  */
113018334Speter      adr = build_unary_op (ADDR_EXPR, exp, 1);
113118334Speter      return convert (ptrtype, adr);
113218334Speter    }
113318334Speter  return exp;
113418334Speter}
113518334Speter
113618334Speter/* Look up component name in the structure type definition.
113718334Speter
113818334Speter   If this component name is found indirectly within an anonymous union,
113918334Speter   store in *INDIRECT the component which directly contains
114018334Speter   that anonymous union.  Otherwise, set *INDIRECT to 0.  */
114118334Speter
114218334Speterstatic tree
114318334Speterlookup_field (type, component, indirect)
114418334Speter     tree type, component;
114518334Speter     tree *indirect;
114618334Speter{
114718334Speter  tree field;
114818334Speter
114918334Speter  /* If TYPE_LANG_SPECIFIC is set, then it is a sorted array of pointers
115018334Speter     to the field elements.  Use a binary search on this array to quickly
115118334Speter     find the element.  Otherwise, do a linear search.  TYPE_LANG_SPECIFIC
115218334Speter     will always be set for structures which have many elements.  */
115318334Speter
115418334Speter  if (TYPE_LANG_SPECIFIC (type))
115518334Speter    {
115618334Speter      int bot, top, half;
115718334Speter      tree *field_array = &TYPE_LANG_SPECIFIC (type)->elts[0];
115818334Speter
115918334Speter      field = TYPE_FIELDS (type);
116018334Speter      bot = 0;
116118334Speter      top = TYPE_LANG_SPECIFIC (type)->len;
116218334Speter      while (top - bot > 1)
116318334Speter	{
116418334Speter	  half = (top - bot + 1) >> 1;
116518334Speter	  field = field_array[bot+half];
116618334Speter
116718334Speter	  if (DECL_NAME (field) == NULL_TREE)
116818334Speter	    {
116918334Speter	      /* Step through all anon unions in linear fashion.  */
117018334Speter	      while (DECL_NAME (field_array[bot]) == NULL_TREE)
117118334Speter		{
117250397Sobrien		  tree anon = 0, junk;
117318334Speter
117418334Speter		  field = field_array[bot++];
117550397Sobrien		  if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE
117650397Sobrien		      || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
117750397Sobrien		    anon = lookup_field (TREE_TYPE (field), component, &junk);
117850397Sobrien
117918334Speter		  if (anon != NULL_TREE)
118018334Speter		    {
118118334Speter		      *indirect = field;
118218334Speter		      return anon;
118318334Speter		    }
118418334Speter		}
118518334Speter
118618334Speter	      /* Entire record is only anon unions.  */
118718334Speter	      if (bot > top)
118818334Speter		return NULL_TREE;
118918334Speter
119018334Speter	      /* Restart the binary search, with new lower bound.  */
119118334Speter	      continue;
119218334Speter	    }
119318334Speter
119418334Speter	  if (DECL_NAME (field) == component)
119518334Speter	    break;
119618334Speter	  if (DECL_NAME (field) < component)
119718334Speter	    bot += half;
119818334Speter	  else
119918334Speter	    top = bot + half;
120018334Speter	}
120118334Speter
120218334Speter      if (DECL_NAME (field_array[bot]) == component)
120318334Speter	field = field_array[bot];
120418334Speter      else if (DECL_NAME (field) != component)
120518334Speter	field = 0;
120618334Speter    }
120718334Speter  else
120818334Speter    {
120918334Speter      for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
121018334Speter	{
121118334Speter	  if (DECL_NAME (field) == NULL_TREE)
121218334Speter	    {
121318334Speter	      tree junk;
121450397Sobrien	      tree anon = 0;
121550397Sobrien
121650397Sobrien	      if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE
121750397Sobrien		  || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
121850397Sobrien		anon = lookup_field (TREE_TYPE (field), component, &junk);
121950397Sobrien
122018334Speter	      if (anon != NULL_TREE)
122118334Speter		{
122218334Speter		  *indirect = field;
122318334Speter		  return anon;
122418334Speter		}
122518334Speter	    }
122618334Speter
122718334Speter	  if (DECL_NAME (field) == component)
122818334Speter	    break;
122918334Speter	}
123018334Speter    }
123118334Speter
123218334Speter  *indirect = NULL_TREE;
123318334Speter  return field;
123418334Speter}
123518334Speter
123618334Speter/* Make an expression to refer to the COMPONENT field of
123718334Speter   structure or union value DATUM.  COMPONENT is an IDENTIFIER_NODE.  */
123818334Speter
123918334Spetertree
124018334Speterbuild_component_ref (datum, component)
124118334Speter     tree datum, component;
124218334Speter{
124318334Speter  register tree type = TREE_TYPE (datum);
124418334Speter  register enum tree_code code = TREE_CODE (type);
124518334Speter  register tree field = NULL;
124618334Speter  register tree ref;
124718334Speter
124818334Speter  /* If DATUM is a COMPOUND_EXPR or COND_EXPR, move our reference inside it
124918334Speter     unless we are not to support things not strictly ANSI.  */
125018334Speter  switch (TREE_CODE (datum))
125118334Speter    {
125218334Speter    case COMPOUND_EXPR:
125318334Speter      {
125418334Speter	tree value = build_component_ref (TREE_OPERAND (datum, 1), component);
125518334Speter	return build (COMPOUND_EXPR, TREE_TYPE (value),
125618334Speter		      TREE_OPERAND (datum, 0), value);
125718334Speter      }
125818334Speter    case COND_EXPR:
125918334Speter      return build_conditional_expr
126018334Speter	(TREE_OPERAND (datum, 0),
126118334Speter	 build_component_ref (TREE_OPERAND (datum, 1), component),
126218334Speter	 build_component_ref (TREE_OPERAND (datum, 2), component));
126350397Sobrien
126450397Sobrien    default:
126550397Sobrien      break;
126618334Speter    }
126718334Speter
126818334Speter  /* See if there is a field or component with name COMPONENT.  */
126918334Speter
127018334Speter  if (code == RECORD_TYPE || code == UNION_TYPE)
127118334Speter    {
127218334Speter      tree indirect = 0;
127318334Speter
127418334Speter      if (TYPE_SIZE (type) == 0)
127518334Speter	{
127618334Speter	  incomplete_type_error (NULL_TREE, type);
127718334Speter	  return error_mark_node;
127818334Speter	}
127918334Speter
128018334Speter      field = lookup_field (type, component, &indirect);
128118334Speter
128218334Speter      if (!field)
128318334Speter	{
128418334Speter	  error (code == RECORD_TYPE
128518334Speter		 ? "structure has no member named `%s'"
128618334Speter		 : "union has no member named `%s'",
128718334Speter		 IDENTIFIER_POINTER (component));
128818334Speter	  return error_mark_node;
128918334Speter	}
129018334Speter      if (TREE_TYPE (field) == error_mark_node)
129118334Speter	return error_mark_node;
129218334Speter
129318334Speter      /* If FIELD was found buried within an anonymous union,
129418334Speter	 make one COMPONENT_REF to get that anonymous union,
129518334Speter	 then fall thru to make a second COMPONENT_REF to get FIELD.  */
129618334Speter      if (indirect != 0)
129718334Speter	{
129818334Speter	  ref = build (COMPONENT_REF, TREE_TYPE (indirect), datum, indirect);
129918334Speter	  if (TREE_READONLY (datum) || TREE_READONLY (indirect))
130018334Speter	    TREE_READONLY (ref) = 1;
130118334Speter	  if (TREE_THIS_VOLATILE (datum) || TREE_THIS_VOLATILE (indirect))
130218334Speter	    TREE_THIS_VOLATILE (ref) = 1;
130318334Speter	  datum = ref;
130418334Speter	}
130518334Speter
130618334Speter      ref = build (COMPONENT_REF, TREE_TYPE (field), datum, field);
130718334Speter
130818334Speter      if (TREE_READONLY (datum) || TREE_READONLY (field))
130918334Speter	TREE_READONLY (ref) = 1;
131018334Speter      if (TREE_THIS_VOLATILE (datum) || TREE_THIS_VOLATILE (field))
131118334Speter	TREE_THIS_VOLATILE (ref) = 1;
131218334Speter
131318334Speter      return ref;
131418334Speter    }
131518334Speter  else if (code != ERROR_MARK)
131618334Speter    error ("request for member `%s' in something not a structure or union",
131718334Speter	    IDENTIFIER_POINTER (component));
131818334Speter
131918334Speter  return error_mark_node;
132018334Speter}
132118334Speter
132218334Speter/* Given an expression PTR for a pointer, return an expression
132318334Speter   for the value pointed to.
132418334Speter   ERRORSTRING is the name of the operator to appear in error messages.  */
132518334Speter
132618334Spetertree
132718334Speterbuild_indirect_ref (ptr, errorstring)
132818334Speter     tree ptr;
132952284Sobrien     const char *errorstring;
133018334Speter{
133118334Speter  register tree pointer = default_conversion (ptr);
133218334Speter  register tree type = TREE_TYPE (pointer);
133318334Speter
133418334Speter  if (TREE_CODE (type) == POINTER_TYPE)
133518334Speter    {
133618334Speter      if (TREE_CODE (pointer) == ADDR_EXPR
133718334Speter	  && !flag_volatile
133818334Speter	  && (TREE_TYPE (TREE_OPERAND (pointer, 0))
133918334Speter	      == TREE_TYPE (type)))
134018334Speter	return TREE_OPERAND (pointer, 0);
134118334Speter      else
134218334Speter	{
134318334Speter	  tree t = TREE_TYPE (type);
134418334Speter	  register tree ref = build1 (INDIRECT_REF,
134518334Speter				      TYPE_MAIN_VARIANT (t), pointer);
134618334Speter
134718334Speter	  if (TYPE_SIZE (t) == 0 && TREE_CODE (t) != ARRAY_TYPE)
134818334Speter	    {
134918334Speter	      error ("dereferencing pointer to incomplete type");
135018334Speter	      return error_mark_node;
135118334Speter	    }
135250397Sobrien	  if (TREE_CODE (t) == VOID_TYPE && skip_evaluation == 0)
135318334Speter	    warning ("dereferencing `void *' pointer");
135418334Speter
135518334Speter	  /* We *must* set TREE_READONLY when dereferencing a pointer to const,
135618334Speter	     so that we get the proper error message if the result is used
135718334Speter	     to assign to.  Also, &* is supposed to be a no-op.
135818334Speter	     And ANSI C seems to specify that the type of the result
135918334Speter	     should be the const type.  */
136018334Speter	  /* A de-reference of a pointer to const is not a const.  It is valid
136118334Speter	     to change it via some other pointer.  */
136218334Speter	  TREE_READONLY (ref) = TYPE_READONLY (t);
136318334Speter	  TREE_SIDE_EFFECTS (ref)
136418334Speter	    = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer) || flag_volatile;
136518334Speter	  TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t);
136618334Speter	  return ref;
136718334Speter	}
136818334Speter    }
136918334Speter  else if (TREE_CODE (pointer) != ERROR_MARK)
137018334Speter    error ("invalid type argument of `%s'", errorstring);
137118334Speter  return error_mark_node;
137218334Speter}
137318334Speter
137418334Speter/* This handles expressions of the form "a[i]", which denotes
137518334Speter   an array reference.
137618334Speter
137718334Speter   This is logically equivalent in C to *(a+i), but we may do it differently.
137818334Speter   If A is a variable or a member, we generate a primitive ARRAY_REF.
137918334Speter   This avoids forcing the array out of registers, and can work on
138018334Speter   arrays that are not lvalues (for example, members of structures returned
138118334Speter   by functions).  */
138218334Speter
138318334Spetertree
138418334Speterbuild_array_ref (array, index)
138518334Speter     tree array, index;
138618334Speter{
138718334Speter  if (index == 0)
138818334Speter    {
138918334Speter      error ("subscript missing in array reference");
139018334Speter      return error_mark_node;
139118334Speter    }
139218334Speter
139318334Speter  if (TREE_TYPE (array) == error_mark_node
139418334Speter      || TREE_TYPE (index) == error_mark_node)
139518334Speter    return error_mark_node;
139618334Speter
139718334Speter  if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE
139818334Speter      && TREE_CODE (array) != INDIRECT_REF)
139918334Speter    {
140018334Speter      tree rval, type;
140118334Speter
140218334Speter      /* Subscripting with type char is likely to lose
140318334Speter	 on a machine where chars are signed.
140418334Speter	 So warn on any machine, but optionally.
140518334Speter	 Don't warn for unsigned char since that type is safe.
140618334Speter	 Don't warn for signed char because anyone who uses that
140718334Speter	 must have done so deliberately.  */
140818334Speter      if (warn_char_subscripts
140918334Speter	  && TYPE_MAIN_VARIANT (TREE_TYPE (index)) == char_type_node)
141018334Speter	warning ("array subscript has type `char'");
141118334Speter
141218334Speter      /* Apply default promotions *after* noticing character types.  */
141318334Speter      index = default_conversion (index);
141418334Speter
141518334Speter      /* Require integer *after* promotion, for sake of enums.  */
141618334Speter      if (TREE_CODE (TREE_TYPE (index)) != INTEGER_TYPE)
141718334Speter	{
141818334Speter	  error ("array subscript is not an integer");
141918334Speter	  return error_mark_node;
142018334Speter	}
142118334Speter
142218334Speter      /* An array that is indexed by a non-constant
142318334Speter	 cannot be stored in a register; we must be able to do
142418334Speter	 address arithmetic on its address.
142518334Speter	 Likewise an array of elements of variable size.  */
142618334Speter      if (TREE_CODE (index) != INTEGER_CST
142718334Speter	  || (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))) != 0
142818334Speter	      && TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array)))) != INTEGER_CST))
142918334Speter	{
143018334Speter	  if (mark_addressable (array) == 0)
143118334Speter	    return error_mark_node;
143218334Speter	}
143318334Speter      /* An array that is indexed by a constant value which is not within
143418334Speter	 the array bounds cannot be stored in a register either; because we
143518334Speter	 would get a crash in store_bit_field/extract_bit_field when trying
143618334Speter	 to access a non-existent part of the register.  */
143718334Speter      if (TREE_CODE (index) == INTEGER_CST
143818334Speter	  && TYPE_VALUES (TREE_TYPE (array))
143918334Speter	  && ! int_fits_type_p (index, TYPE_VALUES (TREE_TYPE (array))))
144018334Speter	{
144118334Speter	  if (mark_addressable (array) == 0)
144218334Speter	    return error_mark_node;
144318334Speter	}
144418334Speter
144518334Speter      if (pedantic && !lvalue_p (array))
144618334Speter	{
144718334Speter	  if (DECL_REGISTER (array))
144818334Speter	    pedwarn ("ANSI C forbids subscripting `register' array");
144918334Speter	  else
145018334Speter	    pedwarn ("ANSI C forbids subscripting non-lvalue array");
145118334Speter	}
145218334Speter
145318334Speter      if (pedantic)
145418334Speter	{
145518334Speter	  tree foo = array;
145618334Speter	  while (TREE_CODE (foo) == COMPONENT_REF)
145718334Speter	    foo = TREE_OPERAND (foo, 0);
145818334Speter	  if (TREE_CODE (foo) == VAR_DECL && DECL_REGISTER (foo))
145918334Speter	    pedwarn ("ANSI C forbids subscripting non-lvalue array");
146018334Speter	}
146118334Speter
146218334Speter      type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (array)));
146318334Speter      rval = build (ARRAY_REF, type, array, index);
146418334Speter      /* Array ref is const/volatile if the array elements are
146518334Speter         or if the array is.  */
146618334Speter      TREE_READONLY (rval)
146718334Speter	|= (TYPE_READONLY (TREE_TYPE (TREE_TYPE (array)))
146818334Speter	    | TREE_READONLY (array));
146918334Speter      TREE_SIDE_EFFECTS (rval)
147018334Speter	|= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array)))
147118334Speter	    | TREE_SIDE_EFFECTS (array));
147218334Speter      TREE_THIS_VOLATILE (rval)
147318334Speter	|= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array)))
147418334Speter	    /* This was added by rms on 16 Nov 91.
147518334Speter	       It fixes  vol struct foo *a;  a->elts[1]
147618334Speter	       in an inline function.
147718334Speter	       Hope it doesn't break something else.  */
147818334Speter	    | TREE_THIS_VOLATILE (array));
147918334Speter      return require_complete_type (fold (rval));
148018334Speter    }
148118334Speter
148218334Speter  {
148318334Speter    tree ar = default_conversion (array);
148418334Speter    tree ind = default_conversion (index);
148518334Speter
148650397Sobrien    /* Do the same warning check as above, but only on the part that's
148750397Sobrien       syntactically the index and only if it is also semantically
148850397Sobrien       the index.  */
148950397Sobrien    if (warn_char_subscripts
149050397Sobrien	&& TREE_CODE (TREE_TYPE (index)) == INTEGER_TYPE
149150397Sobrien	&& TYPE_MAIN_VARIANT (TREE_TYPE (index)) == char_type_node)
149250397Sobrien      warning ("subscript has type `char'");
149350397Sobrien
149418334Speter    /* Put the integer in IND to simplify error checking.  */
149518334Speter    if (TREE_CODE (TREE_TYPE (ar)) == INTEGER_TYPE)
149618334Speter      {
149718334Speter	tree temp = ar;
149818334Speter	ar = ind;
149918334Speter	ind = temp;
150018334Speter      }
150118334Speter
150218334Speter    if (ar == error_mark_node)
150318334Speter      return ar;
150418334Speter
150550397Sobrien    if (TREE_CODE (TREE_TYPE (ar)) != POINTER_TYPE
150650397Sobrien	|| TREE_CODE (TREE_TYPE (TREE_TYPE (ar))) == FUNCTION_TYPE)
150718334Speter      {
150818334Speter	error ("subscripted value is neither array nor pointer");
150918334Speter	return error_mark_node;
151018334Speter      }
151118334Speter    if (TREE_CODE (TREE_TYPE (ind)) != INTEGER_TYPE)
151218334Speter      {
151318334Speter	error ("array subscript is not an integer");
151418334Speter	return error_mark_node;
151518334Speter      }
151618334Speter
151718334Speter    return build_indirect_ref (build_binary_op (PLUS_EXPR, ar, ind, 0),
151818334Speter			       "array indexing");
151918334Speter  }
152018334Speter}
152118334Speter
152218334Speter/* Build a function call to function FUNCTION with parameters PARAMS.
152318334Speter   PARAMS is a list--a chain of TREE_LIST nodes--in which the
152418334Speter   TREE_VALUE of each node is a parameter-expression.
152518334Speter   FUNCTION's data type may be a function type or a pointer-to-function.  */
152618334Speter
152718334Spetertree
152818334Speterbuild_function_call (function, params)
152918334Speter     tree function, params;
153018334Speter{
153118334Speter  register tree fntype, fundecl = 0;
153218334Speter  register tree coerced_params;
153318334Speter  tree name = NULL_TREE, assembler_name = NULL_TREE;
153418334Speter
153518334Speter  /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue.  */
153618334Speter  STRIP_TYPE_NOPS (function);
153718334Speter
153818334Speter  /* Convert anything with function type to a pointer-to-function.  */
153918334Speter  if (TREE_CODE (function) == FUNCTION_DECL)
154018334Speter    {
154118334Speter      name = DECL_NAME (function);
154218334Speter      assembler_name = DECL_ASSEMBLER_NAME (function);
154318334Speter
154418334Speter      /* Differs from default_conversion by not setting TREE_ADDRESSABLE
154518334Speter	 (because calling an inline function does not mean the function
154618334Speter	 needs to be separately compiled).  */
154718334Speter      fntype = build_type_variant (TREE_TYPE (function),
154818334Speter				   TREE_READONLY (function),
154918334Speter				   TREE_THIS_VOLATILE (function));
155018334Speter      fundecl = function;
155118334Speter      function = build1 (ADDR_EXPR, build_pointer_type (fntype), function);
155218334Speter    }
155318334Speter  else
155418334Speter    function = default_conversion (function);
155518334Speter
155618334Speter  fntype = TREE_TYPE (function);
155718334Speter
155818334Speter  if (TREE_CODE (fntype) == ERROR_MARK)
155918334Speter    return error_mark_node;
156018334Speter
156118334Speter  if (!(TREE_CODE (fntype) == POINTER_TYPE
156218334Speter	&& TREE_CODE (TREE_TYPE (fntype)) == FUNCTION_TYPE))
156318334Speter    {
156418334Speter      error ("called object is not a function");
156518334Speter      return error_mark_node;
156618334Speter    }
156718334Speter
156818334Speter  /* fntype now gets the type of function pointed to.  */
156918334Speter  fntype = TREE_TYPE (fntype);
157018334Speter
157118334Speter  /* Convert the parameters to the types declared in the
157218334Speter     function prototype, or apply default promotions.  */
157318334Speter
157418334Speter  coerced_params
157518334Speter    = convert_arguments (TYPE_ARG_TYPES (fntype), params, name, fundecl);
157618334Speter
157718334Speter  /* Check for errors in format strings.  */
157818334Speter
157918334Speter  if (warn_format && (name || assembler_name))
158018334Speter    check_function_format (name, assembler_name, coerced_params);
158118334Speter
158218334Speter  /* Recognize certain built-in functions so we can make tree-codes
158318334Speter     other than CALL_EXPR.  We do this when it enables fold-const.c
158418334Speter     to do something useful.  */
158518334Speter
158618334Speter  if (TREE_CODE (function) == ADDR_EXPR
158718334Speter      && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL
158818334Speter      && DECL_BUILT_IN (TREE_OPERAND (function, 0)))
158918334Speter    switch (DECL_FUNCTION_CODE (TREE_OPERAND (function, 0)))
159018334Speter      {
159118334Speter      case BUILT_IN_ABS:
159218334Speter      case BUILT_IN_LABS:
159318334Speter      case BUILT_IN_FABS:
159418334Speter	if (coerced_params == 0)
159518334Speter	  return integer_zero_node;
159618334Speter	return build_unary_op (ABS_EXPR, TREE_VALUE (coerced_params), 0);
159750397Sobrien      default:
159850397Sobrien	break;
159918334Speter      }
160018334Speter
160118334Speter  {
160218334Speter    register tree result
160318334Speter      = build (CALL_EXPR, TREE_TYPE (fntype),
160418334Speter	       function, coerced_params, NULL_TREE);
160518334Speter
160618334Speter    TREE_SIDE_EFFECTS (result) = 1;
160718334Speter    if (TREE_TYPE (result) == void_type_node)
160818334Speter      return result;
160918334Speter    return require_complete_type (result);
161018334Speter  }
161118334Speter}
161218334Speter
161318334Speter/* Convert the argument expressions in the list VALUES
161418334Speter   to the types in the list TYPELIST.  The result is a list of converted
161518334Speter   argument expressions.
161618334Speter
161718334Speter   If TYPELIST is exhausted, or when an element has NULL as its type,
161818334Speter   perform the default conversions.
161918334Speter
162018334Speter   PARMLIST is the chain of parm decls for the function being called.
162118334Speter   It may be 0, if that info is not available.
162218334Speter   It is used only for generating error messages.
162318334Speter
162418334Speter   NAME is an IDENTIFIER_NODE or 0.  It is used only for error messages.
162518334Speter
162618334Speter   This is also where warnings about wrong number of args are generated.
162718334Speter
162818334Speter   Both VALUES and the returned value are chains of TREE_LIST nodes
162918334Speter   with the elements of the list in the TREE_VALUE slots of those nodes.  */
163018334Speter
163118334Speterstatic tree
163218334Speterconvert_arguments (typelist, values, name, fundecl)
163318334Speter     tree typelist, values, name, fundecl;
163418334Speter{
163518334Speter  register tree typetail, valtail;
163618334Speter  register tree result = NULL;
163718334Speter  int parmnum;
163818334Speter
163918334Speter  /* Scan the given expressions and types, producing individual
164018334Speter     converted arguments and pushing them on RESULT in reverse order.  */
164118334Speter
164218334Speter  for (valtail = values, typetail = typelist, parmnum = 0;
164318334Speter       valtail;
164418334Speter       valtail = TREE_CHAIN (valtail), parmnum++)
164518334Speter    {
164618334Speter      register tree type = typetail ? TREE_VALUE (typetail) : 0;
164718334Speter      register tree val = TREE_VALUE (valtail);
164818334Speter
164918334Speter      if (type == void_type_node)
165018334Speter	{
165118334Speter	  if (name)
165218334Speter	    error ("too many arguments to function `%s'",
165318334Speter		   IDENTIFIER_POINTER (name));
165418334Speter	  else
165518334Speter	    error ("too many arguments to function");
165618334Speter	  break;
165718334Speter	}
165818334Speter
165918334Speter      /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
166018334Speter      /* Do not use STRIP_NOPS here!  We do not want an enumerator with value 0
166118334Speter	 to convert automatically to a pointer.  */
166218334Speter      if (TREE_CODE (val) == NON_LVALUE_EXPR)
166318334Speter	val = TREE_OPERAND (val, 0);
166418334Speter
166518334Speter      if (TREE_CODE (TREE_TYPE (val)) == ARRAY_TYPE
166618334Speter	  || TREE_CODE (TREE_TYPE (val)) == FUNCTION_TYPE)
166718334Speter	val = default_conversion (val);
166818334Speter
166918334Speter      val = require_complete_type (val);
167018334Speter
167118334Speter      if (type != 0)
167218334Speter	{
167318334Speter	  /* Formal parm type is specified by a function prototype.  */
167418334Speter	  tree parmval;
167518334Speter
167618334Speter	  if (TYPE_SIZE (type) == 0)
167718334Speter	    {
167818334Speter	      error ("type of formal parameter %d is incomplete", parmnum + 1);
167918334Speter	      parmval = val;
168018334Speter	    }
168118334Speter	  else
168218334Speter	    {
168318334Speter	      /* Optionally warn about conversions that
168418334Speter		 differ from the default conversions.  */
168518334Speter	      if (warn_conversion)
168618334Speter		{
168718334Speter		  int formal_prec = TYPE_PRECISION (type);
168818334Speter
168918334Speter		  if (INTEGRAL_TYPE_P (type)
169018334Speter		      && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE)
169118334Speter		    warn_for_assignment ("%s as integer rather than floating due to prototype", (char *) 0, name, parmnum + 1);
169218334Speter		  else if (TREE_CODE (type) == COMPLEX_TYPE
169318334Speter			   && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE)
169418334Speter		    warn_for_assignment ("%s as complex rather than floating due to prototype", (char *) 0, name, parmnum + 1);
169518334Speter		  else if (TREE_CODE (type) == REAL_TYPE
169618334Speter			   && INTEGRAL_TYPE_P (TREE_TYPE (val)))
169718334Speter		    warn_for_assignment ("%s as floating rather than integer due to prototype", (char *) 0, name, parmnum + 1);
169818334Speter		  else if (TREE_CODE (type) == REAL_TYPE
169918334Speter			   && TREE_CODE (TREE_TYPE (val)) == COMPLEX_TYPE)
170018334Speter		    warn_for_assignment ("%s as floating rather than complex due to prototype", (char *) 0, name, parmnum + 1);
170118334Speter		  /* ??? At some point, messages should be written about
170218334Speter		     conversions between complex types, but that's too messy
170318334Speter		     to do now.  */
170418334Speter		  else if (TREE_CODE (type) == REAL_TYPE
170518334Speter			   && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE)
170618334Speter		    {
170718334Speter		      /* Warn if any argument is passed as `float',
170818334Speter			 since without a prototype it would be `double'.  */
170918334Speter		      if (formal_prec == TYPE_PRECISION (float_type_node))
171018334Speter			warn_for_assignment ("%s as `float' rather than `double' due to prototype", (char *) 0, name, parmnum + 1);
171118334Speter		    }
171218334Speter		  /* Detect integer changing in width or signedness.  */
171318334Speter		  else if (INTEGRAL_TYPE_P (type)
171418334Speter			   && INTEGRAL_TYPE_P (TREE_TYPE (val)))
171518334Speter		    {
171618334Speter		      tree would_have_been = default_conversion (val);
171718334Speter		      tree type1 = TREE_TYPE (would_have_been);
171818334Speter
171918334Speter		      if (TREE_CODE (type) == ENUMERAL_TYPE
172018334Speter			  && type == TREE_TYPE (val))
172118334Speter			/* No warning if function asks for enum
172218334Speter			   and the actual arg is that enum type.  */
172318334Speter			;
172418334Speter		      else if (formal_prec != TYPE_PRECISION (type1))
172518334Speter			warn_for_assignment ("%s with different width due to prototype", (char *) 0, name, parmnum + 1);
172618334Speter		      else if (TREE_UNSIGNED (type) == TREE_UNSIGNED (type1))
172718334Speter			;
172818334Speter		      /* Don't complain if the formal parameter type
172918334Speter			 is an enum, because we can't tell now whether
173018334Speter			 the value was an enum--even the same enum.  */
173118334Speter		      else if (TREE_CODE (type) == ENUMERAL_TYPE)
173218334Speter			;
173318334Speter		      else if (TREE_CODE (val) == INTEGER_CST
173418334Speter			       && int_fits_type_p (val, type))
173518334Speter			/* Change in signedness doesn't matter
173618334Speter			   if a constant value is unaffected.  */
173718334Speter			;
173818334Speter		      /* Likewise for a constant in a NOP_EXPR.  */
173918334Speter		      else if (TREE_CODE (val) == NOP_EXPR
174018334Speter			       && TREE_CODE (TREE_OPERAND (val, 0)) == INTEGER_CST
174118334Speter			       && int_fits_type_p (TREE_OPERAND (val, 0), type))
174218334Speter			;
174318334Speter#if 0 /* We never get such tree structure here.  */
174418334Speter		      else if (TREE_CODE (TREE_TYPE (val)) == ENUMERAL_TYPE
174518334Speter			       && int_fits_type_p (TYPE_MIN_VALUE (TREE_TYPE (val)), type)
174618334Speter			       && int_fits_type_p (TYPE_MAX_VALUE (TREE_TYPE (val)), type))
174718334Speter			/* Change in signedness doesn't matter
174818334Speter			   if an enum value is unaffected.  */
174918334Speter			;
175018334Speter#endif
175118334Speter		      /* If the value is extended from a narrower
175218334Speter			 unsigned type, it doesn't matter whether we
175318334Speter			 pass it as signed or unsigned; the value
175418334Speter			 certainly is the same either way.  */
175518334Speter		      else if (TYPE_PRECISION (TREE_TYPE (val)) < TYPE_PRECISION (type)
175618334Speter			       && TREE_UNSIGNED (TREE_TYPE (val)))
175718334Speter			;
175818334Speter		      else if (TREE_UNSIGNED (type))
175918334Speter			warn_for_assignment ("%s as unsigned due to prototype", (char *) 0, name, parmnum + 1);
176018334Speter		      else
176118334Speter			warn_for_assignment ("%s as signed due to prototype", (char *) 0, name, parmnum + 1);
176218334Speter		    }
176318334Speter		}
176418334Speter
176518334Speter	      parmval = convert_for_assignment (type, val,
176650397Sobrien					        (char *) 0, /* arg passing  */
176718334Speter						fundecl, name, parmnum + 1);
176818334Speter
176918334Speter#ifdef PROMOTE_PROTOTYPES
177018334Speter	      if ((TREE_CODE (type) == INTEGER_TYPE
177118334Speter		   || TREE_CODE (type) == ENUMERAL_TYPE)
177218334Speter		  && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
177318334Speter		parmval = default_conversion (parmval);
177418334Speter#endif
177518334Speter	    }
177618334Speter	  result = tree_cons (NULL_TREE, parmval, result);
177718334Speter	}
177818334Speter      else if (TREE_CODE (TREE_TYPE (val)) == REAL_TYPE
177918334Speter               && (TYPE_PRECISION (TREE_TYPE (val))
178018334Speter	           < TYPE_PRECISION (double_type_node)))
178118334Speter	/* Convert `float' to `double'.  */
178218334Speter	result = tree_cons (NULL_TREE, convert (double_type_node, val), result);
178318334Speter      else
178418334Speter	/* Convert `short' and `char' to full-size `int'.  */
178518334Speter	result = tree_cons (NULL_TREE, default_conversion (val), result);
178618334Speter
178718334Speter      if (typetail)
178818334Speter	typetail = TREE_CHAIN (typetail);
178918334Speter    }
179018334Speter
179118334Speter  if (typetail != 0 && TREE_VALUE (typetail) != void_type_node)
179218334Speter    {
179318334Speter      if (name)
179418334Speter	error ("too few arguments to function `%s'",
179518334Speter	       IDENTIFIER_POINTER (name));
179618334Speter      else
179718334Speter	error ("too few arguments to function");
179818334Speter    }
179918334Speter
180018334Speter  return nreverse (result);
180118334Speter}
180218334Speter
180318334Speter/* This is the entry point used by the parser
180418334Speter   for binary operators in the input.
180518334Speter   In addition to constructing the expression,
180618334Speter   we check for operands that were written with other binary operators
180718334Speter   in a way that is likely to confuse the user.  */
180818334Speter
180918334Spetertree
181018334Speterparser_build_binary_op (code, arg1, arg2)
181118334Speter     enum tree_code code;
181218334Speter     tree arg1, arg2;
181318334Speter{
181418334Speter  tree result = build_binary_op (code, arg1, arg2, 1);
181518334Speter
181618334Speter  char class;
181718334Speter  char class1 = TREE_CODE_CLASS (TREE_CODE (arg1));
181818334Speter  char class2 = TREE_CODE_CLASS (TREE_CODE (arg2));
181918334Speter  enum tree_code code1 = ERROR_MARK;
182018334Speter  enum tree_code code2 = ERROR_MARK;
182118334Speter
182218334Speter  if (class1 == 'e' || class1 == '1'
182318334Speter      || class1 == '2' || class1 == '<')
182418334Speter    code1 = C_EXP_ORIGINAL_CODE (arg1);
182518334Speter  if (class2 == 'e' || class2 == '1'
182618334Speter      || class2 == '2' || class2 == '<')
182718334Speter    code2 = C_EXP_ORIGINAL_CODE (arg2);
182818334Speter
182918334Speter  /* Check for cases such as x+y<<z which users are likely
183018334Speter     to misinterpret.  If parens are used, C_EXP_ORIGINAL_CODE
183118334Speter     is cleared to prevent these warnings.  */
183218334Speter  if (warn_parentheses)
183318334Speter    {
183418334Speter      if (code == LSHIFT_EXPR || code == RSHIFT_EXPR)
183518334Speter	{
183618334Speter	  if (code1 == PLUS_EXPR || code1 == MINUS_EXPR
183718334Speter	      || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
183818334Speter	    warning ("suggest parentheses around + or - inside shift");
183918334Speter	}
184018334Speter
184118334Speter      if (code == TRUTH_ORIF_EXPR)
184218334Speter	{
184318334Speter	  if (code1 == TRUTH_ANDIF_EXPR
184418334Speter	      || code2 == TRUTH_ANDIF_EXPR)
184518334Speter	    warning ("suggest parentheses around && within ||");
184618334Speter	}
184718334Speter
184818334Speter      if (code == BIT_IOR_EXPR)
184918334Speter	{
185018334Speter	  if (code1 == BIT_AND_EXPR || code1 == BIT_XOR_EXPR
185118334Speter	      || code1 == PLUS_EXPR || code1 == MINUS_EXPR
185218334Speter	      || code2 == BIT_AND_EXPR || code2 == BIT_XOR_EXPR
185318334Speter	      || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
185418334Speter	    warning ("suggest parentheses around arithmetic in operand of |");
185518334Speter	  /* Check cases like x|y==z */
185618334Speter	  if (TREE_CODE_CLASS (code1) == '<' || TREE_CODE_CLASS (code2) == '<')
185718334Speter	    warning ("suggest parentheses around comparison in operand of |");
185818334Speter	}
185918334Speter
186018334Speter      if (code == BIT_XOR_EXPR)
186118334Speter	{
186218334Speter	  if (code1 == BIT_AND_EXPR
186318334Speter	      || code1 == PLUS_EXPR || code1 == MINUS_EXPR
186418334Speter	      || code2 == BIT_AND_EXPR
186518334Speter	      || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
186618334Speter	    warning ("suggest parentheses around arithmetic in operand of ^");
186718334Speter	  /* Check cases like x^y==z */
186818334Speter	  if (TREE_CODE_CLASS (code1) == '<' || TREE_CODE_CLASS (code2) == '<')
186918334Speter	    warning ("suggest parentheses around comparison in operand of ^");
187018334Speter	}
187118334Speter
187218334Speter      if (code == BIT_AND_EXPR)
187318334Speter	{
187418334Speter	  if (code1 == PLUS_EXPR || code1 == MINUS_EXPR
187518334Speter	      || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
187618334Speter	    warning ("suggest parentheses around + or - in operand of &");
187718334Speter	  /* Check cases like x&y==z */
187818334Speter	  if (TREE_CODE_CLASS (code1) == '<' || TREE_CODE_CLASS (code2) == '<')
187918334Speter	    warning ("suggest parentheses around comparison in operand of &");
188018334Speter	}
188118334Speter    }
188218334Speter
188318334Speter  /* Similarly, check for cases like 1<=i<=10 that are probably errors.  */
188418334Speter  if (TREE_CODE_CLASS (code) == '<' && extra_warnings
188518334Speter      && (TREE_CODE_CLASS (code1) == '<' || TREE_CODE_CLASS (code2) == '<'))
188618334Speter    warning ("comparisons like X<=Y<=Z do not have their mathematical meaning");
188718334Speter
188818334Speter  unsigned_conversion_warning (result, arg1);
188918334Speter  unsigned_conversion_warning (result, arg2);
189018334Speter  overflow_warning (result);
189118334Speter
189218334Speter  class = TREE_CODE_CLASS (TREE_CODE (result));
189318334Speter
189418334Speter  /* Record the code that was specified in the source,
189518334Speter     for the sake of warnings about confusing nesting.  */
189618334Speter  if (class == 'e' || class == '1'
189718334Speter      || class == '2' || class == '<')
189818334Speter    C_SET_EXP_ORIGINAL_CODE (result, code);
189918334Speter  else
190018334Speter    {
190118334Speter      int flag = TREE_CONSTANT (result);
190218334Speter      /* We used to use NOP_EXPR rather than NON_LVALUE_EXPR
190318334Speter	 so that convert_for_assignment wouldn't strip it.
190418334Speter	 That way, we got warnings for things like p = (1 - 1).
190518334Speter	 But it turns out we should not get those warnings.  */
190618334Speter      result = build1 (NON_LVALUE_EXPR, TREE_TYPE (result), result);
190718334Speter      C_SET_EXP_ORIGINAL_CODE (result, code);
190818334Speter      TREE_CONSTANT (result) = flag;
190918334Speter    }
191018334Speter
191118334Speter  return result;
191218334Speter}
191318334Speter
191418334Speter/* Build a binary-operation expression without default conversions.
191518334Speter   CODE is the kind of expression to build.
191618334Speter   This function differs from `build' in several ways:
191718334Speter   the data type of the result is computed and recorded in it,
191818334Speter   warnings are generated if arg data types are invalid,
191918334Speter   special handling for addition and subtraction of pointers is known,
192018334Speter   and some optimization is done (operations on narrow ints
192118334Speter   are done in the narrower type when that gives the same result).
192218334Speter   Constant folding is also done before the result is returned.
192318334Speter
192418334Speter   Note that the operands will never have enumeral types, or function
192518334Speter   or array types, because either they will have the default conversions
192618334Speter   performed or they have both just been converted to some other type in which
192718334Speter   the arithmetic is to be done.  */
192818334Speter
192918334Spetertree
193018334Speterbuild_binary_op (code, orig_op0, orig_op1, convert_p)
193118334Speter     enum tree_code code;
193218334Speter     tree orig_op0, orig_op1;
193318334Speter     int convert_p;
193418334Speter{
193518334Speter  tree type0, type1;
193618334Speter  register enum tree_code code0, code1;
193718334Speter  tree op0, op1;
193818334Speter
193918334Speter  /* Expression code to give to the expression when it is built.
194018334Speter     Normally this is CODE, which is what the caller asked for,
194118334Speter     but in some special cases we change it.  */
194218334Speter  register enum tree_code resultcode = code;
194318334Speter
194418334Speter  /* Data type in which the computation is to be performed.
194518334Speter     In the simplest cases this is the common type of the arguments.  */
194618334Speter  register tree result_type = NULL;
194718334Speter
194818334Speter  /* Nonzero means operands have already been type-converted
194918334Speter     in whatever way is necessary.
195018334Speter     Zero means they need to be converted to RESULT_TYPE.  */
195118334Speter  int converted = 0;
195218334Speter
195318334Speter  /* Nonzero means create the expression with this type, rather than
195418334Speter     RESULT_TYPE.  */
195518334Speter  tree build_type = 0;
195618334Speter
195718334Speter  /* Nonzero means after finally constructing the expression
195818334Speter     convert it to this type.  */
195918334Speter  tree final_type = 0;
196018334Speter
196118334Speter  /* Nonzero if this is an operation like MIN or MAX which can
196218334Speter     safely be computed in short if both args are promoted shorts.
196318334Speter     Also implies COMMON.
196418334Speter     -1 indicates a bitwise operation; this makes a difference
196518334Speter     in the exact conditions for when it is safe to do the operation
196618334Speter     in a narrower mode.  */
196718334Speter  int shorten = 0;
196818334Speter
196918334Speter  /* Nonzero if this is a comparison operation;
197018334Speter     if both args are promoted shorts, compare the original shorts.
197118334Speter     Also implies COMMON.  */
197218334Speter  int short_compare = 0;
197318334Speter
197418334Speter  /* Nonzero if this is a right-shift operation, which can be computed on the
197518334Speter     original short and then promoted if the operand is a promoted short.  */
197618334Speter  int short_shift = 0;
197718334Speter
197818334Speter  /* Nonzero means set RESULT_TYPE to the common type of the args.  */
197918334Speter  int common = 0;
198018334Speter
198118334Speter  if (convert_p)
198218334Speter    {
198318334Speter      op0 = default_conversion (orig_op0);
198418334Speter      op1 = default_conversion (orig_op1);
198518334Speter    }
198618334Speter  else
198718334Speter    {
198818334Speter      op0 = orig_op0;
198918334Speter      op1 = orig_op1;
199018334Speter    }
199118334Speter
199218334Speter  type0 = TREE_TYPE (op0);
199318334Speter  type1 = TREE_TYPE (op1);
199418334Speter
199518334Speter  /* The expression codes of the data types of the arguments tell us
199618334Speter     whether the arguments are integers, floating, pointers, etc.  */
199718334Speter  code0 = TREE_CODE (type0);
199818334Speter  code1 = TREE_CODE (type1);
199918334Speter
200018334Speter  /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue.  */
200118334Speter  STRIP_TYPE_NOPS (op0);
200218334Speter  STRIP_TYPE_NOPS (op1);
200318334Speter
200418334Speter  /* If an error was already reported for one of the arguments,
200518334Speter     avoid reporting another error.  */
200618334Speter
200718334Speter  if (code0 == ERROR_MARK || code1 == ERROR_MARK)
200818334Speter    return error_mark_node;
200918334Speter
201018334Speter  switch (code)
201118334Speter    {
201218334Speter    case PLUS_EXPR:
201318334Speter      /* Handle the pointer + int case.  */
201418334Speter      if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
201518334Speter	return pointer_int_sum (PLUS_EXPR, op0, op1);
201618334Speter      else if (code1 == POINTER_TYPE && code0 == INTEGER_TYPE)
201718334Speter	return pointer_int_sum (PLUS_EXPR, op1, op0);
201818334Speter      else
201918334Speter	common = 1;
202018334Speter      break;
202118334Speter
202218334Speter    case MINUS_EXPR:
202318334Speter      /* Subtraction of two similar pointers.
202418334Speter	 We must subtract them as integers, then divide by object size.  */
202518334Speter      if (code0 == POINTER_TYPE && code1 == POINTER_TYPE
202618334Speter	  && comp_target_types (type0, type1))
202718334Speter	return pointer_diff (op0, op1);
202818334Speter      /* Handle pointer minus int.  Just like pointer plus int.  */
202918334Speter      else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
203018334Speter	return pointer_int_sum (MINUS_EXPR, op0, op1);
203118334Speter      else
203218334Speter	common = 1;
203318334Speter      break;
203418334Speter
203518334Speter    case MULT_EXPR:
203618334Speter      common = 1;
203718334Speter      break;
203818334Speter
203918334Speter    case TRUNC_DIV_EXPR:
204018334Speter    case CEIL_DIV_EXPR:
204118334Speter    case FLOOR_DIV_EXPR:
204218334Speter    case ROUND_DIV_EXPR:
204318334Speter    case EXACT_DIV_EXPR:
204418334Speter      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
204518334Speter	   || code0 == COMPLEX_TYPE)
204618334Speter	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
204718334Speter	      || code1 == COMPLEX_TYPE))
204818334Speter	{
204918334Speter	  if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE))
205018334Speter	    resultcode = RDIV_EXPR;
205118334Speter	  else
205218334Speter	    {
205318334Speter	      /* Although it would be tempting to shorten always here, that
205418334Speter		 loses on some targets, since the modulo instruction is
205518334Speter		 undefined if the quotient can't be represented in the
205618334Speter		 computation mode.  We shorten only if unsigned or if
205718334Speter		 dividing by something we know != -1.  */
205818334Speter	      shorten = (TREE_UNSIGNED (TREE_TYPE (orig_op0))
205918334Speter			 || (TREE_CODE (op1) == INTEGER_CST
206018334Speter			     && (TREE_INT_CST_LOW (op1) != -1
206118334Speter				 || TREE_INT_CST_HIGH (op1) != -1)));
206218334Speter	    }
206318334Speter	  common = 1;
206418334Speter	}
206518334Speter      break;
206618334Speter
206718334Speter    case BIT_AND_EXPR:
206818334Speter    case BIT_ANDTC_EXPR:
206918334Speter    case BIT_IOR_EXPR:
207018334Speter    case BIT_XOR_EXPR:
207118334Speter      if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
207218334Speter	shorten = -1;
207318334Speter      /* If one operand is a constant, and the other is a short type
207418334Speter	 that has been converted to an int,
207518334Speter	 really do the work in the short type and then convert the
207618334Speter	 result to int.  If we are lucky, the constant will be 0 or 1
207718334Speter	 in the short type, making the entire operation go away.  */
207818334Speter      if (TREE_CODE (op0) == INTEGER_CST
207918334Speter	  && TREE_CODE (op1) == NOP_EXPR
208018334Speter	  && TYPE_PRECISION (type1) > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op1, 0)))
208118334Speter	  && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op1, 0))))
208218334Speter	{
208318334Speter	  final_type = result_type;
208418334Speter	  op1 = TREE_OPERAND (op1, 0);
208518334Speter	  result_type = TREE_TYPE (op1);
208618334Speter	}
208718334Speter      if (TREE_CODE (op1) == INTEGER_CST
208818334Speter	  && TREE_CODE (op0) == NOP_EXPR
208918334Speter	  && TYPE_PRECISION (type0) > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0)))
209018334Speter	  && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0))))
209118334Speter	{
209218334Speter	  final_type = result_type;
209318334Speter	  op0 = TREE_OPERAND (op0, 0);
209418334Speter	  result_type = TREE_TYPE (op0);
209518334Speter	}
209618334Speter      break;
209718334Speter
209818334Speter    case TRUNC_MOD_EXPR:
209918334Speter    case FLOOR_MOD_EXPR:
210018334Speter      if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
210118334Speter	{
210218334Speter	  /* Although it would be tempting to shorten always here, that loses
210318334Speter	     on some targets, since the modulo instruction is undefined if the
210418334Speter	     quotient can't be represented in the computation mode.  We shorten
210518334Speter	     only if unsigned or if dividing by something we know != -1.  */
210618334Speter	  shorten = (TREE_UNSIGNED (TREE_TYPE (orig_op0))
210718334Speter		     || (TREE_CODE (op1) == INTEGER_CST
210818334Speter			 && (TREE_INT_CST_LOW (op1) != -1
210918334Speter			     || TREE_INT_CST_HIGH (op1) != -1)));
211018334Speter	  common = 1;
211118334Speter	}
211218334Speter      break;
211318334Speter
211418334Speter    case TRUTH_ANDIF_EXPR:
211518334Speter    case TRUTH_ORIF_EXPR:
211618334Speter    case TRUTH_AND_EXPR:
211718334Speter    case TRUTH_OR_EXPR:
211818334Speter    case TRUTH_XOR_EXPR:
211918334Speter      if ((code0 == INTEGER_TYPE || code0 == POINTER_TYPE
212018334Speter	   || code0 == REAL_TYPE || code0 == COMPLEX_TYPE)
212118334Speter	  && (code1 == INTEGER_TYPE || code1 == POINTER_TYPE
212218334Speter	      || code1 == REAL_TYPE || code1 == COMPLEX_TYPE))
212318334Speter	{
212418334Speter	  /* Result of these operations is always an int,
212518334Speter	     but that does not mean the operands should be
212618334Speter	     converted to ints!  */
212718334Speter	  result_type = integer_type_node;
212818334Speter	  op0 = truthvalue_conversion (op0);
212918334Speter	  op1 = truthvalue_conversion (op1);
213018334Speter	  converted = 1;
213118334Speter	}
213218334Speter      break;
213318334Speter
213418334Speter      /* Shift operations: result has same type as first operand;
213518334Speter	 always convert second operand to int.
213618334Speter	 Also set SHORT_SHIFT if shifting rightward.  */
213718334Speter
213818334Speter    case RSHIFT_EXPR:
213918334Speter      if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
214018334Speter	{
214150397Sobrien	  if (TREE_CODE (op1) == INTEGER_CST && skip_evaluation == 0)
214218334Speter	    {
214318334Speter	      if (tree_int_cst_sgn (op1) < 0)
214418334Speter		warning ("right shift count is negative");
214518334Speter	      else
214618334Speter		{
214718334Speter		  if (TREE_INT_CST_LOW (op1) | TREE_INT_CST_HIGH (op1))
214818334Speter		    short_shift = 1;
214918334Speter		  if (TREE_INT_CST_HIGH (op1) != 0
215018334Speter		      || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1)
215118334Speter			  >= TYPE_PRECISION (type0)))
215218334Speter		    warning ("right shift count >= width of type");
215318334Speter		}
215418334Speter	    }
215518334Speter	  /* Use the type of the value to be shifted.
215618334Speter	     This is what most traditional C compilers do.  */
215718334Speter	  result_type = type0;
215818334Speter	  /* Unless traditional, convert the shift-count to an integer,
215918334Speter	     regardless of size of value being shifted.  */
216018334Speter	  if (! flag_traditional)
216118334Speter	    {
216218334Speter	      if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
216318334Speter		op1 = convert (integer_type_node, op1);
216418334Speter	      /* Avoid converting op1 to result_type later.  */
216518334Speter	      converted = 1;
216618334Speter	    }
216718334Speter	}
216818334Speter      break;
216918334Speter
217018334Speter    case LSHIFT_EXPR:
217118334Speter      if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
217218334Speter	{
217350397Sobrien	  if (TREE_CODE (op1) == INTEGER_CST && skip_evaluation == 0)
217418334Speter	    {
217518334Speter	      if (tree_int_cst_sgn (op1) < 0)
217618334Speter		warning ("left shift count is negative");
217718334Speter	      else if (TREE_INT_CST_HIGH (op1) != 0
217818334Speter		       || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1)
217918334Speter			   >= TYPE_PRECISION (type0)))
218018334Speter		warning ("left shift count >= width of type");
218118334Speter	    }
218218334Speter	  /* Use the type of the value to be shifted.
218318334Speter	     This is what most traditional C compilers do.  */
218418334Speter	  result_type = type0;
218518334Speter	  /* Unless traditional, convert the shift-count to an integer,
218618334Speter	     regardless of size of value being shifted.  */
218718334Speter	  if (! flag_traditional)
218818334Speter	    {
218918334Speter	      if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
219018334Speter		op1 = convert (integer_type_node, op1);
219118334Speter	      /* Avoid converting op1 to result_type later.  */
219218334Speter	      converted = 1;
219318334Speter	    }
219418334Speter	}
219518334Speter      break;
219618334Speter
219718334Speter    case RROTATE_EXPR:
219818334Speter    case LROTATE_EXPR:
219918334Speter      if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
220018334Speter	{
220150397Sobrien	  if (TREE_CODE (op1) == INTEGER_CST && skip_evaluation == 0)
220218334Speter	    {
220318334Speter	      if (tree_int_cst_sgn (op1) < 0)
220418334Speter		warning ("shift count is negative");
220518334Speter	      else if (TREE_INT_CST_HIGH (op1) != 0
220618334Speter		       || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1)
220718334Speter			   >= TYPE_PRECISION (type0)))
220818334Speter		warning ("shift count >= width of type");
220918334Speter	    }
221018334Speter	  /* Use the type of the value to be shifted.
221118334Speter	     This is what most traditional C compilers do.  */
221218334Speter	  result_type = type0;
221318334Speter	  /* Unless traditional, convert the shift-count to an integer,
221418334Speter	     regardless of size of value being shifted.  */
221518334Speter	  if (! flag_traditional)
221618334Speter	    {
221718334Speter	      if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
221818334Speter		op1 = convert (integer_type_node, op1);
221918334Speter	      /* Avoid converting op1 to result_type later.  */
222018334Speter	      converted = 1;
222118334Speter	    }
222218334Speter	}
222318334Speter      break;
222418334Speter
222518334Speter    case EQ_EXPR:
222618334Speter    case NE_EXPR:
222718334Speter      /* Result of comparison is always int,
222818334Speter	 but don't convert the args to int!  */
222918334Speter      build_type = integer_type_node;
223018334Speter      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
223118334Speter	   || code0 == COMPLEX_TYPE)
223218334Speter	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
223318334Speter	      || code1 == COMPLEX_TYPE))
223418334Speter	short_compare = 1;
223518334Speter      else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
223618334Speter	{
223718334Speter	  register tree tt0 = TREE_TYPE (type0);
223818334Speter	  register tree tt1 = TREE_TYPE (type1);
223918334Speter	  /* Anything compares with void *.  void * compares with anything.
224018334Speter	     Otherwise, the targets must be compatible
224118334Speter	     and both must be object or both incomplete.  */
224218334Speter	  if (comp_target_types (type0, type1))
224318334Speter	    result_type = common_type (type0, type1);
224418334Speter	  else if (TYPE_MAIN_VARIANT (tt0) == void_type_node)
224518334Speter	    {
224618334Speter	      /* op0 != orig_op0 detects the case of something
224718334Speter		 whose value is 0 but which isn't a valid null ptr const.  */
224818334Speter	      if (pedantic && (!integer_zerop (op0) || op0 != orig_op0)
224918334Speter		  && TREE_CODE (tt1) == FUNCTION_TYPE)
225018334Speter		pedwarn ("ANSI C forbids comparison of `void *' with function pointer");
225118334Speter	    }
225218334Speter	  else if (TYPE_MAIN_VARIANT (tt1) == void_type_node)
225318334Speter	    {
225418334Speter	      if (pedantic && (!integer_zerop (op1) || op1 != orig_op1)
225518334Speter		  && TREE_CODE (tt0) == FUNCTION_TYPE)
225618334Speter		pedwarn ("ANSI C forbids comparison of `void *' with function pointer");
225718334Speter	    }
225818334Speter	  else
225918334Speter	    pedwarn ("comparison of distinct pointer types lacks a cast");
226018334Speter
226118334Speter	  if (result_type == NULL_TREE)
226218334Speter	    result_type = ptr_type_node;
226318334Speter	}
226418334Speter      else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST
226518334Speter	       && integer_zerop (op1))
226618334Speter	result_type = type0;
226718334Speter      else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST
226818334Speter	       && integer_zerop (op0))
226918334Speter	result_type = type1;
227018334Speter      else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
227118334Speter	{
227218334Speter	  result_type = type0;
227318334Speter	  if (! flag_traditional)
227418334Speter	    pedwarn ("comparison between pointer and integer");
227518334Speter	}
227618334Speter      else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
227718334Speter	{
227818334Speter	  result_type = type1;
227918334Speter	  if (! flag_traditional)
228018334Speter	    pedwarn ("comparison between pointer and integer");
228118334Speter	}
228218334Speter      break;
228318334Speter
228418334Speter    case MAX_EXPR:
228518334Speter    case MIN_EXPR:
228618334Speter      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
228718334Speter	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
228818334Speter	shorten = 1;
228918334Speter      else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
229018334Speter	{
229118334Speter	  if (comp_target_types (type0, type1))
229218334Speter	    {
229318334Speter	      result_type = common_type (type0, type1);
229418334Speter	      if (pedantic
229518334Speter		  && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
229618334Speter		pedwarn ("ANSI C forbids ordered comparisons of pointers to functions");
229718334Speter	    }
229818334Speter	  else
229918334Speter	    {
230018334Speter	      result_type = ptr_type_node;
230118334Speter	      pedwarn ("comparison of distinct pointer types lacks a cast");
230218334Speter	    }
230318334Speter	}
230418334Speter      break;
230518334Speter
230618334Speter    case LE_EXPR:
230718334Speter    case GE_EXPR:
230818334Speter    case LT_EXPR:
230918334Speter    case GT_EXPR:
231018334Speter      build_type = integer_type_node;
231118334Speter      if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
231218334Speter	  && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
231318334Speter	short_compare = 1;
231418334Speter      else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
231518334Speter	{
231618334Speter	  if (comp_target_types (type0, type1))
231718334Speter	    {
231818334Speter	      result_type = common_type (type0, type1);
231918334Speter	      if ((TYPE_SIZE (TREE_TYPE (type0)) != 0)
232018334Speter		  != (TYPE_SIZE (TREE_TYPE (type1)) != 0))
232118334Speter		pedwarn ("comparison of complete and incomplete pointers");
232218334Speter	      else if (pedantic
232318334Speter		       && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
232418334Speter		pedwarn ("ANSI C forbids ordered comparisons of pointers to functions");
232518334Speter	    }
232618334Speter	  else
232718334Speter	    {
232818334Speter	      result_type = ptr_type_node;
232918334Speter	      pedwarn ("comparison of distinct pointer types lacks a cast");
233018334Speter	    }
233118334Speter	}
233218334Speter      else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST
233318334Speter	       && integer_zerop (op1))
233418334Speter	{
233518334Speter	  result_type = type0;
233618334Speter	  if (pedantic || extra_warnings)
233718334Speter	    pedwarn ("ordered comparison of pointer with integer zero");
233818334Speter	}
233918334Speter      else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST
234018334Speter	       && integer_zerop (op0))
234118334Speter	{
234218334Speter	  result_type = type1;
234318334Speter	  if (pedantic)
234418334Speter	    pedwarn ("ordered comparison of pointer with integer zero");
234518334Speter	}
234618334Speter      else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
234718334Speter	{
234818334Speter	  result_type = type0;
234918334Speter	  if (! flag_traditional)
235018334Speter	    pedwarn ("comparison between pointer and integer");
235118334Speter	}
235218334Speter      else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
235318334Speter	{
235418334Speter	  result_type = type1;
235518334Speter	  if (! flag_traditional)
235618334Speter	    pedwarn ("comparison between pointer and integer");
235718334Speter	}
235818334Speter      break;
235950397Sobrien
236050397Sobrien    default:
236150397Sobrien      break;
236218334Speter    }
236318334Speter
236418334Speter  if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE)
236518334Speter      &&
236618334Speter      (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE))
236718334Speter    {
236818334Speter      int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE);
236918334Speter
237018334Speter      if (shorten || common || short_compare)
237118334Speter	result_type = common_type (type0, type1);
237218334Speter
237318334Speter      /* For certain operations (which identify themselves by shorten != 0)
237418334Speter	 if both args were extended from the same smaller type,
237518334Speter	 do the arithmetic in that type and then extend.
237618334Speter
237718334Speter	 shorten !=0 and !=1 indicates a bitwise operation.
237818334Speter	 For them, this optimization is safe only if
237918334Speter	 both args are zero-extended or both are sign-extended.
238018334Speter	 Otherwise, we might change the result.
238118334Speter	 Eg, (short)-1 | (unsigned short)-1 is (int)-1
238218334Speter	 but calculated in (unsigned short) it would be (unsigned short)-1.  */
238318334Speter
238418334Speter      if (shorten && none_complex)
238518334Speter	{
238618334Speter	  int unsigned0, unsigned1;
238718334Speter	  tree arg0 = get_narrower (op0, &unsigned0);
238818334Speter	  tree arg1 = get_narrower (op1, &unsigned1);
238918334Speter	  /* UNS is 1 if the operation to be done is an unsigned one.  */
239018334Speter	  int uns = TREE_UNSIGNED (result_type);
239118334Speter	  tree type;
239218334Speter
239318334Speter	  final_type = result_type;
239418334Speter
239518334Speter	  /* Handle the case that OP0 (or OP1) does not *contain* a conversion
239618334Speter	     but it *requires* conversion to FINAL_TYPE.  */
239718334Speter
239818334Speter	  if ((TYPE_PRECISION (TREE_TYPE (op0))
239918334Speter	       == TYPE_PRECISION (TREE_TYPE (arg0)))
240018334Speter	      && TREE_TYPE (op0) != final_type)
240118334Speter	    unsigned0 = TREE_UNSIGNED (TREE_TYPE (op0));
240218334Speter	  if ((TYPE_PRECISION (TREE_TYPE (op1))
240318334Speter	       == TYPE_PRECISION (TREE_TYPE (arg1)))
240418334Speter	      && TREE_TYPE (op1) != final_type)
240518334Speter	    unsigned1 = TREE_UNSIGNED (TREE_TYPE (op1));
240618334Speter
240718334Speter	  /* Now UNSIGNED0 is 1 if ARG0 zero-extends to FINAL_TYPE.  */
240818334Speter
240918334Speter	  /* For bitwise operations, signedness of nominal type
241018334Speter	     does not matter.  Consider only how operands were extended.  */
241118334Speter	  if (shorten == -1)
241218334Speter	    uns = unsigned0;
241318334Speter
241418334Speter	  /* Note that in all three cases below we refrain from optimizing
241518334Speter	     an unsigned operation on sign-extended args.
241618334Speter	     That would not be valid.  */
241718334Speter
241818334Speter	  /* Both args variable: if both extended in same way
241918334Speter	     from same width, do it in that width.
242018334Speter	     Do it unsigned if args were zero-extended.  */
242118334Speter	  if ((TYPE_PRECISION (TREE_TYPE (arg0))
242218334Speter	       < TYPE_PRECISION (result_type))
242318334Speter	      && (TYPE_PRECISION (TREE_TYPE (arg1))
242418334Speter		  == TYPE_PRECISION (TREE_TYPE (arg0)))
242518334Speter	      && unsigned0 == unsigned1
242618334Speter	      && (unsigned0 || !uns))
242718334Speter	    result_type
242818334Speter	      = signed_or_unsigned_type (unsigned0,
242918334Speter					 common_type (TREE_TYPE (arg0), TREE_TYPE (arg1)));
243018334Speter	  else if (TREE_CODE (arg0) == INTEGER_CST
243118334Speter		   && (unsigned1 || !uns)
243218334Speter		   && (TYPE_PRECISION (TREE_TYPE (arg1))
243318334Speter		       < TYPE_PRECISION (result_type))
243418334Speter		   && (type = signed_or_unsigned_type (unsigned1,
243518334Speter						       TREE_TYPE (arg1)),
243618334Speter		       int_fits_type_p (arg0, type)))
243718334Speter	    result_type = type;
243818334Speter	  else if (TREE_CODE (arg1) == INTEGER_CST
243918334Speter		   && (unsigned0 || !uns)
244018334Speter		   && (TYPE_PRECISION (TREE_TYPE (arg0))
244118334Speter		       < TYPE_PRECISION (result_type))
244218334Speter		   && (type = signed_or_unsigned_type (unsigned0,
244318334Speter						       TREE_TYPE (arg0)),
244418334Speter		       int_fits_type_p (arg1, type)))
244518334Speter	    result_type = type;
244618334Speter	}
244718334Speter
244818334Speter      /* Shifts can be shortened if shifting right.  */
244918334Speter
245018334Speter      if (short_shift)
245118334Speter	{
245218334Speter	  int unsigned_arg;
245318334Speter	  tree arg0 = get_narrower (op0, &unsigned_arg);
245418334Speter
245518334Speter	  final_type = result_type;
245618334Speter
245718334Speter	  if (arg0 == op0 && final_type == TREE_TYPE (op0))
245818334Speter	    unsigned_arg = TREE_UNSIGNED (TREE_TYPE (op0));
245918334Speter
246018334Speter	  if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type)
246118334Speter	      /* We can shorten only if the shift count is less than the
246218334Speter		 number of bits in the smaller type size.  */
246318334Speter	      && TREE_INT_CST_HIGH (op1) == 0
246418334Speter	      && TYPE_PRECISION (TREE_TYPE (arg0)) > TREE_INT_CST_LOW (op1)
246518334Speter	      /* If arg is sign-extended and then unsigned-shifted,
246618334Speter		 we can simulate this with a signed shift in arg's type
246718334Speter		 only if the extended result is at least twice as wide
246818334Speter		 as the arg.  Otherwise, the shift could use up all the
246918334Speter		 ones made by sign-extension and bring in zeros.
247018334Speter		 We can't optimize that case at all, but in most machines
247118334Speter		 it never happens because available widths are 2**N.  */
247218334Speter	      && (!TREE_UNSIGNED (final_type)
247318334Speter		  || unsigned_arg
247418334Speter		  || 2 * TYPE_PRECISION (TREE_TYPE (arg0)) <= TYPE_PRECISION (result_type)))
247518334Speter	    {
247618334Speter	      /* Do an unsigned shift if the operand was zero-extended.  */
247718334Speter	      result_type
247818334Speter		= signed_or_unsigned_type (unsigned_arg,
247918334Speter					   TREE_TYPE (arg0));
248018334Speter	      /* Convert value-to-be-shifted to that type.  */
248118334Speter	      if (TREE_TYPE (op0) != result_type)
248218334Speter		op0 = convert (result_type, op0);
248318334Speter	      converted = 1;
248418334Speter	    }
248518334Speter	}
248618334Speter
248718334Speter      /* Comparison operations are shortened too but differently.
248818334Speter	 They identify themselves by setting short_compare = 1.  */
248918334Speter
249018334Speter      if (short_compare)
249118334Speter	{
249218334Speter	  /* Don't write &op0, etc., because that would prevent op0
249318334Speter	     from being kept in a register.
249418334Speter	     Instead, make copies of the our local variables and
249518334Speter	     pass the copies by reference, then copy them back afterward.  */
249618334Speter	  tree xop0 = op0, xop1 = op1, xresult_type = result_type;
249718334Speter	  enum tree_code xresultcode = resultcode;
249818334Speter	  tree val
249918334Speter	    = shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode);
250018334Speter	  if (val != 0)
250118334Speter	    return val;
250218334Speter	  op0 = xop0, op1 = xop1;
250318334Speter	  converted = 1;
250418334Speter	  resultcode = xresultcode;
250518334Speter
250650397Sobrien	  if ((warn_sign_compare < 0 ? extra_warnings : warn_sign_compare != 0)
250750397Sobrien	      && skip_evaluation == 0)
250818334Speter	    {
250918334Speter	      int op0_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op0));
251018334Speter	      int op1_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op1));
251118334Speter
251218334Speter	      int unsignedp0, unsignedp1;
251318334Speter	      tree primop0 = get_narrower (op0, &unsignedp0);
251418334Speter	      tree primop1 = get_narrower (op1, &unsignedp1);
251518334Speter
251618334Speter	      /* Avoid spurious warnings for comparison with enumerators.  */
251718334Speter
251818334Speter	      xop0 = orig_op0;
251918334Speter	      xop1 = orig_op1;
252018334Speter	      STRIP_TYPE_NOPS (xop0);
252118334Speter	      STRIP_TYPE_NOPS (xop1);
252218334Speter
252318334Speter	      /* Give warnings for comparisons between signed and unsigned
252418334Speter		 quantities that may fail.  */
252518334Speter	      /* Do the checking based on the original operand trees, so that
252618334Speter		 casts will be considered, but default promotions won't be.  */
252718334Speter
252818334Speter	      /* Do not warn if the comparison is being done in a signed type,
252918334Speter		 since the signed type will only be chosen if it can represent
253018334Speter		 all the values of the unsigned type.  */
253118334Speter	      if (! TREE_UNSIGNED (result_type))
253218334Speter		/* OK */;
253318334Speter              /* Do not warn if both operands are unsigned.  */
253418334Speter              else if (op0_signed == op1_signed)
253518334Speter                /* OK */;
253618334Speter	      /* Do not warn if the signed quantity is an unsuffixed
253718334Speter		 integer literal (or some static constant expression
253818334Speter		 involving such literals) and it is non-negative.  */
253918334Speter	      else if ((op0_signed && TREE_CODE (xop0) == INTEGER_CST
254018334Speter			&& tree_int_cst_sgn (xop0) >= 0)
254118334Speter		       || (op1_signed && TREE_CODE (xop1) == INTEGER_CST
254218334Speter			   && tree_int_cst_sgn (xop1) >= 0))
254318334Speter		/* OK */;
254418334Speter	      /* Do not warn if the comparison is an equality operation,
254518334Speter                 the unsigned quantity is an integral constant and it does
254618334Speter                 not use the most significant bit of result_type.  */
254718334Speter	      else if ((resultcode == EQ_EXPR || resultcode == NE_EXPR)
254818334Speter		       && ((op0_signed && TREE_CODE (xop1) == INTEGER_CST
254950397Sobrien			    && int_fits_type_p (xop1, signed_type (result_type)))
255018334Speter			   || (op1_signed && TREE_CODE (xop0) == INTEGER_CST
255150397Sobrien			       && int_fits_type_p (xop0, signed_type (result_type)))))
255218334Speter		/* OK */;
255318334Speter	      else
255418334Speter		warning ("comparison between signed and unsigned");
255518334Speter
255618334Speter	      /* Warn if two unsigned values are being compared in a size
255718334Speter		 larger than their original size, and one (and only one) is the
255818334Speter		 result of a `~' operator.  This comparison will always fail.
255918334Speter
256018334Speter		 Also warn if one operand is a constant, and the constant
256118334Speter		 does not have all bits set that are set in the ~ operand
256218334Speter		 when it is extended.  */
256318334Speter
256418334Speter	      if ((TREE_CODE (primop0) == BIT_NOT_EXPR)
256518334Speter		  != (TREE_CODE (primop1) == BIT_NOT_EXPR))
256618334Speter		{
256718334Speter		  if (TREE_CODE (primop0) == BIT_NOT_EXPR)
256818334Speter		    primop0 = get_narrower (TREE_OPERAND (primop0, 0),
256918334Speter					    &unsignedp0);
257018334Speter		  else
257118334Speter		    primop1 = get_narrower (TREE_OPERAND (primop1, 0),
257218334Speter					    &unsignedp1);
257318334Speter
257418334Speter		  if (TREE_CODE (primop0) == INTEGER_CST
257518334Speter		      || TREE_CODE (primop1) == INTEGER_CST)
257618334Speter		    {
257718334Speter		      tree primop;
257818334Speter		      long constant, mask;
257918334Speter		      int unsignedp, bits;
258018334Speter
258118334Speter		      if (TREE_CODE (primop0) == INTEGER_CST)
258218334Speter			{
258318334Speter			  primop = primop1;
258418334Speter			  unsignedp = unsignedp1;
258518334Speter			  constant = TREE_INT_CST_LOW (primop0);
258618334Speter			}
258718334Speter		      else
258818334Speter			{
258918334Speter			  primop = primop0;
259018334Speter			  unsignedp = unsignedp0;
259118334Speter			  constant = TREE_INT_CST_LOW (primop1);
259218334Speter			}
259318334Speter
259418334Speter		      bits = TYPE_PRECISION (TREE_TYPE (primop));
259518334Speter		      if (bits < TYPE_PRECISION (result_type)
259618334Speter			  && bits < HOST_BITS_PER_LONG && unsignedp)
259718334Speter			{
259818334Speter			  mask = (~0L) << bits;
259918334Speter			  if ((mask & constant) != mask)
260018334Speter			    warning ("comparison of promoted ~unsigned with constant");
260118334Speter			}
260218334Speter		    }
260318334Speter		  else if (unsignedp0 && unsignedp1
260418334Speter			   && (TYPE_PRECISION (TREE_TYPE (primop0))
260518334Speter			       < TYPE_PRECISION (result_type))
260618334Speter			   && (TYPE_PRECISION (TREE_TYPE (primop1))
260718334Speter			       < TYPE_PRECISION (result_type)))
260818334Speter		    warning ("comparison of promoted ~unsigned with unsigned");
260918334Speter		}
261018334Speter	    }
261118334Speter	}
261218334Speter    }
261318334Speter
261418334Speter  /* At this point, RESULT_TYPE must be nonzero to avoid an error message.
261518334Speter     If CONVERTED is zero, both args will be converted to type RESULT_TYPE.
261618334Speter     Then the expression will be built.
261718334Speter     It will be given type FINAL_TYPE if that is nonzero;
261818334Speter     otherwise, it will be given type RESULT_TYPE.  */
261918334Speter
262018334Speter  if (!result_type)
262118334Speter    {
262218334Speter      binary_op_error (code);
262318334Speter      return error_mark_node;
262418334Speter    }
262518334Speter
262618334Speter  if (! converted)
262718334Speter    {
262818334Speter      if (TREE_TYPE (op0) != result_type)
262918334Speter	op0 = convert (result_type, op0);
263018334Speter      if (TREE_TYPE (op1) != result_type)
263118334Speter	op1 = convert (result_type, op1);
263218334Speter    }
263318334Speter
263418334Speter  if (build_type == NULL_TREE)
263518334Speter    build_type = result_type;
263618334Speter
263718334Speter  {
263818334Speter    register tree result = build (resultcode, build_type, op0, op1);
263918334Speter    register tree folded;
264018334Speter
264118334Speter    folded = fold (result);
264218334Speter    if (folded == result)
264318334Speter      TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1);
264418334Speter    if (final_type != 0)
264518334Speter      return convert (final_type, folded);
264618334Speter    return folded;
264718334Speter  }
264818334Speter}
264918334Speter
265018334Speter/* Return a tree for the sum or difference (RESULTCODE says which)
265118334Speter   of pointer PTROP and integer INTOP.  */
265218334Speter
265318334Speterstatic tree
265418334Speterpointer_int_sum (resultcode, ptrop, intop)
265518334Speter     enum tree_code resultcode;
265618334Speter     register tree ptrop, intop;
265718334Speter{
265818334Speter  tree size_exp;
265918334Speter
266018334Speter  register tree result;
266118334Speter  register tree folded;
266218334Speter
266318334Speter  /* The result is a pointer of the same type that is being added.  */
266418334Speter
266518334Speter  register tree result_type = TREE_TYPE (ptrop);
266618334Speter
266718334Speter  if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)
266818334Speter    {
266918334Speter      if (pedantic || warn_pointer_arith)
267018334Speter	pedwarn ("pointer of type `void *' used in arithmetic");
267118334Speter      size_exp = integer_one_node;
267218334Speter    }
267318334Speter  else if (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE)
267418334Speter    {
267518334Speter      if (pedantic || warn_pointer_arith)
267618334Speter	pedwarn ("pointer to a function used in arithmetic");
267718334Speter      size_exp = integer_one_node;
267818334Speter    }
267918334Speter  else
268018334Speter    size_exp = c_size_in_bytes (TREE_TYPE (result_type));
268118334Speter
268218334Speter  /* If what we are about to multiply by the size of the elements
268318334Speter     contains a constant term, apply distributive law
268418334Speter     and multiply that constant term separately.
268518334Speter     This helps produce common subexpressions.  */
268618334Speter
268718334Speter  if ((TREE_CODE (intop) == PLUS_EXPR || TREE_CODE (intop) == MINUS_EXPR)
268818334Speter      && ! TREE_CONSTANT (intop)
268918334Speter      && TREE_CONSTANT (TREE_OPERAND (intop, 1))
269018334Speter      && TREE_CONSTANT (size_exp)
269118334Speter      /* If the constant comes from pointer subtraction,
269218334Speter	 skip this optimization--it would cause an error.  */
269318334Speter      && TREE_CODE (TREE_TYPE (TREE_OPERAND (intop, 0))) == INTEGER_TYPE
269418334Speter      /* If the constant is unsigned, and smaller than the pointer size,
269518334Speter	 then we must skip this optimization.  This is because it could cause
269618334Speter	 an overflow error if the constant is negative but INTOP is not.  */
269718334Speter      && (! TREE_UNSIGNED (TREE_TYPE (intop))
269818334Speter	  || (TYPE_PRECISION (TREE_TYPE (intop))
269918334Speter	      == TYPE_PRECISION (TREE_TYPE (ptrop)))))
270018334Speter    {
270118334Speter      enum tree_code subcode = resultcode;
270218334Speter      tree int_type = TREE_TYPE (intop);
270318334Speter      if (TREE_CODE (intop) == MINUS_EXPR)
270418334Speter	subcode = (subcode == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR);
270518334Speter      /* Convert both subexpression types to the type of intop,
270618334Speter	 because weird cases involving pointer arithmetic
270718334Speter	 can result in a sum or difference with different type args.  */
270818334Speter      ptrop = build_binary_op (subcode, ptrop,
270918334Speter			       convert (int_type, TREE_OPERAND (intop, 1)), 1);
271018334Speter      intop = convert (int_type, TREE_OPERAND (intop, 0));
271118334Speter    }
271218334Speter
271350397Sobrien  /* Convert the integer argument to a type the same size as sizetype
271418334Speter     so the multiply won't overflow spuriously.  */
271518334Speter
271650397Sobrien  if (TYPE_PRECISION (TREE_TYPE (intop)) != TYPE_PRECISION (sizetype)
271750397Sobrien      || TREE_UNSIGNED (TREE_TYPE (intop)) != TREE_UNSIGNED (sizetype))
271850397Sobrien    intop = convert (type_for_size (TYPE_PRECISION (sizetype),
271950397Sobrien				    TREE_UNSIGNED (sizetype)), intop);
272018334Speter
272118334Speter  /* Replace the integer argument with a suitable product by the object size.
272218334Speter     Do this multiplication as signed, then convert to the appropriate
272318334Speter     pointer type (actually unsigned integral).  */
272418334Speter
272518334Speter  intop = convert (result_type,
272618334Speter		   build_binary_op (MULT_EXPR, intop,
272718334Speter				    convert (TREE_TYPE (intop), size_exp), 1));
272818334Speter
272918334Speter  /* Create the sum or difference.  */
273018334Speter
273118334Speter  result = build (resultcode, result_type, ptrop, intop);
273218334Speter
273318334Speter  folded = fold (result);
273418334Speter  if (folded == result)
273518334Speter    TREE_CONSTANT (folded) = TREE_CONSTANT (ptrop) & TREE_CONSTANT (intop);
273618334Speter  return folded;
273718334Speter}
273818334Speter
273918334Speter/* Return a tree for the difference of pointers OP0 and OP1.
274018334Speter   The resulting tree has type int.  */
274118334Speter
274218334Speterstatic tree
274318334Speterpointer_diff (op0, op1)
274418334Speter     register tree op0, op1;
274518334Speter{
274618334Speter  register tree result, folded;
274718334Speter  tree restype = ptrdiff_type_node;
274818334Speter
274918334Speter  tree target_type = TREE_TYPE (TREE_TYPE (op0));
275018334Speter
275118334Speter  if (pedantic || warn_pointer_arith)
275218334Speter    {
275318334Speter      if (TREE_CODE (target_type) == VOID_TYPE)
275418334Speter	pedwarn ("pointer of type `void *' used in subtraction");
275518334Speter      if (TREE_CODE (target_type) == FUNCTION_TYPE)
275618334Speter	pedwarn ("pointer to a function used in subtraction");
275718334Speter    }
275818334Speter
275918334Speter  /* First do the subtraction as integers;
276050397Sobrien     then drop through to build the divide operator.
276150397Sobrien     Do not do default conversions on the minus operator
276250397Sobrien     in case restype is a short type.  */
276318334Speter
276418334Speter  op0 = build_binary_op (MINUS_EXPR, convert (restype, op0),
276550397Sobrien			 convert (restype, op1), 0);
276618334Speter  /* This generates an error if op1 is pointer to incomplete type.  */
276718334Speter  if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (op1))) == 0)
276818334Speter    error ("arithmetic on pointer to an incomplete type");
276918334Speter
277018334Speter  /* This generates an error if op0 is pointer to incomplete type.  */
277118334Speter  op1 = c_size_in_bytes (target_type);
277218334Speter
277318334Speter  /* Divide by the size, in easiest possible way.  */
277418334Speter
277518334Speter  result = build (EXACT_DIV_EXPR, restype, op0, convert (restype, op1));
277618334Speter
277718334Speter  folded = fold (result);
277818334Speter  if (folded == result)
277918334Speter    TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1);
278018334Speter  return folded;
278118334Speter}
278218334Speter
278318334Speter/* Construct and perhaps optimize a tree representation
278418334Speter   for a unary operation.  CODE, a tree_code, specifies the operation
278518334Speter   and XARG is the operand.  NOCONVERT nonzero suppresses
278618334Speter   the default promotions (such as from short to int).  */
278718334Speter
278818334Spetertree
278918334Speterbuild_unary_op (code, xarg, noconvert)
279018334Speter     enum tree_code code;
279118334Speter     tree xarg;
279218334Speter     int noconvert;
279318334Speter{
279418334Speter  /* No default_conversion here.  It causes trouble for ADDR_EXPR.  */
279518334Speter  register tree arg = xarg;
279618334Speter  register tree argtype = 0;
279718334Speter  register enum tree_code typecode = TREE_CODE (TREE_TYPE (arg));
279818334Speter  tree val;
279918334Speter
280018334Speter  if (typecode == ERROR_MARK)
280118334Speter    return error_mark_node;
280218334Speter  if (typecode == ENUMERAL_TYPE)
280318334Speter    typecode = INTEGER_TYPE;
280418334Speter
280518334Speter  switch (code)
280618334Speter    {
280718334Speter    case CONVERT_EXPR:
280818334Speter      /* This is used for unary plus, because a CONVERT_EXPR
280918334Speter	 is enough to prevent anybody from looking inside for
281018334Speter	 associativity, but won't generate any code.  */
281118334Speter      if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
281218334Speter	    || typecode == COMPLEX_TYPE))
281352284Sobrien	{
281452284Sobrien	  error ("wrong type argument to unary plus");
281552284Sobrien	  return error_mark_node;
281652284Sobrien	}
281718334Speter      else if (!noconvert)
281818334Speter	arg = default_conversion (arg);
281918334Speter      break;
282018334Speter
282118334Speter    case NEGATE_EXPR:
282218334Speter      if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
282318334Speter	    || typecode == COMPLEX_TYPE))
282452284Sobrien	{
282552284Sobrien	  error ("wrong type argument to unary minus");
282652284Sobrien	  return error_mark_node;
282752284Sobrien	}
282818334Speter      else if (!noconvert)
282918334Speter	arg = default_conversion (arg);
283018334Speter      break;
283118334Speter
283218334Speter    case BIT_NOT_EXPR:
283318334Speter      if (typecode == COMPLEX_TYPE)
283418334Speter	{
283518334Speter	  code = CONJ_EXPR;
283618334Speter	  if (!noconvert)
283718334Speter	    arg = default_conversion (arg);
283818334Speter	}
283918334Speter      else if (typecode != INTEGER_TYPE)
284052284Sobrien	{
284152284Sobrien	  error ("wrong type argument to bit-complement");
284252284Sobrien	  return error_mark_node;
284352284Sobrien	}
284418334Speter      else if (!noconvert)
284518334Speter	arg = default_conversion (arg);
284618334Speter      break;
284718334Speter
284818334Speter    case ABS_EXPR:
284918334Speter      if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
285018334Speter	    || typecode == COMPLEX_TYPE))
285152284Sobrien	{
285252284Sobrien	  error ("wrong type argument to abs");
285352284Sobrien	  return error_mark_node;
285452284Sobrien	}
285518334Speter      else if (!noconvert)
285618334Speter	arg = default_conversion (arg);
285718334Speter      break;
285818334Speter
285918334Speter    case CONJ_EXPR:
286018334Speter      /* Conjugating a real value is a no-op, but allow it anyway.  */
286118334Speter      if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
286218334Speter	    || typecode == COMPLEX_TYPE))
286352284Sobrien	{
286452284Sobrien	  error ("wrong type argument to conjugation");
286552284Sobrien	  return error_mark_node;
286652284Sobrien	}
286718334Speter      else if (!noconvert)
286818334Speter	arg = default_conversion (arg);
286918334Speter      break;
287018334Speter
287118334Speter    case TRUTH_NOT_EXPR:
287218334Speter      if (typecode != INTEGER_TYPE
287318334Speter	  && typecode != REAL_TYPE && typecode != POINTER_TYPE
287418334Speter	  && typecode != COMPLEX_TYPE
287518334Speter	  /* These will convert to a pointer.  */
287618334Speter	  && typecode != ARRAY_TYPE && typecode != FUNCTION_TYPE)
287718334Speter	{
287852284Sobrien	  error ("wrong type argument to unary exclamation mark");
287952284Sobrien	  return error_mark_node;
288018334Speter	}
288118334Speter      arg = truthvalue_conversion (arg);
288218334Speter      return invert_truthvalue (arg);
288318334Speter
288418334Speter    case NOP_EXPR:
288518334Speter      break;
288618334Speter
288718334Speter    case REALPART_EXPR:
288818334Speter      if (TREE_CODE (arg) == COMPLEX_CST)
288918334Speter	return TREE_REALPART (arg);
289018334Speter      else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
289118334Speter	return fold (build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg));
289218334Speter      else
289318334Speter	return arg;
289418334Speter
289518334Speter    case IMAGPART_EXPR:
289618334Speter      if (TREE_CODE (arg) == COMPLEX_CST)
289718334Speter	return TREE_IMAGPART (arg);
289818334Speter      else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
289918334Speter	return fold (build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg));
290018334Speter      else
290118334Speter	return convert (TREE_TYPE (arg), integer_zero_node);
290218334Speter
290318334Speter    case PREINCREMENT_EXPR:
290418334Speter    case POSTINCREMENT_EXPR:
290518334Speter    case PREDECREMENT_EXPR:
290618334Speter    case POSTDECREMENT_EXPR:
290718334Speter      /* Handle complex lvalues (when permitted)
290818334Speter	 by reduction to simpler cases.  */
290918334Speter
291018334Speter      val = unary_complex_lvalue (code, arg);
291118334Speter      if (val != 0)
291218334Speter	return val;
291318334Speter
291418334Speter      /* Increment or decrement the real part of the value,
291518334Speter	 and don't change the imaginary part.  */
291618334Speter      if (typecode == COMPLEX_TYPE)
291718334Speter	{
291818334Speter	  tree real, imag;
291918334Speter
292018334Speter	  arg = stabilize_reference (arg);
292118334Speter	  real = build_unary_op (REALPART_EXPR, arg, 1);
292218334Speter	  imag = build_unary_op (IMAGPART_EXPR, arg, 1);
292318334Speter	  return build (COMPLEX_EXPR, TREE_TYPE (arg),
292418334Speter			build_unary_op (code, real, 1), imag);
292518334Speter	}
292618334Speter
292718334Speter      /* Report invalid types.  */
292818334Speter
292918334Speter      if (typecode != POINTER_TYPE
293018334Speter	  && typecode != INTEGER_TYPE && typecode != REAL_TYPE)
293118334Speter	{
293252284Sobrien	  error (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR
293352284Sobrien		 ? "wrong type argument to increment"
293452284Sobrien		 : "wrong type argument to decrement");
293552284Sobrien	  return error_mark_node;
293618334Speter	}
293718334Speter
293818334Speter      {
293918334Speter	register tree inc;
294018334Speter	tree result_type = TREE_TYPE (arg);
294118334Speter
294218334Speter	arg = get_unwidened (arg, 0);
294318334Speter	argtype = TREE_TYPE (arg);
294418334Speter
294518334Speter	/* Compute the increment.  */
294618334Speter
294718334Speter	if (typecode == POINTER_TYPE)
294818334Speter	  {
294918334Speter	    /* If pointer target is an undefined struct,
295018334Speter	       we just cannot know how to do the arithmetic.  */
295118334Speter	    if (TYPE_SIZE (TREE_TYPE (result_type)) == 0)
295252284Sobrien	      error (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR
295352284Sobrien		     ? "increment of pointer to unknown structure"
295452284Sobrien		     : "decrement of pointer to unknown structure");
295518334Speter	    else if ((pedantic || warn_pointer_arith)
295618334Speter		     && (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE
295718334Speter			 || TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE))
295852284Sobrien	      pedwarn (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR
295952284Sobrien		       ? "wrong type argument to increment"
296052284Sobrien		       : "wrong type argument to decrement");
296118334Speter	    inc = c_size_in_bytes (TREE_TYPE (result_type));
296218334Speter	  }
296318334Speter	else
296418334Speter	  inc = integer_one_node;
296518334Speter
296618334Speter	inc = convert (argtype, inc);
296718334Speter
296818334Speter	/* Handle incrementing a cast-expression.  */
296918334Speter
297018334Speter	while (1)
297118334Speter	  switch (TREE_CODE (arg))
297218334Speter	    {
297318334Speter	    case NOP_EXPR:
297418334Speter	    case CONVERT_EXPR:
297518334Speter	    case FLOAT_EXPR:
297618334Speter	    case FIX_TRUNC_EXPR:
297718334Speter	    case FIX_FLOOR_EXPR:
297818334Speter	    case FIX_ROUND_EXPR:
297918334Speter	    case FIX_CEIL_EXPR:
298018334Speter	      pedantic_lvalue_warning (CONVERT_EXPR);
298118334Speter	      /* If the real type has the same machine representation
298218334Speter		 as the type it is cast to, we can make better output
298318334Speter		 by adding directly to the inside of the cast.  */
298418334Speter	      if ((TREE_CODE (TREE_TYPE (arg))
298518334Speter		   == TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 0))))
298618334Speter		  && (TYPE_MODE (TREE_TYPE (arg))
298718334Speter		      == TYPE_MODE (TREE_TYPE (TREE_OPERAND (arg, 0)))))
298818334Speter		arg = TREE_OPERAND (arg, 0);
298918334Speter	      else
299018334Speter		{
299118334Speter		  tree incremented, modify, value;
299218334Speter		  arg = stabilize_reference (arg);
299318334Speter		  if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
299418334Speter		    value = arg;
299518334Speter		  else
299618334Speter		    value = save_expr (arg);
299718334Speter		  incremented = build (((code == PREINCREMENT_EXPR
299818334Speter					 || code == POSTINCREMENT_EXPR)
299918334Speter					? PLUS_EXPR : MINUS_EXPR),
300018334Speter				       argtype, value, inc);
300118334Speter		  TREE_SIDE_EFFECTS (incremented) = 1;
300218334Speter		  modify = build_modify_expr (arg, NOP_EXPR, incremented);
300318334Speter		  value = build (COMPOUND_EXPR, TREE_TYPE (arg), modify, value);
300418334Speter		  TREE_USED (value) = 1;
300518334Speter		  return value;
300618334Speter		}
300718334Speter	      break;
300818334Speter
300918334Speter	    default:
301018334Speter	      goto give_up;
301118334Speter	    }
301218334Speter      give_up:
301318334Speter
301418334Speter	/* Complain about anything else that is not a true lvalue.  */
301518334Speter	if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR
301618334Speter				    || code == POSTINCREMENT_EXPR)
301752284Sobrien				   ? "invalid lvalue in increment"
301852284Sobrien				   : "invalid lvalue in decrement")))
301918334Speter	  return error_mark_node;
302018334Speter
302118334Speter	/* Report a read-only lvalue.  */
302218334Speter	if (TREE_READONLY (arg))
302318334Speter	  readonly_warning (arg,
302418334Speter			    ((code == PREINCREMENT_EXPR
302518334Speter			      || code == POSTINCREMENT_EXPR)
302618334Speter			     ? "increment" : "decrement"));
302718334Speter
302818334Speter	val = build (code, TREE_TYPE (arg), arg, inc);
302918334Speter	TREE_SIDE_EFFECTS (val) = 1;
303018334Speter	val = convert (result_type, val);
303118334Speter	if (TREE_CODE (val) != code)
303218334Speter	  TREE_NO_UNUSED_WARNING (val) = 1;
303318334Speter	return val;
303418334Speter      }
303518334Speter
303618334Speter    case ADDR_EXPR:
303718334Speter      /* Note that this operation never does default_conversion
303818334Speter	 regardless of NOCONVERT.  */
303918334Speter
304018334Speter      /* Let &* cancel out to simplify resulting code.  */
304118334Speter      if (TREE_CODE (arg) == INDIRECT_REF)
304218334Speter	{
304318334Speter	  /* Don't let this be an lvalue.  */
304418334Speter	  if (lvalue_p (TREE_OPERAND (arg, 0)))
304518334Speter	    return non_lvalue (TREE_OPERAND (arg, 0));
304618334Speter	  return TREE_OPERAND (arg, 0);
304718334Speter	}
304818334Speter
304918334Speter      /* For &x[y], return x+y */
305018334Speter      if (TREE_CODE (arg) == ARRAY_REF)
305118334Speter	{
305218334Speter	  if (mark_addressable (TREE_OPERAND (arg, 0)) == 0)
305318334Speter	    return error_mark_node;
305418334Speter	  return build_binary_op (PLUS_EXPR, TREE_OPERAND (arg, 0),
305518334Speter				  TREE_OPERAND (arg, 1), 1);
305618334Speter	}
305718334Speter
305818334Speter      /* Handle complex lvalues (when permitted)
305918334Speter	 by reduction to simpler cases.  */
306018334Speter      val = unary_complex_lvalue (code, arg);
306118334Speter      if (val != 0)
306218334Speter	return val;
306318334Speter
306418334Speter#if 0 /* Turned off because inconsistent;
306518334Speter	 float f; *&(int)f = 3.4 stores in int format
306618334Speter	 whereas (int)f = 3.4 stores in float format.  */
306718334Speter      /* Address of a cast is just a cast of the address
306818334Speter	 of the operand of the cast.  */
306918334Speter      switch (TREE_CODE (arg))
307018334Speter	{
307118334Speter	case NOP_EXPR:
307218334Speter	case CONVERT_EXPR:
307318334Speter	case FLOAT_EXPR:
307418334Speter	case FIX_TRUNC_EXPR:
307518334Speter	case FIX_FLOOR_EXPR:
307618334Speter	case FIX_ROUND_EXPR:
307718334Speter	case FIX_CEIL_EXPR:
307818334Speter	  if (pedantic)
307918334Speter	    pedwarn ("ANSI C forbids the address of a cast expression");
308018334Speter	  return convert (build_pointer_type (TREE_TYPE (arg)),
308118334Speter			  build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0),
308218334Speter					  0));
308318334Speter	}
308418334Speter#endif
308518334Speter
308618334Speter      /* Allow the address of a constructor if all the elements
308718334Speter	 are constant.  */
308818334Speter      if (TREE_CODE (arg) == CONSTRUCTOR && TREE_CONSTANT (arg))
308918334Speter	;
309018334Speter      /* Anything not already handled and not a true memory reference
309118334Speter	 is an error.  */
309252284Sobrien      else if (typecode != FUNCTION_TYPE
309352284Sobrien	       && !lvalue_or_else (arg, "invalid lvalue in unary `&'"))
309418334Speter	return error_mark_node;
309518334Speter
309618334Speter      /* Ordinary case; arg is a COMPONENT_REF or a decl.  */
309718334Speter      argtype = TREE_TYPE (arg);
309852284Sobrien      /* If the lvalue is const or volatile, merge that into the type
309952284Sobrien         to which the address will point.  Note that you can't get a
310052284Sobrien	 restricted pointer by taking the address of something, so we
310152284Sobrien	 only have to deal with `const' and `volatile' here.  */
310218334Speter      if (TREE_CODE_CLASS (TREE_CODE (arg)) == 'd'
310318334Speter	  || TREE_CODE_CLASS (TREE_CODE (arg)) == 'r')
310418334Speter	{
310518334Speter	  if (TREE_READONLY (arg) || TREE_THIS_VOLATILE (arg))
310618334Speter	    argtype = c_build_type_variant (argtype,
310718334Speter					    TREE_READONLY (arg),
310818334Speter					    TREE_THIS_VOLATILE (arg));
310918334Speter	}
311018334Speter
311118334Speter      argtype = build_pointer_type (argtype);
311218334Speter
311318334Speter      if (mark_addressable (arg) == 0)
311418334Speter	return error_mark_node;
311518334Speter
311618334Speter      {
311718334Speter	tree addr;
311818334Speter
311918334Speter	if (TREE_CODE (arg) == COMPONENT_REF)
312018334Speter	  {
312118334Speter	    tree field = TREE_OPERAND (arg, 1);
312218334Speter
312318334Speter	    addr = build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0), 0);
312418334Speter
312550397Sobrien	    if (DECL_C_BIT_FIELD (field))
312618334Speter	      {
312718334Speter		error ("attempt to take address of bit-field structure member `%s'",
312818334Speter		       IDENTIFIER_POINTER (DECL_NAME (field)));
312918334Speter		return error_mark_node;
313018334Speter	      }
313118334Speter
313218334Speter	    addr = convert (argtype, addr);
313318334Speter
313418334Speter	    if (! integer_zerop (DECL_FIELD_BITPOS (field)))
313518334Speter	      {
313618334Speter		tree offset
313718334Speter		  = size_binop (EASY_DIV_EXPR, DECL_FIELD_BITPOS (field),
313818334Speter				size_int (BITS_PER_UNIT));
313918334Speter		int flag = TREE_CONSTANT (addr);
314018334Speter		addr = fold (build (PLUS_EXPR, argtype,
314118334Speter				    addr, convert (argtype, offset)));
314218334Speter		TREE_CONSTANT (addr) = flag;
314318334Speter	      }
314418334Speter	  }
314518334Speter	else
314618334Speter	  addr = build1 (code, argtype, arg);
314718334Speter
314818334Speter	/* Address of a static or external variable or
314918334Speter	   file-scope function counts as a constant.  */
315018334Speter	if (staticp (arg)
315118334Speter	    && ! (TREE_CODE (arg) == FUNCTION_DECL
315218334Speter		  && DECL_CONTEXT (arg) != 0))
315318334Speter	  TREE_CONSTANT (addr) = 1;
315418334Speter	return addr;
315518334Speter      }
315650397Sobrien
315750397Sobrien    default:
315850397Sobrien      break;
315918334Speter    }
316018334Speter
316152284Sobrien  if (argtype == 0)
316252284Sobrien    argtype = TREE_TYPE (arg);
316352284Sobrien  return fold (build1 (code, argtype, arg));
316418334Speter}
316518334Speter
316618334Speter#if 0
316718334Speter/* If CONVERSIONS is a conversion expression or a nested sequence of such,
316818334Speter   convert ARG with the same conversions in the same order
316918334Speter   and return the result.  */
317018334Speter
317118334Speterstatic tree
317218334Speterconvert_sequence (conversions, arg)
317318334Speter     tree conversions;
317418334Speter     tree arg;
317518334Speter{
317618334Speter  switch (TREE_CODE (conversions))
317718334Speter    {
317818334Speter    case NOP_EXPR:
317918334Speter    case CONVERT_EXPR:
318018334Speter    case FLOAT_EXPR:
318118334Speter    case FIX_TRUNC_EXPR:
318218334Speter    case FIX_FLOOR_EXPR:
318318334Speter    case FIX_ROUND_EXPR:
318418334Speter    case FIX_CEIL_EXPR:
318518334Speter      return convert (TREE_TYPE (conversions),
318618334Speter		      convert_sequence (TREE_OPERAND (conversions, 0),
318718334Speter					arg));
318818334Speter
318918334Speter    default:
319018334Speter      return arg;
319118334Speter    }
319218334Speter}
319318334Speter#endif /* 0 */
319418334Speter
319518334Speter/* Return nonzero if REF is an lvalue valid for this language.
319618334Speter   Lvalues can be assigned, unless their type has TYPE_READONLY.
319718334Speter   Lvalues can have their address taken, unless they have DECL_REGISTER.  */
319818334Speter
319918334Speterint
320018334Speterlvalue_p (ref)
320118334Speter     tree ref;
320218334Speter{
320318334Speter  register enum tree_code code = TREE_CODE (ref);
320418334Speter
320518334Speter  switch (code)
320618334Speter    {
320718334Speter    case REALPART_EXPR:
320818334Speter    case IMAGPART_EXPR:
320918334Speter    case COMPONENT_REF:
321018334Speter      return lvalue_p (TREE_OPERAND (ref, 0));
321118334Speter
321218334Speter    case STRING_CST:
321318334Speter      return 1;
321418334Speter
321518334Speter    case INDIRECT_REF:
321618334Speter    case ARRAY_REF:
321718334Speter    case VAR_DECL:
321818334Speter    case PARM_DECL:
321918334Speter    case RESULT_DECL:
322018334Speter    case ERROR_MARK:
322150397Sobrien      return (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE
322250397Sobrien	      && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE);
322350397Sobrien
322450397Sobrien    case BIND_EXPR:
322550397Sobrien    case RTL_EXPR:
322650397Sobrien      return TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE;
322750397Sobrien
322850397Sobrien    default:
322950397Sobrien      return 0;
323018334Speter    }
323118334Speter}
323218334Speter
323318334Speter/* Return nonzero if REF is an lvalue valid for this language;
323418334Speter   otherwise, print an error message and return zero.  */
323518334Speter
323618334Speterint
323752284Sobrienlvalue_or_else (ref, msgid)
323818334Speter     tree ref;
323952284Sobrien     const char *msgid;
324018334Speter{
324118334Speter  int win = lvalue_p (ref);
324218334Speter  if (! win)
324352284Sobrien    error (msgid);
324418334Speter  return win;
324518334Speter}
324618334Speter
324718334Speter/* Apply unary lvalue-demanding operator CODE to the expression ARG
324818334Speter   for certain kinds of expressions which are not really lvalues
324918334Speter   but which we can accept as lvalues.
325018334Speter
325118334Speter   If ARG is not a kind of expression we can handle, return zero.  */
325218334Speter
325318334Speterstatic tree
325418334Speterunary_complex_lvalue (code, arg)
325518334Speter     enum tree_code code;
325618334Speter     tree arg;
325718334Speter{
325818334Speter  /* Handle (a, b) used as an "lvalue".  */
325918334Speter  if (TREE_CODE (arg) == COMPOUND_EXPR)
326018334Speter    {
326118334Speter      tree real_result = build_unary_op (code, TREE_OPERAND (arg, 1), 0);
326250397Sobrien
326350397Sobrien      /* If this returns a function type, it isn't really being used as
326450397Sobrien	 an lvalue, so don't issue a warning about it.  */
326550397Sobrien      if (TREE_CODE (TREE_TYPE (arg)) != FUNCTION_TYPE)
326650397Sobrien	pedantic_lvalue_warning (COMPOUND_EXPR);
326750397Sobrien
326818334Speter      return build (COMPOUND_EXPR, TREE_TYPE (real_result),
326918334Speter		    TREE_OPERAND (arg, 0), real_result);
327018334Speter    }
327118334Speter
327218334Speter  /* Handle (a ? b : c) used as an "lvalue".  */
327318334Speter  if (TREE_CODE (arg) == COND_EXPR)
327418334Speter    {
327518334Speter      pedantic_lvalue_warning (COND_EXPR);
327650397Sobrien      if (TREE_CODE (TREE_TYPE (arg)) != FUNCTION_TYPE)
327750397Sobrien	pedantic_lvalue_warning (COMPOUND_EXPR);
327850397Sobrien
327918334Speter      return (build_conditional_expr
328018334Speter	      (TREE_OPERAND (arg, 0),
328118334Speter	       build_unary_op (code, TREE_OPERAND (arg, 1), 0),
328218334Speter	       build_unary_op (code, TREE_OPERAND (arg, 2), 0)));
328318334Speter    }
328418334Speter
328518334Speter  return 0;
328618334Speter}
328718334Speter
328818334Speter/* If pedantic, warn about improper lvalue.   CODE is either COND_EXPR
328918334Speter   COMPOUND_EXPR, or CONVERT_EXPR (for casts).  */
329018334Speter
329118334Speterstatic void
329218334Speterpedantic_lvalue_warning (code)
329318334Speter     enum tree_code code;
329418334Speter{
329518334Speter  if (pedantic)
329652284Sobrien    pedwarn (code == COND_EXPR
329752284Sobrien	     ? "ANSI C forbids use of conditional expressions as lvalues"
329852284Sobrien	     : code == COMPOUND_EXPR
329952284Sobrien	     ? "ANSI C forbids use of compound expressions as lvalues"
330052284Sobrien	     : "ANSI C forbids use of cast expressions as lvalues");
330118334Speter}
330218334Speter
330318334Speter/* Warn about storing in something that is `const'.  */
330418334Speter
330518334Spetervoid
330652284Sobrienreadonly_warning (arg, msgid)
330718334Speter     tree arg;
330852284Sobrien     const char *msgid;
330918334Speter{
331018334Speter  /* Forbid assignments to iterators.  */
331118334Speter  if (TREE_CODE (arg) == VAR_DECL && ITERATOR_P (arg))
331252284Sobrien    pedwarn ("%s of iterator `%s'",  _(msgid),
331352284Sobrien	     IDENTIFIER_POINTER (DECL_NAME (arg)));
331418334Speter
331518334Speter  if (TREE_CODE (arg) == COMPONENT_REF)
331618334Speter    {
331718334Speter      if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0))))
331852284Sobrien	readonly_warning (TREE_OPERAND (arg, 0), msgid);
331918334Speter      else
332052284Sobrien	pedwarn ("%s of read-only member `%s'", _(msgid),
332152284Sobrien		 IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (arg, 1))));
332218334Speter    }
332318334Speter  else if (TREE_CODE (arg) == VAR_DECL)
332452284Sobrien    pedwarn ("%s of read-only variable `%s'", _(msgid),
332552284Sobrien	     IDENTIFIER_POINTER (DECL_NAME (arg)));
332618334Speter  else
332752284Sobrien    pedwarn ("%s of read-only location", _(msgid));
332818334Speter}
332918334Speter
333018334Speter/* Mark EXP saying that we need to be able to take the
333118334Speter   address of it; it should not be allocated in a register.
333218334Speter   Value is 1 if successful.  */
333318334Speter
333418334Speterint
333518334Spetermark_addressable (exp)
333618334Speter     tree exp;
333718334Speter{
333818334Speter  register tree x = exp;
333918334Speter  while (1)
334018334Speter    switch (TREE_CODE (x))
334118334Speter      {
334250397Sobrien      case COMPONENT_REF:
334350397Sobrien	if (DECL_C_BIT_FIELD (TREE_OPERAND (x, 1)))
334450397Sobrien	  {
334550397Sobrien	    error ("cannot take address of bitfield `%s'",
334650397Sobrien		   IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (x, 1))));
334750397Sobrien	    return 0;
334850397Sobrien	  }
334950397Sobrien
335050397Sobrien	/* ... fall through ...  */
335150397Sobrien
335218334Speter      case ADDR_EXPR:
335318334Speter      case ARRAY_REF:
335418334Speter      case REALPART_EXPR:
335518334Speter      case IMAGPART_EXPR:
335618334Speter	x = TREE_OPERAND (x, 0);
335718334Speter	break;
335818334Speter
335918334Speter      case CONSTRUCTOR:
336018334Speter	TREE_ADDRESSABLE (x) = 1;
336118334Speter	return 1;
336218334Speter
336318334Speter      case VAR_DECL:
336418334Speter      case CONST_DECL:
336518334Speter      case PARM_DECL:
336618334Speter      case RESULT_DECL:
336718334Speter	if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
336818334Speter	    && DECL_NONLOCAL (x))
336918334Speter	  {
337018334Speter	    if (TREE_PUBLIC (x))
337118334Speter	      {
337218334Speter		error ("global register variable `%s' used in nested function",
337318334Speter		       IDENTIFIER_POINTER (DECL_NAME (x)));
337418334Speter		return 0;
337518334Speter	      }
337618334Speter	    pedwarn ("register variable `%s' used in nested function",
337718334Speter		     IDENTIFIER_POINTER (DECL_NAME (x)));
337818334Speter	  }
337918334Speter	else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
338018334Speter	  {
338118334Speter	    if (TREE_PUBLIC (x))
338218334Speter	      {
338318334Speter		error ("address of global register variable `%s' requested",
338418334Speter		       IDENTIFIER_POINTER (DECL_NAME (x)));
338518334Speter		return 0;
338618334Speter	      }
338718334Speter
338818334Speter	    /* If we are making this addressable due to its having
338918334Speter	       volatile components, give a different error message.  Also
339018334Speter	       handle the case of an unnamed parameter by not trying
339118334Speter	       to give the name.  */
339218334Speter
339318334Speter	    else if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (x)))
339418334Speter	      {
339518334Speter		error ("cannot put object with volatile field into register");
339618334Speter		return 0;
339718334Speter	      }
339818334Speter
339918334Speter	    pedwarn ("address of register variable `%s' requested",
340018334Speter		     IDENTIFIER_POINTER (DECL_NAME (x)));
340118334Speter	  }
340218334Speter	put_var_into_stack (x);
340318334Speter
340418334Speter	/* drops in */
340518334Speter      case FUNCTION_DECL:
340618334Speter	TREE_ADDRESSABLE (x) = 1;
340718334Speter#if 0  /* poplevel deals with this now.  */
340818334Speter	if (DECL_CONTEXT (x) == 0)
340918334Speter	  TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1;
341018334Speter#endif
341118334Speter
341218334Speter      default:
341318334Speter	return 1;
341418334Speter    }
341518334Speter}
341618334Speter
341718334Speter/* Build and return a conditional expression IFEXP ? OP1 : OP2.  */
341818334Speter
341918334Spetertree
342018334Speterbuild_conditional_expr (ifexp, op1, op2)
342118334Speter     tree ifexp, op1, op2;
342218334Speter{
342318334Speter  register tree type1;
342418334Speter  register tree type2;
342518334Speter  register enum tree_code code1;
342618334Speter  register enum tree_code code2;
342718334Speter  register tree result_type = NULL;
342818334Speter  tree orig_op1 = op1, orig_op2 = op2;
342918334Speter
343018334Speter  ifexp = truthvalue_conversion (default_conversion (ifexp));
343118334Speter
343218334Speter#if 0 /* Produces wrong result if within sizeof.  */
343318334Speter  /* Don't promote the operands separately if they promote
343418334Speter     the same way.  Return the unpromoted type and let the combined
343518334Speter     value get promoted if necessary.  */
343618334Speter
343718334Speter  if (TREE_TYPE (op1) == TREE_TYPE (op2)
343818334Speter      && TREE_CODE (TREE_TYPE (op1)) != ARRAY_TYPE
343918334Speter      && TREE_CODE (TREE_TYPE (op1)) != ENUMERAL_TYPE
344018334Speter      && TREE_CODE (TREE_TYPE (op1)) != FUNCTION_TYPE)
344118334Speter    {
344218334Speter      if (TREE_CODE (ifexp) == INTEGER_CST)
344318334Speter	return pedantic_non_lvalue (integer_zerop (ifexp) ? op2 : op1);
344418334Speter
344518334Speter      return fold (build (COND_EXPR, TREE_TYPE (op1), ifexp, op1, op2));
344618334Speter    }
344718334Speter#endif
344818334Speter
344918334Speter  /* Promote both alternatives.  */
345018334Speter
345118334Speter  if (TREE_CODE (TREE_TYPE (op1)) != VOID_TYPE)
345218334Speter    op1 = default_conversion (op1);
345318334Speter  if (TREE_CODE (TREE_TYPE (op2)) != VOID_TYPE)
345418334Speter    op2 = default_conversion (op2);
345518334Speter
345618334Speter  if (TREE_CODE (ifexp) == ERROR_MARK
345718334Speter      || TREE_CODE (TREE_TYPE (op1)) == ERROR_MARK
345818334Speter      || TREE_CODE (TREE_TYPE (op2)) == ERROR_MARK)
345918334Speter    return error_mark_node;
346018334Speter
346118334Speter  type1 = TREE_TYPE (op1);
346218334Speter  code1 = TREE_CODE (type1);
346318334Speter  type2 = TREE_TYPE (op2);
346418334Speter  code2 = TREE_CODE (type2);
346518334Speter
346618334Speter  /* Quickly detect the usual case where op1 and op2 have the same type
346718334Speter     after promotion.  */
346818334Speter  if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2))
346918334Speter    {
347018334Speter      if (type1 == type2)
347118334Speter	result_type = type1;
347218334Speter      else
347318334Speter	result_type = TYPE_MAIN_VARIANT (type1);
347418334Speter    }
347518334Speter  else if ((code1 == INTEGER_TYPE || code1 == REAL_TYPE)
347618334Speter           && (code2 == INTEGER_TYPE || code2 == REAL_TYPE))
347718334Speter    {
347818334Speter      result_type = common_type (type1, type2);
347918334Speter    }
348018334Speter  else if (code1 == VOID_TYPE || code2 == VOID_TYPE)
348118334Speter    {
348218334Speter      if (pedantic && (code1 != VOID_TYPE || code2 != VOID_TYPE))
348318334Speter	pedwarn ("ANSI C forbids conditional expr with only one void side");
348418334Speter      result_type = void_type_node;
348518334Speter    }
348618334Speter  else if (code1 == POINTER_TYPE && code2 == POINTER_TYPE)
348718334Speter    {
348818334Speter      if (comp_target_types (type1, type2))
348918334Speter	result_type = common_type (type1, type2);
349018334Speter      else if (integer_zerop (op1) && TREE_TYPE (type1) == void_type_node
349118334Speter	       && TREE_CODE (orig_op1) != NOP_EXPR)
349218334Speter	result_type = qualify_type (type2, type1);
349318334Speter      else if (integer_zerop (op2) && TREE_TYPE (type2) == void_type_node
349418334Speter	       && TREE_CODE (orig_op2) != NOP_EXPR)
349518334Speter	result_type = qualify_type (type1, type2);
349618334Speter      else if (TYPE_MAIN_VARIANT (TREE_TYPE (type1)) == void_type_node)
349718334Speter	{
349818334Speter	  if (pedantic && TREE_CODE (TREE_TYPE (type2)) == FUNCTION_TYPE)
349918334Speter	    pedwarn ("ANSI C forbids conditional expr between `void *' and function pointer");
350018334Speter	  result_type = qualify_type (type1, type2);
350118334Speter	}
350218334Speter      else if (TYPE_MAIN_VARIANT (TREE_TYPE (type2)) == void_type_node)
350318334Speter	{
350418334Speter	  if (pedantic && TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE)
350518334Speter	    pedwarn ("ANSI C forbids conditional expr between `void *' and function pointer");
350618334Speter	  result_type = qualify_type (type2, type1);
350718334Speter	}
350818334Speter      else
350918334Speter	{
351018334Speter	  pedwarn ("pointer type mismatch in conditional expression");
351118334Speter	  result_type = build_pointer_type (void_type_node);
351218334Speter	}
351318334Speter    }
351418334Speter  else if (code1 == POINTER_TYPE && code2 == INTEGER_TYPE)
351518334Speter    {
351618334Speter      if (! integer_zerop (op2))
351718334Speter	pedwarn ("pointer/integer type mismatch in conditional expression");
351818334Speter      else
351918334Speter	{
352018334Speter	  op2 = null_pointer_node;
352118334Speter#if 0  /* The spec seems to say this is permitted.  */
352218334Speter	  if (pedantic && TREE_CODE (type1) == FUNCTION_TYPE)
352318334Speter	    pedwarn ("ANSI C forbids conditional expr between 0 and function pointer");
352418334Speter#endif
352518334Speter	}
352618334Speter      result_type = type1;
352718334Speter    }
352818334Speter  else if (code2 == POINTER_TYPE && code1 == INTEGER_TYPE)
352918334Speter    {
353018334Speter      if (!integer_zerop (op1))
353118334Speter	pedwarn ("pointer/integer type mismatch in conditional expression");
353218334Speter      else
353318334Speter	{
353418334Speter	  op1 = null_pointer_node;
353518334Speter#if 0  /* The spec seems to say this is permitted.  */
353618334Speter	  if (pedantic && TREE_CODE (type2) == FUNCTION_TYPE)
353718334Speter	    pedwarn ("ANSI C forbids conditional expr between 0 and function pointer");
353818334Speter#endif
353918334Speter	}
354018334Speter      result_type = type2;
354118334Speter    }
354218334Speter
354318334Speter  if (!result_type)
354418334Speter    {
354518334Speter      if (flag_cond_mismatch)
354618334Speter	result_type = void_type_node;
354718334Speter      else
354818334Speter	{
354918334Speter	  error ("type mismatch in conditional expression");
355018334Speter	  return error_mark_node;
355118334Speter	}
355218334Speter    }
355318334Speter
355418334Speter  /* Merge const and volatile flags of the incoming types.  */
355518334Speter  result_type
355618334Speter    = build_type_variant (result_type,
355718334Speter			  TREE_READONLY (op1) || TREE_READONLY (op2),
355818334Speter			  TREE_THIS_VOLATILE (op1) || TREE_THIS_VOLATILE (op2));
355918334Speter
356018334Speter  if (result_type != TREE_TYPE (op1))
356118334Speter    op1 = convert_and_check (result_type, op1);
356218334Speter  if (result_type != TREE_TYPE (op2))
356318334Speter    op2 = convert_and_check (result_type, op2);
356418334Speter
356518334Speter#if 0
356618334Speter  if (code1 == RECORD_TYPE || code1 == UNION_TYPE)
356718334Speter    {
356818334Speter      result_type = TREE_TYPE (op1);
356918334Speter      if (TREE_CONSTANT (ifexp))
357018334Speter	return pedantic_non_lvalue (integer_zerop (ifexp) ? op2 : op1);
357118334Speter
357218334Speter      if (TYPE_MODE (result_type) == BLKmode)
357318334Speter	{
357418334Speter	  register tree tempvar
357518334Speter	    = build_decl (VAR_DECL, NULL_TREE, result_type);
357618334Speter	  register tree xop1 = build_modify_expr (tempvar, op1);
357718334Speter	  register tree xop2 = build_modify_expr (tempvar, op2);
357818334Speter	  register tree result = fold (build (COND_EXPR, result_type,
357918334Speter					      ifexp, xop1, xop2));
358018334Speter
358118334Speter	  layout_decl (tempvar, TYPE_ALIGN (result_type));
358218334Speter	  /* No way to handle variable-sized objects here.
358318334Speter	     I fear that the entire handling of BLKmode conditional exprs
358418334Speter	     needs to be redone.  */
358518334Speter	  if (TREE_CODE (DECL_SIZE (tempvar)) != INTEGER_CST)
358618334Speter	    abort ();
358718334Speter	  DECL_RTL (tempvar)
358818334Speter	    = assign_stack_local (DECL_MODE (tempvar),
358918334Speter				  (TREE_INT_CST_LOW (DECL_SIZE (tempvar))
359018334Speter				   + BITS_PER_UNIT - 1)
359118334Speter				  / BITS_PER_UNIT,
359218334Speter				  0);
359318334Speter
359418334Speter	  TREE_SIDE_EFFECTS (result)
359518334Speter	    = TREE_SIDE_EFFECTS (ifexp) | TREE_SIDE_EFFECTS (op1)
359618334Speter	      | TREE_SIDE_EFFECTS (op2);
359718334Speter	  return build (COMPOUND_EXPR, result_type, result, tempvar);
359818334Speter	}
359918334Speter    }
360018334Speter#endif /* 0 */
360118334Speter
360218334Speter  if (TREE_CODE (ifexp) == INTEGER_CST)
360318334Speter    return pedantic_non_lvalue (integer_zerop (ifexp) ? op2 : op1);
360418334Speter
360518334Speter  return fold (build (COND_EXPR, result_type, ifexp, op1, op2));
360618334Speter}
360718334Speter
360818334Speter/* Given a list of expressions, return a compound expression
360918334Speter   that performs them all and returns the value of the last of them.  */
361018334Speter
361118334Spetertree
361218334Speterbuild_compound_expr (list)
361318334Speter     tree list;
361418334Speter{
361518334Speter  return internal_build_compound_expr (list, TRUE);
361618334Speter}
361718334Speter
361818334Speterstatic tree
361918334Speterinternal_build_compound_expr (list, first_p)
362018334Speter     tree list;
362118334Speter     int first_p;
362218334Speter{
362318334Speter  register tree rest;
362418334Speter
362518334Speter  if (TREE_CHAIN (list) == 0)
362618334Speter    {
362718334Speter#if 0 /* If something inside inhibited lvalueness, we should not override.  */
362818334Speter      /* Consider (x, y+0), which is not an lvalue since y+0 is not.  */
362918334Speter
363018334Speter      /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
363118334Speter      if (TREE_CODE (list) == NON_LVALUE_EXPR)
363218334Speter	list = TREE_OPERAND (list, 0);
363318334Speter#endif
363418334Speter
363518334Speter      /* Don't let (0, 0) be null pointer constant.  */
363618334Speter      if (!first_p && integer_zerop (TREE_VALUE (list)))
363718334Speter	return non_lvalue (TREE_VALUE (list));
363818334Speter      return TREE_VALUE (list);
363918334Speter    }
364018334Speter
364118334Speter  if (TREE_CHAIN (list) != 0 && TREE_CHAIN (TREE_CHAIN (list)) == 0)
364218334Speter    {
364318334Speter      /* Convert arrays to pointers when there really is a comma operator.  */
364418334Speter      if (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (list)))) == ARRAY_TYPE)
364518334Speter	TREE_VALUE (TREE_CHAIN (list))
364618334Speter	  = default_conversion (TREE_VALUE (TREE_CHAIN (list)));
364718334Speter    }
364818334Speter
364918334Speter  rest = internal_build_compound_expr (TREE_CHAIN (list), FALSE);
365018334Speter
365118334Speter  if (! TREE_SIDE_EFFECTS (TREE_VALUE (list)))
365218334Speter    {
365318334Speter      /* The left-hand operand of a comma expression is like an expression
365418334Speter         statement: with -W or -Wunused, we should warn if it doesn't have
365518334Speter	 any side-effects, unless it was explicitly cast to (void).  */
365618334Speter      if ((extra_warnings || warn_unused)
365718334Speter           && ! (TREE_CODE (TREE_VALUE (list)) == CONVERT_EXPR
365818334Speter                && TREE_TYPE (TREE_VALUE (list)) == void_type_node))
365918334Speter        warning ("left-hand operand of comma expression has no effect");
366018334Speter
366118334Speter      /* When pedantic, a compound expression can be neither an lvalue
366218334Speter         nor an integer constant expression.  */
366318334Speter      if (! pedantic)
366418334Speter        return rest;
366518334Speter    }
366618334Speter
366718334Speter  /* With -Wunused, we should also warn if the left-hand operand does have
366818334Speter     side-effects, but computes a value which is not used.  For example, in
366918334Speter     `foo() + bar(), baz()' the result of the `+' operator is not used,
367018334Speter     so we should issue a warning.  */
367118334Speter  else if (warn_unused)
367218334Speter    warn_if_unused_value (TREE_VALUE (list));
367318334Speter
367418334Speter  return build (COMPOUND_EXPR, TREE_TYPE (rest), TREE_VALUE (list), rest);
367518334Speter}
367618334Speter
367718334Speter/* Build an expression representing a cast to type TYPE of expression EXPR.  */
367818334Speter
367918334Spetertree
368018334Speterbuild_c_cast (type, expr)
368118334Speter     register tree type;
368218334Speter     tree expr;
368318334Speter{
368418334Speter  register tree value = expr;
368518334Speter
368618334Speter  if (type == error_mark_node || expr == error_mark_node)
368718334Speter    return error_mark_node;
368818334Speter  type = TYPE_MAIN_VARIANT (type);
368918334Speter
369018334Speter#if 0
369118334Speter  /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
369218334Speter  if (TREE_CODE (value) == NON_LVALUE_EXPR)
369318334Speter    value = TREE_OPERAND (value, 0);
369418334Speter#endif
369518334Speter
369618334Speter  if (TREE_CODE (type) == ARRAY_TYPE)
369718334Speter    {
369818334Speter      error ("cast specifies array type");
369918334Speter      return error_mark_node;
370018334Speter    }
370118334Speter
370218334Speter  if (TREE_CODE (type) == FUNCTION_TYPE)
370318334Speter    {
370418334Speter      error ("cast specifies function type");
370518334Speter      return error_mark_node;
370618334Speter    }
370718334Speter
370818334Speter  if (type == TREE_TYPE (value))
370918334Speter    {
371018334Speter      if (pedantic)
371118334Speter	{
371218334Speter	  if (TREE_CODE (type) == RECORD_TYPE
371318334Speter	      || TREE_CODE (type) == UNION_TYPE)
371418334Speter	    pedwarn ("ANSI C forbids casting nonscalar to the same type");
371518334Speter	}
371618334Speter    }
371718334Speter  else if (TREE_CODE (type) == UNION_TYPE)
371818334Speter    {
371918334Speter      tree field;
372018334Speter      if (TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE
372118334Speter	  || TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE)
372218334Speter	value = default_conversion (value);
372318334Speter
372418334Speter      for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
372518334Speter	if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (field)),
372618334Speter		       TYPE_MAIN_VARIANT (TREE_TYPE (value))))
372718334Speter	  break;
372818334Speter
372918334Speter      if (field)
373018334Speter	{
373152284Sobrien	  const char *name;
373218334Speter	  tree t;
373318334Speter
373418334Speter	  if (pedantic)
373518334Speter	    pedwarn ("ANSI C forbids casts to union type");
373618334Speter	  if (TYPE_NAME (type) != 0)
373718334Speter	    {
373818334Speter	      if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
373918334Speter		name = IDENTIFIER_POINTER (TYPE_NAME (type));
374018334Speter	      else
374118334Speter		name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
374218334Speter	    }
374318334Speter	  else
374418334Speter	    name = "";
374518334Speter	  t = digest_init (type, build (CONSTRUCTOR, type, NULL_TREE,
374618334Speter					build_tree_list (field, value)),
374718334Speter			   0, 0);
374818334Speter	  TREE_CONSTANT (t) = TREE_CONSTANT (value);
374918334Speter	  return t;
375018334Speter	}
375118334Speter      error ("cast to union type from type not present in union");
375218334Speter      return error_mark_node;
375318334Speter    }
375418334Speter  else
375518334Speter    {
375618334Speter      tree otype, ovalue;
375718334Speter
375818334Speter      /* If casting to void, avoid the error that would come
375918334Speter	 from default_conversion in the case of a non-lvalue array.  */
376018334Speter      if (type == void_type_node)
376118334Speter	return build1 (CONVERT_EXPR, type, value);
376218334Speter
376318334Speter      /* Convert functions and arrays to pointers,
376418334Speter	 but don't convert any other types.  */
376518334Speter      if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE
376618334Speter	  || TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE)
376718334Speter	value = default_conversion (value);
376818334Speter      otype = TREE_TYPE (value);
376918334Speter
377018334Speter      /* Optionally warn about potentially worrisome casts.  */
377118334Speter
377218334Speter      if (warn_cast_qual
377318334Speter	  && TREE_CODE (type) == POINTER_TYPE
377418334Speter	  && TREE_CODE (otype) == POINTER_TYPE)
377518334Speter	{
377650397Sobrien	  /* Go to the innermost object being pointed to.  */
377750397Sobrien	  tree in_type = type;
377850397Sobrien	  tree in_otype = otype;
377950397Sobrien
378050397Sobrien	  while (TREE_CODE (in_type) == POINTER_TYPE)
378150397Sobrien	    in_type = TREE_TYPE (in_type);
378250397Sobrien	  while (TREE_CODE (in_otype) == POINTER_TYPE)
378350397Sobrien	    in_otype = TREE_TYPE (in_otype);
378452284Sobrien
378552284Sobrien	  if (TYPE_QUALS (in_otype) & ~TYPE_QUALS (in_type))
378652284Sobrien	    /* There are qualifiers present in IN_OTYPE that are not
378752284Sobrien	       present in IN_TYPE.  */
378852284Sobrien	    pedwarn ("cast discards qualifiers from pointer target type");
378918334Speter	}
379018334Speter
379118334Speter      /* Warn about possible alignment problems.  */
379218334Speter      if (STRICT_ALIGNMENT && warn_cast_align
379318334Speter	  && TREE_CODE (type) == POINTER_TYPE
379418334Speter	  && TREE_CODE (otype) == POINTER_TYPE
379518334Speter	  && TREE_CODE (TREE_TYPE (otype)) != VOID_TYPE
379618334Speter	  && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE
379750397Sobrien	  /* Don't warn about opaque types, where the actual alignment
379850397Sobrien	     restriction is unknown.  */
379950397Sobrien	  && !((TREE_CODE (TREE_TYPE (otype)) == UNION_TYPE
380050397Sobrien		|| TREE_CODE (TREE_TYPE (otype)) == RECORD_TYPE)
380150397Sobrien	       && TYPE_MODE (TREE_TYPE (otype)) == VOIDmode)
380218334Speter	  && TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (otype)))
380318334Speter	warning ("cast increases required alignment of target type");
380418334Speter
380518334Speter      if (TREE_CODE (type) == INTEGER_TYPE
380618334Speter	  && TREE_CODE (otype) == POINTER_TYPE
380718334Speter	  && TYPE_PRECISION (type) != TYPE_PRECISION (otype)
380818334Speter	  && !TREE_CONSTANT (value))
380918334Speter	warning ("cast from pointer to integer of different size");
381018334Speter
381118334Speter      if (warn_bad_function_cast
381218334Speter	  && TREE_CODE (value) == CALL_EXPR
381318334Speter	  && TREE_CODE (type) != TREE_CODE (otype))
381418334Speter	warning ("cast does not match function type");
381518334Speter
381618334Speter      if (TREE_CODE (type) == POINTER_TYPE
381718334Speter	  && TREE_CODE (otype) == INTEGER_TYPE
381818334Speter	  && TYPE_PRECISION (type) != TYPE_PRECISION (otype)
381918334Speter#if 0
382018334Speter	  /* Don't warn about converting 0 to pointer,
382118334Speter	     provided the 0 was explicit--not cast or made by folding.  */
382218334Speter	  && !(TREE_CODE (value) == INTEGER_CST && integer_zerop (value))
382318334Speter#endif
382418334Speter	  /* Don't warn about converting any constant.  */
382518334Speter	  && !TREE_CONSTANT (value))
382618334Speter	warning ("cast to pointer from integer of different size");
382718334Speter
382818334Speter      ovalue = value;
382918334Speter      value = convert (type, value);
383018334Speter
383118334Speter      /* Ignore any integer overflow caused by the cast.  */
383218334Speter      if (TREE_CODE (value) == INTEGER_CST)
383318334Speter	{
383418334Speter	  TREE_OVERFLOW (value) = TREE_OVERFLOW (ovalue);
383518334Speter	  TREE_CONSTANT_OVERFLOW (value) = TREE_CONSTANT_OVERFLOW (ovalue);
383618334Speter	}
383718334Speter    }
383818334Speter
383918334Speter  /* Pedantically, don't ley (void *) (FOO *) 0 be a null pointer constant.  */
384018334Speter  if (pedantic && TREE_CODE (value) == INTEGER_CST
384118334Speter      && TREE_CODE (expr) == INTEGER_CST
384218334Speter      && TREE_CODE (TREE_TYPE (expr)) != INTEGER_TYPE)
384318334Speter    value = non_lvalue (value);
384418334Speter
384518334Speter  /* If pedantic, don't let a cast be an lvalue.  */
384618334Speter  if (value == expr && pedantic)
384718334Speter    value = non_lvalue (value);
384818334Speter
384918334Speter  return value;
385018334Speter}
385118334Speter
385218334Speter/* Build an assignment expression of lvalue LHS from value RHS.
385318334Speter   MODIFYCODE is the code for a binary operator that we use
385418334Speter   to combine the old value of LHS with RHS to get the new value.
385518334Speter   Or else MODIFYCODE is NOP_EXPR meaning do a simple assignment.  */
385618334Speter
385718334Spetertree
385818334Speterbuild_modify_expr (lhs, modifycode, rhs)
385918334Speter     tree lhs, rhs;
386018334Speter     enum tree_code modifycode;
386118334Speter{
386218334Speter  register tree result;
386318334Speter  tree newrhs;
386418334Speter  tree lhstype = TREE_TYPE (lhs);
386518334Speter  tree olhstype = lhstype;
386618334Speter
386718334Speter  /* Types that aren't fully specified cannot be used in assignments.  */
386818334Speter  lhs = require_complete_type (lhs);
386918334Speter
387018334Speter  /* Avoid duplicate error messages from operands that had errors.  */
387118334Speter  if (TREE_CODE (lhs) == ERROR_MARK || TREE_CODE (rhs) == ERROR_MARK)
387218334Speter    return error_mark_node;
387318334Speter
387418334Speter  /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
387518334Speter  /* Do not use STRIP_NOPS here.  We do not want an enumerator
387618334Speter     whose value is 0 to count as a null pointer constant.  */
387718334Speter  if (TREE_CODE (rhs) == NON_LVALUE_EXPR)
387818334Speter    rhs = TREE_OPERAND (rhs, 0);
387918334Speter
388018334Speter  newrhs = rhs;
388118334Speter
388218334Speter  /* Handle control structure constructs used as "lvalues".  */
388318334Speter
388418334Speter  switch (TREE_CODE (lhs))
388518334Speter    {
388618334Speter      /* Handle (a, b) used as an "lvalue".  */
388718334Speter    case COMPOUND_EXPR:
388818334Speter      pedantic_lvalue_warning (COMPOUND_EXPR);
388918334Speter      newrhs = build_modify_expr (TREE_OPERAND (lhs, 1),
389018334Speter				  modifycode, rhs);
389118334Speter      if (TREE_CODE (newrhs) == ERROR_MARK)
389218334Speter	return error_mark_node;
389318334Speter      return build (COMPOUND_EXPR, lhstype,
389418334Speter		    TREE_OPERAND (lhs, 0), newrhs);
389518334Speter
389618334Speter      /* Handle (a ? b : c) used as an "lvalue".  */
389718334Speter    case COND_EXPR:
389818334Speter      pedantic_lvalue_warning (COND_EXPR);
389918334Speter      rhs = save_expr (rhs);
390018334Speter      {
390118334Speter	/* Produce (a ? (b = rhs) : (c = rhs))
390218334Speter	   except that the RHS goes through a save-expr
390318334Speter	   so the code to compute it is only emitted once.  */
390418334Speter	tree cond
390518334Speter	  = build_conditional_expr (TREE_OPERAND (lhs, 0),
390618334Speter				    build_modify_expr (TREE_OPERAND (lhs, 1),
390718334Speter						       modifycode, rhs),
390818334Speter				    build_modify_expr (TREE_OPERAND (lhs, 2),
390918334Speter						       modifycode, rhs));
391018334Speter	if (TREE_CODE (cond) == ERROR_MARK)
391118334Speter	  return cond;
391218334Speter	/* Make sure the code to compute the rhs comes out
391318334Speter	   before the split.  */
391418334Speter	return build (COMPOUND_EXPR, TREE_TYPE (lhs),
391518334Speter		      /* But cast it to void to avoid an "unused" error.  */
391618334Speter		      convert (void_type_node, rhs), cond);
391718334Speter      }
391850397Sobrien    default:
391950397Sobrien      break;
392018334Speter    }
392118334Speter
392218334Speter  /* If a binary op has been requested, combine the old LHS value with the RHS
392318334Speter     producing the value we should actually store into the LHS.  */
392418334Speter
392518334Speter  if (modifycode != NOP_EXPR)
392618334Speter    {
392718334Speter      lhs = stabilize_reference (lhs);
392818334Speter      newrhs = build_binary_op (modifycode, lhs, rhs, 1);
392918334Speter    }
393018334Speter
393118334Speter  /* Handle a cast used as an "lvalue".
393218334Speter     We have already performed any binary operator using the value as cast.
393318334Speter     Now convert the result to the cast type of the lhs,
393418334Speter     and then true type of the lhs and store it there;
393518334Speter     then convert result back to the cast type to be the value
393618334Speter     of the assignment.  */
393718334Speter
393818334Speter  switch (TREE_CODE (lhs))
393918334Speter    {
394018334Speter    case NOP_EXPR:
394118334Speter    case CONVERT_EXPR:
394218334Speter    case FLOAT_EXPR:
394318334Speter    case FIX_TRUNC_EXPR:
394418334Speter    case FIX_FLOOR_EXPR:
394518334Speter    case FIX_ROUND_EXPR:
394618334Speter    case FIX_CEIL_EXPR:
394718334Speter      if (TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE
394818334Speter	  || TREE_CODE (TREE_TYPE (newrhs)) == FUNCTION_TYPE)
394918334Speter	newrhs = default_conversion (newrhs);
395018334Speter      {
395118334Speter	tree inner_lhs = TREE_OPERAND (lhs, 0);
395218334Speter	tree result;
395318334Speter	result = build_modify_expr (inner_lhs, NOP_EXPR,
395418334Speter				    convert (TREE_TYPE (inner_lhs),
395518334Speter					     convert (lhstype, newrhs)));
395618334Speter	if (TREE_CODE (result) == ERROR_MARK)
395718334Speter	  return result;
395818334Speter	pedantic_lvalue_warning (CONVERT_EXPR);
395918334Speter	return convert (TREE_TYPE (lhs), result);
396018334Speter      }
396150397Sobrien
396250397Sobrien    default:
396350397Sobrien      break;
396418334Speter    }
396518334Speter
396618334Speter  /* Now we have handled acceptable kinds of LHS that are not truly lvalues.
396718334Speter     Reject anything strange now.  */
396818334Speter
396952284Sobrien  if (!lvalue_or_else (lhs, "invalid lvalue in assignment"))
397018334Speter    return error_mark_node;
397118334Speter
397218334Speter  /* Warn about storing in something that is `const'.  */
397318334Speter
397418334Speter  if (TREE_READONLY (lhs) || TYPE_READONLY (lhstype)
397518334Speter      || ((TREE_CODE (lhstype) == RECORD_TYPE
397618334Speter	   || TREE_CODE (lhstype) == UNION_TYPE)
397718334Speter	  && C_TYPE_FIELDS_READONLY (lhstype)))
397818334Speter    readonly_warning (lhs, "assignment");
397918334Speter
398018334Speter  /* If storing into a structure or union member,
398118334Speter     it has probably been given type `int'.
398218334Speter     Compute the type that would go with
398318334Speter     the actual amount of storage the member occupies.  */
398418334Speter
398518334Speter  if (TREE_CODE (lhs) == COMPONENT_REF
398618334Speter      && (TREE_CODE (lhstype) == INTEGER_TYPE
398718334Speter	  || TREE_CODE (lhstype) == REAL_TYPE
398818334Speter	  || TREE_CODE (lhstype) == ENUMERAL_TYPE))
398918334Speter    lhstype = TREE_TYPE (get_unwidened (lhs, 0));
399018334Speter
399118334Speter  /* If storing in a field that is in actuality a short or narrower than one,
399218334Speter     we must store in the field in its actual type.  */
399318334Speter
399418334Speter  if (lhstype != TREE_TYPE (lhs))
399518334Speter    {
399618334Speter      lhs = copy_node (lhs);
399718334Speter      TREE_TYPE (lhs) = lhstype;
399818334Speter    }
399918334Speter
400018334Speter  /* Convert new value to destination type.  */
400118334Speter
400252284Sobrien  newrhs = convert_for_assignment (lhstype, newrhs, _("assignment"),
400318334Speter				   NULL_TREE, NULL_TREE, 0);
400418334Speter  if (TREE_CODE (newrhs) == ERROR_MARK)
400518334Speter    return error_mark_node;
400618334Speter
400718334Speter  result = build (MODIFY_EXPR, lhstype, lhs, newrhs);
400818334Speter  TREE_SIDE_EFFECTS (result) = 1;
400918334Speter
401018334Speter  /* If we got the LHS in a different type for storing in,
401118334Speter     convert the result back to the nominal type of LHS
401218334Speter     so that the value we return always has the same type
401318334Speter     as the LHS argument.  */
401418334Speter
401518334Speter  if (olhstype == TREE_TYPE (result))
401618334Speter    return result;
401752284Sobrien  return convert_for_assignment (olhstype, result, _("assignment"),
401818334Speter				 NULL_TREE, NULL_TREE, 0);
401918334Speter}
402018334Speter
402118334Speter/* Convert value RHS to type TYPE as preparation for an assignment
402218334Speter   to an lvalue of type TYPE.
402318334Speter   The real work of conversion is done by `convert'.
402418334Speter   The purpose of this function is to generate error messages
402518334Speter   for assignments that are not allowed in C.
402618334Speter   ERRTYPE is a string to use in error messages:
402718334Speter   "assignment", "return", etc.  If it is null, this is parameter passing
402852284Sobrien   for a function call (and different error messages are output).
402918334Speter
403018334Speter   FUNNAME is the name of the function being called,
403118334Speter   as an IDENTIFIER_NODE, or null.
403218334Speter   PARMNUM is the number of the argument, for printing in error messages.  */
403318334Speter
403418334Speterstatic tree
403518334Speterconvert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
403618334Speter     tree type, rhs;
403752284Sobrien     const char *errtype;
403818334Speter     tree fundecl, funname;
403918334Speter     int parmnum;
404018334Speter{
404118334Speter  register enum tree_code codel = TREE_CODE (type);
404218334Speter  register tree rhstype;
404318334Speter  register enum tree_code coder;
404418334Speter
404518334Speter  /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
404618334Speter  /* Do not use STRIP_NOPS here.  We do not want an enumerator
404718334Speter     whose value is 0 to count as a null pointer constant.  */
404818334Speter  if (TREE_CODE (rhs) == NON_LVALUE_EXPR)
404918334Speter    rhs = TREE_OPERAND (rhs, 0);
405018334Speter
405118334Speter  if (TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE
405218334Speter      || TREE_CODE (TREE_TYPE (rhs)) == FUNCTION_TYPE)
405318334Speter    rhs = default_conversion (rhs);
405418334Speter  else if (optimize && TREE_CODE (rhs) == VAR_DECL)
405518334Speter    rhs = decl_constant_value (rhs);
405618334Speter
405718334Speter  rhstype = TREE_TYPE (rhs);
405818334Speter  coder = TREE_CODE (rhstype);
405918334Speter
406018334Speter  if (coder == ERROR_MARK)
406118334Speter    return error_mark_node;
406218334Speter
406318334Speter  if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (rhstype))
406418334Speter    {
406518334Speter      overflow_warning (rhs);
406618334Speter      /* Check for Objective-C protocols.  This will issue a warning if
406718334Speter	 there are protocol violations.  No need to use the return value.  */
406818334Speter      maybe_objc_comptypes (type, rhstype, 0);
406918334Speter      return rhs;
407018334Speter    }
407118334Speter
407218334Speter  if (coder == VOID_TYPE)
407318334Speter    {
407418334Speter      error ("void value not ignored as it ought to be");
407518334Speter      return error_mark_node;
407618334Speter    }
407718334Speter  /* Arithmetic types all interconvert, and enum is treated like int.  */
407818334Speter  if ((codel == INTEGER_TYPE || codel == REAL_TYPE || codel == ENUMERAL_TYPE
407918334Speter       || codel == COMPLEX_TYPE)
408018334Speter      && (coder == INTEGER_TYPE || coder == REAL_TYPE || coder == ENUMERAL_TYPE
408118334Speter	  || coder == COMPLEX_TYPE))
408218334Speter    return convert_and_check (type, rhs);
408318334Speter
408450397Sobrien  /* Conversion to a transparent union from its member types.
408550397Sobrien     This applies only to function arguments.  */
408650397Sobrien  else if (codel == UNION_TYPE && TYPE_TRANSPARENT_UNION (type) && ! errtype)
408718334Speter    {
408818334Speter      tree memb_types;
408950397Sobrien      tree marginal_memb_type = 0;
409018334Speter
409118334Speter      for (memb_types = TYPE_FIELDS (type); memb_types;
409218334Speter	   memb_types = TREE_CHAIN (memb_types))
409318334Speter	{
409450397Sobrien	  tree memb_type = TREE_TYPE (memb_types);
409518334Speter
409650397Sobrien	  if (comptypes (TYPE_MAIN_VARIANT (memb_type),
409750397Sobrien			 TYPE_MAIN_VARIANT (rhstype)))
409850397Sobrien	    break;
409950397Sobrien
410050397Sobrien	  if (TREE_CODE (memb_type) != POINTER_TYPE)
410150397Sobrien	    continue;
410250397Sobrien
410350397Sobrien	  if (coder == POINTER_TYPE)
410418334Speter	    {
410518334Speter	      register tree ttl = TREE_TYPE (memb_type);
410618334Speter	      register tree ttr = TREE_TYPE (rhstype);
410718334Speter
410818334Speter	      /* Any non-function converts to a [const][volatile] void *
410918334Speter		 and vice versa; otherwise, targets must be the same.
411018334Speter		 Meanwhile, the lhs target must have all the qualifiers of
411118334Speter		 the rhs.  */
411218334Speter	      if (TYPE_MAIN_VARIANT (ttl) == void_type_node
411318334Speter		  || TYPE_MAIN_VARIANT (ttr) == void_type_node
411418334Speter		  || comp_target_types (memb_type, rhstype))
411518334Speter		{
411650397Sobrien		  /* If this type won't generate any warnings, use it.  */
411752284Sobrien		  if (TYPE_QUALS (ttl) == TYPE_QUALS (ttr)
411852284Sobrien		      || ((TREE_CODE (ttr) == FUNCTION_TYPE
411952284Sobrien			   && TREE_CODE (ttl) == FUNCTION_TYPE)
412052284Sobrien			  ? ((TYPE_QUALS (ttl) | TYPE_QUALS (ttr))
412152284Sobrien			     == TYPE_QUALS (ttr))
412252284Sobrien			  : ((TYPE_QUALS (ttl) | TYPE_QUALS (ttr))
412352284Sobrien			     == TYPE_QUALS (ttl))))
412450397Sobrien		    break;
412518334Speter
412650397Sobrien		  /* Keep looking for a better type, but remember this one.  */
412750397Sobrien		  if (! marginal_memb_type)
412850397Sobrien		    marginal_memb_type = memb_type;
412918334Speter		}
413018334Speter	    }
413118334Speter
413218334Speter	  /* Can convert integer zero to any pointer type.  */
413350397Sobrien	  if (integer_zerop (rhs)
413450397Sobrien	      || (TREE_CODE (rhs) == NOP_EXPR
413550397Sobrien		  && integer_zerop (TREE_OPERAND (rhs, 0))))
413650397Sobrien	    {
413750397Sobrien	      rhs = null_pointer_node;
413850397Sobrien	      break;
413950397Sobrien	    }
414018334Speter	}
414150397Sobrien
414250397Sobrien      if (memb_types || marginal_memb_type)
414350397Sobrien	{
414450397Sobrien	  if (! memb_types)
414550397Sobrien	    {
414650397Sobrien	      /* We have only a marginally acceptable member type;
414750397Sobrien		 it needs a warning.  */
414850397Sobrien	      register tree ttl = TREE_TYPE (marginal_memb_type);
414950397Sobrien	      register tree ttr = TREE_TYPE (rhstype);
415050397Sobrien
415150397Sobrien	      /* Const and volatile mean something different for function
415250397Sobrien		 types, so the usual warnings are not appropriate.  */
415350397Sobrien	      if (TREE_CODE (ttr) == FUNCTION_TYPE
415450397Sobrien		  && TREE_CODE (ttl) == FUNCTION_TYPE)
415550397Sobrien		{
415650397Sobrien		  /* Because const and volatile on functions are
415750397Sobrien		     restrictions that say the function will not do
415850397Sobrien		     certain things, it is okay to use a const or volatile
415950397Sobrien		     function where an ordinary one is wanted, but not
416050397Sobrien		     vice-versa.  */
416152284Sobrien		  if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr))
416252284Sobrien		    warn_for_assignment ("%s makes qualified function pointer from unqualified",
416352284Sobrien					 errtype, funname, parmnum);
416450397Sobrien		}
416552284Sobrien	      else if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl))
416652284Sobrien		warn_for_assignment ("%s discards qualifiers from pointer target type",
416752284Sobrien				     errtype, funname,
416852284Sobrien				     parmnum);
416950397Sobrien	    }
417050397Sobrien
417150397Sobrien	  if (pedantic && ! DECL_IN_SYSTEM_HEADER (fundecl))
417250397Sobrien	    pedwarn ("ANSI C prohibits argument conversion to union type");
417350397Sobrien
417450397Sobrien	  return build1 (NOP_EXPR, type, rhs);
417550397Sobrien	}
417618334Speter    }
417718334Speter
417818334Speter  /* Conversions among pointers */
417918334Speter  else if (codel == POINTER_TYPE && coder == POINTER_TYPE)
418018334Speter    {
418118334Speter      register tree ttl = TREE_TYPE (type);
418218334Speter      register tree ttr = TREE_TYPE (rhstype);
418318334Speter
418418334Speter      /* Any non-function converts to a [const][volatile] void *
418518334Speter	 and vice versa; otherwise, targets must be the same.
418618334Speter	 Meanwhile, the lhs target must have all the qualifiers of the rhs.  */
418718334Speter      if (TYPE_MAIN_VARIANT (ttl) == void_type_node
418818334Speter	  || TYPE_MAIN_VARIANT (ttr) == void_type_node
418918334Speter	  || comp_target_types (type, rhstype)
419018334Speter	  || (unsigned_type (TYPE_MAIN_VARIANT (ttl))
419118334Speter	      == unsigned_type (TYPE_MAIN_VARIANT (ttr))))
419218334Speter	{
419318334Speter	  if (pedantic
419418334Speter	      && ((TYPE_MAIN_VARIANT (ttl) == void_type_node
419518334Speter		   && TREE_CODE (ttr) == FUNCTION_TYPE)
419618334Speter		  ||
419718334Speter		  (TYPE_MAIN_VARIANT (ttr) == void_type_node
419818334Speter		   /* Check TREE_CODE to catch cases like (void *) (char *) 0
419918334Speter		      which are not ANSI null ptr constants.  */
420018334Speter		   && (!integer_zerop (rhs) || TREE_CODE (rhs) == NOP_EXPR)
420118334Speter		   && TREE_CODE (ttl) == FUNCTION_TYPE)))
420218334Speter	    warn_for_assignment ("ANSI forbids %s between function pointer and `void *'",
420352284Sobrien				 errtype, funname, parmnum);
420418334Speter	  /* Const and volatile mean something different for function types,
420518334Speter	     so the usual warnings are not appropriate.  */
420618334Speter	  else if (TREE_CODE (ttr) != FUNCTION_TYPE
420718334Speter		   && TREE_CODE (ttl) != FUNCTION_TYPE)
420818334Speter	    {
420952284Sobrien	      if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl))
421052284Sobrien		warn_for_assignment ("%s discards qualifiers from pointer target type",
421152284Sobrien				     errtype, funname, parmnum);
421218334Speter	      /* If this is not a case of ignoring a mismatch in signedness,
421318334Speter		 no warning.  */
421418334Speter	      else if (TYPE_MAIN_VARIANT (ttl) == void_type_node
421518334Speter		       || TYPE_MAIN_VARIANT (ttr) == void_type_node
421618334Speter		       || comp_target_types (type, rhstype))
421718334Speter		;
421818334Speter	      /* If there is a mismatch, do warn.  */
421918334Speter	      else if (pedantic)
422018334Speter		warn_for_assignment ("pointer targets in %s differ in signedness",
422152284Sobrien				     errtype, funname, parmnum);
422218334Speter	    }
422318334Speter	  else if (TREE_CODE (ttl) == FUNCTION_TYPE
422418334Speter		   && TREE_CODE (ttr) == FUNCTION_TYPE)
422518334Speter	    {
422618334Speter	      /* Because const and volatile on functions are restrictions
422718334Speter		 that say the function will not do certain things,
422818334Speter		 it is okay to use a const or volatile function
422918334Speter		 where an ordinary one is wanted, but not vice-versa.  */
423052284Sobrien	      if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr))
423152284Sobrien		warn_for_assignment ("%s makes qualified function pointer from unqualified",
423252284Sobrien				     errtype, funname, parmnum);
423318334Speter	    }
423418334Speter	}
423518334Speter      else
423618334Speter	warn_for_assignment ("%s from incompatible pointer type",
423752284Sobrien			     errtype, funname, parmnum);
423818334Speter      return convert (type, rhs);
423918334Speter    }
424018334Speter  else if (codel == POINTER_TYPE && coder == INTEGER_TYPE)
424118334Speter    {
424218334Speter      /* An explicit constant 0 can convert to a pointer,
424318334Speter	 or one that results from arithmetic, even including
424418334Speter	 a cast to integer type.  */
424518334Speter      if (! (TREE_CODE (rhs) == INTEGER_CST && integer_zerop (rhs))
424618334Speter	  &&
424718334Speter	  ! (TREE_CODE (rhs) == NOP_EXPR
424818334Speter	     && TREE_CODE (TREE_TYPE (rhs)) == INTEGER_TYPE
424918334Speter	     && TREE_CODE (TREE_OPERAND (rhs, 0)) == INTEGER_CST
425018334Speter	     && integer_zerop (TREE_OPERAND (rhs, 0))))
425118334Speter	{
425218334Speter	  warn_for_assignment ("%s makes pointer from integer without a cast",
425352284Sobrien			       errtype, funname, parmnum);
425418334Speter	  return convert (type, rhs);
425518334Speter	}
425618334Speter      return null_pointer_node;
425718334Speter    }
425818334Speter  else if (codel == INTEGER_TYPE && coder == POINTER_TYPE)
425918334Speter    {
426018334Speter      warn_for_assignment ("%s makes integer from pointer without a cast",
426152284Sobrien			   errtype, funname, parmnum);
426218334Speter      return convert (type, rhs);
426318334Speter    }
426418334Speter
426518334Speter  if (!errtype)
426618334Speter    {
426718334Speter      if (funname)
426818334Speter 	{
426918334Speter 	  tree selector = maybe_building_objc_message_expr ();
427018334Speter
427118334Speter 	  if (selector && parmnum > 2)
427218334Speter 	    error ("incompatible type for argument %d of `%s'",
427318334Speter		   parmnum - 2, IDENTIFIER_POINTER (selector));
427418334Speter 	  else
427518334Speter	    error ("incompatible type for argument %d of `%s'",
427618334Speter		   parmnum, IDENTIFIER_POINTER (funname));
427718334Speter	}
427818334Speter      else
427918334Speter	error ("incompatible type for argument %d of indirect function call",
428018334Speter	       parmnum);
428118334Speter    }
428218334Speter  else
428352284Sobrien    error ("incompatible types in %s", errtype);
428418334Speter
428518334Speter  return error_mark_node;
428618334Speter}
428718334Speter
428852284Sobrien/* Print a warning using MSGID.
428918334Speter   It gets OPNAME as its one parameter.
429018334Speter   If OPNAME is null, it is replaced by "passing arg ARGNUM of `FUNCTION'".
429118334Speter   FUNCTION and ARGNUM are handled specially if we are building an
429218334Speter   Objective-C selector.  */
429318334Speter
429418334Speterstatic void
429552284Sobrienwarn_for_assignment (msgid, opname, function, argnum)
429652284Sobrien     const char *msgid;
429752284Sobrien     const char *opname;
429818334Speter     tree function;
429918334Speter     int argnum;
430018334Speter{
430118334Speter  if (opname == 0)
430218334Speter    {
430318334Speter      tree selector = maybe_building_objc_message_expr ();
430452284Sobrien      char * new_opname;
430518334Speter
430618334Speter      if (selector && argnum > 2)
430718334Speter	{
430818334Speter	  function = selector;
430918334Speter	  argnum -= 2;
431018334Speter	}
431118334Speter      if (function)
431218334Speter	{
431318334Speter	  /* Function name is known; supply it.  */
431452284Sobrien	  const char *argstring = _("passing arg %d of `%s'");
431552284Sobrien	  new_opname = (char *) alloca (IDENTIFIER_LENGTH (function)
431652284Sobrien					+ strlen (argstring) + 1 + 25
431752284Sobrien					/*%d*/ + 1);
431852284Sobrien	  sprintf (new_opname, argstring, argnum,
431952284Sobrien		   IDENTIFIER_POINTER (function));
432018334Speter	}
432118334Speter      else
432218334Speter	{
432352284Sobrien	  /* Function name unknown (call through ptr); just give arg number.*/
432452284Sobrien	  const char *argnofun = _("passing arg %d of pointer to function");
432552284Sobrien	  new_opname = (char *) alloca (strlen (argnofun) + 1 + 25 /*%d*/ + 1);
432652284Sobrien	  sprintf (new_opname, argnofun, argnum);
432718334Speter	}
432852284Sobrien      opname = new_opname;
432918334Speter    }
433052284Sobrien  pedwarn (msgid, opname);
433118334Speter}
433218334Speter
433318334Speter/* Return nonzero if VALUE is a valid constant-valued expression
433418334Speter   for use in initializing a static variable; one that can be an
433518334Speter   element of a "constant" initializer.
433618334Speter
433718334Speter   Return null_pointer_node if the value is absolute;
433818334Speter   if it is relocatable, return the variable that determines the relocation.
433918334Speter   We assume that VALUE has been folded as much as possible;
434018334Speter   therefore, we do not need to check for such things as
434118334Speter   arithmetic-combinations of integers.  */
434218334Speter
434318334Spetertree
434418334Speterinitializer_constant_valid_p (value, endtype)
434518334Speter     tree value;
434618334Speter     tree endtype;
434718334Speter{
434818334Speter  switch (TREE_CODE (value))
434918334Speter    {
435018334Speter    case CONSTRUCTOR:
435118334Speter      if ((TREE_CODE (TREE_TYPE (value)) == UNION_TYPE
435218334Speter	   || TREE_CODE (TREE_TYPE (value)) == RECORD_TYPE)
435350397Sobrien	  && TREE_CONSTANT (value)
435450397Sobrien	  && CONSTRUCTOR_ELTS (value))
435518334Speter	return
435618334Speter	  initializer_constant_valid_p (TREE_VALUE (CONSTRUCTOR_ELTS (value)),
435718334Speter					endtype);
435818334Speter
435918334Speter      return TREE_STATIC (value) ? null_pointer_node : 0;
436018334Speter
436118334Speter    case INTEGER_CST:
436218334Speter    case REAL_CST:
436318334Speter    case STRING_CST:
436418334Speter    case COMPLEX_CST:
436518334Speter      return null_pointer_node;
436618334Speter
436718334Speter    case ADDR_EXPR:
436818334Speter      return TREE_OPERAND (value, 0);
436918334Speter
437018334Speter    case NON_LVALUE_EXPR:
437118334Speter      return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
437218334Speter
437318334Speter    case CONVERT_EXPR:
437418334Speter    case NOP_EXPR:
437518334Speter      /* Allow conversions between pointer types.  */
437618334Speter      if (TREE_CODE (TREE_TYPE (value)) == POINTER_TYPE
437718334Speter	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == POINTER_TYPE)
437818334Speter	return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
437918334Speter
438018334Speter      /* Allow conversions between real types.  */
438118334Speter      if (TREE_CODE (TREE_TYPE (value)) == REAL_TYPE
438218334Speter	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == REAL_TYPE)
438318334Speter	return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
438418334Speter
438518334Speter      /* Allow length-preserving conversions between integer types.  */
438618334Speter      if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
438718334Speter	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE
438818334Speter	  && (TYPE_PRECISION (TREE_TYPE (value))
438918334Speter	      == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))))
439018334Speter	return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
439118334Speter
439218334Speter      /* Allow conversions between other integer types only if
439318334Speter	 explicit value.  */
439418334Speter      if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
439518334Speter	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE)
439618334Speter	{
439718334Speter	  tree inner = initializer_constant_valid_p (TREE_OPERAND (value, 0),
439818334Speter						     endtype);
439918334Speter	  if (inner == null_pointer_node)
440018334Speter	    return null_pointer_node;
440118334Speter	  return 0;
440218334Speter	}
440318334Speter
440418334Speter      /* Allow (int) &foo provided int is as wide as a pointer.  */
440518334Speter      if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
440618334Speter	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == POINTER_TYPE
440718334Speter	  && (TYPE_PRECISION (TREE_TYPE (value))
440818334Speter	      >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))))
440918334Speter	return initializer_constant_valid_p (TREE_OPERAND (value, 0),
441018334Speter					     endtype);
441118334Speter
441252284Sobrien      /* Likewise conversions from int to pointers, but also allow
441352284Sobrien	 conversions from 0.  */
441418334Speter      if (TREE_CODE (TREE_TYPE (value)) == POINTER_TYPE
441552284Sobrien	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE)
441652284Sobrien	{
441752284Sobrien	  if (integer_zerop (TREE_OPERAND (value, 0)))
441852284Sobrien	    return null_pointer_node;
441952284Sobrien	  else if (TYPE_PRECISION (TREE_TYPE (value))
442052284Sobrien		   <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0))))
442152284Sobrien	    return initializer_constant_valid_p (TREE_OPERAND (value, 0),
442252284Sobrien						 endtype);
442352284Sobrien	}
442418334Speter
442518334Speter      /* Allow conversions to union types if the value inside is okay.  */
442618334Speter      if (TREE_CODE (TREE_TYPE (value)) == UNION_TYPE)
442718334Speter	return initializer_constant_valid_p (TREE_OPERAND (value, 0),
442818334Speter					     endtype);
442918334Speter      return 0;
443018334Speter
443118334Speter    case PLUS_EXPR:
443218334Speter      if (TREE_CODE (endtype) == INTEGER_TYPE
443318334Speter	  && TYPE_PRECISION (endtype) < POINTER_SIZE)
443418334Speter	return 0;
443518334Speter      {
443618334Speter	tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
443718334Speter						    endtype);
443818334Speter	tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1),
443918334Speter						    endtype);
444018334Speter	/* If either term is absolute, use the other terms relocation.  */
444118334Speter	if (valid0 == null_pointer_node)
444218334Speter	  return valid1;
444318334Speter	if (valid1 == null_pointer_node)
444418334Speter	  return valid0;
444518334Speter	return 0;
444618334Speter      }
444718334Speter
444818334Speter    case MINUS_EXPR:
444918334Speter      if (TREE_CODE (endtype) == INTEGER_TYPE
445018334Speter	  && TYPE_PRECISION (endtype) < POINTER_SIZE)
445118334Speter	return 0;
445218334Speter      {
445318334Speter	tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
445418334Speter						    endtype);
445518334Speter	tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1),
445618334Speter						    endtype);
445718334Speter	/* Win if second argument is absolute.  */
445818334Speter	if (valid1 == null_pointer_node)
445918334Speter	  return valid0;
446018334Speter	/* Win if both arguments have the same relocation.
446118334Speter	   Then the value is absolute.  */
446218334Speter	if (valid0 == valid1)
446318334Speter	  return null_pointer_node;
446418334Speter	return 0;
446518334Speter      }
446650397Sobrien
446750397Sobrien    default:
446850397Sobrien      return 0;
446918334Speter    }
447018334Speter}
447118334Speter
447218334Speter/* If VALUE is a compound expr all of whose expressions are constant, then
447318334Speter   return its value.  Otherwise, return error_mark_node.
447418334Speter
447518334Speter   This is for handling COMPOUND_EXPRs as initializer elements
447618334Speter   which is allowed with a warning when -pedantic is specified.  */
447718334Speter
447818334Speterstatic tree
447918334Spetervalid_compound_expr_initializer (value, endtype)
448018334Speter     tree value;
448118334Speter     tree endtype;
448218334Speter{
448318334Speter  if (TREE_CODE (value) == COMPOUND_EXPR)
448418334Speter    {
448518334Speter      if (valid_compound_expr_initializer (TREE_OPERAND (value, 0), endtype)
448618334Speter	  == error_mark_node)
448718334Speter	return error_mark_node;
448818334Speter      return valid_compound_expr_initializer (TREE_OPERAND (value, 1),
448918334Speter					      endtype);
449018334Speter    }
449118334Speter  else if (! TREE_CONSTANT (value)
449218334Speter	   && ! initializer_constant_valid_p (value, endtype))
449318334Speter    return error_mark_node;
449418334Speter  else
449518334Speter    return value;
449618334Speter}
449718334Speter
449818334Speter/* Perform appropriate conversions on the initial value of a variable,
449918334Speter   store it in the declaration DECL,
450018334Speter   and print any error messages that are appropriate.
450118334Speter   If the init is invalid, store an ERROR_MARK.  */
450218334Speter
450318334Spetervoid
450418334Speterstore_init_value (decl, init)
450518334Speter     tree decl, init;
450618334Speter{
450718334Speter  register tree value, type;
450818334Speter
450918334Speter  /* If variable's type was invalidly declared, just ignore it.  */
451018334Speter
451118334Speter  type = TREE_TYPE (decl);
451218334Speter  if (TREE_CODE (type) == ERROR_MARK)
451318334Speter    return;
451418334Speter
451518334Speter  /* Digest the specified initializer into an expression.  */
451618334Speter
451718334Speter  value = digest_init (type, init, TREE_STATIC (decl),
451818334Speter		       TREE_STATIC (decl) || pedantic);
451918334Speter
452018334Speter  /* Store the expression if valid; else report error.  */
452118334Speter
452218334Speter#if 0
452318334Speter  /* Note that this is the only place we can detect the error
452418334Speter     in a case such as   struct foo bar = (struct foo) { x, y };
452518334Speter     where there is one initial value which is a constructor expression.  */
452618334Speter  if (value == error_mark_node)
452718334Speter    ;
452818334Speter  else if (TREE_STATIC (decl) && ! TREE_CONSTANT (value))
452918334Speter    {
453018334Speter      error ("initializer for static variable is not constant");
453118334Speter      value = error_mark_node;
453218334Speter    }
453318334Speter  else if (TREE_STATIC (decl)
453418334Speter	   && initializer_constant_valid_p (value, TREE_TYPE (value)) == 0)
453518334Speter    {
453618334Speter      error ("initializer for static variable uses complicated arithmetic");
453718334Speter      value = error_mark_node;
453818334Speter    }
453918334Speter  else
454018334Speter    {
454118334Speter      if (pedantic && TREE_CODE (value) == CONSTRUCTOR)
454218334Speter	{
454318334Speter	  if (! TREE_CONSTANT (value))
454418334Speter	    pedwarn ("aggregate initializer is not constant");
454518334Speter	  else if (! TREE_STATIC (value))
454618334Speter	    pedwarn ("aggregate initializer uses complicated arithmetic");
454718334Speter	}
454818334Speter    }
454918334Speter#endif
455018334Speter
455118334Speter  DECL_INITIAL (decl) = value;
455218334Speter
455318334Speter  /* ANSI wants warnings about out-of-range constant initializers.  */
455418334Speter  STRIP_TYPE_NOPS (value);
455518334Speter  constant_expression_warning (value);
455618334Speter}
455718334Speter
455818334Speter/* Methods for storing and printing names for error messages.  */
455918334Speter
456018334Speter/* Implement a spelling stack that allows components of a name to be pushed
456118334Speter   and popped.  Each element on the stack is this structure.  */
456218334Speter
456318334Speterstruct spelling
456418334Speter{
456518334Speter  int kind;
456618334Speter  union
456718334Speter    {
456818334Speter      int i;
456952284Sobrien      const char *s;
457018334Speter    } u;
457118334Speter};
457218334Speter
457318334Speter#define SPELLING_STRING 1
457418334Speter#define SPELLING_MEMBER 2
457518334Speter#define SPELLING_BOUNDS 3
457618334Speter
457718334Speterstatic struct spelling *spelling;	/* Next stack element (unused).  */
457818334Speterstatic struct spelling *spelling_base;	/* Spelling stack base.  */
457918334Speterstatic int spelling_size;		/* Size of the spelling stack.  */
458018334Speter
458118334Speter/* Macros to save and restore the spelling stack around push_... functions.
458218334Speter   Alternative to SAVE_SPELLING_STACK.  */
458318334Speter
458418334Speter#define SPELLING_DEPTH() (spelling - spelling_base)
458518334Speter#define RESTORE_SPELLING_DEPTH(depth) (spelling = spelling_base + depth)
458618334Speter
458718334Speter/* Save and restore the spelling stack around arbitrary C code.  */
458818334Speter
458918334Speter#define SAVE_SPELLING_DEPTH(code)		\
459018334Speter{						\
459118334Speter  int __depth = SPELLING_DEPTH ();		\
459218334Speter  code;						\
459318334Speter  RESTORE_SPELLING_DEPTH (__depth);		\
459418334Speter}
459518334Speter
459618334Speter/* Push an element on the spelling stack with type KIND and assign VALUE
459718334Speter   to MEMBER.  */
459818334Speter
459918334Speter#define PUSH_SPELLING(KIND, VALUE, MEMBER)				\
460018334Speter{									\
460118334Speter  int depth = SPELLING_DEPTH ();					\
460218334Speter									\
460318334Speter  if (depth >= spelling_size)						\
460418334Speter    {									\
460518334Speter      spelling_size += 10;						\
460618334Speter      if (spelling_base == 0)						\
460718334Speter	spelling_base							\
460818334Speter	  = (struct spelling *) xmalloc (spelling_size * sizeof (struct spelling));	\
460918334Speter      else								\
461018334Speter        spelling_base							\
461118334Speter	  = (struct spelling *) xrealloc (spelling_base,		\
461218334Speter					  spelling_size * sizeof (struct spelling));	\
461318334Speter      RESTORE_SPELLING_DEPTH (depth);					\
461418334Speter    }									\
461518334Speter									\
461618334Speter  spelling->kind = (KIND);						\
461718334Speter  spelling->MEMBER = (VALUE);						\
461818334Speter  spelling++;								\
461918334Speter}
462018334Speter
462118334Speter/* Push STRING on the stack.  Printed literally.  */
462218334Speter
462318334Speterstatic void
462418334Speterpush_string (string)
462552284Sobrien     const char *string;
462618334Speter{
462718334Speter  PUSH_SPELLING (SPELLING_STRING, string, u.s);
462818334Speter}
462918334Speter
463018334Speter/* Push a member name on the stack.  Printed as '.' STRING.  */
463118334Speter
463218334Speterstatic void
463318334Speterpush_member_name (decl)
463418334Speter     tree decl;
463518334Speter
463618334Speter{
463752284Sobrien  const char *string
463818334Speter    = DECL_NAME (decl) ? IDENTIFIER_POINTER (DECL_NAME (decl)) : "<anonymous>";
463918334Speter  PUSH_SPELLING (SPELLING_MEMBER, string, u.s);
464018334Speter}
464118334Speter
464218334Speter/* Push an array bounds on the stack.  Printed as [BOUNDS].  */
464318334Speter
464418334Speterstatic void
464518334Speterpush_array_bounds (bounds)
464618334Speter     int bounds;
464718334Speter{
464818334Speter  PUSH_SPELLING (SPELLING_BOUNDS, bounds, u.i);
464918334Speter}
465018334Speter
465118334Speter/* Compute the maximum size in bytes of the printed spelling.  */
465218334Speter
465318334Speterstatic int
465418334Speterspelling_length ()
465518334Speter{
465618334Speter  register int size = 0;
465718334Speter  register struct spelling *p;
465818334Speter
465918334Speter  for (p = spelling_base; p < spelling; p++)
466018334Speter    {
466118334Speter      if (p->kind == SPELLING_BOUNDS)
466218334Speter	size += 25;
466318334Speter      else
466418334Speter	size += strlen (p->u.s) + 1;
466518334Speter    }
466618334Speter
466718334Speter  return size;
466818334Speter}
466918334Speter
467018334Speter/* Print the spelling to BUFFER and return it.  */
467118334Speter
467218334Speterstatic char *
467318334Speterprint_spelling (buffer)
467418334Speter     register char *buffer;
467518334Speter{
467618334Speter  register char *d = buffer;
467718334Speter  register struct spelling *p;
467818334Speter
467918334Speter  for (p = spelling_base; p < spelling; p++)
468018334Speter    if (p->kind == SPELLING_BOUNDS)
468118334Speter      {
468218334Speter	sprintf (d, "[%d]", p->u.i);
468318334Speter	d += strlen (d);
468418334Speter      }
468518334Speter    else
468618334Speter      {
468752284Sobrien	register const char *s;
468818334Speter	if (p->kind == SPELLING_MEMBER)
468918334Speter	  *d++ = '.';
469050397Sobrien	for (s = p->u.s; (*d = *s++); d++)
469118334Speter	  ;
469218334Speter      }
469318334Speter  *d++ = '\0';
469418334Speter  return buffer;
469518334Speter}
469618334Speter
469718334Speter/* Issue an error message for a bad initializer component.
469852284Sobrien   MSGID identifies the message.
469952284Sobrien   The component name is taken from the spelling stack.  */
470018334Speter
470118334Spetervoid
470252284Sobrienerror_init (msgid)
470352284Sobrien     const char *msgid;
470418334Speter{
470552284Sobrien  char *ofwhat;
470618334Speter
470752284Sobrien  error (msgid);
470852284Sobrien  ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
470918334Speter  if (*ofwhat)
471052284Sobrien    error ("(near initialization for `%s')", ofwhat);
471118334Speter}
471218334Speter
471318334Speter/* Issue a pedantic warning for a bad initializer component.
471452284Sobrien   MSGID identifies the message.
471552284Sobrien   The component name is taken from the spelling stack.  */
471618334Speter
471718334Spetervoid
471852284Sobrienpedwarn_init (msgid)
471952284Sobrien     const char *msgid;
472018334Speter{
472152284Sobrien  char *ofwhat;
472218334Speter
472352284Sobrien  pedwarn (msgid);
472452284Sobrien  ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
472518334Speter  if (*ofwhat)
472652284Sobrien    pedwarn ("(near initialization for `%s')", ofwhat);
472718334Speter}
472818334Speter
472918334Speter/* Issue a warning for a bad initializer component.
473052284Sobrien   MSGID identifies the message.
473152284Sobrien   The component name is taken from the spelling stack.  */
473218334Speter
473318334Speterstatic void
473452284Sobrienwarning_init (msgid)
473552284Sobrien     const char *msgid;
473618334Speter{
473752284Sobrien  char *ofwhat;
473818334Speter
473952284Sobrien  warning (msgid);
474052284Sobrien  ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
474118334Speter  if (*ofwhat)
474252284Sobrien    warning ("(near initialization for `%s')", ofwhat);
474318334Speter}
474418334Speter
474518334Speter/* Digest the parser output INIT as an initializer for type TYPE.
474618334Speter   Return a C expression of type TYPE to represent the initial value.
474718334Speter
474818334Speter   The arguments REQUIRE_CONSTANT and CONSTRUCTOR_CONSTANT request errors
474918334Speter   if non-constant initializers or elements are seen.  CONSTRUCTOR_CONSTANT
475018334Speter   applies only to elements of constructors.  */
475118334Speter
475218334Speterstatic tree
475318334Speterdigest_init (type, init, require_constant, constructor_constant)
475418334Speter     tree type, init;
475518334Speter     int require_constant, constructor_constant;
475618334Speter{
475718334Speter  enum tree_code code = TREE_CODE (type);
475818334Speter  tree inside_init = init;
475918334Speter
476018334Speter  if (init == error_mark_node)
476118334Speter    return init;
476218334Speter
476318334Speter  /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
476418334Speter  /* Do not use STRIP_NOPS here.  We do not want an enumerator
476518334Speter     whose value is 0 to count as a null pointer constant.  */
476618334Speter  if (TREE_CODE (init) == NON_LVALUE_EXPR)
476718334Speter    inside_init = TREE_OPERAND (init, 0);
476818334Speter
476918334Speter  /* Initialization of an array of chars from a string constant
477018334Speter     optionally enclosed in braces.  */
477118334Speter
477218334Speter  if (code == ARRAY_TYPE)
477318334Speter    {
477418334Speter      tree typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type));
477518334Speter      if ((typ1 == char_type_node
477618334Speter	   || typ1 == signed_char_type_node
477718334Speter	   || typ1 == unsigned_char_type_node
477818334Speter	   || typ1 == unsigned_wchar_type_node
477918334Speter	   || typ1 == signed_wchar_type_node)
478018334Speter	  && ((inside_init && TREE_CODE (inside_init) == STRING_CST)))
478118334Speter	{
478218334Speter	  if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
478318334Speter			 TYPE_MAIN_VARIANT (type)))
478418334Speter	    return inside_init;
478518334Speter
478618334Speter	  if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init)))
478718334Speter	       != char_type_node)
478818334Speter	      && TYPE_PRECISION (typ1) == TYPE_PRECISION (char_type_node))
478918334Speter	    {
479052284Sobrien	      error_init ("char-array initialized from wide string");
479118334Speter	      return error_mark_node;
479218334Speter	    }
479318334Speter	  if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init)))
479418334Speter	       == char_type_node)
479518334Speter	      && TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node))
479618334Speter	    {
479752284Sobrien	      error_init ("int-array initialized from non-wide string");
479818334Speter	      return error_mark_node;
479918334Speter	    }
480018334Speter
480118334Speter	  TREE_TYPE (inside_init) = type;
480218334Speter	  if (TYPE_DOMAIN (type) != 0
480318334Speter	      && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
480418334Speter	    {
480518334Speter	      register int size = TREE_INT_CST_LOW (TYPE_SIZE (type));
480618334Speter	      size = (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
480718334Speter	      /* Subtract 1 (or sizeof (wchar_t))
480818334Speter		 because it's ok to ignore the terminating null char
480918334Speter		 that is counted in the length of the constant.  */
481018334Speter	      if (size < TREE_STRING_LENGTH (inside_init)
481118334Speter		  - (TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node)
481218334Speter		     ? TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT
481318334Speter		     : 1))
481452284Sobrien		pedwarn_init ("initializer-string for array of chars is too long");
481518334Speter	    }
481618334Speter	  return inside_init;
481718334Speter	}
481818334Speter    }
481918334Speter
482018334Speter  /* Any type can be initialized
482118334Speter     from an expression of the same type, optionally with braces.  */
482218334Speter
482318334Speter  if (inside_init && TREE_TYPE (inside_init) != 0
482418334Speter      && (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
482518334Speter		     TYPE_MAIN_VARIANT (type))
482618334Speter	  || (code == ARRAY_TYPE
482718334Speter	      && comptypes (TREE_TYPE (inside_init), type))
482818334Speter	  || (code == POINTER_TYPE
482918334Speter	      && (TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE
483018334Speter		  || TREE_CODE (TREE_TYPE (inside_init)) == FUNCTION_TYPE)
483118334Speter	      && comptypes (TREE_TYPE (TREE_TYPE (inside_init)),
483218334Speter			    TREE_TYPE (type)))))
483318334Speter    {
483418334Speter      if (code == POINTER_TYPE
483518334Speter	  && (TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE
483618334Speter	      || TREE_CODE (TREE_TYPE (inside_init)) == FUNCTION_TYPE))
483718334Speter	inside_init = default_conversion (inside_init);
483818334Speter      else if (code == ARRAY_TYPE && TREE_CODE (inside_init) != STRING_CST
483918334Speter	       && TREE_CODE (inside_init) != CONSTRUCTOR)
484018334Speter	{
484152284Sobrien	  error_init ("array initialized from non-constant array expression");
484218334Speter	  return error_mark_node;
484318334Speter	}
484418334Speter
484518334Speter      if (optimize && TREE_CODE (inside_init) == VAR_DECL)
484618334Speter	inside_init = decl_constant_value (inside_init);
484718334Speter
484818334Speter      /* Compound expressions can only occur here if -pedantic or
484918334Speter	 -pedantic-errors is specified.  In the later case, we always want
485018334Speter	 an error.  In the former case, we simply want a warning.  */
485118334Speter      if (require_constant && pedantic
485218334Speter	  && TREE_CODE (inside_init) == COMPOUND_EXPR)
485318334Speter	{
485418334Speter	  inside_init
485518334Speter	    = valid_compound_expr_initializer (inside_init,
485618334Speter					       TREE_TYPE (inside_init));
485718334Speter	  if (inside_init == error_mark_node)
485852284Sobrien	    error_init ("initializer element is not constant");
485918334Speter	  else
486052284Sobrien	    pedwarn_init ("initializer element is not constant");
486118334Speter	  if (flag_pedantic_errors)
486218334Speter	    inside_init = error_mark_node;
486318334Speter	}
486418334Speter      else if (require_constant && ! TREE_CONSTANT (inside_init))
486518334Speter	{
486652284Sobrien	  error_init ("initializer element is not constant");
486718334Speter	  inside_init = error_mark_node;
486818334Speter	}
486918334Speter      else if (require_constant
487018334Speter	       && initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init)) == 0)
487118334Speter	{
487252284Sobrien	  error_init ("initializer element is not computable at load time");
487318334Speter	  inside_init = error_mark_node;
487418334Speter	}
487518334Speter
487618334Speter      return inside_init;
487718334Speter    }
487818334Speter
487918334Speter  /* Handle scalar types, including conversions.  */
488018334Speter
488118334Speter  if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE
488218334Speter      || code == ENUMERAL_TYPE || code == COMPLEX_TYPE)
488318334Speter    {
488418334Speter      /* Note that convert_for_assignment calls default_conversion
488518334Speter	 for arrays and functions.  We must not call it in the
488618334Speter	 case where inside_init is a null pointer constant.  */
488718334Speter      inside_init
488852284Sobrien	= convert_for_assignment (type, init, _("initialization"),
488918334Speter				  NULL_TREE, NULL_TREE, 0);
489018334Speter
489118334Speter      if (require_constant && ! TREE_CONSTANT (inside_init))
489218334Speter	{
489352284Sobrien	  error_init ("initializer element is not constant");
489418334Speter	  inside_init = error_mark_node;
489518334Speter	}
489618334Speter      else if (require_constant
489718334Speter	       && initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init)) == 0)
489818334Speter	{
489952284Sobrien	  error_init ("initializer element is not computable at load time");
490018334Speter	  inside_init = error_mark_node;
490118334Speter	}
490218334Speter
490318334Speter      return inside_init;
490418334Speter    }
490518334Speter
490618334Speter  /* Come here only for records and arrays.  */
490718334Speter
490818334Speter  if (TYPE_SIZE (type) && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
490918334Speter    {
491052284Sobrien      error_init ("variable-sized object may not be initialized");
491118334Speter      return error_mark_node;
491218334Speter    }
491318334Speter
491418334Speter  /* Traditionally, you can write  struct foo x = 0;
491518334Speter     and it initializes the first element of x to 0.  */
491618334Speter  if (flag_traditional)
491718334Speter    {
491818334Speter      tree top = 0, prev = 0, otype = type;
491918334Speter      while (TREE_CODE (type) == RECORD_TYPE
492018334Speter	     || TREE_CODE (type) == ARRAY_TYPE
492118334Speter	     || TREE_CODE (type) == QUAL_UNION_TYPE
492218334Speter	     || TREE_CODE (type) == UNION_TYPE)
492318334Speter	{
492418334Speter	  tree temp = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
492518334Speter	  if (prev == 0)
492618334Speter	    top = temp;
492718334Speter	  else
492818334Speter	    TREE_OPERAND (prev, 1) = build_tree_list (NULL_TREE, temp);
492918334Speter	  prev = temp;
493018334Speter	  if (TREE_CODE (type) == ARRAY_TYPE)
493118334Speter	    type = TREE_TYPE (type);
493218334Speter	  else if (TYPE_FIELDS (type))
493318334Speter	    type = TREE_TYPE (TYPE_FIELDS (type));
493418334Speter	  else
493518334Speter	    {
493652284Sobrien	      error_init ("invalid initializer");
493718334Speter	      return error_mark_node;
493818334Speter	    }
493918334Speter	}
494018334Speter
494118334Speter      if (otype != type)
494218334Speter	{
494318334Speter	  TREE_OPERAND (prev, 1)
494418334Speter	    = build_tree_list (NULL_TREE,
494518334Speter			       digest_init (type, init, require_constant,
494618334Speter					    constructor_constant));
494718334Speter	  return top;
494818334Speter	}
494918334Speter      else
495018334Speter	return error_mark_node;
495118334Speter    }
495252284Sobrien  error_init ("invalid initializer");
495318334Speter  return error_mark_node;
495418334Speter}
495518334Speter
495618334Speter/* Handle initializers that use braces.  */
495718334Speter
495818334Speter/* Type of object we are accumulating a constructor for.
495918334Speter   This type is always a RECORD_TYPE, UNION_TYPE or ARRAY_TYPE.  */
496018334Speterstatic tree constructor_type;
496118334Speter
496218334Speter/* For a RECORD_TYPE or UNION_TYPE, this is the chain of fields
496318334Speter   left to fill.  */
496418334Speterstatic tree constructor_fields;
496518334Speter
496618334Speter/* For an ARRAY_TYPE, this is the specified index
496718334Speter   at which to store the next element we get.
496818334Speter   This is a special INTEGER_CST node that we modify in place.  */
496918334Speterstatic tree constructor_index;
497018334Speter
497118334Speter/* For an ARRAY_TYPE, this is the end index of the range
497218334Speter   to initialize with the next element, or NULL in the ordinary case
497318334Speter   where the element is used just once.  */
497418334Speterstatic tree constructor_range_end;
497518334Speter
497618334Speter/* For an ARRAY_TYPE, this is the maximum index.  */
497718334Speterstatic tree constructor_max_index;
497818334Speter
497918334Speter/* For a RECORD_TYPE, this is the first field not yet written out.  */
498018334Speterstatic tree constructor_unfilled_fields;
498118334Speter
498218334Speter/* For an ARRAY_TYPE, this is the index of the first element
498318334Speter   not yet written out.
498418334Speter   This is a special INTEGER_CST node that we modify in place.  */
498518334Speterstatic tree constructor_unfilled_index;
498618334Speter
498718334Speter/* In a RECORD_TYPE, the byte index of the next consecutive field.
498818334Speter   This is so we can generate gaps between fields, when appropriate.
498918334Speter   This is a special INTEGER_CST node that we modify in place.  */
499018334Speterstatic tree constructor_bit_index;
499118334Speter
499218334Speter/* If we are saving up the elements rather than allocating them,
499318334Speter   this is the list of elements so far (in reverse order,
499418334Speter   most recent first).  */
499518334Speterstatic tree constructor_elements;
499618334Speter
499718334Speter/* 1 if so far this constructor's elements are all compile-time constants.  */
499818334Speterstatic int constructor_constant;
499918334Speter
500018334Speter/* 1 if so far this constructor's elements are all valid address constants.  */
500118334Speterstatic int constructor_simple;
500218334Speter
500318334Speter/* 1 if this constructor is erroneous so far.  */
500418334Speterstatic int constructor_erroneous;
500518334Speter
500618334Speter/* 1 if have called defer_addressed_constants.  */
500718334Speterstatic int constructor_subconstants_deferred;
500818334Speter
500950397Sobrien/* Structure for managing pending initializer elements, organized as an
501050397Sobrien   AVL tree.  */
501150397Sobrien
501250397Sobrienstruct init_node
501350397Sobrien{
501450397Sobrien  struct init_node *left, *right;
501550397Sobrien  struct init_node *parent;
501650397Sobrien  int balance;
501750397Sobrien  tree purpose;
501850397Sobrien  tree value;
501950397Sobrien};
502050397Sobrien
502150397Sobrien/* Tree of pending elements at this constructor level.
502218334Speter   These are elements encountered out of order
502318334Speter   which belong at places we haven't reached yet in actually
502418334Speter   writing the output.  */
502550397Sobrienstatic struct init_node *constructor_pending_elts;
502618334Speter
502718334Speter/* The SPELLING_DEPTH of this constructor.  */
502818334Speterstatic int constructor_depth;
502918334Speter
503018334Speter/* 0 if implicitly pushing constructor levels is allowed.  */
503150397Sobrienint constructor_no_implicit = 0; /* 0 for C; 1 for some other languages.  */
503218334Speter
503318334Speterstatic int require_constant_value;
503418334Speterstatic int require_constant_elements;
503518334Speter
503618334Speter/* 1 if it is ok to output this constructor as we read it.
503718334Speter   0 means must accumulate a CONSTRUCTOR expression.  */
503818334Speterstatic int constructor_incremental;
503918334Speter
504018334Speter/* DECL node for which an initializer is being read.
504118334Speter   0 means we are reading a constructor expression
504218334Speter   such as (struct foo) {...}.  */
504318334Speterstatic tree constructor_decl;
504418334Speter
504518334Speter/* start_init saves the ASMSPEC arg here for really_start_incremental_init.  */
504618334Speterstatic char *constructor_asmspec;
504718334Speter
504818334Speter/* Nonzero if this is an initializer for a top-level decl.  */
504918334Speterstatic int constructor_top_level;
505018334Speter
505118334Speter
505218334Speter/* This stack has a level for each implicit or explicit level of
505318334Speter   structuring in the initializer, including the outermost one.  It
505418334Speter   saves the values of most of the variables above.  */
505518334Speter
505618334Speterstruct constructor_stack
505718334Speter{
505818334Speter  struct constructor_stack *next;
505918334Speter  tree type;
506018334Speter  tree fields;
506118334Speter  tree index;
506218334Speter  tree range_end;
506318334Speter  tree max_index;
506418334Speter  tree unfilled_index;
506518334Speter  tree unfilled_fields;
506618334Speter  tree bit_index;
506718334Speter  tree elements;
506818334Speter  int offset;
506950397Sobrien  struct init_node *pending_elts;
507018334Speter  int depth;
507118334Speter  /* If nonzero, this value should replace the entire
507218334Speter     constructor at this level.  */
507318334Speter  tree replacement_value;
507418334Speter  char constant;
507518334Speter  char simple;
507618334Speter  char implicit;
507718334Speter  char incremental;
507818334Speter  char erroneous;
507918334Speter  char outer;
508018334Speter};
508118334Speter
508218334Speterstruct constructor_stack *constructor_stack;
508318334Speter
508418334Speter/* This stack records separate initializers that are nested.
508518334Speter   Nested initializers can't happen in ANSI C, but GNU C allows them
508618334Speter   in cases like { ... (struct foo) { ... } ... }.  */
508718334Speter
508818334Speterstruct initializer_stack
508918334Speter{
509018334Speter  struct initializer_stack *next;
509118334Speter  tree decl;
509218334Speter  char *asmspec;
509318334Speter  struct constructor_stack *constructor_stack;
509418334Speter  tree elements;
509518334Speter  struct spelling *spelling;
509618334Speter  struct spelling *spelling_base;
509718334Speter  int spelling_size;
509818334Speter  char top_level;
509918334Speter  char incremental;
510018334Speter  char require_constant_value;
510118334Speter  char require_constant_elements;
510218334Speter  char deferred;
510318334Speter};
510418334Speter
510518334Speterstruct initializer_stack *initializer_stack;
510618334Speter
510718334Speter/* Prepare to parse and output the initializer for variable DECL.  */
510818334Speter
510918334Spetervoid
511018334Speterstart_init (decl, asmspec_tree, top_level)
511118334Speter     tree decl;
511218334Speter     tree asmspec_tree;
511318334Speter     int top_level;
511418334Speter{
511552284Sobrien  const char *locus;
511618334Speter  struct initializer_stack *p
511718334Speter    = (struct initializer_stack *) xmalloc (sizeof (struct initializer_stack));
511818334Speter  char *asmspec = 0;
511918334Speter
512018334Speter  if (asmspec_tree)
512118334Speter    asmspec = TREE_STRING_POINTER (asmspec_tree);
512218334Speter
512318334Speter  p->decl = constructor_decl;
512418334Speter  p->asmspec = constructor_asmspec;
512518334Speter  p->incremental = constructor_incremental;
512618334Speter  p->require_constant_value = require_constant_value;
512718334Speter  p->require_constant_elements = require_constant_elements;
512818334Speter  p->constructor_stack = constructor_stack;
512918334Speter  p->elements = constructor_elements;
513018334Speter  p->spelling = spelling;
513118334Speter  p->spelling_base = spelling_base;
513218334Speter  p->spelling_size = spelling_size;
513318334Speter  p->deferred = constructor_subconstants_deferred;
513418334Speter  p->top_level = constructor_top_level;
513518334Speter  p->next = initializer_stack;
513618334Speter  initializer_stack = p;
513718334Speter
513818334Speter  constructor_decl = decl;
513918334Speter  constructor_incremental = top_level;
514018334Speter  constructor_asmspec = asmspec;
514118334Speter  constructor_subconstants_deferred = 0;
514218334Speter  constructor_top_level = top_level;
514318334Speter
514418334Speter  if (decl != 0)
514518334Speter    {
514618334Speter      require_constant_value = TREE_STATIC (decl);
514718334Speter      require_constant_elements
514818334Speter	= ((TREE_STATIC (decl) || pedantic)
514918334Speter	   /* For a scalar, you can always use any value to initialize,
515018334Speter	      even within braces.  */
515118334Speter	   && (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
515218334Speter	       || TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
515318334Speter	       || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE
515418334Speter	       || TREE_CODE (TREE_TYPE (decl)) == QUAL_UNION_TYPE));
515518334Speter      locus = IDENTIFIER_POINTER (DECL_NAME (decl));
515618334Speter      constructor_incremental |= TREE_STATIC (decl);
515718334Speter    }
515818334Speter  else
515918334Speter    {
516018334Speter      require_constant_value = 0;
516118334Speter      require_constant_elements = 0;
516218334Speter      locus = "(anonymous)";
516318334Speter    }
516418334Speter
516518334Speter  constructor_stack = 0;
516618334Speter
516718334Speter  missing_braces_mentioned = 0;
516818334Speter
516918334Speter  spelling_base = 0;
517018334Speter  spelling_size = 0;
517118334Speter  RESTORE_SPELLING_DEPTH (0);
517218334Speter
517318334Speter  if (locus)
517418334Speter    push_string (locus);
517518334Speter}
517618334Speter
517718334Spetervoid
517818334Speterfinish_init ()
517918334Speter{
518018334Speter  struct initializer_stack *p = initializer_stack;
518118334Speter
518218334Speter  /* Output subconstants (string constants, usually)
518318334Speter     that were referenced within this initializer and saved up.
518418334Speter     Must do this if and only if we called defer_addressed_constants.  */
518518334Speter  if (constructor_subconstants_deferred)
518618334Speter    output_deferred_addressed_constants ();
518718334Speter
518818334Speter  /* Free the whole constructor stack of this initializer.  */
518918334Speter  while (constructor_stack)
519018334Speter    {
519118334Speter      struct constructor_stack *q = constructor_stack;
519218334Speter      constructor_stack = q->next;
519318334Speter      free (q);
519418334Speter    }
519518334Speter
519618334Speter  /* Pop back to the data of the outer initializer (if any).  */
519718334Speter  constructor_decl = p->decl;
519818334Speter  constructor_asmspec = p->asmspec;
519918334Speter  constructor_incremental = p->incremental;
520018334Speter  require_constant_value = p->require_constant_value;
520118334Speter  require_constant_elements = p->require_constant_elements;
520218334Speter  constructor_stack = p->constructor_stack;
520318334Speter  constructor_elements = p->elements;
520418334Speter  spelling = p->spelling;
520518334Speter  spelling_base = p->spelling_base;
520618334Speter  spelling_size = p->spelling_size;
520718334Speter  constructor_subconstants_deferred = p->deferred;
520818334Speter  constructor_top_level = p->top_level;
520918334Speter  initializer_stack = p->next;
521018334Speter  free (p);
521118334Speter}
521218334Speter
521318334Speter/* Call here when we see the initializer is surrounded by braces.
521418334Speter   This is instead of a call to push_init_level;
521518334Speter   it is matched by a call to pop_init_level.
521618334Speter
521718334Speter   TYPE is the type to initialize, for a constructor expression.
521818334Speter   For an initializer for a decl, TYPE is zero.  */
521918334Speter
522018334Spetervoid
522118334Speterreally_start_incremental_init (type)
522218334Speter     tree type;
522318334Speter{
522418334Speter  struct constructor_stack *p
522518334Speter    = (struct constructor_stack *) xmalloc (sizeof (struct constructor_stack));
522618334Speter
522718334Speter  if (type == 0)
522818334Speter    type = TREE_TYPE (constructor_decl);
522918334Speter
523018334Speter  /* Turn off constructor_incremental if type is a struct with bitfields.
523118334Speter     Do this before the first push, so that the corrected value
523218334Speter     is available in finish_init.  */
523318334Speter  check_init_type_bitfields (type);
523418334Speter
523518334Speter  p->type = constructor_type;
523618334Speter  p->fields = constructor_fields;
523718334Speter  p->index = constructor_index;
523818334Speter  p->range_end = constructor_range_end;
523918334Speter  p->max_index = constructor_max_index;
524018334Speter  p->unfilled_index = constructor_unfilled_index;
524118334Speter  p->unfilled_fields = constructor_unfilled_fields;
524218334Speter  p->bit_index = constructor_bit_index;
524318334Speter  p->elements = constructor_elements;
524418334Speter  p->constant = constructor_constant;
524518334Speter  p->simple = constructor_simple;
524618334Speter  p->erroneous = constructor_erroneous;
524718334Speter  p->pending_elts = constructor_pending_elts;
524818334Speter  p->depth = constructor_depth;
524918334Speter  p->replacement_value = 0;
525018334Speter  p->implicit = 0;
525118334Speter  p->incremental = constructor_incremental;
525218334Speter  p->outer = 0;
525318334Speter  p->next = 0;
525418334Speter  constructor_stack = p;
525518334Speter
525618334Speter  constructor_constant = 1;
525718334Speter  constructor_simple = 1;
525818334Speter  constructor_depth = SPELLING_DEPTH ();
525918334Speter  constructor_elements = 0;
526018334Speter  constructor_pending_elts = 0;
526118334Speter  constructor_type = type;
526218334Speter
526318334Speter  if (TREE_CODE (constructor_type) == RECORD_TYPE
526418334Speter      || TREE_CODE (constructor_type) == UNION_TYPE)
526518334Speter    {
526618334Speter      constructor_fields = TYPE_FIELDS (constructor_type);
526718334Speter      /* Skip any nameless bit fields at the beginning.  */
526850397Sobrien      while (constructor_fields != 0 && DECL_C_BIT_FIELD (constructor_fields)
526918334Speter	     && DECL_NAME (constructor_fields) == 0)
527018334Speter	constructor_fields = TREE_CHAIN (constructor_fields);
527118334Speter      constructor_unfilled_fields = constructor_fields;
527218334Speter      constructor_bit_index = copy_node (integer_zero_node);
527350397Sobrien      TREE_TYPE (constructor_bit_index) = sbitsizetype;
527418334Speter    }
527518334Speter  else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
527618334Speter    {
527718334Speter      constructor_range_end = 0;
527818334Speter      if (TYPE_DOMAIN (constructor_type))
527918334Speter	{
528018334Speter	  constructor_max_index
528118334Speter	    = TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type));
528218334Speter	  constructor_index
528318334Speter	    = copy_node (TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type)));
528418334Speter	}
528518334Speter      else
528618334Speter	constructor_index = copy_node (integer_zero_node);
528718334Speter      constructor_unfilled_index = copy_node (constructor_index);
528818334Speter    }
528918334Speter  else
529018334Speter    {
529118334Speter      /* Handle the case of int x = {5}; */
529218334Speter      constructor_fields = constructor_type;
529318334Speter      constructor_unfilled_fields = constructor_type;
529418334Speter    }
529518334Speter
529618334Speter  if (constructor_incremental)
529718334Speter    {
529818334Speter      int momentary = suspend_momentary ();
529918334Speter      push_obstacks_nochange ();
530018334Speter      if (TREE_PERMANENT (constructor_decl))
530118334Speter	end_temporary_allocation ();
530218334Speter      make_decl_rtl (constructor_decl, constructor_asmspec,
530318334Speter		     constructor_top_level);
530418334Speter      assemble_variable (constructor_decl, constructor_top_level, 0, 1);
530518334Speter      pop_obstacks ();
530618334Speter      resume_momentary (momentary);
530718334Speter    }
530818334Speter
530918334Speter  if (constructor_incremental)
531018334Speter    {
531118334Speter      defer_addressed_constants ();
531218334Speter      constructor_subconstants_deferred = 1;
531318334Speter    }
531418334Speter}
531518334Speter
531618334Speter/* Push down into a subobject, for initialization.
531718334Speter   If this is for an explicit set of braces, IMPLICIT is 0.
531818334Speter   If it is because the next element belongs at a lower level,
531918334Speter   IMPLICIT is 1.  */
532018334Speter
532118334Spetervoid
532218334Speterpush_init_level (implicit)
532318334Speter     int implicit;
532418334Speter{
532518334Speter  struct constructor_stack *p;
532618334Speter
532718334Speter  /* If we've exhausted any levels that didn't have braces,
532818334Speter     pop them now.  */
532918334Speter  while (constructor_stack->implicit)
533018334Speter    {
533118334Speter      if ((TREE_CODE (constructor_type) == RECORD_TYPE
533218334Speter	   || TREE_CODE (constructor_type) == UNION_TYPE)
533318334Speter	  && constructor_fields == 0)
533418334Speter	process_init_element (pop_init_level (1));
533518334Speter      else if (TREE_CODE (constructor_type) == ARRAY_TYPE
533618334Speter	       && tree_int_cst_lt (constructor_max_index, constructor_index))
533718334Speter	process_init_element (pop_init_level (1));
533818334Speter      else
533918334Speter	break;
534018334Speter    }
534118334Speter
534250397Sobrien  /* Structure elements may require alignment.  Do this now if necessary
534350397Sobrien     for the subaggregate, and if it comes next in sequence.  Don't do
534450397Sobrien     this for subaggregates that will go on the pending list.  */
534518334Speter  if (constructor_incremental && constructor_type != 0
534650397Sobrien      && TREE_CODE (constructor_type) == RECORD_TYPE && constructor_fields
534750397Sobrien      && constructor_fields == constructor_unfilled_fields)
534818334Speter    {
534918334Speter      /* Advance to offset of this element.  */
535018334Speter      if (! tree_int_cst_equal (constructor_bit_index,
535118334Speter				DECL_FIELD_BITPOS (constructor_fields)))
535218334Speter	{
535350397Sobrien	  /* By using unsigned arithmetic, the result will be correct even
535450397Sobrien	     in case of overflows, if BITS_PER_UNIT is a power of two.  */
535550397Sobrien	  unsigned next = (TREE_INT_CST_LOW
535650397Sobrien			   (DECL_FIELD_BITPOS (constructor_fields))
535750397Sobrien			   / (unsigned)BITS_PER_UNIT);
535850397Sobrien	  unsigned here = (TREE_INT_CST_LOW (constructor_bit_index)
535950397Sobrien			   / (unsigned)BITS_PER_UNIT);
536018334Speter
536150397Sobrien	  assemble_zeros ((next - here)
536250397Sobrien			  * (unsigned)BITS_PER_UNIT
536350397Sobrien			  / (unsigned)BITS_PER_UNIT);
536418334Speter	}
536550397Sobrien      /* Indicate that we have now filled the structure up to the current
536650397Sobrien	 field.  */
536750397Sobrien      constructor_unfilled_fields = constructor_fields;
536818334Speter    }
536918334Speter
537018334Speter  p = (struct constructor_stack *) xmalloc (sizeof (struct constructor_stack));
537118334Speter  p->type = constructor_type;
537218334Speter  p->fields = constructor_fields;
537318334Speter  p->index = constructor_index;
537418334Speter  p->range_end = constructor_range_end;
537518334Speter  p->max_index = constructor_max_index;
537618334Speter  p->unfilled_index = constructor_unfilled_index;
537718334Speter  p->unfilled_fields = constructor_unfilled_fields;
537818334Speter  p->bit_index = constructor_bit_index;
537918334Speter  p->elements = constructor_elements;
538018334Speter  p->constant = constructor_constant;
538118334Speter  p->simple = constructor_simple;
538218334Speter  p->erroneous = constructor_erroneous;
538318334Speter  p->pending_elts = constructor_pending_elts;
538418334Speter  p->depth = constructor_depth;
538518334Speter  p->replacement_value = 0;
538618334Speter  p->implicit = implicit;
538718334Speter  p->incremental = constructor_incremental;
538818334Speter  p->outer = 0;
538918334Speter  p->next = constructor_stack;
539018334Speter  constructor_stack = p;
539118334Speter
539218334Speter  constructor_constant = 1;
539318334Speter  constructor_simple = 1;
539418334Speter  constructor_depth = SPELLING_DEPTH ();
539518334Speter  constructor_elements = 0;
539618334Speter  constructor_pending_elts = 0;
539718334Speter
539818334Speter  /* Don't die if an entire brace-pair level is superfluous
539918334Speter     in the containing level.  */
540018334Speter  if (constructor_type == 0)
540118334Speter    ;
540218334Speter  else if (TREE_CODE (constructor_type) == RECORD_TYPE
540318334Speter	   || TREE_CODE (constructor_type) == UNION_TYPE)
540418334Speter    {
540518334Speter      /* Don't die if there are extra init elts at the end.  */
540618334Speter      if (constructor_fields == 0)
540718334Speter	constructor_type = 0;
540818334Speter      else
540918334Speter	{
541018334Speter	  constructor_type = TREE_TYPE (constructor_fields);
541118334Speter	  push_member_name (constructor_fields);
541218334Speter	  constructor_depth++;
541318334Speter	  if (constructor_fields != constructor_unfilled_fields)
541418334Speter	    constructor_incremental = 0;
541518334Speter	}
541618334Speter    }
541718334Speter  else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
541818334Speter    {
541918334Speter      constructor_type = TREE_TYPE (constructor_type);
542018334Speter      push_array_bounds (TREE_INT_CST_LOW (constructor_index));
542118334Speter      constructor_depth++;
542218334Speter      if (! tree_int_cst_equal (constructor_index, constructor_unfilled_index)
542318334Speter	  || constructor_range_end != 0)
542418334Speter	constructor_incremental = 0;
542518334Speter    }
542618334Speter
542718334Speter  if (constructor_type == 0)
542818334Speter    {
542952284Sobrien      error_init ("extra brace group at end of initializer");
543018334Speter      constructor_fields = 0;
543118334Speter      constructor_unfilled_fields = 0;
543218334Speter      return;
543318334Speter    }
543418334Speter
543518334Speter  /* Turn off constructor_incremental if type is a struct with bitfields.  */
543618334Speter  check_init_type_bitfields (constructor_type);
543718334Speter
543818334Speter  if (implicit && warn_missing_braces && !missing_braces_mentioned)
543918334Speter    {
544018334Speter      missing_braces_mentioned = 1;
544152284Sobrien      warning_init ("missing braces around initializer");
544218334Speter    }
544318334Speter
544418334Speter  if (TREE_CODE (constructor_type) == RECORD_TYPE
544518334Speter	   || TREE_CODE (constructor_type) == UNION_TYPE)
544618334Speter    {
544718334Speter      constructor_fields = TYPE_FIELDS (constructor_type);
544818334Speter      /* Skip any nameless bit fields at the beginning.  */
544950397Sobrien      while (constructor_fields != 0 && DECL_C_BIT_FIELD (constructor_fields)
545018334Speter	     && DECL_NAME (constructor_fields) == 0)
545118334Speter	constructor_fields = TREE_CHAIN (constructor_fields);
545218334Speter      constructor_unfilled_fields = constructor_fields;
545318334Speter      constructor_bit_index = copy_node (integer_zero_node);
545450397Sobrien      TREE_TYPE (constructor_bit_index) = sbitsizetype;
545518334Speter    }
545618334Speter  else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
545718334Speter    {
545818334Speter      constructor_range_end = 0;
545918334Speter      if (TYPE_DOMAIN (constructor_type))
546018334Speter	{
546118334Speter	  constructor_max_index
546218334Speter	    = TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type));
546318334Speter	  constructor_index
546418334Speter	    = copy_node (TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type)));
546518334Speter	}
546618334Speter      else
546718334Speter	constructor_index = copy_node (integer_zero_node);
546818334Speter      constructor_unfilled_index = copy_node (constructor_index);
546918334Speter    }
547018334Speter  else
547118334Speter    {
547252284Sobrien      warning_init ("braces around scalar initializer");
547318334Speter      constructor_fields = constructor_type;
547418334Speter      constructor_unfilled_fields = constructor_type;
547518334Speter    }
547618334Speter}
547718334Speter
547818334Speter/* Don't read a struct incrementally if it has any bitfields,
547918334Speter   because the incremental reading code doesn't know how to
548018334Speter   handle bitfields yet.  */
548118334Speter
548218334Speterstatic void
548318334Spetercheck_init_type_bitfields (type)
548418334Speter     tree type;
548518334Speter{
548618334Speter  if (TREE_CODE (type) == RECORD_TYPE)
548718334Speter    {
548818334Speter      tree tail;
548918334Speter      for (tail = TYPE_FIELDS (type); tail;
549018334Speter	   tail = TREE_CHAIN (tail))
549118334Speter	{
549252284Sobrien	  if (DECL_C_BIT_FIELD (tail))
549318334Speter	    {
549418334Speter	      constructor_incremental = 0;
549518334Speter	      break;
549618334Speter	    }
549718334Speter
549818334Speter	  check_init_type_bitfields (TREE_TYPE (tail));
549918334Speter	}
550018334Speter    }
550118334Speter
550252284Sobrien  else if (TREE_CODE (type) == UNION_TYPE)
550352284Sobrien    {
550452284Sobrien      tree tail = TYPE_FIELDS (type);
550552284Sobrien      if (tail && DECL_C_BIT_FIELD (tail))
550652284Sobrien	/* We also use the nonincremental algorithm for initiliazation
550752284Sobrien	   of unions whose first member is a bitfield, becuase the
550852284Sobrien	   incremental algorithm has no code for dealing with
550952284Sobrien	   bitfields. */
551052284Sobrien	constructor_incremental = 0;
551152284Sobrien    }
551252284Sobrien
551318334Speter  else if (TREE_CODE (type) == ARRAY_TYPE)
551418334Speter    check_init_type_bitfields (TREE_TYPE (type));
551518334Speter}
551618334Speter
551718334Speter/* At the end of an implicit or explicit brace level,
551818334Speter   finish up that level of constructor.
551918334Speter   If we were outputting the elements as they are read, return 0
552018334Speter   from inner levels (process_init_element ignores that),
552118334Speter   but return error_mark_node from the outermost level
552218334Speter   (that's what we want to put in DECL_INITIAL).
552318334Speter   Otherwise, return a CONSTRUCTOR expression.  */
552418334Speter
552518334Spetertree
552618334Speterpop_init_level (implicit)
552718334Speter     int implicit;
552818334Speter{
552918334Speter  struct constructor_stack *p;
553018334Speter  int size = 0;
553118334Speter  tree constructor = 0;
553218334Speter
553318334Speter  if (implicit == 0)
553418334Speter    {
553518334Speter      /* When we come to an explicit close brace,
553618334Speter	 pop any inner levels that didn't have explicit braces.  */
553718334Speter      while (constructor_stack->implicit)
553818334Speter	process_init_element (pop_init_level (1));
553918334Speter    }
554018334Speter
554118334Speter  p = constructor_stack;
554218334Speter
554318334Speter  if (constructor_type != 0)
554418334Speter    size = int_size_in_bytes (constructor_type);
554518334Speter
554650397Sobrien  /* Warn when some struct elements are implicitly initialized to zero.  */
554750397Sobrien  if (extra_warnings
554850397Sobrien      && constructor_type
554950397Sobrien      && TREE_CODE (constructor_type) == RECORD_TYPE
555050397Sobrien      && constructor_unfilled_fields)
555150397Sobrien    {
555250397Sobrien      push_member_name (constructor_unfilled_fields);
555352284Sobrien      warning_init ("missing initializer");
555450397Sobrien      RESTORE_SPELLING_DEPTH (constructor_depth);
555550397Sobrien    }
555650397Sobrien
555718334Speter  /* Now output all pending elements.  */
555818334Speter  output_pending_init_elements (1);
555918334Speter
556018334Speter#if 0 /* c-parse.in warns about {}.  */
556118334Speter  /* In ANSI, each brace level must have at least one element.  */
556218334Speter  if (! implicit && pedantic
556318334Speter      && (TREE_CODE (constructor_type) == ARRAY_TYPE
556418334Speter	  ? integer_zerop (constructor_unfilled_index)
556518334Speter	  : constructor_unfilled_fields == TYPE_FIELDS (constructor_type)))
556652284Sobrien    pedwarn_init ("empty braces in initializer");
556718334Speter#endif
556818334Speter
556918334Speter  /* Pad out the end of the structure.  */
557018334Speter
557118334Speter  if (p->replacement_value)
557218334Speter    {
557318334Speter      /* If this closes a superfluous brace pair,
557418334Speter	 just pass out the element between them.  */
557518334Speter      constructor = p->replacement_value;
557618334Speter      /* If this is the top level thing within the initializer,
557718334Speter	 and it's for a variable, then since we already called
557818334Speter	 assemble_variable, we must output the value now.  */
557918334Speter      if (p->next == 0 && constructor_decl != 0
558018334Speter	  && constructor_incremental)
558118334Speter	{
558218334Speter	  constructor = digest_init (constructor_type, constructor,
558318334Speter				     require_constant_value,
558418334Speter				     require_constant_elements);
558518334Speter
558618334Speter	  /* If initializing an array of unknown size,
558718334Speter	     determine the size now.  */
558818334Speter	  if (TREE_CODE (constructor_type) == ARRAY_TYPE
558918334Speter	      && TYPE_DOMAIN (constructor_type) == 0)
559018334Speter	    {
559118334Speter	      int failure;
559218334Speter	      int momentary_p;
559318334Speter
559418334Speter	      push_obstacks_nochange ();
559518334Speter	      if (TREE_PERMANENT (constructor_type))
559618334Speter		end_temporary_allocation ();
559718334Speter
559818334Speter	      momentary_p = suspend_momentary ();
559918334Speter
560018334Speter	      /* We shouldn't have an incomplete array type within
560118334Speter		 some other type.  */
560218334Speter	      if (constructor_stack->next)
560318334Speter		abort ();
560418334Speter
560518334Speter	      failure
560618334Speter		= complete_array_type (constructor_type,
560718334Speter				       constructor, 0);
560818334Speter	      if (failure)
560918334Speter		abort ();
561018334Speter
561118334Speter	      size = int_size_in_bytes (constructor_type);
561218334Speter	      resume_momentary (momentary_p);
561318334Speter	      pop_obstacks ();
561418334Speter	    }
561518334Speter
561618334Speter	  output_constant (constructor, size);
561718334Speter	}
561818334Speter    }
561918334Speter  else if (constructor_type == 0)
562018334Speter    ;
562118334Speter  else if (TREE_CODE (constructor_type) != RECORD_TYPE
562218334Speter	   && TREE_CODE (constructor_type) != UNION_TYPE
562318334Speter	   && TREE_CODE (constructor_type) != ARRAY_TYPE
562418334Speter	   && ! constructor_incremental)
562518334Speter    {
562618334Speter      /* A nonincremental scalar initializer--just return
562718334Speter	 the element, after verifying there is just one.  */
562818334Speter      if (constructor_elements == 0)
562918334Speter	{
563052284Sobrien	  error_init ("empty scalar initializer");
563118334Speter	  constructor = error_mark_node;
563218334Speter	}
563318334Speter      else if (TREE_CHAIN (constructor_elements) != 0)
563418334Speter	{
563552284Sobrien	  error_init ("extra elements in scalar initializer");
563618334Speter	  constructor = TREE_VALUE (constructor_elements);
563718334Speter	}
563818334Speter      else
563918334Speter	constructor = TREE_VALUE (constructor_elements);
564018334Speter    }
564118334Speter  else if (! constructor_incremental)
564218334Speter    {
564318334Speter      if (constructor_erroneous)
564418334Speter	constructor = error_mark_node;
564518334Speter      else
564618334Speter	{
564718334Speter	  int momentary = suspend_momentary ();
564818334Speter
564918334Speter	  constructor = build (CONSTRUCTOR, constructor_type, NULL_TREE,
565018334Speter			       nreverse (constructor_elements));
565118334Speter	  if (constructor_constant)
565218334Speter	    TREE_CONSTANT (constructor) = 1;
565318334Speter	  if (constructor_constant && constructor_simple)
565418334Speter	    TREE_STATIC (constructor) = 1;
565518334Speter
565618334Speter	  resume_momentary (momentary);
565718334Speter	}
565818334Speter    }
565918334Speter  else
566018334Speter    {
566118334Speter      tree filled;
566218334Speter      int momentary = suspend_momentary ();
566318334Speter
566418334Speter      if (TREE_CODE (constructor_type) == RECORD_TYPE
566518334Speter	  || TREE_CODE (constructor_type) == UNION_TYPE)
566618334Speter	{
566718334Speter	  /* Find the offset of the end of that field.  */
566818334Speter	  filled = size_binop (CEIL_DIV_EXPR,
566918334Speter			       constructor_bit_index,
567018334Speter			       size_int (BITS_PER_UNIT));
567118334Speter	}
567218334Speter      else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
567318334Speter	{
567418334Speter	  /* If initializing an array of unknown size,
567518334Speter	     determine the size now.  */
567618334Speter	  if (TREE_CODE (constructor_type) == ARRAY_TYPE
567718334Speter	      && TYPE_DOMAIN (constructor_type) == 0)
567818334Speter	    {
567918334Speter	      tree maxindex
568018334Speter		= size_binop (MINUS_EXPR,
568118334Speter			      constructor_unfilled_index,
568218334Speter			      integer_one_node);
568318334Speter
568418334Speter	      push_obstacks_nochange ();
568518334Speter	      if (TREE_PERMANENT (constructor_type))
568618334Speter		end_temporary_allocation ();
568718334Speter	      maxindex = copy_node (maxindex);
568818334Speter	      TYPE_DOMAIN (constructor_type) = build_index_type (maxindex);
568918334Speter	      TREE_TYPE (maxindex) = TYPE_DOMAIN (constructor_type);
569018334Speter
569118334Speter	      /* TYPE_MAX_VALUE is always one less than the number of elements
569218334Speter		 in the array, because we start counting at zero.  Therefore,
569318334Speter		 warn only if the value is less than zero.  */
569418334Speter	      if (pedantic
569518334Speter		  && (tree_int_cst_sgn (TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type)))
569618334Speter		      < 0))
569718334Speter		error_with_decl (constructor_decl,
569818334Speter				 "zero or negative array size `%s'");
569918334Speter	      layout_type (constructor_type);
570018334Speter	      size = int_size_in_bytes (constructor_type);
570118334Speter	      pop_obstacks ();
570218334Speter	    }
570318334Speter
570418334Speter	  filled = size_binop (MULT_EXPR, constructor_unfilled_index,
570518334Speter			       size_in_bytes (TREE_TYPE (constructor_type)));
570618334Speter	}
570718334Speter      else
570818334Speter	filled = 0;
570918334Speter
571018334Speter      if (filled != 0)
571118334Speter	assemble_zeros (size - TREE_INT_CST_LOW (filled));
571218334Speter
571318334Speter      resume_momentary (momentary);
571418334Speter    }
571518334Speter
571618334Speter
571718334Speter  constructor_type = p->type;
571818334Speter  constructor_fields = p->fields;
571918334Speter  constructor_index = p->index;
572018334Speter  constructor_range_end = p->range_end;
572118334Speter  constructor_max_index = p->max_index;
572218334Speter  constructor_unfilled_index = p->unfilled_index;
572318334Speter  constructor_unfilled_fields = p->unfilled_fields;
572418334Speter  constructor_bit_index = p->bit_index;
572518334Speter  constructor_elements = p->elements;
572618334Speter  constructor_constant = p->constant;
572718334Speter  constructor_simple = p->simple;
572818334Speter  constructor_erroneous = p->erroneous;
572918334Speter  constructor_pending_elts = p->pending_elts;
573018334Speter  constructor_depth = p->depth;
573118334Speter  constructor_incremental = p->incremental;
573218334Speter  RESTORE_SPELLING_DEPTH (constructor_depth);
573318334Speter
573418334Speter  constructor_stack = p->next;
573518334Speter  free (p);
573618334Speter
573718334Speter  if (constructor == 0)
573818334Speter    {
573918334Speter      if (constructor_stack == 0)
574018334Speter	return error_mark_node;
574118334Speter      return NULL_TREE;
574218334Speter    }
574318334Speter  return constructor;
574418334Speter}
574518334Speter
574618334Speter/* Within an array initializer, specify the next index to be initialized.
574718334Speter   FIRST is that index.  If LAST is nonzero, then initialize a range
574818334Speter   of indices, running from FIRST through LAST.  */
574918334Speter
575018334Spetervoid
575118334Speterset_init_index (first, last)
575218334Speter     tree first, last;
575318334Speter{
575418334Speter  while ((TREE_CODE (first) == NOP_EXPR
575518334Speter	  || TREE_CODE (first) == CONVERT_EXPR
575618334Speter	  || TREE_CODE (first) == NON_LVALUE_EXPR)
575718334Speter	 && (TYPE_MODE (TREE_TYPE (first))
575818334Speter	     == TYPE_MODE (TREE_TYPE (TREE_OPERAND (first, 0)))))
575918334Speter    (first) = TREE_OPERAND (first, 0);
576018334Speter  if (last)
576118334Speter    while ((TREE_CODE (last) == NOP_EXPR
576218334Speter	    || TREE_CODE (last) == CONVERT_EXPR
576318334Speter	    || TREE_CODE (last) == NON_LVALUE_EXPR)
576418334Speter	   && (TYPE_MODE (TREE_TYPE (last))
576518334Speter	       == TYPE_MODE (TREE_TYPE (TREE_OPERAND (last, 0)))))
576618334Speter      (last) = TREE_OPERAND (last, 0);
576718334Speter
576818334Speter  if (TREE_CODE (first) != INTEGER_CST)
576952284Sobrien    error_init ("nonconstant array index in initializer");
577018334Speter  else if (last != 0 && TREE_CODE (last) != INTEGER_CST)
577152284Sobrien    error_init ("nonconstant array index in initializer");
577218336Speter  else if (! constructor_unfilled_index)
577352284Sobrien    error_init ("array index in non-array initializer");
577418334Speter  else if (tree_int_cst_lt (first, constructor_unfilled_index))
577552284Sobrien    error_init ("duplicate array index in initializer");
577618334Speter  else
577718334Speter    {
577850397Sobrien      TREE_INT_CST_LOW (constructor_index) = TREE_INT_CST_LOW (first);
577950397Sobrien      TREE_INT_CST_HIGH (constructor_index) = TREE_INT_CST_HIGH (first);
578018334Speter
578118334Speter      if (last != 0 && tree_int_cst_lt (last, first))
578252284Sobrien	error_init ("empty index range in initializer");
578318334Speter      else
578418334Speter	{
578518334Speter	  if (pedantic)
578618334Speter	    pedwarn ("ANSI C forbids specifying element to initialize");
578718334Speter	  constructor_range_end = last;
578818334Speter	}
578918334Speter    }
579018334Speter}
579118334Speter
579218334Speter/* Within a struct initializer, specify the next field to be initialized.  */
579318334Speter
579418334Spetervoid
579518334Speterset_init_label (fieldname)
579618334Speter     tree fieldname;
579718334Speter{
579818334Speter  tree tail;
579918334Speter  int passed = 0;
580018334Speter
580118334Speter  /* Don't die if an entire brace-pair level is superfluous
580218334Speter     in the containing level.  */
580318334Speter  if (constructor_type == 0)
580418334Speter    return;
580518334Speter
580618334Speter  for (tail = TYPE_FIELDS (constructor_type); tail;
580718334Speter       tail = TREE_CHAIN (tail))
580818334Speter    {
580918334Speter      if (tail == constructor_unfilled_fields)
581018334Speter	passed = 1;
581118334Speter      if (DECL_NAME (tail) == fieldname)
581218334Speter	break;
581318334Speter    }
581418334Speter
581518334Speter  if (tail == 0)
581618334Speter    error ("unknown field `%s' specified in initializer",
581718334Speter	   IDENTIFIER_POINTER (fieldname));
581818334Speter  else if (!passed)
581918334Speter    error ("field `%s' already initialized",
582018334Speter	   IDENTIFIER_POINTER (fieldname));
582118334Speter  else
582218334Speter    {
582318334Speter      constructor_fields = tail;
582418334Speter      if (pedantic)
582518334Speter	pedwarn ("ANSI C forbids specifying structure member to initialize");
582618334Speter    }
582718334Speter}
582818334Speter
582950397Sobrien/* Add a new initializer to the tree of pending initializers.  PURPOSE
583050397Sobrien   indentifies the initializer, either array index or field in a structure.
583150397Sobrien   VALUE is the value of that index or field.  */
583250397Sobrien
583350397Sobrienstatic void
583450397Sobrienadd_pending_init (purpose, value)
583550397Sobrien     tree purpose, value;
583650397Sobrien{
583750397Sobrien  struct init_node *p, **q, *r;
583850397Sobrien
583950397Sobrien  q = &constructor_pending_elts;
584050397Sobrien  p = 0;
584150397Sobrien
584250397Sobrien  if (TREE_CODE (constructor_type) == ARRAY_TYPE)
584350397Sobrien    {
584450397Sobrien      while (*q != 0)
584550397Sobrien	{
584650397Sobrien	  p = *q;
584750397Sobrien	  if (tree_int_cst_lt (purpose, p->purpose))
584850397Sobrien	    q = &p->left;
584950397Sobrien	  else if (tree_int_cst_lt (p->purpose, purpose))
585050397Sobrien	    q = &p->right;
585150397Sobrien	  else
585250397Sobrien	    abort ();
585350397Sobrien	}
585450397Sobrien    }
585550397Sobrien  else
585650397Sobrien    {
585750397Sobrien      while (*q != NULL)
585850397Sobrien	{
585950397Sobrien	  p = *q;
586050397Sobrien	  if (tree_int_cst_lt (DECL_FIELD_BITPOS (purpose),
586150397Sobrien			       DECL_FIELD_BITPOS (p->purpose)))
586250397Sobrien	    q = &p->left;
586350397Sobrien	  else if (tree_int_cst_lt (DECL_FIELD_BITPOS (p->purpose),
586450397Sobrien				    DECL_FIELD_BITPOS (purpose)))
586550397Sobrien	    q = &p->right;
586650397Sobrien	  else
586750397Sobrien	    abort ();
586850397Sobrien	}
586950397Sobrien    }
587050397Sobrien
587150397Sobrien  r = (struct init_node *) oballoc (sizeof (struct init_node));
587250397Sobrien  r->purpose = purpose;
587350397Sobrien  r->value = value;
587450397Sobrien
587550397Sobrien  *q = r;
587650397Sobrien  r->parent = p;
587750397Sobrien  r->left = 0;
587850397Sobrien  r->right = 0;
587950397Sobrien  r->balance = 0;
588050397Sobrien
588150397Sobrien  while (p)
588250397Sobrien    {
588350397Sobrien      struct init_node *s;
588450397Sobrien
588550397Sobrien      if (r == p->left)
588650397Sobrien	{
588750397Sobrien	  if (p->balance == 0)
588850397Sobrien	    p->balance = -1;
588950397Sobrien	  else if (p->balance < 0)
589050397Sobrien	    {
589150397Sobrien	      if (r->balance < 0)
589250397Sobrien		{
589350397Sobrien		  /* L rotation. */
589450397Sobrien		  p->left = r->right;
589550397Sobrien		  if (p->left)
589650397Sobrien		    p->left->parent = p;
589750397Sobrien		  r->right = p;
589850397Sobrien
589950397Sobrien		  p->balance = 0;
590050397Sobrien		  r->balance = 0;
590150397Sobrien
590250397Sobrien		  s = p->parent;
590350397Sobrien		  p->parent = r;
590450397Sobrien		  r->parent = s;
590550397Sobrien		  if (s)
590650397Sobrien		    {
590750397Sobrien		      if (s->left == p)
590850397Sobrien			s->left = r;
590950397Sobrien		      else
591050397Sobrien			s->right = r;
591150397Sobrien		    }
591250397Sobrien		  else
591350397Sobrien		    constructor_pending_elts = r;
591450397Sobrien		}
591550397Sobrien	      else
591650397Sobrien		{
591750397Sobrien		  /* LR rotation. */
591850397Sobrien		  struct init_node *t = r->right;
591950397Sobrien
592050397Sobrien		  r->right = t->left;
592150397Sobrien		  if (r->right)
592250397Sobrien		    r->right->parent = r;
592350397Sobrien		  t->left = r;
592450397Sobrien
592550397Sobrien		  p->left = t->right;
592650397Sobrien		  if (p->left)
592750397Sobrien		    p->left->parent = p;
592850397Sobrien		  t->right = p;
592950397Sobrien
593050397Sobrien		  p->balance = t->balance < 0;
593150397Sobrien		  r->balance = -(t->balance > 0);
593250397Sobrien		  t->balance = 0;
593350397Sobrien
593450397Sobrien		  s = p->parent;
593550397Sobrien		  p->parent = t;
593650397Sobrien		  r->parent = t;
593750397Sobrien		  t->parent = s;
593850397Sobrien		  if (s)
593950397Sobrien		    {
594050397Sobrien		      if (s->left == p)
594150397Sobrien			s->left = t;
594250397Sobrien		      else
594350397Sobrien			s->right = t;
594450397Sobrien		    }
594550397Sobrien		  else
594650397Sobrien		    constructor_pending_elts = t;
594750397Sobrien		}
594850397Sobrien	      break;
594950397Sobrien	    }
595050397Sobrien	  else
595150397Sobrien	    {
595250397Sobrien	      /* p->balance == +1; growth of left side balances the node.  */
595350397Sobrien	      p->balance = 0;
595450397Sobrien	      break;
595550397Sobrien	    }
595650397Sobrien	}
595750397Sobrien      else /* r == p->right */
595850397Sobrien	{
595950397Sobrien	  if (p->balance == 0)
596050397Sobrien	    /* Growth propagation from right side.  */
596150397Sobrien	    p->balance++;
596250397Sobrien	  else if (p->balance > 0)
596350397Sobrien	    {
596450397Sobrien	      if (r->balance > 0)
596550397Sobrien		{
596650397Sobrien		  /* R rotation. */
596750397Sobrien		  p->right = r->left;
596850397Sobrien		  if (p->right)
596950397Sobrien		    p->right->parent = p;
597050397Sobrien		  r->left = p;
597150397Sobrien
597250397Sobrien		  p->balance = 0;
597350397Sobrien		  r->balance = 0;
597450397Sobrien
597550397Sobrien		  s = p->parent;
597650397Sobrien		  p->parent = r;
597750397Sobrien		  r->parent = s;
597850397Sobrien		  if (s)
597950397Sobrien		    {
598050397Sobrien		      if (s->left == p)
598150397Sobrien			s->left = r;
598250397Sobrien		      else
598350397Sobrien			s->right = r;
598450397Sobrien		    }
598550397Sobrien		  else
598650397Sobrien		    constructor_pending_elts = r;
598750397Sobrien		}
598850397Sobrien	      else /* r->balance == -1 */
598950397Sobrien		{
599050397Sobrien		  /* RL rotation */
599150397Sobrien		  struct init_node *t = r->left;
599250397Sobrien
599350397Sobrien		  r->left = t->right;
599450397Sobrien		  if (r->left)
599550397Sobrien		    r->left->parent = r;
599650397Sobrien		  t->right = r;
599750397Sobrien
599850397Sobrien		  p->right = t->left;
599950397Sobrien		  if (p->right)
600050397Sobrien		    p->right->parent = p;
600150397Sobrien		  t->left = p;
600250397Sobrien
600350397Sobrien		  r->balance = (t->balance < 0);
600450397Sobrien		  p->balance = -(t->balance > 0);
600550397Sobrien		  t->balance = 0;
600650397Sobrien
600750397Sobrien		  s = p->parent;
600850397Sobrien		  p->parent = t;
600950397Sobrien		  r->parent = t;
601050397Sobrien		  t->parent = s;
601150397Sobrien		  if (s)
601250397Sobrien		    {
601350397Sobrien		      if (s->left == p)
601450397Sobrien			s->left = t;
601550397Sobrien		      else
601650397Sobrien			s->right = t;
601750397Sobrien		    }
601850397Sobrien		  else
601950397Sobrien		    constructor_pending_elts = t;
602050397Sobrien		}
602150397Sobrien	      break;
602250397Sobrien	    }
602350397Sobrien	  else
602450397Sobrien	    {
602550397Sobrien	      /* p->balance == -1; growth of right side balances the node. */
602650397Sobrien	      p->balance = 0;
602750397Sobrien	      break;
602850397Sobrien	    }
602950397Sobrien	}
603050397Sobrien
603150397Sobrien      r = p;
603250397Sobrien      p = p->parent;
603350397Sobrien    }
603450397Sobrien}
603550397Sobrien
603650397Sobrien/* Return nonzero if FIELD is equal to the index of a pending initializer.  */
603750397Sobrien
603850397Sobrienstatic int
603950397Sobrienpending_init_member (field)
604050397Sobrien     tree field;
604150397Sobrien{
604250397Sobrien  struct init_node *p;
604350397Sobrien
604450397Sobrien  p = constructor_pending_elts;
604550397Sobrien  if (TREE_CODE (constructor_type) == ARRAY_TYPE)
604650397Sobrien    {
604750397Sobrien      while (p)
604850397Sobrien	{
604950397Sobrien	  if (tree_int_cst_equal (field, p->purpose))
605050397Sobrien	    return 1;
605150397Sobrien	  else if (tree_int_cst_lt (field, p->purpose))
605250397Sobrien	    p = p->left;
605350397Sobrien	  else
605450397Sobrien	    p = p->right;
605550397Sobrien	}
605650397Sobrien    }
605750397Sobrien  else
605850397Sobrien    {
605950397Sobrien      while (p)
606050397Sobrien	{
606150397Sobrien	  if (field == p->purpose)
606250397Sobrien	    return 1;
606350397Sobrien	  else if (tree_int_cst_lt (DECL_FIELD_BITPOS (field),
606450397Sobrien				    DECL_FIELD_BITPOS (p->purpose)))
606550397Sobrien	    p = p->left;
606650397Sobrien	  else
606750397Sobrien	    p = p->right;
606850397Sobrien	}
606950397Sobrien    }
607050397Sobrien
607150397Sobrien  return 0;
607250397Sobrien}
607350397Sobrien
607418334Speter/* "Output" the next constructor element.
607518334Speter   At top level, really output it to assembler code now.
607618334Speter   Otherwise, collect it in a list from which we will make a CONSTRUCTOR.
607718334Speter   TYPE is the data type that the containing data type wants here.
607818334Speter   FIELD is the field (a FIELD_DECL) or the index that this element fills.
607918334Speter
608018334Speter   PENDING if non-nil means output pending elements that belong
608118334Speter   right after this element.  (PENDING is normally 1;
608218334Speter   it is 0 while outputting pending elements, to avoid recursion.)  */
608318334Speter
608418334Speterstatic void
608518334Speteroutput_init_element (value, type, field, pending)
608618334Speter     tree value, type, field;
608718334Speter     int pending;
608818334Speter{
608918334Speter  int duplicate = 0;
609018334Speter
609118334Speter  if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE
609218334Speter      || (TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE
609318334Speter	  && !(TREE_CODE (value) == STRING_CST
609418334Speter	       && TREE_CODE (type) == ARRAY_TYPE
609518334Speter	       && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE)
609618334Speter	  && !comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (value)),
609718334Speter			 TYPE_MAIN_VARIANT (type))))
609818334Speter    value = default_conversion (value);
609918334Speter
610018334Speter  if (value == error_mark_node)
610118334Speter    constructor_erroneous = 1;
610218334Speter  else if (!TREE_CONSTANT (value))
610318334Speter    constructor_constant = 0;
610418334Speter  else if (initializer_constant_valid_p (value, TREE_TYPE (value)) == 0
610518334Speter	   || ((TREE_CODE (constructor_type) == RECORD_TYPE
610618334Speter		|| TREE_CODE (constructor_type) == UNION_TYPE)
610750397Sobrien	       && DECL_C_BIT_FIELD (field)
610850397Sobrien	       && TREE_CODE (value) != INTEGER_CST))
610918334Speter    constructor_simple = 0;
611018334Speter
611118334Speter  if (require_constant_value && ! TREE_CONSTANT (value))
611218334Speter    {
611352284Sobrien      error_init ("initializer element is not constant");
611418334Speter      value = error_mark_node;
611518334Speter    }
611618334Speter  else if (require_constant_elements
611718334Speter	   && initializer_constant_valid_p (value, TREE_TYPE (value)) == 0)
611818334Speter    {
611952284Sobrien      error_init ("initializer element is not computable at load time");
612018334Speter      value = error_mark_node;
612118334Speter    }
612218334Speter
612318334Speter  /* If this element duplicates one on constructor_pending_elts,
612418334Speter     print a message and ignore it.  Don't do this when we're
612518334Speter     processing elements taken off constructor_pending_elts,
612618334Speter     because we'd always get spurious errors.  */
612718334Speter  if (pending)
612818334Speter    {
612918334Speter      if (TREE_CODE (constructor_type) == RECORD_TYPE
613050397Sobrien	  || TREE_CODE (constructor_type) == UNION_TYPE
613150397Sobrien	  || TREE_CODE (constructor_type) == ARRAY_TYPE)
613218334Speter	{
613350397Sobrien	  if (pending_init_member (field))
613418334Speter	    {
613552284Sobrien	      error_init ("duplicate initializer");
613618334Speter	      duplicate = 1;
613718334Speter	    }
613818334Speter	}
613918334Speter    }
614018334Speter
614118334Speter  /* If this element doesn't come next in sequence,
614218334Speter     put it on constructor_pending_elts.  */
614318334Speter  if (TREE_CODE (constructor_type) == ARRAY_TYPE
614418334Speter      && !tree_int_cst_equal (field, constructor_unfilled_index))
614518334Speter    {
614618334Speter      if (! duplicate)
614718334Speter	/* The copy_node is needed in case field is actually
614818334Speter	   constructor_index, which is modified in place.  */
614950397Sobrien	add_pending_init (copy_node (field),
615050397Sobrien			  digest_init (type, value, require_constant_value,
615150397Sobrien				       require_constant_elements));
615218334Speter    }
615318334Speter  else if (TREE_CODE (constructor_type) == RECORD_TYPE
615418334Speter	   && field != constructor_unfilled_fields)
615518334Speter    {
615618334Speter      /* We do this for records but not for unions.  In a union,
615718334Speter	 no matter which field is specified, it can be initialized
615818334Speter	 right away since it starts at the beginning of the union.  */
615918334Speter      if (!duplicate)
616050397Sobrien	add_pending_init (field,
616150397Sobrien			  digest_init (type, value, require_constant_value,
616250397Sobrien				       require_constant_elements));
616318334Speter    }
616418334Speter  else
616518334Speter    {
616618334Speter      /* Otherwise, output this element either to
616718334Speter	 constructor_elements or to the assembler file.  */
616818334Speter
616918334Speter      if (!duplicate)
617018334Speter	{
617118334Speter	  if (! constructor_incremental)
617218334Speter	    {
617318334Speter	      if (field && TREE_CODE (field) == INTEGER_CST)
617418334Speter		field = copy_node (field);
617518334Speter	      constructor_elements
617618334Speter		= tree_cons (field, digest_init (type, value,
617718334Speter						 require_constant_value,
617818334Speter						 require_constant_elements),
617918334Speter			     constructor_elements);
618018334Speter	    }
618118334Speter	  else
618218334Speter	    {
618318334Speter	      /* Structure elements may require alignment.
618418334Speter		 Do this, if necessary.  */
618518334Speter	      if (TREE_CODE (constructor_type) == RECORD_TYPE)
618618334Speter		{
618718334Speter		  /* Advance to offset of this element.  */
618818334Speter		  if (! tree_int_cst_equal (constructor_bit_index,
618918334Speter					    DECL_FIELD_BITPOS (field)))
619018334Speter		    {
619150397Sobrien		      /* By using unsigned arithmetic, the result will be
619250397Sobrien			 correct even in case of overflows, if BITS_PER_UNIT
619350397Sobrien			 is a power of two.  */
619450397Sobrien		      unsigned next = (TREE_INT_CST_LOW
619550397Sobrien				       (DECL_FIELD_BITPOS (field))
619650397Sobrien				       / (unsigned)BITS_PER_UNIT);
619750397Sobrien		      unsigned here = (TREE_INT_CST_LOW
619850397Sobrien				       (constructor_bit_index)
619950397Sobrien				       / (unsigned)BITS_PER_UNIT);
620018334Speter
620150397Sobrien		      assemble_zeros ((next - here)
620250397Sobrien				      * (unsigned)BITS_PER_UNIT
620350397Sobrien				      / (unsigned)BITS_PER_UNIT);
620418334Speter		    }
620518334Speter		}
620618334Speter	      output_constant (digest_init (type, value,
620718334Speter					    require_constant_value,
620818334Speter					    require_constant_elements),
620918334Speter			       int_size_in_bytes (type));
621018334Speter
621118334Speter	      /* For a record or union,
621218334Speter		 keep track of end position of last field.  */
621318334Speter	      if (TREE_CODE (constructor_type) == RECORD_TYPE
621418334Speter		  || TREE_CODE (constructor_type) == UNION_TYPE)
621518334Speter		{
621618334Speter		  tree temp = size_binop (PLUS_EXPR, DECL_FIELD_BITPOS (field),
621718334Speter					  DECL_SIZE (field));
621818334Speter		  TREE_INT_CST_LOW (constructor_bit_index)
621918334Speter		    = TREE_INT_CST_LOW (temp);
622018334Speter		  TREE_INT_CST_HIGH (constructor_bit_index)
622118334Speter		    = TREE_INT_CST_HIGH (temp);
622218334Speter		}
622318334Speter	    }
622418334Speter	}
622518334Speter
622618334Speter      /* Advance the variable that indicates sequential elements output.  */
622718334Speter      if (TREE_CODE (constructor_type) == ARRAY_TYPE)
622818334Speter	{
622918334Speter	  tree tem = size_binop (PLUS_EXPR, constructor_unfilled_index,
623018334Speter				 integer_one_node);
623118334Speter	  TREE_INT_CST_LOW (constructor_unfilled_index)
623218334Speter	    = TREE_INT_CST_LOW (tem);
623318334Speter	  TREE_INT_CST_HIGH (constructor_unfilled_index)
623418334Speter	    = TREE_INT_CST_HIGH (tem);
623518334Speter	}
623618334Speter      else if (TREE_CODE (constructor_type) == RECORD_TYPE)
623718334Speter	constructor_unfilled_fields = TREE_CHAIN (constructor_unfilled_fields);
623818334Speter      else if (TREE_CODE (constructor_type) == UNION_TYPE)
623918334Speter	constructor_unfilled_fields = 0;
624018334Speter
624118334Speter      /* Now output any pending elements which have become next.  */
624218334Speter      if (pending)
624318334Speter	output_pending_init_elements (0);
624418334Speter    }
624518334Speter}
624618334Speter
624718334Speter/* Output any pending elements which have become next.
624818334Speter   As we output elements, constructor_unfilled_{fields,index}
624918334Speter   advances, which may cause other elements to become next;
625018334Speter   if so, they too are output.
625118334Speter
625218334Speter   If ALL is 0, we return when there are
625318334Speter   no more pending elements to output now.
625418334Speter
625518334Speter   If ALL is 1, we output space as necessary so that
625618334Speter   we can output all the pending elements.  */
625718334Speter
625818334Speterstatic void
625918334Speteroutput_pending_init_elements (all)
626018334Speter     int all;
626118334Speter{
626250397Sobrien  struct init_node *elt = constructor_pending_elts;
626318334Speter  tree next;
626418334Speter
626518334Speter retry:
626618334Speter
626750397Sobrien  /* Look thru the whole pending tree.
626818334Speter     If we find an element that should be output now,
626918334Speter     output it.  Otherwise, set NEXT to the element
627018334Speter     that comes first among those still pending.  */
627118334Speter
627218334Speter  next = 0;
627350397Sobrien  while (elt)
627418334Speter    {
627518334Speter      if (TREE_CODE (constructor_type) == ARRAY_TYPE)
627618334Speter	{
627750397Sobrien	  if (tree_int_cst_equal (elt->purpose,
627818334Speter				  constructor_unfilled_index))
627950397Sobrien	    output_init_element (elt->value,
628050397Sobrien				 TREE_TYPE (constructor_type),
628150397Sobrien				 constructor_unfilled_index, 0);
628250397Sobrien	  else if (tree_int_cst_lt (constructor_unfilled_index,
628350397Sobrien				    elt->purpose))
628418334Speter	    {
628550397Sobrien	      /* Advance to the next smaller node.  */
628650397Sobrien	      if (elt->left)
628750397Sobrien		elt = elt->left;
628850397Sobrien	      else
628950397Sobrien		{
629050397Sobrien		  /* We have reached the smallest node bigger than the
629150397Sobrien		     current unfilled index.  Fill the space first.  */
629250397Sobrien		  next = elt->purpose;
629350397Sobrien		  break;
629450397Sobrien		}
629518334Speter	    }
629650397Sobrien	  else
629750397Sobrien	    {
629850397Sobrien	      /* Advance to the next bigger node.  */
629950397Sobrien	      if (elt->right)
630050397Sobrien		elt = elt->right;
630150397Sobrien	      else
630250397Sobrien		{
630350397Sobrien		  /* We have reached the biggest node in a subtree.  Find
630450397Sobrien		     the parent of it, which is the next bigger node.  */
630550397Sobrien		  while (elt->parent && elt->parent->right == elt)
630650397Sobrien		    elt = elt->parent;
630750397Sobrien		  elt = elt->parent;
630850397Sobrien		  if (elt && tree_int_cst_lt (constructor_unfilled_index,
630950397Sobrien					      elt->purpose))
631050397Sobrien		    {
631150397Sobrien		      next = elt->purpose;
631250397Sobrien		      break;
631350397Sobrien		    }
631450397Sobrien		}
631550397Sobrien	    }
631618334Speter	}
631718334Speter      else if (TREE_CODE (constructor_type) == RECORD_TYPE
631818334Speter	       || TREE_CODE (constructor_type) == UNION_TYPE)
631918334Speter	{
632050397Sobrien	  /* If the current record is complete we are done.  */
632150397Sobrien	  if (constructor_unfilled_fields == 0)
632250397Sobrien	    break;
632350397Sobrien	  if (elt->purpose == constructor_unfilled_fields)
632418334Speter	    {
632550397Sobrien	      output_init_element (elt->value,
632618334Speter				   TREE_TYPE (constructor_unfilled_fields),
632718334Speter				   constructor_unfilled_fields,
632818334Speter				   0);
632918334Speter	    }
633050397Sobrien	  else if (tree_int_cst_lt (DECL_FIELD_BITPOS (constructor_unfilled_fields),
633150397Sobrien				    DECL_FIELD_BITPOS (elt->purpose)))
633250397Sobrien	    {
633350397Sobrien	      /* Advance to the next smaller node.  */
633450397Sobrien	      if (elt->left)
633550397Sobrien		elt = elt->left;
633650397Sobrien	      else
633750397Sobrien		{
633850397Sobrien		  /* We have reached the smallest node bigger than the
633950397Sobrien		     current unfilled field.  Fill the space first.  */
634050397Sobrien		  next = elt->purpose;
634150397Sobrien		  break;
634250397Sobrien		}
634350397Sobrien	    }
634450397Sobrien	  else
634550397Sobrien	    {
634650397Sobrien	      /* Advance to the next bigger node.  */
634750397Sobrien	      if (elt->right)
634850397Sobrien		elt = elt->right;
634950397Sobrien	      else
635050397Sobrien		{
635150397Sobrien		  /* We have reached the biggest node in a subtree.  Find
635250397Sobrien		     the parent of it, which is the next bigger node.  */
635350397Sobrien		  while (elt->parent && elt->parent->right == elt)
635450397Sobrien		    elt = elt->parent;
635550397Sobrien		  elt = elt->parent;
635650397Sobrien		  if (elt
635750397Sobrien		      && tree_int_cst_lt (DECL_FIELD_BITPOS (constructor_unfilled_fields),
635850397Sobrien					  DECL_FIELD_BITPOS (elt->purpose)))
635950397Sobrien		    {
636050397Sobrien		      next = elt->purpose;
636150397Sobrien		      break;
636250397Sobrien		    }
636350397Sobrien		}
636450397Sobrien	    }
636518334Speter	}
636618334Speter    }
636718334Speter
636818334Speter  /* Ordinarily return, but not if we want to output all
636918334Speter     and there are elements left.  */
637018334Speter  if (! (all && next != 0))
637118334Speter    return;
637218334Speter
637318334Speter  /* Generate space up to the position of NEXT.  */
637418334Speter  if (constructor_incremental)
637518334Speter    {
637618334Speter      tree filled;
637718334Speter      tree nextpos_tree = size_int (0);
637818334Speter
637918334Speter      if (TREE_CODE (constructor_type) == RECORD_TYPE
638018334Speter	  || TREE_CODE (constructor_type) == UNION_TYPE)
638118334Speter	{
638250397Sobrien	  tree tail;
638318334Speter	  /* Find the last field written out, if any.  */
638418334Speter	  for (tail = TYPE_FIELDS (constructor_type); tail;
638518334Speter	       tail = TREE_CHAIN (tail))
638618334Speter	    if (TREE_CHAIN (tail) == constructor_unfilled_fields)
638718334Speter	      break;
638818334Speter
638918334Speter	  if (tail)
639018334Speter	    /* Find the offset of the end of that field.  */
639118334Speter	    filled = size_binop (CEIL_DIV_EXPR,
639218334Speter				 size_binop (PLUS_EXPR,
639318334Speter					     DECL_FIELD_BITPOS (tail),
639418334Speter					     DECL_SIZE (tail)),
639518334Speter				 size_int (BITS_PER_UNIT));
639618334Speter	  else
639718334Speter	    filled = size_int (0);
639818334Speter
639918334Speter	  nextpos_tree = size_binop (CEIL_DIV_EXPR,
640018334Speter				     DECL_FIELD_BITPOS (next),
640118334Speter				     size_int (BITS_PER_UNIT));
640218334Speter
640318334Speter	  TREE_INT_CST_HIGH (constructor_bit_index)
640418334Speter	    = TREE_INT_CST_HIGH (DECL_FIELD_BITPOS (next));
640518334Speter	  TREE_INT_CST_LOW (constructor_bit_index)
640618334Speter	    = TREE_INT_CST_LOW (DECL_FIELD_BITPOS (next));
640718334Speter	  constructor_unfilled_fields = next;
640818334Speter	}
640918334Speter      else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
641018334Speter	{
641118334Speter	  filled = size_binop (MULT_EXPR, constructor_unfilled_index,
641218334Speter			       size_in_bytes (TREE_TYPE (constructor_type)));
641318334Speter	  nextpos_tree
641418334Speter	    = size_binop (MULT_EXPR, next,
641518334Speter			  size_in_bytes (TREE_TYPE (constructor_type)));
641618334Speter	  TREE_INT_CST_LOW (constructor_unfilled_index)
641718334Speter	    = TREE_INT_CST_LOW (next);
641818334Speter	  TREE_INT_CST_HIGH (constructor_unfilled_index)
641918334Speter	    = TREE_INT_CST_HIGH (next);
642018334Speter	}
642118334Speter      else
642218334Speter	filled = 0;
642318334Speter
642418334Speter      if (filled)
642518334Speter	{
642618334Speter	  int nextpos = TREE_INT_CST_LOW (nextpos_tree);
642718334Speter
642818334Speter	  assemble_zeros (nextpos - TREE_INT_CST_LOW (filled));
642918334Speter	}
643018334Speter    }
643118334Speter  else
643218334Speter    {
643318334Speter      /* If it's not incremental, just skip over the gap,
643418334Speter	 so that after jumping to retry we will output the next
643518334Speter	 successive element.  */
643618334Speter      if (TREE_CODE (constructor_type) == RECORD_TYPE
643718334Speter	  || TREE_CODE (constructor_type) == UNION_TYPE)
643818334Speter	constructor_unfilled_fields = next;
643918334Speter      else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
644018334Speter	{
644118334Speter	  TREE_INT_CST_LOW (constructor_unfilled_index)
644218334Speter	    = TREE_INT_CST_LOW (next);
644318334Speter	  TREE_INT_CST_HIGH (constructor_unfilled_index)
644418334Speter	    = TREE_INT_CST_HIGH (next);
644518334Speter	}
644618334Speter    }
644718334Speter
644850397Sobrien  /* ELT now points to the node in the pending tree with the next
644950397Sobrien     initializer to output.  */
645018334Speter  goto retry;
645118334Speter}
645218334Speter
645318334Speter/* Add one non-braced element to the current constructor level.
645418334Speter   This adjusts the current position within the constructor's type.
645518334Speter   This may also start or terminate implicit levels
645618334Speter   to handle a partly-braced initializer.
645718334Speter
645818334Speter   Once this has found the correct level for the new element,
645918334Speter   it calls output_init_element.
646018334Speter
646118334Speter   Note: if we are incrementally outputting this constructor,
646218334Speter   this function may be called with a null argument
646318334Speter   representing a sub-constructor that was already incrementally output.
646418334Speter   When that happens, we output nothing, but we do the bookkeeping
646518334Speter   to skip past that element of the current constructor.  */
646618334Speter
646718334Spetervoid
646818334Speterprocess_init_element (value)
646918334Speter     tree value;
647018334Speter{
647118334Speter  tree orig_value = value;
647218334Speter  int string_flag = value != 0 && TREE_CODE (value) == STRING_CST;
647318334Speter
647418334Speter  /* Handle superfluous braces around string cst as in
647518334Speter     char x[] = {"foo"}; */
647618334Speter  if (string_flag
647718334Speter      && constructor_type
647818334Speter      && TREE_CODE (constructor_type) == ARRAY_TYPE
647918334Speter      && TREE_CODE (TREE_TYPE (constructor_type)) == INTEGER_TYPE
648018334Speter      && integer_zerop (constructor_unfilled_index))
648118334Speter    {
648218334Speter      constructor_stack->replacement_value = value;
648318334Speter      return;
648418334Speter    }
648518334Speter
648618334Speter  if (constructor_stack->replacement_value != 0)
648718334Speter    {
648852284Sobrien      error_init ("excess elements in struct initializer");
648918334Speter      return;
649018334Speter    }
649118334Speter
649218334Speter  /* Ignore elements of a brace group if it is entirely superfluous
649318334Speter     and has already been diagnosed.  */
649418334Speter  if (constructor_type == 0)
649518334Speter    return;
649618334Speter
649718334Speter  /* If we've exhausted any levels that didn't have braces,
649818334Speter     pop them now.  */
649918334Speter  while (constructor_stack->implicit)
650018334Speter    {
650118334Speter      if ((TREE_CODE (constructor_type) == RECORD_TYPE
650218334Speter	   || TREE_CODE (constructor_type) == UNION_TYPE)
650318334Speter	  && constructor_fields == 0)
650418334Speter	process_init_element (pop_init_level (1));
650518334Speter      else if (TREE_CODE (constructor_type) == ARRAY_TYPE
650650397Sobrien	       && (constructor_max_index == 0
650750397Sobrien		   || tree_int_cst_lt (constructor_max_index,
650850397Sobrien				       constructor_index)))
650918334Speter	process_init_element (pop_init_level (1));
651018334Speter      else
651118334Speter	break;
651218334Speter    }
651318334Speter
651418334Speter  while (1)
651518334Speter    {
651618334Speter      if (TREE_CODE (constructor_type) == RECORD_TYPE)
651718334Speter	{
651818334Speter	  tree fieldtype;
651918334Speter	  enum tree_code fieldcode;
652018334Speter
652118334Speter	  if (constructor_fields == 0)
652218334Speter	    {
652352284Sobrien	      pedwarn_init ("excess elements in struct initializer");
652418334Speter	      break;
652518334Speter	    }
652618334Speter
652718334Speter	  fieldtype = TREE_TYPE (constructor_fields);
652818334Speter	  if (fieldtype != error_mark_node)
652918334Speter	    fieldtype = TYPE_MAIN_VARIANT (fieldtype);
653018334Speter	  fieldcode = TREE_CODE (fieldtype);
653118334Speter
653218334Speter	  /* Accept a string constant to initialize a subarray.  */
653318334Speter	  if (value != 0
653418334Speter	      && fieldcode == ARRAY_TYPE
653518334Speter	      && TREE_CODE (TREE_TYPE (fieldtype)) == INTEGER_TYPE
653618334Speter	      && string_flag)
653718334Speter	    value = orig_value;
653818334Speter	  /* Otherwise, if we have come to a subaggregate,
653918334Speter	     and we don't have an element of its type, push into it.  */
654018334Speter	  else if (value != 0 && !constructor_no_implicit
654118334Speter		   && value != error_mark_node
654218334Speter		   && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype
654318334Speter		   && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE
654418334Speter		       || fieldcode == UNION_TYPE))
654518334Speter	    {
654618334Speter	      push_init_level (1);
654718334Speter	      continue;
654818334Speter	    }
654918334Speter
655018334Speter	  if (value)
655118334Speter	    {
655218334Speter	      push_member_name (constructor_fields);
655318334Speter	      output_init_element (value, fieldtype, constructor_fields, 1);
655418334Speter	      RESTORE_SPELLING_DEPTH (constructor_depth);
655518334Speter	    }
655618334Speter	  else
655718334Speter	    /* Do the bookkeeping for an element that was
655818334Speter	       directly output as a constructor.  */
655918334Speter	    {
656018334Speter	      /* For a record, keep track of end position of last field.  */
656118334Speter	      tree temp = size_binop (PLUS_EXPR,
656218334Speter				      DECL_FIELD_BITPOS (constructor_fields),
656318334Speter				      DECL_SIZE (constructor_fields));
656418334Speter	      TREE_INT_CST_LOW (constructor_bit_index)
656518334Speter		= TREE_INT_CST_LOW (temp);
656618334Speter	      TREE_INT_CST_HIGH (constructor_bit_index)
656718334Speter		= TREE_INT_CST_HIGH (temp);
656818334Speter
656918334Speter	      constructor_unfilled_fields = TREE_CHAIN (constructor_fields);
657018334Speter	    }
657118334Speter
657218334Speter	  constructor_fields = TREE_CHAIN (constructor_fields);
657318334Speter	  /* Skip any nameless bit fields at the beginning.  */
657450397Sobrien	  while (constructor_fields != 0
657550397Sobrien		 && DECL_C_BIT_FIELD (constructor_fields)
657618334Speter		 && DECL_NAME (constructor_fields) == 0)
657718334Speter	    constructor_fields = TREE_CHAIN (constructor_fields);
657818334Speter	  break;
657918334Speter	}
658018334Speter      if (TREE_CODE (constructor_type) == UNION_TYPE)
658118334Speter	{
658218334Speter	  tree fieldtype;
658318334Speter	  enum tree_code fieldcode;
658418334Speter
658518334Speter	  if (constructor_fields == 0)
658618334Speter	    {
658752284Sobrien	      pedwarn_init ("excess elements in union initializer");
658818334Speter	      break;
658918334Speter	    }
659018334Speter
659118334Speter	  fieldtype = TREE_TYPE (constructor_fields);
659218334Speter	  if (fieldtype != error_mark_node)
659318334Speter	    fieldtype = TYPE_MAIN_VARIANT (fieldtype);
659418334Speter	  fieldcode = TREE_CODE (fieldtype);
659518334Speter
659618334Speter	  /* Accept a string constant to initialize a subarray.  */
659718334Speter	  if (value != 0
659818334Speter	      && fieldcode == ARRAY_TYPE
659918334Speter	      && TREE_CODE (TREE_TYPE (fieldtype)) == INTEGER_TYPE
660018334Speter	      && string_flag)
660118334Speter	    value = orig_value;
660218334Speter	  /* Otherwise, if we have come to a subaggregate,
660318334Speter	     and we don't have an element of its type, push into it.  */
660418334Speter	  else if (value != 0 && !constructor_no_implicit
660518334Speter		   && value != error_mark_node
660618334Speter		   && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != fieldtype
660718334Speter		   && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE
660818334Speter		       || fieldcode == UNION_TYPE))
660918334Speter	    {
661018334Speter	      push_init_level (1);
661118334Speter	      continue;
661218334Speter	    }
661318334Speter
661418334Speter	  if (value)
661518334Speter	    {
661618334Speter	      push_member_name (constructor_fields);
661718334Speter	      output_init_element (value, fieldtype, constructor_fields, 1);
661818334Speter	      RESTORE_SPELLING_DEPTH (constructor_depth);
661918334Speter	    }
662018334Speter	  else
662118334Speter	    /* Do the bookkeeping for an element that was
662218334Speter	       directly output as a constructor.  */
662318334Speter	    {
662418334Speter	      TREE_INT_CST_LOW (constructor_bit_index)
662518334Speter		= TREE_INT_CST_LOW (DECL_SIZE (constructor_fields));
662618334Speter	      TREE_INT_CST_HIGH (constructor_bit_index)
662718334Speter		= TREE_INT_CST_HIGH (DECL_SIZE (constructor_fields));
662818334Speter
662918334Speter	      constructor_unfilled_fields = TREE_CHAIN (constructor_fields);
663018334Speter	    }
663118334Speter
663218334Speter	  constructor_fields = 0;
663318334Speter	  break;
663418334Speter	}
663518334Speter      if (TREE_CODE (constructor_type) == ARRAY_TYPE)
663618334Speter	{
663718334Speter	  tree elttype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type));
663818334Speter	  enum tree_code eltcode = TREE_CODE (elttype);
663918334Speter
664018334Speter	  /* Accept a string constant to initialize a subarray.  */
664118334Speter	  if (value != 0
664218334Speter	      && eltcode == ARRAY_TYPE
664318334Speter	      && TREE_CODE (TREE_TYPE (elttype)) == INTEGER_TYPE
664418334Speter	      && string_flag)
664518334Speter	    value = orig_value;
664618334Speter	  /* Otherwise, if we have come to a subaggregate,
664718334Speter	     and we don't have an element of its type, push into it.  */
664818334Speter	  else if (value != 0 && !constructor_no_implicit
664918334Speter		   && value != error_mark_node
665018334Speter		   && TYPE_MAIN_VARIANT (TREE_TYPE (value)) != elttype
665118334Speter		   && (eltcode == RECORD_TYPE || eltcode == ARRAY_TYPE
665218334Speter		       || eltcode == UNION_TYPE))
665318334Speter	    {
665418334Speter	      push_init_level (1);
665518334Speter	      continue;
665618334Speter	    }
665718334Speter
665818334Speter	  if (constructor_max_index != 0
665918334Speter	      && tree_int_cst_lt (constructor_max_index, constructor_index))
666018334Speter	    {
666152284Sobrien	      pedwarn_init ("excess elements in array initializer");
666218334Speter	      break;
666318334Speter	    }
666418334Speter
666550397Sobrien	  /* In the case of [LO .. HI] = VALUE, only evaluate VALUE once.  */
666618334Speter	  if (constructor_range_end)
666750397Sobrien	    {
666850397Sobrien	      if (constructor_max_index != 0
666950397Sobrien		  && tree_int_cst_lt (constructor_max_index,
667050397Sobrien				      constructor_range_end))
667150397Sobrien		{
667252284Sobrien		  pedwarn_init ("excess elements in array initializer");
667350397Sobrien		  TREE_INT_CST_HIGH (constructor_range_end)
667450397Sobrien		    = TREE_INT_CST_HIGH (constructor_max_index);
667550397Sobrien		  TREE_INT_CST_LOW (constructor_range_end)
667650397Sobrien		    = TREE_INT_CST_LOW (constructor_max_index);
667750397Sobrien		}
667818334Speter
667950397Sobrien	      value = save_expr (value);
668050397Sobrien	    }
668150397Sobrien
668218334Speter	  /* Now output the actual element.
668318334Speter	     Ordinarily, output once.
668418334Speter	     If there is a range, repeat it till we advance past the range.  */
668518334Speter	  do
668618334Speter	    {
668718334Speter	      tree tem;
668818334Speter
668918334Speter	      if (value)
669018334Speter		{
669118334Speter		  push_array_bounds (TREE_INT_CST_LOW (constructor_index));
669218334Speter		  output_init_element (value, elttype, constructor_index, 1);
669318334Speter		  RESTORE_SPELLING_DEPTH (constructor_depth);
669418334Speter		}
669518334Speter
669618334Speter	      tem = size_binop (PLUS_EXPR, constructor_index,
669718334Speter				integer_one_node);
669850397Sobrien	      TREE_INT_CST_LOW (constructor_index) = TREE_INT_CST_LOW (tem);
669950397Sobrien	      TREE_INT_CST_HIGH (constructor_index) = TREE_INT_CST_HIGH (tem);
670018334Speter
670118334Speter	      if (!value)
670218334Speter		/* If we are doing the bookkeeping for an element that was
670318334Speter		   directly output as a constructor,
670418334Speter		   we must update constructor_unfilled_index.  */
670518334Speter		{
670618334Speter		  TREE_INT_CST_LOW (constructor_unfilled_index)
670718334Speter		    = TREE_INT_CST_LOW (constructor_index);
670818334Speter		  TREE_INT_CST_HIGH (constructor_unfilled_index)
670918334Speter		    = TREE_INT_CST_HIGH (constructor_index);
671018334Speter		}
671118334Speter	    }
671218334Speter	  while (! (constructor_range_end == 0
671318334Speter		    || tree_int_cst_lt (constructor_range_end,
671418334Speter					constructor_index)));
671518334Speter
671618334Speter	  break;
671718334Speter	}
671818334Speter
671918334Speter      /* Handle the sole element allowed in a braced initializer
672018334Speter	 for a scalar variable.  */
672118334Speter      if (constructor_fields == 0)
672218334Speter	{
672352284Sobrien	  pedwarn_init ("excess elements in scalar initializer");
672418334Speter	  break;
672518334Speter	}
672618334Speter
672718334Speter      if (value)
672818334Speter	output_init_element (value, constructor_type, NULL_TREE, 1);
672918334Speter      constructor_fields = 0;
673018334Speter      break;
673118334Speter    }
673218334Speter
673318334Speter  /* If the (lexically) previous elments are not now saved,
673418334Speter     we can discard the storage for them.  */
673518334Speter  if (constructor_incremental && constructor_pending_elts == 0 && value != 0
673618334Speter      && constructor_stack == 0)
673718334Speter    clear_momentary ();
673818334Speter}
673918334Speter
674018334Speter/* Expand an ASM statement with operands, handling output operands
674118334Speter   that are not variables or INDIRECT_REFS by transforming such
674218334Speter   cases into cases that expand_asm_operands can handle.
674318334Speter
674418334Speter   Arguments are same as for expand_asm_operands.  */
674518334Speter
674618334Spetervoid
674718334Speterc_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
674818334Speter     tree string, outputs, inputs, clobbers;
674918334Speter     int vol;
675018334Speter     char *filename;
675118334Speter     int line;
675218334Speter{
675318334Speter  int noutputs = list_length (outputs);
675418334Speter  register int i;
675518334Speter  /* o[I] is the place that output number I should be written.  */
675618334Speter  register tree *o = (tree *) alloca (noutputs * sizeof (tree));
675718334Speter  register tree tail;
675818334Speter
675918334Speter  if (TREE_CODE (string) == ADDR_EXPR)
676018334Speter    string = TREE_OPERAND (string, 0);
676118334Speter  if (TREE_CODE (string) != STRING_CST)
676218334Speter    {
676318334Speter      error ("asm template is not a string constant");
676418334Speter      return;
676518334Speter    }
676618334Speter
676718334Speter  /* Record the contents of OUTPUTS before it is modified.  */
676818334Speter  for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
676918334Speter    o[i] = TREE_VALUE (tail);
677018334Speter
677118334Speter  /* Perform default conversions on array and function inputs.  */
677218334Speter  /* Don't do this for other types--
677318334Speter     it would screw up operands expected to be in memory.  */
677418334Speter  for (i = 0, tail = inputs; tail; tail = TREE_CHAIN (tail), i++)
677518334Speter    if (TREE_CODE (TREE_TYPE (TREE_VALUE (tail))) == ARRAY_TYPE
677618334Speter	|| TREE_CODE (TREE_TYPE (TREE_VALUE (tail))) == FUNCTION_TYPE)
677718334Speter      TREE_VALUE (tail) = default_conversion (TREE_VALUE (tail));
677818334Speter
677918334Speter  /* Generate the ASM_OPERANDS insn;
678018334Speter     store into the TREE_VALUEs of OUTPUTS some trees for
678118334Speter     where the values were actually stored.  */
678218334Speter  expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line);
678318334Speter
678418334Speter  /* Copy all the intermediate outputs into the specified outputs.  */
678518334Speter  for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
678618334Speter    {
678718334Speter      if (o[i] != TREE_VALUE (tail))
678818334Speter	{
678918334Speter	  expand_expr (build_modify_expr (o[i], NOP_EXPR, TREE_VALUE (tail)),
679050397Sobrien		       NULL_RTX, VOIDmode, EXPAND_NORMAL);
679118334Speter	  free_temp_slots ();
679218334Speter	}
679318334Speter      /* Detect modification of read-only values.
679418334Speter	 (Otherwise done by build_modify_expr.)  */
679518334Speter      else
679618334Speter	{
679718334Speter	  tree type = TREE_TYPE (o[i]);
679818334Speter	  if (TREE_READONLY (o[i])
679918334Speter	      || TYPE_READONLY (type)
680018334Speter	      || ((TREE_CODE (type) == RECORD_TYPE
680118334Speter		   || TREE_CODE (type) == UNION_TYPE)
680218334Speter		  && C_TYPE_FIELDS_READONLY (type)))
680318334Speter	    readonly_warning (o[i], "modification by `asm'");
680418334Speter	}
680518334Speter    }
680618334Speter
680718334Speter  /* Those MODIFY_EXPRs could do autoincrements.  */
680818334Speter  emit_queue ();
680918334Speter}
681018334Speter
681118334Speter/* Expand a C `return' statement.
681218334Speter   RETVAL is the expression for what to return,
681318334Speter   or a null pointer for `return;' with no value.  */
681418334Speter
681518334Spetervoid
681618334Speterc_expand_return (retval)
681718334Speter     tree retval;
681818334Speter{
681918334Speter  tree valtype = TREE_TYPE (TREE_TYPE (current_function_decl));
682018334Speter
682118334Speter  if (TREE_THIS_VOLATILE (current_function_decl))
682218334Speter    warning ("function declared `noreturn' has a `return' statement");
682318334Speter
682418334Speter  if (!retval)
682518334Speter    {
682618334Speter      current_function_returns_null = 1;
682718334Speter      if (warn_return_type && valtype != 0 && TREE_CODE (valtype) != VOID_TYPE)
682818334Speter	warning ("`return' with no value, in function returning non-void");
682918334Speter      expand_null_return ();
683018334Speter    }
683118334Speter  else if (valtype == 0 || TREE_CODE (valtype) == VOID_TYPE)
683218334Speter    {
683318334Speter      current_function_returns_null = 1;
683418334Speter      if (pedantic || TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
683518334Speter	pedwarn ("`return' with a value, in function returning void");
683618334Speter      expand_return (retval);
683718334Speter    }
683818334Speter  else
683918334Speter    {
684052284Sobrien      tree t = convert_for_assignment (valtype, retval, _("return"),
684118334Speter				       NULL_TREE, NULL_TREE, 0);
684218334Speter      tree res = DECL_RESULT (current_function_decl);
684318334Speter      tree inner;
684418334Speter
684518334Speter      if (t == error_mark_node)
684618334Speter	return;
684718334Speter
684818334Speter      inner = t = convert (TREE_TYPE (res), t);
684918334Speter
685018334Speter      /* Strip any conversions, additions, and subtractions, and see if
685118334Speter	 we are returning the address of a local variable.  Warn if so.  */
685218334Speter      while (1)
685318334Speter	{
685418334Speter	  switch (TREE_CODE (inner))
685518334Speter	    {
685618334Speter	    case NOP_EXPR:   case NON_LVALUE_EXPR:  case CONVERT_EXPR:
685718334Speter	    case PLUS_EXPR:
685818334Speter	      inner = TREE_OPERAND (inner, 0);
685918334Speter	      continue;
686018334Speter
686118334Speter	    case MINUS_EXPR:
686218334Speter	      /* If the second operand of the MINUS_EXPR has a pointer
686318334Speter		 type (or is converted from it), this may be valid, so
686418334Speter		 don't give a warning.  */
686518334Speter	      {
686618334Speter		tree op1 = TREE_OPERAND (inner, 1);
686718334Speter
686818334Speter		while (! POINTER_TYPE_P (TREE_TYPE (op1))
686918334Speter		       && (TREE_CODE (op1) == NOP_EXPR
687018334Speter			   || TREE_CODE (op1) == NON_LVALUE_EXPR
687118334Speter			   || TREE_CODE (op1) == CONVERT_EXPR))
687218334Speter		  op1 = TREE_OPERAND (op1, 0);
687318334Speter
687418334Speter		if (POINTER_TYPE_P (TREE_TYPE (op1)))
687518334Speter		  break;
687618334Speter
687718334Speter		inner = TREE_OPERAND (inner, 0);
687818334Speter		continue;
687918334Speter	      }
688018334Speter
688118334Speter	    case ADDR_EXPR:
688218334Speter	      inner = TREE_OPERAND (inner, 0);
688318334Speter
688418334Speter	      while (TREE_CODE_CLASS (TREE_CODE (inner)) == 'r')
688518334Speter		inner = TREE_OPERAND (inner, 0);
688618334Speter
688718334Speter	      if (TREE_CODE (inner) == VAR_DECL
688818334Speter		  && ! DECL_EXTERNAL (inner)
688918334Speter		  && ! TREE_STATIC (inner)
689018334Speter		  && DECL_CONTEXT (inner) == current_function_decl)
689118334Speter		warning ("function returns address of local variable");
689218334Speter	      break;
689350397Sobrien
689450397Sobrien	    default:
689550397Sobrien	      break;
689618334Speter	    }
689718334Speter
689818334Speter	  break;
689918334Speter	}
690018334Speter
690118334Speter      t = build (MODIFY_EXPR, TREE_TYPE (res), res, t);
690218334Speter      TREE_SIDE_EFFECTS (t) = 1;
690318334Speter      expand_return (t);
690418334Speter      current_function_returns_value = 1;
690518334Speter    }
690618334Speter}
690718334Speter
690818334Speter/* Start a C switch statement, testing expression EXP.
690918334Speter   Return EXP if it is valid, an error node otherwise.  */
691018334Speter
691118334Spetertree
691218334Speterc_expand_start_case (exp)
691318334Speter     tree exp;
691418334Speter{
691518334Speter  register enum tree_code code = TREE_CODE (TREE_TYPE (exp));
691618334Speter  tree type = TREE_TYPE (exp);
691718334Speter
691818334Speter  if (code != INTEGER_TYPE && code != ENUMERAL_TYPE && code != ERROR_MARK)
691918334Speter    {
692018334Speter      error ("switch quantity not an integer");
692118334Speter      exp = error_mark_node;
692218334Speter    }
692318334Speter  else
692418334Speter    {
692518334Speter      tree index;
692618334Speter      type = TYPE_MAIN_VARIANT (TREE_TYPE (exp));
692718334Speter
692818334Speter      if (warn_traditional
692918334Speter	  && (type == long_integer_type_node
693018334Speter	      || type == long_unsigned_type_node))
693118334Speter	pedwarn ("`long' switch expression not converted to `int' in ANSI C");
693218334Speter
693318334Speter      exp = default_conversion (exp);
693418334Speter      type = TREE_TYPE (exp);
693518334Speter      index = get_unwidened (exp, NULL_TREE);
693618334Speter      /* We can't strip a conversion from a signed type to an unsigned,
693718334Speter	 because if we did, int_fits_type_p would do the wrong thing
693818334Speter	 when checking case values for being in range,
693918334Speter	 and it's too hard to do the right thing.  */
694018334Speter      if (TREE_UNSIGNED (TREE_TYPE (exp))
694118334Speter	  == TREE_UNSIGNED (TREE_TYPE (index)))
694218334Speter	exp = index;
694318334Speter    }
694418334Speter
694518334Speter  expand_start_case (1, exp, type, "switch statement");
694618334Speter
694718334Speter  return exp;
694818334Speter}
6949