From 97a424bca4aecf4deb54e28fd7a1f93dc0e1f2e7 Mon Sep 17 00:00:00 2001 From: dannysmith Date: Thu, 24 May 2007 10:11:49 +0000 Subject: [PATCH] ChangeLog PR target/27067 * doc/tm.texi (TARGET_MANGLE_DECL_ASSEMBLER_NAME): Document. * targhooks.h (default_mangle_decl_assembler_name): Declare default hook. * targhooks.c (default_mangle_decl_assembler_name): Define default hook. * target-def.h (TARGET_MANGLE_DECL_ASSEMBLER_NAME) New. Set to default hook. * target.h (struct gcc_target): Add mangle_decl_assembler_name field. * langhooks.c (lhd_set_decl_assembler_name): Call targetm.mangle_decl_assembler_name for names with global scope. * config/i386/cygming.h (TARGET_MANGLE_DECL_ASSEMBLER_NAME) Override default. (ASM_OUTPUT_DEF_FROM_DECLS): Simplify to use DECL_ASSEMBLER_NAME. * config/i386/i386-protos.h (i386_pe_mangle_decl_assembler_name): Declare. * config/i386/winnt.c (i386_pe_maybe_mangle_decl_assembler_name): New. Factored out of i386_pe_encode_section_info. (gen_stdcall_or_fastcall_suffix): Get name identifier as argument. Move check for prior decoration of stdcall symbols to i386_pe_encode_section_info. (i386_pe_encode_section_info): Adjust call to gen_stdcall_or_fastcall_suffix. Use i386_pe_maybe_mangle_decl_assembler_name, if needed. (i386_pe_mangle_decl_assembler_name): New. Wrap i386_pe_maybe_mangle_decl_assembler_name. cp/ChangeLog * mangle.c (mangle_decl): Call targetm.mangle_decl_assembler_name. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@125020 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 30 +++++++++++++++ gcc/config/i386/cygming.h | 13 +++---- gcc/config/i386/i386-protos.h | 3 +- gcc/config/i386/winnt.c | 85 ++++++++++++++++++++++++++++++------------- gcc/cp/ChangeLog | 5 +++ gcc/cp/mangle.c | 5 ++- gcc/doc/tm.texi | 10 +++++ gcc/langhooks.c | 16 ++++++-- gcc/target-def.h | 5 +++ gcc/target.h | 6 +++ gcc/targhooks.c | 7 ++++ gcc/targhooks.h | 3 +- 12 files changed, 146 insertions(+), 42 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6422382491a..3dbc238641d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,33 @@ +2007-05-24 Danny Smith + + PR target/27067 + * doc/tm.texi (TARGET_MANGLE_DECL_ASSEMBLER_NAME): Document. + * targhooks.h (default_mangle_decl_assembler_name): Declare + default hook. + * targhooks.c (default_mangle_decl_assembler_name): Define + default hook. + * target-def.h (TARGET_MANGLE_DECL_ASSEMBLER_NAME) New. Set to + default hook. + * target.h (struct gcc_target): Add mangle_decl_assembler_name field. + * langhooks.c (lhd_set_decl_assembler_name): Call + targetm.mangle_decl_assembler_name for names with global scope. + + * config/i386/cygming.h (TARGET_MANGLE_DECL_ASSEMBLER_NAME) Override + default. + (ASM_OUTPUT_DEF_FROM_DECLS): Simplify to use DECL_ASSEMBLER_NAME. + * config/i386/i386-protos.h (i386_pe_mangle_decl_assembler_name): + Declare. + * config/i386/winnt.c (i386_pe_maybe_mangle_decl_assembler_name): + New. Factored out of i386_pe_encode_section_info. + (gen_stdcall_or_fastcall_suffix): Get name identifier as argument. + Move check for prior decoration of stdcall + symbols to i386_pe_encode_section_info. + (i386_pe_encode_section_info): Adjust call to + gen_stdcall_or_fastcall_suffix. Use + i386_pe_maybe_mangle_decl_assembler_name, if needed. + (i386_pe_mangle_decl_assembler_name): New. Wrap + i386_pe_maybe_mangle_decl_assembler_name. + 2007-05-16 Rafael Avila de Espindola * c-common.c (c_common_signed_or_unsigned_type): Delay the check for diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h index f7e8febb16e..9ce11b2dbe1 100644 --- a/gcc/config/i386/cygming.h +++ b/gcc/config/i386/cygming.h @@ -1,7 +1,7 @@ /* Operating system specific defines to be used when targeting GCC for hosting on Windows32, using a Unix style C library and tools. Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, - 2004, 2005 + 2004, 2005, 2007 Free Software Foundation, Inc. This file is part of GCC. @@ -347,15 +347,11 @@ do { \ /* This implements the `alias' attribute, keeping any stdcall or fastcall decoration. */ #undef ASM_OUTPUT_DEF_FROM_DECLS -#define ASM_OUTPUT_DEF_FROM_DECLS(STREAM, DECL, TARGET) \ +#define ASM_OUTPUT_DEF_FROM_DECLS(STREAM, DECL, TARGET) \ do \ { \ - const char *alias; \ - rtx rtlname = XEXP (DECL_RTL (DECL), 0); \ - if (GET_CODE (rtlname) == SYMBOL_REF) \ - alias = XSTR (rtlname, 0); \ - else \ - abort (); \ + const char *alias \ + = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL)); \ if (TREE_CODE (DECL) == FUNCTION_DECL) \ i386_pe_declare_function_type (STREAM, alias, \ TREE_PUBLIC (DECL)); \ @@ -394,6 +390,7 @@ do { \ #define TARGET_VALID_DLLIMPORT_ATTRIBUTE_P i386_pe_valid_dllimport_attribute_p #define TARGET_CXX_ADJUST_CLASS_AT_DEFINITION i386_pe_adjust_class_at_definition +#define TARGET_MANGLE_DECL_ASSEMBLER_NAME i386_pe_mangle_decl_assembler_name #undef TREE diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 3dca7c587a6..2f320391943 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -1,6 +1,6 @@ /* Definitions of target machine for GCC for IA-32. Copyright (C) 1988, 1992, 1994, 1995, 1996, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006 + 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This file is part of GCC. @@ -220,6 +220,7 @@ extern void i386_pe_asm_output_aligned_decl_common (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT); extern void i386_pe_file_end (void); +extern tree i386_pe_mangle_decl_assembler_name (tree, tree); /* In winnt-cxx.c and winnt-stubs.c */ extern void i386_pe_adjust_class_at_definition (tree); diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c index 0d79fb1344a..6ef658671e6 100644 --- a/gcc/config/i386/winnt.c +++ b/gcc/config/i386/winnt.c @@ -1,7 +1,7 @@ /* Subroutines for insn-output.c for Windows NT. Contributed by Douglas Rupp (drupp@cs.washington.edu) Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006 Free Software Foundation, Inc. + 2005, 2006, 2007 Free Software Foundation, Inc. This file is part of GCC. @@ -75,7 +75,7 @@ ix86_handle_selectany_attribute (tree *node, tree name, /* The attribute applies only to objects that are initialized and have external linkage. However, we may not know about initialization until the language frontend has processed the decl. We'll check for - initialization later in encode_section_info. */ + initialization later in encode_section_info. */ if (TREE_CODE (*node) != VAR_DECL || !TREE_PUBLIC (*node)) { error ("%qs attribute applies only to initialized variables" @@ -154,22 +154,21 @@ i386_pe_valid_dllimport_attribute_p (tree decl) return true; } -/* Return string which is the former assembler name modified with a - suffix consisting of an atsign (@) followed by the number of bytes of - arguments. If FASTCALL is true, also add the FASTCALL_PREFIX. +/* Return string which is the function name, identified by ID, modified + with a suffix consisting of an atsign (@) followed by the number of + bytes of arguments. If ID is NULL use the DECL_NAME as base. If + FASTCALL is true, also add the FASTCALL_PREFIX. Return NULL if no change required. */ static tree -gen_stdcall_or_fastcall_suffix (tree decl, bool fastcall) +gen_stdcall_or_fastcall_suffix (tree decl, tree id, bool fastcall) { HOST_WIDE_INT total = 0; - const char *asm_str = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); + const char *old_str = IDENTIFIER_POINTER (id != NULL_TREE ? id : DECL_NAME (decl)); char *new_str, *p; tree formal_type; - /* Do not change the identifier if a verbatim asmspec or already done. */ - if (*asm_str == '*' || strchr (asm_str, '@')) - return NULL_TREE; + gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl)); if (formal_type != NULL_TREE) @@ -202,16 +201,47 @@ gen_stdcall_or_fastcall_suffix (tree decl, bool fastcall) formal_type = TREE_CHAIN (formal_type); } - /* Assume max of 8 base 10 digits in the suffix. */ - p = new_str = alloca (1 + strlen (asm_str) + 1 + 8 + 1); + p = new_str = alloca (1 + strlen (old_str) + 1 + 8 + 1); if (fastcall) *p++ = FASTCALL_PREFIX; - sprintf (p, "%s@" HOST_WIDE_INT_PRINT_DEC, asm_str, total); + sprintf (p, "%s@" HOST_WIDE_INT_PRINT_DEC, old_str, total); return get_identifier (new_str); } +/* Maybe decorate and get a new identifier for the DECL of a stdcall or + fastcall function. The original identifier is supplied in ID. */ + +static tree +i386_pe_maybe_mangle_decl_assembler_name (tree decl, tree id) +{ + tree new_id = NULL_TREE; + + if (TREE_CODE (decl) == FUNCTION_DECL) + { + tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl)); + if (lookup_attribute ("stdcall", type_attributes)) + new_id = gen_stdcall_or_fastcall_suffix (decl, id, false); + else if (lookup_attribute ("fastcall", type_attributes)) + new_id = gen_stdcall_or_fastcall_suffix (decl, id, true); + } + + return new_id; +} + +/* This is used as a target hook to modify the DECL_ASSEMBLER_NAME + in the language-independent default hook + langhooks,c:lhd_set_decl_assembler_name () + and in cp/mangle,c:mangle_decl (). */ +tree +i386_pe_mangle_decl_assembler_name (tree decl, tree id) +{ + tree new_id = i386_pe_maybe_mangle_decl_assembler_name (decl, id); + + return (new_id ? new_id : id); +} + void i386_pe_encode_section_info (tree decl, rtx rtl, int first) { @@ -233,21 +263,24 @@ i386_pe_encode_section_info (tree decl, rtx rtl, int first) case FUNCTION_DECL: if (first) { - tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl)); - tree newid = NULL_TREE; - - if (lookup_attribute ("stdcall", type_attributes)) - newid = gen_stdcall_or_fastcall_suffix (decl, false); - else if (lookup_attribute ("fastcall", type_attributes)) - newid = gen_stdcall_or_fastcall_suffix (decl, true); - if (newid != NULL_TREE) + /* FIXME: In Ada, and perhaps other language frontends, + imported stdcall names may not yet have been modified. + Check and do it know. */ + tree new_id; + tree old_id = DECL_ASSEMBLER_NAME (decl); + const char* asm_str = IDENTIFIER_POINTER (old_id); + /* Do not change the identifier if a verbatim asmspec + or if stdcall suffix already added. */ + if (*asm_str == '*' || strchr (asm_str, '@')) + break; + if ((new_id = i386_pe_maybe_mangle_decl_assembler_name (decl, old_id))) { - XSTR (symbol, 0) = IDENTIFIER_POINTER (newid); /* These attributes must be present on first declaration, - change_decl_assembler_name will warn if they are added - later and the decl has been referenced, but duplicate_decls - should catch the mismatch before this is called. */ - change_decl_assembler_name (decl, newid); + change_decl_assembler_name will warn if they are added + later and the decl has been referenced, but duplicate_decls + should catch the mismatch first. */ + change_decl_assembler_name (decl, new_id); + XSTR (symbol, 0) = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); } } break; diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index df07249a0dd..7738d1f09b5 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2007-05-24 Danny Smith + + PR target/27067 + * mangle.c (mangle_decl): Call targetm.mangle_decl_assembler_name. + 2007-05-22 Ollie Wild * name-lookup.c (ambiguous_decl): Adds check for hidden types. diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index df5b7d8bab4..3ec02ed7393 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -2621,8 +2621,9 @@ get_identifier_nocopy (const char *name) void mangle_decl (const tree decl) { - SET_DECL_ASSEMBLER_NAME (decl, - get_identifier_nocopy (mangle_decl_string (decl))); + tree id = get_identifier_nocopy (mangle_decl_string (decl)); + id = targetm.mangle_decl_assembler_name (decl, id); + SET_DECL_ASSEMBLER_NAME (decl, id); } /* Generate the mangled representation of TYPE. */ diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 98fe8bbc54d..1dcf73c23d6 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -6462,6 +6462,16 @@ constants in @code{flag_pic} mode in @code{data_section} and everything else in @code{readonly_data_section}. @end deftypefn +@deftypefn {Target Hook} void TARGET_MANGLE_DECL_ASSEMBLER_NAME (tree @var{decl}, tree @var{id}) +Define this hook if you need to postprocess the assembler name generated +by target-independent code. The @var{id} provided to this hook will be +the computed name (e.g., the macro @code{DECL_NAME} of the @var{decl} in C, +or the mangled name of the @var{decl} in C++). The return value of the +hook is an @code{IDENTIFIER_NODE} for the appropriate mangled name on +your target system. The default implementation of this hook just +returns the @var{id} provided. +@end deftypefn + @deftypefn {Target Hook} void TARGET_ENCODE_SECTION_INFO (tree @var{decl}, rtx @var{rtl}, int @var{new_decl_p}) Define this hook if references to a symbol or a constant must be treated differently depending on something about the variable or diff --git a/gcc/langhooks.c b/gcc/langhooks.c index dc816ba37c5..96234f60e16 100644 --- a/gcc/langhooks.c +++ b/gcc/langhooks.c @@ -34,6 +34,7 @@ Boston, MA 02110-1301, USA. */ #include "integrate.h" #include "flags.h" #include "langhooks.h" +#include "target.h" #include "langhooks-def.h" #include "ggc.h" #include "diagnostic.h" @@ -147,6 +148,8 @@ lhd_warn_unused_global_decl (tree decl) void lhd_set_decl_assembler_name (tree decl) { + tree id; + /* The language-independent code should never use the DECL_ASSEMBLER_NAME for lots of DECLs. Only FUNCTION_DECLs and VAR_DECLs for variables with static storage duration need a real @@ -161,21 +164,26 @@ lhd_set_decl_assembler_name (tree decl) as that used in the source language. (That's correct for C, and GCC used to set DECL_ASSEMBLER_NAME to the same value as DECL_NAME in build_decl, so this choice provides backwards - compatibility with existing front-ends. - + compatibility with existing front-ends. This assumption is wrapped + in a target hook, to allow for target-specific modification of the + identifier. + Can't use just the variable's own name for a variable whose scope is less than the whole compilation. Concatenate a distinguishing number - we use the DECL_UID. */ + if (TREE_PUBLIC (decl) || DECL_CONTEXT (decl) == NULL_TREE) - SET_DECL_ASSEMBLER_NAME (decl, DECL_NAME (decl)); + id = targetm.mangle_decl_assembler_name (decl, DECL_NAME (decl)); else { const char *name = IDENTIFIER_POINTER (DECL_NAME (decl)); char *label; ASM_FORMAT_PRIVATE_NAME (label, name, DECL_UID (decl)); - SET_DECL_ASSEMBLER_NAME (decl, get_identifier (label)); + id = get_identifier (label); } + SET_DECL_ASSEMBLER_NAME (decl, id); + } /* Type promotion for variable arguments. */ diff --git a/gcc/target-def.h b/gcc/target-def.h index 3a17c121543..690a8fdc6d2 100644 --- a/gcc/target-def.h +++ b/gcc/target-def.h @@ -464,6 +464,10 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define TARGET_IN_SMALL_DATA_P hook_bool_tree_false #endif +#ifndef TARGET_MANGLE_DECL_ASSEMBLER_NAME +#define TARGET_MANGLE_DECL_ASSEMBLER_NAME mangle_decl_assembler_name +#endif + #ifndef TARGET_ENCODE_SECTION_INFO #define TARGET_ENCODE_SECTION_INFO default_encode_section_info #endif @@ -681,6 +685,7 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. TARGET_FUNCTION_OK_FOR_SIBCALL, \ TARGET_IN_SMALL_DATA_P, \ TARGET_BINDS_LOCAL_P, \ + TARGET_MANGLE_DECL_ASSEMBLER_NAME, \ TARGET_ENCODE_SECTION_INFO, \ TARGET_STRIP_NAME_ENCODING, \ TARGET_SHIFT_TRUNCATION_MASK, \ diff --git a/gcc/target.h b/gcc/target.h index 476eb8810b1..f769ae0938a 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -544,6 +544,12 @@ struct gcc_target to the current module. */ bool (* binds_local_p) (tree); + /* Modify and return the identifier of a DECL's external name, + originally identified by ID, as required by the target, + (eg, append @nn to windows32 stdcall function names). + The default is to return ID without modification. */ + tree (* mangle_decl_assembler_name) (tree decl, tree id); + /* Do something target-specific to record properties of the DECL into the associated SYMBOL_REF. */ void (* encode_section_info) (tree, rtx, int); diff --git a/gcc/targhooks.c b/gcc/targhooks.c index baad65b0cac..77f624c2990 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -631,4 +631,11 @@ default_reloc_rw_mask (void) return flag_pic ? 3 : 0; } +/* By default, do no modification. */ +tree default_mangle_decl_assembler_name (tree decl ATTRIBUTE_UNUSED, + tree id) +{ + return id; +} + #include "gt-targhooks.h" diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 062d4f0b5b4..1b9bb10ed65 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -1,5 +1,5 @@ /* Default target hook functions. - Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation, Inc. This file is part of GCC. @@ -84,3 +84,4 @@ extern enum reg_class default_secondary_reload (bool, rtx, enum reg_class, extern void hook_void_bitmap (bitmap); extern bool default_handle_c_option (size_t, const char *, int); extern int default_reloc_rw_mask (void); +extern tree default_mangle_decl_assembler_name (tree, tree); -- 2.11.0