summaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/gcc-interface/decl.c')
-rw-r--r--gcc/ada/gcc-interface/decl.c76
1 files changed, 45 insertions, 31 deletions
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 094d7e0ec21..3284f84db6f 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -6,7 +6,7 @@
* *
* C Implementation File *
* *
- * Copyright (C) 1992-2012, Free Software Foundation, Inc. *
+ * Copyright (C) 1992-2013, Free Software Foundation, Inc. *
* *
* GNAT is free software; you can redistribute it and/or modify it under *
* terms of the GNU General Public License as published by the Free Soft- *
@@ -1887,8 +1887,10 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
}
/* If the type we are dealing with has got a smaller alignment than the
- natural one, we need to wrap it up in a record type and under-align
- the latter. We reuse the padding machinery for this purpose. */
+ natural one, we need to wrap it up in a record type and misalign the
+ latter; we reuse the padding machinery for this purpose. Note that,
+ even if the record type is marked as packed because of misalignment,
+ we don't pack the field so as to give it the size of the type. */
else if (align > 0)
{
tree gnu_field_type, gnu_field;
@@ -1918,7 +1920,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
a bitfield. */
gnu_field
= create_field_decl (get_identifier ("F"), gnu_field_type,
- gnu_type, NULL_TREE, bitsize_zero_node, 1, 0);
+ gnu_type, TYPE_SIZE (gnu_field_type),
+ bitsize_zero_node, 0, 0);
finish_record_type (gnu_type, gnu_field, 2, debug_info_p);
compute_record_mode (gnu_type);
@@ -4965,7 +4968,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
}
}
- /* If this is a record type or subtype, call elaborate_expression_1 on
+ /* If this is a record type or subtype, call elaborate_expression_2 on
any field position. Do this for both global and local types.
Skip any fields that we haven't made trees for to avoid problems with
class wide types. */
@@ -5941,18 +5944,6 @@ elaborate_entity (Entity_Id gnat_entity)
break;
}
- case E_Record_Type:
- {
- Node_Id full_definition = Declaration_Node (gnat_entity);
- Node_Id record_definition = Type_Definition (full_definition);
-
- /* If this is a record extension, go a level further to find the
- record definition. */
- if (Nkind (record_definition) == N_Derived_Type_Definition)
- record_definition = Record_Extension_Part (record_definition);
- }
- break;
-
case E_Record_Subtype:
case E_Private_Subtype:
case E_Limited_Private_Subtype:
@@ -6498,10 +6489,11 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed,
}
/* If this field needs strict alignment, check that the record is
- sufficiently aligned and that position and size are consistent
- with the alignment. But don't do it if we are just annotating
- types and the field's type is tagged, since tagged types aren't
- fully laid out in this mode. */
+ sufficiently aligned and that position and size are consistent with
+ the alignment. But don't do it if we are just annotating types and
+ the field's type is tagged, since tagged types aren't fully laid out
+ in this mode. Also, note that atomic implies volatile so the inner
+ test sequences ordering is significant here. */
if (needs_strict_alignment
&& !(type_annotate_only && Is_Tagged_Type (gnat_field_type)))
{
@@ -6517,6 +6509,12 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed,
Last_Bit (Component_Clause (gnat_field)), gnat_field,
TYPE_SIZE (gnu_field_type));
+ else if (is_volatile)
+ post_error_ne_tree
+ ("volatile field& must be natural size of type{ (^)}",
+ Last_Bit (Component_Clause (gnat_field)), gnat_field,
+ TYPE_SIZE (gnu_field_type));
+
else if (Is_Aliased (gnat_field))
post_error_ne_tree
("size of aliased field& must be ^ bits",
@@ -6529,6 +6527,9 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed,
Last_Bit (Component_Clause (gnat_field)), gnat_field,
TYPE_SIZE (gnu_field_type));
+ else
+ gcc_unreachable ();
+
gnu_size = NULL_TREE;
}
@@ -6536,7 +6537,13 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed,
(TRUNC_MOD_EXPR, gnu_pos,
bitsize_int (TYPE_ALIGN (gnu_field_type)))))
{
- if (is_volatile)
+ if (Is_Atomic (gnat_field) || Is_Atomic (gnat_field_type))
+ post_error_ne_num
+ ("position of atomic field& must be multiple of ^ bits",
+ First_Bit (Component_Clause (gnat_field)), gnat_field,
+ TYPE_ALIGN (gnu_field_type));
+
+ else if (is_volatile)
post_error_ne_num
("position of volatile field& must be multiple of ^ bits",
First_Bit (Component_Clause (gnat_field)), gnat_field,
@@ -7286,15 +7293,22 @@ annotate_value (tree gnu_size)
case COMPONENT_REF:
/* The only case we handle here is a simple discriminant reference. */
- if (TREE_CODE (TREE_OPERAND (gnu_size, 0)) == PLACEHOLDER_EXPR
- && TREE_CODE (TREE_OPERAND (gnu_size, 1)) == FIELD_DECL
- && DECL_DISCRIMINANT_NUMBER (TREE_OPERAND (gnu_size, 1)))
- return Create_Node (Discrim_Val,
- annotate_value (DECL_DISCRIMINANT_NUMBER
- (TREE_OPERAND (gnu_size, 1))),
- No_Uint, No_Uint);
- else
- return No_Uint;
+ if (DECL_DISCRIMINANT_NUMBER (TREE_OPERAND (gnu_size, 1)))
+ {
+ tree n = DECL_DISCRIMINANT_NUMBER (TREE_OPERAND (gnu_size, 1));
+
+ /* Climb up the chain of successive extensions, if any. */
+ while (TREE_CODE (TREE_OPERAND (gnu_size, 0)) == COMPONENT_REF
+ && DECL_NAME (TREE_OPERAND (TREE_OPERAND (gnu_size, 0), 1))
+ == parent_name_id)
+ gnu_size = TREE_OPERAND (gnu_size, 0);
+
+ if (TREE_CODE (TREE_OPERAND (gnu_size, 0)) == PLACEHOLDER_EXPR)
+ return
+ Create_Node (Discrim_Val, annotate_value (n), No_Uint, No_Uint);
+ }
+
+ return No_Uint;
CASE_CONVERT: case NON_LVALUE_EXPR:
return annotate_value (TREE_OPERAND (gnu_size, 0));