widl: Allow runtimeclass to not have a default interface.

Or any interfaces, as long as they have a static factory, as MIDL
requires.

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:
Rémi Bernon 2021-03-09 20:41:18 +01:00 committed by Alexandre Julliard
parent 462f5759d1
commit e137becb13
3 changed files with 13 additions and 8 deletions

View File

@ -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));

View File

@ -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 */

View File

@ -20,6 +20,9 @@
#include "widltypes.h"
#include <assert.h>
#include <stdio.h>
#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)