[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