https://git.reactos.org/?p=reactos.git;a=commitdiff;h=891d81e058237344de3fe…
commit 891d81e058237344de3fe4e183f6b1933d1f2bbc
Author: Amine Khaldi <amine.khaldi(a)reactos.org>
AuthorDate: Sun Oct 8 10:52:42 2017 +0100
[WIDL] Sync with Wine Staging 2.16. CORE-13762
b42a155 widl: Handle C++ aggregate returns in a MSVC compatible way.
084fa63 widl: Only generate Proxy Stubs when functions have the call_as attribute.
fbdf119 widl: Try to find imported typelib using .tlb extension if it wasn't
specified.
---
media/doc/README.WINE | 2 +-
sdk/tools/widl/header.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++--
sdk/tools/widl/typelib.c | 36 ++++++++++++++++++++++++--------
3 files changed, 80 insertions(+), 11 deletions(-)
diff --git a/media/doc/README.WINE b/media/doc/README.WINE
index 1a7c651da6..8dcdd23aa5 100644
--- a/media/doc/README.WINE
+++ b/media/doc/README.WINE
@@ -16,7 +16,7 @@ wine-patches(a)winehq.com and ros-dev(a)reactos.org
The following build tools are shared with Wine.
reactos/sdk/tools/unicode # Synced to WineStaging-2.9
-reactos/sdk/tools/widl # Synced to WineStaging-2.9
+reactos/sdk/tools/widl # Synced to WineStaging-2.16
reactos/sdk/tools/wpp # Synced to WineStaging-2.9
The following libraries are shared with Wine.
diff --git a/sdk/tools/widl/header.c b/sdk/tools/widl/header.c
index a5dadbaf68..27bca0ed0d 100644
--- a/sdk/tools/widl/header.c
+++ b/sdk/tools/widl/header.c
@@ -1043,13 +1043,62 @@ static void write_cpp_method_def(FILE *header, const type_t
*iface)
const var_t *func = stmt->u.var;
if (!is_callas(func->attrs)) {
const char *callconv = get_attrp(func->type->attrs, ATTR_CALLCONV);
+ const var_list_t *args = type_get_function_args(func->type);
+ const var_t *arg;
+
if (!callconv) callconv = "STDMETHODCALLTYPE";
+
+ if (is_aggregate_return(func)) {
+ fprintf(header, "#ifdef WIDL_EXPLICIT_AGGREGATE_RETURNS\n");
+
+ indent(header, 0);
+ fprintf(header, "virtual ");
+ write_type_decl_left(header, type_function_get_rettype(func->type));
+ fprintf(header, "* %s %s(\n", callconv, get_name(func));
+ ++indentation;
+ indent(header, 0);
+ write_type_decl_left(header, type_function_get_rettype(func->type));
+ fprintf(header, " *__ret");
+ --indentation;
+ if (args) {
+ fprintf(header, ",\n");
+ write_args(header, args, iface->name, 2, TRUE);
+ }
+ fprintf(header, ") = 0;\n");
+
+ indent(header, 0);
+ write_type_decl_left(header, type_function_get_rettype(func->type));
+ fprintf(header, " %s %s(\n", callconv, get_name(func));
+ write_args(header, args, iface->name, 2, TRUE);
+ fprintf(header, ")\n");
+ indent(header, 0);
+ fprintf(header, "{\n");
+ ++indentation;
+ indent(header, 0);
+ write_type_decl_left(header, type_function_get_rettype(func->type));
+ fprintf(header, " __ret;\n");
+ indent(header, 0);
+ fprintf(header, "return *%s(&__ret", get_name(func));
+ if (args)
+ LIST_FOR_EACH_ENTRY(arg, args, const var_t, entry)
+ fprintf(header, ", %s", arg->name);
+ fprintf(header, ");\n");
+ --indentation;
+ indent(header, 0);
+ fprintf(header, "}\n");
+
+ fprintf(header, "#else\n");
+ }
+
indent(header, 0);
fprintf(header, "virtual ");
write_type_decl_left(header, type_function_get_rettype(func->type));
fprintf(header, " %s %s(\n", callconv, get_name(func));
- write_args(header, type_get_function_args(func->type), iface->name, 2,
TRUE);
+ write_args(header, args, iface->name, 2, TRUE);
fprintf(header, ") = 0;\n");
+
+ if (is_aggregate_return(func))
+ fprintf(header, "#endif\n");
fprintf(header, "\n");
}
}
@@ -1181,7 +1230,7 @@ static void write_method_proto(FILE *header, const type_t *iface)
{
const var_t *func = stmt->u.var;
- if (!is_local(func->attrs)) {
+ if (is_callas(func->attrs)) {
const char *callconv = get_attrp(func->type->attrs, ATTR_CALLCONV);
if (!callconv) callconv = "STDMETHODCALLTYPE";
/* proxy prototype */
diff --git a/sdk/tools/widl/typelib.c b/sdk/tools/widl/typelib.c
index f8f92e2062..ba71de71ab 100644
--- a/sdk/tools/widl/typelib.c
+++ b/sdk/tools/widl/typelib.c
@@ -327,22 +327,42 @@ static void read_msft_importlib(importlib_t *importlib, int fd)
free(typeinfo_offs);
}
+static int open_typelib(const char *name)
+{
+ char *file_name;
+ int fd;
+
+ file_name = wpp_find_include(name, NULL);
+ if(!file_name)
+ return open(name, O_RDONLY | O_BINARY );
+
+ fd = open(file_name, O_RDONLY | O_BINARY );
+ free(file_name);
+ return fd;
+}
+
static void read_importlib(importlib_t *importlib)
{
int fd;
INT magic;
- char *file_name;
- file_name = wpp_find_include(importlib->name, NULL);
- if(file_name) {
- fd = open(file_name, O_RDONLY | O_BINARY );
- free(file_name);
- }else {
- fd = open(importlib->name, O_RDONLY | O_BINARY );
+ fd = open_typelib(importlib->name);
+
+ /* widl extension: if importlib name has no .tlb extension, try using .tlb */
+ if(fd < 0) {
+ const char *p = strrchr(importlib->name, '.');
+ size_t len = p ? p - importlib->name : strlen(importlib->name);
+ if(strcmp(importlib->name + len, ".tlb")) {
+ char *tlb_name = xmalloc(len + 5);
+ memcpy(tlb_name, importlib->name, len);
+ strcpy(tlb_name + len, ".tlb");
+ fd = open_typelib(tlb_name);
+ free(tlb_name);
+ }
}
if(fd < 0)
- error("Could not open importlib %s.\n", importlib->name);
+ error("Could not find importlib %s.\n", importlib->name);
tlb_read(fd, &magic, sizeof(magic));