6f48294de2
From-SVN: r24612
284 lines
8.2 KiB
C
284 lines
8.2 KiB
C
/* Copyright (C) 1992, 93, 1994, 1998 Free Software Foundation, Inc.
|
|
|
|
This file is part of GNU CC.
|
|
|
|
GNU CC is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2, or (at your option)
|
|
any later version.
|
|
|
|
GNU CC is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with GNU CC; see the file COPYING. If not, write to
|
|
the Free Software Foundation, 59 Temple Place - Suite 330,
|
|
Boston, MA 02111-1307, USA. */
|
|
|
|
|
|
#if 0
|
|
tree
|
|
build_component_ref (datum, field_name)
|
|
tree datum, field_name;
|
|
{
|
|
return build_chill_component_ref (datum, field_name);
|
|
}
|
|
|
|
/* Mark EXP saying that we need to be able to take the
|
|
address of it; it should not be allocated in a register.
|
|
Value is 1 if successful. */
|
|
|
|
int
|
|
mark_addressable (exp)
|
|
tree exp;
|
|
{
|
|
register tree x = exp;
|
|
while (1)
|
|
switch (TREE_CODE (x))
|
|
{
|
|
case ADDR_EXPR:
|
|
case COMPONENT_REF:
|
|
case ARRAY_REF:
|
|
case REALPART_EXPR:
|
|
case IMAGPART_EXPR:
|
|
/* start-sanitize-chill */
|
|
case TRUTH_ANDIF_EXPR:
|
|
case TRUTH_ORIF_EXPR:
|
|
case COMPOUND_EXPR:
|
|
/* end-sanitize-chill */
|
|
x = TREE_OPERAND (x, 0);
|
|
break;
|
|
/* start-sanitize-chill */
|
|
|
|
case COND_EXPR:
|
|
return mark_addressable (TREE_OPERAND (x, 1))
|
|
& mark_addressable (TREE_OPERAND (x, 2));
|
|
/* end-sanitize-chill */
|
|
|
|
case CONSTRUCTOR:
|
|
TREE_ADDRESSABLE (x) = 1;
|
|
return 1;
|
|
|
|
case VAR_DECL:
|
|
case CONST_DECL:
|
|
case PARM_DECL:
|
|
case RESULT_DECL:
|
|
if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
|
|
&& DECL_NONLOCAL (x))
|
|
{
|
|
if (TREE_PUBLIC (x))
|
|
{
|
|
error ("global register variable `%s' used in nested function",
|
|
IDENTIFIER_POINTER (DECL_NAME (x)));
|
|
return 0;
|
|
}
|
|
pedwarn ("register variable `%s' used in nested function",
|
|
IDENTIFIER_POINTER (DECL_NAME (x)));
|
|
}
|
|
else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
|
|
{
|
|
if (TREE_PUBLIC (x))
|
|
{
|
|
error ("address of global register variable `%s' requested",
|
|
IDENTIFIER_POINTER (DECL_NAME (x)));
|
|
return 0;
|
|
}
|
|
|
|
/* If we are making this addressable due to its having
|
|
volatile components, give a different error message. Also
|
|
handle the case of an unnamed parameter by not trying
|
|
to give the name. */
|
|
|
|
else if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (x)))
|
|
{
|
|
error ("cannot put object with volatile field into register");
|
|
return 0;
|
|
}
|
|
|
|
pedwarn ("address of register variable `%s' requested",
|
|
IDENTIFIER_POINTER (DECL_NAME (x)));
|
|
}
|
|
put_var_into_stack (x);
|
|
|
|
/* drops in */
|
|
case FUNCTION_DECL:
|
|
TREE_ADDRESSABLE (x) = 1;
|
|
#if 0 /* poplevel deals with this now. */
|
|
if (DECL_CONTEXT (x) == 0)
|
|
TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1;
|
|
#endif
|
|
|
|
default:
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
/* Return an unsigned type the same as TYPE in other respects. */
|
|
|
|
tree
|
|
unsigned_type (type)
|
|
tree type;
|
|
{
|
|
tree type1 = TYPE_MAIN_VARIANT (type);
|
|
if (type1 == signed_char_type_node || type1 == char_type_node)
|
|
return unsigned_char_type_node;
|
|
if (type1 == integer_type_node)
|
|
return unsigned_type_node;
|
|
if (type1 == short_integer_type_node)
|
|
return short_unsigned_type_node;
|
|
if (type1 == long_integer_type_node)
|
|
return long_unsigned_type_node;
|
|
if (type1 == long_long_integer_type_node)
|
|
return long_long_unsigned_type_node;
|
|
return type;
|
|
}
|
|
|
|
/* Return a signed type the same as TYPE in other respects. */
|
|
|
|
tree
|
|
signed_type (type)
|
|
tree type;
|
|
{
|
|
tree type1 = TYPE_MAIN_VARIANT (type);
|
|
if (type1 == unsigned_char_type_node || type1 == char_type_node)
|
|
return signed_char_type_node;
|
|
if (type1 == unsigned_type_node)
|
|
return integer_type_node;
|
|
if (type1 == short_unsigned_type_node)
|
|
return short_integer_type_node;
|
|
if (type1 == long_unsigned_type_node)
|
|
return long_integer_type_node;
|
|
if (type1 == long_long_unsigned_type_node)
|
|
return long_long_integer_type_node;
|
|
return type;
|
|
}
|
|
|
|
/* Return a type the same as TYPE except unsigned or
|
|
signed according to UNSIGNEDP. */
|
|
|
|
tree
|
|
signed_or_unsigned_type (unsignedp, type)
|
|
int unsignedp;
|
|
tree type;
|
|
{
|
|
if (! INTEGRAL_TYPE_P (type))
|
|
return type;
|
|
if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
|
|
return unsignedp ? unsigned_char_type_node : signed_char_type_node;
|
|
if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
|
|
return unsignedp ? unsigned_type_node : integer_type_node;
|
|
if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))
|
|
return unsignedp ? short_unsigned_type_node : short_integer_type_node;
|
|
if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))
|
|
return unsignedp ? long_unsigned_type_node : long_integer_type_node;
|
|
if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))
|
|
return (unsignedp ? long_long_unsigned_type_node
|
|
: long_long_integer_type_node);
|
|
return type;
|
|
}
|
|
|
|
extern tree intHI_type_node;
|
|
extern tree intSI_type_node;
|
|
extern tree intDI_type_node;
|
|
|
|
extern tree unsigned_intHI_type_node;
|
|
extern tree unsigned_intSI_type_node;
|
|
extern tree unsigned_intDI_type_node;
|
|
|
|
/* Return an integer type with BITS bits of precision,
|
|
that is unsigned if UNSIGNEDP is nonzero, otherwise signed. */
|
|
|
|
tree
|
|
type_for_size (bits, unsignedp)
|
|
unsigned bits;
|
|
int unsignedp;
|
|
{
|
|
if (bits == TYPE_PRECISION (signed_char_type_node))
|
|
return unsignedp ? unsigned_char_type_node : signed_char_type_node;
|
|
|
|
if (bits == TYPE_PRECISION (short_integer_type_node))
|
|
return unsignedp ? short_unsigned_type_node : short_integer_type_node;
|
|
|
|
if (bits == TYPE_PRECISION (integer_type_node))
|
|
return unsignedp ? unsigned_type_node : integer_type_node;
|
|
|
|
if (bits == TYPE_PRECISION (long_integer_type_node))
|
|
return unsignedp ? long_unsigned_type_node : long_integer_type_node;
|
|
|
|
if (bits == TYPE_PRECISION (long_long_integer_type_node))
|
|
return (unsignedp ? long_long_unsigned_type_node
|
|
: long_long_integer_type_node);
|
|
|
|
if (bits <= TYPE_PRECISION (intHI_type_node))
|
|
return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
|
|
|
|
if (bits <= TYPE_PRECISION (intSI_type_node))
|
|
return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
|
|
|
|
if (bits <= TYPE_PRECISION (intDI_type_node))
|
|
return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Return a data type that has machine mode MODE.
|
|
If the mode is an integer,
|
|
then UNSIGNEDP selects between signed and unsigned types. */
|
|
|
|
tree
|
|
type_for_mode (mode, unsignedp)
|
|
enum machine_mode mode;
|
|
int unsignedp;
|
|
{
|
|
if (mode == TYPE_MODE (signed_char_type_node))
|
|
return unsignedp ? unsigned_char_type_node : signed_char_type_node;
|
|
|
|
if (mode == TYPE_MODE (short_integer_type_node))
|
|
return unsignedp ? short_unsigned_type_node : short_integer_type_node;
|
|
|
|
if (mode == TYPE_MODE (integer_type_node))
|
|
return unsignedp ? unsigned_type_node : integer_type_node;
|
|
|
|
if (mode == 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))
|
|
return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
|
|
|
|
if (mode == TYPE_MODE (intHI_type_node))
|
|
return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
|
|
|
|
if (mode == TYPE_MODE (intSI_type_node))
|
|
return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
|
|
|
|
if (mode == TYPE_MODE (intDI_type_node))
|
|
return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
|
|
|
|
if (mode == TYPE_MODE (float_type_node))
|
|
return float_type_node;
|
|
|
|
if (mode == TYPE_MODE (double_type_node))
|
|
return double_type_node;
|
|
|
|
if (mode == TYPE_MODE (long_double_type_node))
|
|
return long_double_type_node;
|
|
|
|
if (mode == 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)))
|
|
return build_pointer_type (integer_type_node);
|
|
|
|
return 0;
|
|
}
|
|
|
|
tree
|
|
truthvalue_conversion (expr)
|
|
tree expr;
|
|
{
|
|
return chill_truthvalue_conversion (expr);
|
|
}
|
|
#endif
|