OSDN Git Service

* gcc-interface/ada-tree.def (LOOP_STMT): Change to 4-operand nodes.
[pf3gnuchains/gcc-fork.git] / gcc / ada / gcc-interface / trans.c
index e2a480d..710887b 100644 (file)
@@ -230,8 +230,9 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name ATTRIBUTE_UNUSED,
       struct Elist_Header *elists_ptr, struct Elmt_Item *elmts_ptr,
       struct String_Entry *strings_ptr, Char_Code *string_chars_ptr,
       struct List_Header *list_headers_ptr, Nat number_file,
-      struct File_Info_Type *file_info_ptr, Entity_Id standard_boolean,
-      Entity_Id standard_integer, Entity_Id standard_long_long_float,
+      struct File_Info_Type *file_info_ptr,
+      Entity_Id standard_boolean, Entity_Id standard_integer,
+      Entity_Id standard_character, Entity_Id standard_long_long_float,
       Entity_Id standard_exception_type, Int gigi_operating_mode)
 {
   Entity_Id gnat_literal;
@@ -317,23 +318,26 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name ATTRIBUTE_UNUSED,
   double_float_alignment = get_target_double_float_alignment ();
   double_scalar_alignment = get_target_double_scalar_alignment ();
 
-  /* Record the builtin types.  Define `integer' and `unsigned char' first so
-     that dbx will output them first.  */
+  /* Record the builtin types.  Define `integer' and `character' first so that
+     dbx will output them first.  */
   record_builtin_type ("integer", integer_type_node);
-  record_builtin_type ("unsigned char", char_type_node);
-  record_builtin_type ("long integer", long_integer_type_node);
-  unsigned_type_node = gnat_type_for_size (INT_TYPE_SIZE, 1);
-  record_builtin_type ("unsigned int", unsigned_type_node);
-  record_builtin_type (SIZE_TYPE, sizetype);
+  record_builtin_type ("character", unsigned_char_type_node);
   record_builtin_type ("boolean", boolean_type_node);
   record_builtin_type ("void", void_type_node);
 
   /* Save the type we made for integer as the type for Standard.Integer.  */
-  save_gnu_tree (Base_Type (standard_integer), TYPE_NAME (integer_type_node),
+  save_gnu_tree (Base_Type (standard_integer),
+                TYPE_NAME (integer_type_node),
                 false);
 
-  /* Save the type we made for boolean as the type for Standard.Boolean.  */
-  save_gnu_tree (Base_Type (standard_boolean), TYPE_NAME (boolean_type_node),
+  /* Likewise for character as the type for Standard.Character.  */
+  save_gnu_tree (Base_Type (standard_character),
+                TYPE_NAME (unsigned_char_type_node),
+                false);
+
+  /* Likewise for boolean as the type for Standard.Boolean.  */
+  save_gnu_tree (Base_Type (standard_boolean),
+                TYPE_NAME (boolean_type_node),
                 false);
   gnat_literal = First_Literal (Base_Type (standard_boolean));
   t = UI_To_gnu (Enumeration_Rep (gnat_literal), boolean_type_node);
@@ -474,7 +478,8 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name ATTRIBUTE_UNUSED,
          (get_identifier ("__gnat_last_chance_handler"), NULL_TREE,
           build_function_type (void_type_node,
                                tree_cons (NULL_TREE,
-                                          build_pointer_type (char_type_node),
+                                          build_pointer_type
+                                          (unsigned_char_type_node),
                                           tree_cons (NULL_TREE,
                                                      integer_type_node,
                                                      t))),
@@ -496,7 +501,7 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name ATTRIBUTE_UNUSED,
             build_function_type (void_type_node,
                                  tree_cons (NULL_TREE,
                                             build_pointer_type
-                                            (char_type_node),
+                                            (unsigned_char_type_node),
                                             tree_cons (NULL_TREE,
                                                        integer_type_node,
                                                        t))),
@@ -512,9 +517,7 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name ATTRIBUTE_UNUSED,
                                TYPE_QUAL_VOLATILE);
     }
 
-  /* Set the types that GCC and Gigi use from the front end.  We would
-     like to do this for char_type_node, but it needs to correspond to
-     the C char type.  */
+  /* Set the types that GCC and Gigi use from the front end.  */
   exception_type
     = gnat_to_gnu_entity (Base_Type (standard_exception_type),  NULL_TREE, 0);
   except_type_node = TREE_TYPE (exception_type);
@@ -556,8 +559,9 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name ATTRIBUTE_UNUSED,
 
       for (j = 0; j < TARGET_VTABLE_USES_DESCRIPTORS; j++)
        {
-         tree field = create_field_decl (NULL_TREE, ptr_void_ftype,
-                                         fdesc_type_node, 0, 0, 0, 1);
+         tree field
+           = create_field_decl (NULL_TREE, ptr_void_ftype, fdesc_type_node,
+                                NULL_TREE, NULL_TREE, 0, 1);
          TREE_CHAIN (field) = field_list;
          field_list = field;
          null_list = tree_cons (field, null_node, null_list);
@@ -1354,7 +1358,8 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
        if (TREE_CODE (gnu_obj_type) == RECORD_TYPE
            && TYPE_CONTAINS_TEMPLATE_P (gnu_obj_type))
          {
-           tree gnu_char_ptr_type = build_pointer_type (char_type_node);
+           tree gnu_char_ptr_type
+             = build_pointer_type (unsigned_char_type_node);
            tree gnu_pos = byte_position (TYPE_FIELDS (gnu_obj_type));
            tree gnu_byte_offset
              = convert (sizetype,
@@ -1364,7 +1369,7 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
 
            gnu_ptr = convert (gnu_char_ptr_type, gnu_ptr);
            gnu_ptr = build_binary_op (POINTER_PLUS_EXPR, gnu_char_ptr_type,
-                                      gnu_ptr, gnu_byte_offset);
+                                      gnu_ptr, gnu_pos);
          }
 
        gnu_result = convert (gnu_result_type, gnu_ptr);
@@ -1448,7 +1453,8 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
                  gnu_type
                    = build_unc_object_type_from_ptr (gnu_ptr_type,
                                                      gnu_actual_obj_type,
-                                                     get_identifier ("SIZE"));
+                                                     get_identifier ("SIZE"),
+                                                     false);
                }
 
              gnu_result = TYPE_SIZE (gnu_type);
@@ -2280,7 +2286,7 @@ Loop_Statement_to_gnu (Node_Id gnat_node)
 
       /* Set either the top or bottom exit condition.  */
       LOOP_STMT_COND (gnu_loop_stmt)
-       = build_binary_op (test_code, boolean_type_node, gnu_loop_var,
+       = build_binary_op (test_code, integer_type_node, gnu_loop_var,
                           gnu_last);
 
       /* Set either the top or bottom update statement and give it the source
@@ -2619,7 +2625,7 @@ call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target)
   tree gnu_subprog_addr = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_subprog);
   Entity_Id gnat_formal;
   Node_Id gnat_actual;
-  tree gnu_actual_list = NULL_TREE;
+  VEC(tree,gc) *gnu_actual_vec = NULL;
   tree gnu_name_list = NULL_TREE;
   tree gnu_before_list = NULL_TREE;
   tree gnu_after_list = NULL_TREE;
@@ -2969,7 +2975,7 @@ call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target)
            gnu_actual = convert (DECL_ARG_TYPE (gnu_formal), gnu_actual);
        }
 
-      gnu_actual_list = tree_cons (NULL_TREE, gnu_actual, gnu_actual_list);
+      VEC_safe_push (tree, gc, gnu_actual_vec, gnu_actual);
     }
 
   gnu_call = build_call_list (TREE_TYPE (gnu_subprog_type), gnu_subprog_addr,
@@ -3574,6 +3580,11 @@ Compilation_Unit_to_gnu (Node_Id gnat_node)
   start_stmt_group ();
   gnat_pushlevel ();
 
+  current_function_decl = NULL_TREE;
+
+  start_stmt_group ();
+  gnat_pushlevel ();
+
   /* For a body, first process the spec if there is one.  */
   if (Nkind (Unit (gnat_node)) == N_Package_Body
       || (Nkind (Unit (gnat_node)) == N_Subprogram_Body
@@ -4285,21 +4296,20 @@ gnat_to_gnu (Node_Id gnat_node)
 
     case N_Attribute_Reference:
       {
-       /* The attribute designator (like an enumeration value).  */
-       int attribute = Get_Attribute_Id (Attribute_Name (gnat_node));
-
-       /* The Elab_Spec and Elab_Body attributes are special in that
-          Prefix is a unit, not an object with a GCC equivalent.  Similarly
-          for Elaborated, since that variable isn't otherwise known.  */
-       if (attribute == Attr_Elab_Body || attribute == Attr_Elab_Spec)
-         return (create_subprog_decl
-                 (create_concat_name (Entity (Prefix (gnat_node)),
-                                      attribute == Attr_Elab_Body
-                                      ? "elabb" : "elabs"),
-                  NULL_TREE, void_ftype, NULL_TREE, false, true, true, NULL,
-                  gnat_node));
-
-       gnu_result = Attribute_to_gnu (gnat_node, &gnu_result_type, attribute);
+       /* The attribute designator.  */
+       const int attr = Get_Attribute_Id (Attribute_Name (gnat_node));
+
+       /* The Elab_Spec and Elab_Body attributes are special in that Prefix
+          is a unit, not an object with a GCC equivalent.  */
+       if (attr == Attr_Elab_Spec || attr == Attr_Elab_Body)
+         return
+           create_subprog_decl (create_concat_name
+                                (Entity (Prefix (gnat_node)),
+                                 attr == Attr_Elab_Body ? "elabb" : "elabs"),
+                                NULL_TREE, void_ftype, NULL_TREE, false,
+                                true, true, NULL, gnat_node);
+
+       gnu_result = Attribute_to_gnu (gnat_node, &gnu_result_type, attr);
       }
       break;
 
@@ -4800,10 +4810,12 @@ gnat_to_gnu (Node_Id gnat_node)
          gnu_result
            = build_binary_op (MODIFY_EXPR, NULL_TREE, gnu_lhs, gnu_rhs);
 
-         /* If the type being assigned is an array type and the two sides
-            are not completely disjoint, play safe and use memmove.  */
+         /* If the type being assigned is an array type and the two sides are
+            not completely disjoint, play safe and use memmove.  But don't do
+            it for a bit-packed array as it might not be byte-aligned.  */
          if (TREE_CODE (gnu_result) == MODIFY_EXPR
              && Is_Array_Type (Etype (Name (gnat_node)))
+             && !Is_Bit_Packed_Array (Etype (Name (gnat_node)))
              && !(Forwards_OK (gnat_node) && Backwards_OK (gnat_node)))
            {
              tree to, from, size, to_ptr, from_ptr, t;
@@ -5398,7 +5410,8 @@ gnat_to_gnu (Node_Id gnat_node)
          if (TREE_CODE (gnu_obj_type) == RECORD_TYPE
              && TYPE_CONTAINS_TEMPLATE_P (gnu_obj_type))
            {
-             tree gnu_char_ptr_type = build_pointer_type (char_type_node);
+             tree gnu_char_ptr_type
+               = build_pointer_type (unsigned_char_type_node);
              tree gnu_pos = byte_position (TYPE_FIELDS (gnu_obj_type));
              tree gnu_byte_offset
                = convert (sizetype,
@@ -5408,7 +5421,7 @@ gnat_to_gnu (Node_Id gnat_node)
 
              gnu_ptr = convert (gnu_char_ptr_type, gnu_ptr);
              gnu_ptr = build_binary_op (POINTER_PLUS_EXPR, gnu_char_ptr_type,
-                                        gnu_ptr, gnu_byte_offset);
+                                        gnu_ptr, gnu_pos);
            }
 
          gnu_result
@@ -6995,7 +7008,7 @@ convert_with_check (Entity_Id gnat_type, tree gnu_expr, bool overflowp,
       gnu_result = gnat_protect_expr (gnu_result);
       gnu_conv = convert (calc_type, gnu_result);
       gnu_comp
-       = fold_build2 (GE_EXPR, boolean_type_node, gnu_result, gnu_zero);
+       = fold_build2 (GE_EXPR, integer_type_node, gnu_result, gnu_zero);
       gnu_add_pred_half
        = fold_build2 (PLUS_EXPR, calc_type, gnu_conv, gnu_pred_half);
       gnu_subtract_pred_half