winebuild: Add support for specifying thiscall calling convention.
authorAlexandre Julliard <julliard@winehq.org>
Tue, 24 Aug 2010 13:20:00 +0000 (15:20 +0200)
committerAlexandre Julliard <julliard@winehq.org>
Tue, 24 Aug 2010 14:23:20 +0000 (16:23 +0200)
tools/winebuild/build.h
tools/winebuild/import.c
tools/winebuild/parser.c
tools/winebuild/spec32.c
tools/winebuild/winebuild.man.in

index 85b84276664f4682f6770cd89e0bec8ce082ffaf..ef9196193f03c89c720481b33ad4f2671ee18be2 100644 (file)
@@ -47,6 +47,7 @@ typedef enum
     TYPE_STDCALL,      /* stdcall function (Win32) */
     TYPE_CDECL,        /* cdecl function (Win32) */
     TYPE_VARARGS,      /* varargs function (Win32) */
+    TYPE_THISCALL,     /* thiscall function (Win32 on i386) */
     TYPE_EXTERN,       /* external symbol (Win32) */
     TYPE_NBTYPES
 } ORD_TYPE;
index a221a9dd2283ae01a057945812ea4509ff7b93f3..6a77a3f5eaadddb319a102cc78207b219bb0dc65 100644 (file)
@@ -457,6 +457,7 @@ static void check_undefined_exports( DLLSPEC *spec )
             case TYPE_STDCALL:
             case TYPE_CDECL:
             case TYPE_VARARGS:
+            case TYPE_THISCALL:
                 if (link_ext_symbols)
                 {
                     odp->flags |= FLAG_EXT_LINK;
index f48471c8c5006f2a66e0732291fd27a0543715ce..459bf97dc9a0a1e2b391ad1742a62f9606e0d477 100644 (file)
@@ -56,6 +56,7 @@ static const char * const TypeNames[TYPE_NBTYPES] =
     "stdcall",      /* TYPE_STDCALL */
     "cdecl",        /* TYPE_CDECL */
     "varargs",      /* TYPE_VARARGS */
+    "thiscall",     /* TYPE_THISCALL */
     "extern"        /* TYPE_EXTERN */
 };
 
@@ -235,6 +236,11 @@ static int parse_spec_export( ORDDEF *odp, DLLSPEC *spec )
         error( "'stdcall' not supported for Win16\n" );
         return 0;
     }
+    if (!is_win32 && odp->type == TYPE_THISCALL)
+    {
+        error( "'thiscall' not supported for Win16\n" );
+        return 0;
+    }
     if (is_win32 && odp->type == TYPE_PASCAL)
     {
         error( "'pascal' not supported for Win32\n" );
@@ -325,6 +331,12 @@ static int parse_spec_export( ORDDEF *odp, DLLSPEC *spec )
             odp->flags |= FLAG_FORWARD;
         }
     }
+    if (target_cpu == CPU_x86 && odp->type == TYPE_THISCALL && !(odp->flags & FLAG_FORWARD))
+    {
+        char *link_name = strmake( "__thiscall_%s", odp->link_name );
+        free( odp->link_name );
+        odp->link_name = link_name;
+    }
     return 1;
 }
 
@@ -524,6 +536,7 @@ static int parse_spec_ordinal( int ordinal, DLLSPEC *spec )
     case TYPE_STDCALL:
     case TYPE_VARARGS:
     case TYPE_CDECL:
+    case TYPE_THISCALL:
         if (!parse_spec_export( odp, spec )) goto error;
         break;
     case TYPE_ABS:
index 31526601ef9c873c5f0094b67a4785ea2b9404e4..cf0b76eebe7e93f70ad4d0f0a81a9586be4e59b8 100644 (file)
@@ -246,6 +246,7 @@ void output_exports( DLLSPEC *spec )
         case TYPE_STDCALL:
         case TYPE_VARARGS:
         case TYPE_CDECL:
+        case TYPE_THISCALL:
             if (odp->flags & FLAG_FORWARD)
             {
                 output( "\t%s .L__wine_spec_forwards+%u\n", get_asm_ptr_keyword(), fwd_size );
@@ -816,6 +817,7 @@ void output_def_file( DLLSPEC *spec, int include_private )
             /* fall through */
         case TYPE_VARARGS:
         case TYPE_CDECL:
+        case TYPE_THISCALL:
             /* try to reduce output */
             if(strcmp(name, odp->link_name) || (odp->flags & FLAG_FORWARD))
                 output( "=%s", odp->link_name );
index 5ea9465b1054c1052673d61bfb05153ae86763fb..fb554f7613f79ce7364424954a63a8d67dacefee 100644 (file)
@@ -325,6 +325,11 @@ for a Win16 or Win32 function using the C calling convention
 .B varargs
 for a Win16 or Win32 function using the C calling convention with a
 variable number of arguments
+.TP
+.B thiscall
+for a Win32 function using the
+.I thiscall
+calling convention (first parameter in %ecx register on i386)
 .RE
 .PP
 .I args