diff options
-rw-r--r-- | gcc/integrate.c | 45 | ||||
-rw-r--r-- | gcc/print-tree.c | 4 | ||||
-rw-r--r-- | gcc/tree.h | 21 |
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; |