[PATCH 4/4] widl: Generate correct size and alignment for all types.

Zebediah Figura z.figura12 at gmail.com
Sun Jun 3 13:52:56 CDT 2018


Using type_memsize_and_alignment() directly instead of reimplementing it.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/oleaut32/tests/typelib.c | 13 ------
 tools/widl/typegen.c          |  5 +--
 tools/widl/typegen.h          |  1 +
 tools/widl/write_msft.c       | 95 +++++++++----------------------------------
 4 files changed, 23 insertions(+), 91 deletions(-)

diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c
index 7c35e87..4d5314e 100644
--- a/dlls/oleaut32/tests/typelib.c
+++ b/dlls/oleaut32/tests/typelib.c
@@ -4724,21 +4724,8 @@ static void test_dump_typelib(const char *name)
         ole_check(ITypeInfo_GetTypeAttr(typeinfo, &typeattr));
         expect_int(typeattr->typekind, ti->type);
         expect_hex(typeattr->wTypeFlags, ti->wTypeFlags);
-        /* FIXME: remove once widl is fixed */
-        if (typeattr->typekind == TKIND_ALIAS && typeattr->cbAlignment != ti->cbAlignment)
-        {
-todo_wine /* widl generates broken typelib and typeattr just reflects that */
-        ok(typeattr->cbAlignment == ti->cbAlignment || broken(typeattr->cbAlignment == 1),
-           "expected %d, got %d\n", ti->cbAlignment, typeattr->cbAlignment);
-todo_wine /* widl generates broken typelib and typeattr just reflects that */
-        ok(typeattr->cbSizeInstance == ti->cbSizeInstance || broken(typeattr->cbSizeInstance == 0),
-           "expected %d, got %d\n", ti->cbSizeInstance, typeattr->cbSizeInstance);
-        }
-        else
-        {
         expect_int(typeattr->cbAlignment, ti->cbAlignment);
         expect_int(typeattr->cbSizeInstance, ti->cbSizeInstance);
-        }
         expect_int(help_ctx, ti->help_ctx);
         expect_int(MAKELONG(typeattr->wMinorVerNum, typeattr->wMajorVerNum), ti->version);
         expect_int(typeattr->cbSizeVft, ti->cbSizeVft * sizeof(void*));
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index 9f62589..38cbfa0 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -84,7 +84,6 @@ static const unsigned short IsSimpleRef = 0x0100;
 
 static unsigned int field_memsize(const type_t *type, unsigned int *offset);
 static unsigned int fields_memsize(const var_list_t *fields, unsigned int *align);
-static unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *align);
 static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type,
                                     const char *name, unsigned int *typestring_offset);
 static unsigned int write_struct_tfs(FILE *file, type_t *type, const char *name, unsigned int *tfsoff);
@@ -1841,7 +1840,7 @@ static unsigned int union_memsize(const var_list_t *fields, unsigned int *pmaxa)
     return maxs;
 }
 
-static unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *align)
+unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *align)
 {
     unsigned int size = 0;
 
@@ -1910,6 +1909,7 @@ static unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *al
         size = union_memsize(type_union_get_cases(t), align);
         break;
     case TYPE_POINTER:
+    case TYPE_INTERFACE:
         assert( pointer_size );
         size = pointer_size;
         if (size > *align) *align = size;
@@ -1933,7 +1933,6 @@ static unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *al
             if (size > *align) *align = size;
         }
         break;
-    case TYPE_INTERFACE:
     case TYPE_ALIAS:
     case TYPE_VOID:
     case TYPE_COCLASS:
diff --git a/tools/widl/typegen.h b/tools/widl/typegen.h
index b6540e2..95ad601 100644
--- a/tools/widl/typegen.h
+++ b/tools/widl/typegen.h
@@ -100,3 +100,4 @@ unsigned char get_basic_fc(const type_t *type);
 unsigned char get_pointer_fc(const type_t *type, const attr_list_t *attrs, int toplevel_param);
 unsigned char get_struct_fc(const type_t *type);
 enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *attrs, unsigned int flags);
+unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *align);
diff --git a/tools/widl/write_msft.c b/tools/widl/write_msft.c
index f7e53e4..b1f467d 100644
--- a/tools/widl/write_msft.c
+++ b/tools/widl/write_msft.c
@@ -52,6 +52,7 @@
 #include "hash.h"
 #include "typetree.h"
 #include "parser.h"
