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