widl #28: add support for enums

Huw D M Davies h.davies1 at physics.ox.ac.uk
Tue Jan 25 08:54:14 CST 2005


        Huw Davies <huw at codeweavers.com>
        Add enum support.
        Another attempt at getting the alignment bits correct.
-- 
Huw Davies
huw at codeweavers.com
diff -u -p -X widl/.cvsignore -x '.*' -x '*.o' widl.orig/parser.y widl/parser.y
--- tools/widl/parser.y	2005-01-25 14:18:48.647522829 +0000
+++ tools/widl/parser.y	2005-01-25 14:39:42.022713893 +0000
@@ -428,15 +428,19 @@ enum_list: enum
 enum:	  ident '=' expr_const			{ $$ = reg_const($1);
 						  $$->eval = $3;
 						  $$->lval = $3->cval;
+                                                  $$->type = make_type(RPC_FC_LONG, &std_int);
 						}
 	| ident					{ $$ = reg_const($1);
 						  $$->lval = 0; /* default for first enum entry */
+                                                  $$->type = make_type(RPC_FC_LONG, &std_int);
 						}
 	;
 
 enumdef: tENUM t_ident '{' enums '}'		{ $$ = get_typev(RPC_FC_ENUM16, $2, tsENUM);
 						  $$->fields = $4;
 						  $$->defined = TRUE;
+                                                  if(in_typelib)
+                                                      add_enum($$);
 						}
 	;
 
diff -u -p -X widl/.cvsignore -x '.*' -x '*.o' widl.orig/typelib.c widl/typelib.c
--- tools/widl/typelib.c	2005-01-18 13:42:34.000000000 +0000
+++ tools/widl/typelib.c	2005-01-25 14:39:42.040709645 +0000
@@ -250,3 +250,16 @@ void add_struct(type_t *structure)
      LINK(entry, typelib->entry);
      typelib->entry = entry;
 }
+
+void add_enum(type_t *enumeration)
+{
+     typelib_entry_t *entry;
+     if (!typelib) return;
+
+     chat("add enum: %s\n", enumeration->name);
+     entry = xmalloc(sizeof(*entry));
+     entry->kind = TKIND_ENUM;
+     entry->u.enumeration = enumeration;
+     LINK(entry, typelib->entry);
+     typelib->entry = entry;
+}
diff -u -p -X widl/.cvsignore -x '.*' -x '*.o' widl.orig/typelib.h widl/typelib.h
--- tools/widl/typelib.h	2005-01-18 13:42:34.000000000 +0000
+++ tools/widl/typelib.h	2005-01-25 14:39:42.041709409 +0000
@@ -28,6 +28,7 @@ extern void add_interface(type_t *iface)
 extern void add_coclass(class_t *cls);
 extern void add_module(type_t *module);
 extern void add_struct(type_t *structure);
+extern void add_enum(type_t *enumeration);
 
 /* Copied from wtypes.h. Not included directly because that would create a
  * circular dependency (after all, wtypes.h is generated by widl...) */
diff -u -p -X widl/.cvsignore -x '.*' -x '*.o' widl.orig/widltypes.h widl/widltypes.h
--- tools/widl/widltypes.h	2005-01-18 13:42:34.000000000 +0000
+++ tools/widl/widltypes.h	2005-01-25 14:39:42.041709409 +0000
@@ -240,6 +240,7 @@ struct _typelib_entry_t {
         type_t *interface;
         type_t *module;
         type_t *structure;
+        type_t *enumeration;
     } u;
     DECL_LINK(typelib_entry_t)
 };
