/* Language-independent node constructors for parse phase of GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000 Free Software Foundation, Inc.
+ 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of GNU CC.
#include "ggc.h"
#include "hashtab.h"
#include "output.h"
-#include "defaults.h"
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
static void print_type_hash_statistics PARAMS((void));
static int mark_hash_entry PARAMS((void **, void *));
static void finish_vector_type PARAMS((tree));
+static int mark_tree_hashtable_entry PARAMS((void **, void *));
/* If non-null, these are language-specific helper functions for
unsave_expr_now. If present, LANG_UNSAVE is called before its
void (*lang_unsave) PARAMS ((tree *));
void (*lang_unsave_expr_now) PARAMS ((tree));
+/* If non-null, these are language-specific helper functions for
+ unsafe_for_reeval. Return negative to not handle some tree. */
+int (*lang_unsafe_for_reeval) PARAMS ((tree));
\f
tree global_trees[TI_MAX];
tree integer_types[itk_none];
}
\f
/* Return a new node with the same contents as NODE except that its
- TREE_CHAIN is zero and it has a fresh uid. Unlike make_node, this
- function always performs the allocation on the CURRENT_OBSTACK;
- it's up to the caller to pick the right obstack before calling this
- function. */
+ TREE_CHAIN is zero and it has a fresh uid. */
tree
copy_node (node)
break;
default:
- /* ??? Add a lang hook if it becomes necessary. */
+ if (lang_unsafe_for_reeval != 0)
+ {
+ tmp = (*lang_unsafe_for_reeval) (expr);
+ if (tmp >= 0)
+ return tmp;
+ }
break;
}
register int length;
register int i;
int fro;
+ int constant;
VA_START (p, tt);
to do this. */
fro = first_rtl_op (code);
+ /* Expressions without side effects may be constant if their
+ arguments are as well. */
+ constant = (TREE_CODE_CLASS (code) == '<'
+ || TREE_CODE_CLASS (code) == '1'
+ || TREE_CODE_CLASS (code) == '2'
+ || TREE_CODE_CLASS (code) == 'c');
+
if (length == 2)
{
/* This is equivalent to the loop below, but faster. */
TREE_SIDE_EFFECTS (t) = 1;
if (!TREE_READONLY (arg0))
TREE_READONLY (t) = 0;
+ if (!TREE_CONSTANT (arg0))
+ constant = 0;
}
if (arg1 && fro > 1)
TREE_SIDE_EFFECTS (t) = 1;
if (!TREE_READONLY (arg1))
TREE_READONLY (t) = 0;
+ if (!TREE_CONSTANT (arg1))
+ constant = 0;
}
}
else if (length == 1)
{
if (TREE_SIDE_EFFECTS (operand))
TREE_SIDE_EFFECTS (t) = 1;
+ if (!TREE_CONSTANT (operand))
+ constant = 0;
}
}
}
va_end (p);
+
+ TREE_CONSTANT (t) = constant;
return t;
}
kind = e_kind;
#endif
+#ifdef ENABLE_CHECKING
+ if (TREE_CODE_CLASS (code) == '2'
+ || TREE_CODE_CLASS (code) == '<'
+ || TREE_CODE_LENGTH (code) != 1)
+ abort ();
+#endif /* ENABLE_CHECKING */
+
length = sizeof (struct tree_exp);
t = ggc_alloc_tree (length);
break;
default:
+ if (TREE_CODE_CLASS (code) == '1' && node && TREE_CONSTANT (node))
+ TREE_CONSTANT (t) = 1;
break;
}
return t;
}
-/* Similar to `build_nt', except we build
- on the temp_decl_obstack, regardless. */
-
-tree
-build_parse_node VPARAMS ((enum tree_code code, ...))
-{
-#ifndef ANSI_PROTOTYPES
- enum tree_code code;
-#endif
- va_list p;
- register tree t;
- register int length;
- register int i;
-
- VA_START (p, code);
-
-#ifndef ANSI_PROTOTYPES
- code = va_arg (p, enum tree_code);
-#endif
-
- t = make_node (code);
- length = TREE_CODE_LENGTH (code);
-
- for (i = 0; i < length; i++)
- TREE_OPERAND (t, i) = va_arg (p, tree);
-
- va_end (p);
- return t;
-}
-
#if 0
/* Commented out because this wants to be done very
differently. See cp-lex.c. */
htab_traverse (t, mark_hash_entry, 0);
}
+/* Mark the hashtable slot pointed to by ENTRY (which is really a
+ `tree**') for GC. */
+
+static int
+mark_tree_hashtable_entry (entry, data)
+ void **entry;
+ void *data ATTRIBUTE_UNUSED;
+{
+ ggc_mark_tree ((tree) *entry);
+ return 1;
+}
+
+/* Mark ARG (which is really a htab_t whose slots are trees) for
+ GC. */
+
+void
+mark_tree_hashtable (arg)
+ void *arg;
+{
+ htab_t t = *(htab_t *) arg;
+ htab_traverse (t, mark_tree_hashtable_entry, 0);
+}
+
static void
print_type_hash_statistics ()
{
{
/* If the bounds of the type are integers, we can check ourselves.
Otherwise,. use force_fit_type, which checks against the precision. */
- if (TREE_CODE (TYPE_MAX_VALUE (type)) == INTEGER_CST
+ if (TYPE_MAX_VALUE (type) != NULL_TREE
+ && TYPE_MIN_VALUE (type) != NULL_TREE
+ && TREE_CODE (TYPE_MAX_VALUE (type)) == INTEGER_CST
&& TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST)
{
if (TREE_UNSIGNED (type))
int i;
tree vals;
HOST_WIDE_INT domain_min
- = TREE_INT_CST_LOW (TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (init))));
+ = tree_low_cst (TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (init))), 0);
tree non_const_bits = NULL_TREE;
+
for (i = 0; i < bit_size; i++)
buffer[i] = 0;
for (vals = TREE_OPERAND (init, 1);
vals != NULL_TREE; vals = TREE_CHAIN (vals))
{
- if (TREE_CODE (TREE_VALUE (vals)) != INTEGER_CST
+ if (!host_integerp (TREE_VALUE (vals), 0)
|| (TREE_PURPOSE (vals) != NULL_TREE
- && TREE_CODE (TREE_PURPOSE (vals)) != INTEGER_CST))
+ && !host_integerp (TREE_PURPOSE (vals), 0)))
non_const_bits
= 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. */
HOST_WIDE_INT lo_index
- = TREE_INT_CST_LOW (TREE_PURPOSE (vals)) - domain_min;
+ = tree_low_cst (TREE_PURPOSE (vals), 0) - domain_min;
HOST_WIDE_INT hi_index
- = TREE_INT_CST_LOW (TREE_VALUE (vals)) - domain_min;
+ = tree_low_cst (TREE_VALUE (vals), 0) - domain_min;
if (lo_index < 0 || lo_index >= bit_size
|| hi_index < 0 || hi_index >= bit_size)
{
/* Set a single bit to one. */
HOST_WIDE_INT index
- = TREE_INT_CST_LOW (TREE_VALUE (vals)) - domain_min;
+ = tree_low_cst (TREE_VALUE (vals), 0) - domain_min;
if (index < 0 || index >= bit_size)
{
error ("invalid initializer for bit string");
/* Define these next since types below may used them. */
integer_zero_node = build_int_2 (0, 0);
integer_one_node = build_int_2 (1, 0);
+ integer_minus_one_node = build_int_2 (-1, -1);
size_zero_node = size_int (0);
size_one_node = size_int (1);
TREE_TYPE (complex_long_double_type_node) = long_double_type_node;
layout_type (complex_long_double_type_node);
-#ifdef BUILD_VA_LIST_TYPE
- BUILD_VA_LIST_TYPE (va_list_type_node);
-#else
- va_list_type_node = build_type_copy (ptr_type_node);
-#endif
+ {
+ tree t;
+ BUILD_VA_LIST_TYPE (t);
+ va_list_type_node = build_type_copy (t);
+ }
V4SF_type_node = make_node (VECTOR_TYPE);
TREE_TYPE (V4SF_type_node) = float_type_node;