widl: Use C++ template implementation for parameterized types.
Based on a patch from Steve Lhomme. Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
3556ecd5d7
commit
41a3087394
|
@ -1588,10 +1588,12 @@ static void write_forward(FILE *header, type_t *iface)
|
||||||
fprintf(header, "#ifdef __cplusplus\n");
|
fprintf(header, "#ifdef __cplusplus\n");
|
||||||
if (iface->namespace && !is_global_namespace(iface->namespace))
|
if (iface->namespace && !is_global_namespace(iface->namespace))
|
||||||
fprintf(header, "#define %s %s\n", iface->c_name, iface->qualified_name);
|
fprintf(header, "#define %s %s\n", iface->c_name, iface->qualified_name);
|
||||||
write_namespace_start(header, iface->namespace);
|
if (!iface->impl_name)
|
||||||
if (strchr(iface->name, '<')) write_line(header, 0, "template<> struct %s;", iface->name);
|
{
|
||||||
else write_line(header, 0, "interface %s;", iface->name);
|
write_namespace_start(header, iface->namespace);
|
||||||
write_namespace_end(header, iface->namespace);
|
write_line(header, 0, "interface %s;", iface->name);
|
||||||
|
write_namespace_end(header, iface->namespace);
|
||||||
|
}
|
||||||
fprintf(header, "#endif /* __cplusplus */\n");
|
fprintf(header, "#endif /* __cplusplus */\n");
|
||||||
fprintf(header, "#endif\n\n" );
|
fprintf(header, "#endif\n\n" );
|
||||||
}
|
}
|
||||||
|
@ -1667,7 +1669,12 @@ static void write_com_interface_end(FILE *header, type_t *iface)
|
||||||
if (strchr(iface->name, '<')) fprintf(header, "template<> struct ");
|
if (strchr(iface->name, '<')) fprintf(header, "template<> struct ");
|
||||||
else fprintf(header, "interface ");
|
else fprintf(header, "interface ");
|
||||||
}
|
}
|
||||||
if (type_iface_get_inherit(iface))
|
if (iface->impl_name)
|
||||||
|
{
|
||||||
|
fprintf(header, "%s : %s\n", iface->name, iface->impl_name);
|
||||||
|
write_line(header, 1, "{");
|
||||||
|
}
|
||||||
|
else if (type_iface_get_inherit(iface))
|
||||||
{
|
{
|
||||||
fprintf(header, "%s : public %s\n", iface->name,
|
fprintf(header, "%s : public %s\n", iface->name,
|
||||||
type_iface_get_inherit(iface)->name);
|
type_iface_get_inherit(iface)->name);
|
||||||
|
@ -1681,9 +1688,9 @@ static void write_com_interface_end(FILE *header, type_t *iface)
|
||||||
}
|
}
|
||||||
/* dispinterfaces don't have real functions, so don't write C++ functions for
|
/* dispinterfaces don't have real functions, so don't write C++ functions for
|
||||||
* them */
|
* them */
|
||||||
if (!dispinterface)
|
if (!dispinterface && !iface->impl_name)
|
||||||
write_cpp_method_def(header, iface);
|
write_cpp_method_def(header, iface);
|
||||||
if (!type_iface_get_inherit(iface))
|
if (!type_iface_get_inherit(iface) && !iface->impl_name)
|
||||||
write_line(header, 0, "END_INTERFACE\n");
|
write_line(header, 0, "END_INTERFACE\n");
|
||||||
write_line(header, -1, "};");
|
write_line(header, -1, "};");
|
||||||
if (!is_global_namespace(iface->namespace)) {
|
if (!is_global_namespace(iface->namespace)) {
|
||||||
|
|
|
@ -52,6 +52,7 @@ type_t *make_type(enum type_type type)
|
||||||
t->c_name = NULL;
|
t->c_name = NULL;
|
||||||
t->signature = NULL;
|
t->signature = NULL;
|
||||||
t->qualified_name = NULL;
|
t->qualified_name = NULL;
|
||||||
|
t->impl_name = NULL;
|
||||||
memset(&t->details, 0, sizeof(t->details));
|
memset(&t->details, 0, sizeof(t->details));
|
||||||
t->typestring_offset = 0;
|
t->typestring_offset = 0;
|
||||||
t->ptrdesc = 0;
|
t->ptrdesc = 0;
|
||||||
|
@ -127,6 +128,13 @@ static size_t append_namespaces(char **buf, size_t *len, size_t pos, struct name
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t append_pointer_stars(char **buf, size_t *len, size_t pos, type_t *type)
|
||||||
|
{
|
||||||
|
size_t n = 0;
|
||||||
|
for (; type && type->type_type == TYPE_POINTER; type = type_pointer_get_ref_type(type)) n += strappend(buf, len, pos + n, "*");
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
static size_t append_type_signature(char **buf, size_t *len, size_t pos, type_t *type);
|
static size_t append_type_signature(char **buf, size_t *len, size_t pos, type_t *type);
|
||||||
|
|
||||||
static size_t append_var_list_signature(char **buf, size_t *len, size_t pos, var_list_t *var_list)
|
static size_t append_var_list_signature(char **buf, size_t *len, size_t pos, var_list_t *var_list)
|
||||||
|
@ -266,9 +274,9 @@ char *format_parameterized_type_name(type_t *type, typeref_list_t *params)
|
||||||
pos += strappend(&buf, &len, pos, "%s<", type->name);
|
pos += strappend(&buf, &len, pos, "%s<", type->name);
|
||||||
if (params) LIST_FOR_EACH_ENTRY(ref, params, typeref_t, entry)
|
if (params) LIST_FOR_EACH_ENTRY(ref, params, typeref_t, entry)
|
||||||
{
|
{
|
||||||
for (type = ref->type; type->type_type == TYPE_POINTER; type = type_pointer_get_ref_type(type)) {}
|
type = type_pointer_get_root_type(ref->type);
|
||||||
pos += append_namespaces(&buf, &len, pos, type->namespace, "", "::", type->name, use_abi_namespace ? "ABI" : NULL);
|
pos += strappend(&buf, &len, pos, "%s", type->qualified_name);
|
||||||
for (type = ref->type; type->type_type == TYPE_POINTER; type = type_pointer_get_ref_type(type)) pos += strappend(&buf, &len, pos, "*");
|
pos += append_pointer_stars(&buf, &len, pos, ref->type);
|
||||||
if (list_next(params, &ref->entry)) pos += strappend(&buf, &len, pos, ",");
|
if (list_next(params, &ref->entry)) pos += strappend(&buf, &len, pos, ",");
|
||||||
}
|
}
|
||||||
pos += strappend(&buf, &len, pos, ">");
|
pos += strappend(&buf, &len, pos, ">");
|
||||||
|
@ -292,7 +300,7 @@ static char *format_parameterized_type_c_name(type_t *type, typeref_list_t *para
|
||||||
pos += strappend(&buf, &len, pos, "%s%s_%d", prefix, type->name, count);
|
pos += strappend(&buf, &len, pos, "%s%s_%d", prefix, type->name, count);
|
||||||
if (params) LIST_FOR_EACH_ENTRY(ref, params, typeref_t, entry)
|
if (params) LIST_FOR_EACH_ENTRY(ref, params, typeref_t, entry)
|
||||||
{
|
{
|
||||||
for (type = ref->type; type->type_type == TYPE_POINTER; type = type_pointer_get_ref_type(type)) {}
|
type = type_pointer_get_root_type(ref->type);
|
||||||
pos += append_namespaces(&buf, &len, pos, type->namespace, "_", "__C", type->name, NULL);
|
pos += append_namespaces(&buf, &len, pos, type->namespace, "_", "__C", type->name, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,6 +342,38 @@ static char *format_parameterized_type_signature(type_t *type, typeref_list_t *p
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *format_parameterized_type_impl_name(type_t *type, typeref_list_t *params, const char *prefix)
|
||||||
|
{
|
||||||
|
size_t len = 0, pos = 0;
|
||||||
|
char *buf = NULL;
|
||||||
|
typeref_t *ref;
|
||||||
|
type_t *iface;
|
||||||
|
|
||||||
|
pos += strappend(&buf, &len, pos, "%s%s_impl<", prefix, type->name);
|
||||||
|
if (params) LIST_FOR_EACH_ENTRY(ref, params, typeref_t, entry)
|
||||||
|
{
|
||||||
|
type = type_pointer_get_root_type(ref->type);
|
||||||
|
if (type->type_type == TYPE_RUNTIMECLASS)
|
||||||
|
{
|
||||||
|
pos += strappend(&buf, &len, pos, "ABI::Windows::Foundation::Internal::AggregateType<%s", type->qualified_name);
|
||||||
|
pos += append_pointer_stars(&buf, &len, pos, ref->type);
|
||||||
|
iface = type_runtimeclass_get_default_iface(type);
|
||||||
|
pos += strappend(&buf, &len, pos, ", %s", iface->qualified_name);
|
||||||
|
pos += append_pointer_stars(&buf, &len, pos, ref->type);
|
||||||
|
pos += strappend(&buf, &len, pos, ">");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pos += strappend(&buf, &len, pos, "%s", type->qualified_name);
|
||||||
|
pos += append_pointer_stars(&buf, &len, pos, ref->type);
|
||||||
|
}
|
||||||
|
if (list_next(params, &ref->entry)) pos += strappend(&buf, &len, pos, ", ");
|
||||||
|
}
|
||||||
|
pos += strappend(&buf, &len, pos, ">");
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
type_t *type_new_function(var_list_t *args)
|
type_t *type_new_function(var_list_t *args)
|
||||||
{
|
{
|
||||||
var_t *arg;
|
var_t *arg;
|
||||||
|
@ -1226,11 +1266,13 @@ type_t *type_parameterized_type_specialize_define(type_t *type)
|
||||||
error_loc("pinterface/pdelegate %s previously not declared a pinterface/pdelegate at %s:%d\n",
|
error_loc("pinterface/pdelegate %s previously not declared a pinterface/pdelegate at %s:%d\n",
|
||||||
iface->name, iface->loc_info.input_name, iface->loc_info.line_number);
|
iface->name, iface->loc_info.input_name, iface->loc_info.line_number);
|
||||||
|
|
||||||
|
iface->impl_name = format_parameterized_type_impl_name(type, repl, "");
|
||||||
iface->signature = format_parameterized_type_signature(type, repl);
|
iface->signature = format_parameterized_type_signature(type, repl);
|
||||||
iface->defined = TRUE;
|
iface->defined = TRUE;
|
||||||
if (iface->type_type == TYPE_DELEGATE)
|
if (iface->type_type == TYPE_DELEGATE)
|
||||||
{
|
{
|
||||||
iface = iface->details.delegate.iface;
|
iface = iface->details.delegate.iface;
|
||||||
|
iface->impl_name = format_parameterized_type_impl_name(type, repl, "I");
|
||||||
iface->signature = format_parameterized_type_signature(type, repl);
|
iface->signature = format_parameterized_type_signature(type, repl);
|
||||||
iface->defined = TRUE;
|
iface->defined = TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -411,6 +411,12 @@ static inline type_t *type_pointer_get_ref_type(const type_t *type)
|
||||||
return type_pointer_get_ref(type)->type;
|
return type_pointer_get_ref(type)->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline type_t *type_pointer_get_root_type(type_t *type)
|
||||||
|
{
|
||||||
|
for (; type && type->type_type == TYPE_POINTER; type = type_pointer_get_ref_type(type)) {}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
static inline type_t *type_bitfield_get_field(const type_t *type)
|
static inline type_t *type_bitfield_get_field(const type_t *type)
|
||||||
{
|
{
|
||||||
type = type_get_real_type(type);
|
type = type_get_real_type(type);
|
||||||
|
|
|
@ -504,6 +504,7 @@ struct _type_t {
|
||||||
const char *c_name;
|
const char *c_name;
|
||||||
const char *signature;
|
const char *signature;
|
||||||
const char *qualified_name;
|
const char *qualified_name;
|
||||||
|
const char *impl_name;
|
||||||
unsigned int typestring_offset;
|
unsigned int typestring_offset;
|
||||||
unsigned int ptrdesc; /* used for complex structs */
|
unsigned int ptrdesc; /* used for complex structs */
|
||||||
int typelib_idx;
|
int typelib_idx;
|
||||||
|
|
Loading…
Reference in New Issue