Alexandre Julliard : widl: Fix packing of parameter structures for arguments larger than a pointer.

Alexandre Julliard julliard at winehq.org
Thu Jun 9 11:47:38 CDT 2011


Module: wine
Branch: master
Commit: 211ed7be48002c8af997a1c0b553344a817ce289
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=211ed7be48002c8af997a1c0b553344a817ce289

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Jun  9 12:03:54 2011 +0200

widl: Fix packing of parameter structures for arguments larger than a pointer.

---

 tools/widl/typegen.c |   20 ++++++++++++++++++--
 1 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index 04e014a..2cb8767 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -4667,7 +4667,16 @@ void write_func_param_struct( FILE *file, const type_t *iface, const type_t *fun
     type_t *rettype = type_function_get_rettype( func );
     const var_list_t *args = type_get_function_args( func );
     const var_t *arg;
+    int needs_packing;
+    unsigned int align = 0;
+
+    if (args)
+        LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry )
+            if (!is_array( arg->type )) type_memsize_and_alignment( arg->type, &align );
+
+    needs_packing = (align > pointer_size);
 
+    if (needs_packing) print_file( file, 0, "#include <pshpack%u.h>\n", pointer_size );
     print_file(file, 1, "struct _PARAM_STRUCT\n" );
     print_file(file, 1, "{\n" );
     if (is_object( iface )) print_file(file, 2, "%s *This;\n", iface->name );
@@ -4678,8 +4687,13 @@ void write_func_param_struct( FILE *file, const type_t *iface, const type_t *fun
         write_type_left( file, (type_t *)arg->type, TRUE );
         if (needs_space_after( arg->type )) fputc( ' ', file );
         if (is_array( arg->type ) && !type_array_is_decl_as_ptr( arg->type )) fputc( '*', file );
+
         /* FIXME: should check for large args being passed by pointer */
-        if (is_array( arg->type ) || is_ptr( arg->type ) || type_memsize( arg->type ) == pointer_size)
+        align = 0;
+        if (is_array( arg->type ) || is_ptr( arg->type )) align = pointer_size;
+        else type_memsize_and_alignment( arg->type, &align );
+
+        if (align >= pointer_size)
             fprintf( file, "%s;\n", arg->name );
         else
             fprintf( file, "%s DECLSPEC_ALIGN(%u);\n", arg->name, pointer_size );
@@ -4693,7 +4707,9 @@ void write_func_param_struct( FILE *file, const type_t *iface, const type_t *fun
         else
             fprintf( file, " DECLSPEC_ALIGN(%u);\n", pointer_size );
     }
-    print_file(file, 1, "} %s;\n\n", var_decl );
+    print_file(file, 1, "} %s;\n", var_decl );
+    if (needs_packing) print_file( file, 0, "#include <poppack.h>\n" );
+    print_file( file, 0, "\n" );
 }
 
 int write_expr_eval_routines(FILE *file, const char *iface)




More information about the wine-cvs mailing list