OSDN Git Service

Update copyrights
[pf3gnuchains/gcc-fork.git] / gcc / ch / typeck.c
index 3a7b464..0116de3 100644 (file)
@@ -1,5 +1,5 @@
 /* Build expressions with type checking for CHILL compiler.
-   Copyright (C) 1992, 93, 1994 Free Software Foundation, Inc.
+   Copyright (C) 1992, 93, 94, 98, 99, 2000 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -15,7 +15,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
 
 /* This file is part of the CHILL front end.
@@ -28,44 +29,27 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
    like a strange sort of assignment).  */
 
 #include "config.h"
-#include <stdio.h>
+#include "system.h"
 #include "tree.h"
 #include "ch-tree.h"
 #include "flags.h"
 #include "rtl.h"
 #include "expr.h"
 #include "lex.h"
-
-extern tree build_chill_compound_expr PROTO((tree));
-extern tree build_component_ref       PROTO((tree, tree));
-extern void c_expand_return           PROTO((tree));
-extern int  ch_singleton_set          PROTO((tree));
-extern void error                     PROTO((char *, ...));
-extern void error_with_decl           PROTO((tree, char *, ...));
-extern int  mark_addressable          PROTO((tree));
-extern void pedwarn                   PROTO((char *, ...));
-extern void pedwarn_with_decl         PROTO((tree, char *, ...));
-extern tree require_complete_type     PROTO((tree));
-extern void sorry                     PROTO((char *, ...));
-extern void warning                   PROTO((char *, ...));
-extern int  get_type_precision        PROTO((tree, tree));
-
-extern tree intQI_type_node;
-extern tree intHI_type_node;
-extern tree intSI_type_node;
-extern tree intDI_type_node;
-extern tree intTI_type_node;
-
-extern tree unsigned_intQI_type_node;
-extern tree unsigned_intHI_type_node;
-extern tree unsigned_intSI_type_node;
-extern tree unsigned_intDI_type_node;
-extern tree unsigned_intTI_type_node;
+#include "toplev.h"
+#include "output.h"
 
 /* forward declarations */
-tree chill_expand_tuple PROTO((tree, tree));
-static int chill_l_equivalent PROTO((tree, tree, struct mode_chain*));
-extern tree extract_constant_from_buffer();
+static int chill_l_equivalent PARAMS ((tree, tree, struct mode_chain*));
+static tree extract_constant_from_buffer PARAMS ((tree, const unsigned char *, int));
+static int expand_constant_to_buffer PARAMS ((tree, unsigned char *, int));
+static tree build_empty_string PARAMS ((tree));
+static tree make_chill_pointer_type PARAMS ((tree, enum tree_code));
+static tree make_chill_range_type PARAMS ((tree, tree, tree));
+static void apply_chill_array_layout PARAMS ((tree));
+static int field_decl_cmp PARAMS ((tree *, tree*));
+static tree make_chill_struct_type PARAMS ((tree));
+static int apply_chill_field_layout PARAMS ((tree, int *));
 \f
 /*
  * This function checks an array access.
@@ -80,7 +64,7 @@ extern tree extract_constant_from_buffer();
 tree
 valid_array_index_p (array, idx, error_message, is_varying_lhs)
      tree array, idx;
-     char *error_message;
+     const char *error_message;
      int is_varying_lhs;
 {
   tree cond, low_limit, high_cond, atype, domain;
@@ -171,7 +155,7 @@ valid_array_index_p (array, idx, error_message, is_varying_lhs)
     {
       if (tree_int_cst_equal (cond, boolean_false_node))
        return idx;       /* condition met at compile time */
-      error (error_message); /* condition failed at compile time */
+      error ("%s", error_message); /* condition failed at compile time */
       return error_mark_node;
     }
   else if (range_checking)
@@ -249,7 +233,6 @@ build_chill_slice (array, min_value, length)
       tree element_type = TREE_TYPE (array_type);
       tree slice_type = build_simple_array_type (element_type, index_type, NULL_TREE);
       tree slice_pointer_type;
-      int is_static;
       tree max_size;
 
       if (CH_CHARS_TYPE_P (array_type))
