Module: wine Branch: master Commit: 211ed7be48002c8af997a1c0b553344a817ce289 URL: http://source.winehq.org/git/wine.git/?a=commit;h=211ed7be48002c8af997a1c0b5...
Author: Alexandre Julliard julliard@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)