------- 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