widl [2/4]: Add a declonly argument to write_type_left

Dan Hipschman dsh at linux.ucla.edu
Tue Oct 2 23:39:38 CDT 2007


This patch adds another argument to write_type and friends to tell it to
only write the declaration of the type, instead of the full definition (with
structure fields, etc.).  This is mainly needed for the next patch, but it is
also cleaner to do things this way.  For example: In a cast expression or
function parameter, we should never write the whole type definition.  This
patch makes it easier to verify that we never do.  This doesn't change any
of the generated header files, and no new tests fail.

This was sent before, but came after a bad patch in a patch set:
http://www.winehq.org/pipermail/wine-patches/2007-September/044368.html

I guess this is a good place to mention that there is currently
another crash in the ole32 test that is not caused by a widl patch (at
least, not a recent one).  It only happens once in a while.  This is
from the official git branch with no local commits applied:

$ for i in `seq 1 10` ; do make -j1 clean check || break ; done
...
fixme:ntdll:RtlNtStatusToDosErrorNoTeb no mapping for 8000000a
err:ole:local_server_thread Failure during ConnectNamedPipe 317
marshal.c:2474: Test failed: error: 0
marshal.c:2476: Test failed: error 6
marshal.c:2551: Test failed: couldn't start local server process, error was 6
err:ole:create_server class {5201163f-8164-4fd0-a1a2-5d5a3654d3bd} not registered
err:ole:CoGetClassObject no class object {5201163f-8164-4fd0-a1a2-5d5a3654d3bd} could be created for context 0x4
marshal.c:2558: Test failed: CoCreateInstance failed with error 0x80040154
wine: Unhandled page fault on read access to 0x00000000 at address 0x60cc7f58 (thread 0021), starting debugger...
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x60cc7f58).
Register dump:
 CS:0023 SS:002b DS:002b ES:002b FS:0063 GS:006b
 EIP:60cc7f58 ESP:0033fc10 EBP:0033fdd8 EFLAGS:00010246(   - 00      -RIZP1)
 EAX:00000000 EBX:60ced3b4 ECX:00000000 EDX:60ceef70
 ESI:80040154 EDI:00000000
Stack dump:
0x0033fc10:  00000000 60ce15f4 80040154 60cebe48
0x0033fc20:  0033fdc4 00000000 00000000 00000000
0x0033fc30:  0033fd6c 0033fdb0 0033fd6c 60ce3be8
0x0033fc40:  60ce1158 60cebe48 60ce8f3b 60ce28c0
0x0033fc50:  0033fdc4 00000000 00000001 7bc4b173
0x0033fc60:  0033fc6c 0033fc6c 33656c6f 65745f32
Backtrace:
=>1 0x60cc7f58 test_local_server+0x69e() [/usr/local/google/work/wine/dlls/ole32/tests/marshal.c:2560] in ole32_test (0x0033fdd8)
  2 0x60cc9fc5 func_marshal+0xdb1() [/usr/local/google/work/wine/dlls/ole32/tests/marshal.c:2941] in ole32_test (0x0033fe98)
  3 0x60ce0582 run_test+0x131(name=0x1103ee) [/usr/local/google/work/wine/dlls/ole32/tests/../../../include/wine/test.h:389] in ole32_test (0x0033fee8)
  4 0x60ce08c3 __wine_spec_exe_entry+0x93(peb=0x7ffdf000) [/usr/local/google/work/wine/dlls/winecrt0/exe_entry.c:36] in ole32_test (0x0033ff08)
  5 0x7b86e04f start_process+0xe3(arg=0x0) [/usr/local/google/work/wine/dlls/kernel32/process.c:839] in kernel32 (0x0033ffe8)
  6 0x600204a7 wine_switch_to_stack+0x17() in libwine.so.1 (0x00000000)
0x60cc7f58 test_local_server+0x69e [/usr/local/google/work/wine/dlls/ole32/tests/marshal.c:2560] in ole32_test: movl    0x0(%eax),%edx
2560        IClassFactory_Release(cf);

This is different from the crash mentioned here:
http://www.winehq.org/pipermail/wine-devel/2007-September/059383.html

