[PATCH 3/5] widl: Fix nested parameterized types C / short name output.

Rémi Bernon rbernon at codeweavers.com
Tue Jan 25 03:13:37 CST 2022


We append type->name from each parameter when constructing the c_name
of parameterized type. When the parameter is itself a parameterized type
this field contains C++-like name, with template brackets.

Instead this precomputes the names of parameterized types whenever they
are used as a parameter. In this case the format is the same as the C
name, except that __C is used as a namespace separator, instead of _C,
and that there's no namespace or abi prefix included.

Shorthands need to be applied too, altough they have to match the __C.

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

This is currently no-op, but it will fix nested parameterized types,
like:

  IMapView<HSTRING, IVectorView<HSTRING>*>

And Bernhard Kölbl needed it in their windows.media.speech series.

 tools/widl/typetree.c  | 28 ++++++++++++++++++++--------
 tools/widl/widltypes.h | 11 ++++++-----
 2 files changed, 26 insertions(+), 13 deletions(-)

diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
index 765ed483d47..f4175b1ae45 100644
--- a/tools/widl/typetree.c
+++ b/tools/widl/typetree.c
@@ -53,6 +53,7 @@ type_t *make_type(enum type_type type)
     t->signature = NULL;
     t->qualified_name = NULL;
     t->impl_name = NULL;
+    t->param_name = NULL;
     t->short_name = NULL;
     memset(&t->details, 0, sizeof(t->details));
     t->typestring_offset = 0;
@@ -291,29 +292,36 @@ char *format_parameterized_type_name(type_t *type, typeref_list_t *params)
 }
 
 static char const *parameterized_type_shorthands[][2] = {
+    {"Windows__CFoundation__CCollections__C", "__F"},
     {"Windows_CFoundation_CCollections_C", "__F"},
+    {"Windows__CFoundation__C", "__F"},
     {"Windows_CFoundation_C", "__F"},
 };
 
-static char *format_parameterized_type_c_name(type_t *type, typeref_list_t *params, const char *prefix)
+static char *format_parameterized_type_c_name(type_t *type, typeref_list_t *params, const char *prefix, const char *separator)
 {
+    const char *tmp, *ns_prefix = "__x_", *abi_prefix = NULL;
     size_t len = 0, pos = 0;
-    char *buf = NULL, *tmp;
+    char *buf = NULL;
     int i, count = params ? list_count(params) : 0;
     typeref_t *ref;
 
-    pos += append_namespaces(&buf, &len, pos, type->namespace, "__x_", "_C", "", use_abi_namespace ? "ABI" : NULL);
+    if (!strcmp(separator, "__C")) ns_prefix = "_C";
+    else if (use_abi_namespace) abi_prefix = "ABI";
+
+    pos += append_namespaces(&buf, &len, pos, type->namespace, ns_prefix, separator, "", abi_prefix);
     pos += strappend(&buf, &len, pos, "%s%s_%d", prefix, type->name, count);
     if (params) LIST_FOR_EACH_ENTRY(ref, params, typeref_t, entry)
     {
         type = type_pointer_get_root_type(ref->type);
-        pos += append_namespaces(&buf, &len, pos, type->namespace, "_", "__C", type->name, NULL);
+        if ((tmp = type->param_name)) pos += strappend(&buf, &len, pos, "_%s", tmp);
+        else pos += append_namespaces(&buf, &len, pos, type->namespace, "_", "__C", type->name, NULL);
     }
 
     for (i = 0; i < ARRAY_SIZE(parameterized_type_shorthands); ++i)
     {
         if ((tmp = strstr(buf, parameterized_type_shorthands[i][0])) &&
-            (tmp - buf) == strlen(use_abi_namespace ? "__x_ABI_C" : "__x_C"))
+            (tmp - buf) == strlen(ns_prefix) + (abi_prefix ? 5 : 0))
         {
            tmp += strlen(parameterized_type_shorthands[i][0]);
            strcpy(buf, parameterized_type_shorthands[i][1]);
@@ -358,7 +366,8 @@ static char *format_parameterized_type_short_name(type_t *type, typeref_list_t *
     if (params) LIST_FOR_EACH_ENTRY(ref, params, typeref_t, entry)
     {
         type = type_pointer_get_root_type(ref->type);
-        pos += strappend(&buf, &len, pos, "_%s", type->name);
+        if (type->short_name) pos += strappend(&buf, &len, pos, "_%s", type->short_name);
+        else pos += strappend(&buf, &len, pos, "_%s", type->name);
     }
 
     return buf;
@@ -895,8 +904,10 @@ static void compute_delegate_iface_names(type_t *delegate, type_t *type, typeref
     type_t *iface = delegate->details.delegate.iface;
     iface->namespace = delegate->namespace;
     iface->name = strmake("I%s", delegate->name);
-    if (type) iface->c_name = format_parameterized_type_c_name(type, params, "I");
+    if (type) iface->c_name = format_parameterized_type_c_name(type, params, "I", "_C");
     else iface->c_name = format_namespace(delegate->namespace, "__x_", "_C", iface->name, use_abi_namespace ? "ABI" : NULL);
+    if (type) iface->param_name = format_parameterized_type_c_name(type, params, "I", "__C");
+    else iface->param_name = format_namespace(delegate->namespace, "_", "__C", iface->name, NULL);
     iface->qualified_name = format_namespace(delegate->namespace, "", "::", iface->name, use_abi_namespace ? "ABI" : NULL);
 }
 
@@ -1218,8 +1229,9 @@ type_t *type_parameterized_type_specialize_declare(type_t *type, typeref_list_t
     new_type->namespace = type->namespace;
     new_type->name = format_parameterized_type_name(type, params);
     reg_type(new_type, new_type->name, new_type->namespace, 0);
-    new_type->c_name = format_parameterized_type_c_name(type, params, "");
+    new_type->c_name = format_parameterized_type_c_name(type, params, "", "_C");
     new_type->short_name = format_parameterized_type_short_name(type, params, "");
+    new_type->param_name = format_parameterized_type_c_name(type, params, "", "__C");
 
     if (new_type->type_type == TYPE_DELEGATE)
     {
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index 622c4708a87..1a46beb9cdd 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -482,7 +482,7 @@ enum type_type
 };
 
 struct _type_t {
-  const char *name;
+  const char *name;               /* C++ name with parameters in brackets */
   struct namespace *namespace;
   enum type_type type_type;
   attr_list_t *attrs;
@@ -503,11 +503,12 @@ struct _type_t {
     struct parameterized_details parameterized;
     struct delegate_details delegate;
   } details;
-  const char *c_name;
+  const char *c_name;             /* mangled C name, with namespaces and parameters */
   const char *signature;
-  const char *qualified_name;
-  const char *impl_name;
-  const char *short_name;
+  const char *qualified_name;     /* C++ fully qualified name */
+  const char *impl_name;          /* C++ parameterized types impl base class name */
+  const char *param_name;         /* used to build c_name of a parameterized type, when used as a parameter */
+  const char *short_name;         /* widl specific short name */
   unsigned int typestring_offset;
   unsigned int ptrdesc;           /* used for complex structs */
   int typelib_idx;
-- 
2.34.1




More information about the wine-devel mailing list