Module: wine Branch: master Commit: bfde2c2e7980c6ca6cd39a48c0e20f140ed3275c URL: http://source.winehq.org/git/wine.git/?a=commit;h=bfde2c2e7980c6ca6cd39a48c0...
Author: Rob Shearman rob@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;