Anyway, this patch set has been tested and doesn't cause any new tests
to fail, but this crash still exists.

---
 tools/widl/client.c  |    4 +-
 tools/widl/header.c  |   67 ++++++++++++++++++++++++++++++++------------------
 tools/widl/header.h  |    6 +++-
 tools/widl/parser.y  |    6 ++--
 tools/widl/proxy.c   |    4 +-
 tools/widl/server.c  |    2 +-
 tools/widl/typegen.c |   16 ++++++------
 7 files changed, 63 insertions(+), 42 deletions(-)

diff --git a/tools/widl/client.c b/tools/widl/client.c
index 86ead20..1f35c3e 100644
--- a/tools/widl/client.c
+++ b/tools/widl/client.c
@@ -109,7 +109,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
             }
         }
 
-        write_type_left(client, def->type);
+        write_type_decl_left(client, def->type);
         if (needs_space_after(def->type))
           fprintf(client, " ");
         write_prefix_name(client, prefix_client, def);
@@ -130,7 +130,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
         if (!is_void(def->type))
         {
             print_client("");
-            write_type_left(client, def->type);
+            write_type_decl_left(client, def->type);
             fprintf(client, " _RetVal;\n");
         }
 
diff --git a/tools/widl/header.c b/tools/widl/header.c
index ded4c18..07a562b 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -156,7 +156,7 @@ static void write_field(FILE *h, var_t *v)
       }
     }
     indent(h, 0);
-    write_type(h, v->type, TRUE, "%s", name);
+    write_type_def_or_decl(h, v->type, TRUE, "%s", name);
     fprintf(h, ";\n");
   }
 }
@@ -193,19 +193,19 @@ int needs_space_after(type_t *t)
           || (!is_ptr(t) && (!is_conformant_array(t) || t->declarray)));
 }
 
