/* Convert language-specific tree expression to rtl instructions,
for GNU CHILL compiler.
- Copyright (C) 1992, 93, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1993, 1994, 1998, 1999, 2000, 2001
+ 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. */
#include "config.h"
extern char **boolean_code_name;
extern int flag_old_strings;
-extern tree long_unsigned_type_node;
extern int ignore_case;
extern int special_UC;
#define HOURS_MAX 1193
#define DAYS_MAX 49
-/* forward declaration */
-rtx chill_expand_expr PROTO((tree, rtx, enum machine_mode,
- enum expand_modifier));
+/* forward declarations */
+static rtx chill_expand_expr PARAMS ((tree, rtx, enum machine_mode,
+ enum expand_modifier));
+static tree chill_expand_case_expr PARAMS ((tree));
+static int check_arglist_length PARAMS ((tree, int, int, tree));
+static tree internal_build_compound_expr PARAMS ((tree, int));
+static int is_really_instance PARAMS ((tree));
+static int invalid_operand PARAMS ((enum chill_tree_code,
+ tree, int));
+static int invalid_right_operand PARAMS ((enum chill_tree_code, tree));
+static tree build_chill_abstime PARAMS ((tree));
+static tree build_allocate_memory_call PARAMS ((tree, tree));
+static tree build_allocate_global_memory_call PARAMS ((tree, tree));
+static tree build_return_memory PARAMS ((tree));
+static tree build_chill_duration PARAMS ((tree, unsigned long,
+ tree, unsigned long));
+static tree build_chill_floatcall PARAMS ((tree, const char *,
+ const char *));
+static tree build_allocate_getstack PARAMS ((tree, tree, const char *,
+ const char *, tree, tree));
+static tree build_chill_allocate PARAMS ((tree, tree));
+static tree build_chill_getstack PARAMS ((tree, tree));
+static tree build_chill_terminate PARAMS ((tree));
+static tree build_chill_inttime PARAMS ((tree, tree));
+static tree build_chill_lower_or_upper PARAMS ((tree, int));
+static tree build_max_min PARAMS ((tree, int));
+static tree build_chill_pred_or_succ PARAMS ((tree, enum tree_code));
+static tree expand_packed_set PARAMS ((const char *, int, tree));
+static tree fold_set_expr PARAMS ((enum chill_tree_code,
+ tree, tree));
+static tree build_compare_set_expr PARAMS ((enum tree_code, tree, tree));
+static tree scalar_to_string PARAMS ((tree));
+static tree build_concat_expr PARAMS ((tree, tree));
+static tree build_compare_string_expr PARAMS ((enum tree_code, tree, tree));
+static tree compare_records PARAMS ((tree, tree));
+static tree string_char_rep PARAMS ((int, tree));
+static tree build_boring_bitstring PARAMS ((long, int));
/* variable to hold the type the DESCR built-in returns */
static tree descr_type = NULL_TREE;
tree
check_have_mode (exp, context)
tree exp;
- char *context;
+ const char *context;
{
if (TREE_CODE (exp) != ERROR_MARK && TREE_TYPE (exp) == NULL_TREE)
{
return nreverse(return_list);
}
-tree
+static tree
chill_expand_case_expr (expr)
tree expr;
{
chill_handle_case_label (TREE_VALUE (label), selector);
labels = TREE_CHAIN (labels);
if (labels != NULL_TREE)
- error ("The number of CASE selectors does not match the number "
- "of CASE label lists");
+ error ("The number of CASE selectors does not match the number of CASE label lists");
}
}
\f
/* Hook used by expand_expr to expand CHILL-specific tree codes. */
-rtx
+static rtx
chill_expand_expr (exp, target, tmode, modifier)
tree exp;
rtx target;
rtx original_target = target;
rtx op0, op1;
int ignore = target == const0_rtx;
- char *lib_func; /* name of library routine */
+ const char *lib_func; /* name of library routine */
if (ignore)
target = 0, original_target = 0;
{
tree exp0 = TREE_OPERAND (exp, 0);
tree exp1 = TREE_OPERAND (exp, 1);
- rtx size0, size1;
+ rtx size0 = NULL_RTX, size1 = NULL_RTX;
rtx targetx;
if (TREE_CODE (exp1) == UNDEFINED_EXPR)
if (temp == target || target == NULL_RTX)
return temp;
emit_block_move (target, temp, expr_size (exp0),
- TYPE_ALIGN (TREE_TYPE(exp0)) / BITS_PER_UNIT);
+ TYPE_ALIGN (TREE_TYPE(exp0)));
return target;
}
else
{
tree type0 = TREE_TYPE (exp0);
tree type1 = TREE_TYPE (exp1);
- int len0 = int_size_in_bytes (type0);
- int len1 = int_size_in_bytes (type1);
+ HOST_WIDE_INT len0 = int_size_in_bytes (type0);
+ HOST_WIDE_INT len1 = int_size_in_bytes (type1);
if (len0 < 0 && TYPE_ARRAY_MAX_SIZE (type0)
- && TREE_CODE (TYPE_ARRAY_MAX_SIZE (type0)) == INTEGER_CST)
- len0 = TREE_INT_CST_LOW (TYPE_ARRAY_MAX_SIZE (type0));
+ && host_integerp (TYPE_ARRAY_MAX_SIZE (type0), 1))
+ len0 = tree_low_cst (TYPE_ARRAY_MAX_SIZE (type0), 1);
if (len1 < 0 && TYPE_ARRAY_MAX_SIZE (type1)
- && TREE_CODE (TYPE_ARRAY_MAX_SIZE (type1)) == INTEGER_CST)
- len1 = TREE_INT_CST_LOW (TYPE_ARRAY_MAX_SIZE (type1));
+ && host_integerp (TYPE_ARRAY_MAX_SIZE (type1), 1))
+ len1 = tree_low_cst (TYPE_ARRAY_MAX_SIZE (type1), 1);
if (len0 < 0 || len1 < 0)
- fatal ("internal error - don't know how much space is needed for concatenation");
+ abort ();
+
target = assign_stack_temp (mode, len0 + len1, 0);
preserve_temp_slots (target);
}
{
int length = list_length (args);
if (length < min_length)
- error ("Too few arguments in call to `%s'", IDENTIFIER_POINTER (name));
+ error ("too few arguments in call to `%s'", IDENTIFIER_POINTER (name));
else if (max_length != -1 && length > max_length)
- error ("Too many arguments in call to `%s'", IDENTIFIER_POINTER (name));
+ error ("too many arguments in call to `%s'", IDENTIFIER_POINTER (name));
else
return length;
return -1;
/* check for ptr is really a POINTER */
if (TREE_CODE (type) != POINTER_TYPE)
{
- error ("cannot dereference, not a pointer.");
+ error ("cannot dereference, not a pointer");
return error_mark_node;
}
if (decl == NULL_TREE || TREE_CODE (decl) != TYPE_DECL)
{
if (pass == 2)
- error ("missing '.' operator or undefined mode name `%s'.",
+ error ("missing '.' operator or undefined mode name `%s'",
IDENTIFIER_POINTER (mode));
#if 0
- error ("You have forgotten the '.' operator which must");
+ error ("you have forgotten the '.' operator which must");
error (" precede a STRUCT field reference, or `%s' is an undefined mode",
IDENTIFIER_POINTER (mode));
#endif
}
else if (type == ptr_type_node)
{
- error ("Can't dereference PTR value using unary `->'.");
+ error ("can't dereference PTR value using unary `->'");
return error_mark_node;
}
}
}
- error ("No field named `%s'", IDENTIFIER_POINTER (field_name));
+ error ("no field named `%s'", IDENTIFIER_POINTER (field_name));
return error_mark_node;
}
return temp;
}
-tree
+static tree
build_chill_abstime (exprlist)
tree exprlist;
{
had_errors = 1;
else if (TREE_CODE (TREE_TYPE (exp)) != INTEGER_TYPE)
{
- error ("argument %d to ABSTIME must be of integer type.", i);
+ error ("argument %d to ABSTIME must be of integer type", i);
had_errors = 1;
}
tmp = TREE_CHAIN (tmp);
}
-tree
+static tree
build_allocate_memory_call (ptr, size)
tree ptr, size;
{
/* check for ptr is referable */
if (! CH_REFERABLE (ptr))
{
- error ("parameter 1 must be referable.");
+ error ("parameter 1 must be referable");
err++;
}
/* check for pointer */
else if (TREE_CODE (TREE_TYPE (ptr)) != POINTER_TYPE)
{
- error ("mode mismatch in parameter 1.");
+ error ("mode mismatch in parameter 1");
err++;
}
/* check for size > 0 if it is a constant */
if (TREE_CODE (size) == INTEGER_CST && TREE_INT_CST_LOW (size) <= 0)
{
- error ("parameter 2 must be a positive integer.");
+ error ("parameter 2 must be a positive integer");
err++;
}
if (err)
}
-tree
+static tree
build_allocate_global_memory_call (ptr, size)
tree ptr, size;
{
/* check for ptr is referable */
if (! CH_REFERABLE (ptr))
{
- error ("parameter 1 must be referable.");
+ error ("parameter 1 must be referable");
err++;
}
/* check for pointer */
else if (TREE_CODE (TREE_TYPE (ptr)) != POINTER_TYPE)
{
- error ("mode mismatch in parameter 1.");
+ error ("mode mismatch in parameter 1");
err++;
}
/* check for size > 0 if it is a constant */
if (TREE_CODE (size) == INTEGER_CST && TREE_INT_CST_LOW (size) <= 0)
{
- error ("parameter 2 must be a positive integer.");
+ error ("parameter 2 must be a positive integer");
err++;
}
if (err)
}
-tree
+static tree
build_return_memory (ptr)
tree ptr;
{
/* check for pointer */
if (TREE_CODE (TREE_TYPE (ptr)) != POINTER_TYPE)
{
- error ("mode mismatch in parameter 1.");
+ error ("mode mismatch in parameter 1");
return error_mark_node;
}
/* check for expression is referable */
if (! CH_REFERABLE (expr))
{
- error ("expression for DESCR-builtin must be referable.");
+ error ("expression for DESCR-built-in must be referable");
return error_mark_node;
}
MILLISECS, SECS, MINUTES, HOURS and DAYS.
The built duration value is in milliseconds. */
-tree
+static tree
build_chill_duration (expr, multiplier, fnname, maxvalue)
tree expr;
unsigned long multiplier;
if (TREE_CODE (TREE_TYPE (expr)) != INTEGER_TYPE)
{
- error ("argument to `%s' must be of integer type.", IDENTIFIER_POINTER (fnname));
+ error ("argument to `%s' must be of integer type", IDENTIFIER_POINTER (fnname));
return error_mark_node;
}
static tree
build_chill_floatcall (expr, chillname, funcname)
tree expr;
- char *chillname;
- char *funcname;
+ const char *chillname;
+ const char *funcname;
{
tree result;
tree type;
build_allocate_getstack (mode, value, chill_name, fnname, filename, linenumber)
tree mode;
tree value;
- char *chill_name;
- char *fnname;
+ const char *chill_name;
+ const char *fnname;
tree filename;
tree linenumber;
{
/* check if we have a mode */
if (TREE_CODE_CLASS (TREE_CODE (type)) != 't')
{
- error ("First argument to `%s' must be a mode", chill_name);
+ error ("first argument to `%s' must be a mode", chill_name);
return error_mark_node;
}
}
/* process the ALLOCATE built-in */
-tree
+static tree
build_chill_allocate (mode, value)
tree mode;
tree value;
}
/* process the GETSTACK built-in */
-tree
+static tree
build_chill_getstack (mode, value)
tree mode;
tree value;
}
/* process the TERMINATE built-in */
-tree
+static tree
build_chill_terminate (ptr)
tree ptr;
{
satisfy_decl (decl, 0);
}
-tree
+static tree
build_chill_inttime (t, loclist)
tree t, loclist;
{
/* check first argument to be NEWMODE TIME */
if (TREE_TYPE (t) != abs_timing_type_node)
{
- error ("argument 1 to INTTIME must be of mode TIME.");
+ error ("argument 1 to INTTIME must be of mode TIME");
had_errors = 1;
}
}
/* FIXME: what's about ranges can't hold the result ?? */
if (write_error)
- error ("%s.", errmsg);
+ error ("%s", errmsg);
}
/* next location */
tmp = TREE_CHAIN (tmp);
else
{
tree parmlist, filename, lineno;
- char *funcname;
+ const char *funcname;
/* set up to call appropriate runtime function */
if (max_min)
need_unsigned);
if (temp == NULL_TREE)
{
- error ("No integer mode which matches expression's mode");
+ error ("no integer mode which matches expression's mode");
return integer_zero_node;
}
temp = convert (temp, expr);
if (TREE_CODE (TREE_TYPE (expr)) == ENUMERAL_TYPE
&& CH_ENUM_IS_NUMBERED (TREE_TYPE (expr)))
{
- error ("Cannot take SUCC or PRED of a numbered SET");
+ error ("cannot take SUCC or PRED of a numbered SET");
return error_mark_node;
}
{
if (TREE_TYPE (TREE_TYPE (expr)) == void_type_node)
{
- error ("SUCC or PRED must not be done on a PTR.");
+ error ("SUCC or PRED must not be done on a PTR");
return error_mark_node;
}
- pedwarn ("SUCC or PRED for a reference type is not standard.");
+ pedwarn ("SUCC or PRED for a reference type is not standard");
return fold (build (op, TREE_TYPE (expr),
expr,
size_in_bytes (TREE_TYPE (TREE_TYPE (expr)))));
if (TREE_CODE (cond) == INTEGER_CST
&& tree_int_cst_equal (cond, integer_one_node))
{
- error ("Taking the %s of a value already at its %s value",
+ error ("taking the %s of a value already at its %s value",
op == PLUS_EXPR ? "SUCC" : "PRED",
op == PLUS_EXPR ? "maximum" : "minimum");
return error_mark_node;
return error_mark_node;
}
- temp = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
- size_int (TYPE_PRECISION (char_type_node)));
+ temp = size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
+ size_int (TYPE_PRECISION (char_type_node)
+ / BITS_PER_UNIT));
if (signame != NULL_TREE)
{
/* we have a signal definition. This signal may have no
if (valtail != 0 && TREE_VALUE (valtail) != void_type_node)
{
- char *errstr = "too many arguments to procedure";
if (name)
- error ("%s `%s'", errstr, IDENTIFIER_POINTER (name));
+ error ("too many arguments to procedure `%s'",
+ IDENTIFIER_POINTER (name));
else
- error (errstr);
+ error ("too many arguments to procedure");
return error_mark_node;
}
else if (typetail != 0 && TREE_VALUE (typetail) != void_type_node)
{
- char *errstr = "too few arguments to procedure";
if (name)
- error ("%s `%s'", errstr, IDENTIFIER_POINTER (name));
+ error ("too few arguments to procedure `%s'",
+ IDENTIFIER_POINTER (name));
else
- error (errstr);
+ error ("too few arguments to procedure");
return error_mark_node;
}
case BUILT_IN_EXPIRED:
case BUILT_IN_WAIT:
- sorry ("unimplemented builtin function `%s'",
+ sorry ("unimplemented built-in function `%s'",
IDENTIFIER_POINTER (fnname));
break;
default:
- error ("internal error - bad builtin function `%s'",
+ error ("internal error - bad built-in function `%s'",
IDENTIFIER_POINTER (fnname));
}
}
\f
/* Given a set stored as one bit per char (in BUFFER[0 .. BIT_SIZE-1]),
return a CONTRUCTOR, of type TYPE (a SET_TYPE). */
-tree
+static tree
expand_packed_set (buffer, bit_size, type)
- char *buffer;
+ const char *buffer;
int bit_size;
tree type;
{
tree op0, op1;
{
tree temp;
- char *buffer0, *buffer1, *bufferr;
+ char *buffer0, *buffer1 = NULL, *bufferr;
int i, size0, size1, first_unused_bit;
if (! TREE_CONSTANT (op0) || TREE_CODE (op0) != CONSTRUCTOR)
tree op0, op1;
{
tree result_type = NULL_TREE;
- char *fnname;
+ const char *fnname;
tree x;
/* These conversions are needed if -fold-strings. */
if (TREE_CODE (type0) == SET_TYPE)
{
- result_size = size_binop (PLUS_EXPR,
- discrete_count (TYPE_DOMAIN (type0)),
- discrete_count (TYPE_DOMAIN (type1)));
+ result_size = fold (build (PLUS_EXPR, integer_type_node,
+ discrete_count (TYPE_DOMAIN (type0)),
+ discrete_count (TYPE_DOMAIN (type1))));
result_class.mode = build_bitstring_type (result_size);
}
else
case NE_EXPR:
return invert_truthvalue (build_compare_string_expr (EQ_EXPR, op0, op1));
default:
- error ("Invalid operation on array of chars");
+ error ("invalid operation on array of chars");
return error_mark_node;
}
return build (code, boolean_type_node, op0, op1);
}
-tree
+static tree
compare_records (exp0, exp1)
tree exp0, exp1;
{
int have_variants = 0;
tree result = boolean_true_node;
- extern int maximum_field_alignment;
if (TREE_CODE (type) != RECORD_TYPE)
abort ();
op1 = convert (build_pointer_type (TREE_TYPE (op1)), op1);
if ((op0f || op1f)
&& code != EQ_EXPR && code != NE_EXPR)
- error ("Cannot use %s operator on PROC mode variable",
+ error ("cannot use %s operator on PROC mode variable",
tree_code_name[(int)code]);
}
tree
build_chill_addr_expr (ref, errormsg)
tree ref;
- char *errormsg;
+ const char *errormsg;
{
if (ref == error_mark_node)
return ref;
/*
* process a string repetition phrase '(' COUNT ')' STRING
*/
-tree
+static tree
string_char_rep (count, string)
int count;
tree string;
int slen, charindx, repcnt;
char ch;
char *temp;
- char *inp;
+ const char *inp;
char *outp;
tree type;
/* Build a bit-string constant containing with the given LENGTH
containing all ones (if VALUE is true), or all zeros (if VALUE is false). */
-tree
+static tree
build_boring_bitstring (length, value)
long length;
int value;
for (temp = vallist; temp; temp = TREE_CHAIN (temp))
{
tree new_value
- = fold (size_binop (PLUS_EXPR, origin, TREE_VALUE (temp)));
+ = fold (build (PLUS_EXPR, TREE_TYPE (origin),
+ TREE_VALUE (temp)));
tree new_purpose = NULL_TREE;
+
if (! TREE_CONSTANT (TREE_VALUE (temp)))
tree_const = 0;
if (TREE_PURPOSE (temp))
{
- new_purpose = fold (size_binop (PLUS_EXPR,
- origin,
- TREE_PURPOSE (temp)));
+ new_purpose = fold (build (PLUS_EXPR, TREE_TYPE (origin),
+ origin, TREE_PURPOSE (temp)));
if (! TREE_CONSTANT (TREE_PURPOSE (temp)))
tree_const = 0;
}