Commit 652ec646 authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

When adding an interface, midl adds the inherited interface first

unless the inherited interface doesn't itself inherit. Fix the id, sizevft and datatype2 fields for interfaces that inherit. Prevent a crash if the typelib is empty. Clarify a few more entries on typelib_struct.h
parent e5f2ed4c
......@@ -137,11 +137,11 @@ typedef struct tagMSFT_TypeInfoBase {
INT helpcontext; /* */
INT oCustData; /* offset in customer data table */
#ifdef WORDS_BIGENDIAN
INT16 cbSizeVft; /* virtual table size, not including inherits */
INT16 cbSizeVft; /* virtual table size, including inherits */
INT16 cImplTypes; /* nr of implemented interfaces */
#else
INT16 cImplTypes; /* nr of implemented interfaces */
INT16 cbSizeVft; /* virtual table size, not including inherits */
INT16 cbSizeVft; /* virtual table size, including inherits */
#endif
/*050*/ INT size; /* size in bytes, at least for structures */
/* FIXME: name of this field */
......@@ -149,9 +149,8 @@ typedef struct tagMSFT_TypeInfoBase {
/* or in base intefaces */
/* if coclass: offset in reftable */
/* if interface: reference to inherited if */
INT datatype2; /* if 0x8000, entry above is valid */
/* actually dunno */
/* else it is zero? */
INT datatype2; /* for interfaces: hiword is num of inherited funcs */
/* loword is num of inherited interfaces */
INT res18; /* always? 0 */
/*060*/ INT res19; /* always? -1 */
} MSFT_TypeInfoBase;
......@@ -272,9 +271,11 @@ typedef struct {
to the typeinfo itself or to a member of
the typeinfo */
INT next_hash; /* offset to next name in the hash bucket */
INT namelen; /* only lower 8 bits are valid,
lower-middle 8 bits are unknown (flags?),
upper 16 bits are hash code */
INT namelen; /* only lower 8 bits are valid */
/* 0x1000 if name is only used once as a variable name */
/* 0x2000 if name is a variable in an enumeration */
/* 0x3800 if name is typeinfo name */
/* upper 16 bits are hash code */
} MSFT_NameIntro;
/* the custom data table directory has enties like this */
typedef struct {
......
......@@ -1179,7 +1179,7 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func, int index)
unsigned int funckind = 1 /* FUNC_PUREVIRTUAL */, invokekind = 1 /* INVOKE_FUNC */;
int help_context = 0, help_string_context = 0, help_string_offset = -1;
id = ((0x6000 | typeinfo->typeinfo->cImplTypes) << 16) | index;
id = ((0x6000 | (typeinfo->typeinfo->datatype2 & 0xffff)) << 16) | index;
chat("add_func_desc(%p,%d)\n", typeinfo, index);
......@@ -1580,12 +1580,19 @@ static msft_typeinfo_t *create_msft_typeinfo(msft_typelib_t *typelib, enum type_
return msft_typeinfo;
}
static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface)
{
int idx = 0;
func_t *cur = interface->funcs;
func_t *func;
type_t *ref;
msft_typeinfo_t *msft_typeinfo;
int num_parents = 0, num_funcs = 0;
/* midl adds the parent interface first, unless the parent itself
has no parent (i.e. it stops before IUnknown). */
if(interface->ref && interface->ref->ref && interface->ref->typelib_idx == -1)
add_interface_typeinfo(typelib, interface->ref);
interface->typelib_idx = typelib->typelib_header.nrtypeinfos;
msft_typeinfo = create_msft_typeinfo(typelib, TKIND_INTERFACE, interface->name, interface->attrs,
......@@ -1596,11 +1603,27 @@ static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface)
if(interface->ref)
add_impl_type(msft_typeinfo, interface->ref);
while(NEXT_LINK(cur)) cur = NEXT_LINK(cur);
while(cur) {
if(add_func_desc(msft_typeinfo, cur, idx) == S_OK)
/* count the number of inherited interfaces and non-local functions */
for(ref = interface->ref; ref; ref = ref->ref) {
num_parents++;
for(func = ref->funcs; func; func = NEXT_LINK(func)) {
attr_t *attr;
for(attr = func->def->attrs; attr; attr = NEXT_LINK(attr))
if(attr->type == ATTR_LOCAL)
break;
if(!attr)
num_funcs++;
}
}
msft_typeinfo->typeinfo->datatype2 = num_funcs << 16 | num_parents;
msft_typeinfo->typeinfo->cbSizeVft = num_funcs * 4;
func = interface->funcs;
while(NEXT_LINK(func)) func = NEXT_LINK(func);
while(func) {
if(add_func_desc(msft_typeinfo, func, idx) == S_OK)
idx++;
cur = PREV_LINK(cur);
func = PREV_LINK(func);
}
}
......@@ -1985,7 +2008,7 @@ int create_msft_typelib(typelib_t *typelib)
set_custdata(msft, &midl_time_guid, VT_UI4, &cur_time, &msft->typelib_header.CustomDataOffset);
set_custdata(msft, &midl_version_guid, VT_UI4, &version, &msft->typelib_header.CustomDataOffset);
for(entry = typelib->entry; NEXT_LINK(entry); entry = NEXT_LINK(entry))
for(entry = typelib->entry; entry && NEXT_LINK(entry); entry = NEXT_LINK(entry))
;
for( ; entry; entry = PREV_LINK(entry))
......
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