@@ -729,7 +712,7 @@ convert_to_discrete (exp)
    Returns 1 on success, or 0 on failure. (Either the VALUE was
    not constant, or we don't know how to do the conversion.) */
 
-int
+static int
 expand_constant_to_buffer (value, buffer, buf_size)
      tree value;
      unsigned char *buffer; 
@@ -782,10 +765,12 @@ expand_constant_to_buffer (value, buffer, buf_size)
            {
              tree min_val = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
              if (min_val)
-               if (TREE_CODE (min_val) != INTEGER_CST)
-                 return 0;
-               else
-                 min_index = TREE_INT_CST_LOW (min_val);
+               {
+                 if (TREE_CODE (min_val) != INTEGER_CST)
+                   return 0;
+                 else
+                   min_index = TREE_INT_CST_LOW (min_val);
+               }
            }
 
          next_index = min_index;
@@ -858,10 +843,10 @@ expand_constant_to_buffer (value, buffer, buf_size)
    Returns NULL_TREE on failure. (E.g. the TYPE might be variable size,
    or perhaps we don't know how to do the conversion.) */
 
-tree
+static tree
 extract_constant_from_buffer (type, buffer, buf_size)
      tree type;
-     unsigned char *buffer;
+     const unsigned char *buffer;
      int buf_size;
 {
   tree value;
@@ -912,10 +897,12 @@ extract_constant_from_buffer (type, buffer, buf_size)
          return 0;
        value = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
        if (value)
-         if (TREE_CODE (value) != INTEGER_CST)
-           return 0;
-         else
-           min_index = TREE_INT_CST_LOW (value);
+         {
+           if (TREE_CODE (value) != INTEGER_CST)
+             return 0;
+           else
+             min_index = TREE_INT_CST_LOW (value);
+         }
        value = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
        if (value == NULL_TREE || TREE_CODE (value) != INTEGER_CST)
          return 0;
@@ -1217,7 +1204,7 @@ build_chill_cast (type, expr)
                 build1 (NOP_EXPR, build_pointer_type (type),
                         build1 (ADDR_EXPR, build_pointer_type (expr_type),
                                 expr)));
-  TREE_READONLY (expr) == TYPE_READONLY (type);
+  TREE_READONLY (expr) = TYPE_READONLY (type);
   return expr;
 }
 \f
@@ -1292,7 +1279,7 @@ tree
 chill_expand_tuple (type, constructor)
      tree type, constructor;
 {
-  char *name;
+  const char *name;
   tree nonreft = type;
 
   if (TYPE_NAME (type) != NULL_TREE)
@@ -1845,12 +1832,14 @@ chill_compatible (expr, mode)
     mode = TREE_TYPE (mode);
 
   if (TREE_TYPE (expr) == NULL_TREE)
-    if (TREE_CODE (expr) == CONSTRUCTOR)
-      return TREE_CODE (mode) == RECORD_TYPE
-       || ((TREE_CODE (mode) == SET_TYPE || TREE_CODE (mode) == ARRAY_TYPE)
-           && ! TYPE_STRING_FLAG (mode));
-    else
-      return TREE_CODE (expr) == CASE_EXPR || TREE_CODE (expr) == COND_EXPR;
+    {
+      if (TREE_CODE (expr) == CONSTRUCTOR)
+       return TREE_CODE (mode) == RECORD_TYPE
+         || ((TREE_CODE (mode) == SET_TYPE || TREE_CODE (mode) == ARRAY_TYPE)
+             && ! TYPE_STRING_FLAG (mode));
+      else
+       return TREE_CODE (expr) == CASE_EXPR || TREE_CODE (expr) == COND_EXPR;
+    }
 
   class = chill_expr_class (expr);
   switch (class.kind)
@@ -2044,7 +2033,10 @@ chill_resulting_class (class1, class2)
          class.mode
            = CH_ROOT_MODE (CH_RESULTING_MODE (class1.mode, class2.mode));
          return class;
+       default:
+         break;
        }
+      break;
     case CH_DERIVED_CLASS:
       switch (class2.kind)
        {
@@ -2060,7 +2052,10 @@ chill_resulting_class (class1, class2)
          class.kind = CH_DERIVED_CLASS;
          class.mode = CH_ROOT_MODE (class1.mode);
          return class;
+       default:
+         break;
        }
+      break;
     case CH_ALL_CLASS:
       switch (class2.kind)
        {
@@ -2076,7 +2071,12 @@ chill_resulting_class (class1, class2)
          class.kind = CH_DERIVED_CLASS;
          class.mode = CH_ROOT_MODE (class2.mode);
          return class;
+       default:
+         break;
        }
+      break;
+    default:
+      break;
     }
   error ("internal error in chill_root_resulting_mode");
   class.kind = CH_VALUE_CLASS;
