From 0d4b5b86f2020986ca74c4c79d425764b563f83f Mon Sep 17 00:00:00 2001 From: Bernd Schmidt Date: Mon, 10 Nov 2014 16:12:21 +0000 Subject: [PATCH] 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. From-SVN: r217293 --- gcc/ChangeLog | 13 +++++++++++++ gcc/doc/tm.texi | 7 +++++++ gcc/doc/tm.texi.in | 2 ++ gcc/final.c | 12 +----------- gcc/hooks.c | 7 +++++++ gcc/hooks.h | 2 ++ gcc/output.h | 7 +++++++ gcc/target.def | 10 ++++++++++ gcc/varasm.c | 21 +++++++++++++++++++++ gcc/varpool.c | 3 +++ 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 + * 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. */ -- 2.30.2