widl: Properly implement syntax 2 dispinterfaces.
Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
3e7a5301f2
commit
413821f8b1
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -2040,11 +2040,29 @@ 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;
|
||||
msft_typeinfo_t *msft_typeinfo;
|
||||
|
||||
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;
|
||||
|
||||
|
@ -2057,7 +2075,27 @@ 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)
|
||||
|
|
Loading…
Reference in New Issue