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
This commit is contained in:
Huw Davies 2005-01-26 20:40:34 +00:00 committed by Alexandre Julliard
parent e5f2ed4c66
commit 652ec646ad
2 changed files with 40 additions and 16 deletions

View File

@ -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 {

View File

@ -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))