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