summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/cc/cc_int/tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/cc/cc_int/tree.c')
-rw-r--r--gnu/usr.bin/cc/cc_int/tree.c178
1 files changed, 146 insertions, 32 deletions
diff --git a/gnu/usr.bin/cc/cc_int/tree.c b/gnu/usr.bin/cc/cc_int/tree.c
index e0aa0ae..1787d0c 100644
--- a/gnu/usr.bin/cc/cc_int/tree.c
+++ b/gnu/usr.bin/cc/cc_int/tree.c
@@ -319,8 +319,9 @@ gcc_obstack_init (obstack)
This is used before starting a nested function. */
void
-save_tree_status (p)
+save_tree_status (p, toplevel)
struct function *p;
+ int toplevel;
{
p->all_types_permanent = all_types_permanent;
p->momentary_stack = momentary_stack;
@@ -334,10 +335,15 @@ save_tree_status (p)
p->saveable_obstack = saveable_obstack;
p->rtl_obstack = rtl_obstack;
- /* Objects that need to be saved in this function can be in the nonsaved
- obstack of the enclosing function since they can't possibly be needed
- once it has returned. */
- function_maybepermanent_obstack = function_obstack;
+ if (! toplevel)
+ {
+ /* Objects that need to be saved in this function can be in the nonsaved
+ obstack of the enclosing function since they can't possibly be needed
+ once it has returned. */
+ function_maybepermanent_obstack = function_obstack;
+ maybepermanent_firstobj
+ = (char *) obstack_finish (function_maybepermanent_obstack);
+ }
function_obstack = (struct obstack *) xmalloc (sizeof (struct obstack));
gcc_obstack_init (function_obstack);
@@ -348,30 +354,32 @@ save_tree_status (p)
momentary_firstobj = (char *) obstack_finish (&momentary_obstack);
momentary_function_firstobj = momentary_firstobj;
- maybepermanent_firstobj
- = (char *) obstack_finish (function_maybepermanent_obstack);
}
/* Restore all variables describing the current status from the structure *P.
This is used after a nested function. */
void
-restore_tree_status (p)
+restore_tree_status (p, toplevel)
struct function *p;
+ int toplevel;
{
all_types_permanent = p->all_types_permanent;
momentary_stack = p->momentary_stack;
obstack_free (&momentary_obstack, momentary_function_firstobj);
- /* Free saveable storage used by the function just compiled and not
- saved.
-
- CAUTION: This is in function_obstack of the containing function. So
- we must be sure that we never allocate from that obstack during
- the compilation of a nested function if we expect it to survive past the
- nested function's end. */
- obstack_free (function_maybepermanent_obstack, maybepermanent_firstobj);
+ if (! toplevel)
+ {
+ /* Free saveable storage used by the function just compiled and not
+ saved.
+
+ CAUTION: This is in function_obstack of the containing function.
+ So we must be sure that we never allocate from that obstack during
+ the compilation of a nested function if we expect it to survive
+ past the nested function's end. */
+ obstack_free (function_maybepermanent_obstack, maybepermanent_firstobj);
+ }
obstack_free (function_obstack, 0);
free (function_obstack);
@@ -519,7 +527,10 @@ permanent_allocation (function_end)
/* Free up previous temporary obstack data */
obstack_free (&temporary_obstack, temporary_firstobj);
if (function_end)
- obstack_free (&momentary_obstack, momentary_function_firstobj);
+ {
+ obstack_free (&momentary_obstack, momentary_function_firstobj);
+ momentary_firstobj = momentary_function_firstobj;
+ }
else
obstack_free (&momentary_obstack, momentary_firstobj);
obstack_free (&maybepermanent_obstack, maybepermanent_firstobj);
@@ -2353,6 +2364,13 @@ stabilize_reference (ref)
stabilize_reference_1 (TREE_OPERAND (ref, 1)));
break;
+ case COMPOUND_EXPR:
+ result = build_nt (COMPOUND_EXPR,
+ stabilize_reference_1 (TREE_OPERAND (ref, 0)),
+ stabilize_reference (TREE_OPERAND (ref, 1)));
+ break;
+
+
/* If arg isn't a kind of lvalue we recognize, make no change.
Caller should recognize the error for an invalid lvalue. */
default:
@@ -2792,19 +2810,14 @@ build_type_variant (type, constp, volatilep)
constp = !!constp;
volatilep = !!volatilep;
- /* If not generating auxiliary info, search the chain of variants to see
- if there is already one there just like the one we need to have. If so,
- use that existing one.
+ /* Search the chain of variants to see if there is already one there just
+ 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. */
- We don't do this in the case where we are generating aux info because
- in that case we want each typedef names to get it's own distinct type
- node, even if the type of this new typedef is the same as some other
- (existing) type. */
-
- if (!flag_gen_aux_info)
- for (t = TYPE_MAIN_VARIANT(type); t; t = TYPE_NEXT_VARIANT (t))
- if (constp == TYPE_READONLY (t) && volatilep == TYPE_VOLATILE (t))
- return 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;
/* We need a new one. */
@@ -2819,7 +2832,7 @@ build_type_variant (type, constp, volatilep)
This is the right thing to do only when something else
about TYPE is modified in place. */
-tree
+void
change_main_variant (type, new_main)
tree type, new_main;
{
@@ -3054,7 +3067,9 @@ type_list_equal (l1, l2)
int cmp = simple_cst_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2));
if (cmp < 0)
abort ();
- if (cmp == 0)
+ if (cmp == 0
+ || TREE_TYPE (TREE_PURPOSE (t1))
+ != TREE_TYPE (TREE_PURPOSE (t2)))
return 0;
}
}
@@ -3843,7 +3858,7 @@ decl_function_context (decl)
{
if (TREE_CODE (context) == RECORD_TYPE
|| TREE_CODE (context) == UNION_TYPE)
- context = TYPE_CONTEXT (context);
+ context = NULL_TREE;
else if (TREE_CODE (context) == TYPE_DECL)
context = DECL_CONTEXT (context);
else if (TREE_CODE (context) == BLOCK)
@@ -3994,3 +4009,102 @@ get_file_function_name (kind)
return get_identifier (buf);
}
+
+/* Expand (the constant part of) a SET_TYPE CONTRUCTOR node.
+ The result is placed in BUFFER (which has length BIT_SIZE),
+ 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. */
+
+tree
+get_set_constructor_bits (init, buffer, bit_size)
+ tree init;
+ char *buffer;
+ int bit_size;
+{
+ int i;
+ tree vals;
+ HOST_WIDE_INT domain_min
+ = TREE_INT_CST_LOW (TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (init))));
+ 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
+ || (TREE_PURPOSE (vals) != NULL_TREE
+ && TREE_CODE (TREE_PURPOSE (vals)) != INTEGER_CST))
+ 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;
+ HOST_WIDE_INT hi_index
+ = TREE_INT_CST_LOW (TREE_VALUE (vals)) - domain_min;
+ if (lo_index < 0 || lo_index >= bit_size
+ || hi_index < 0 || hi_index >= bit_size)
+ abort ();
+ for ( ; lo_index <= hi_index; lo_index++)
+ buffer[lo_index] = 1;
+ }
+ else
+ {
+ /* 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)
+ {
+ error ("invalid initializer for bit string");
+ return NULL_TREE;
+ }
+ buffer[index] = 1;
+ }
+ }
+ return non_const_bits;
+}
+
+/* Expand (the constant part of) a SET_TYPE CONTRUCTOR node.
+ The result is placed in BUFFER (which is an array of WD_SIZE
+ words). TYPE_ALIGN bits are stored in each element of BUFFER.
+ If the constructor is constant, NULL_TREE is returned.
+ Otherwise, a TREE_LIST of the non-constant elements is emitted. */
+
+tree
+get_set_constructor_words (init, buffer, wd_size)
+ tree init;
+ HOST_WIDE_INT *buffer;
+ int wd_size;
+{
+ int i;
+ tree vals = TREE_OPERAND (init, 1);
+ int set_word_size = TYPE_ALIGN (TREE_TYPE (init));
+ int bit_size = wd_size * set_word_size;
+ int bit_pos = 0;
+ HOST_WIDE_INT *wordp = buffer;
+ 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++)
+ buffer[i] = 0;
+
+ for (i = 0; i < bit_size; i++)
+ {
+ if (bit_buffer[i])
+ {
+#if BITS_BIG_ENDIAN
+ *wordp |= (1 << (set_word_size - 1 - bit_pos));
+#else
+ *wordp |= 1 << bit_pos;
+#endif
+ }
+ bit_pos++;
+ if (bit_pos >= set_word_size)
+ bit_pos = 0, wordp++;
+ }
+ return non_const_bits;
+}
OpenPOWER on IntegriCloud