+#include "typegen.h"
 
 enum MSFT_segment_index {
     MSFT_SEG_TYPEINFO = 0,  /* type information */
@@ -780,8 +781,6 @@ static int encode_type(
         int vt,                    /* [I] vt to encode */
 	type_t *type,              /* [I] type */
 	int *encoded_type,         /* [O] The encoded type description. */
-	int *width,                /* [O] The width of the type, or NULL. */
-	int *alignment,            /* [O] The alignment of the type, or NULL. */
 	int *decoded_size)         /* [O] The total size of the unencoded TYPEDESCs, including nested descs. */
 {
     int default_type;
@@ -794,8 +793,6 @@ static int encode_type(
     chat("encode_type vt %d type %p\n", vt, type);
 
     default_type = 0x80000000 | (vt << 16) | vt;
-    if (!width) width = &scratch;
-    if (!alignment) alignment = &scratch;
     if (!decoded_size) decoded_size = &scratch;
 
     *decoded_size = 0;
@@ -804,38 +801,20 @@ static int encode_type(
     case VT_I1:
     case VT_UI1:
 	*encoded_type = default_type;
-	*width = 1;
-	*alignment = 1;
 	break;
 
     case VT_INT:
 	*encoded_type = 0x80000000 | (VT_I4 << 16) | VT_INT;
-	if ((typelib->typelib_header.varflags & 0x0f) == SYS_WIN16) {
-	    *width = 2;
-	    *alignment = 2;
-	} else {
-	    *width = 4;
-	    *alignment = 4;
-	}
 	break;
 
     case VT_UINT:
 	*encoded_type = 0x80000000 | (VT_UI4 << 16) | VT_UINT;
-	if ((typelib->typelib_header.varflags & 0x0f) == SYS_WIN16) {
-	    *width = 2;
-	    *alignment = 2;
-	} else {
-	    *width = 4;
-	    *alignment = 4;
-	}
 	break;
 
     case VT_UI2:
     case VT_I2:
     case VT_BOOL:
 	*encoded_type = default_type;
-	*width = 2;
-	*alignment = 2;
 	break;
 
     case VT_I4:
@@ -844,56 +823,40 @@ static int encode_type(
     case VT_ERROR:
     case VT_HRESULT:
 	*encoded_type = default_type;
-	*width = 4;
-	*alignment = 4;
 	break;
 
     case VT_R8:
     case VT_I8:
     case VT_UI8:
 	*encoded_type = default_type;
-	*width = 8;
-	*alignment = 8;
 	break;
 
     case VT_CY:
     case VT_DATE:
 	*encoded_type = default_type;
-	*width = 8;
-	*alignment = 8;
 	break;
 
     case VT_DECIMAL:
         *encoded_type = default_type;
-        *width = 16;
-        *alignment = 8;
         break;
 
     case VT_VOID:
 	*encoded_type = 0x80000000 | (VT_EMPTY << 16) | vt;
-	*width = 0;
-	*alignment = 1;
 	break;
 
     case VT_UNKNOWN:
     case VT_DISPATCH:
     case VT_BSTR:
         *encoded_type = default_type;
-        *width = pointer_size;
-        *alignment = 4;
         break;
 
     case VT_VARIANT:
         *encoded_type = default_type;
-        *width = 8 + 2 * pointer_size;
-        *alignment = 8;
         break;
 
     case VT_LPSTR:
     case VT_LPWSTR:
         *encoded_type = 0xfffe0000 | vt;
-        *width = pointer_size;
-        *alignment = 4;
         break;
 
     case VT_PTR:
@@ -909,14 +872,12 @@ static int encode_type(
             next_vt = VT_VOID;
 
         encode_type(typelib, next_vt, type_pointer_get_ref(type),
-                    &target_type, NULL, NULL, &child_size);
+                    &target_type, &child_size);
         /* these types already have an implicit pointer, so we don't need to
          * add another */
         if(next_vt == VT_DISPATCH || next_vt == VT_UNKNOWN) {
             chat("encode_type: skipping ptr\n");
             *encoded_type = target_type;
-            *width = pointer_size;
-            *alignment = 4;
             *decoded_size = child_size;
             break;
         }
@@ -945,8 +906,6 @@ static int encode_type(
 
 	*encoded_type = typeoffset;
 
-	*width = pointer_size;
-	*alignment = 4;
 	*decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size;
         break;
     }
@@ -956,7 +915,8 @@ static int encode_type(
 	type_t *element_type = type_alias_get_aliasee(type_array_get_element(type));
 	int next_vt = get_type_vt(element_type);
 
-	encode_type(typelib, next_vt, type_alias_get_aliasee(type_array_get_element(type)), &target_type, NULL, NULL, &child_size);
+	encode_type(typelib, next_vt, type_alias_get_aliasee(type_array_get_element(type)),
+        &target_type, &child_size);
 
 	for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
 	    typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
@@ -982,8 +942,6 @@ static int encode_type(
 
 	*encoded_type = typeoffset;
 
-	*width = pointer_size;
-	*alignment = 4;
 	*decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size;
 	break;
 	}
@@ -1053,16 +1011,12 @@ static int encode_type(
 	}
 
 	*encoded_type = typeoffset;
-	*width = 0;
-	*alignment = 1;
         break;
       }
 
     default:
 	error("encode_type: unrecognized type %d.\n", vt);
 	*encoded_type = default_type;
-	*width = 0;
-	*alignment = 1;
 	break;
     }
 
@@ -1079,8 +1033,6 @@ static int encode_var(
 	type_t *type,              /* [I] The type description to encode. */
 	var_t *var,                /* [I] The var to encode. */
 	int *encoded_type,         /* [O] The encoded type description. */
-	int *width,                /* [O] The width of the type, or NULL. */
-	int *alignment,            /* [O] The alignment of the type, or NULL. */
 	int *decoded_size)         /* [O] The total size of the unencoded TYPEDESCs, including nested descs. */
 {
     int typeoffset;
@@ -1090,8 +1042,6 @@ static int encode_var(
     int vt;
     int scratch;
 
-    if (!width) width = &scratch;
-    if (!alignment) alignment = &scratch;
     if (!decoded_size) decoded_size = &scratch;
     *decoded_size = 0;
 
@@ -1110,7 +1060,7 @@ static int encode_var(
             ++num_dims;
 
         chat("array with %d dimensions\n", num_dims);
-        encode_var(typelib, atype, var, &target_type, width, alignment, NULL);
+        encode_var(typelib, atype, var, &target_type, NULL);
         arrayoffset = ctl2_alloc_segment(typelib, MSFT_SEG_ARRAYDESC, (2 + 2 * num_dims) * sizeof(int), 0);
         arraydata = (void *)&typelib->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset];
 
@@ -1136,7 +1086,6 @@ static int encode_var(
         typedata[1] = arrayoffset;
 
         *encoded_type = typeoffset;
-        *width = *width * elements;
         *decoded_size = 20 /*sizeof(ARRAYDESC)*/ + (num_dims - 1) * 8 /*sizeof(SAFEARRAYBOUND)*/;
         return 0;
     }
@@ -1145,15 +1094,12 @@ static int encode_var(
     if (vt == VT_PTR) {
         type_t *ref = is_ptr(type) ?
             type_pointer_get_ref(type) : type_array_get_element(type);
-        int skip_ptr = encode_var(typelib, ref, var,
-                                  &target_type, NULL, NULL, &child_size);
+        int skip_ptr = encode_var(typelib, ref, var, &target_type, &child_size);
 
         if(skip_ptr == 2) {
             chat("encode_var: skipping ptr\n");
             *encoded_type = target_type;
             *decoded_size = child_size;
-            *width = pointer_size;
-            *alignment = 4;
             return 0;
         }
 
@@ -1184,15 +1130,13 @@ static int encode_var(
 
 	*encoded_type = typeoffset;
 
-	*width = pointer_size;
-	*alignment = 4;
 	*decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size;
         return 0;
     }
 
     dump_type(type);
 
-    encode_type(typelib, vt, type, encoded_type, width, alignment, decoded_size);
+    encode_type(typelib, vt, type, encoded_type, decoded_size);
     /* these types already have an implicit pointer, so we don't need to
      * add another */
     if(vt == VT_DISPATCH || vt == VT_UNKNOWN) return 2;
@@ -1504,7 +1448,8 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index)
 
     /* fill out the basic type information */
     typedata[0] = typedata_size | (index << 16);
-    encode_var(typeinfo->typelib, type_function_get_rettype(func->type), func, &typedata[1], NULL, NULL, &decoded_size);
+    encode_var(typeinfo->typelib, type_function_get_rettype(func->type), func,
+        &typedata[1], &decoded_size);
     typedata[2] = funcflags;
     typedata[3] = ((52 /*sizeof(FUNCDESC)*/ + decoded_size) << 16) | typeinfo->typeinfo->cbSizeVft;
     typedata[4] = (next_idx << 16) | (callconv << 8) | (invokekind << 3) | funckind;
@@ -1541,7 +1486,7 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index)
 
         if(defaultdata) *defaultdata = -1;
 
-	encode_var(typeinfo->typelib, arg->type, arg, paramdata, NULL, NULL, &decoded_size);
+	encode_var(typeinfo->typelib, arg->type, arg, paramdata, &decoded_size);
         if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) {
             switch(attr->type) {
             case ATTR_DEFAULTVALUE:
@@ -1667,8 +1612,7 @@ static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var)
     int offset, id;
     unsigned int typedata_size;
     INT *typedata;
-    int var_datawidth;
-    int var_alignment;
+    unsigned int var_datawidth, var_alignment = 0;
     int var_type_size, var_kind = 0 /* VAR_PERINSTANCE */; 
     int alignment;
     int varflags = 0;
@@ -1770,8 +1714,8 @@ static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var)
     typeinfo->var_offsets[var_num] = offset;
 
     /* figure out type widths and whatnot */
-    encode_var(typeinfo->typelib, var->type, var, &typedata[1], &var_datawidth,
-               &var_alignment, &var_type_size);
+    var_datawidth = type_memsize_and_alignment(var->type, &var_alignment);
+    encode_var(typeinfo->typelib, var->type, var, &typedata[1], &var_type_size);
 
     /* pad out starting position to data width */
     typeinfo->datawidth += var_alignment - 1;
@@ -1795,7 +1739,6 @@ static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var)
     case TKIND_DISPATCH:
         var_kind = 3; /* VAR_DISPATCH */
         typeinfo->datawidth = pointer_size;
-        var_alignment = 4;
         break;
     default:
         error("add_var_desc: unhandled type kind %d\n", typeinfo->typekind);
@@ -2073,7 +2016,7 @@ static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinte
                                          dispinterface->attrs);
 
     msft_typeinfo->typeinfo->size = pointer_size;
-    msft_typeinfo->typeinfo->typekind |= 0x2100;
+    msft_typeinfo->typeinfo->typekind |= pointer_size << 11 | pointer_size << 6;
 
     msft_typeinfo->typeinfo->flags |= 0x1000; /* TYPEFLAG_FDISPATCHABLE */
     add_dispatch(typelib);
@@ -2162,7 +2105,8 @@ static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface)
     interface->typelib_idx = typelib->typelib_header.nrtypeinfos;
     msft_typeinfo = create_msft_typeinfo(typelib, TKIND_INTERFACE, interface->name, interface->attrs);
     msft_typeinfo->typeinfo->size = pointer_size;
-    msft_typeinfo->typeinfo->typekind |= 0x2200;
+    msft_typeinfo->typeinfo->typekind |= 0x0200;
+    msft_typeinfo->typeinfo->typekind |= pointer_size << 11;
 
     for (derived = inherit; derived; derived = type_iface_get_inherit(derived))
         if (derived->name && !strcmp(derived->name, "IDispatch"))
@@ -2247,7 +2191,8 @@ static void add_union_typeinfo(msft_typelib_t *typelib, type_t *tunion)
 static void add_typedef_typeinfo(msft_typelib_t *typelib, type_t *tdef)
 {
     msft_typeinfo_t *msft_typeinfo = NULL;
-    int alignment, datatype1, datatype2, size, duplicate = 0;
+    int datatype1, datatype2, duplicate = 0;
+    unsigned int size, alignment = 0;
     type_t *type;
 
     if (-1 < tdef->typelib_idx)
@@ -2263,8 +2208,8 @@ static void add_typedef_typeinfo(msft_typelib_t *typelib, type_t *tdef)
     else
         duplicate = 1;
 
-    encode_type(typelib, get_type_vt(type), type,
-                &datatype1, &size, &alignment, &datatype2);
+    encode_type(typelib, get_type_vt(type), type, &datatype1, &datatype2);
+    size = type_memsize_and_alignment(type, &alignment);
 
     if (msft_typeinfo)
     {
-- 
2.7.4




More information about the wine-devel mailing list