/* Language-independent node constructors for parse phase of GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
This file is part of GCC.
tree_contains_struct[FIELD_DECL][TS_DECL_MINIMAL] = 1;
tree_contains_struct[STRUCT_FIELD_TAG][TS_DECL_MINIMAL] = 1;
tree_contains_struct[NAME_MEMORY_TAG][TS_DECL_MINIMAL] = 1;
- tree_contains_struct[TYPE_MEMORY_TAG][TS_DECL_MINIMAL] = 1;
+ tree_contains_struct[SYMBOL_MEMORY_TAG][TS_DECL_MINIMAL] = 1;
tree_contains_struct[STRUCT_FIELD_TAG][TS_MEMORY_TAG] = 1;
tree_contains_struct[NAME_MEMORY_TAG][TS_MEMORY_TAG] = 1;
- tree_contains_struct[TYPE_MEMORY_TAG][TS_MEMORY_TAG] = 1;
+ tree_contains_struct[SYMBOL_MEMORY_TAG][TS_MEMORY_TAG] = 1;
+
+ tree_contains_struct[STRUCT_FIELD_TAG][TS_STRUCT_FIELD_TAG] = 1;
tree_contains_struct[VAR_DECL][TS_DECL_WITH_VIS] = 1;
tree_contains_struct[FUNCTION_DECL][TS_DECL_WITH_VIS] = 1;
case FUNCTION_DECL:
return sizeof (struct tree_function_decl);
case NAME_MEMORY_TAG:
- case TYPE_MEMORY_TAG:
- case STRUCT_FIELD_TAG:
+ case SYMBOL_MEMORY_TAG:
return sizeof (struct tree_memory_tag);
+ case STRUCT_FIELD_TAG:
+ return sizeof (struct tree_struct_field_tag);
default:
return sizeof (struct tree_decl_non_common);
}
break;
case INTEGER_TYPE:
- case CHAR_TYPE:
case OFFSET_TYPE:
if (TYPE_UNSIGNED (type))
{
{
VEC(constructor_elt,gc) *v;
constructor_elt *elt;
+ tree t;
v = VEC_alloc (constructor_elt, gc, 1);
elt = VEC_quick_push (constructor_elt, v, NULL);
elt->index = index;
elt->value = value;
- return build_constructor (type, v);
+ t = build_constructor (type, v);
+ TREE_CONSTANT (t) = TREE_CONSTANT (value);
+ return t;
}
tree
build_constructor_from_list (tree type, tree vals)
{
- tree t;
+ tree t, val;
VEC(constructor_elt,gc) *v = NULL;
+ bool constant_p = true;
if (vals)
{
for (t = vals; t; t = TREE_CHAIN (t))
{
constructor_elt *elt = VEC_quick_push (constructor_elt, v, NULL);
+ val = TREE_VALUE (t);
elt->index = TREE_PURPOSE (t);
- elt->value = TREE_VALUE (t);
+ elt->value = val;
+ if (!TREE_CONSTANT (val))
+ constant_p = false;
}
}
- return build_constructor (type, v);
+ t = build_constructor (type, v);
+ TREE_CONSTANT (t) = constant_p;
+ return t;
}
STRIP_NOPS (expr);
return ((TREE_CODE (expr) == INTEGER_CST
- && ! TREE_CONSTANT_OVERFLOW (expr)
&& TREE_INT_CST_LOW (expr) == 0
&& TREE_INT_CST_HIGH (expr) == 0)
|| (TREE_CODE (expr) == COMPLEX_CST
STRIP_NOPS (expr);
return ((TREE_CODE (expr) == INTEGER_CST
- && ! TREE_CONSTANT_OVERFLOW (expr)
&& TREE_INT_CST_LOW (expr) == 1
&& TREE_INT_CST_HIGH (expr) == 0)
|| (TREE_CODE (expr) == COMPLEX_CST
&& integer_zerop (TREE_IMAGPART (expr)))
return 1;
- else if (TREE_CODE (expr) != INTEGER_CST
- || TREE_CONSTANT_OVERFLOW (expr))
+ else if (TREE_CODE (expr) != INTEGER_CST)
return 0;
uns = TYPE_UNSIGNED (TREE_TYPE (expr));
&& integer_zerop (TREE_IMAGPART (expr)))
return 1;
- if (TREE_CODE (expr) != INTEGER_CST || TREE_CONSTANT_OVERFLOW (expr))
+ if (TREE_CODE (expr) != INTEGER_CST)
return 0;
prec = (POINTER_TYPE_P (TREE_TYPE (expr))
STRIP_NOPS (expr);
return ((TREE_CODE (expr) == INTEGER_CST
- && ! TREE_CONSTANT_OVERFLOW (expr)
&& (TREE_INT_CST_LOW (expr) != 0
|| TREE_INT_CST_HIGH (expr) != 0))
|| (TREE_CODE (expr) == COMPLEX_CST
STRIP_NOPS (expr);
return ((TREE_CODE (expr) == REAL_CST
- && ! TREE_CONSTANT_OVERFLOW (expr)
&& REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst0))
|| (TREE_CODE (expr) == COMPLEX_CST
&& real_zerop (TREE_REALPART (expr))
STRIP_NOPS (expr);
return ((TREE_CODE (expr) == REAL_CST
- && ! TREE_CONSTANT_OVERFLOW (expr)
&& REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst1))
|| (TREE_CODE (expr) == COMPLEX_CST
&& real_onep (TREE_REALPART (expr))
STRIP_NOPS (expr);
return ((TREE_CODE (expr) == REAL_CST
- && ! TREE_CONSTANT_OVERFLOW (expr)
&& REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst2))
|| (TREE_CODE (expr) == COMPLEX_CST
&& real_twop (TREE_REALPART (expr))
STRIP_NOPS (expr);
return ((TREE_CODE (expr) == REAL_CST
- && ! TREE_CONSTANT_OVERFLOW (expr)
&& REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconstm1))
|| (TREE_CODE (expr) == COMPLEX_CST
&& real_minus_onep (TREE_REALPART (expr))
t = TYPE_SIZE_UNIT (type);
if (t == 0
|| TREE_CODE (t) != INTEGER_CST
- || TREE_OVERFLOW (t)
|| TREE_INT_CST_HIGH (t) != 0
/* If the result would appear negative, it's too big to represent. */
|| (HOST_WIDE_INT) TREE_INT_CST_LOW (t) < 0)
return TREE_INT_CST_LOW (t);
}
+
+/* Return the maximum size of TYPE (in bytes) as a wide integer
+ or return -1 if the size can vary or is larger than an integer. */
+
+HOST_WIDE_INT
+max_int_size_in_bytes (tree type)
+{
+ HOST_WIDE_INT size = -1;
+ tree size_tree;
+
+ /* If this is an array type, check for a possible MAX_SIZE attached. */
+
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ size_tree = TYPE_ARRAY_MAX_SIZE (type);
+
+ if (size_tree && host_integerp (size_tree, 1))
+ size = tree_low_cst (size_tree, 1);
+ }
+
+ /* If we still haven't been able to get a size, see if the language
+ can compute a maximum size. */
+
+ if (size == -1)
+ {
+ size_tree = lang_hooks.types.max_size (type);
+
+ if (size_tree && host_integerp (size_tree, 1))
+ size = tree_low_cst (size_tree, 1);
+ }
+
+ return size;
+}
\f
/* Return the bit position of FIELD, in bits from the start of the record.
This is a tree of type bitsizetype. */
return TS_TYPE_DECL;
case FUNCTION_DECL:
return TS_FUNCTION_DECL;
- case TYPE_MEMORY_TAG:
+ case SYMBOL_MEMORY_TAG:
case NAME_MEMORY_TAG:
case STRUCT_FIELD_TAG:
return TS_MEMORY_TAG;
case COMPLEX_TYPE:
case ENUMERAL_TYPE:
case BOOLEAN_TYPE:
- case CHAR_TYPE:
case POINTER_TYPE:
case OFFSET_TYPE:
case REFERENCE_TYPE:
#if 1 /* ! defined(USE_MAPPED_LOCATION) */
/* ??? gengtype doesn't handle conditionals */
-static GTY(()) location_t *last_annotated_node;
+static GTY(()) source_locus last_annotated_node;
#endif
#ifdef USE_MAPPED_LOCATION
case INTEGER_TYPE:
case REAL_TYPE:
case BOOLEAN_TYPE:
- case CHAR_TYPE:
return ((TYPE_MAX_VALUE (a->type) == TYPE_MAX_VALUE (b->type)
|| tree_int_cst_equal (TYPE_MAX_VALUE (a->type),
TYPE_MAX_VALUE (b->type)))
host_integerp (tree t, int pos)
{
return (TREE_CODE (t) == INTEGER_CST
- && ! TREE_OVERFLOW (t)
&& ((TREE_INT_CST_HIGH (t) == 0
&& (HOST_WIDE_INT) TREE_INT_CST_LOW (t) >= 0)
|| (! pos && TREE_INT_CST_HIGH (t) == -1
}
/* Create a range of some discrete type TYPE (an INTEGER_TYPE,
- ENUMERAL_TYPE, BOOLEAN_TYPE, or CHAR_TYPE), with
- low bound LOWVAL and high bound HIGHVAL.
- if TYPE==NULL_TREE, sizetype is used. */
+ ENUMERAL_TYPE or BOOLEAN_TYPE), with low bound LOWVAL and
+ high bound HIGHVAL. If TYPE is NULL, sizetype is used. */
tree
build_range_type (tree type, tree lowval, tree highval)
if (type == NULL_TREE)
type = sizetype;
- TYPE_MIN_VALUE (itype) = convert (type, lowval);
- TYPE_MAX_VALUE (itype) = highval ? convert (type, highval) : NULL;
+ TYPE_MIN_VALUE (itype) = fold_convert (type, lowval);
+ TYPE_MAX_VALUE (itype) = highval ? fold_convert (type, highval) : NULL;
TYPE_PRECISION (itype) = TYPE_PRECISION (type);
TYPE_MODE (itype) = TYPE_MODE (type);
}
/* Returns true if T is, contains, or refers to a type with variable
- size. If FN is nonzero, only return true if a modifier of the type
- or position of FN is a variable or parameter inside FN.
+ size. For METHOD_TYPEs and FUNCTION_TYPEs we exclude the
+ arguments, but not the return type. If FN is nonzero, only return
+ true if a modifier of the type or position of FN is a variable or
+ parameter inside FN.
This concept is more general than that of C99 'variably modified types':
in C99, a struct type is never variably modified because a VLA may not
if (type == error_mark_node)
return false;
- /* If TYPE itself has variable size, it is variably modified.
-
- We do not yet have a representation of the C99 '[*]' syntax.
- When a representation is chosen, this function should be modified
- to test for that case as well. */
+ /* If TYPE itself has variable size, it is variably modified. */
RETURN_TRUE_IF_VAR (TYPE_SIZE (type));
- RETURN_TRUE_IF_VAR (TYPE_SIZE_UNIT(type));
+ RETURN_TRUE_IF_VAR (TYPE_SIZE_UNIT (type));
switch (TREE_CODE (type))
{
case POINTER_TYPE:
case REFERENCE_TYPE:
- case ARRAY_TYPE:
case VECTOR_TYPE:
if (variably_modified_type_p (TREE_TYPE (type), fn))
return true;
case FUNCTION_TYPE:
case METHOD_TYPE:
- /* If TYPE is a function type, it is variably modified if any of the
- parameters or the return type are variably modified. */
+ /* If TYPE is a function type, it is variably modified if the
+ return type is variably modified. */
if (variably_modified_type_p (TREE_TYPE (type), fn))
return true;
-
- for (t = TYPE_ARG_TYPES (type);
- t && t != void_list_node;
- t = TREE_CHAIN (t))
- if (variably_modified_type_p (TREE_VALUE (t), fn))
- return true;
break;
case INTEGER_TYPE:
case REAL_TYPE:
case ENUMERAL_TYPE:
case BOOLEAN_TYPE:
- case CHAR_TYPE:
/* Scalar types are variably modified if their end points
aren't constant. */
RETURN_TRUE_IF_VAR (TYPE_MIN_VALUE (type));
case RECORD_TYPE:
case UNION_TYPE:
case QUAL_UNION_TYPE:
- /* We can't see if any of the field are variably-modified by the
+ /* We can't see if any of the fields are variably-modified by the
definition we normally use, since that would produce infinite
recursion via pointers. */
/* This is variably modified if some field's type is. */
}
break;
+ case ARRAY_TYPE:
+ /* Do not call ourselves to avoid infinite recursion. This is
+ variably modified if the element type is. */
+ RETURN_TRUE_IF_VAR (TYPE_SIZE (TREE_TYPE (type)));
+ RETURN_TRUE_IF_VAR (TYPE_SIZE_UNIT (TREE_TYPE (type)));
+ break;
+
default:
break;
}
{
tree addr;
+ if (call == error_mark_node)
+ return call;
+
/* It's invalid to call this function with anything but a
CALL_EXPR. */
gcc_assert (TREE_CODE (call) == CALL_EXPR);
/* Define both `signed char' and `unsigned char'. */
signed_char_type_node = make_signed_type (CHAR_TYPE_SIZE);
+ TYPE_STRING_FLAG (signed_char_type_node) = 1;
unsigned_char_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
+ TYPE_STRING_FLAG (unsigned_char_type_node) = 1;
/* Define `char', which is like either `signed char' or `unsigned char'
but not the same as either. */
= (signed_char
? make_signed_type (CHAR_TYPE_SIZE)
: make_unsigned_type (CHAR_TYPE_SIZE));
+ TYPE_STRING_FLAG (char_type_node) = 1;
short_integer_type_node = make_signed_type (SHORT_TYPE_SIZE);
short_unsigned_type_node = make_unsigned_type (SHORT_TYPE_SIZE);
}
}
-void
-add_var_to_bind_expr (tree bind_expr, tree var)
-{
- BIND_EXPR_VARS (bind_expr)
- = chainon (BIND_EXPR_VARS (bind_expr), var);
- if (BIND_EXPR_BLOCK (bind_expr))
- BLOCK_VARS (BIND_EXPR_BLOCK (bind_expr))
- = BIND_EXPR_VARS (bind_expr);
-}
-
/* Build an empty statement. */
tree
unsigned_type_for (tree type)
{
if (POINTER_TYPE_P (type))
- return size_type_node;
+ return lang_hooks.types.unsigned_type (size_type_node);
return lang_hooks.types.unsigned_type (type);
}
tree
signed_type_for (tree type)
{
+ if (POINTER_TYPE_P (type))
+ return lang_hooks.types.signed_type (size_type_node);
return lang_hooks.types.signed_type (type);
}
case BOOLEAN_TYPE:
case ENUMERAL_TYPE:
case INTEGER_TYPE:
- case CHAR_TYPE:
case REAL_TYPE:
WALK_SUBTREE (TYPE_MIN_VALUE (type));
WALK_SUBTREE (TYPE_MAX_VALUE (type));