diff -u -p -X widl/.cvsignore -x '.*' -x '*.o' widl.orig/write_msft.c widl/write_msft.c
--- tools/widl/write_msft.c	2005-01-25 14:42:24.151444027 +0000
+++ tools/widl/write_msft.c	2005-01-25 14:41:28.105673214 +0000
@@ -1353,9 +1353,9 @@ static HRESULT add_func_desc(msft_typein
     typeinfo->names[index] = offset;
 
     namedata = typeinfo->typelib->typelib_segment_data[MSFT_SEG_NAME] + offset;
-    namedata[9] &= ~0x10;
     if (*((INT *)namedata) == -1) {
 	*((INT *)namedata) = typeinfo->typelib->typelib_typeinfo_offsets[typeinfo->typeinfo->typekind >> 16];
+        namedata[9] &= ~0x10;
     }
 
     for (arg = last_arg, i = 0; arg; arg = PREV_LINK(arg), i++) {
@@ -1369,49 +1369,13 @@ static HRESULT add_func_desc(msft_typein
     return S_OK;
 }
 
-
-static void set_alignment(
-        msft_typeinfo_t* typeinfo,
-        WORD cbAlignment)
-{
-
-    if (!cbAlignment) return;
-    if (cbAlignment > 16) return;
-
-    typeinfo->typeinfo->typekind &= ~0xf800;
-
-    /* FIXME: There's probably some way to simplify this. */
-    switch (typeinfo->typeinfo->typekind & 15) {
-    case TKIND_ALIAS:
-    default:
-	break;
-
-    case TKIND_ENUM:
-    case TKIND_INTERFACE:
-    case TKIND_DISPATCH:
-    case TKIND_COCLASS:
-	if (cbAlignment > 4) cbAlignment = 4;
-	break;
-
-    case TKIND_RECORD:
-    case TKIND_MODULE:
-    case TKIND_UNION:
-	cbAlignment = 1;
-	break;
-    }
-
-    typeinfo->typeinfo->typekind |= cbAlignment << 11;
-
-    return;
-}
-
 static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var)
 {
     int offset;
     INT *typedata;
     int var_datawidth;
     int var_alignment;
-    int var_type_size;
+    int var_type_size, var_kind = 0 /* VAR_PERINSTANCE */; 
     int alignment;
     int varflags = 0;
     attr_t *attr;
@@ -1460,20 +1424,26 @@ static HRESULT add_var_desc(msft_typeinf
     /* pad out starting position to data width */
     typeinfo->datawidth += var_alignment - 1;
     typeinfo->datawidth &= ~(var_alignment - 1);
-    typedata[4] = typeinfo->datawidth;
-    
-    /* add the new variable to the total data width */
-    typeinfo->datawidth += var_datawidth;
+
+    if((typeinfo->typeinfo->typekind & 0xf) == TKIND_ENUM) {
+        write_value(typeinfo->typelib, &typedata[4], VT_I4, &var->lval);
+        var_kind = 2; /* VAR_CONST */
+        var_type_size += 16; /* sizeof(VARIANT) */
+        typeinfo->datawidth = var_datawidth;
+    } else {
+        typedata[4] = typeinfo->datawidth;
+        typeinfo->datawidth += var_datawidth;
+    }
 
     /* add type description size to total required allocation */
-    typedata[3] += var_type_size << 16;
+    typedata[3] += var_type_size << 16 | var_kind;
 
     /* fix type alignment */
     alignment = (typeinfo->typeinfo->typekind >> 11) & 0x1f;
     if (alignment < var_alignment) {
 	alignment = var_alignment;
-	typeinfo->typeinfo->typekind &= ~0xf800;
-	typeinfo->typeinfo->typekind |= alignment << 11;
+	typeinfo->typeinfo->typekind &= ~0xffc0;
+	typeinfo->typeinfo->typekind |= alignment << 11 | alignment << 6;
     }
 
     /* ??? */
@@ -1499,7 +1469,9 @@ static HRESULT add_var_desc(msft_typeinf
     if (*((INT *)namedata) == -1) {
 	*((INT *)namedata) = typeinfo->typelib->typelib_typeinfo_offsets[typeinfo->typeinfo->typekind >> 16];
 	namedata[9] |= 0x10;
-    }
+    } else
+        namedata[9] &= ~0x10;
+
     if ((typeinfo->typeinfo->typekind & 15) == TKIND_ENUM) {
 	namedata[9] |= 0x20;
     }
@@ -1544,8 +1516,7 @@ static msft_typeinfo_t *create_msft_type
 
     msft_typeinfo->typeinfo = typeinfo;
 
-    typeinfo->typekind |= kind | 0x220;
-    set_alignment(msft_typeinfo, 4);
+    typeinfo->typekind |= kind | 0x20;
 
     for( ; attr; attr = NEXT_LINK(attr)) {
         switch(attr->type) {
@@ -1620,6 +1591,7 @@ static void add_interface_typeinfo(msft_
     msft_typeinfo = create_msft_typeinfo(typelib, TKIND_INTERFACE, interface->name, interface->attrs,
                                          typelib->typelib_header.nrtypeinfos);
     msft_typeinfo->typeinfo->size = 4;
+    msft_typeinfo->typeinfo->typekind |= 0x2200;
 
     if(interface->ref)
         add_impl_type(msft_typeinfo, interface->ref);
@@ -1651,6 +1623,25 @@ static void add_structure_typeinfo(msft_
     }
 }
 
+static void add_enum_typeinfo(msft_typelib_t *typelib, type_t *enumeration)
+{
+    int idx = 0;
+    var_t *cur = enumeration->fields;
+    msft_typeinfo_t *msft_typeinfo;
+
+    enumeration->typelib_idx = typelib->typelib_header.nrtypeinfos;
+    msft_typeinfo = create_msft_typeinfo(typelib, TKIND_ENUM, enumeration->name, enumeration->attrs,
+                                         typelib->typelib_header.nrtypeinfos);
+    msft_typeinfo->typeinfo->size = 0;
+
+    while(NEXT_LINK(cur)) cur = NEXT_LINK(cur);
+    while(cur) {
+        add_var_desc(msft_typeinfo, idx, cur);
+        idx++;
+        cur = PREV_LINK(cur);
+    }
+}
+
 static void add_entry(msft_typelib_t *typelib, typelib_entry_t *entry)
 {
     switch(entry->kind) {
@@ -1662,13 +1653,16 @@ static void add_entry(msft_typelib_t *ty
         add_structure_typeinfo(typelib, entry->u.structure);
         break;
 
+    case TKIND_ENUM:
+        add_enum_typeinfo(typelib, entry->u.enumeration);
+        break;
+
     default:
         error("add_entry: unhandled type %d\n", entry->kind);
         break;
     }
 }
 
-
 static void set_name(msft_typelib_t *typelib)
 {
     int offset;



More information about the wine-patches mailing list