From: "Rémi Bernon" Subject: [PATCH 4/7] widl: Write C++ template declarations for parameterized types. Message-Id: <20210222090305.557337-4-rbernon@codeweavers.com> Date: Mon, 22 Feb 2021 10:03:02 +0100 In-Reply-To: <20210222090305.557337-1-rbernon@codeweavers.com> References: <20210222090305.557337-1-rbernon@codeweavers.com> Based on a patch from Steve Lhomme. Signed-off-by: Rémi Bernon --- 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