Signed-off-by: Zebediah Figura z.figura12@gmail.com --- tools/widl/write_msft.c | 71 ++++++++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 30 deletions(-)
diff --git a/tools/widl/write_msft.c b/tools/widl/write_msft.c index 4b09317..1b05159 100644 --- a/tools/widl/write_msft.c +++ b/tools/widl/write_msft.c @@ -990,40 +990,51 @@ static int encode_type(
case VT_USERDEFINED: { + importinfo_t *importinfo; int typeinfo_offset;
- /* typedef'd types without public attribute aren't included in the typelib */ - while (type->typelib_idx < 0 && type_is_alias(type) && !is_attr(type->attrs, ATTR_PUBLIC)) - type = type_alias_get_aliasee(type); - - chat("encode_type: VT_USERDEFINED - type %p name = %s real type %d idx %d\n", type, - type->name, type_get_type(type), type->typelib_idx); - - if(type->typelib_idx == -1) { - chat("encode_type: 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("encode_type: VT_USERDEFINED - unhandled type %d\n", - type_get_type(type)); - } + if ((importinfo = find_importinfo(typelib, type->name))) + { + chat("encode_type: VT_USERDEFINED - found imported type %s in %s\n", + type->name, importinfo->importlib->name); + alloc_importinfo(typelib, importinfo); + typeinfo_offset = importinfo->offset | 0x1; } + else + { + /* typedef'd types without public attribute aren't included in the typelib */ + while (type->typelib_idx < 0 && type_is_alias(type) && !is_attr(type->attrs, ATTR_PUBLIC)) + type = type_alias_get_aliasee(type);
- typeinfo_offset = typelib->typelib_typeinfo_offsets[type->typelib_idx]; + chat("encode_type: VT_USERDEFINED - type %p name = %s real type %d idx %d\n", type, + type->name, type_get_type(type), type->typelib_idx); + + if(type->typelib_idx == -1) { + chat("encode_type: 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("encode_type: VT_USERDEFINED - unhandled type %d\n", + type_get_type(type)); + } + } + + typeinfo_offset = typelib->typelib_typeinfo_offsets[type->typelib_idx]; + } for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; if ((typedata[0] == ((0x7fff << 16) | VT_USERDEFINED)) && (typedata[1] == typeinfo_offset)) break;
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/oleaut32/tests/typelib.c | 18 ------------------ tools/widl/typetree.c | 13 +++++++++++-- tools/widl/typetree.h | 7 +++++++ tools/widl/widltypes.h | 1 + tools/widl/write_msft.c | 39 ++++++++++++++++++++++++++++++++++++++- 5 files changed, 57 insertions(+), 21 deletions(-)
diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c index b518e1a..05476a3 100644 --- a/dlls/oleaut32/tests/typelib.c +++ b/dlls/oleaut32/tests/typelib.c @@ -1530,13 +1530,10 @@ static void test_inheritance(void) ok(pTA->typekind == TKIND_DISPATCH, "kind %04x\n", pTA->typekind); ok(pTA->cbSizeVft == 7 * sizeof(void *), "sizevft %d\n", pTA->cbSizeVft); ok(pTA->wTypeFlags == TYPEFLAG_FDISPATCHABLE, "typeflags %x\n", pTA->wTypeFlags); -if(use_midl_tlb) { ok(pTA->cFuncs == 6, "cfuncs %d\n", pTA->cFuncs); ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes); -} ITypeInfo_ReleaseTypeAttr(pTI, pTA);
-if(use_midl_tlb) { hr = ITypeInfo_GetRefTypeOfImplType(pTI, 0, &href); ok(hr == S_OK, "hr %08x\n", hr); hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p); @@ -1555,7 +1552,6 @@ if(use_midl_tlb) { ok(pFD->memid == 0x60020000, "memid %08x\n", pFD->memid); ok(pFD->oVft == 5 * sizeof(void *), "oVft %d\n", pFD->oVft); ITypeInfo_ReleaseFuncDesc(pTI, pFD); -} ITypeInfo_Release(pTI);
@@ -1616,12 +1612,10 @@ if(use_midl_tlb) { ok(IsEqualGUID(&pTA->guid, &IID_IDispatch), "guid {%08x-....\n", pTA->guid.Data1); ITypeInfo_ReleaseTypeAttr(pTI_p, pTA); ITypeInfo_Release(pTI_p); -if(use_midl_tlb) { hr = ITypeInfo_GetFuncDesc(pTI, 6, &pFD); ok(hr == S_OK, "hr %08x\n", hr); ok(pFD->memid == 0x1234, "memid %08x\n", pFD->memid); ITypeInfo_ReleaseFuncDesc(pTI, pFD); -} ITypeInfo_Release(pTI);
/* ItestIF7 is dual with inherited ifaces which derive from Dispatch */ @@ -1662,13 +1656,10 @@ if(use_midl_tlb) { ok(pTA->typekind == TKIND_DISPATCH, "kind %04x\n", pTA->typekind); ok(pTA->cbSizeVft == 7 * sizeof(void *), "sizevft %d\n", pTA->cbSizeVft); ok(pTA->wTypeFlags == TYPEFLAG_FDISPATCHABLE, "typeflags %x\n", pTA->wTypeFlags); -if(use_midl_tlb) { ok(pTA->cFuncs == 3, "cfuncs %d\n", pTA->cFuncs); ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes); -} ITypeInfo_ReleaseTypeAttr(pTI, pTA);
-if(use_midl_tlb) { hr = ITypeInfo_GetRefTypeOfImplType(pTI, -1, &href); ok(hr == TYPE_E_ELEMENTNOTFOUND, "hr %08x\n", hr); hr = ITypeInfo_GetRefTypeOfImplType(pTI, 0, &href); @@ -1689,7 +1680,6 @@ if(use_midl_tlb) { ok(pFD->memid == 0x60010000, "memid %08x\n", pFD->memid); ok(pFD->oVft == 2 * sizeof(void *), "oVft %d\n", pFD->oVft); ITypeInfo_ReleaseFuncDesc(pTI, pFD); -} ITypeInfo_Release(pTI);
/* ItestIF11 is a syntax 2 dispinterface which derives from IDispatch */ @@ -1701,13 +1691,10 @@ if(use_midl_tlb) { ok(pTA->typekind == TKIND_DISPATCH, "kind %04x\n", pTA->typekind); ok(pTA->cbSizeVft == 7 * sizeof(void *), "sizevft %d\n", pTA->cbSizeVft); ok(pTA->wTypeFlags == TYPEFLAG_FDISPATCHABLE, "typeflags %x\n", pTA->wTypeFlags); -if(use_midl_tlb) { ok(pTA->cFuncs == 10, "cfuncs %d\n", pTA->cFuncs); ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes); -} ITypeInfo_ReleaseTypeAttr(pTI, pTA);
-if(use_midl_tlb) { hr = ITypeInfo_GetRefTypeOfImplType(pTI, 0, &href); ok(hr == S_OK, "hr %08x\n", hr); hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p); @@ -1736,7 +1723,6 @@ if(use_midl_tlb) { ok(hr == S_OK, "hr %08x\n", hr); if (SUCCEEDED(hr)) ITypeInfo_Release(pTI_p); ITypeInfo_ReleaseFuncDesc(pTI, pFD); -} ITypeInfo_Release(pTI);
@@ -1749,13 +1735,10 @@ if(use_midl_tlb) { ok(pTA->typekind == TKIND_INTERFACE, "kind %04x\n", pTA->typekind); ok(pTA->cbSizeVft == 6 * sizeof(void *), "sizevft %d\n", pTA->cbSizeVft); ok(pTA->wTypeFlags == 0, "typeflags %x\n", pTA->wTypeFlags); -if(use_midl_tlb) { ok(pTA->cFuncs == 1, "cfuncs %d\n", pTA->cFuncs); ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes); -} ITypeInfo_ReleaseTypeAttr(pTI, pTA);
-if(use_midl_tlb) { /* Should have one method */ hr = ITypeInfo_GetFuncDesc(pTI, 1, &pFD); ok(hr == TYPE_E_ELEMENTNOTFOUND, "hr %08x\n", hr); @@ -1764,7 +1747,6 @@ if(use_midl_tlb) { ok(pFD->memid == 0x60020000, "memid %08x\n", pFD->memid); ok(pFD->oVft == 5 * sizeof(void *), "oVft %d\n", pFD->oVft); ITypeInfo_ReleaseFuncDesc(pTI, pFD); -} ITypeInfo_Release(pTI);
ITypeLib_Release(pTL); diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c index e316614..baf53a1 100644 --- a/tools/widl/typetree.c +++ b/tools/widl/typetree.c @@ -442,6 +442,7 @@ void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stm iface->details.iface->disp_methods = NULL; iface->details.iface->stmts = stmts; iface->details.iface->inherit = inherit; + iface->details.iface->disp_inherit = NULL; iface->defined = TRUE; compute_method_indexes(iface); } @@ -454,14 +455,22 @@ void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *met iface->details.iface->stmts = NULL; iface->details.iface->inherit = find_type("IDispatch", NULL, 0); if (!iface->details.iface->inherit) error_loc("IDispatch is undefined\n"); + iface->details.iface->disp_inherit = NULL; iface->defined = TRUE; compute_method_indexes(iface); }
void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface) { - type_dispinterface_define(dispiface, iface->details.iface->disp_props, - iface->details.iface->disp_methods); + dispiface->details.iface = xmalloc(sizeof(*dispiface->details.iface)); + dispiface->details.iface->disp_props = NULL; + dispiface->details.iface->disp_methods = NULL; + dispiface->details.iface->stmts = NULL; + dispiface->details.iface->inherit = find_type("IDispatch", NULL, 0); + if (!dispiface->details.iface->inherit) error_loc("IDispatch is undefined\n"); + dispiface->details.iface->disp_inherit = iface; + dispiface->defined = TRUE; + compute_method_indexes(dispiface); }
void type_module_define(type_t *module, statement_list_t *stmts) diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h index bf05f25..fc134cd 100644 --- a/tools/widl/typetree.h +++ b/tools/widl/typetree.h @@ -176,6 +176,13 @@ static inline var_list_t *type_dispiface_get_methods(const type_t *type) return type->details.iface->disp_methods; }
+static inline type_t *type_dispiface_get_inherit(const type_t *type) +{ + type = type_get_real_type(type); + assert(type_get_type(type) == TYPE_INTERFACE); + return type->details.iface->disp_inherit; +} + static inline int type_is_defined(const type_t *type) { return type->defined; diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index 1f4a9dd..0387846 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -343,6 +343,7 @@ struct iface_details var_list_t *disp_methods; var_list_t *disp_props; struct _type_t *inherit; + struct _type_t *disp_inherit; };
struct module_details diff --git a/tools/widl/write_msft.c b/tools/widl/write_msft.c index 1b05159..f8e9143 100644 --- a/tools/widl/write_msft.c +++ b/tools/widl/write_msft.c @@ -2038,6 +2038,10 @@ static void add_dispatch(msft_typelib_t *typelib)
static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinterface) { + int num_parents = 0, num_funcs = 0; + importinfo_t *importinfo = NULL; + const statement_t *stmt_func; + type_t *inherit, *ref; int idx = 0; var_t *func; var_t *var; @@ -2046,6 +2050,20 @@ static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinte if (-1 < dispinterface->typelib_idx) return;
+ inherit = type_dispiface_get_inherit(dispinterface); + + if (inherit) + { + importinfo = find_importinfo(typelib, inherit->name); + + if (!importinfo && type_iface_get_inherit(inherit) && inherit->typelib_idx == -1) + add_interface_typeinfo(typelib, inherit); + } + + /* check typelib_idx again, it could have been added while resolving the parent interface */ + if (-1 < dispinterface->typelib_idx) + return; + dispinterface->typelib_idx = typelib->typelib_header.nrtypeinfos; msft_typeinfo = create_msft_typeinfo(typelib, TKIND_DISPATCH, dispinterface->name, dispinterface->attrs); @@ -2055,7 +2073,26 @@ static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinte
msft_typeinfo->typeinfo->flags |= 0x1000; /* TYPEFLAG_FDISPATCHABLE */ add_dispatch(typelib); - msft_typeinfo->typeinfo->cImplTypes = 1; + + if (inherit) + { + add_impl_type(msft_typeinfo, inherit, importinfo); + msft_typeinfo->typeinfo->typekind |= 0x10; + } + + /* count the number of inherited interfaces and non-local functions */ + for (ref = inherit; ref; ref = type_iface_get_inherit(ref)) + { + num_parents++; + STATEMENTS_FOR_EACH_FUNC( stmt_func, type_iface_get_stmts(ref) ) { + var_t *func = stmt_func->u.var; + if (!is_local(func->attrs)) num_funcs++; + } + } + msft_typeinfo->typeinfo->datatype2 = num_funcs << 16 | num_parents; + msft_typeinfo->typeinfo->cbSizeVft = num_funcs * pointer_size; + + msft_typeinfo->typeinfo->cImplTypes = 1; /* IDispatch */
/* count the no of methods, as the variable indices come after the funcs */ if (dispinterface->details.iface->disp_methods)
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/oleaut32/tests/tmarshal.idl | 2 -- dlls/oleaut32/tests/typelib.c | 31 +++++++++++-------------------- tools/widl/write_msft.c | 4 ---- 3 files changed, 11 insertions(+), 26 deletions(-)
diff --git a/dlls/oleaut32/tests/tmarshal.idl b/dlls/oleaut32/tests/tmarshal.idl index 12c0bd5..996e948 100644 --- a/dlls/oleaut32/tests/tmarshal.idl +++ b/dlls/oleaut32/tests/tmarshal.idl @@ -208,9 +208,7 @@ library TestTypelib [ odl, uuid(a028db05-30f0-4b93-b17a-41c72f831d84), -#if 0 /* FIXME: commented out as causes widl to generate incorrect typelib */ dual, -#endif oleautomation ] interface IKindaEnumWidget : IUnknown diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c index 05476a3..f4ad8f9 100644 --- a/dlls/oleaut32/tests/typelib.c +++ b/dlls/oleaut32/tests/typelib.c @@ -1507,16 +1507,10 @@ static void test_inheritance(void) FUNCDESC *pFD; WCHAR path[MAX_PATH]; CHAR pathA[MAX_PATH]; - static const WCHAR tl_path[] = {'.','\','m','i','d','l','_','t','m','a','r','s','h','a','l','.','t','l','b',0}; - - BOOL use_midl_tlb = FALSE;
GetModuleFileNameA(NULL, pathA, MAX_PATH); MultiByteToWideChar(CP_ACP, 0, pathA, -1, path, MAX_PATH);
- if(use_midl_tlb) - memcpy(path, tl_path, sizeof(tl_path)); - hr = LoadTypeLib(path, &pTL); if(FAILED(hr)) return;
@@ -1592,17 +1586,13 @@ static void test_inheritance(void)
hr = ITypeInfo_GetTypeAttr(pTI, &pTA); ok(hr == S_OK, "hr %08x\n", hr); - if (hr == S_OK) - { - ok(pTA->typekind == TKIND_DISPATCH, "kind %04x\n", pTA->typekind); - ok(pTA->cbSizeVft == 7 * sizeof(void *), "sizevft %d\n", pTA->cbSizeVft); - if(use_midl_tlb) { - ok(pTA->wTypeFlags == TYPEFLAG_FDUAL, "typeflags %x\n", pTA->wTypeFlags); - } - ok(pTA->cFuncs == 8, "cfuncs %d\n", pTA->cFuncs); - ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes); - ITypeInfo_ReleaseTypeAttr(pTI, pTA); - } + ok(pTA->typekind == TKIND_DISPATCH, "kind %04x\n", pTA->typekind); + ok(pTA->cbSizeVft == 7 * sizeof(void *), "sizevft %d\n", pTA->cbSizeVft); + ok(pTA->wTypeFlags == TYPEFLAG_FDUAL, "typeflags %x\n", pTA->wTypeFlags); + ok(pTA->cFuncs == 8, "cfuncs %d\n", pTA->cFuncs); + ok(pTA->cImplTypes == 1, "cimpltypes %d\n", pTA->cImplTypes); + ITypeInfo_ReleaseTypeAttr(pTI, pTA); + hr = ITypeInfo_GetRefTypeOfImplType(pTI, 0, &href); ok(hr == S_OK, "hr %08x\n", hr); hr = ITypeInfo_GetRefTypeInfo(pTI, href, &pTI_p); @@ -4903,8 +4893,8 @@ static void test_register_typelib(BOOL system_registration) { TKIND_INTERFACE, TYPEFLAG_FDISPATCHABLE }, { TKIND_INTERFACE, TYPEFLAG_FOLEAUTOMATION }, { TKIND_INTERFACE, TYPEFLAG_FDISPATCHABLE | TYPEFLAG_FOLEAUTOMATION }, - { TKIND_DISPATCH, 0 /* TYPEFLAG_FDUAL - widl clears this flag for non-IDispatch derived interfaces */ }, - { TKIND_DISPATCH, 0 /* TYPEFLAG_FDUAL - widl clears this flag for non-IDispatch derived interfaces */ }, + { TKIND_DISPATCH, TYPEFLAG_FDUAL }, + { TKIND_DISPATCH, TYPEFLAG_FDUAL }, { TKIND_DISPATCH, TYPEFLAG_FDISPATCHABLE | TYPEFLAG_FDUAL }, { TKIND_DISPATCH, TYPEFLAG_FDISPATCHABLE | TYPEFLAG_FDUAL }, { TKIND_DISPATCH, TYPEFLAG_FDISPATCHABLE }, @@ -4979,7 +4969,8 @@ static void test_register_typelib(BOOL system_registration) ok(hr == S_OK, "got %08x\n", hr);
ok(dual_attr->typekind == TKIND_INTERFACE, "%d: got kind %d\n", i, dual_attr->typekind); - ok(dual_attr->wTypeFlags == (TYPEFLAG_FDISPATCHABLE | TYPEFLAG_FOLEAUTOMATION | TYPEFLAG_FDUAL), "%d: got flags %04x\n", i, dual_attr->wTypeFlags); + ok(dual_attr->wTypeFlags == (attrs[i].flags | TYPEFLAG_FOLEAUTOMATION), + "%d: got flags %04x\n", i, dual_attr->wTypeFlags);
ITypeInfo_ReleaseTypeAttr(dual_info, dual_attr); ITypeInfo_Release(dual_info); diff --git a/tools/widl/write_msft.c b/tools/widl/write_msft.c index f8e9143..2e8c0dd 100644 --- a/tools/widl/write_msft.c +++ b/tools/widl/write_msft.c @@ -2163,10 +2163,6 @@ static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface) if (derived->name && !strcmp(derived->name, "IDispatch")) msft_typeinfo->typeinfo->flags |= 0x1000; /* TYPEFLAG_FDISPATCHABLE */
- /* can't be dual if it doesn't derive from IDispatch */ - if (!(msft_typeinfo->typeinfo->flags & 0x1000)) /* TYPEFLAG_FDISPATCHABLE */ - msft_typeinfo->typeinfo->flags &= ~0x40; /* TYPEFLAG_FDUAL */ - if(type_iface_get_inherit(interface)) add_impl_type(msft_typeinfo, type_iface_get_inherit(interface), ref_importinfo);
On Mon, May 28, 2018 at 11:21:09PM -0500, Zebediah Figura wrote:
Signed-off-by: Zebediah Figura z.figura12@gmail.com
tools/widl/write_msft.c | 71 ++++++++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 30 deletions(-)
This series looks good; resent with minor whitespace changes.
Huw.