/* Language-independent node constructors for parse phase of GNU compiler.
- Copyright (C) 1987, 88, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 92-96, 1997 Free Software Foundation, Inc.
This file is part of GNU CC.
#include "config.h"
#include "flags.h"
#include "tree.h"
+#include "except.h"
#include "function.h"
#include "obstack.h"
#ifdef __STDC__
obstack_name = "temp_decl_obstack";
}
- /* Check to see if the object is in the free area of the obstack. */
+ /* Check to see if the object is in the free area of the obstack. */
if (obstack != NULL)
{
if (object >= obstack->next_free
for REAL_CST, since the number of words is machine-dependent due
to varying size and alignment of `double'. */
if (code == INTEGER_CST)
- {
- length = sizeof (struct tree_int_cst);
- break;
- }
+ length = sizeof (struct tree_int_cst);
else if (code == REAL_CST)
- {
- length = sizeof (struct tree_real_cst);
- break;
- }
+ length = sizeof (struct tree_real_cst);
+ else
+ length = (sizeof (struct tree_common)
+ + tree_code_length[(int) code] * sizeof (char *));
+ break;
case 'x': /* something random, like an identifier. */
length = sizeof (struct tree_common)
((char *) t)[i] = ((char *) node)[i];
TREE_CHAIN (t) = 0;
+ TREE_ASM_WRITTEN (t) = 0;
if (TREE_CODE_CLASS (code) == 'd')
DECL_UID (t) = next_decl_uid++;
the copy is different from the original type.
The two statements usually duplicate each other
(because they clear fields of the same union),
- but the optimizer should catch that. */
+ but the optimizer should catch that. */
TYPE_SYMTAB_POINTER (t) = 0;
TYPE_SYMTAB_ADDRESS (t) = 0;
}
hash_len = id_clash_len;
/* Compute hash code */
- hi = hash_len * 613 + (unsigned)text[0];
+ hi = hash_len * 613 + (unsigned) text[0];
for (i = 1; i < hash_len; i += 2)
- hi = ((hi * 613) + (unsigned)(text[i]));
+ hi = ((hi * 613) + (unsigned) (text[i]));
hi &= (1 << HASHBITS) - 1;
hi %= MAX_HASH_TABLE;
return idp; /* <-- return if created */
}
+/* If an identifier with the name TEXT (a null-terminated string) has
+ previously been referred to, return that node; otherwise return
+ NULL_TREE. */
+
+tree
+maybe_get_identifier (text)
+ register char *text;
+{
+ register int hi;
+ register int i;
+ register tree idp;
+ register int len, hash_len;
+
+ /* Compute length of text in len. */
+ for (len = 0; text[len]; len++);
+
+ /* Decide how much of that length to hash on */
+ hash_len = len;
+ if (warn_id_clash && len > id_clash_len)
+ hash_len = id_clash_len;
+
+ /* Compute hash code */
+ hi = hash_len * 613 + (unsigned) text[0];
+ for (i = 1; i < hash_len; i += 2)
+ hi = ((hi * 613) + (unsigned) (text[i]));
+
+ hi &= (1 << HASHBITS) - 1;
+ hi %= MAX_HASH_TABLE;
+
+ /* Search table for identifier */
+ for (idp = hash_table[hi]; idp; idp = TREE_CHAIN (idp))
+ if (IDENTIFIER_LENGTH (idp) == len
+ && IDENTIFIER_POINTER (idp)[0] == text[0]
+ && !bcmp (IDENTIFIER_POINTER (idp), text, len))
+ return idp; /* <-- return if found */
+
+ return NULL_TREE;
+}
+
/* Enable warnings on similar identifiers (if requested).
Done after the built-in identifiers are created. */
/* Return a newly constructed COMPLEX_CST node whose value is
specified by the real and imaginary parts REAL and IMAG.
- Both REAL and IMAG should be constant nodes.
- The TREE_TYPE is not initialized. */
+ Both REAL and IMAG should be constant nodes. TYPE, if specified,
+ will be the type of the COMPLEX_CST; otherwise a new type will be made. */
tree
-build_complex (real, imag)
+build_complex (type, real, imag)
+ tree type;
tree real, imag;
{
register tree t = make_node (COMPLEX_CST);
TREE_REALPART (t) = real;
TREE_IMAGPART (t) = imag;
- TREE_TYPE (t) = build_complex_type (TREE_TYPE (real));
+ TREE_TYPE (t) = type ? type : build_complex_type (TREE_TYPE (real));
TREE_OVERFLOW (t) = TREE_OVERFLOW (real) | TREE_OVERFLOW (imag);
TREE_CONSTANT_OVERFLOW (t)
= TREE_CONSTANT_OVERFLOW (real) | TREE_CONSTANT_OVERFLOW (imag);
}
/* Build a newly constructed TREE_VEC node of length LEN. */
+
tree
make_tree_vec (len)
int len;
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)
+ else if (TREE_CODE (expr) != INTEGER_CST
+ || TREE_CONSTANT_OVERFLOW (expr))
return 0;
uns = TREE_UNSIGNED (TREE_TYPE (expr));
integer_pow2p (expr)
tree expr;
{
+ int prec;
HOST_WIDE_INT high, low;
STRIP_NOPS (expr);
&& integer_zerop (TREE_IMAGPART (expr)))
return 1;
- if (TREE_CODE (expr) != INTEGER_CST)
+ if (TREE_CODE (expr) != INTEGER_CST || TREE_CONSTANT_OVERFLOW (expr))
return 0;
+ prec = (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE
+ ? POINTER_SIZE : TYPE_PRECISION (TREE_TYPE (expr)));
high = TREE_INT_CST_HIGH (expr);
low = TREE_INT_CST_LOW (expr);
+ /* First clear all bits that are beyond the type's precision in case
+ we've been sign extended. */
+
+ if (prec == 2 * HOST_BITS_PER_WIDE_INT)
+ ;
+ else if (prec > HOST_BITS_PER_WIDE_INT)
+ high &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
+ else
+ {
+ high = 0;
+ if (prec < HOST_BITS_PER_WIDE_INT)
+ low &= ~((HOST_WIDE_INT) (-1) << prec);
+ }
+
if (high == 0 && low == 0)
return 0;
|| (low == 0 && (high & (high - 1)) == 0));
}
+/* Return the power of two represented by a tree node known to be a
+ power of two. */
+
+int
+tree_log2 (expr)
+ tree expr;
+{
+ int prec;
+ HOST_WIDE_INT high, low;
+
+ STRIP_NOPS (expr);
+
+ if (TREE_CODE (expr) == COMPLEX_CST)
+ return tree_log2 (TREE_REALPART (expr));
+
+ prec = (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE
+ ? POINTER_SIZE : TYPE_PRECISION (TREE_TYPE (expr)));
+
+ high = TREE_INT_CST_HIGH (expr);
+ low = TREE_INT_CST_LOW (expr);
+
+ /* First clear all bits that are beyond the type's precision in case
+ we've been sign extended. */
+
+ if (prec == 2 * HOST_BITS_PER_WIDE_INT)
+ ;
+ else if (prec > HOST_BITS_PER_WIDE_INT)
+ high &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
+ else
+ {
+ high = 0;
+ if (prec < HOST_BITS_PER_WIDE_INT)
+ low &= ~((HOST_WIDE_INT) (-1) << prec);
+ }
+
+ return (high != 0 ? HOST_BITS_PER_WIDE_INT + exact_log2 (high)
+ : exact_log2 (low));
+}
+
/* Return 1 if EXPR is the real constant zero. */
int
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))
return NULL_TREE;
}
-/* Return nonzero if ELEM is part of the chain CHAIN. */
+/* Return nonzero if ELEM is part of the chain CHAIN. */
int
chain_member (elem, chain)
}
/* Return nonzero if ELEM is equal to TREE_VALUE (CHAIN) for any piece of
- chain CHAIN. */
+ chain CHAIN. */
/* ??? This function was added for machine specific attributes but is no
longer used. It could be deleted if we could confirm all front ends
don't use it. */
}
/* Return nonzero if ELEM is equal to TREE_PURPOSE (CHAIN)
- for any piece of chain CHAIN. */
+ for any piece of chain CHAIN. */
/* ??? This function was added for machine specific attributes but is no
longer used. It could be deleted if we could confirm all front ends
don't use it. */
case STRING_CST:
return 1;
+ /* If we are referencing a bitfield, we can't evaluate an
+ ADDR_EXPR at compile time and so it isn't a constant. */
case COMPONENT_REF:
+ return (! DECL_BIT_FIELD (TREE_OPERAND (arg, 1))
+ && staticp (TREE_OPERAND (arg, 0)));
+
case BIT_FIELD_REF:
- return staticp (TREE_OPERAND (arg, 0));
+ return 0;
#if 0
/* This case is technically correct, but results in setting
fact (i.e. this allows further folding, and direct checks for constants).
However, a read-only object that has side effects cannot be bypassed.
Since it is no problem to reevaluate literals, we just return the
- literal node. */
+ literal node. */
if (TREE_CONSTANT (t) || (TREE_READONLY (t) && ! TREE_SIDE_EFFECTS (t))
|| TREE_CODE (t) == SAVE_EXPR || TREE_CODE (t) == ERROR_MARK)
/* Arrange for an expression to be expanded multiple independent
times. This is useful for cleanup actions, as the backend can
expand them multiple times in different places. */
+
tree
unsave_expr (expr)
tree expr;
/* Modify a tree in place so that all the evaluate only once things
are cleared out. Return the EXPR given. */
+
tree
unsave_expr_now (expr)
tree expr;
switch (code)
{
case SAVE_EXPR:
- SAVE_EXPR_RTL (expr) = NULL_RTX;
+ SAVE_EXPR_RTL (expr) = 0;
break;
case TARGET_EXPR:
case RTL_EXPR:
/* I don't yet know how to emit a sequence multiple times. */
- if (RTL_EXPR_SEQUENCE (expr) != NULL_RTX)
+ if (RTL_EXPR_SEQUENCE (expr) != 0)
abort ();
break;
case CALL_EXPR:
- CALL_EXPR_RTL (expr) = NULL_RTX;
+ CALL_EXPR_RTL (expr) = 0;
if (TREE_OPERAND (expr, 1)
&& TREE_CODE (TREE_OPERAND (expr, 1)) == TREE_LIST)
{
in it since it is supplying a value for it. */
if (code == WITH_RECORD_EXPR)
return 0;
+ else if (code == PLACEHOLDER_EXPR)
+ return 1;
switch (TREE_CODE_CLASS (code))
{
new = fold (build1 (code, TREE_TYPE (exp), op0));
break;
-
- case OFFSET_REF:
- op0 = substitute_in_expr (TREE_OPERAND (exp, 0), f, r);
- op1 = substitute_in_expr (TREE_OPERAND (exp, 1), f, r);
- if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1))
- return exp;
-
- new = fold (build (code, TREE_TYPE (exp), op0, op1));
- break;
}
}
/* Same as above, but only builds for unary operators.
Saves lions share of calls to `build'; cuts down use
of varargs, which is expensive for RISC machines. */
+
tree
build1 (code, type, node)
enum tree_code code;
tree type;
tree node;
{
- register struct obstack *obstack = current_obstack;
+ register struct obstack *obstack = expression_obstack;
register int i, length;
register tree_node_kind kind;
register tree t;
kind = e_kind;
#endif
- obstack = expression_obstack;
length = sizeof (struct tree_exp);
t = (tree) obstack_alloc (obstack, length);
}
\f
/* Return a declaration like DDECL except that its DECL_MACHINE_ATTRIBUTE
- is ATTRIBUTE. */
+ is ATTRIBUTE. */
tree
build_decl_attribute_variant (ddecl, attribute)
/* Return a 1 if ATTR_NAME and ATTR_ARGS is valid for either declaration DECL
or type TYPE and 0 otherwise. Validity is determined the configuration
- macros VALID_MACHINE_DECL_ATTRIBUTE and VALID_MACHINE_TYPE_ATTRIBUTE. */
+ macros VALID_MACHINE_DECL_ATTRIBUTE and VALID_MACHINE_TYPE_ATTRIBUTE. */
int
valid_machine_attribute (attr_name, attr_args, decl, type)
like the one we need to have. If so, use that existing one. We must
preserve the TYPE_NAME, since there is code that depends on this. */
- for (t = TYPE_MAIN_VARIANT(type); t; t = TYPE_NEXT_VARIANT (t))
+ for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
if (constp == TYPE_READONLY (t) && volatilep == TYPE_VOLATILE (t)
&& TYPE_NAME (t) == TYPE_NAME (type))
return t;
/* 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. */
+ if TYPE==NULL_TREE, sizetype is used. */
tree
build_range_type (type, lowval, highval)
}
/* Just like build_index_type, but takes lowval and highval instead
- of just highval (maxval). */
+ of just highval (maxval). */
tree
build_index_2_type (lowval,highval)
if (TREE_CODE (op) == COMPONENT_REF
/* Since type_for_size always gives an integer type. */
- && TREE_CODE (type) != REAL_TYPE)
+ && TREE_CODE (type) != REAL_TYPE
+ /* Don't crash if field not layed out yet. */
+ && DECL_SIZE (TREE_OPERAND (op, 1)) != 0)
{
unsigned innerprec = TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (op, 1)));
type = type_for_size (innerprec, TREE_UNSIGNED (TREE_OPERAND (op, 1)));
while (context && TREE_CODE (context) != FUNCTION_DECL)
{
if (TREE_CODE (context) == RECORD_TYPE
- || TREE_CODE (context) == UNION_TYPE)
+ || TREE_CODE (context) == UNION_TYPE
+ || TREE_CODE (context) == QUAL_UNION_TYPE)
context = TYPE_CONTEXT (context);
else if (TREE_CODE (context) == TYPE_DECL)
context = DECL_CONTEXT (context);
extern char * first_global_object_name;
/* If KIND=='I', return a suitable global initializer (constructor) name.
- If KIND=='D', return a suitable global clean-up (destructor) name. */
+ If KIND=='D', return a suitable global clean-up (destructor) name. */
tree
get_file_function_name (kind)
#ifndef NO_DOLLAR_IN_LABEL /* this for `$'; unlikely, but... -- kr */
|| *p == '$'
#endif
-#ifndef NO_DOT_IN_LABEL /* this for `.'; unlikely, but... */
+#ifndef NO_DOT_IN_LABEL /* this for `.'; unlikely, but... */
|| *p == '.'
#endif
|| (*p >= 'A' && *p <= 'Z')
with one bit in each char ('\000' or '\001').
If the constructor is constant, NULL_TREE is returned.
- Otherwise, a TREE_LIST of the non-constant elements is emitted. */
+ Otherwise, a TREE_LIST of the non-constant elements is emitted. */
tree
get_set_constructor_bits (init, buffer, bit_size)
tree_cons (TREE_PURPOSE (vals), TREE_VALUE (vals), non_const_bits);
else if (TREE_PURPOSE (vals) != NULL_TREE)
{
- /* Set a range of bits to ones. */
+ /* Set a range of bits to ones. */
HOST_WIDE_INT lo_index
= TREE_INT_CST_LOW (TREE_PURPOSE (vals)) - domain_min;
HOST_WIDE_INT hi_index
}
else
{
- /* Set a single bit to one. */
+ /* Set a single bit to one. */
HOST_WIDE_INT index
= TREE_INT_CST_LOW (TREE_VALUE (vals)) - domain_min;
if (index < 0 || index >= bit_size)
/* Expand (the constant part of) a SET_TYPE CONSTRUCTOR node.
The result is placed in BUFFER (which is an array of bytes).
If the constructor is constant, NULL_TREE is returned.
- Otherwise, a TREE_LIST of the non-constant elements is emitted. */
+ Otherwise, a TREE_LIST of the non-constant elements is emitted. */
tree
get_set_constructor_bytes (init, buffer, wd_size)
int bit_size = wd_size * set_word_size;
int bit_pos = 0;
unsigned char *bytep = buffer;
- char *bit_buffer = (char*)alloca(bit_size);
+ char *bit_buffer = (char *) alloca(bit_size);
tree non_const_bits = get_set_constructor_bits (init, bit_buffer, bit_size);
for (i = 0; i < wd_size; i++)