Commit 413821f8 authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

widl: Properly implement syntax 2 dispinterfaces.

parent 3e7a5301
......@@ -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,6 +2040,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;
......@@ -2048,6 +2052,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);
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment