widl: Added support for importing parent interfaces from importlib.
This commit is contained in:
parent
ae2c061e8e
commit
a7fa3a985b
|
@ -583,7 +583,7 @@ static int ctl2_alloc_string(
|
|||
}
|
||||
|
||||
/****************************************************************************
|
||||
* alloc_importinfo
|
||||
* alloc_msft_importinfo
|
||||
*
|
||||
* Allocates and initializes an import information structure in a type library.
|
||||
*
|
||||
|
@ -592,7 +592,7 @@ static int ctl2_alloc_string(
|
|||
* Success: The offset of the new importinfo.
|
||||
* Failure: -1 (this is invariably an out of memory condition).
|
||||
*/
|
||||
static int alloc_importinfo(
|
||||
static int alloc_msft_importinfo(
|
||||
msft_typelib_t *typelib, /* [I] The type library to allocate in. */
|
||||
MSFT_ImpInfo *impinfo) /* [I] The import information to store. */
|
||||
{
|
||||
|
@ -664,6 +664,79 @@ static int alloc_importfile(
|
|||
return offset;
|
||||
}
|
||||
|
||||
static void alloc_importinfo(msft_typelib_t *typelib, importinfo_t *importinfo)
|
||||
{
|
||||
importlib_t *importlib = importinfo->importlib;
|
||||
|
||||
chat("alloc_importinfo: %s\n", importinfo->name);
|
||||
|
||||
if(!importlib->allocated) {
|
||||
MSFT_GuidEntry guid;
|
||||
int guid_idx;
|
||||
|
||||
chat("allocating importlib %s\n", importlib->name);
|
||||
|
||||
importlib->allocated = -1;
|
||||
|
||||
memcpy(&guid.guid, &importlib->guid, sizeof(GUID));
|
||||
guid.hreftype = 2;
|
||||
|
||||
guid_idx = ctl2_alloc_guid(typelib, &guid);
|
||||
|
||||
alloc_importfile(typelib, guid_idx, importlib->version&0xffff,
|
||||
importlib->version>>16, importlib->name);
|
||||
}
|
||||
|
||||
if(importinfo->offset == -1 || !(importinfo->flags & MSFT_IMPINFO_OFFSET_IS_GUID)) {
|
||||
MSFT_ImpInfo impinfo;
|
||||
|
||||
impinfo.flags = importinfo->flags;
|
||||
impinfo.oImpFile = 0;
|
||||
|
||||
if(importinfo->flags & MSFT_IMPINFO_OFFSET_IS_GUID) {
|
||||
MSFT_GuidEntry guid;
|
||||
|
||||
guid.hreftype = 0;
|
||||
memcpy(&guid.guid, &importinfo->guid, sizeof(GUID));
|
||||
|
||||
impinfo.oGuid = ctl2_alloc_guid(typelib, &guid);
|
||||
|
||||
importinfo->offset = alloc_msft_importinfo(typelib, &impinfo);
|
||||
|
||||
typelib->typelib_segment_data[MSFT_SEG_GUID][impinfo.oGuid+sizeof(GUID)]
|
||||
= importinfo->offset+1;
|
||||
|
||||
if(!strcmp(importinfo->name, "IDispatch"))
|
||||
typelib->typelib_header.dispatchpos = importinfo->offset+1;
|
||||
}else {
|
||||
impinfo.oGuid = importinfo->id;
|
||||
importinfo->offset = alloc_msft_importinfo(typelib, &impinfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static importinfo_t *find_importinfo(msft_typelib_t *typelib, const char *name)
|
||||
{
|
||||
importlib_t *importlib;
|
||||
int i;
|
||||
|
||||
chat("search importlib %s\n", name);
|
||||
|
||||
if(!name)
|
||||
return NULL;
|
||||
|
||||
for(importlib = typelib->typelib->importlibs; importlib; importlib = NEXT_LINK(importlib)) {
|
||||
for(i=0; i < importlib->ntypeinfos; i++) {
|
||||
if(!strcmp(name, importlib->importinfos[i].name)) {
|
||||
chat("Found %s in importlib.\n", name);
|
||||
return importlib->importinfos+i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void add_structure_typeinfo(msft_typelib_t *typelib, type_t *structure);
|
||||
static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface);
|
||||
static void add_enum_typeinfo(msft_typelib_t *typelib, type_t *enumeration);
|
||||
|
@ -1634,14 +1707,20 @@ static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var)
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT add_impl_type(msft_typeinfo_t *typeinfo, type_t *ref)
|
||||
static HRESULT add_impl_type(msft_typeinfo_t *typeinfo, type_t *ref, importinfo_t *importinfo)
|
||||
{
|
||||
if(ref->typelib_idx == -1)
|
||||
add_interface_typeinfo(typeinfo->typelib, ref);
|
||||
if(ref->typelib_idx == -1)
|
||||
error("add_impl_type: unable to add inherited interface\n");
|
||||
if(importinfo) {
|
||||
alloc_importinfo(typeinfo->typelib, importinfo);
|
||||
typeinfo->typeinfo->datatype1 = importinfo->offset+1;
|
||||
}else {
|
||||
if(ref->typelib_idx == -1)
|
||||
add_interface_typeinfo(typeinfo->typelib, ref);
|
||||
if(ref->typelib_idx == -1)
|
||||
error("add_impl_type: unable to add inherited interface\n");
|
||||
|
||||
typeinfo->typeinfo->datatype1 = typeinfo->typelib->typelib_typeinfo_offsets[ref->typelib_idx];
|
||||
}
|
||||
|
||||
typeinfo->typeinfo->datatype1 = typeinfo->typelib->typelib_typeinfo_offsets[ref->typelib_idx];
|
||||
typeinfo->typeinfo->cImplTypes++;
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -1807,7 +1886,7 @@ static void add_dispatch(msft_typelib_t *typelib)
|
|||
impinfo.flags = TKIND_INTERFACE << 24 | MSFT_IMPINFO_OFFSET_IS_GUID;
|
||||
impinfo.oImpFile = impfile_offset;
|
||||
impinfo.oGuid = ctl2_alloc_guid(typelib, &guidentry);
|
||||
typelib->typelib_header.dispatchpos = alloc_importinfo(typelib, &impinfo) | 0x01;
|
||||
typelib->typelib_header.dispatchpos = alloc_msft_importinfo(typelib, &impinfo) | 0x01;
|
||||
}
|
||||
|
||||
static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinterface)
|
||||
|
@ -1861,6 +1940,7 @@ static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface)
|
|||
func_t *func;
|
||||
type_t *ref;
|
||||
msft_typeinfo_t *msft_typeinfo;
|
||||
importinfo_t *ref_importinfo = NULL;
|
||||
int num_parents = 0, num_funcs = 0;
|
||||
const attr_t *attr;
|
||||
const type_t *derived;
|
||||
|
@ -1872,8 +1952,12 @@ static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface)
|
|||
/* 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);
|
||||
if(interface->ref) {
|
||||
ref_importinfo = find_importinfo(typelib, interface->ref->name);
|
||||
|
||||
if(!ref_importinfo && 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,
|
||||
|
@ -1890,7 +1974,7 @@ static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface)
|
|||
msft_typeinfo->typeinfo->flags &= ~0x40; /* TYPEFLAG_FDUAL */
|
||||
|
||||
if(interface->ref)
|
||||
add_impl_type(msft_typeinfo, interface->ref);
|
||||
add_impl_type(msft_typeinfo, interface->ref, ref_importinfo);
|
||||
|
||||
/* count the number of inherited interfaces and non-local functions */
|
||||
for(ref = interface->ref; ref; ref = ref->ref) {
|
||||
|
|
Loading…
Reference in New Issue