From e137becb13113d669c8d5e3cf8d5c2a9c4f50129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Bernon?= Date: Tue, 9 Mar 2021 20:41:18 +0100 Subject: [PATCH] widl: Allow runtimeclass to not have a default interface. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Or any interfaces, as long as they have a static factory, as MIDL requires. Signed-off-by: RĂ©mi Bernon Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- tools/widl/header.c | 2 +- tools/widl/typetree.c | 11 ++++++----- tools/widl/typetree.h | 8 ++++++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/tools/widl/header.c b/tools/widl/header.c index 40c1f9d008e..a5e5d6c6fb3 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -488,7 +488,7 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i fprintf(h, "%s", type_get_qualified_name(t, name_type)); break; case TYPE_RUNTIMECLASS: - fprintf(h, "%s", type_get_name(type_runtimeclass_get_default_iface(t), name_type)); + fprintf(h, "%s", type_get_name(type_runtimeclass_get_default_iface(t, TRUE), name_type)); break; case TYPE_DELEGATE: fprintf(h, "%s", type_get_qualified_name(type_delegate_get_iface(t), name_type)); diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c index 591a58b2849..a4e1696d2af 100644 --- a/tools/widl/typetree.c +++ b/tools/widl/typetree.c @@ -188,7 +188,7 @@ static size_t append_type_signature(char **buf, size_t *len, size_t pos, type_t n += strappend(buf, len, pos + n, "rc("); n += append_namespaces(buf, len, pos + n, type->namespace, "", ".", type->name, NULL); n += strappend(buf, len, pos + n, ";"); - n += append_type_signature(buf, len, pos + n, type_runtimeclass_get_default_iface(type)); + n += append_type_signature(buf, len, pos + n, type_runtimeclass_get_default_iface(type, TRUE)); n += strappend(buf, len, pos + n, ")"); return n; case TYPE_POINTER: @@ -379,7 +379,7 @@ static char *format_parameterized_type_impl_name(type_t *type, typeref_list_t *p { 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); + iface = type_runtimeclass_get_default_iface(type, TRUE); pos += strappend(&buf, &len, pos, ", %s", iface->qualified_name); pos += append_pointer_stars(&buf, &len, pos, ref->type); pos += strappend(&buf, &len, pos, " >"); @@ -843,10 +843,11 @@ type_t *type_runtimeclass_define(type_t *runtimeclass, attr_list_t *attrs, typer runtimeclass->attrs = check_runtimeclass_attrs(runtimeclass->name, attrs); runtimeclass->details.runtimeclass.ifaces = ifaces; runtimeclass->defined = TRUE; - if (!type_runtimeclass_get_default_iface(runtimeclass)) - error_loc("missing default interface on runtimeclass %s\n", runtimeclass->name); + if (!type_runtimeclass_get_default_iface(runtimeclass, FALSE) && + !get_attrp(runtimeclass->attrs, ATTR_STATIC)) + error_loc("runtimeclass %s must have a default interface or static factory\n", runtimeclass->name); - LIST_FOR_EACH_ENTRY(ref, ifaces, typeref_t, entry) + if (ifaces) LIST_FOR_EACH_ENTRY(ref, ifaces, typeref_t, entry) { /* FIXME: this should probably not be allowed, here or in coclass, */ /* but for now there's too many places in Wine IDL where it is to */ diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h index b9833dc4e8f..b43b6bfbf79 100644 --- a/tools/widl/typetree.h +++ b/tools/widl/typetree.h @@ -20,6 +20,9 @@ #include "widltypes.h" #include +#include + +#include "utils.h" #ifndef WIDL_TYPE_TREE_H #define WIDL_TYPE_TREE_H @@ -379,7 +382,7 @@ static inline typeref_list_t *type_runtimeclass_get_ifaces(const type_t *type) return type->details.runtimeclass.ifaces; } -static inline type_t *type_runtimeclass_get_default_iface(const type_t *type) +static inline type_t *type_runtimeclass_get_default_iface(const type_t *type, int check) { typeref_list_t *ifaces = type_runtimeclass_get_ifaces(type); typeref_t *ref; @@ -389,7 +392,8 @@ static inline type_t *type_runtimeclass_get_default_iface(const type_t *type) if (is_attr(ref->attrs, ATTR_DEFAULT)) return ref->type; - return NULL; + if (!check) return NULL; + error_loc_info(&type->loc_info, "runtimeclass %s needs a default interface\n", type->name); } static inline type_t *type_delegate_get_iface(const type_t *type)