summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>2014-11-10 16:12:21 +0000
committerbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>2014-11-10 16:12:21 +0000
commit7260826dd33354c89105f1ebfc1a021dfbcbecbf (patch)
tree9c8ca24ffe36df06c483d82a49f4e61dcb15c17e
parent3aa2fa443f8de74ae74fb13ec81ce2edc1b29a82 (diff)
downloadgcc-7260826dd33354c89105f1ebfc1a021dfbcbecbf.tar.gz
Add a target hook for assembling undeclared decls.
* target.def (assemble_undefined_decl): New hooks. * hooks.c (hook_void_FILEptr_constcharptr_const_tree): New function. * hooks.h (hook_void_FILEptr_constcharptr_const_tree): Declare. * doc/tm.texi.in (TARGET_ASM_ASSEMBLE_UNDEFINED_DECL): Add. * doc/tm.texi: Regenerate. * output.h (assemble_undefined_decl): Declare. (get_fnname_from_decl): Declare. * varasm.c (assemble_undefined_decl): New function. (get_fnname_from_decl): New function. * final.c (rest_of_handle_final): Use it. * varpool.c (varpool_output_variables): Call assemble_undefined_decl for nodes without a definition. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@217293 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/doc/tm.texi7
-rw-r--r--gcc/doc/tm.texi.in2
-rw-r--r--gcc/final.c12
-rw-r--r--gcc/hooks.c7
-rw-r--r--gcc/hooks.h2
-rw-r--r--gcc/output.h7
-rw-r--r--gcc/target.def10
-rw-r--r--gcc/varasm.c21
-rw-r--r--gcc/varpool.c3
10 files changed, 73 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c49af15ca6b..4dc83d3f5ad 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -272,6 +272,19 @@
2014-11-06 Bernd Schmidt <bernds@codesourcery.com>
+ * target.def (assemble_undefined_decl): New hooks.
+ * hooks.c (hook_void_FILEptr_constcharptr_const_tree): New function.
+ * hooks.h (hook_void_FILEptr_constcharptr_const_tree): Declare.
+ * doc/tm.texi.in (TARGET_ASM_ASSEMBLE_UNDEFINED_DECL): Add.
+ * doc/tm.texi: Regenerate.
+ * output.h (assemble_undefined_decl): Declare.
+ (get_fnname_from_decl): Declare.
+ * varasm.c (assemble_undefined_decl): New function.
+ (get_fnname_from_decl): New function.
+ * final.c (rest_of_handle_final): Use it.
+ * varpool.c (varpool_output_variables): Call assemble_undefined_decl
+ for nodes without a definition.
+
* target.def (call_args, end_call_args): New hooks.
* hooks.c (hook_void_rtx_tree): New empty function.
* hooks.h (hook_void_rtx_tree): Declare.
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index a55206d6c05..33a5a9744e5 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -7896,6 +7896,13 @@ global; that is, available for reference from other files.
The default implementation uses the TARGET_ASM_GLOBALIZE_LABEL target hook.
@end deftypefn
+@deftypefn {Target Hook} void TARGET_ASM_ASSEMBLE_UNDEFINED_DECL (FILE *@var{stream}, const char *@var{name}, const_tree @var{decl})
+This target hook is a function to output to the stdio stream
+@var{stream} some commands that will declare the name associated with
+@var{decl} which is not defined in the current translation unit. Most
+assemblers do not require anything to be output in this case.
+@end deftypefn
+
@defmac ASM_WEAKEN_LABEL (@var{stream}, @var{name})
A C statement (sans semicolon) to output to the stdio stream
@var{stream} some commands that will make the label @var{name} weak;
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index e0c52c8a37a..068aa31ba32 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -5606,6 +5606,8 @@ You may wish to use @code{ASM_OUTPUT_SIZE_DIRECTIVE} and/or
@hook TARGET_ASM_GLOBALIZE_DECL_NAME
+@hook TARGET_ASM_ASSEMBLE_UNDEFINED_DECL
+
@defmac ASM_WEAKEN_LABEL (@var{stream}, @var{name})
A C statement (sans semicolon) to output to the stdio stream
@var{stream} some commands that will make the label @var{name} weak;
diff --git a/gcc/final.c b/gcc/final.c
index e958a520246..c3805c9e283 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -4468,17 +4468,7 @@ leaf_renumber_regs_insn (rtx in_rtx)
static unsigned int
rest_of_handle_final (void)
{
- rtx x;
- const char *fnname;
-
- /* Get the function's name, as described by its RTL. This may be
- different from the DECL_NAME name used in the source file. */
-
- x = DECL_RTL (current_function_decl);
- gcc_assert (MEM_P (x));
- x = XEXP (x, 0);
- gcc_assert (GET_CODE (x) == SYMBOL_REF);
- fnname = XSTR (x, 0);
+ const char *fnname = get_fnname_from_decl (current_function_decl);
assemble_start_function (current_function_decl, fnname);
final_start_function (get_insns (), asm_out_file, optimize);
diff --git a/gcc/hooks.c b/gcc/hooks.c
index 91e17cd70c2..356c64c9d92 100644
--- a/gcc/hooks.c
+++ b/gcc/hooks.c
@@ -139,6 +139,13 @@ hook_void_FILEptr_constcharptr (FILE *a ATTRIBUTE_UNUSED, const char *b ATTRIBUT
{
}
+/* Generic hook that takes (FILE *, const char *, constr_tree *) and does
+ nothing. */
+void
+hook_void_FILEptr_constcharptr_const_tree (FILE *, const char *, const_tree)
+{
+}
+
/* Generic hook that takes (FILE *, rtx) and returns false. */
bool
hook_bool_FILEptr_rtx_false (FILE *a ATTRIBUTE_UNUSED,
diff --git a/gcc/hooks.h b/gcc/hooks.h
index 4006cad3412..5e4f95b0f0a 100644
--- a/gcc/hooks.h
+++ b/gcc/hooks.h
@@ -70,6 +70,8 @@ extern void hook_void_void (void);
extern void hook_void_constcharptr (const char *);
extern void hook_void_rtx_insn_int (rtx_insn *, int);
extern void hook_void_FILEptr_constcharptr (FILE *, const char *);
+extern void hook_void_FILEptr_constcharptr_const_tree (FILE *, const char *,
+ const_tree);
extern bool hook_bool_FILEptr_rtx_false (FILE *, rtx);
extern void hook_void_rtx_tree (rtx, tree);
extern void hook_void_tree (tree);
diff --git a/gcc/output.h b/gcc/output.h
index f213b996429..e19fdd3f42b 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -178,6 +178,9 @@ extern void default_assemble_visibility (tree, int);
for an `asm' keyword used between functions. */
extern void assemble_asm (tree);
+/* Get the function's name from a decl, as described by its RTL. */
+extern const char *get_fnname_from_decl (tree);
+
/* Output assembler code for the constant pool of a function and associated
with defining the name of the function. DECL describes the function.
NAME is the function's name. For the constant pool, we use the current
@@ -203,6 +206,10 @@ extern void assemble_variable (tree, int, int, int);
into the preinit array. */
extern void assemble_vtv_preinit_initializer (tree);
+/* Assemble everything that is needed for a variable declaration that has
+ no definition in the current translation unit. */
+extern void assemble_undefined_decl (tree);
+
/* Compute the alignment of variable specified by DECL.
DONT_OUTPUT_DATA is from assemble_variable. */
extern void align_variable (tree decl, bool dont_output_data);
diff --git a/gcc/target.def b/gcc/target.def
index d6198ad3569..b2fe47b8066 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -158,6 +158,16 @@ global; that is, available for reference from other files.\n\
The default implementation uses the TARGET_ASM_GLOBALIZE_LABEL target hook.",
void, (FILE *stream, tree decl), default_globalize_decl_name)
+/* Output code that will declare an external variable. */
+DEFHOOK
+(assemble_undefined_decl,
+ "This target hook is a function to output to the stdio stream\n\
+@var{stream} some commands that will declare the name associated with\n\
+@var{decl} which is not defined in the current translation unit. Most\n\
+assemblers do not require anything to be output in this case.",
+ void, (FILE *stream, const char *name, const_tree decl),
+ hook_void_FILEptr_constcharptr_const_tree)
+
/* Output code that will emit a label for unwind info, if this
target requires such labels. Second argument is the decl the
unwind info is associated with, third is a boolean: true if
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 8d857a4bc9a..54611f8fd3f 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -1673,6 +1673,18 @@ decide_function_section (tree decl)
in_cold_section_p = first_function_block_is_cold;
}
+/* Get the function's name, as described by its RTL. This may be
+ different from the DECL_NAME name used in the source file. */
+const char *
+get_fnname_from_decl (tree decl)
+{
+ rtx x = DECL_RTL (decl);
+ gcc_assert (MEM_P (x));
+ x = XEXP (x, 0);
+ gcc_assert (GET_CODE (x) == SYMBOL_REF);
+ return XSTR (x, 0);
+}
+
/* Output assembler code for the constant pool of a function and associated
with defining the name of the function. DECL describes the function.
NAME is the function's name. For the constant pool, we use the current
@@ -2045,6 +2057,15 @@ assemble_variable_contents (tree decl, const char *name,
}
}
+/* Write out assembly for the variable DECL, which is not defined in
+ the current translation unit. */
+void
+assemble_undefined_decl (tree decl)
+{
+ const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
+ targetm.asm_out.assemble_undefined_decl (asm_out_file, name, decl);
+}
+
/* Assemble everything that is needed for a variable or function declaration.
Not used for automatic variables, and not used for function definitions.
Should not be called for variables of incomplete structure type.
diff --git a/gcc/varpool.c b/gcc/varpool.c
index 5bfb0a7c867..ac7abc1be86 100644
--- a/gcc/varpool.c
+++ b/gcc/varpool.c
@@ -707,6 +707,9 @@ symbol_table::output_variables (void)
timevar_push (TV_VAROUT);
+ FOR_EACH_VARIABLE (node)
+ if (!node->definition)
+ assemble_undefined_decl (node->decl);
FOR_EACH_DEFINED_VARIABLE (node)
{
/* Handled in output_in_order. */