@@ -2399,7 +2399,7 @@ build_chill_modify_expr (lhs, rhs)
 /* Construct, lay out and return the type of pointers to TO_TYPE.
    If such a type has already been constructed, reuse it.  */
 
-tree
+static tree
 make_chill_pointer_type (to_type, code)
      tree to_type;
      enum tree_code code;  /* POINTER_TYPE or REFERENCE_TYPE */
@@ -2486,7 +2486,7 @@ build_chill_reference_type (to_type)
   return t;
 }
 \f
-tree
+static tree
 make_chill_range_type (type, lowval, highval)
      tree type, lowval, highval;
 {
@@ -2594,7 +2594,7 @@ layout_chill_range_type (rangetype, must_be_const)
                  /* Compute number of bits to represent magnitude of a
                     negative value.  Add one to MINVALUE since range of
                     negative numbers includes the power of two.  */
-                 unsigned negprecision = floor_log2 (-minvalue - 1) + 1;
+                 int negprecision = floor_log2 (-minvalue - 1) + 1;
                  if (negprecision > precision)
                    precision = negprecision;
                  precision += 1;       /* room for sign bit */
@@ -2733,7 +2733,7 @@ apply_chill_array_layout (array_type)
      tree array_type;
 {
   tree layout, temp, what, element_type;
-  int stepsize, word, start_bit, offset, length, natural_length;
+  int stepsize=0, word, start_bit=0, length, natural_length;
   int stepsize_specified;
   int start_bit_error = 0;
   int length_error = 0;
@@ -2782,8 +2782,7 @@ apply_chill_array_layout (array_type)
            stepsize_specified = 1;
 
          if (stepsize != natural_length)
-           sorry ("Stepsize in STEP must be the natural width of "
-                  "the array element mode");
+           sorry ("Stepsize in STEP must be the natural width of the array element mode");
        }
     }
 
@@ -2876,8 +2875,7 @@ apply_chill_array_layout (array_type)
            }
          if (! length_error && length != natural_length)
            {
-             sorry ("The length specified on POS within STEP must be "
-                    "the natural length of the array element type");
+             sorry ("The length specified on POS within STEP must be the natural length of the array element type");
            }
        }
     }
@@ -2986,7 +2984,7 @@ field_decl_cmp (x, y)
   return (long)DECL_NAME (*x) - (long)DECL_NAME (*y);
 }
 
-tree
+static tree
 make_chill_struct_type (fieldlist)
      tree fieldlist;
 {
@@ -3042,7 +3040,7 @@ apply_chill_field_layout (decl, next_struct_offset)
      int* next_struct_offset;
 {
   tree layout, type, temp, what;
-  int word, wordsize, start_bit, offset, length, natural_length;
+  int word = 0, wordsize, start_bit, offset, length, natural_length;
   int pos_error = 0;
   int is_discrete;
 
@@ -3175,8 +3173,7 @@ apply_chill_field_layout (decl, next_struct_offset)
            }
          if (length != natural_length && ! pos_error)
            {
-             sorry ("The length specified on POS must be the natural length "
-                    "of the field type");
+             sorry ("The length specified on POS must be the natural length of the field type");
              length = natural_length;
            }
        }
@@ -3240,7 +3237,7 @@ layout_chill_struct_type (t)
        }
       else
        {
-         int min_align = TYPE_ALIGN (TREE_TYPE (x));
+         unsigned int min_align = TYPE_ALIGN (TREE_TYPE (x));
          DECL_ALIGN (x) = MAX (DECL_ALIGN (x), min_align);
          was_pos = 0;
        }
@@ -3294,7 +3291,8 @@ layout_chill_struct_type (t)
        for (x = fieldlist; x; x = TREE_CHAIN (x))
          field_array[len++] = x;
 
-       qsort (field_array, len, sizeof (tree), field_decl_cmp);
+       qsort (field_array, len, sizeof (tree),
+              (int (*) PARAMS ((const void *, const void *))) field_decl_cmp);
       }
   }
 