-void write_type_left(FILE *h, type_t *t)
+void write_type_left(FILE *h, type_t *t, int declonly)
 {
   if (t->is_const) fprintf(h, "const ");
 
   if (t->kind == TKIND_ALIAS) fprintf(h, "%s", t->name);
-  else if (t->declarray) write_type_left(h, t->ref);
+  else if (t->declarray) write_type_left(h, t->ref, declonly);
   else {
     if (t->sign > 0) fprintf(h, "signed ");
     else if (t->sign < 0) fprintf(h, "unsigned ");
     switch (t->type) {
       case RPC_FC_ENUM16:
       case RPC_FC_ENUM32:
-        if (t->defined && !t->written && !t->ignore) {
+        if (!declonly && t->defined && !t->written && !t->ignore) {
           if (t->name) fprintf(h, "enum %s {\n", t->name);
           else fprintf(h, "enum {\n");
           t->written = TRUE;
@@ -223,7 +223,7 @@ void write_type_left(FILE *h, type_t *t)
       case RPC_FC_PSTRUCT:
       case RPC_FC_BOGUS_STRUCT:
       case RPC_FC_ENCAPSULATED_UNION:
-        if (t->defined && !t->written && !t->ignore) {
+        if (!declonly && t->defined && !t->written && !t->ignore) {
           if (t->name) fprintf(h, "struct %s {\n", t->name);
           else fprintf(h, "struct {\n");
           t->written = TRUE;
@@ -235,7 +235,7 @@ void write_type_left(FILE *h, type_t *t)
         else fprintf(h, "struct %s", t->name);
         break;
       case RPC_FC_NON_ENCAPSULATED_UNION:
-        if (t->defined && !t->written && !t->ignore) {
+        if (!declonly && t->defined && !t->written && !t->ignore) {
           if (t->name) fprintf(h, "union %s {\n", t->name);
           else fprintf(h, "union {\n");
           t->written = TRUE;
@@ -253,7 +253,7 @@ void write_type_left(FILE *h, type_t *t)
       case RPC_FC_CARRAY:
       case RPC_FC_CVARRAY:
       case RPC_FC_BOGUS_ARRAY:
-        write_type_left(h, t->ref);
+        write_type_left(h, t->ref, declonly);
         fprintf(h, "%s*", needs_space_after(t->ref) ? " " : "");
         break;
       default:
@@ -274,20 +274,39 @@ void write_type_right(FILE *h, type_t *t, int is_field)
   }
 }
 
-void write_type(FILE *h, type_t *t, int is_field, const char *fmt, ...)
+void write_type_v(FILE *h, type_t *t, int is_field, int declonly,
+                  const char *fmt, va_list args)
 {
-  write_type_left(h, t);
+  write_type_left(h, t, declonly);
   if (fmt) {
-    va_list args;
-    va_start(args, fmt);
     if (needs_space_after(t))
       fprintf(h, " ");
     vfprintf(h, fmt, args);
-    va_end(args);
   }
   write_type_right(h, t, is_field);
 }
 
+void write_type_def_or_decl(FILE *f, type_t *t, int field, const char *fmt, ...)
+{
+  va_list args;
+  va_start(args, fmt);
+  write_type_v(f, t, field, FALSE, fmt, args);
+  va_end(args);
+}
+
+void write_type_decl(FILE *f, type_t *t, const char *fmt, ...)
+{
+  va_list args;
+  va_start(args, fmt);
+  write_type_v(f, t, FALSE, TRUE, fmt, args);
+  va_end(args);
+}
+
+void write_type_decl_left(FILE *f, type_t *t)
+{
+  write_type_left(f, t, TRUE);
+}
+
 static int user_type_registered(const char *name)
 {
   user_type_t *ut;
@@ -373,7 +392,7 @@ void write_context_handle_rundowns(void)
 void write_typedef(type_t *type)
 {
   fprintf(header, "typedef ");
-  write_type(header, type->orig, FALSE, "%s", type->name);
+  write_type_def_or_decl(header, type->orig, FALSE, "%s", type->name);
   fprintf(header, ";\n");
 }
 
@@ -414,13 +433,13 @@ void write_expr(FILE *h, const expr_t *e, int brackets)
     break;
   case EXPR_CAST:
     fprintf(h, "(");
-    write_type(h, e->u.tref, FALSE, NULL);
+    write_type_decl(h, e->u.tref, NULL);
     fprintf(h, ")");
     write_expr(h, e->ref, 1);
     break;
   case EXPR_SIZEOF:
     fprintf(h, "sizeof(");
-    write_type(h, e->u.tref, FALSE, NULL);
+    write_type_decl(h, e->u.tref, NULL);
     fprintf(h, ")");
     break;
   case EXPR_SHL:
@@ -469,7 +488,7 @@ void write_constdef(const var_t *v)
 void write_externdef(const var_t *v)
 {
   fprintf(header, "extern const ");
-  write_type(header, v->type, FALSE, "%s", v->name);
+  write_type_def_or_decl(header, v->type, FALSE, "%s", v->name);
   fprintf(header, ";\n\n");
 }
 
@@ -595,7 +614,7 @@ void write_args(FILE *h, const var_list_t *args, const char *name, int method, i
     }
     if (arg->args)
     {
-      write_type_left(h, arg->type);
+      write_type_decl_left(h, arg->type);
       fprintf(h, " (STDMETHODCALLTYPE *");
       write_name(h,arg);
       fprintf(h, ")(");
@@ -603,7 +622,7 @@ void write_args(FILE *h, const var_list_t *args, const char *name, int method, i
       fprintf(h, ")");
     }
     else
-      write_type(h, arg->type, FALSE, "%s", arg->name);
+      write_type_decl(h, arg->type, "%s", arg->name);
     count++;
   }
   if (do_indent) indentation--;
@@ -621,7 +640,7 @@ static void write_cpp_method_def(const type_t *iface)
     if (!is_callas(def->attrs)) {
       indent(header, 0);
       fprintf(header, "virtual ");
-      write_type_left(header, def->type);
+      write_type_decl_left(header, def->type);
       fprintf(header, " STDMETHODCALLTYPE ");
       write_name(header, def);
       fprintf(header, "(\n");
@@ -646,7 +665,7 @@ static void do_write_c_method_def(const type_t *iface, const char *name)
     const var_t *def = cur->def;
     if (!is_callas(def->attrs)) {
       indent(header, 0);
-      write_type_left(header, def->type);
+      write_type_decl_left(header, def->type);
       fprintf(header, " (STDMETHODCALLTYPE *");
       write_name(header, def);
       fprintf(header, ")(\n");
@@ -679,7 +698,7 @@ static void write_method_proto(const type_t *iface)
 
     if (!is_local(def->attrs)) {
       /* proxy prototype */
-      write_type_left(header, def->type);
+      write_type_decl_left(header, def->type);
       fprintf(header, " CALLBACK %s_", iface->name);
       write_name(header, def);
       fprintf(header, "_Proxy(\n");
@@ -701,14 +720,14 @@ static void write_method_proto(const type_t *iface)
       if (&m->entry != iface->funcs) {
         const var_t *mdef = m->def;
         /* proxy prototype - use local prototype */
-        write_type_left(header, mdef->type);
+        write_type_decl_left(header, mdef->type);
         fprintf(header, " CALLBACK %s_", iface->name);
         write_name(header, mdef);
         fprintf(header, "_Proxy(\n");
         write_args(header, m->args, iface->name, 1, TRUE);
         fprintf(header, ");\n");
         /* stub prototype - use remotable prototype */
-        write_type_left(header, def->type);
+        write_type_decl_left(header, def->type);
         fprintf(header, " __RPC_STUB %s_", iface->name);
         write_name(header, mdef);
         fprintf(header, "_Stub(\n");
@@ -727,7 +746,7 @@ static void write_function_proto(const type_t *iface, const func_t *fun, const c
   var_t *def = fun->def;
 
   /* FIXME: do we need to handle call_as? */
-  write_type_left(header, def->type);
+  write_type_decl_left(header, def->type);
   fprintf(header, " ");
   write_prefix_name(header, prefix, def);
   fprintf(header, "(\n");
diff --git a/tools/widl/header.h b/tools/widl/header.h
index 3c6a124..3937971 100644
--- a/tools/widl/header.h
+++ b/tools/widl/header.h
@@ -32,9 +32,11 @@ extern int is_conformant_array(const type_t *t);
 extern void write_name(FILE *h, const var_t *v);
 extern void write_prefix_name(FILE *h, const char *prefix, const var_t *v);
 extern const char* get_name(const var_t *v);
-extern void write_type_left(FILE *h, type_t *t);
+extern void write_type_left(FILE *h, type_t *t, int declonly);
 extern void write_type_right(FILE *h, type_t *t, int is_field);
-extern void write_type(FILE *h, type_t *t, int is_field, const char *fmt, ...);
+extern void write_type_def_or_decl(FILE *h, type_t *t, int is_field, const char *fmt, ...);
+extern void write_type_decl(FILE *f, type_t *t, const char *fmt, ...);
+extern void write_type_decl_left(FILE *f, type_t *t);
 extern int needs_space_after(type_t *t);
 extern int is_object(const attr_list_t *list);
 extern int is_local(const attr_list_t *list);
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 365d546..59bc6e1 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -325,20 +325,20 @@ statement: ';'					{}
 	| constdef ';'				{ if (!parse_only && do_header) { write_constdef($1); } }
 	| cppquote				{}
 	| enumdef ';'				{ if (!parse_only && do_header) {
-						    write_type(header, $1, FALSE, NULL);
+						    write_type_def_or_decl(header, $1, FALSE, NULL);
 						    fprintf(header, ";\n\n");
 						  }
 						}
 	| externdef ';'				{ if (!parse_only && do_header) { write_externdef($1); } }
 	| import				{}
 	| structdef ';'				{ if (!parse_only && do_header) {
-						    write_type(header, $1, FALSE, NULL);
+						    write_type_def_or_decl(header, $1, FALSE, NULL);
 						    fprintf(header, ";\n\n");
 						  }
 						}
 	| typedef ';'				{}
 	| uniondef ';'				{ if (!parse_only && do_header) {
-						    write_type(header, $1, FALSE, NULL);
+						    write_type_def_or_decl(header, $1, FALSE, NULL);
 						    fprintf(header, ";\n\n");
 						  }
 						}
diff --git a/tools/widl/proxy.c b/tools/widl/proxy.c
index 4911caf..98d4ddb 100644
--- a/tools/widl/proxy.c
+++ b/tools/widl/proxy.c
@@ -255,7 +255,7 @@ static void gen_proxy(type_t *iface, const func_t *cur, int idx,
   int has_ret = !is_void(def->type);
 
   indent = 0;
-  write_type_left(proxy, def->type);
+  write_type_decl_left(proxy, def->type);
   print_proxy( " STDMETHODCALLTYPE %s_", iface->name);
   write_name(proxy, def);
   print_proxy( "_Proxy(\n");
@@ -266,7 +266,7 @@ static void gen_proxy(type_t *iface, const func_t *cur, int idx,
   /* local variables */
   if (has_ret) {
     print_proxy( "" );
-    write_type_left(proxy, def->type);
+    write_type_decl_left(proxy, def->type);
     print_proxy( " _RetVal;\n");
   }
   print_proxy( "RPC_MESSAGE _RpcMessage;\n" );
diff --git a/tools/widl/server.c b/tools/widl/server.c
index f708d25..8c9345c 100644
--- a/tools/widl/server.c
+++ b/tools/widl/server.c
@@ -187,7 +187,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
                 if (is_context_handle(var->type))
                 {
                     print_server("(");
-                    write_type_left(server, var->type);
+                    write_type_decl_left(server, var->type);
                     fprintf(server, ")%sNDRSContextValue(%s)", is_ptr(var->type) ? "" : "*", var->name);
                 }
                 else
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index b5c861c..e3bdd83 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -2548,7 +2548,7 @@ void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase,
     if (phase == PHASE_MARSHAL)
     {
         print_file(file, indent, "*(");
-        write_type(file, is_ptr(type) ? type->ref : type, FALSE, NULL);
+        write_type_decl(file, is_ptr(type) ? type->ref : type, NULL);
         if (is_ptr(type))
             fprintf(file, " *)_StubMsg.Buffer = *");
         else
@@ -2567,12 +2567,12 @@ void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase,
             fprintf(file, " = (");
         else
             fprintf(file, " = *(");
-        write_type(file, is_ptr(type) ? type->ref : type, FALSE, NULL);
+        write_type_decl(file, is_ptr(type) ? type->ref : type, NULL);
         fprintf(file, " *)_StubMsg.Buffer;\n");
     }
 
     print_file(file, indent, "_StubMsg.Buffer += sizeof(");
-    write_type(file, var->type, FALSE, NULL);
+    write_type_decl(file, var->type, NULL);
     fprintf(file, ");\n");
 }
 
@@ -2930,13 +2930,13 @@ static void write_struct_expr(FILE *h, const expr_t *e, int brackets,
             break;
         case EXPR_CAST:
             fprintf(h, "(");
-            write_type(h, e->u.tref, FALSE, NULL);
+            write_type_decl(h, e->u.tref, NULL);
             fprintf(h, ")");
             write_struct_expr(h, e->ref, 1, fields, structvar);
             break;
         case EXPR_SIZEOF:
             fprintf(h, "sizeof(");
-            write_type(h, e->u.tref, FALSE, NULL);
+            write_type_decl(h, e->u.tref, NULL);
             fprintf(h, ")");
             break;
         case EXPR_SHL:
@@ -2987,7 +2987,7 @@ void declare_stub_args( FILE *file, int indent, const func_t *func )
     if (!is_void(def->type))
     {
         print_file(file, indent, "");
-        write_type_left(file, def->type);
+        write_type_decl_left(file, def->type);
         fprintf(file, " _RetVal;\n");
     }
 
@@ -3010,12 +3010,12 @@ void declare_stub_args( FILE *file, int indent, const func_t *func )
             if (!in_attr && !var->type->size_is && !is_string)
             {
                 print_file(file, indent, "");
-                write_type(file, var->type->ref, FALSE, "_W%u", i++);
+                write_type_decl(file, var->type->ref, "_W%u", i++);
                 fprintf(file, ";\n");
             }
 
             print_file(file, indent, "");
-            write_type_left(file, var->type);
+            write_type_decl_left(file, var->type);
             fprintf(file, " ");
             if (var->type->declarray) {
                 fprintf(file, "( *");



More information about the wine-patches mailing list