Nikolay Sivov : widl: Generate method macros/ wrappers for overridden methods.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Oct 14 09:37:29 CDT 2014
Module: wine
Branch: master
Commit: c27af4774e769824f0ebe6f1e5733fc2c99659d7
URL: http://source.winehq.org/git/wine.git/?a=commit;h=c27af4774e769824f0ebe6f1e5733fc2c99659d7
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Mon Oct 13 14:23:22 2014 +0400
widl: Generate method macros/wrappers for overridden methods.
---
dlls/dwrite/tests/layout.c | 15 +++++++----
tools/widl/header.c | 67 +++++++++++++++++++++++++++++++++++++---------
2 files changed, 65 insertions(+), 17 deletions(-)
diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c
index 2e4618a..bff9d15 100644
--- a/dlls/dwrite/tests/layout.c
+++ b/dlls/dwrite/tests/layout.c
@@ -478,7 +478,7 @@ static void test_GetLocaleName(void)
static const WCHAR strW[] = {'s','t','r','i','n','g',0};
static const WCHAR ruW[] = {'r','u',0};
IDWriteTextLayout *layout;
- IDWriteTextFormat *format;
+ IDWriteTextFormat *format, *format2;
WCHAR buff[10];
UINT32 len;
HRESULT hr;
@@ -489,13 +489,17 @@ static void test_GetLocaleName(void)
hr = IDWriteFactory_CreateGdiCompatibleTextLayout(factory, strW, 0, format, 100.0, 100.0, 1.0, NULL, FALSE, &layout);
ok(hr == S_OK, "got 0x%08x\n", hr);
- len = IDWriteTextLayout_GetLocaleNameLength(layout);
+
+ hr = IDWriteTextLayout_QueryInterface(layout, &IID_IDWriteTextFormat, (void**)&format2);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ len = IDWriteTextFormat_GetLocaleNameLength(format2);
ok(len == 2, "got %u\n", len);
len = IDWriteTextFormat_GetLocaleNameLength(format);
ok(len == 2, "got %u\n", len);
- hr = IDWriteTextLayout_GetLocaleName(layout, buff, len);
+ hr = IDWriteTextFormat_GetLocaleName(format2, buff, len);
ok(hr == E_NOT_SUFFICIENT_BUFFER, "got 0x%08x\n", hr);
- hr = IDWriteTextLayout_GetLocaleName(layout, buff, len+1);
+ hr = IDWriteTextFormat_GetLocaleName(format2, buff, len+1);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(!lstrcmpW(buff, ruW), "got %s\n", wine_dbgstr_w(buff));
hr = IDWriteTextFormat_GetLocaleName(format, buff, len);
@@ -506,6 +510,7 @@ static void test_GetLocaleName(void)
IDWriteTextLayout_Release(layout);
IDWriteTextFormat_Release(format);
+ IDWriteTextFormat_Release(format2);
}
static void test_CreateEllipsisTrimmingSign(void)
@@ -571,7 +576,7 @@ static void test_fontweight(void)
range.length = 0;
weight = DWRITE_FONT_WEIGHT_BOLD;
- hr = layout->lpVtbl->IDWriteTextLayout_GetFontWeight(layout, 0, &weight, &range);
+ hr = IDWriteTextLayout_GetFontWeight(layout, 0, &weight, &range);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(weight == DWRITE_FONT_WEIGHT_NORMAL, "got %d\n", weight);
ok(range.length == 6, "got %d\n", range.length);
diff --git a/tools/widl/header.c b/tools/widl/header.c
index f0f0156..c23faf4 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -828,6 +828,32 @@ static int is_inherited_method(const type_t *iface, const var_t *func)
return 0;
}
+static int is_override_method(const type_t *iface, const type_t *child, const var_t *func)
+{
+ if (iface == child)
+ return 0;
+
+ do
+ {
+ const statement_t *stmt;
+ STATEMENTS_FOR_EACH_FUNC(stmt, type_iface_get_stmts(child))
+ {
+ const var_t *funccmp = stmt->u.var;
+
+ if (!is_callas(func->attrs))
+ {
+ char inherit_name[256];
+ /* compare full name including property prefix */
+ strcpy(inherit_name, get_name(funccmp));
+ if (!strcmp(inherit_name, get_name(func))) return 1;
+ }
+ }
+ }
+ while ((child = type_iface_get_inherit(child)) && child != iface);
+
+ return 0;
+}
+
static int is_aggregate_return(const var_t *func)
{
enum type_type type = type_get_type(type_function_get_rettype(func->type));
@@ -835,13 +861,23 @@ static int is_aggregate_return(const var_t *func)
type == TYPE_COCLASS || type == TYPE_INTERFACE;
}
-static void write_method_macro(FILE *header, const type_t *iface, const char *name)
+static char *get_vtbl_entry_name(const type_t *iface, const var_t *func)
+{
+ static char buff[255];
+ if (is_inherited_method(iface, func))
+ sprintf(buff, "%s_%s", iface->name, get_name(func));
+ else
+ sprintf(buff, "%s", get_name(func));
+ return buff;
+}
+
+static void write_method_macro(FILE *header, const type_t *iface, const type_t *child, const char *name)
{
const statement_t *stmt;
int first_iface = 1;
if (type_iface_get_inherit(iface))
- write_method_macro(header, type_iface_get_inherit(iface), name);
+ write_method_macro(header, type_iface_get_inherit(iface), child, name);
STATEMENTS_FOR_EACH_FUNC(stmt, type_iface_get_stmts(iface))
{
@@ -853,8 +889,10 @@ static void write_method_macro(FILE *header, const type_t *iface, const char *na
first_iface = 0;
}
- if (!is_callas(func->attrs) && !is_inherited_method(iface, func) &&
- !is_aggregate_return(func)) {
+ if (is_override_method(iface, child, func))
+ continue;
+
+ if (!is_callas(func->attrs) && !is_aggregate_return(func)) {
const var_t *arg;
fprintf(header, "#define %s_%s(This", name, get_name(func));
@@ -863,7 +901,7 @@ static void write_method_macro(FILE *header, const type_t *iface, const char *na
fprintf(header, ",%s", arg->name);
fprintf(header, ") ");
- fprintf(header, "(This)->lpVtbl->%s(This", get_name(func));
+ fprintf(header, "(This)->lpVtbl->%s(This", get_vtbl_entry_name(iface, func));
if (type_get_function_args(func->type))
LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), const var_t, entry )
fprintf(header, ",%s", arg->name);
@@ -929,13 +967,13 @@ static void write_cpp_method_def(FILE *header, const type_t *iface)
}
}
-static void write_inline_wrappers(FILE *header, const type_t *iface, const char *name)
+static void write_inline_wrappers(FILE *header, const type_t *iface, const type_t *child, const char *name)
{
const statement_t *stmt;
int first_iface = 1;
if (type_iface_get_inherit(iface))
- write_inline_wrappers(header, type_iface_get_inherit(iface), name);
+ write_inline_wrappers(header, type_iface_get_inherit(iface), child, name);
STATEMENTS_FOR_EACH_FUNC(stmt, type_iface_get_stmts(iface))
{
@@ -947,7 +985,10 @@ static void write_inline_wrappers(FILE *header, const type_t *iface, const char
first_iface = 0;
}
- if (!is_callas(func->attrs) && !is_inherited_method(iface, func)) {
+ if (is_override_method(iface, child, func))
+ continue;
+
+ if (!is_callas(func->attrs)) {
const var_t *arg;
fprintf(header, "static FORCEINLINE ");
@@ -960,13 +1001,13 @@ static void write_inline_wrappers(FILE *header, const type_t *iface, const char
indent(header, 0);
fprintf(header, "%sThis->lpVtbl->%s(This",
is_void(type_function_get_rettype(func->type)) ? "" : "return ",
- get_name(func));
+ get_vtbl_entry_name(iface, func));
} else {
indent(header, 0);
write_type_decl_left(header, type_function_get_rettype(func->type));
fprintf(header, " __ret;\n");
indent(header, 0);
- fprintf(header, "return *This->lpVtbl->%s(This,&__ret", get_name(func));
+ fprintf(header, "return *This->lpVtbl->%s(This,&__ret", get_vtbl_entry_name(iface, func));
}
if (type_get_function_args(func->type))
LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), const var_t, entry )
@@ -1188,6 +1229,7 @@ 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 (uuid)
write_guid(header, dispinterface ? "DIID" : "IID", iface->name, uuid);
@@ -1245,9 +1287,10 @@ static void write_com_interface_end(FILE *header, type_t *iface)
/* dispinterfaces don't have real functions, so don't write macros for them,
* only for the interface this interface inherits from, i.e. IDispatch */
fprintf(header, "#ifndef WIDL_C_INLINE_WRAPPERS\n");
- write_method_macro(header, dispinterface ? type_iface_get_inherit(iface) : iface, iface->name);
+ type = dispinterface ? type_iface_get_inherit(iface) : iface;
+ write_method_macro(header, type, type, iface->name);
fprintf(header, "#else\n");
- write_inline_wrappers(header, dispinterface ? type_iface_get_inherit(iface) : iface, iface->name);
+ write_inline_wrappers(header, type, type, iface->name);
fprintf(header, "#endif\n");
fprintf(header, "#endif\n");
fprintf(header, "\n");
More information about the wine-cvs
mailing list