[PATCH v2] widl: Support function pointers in structs
Zebediah Figura
z.figura12 at gmail.com
Tue Jan 28 15:09:06 CST 2020
On 1/23/20 9:04 PM, Alistair Leslie-Hughes wrote:
> Visual Studio idl's support functions pointers within struct's.
>
> Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
> ---
> tools/widl/parser.y | 5 ++---
> tools/widl/typegen.c | 12 ++++++++++++
> tools/widl/typegen.h | 1 +
> 3 files changed, 15 insertions(+), 3 deletions(-)
>
At least MIDL from the Windows 7 SDK doesn't support them, and I would
be surprised if later versions did, as I don't think remoting a function
pointer is supported by rpcrt4.
I think you instead want to mark the interfaces that use these
structures as "local", denoting that they can't be remoted. That'll also
fix your problems with void pointers and bitfields.
> diff --git a/tools/widl/parser.y b/tools/widl/parser.y
> index 5f6eb50878..090fb00339 100644
> --- a/tools/widl/parser.y
> +++ b/tools/widl/parser.y
> @@ -2521,9 +2521,6 @@ static void check_field_common(const type_t *container_type,
> case TYPE_VOID:
> reason = "cannot derive from void *";
> break;
> - case TYPE_FUNCTION:
> - reason = "cannot be a function pointer";
> - break;
> case TYPE_BITFIELD:
> reason = "cannot be a bit-field";
> break;
> @@ -2575,6 +2572,7 @@ static void check_field_common(const type_t *container_type,
> error_loc_info(&arg->loc_info, "undefined type declaration \"enum %s\"\n", type->name);
> }
> case TGT_USER_TYPE:
> + case TGT_FUNCTION_POINTER:
> case TGT_IFACE_POINTER:
> case TGT_BASIC:
> case TGT_RANGE:
> @@ -2659,6 +2657,7 @@ static void check_remoting_args(const var_t *func)
> case TGT_INVALID:
> /* already error'd before we get here */
> case TGT_CTXT_HANDLE_POINTER:
> + case TGT_FUNCTION_POINTER:
> case TGT_POINTER:
> case TGT_ARRAY:
> /* OK */
> diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
> index 9b8aa1a322..c2f1ca9359 100644
> --- a/tools/widl/typegen.c
> +++ b/tools/widl/typegen.c
> @@ -367,6 +367,7 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att
> case TYPE_ARRAY:
> return TGT_ARRAY;
> case TYPE_FUNCTION:
> + return TGT_FUNCTION_POINTER;
> case TYPE_COCLASS:
> case TYPE_INTERFACE:
> case TYPE_MODULE:
> @@ -598,6 +599,7 @@ unsigned char get_struct_fc(const type_t *type)
> case TGT_INVALID:
> case TGT_CTXT_HANDLE:
> case TGT_CTXT_HANDLE_POINTER:
> + case TGT_FUNCTION_POINTER:
> /* checking after parsing should mean that we don't get here. if we do,
> * it's a checker bug */
> assert(0);
> @@ -690,6 +692,7 @@ static unsigned char get_array_fc(const type_t *type)
> break;
> case TGT_CTXT_HANDLE:
> case TGT_CTXT_HANDLE_POINTER:
> + case TGT_FUNCTION_POINTER:
> case TGT_STRING:
> case TGT_INVALID:
> case TGT_ARRAY:
> @@ -743,6 +746,7 @@ static int type_has_pointers(const type_t *type)
> case TGT_CTXT_HANDLE_POINTER:
> case TGT_STRING:
> case TGT_IFACE_POINTER:
> + case TGT_FUNCTION_POINTER:
> case TGT_BASIC:
> case TGT_ENUM:
> case TGT_RANGE:
> @@ -795,6 +799,7 @@ static int type_has_full_pointer(const type_t *type, const attr_list_t *attrs,
> }
> case TGT_CTXT_HANDLE:
> case TGT_CTXT_HANDLE_POINTER:
> + case TGT_FUNCTION_POINTER:
> case TGT_STRING:
> case TGT_IFACE_POINTER:
> case TGT_BASIC:
> @@ -1037,6 +1042,7 @@ static unsigned char get_parameter_fc( const var_t *var, int is_return, unsigned
> case TGT_CTXT_HANDLE:
> buffer_size = 20;
> break;
> + case TGT_FUNCTION_POINTER:
> case TGT_POINTER:
> if (get_pointer_fc( var->declspec.type, var->attrs, !is_return ) == FC_RP)
> {
> @@ -1083,6 +1089,7 @@ static unsigned char get_parameter_fc( const var_t *var, int is_return, unsigned
> case TGT_POINTER:
> case TGT_CTXT_HANDLE:
> case TGT_CTXT_HANDLE_POINTER:
> + case TGT_FUNCTION_POINTER:
> *flags |= MustFree;
> server_size = pointer_size;
> break;
> @@ -3635,6 +3642,7 @@ static unsigned int write_type_tfs(FILE *file, const attr_list_t *attrs,
> return write_union_tfs(file, attrs, type, typeformat_offset);
> case TGT_ENUM:
> case TGT_BASIC:
> + case TGT_FUNCTION_POINTER:
> /* nothing to do */
> return 0;
> case TGT_RANGE:
> @@ -4176,6 +4184,7 @@ void write_parameter_conf_or_var_exprs(FILE *file, int indent, const char *local
> case TGT_USER_TYPE:
> case TGT_CTXT_HANDLE:
> case TGT_CTXT_HANDLE_POINTER:
> + case TGT_FUNCTION_POINTER:
> case TGT_STRING:
> case TGT_BASIC:
> case TGT_ENUM:
> @@ -4435,6 +4444,7 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
> phase, var, start_offset);
> break;
> }
> + case TGT_FUNCTION_POINTER:
> case TGT_POINTER:
> {
> const type_t *ref = type_pointer_get_ref_type(type);
> @@ -4526,6 +4536,7 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
> case TGT_IFACE_POINTER:
> case TGT_CTXT_HANDLE:
> case TGT_CTXT_HANDLE_POINTER:
> + case TGT_FUNCTION_POINTER:
> print_phase_function(file, indent, "Pointer", local_var_prefix, phase, var, start_offset);
> break;
> case TGT_INVALID:
> @@ -4762,6 +4773,7 @@ void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char
> break;
> case TGT_CTXT_HANDLE:
> case TGT_CTXT_HANDLE_POINTER:
> + case TGT_FUNCTION_POINTER:
> case TGT_INVALID:
> case TGT_STRING:
> /* not initialised */
> diff --git a/tools/widl/typegen.h b/tools/widl/typegen.h
> index 95ad601768..c388e62434 100644
> --- a/tools/widl/typegen.h
> +++ b/tools/widl/typegen.h
> @@ -58,6 +58,7 @@ enum typegen_type
> TGT_STRUCT,
> TGT_UNION,
> TGT_RANGE,
> + TGT_FUNCTION_POINTER,
> };
>
> typedef int (*type_pred_t)(const type_t *);
>
More information about the wine-devel
mailing list