summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ada/ada-tree.def3
-rw-r--r--gcc/ada/ada-tree.h3
-rw-r--r--gcc/ada/decl.c16
-rw-r--r--gcc/ada/gigi.h2
-rw-r--r--gcc/ada/trans.c108
-rw-r--r--gcc/ada/utils.c11
6 files changed, 64 insertions, 79 deletions
diff --git a/gcc/ada/ada-tree.def b/gcc/ada/ada-tree.def
index b185106f62e..fe68c633f2c 100644
--- a/gcc/ada/ada-tree.def
+++ b/gcc/ada/ada-tree.def
@@ -49,9 +49,6 @@ DEFTREECODE (ATTR_ADDR_EXPR, "attr_addr_expr", 'r', 1)
/* Here are the tree codes for the statement types known to Ada. These
must be at the end of this file to allow IS_ADA_STMT to work. */
-/* This defines the variable in DECL_STMT_VAR. */
-DEFTREECODE (DECL_STMT, "decl_stmt", 's', 1)
-
/* This is how record_code_position and insert_code_for work. The former
makes this tree node, whose operand is a statement. The latter inserts
the actual statements into this node. Gimplification consists of
diff --git a/gcc/ada/ada-tree.h b/gcc/ada/ada-tree.h
index 9cdcc5d5584..ca099b8462d 100644
--- a/gcc/ada/ada-tree.h
+++ b/gcc/ada/ada-tree.h
@@ -262,9 +262,8 @@ struct lang_type GTY(()) {union lang_tree_node t; };
Start by defining which tree codes are used for statements. */
#define IS_STMT(NODE) (TREE_CODE_CLASS (TREE_CODE (NODE)) == 's')
#define IS_ADA_STMT(NODE) (IS_STMT (NODE) \
- && TREE_CODE (NODE) >= DECL_STMT)
+ && TREE_CODE (NODE) >= STMT_STMT)
-#define DECL_STMT_VAR(NODE) TREE_OPERAND_CHECK_CODE (NODE, DECL_STMT, 0)
#define STMT_STMT_STMT(NODE) TREE_OPERAND_CHECK_CODE (NODE, STMT_STMT, 0)
#define LOOP_STMT_TOP_COND(NODE) TREE_OPERAND_CHECK_CODE (NODE, LOOP_STMT, 0)
#define LOOP_STMT_BOT_COND(NODE) TREE_OPERAND_CHECK_CODE (NODE, LOOP_STMT, 1)
diff --git a/gcc/ada/decl.c b/gcc/ada/decl.c
index 25fe2c8dd58..0fd4c2b22c5 100644
--- a/gcc/ada/decl.c
+++ b/gcc/ada/decl.c
@@ -959,7 +959,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
NULL_TREE, gnu_new_type, gnu_expr,
0, 0, 0, 0, 0);
annotate_decl_with_node (gnu_new_var, gnat_entity);
- add_decl_stmt (gnu_new_var, gnat_entity);
+ add_decl_expr (gnu_new_var, gnat_entity);
if (gnu_expr != 0)
add_stmt_with_node
@@ -1041,7 +1041,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
if (Present (Address_Clause (gnat_entity)) && used_by_ref)
DECL_POINTER_ALIAS_SET (gnu_decl) = 0;
- add_decl_stmt (gnu_decl, gnat_entity);
+ add_decl_expr (gnu_decl, gnat_entity);
if (definition && DECL_SIZE (gnu_decl) != 0
&& get_block_jmpbuf_decl ()
@@ -1071,7 +1071,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
gnu_expr, 0, Is_Public (gnat_entity), 0,
static_p, 0);
- add_decl_stmt (gnu_corr_var, gnat_entity);
+ add_decl_expr (gnu_corr_var, gnat_entity);
SET_DECL_CONST_CORRESPONDING_VAR (gnu_decl, gnu_corr_var);
}
@@ -1154,7 +1154,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
= create_var_decl (get_entity_name (gnat_literal),
0, gnu_type, gnu_value, 1, 0, 0, 0, 0);
- add_decl_stmt (gnu_literal, gnat_literal);
+ add_decl_expr (gnu_literal, gnat_literal);
save_gnu_tree (gnat_literal, gnu_literal, 0);
gnu_literal_list = tree_cons (DECL_NAME (gnu_literal),
gnu_value, gnu_literal_list);
@@ -3627,7 +3627,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
gnu_address, 0, Is_Public (gnat_entity),
extern_flag, 0, 0);
DECL_BY_REF_P (gnu_decl) = 1;
- add_decl_stmt (gnu_decl, gnat_entity);
+ add_decl_expr (gnu_decl, gnat_entity);
}
else if (kind == E_Subprogram_Type)
@@ -3925,7 +3925,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
else
TREE_TYPE (gnu_decl) = gnu_type;
- add_decl_stmt (gnu_decl, gnat_entity);
+ add_decl_expr (gnu_decl, gnat_entity);
}
if (IN (kind, Type_Kind) && ! TYPE_IS_DUMMY_P (TREE_TYPE (gnu_decl)))
@@ -4545,7 +4545,7 @@ elaborate_expression_1 (Node_Id gnat_expr, Entity_Id gnat_entity,
NULL_TREE, TREE_TYPE (gnu_expr), gnu_expr, 1,
Is_Public (gnat_entity), ! definition, 0, 0);
annotate_decl_with_node (gnu_decl, gnat_entity);
- add_decl_stmt (gnu_decl, gnat_entity);
+ add_decl_expr (gnu_decl, gnat_entity);
}
/* We only need to use this variable if we are in global context since GCC
@@ -4824,7 +4824,7 @@ maybe_pad_type (tree type, tree size, unsigned int align,
= create_var_decl (concat_id_with_name (name, "XVZ"), NULL_TREE,
sizetype, TYPE_SIZE (record), 0, 0, 0, 0, 0);
- add_decl_stmt (gnu_xvz, gnat_entity);
+ add_decl_expr (gnu_xvz, gnat_entity);
}
}
diff --git a/gcc/ada/gigi.h b/gcc/ada/gigi.h
index ae8b401b766..6e64aa4b4a5 100644
--- a/gcc/ada/gigi.h
+++ b/gcc/ada/gigi.h
@@ -91,7 +91,7 @@ extern void set_block_for_group (tree);
/* Add a declaration statement for GNU_DECL to the current BLOCK_STMT node.
Get SLOC from Entity_Id. */
-extern void add_decl_stmt (tree, Entity_Id);
+extern void add_decl_expr (tree, Entity_Id);
/* Given GNAT_ENTITY, elaborate all expressions that are required to
be elaborated at the point of its definition, but do nothing else. */
diff --git a/gcc/ada/trans.c b/gcc/ada/trans.c
index b321ef9c6ac..a7c10851537 100644
--- a/gcc/ada/trans.c
+++ b/gcc/ada/trans.c
@@ -133,8 +133,6 @@ static tree build_stmt_group (List_Id, bool);
static void push_stack (tree *, tree, tree);
static void pop_stack (tree *);
static enum gimplify_status gnat_gimplify_stmt (tree *);
-static tree gnat_gimplify_type_sizes (tree);
-static void gnat_gimplify_one_sizepos (tree *, tree *);
static void gnat_expand_body_1 (tree, bool);
static void elaborate_all_entities (Node_Id);
static void process_freeze_entity (Node_Id);
@@ -729,7 +727,7 @@ gnat_to_gnu (Node_Id gnat_node)
NULL_TREE, TREE_TYPE (gnu_expr),
gnu_expr, 0, Is_Public (gnat_temp), 0,
0, 0);
- add_decl_stmt (gnu_expr, gnat_temp);
+ add_decl_expr (gnu_expr, gnat_temp);
}
else
gnu_expr = maybe_variable (gnu_expr);
@@ -2598,7 +2596,16 @@ gnat_to_gnu (Node_Id gnat_node)
pop_stack (&gnu_return_label_stack);
if (!type_annotate_only)
- add_decl_stmt (current_function_decl, gnat_node);
+ add_decl_expr (current_function_decl, gnat_node);
+
+ /* Initialize the information node for the function and set the
+ end location. */
+ allocate_struct_function (current_function_decl);
+ Sloc_to_locus
+ ((Present (End_Label (Handled_Statement_Sequence (gnat_node)))
+ ? Sloc (End_Label (Handled_Statement_Sequence (gnat_node)))
+ : Sloc (gnat_node)),
+ &cfun->function_end_locus);
end_subprog_body (gnu_result);
@@ -3284,8 +3291,8 @@ gnat_to_gnu (Node_Id gnat_node)
NULL_TREE, jmpbuf_type,
NULL_TREE, 0, 0, 0, 0, 0);
- add_decl_stmt (gnu_jmpsave_decl, gnat_node);
- add_decl_stmt (gnu_jmpbuf_decl, gnat_node);
+ add_decl_expr (gnu_jmpsave_decl, gnat_node);
+ add_decl_expr (gnu_jmpbuf_decl, gnat_node);
set_block_jmpbuf_decl (gnu_jmpbuf_decl);
/* When we exit this block, restore the saved value. */
@@ -3334,7 +3341,7 @@ gnat_to_gnu (Node_Id gnat_node)
build_pointer_type (except_type_node),
build_call_0_expr (get_excptr_decl),
0, 0, 0, 0, 0));
- add_decl_stmt (TREE_VALUE (gnu_except_ptr_stack), gnat_node);
+ add_decl_expr (TREE_VALUE (gnu_except_ptr_stack), gnat_node);
/* Generate code for each handler. The N_Exception_Handler case
below does the real work and returns a COND_EXPR for each
@@ -3597,7 +3604,7 @@ gnat_to_gnu (Node_Id gnat_node)
ptr_type_node, gnu_current_exc_ptr,
0, 0, 0, 0, 0);
- add_decl_stmt (gnu_incoming_exc_ptr, gnat_node);
+ add_decl_expr (gnu_incoming_exc_ptr, gnat_node);
add_stmt_with_node (build_call_1_expr (begin_handler_decl,
gnu_incoming_exc_ptr),
gnat_node);
@@ -4023,26 +4030,23 @@ add_stmt (tree gnu_stmt)
{
append_to_statement_list (gnu_stmt, &current_stmt_group->stmt_list);
- /* If this is a DECL_STMT for a variable with DECL_INITIAL set,
- generate the assignment statement too. */
- if (TREE_CODE (gnu_stmt) == DECL_STMT
- && TREE_CODE (DECL_STMT_VAR (gnu_stmt)) == VAR_DECL
- && DECL_INITIAL (DECL_STMT_VAR (gnu_stmt)))
+ /* If this is a DECL_EXPR for a variable with DECL_INITIAL set
+ and decl has a padded type, convert it to the unpadded type so the
+ assignment is done properly. In other case, the gimplification
+ of the DECL_EXPR will deal with DECL_INITIAL. */
+ if (TREE_CODE (gnu_stmt) == DECL_EXPR
+ && TREE_CODE (DECL_EXPR_DECL (gnu_stmt)) == VAR_DECL
+ && DECL_INITIAL (DECL_EXPR_DECL (gnu_stmt))
+ && TREE_CODE (TREE_TYPE (DECL_EXPR_DECL (gnu_stmt))) == RECORD_TYPE
+ && TYPE_IS_PADDING_P (TREE_TYPE (DECL_EXPR_DECL (gnu_stmt))))
{
- tree gnu_decl = DECL_STMT_VAR (gnu_stmt);
- tree gnu_lhs = gnu_decl;
- tree gnu_assign_stmt;
-
- /* If decl has a padded type, convert it to the unpadded type so the
- assignment is done properly. */
- if (TREE_CODE (TREE_TYPE (gnu_lhs)) == RECORD_TYPE
- && TYPE_IS_PADDING_P (TREE_TYPE (gnu_lhs)))
- gnu_lhs
- = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_lhs))), gnu_lhs);
-
- gnu_assign_stmt
+ tree gnu_decl = DECL_EXPR_DECL (gnu_stmt);
+ tree gnu_lhs
+ = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_decl))), gnu_decl);
+ tree gnu_assign_stmt
= build_binary_op (MODIFY_EXPR, NULL_TREE,
gnu_lhs, DECL_INITIAL (gnu_decl));
+
DECL_INITIAL (gnu_decl) = 0;
annotate_with_locus (gnu_assign_stmt, DECL_SOURCE_LOCATION (gnu_decl));
@@ -4055,7 +4059,8 @@ add_stmt (tree gnu_stmt)
void
add_stmt_with_node (tree gnu_stmt, Node_Id gnat_node)
{
- annotate_with_node (gnu_stmt, gnat_node);
+ if (Present (gnat_node))
+ annotate_with_node (gnu_stmt, gnat_node);
add_stmt (gnu_stmt);
}
@@ -4063,7 +4068,7 @@ add_stmt_with_node (tree gnu_stmt, Node_Id gnat_node)
Get SLOC from Entity_Id. */
void
-add_decl_stmt (tree gnu_decl, Entity_Id gnat_entity)
+add_decl_expr (tree gnu_decl, Entity_Id gnat_entity)
{
/* If this is a variable that Gigi is to ignore, we may have been given
an ERROR_MARK. So test for it. We also might have been given a
@@ -4074,7 +4079,7 @@ add_decl_stmt (tree gnu_decl, Entity_Id gnat_entity)
&& TREE_CODE (TREE_TYPE (gnu_decl)) == UNCONSTRAINED_ARRAY_TYPE))
return;
- add_stmt_with_node (build (DECL_STMT, void_type_node, gnu_decl),
+ add_stmt_with_node (build (DECL_EXPR, void_type_node, gnu_decl),
gnat_entity);
}
@@ -4273,39 +4278,9 @@ gnat_gimplify_stmt (tree *stmt_p)
return GS_OK;
case USE_STMT:
- *stmt_p = alloc_stmt_list ();
+ *stmt_p = NULL_TREE;
return GS_ALL_DONE;
- case DECL_STMT:
- {
- tree var = DECL_STMT_VAR (stmt);
-
- *stmt_p = NULL_TREE;
- if (TREE_CODE (var) == TYPE_DECL)
- gimplify_type_sizes (TREE_TYPE (var), stmt_p);
- else if (TREE_CODE (var) == VAR_DECL)
- {
- gimplify_one_sizepos (&DECL_SIZE (var), stmt_p);
- gimplify_one_sizepos (&DECL_SIZE_UNIT (var), stmt_p);
-
- if (!DECL_EXTERNAL (var) && !TREE_CONSTANT (DECL_SIZE_UNIT (var)))
- {
- DECL_DEFER_OUTPUT (var) = 1;
- append_to_statement_list
- (build_function_call_expr
- (implicit_built_in_decls[BUILT_IN_STACK_ALLOC],
- tree_cons (NULL_TREE,
- build1 (ADDR_EXPR,
- build_pointer_type (TREE_TYPE (var)),
- var),
- tree_cons (NULL_TREE, DECL_SIZE_UNIT (var),
- NULL_TREE))),
- stmt_p);
- }
- }
- return GS_ALL_DONE;
- }
-
case LOOP_STMT:
{
tree gnu_start_label = create_artificial_label ();
@@ -5493,9 +5468,20 @@ gnat_stabilize_reference_1 (tree e, int force)
case 's':
case 'e':
case 'r':
- if (TREE_SIDE_EFFECTS (e) || force)
+ /* If this is a COMPONENT_REF of a fat pointer, save the entire
+ fat pointer. This may be more efficient, but will also allow
+ us to more easily find the match for the PLACEHOLDER_EXPR. */
+ if (code == COMPONENT_REF
+ && TYPE_FAT_POINTER_P (TREE_TYPE (TREE_OPERAND (e, 0))))
+ result = build (COMPONENT_REF, type,
+ gnat_stabilize_reference_1 (TREE_OPERAND (e, 0),
+ force),
+ TREE_OPERAND (e, 1), TREE_OPERAND (e, 2));
+ else if (TREE_SIDE_EFFECTS (e) || force)
return save_expr (e);
- return e;
+ else
+ return e;
+ break;
case 'c':
/* Constants need no processing. In fact, we should never reach
diff --git a/gcc/ada/utils.c b/gcc/ada/utils.c
index 7619b4a0e57..53823e8f2f6 100644
--- a/gcc/ada/utils.c
+++ b/gcc/ada/utils.c
@@ -365,8 +365,12 @@ pushdecl (tree decl)
that are part of sizes and positions. */
if (global_bindings_p () && TREE_CODE (decl) != PARM_DECL)
{
+ /* Make a DECL_EXPR so we'll walk into the appropriate fields of
+ the type or decl. */
+ tree decl_expr = build1 (DECL_EXPR, void_type_node, decl);
+
DECL_CONTEXT (decl) = 0;
- walk_tree (&decl, mark_visited, NULL, NULL);
+ walk_tree (&decl_expr, mark_visited, NULL, NULL);
}
else
DECL_CONTEXT (decl) = current_function_decl;
@@ -1271,6 +1275,7 @@ create_index_type (tree min, tree max, tree index)
type = copy_type (type);
SET_TYPE_INDEX_TYPE (type, index);
+ add_decl_expr (create_type_decl (NULL_TREE, type, NULL, 1, 0), Empty);
return type;
}
@@ -1899,9 +1904,6 @@ end_subprog_body (tree body)
DECL_INLINE (fndecl)
= DECL_DECLARED_INLINE_P (fndecl) || flag_inline_trees == 2;
- /* Initialize the RTL code for the function. */
- allocate_struct_function (fndecl);
-
/* We handle pending sizes via the elaboration of types, so we don't
need to save them. */
get_pending_sizes ();
@@ -1912,6 +1914,7 @@ end_subprog_body (tree body)
DECL_SAVED_TREE (fndecl) = body;
current_function_decl = DECL_CONTEXT (fndecl);
+ cfun = NULL;
/* If we're only annotating types, don't actually compile this function. */
if (type_annotate_only)