static tree float_type_for_precision (int, machine_mode);
static tree convert_to_fat_pointer (tree, tree);
static unsigned int scale_by_factor_of (tree, unsigned int);
-static bool potential_alignment_gap (tree, tree, tree);
/* Linked list used as a queue to defer the initialization of the DECL_CONTEXT
of ..._DECL nodes and of the TYPE_CONTEXT of ..._TYPE nodes. */
? UNION_TYPE : TREE_CODE (record_type));
tree orig_name = TYPE_IDENTIFIER (record_type), new_name;
tree last_pos = bitsize_zero_node;
- tree old_field, prev_old_field = NULL_TREE;
new_name
= concat_name (orig_name, TREE_CODE (record_type) == QUAL_UNION_TYPE
/* Now scan all the fields, replacing each field with a new field
corresponding to the new encoding. */
- for (old_field = TYPE_FIELDS (record_type); old_field;
+ for (tree old_field = TYPE_FIELDS (record_type);
+ old_field;
old_field = DECL_CHAIN (old_field))
{
tree field_type = TREE_TYPE (old_field);
else
pos = compute_related_constant (curpos, last_pos);
- if (!pos
- && TREE_CODE (curpos) == MULT_EXPR
- && tree_fits_uhwi_p (TREE_OPERAND (curpos, 1)))
+ if (pos)
+ ;
+ else if (TREE_CODE (curpos) == MULT_EXPR
+ && tree_fits_uhwi_p (TREE_OPERAND (curpos, 1)))
{
tree offset = TREE_OPERAND (curpos, 0);
align = tree_to_uhwi (TREE_OPERAND (curpos, 1));
last_pos = round_up (last_pos, align);
pos = compute_related_constant (curpos, last_pos);
}
- else if (!pos
- && TREE_CODE (curpos) == PLUS_EXPR
+ else if (TREE_CODE (curpos) == PLUS_EXPR
&& tree_fits_uhwi_p (TREE_OPERAND (curpos, 1))
&& TREE_CODE (TREE_OPERAND (curpos, 0)) == MULT_EXPR
&& tree_fits_uhwi_p
last_pos = round_up (last_pos, align);
pos = compute_related_constant (curpos, last_pos);
}
- else if (potential_alignment_gap (prev_old_field, old_field, pos))
+ else
{
- align = TYPE_ALIGN (field_type);
+ align = DECL_ALIGN (old_field);
last_pos = round_up (last_pos, align);
pos = compute_related_constant (curpos, last_pos);
}
in this case, if we don't preventively counter that. */
if (TREE_CODE (DECL_SIZE (old_field)) != INTEGER_CST)
{
- field_type = build_pointer_type (field_type);
- if (align != 0 && TYPE_ALIGN (field_type) > align)
+ field_type = copy_type (build_pointer_type (field_type));
+ SET_TYPE_ALIGN (field_type, BITS_PER_UNIT);
+ var = true;
+
+ /* ??? Kludge to work around a bug in Workbench's debugger. */
+ if (align == 0)
{
- field_type = copy_type (field_type);
- SET_TYPE_ALIGN (field_type, align);
+ align = DECL_ALIGN (old_field);
+ last_pos = round_up (last_pos, align);
+ pos = compute_related_constant (curpos, last_pos);
}
- var = true;
}
/* Make a new field name, if necessary. */
new_field
= create_field_decl (field_name, field_type, new_record_type,
DECL_SIZE (old_field), pos, 0, 0);
+ /* The specified position is not the actual position of the field
+ but the gap with the previous field, so the computation of the
+ bit-field status may be incorrect. We adjust it manually to
+ avoid generating useless attributes for the field in DWARF. */
+ if (DECL_SIZE (old_field) == TYPE_SIZE (field_type)
+ && value_factor_p (pos, BITS_PER_UNIT))
+ {
+ DECL_BIT_FIELD (new_field) = 0;
+ DECL_BIT_FIELD_TYPE (new_field) = NULL_TREE;
+ }
DECL_CHAIN (new_field) = TYPE_FIELDS (new_record_type);
TYPE_FIELDS (new_record_type) = new_field;
== QUAL_UNION_TYPE)
? bitsize_zero_node
: DECL_SIZE (old_field));
- prev_old_field = old_field;
}
TYPE_FIELDS (new_record_type) = nreverse (TYPE_FIELDS (new_record_type));
return new_size;
}
+/* Convert the size expression EXPR to TYPE and fold the result. */
+
+static tree
+fold_convert_size (tree type, tree expr)
+{
+ /* We assume that size expressions do not wrap around. */
+ if (TREE_CODE (expr) == MULT_EXPR || TREE_CODE (expr) == PLUS_EXPR)
+ return size_binop (TREE_CODE (expr),
+ fold_convert_size (type, TREE_OPERAND (expr, 0)),
+ fold_convert_size (type, TREE_OPERAND (expr, 1)));
+
+ return fold_convert (type, expr);
+}
+
/* Return the bit position of FIELD, in bits from the start of the record,
and fold it as much as possible. This is a tree of type bitsizetype. */
static tree
fold_bit_position (const_tree field)
{
- tree offset = DECL_FIELD_OFFSET (field);
- if (TREE_CODE (offset) == MULT_EXPR || TREE_CODE (offset) == PLUS_EXPR)
- offset = size_binop (TREE_CODE (offset),
- fold_convert (bitsizetype, TREE_OPERAND (offset, 0)),
- fold_convert (bitsizetype, TREE_OPERAND (offset, 1)));
- else
- offset = fold_convert (bitsizetype, offset);
+ tree offset = fold_convert_size (bitsizetype, DECL_FIELD_OFFSET (field));
return size_binop (PLUS_EXPR, DECL_FIELD_BIT_OFFSET (field),
size_binop (MULT_EXPR, offset, bitsize_unit_node));
}
&& !have_global_bss_p ())
DECL_COMMON (var_decl) = 1;
- /* Do not emit debug info for a CONST_DECL if optimization isn't enabled,
- since we will create an associated variable. Likewise for an external
- constant whose initializer is not absolute, because this would mean a
- global relocation in a read-only section which runs afoul of the PE-COFF
- run-time relocation mechanism. */
+ /* Do not emit debug info if not requested, or for an external constant whose
+ initializer is not absolute because this would require a global relocation
+ in a read-only section which runs afoul of the PE-COFF run-time relocation
+ mechanism. */
if (!debug_info_p
- || (TREE_CODE (var_decl) == CONST_DECL && !optimize)
|| (extern_flag
&& constant_p
&& init
return factor * value;
}
-/* Given two consecutive field decls PREV_FIELD and CURR_FIELD, return true
- unless we can prove these 2 fields are laid out in such a way that no gap
- exist between the end of PREV_FIELD and the beginning of CURR_FIELD. OFFSET
- is the distance in bits between the end of PREV_FIELD and the starting
- position of CURR_FIELD. It is ignored if null. */
-
-static bool
-potential_alignment_gap (tree prev_field, tree curr_field, tree offset)
-{
- /* If this is the first field of the record, there cannot be any gap */
- if (!prev_field)
- return false;
-
- /* If the previous field is a union type, then return false: The only
- time when such a field is not the last field of the record is when
- there are other components at fixed positions after it (meaning there
- was a rep clause for every field), in which case we don't want the
- alignment constraint to override them. */
- if (TREE_CODE (TREE_TYPE (prev_field)) == QUAL_UNION_TYPE)
- return false;
-
- /* If the distance between the end of prev_field and the beginning of
- curr_field is constant, then there is a gap if the value of this
- constant is not null. */
- if (offset && tree_fits_uhwi_p (offset))
- return !integer_zerop (offset);
-
- /* If the size and position of the previous field are constant,
- then check the sum of this size and position. There will be a gap
- iff it is not multiple of the current field alignment. */
- if (tree_fits_uhwi_p (DECL_SIZE (prev_field))
- && tree_fits_uhwi_p (bit_position (prev_field)))
- return ((tree_to_uhwi (bit_position (prev_field))
- + tree_to_uhwi (DECL_SIZE (prev_field)))
- % DECL_ALIGN (curr_field) != 0);
-
- /* If both the position and size of the previous field are multiples
- of the current field alignment, there cannot be any gap. */
- if (value_factor_p (bit_position (prev_field), DECL_ALIGN (curr_field))
- && value_factor_p (DECL_SIZE (prev_field), DECL_ALIGN (curr_field)))
- return false;
-
- /* Fallback, return that there may be a potential gap */
- return true;
-}
-
/* Return a LABEL_DECL with NAME. GNAT_NODE is used for the position of
the decl. */
/* If the type is unsigned, overflow is allowed so we cannot be sure that
EXPR doesn't overflow. Keep it simple if optimization is disabled. */
- if (TYPE_UNSIGNED (type) || !optimize)
+ if (TYPE_UNSIGNED (type) || !optimize || optimize_debug)
return convert (sizetype, expr);
switch (code)
&& DECL_FUNCTION_IS_DEF (iter))
debug_hooks->early_global_decl (iter);
+ /* Output global constants. */
+ FOR_EACH_VEC_SAFE_ELT (global_decls, i, iter)
+ if (TREE_CODE (iter) == CONST_DECL && !DECL_IGNORED_P (iter))
+ debug_hooks->early_global_decl (iter);
+
/* Then output the global variables. We need to do that after the debug
information for global types is emitted so that they are finalized. Skip
external global variables, unless we need to emit debug info for them:
static int flag_isoc94 = 0;
static int flag_isoc99 = 0;
static int flag_isoc11 = 0;
+static int flag_isoc2x = 0;
/* Install what the common builtins.def offers plus our local additions.