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