[2/5] widl: Handle encapsulated unions

Dan Hipschman dsh at linux.ucla.edu
Thu Jun 14 20:28:03 CDT 2007


This patch adds encapsulated union handling, which is the next feature
needed by oaidl.idl after interface pointers (handled by the previous
patch).  The test for it is included in the next patch, because the
test crashes in wine (but it passes on XP), and I've heard different
stories about what to do with tests that crash wine.  I'm sending them
separately in case the test gets rejected, this can still get
committed.

---
 tools/widl/parser.y  |    2 +-
 tools/widl/typegen.c |   27 +++++++++++++++++++++++++--
 2 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 739b60c..5f30ccc 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -509,7 +509,7 @@ cases:						{ $$ = NULL; }
 	| cases case				{ $$ = append_var( $1, $2 ); }
 	;
 
-case:	  tCASE expr ':' field			{ attr_t *a = make_attrp(ATTR_CASE, $2);
+case:	  tCASE expr ':' field			{ attr_t *a = make_attrp(ATTR_CASE, append_expr( NULL, $2 ));
 						  $$ = $4; if (!$$) $$ = make_var(NULL);
 						  $$->attrs = append_attr( $$->attrs, a );
 						}
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index 9a5910a..67872f0 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -1327,7 +1327,11 @@ static size_t write_pointer_only_tfs(FILE *file, const attr_list_t *attrs, int p
 
 static void write_branch_type(FILE *file, const type_t *t, unsigned int *tfsoff)
 {
-    if (is_base_type(t->type))
+    if (t == NULL)
+    {
+        print_file(file, 2, "NdrFcShort(0x0),\t/* No type */\n");
+    }
+    else if (is_base_type(t->type))
     {
         print_file(file, 2, "NdrFcShort(0x80%02x),\t/* Simple arm type: %s */\n",
                    t->type, string_of_type(t->type));
@@ -1349,7 +1353,7 @@ static size_t write_union_tfs(FILE *file, type_t *type, unsigned int *tfsoff)
     unsigned int align = 0;
     unsigned int start_offset;
     size_t size = type_memsize(type, &align);
-    var_list_t *fields = type->fields;
+    var_list_t *fields;
     size_t nbranch = 0;
     type_t *deftype = NULL;
     short nodeftype = 0xffff;
@@ -1357,6 +1361,14 @@ static size_t write_union_tfs(FILE *file, type_t *type, unsigned int *tfsoff)
 
     guard_rec(type);
 
+    if (type->type == RPC_FC_ENCAPSULATED_UNION)
+    {
+        const var_t *uv = LIST_ENTRY(list_tail(type->fields), const var_t, entry);
+        fields = uv->type->fields;
+    }
+    else
+        fields = type->fields;
+
     if (fields) LIST_FOR_EACH_ENTRY(f, fields, var_t, entry)
     {
         expr_list_t *cases = get_attrp(f->attrs, ATTR_CASE);
@@ -1369,6 +1381,17 @@ static size_t write_union_tfs(FILE *file, type_t *type, unsigned int *tfsoff)
     start_offset = *tfsoff;
     update_tfsoff(type, start_offset, file);
     print_file(file, 0, "/* %d */\n", start_offset);
+    if (type->type == RPC_FC_ENCAPSULATED_UNION)
+    {
+        const var_t *sv = LIST_ENTRY(list_head(type->fields), const var_t, entry);
+        const type_t *st = sv->type;
+        size_t ss = type_memsize(st, &align);
+
+        print_file(file, 2, "0x%x,\t/* %s */\n", type->type, string_of_type(type->type));
+        print_file(file, 2, "0x%x,\t/* Switch type= %s */\n",
+                   (ss << 4) | st->type, string_of_type(st->type));
+        *tfsoff += 2;
+    }
     print_file(file, 2, "NdrFcShort(0x%x),\t/* %d */\n", size, size);
     print_file(file, 2, "NdrFcShort(0x%x),\t/* %d */\n", nbranch, nbranch);
     *tfsoff += 4;



More information about the wine-patches mailing list