diff --git a/tools/widl/parser.l b/tools/widl/parser.l index c03d3a52d1..340322cc15 100644 --- a/tools/widl/parser.l +++ b/tools/widl/parser.l @@ -259,6 +259,7 @@ static struct keyword { /* ... */ {"module", tMODULE}, /* ... */ + {"noncreatable", tNONCREATABLE}, {"object", tOBJECT}, {"odl", tODL}, {"oleautomation", tOLEAUTOMATION}, diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 3a981cf547..80b7815597 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -157,6 +157,7 @@ static type_t std_uhyper = { "MIDL_uhyper" }; %token tLONG %token tMETHODS %token tMODULE +%token tNONCREATABLE %token tOBJECT tODL tOLEAUTOMATION %token tOPTIONAL %token tOUT @@ -360,6 +361,7 @@ attribute: | tINPUTSYNC { $$ = make_attr(ATTR_INPUTSYNC); } | tLENGTHIS '(' m_exprs ')' { $$ = make_attrp(ATTR_LENGTHIS, $3); } | tLOCAL { $$ = make_attr(ATTR_LOCAL); } + | tNONCREATABLE { $$ = make_attr(ATTR_NONCREATABLE); } | tOBJECT { $$ = make_attr(ATTR_OBJECT); } | tODL { $$ = make_attr(ATTR_ODL); } | tOLEAUTOMATION { $$ = make_attr(ATTR_OLEAUTOMATION); } diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c index af3d687b06..52c4713ed3 100644 --- a/tools/widl/typelib.c +++ b/tools/widl/typelib.c @@ -205,22 +205,12 @@ void add_interface(type_t *iface) void add_coclass(class_t *cls) { - ifref_t *lcur = cls->ifaces; - ifref_t *cur; typelib_entry_t *entry; - if (lcur) { - while (NEXT_LINK(lcur)) lcur = NEXT_LINK(lcur); - } - if (!typelib) return; - /* install interfaces the coclass depends on */ - cur = lcur; - while (cur) { - add_interface(cur->iface); - cur = PREV_LINK(cur); - } + chat("add coclass: %s\n", cls->name); + entry = xmalloc(sizeof(*entry)); entry->kind = TKIND_COCLASS; entry->u.class = cls; diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index 559365909a..5f142225e3 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -83,6 +83,7 @@ enum attr_type ATTR_INPUTSYNC, ATTR_LENGTHIS, ATTR_LOCAL, + ATTR_NONCREATABLE, ATTR_OBJECT, ATTR_ODL, ATTR_OLEAUTOMATION, diff --git a/tools/widl/write_msft.c b/tools/widl/write_msft.c index a1e8d962de..e0a4df42f0 100644 --- a/tools/widl/write_msft.c +++ b/tools/widl/write_msft.c @@ -1590,6 +1590,9 @@ static msft_typeinfo_t *create_msft_typeinfo(msft_typelib_t *typelib, enum type_ typeinfo->typekind |= kind | 0x20; + if(kind == TKIND_COCLASS) + typeinfo->flags |= 0x2; /* TYPEFLAG_FCANCREATE */ + for( ; attr; attr = NEXT_LINK(attr)) { switch(attr->type) { case ATTR_HELPCONTEXT: @@ -1615,6 +1618,10 @@ static msft_typeinfo_t *create_msft_typeinfo(msft_typelib_t *typelib, enum type_ typeinfo->flags |= 0x10; /* TYPEFLAG_FHIDDEN */ break; + case ATTR_NONCREATABLE: + typeinfo->flags &= ~0x2; /* TYPEFLAG_FCANCREATE */ + break; + case ATTR_ODL: break; @@ -1819,7 +1826,6 @@ static void add_enum_typeinfo(msft_typelib_t *typelib, type_t *enumeration) } } - static void add_typedef_typeinfo(msft_typelib_t *typelib, var_t *tdef) { msft_typeinfo_t *msft_typeinfo; @@ -1837,6 +1843,86 @@ static void add_typedef_typeinfo(msft_typelib_t *typelib, var_t *tdef) msft_typeinfo->typeinfo->typekind |= (alignment << 11 | alignment << 6); } +static void add_coclass_typeinfo(msft_typelib_t *typelib, class_t *cls) +{ + msft_typeinfo_t *msft_typeinfo; + ifref_t *iref; + int num_ifaces = 0, offset, i; + MSFT_RefRecord *ref, *first = NULL, *first_source = NULL; + int have_default = 0, have_default_source = 0; + attr_t *attr; + + msft_typeinfo = create_msft_typeinfo(typelib, TKIND_COCLASS, cls->name, cls->attrs, + typelib->typelib_header.nrtypeinfos); + + if((iref = cls->ifaces)) { + num_ifaces++; + while(NEXT_LINK(iref)) { + iref = NEXT_LINK(iref); + num_ifaces++; + } + } + + offset = msft_typeinfo->typeinfo->datatype1 = ctl2_alloc_segment(typelib, MSFT_SEG_REFERENCES, + num_ifaces * sizeof(*ref), 0); + for(i = 0; i < num_ifaces; i++) { + if(iref->iface->typelib_idx == -1) + add_interface_typeinfo(typelib, iref->iface); + ref = (MSFT_RefRecord*) (typelib->typelib_segment_data[MSFT_SEG_REFERENCES] + offset + i * sizeof(*ref)); + ref->reftype = typelib->typelib_typeinfo_offsets[iref->iface->typelib_idx]; + ref->flags = 0; + ref->oCustData = -1; + ref->onext = -1; + if(i < num_ifaces - 1) + ref->onext = offset + (i + 1) * sizeof(*ref); + + for(attr = iref->attrs; attr; attr = NEXT_LINK(attr)) { + switch(attr->type) { + case ATTR_DEFAULT: + ref->flags |= 0x1; /* IMPLTYPEFLAG_FDEFAULT */ + break; + case ATTR_RESTRICTED: + ref->flags |= 0x4; /* IMPLTYPEFLAG_FRESTRICTED */ + break; + case ATTR_SOURCE: + ref->flags |= 0x2; /* IMPLTYPEFLAG_FSOURCE */ + break; + default: + warning("add_coclass_typeinfo: unhandled attr %d\n", attr->type); + } + } + if(ref->flags & 0x1) { /* IMPLTYPEFLAG_FDEFAULT */ + if(ref->flags & 0x2) /* IMPLTYPEFLAG_SOURCE */ + have_default_source = 1; + else + have_default = 1; + } + + /* If the interface is non-restricted and we haven't already had one then + remember it so that we can use it as a default later */ + if((ref->flags & 0x4) == 0) { /* IMPLTYPEFLAG_FRESTRICTED */ + if(ref->flags & 0x2) { /* IMPLTYPEFLAG_FSOURCE */ + if(!first_source) + first_source = ref; + } + else if(!first) + first = ref; + } + iref = PREV_LINK(iref); + } + + /* If we haven't had a default interface, then set the default flags on the + first ones */ + if(!have_default && first) + first->flags |= 0x1; + if(!have_default_source && first_source) + first_source->flags |= 0x1; + + msft_typeinfo->typeinfo->cImplTypes = num_ifaces; + msft_typeinfo->typeinfo->size = 4; + msft_typeinfo->typeinfo->typekind |= 0x2200; +} + static void add_entry(msft_typelib_t *typelib, typelib_entry_t *entry) { switch(entry->kind) { @@ -1856,6 +1942,10 @@ static void add_entry(msft_typelib_t *typelib, typelib_entry_t *entry) add_typedef_typeinfo(typelib, entry->u.tdef); break; + case TKIND_COCLASS: + add_coclass_typeinfo(typelib, entry->u.class); + break; + default: error("add_entry: unhandled type %d\n", entry->kind); break;