Coclass support.
authorHuw Davies <huw@codeweavers.com>
Thu, 3 Feb 2005 13:34:28 +0000 (13:34 +0000)
committerAlexandre Julliard <julliard@winehq.org>
Thu, 3 Feb 2005 13:34:28 +0000 (13:34 +0000)
tools/widl/parser.l
tools/widl/parser.y
tools/widl/typelib.c
tools/widl/widltypes.h
tools/widl/write_msft.c

index c03d3a52d104e8ce7b9ecc9e8abdc72b097981d7..340322cc15c11027025c3e563009b8f677c93b0d 100644 (file)
@@ -259,6 +259,7 @@ static struct keyword {
 /* ... */
        {"module",                      tMODULE},
 /* ... */
+       {"noncreatable",                tNONCREATABLE},
        {"object",                      tOBJECT},
        {"odl",                         tODL},
        {"oleautomation",               tOLEAUTOMATION},
index 3a981cf547d6b2607108ddf881b7d7717e02197d..80b781559779fa064693227e7f0dd223ba0dfeab 100644 (file)
@@ -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); }
index af3d687b06b9a32005e2cfd37c4523d0d28e0938..52c4713ed3cc96f8e3c6358490ca1b9617d10e0c 100644 (file)
@@ -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;
index 559365909a66b3ef4fd567d54d7f4a55480158e4..5f142225e3778c073841b87f5aea49c0a8057d77 100644 (file)
@@ -83,6 +83,7 @@ enum attr_type
     ATTR_INPUTSYNC,
     ATTR_LENGTHIS,
     ATTR_LOCAL,
+    ATTR_NONCREATABLE,
     ATTR_OBJECT,
     ATTR_ODL,
     ATTR_OLEAUTOMATION,
index a1e8d962de1c3f2fb596a94d9651fbabb14a574e..e0a4df42f0185d197244021bb842f0ff3fad0174 100644 (file)
@@ -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;