[PATCH 3/3] widl: Prefer mangled name over typedef in WinRT mode.

Rémi Bernon rbernon at codeweavers.com
Wed Nov 4 12:49:29 CST 2020


For types under a non-global namespace.

MIDL generates prefixed mangled name for every use of enum, struct and
union types. When the types are in the global namespace, the typedef
name is used instead.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---

Sneaking this one as well, it will be needed to correctly generate code
for additional WinRT types, and I'd like to have it upstreamed before
the patches that will add the actual WinRT types.

>From this sample idl:
    
    namespace Foo {
        typedef struct Bar Bar;
        struct Bar {};
        struct Boo { Bar bar; };
        [object] interface IBoo { void Do([in] Bar bar); }
    }
    
This changes the generated code in the following way:
    
    @@ -37,7 +37,6 @@ namespace ABI {
     extern "C" {
     #endif
    
    -typedef struct Bar Bar;
     #ifdef __cplusplus
     } /* extern "C" */
     namespace ABI {
    @@ -57,14 +56,14 @@ struct __x_ABI_CFoo_CBar {
     namespace ABI {
         namespace Foo {
             struct Boo {
    -            Bar bar;
    +            struct Bar bar;
             };
         }
     }
     extern "C" {
     #else
     struct __x_ABI_CFoo_CBoo {
    -    Bar bar;
    +    struct __x_ABI_CFoo_CBar bar;
     };
     #endif
    
    @@ -84,7 +83,7 @@ namespace ABI {
                 BEGIN_INTERFACE
    
                 virtual void STDMETHODCALLTYPE Do(
    -                Bar bar) = 0;
    +                struct Bar bar) = 0;
    
                 END_INTERFACE
    
    @@ -99,7 +98,7 @@ typedef struct __x_ABI_CFoo_CIBooVtbl {
         /*** IBoo methods ***/
         void (STDMETHODCALLTYPE *Do)(
             __x_ABI_CFoo_CIBoo *This,
    -        Bar bar);
    +        struct __x_ABI_CFoo_CBar bar);
    
         END_INTERFACE
     } __x_ABI_CFoo_CIBooVtbl;
    @@ -114,7 +113,7 @@ interface __x_ABI_CFoo_CIBoo {
     #define __x_ABI_CFoo_CIBoo_Do(This,bar) (This)->lpVtbl->Do(This,bar)
     #else
     /*** IBoo methods ***/
    -static FORCEINLINE void __x_ABI_CFoo_CIBoo_Do(__x_ABI_CFoo_CIBoo* This,Bar bar) {
    +static FORCEINLINE void __x_ABI_CFoo_CIBoo_Do(__x_ABI_CFoo_CIBoo* This,struct __x_ABI_CFoo_CBar bar) {
         This->lpVtbl->Do(This,bar);
     }
     #endif

 tools/widl/header.c   | 22 ++++++++++++++--------
 tools/widl/typetree.c |  2 +-
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/tools/widl/header.c b/tools/widl/header.c
index 743d86f0ee9..015bbe2ece7 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -192,7 +192,7 @@ const char *get_name(const var_t *v)
     return v->name;
 }
 
-static void write_fields(FILE *h, var_list_t *fields)
+static void write_fields(FILE *h, var_list_t *fields, enum name_type name_type)
 {
     unsigned nameless_struct_cnt = 0, nameless_struct_i = 0, nameless_union_cnt = 0, nameless_union_i = 0;
     const char *name;
@@ -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, NAME_DEFAULT);
+        write_type_v(h, &v->declspec, TRUE, v->declonly, name, name_type);
         fprintf(h, ";\n");
     }
 }
@@ -322,7 +322,7 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i
   if ((ds->qualifier & TYPE_QUALIFIER_CONST) && (type_is_alias(t) || !is_ptr(t)))
     fprintf(h, "const ");
 
-  if (type_is_alias(t)) fprintf(h, "%s", t->name);
+  if (!winrt_mode && type_is_alias(t)) fprintf(h, "%s", t->name);
   else {
     switch (type_get_type_detect_alias(t)) {
       case TYPE_ENUM:
@@ -347,9 +347,9 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i
           t->written = TRUE;
           indentation++;
           if (type_get_type(t) != TYPE_STRUCT)
-            write_fields(h, type_encapsulated_union_get_fields(t));
+            write_fields(h, type_encapsulated_union_get_fields(t), name_type);
           else
-            write_fields(h, type_struct_get_fields(t));
+            write_fields(h, type_struct_get_fields(t), name_type);
           indent(h, -1);
           fprintf(h, "}");
         }
@@ -362,7 +362,7 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i
           else fprintf(h, "union {\n");
           t->written = TRUE;
           indentation++;
-          write_fields(h, type_union_get_cases(t));
+          write_fields(h, type_union_get_cases(t), name_type);
           indent(h, -1);
           fprintf(h, "}");
         }
@@ -464,9 +464,13 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i
         break;
       }
       case TYPE_ALIAS:
-        /* handled elsewhere */
-        assert(0);
+      {
+        const decl_spec_t *ds = type_alias_get_aliasee(t);
+        int in_namespace = ds && ds->type && ds->type->namespace && !is_global_namespace(ds->type->namespace);
+        if (!in_namespace) fprintf(h, "%s", t->name);
+        else write_type_left(h, ds, name_type, declonly, write_callconv);
         break;
+      }
     }
   }
 }
@@ -801,6 +805,8 @@ static void write_generic_handle_routines(FILE *header)
 
 static void write_typedef(FILE *header, type_t *type, int declonly)
 {
+  type_t *t = type_alias_get_aliasee_type(type);
+  if (winrt_mode && t->namespace && !is_global_namespace(t->namespace)) return;
   fprintf(header, "typedef ");
   write_type_v(header, type_alias_get_aliasee(type), FALSE, declonly, type->name, NAME_DEFAULT);
   fprintf(header, ";\n");
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
index e9afc6fdd28..c0547b36a96 100644
--- a/tools/widl/typetree.c
+++ b/tools/widl/typetree.c
@@ -82,7 +82,7 @@ const char *type_get_name(const type_t *type, enum name_type name_type)
     case NAME_DEFAULT:
         return type->name;
     case NAME_C:
-        return type->c_name;
+        return type->c_name ? type->c_name : type->name;
     }
 
     assert(0);
-- 
2.29.2




More information about the wine-devel mailing list