summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/integrate.c45
-rw-r--r--gcc/print-tree.c4
-rw-r--r--gcc/tree.h21
3 files changed, 62 insertions, 8 deletions
diff --git a/gcc/integrate.c b/gcc/integrate.c
index 743a0c28380..88227412265 100644
--- a/gcc/integrate.c
+++ b/gcc/integrate.c
@@ -66,6 +66,7 @@ static rtx copy_for_inline ();
static void copy_decl_rtls ();
static tree copy_decl_tree ();
+static tree copy_decl_list ();
/* Return the constant equivalent of a given rtx, or 0 if none. */
static rtx const_equiv ();
@@ -479,11 +480,15 @@ save_for_inline_copying (fndecl)
whose space has been freed. */
DECL_INITIAL (fndecl) = copy_decl_tree (DECL_INITIAL (fndecl));
+ DECL_ARGUMENTS (fndecl) = copy_decl_list (DECL_ARGUMENTS (fndecl));
/* Now copy each DECL_RTL which is a MEM,
so it is safe to modify their addresses. */
copy_decl_rtls (DECL_INITIAL (fndecl));
+ /* The fndecl node acts as its own progenitor, so mark it as such. */
+ DECL_ABSTRACT_ORIGIN (fndecl) = fndecl;
+
/* Now copy the chain of insns. Do this twice. The first copy the insn
itself and its body. The second time copy of REG_NOTES. This is because
a REG_NOTE may have a forward pointer to another insn. */
@@ -550,6 +555,40 @@ save_for_inline_copying (fndecl)
set_new_first_and_last_insn (first_insn, last_insn);
}
+/* Return a copy of a chain of nodes, chained through the TREE_CHAIN field.
+ For example, this can copy a list made of TREE_LIST nodes. While copying,
+ for each node copied which doesn't already have is DECL_ABSTRACT_ORIGIN
+ set to some non-zero value, set the DECL_ABSTRACT_ORIGIN of the copy to
+ point to the corresponding (abstract) original node. */
+
+static tree
+copy_decl_list (list)
+ tree list;
+{
+ tree head;
+ register tree prev, next;
+
+ if (list == 0)
+ return 0;
+
+ head = prev = copy_node (list);
+ if (DECL_ABSTRACT_ORIGIN (head) == NULL_TREE)
+ DECL_ABSTRACT_ORIGIN (head) = list;
+ next = TREE_CHAIN (list);
+ while (next)
+ {
+ register tree copy;
+
+ copy = copy_node (next);
+ if (DECL_ABSTRACT_ORIGIN (copy) == NULL_TREE)
+ DECL_ABSTRACT_ORIGIN (copy) = next;
+ TREE_CHAIN (prev) = copy;
+ prev = copy;
+ next = TREE_CHAIN (next);
+ }
+ return head;
+}
+
/* Make a copy of the entire tree of blocks BLOCK, and return it. */
static tree
@@ -558,7 +597,7 @@ copy_decl_tree (block)
{
tree t, vars, subblocks;
- vars = copy_list (BLOCK_VARS (block));
+ vars = copy_decl_list (BLOCK_VARS (block));
subblocks = 0;
/* Process all subblocks. */
@@ -1655,7 +1694,7 @@ integrate_parm_decls (args, map, arg_vector)
/* These args would always appear unused, if not for this. */
TREE_USED (decl) = 1;
/* Prevent warning for shadowing with these. */
- DECL_FROM_INLINE (decl) = 1;
+ DECL_ABSTRACT_ORIGIN (decl) = tail;
pushdecl (decl);
/* Fully instantiate the address with the equivalent form so that the
debugging information contains the actual register, instead of the
@@ -1715,7 +1754,7 @@ integrate_decl_tree (let, level, map)
/* These args would always appear unused, if not for this. */
TREE_USED (d) = 1;
/* Prevent warning for shadowing with these. */
- DECL_FROM_INLINE (d) = 1;
+ DECL_ABSTRACT_ORIGIN (d) = t;
pushdecl (d);
}
diff --git a/gcc/print-tree.c b/gcc/print-tree.c
index 27d1591a541..b7c9e660d23 100644
--- a/gcc/print-tree.c
+++ b/gcc/print-tree.c
@@ -329,8 +329,6 @@ print_node (file, prefix, node, indent)
fputs (" bit-field", file);
if (DECL_VIRTUAL_P (node))
fputs (" virtual", file);
- if (DECL_FROM_INLINE (node))
- fputs (" from_inline", file);
if (DECL_IGNORED_P (node))
fputs (" ignored", file);
if (DECL_IN_SYSTEM_HEADER (node))
@@ -368,6 +366,8 @@ print_node (file, prefix, node, indent)
if (TREE_CODE (node) == FIELD_DECL)
print_node (file, "bitpos", DECL_FIELD_BITPOS (node), indent + 4);
print_node_brief (file, "context", DECL_CONTEXT (node), indent + 4);
+ print_node_brief (file, "abstract_origin",
+ DECL_ABSTRACT_ORIGIN (node), indent + 4);
print_node (file, "arguments", DECL_ARGUMENTS (node), indent + 4);
print_node (file, "result", DECL_RESULT (node), indent + 4);
diff --git a/gcc/tree.h b/gcc/tree.h
index e632cdca841..72ef3f6f1fd 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -725,14 +725,28 @@ struct tree_type
/* Every ..._DECL node gets a unique number. */
#define DECL_UID(NODE) ((NODE)->decl.uid)
-/* Nonzero in a VAR_DECL or PARM_DECL means this decl was made by inlining;
+/* For any sort of a ..._DECL node, this points to the original (abstract)
+ decl node which this decl is an instance of, or else it is NULL indicating
+ that this decl is not an instance of some other decl. */
+#define DECL_ABSTRACT_ORIGIN(NODE) ((NODE)->decl.abstract_origin)
+
+/* Nonzero for any sort of ..._DECL node means this decl node represents
+ an inline instance of some original (abstract) decl from an inline function;
suppress any warnings about shadowing some other variable. */
-#define DECL_FROM_INLINE(NODE) ((NODE)->decl.from_inline_flag)
+#define DECL_FROM_INLINE(NODE) (DECL_ABSTRACT_ORIGIN (NODE) != (tree) 0)
/* Nonzero if a _DECL means that the name of this decl should be ignored
for symbolic debug purposes. */
#define DECL_IGNORED_P(NODE) ((NODE)->decl.ignored_flag)
+/* Nonzero for a given ..._DECL node means that this node represents an
+ "abstract instance" of the given declaration (e.g. in the original
+ declaration of an inline function). When generating symbolic debugging
+ information, we musn't try to generate any address information for nodes
+ marked as "abstract instances" because we don't actually generate
+ any code or allocate any data space for such instances. */
+#define DECL_ABSTRACT(NODE) ((NODE)->decl.abstract_flag)
+
/* Nonzero if a _DECL means that no warnings should be generated just
because this decl is unused. */
#define DECL_IN_SYSTEM_HEADER(NODE) ((NODE)->decl.in_system_header_flag)
@@ -812,8 +826,8 @@ struct tree_decl
unsigned inline_flag : 1;
unsigned bit_field_flag : 1;
unsigned virtual_flag : 1;
- unsigned from_inline_flag : 1;
unsigned ignored_flag : 1;
+ unsigned abstract_flag : 1;
unsigned in_system_header_flag : 1;
/* room for seven more */
@@ -832,6 +846,7 @@ struct tree_decl
union tree_node *arguments;
union tree_node *result;
union tree_node *initial;
+ union tree_node *abstract_origin;
/* The PRINT_NAME field is marked for death. */
char *print_name;
union tree_node *assembler_name;