[PATCH 4/7] widl: Write C++ template declarations for parameterized types.

Rémi Bernon rbernon at codeweavers.com
Mon Feb 22 03:03:02 CST 2021


Based on a patch from Steve Lhomme.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 tools/widl/header.c   | 45 +++++++++++++++++++++++++++++++++++++++++++
 tools/widl/typetree.c |  5 +++++
 2 files changed, 50 insertions(+)

diff --git a/tools/widl/header.c b/tools/widl/header.c
index 95bdb8cacb8..4e3b1cb6cf3 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -125,6 +125,25 @@ unsigned int get_attrv(const attr_list_t *list, enum attr_type t)
     return 0;
 }
 
+static char *format_parameterized_type_args(const type_t *type, const char *prefix, const char *suffix)
+{
+    typeref_list_t *params;
+    typeref_t *ref;
+    size_t len = 0, pos = 0;
+    char *buf = NULL;
+
+    params = type->details.parameterized.params;
+    if (params) LIST_FOR_EACH_ENTRY(ref, params, typeref_t, entry)
+    {
+        assert(ref->type->type_type != TYPE_POINTER);
+        pos += strappend(&buf, &len, pos, "%s%s%s", prefix, ref->type->name, suffix);
+        if (list_next(params, &ref->entry)) pos += strappend(&buf, &len, pos, ", ");
+    }
+
+    if (!buf) return xstrdup("");
+    return buf;
+}
+
 static void write_guid(FILE *f, const char *guid_prefix, const char *name, const UUID *uuid)
 {
   if (!uuid) return;
@@ -1477,6 +1496,30 @@ static void write_function_proto(FILE *header, const type_t *iface, const var_t
   fprintf(header, ");\n\n");
 }
 
+static void write_parameterized_type_forward(FILE *header, type_t *type)
+{
+    type_t *iface = type->details.parameterized.type;
+    char *args;
+
+    if (type_get_type(iface) == TYPE_DELEGATE) iface = type_delegate_get_iface(iface);
+
+    fprintf(header, "#if defined(__cplusplus) && !defined(CINTERFACE)\n");
+    write_namespace_start(header, type->namespace);
+
+    args = format_parameterized_type_args(type, "class ", "");
+    write_line(header, 0, "template <%s>", args);
+    write_line(header, 0, "struct %s_impl;\n", iface->name);
+
+    write_line(header, 0, "template <%s>", args);
+    free(args);
+    args = format_parameterized_type_args(type, "", "");
+    write_line(header, 0, "struct %s : %s_impl<%s> {};", iface->name, iface->name, args);
+    free(args);
+
+    write_namespace_end(header, type->namespace);
+    fprintf(header, "#endif\n\n" );
+}
+
 static void write_forward(FILE *header, type_t *iface)
 {
   fprintf(header, "#ifndef __%s_FWD_DEFINED__\n", iface->c_name);
@@ -1872,6 +1915,8 @@ static void write_forward_decls(FILE *header, const statement_list_t *stmts)
           write_coclass_forward(header, stmt->u.type);
         else if (type_get_type(stmt->u.type) == TYPE_RUNTIMECLASS)
           write_runtimeclass_forward(header, stmt->u.type);
+        else if (type_get_type(stmt->u.type) == TYPE_PARAMETERIZED_TYPE)
+          write_parameterized_type_forward(header, stmt->u.type);
         break;
       case STMT_TYPEREF:
       case STMT_IMPORTLIB:
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
index 8bce314018a..e16b7713e91 100644
--- a/tools/widl/typetree.c
+++ b/tools/widl/typetree.c
@@ -929,6 +929,8 @@ type_t *type_parameterized_interface_define(type_t *type, attr_list_t *attrs, ty
     iface->details.iface->async_iface = NULL;
     iface->details.iface->requires = requires;
 
+    iface->name = type->name;
+
     type->defined = TRUE;
     return type;
 }
@@ -969,6 +971,9 @@ type_t *type_parameterized_delegate_define(type_t *type, attr_list_t *attrs, sta
     iface->details.iface->async_iface = NULL;
     iface->details.iface->requires = NULL;
 
+    delegate->name = type->name;
+    compute_delegate_iface_names(delegate, type, type->details.parameterized.params);
+
     type->defined = TRUE;
     return type;
 }
-- 
2.30.0




More information about the wine-devel mailing list