widl: Update to current Wine version. Signed-off-by: Jacek Caban <jacek@codeweavers.com>
diff --git a/mingw-w64-tools/widl/VERSION b/mingw-w64-tools/widl/VERSION index 9440edf..ecdc406 100644 --- a/mingw-w64-tools/widl/VERSION +++ b/mingw-w64-tools/widl/VERSION
@@ -1 +1 @@ -WIDL version 9.5 +WIDL version 9.6
diff --git a/mingw-w64-tools/widl/configure b/mingw-w64-tools/widl/configure index 4c1098c..7af3bca 100755 --- a/mingw-w64-tools/widl/configure +++ b/mingw-w64-tools/widl/configure
@@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for widl 9.5. +# Generated by GNU Autoconf 2.71 for widl 9.6. # # Report bugs to <mingw-w64-public@lists.sourceforge.net>. # @@ -610,8 +610,8 @@ # Identity of this package. PACKAGE_NAME='widl' PACKAGE_TARNAME='widl' -PACKAGE_VERSION='9.5' -PACKAGE_STRING='widl 9.5' +PACKAGE_VERSION='9.6' +PACKAGE_STRING='widl 9.6' PACKAGE_BUGREPORT='mingw-w64-public@lists.sourceforge.net' PACKAGE_URL='' @@ -1319,7 +1319,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures widl 9.5 to adapt to many kinds of systems. +\`configure' configures widl 9.6 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1391,7 +1391,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of widl 9.5:";; + short | recursive ) echo "Configuration of widl 9.6:";; esac cat <<\_ACEOF @@ -1493,7 +1493,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -widl configure 9.5 +widl configure 9.6 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -1905,7 +1905,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by widl $as_me 9.5, which was +It was created by widl $as_me 9.6, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -3295,7 +3295,7 @@ # Define the identity of the package. PACKAGE='widl' - VERSION='9.5' + VERSION='9.6' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -5789,7 +5789,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by widl $as_me 9.5, which was +This file was extended by widl $as_me 9.6, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -5857,7 +5857,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -widl config.status 9.5 +widl config.status 9.6 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\"
diff --git a/mingw-w64-tools/widl/src/typegen.c b/mingw-w64-tools/widl/src/typegen.c index 917f4b4..063080b 100644 --- a/mingw-w64-tools/widl/src/typegen.c +++ b/mingw-w64-tools/widl/src/typegen.c
@@ -417,29 +417,62 @@ return ROUNDING(offset, salign); } -static unsigned int get_stack_size( const var_t *var, int *by_value ) +static unsigned int get_stack_size( const var_t *var, unsigned int *stack_align, int *by_value ) { - unsigned int stack_size; + unsigned int stack_size, align = 0; int by_val; switch (typegen_detect_type( var->declspec.type, var->attrs, TDT_ALL_TYPES )) { case TGT_BASIC: + if (target.cpu == CPU_ARM) + { + switch (type_basic_get_type( var->declspec.type )) + { + case TYPE_BASIC_FLOAT: + case TYPE_BASIC_DOUBLE: + case TYPE_BASIC_INT64: + case TYPE_BASIC_HYPER: + align = 8; + break; + default: + break; + } + } + /* fall through */ case TGT_ENUM: case TGT_RANGE: case TGT_STRUCT: case TGT_UNION: case TGT_USER_TYPE: - stack_size = type_memsize( var->declspec.type ); - by_val = (pointer_size < 8 || stack_size <= pointer_size); /* FIXME: should be platform-specific */ + stack_size = type_memsize_and_alignment( var->declspec.type, &align ); + switch (target.cpu) + { + case CPU_x86_64: + by_val = (stack_size == 1 || stack_size == 2 || stack_size == 4 || stack_size == 8); + break; + case CPU_ARM64: + by_val = (stack_size <= 2 * pointer_size); + break; + case CPU_ARM: + by_val = 1; + break; + default: + align = pointer_size; + by_val = 1; + break; + } break; default: by_val = 0; break; } - if (!by_val) stack_size = pointer_size; + if (align < pointer_size) align = pointer_size; + if (!by_val) stack_size = align = pointer_size; + if (by_value) *by_value = by_val; - return ROUND_SIZE( stack_size, pointer_size ); + if (stack_align) *stack_align = align; + return ROUND_SIZE( stack_size, align ); } static unsigned char get_contexthandle_flags( const type_t *iface, const attr_list_t *attrs, @@ -1024,7 +1057,8 @@ } static unsigned char get_parameter_fc( const var_t *var, int is_return, unsigned short *flags, - unsigned int *stack_size, unsigned int *typestring_offset ) + unsigned int *stack_size, unsigned int *stack_align, + unsigned int *typestring_offset ) { unsigned int alignment, server_size = 0, buffer_size = 0; unsigned char fc = 0; @@ -1036,7 +1070,7 @@ else if (!is_in && !is_out) is_in = TRUE; *flags = 0; - *stack_size = get_stack_size( var, &is_byval ); + *stack_size = get_stack_size( var, stack_align, &is_byval ); *typestring_offset = var->typestring_offset; if (is_in) *flags |= IsIn; @@ -1192,11 +1226,11 @@ var_t *retval = type_function_get_retval( func->declspec.type ); unsigned char oi2_flags = 0x40; /* HasExtensions */ unsigned short flags; - unsigned int stack_size, typestring_offset; + unsigned int stack_size, stack_align, typestring_offset; if (args) LIST_FOR_EACH_ENTRY( var, args, const var_t, entry ) { - get_parameter_fc( var, 0, &flags, &stack_size, &typestring_offset ); + get_parameter_fc( var, 0, &flags, &stack_size, &stack_align, &typestring_offset ); if (flags & MustSize) { if (flags & IsIn) oi2_flags |= 0x02; /* ClientMustSize */ @@ -1207,7 +1241,7 @@ if (!is_void( retval->declspec.type )) { oi2_flags |= 0x04; /* HasRet */ - get_parameter_fc( retval, 1, &flags, &stack_size, &typestring_offset ); + get_parameter_fc( retval, 1, &flags, &stack_size, &stack_align, &typestring_offset ); if (flags & MustSize) oi2_flags |= 0x01; /* ServerMustSize */ } return oi2_flags; @@ -1217,10 +1251,11 @@ int is_return, unsigned int *stack_offset) { char buffer[128]; - unsigned int stack_size, typestring_offset; + unsigned int stack_size, stack_align, typestring_offset; unsigned short flags; - unsigned char fc = get_parameter_fc( var, is_return, &flags, &stack_size, &typestring_offset ); + unsigned char fc = get_parameter_fc( var, is_return, &flags, &stack_size, &stack_align, &typestring_offset ); + *stack_offset = ROUND_SIZE( *stack_offset, stack_align ); strcpy( buffer, "/* flags:" ); if (flags & MustSize) strcat( buffer, " must size," ); if (flags & MustFree) strcat( buffer, " must free," ); @@ -1244,7 +1279,7 @@ else print_file( file, indent, "NdrFcShort(0x%x), /* type offset = %u */\n", typestring_offset, typestring_offset ); - *stack_offset += max( stack_size, pointer_size ); + *stack_offset += stack_size; return 6; } @@ -1302,7 +1337,7 @@ else print_file(file, indent, "0x4d, /* FC_IN_PARAM */\n"); - size = get_stack_size( var, NULL ); + size = get_stack_size( var, NULL, NULL ); print_file(file, indent, "0x%02x,\n", size / pointer_size ); print_file(file, indent, "NdrFcShort(0x%x), /* type offset = %u */\n", offset, offset); size = 4; /* includes param type prefix */ @@ -1354,6 +1389,7 @@ unsigned int nb_args = 0; unsigned int stack_size = 0; unsigned int stack_offset = 0; + unsigned int stack_align; unsigned short param_num = 0; unsigned short handle_stack_offset = 0; unsigned short handle_param_num = 0; @@ -1374,7 +1410,9 @@ handle_stack_offset = stack_size; handle_param_num = param_num; } - stack_size += get_stack_size( var, NULL ); + size = get_stack_size( var, &stack_align, NULL ); + stack_size = ROUND_SIZE( stack_size, stack_align ); + stack_size += size; param_num++; nb_args++; } @@ -1762,13 +1800,15 @@ if (is_object( iface )) offset += pointer_size; if (args) LIST_FOR_EACH_ENTRY( var, args, const var_t, entry ) { + unsigned int align, size = get_stack_size( var, &align, NULL ); + offset = ROUND_SIZE( offset, align ); if (var->name && !strcmp(var->name, subexpr->u.sval)) { expr_loc.v = var; correlation_variable = var->declspec.type; break; } - offset += get_stack_size( var, NULL ); + offset += size; if (var == current_arg) robust_flags &= ~RobustEarly; } } @@ -5023,7 +5063,7 @@ int len, needs_params = 0; /* we need a param structure if we have more than one arg */ - if (pointer_size == 4 && args) needs_params = is_object( iface ) || list_count( args ) > 1; + if (target.cpu == CPU_i386 && args) needs_params = is_object( iface ) || list_count( args ) > 1; print_file( file, 0, "{\n"); if (needs_params) @@ -5046,7 +5086,7 @@ { fprintf( file, ",\n%*s&__params", len, "" ); } - else if (pointer_size == 8) + else if (target.cpu != CPU_i386) { if (is_object( iface )) fprintf( file, ",\n%*sThis", len, "" ); if (args) @@ -5067,7 +5107,7 @@ { print_file( file, 1, "return (" ); write_type_decl_left(file, rettype); - fprintf( file, ")%s;\n", pointer_size == 8 ? "_RetVal.Simple" : "*(LONG_PTR *)&_RetVal" ); + fprintf( file, ")%s;\n", target.cpu != CPU_i386 ? "_RetVal.Simple" : "*(LONG_PTR *)&_RetVal" ); } print_file( file, 0, "}\n\n"); }
diff --git a/mingw-w64-tools/widl/src/widl.c b/mingw-w64-tools/widl/src/widl.c index e56be63..30bff0f 100644 --- a/mingw-w64-tools/widl/src/widl.c +++ b/mingw-w64-tools/widl/src/widl.c
@@ -90,7 +90,7 @@ static const char version_string[] = "Wine IDL Compiler version " PACKAGE_VERSION "\n" "Copyright 2002 Ove Kaaven\n"; -static struct target target; +struct target target = { 0 }; int debuglevel = DEBUGLEVEL_NONE; int parser_debug, yy_flex_debug;
diff --git a/mingw-w64-tools/widl/src/widl.h b/mingw-w64-tools/widl/src/widl.h index c5ccc14..31bb2c8 100644 --- a/mingw-w64-tools/widl/src/widl.h +++ b/mingw-w64-tools/widl/src/widl.h
@@ -71,6 +71,7 @@ extern const char *prefix_server; extern unsigned int packing; extern unsigned int pointer_size; +extern struct target target; extern time_t now; extern int open_typelib( const char *name );
diff --git a/mingw-w64-tools/widl/src/write_sltg.c b/mingw-w64-tools/widl/src/write_sltg.c index ac4db60..94ebf67 100644 --- a/mingw-w64-tools/widl/src/write_sltg.c +++ b/mingw-w64-tools/widl/src/write_sltg.c
@@ -147,8 +147,8 @@ short res1e; /* always 0000 */ short cbSizeInstance; short cbAlignment; - short res24; /* always ffff */ - short res26; /* always ffff */ + short res24; + short res26; short cbSizeVft; short res2a; /* always ffff */ short res2c; /* always ffff */ @@ -181,8 +181,54 @@ char resxx; /* 0xdf */ }; +struct sltg_function +{ + char magic; /* 0x4c, 0xcb or 0x8b with optional SLTG_FUNCTION_FLAGS_PRESENT flag */ + char flags; /* high nibble is INVOKE_KIND, low nibble = 2 */ + short next; /* byte offset from beginning of group to next fn */ + short name; /* Offset within name table to name */ + int dispid; /* dispid */ + short helpcontext; /* helpcontext (again 1 is special) */ + short helpstring; /* helpstring offset to offset */ + short arg_off; /* offset to args from start of block */ + char nacc; /* lowest 3bits are CALLCONV, rest are no of args */ + char retnextopt; /* if 0x80 bit set ret type follows else next WORD + is offset to ret type. No of optional args is + middle 6 bits */ + short rettype; /* return type VT_?? or offset to ret type */ + short vtblpos; /* position in vtbl? */ + short funcflags; /* present if magic & 0x20 */ +/* Param list starts, repeat next two as required */ +#if 0 + WORD name; /* offset to 2nd letter of name */ + WORD+ type; /* VT_ of param */ +#endif +}; + +struct sltg_impl_info +{ + short res00; + short next; + short res04; + char impltypeflags; + char res07; + short res08; + short ref; + short res0c; + short res0e; + short res10; + short res12; + short pos; +}; + #include "poppack.h" +static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type); +static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *type); +static void add_enum_typeinfo(struct sltg_typelib *typelib, type_t *type); +static void add_union_typeinfo(struct sltg_typelib *typelib, type_t *type); +static void add_coclass_typeinfo(struct sltg_typelib *typelib, type_t *type); + static void init_sltg_data(struct sltg_data *data) { data->size = 0; @@ -411,21 +457,11 @@ block->size = new_size; } -static void add_typedef_typeinfo(struct sltg_typelib *typelib, type_t *type) -{ - error("add_typedef_typeinfo: %s not implemented\n", type->name); -} - static void add_module_typeinfo(struct sltg_typelib *typelib, type_t *type) { error("add_module_typeinfo: %s not implemented\n", type->name); } -static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *type) -{ - error("add_interface_typeinfo: %s not implemented\n", type->name); -} - static const char *add_typeinfo_block(struct sltg_typelib *typelib, const type_t *type, short kind) { struct sltg_data block; @@ -486,7 +522,7 @@ ti->misc.flags = 0; /* FIXME */ ti->misc.unknown2 = 0x02; ti->misc.typekind = kind; - ti->res1e = -1; + ti->res1e = 0; if (hrefmap->href_count) { @@ -649,8 +685,8 @@ return href << 2; } -static short write_var_desc(struct sltg_data *data, type_t *type, short flags, short base_offset, - int *size_instance, struct sltg_hrefmap *hrefmap) +static short write_var_desc(struct sltg_typelib *typelib, struct sltg_data *data, type_t *type, short flags, + short base_offset, int *size_instance, struct sltg_hrefmap *hrefmap) { short vt, vt_flags, desc_offset; @@ -714,8 +750,12 @@ atype = type_array_get_element_type(atype); } - *size_instance += array_size; - size_instance = NULL; /* don't account for element size */ + if (size_instance) + { + *size_instance += array_size; + size_instance = NULL; /* don't account for element size */ + } + append_data(data, array, size); @@ -742,10 +782,10 @@ chat("write_var_desc: vt VT_PTR | 0x0400\n"); vt = VT_PTR | 0x0400; append_data(data, &vt, sizeof(vt)); - write_var_desc(data, ref, 0, base_offset, size_instance, hrefmap); + write_var_desc(typelib, data, ref, 0, base_offset, size_instance, hrefmap); } else - write_var_desc(data, ref, 0x0e00, base_offset, size_instance, hrefmap); + write_var_desc(typelib, data, ref, 0x0e00, base_offset, size_instance, hrefmap); return desc_offset; } @@ -765,6 +805,33 @@ type, type->name, type_get_type(type), type->typelib_idx); if (type->typelib_idx == -1) + { + chat("write_var_desc: trying to ref not added type\n"); + + switch (type_get_type(type)) + { + case TYPE_STRUCT: + add_structure_typeinfo(typelib, type); + break; + case TYPE_INTERFACE: + add_interface_typeinfo(typelib, type); + break; + case TYPE_ENUM: + add_enum_typeinfo(typelib, type); + break; + case TYPE_UNION: + add_union_typeinfo(typelib, type); + break; + case TYPE_COCLASS: + add_coclass_typeinfo(typelib, type); + break; + default: + error("write_var_desc: VT_USERDEFINED - unhandled type %d\n", + type_get_type(type)); + } + } + + if (type->typelib_idx == -1) error("write_var_desc: trying to ref not added type\n"); href = local_href(hrefmap, type->typelib_idx); @@ -786,10 +853,10 @@ tail->cImplTypes = 0; tail->res06 = 0; tail->funcs_off = -1; - tail->vars_off = 0; + tail->vars_off = -1; tail->impls_off = -1; tail->funcs_bytes = -1; - tail->vars_bytes = 0; + tail->vars_bytes = -1; tail->impls_bytes = -1; tail->tdescalias_vt = -1; tail->res16 = -1; @@ -821,6 +888,8 @@ int member_offset, var_count = 0, var_data_size = 0, size_instance = 0; short *type_desc_offset = NULL; + if (type->typelib_idx != -1) return; + chat("add_structure_typeinfo: type %p, type->name %s\n", type, type->name); type->typelib_idx = typelib->block_count; @@ -828,10 +897,6 @@ hrefmap.href_count = 0; hrefmap.href = NULL; - init_sltg_data(&data); - - index_name = add_typeinfo_block(typelib, type, TKIND_RECORD); - if (type_struct_get_fields(type)) { int i = 0; @@ -846,13 +911,13 @@ { short base_offset; - chat("add_structure_typeinfo: var %p, name %s, type %p\n", - var, var->name, var->declspec.type); + chat("add_structure_typeinfo: var %p (%s), type %p (%s)\n", + var, var->name, var->declspec.type, var->declspec.type->name); init_sltg_data(&var_data[i]); base_offset = var_data_size + (i + 1) * sizeof(struct sltg_variable); - type_desc_offset[i] = write_var_desc(&var_data[i], var->declspec.type, 0, base_offset, &size_instance, &hrefmap); + type_desc_offset[i] = write_var_desc(typelib, &var_data[i], var->declspec.type, 0, base_offset, &size_instance, &hrefmap); dump_var_desc(var_data[i].data, var_data[i].size); if (var_data[i].size > sizeof(short)) @@ -861,6 +926,10 @@ } } + init_sltg_data(&data); + + index_name = add_typeinfo_block(typelib, type, TKIND_RECORD); + init_typeinfo(&ti, type, TKIND_RECORD, &hrefmap); append_data(&data, &ti, sizeof(ti)); @@ -919,6 +988,7 @@ init_sltg_tail(&tail); tail.cVars = var_count; + tail.vars_off = 0; tail.vars_bytes = var_data_size; tail.cbSizeInstance = size_instance; tail.type_bytes = data.size - member_offset - sizeof(member); @@ -927,6 +997,426 @@ add_block(typelib, data.data, data.size, index_name); } +static importinfo_t *find_importinfo(typelib_t *typelib, const char *name) +{ + importlib_t *importlib; + + LIST_FOR_EACH_ENTRY(importlib, &typelib->importlibs, importlib_t, entry) + { + int i; + + for (i = 0; i < importlib->ntypeinfos; i++) + { + if (!strcmp(name, importlib->importinfos[i].name)) + { + chat("Found %s in importlib list\n", name); + return &importlib->importinfos[i]; + } + } + } + + return NULL; +} + +static int get_func_flags(const var_t *func, int *dispid, int *invokekind, int *helpcontext, const char **helpstring) +{ + static int dispid_base = 0x60000000; + const attr_t *attr; + int flags; + + *dispid = dispid_base++; + *invokekind = 1 /* INVOKE_FUNC */; + *helpcontext = -2; + *helpstring = NULL; + + if (!func->attrs) return 0; + + flags = 0; + + LIST_FOR_EACH_ENTRY(attr, func->attrs, const attr_t, entry) + { + expr_t *expr = attr->u.pval; + switch(attr->type) + { + case ATTR_BINDABLE: + flags |= 0x4; /* FUNCFLAG_FBINDABLE */ + break; + case ATTR_DEFAULTBIND: + flags |= 0x20; /* FUNCFLAG_FDEFAULTBIND */ + break; + case ATTR_DEFAULTCOLLELEM: + flags |= 0x100; /* FUNCFLAG_FDEFAULTCOLLELEM */ + break; + case ATTR_DISPLAYBIND: + flags |= 0x10; /* FUNCFLAG_FDISPLAYBIND */ + break; + case ATTR_HELPCONTEXT: + *helpcontext = expr->u.lval; + break; + case ATTR_HELPSTRING: + *helpstring = attr->u.pval; + break; + case ATTR_HIDDEN: + flags |= 0x40; /* FUNCFLAG_FHIDDEN */ + break; + case ATTR_ID: + *dispid = expr->cval; + break; + case ATTR_IMMEDIATEBIND: + flags |= 0x1000; /* FUNCFLAG_FIMMEDIATEBIND */ + break; + case ATTR_NONBROWSABLE: + flags |= 0x400; /* FUNCFLAG_FNONBROWSABLE */ + break; + case ATTR_PROPGET: + *invokekind = 0x2; /* INVOKE_PROPERTYGET */ + break; + case ATTR_PROPPUT: + *invokekind = 0x4; /* INVOKE_PROPERTYPUT */ + break; + case ATTR_PROPPUTREF: + *invokekind = 0x8; /* INVOKE_PROPERTYPUTREF */ + break; + /* FIXME: FUNCFLAG_FREPLACEABLE */ + case ATTR_REQUESTEDIT: + flags |= 0x8; /* FUNCFLAG_FREQUESTEDIT */ + break; + case ATTR_RESTRICTED: + flags |= 0x1; /* FUNCFLAG_FRESTRICTED */ + break; + case ATTR_SOURCE: + flags |= 0x2; /* FUNCFLAG_FSOURCE */ + break; + case ATTR_UIDEFAULT: + flags |= 0x200; /* FUNCFLAG_FUIDEFAULT */ + break; + case ATTR_USESGETLASTERROR: + flags |= 0x80; /* FUNCFLAG_FUSESGETLASTERROR */ + break; + default: + break; + } + } + + return flags; +} + +static int add_func_desc(struct sltg_typelib *typelib, struct sltg_data *data, var_t *func, + int idx, short base_offset, struct sltg_hrefmap *hrefmap) +{ + struct sltg_data ret_data, *arg_data; + int arg_count = 0, arg_data_size, optional = 0, defaults = 0, old_size; + int funcflags = 0, dispid, invokekind = 1 /* INVOKE_FUNC */, helpcontext; + const char *helpstring; + const var_t *arg; + short ret_desc_offset, *arg_desc_offset, arg_offset; + struct sltg_function func_desc; + + chat("add_func_desc: %s, idx %#x\n", func->name, idx); + + old_size = data->size; + + init_sltg_data(&ret_data); + ret_desc_offset = write_var_desc(typelib, &ret_data, type_function_get_rettype(func->declspec.type), + 0, base_offset, NULL, hrefmap); + dump_var_desc(ret_data.data, ret_data.size); + + arg_data_size = 0; + arg_offset = base_offset + sizeof(struct sltg_function); + + if (ret_data.size > sizeof(short)) + { + arg_data_size += ret_data.size; + arg_offset += ret_data.size; + } + + if (type_function_get_args(func->declspec.type)) + { + int i = 0; + + arg_count = list_count(type_function_get_args(func->declspec.type)); + + arg_data = xmalloc(arg_count * sizeof(*arg_data)); + arg_desc_offset = xmalloc(arg_count * sizeof(*arg_desc_offset)); + + arg_offset += arg_count * 2 * sizeof(short); + + LIST_FOR_EACH_ENTRY(arg, type_function_get_args(func->declspec.type), const var_t, entry) + { + const attr_t *attr; + + chat("add_func_desc: arg[%d] %p (%s), type %p (%s)\n", + i, arg, arg->name, arg->declspec.type, arg->declspec.type->name); + + init_sltg_data(&arg_data[i]); + + arg_desc_offset[i] = write_var_desc(typelib, &arg_data[i], arg->declspec.type, 0, arg_offset, NULL, hrefmap); + dump_var_desc(arg_data[i].data, arg_data[i].size); + + if (arg_data[i].size > sizeof(short)) + { + arg_data_size += arg_data[i].size; + arg_offset += arg_data[i].size; + } + + i++; + + if (!arg->attrs) continue; + + LIST_FOR_EACH_ENTRY(attr, arg->attrs, const attr_t, entry) + { + if (attr->type == ATTR_DEFAULTVALUE) + defaults++; + else if(attr->type == ATTR_OPTIONAL) + optional++; + } + } + } + + funcflags = get_func_flags(func, &dispid, &invokekind, &helpcontext, &helpstring); + + if (base_offset != -1) + chat("add_func_desc: flags %#x, dispid %#x, invokekind %d, helpcontext %#x, helpstring %s\n", + funcflags, dispid, invokekind, helpcontext, helpstring); + + func_desc.magic = 0x6c; /* always write flags to simplify calculations */ + func_desc.flags = (invokekind << 4) | 0x02; + if (idx & 0x80000000) + { + func_desc.next = -1; + idx &= ~0x80000000; + } + else + func_desc.next = base_offset + sizeof(func_desc) + arg_data_size + arg_count * 2 * sizeof(short); + func_desc.name = base_offset != -1 ? add_name(&typelib->name_table, func->name) : -1; + func_desc.dispid = dispid; + func_desc.helpcontext = helpcontext; + func_desc.helpstring = (helpstring && base_offset != -1) ? add_name(&typelib->name_table, helpstring) : -1; + func_desc.arg_off = arg_count ? base_offset + sizeof(func_desc) : -1; + func_desc.nacc = (arg_count << 3) | 4 /* CC_STDCALL */; + func_desc.retnextopt = (optional << 1); + if (ret_data.size > sizeof(short)) + { + func_desc.rettype = base_offset + sizeof(func_desc) + ret_desc_offset; + if (arg_count) + func_desc.arg_off += ret_data.size; + } + else + { + func_desc.retnextopt |= 0x80; + func_desc.rettype = *(short *)ret_data.data; + } + func_desc.vtblpos = idx * pointer_size; + func_desc.funcflags = funcflags; + + append_data(data, &func_desc, sizeof(func_desc)); + + arg_offset = base_offset + sizeof(struct sltg_function); + + if (ret_data.size > sizeof(short)) + { + append_data(data, ret_data.data, ret_data.size); + func_desc.arg_off += ret_data.size; + arg_offset += ret_data.size; + } + + if (arg_count) + { + int i = 0; + + arg_offset += arg_count * 2 * sizeof(short); + + LIST_FOR_EACH_ENTRY(arg, type_function_get_args(func->declspec.type), const var_t, entry) + { + short name, type_offset; + + name = base_offset != -1 ? add_name(&typelib->name_table, arg->name) : -1; + append_data(data, &name, sizeof(name)); + + if (arg_data[i].size > sizeof(short)) + { + type_offset = (arg_offset + arg_desc_offset[i]); + arg_offset += arg_data[i].size; + } + else + type_offset = *(short *)arg_data[i].data; + + append_data(data, &type_offset, sizeof(type_offset)); + + if (base_offset != -1) + chat("add_func_desc: arg[%d] - name %s (%#x), type_offset %#x\n", + i, arg->name, name, type_offset); + + i++; + } + + for (i = 0; i < arg_count; i++) + { + if (arg_data[i].size > sizeof(short)) + append_data(data, arg_data[i].data, arg_data[i].size); + } + } + + return data->size - old_size; +} + +static void write_impl_href(struct sltg_data *data, short href) +{ + struct sltg_impl_info impl_info; + + impl_info.res00 = 0x004a; + impl_info.next = -1; + impl_info.res04 = -1; + impl_info.impltypeflags = 0; + impl_info.res07 = 0x80; + impl_info.res08 = 0x0012; + impl_info.ref = href; + impl_info.res0c = 0x4001; + impl_info.res0e = -2; /* 0xfffe */ + impl_info.res10 = -1; + impl_info.res12 = 0x001d; + impl_info.pos = 0; + + append_data(data, &impl_info, sizeof(impl_info)); +} + +static void add_interface_typeinfo(struct sltg_typelib *typelib, type_t *iface) +{ + const statement_t *stmt_func; + importinfo_t *ref_importinfo = NULL; + short inherit_href = -1; + struct sltg_data data; + struct sltg_hrefmap hrefmap; + const char *index_name; + struct sltg_typeinfo_header ti; + struct sltg_member_header member; + struct sltg_tail tail; + int member_offset, base_offset, func_data_size, i; + int func_count, inherited_func_count = 0; + + if (iface->typelib_idx != -1) return; + + chat("add_interface_typeinfo: type %p, type->name %s\n", iface, iface->name); + + if (!iface->details.iface) + { + error("interface %s is referenced but not defined\n", iface->name); + return; + } + + if (is_attr(iface->attrs, ATTR_DISPINTERFACE)) + { + error("support for dispinterface %s is not implemented\n", iface->name); + return; + } + + hrefmap.href_count = 0; + hrefmap.href = NULL; + + if (type_iface_get_inherit(iface)) + { + type_t *inherit; + + inherit = type_iface_get_inherit(iface); + + chat("add_interface_typeinfo: inheriting from base interface %s\n", inherit->name); + + ref_importinfo = find_importinfo(typelib->typelib, inherit->name); + + if (!ref_importinfo && type_iface_get_inherit(inherit)) + add_interface_typeinfo(typelib, inherit); + + if (ref_importinfo) + error("support for imported interfaces is not implemented\n"); + + inherit_href = local_href(&hrefmap, inherit->typelib_idx); + + while (inherit) + { + inherited_func_count += list_count(type_iface_get_stmts(inherit)); + inherit = type_iface_get_inherit(inherit); + } + } + + /* check typelib_idx again, it could have been added while resolving the parent interface */ + if (iface->typelib_idx != -1) return; + + iface->typelib_idx = typelib->block_count; + + /* pass 1: calculate function descriptions data size */ + init_sltg_data(&data); + + STATEMENTS_FOR_EACH_FUNC(stmt_func, type_iface_get_stmts(iface)) + { + add_func_desc(typelib, &data, stmt_func->u.var, -1, -1, &hrefmap); + } + + func_data_size = data.size; + + /* pass 2: write function descriptions */ + init_sltg_data(&data); + + func_count = list_count(type_iface_get_stmts(iface)); + + index_name = add_typeinfo_block(typelib, iface, TKIND_INTERFACE); + + init_typeinfo(&ti, iface, TKIND_INTERFACE, &hrefmap); + append_data(&data, &ti, sizeof(ti)); + + write_hrefmap(&data, &hrefmap); + + member_offset = data.size; + base_offset = 0; + + member.res00 = 0x0001; + member.res02 = 0xffff; + member.res04 = 0x01; + member.extra = func_data_size; + if (inherit_href != -1) + { + member.extra += sizeof(struct sltg_impl_info); + base_offset += sizeof(struct sltg_impl_info); + } + append_data(&data, &member, sizeof(member)); + + if (inherit_href != -1) + write_impl_href(&data, inherit_href); + + i = 0; + + STATEMENTS_FOR_EACH_FUNC(stmt_func, type_iface_get_stmts(iface)) + { + if (i == func_count - 1) i |= 0x80000000; + + base_offset += add_func_desc(typelib, &data, stmt_func->u.var, + inherited_func_count + i, base_offset, &hrefmap); + i++; + } + + init_sltg_tail(&tail); + + tail.cFuncs = func_count; + tail.funcs_off = 0; + tail.funcs_bytes = func_data_size; + tail.cbSizeInstance = pointer_size; + tail.cbAlignment = pointer_size; + tail.cbSizeVft = (inherited_func_count + func_count) * pointer_size; + tail.type_bytes = data.size - member_offset - sizeof(member); + tail.res24 = 0; + tail.res26 = 0; + if (inherit_href != -1) + { + tail.cImplTypes++; + tail.impls_off = 0; + tail.impls_bytes = 0; + + tail.funcs_off += sizeof(struct sltg_impl_info); + } + append_data(&data, &tail, sizeof(tail)); + + add_block(typelib, data.data, data.size, index_name); +} + static void add_enum_typeinfo(struct sltg_typelib *typelib, type_t *type) { error("add_enum_typeinfo: %s not implemented\n", type->name); @@ -996,12 +1486,8 @@ LIST_FOR_EACH_ENTRY(ref, stmt->u.type_list, typeref_t, entry) { - /* if the type is public then add the typedef, otherwise attempt - * to add the aliased type */ - if (is_attr(ref->type->attrs, ATTR_PUBLIC)) - add_typedef_typeinfo(typelib, ref->type); - else - add_type_typeinfo(typelib, type_alias_get_aliasee_type(ref->type)); + /* in old style typelibs all types are public */ + add_type_typeinfo(typelib, ref->type); } break; }
diff --git a/mingw-w64-tools/widl/tools.h b/mingw-w64-tools/widl/tools.h index 5372b5b..076f22d 100644 --- a/mingw-w64-tools/widl/tools.h +++ b/mingw-w64-tools/widl/tools.h
@@ -573,7 +573,7 @@ [CPU_x86_64] = "x86_64", [CPU_ARM] = "arm", [CPU_ARM64] = "aarch64", - [CPU_ARM64EC] = "arm64ec", + [CPU_ARM64EC] = "aarch64", }; if (!cpu_names[target.cpu]) return "";