This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[lto][patch] Don't write DECL_CONTEXT of PARM_DECL.
- From: Rafael Espindola <espindola at google dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: Diego Novillo <dnovillo at google dot com>
- Date: Mon, 26 Jan 2009 22:42:07 +0000
- Subject: [lto][patch] Don't write DECL_CONTEXT of PARM_DECL.
2009-01-26 Rafael Avila de Espindola <espindola@google.com>
* c-decl.c (merge_decls): Make sure newdecl and olddecl don't
share the arugment list.
* lto-function-in.c (input_function_decl): Pass the context
while reading the arguments.
(input_parm_decl): Add the FN argument. Set the contetxt to it.
(input_tree_operand): Update call to input_parm_decl.
* lto-function-out.c (output_function_decl): Pass the context
while writting the arguments.
(output_parm_decl): Add the FN argument. Check that it is
equal to the context.
(output_tree_with_context): Update the call to ouput_parm_decl.
* tree.c (free_lang_data_in_decl): Force every PARM_DECL to
point the the correct FUNCTION_DECL.
Cheers,
--
Rafael Avila de Espindola
Google | Gordon House | Barrow Street | Dublin 4 | Ireland
Registered in Dublin, Ireland | Registration Number: 368047
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index bda46dc..df014a0 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -1782,12 +1782,17 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
/* Also preserve various other info from the definition. */
if (!new_is_definition)
{
+ tree t;
DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
DECL_STRUCT_FUNCTION (newdecl) = DECL_STRUCT_FUNCTION (olddecl);
DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl);
gimple_set_body (newdecl, gimple_body (olddecl));
- DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
+ DECL_ARGUMENTS (newdecl) = copy_list (DECL_ARGUMENTS (olddecl));
+
+ for (t = DECL_ARGUMENTS (newdecl); t ; t = TREE_CHAIN (t))
+ DECL_CONTEXT (t) = newdecl;
+
/* See if we've got a function to instantiate from. */
if (DECL_SAVED_TREE (olddecl))
@@ -1809,6 +1814,9 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
{
unsigned olddecl_uid = DECL_UID (olddecl);
tree olddecl_context = DECL_CONTEXT (olddecl);
+ tree olddecl_arguments;
+ if (TREE_CODE (olddecl) == FUNCTION_DECL)
+ olddecl_arguments = DECL_ARGUMENTS (olddecl);
memcpy ((char *) olddecl + sizeof (struct tree_common),
(char *) newdecl + sizeof (struct tree_common),
@@ -1839,6 +1847,9 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
}
DECL_UID (olddecl) = olddecl_uid;
DECL_CONTEXT (olddecl) = olddecl_context;
+ if (TREE_CODE (olddecl) == FUNCTION_DECL)
+ DECL_ARGUMENTS (olddecl) = olddecl_arguments;
+
}
/* If OLDDECL had its DECL_RTL instantiated, re-invoke make_decl_rtl
diff --git a/gcc/lto-function-in.c b/gcc/lto-function-in.c
index 92d65db..79ac442 100644
--- a/gcc/lto-function-in.c
+++ b/gcc/lto-function-in.c
@@ -2583,7 +2583,7 @@ input_function_decl (struct lto_input_block *ib, struct data_in *data_in)
decl->decl_common.size_unit = input_tree (ib, data_in);
/* saved_tree -- this is a function body, so omit it here */
- decl->decl_non_common.arguments = input_tree (ib, data_in);
+ decl->decl_non_common.arguments = input_tree_with_context (ib, data_in, decl);
decl->decl_non_common.result = input_tree_with_context (ib, data_in, decl);
decl->decl_non_common.vindex = input_tree (ib, data_in);
@@ -2771,7 +2771,7 @@ input_var_decl (struct lto_input_block *ib, struct data_in *data_in)
}
static tree
-input_parm_decl (struct lto_input_block *ib, struct data_in *data_in)
+input_parm_decl (struct lto_input_block *ib, struct data_in *data_in, tree fn)
{
tree decl = make_node (PARM_DECL);
@@ -2784,12 +2784,12 @@ input_parm_decl (struct lto_input_block *ib, struct data_in *data_in)
/* omit locus, uid */
decl->decl_minimal.name = input_tree (ib, data_in);
- decl->decl_minimal.context = input_tree (ib, data_in);
+ decl->decl_minimal.context = fn;
decl->common.type = input_tree (ib, data_in);
decl->decl_common.attributes = input_tree (ib, data_in);
- decl->decl_common.abstract_origin = input_tree (ib, data_in);
+ decl->decl_common.abstract_origin = NULL_TREE;
decl->decl_common.mode = lto_input_uleb128 (ib);
decl->decl_common.align = lto_input_uleb128 (ib);
@@ -2803,7 +2803,7 @@ input_parm_decl (struct lto_input_block *ib, struct data_in *data_in)
/* lang_specific */
/* omit rtl, incoming_rtl */
- decl->common.chain = input_tree (ib, data_in);
+ decl->common.chain = input_tree_with_context (ib, data_in, fn);
LTO_DEBUG_TOKEN ("end_parm_decl");
@@ -3327,7 +3327,7 @@ input_tree_operand (struct lto_input_block *ib, struct data_in *data_in,
case PARM_DECL:
/* These should be dummy parameters in extern declarations, etc. */
- result = input_parm_decl (ib, data_in);
+ result = input_parm_decl (ib, data_in, fn);
break;
case RESULT_DECL:
diff --git a/gcc/lto-function-out.c b/gcc/lto-function-out.c
index 7c0f610..cef2af4 100644
--- a/gcc/lto-function-out.c
+++ b/gcc/lto-function-out.c
@@ -2541,7 +2541,7 @@ output_function_decl (struct output_block *ob, tree decl)
/* omit rtl */
/* saved_tree -- this is a function body, so omit it here */
- output_tree (ob, decl->decl_non_common.arguments);
+ output_tree_with_context (ob, decl->decl_non_common.arguments, decl);
output_tree_with_context (ob, decl->decl_non_common.result, decl);
output_tree (ob, decl->decl_non_common.vindex);
@@ -2639,7 +2639,7 @@ output_var_decl (struct output_block *ob, tree decl)
}
static void
-output_parm_decl (struct output_block *ob, tree decl)
+output_parm_decl (struct output_block *ob, tree decl, tree fn)
{
/* tag and flags */
output_global_record_start (ob, NULL, NULL, LTO_parm_decl);
@@ -2649,12 +2649,11 @@ output_parm_decl (struct output_block *ob, tree decl)
/* uid and locus are handled specially */
output_tree (ob, decl->decl_minimal.name);
- output_tree (ob, decl->decl_minimal.context);
-
+ gcc_assert (decl->decl_minimal.context == fn);
+
output_tree (ob, decl->common.type);
output_tree (ob, decl->decl_common.attributes);
- output_tree (ob, decl->decl_common.abstract_origin);
output_uleb128 (ob, decl->decl_common.mode);
output_uleb128 (ob, decl->decl_common.align);
@@ -2668,7 +2667,7 @@ output_parm_decl (struct output_block *ob, tree decl)
/* lang_specific */
/* omit rtl, incoming_rtl */
- output_tree (ob, decl->common.chain);
+ output_tree_with_context (ob, decl->common.chain, fn);
LTO_DEBUG_TOKEN ("end_parm_decl");
}
@@ -3216,7 +3215,7 @@ output_tree_with_context (struct output_block *ob, tree expr, tree fn)
break;
case PARM_DECL:
- output_parm_decl (ob, expr);
+ output_parm_decl (ob, expr, fn);
break;
case RESULT_DECL:
diff --git a/gcc/tree.c b/gcc/tree.c
index ae0b7e4..5f8a275 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -3959,7 +3959,7 @@ free_lang_data_in_decl (tree decl)
if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL)
DECL_CONTEXT (decl) = NULL_TREE;
- if (TREE_CODE (decl) == PARM_DECL || TREE_CODE (decl) == VAR_DECL)
+ if (TREE_CODE (decl) == VAR_DECL)
{
tree context = DECL_CONTEXT (decl);
@@ -3989,8 +3989,11 @@ free_lang_data_in_decl (tree decl)
else if (TREE_CODE (decl) == FUNCTION_DECL)
{
tree context = DECL_CONTEXT (decl);
+ tree t;
if (context && TREE_CODE (context) == FUNCTION_DECL)
DECL_CONTEXT (decl) = NULL_TREE;
+ for (t = DECL_ARGUMENTS (decl); t ; t = TREE_CHAIN (t))
+ DECL_CONTEXT (t) = decl;
}
else if (TREE_CODE (decl) == VAR_DECL)
{