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,
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue