/* 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.
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.
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.
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;
{
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)
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))
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;
{
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;
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;
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;
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
chill_expand_tuple (type, constructor)
tree type, constructor;
{
- char *name;
+ const char *name;
tree nonreft = type;
if (TYPE_NAME (type) != NULL_TREE)
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)
class.mode
= CH_ROOT_MODE (CH_RESULTING_MODE (class1.mode, class2.mode));
return class;
+ default:
+ break;
}
+ break;
case CH_DERIVED_CLASS:
switch (class2.kind)
{
class.kind = CH_DERIVED_CLASS;
class.mode = CH_ROOT_MODE (class1.mode);
return class;
+ default:
+ break;
}
+ break;
case CH_ALL_CLASS:
switch (class2.kind)
{
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;
/* 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 */
return t;
}
\f
-tree
+static tree
make_chill_range_type (type, lowval, highval)
tree type, lowval, highval;
{
/* 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 */
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;
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");
}
}
}
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");
}
}
}
return (long)DECL_NAME (*x) - (long)DECL_NAME (*y);
}
-tree
+static tree
make_chill_struct_type (fieldlist)
tree fieldlist;
{
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;
}
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;
}
}
}
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;
}
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);
}
}
{
/* 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);
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 ();
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
}
}
\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. */
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;
}
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;