@@ -3343,7 +3341,7 @@ smash_dummy_type (type)
 {
   /* Save fields that we don't want to copy from ORIGIN. */ 
   tree origin = TREE_TYPE (type);
-  tree main = TYPE_MAIN_VARIANT (origin);
+  tree main_tree = TYPE_MAIN_VARIANT (origin);
   int  save_uid = TYPE_UID (type);
   struct obstack *save_obstack = TYPE_OBSTACK (type);
   tree save_name = TYPE_NAME (type);
@@ -3351,7 +3349,6 @@ smash_dummy_type (type)
   int  save_readonly = TYPE_READONLY (type);
   tree  save_novelty = CH_NOVELTY (type);
   tree save_domain = TYPE_DOMAIN (type);
-  struct lang_type *save_lang_specific = TYPE_LANG_SPECIFIC (type);
 
   if (origin == NULL_TREE)
     abort ();
@@ -3437,8 +3434,8 @@ smash_dummy_type (type)
   if (save_readonly)
     { /* TYPE is READ ORIGIN.
         Add this type to the chain of variants of TYPE.  */
-      TYPE_NEXT_VARIANT (type) = TYPE_NEXT_VARIANT (main);
-      TYPE_NEXT_VARIANT (main) = type;
+      TYPE_NEXT_VARIANT (type) = TYPE_NEXT_VARIANT (main_tree);
+      TYPE_NEXT_VARIANT (main_tree) = type;
       TYPE_READONLY (type) = save_readonly;
     }
   else
@@ -3669,137 +3666,6 @@ mark_addressable (exp)
     }
 }
 \f
-/* Return nonzero if VALUE is a valid constant-valued expression
-   for use in initializing a static variable; one that can be an
-   element of a "constant" initializer.
-
-   Return null_pointer_node if the value is absolute;
-   if it is relocatable, return the variable that determines the relocation.
-   We assume that VALUE has been folded as much as possible;
-   therefore, we do not need to check for such things as
-   arithmetic-combinations of integers.  */
-
-tree
-initializer_constant_valid_p (value, endtype)
-     tree value;
-     tree endtype;
-{
-  switch (TREE_CODE (value))
-    {
-    case CONSTRUCTOR:
-      if (TREE_CODE (TREE_TYPE (value)) == UNION_TYPE
-         && TREE_CONSTANT (value))
-       return
-         initializer_constant_valid_p (TREE_VALUE (CONSTRUCTOR_ELTS (value)),
-                                       endtype);
-       
-      return TREE_STATIC (value) ? null_pointer_node : 0;
-
-    case INTEGER_CST:
-    case REAL_CST:
-    case STRING_CST:
-    case COMPLEX_CST:
-      return null_pointer_node;
-
-    case ADDR_EXPR:
-      return TREE_OPERAND (value, 0);
-
-    case NON_LVALUE_EXPR:
-      return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
-
-    case CONVERT_EXPR:
-    case NOP_EXPR:
-      /* Allow conversions between pointer types.  */
-      if (TREE_CODE (TREE_TYPE (value)) == POINTER_TYPE
-         && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == POINTER_TYPE)
-       return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
-
-      /* Allow conversions between real types.  */
-      if (TREE_CODE (TREE_TYPE (value)) == REAL_TYPE
-         && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == REAL_TYPE)
-       return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
-
-      /* Allow length-preserving conversions between integer types.  */
-      if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
-         && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE
-         && (TYPE_PRECISION (TREE_TYPE (value))
-             == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))))
-       return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
-
-      /* Allow conversions between other integer types only if
-        explicit value.  */
-      if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
-         && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE)
-       {
-         tree inner = initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                                    endtype);
-         if (inner == null_pointer_node)
-           return null_pointer_node;
-         return 0;
-       }
-
-      /* Allow (int) &foo provided int is as wide as a pointer.  */
-      if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
-         && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == POINTER_TYPE
-         && (TYPE_PRECISION (TREE_TYPE (value))
-             >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))))
-       return initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                            endtype);
-
-      /* Likewise conversions from int to pointers.  */
-      if (TREE_CODE (TREE_TYPE (value)) == POINTER_TYPE
-         && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE
-         && (TYPE_PRECISION (TREE_TYPE (value))
-             <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))))
-       return initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                            endtype);
-
-      /* Allow conversions to union types if the value inside is okay.  */
-      if (TREE_CODE (TREE_TYPE (value)) == UNION_TYPE)
-       return initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                            endtype);
-      return 0;
-
-    case PLUS_EXPR:
-      if (TREE_CODE (endtype) == INTEGER_TYPE
-         && TYPE_PRECISION (endtype) < POINTER_SIZE)
-       return 0;
-      {
-       tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                                   endtype);
-       tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1),
-                                                   endtype);
-       /* If either term is absolute, use the other terms relocation.  */
-       if (valid0 == null_pointer_node)
-         return valid1;
-       if (valid1 == null_pointer_node)
-         return valid0;
-       return 0;
-      }
-
-    case MINUS_EXPR:
-      if (TREE_CODE (endtype) == INTEGER_TYPE
-         && TYPE_PRECISION (endtype) < POINTER_SIZE)
-       return 0;
-      {
-       tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                                   endtype);
-       tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1),
-                                                   endtype);
-       /* Win if second argument is absolute.  */
-       if (valid1 == null_pointer_node)
-         return valid0;
-       /* Win if both arguments have the same relocation.
-          Then the value is absolute.  */
-       if (valid0 == valid1)
-         return null_pointer_node;
-       return 0;
-      }
-    }
-
-  return 0;
-}
-\f
 /* Return an integer type with BITS bits of precision,
    that is unsigned if UNSIGNEDP is nonzero, otherwise signed.  */
 
