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

oldstable
Rob Shearman 2008-04-02 12:56:38 +01:00 committed by Alexandre Julliard
parent 5a378905be
commit bfde2c2e79
2 changed files with 23 additions and 15 deletions

View File

@ -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);
}

View File

@ -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;