Module: wine Branch: master Commit: c27af4774e769824f0ebe6f1e5733fc2c99659d7 URL: http://source.winehq.org/git/wine.git/?a=commit;h=c27af4774e769824f0ebe6f1e5...
Author: Nikolay Sivov nsivov@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");