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)