------- Comment #1 from dannysmith at users dot sourceforge dot net 2006-04-16
05:14 -------
The DECL_ASSEMBLER_NAMES of these stdcall virtaul methods do not get
decorated in time for cp/method.c:make_alias_for_thunk.
(cf this comment in varasm.c: find_decl_and_mark_needed:
/* We can't mark function nodes as used after cgraph global info
is finished. This wouldn't generally be necessary, but C++
virtual table thunks are introduced late in the game and
might seem like they need marking, although in fact they
don't. */
)
Somehow we need to ensure that these methods know what their final
assembler name is. This patch fixes your testcase. Could you test on your
wxwidgets case? I suspect that there are cleaner ways of doing this but
I don't know exactly where we can first safely modify these stdcall and
fastcall names.
Danny
ChangeLog
* target.h (asm_out.change_extern_name): New hook.
* target-def.h (TARGET_ASM_CHANGE_EXTERN_NAME): New define,
defaulting to hook_void_tree. Add to struct asm_out.
* config/i386/cygming.h (TARGET_ASM_CHANGE_EXTERN_NAME): Override
default with i386_pe_decorate_assembler_name.
* config/i386/winnt.c (i386_pe_decorate_assembler_name): New function,
extracted from i386_pe_encode_section_info.
(i386_pe_encode_section_info): Call i386_pe_decorate_assembler_name.
cp/ChangeLog
* method.c (use_thunk): Call asm_out.change_extern_name before making
alias for thunked-to function.
Index: target.h
===================================================================
--- target.h (revision 112968)
+++ target.h (working copy)
@@ -206,6 +206,11 @@
/* Output a DTP-relative reference to a TLS symbol. */
void (*output_dwarf_dtprel) (FILE *file, int size, rtx x);
+ /* This target hook allows the operating system to modify the extern
assembler name
+ of a DECL. For example, windows targets use this to decorate stdcall and
fastcall functions
+ with a a trailing '@n'. */
+ void (*change_extern_name) (tree decl);
+
} asm_out;
/* Functions relating to instruction scheduling. */
Index: target-def.h
===================================================================
--- target-def.h (revision 112968)
+++ target-def.h (working copy)
@@ -221,6 +221,10 @@
#define TARGET_ASM_OUTPUT_DWARF_DTPREL NULL
#endif
+#ifndef TARGET_ASM_CHANGE_EXTERN_NAME
+#define TARGET_ASM_CHANGE_EXTERN_NAME hook_void_tree
+#endif
+
#define TARGET_ASM_ALIGNED_INT_OP \
{TARGET_ASM_ALIGNED_HI_OP, \
TARGET_ASM_ALIGNED_SI_OP, \
@@ -265,7 +269,8 @@
TARGET_ASM_EXTERNAL_LIBCALL, \
TARGET_ASM_MARK_DECL_PRESERVED, \
TARGET_ASM_OUTPUT_ANCHOR, \
- TARGET_ASM_OUTPUT_DWARF_DTPREL}
+ TARGET_ASM_OUTPUT_DWARF_DTPREL, \
+ TARGET_ASM_CHANGE_EXTERN_NAME}
/* Scheduler hooks. All of these default to null pointers, which
haifa-sched.c looks for and handles. */
Index: config/i386/cygming.h
===================================================================
--- config/i386/cygming.h (revision 112968)
+++ config/i386/cygming.h (working copy)
@@ -296,6 +298,7 @@
extern void i386_pe_file_end (void);
extern int i386_pe_dllexport_name_p (const char *);
extern int i386_pe_dllimport_name_p (const char *);
+extern void i386_pe_decorate_assembler_name (tree);
/* For Win32 ABI compatibility */
#undef DEFAULT_PCC_STRUCT_RETURN
@@ -374,6 +377,8 @@
#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_ASM_CHANGE_EXTERN_NAME i386_pe_decorate_assembler_name
+
#undef TREE
#ifndef BUFSIZ
Index: config/i386/winnt.c
===================================================================
--- config/i386/winnt.c (revision 112968)
+++ config/i386/winnt.c (working copy)
@@ -335,33 +335,38 @@
}
void
-i386_pe_encode_section_info (tree decl, rtx rtl, int first)
+i386_pe_decorate_assembler_name (tree decl)
{
- default_encode_section_info (decl, rtl, first);
+ tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl));
+ tree newid = NULL_TREE;
- if (first && TREE_CODE (decl) == FUNCTION_DECL)
+ 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)
{
- tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl));
- tree newid = NULL_TREE;
+ rtx rtlname = XEXP (DECL_RTL (decl), 0);
+ if (GET_CODE (rtlname) == MEM)
+ rtlname = XEXP (rtlname, 0);
+ XSTR (rtlname, 0) = IDENTIFIER_POINTER (newid);
- 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)
- {
- rtx rtlname = XEXP (rtl, 0);
- if (GET_CODE (rtlname) == MEM)
- rtlname = XEXP (rtlname, 0);
- XSTR (rtlname, 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);
- }
+ /* 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);
}
+}
+void
+i386_pe_encode_section_info (tree decl, rtx rtl, int first)
+{
+ default_encode_section_info (decl, rtl, first);
+
+ if (first && TREE_CODE (decl) == FUNCTION_DECL)
+ i386_pe_decorate_assembler_name (decl);
+
/* Mark the decl so we can tell from the rtl whether the object is
dllexport'd or dllimport'd. tree.c: merge_dllimport_decl_attributes
handles dllexport/dllimport override semantics. */
Index: cp/method.c
===================================================================
--- cp/method.c (revision 112968)
+++ cp/method.c (working copy)
@@ -348,13 +348,15 @@
this translation unit. */
TREE_ADDRESSABLE (function) = 1;
mark_used (function);
+ /* The DECL_ASSEMBLER_NAME of the thunked function may need modification.
*/
+ targetm.asm_out.change_extern_name (function);
if (!emit_p)
return;
if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function))
- alias = make_alias_for_thunk (function);
+ alias = make_alias_for_thunk (function);
else
- alias = function;
+ alias = function;
fixed_offset = THUNK_FIXED_OFFSET (thunk_fndecl);
virtual_offset = THUNK_VIRTUAL_OFFSET (thunk_fndecl);
--
dannysmith at users dot sourceforge dot net changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |dannysmith at users dot
| |sourceforge dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27067