Rob Shearman : widl: Fix the writing out of function pointers with more than one level of indirection .

Alexandre Julliard julliard at winehq.org
Wed Apr 2 16:36:18 CDT 2008


Module: wine
Branch: master
Commit: bfde2c2e7980c6ca6cd39a48c0e20f140ed3275c
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=bfde2c2e7980c6ca6cd39a48c0e20f140ed3275c

Author: Rob Shearman <rob at codeweavers.com>
Date:   Wed Apr  2 12:56:38 2008 +0100

widl: Fix the writing out of function pointers with more than one level of indirection.

---

 tools/widl/header.c |   30 +++++++++++++++++++++---------
 tools/widl/parser.y |    8 ++------
 2 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/tools/widl/header.c b/tools/widl/header.c
index 9fe5082..a568bb4 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -296,24 +296,36 @@ void write_type_right(FILE *h, type_t *t, int is_field)
 void write_type_v(FILE *h, type_t *t, int is_field, int declonly,
                   const char *fmt, va_list args)
 {
+  type_t *pt;
+  int ptr_level = 0;
+
   if (!h) return;
 
-  if (t->type == RPC_FC_FUNCTION) {
-    const char *callconv = get_attrp(t->attrs, ATTR_CALLCONV);
+  for (pt = t; is_ptr(pt); pt = pt->ref, ptr_level++)
+    ;
+
+  if (pt->type == RPC_FC_FUNCTION) {
+    int i;
+    const char *callconv = get_attrp(pt->attrs, ATTR_CALLCONV);
     if (!callconv) callconv = "";
-    write_type_left(h, t->ref, declonly);
-    fprintf(h, " (%s *", callconv);
+    write_type_left(h, pt->ref, declonly);
+    fputc(' ', h);
+    if (ptr_level) fputc('(', h);
+    fprintf(h, "%s ", callconv);
+    for (i = 0; i < ptr_level; i++)
+      fputc('*', h);
   } else
     write_type_left(h, t, declonly);
   if (fmt) {
     if (needs_space_after(t))
-      fprintf(h, " ");
+      fputc(' ', h);
     vfprintf(h, fmt, args);
   }
-  if (t->type == RPC_FC_FUNCTION) {
-    fprintf(h, ")(");
-    write_args(h, t->fields_or_args, NULL, 0, FALSE);
-    fprintf(h, ")");
+  if (pt->type == RPC_FC_FUNCTION) {
+    if (ptr_level) fputc(')', h);
+    fputc('(', h);
+    write_args(h, pt->fields_or_args, NULL, 0, FALSE);
+    fputc(')', h);
   } else
     write_type_right(h, t, is_field);
 }
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 155e026..0f22c65 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -1375,8 +1375,6 @@ static void set_type(var_t *v, type_t *type, const pident_t *pident, array_dims_
 
   if (pident && pident->is_func) {
     int func_ptr_level = pident->func_ptr_level;
-    /* function pointers always have one implicit level of pointer */
-    if (func_ptr_level == 1) func_ptr_level = 0;
     v->type = make_type(RPC_FC_FUNCTION, v->type);
     v->type->fields_or_args = pident->args;
     if (pident->callconv)
@@ -1738,12 +1736,8 @@ static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *a
       }
       if (pident->is_func) {
         int func_ptr_level = pident->func_ptr_level;
-        /* function pointers always have one implicit level of pointer */
-        if (func_ptr_level == 1) func_ptr_level = 0;
         cur = make_type(RPC_FC_FUNCTION, cur);
         cur->fields_or_args = pident->args;
-        for (; func_ptr_level > 0; func_ptr_level--)
-          cur = make_type(pointer_default, cur);
         if (pident->callconv)
           cur->attrs = append_attr(NULL, make_attrp(ATTR_CALLCONV, pident->callconv));
         else if (is_object_interface) {
@@ -1751,6 +1745,8 @@ static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *a
           if (!stdmethodcalltype) stdmethodcalltype = strdup("STDMETHODCALLTYPE");
           cur->attrs = append_attr(NULL, make_attrp(ATTR_CALLCONV, stdmethodcalltype));
         }
+        for (; func_ptr_level > 0; func_ptr_level--)
+          cur = make_type(pointer_default, cur);
       }
       cur = alias(cur, name->name);
       cur->attrs = attrs;




More information about the wine-cvs mailing list