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

Reply via email to