Fixes the following error with this sample idl:
#ifdef __WIDL__ #pragma winrt ns_prefix #endif
import "wtypes.idl";
namespace Windows { [object] interface IFoo {}
[object] interface IBar { HRESULT DoBar([in] IFoo *foo); } }
$ widl -o windows.foo.h windows.foo.idl windows.foo.idl:13: error: type 'IFoo' not found
Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
v3: I included sample idl with each patch to better show the use case they cover. The whole series then will allow us to declare WinRT interfaces in the correct idl files, in order to stub several DLLs that are required for Death Stranding and Flight Simulator to start.
The DLL stubbing would look like the following patches I intend to send next if this widl series is accepted:
* https://gitlab.com/rbernon/wine/-/commit/478b77d3f8.patch
* https://gitlab.com/rbernon/wine/-/commit/a2d705e0f5.patch
* https://gitlab.com/rbernon/wine/-/commit/cca2304aa1.patch
* https://gitlab.com/rbernon/wine/-/commit/03f0f3a9d1.patch
* https://gitlab.com/rbernon/wine/-/commit/745b9f01e4.patch
tools/widl/parser.y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 3ef8d89ba1c..91c5b809bb3 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -1959,7 +1959,7 @@ type_t *find_type(const char *name, struct namespace *namespace, int t)
static type_t *find_type_or_error(const char *name, int t) { - type_t *type = find_type(name, NULL, t); + type_t *type = find_type(name, current_namespace, t); if (!type) { error_loc("type '%s' not found\n", name); return NULL;
This fixes WinRT interface generation where only simple names were used instead of the C interface names.
With the previous sample idl:
#ifdef __WIDL__ #pragma winrt ns_prefix #endif
import "wtypes.idl";
namespace Windows { [object] interface IFoo {}
[object] interface IBar { HRESULT DoBar([in] IFoo *foo); } }
$ widl -o windows.foo.h windows.foo.idl
Generated file diff before/after:
diff --git a/windows.foo.h b/windows.foo.h index 3790dc7..65151cb 100644 --- a/windows.foo.h +++ b/windows.foo.h @@ -123,7 +123,7 @@ typedef struct __x_ABI_CWindows_CIBarVtbl { /*** IBar methods ***/ HRESULT (STDMETHODCALLTYPE *DoBar)( __x_ABI_CWindows_CIBar *This, - IFoo *foo); + __x_ABI_CWindows_CIFoo *foo);
END_INTERFACE } __x_ABI_CWindows_CIBarVtbl; @@ -138,7 +138,7 @@ interface __x_ABI_CWindows_CIBar { #define __x_ABI_CWindows_CIBar_DoBar(This,foo) (This)->lpVtbl->DoBar(This,foo) #else /*** IBar methods ***/ -static FORCEINLINE HRESULT __x_ABI_CWindows_CIBar_DoBar(__x_ABI_CWindows_CIBar* This,IFoo *foo) { +static FORCEINLINE HRESULT __x_ABI_CWindows_CIBar_DoBar(__x_ABI_CWindows_CIBar* This,__x_ABI_CWindows_CIFoo *foo) { return This->lpVtbl->DoBar(This,foo); } #endif
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- tools/widl/client.c | 3 +-- tools/widl/header.c | 42 ++++++++++++++++++++---------------------- tools/widl/header.h | 2 +- tools/widl/proxy.c | 4 ++-- 4 files changed, 24 insertions(+), 27 deletions(-)
diff --git a/tools/widl/client.c b/tools/widl/client.c index 6ef1cee2f73..185ab8dffc2 100644 --- a/tools/widl/client.c +++ b/tools/widl/client.c @@ -61,8 +61,7 @@ static void write_client_func_decl( const type_t *iface, const var_t *func ) fprintf(client, " %s ", callconv); fprintf(client, "%s%s(\n", prefix_client, get_name(func)); indent++; - if (args) - write_args(client, args, iface->name, 0, TRUE); + if (args) write_args(client, args, iface->name, 0, TRUE, NAME_DEFAULT); else print_client("void"); fprintf(client, ")\n"); diff --git a/tools/widl/header.c b/tools/widl/header.c index a319f2425e3..c8a12556cc9 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -43,7 +43,7 @@ user_type_list_t user_type_list = LIST_INIT(user_type_list); context_handle_list_t context_handle_list = LIST_INIT(context_handle_list); generic_handle_list_t generic_handle_list = LIST_INIT(generic_handle_list);
-static void write_type_v(FILE *f, const decl_spec_t *t, int is_field, int declonly, const char *name); +static void write_type_v(FILE *f, const decl_spec_t *t, int is_field, int declonly, const char *name, enum name_type name_type);
static void indent(FILE *h, int delta) { @@ -250,7 +250,7 @@ static void write_fields(FILE *h, var_list_t *fields) default: ; } - write_type_v(h, &v->declspec, TRUE, v->declonly, name); + write_type_v(h, &v->declspec, TRUE, v->declonly, name, NAME_DEFAULT); fprintf(h, ";\n"); } } @@ -452,7 +452,7 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i case TYPE_INTERFACE: case TYPE_MODULE: case TYPE_COCLASS: - fprintf(h, "%s", t->name); + fprintf(h, "%s", name); break; case TYPE_VOID: fprintf(h, "void"); @@ -500,8 +500,7 @@ void write_type_right(FILE *h, type_t *t, int is_field) { const var_list_t *args = type_function_get_args(t); fputc('(', h); - if (args) - write_args(h, args, NULL, 0, FALSE); + if (args) write_args(h, args, NULL, 0, FALSE, NAME_DEFAULT); else fprintf(h, "void"); fputc(')', h); @@ -533,14 +532,13 @@ void write_type_right(FILE *h, type_t *t, int is_field) } }
-static void write_type_v(FILE *h, const decl_spec_t *ds, int is_field, int declonly, const char *name) +static void write_type_v(FILE *h, const decl_spec_t *ds, int is_field, int declonly, const char *name, enum name_type name_type) { type_t *t = ds->type;
if (!h) return;
- if (t) - write_type_left(h, ds, NAME_DEFAULT, declonly, TRUE); + if (t) write_type_left(h, ds, name_type, declonly, TRUE);
if (name) fprintf(h, "%s%s", !t || needs_space_after(t) ? " " : "", name );
@@ -575,7 +573,7 @@ static void write_type_definition(FILE *f, type_t *t, int declonly)
void write_type_decl(FILE *f, const decl_spec_t *t, const char *name) { - write_type_v(f, t, FALSE, TRUE, name); + write_type_v(f, t, FALSE, TRUE, name, NAME_DEFAULT); }
void write_type_decl_left(FILE *f, const decl_spec_t *ds) @@ -804,7 +802,7 @@ static void write_generic_handle_routines(FILE *header) static void write_typedef(FILE *header, type_t *type, int declonly) { fprintf(header, "typedef "); - write_type_v(header, type_alias_get_aliasee(type), FALSE, declonly, type->name); + write_type_v(header, type_alias_get_aliasee(type), FALSE, declonly, type->name, NAME_DEFAULT); fprintf(header, ";\n"); }
@@ -848,7 +846,7 @@ static void write_declaration(FILE *header, const var_t *v) fprintf(header, "extern "); break; } - write_type_v(header, &v->declspec, FALSE, v->declonly, v->name); + write_type_v(header, &v->declspec, FALSE, v->declonly, v->name, NAME_DEFAULT); fprintf(header, ";\n\n"); } } @@ -1065,7 +1063,7 @@ static void write_method_macro(FILE *header, const type_t *iface, const type_t * } }
-void write_args(FILE *h, const var_list_t *args, const char *name, int method, int do_indent) +void write_args(FILE *h, const var_list_t *args, const char *name, int method, int do_indent, enum name_type name_type) { const var_t *arg; int count = 0; @@ -1091,7 +1089,7 @@ void write_args(FILE *h, const var_list_t *args, const char *name, int method, i /* In theory we should be writing the definition using write_type_v(..., arg->declonly), * but that causes redefinition in e.g. proxy files. In fact MIDL disallows * defining UDTs inside of an argument list. */ - write_type_decl(h, &arg->declspec, arg->name); + write_type_v(h, &arg->declspec, FALSE, TRUE, arg->name, name_type); if (method == 2) { const expr_t *expr = get_attrp(arg->attrs, ATTR_DEFAULTVALUE); if (expr) { @@ -1153,14 +1151,14 @@ static void write_cpp_method_def(FILE *header, const type_t *iface) --indentation; if (args) { fprintf(header, ",\n"); - write_args(header, args, iface->name, 2, TRUE); + write_args(header, args, iface->name, 2, TRUE, NAME_DEFAULT); } fprintf(header, ") = 0;\n");
indent(header, 0); write_type_decl_left(header, ret); fprintf(header, " %s %s(\n", callconv, get_name(func)); - write_args(header, args, iface->name, 2, TRUE); + write_args(header, args, iface->name, 2, TRUE, NAME_DEFAULT); fprintf(header, ")\n"); indent(header, 0); fprintf(header, "{\n"); @@ -1185,7 +1183,7 @@ static void write_cpp_method_def(FILE *header, const type_t *iface) fprintf(header, "virtual "); write_type_decl_left(header, ret); fprintf(header, " %s %s(\n", callconv, get_name(func)); - write_args(header, args, iface->name, 2, TRUE); + write_args(header, args, iface->name, 2, TRUE, NAME_DEFAULT); fprintf(header, ") = 0;\n");
if (is_aggregate_return(func)) @@ -1222,7 +1220,7 @@ static void write_inline_wrappers(FILE *header, const type_t *iface, const type_ fprintf(header, "static FORCEINLINE "); write_type_decl_left(header, type_function_get_ret(func->declspec.type)); fprintf(header, " %s_%s(", name, get_name(func)); - write_args(header, type_function_get_args(func->declspec.type), name, 1, FALSE); + write_args(header, type_function_get_args(func->declspec.type), name, 1, FALSE, NAME_C); fprintf(header, ") {\n"); ++indentation; if (!is_aggregate_return(func)) { @@ -1286,7 +1284,7 @@ static void do_write_c_method_def(FILE *header, const type_t *iface, const char --indentation; if (type_function_get_args(func->declspec.type)) { fprintf(header, ",\n"); - write_args(header, type_function_get_args(func->declspec.type), name, 0, TRUE); + write_args(header, type_function_get_args(func->declspec.type), name, 0, TRUE, NAME_C); } fprintf(header, ");\n"); fprintf(header, "\n"); @@ -1318,7 +1316,7 @@ static void write_method_proto(FILE *header, const type_t *iface) /* proxy prototype */ write_type_decl_left(header, type_function_get_ret(func->declspec.type)); fprintf(header, " %s %s_%s_Proxy(\n", callconv, iface->name, get_name(func)); - write_args(header, type_function_get_args(func->declspec.type), iface->name, 1, TRUE); + write_args(header, type_function_get_args(func->declspec.type), iface->name, 1, TRUE, NAME_DEFAULT); fprintf(header, ");\n"); /* stub prototype */ fprintf(header, "void __RPC_STUB %s_%s_Stub(\n", iface->name, get_name(func)); @@ -1353,7 +1351,7 @@ static void write_locals(FILE *fp, const type_t *iface, int body) /* proxy prototype - use local prototype */ write_type_decl_left(fp, type_function_get_ret(m->declspec.type)); fprintf(fp, " CALLBACK %s_%s_Proxy(\n", iface->name, get_name(m)); - write_args(fp, type_function_get_args(m->declspec.type), iface->name, 1, TRUE); + write_args(fp, type_function_get_args(m->declspec.type), iface->name, 1, TRUE, NAME_DEFAULT); fprintf(fp, ")"); if (body) { const decl_spec_t *rt = type_function_get_ret(m->declspec.type); @@ -1375,7 +1373,7 @@ static void write_locals(FILE *fp, const type_t *iface, int body) /* stub prototype - use remotable prototype */ write_type_decl_left(fp, type_function_get_ret(func->declspec.type)); fprintf(fp, " __RPC_STUB %s_%s_Stub(\n", iface->name, get_name(m)); - write_args(fp, type_function_get_args(func->declspec.type), iface->name, 1, TRUE); + write_args(fp, type_function_get_args(func->declspec.type), iface->name, 1, TRUE, NAME_DEFAULT); fprintf(fp, ")"); if (body) /* Remotable methods must all return HRESULTs. */ @@ -1429,7 +1427,7 @@ static void write_function_proto(FILE *header, const type_t *iface, const var_t fprintf(header, " %s ", callconv); fprintf(header, "%s%s(\n", prefix, get_name(fun)); if (type_function_get_args(fun->declspec.type)) - write_args(header, type_function_get_args(fun->declspec.type), iface->name, 0, TRUE); + write_args(header, type_function_get_args(fun->declspec.type), iface->name, 0, TRUE, NAME_DEFAULT); else fprintf(header, " void"); fprintf(header, ");\n\n"); diff --git a/tools/widl/header.h b/tools/widl/header.h index cebfd83fe4c..d14e310addf 100644 --- a/tools/widl/header.h +++ b/tools/widl/header.h @@ -47,7 +47,7 @@ extern int need_proxy_file(const statement_list_t *stmts); extern int need_proxy_delegation(const statement_list_t *stmts); extern int need_inline_stubs_file(const statement_list_t *stmts); extern const var_t *is_callas(const attr_list_t *list); -extern void write_args(FILE *h, const var_list_t *arg, const char *name, int obj, int do_indent); +extern void write_args(FILE *h, const var_list_t *arg, const char *name, int obj, int do_indent, enum name_type name_type); extern const type_t* get_explicit_generic_handle_type(const var_t* var); extern const var_t *get_func_handle_var( const type_t *iface, const var_t *func, unsigned char *explicit_fc, unsigned char *implicit_fc ); diff --git a/tools/widl/proxy.c b/tools/widl/proxy.c index d7788e1d57e..457f29a2650 100644 --- a/tools/widl/proxy.c +++ b/tools/widl/proxy.c @@ -204,7 +204,7 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx, if (get_stub_mode() == MODE_Oif && !is_callas( func->attrs )) return; write_type_decl_left(proxy, &retval->declspec); print_proxy( " %s %s_%s_Proxy(\n", callconv, iface->name, get_name(func)); - write_args(proxy, args, iface->name, 1, TRUE); + write_args(proxy, args, iface->name, 1, TRUE, NAME_DEFAULT); print_proxy( ")\n"); write_client_call_routine( proxy, iface, func, "Object", proc_offset ); return; @@ -221,7 +221,7 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
write_type_decl_left(proxy, &retval->declspec); print_proxy( " %s %s_%s_Proxy(\n", callconv, iface->name, get_name(func)); - write_args(proxy, args, iface->name, 1, TRUE); + write_args(proxy, args, iface->name, 1, TRUE, NAME_DEFAULT); print_proxy( ")\n"); print_proxy( "{\n"); indent ++;
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=78036
Your paranoid android.
=== debiant (build log) ===
Task: Patch failed to apply
=== debiant (build log) ===
Task: Patch failed to apply
This fixes WinRT interface generation where only simple names were used instead of the C interface names.
With the previous sample idl:
#ifdef __WIDL__ #pragma winrt ns_prefix #endif
import "wtypes.idl";
namespace Windows { [object] interface IFoo {}
[object] interface IBar { HRESULT DoBar([in] IFoo *foo); } }
$ widl -o windows.foo.h windows.foo.idl
Generated file diff before/after:
diff --git a/windows.foo.h b/windows.foo.h index 3790dc7..65151cb 100644 --- a/windows.foo.h +++ b/windows.foo.h @@ -123,7 +123,7 @@ typedef struct __x_ABI_CWindows_CIBarVtbl { /*** IBar methods ***/ HRESULT (STDMETHODCALLTYPE *DoBar)( __x_ABI_CWindows_CIBar *This, - IFoo *foo); + __x_ABI_CWindows_CIFoo *foo);
END_INTERFACE } __x_ABI_CWindows_CIBarVtbl; @@ -138,7 +138,7 @@ interface __x_ABI_CWindows_CIBar { #define __x_ABI_CWindows_CIBar_DoBar(This,foo) (This)->lpVtbl->DoBar(This,foo) #else /*** IBar methods ***/ -static FORCEINLINE HRESULT __x_ABI_CWindows_CIBar_DoBar(__x_ABI_CWindows_CIBar* This,IFoo *foo) { +static FORCEINLINE HRESULT __x_ABI_CWindows_CIBar_DoBar(__x_ABI_CWindows_CIBar* This,__x_ABI_CWindows_CIFoo *foo) { return This->lpVtbl->DoBar(This,foo); } #endif
Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
v4: Just resending this one with the diff indented so that it doesn't confuse git am, sorry.
tools/widl/client.c | 3 +-- tools/widl/header.c | 42 ++++++++++++++++++++---------------------- tools/widl/header.h | 2 +- tools/widl/proxy.c | 4 ++-- 4 files changed, 24 insertions(+), 27 deletions(-)
diff --git a/tools/widl/client.c b/tools/widl/client.c index 6ef1cee2f73..185ab8dffc2 100644 --- a/tools/widl/client.c +++ b/tools/widl/client.c @@ -61,8 +61,7 @@ static void write_client_func_decl( const type_t *iface, const var_t *func ) fprintf(client, " %s ", callconv); fprintf(client, "%s%s(\n", prefix_client, get_name(func)); indent++; - if (args) - write_args(client, args, iface->name, 0, TRUE); + if (args) write_args(client, args, iface->name, 0, TRUE, NAME_DEFAULT); else print_client("void"); fprintf(client, ")\n"); diff --git a/tools/widl/header.c b/tools/widl/header.c index a319f2425e3..c8a12556cc9 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -43,7 +43,7 @@ user_type_list_t user_type_list = LIST_INIT(user_type_list); context_handle_list_t context_handle_list = LIST_INIT(context_handle_list); generic_handle_list_t generic_handle_list = LIST_INIT(generic_handle_list);
-static void write_type_v(FILE *f, const decl_spec_t *t, int is_field, int declonly, const char *name); +static void write_type_v(FILE *f, const decl_spec_t *t, int is_field, int declonly, const char *name, enum name_type name_type);
static void indent(FILE *h, int delta) { @@ -250,7 +250,7 @@ static void write_fields(FILE *h, var_list_t *fields) default: ; } - write_type_v(h, &v->declspec, TRUE, v->declonly, name); + write_type_v(h, &v->declspec, TRUE, v->declonly, name, NAME_DEFAULT); fprintf(h, ";\n"); } } @@ -452,7 +452,7 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i case TYPE_INTERFACE: case TYPE_MODULE: case TYPE_COCLASS: - fprintf(h, "%s", t->name); + fprintf(h, "%s", name); break; case TYPE_VOID: fprintf(h, "void"); @@ -500,8 +500,7 @@ void write_type_right(FILE *h, type_t *t, int is_field) { const var_list_t *args = type_function_get_args(t); fputc('(', h); - if (args) - write_args(h, args, NULL, 0, FALSE); + if (args) write_args(h, args, NULL, 0, FALSE, NAME_DEFAULT); else fprintf(h, "void"); fputc(')', h); @@ -533,14 +532,13 @@ void write_type_right(FILE *h, type_t *t, int is_field) } }
-static void write_type_v(FILE *h, const decl_spec_t *ds, int is_field, int declonly, const char *name) +static void write_type_v(FILE *h, const decl_spec_t *ds, int is_field, int declonly, const char *name, enum name_type name_type) { type_t *t = ds->type;
if (!h) return;
- if (t) - write_type_left(h, ds, NAME_DEFAULT, declonly, TRUE); + if (t) write_type_left(h, ds, name_type, declonly, TRUE);
if (name) fprintf(h, "%s%s", !t || needs_space_after(t) ? " " : "", name );
@@ -575,7 +573,7 @@ static void write_type_definition(FILE *f, type_t *t, int declonly)
void write_type_decl(FILE *f, const decl_spec_t *t, const char *name) { - write_type_v(f, t, FALSE, TRUE, name); + write_type_v(f, t, FALSE, TRUE, name, NAME_DEFAULT); }
void write_type_decl_left(FILE *f, const decl_spec_t *ds) @@ -804,7 +802,7 @@ static void write_generic_handle_routines(FILE *header) static void write_typedef(FILE *header, type_t *type, int declonly) { fprintf(header, "typedef "); - write_type_v(header, type_alias_get_aliasee(type), FALSE, declonly, type->name); + write_type_v(header, type_alias_get_aliasee(type), FALSE, declonly, type->name, NAME_DEFAULT); fprintf(header, ";\n"); }
@@ -848,7 +846,7 @@ static void write_declaration(FILE *header, const var_t *v) fprintf(header, "extern "); break; } - write_type_v(header, &v->declspec, FALSE, v->declonly, v->name); + write_type_v(header, &v->declspec, FALSE, v->declonly, v->name, NAME_DEFAULT); fprintf(header, ";\n\n"); } } @@ -1065,7 +1063,7 @@ static void write_method_macro(FILE *header, const type_t *iface, const type_t * } }
-void write_args(FILE *h, const var_list_t *args, const char *name, int method, int do_indent) +void write_args(FILE *h, const var_list_t *args, const char *name, int method, int do_indent, enum name_type name_type) { const var_t *arg; int count = 0; @@ -1091,7 +1089,7 @@ void write_args(FILE *h, const var_list_t *args, const char *name, int method, i /* In theory we should be writing the definition using write_type_v(..., arg->declonly), * but that causes redefinition in e.g. proxy files. In fact MIDL disallows * defining UDTs inside of an argument list. */ - write_type_decl(h, &arg->declspec, arg->name); + write_type_v(h, &arg->declspec, FALSE, TRUE, arg->name, name_type); if (method == 2) { const expr_t *expr = get_attrp(arg->attrs, ATTR_DEFAULTVALUE); if (expr) { @@ -1153,14 +1151,14 @@ static void write_cpp_method_def(FILE *header, const type_t *iface) --indentation; if (args) { fprintf(header, ",\n"); - write_args(header, args, iface->name, 2, TRUE); + write_args(header, args, iface->name, 2, TRUE, NAME_DEFAULT); } fprintf(header, ") = 0;\n");
indent(header, 0); write_type_decl_left(header, ret); fprintf(header, " %s %s(\n", callconv, get_name(func)); - write_args(header, args, iface->name, 2, TRUE); + write_args(header, args, iface->name, 2, TRUE, NAME_DEFAULT); fprintf(header, ")\n"); indent(header, 0); fprintf(header, "{\n"); @@ -1185,7 +1183,7 @@ static void write_cpp_method_def(FILE *header, const type_t *iface) fprintf(header, "virtual "); write_type_decl_left(header, ret); fprintf(header, " %s %s(\n", callconv, get_name(func)); - write_args(header, args, iface->name, 2, TRUE); + write_args(header, args, iface->name, 2, TRUE, NAME_DEFAULT); fprintf(header, ") = 0;\n");
if (is_aggregate_return(func)) @@ -1222,7 +1220,7 @@ static void write_inline_wrappers(FILE *header, const type_t *iface, const type_ fprintf(header, "static FORCEINLINE "); write_type_decl_left(header, type_function_get_ret(func->declspec.type)); fprintf(header, " %s_%s(", name, get_name(func)); - write_args(header, type_function_get_args(func->declspec.type), name, 1, FALSE); + write_args(header, type_function_get_args(func->declspec.type), name, 1, FALSE, NAME_C); fprintf(header, ") {\n"); ++indentation; if (!is_aggregate_return(func)) { @@ -1286,7 +1284,7 @@ static void do_write_c_method_def(FILE *header, const type_t *iface, const char --indentation; if (type_function_get_args(func->declspec.type)) { fprintf(header, ",\n"); - write_args(header, type_function_get_args(func->declspec.type), name, 0, TRUE); + write_args(header, type_function_get_args(func->declspec.type), name, 0, TRUE, NAME_C); } fprintf(header, ");\n"); fprintf(header, "\n"); @@ -1318,7 +1316,7 @@ static void write_method_proto(FILE *header, const type_t *iface) /* proxy prototype */ write_type_decl_left(header, type_function_get_ret(func->declspec.type)); fprintf(header, " %s %s_%s_Proxy(\n", callconv, iface->name, get_name(func)); - write_args(header, type_function_get_args(func->declspec.type), iface->name, 1, TRUE); + write_args(header, type_function_get_args(func->declspec.type), iface->name, 1, TRUE, NAME_DEFAULT); fprintf(header, ");\n"); /* stub prototype */ fprintf(header, "void __RPC_STUB %s_%s_Stub(\n", iface->name, get_name(func)); @@ -1353,7 +1351,7 @@ static void write_locals(FILE *fp, const type_t *iface, int body) /* proxy prototype - use local prototype */ write_type_decl_left(fp, type_function_get_ret(m->declspec.type)); fprintf(fp, " CALLBACK %s_%s_Proxy(\n", iface->name, get_name(m)); - write_args(fp, type_function_get_args(m->declspec.type), iface->name, 1, TRUE); + write_args(fp, type_function_get_args(m->declspec.type), iface->name, 1, TRUE, NAME_DEFAULT); fprintf(fp, ")"); if (body) { const decl_spec_t *rt = type_function_get_ret(m->declspec.type); @@ -1375,7 +1373,7 @@ static void write_locals(FILE *fp, const type_t *iface, int body) /* stub prototype - use remotable prototype */ write_type_decl_left(fp, type_function_get_ret(func->declspec.type)); fprintf(fp, " __RPC_STUB %s_%s_Stub(\n", iface->name, get_name(m)); - write_args(fp, type_function_get_args(func->declspec.type), iface->name, 1, TRUE); + write_args(fp, type_function_get_args(func->declspec.type), iface->name, 1, TRUE, NAME_DEFAULT); fprintf(fp, ")"); if (body) /* Remotable methods must all return HRESULTs. */ @@ -1429,7 +1427,7 @@ static void write_function_proto(FILE *header, const type_t *iface, const var_t fprintf(header, " %s ", callconv); fprintf(header, "%s%s(\n", prefix, get_name(fun)); if (type_function_get_args(fun->declspec.type)) - write_args(header, type_function_get_args(fun->declspec.type), iface->name, 0, TRUE); + write_args(header, type_function_get_args(fun->declspec.type), iface->name, 0, TRUE, NAME_DEFAULT); else fprintf(header, " void"); fprintf(header, ");\n\n"); diff --git a/tools/widl/header.h b/tools/widl/header.h index cebfd83fe4c..d14e310addf 100644 --- a/tools/widl/header.h +++ b/tools/widl/header.h @@ -47,7 +47,7 @@ extern int need_proxy_file(const statement_list_t *stmts); extern int need_proxy_delegation(const statement_list_t *stmts); extern int need_inline_stubs_file(const statement_list_t *stmts); extern const var_t *is_callas(const attr_list_t *list); -extern void write_args(FILE *h, const var_list_t *arg, const char *name, int obj, int do_indent); +extern void write_args(FILE *h, const var_list_t *arg, const char *name, int obj, int do_indent, enum name_type name_type); extern const type_t* get_explicit_generic_handle_type(const var_t* var); extern const var_t *get_func_handle_var( const type_t *iface, const var_t *func, unsigned char *explicit_fc, unsigned char *implicit_fc ); diff --git a/tools/widl/proxy.c b/tools/widl/proxy.c index d7788e1d57e..457f29a2650 100644 --- a/tools/widl/proxy.c +++ b/tools/widl/proxy.c @@ -204,7 +204,7 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx, if (get_stub_mode() == MODE_Oif && !is_callas( func->attrs )) return; write_type_decl_left(proxy, &retval->declspec); print_proxy( " %s %s_%s_Proxy(\n", callconv, iface->name, get_name(func)); - write_args(proxy, args, iface->name, 1, TRUE); + write_args(proxy, args, iface->name, 1, TRUE, NAME_DEFAULT); print_proxy( ")\n"); write_client_call_routine( proxy, iface, func, "Object", proc_offset ); return; @@ -221,7 +221,7 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
write_type_decl_left(proxy, &retval->declspec); print_proxy( " %s %s_%s_Proxy(\n", callconv, iface->name, get_name(func)); - write_args(proxy, args, iface->name, 1, TRUE); + write_args(proxy, args, iface->name, 1, TRUE, NAME_DEFAULT); print_proxy( ")\n"); print_proxy( "{\n"); indent ++;
Interfaces are going to reference each other across namespaces, so this implements a type lookup with the full name.
It supports the following idl syntax in WinRT mode:
#ifdef __WIDL__ #pragma winrt ns_prefix #endif
import "wtypes.idl";
namespace Windows { namespace Foo { [object] interface IFoo {} } namespace Bar { [object] interface IBar { HRESULT DoBar([in] Windows.Foo.IFoo *foo); } } }
That was previously failing to parse the Windows.Foo.IFoo part and to lookup the corresponding type.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- tools/widl/parser.h | 1 + tools/widl/parser.l | 2 +- tools/widl/parser.y | 60 ++++++++++++++++++++++++++++++++++++--------- 3 files changed, 51 insertions(+), 12 deletions(-)
diff --git a/tools/widl/parser.h b/tools/widl/parser.h index a67b160d48a..a6dc94ae6b8 100644 --- a/tools/widl/parser.h +++ b/tools/widl/parser.h @@ -38,6 +38,7 @@ void pop_import(void); #define parse_only import_stack_ptr
int is_type(const char *name); +int is_namespace(const char *name);
int do_warning(char *toggle, warning_list_t *wnum); int is_warning_enabled(int warning); diff --git a/tools/widl/parser.l b/tools/widl/parser.l index 3cbf4ff2d2b..925265d00db 100644 --- a/tools/widl/parser.l +++ b/tools/widl/parser.l @@ -451,7 +451,7 @@ static int kw_token(const char *kw) return kwp->token; } parser_lval.str = xstrdup(kw); - return is_type(kw) ? aKNOWNTYPE : aIDENTIFIER; + return is_type(kw) ? aKNOWNTYPE : is_namespace(kw) ? aNAMESPACE : aIDENTIFIER; }
static int attr_token(const char *kw) diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 91c5b809bb3..7d5aaebf339 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -81,6 +81,8 @@ static var_t *reg_const(var_t *var);
static void push_namespace(const char *name); static void pop_namespace(const char *name); +static void init_lookup_namespace(const char *name); +static void push_lookup_namespace(const char *name);
static void check_arg_attrs(const var_t *arg); static void check_statements(const statement_list_t *stmts, int is_inside_library); @@ -122,6 +124,7 @@ static struct namespace global_namespace = { };
static struct namespace *current_namespace = &global_namespace; +static struct namespace *lookup_namespace = &global_namespace;
static typelib_t *current_typelib;
@@ -156,7 +159,7 @@ static typelib_t *current_typelib; }
%token <str> aIDENTIFIER aPRAGMA -%token <str> aKNOWNTYPE +%token <str> aKNOWNTYPE aNAMESPACE %token <num> aNUM aHEXNUM %token <dbl> aDOUBLE %token <str> aSTRING aWSTRING aSQSTRING @@ -271,7 +274,7 @@ static typelib_t *current_typelib; %type <str> namespacedef %type <type> base_type int_std %type <type> enumdef structdef uniondef typedecl -%type <type> type +%type <type> type qualified_seq qualified_type %type <ifref> coclass_int %type <ifref_list> coclass_ints %type <var> arg ne_union_field union_field s_field case enum declaration @@ -817,6 +820,16 @@ int_std: tINT { $$ = type_new_int(TYPE_BASIC_INT, 0); } | tINT3264 { $$ = type_new_int(TYPE_BASIC_INT3264, 0); } ;
+qualified_seq: + aKNOWNTYPE { $$ = find_type_or_error($1, 0); } + | aIDENTIFIER '.' { push_lookup_namespace($1); } qualified_seq { $$ = $4; } + ; + +qualified_type: + aKNOWNTYPE { $$ = find_type_or_error($1, 0); } + | aNAMESPACE '.' { init_lookup_namespace($1); } qualified_seq { $$ = $4; } + ; + coclass: tCOCLASS aIDENTIFIER { $$ = type_new_coclass($2); } | tCOCLASS aKNOWNTYPE { $$ = find_type($2, NULL, 0); if (type_get_type_detect_alias($$) != TYPE_COCLASS) @@ -837,6 +850,7 @@ coclassdef: coclasshdr '{' coclass_ints '}' semicolon_opt ;
namespacedef: tNAMESPACE aIDENTIFIER { $$ = $2; } + | tNAMESPACE aNAMESPACE { $$ = $2; } ;
coclass_ints: { $$ = NULL; } @@ -881,7 +895,7 @@ dispinterfacedef: dispinterfacehdr '{' ;
inherit: { $$ = NULL; } - | ':' aKNOWNTYPE { $$ = find_type_or_error2($2, 0); } + | ':' qualified_type { $$ = $2; } ;
interface: tINTERFACE aIDENTIFIER { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); } @@ -1096,7 +1110,7 @@ structdef: tSTRUCT t_ident '{' fields '}' { $$ = type_new_struct($2, current_nam ;
type: tVOID { $$ = type_new_void(); } - | aKNOWNTYPE { $$ = find_type_or_error($1, 0); } + | qualified_type { $$ = $1; } | base_type { $$ = $1; } | enumdef { $$ = $1; } | tENUM aIDENTIFIER { $$ = type_new_enum($2, current_namespace, FALSE, NULL); } @@ -1848,6 +1862,20 @@ static void pop_namespace(const char *name) current_namespace = current_namespace->parent; }
+static void init_lookup_namespace(const char *name) +{ + if (!(lookup_namespace = find_sub_namespace(&global_namespace, name))) + error_loc("namespace '%s' not found\n", name); +} + +static void push_lookup_namespace(const char *name) +{ + struct namespace *namespace; + if (!(namespace = find_sub_namespace(lookup_namespace, name))) + error_loc("namespace '%s' not found\n", name); + lookup_namespace = namespace; +} + struct rtype { const char *name; type_t *type; @@ -1959,12 +1987,14 @@ type_t *find_type(const char *name, struct namespace *namespace, int t)
static type_t *find_type_or_error(const char *name, int t) { - type_t *type = find_type(name, current_namespace, t); - if (!type) { - error_loc("type '%s' not found\n", name); - return NULL; - } - return type; + type_t *type; + if (!(type = find_type(name, current_namespace, t)) && + !(type = find_type(name, lookup_namespace, t))) + { + error_loc("type '%s' not found\n", name); + return NULL; + } + return type; }
static type_t *find_type_or_error2(char *name, int t) @@ -1976,7 +2006,15 @@ static type_t *find_type_or_error2(char *name, int t)
int is_type(const char *name) { - return find_type(name, current_namespace, 0) != NULL; + return find_type(name, current_namespace, 0) != NULL || + find_type(name, lookup_namespace, 0) != NULL; +} + +int is_namespace(const char *name) +{ + if (!winrt_mode) return 0; + return find_sub_namespace(current_namespace, name) != NULL || + find_sub_namespace(&global_namespace, name) != NULL; }
type_t *get_type(enum type_type type, char *name, struct namespace *namespace, int t)
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=78037
Your paranoid android.
=== debiant (build log) ===
Task: Patch failed to apply
=== debiant (build log) ===
Task: Patch failed to apply
This allows the following syntax:
#ifdef __WIDL__ #pragma winrt ns_prefix #endif
import "wtypes.idl";
namespace Windows { namespace Foo { [object] interface IFoo<T,U> { HRESULT DoFoo([in] T value, [out, retval] U *out_value); } } namespace Bar { [object] interface IBaz {}
[object] interface IBar { HRESULT DoBar([in] Windows.Foo.IFoo<IBaz> *foo); } } }
Generating the following IFoo method:
HRESULT (STDMETHODCALLTYPE *DoFoo)( __x_ABI_CWindows_CFoo_CIFoo *This, void*/*__x_ABI_CWindows_CFoo_CIFoo_CT*/ value, void*/*__x_ABI_CWindows_CFoo_CIFoo_CU*/ *out_value);
And the following (unchanged) IBar method:
HRESULT (STDMETHODCALLTYPE *DoBar)( __x_ABI_CWindows_CBar_CIBar *This, __x_ABI_CWindows_CFoo_CIFoo *foo);
It should be enough to add the UWP dll stubs in idl files, but it's casting generics to void*. MIDL does something different apparently and even generates a new interface for every parameter type.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- tools/widl/expr.c | 1 + tools/widl/header.c | 4 ++++ tools/widl/parser.y | 27 +++++++++++++++++++++++---- tools/widl/typegen.c | 4 ++++ tools/widl/typelib.c | 1 + tools/widl/typetree.h | 1 + tools/widl/widltypes.h | 1 + 7 files changed, 35 insertions(+), 4 deletions(-)
diff --git a/tools/widl/expr.c b/tools/widl/expr.c index d1ee599a39e..950a1e46b6f 100644 --- a/tools/widl/expr.c +++ b/tools/widl/expr.c @@ -460,6 +460,7 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type, case TYPE_COCLASS: case TYPE_INTERFACE: case TYPE_POINTER: + case TYPE_GENERIC: case TYPE_ARRAY: case TYPE_BITFIELD: /* nothing to do */ diff --git a/tools/widl/header.c b/tools/widl/header.c index c8a12556cc9..fcc73169d00 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -454,6 +454,9 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i case TYPE_COCLASS: fprintf(h, "%s", name); break; + case TYPE_GENERIC: + fprintf(h, "void*/*%s*/", name); + break; case TYPE_VOID: fprintf(h, "void"); break; @@ -518,6 +521,7 @@ void write_type_right(FILE *h, type_t *t, int is_field) case TYPE_BITFIELD: fprintf(h, " : %u", type_bitfield_get_bits(t)->cval); break; + case TYPE_GENERIC: case TYPE_VOID: case TYPE_BASIC: case TYPE_ENUM: diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 7d5aaebf339..324836565a9 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -274,7 +274,7 @@ static typelib_t *current_typelib; %type <str> namespacedef %type <type> base_type int_std %type <type> enumdef structdef uniondef typedecl -%type <type> type qualified_seq qualified_type +%type <type> type qualified_seq qualified_type generics_type generics_decl %type <ifref> coclass_int %type <ifref_list> coclass_ints %type <var> arg ne_union_field union_field s_field case enum declaration @@ -830,6 +830,11 @@ qualified_type: | aNAMESPACE '.' { init_lookup_namespace($1); } qualified_seq { $$ = $4; } ;
+generics_list: generics_type | generics_type '*' | generics_list ',' generics_list; +generics_args: | '<' generics_list '>'; + +generics_type: qualified_type generics_args; + coclass: tCOCLASS aIDENTIFIER { $$ = type_new_coclass($2); } | tCOCLASS aKNOWNTYPE { $$ = find_type($2, NULL, 0); if (type_get_type_detect_alias($$) != TYPE_COCLASS) @@ -895,13 +900,16 @@ dispinterfacedef: dispinterfacehdr '{' ;
inherit: { $$ = NULL; } - | ':' qualified_type { $$ = $2; } + | ':' generics_type { $$ = $2; } ;
interface: tINTERFACE aIDENTIFIER { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); } | tINTERFACE aKNOWNTYPE { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); } ;
+generics_decl: aIDENTIFIER { $$ = get_type(TYPE_GENERIC, $1, current_namespace, 0); }; +generics_decls: generics_decl | generics_decls ',' generics_decls; + interfacehdr: attributes interface { $$ = $2; check_def($2); $2->attrs = check_iface_attrs($2->name, $1); @@ -923,11 +931,21 @@ interfacedef: interfacehdr inherit semicolon_opt { $$ = $1; type_interface_define($$, find_type_or_error2($3, 0), $6); } + | interfacehdr + '<' { push_namespace($1->name); } generics_decls '>' inherit + '{' int_statements '}' semicolon_opt + { + $$ = $1; + if($$ == $6) error_loc("Interface can't inherit from itself\n"); + type_interface_define($$, $6, $8); + check_async_uuid($$); + pop_namespace($1->name); + } | dispinterfacedef semicolon_opt { $$ = $1; } ;
interfacedec: - interface ';' { $$ = $1; } + interface generics_args ';' { $$ = $1; } | dispinterface ';' { $$ = $1; } ;
@@ -1110,7 +1128,7 @@ structdef: tSTRUCT t_ident '{' fields '}' { $$ = type_new_struct($2, current_nam ;
type: tVOID { $$ = type_new_void(); } - | qualified_type { $$ = $1; } + | generics_type { $$ = $1; } | base_type { $$ = $1; } | enumdef { $$ = $1; } | tENUM aIDENTIFIER { $$ = type_new_enum($2, current_namespace, FALSE, NULL); } @@ -2422,6 +2440,7 @@ static int is_allowed_conf_type(const type_t *type) case TYPE_ENCAPSULATED_UNION: case TYPE_ARRAY: case TYPE_POINTER: + case TYPE_GENERIC: case TYPE_VOID: case TYPE_MODULE: case TYPE_COCLASS: diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c index 04280cbb722..f872e039010 100644 --- a/tools/widl/typegen.c +++ b/tools/widl/typegen.c @@ -351,6 +351,8 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att (is_attr(attrs, ATTR_RANGE) || is_aliaschain_attr(type, ATTR_RANGE))) return TGT_RANGE; return TGT_ENUM; + case TYPE_GENERIC: + return TGT_IFACE_POINTER; case TYPE_POINTER: if (type_get_type(type_pointer_get_ref_type(type)) == TYPE_INTERFACE || (type_get_type(type_pointer_get_ref_type(type)) == TYPE_VOID && is_attr(attrs, ATTR_IIDIS))) @@ -1936,6 +1938,7 @@ unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *align) size = union_memsize(type_union_get_cases(t), align); break; case TYPE_POINTER: + case TYPE_GENERIC: case TYPE_INTERFACE: assert( pointer_size ); size = pointer_size; @@ -2060,6 +2063,7 @@ static unsigned int type_buffer_alignment(const type_t *t) /* else fall through */ case TYPE_POINTER: return 4; + case TYPE_GENERIC: case TYPE_INTERFACE: case TYPE_ALIAS: case TYPE_VOID: diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c index cf027558d0a..060ef45218a 100644 --- a/tools/widl/typelib.c +++ b/tools/widl/typelib.c @@ -193,6 +193,7 @@ unsigned short get_type_vt(type_t *t) break;
case TYPE_POINTER: + case TYPE_GENERIC: return VT_PTR;
case TYPE_ARRAY: diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h index e288c574002..6afa5d25fe5 100644 --- a/tools/widl/typetree.h +++ b/tools/widl/typetree.h @@ -220,6 +220,7 @@ static inline int type_is_complete(const type_t *type) case TYPE_MODULE: case TYPE_COCLASS: case TYPE_POINTER: + case TYPE_GENERIC: case TYPE_ARRAY: case TYPE_BITFIELD: return TRUE; diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index 085a0ff55f5..e957ef19c1a 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -431,6 +431,7 @@ enum type_type TYPE_POINTER, TYPE_ARRAY, TYPE_BITFIELD, + TYPE_GENERIC, };
struct _type_t {
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=78038
Your paranoid android.
=== debiant (build log) ===
Task: Patch failed to apply
=== debiant (build log) ===
Task: Patch failed to apply
With the previous sample idl:
#ifdef __WIDL__ #pragma winrt ns_prefix #endif
import "wtypes.idl";
namespace Windows { namespace Foo { [object] interface IFoo<T,U> { HRESULT DoFoo([in] T value, [out, retval] U *out_value); } } namespace Bar { [object] interface IBaz {}
[object] interface IBar { HRESULT DoBar([in] Windows.Foo.IFoo<IBaz> *foo); } } }
This generates, in WinRT mode, these additional macros to help keeping implementation simple (and similarly for other interfaces):
#ifdef WIDL_USING_CWINDOWS_CFOO_CIFOO #define IFooVtbl __x_ABI_CWindows_CFoo_CIFooVtbl #define IFoo __x_ABI_CWindows_CFoo_CIFoo #define IFoo_DoFoo __x_ABI_CWindows_CFoo_CIFoo_DoFoo #endif /* WIDL_USING_CWINDOWS_CFOO_CIFOO */
Implementation files can define the desired WIDL_USING preprocessor macros before including the header, and then implement or use the interface methods with the simple non-prefixed names instead:
#define COBJMACROS #define WIDL_USING_CWINDOWS_CFOO_CIFOO #define WIDL_USING_CWINDOWS_CBAR_CIBAZ #define WIDL_USING_CWINDOWS_CBAR_CIBAR #include "windows.foo.h"
struct bar { IBar IBar_iface; IBaz *baz; };
static struct bar *impl_from_IBar(IBar *iface) { return CONTAINING_RECORD(iface, struct bar, IBar_iface); }
static HRESULT WINAPI bar_DoBar(IBar *iface, IFoo *foo) { struct bar *This = impl_from_IBar(iface); return IFoo_DoFoo(foo, This->baz, (void **)&This->baz); }
static const IBarVtbl bar_vtbl = { bar_DoBar, };
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- tools/widl/header.c | 53 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+)
diff --git a/tools/widl/header.c b/tools/widl/header.c index fcc73169d00..6b86f0a95fe 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -1460,12 +1460,65 @@ static void write_com_interface_start(FILE *header, const type_t *iface) fprintf(header,"#define __%s_%sINTERFACE_DEFINED__\n\n", iface->c_name, dispinterface ? "DISP" : ""); }
+static char *get_winrt_guard_macro(type_t *iface) +{ + const char *tmp = (char *)iface->c_name; + char *macro; + int i; + + if (!strncmp(tmp, "__x", 3)) tmp += 3; + if (!strncmp(tmp, "_ABI_", 5)) tmp += 5; + macro = xstrdup(tmp); + for (i = strlen(macro); i > 0; --i) macro[i - 1] = toupper(macro[i - 1]); + + return macro; +} + +static void write_widl_using_method_macros(FILE *header, const type_t *iface, const type_t *child) +{ + const statement_t *stmt; + + if (type_iface_get_inherit(iface)) write_widl_using_method_macros(header, type_iface_get_inherit(iface), child); + + STATEMENTS_FOR_EACH_FUNC(stmt, type_iface_get_stmts(iface)) + { + const var_t *func = stmt->u.var; + + if (is_override_method(iface, child, func)) continue; + + if (!is_callas(func->attrs)) + fprintf(header, "#define %s_%s %s_%s\n", child->name, get_name(func), child->c_name, get_name(func)); + } +} + +static void write_widl_using_macros(FILE *header, type_t *iface) +{ + const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); + char *macro; + + if (!strcmp(iface->name, iface->c_name)) return; + + macro = get_winrt_guard_macro(iface); + fprintf(header, "#ifdef WIDL_USING_%s\n", macro); + + if (uuid) fprintf(header, "#define IID_%s IID_%s\n", iface->name, iface->c_name); + fprintf(header, "#define %sVtbl %sVtbl\n", iface->name, iface->c_name); + fprintf(header, "#define %s %s\n", iface->name, iface->c_name); + + write_widl_using_method_macros(header, iface, iface); + + fprintf(header, "#endif /* WIDL_USING_%s */\n\n", macro); + free(macro); +} + static void write_com_interface_end(FILE *header, type_t *iface) { int dispinterface = is_attr(iface->attrs, ATTR_DISPINTERFACE); const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); type_t *type;
+ if (winrt_mode) write_widl_using_macros(header, iface); + if (uuid) write_guid(header, dispinterface ? "DIID" : "IID", iface->c_name, uuid);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=78039
Your paranoid android.
=== debiant (build log) ===
Task: Patch failed to apply
=== debiant (build log) ===
Task: Patch failed to apply