Rémi Bernon : widl: Write C++ template implementations for parameterized types.
Alexandre Julliard
julliard at winehq.org
Thu Feb 25 16:45:37 CST 2021
Module: wine
Branch: master
Commit: 3556ecd5d7db97984f340d59769bca0f23232f2f
URL: https://source.winehq.org/git/wine.git/?a=commit;h=3556ecd5d7db97984f340d59769bca0f23232f2f
Author: Rémi Bernon <rbernon at codeweavers.com>
Date: Thu Feb 25 14:16:02 2021 +0100
widl: Write C++ template implementations for parameterized types.
Based on a patch from Steve Lhomme.
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
tools/widl/header.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++---
tools/widl/typetree.h | 8 ++++++
2 files changed, 80 insertions(+), 3 deletions(-)
diff --git a/tools/widl/header.c b/tools/widl/header.c
index 8f8c66b2443..d81c66a3558 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -341,6 +341,7 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i
{
type_t *t = ds->type;
const char *name;
+ char *args;
if (!h) return;
@@ -507,9 +508,19 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i
else write_type_left(h, ds, name_type, declonly, write_callconv);
break;
}
- case TYPE_APICONTRACT:
case TYPE_PARAMETERIZED_TYPE:
+ {
+ type_t *iface = type_parameterized_type_get_real_type(t);
+ if (type_get_type(iface) == TYPE_DELEGATE) iface = type_delegate_get_iface(iface);
+ args = format_parameterized_type_args(t, "", "_logical");
+ fprintf(h, "%s<%s>", iface->name, args);
+ free(args);
+ break;
+ }
case TYPE_PARAMETER:
+ fprintf(h, "%s_abi", t->name);
+ break;
+ case TYPE_APICONTRACT:
/* shouldn't be here */
assert(0);
break;
@@ -576,10 +587,10 @@ void write_type_right(FILE *h, type_t *t, int is_field)
case TYPE_INTERFACE:
case TYPE_RUNTIMECLASS:
case TYPE_DELEGATE:
- break;
- case TYPE_APICONTRACT:
case TYPE_PARAMETERIZED_TYPE:
case TYPE_PARAMETER:
+ break;
+ case TYPE_APICONTRACT:
/* not supposed to be here */
assert(0);
break;
@@ -1517,6 +1528,58 @@ static void write_parameterized_type_forward(FILE *header, type_t *type)
fprintf(header, "#endif\n\n" );
}
+static void write_parameterized_implementation(FILE *header, type_t *type, int declonly)
+{
+ const statement_t *stmt;
+ typeref_list_t *params = params = type->details.parameterized.params;
+ typeref_t *ref;
+ type_t *iface = type->details.parameterized.type, *base;
+ char *args = NULL;
+
+ fprintf(header, "#if defined(__cplusplus) && !defined(CINTERFACE)\n");
+ write_line(header, 0, "} /* extern \"C\" */");
+ write_namespace_start(header, type->namespace);
+
+ if (type_get_type(iface) == TYPE_DELEGATE) iface = type_delegate_get_iface(iface);
+ base = type_iface_get_inherit(iface);
+
+ args = format_parameterized_type_args(type, "class ", "");
+ write_line(header, 0, "template <%s>", args);
+ free(args);
+ write_line(header, 0, "struct %s_impl%s", iface->name, base ? strmake(" : %s", base->name) : "");
+ write_line(header, 0, "{");
+
+ write_line(header, 1, "private:");
+ if (params) LIST_FOR_EACH_ENTRY(ref, params, typeref_t, entry)
+ {
+ write_line(header, 0, "typedef typename Windows::Foundation::Internal::GetAbiType<%s>::type %s_abi;", ref->type->name, ref->type->name);
+ write_line(header, 0, "typedef typename Windows::Foundation::Internal::GetLogicalType<%s>::type %s_logical;", ref->type->name, ref->type->name);
+ }
+ indentation -= 1;
+
+ write_line(header, 1, "public:");
+ if (params) LIST_FOR_EACH_ENTRY(ref, params, typeref_t, entry)
+ write_line(header, 0, "typedef %s %s_complex;", ref->type->name, ref->type->name);
+
+ STATEMENTS_FOR_EACH_FUNC(stmt, type_iface_get_stmts(iface))
+ {
+ const var_t *func = stmt->u.var;
+ if (is_callas(func->attrs)) continue;
+ indent(header, 1);
+ fprintf(header, "virtual ");
+ write_type_decl_left(header, &func->declspec);
+ fprintf(header, "%s(", get_name(func));
+ write_args(header, type_function_get_args(func->declspec.type), NULL, 0, 0, NAME_DEFAULT);
+ fprintf(header, ") = 0;\n");
+ indentation -= 1;
+ }
+ write_line(header, -1, "};");
+
+ write_namespace_end(header, type->namespace);
+ write_line(header, 0, "extern \"C\" {");
+ write_line(header, 0, "#endif\n");
+}
+
static void write_forward(FILE *header, type_t *iface)
{
fprintf(header, "#ifndef __%s_FWD_DEFINED__\n", iface->c_name);
@@ -1924,6 +1987,12 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
write_runtimeclass(header, stmt->u.type);
else if (type_get_type(stmt->u.type) != TYPE_PARAMETERIZED_TYPE)
write_type_definition(header, stmt->u.type, stmt->declonly);
+ else
+ {
+ is_object_interface++;
+ write_parameterized_implementation(header, stmt->u.type, stmt->declonly);
+ is_object_interface--;
+ }
break;
case STMT_TYPEREF:
/* FIXME: shouldn't write out forward declarations for undefined
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
index 805e96a9305..0b7cd385cc2 100644
--- a/tools/widl/typetree.h
+++ b/tools/widl/typetree.h
@@ -96,6 +96,14 @@ static inline type_t *type_get_real_type(const type_t *type)
return (type_t *)type;
}
+static inline type_t *type_parameterized_type_get_real_type(const type_t *type)
+{
+ if (type->type_type == TYPE_PARAMETERIZED_TYPE)
+ return type_parameterized_type_get_real_type(type->details.parameterized.type);
+ else
+ return (type_t *)type;
+}
+
static inline enum type_type type_get_type(const type_t *type)
{
return type_get_type_detect_alias(type_get_real_type(type));
More information about the wine-cvs
mailing list