@@ -3836,8 +3702,10 @@ type_for_size (bits, unsignedp)
   if (bits <= TYPE_PRECISION (intDI_type_node))
     return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
 
+#if HOST_BITS_PER_WIDE_INT >= 64
   if (bits <= TYPE_PRECISION (intTI_type_node))
     return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
+#endif
 
   return 0;
 }
@@ -3851,49 +3719,51 @@ type_for_mode (mode, unsignedp)
      enum machine_mode mode;
      int unsignedp;
 {
-  if (mode == TYPE_MODE (integer_type_node))
+  if ((int)mode == (int)TYPE_MODE (integer_type_node))
     return unsignedp ? unsigned_type_node : integer_type_node;
 
-  if (mode == TYPE_MODE (signed_char_type_node))
+  if ((int)mode == (int)TYPE_MODE (signed_char_type_node))
     return unsignedp ? unsigned_char_type_node : signed_char_type_node;
 
-  if (mode == TYPE_MODE (short_integer_type_node))
+  if ((int)mode == (int)TYPE_MODE (short_integer_type_node))
     return unsignedp ? short_unsigned_type_node : short_integer_type_node;
 
-  if (mode == TYPE_MODE (long_integer_type_node))
+  if ((int)mode == (int)TYPE_MODE (long_integer_type_node))
     return unsignedp ? long_unsigned_type_node : long_integer_type_node;
 
-  if (mode == TYPE_MODE (long_long_integer_type_node))
+  if ((int)mode == (int)TYPE_MODE (long_long_integer_type_node))
     return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
 
-  if (mode == TYPE_MODE (intQI_type_node))
+  if ((int)mode == (int)TYPE_MODE (intQI_type_node))
     return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
 
-  if (mode == TYPE_MODE (intHI_type_node))
+  if ((int)mode == (int)TYPE_MODE (intHI_type_node))
     return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
 
-  if (mode == TYPE_MODE (intSI_type_node))
+  if ((int)mode == (int)TYPE_MODE (intSI_type_node))
     return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
 
-  if (mode == TYPE_MODE (intDI_type_node))
+  if ((int)mode == (int)TYPE_MODE (intDI_type_node))
     return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
 
-  if (mode == TYPE_MODE (intTI_type_node))
+#if HOST_BITS_PER_WIDE_INT >= 64
+  if ((int)mode == (int)TYPE_MODE (intTI_type_node))
     return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
+#endif
 
-  if (mode == TYPE_MODE (float_type_node))
+  if ((int)mode == (int)TYPE_MODE (float_type_node))
     return float_type_node;
 
-  if (mode == TYPE_MODE (double_type_node))
+  if ((int)mode == (int)TYPE_MODE (double_type_node))
     return double_type_node;
 
-  if (mode == TYPE_MODE (long_double_type_node))
+  if ((int)mode == (int)TYPE_MODE (long_double_type_node))
     return long_double_type_node;
 
-  if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
+  if ((int)mode == (int)TYPE_MODE (build_pointer_type (char_type_node)))
     return build_pointer_type (char_type_node);
 
-  if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
+  if ((int)mode == (int)TYPE_MODE (build_pointer_type (integer_type_node)))
     return build_pointer_type (integer_type_node);
 
   return 0;