widl [3/3]: Don't output a void conformance for NdrClearOutParameters.

Dan Hipschman dsh at linux.ucla.edu
Fri Nov 2 17:25:26 CDT 2007


This fixes a bug in the proxy output which produced code that wouldn't
compile from dcom.idl.  The problem was that there is a [size_is(, n)]
attribute, but widl code was taking the first expression regardless of
the fact it was void.

This and the last patch both punt on true multidimensional conformant
arrays for now (where more than one of the size_is expressions are
non-void), but those weren't implemented anyways and would probably
just crash when the stubs were executed.  This way widl actually complains
and dies.  I don't know of anything in Wine that needs them yet, anyway.

With this we can get a proxy for dcom.idl.  I'm trying to replace the
PSFactoryBuffer that only works for IClassFactory and IRemUnknown in ole32
with the CStdPSFactoryBuffer initialized by NdrDllGetClassObject so we can
add all the new proxies to ole32 in a general way.  Hopefully that's
actually possible.  :-)

---
 tools/widl/proxy.c   |    9 +++------
 tools/widl/typegen.c |   44 +++++++++++++++++++++++++-------------------
 tools/widl/typegen.h |    1 +
 3 files changed, 29 insertions(+), 25 deletions(-)

diff --git a/tools/widl/proxy.c b/tools/widl/proxy.c
index aa9fe11..8a81885 100644
--- a/tools/widl/proxy.c
+++ b/tools/widl/proxy.c
@@ -189,13 +189,11 @@ static void free_variable( const var_t *arg )
 {
   unsigned int type_offset = arg->type->typestring_offset;
   var_t *constraint;
-  type_t *type;
-  expr_list_t *expr;
+  type_t *type = arg->type;
+  expr_t *size = get_size_is_expr(type, arg->name);
 
-  expr = get_attrp( arg->attrs, ATTR_SIZEIS );
-  if (expr)
+  if (size)
   {
-    const expr_t *size = LIST_ENTRY( list_head(expr), const expr_t, entry );
     print_proxy( "_StubMsg.MaxCount = " );
     write_expr(proxy, size, 0);
     fprintf(proxy, ";\n\n");
@@ -205,7 +203,6 @@ static void free_variable( const var_t *arg )
     return;
   }
 
-  type = arg->type;
   switch( type->type )
   {
   case RPC_FC_BYTE:
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index a9cd2eb..2cb8dc9 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -2609,6 +2609,24 @@ static int needs_freeing(const attr_list_t *attrs, const type_t *t, int out)
                     || is_array(t)));
 }
 
+expr_t *get_size_is_expr(const type_t *t, const char *name)
+{
+    expr_t *x = NULL;
+
+    for ( ; is_ptr(t) || is_array(t); t = t->ref)
+        if (t->size_is)
+        {
+            if (!x)
+                x = t->size_is;
+            else
+                error("%s: multidimensional conformant"
+                      " arrays not supported at the top level\n",
+                      name);
+        }
+
+    return x;
+}
+
 void write_remoting_arguments(FILE *file, int indent, const func_t *func,
                               enum pass pass, enum remoting_phase phase)
 {
@@ -2719,13 +2737,13 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
         {
             unsigned char tc = type->type;
             const char *array_type = "FixedArray";
-            type_t *st;
 
-            for (st = type->ref; is_ptr(st) || is_array(st); st = st->ref)
-                if (st->size_is)
-                    error("in function %s: multidimensional conformant arrays"
-                          " not supported at the top level\n",
-                          func->def->name);
+            /* We already have the size_is expression since it's at the
+               top level, but do checks for multidimensional conformant
+               arrays.  When we handle them, we'll need to extend this
+               function to return a list, and then we'll actually use
+               the return value.  */
+            get_size_is_expr(type, var->name);
 
             if (tc == RPC_FC_SMVARRAY || tc == RPC_FC_LGVARRAY)
             {
@@ -2841,19 +2859,7 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
             else
             {
                 const var_t *iid;
-                expr_t *sx = NULL;
-                type_t *st;
-
-                for (st = type->ref; is_ptr(st) || is_array(st); st = st->ref)
-                    if (st->size_is)
-                    {
-                        if (!sx)
-                            sx = st->size_is;
-                        else
-                            error("in function %s: multidimensional conformant"
-                                  " arrays not supported at the top level\n",
-                                  func->def->name);
-                    }
+                expr_t *sx = get_size_is_expr(type, var->name);
 
                 if ((iid = get_attrp( var->attrs, ATTR_IIDIS )))
                     print_file( file, indent, "_StubMsg.MaxCount = (unsigned long)%s;\n", iid->name );
diff --git a/tools/widl/typegen.h b/tools/widl/typegen.h
index 8649d9d..c9a5148 100644
--- a/tools/widl/typegen.h
+++ b/tools/widl/typegen.h
@@ -59,3 +59,4 @@ void write_parameters_init(FILE *file, int indent, const func_t *func);
 void print(FILE *file, int indent, const char *format, va_list ap);
 int get_padding(const var_list_t *fields);
 int is_user_type(const type_t *t);
+expr_t *get_size_is_expr(const type_t *t, const char *name);



More information about the wine-patches mailing list