widl: Fix the writing out of function pointers with more than one level of indirection.
This commit is contained in:
parent
5a378905be
commit
bfde2c2e79
|
@ -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,
|
void write_type_v(FILE *h, type_t *t, int is_field, int declonly,
|
||||||
const char *fmt, va_list args)
|
const char *fmt, va_list args)
|
||||||
{
|
{
|
||||||
|
type_t *pt;
|
||||||
|
int ptr_level = 0;
|
||||||
|
|
||||||
if (!h) return;
|
if (!h) return;
|
||||||
|
|
||||||
if (t->type == RPC_FC_FUNCTION) {
|
for (pt = t; is_ptr(pt); pt = pt->ref, ptr_level++)
|
||||||
const char *callconv = get_attrp(t->attrs, ATTR_CALLCONV);
|
;
|
||||||
|
|
||||||
|
if (pt->type == RPC_FC_FUNCTION) {
|
||||||
|
int i;
|
||||||
|
const char *callconv = get_attrp(pt->attrs, ATTR_CALLCONV);
|
||||||
if (!callconv) callconv = "";
|
if (!callconv) callconv = "";
|
||||||
write_type_left(h, t->ref, declonly);
|
write_type_left(h, pt->ref, declonly);
|
||||||
fprintf(h, " (%s *", callconv);
|
fputc(' ', h);
|
||||||
|
if (ptr_level) fputc('(', h);
|
||||||
|
fprintf(h, "%s ", callconv);
|
||||||
|
for (i = 0; i < ptr_level; i++)
|
||||||
|
fputc('*', h);
|
||||||
} else
|
} else
|
||||||
write_type_left(h, t, declonly);
|
write_type_left(h, t, declonly);
|
||||||
if (fmt) {
|
if (fmt) {
|
||||||
if (needs_space_after(t))
|
if (needs_space_after(t))
|
||||||
fprintf(h, " ");
|
fputc(' ', h);
|
||||||
vfprintf(h, fmt, args);
|
vfprintf(h, fmt, args);
|
||||||
}
|
}
|
||||||
if (t->type == RPC_FC_FUNCTION) {
|
if (pt->type == RPC_FC_FUNCTION) {
|
||||||
fprintf(h, ")(");
|
if (ptr_level) fputc(')', h);
|
||||||
write_args(h, t->fields_or_args, NULL, 0, FALSE);
|
fputc('(', h);
|
||||||
fprintf(h, ")");
|
write_args(h, pt->fields_or_args, NULL, 0, FALSE);
|
||||||
|
fputc(')', h);
|
||||||
} else
|
} else
|
||||||
write_type_right(h, t, is_field);
|
write_type_right(h, t, is_field);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
if (pident && pident->is_func) {
|
||||||
int func_ptr_level = pident->func_ptr_level;
|
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 = make_type(RPC_FC_FUNCTION, v->type);
|
||||||
v->type->fields_or_args = pident->args;
|
v->type->fields_or_args = pident->args;
|
||||||
if (pident->callconv)
|
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) {
|
if (pident->is_func) {
|
||||||
int func_ptr_level = pident->func_ptr_level;
|
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 = make_type(RPC_FC_FUNCTION, cur);
|
||||||
cur->fields_or_args = pident->args;
|
cur->fields_or_args = pident->args;
|
||||||
for (; func_ptr_level > 0; func_ptr_level--)
|
|
||||||
cur = make_type(pointer_default, cur);
|
|
||||||
if (pident->callconv)
|
if (pident->callconv)
|
||||||
cur->attrs = append_attr(NULL, make_attrp(ATTR_CALLCONV, pident->callconv));
|
cur->attrs = append_attr(NULL, make_attrp(ATTR_CALLCONV, pident->callconv));
|
||||||
else if (is_object_interface) {
|
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");
|
if (!stdmethodcalltype) stdmethodcalltype = strdup("STDMETHODCALLTYPE");
|
||||||
cur->attrs = append_attr(NULL, make_attrp(ATTR_CALLCONV, 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 = alias(cur, name->name);
|
||||||
cur->attrs = attrs;
|
cur->attrs = attrs;
|
||||||
|
|
Loading…
Reference in New Issue