-- v2: widl: Store the runtimeclass for constructor interfaces. widl: Store a variable pointer instead of a declaration in expressions. widl: Relax check on runtimeclass definitions.
From: Hans Leidekker hans@codeweavers.com
--- tools/widl/typetree.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c index 2f67545393e..c6c2a5bfc0f 100644 --- a/tools/widl/typetree.c +++ b/tools/widl/typetree.c @@ -854,9 +854,8 @@ type_t *type_runtimeclass_define(type_t *runtimeclass, attr_list_t *attrs, runtimeclass->attrs = check_runtimeclass_attrs(runtimeclass->name, attrs); runtimeclass->details.runtimeclass.ifaces = ifaces; define_type(runtimeclass, where); - 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); + if (!type_runtimeclass_get_ifaces(runtimeclass) && !get_attrp(runtimeclass->attrs, ATTR_STATIC)) + error_loc("runtimeclass %s must have at least one interface or static factory\n", runtimeclass->name);
if (ifaces) LIST_FOR_EACH_ENTRY(ref, ifaces, typeref_t, entry) {
From: Hans Leidekker hans@codeweavers.com
--- tools/widl/expr.c | 13 ++++++------- tools/widl/header.c | 4 ++-- tools/widl/metadata.c | 27 +++++++++++++++------------ tools/widl/widltypes.h | 2 +- 4 files changed, 24 insertions(+), 22 deletions(-)
diff --git a/tools/widl/expr.c b/tools/widl/expr.c index be818de2e83..6d162094b82 100644 --- a/tools/widl/expr.c +++ b/tools/widl/expr.c @@ -198,7 +198,7 @@ expr_t *make_exprt(enum expr_type type, var_t *var, expr_t *expr) e = xmalloc(sizeof(expr_t)); e->type = type; e->ref = expr; - e->u.tref = var->declspec; + e->u.var = var; e->is_const = FALSE; if (type == EXPR_SIZEOF) { @@ -240,7 +240,6 @@ expr_t *make_exprt(enum expr_type type, var_t *var, expr_t *expr) e->cval = expr->cval; } } - free(var); return e; }
@@ -581,7 +580,7 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc break; case EXPR_CAST: result = resolve_expression(expr_loc, cont_type, e->ref); - result.type = e->u.tref.type; + result.type = e->u.var->declspec.type; break; case EXPR_SIZEOF: result.is_temporary = FALSE; @@ -752,13 +751,13 @@ void write_expr(FILE *h, const expr_t *e, int brackets, break; case EXPR_CAST: fprintf(h, "("); - write_type_decl(h, &e->u.tref, NULL); + write_type_decl(h, &e->u.var->declspec, NULL); fprintf(h, ")"); write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix); break; case EXPR_SIZEOF: fprintf(h, "sizeof("); - write_type_decl(h, &e->u.tref, NULL); + write_type_decl(h, &e->u.var->declspec, NULL); fprintf(h, ")"); break; case EXPR_SHL: @@ -909,7 +908,7 @@ int compare_expr(const expr_t *a, const expr_t *b) return ret; return compare_expr(a->u.ext, b->u.ext); case EXPR_CAST: - ret = compare_type(a->u.tref.type, b->u.tref.type); + ret = compare_type(a->u.var->declspec.type, b->u.var->declspec.type); if (ret != 0) return ret; /* Fall through. */ @@ -921,7 +920,7 @@ int compare_expr(const expr_t *a, const expr_t *b) case EXPR_POS: return compare_expr(a->ref, b->ref); case EXPR_SIZEOF: - return compare_type(a->u.tref.type, b->u.tref.type); + return compare_type(a->u.var->declspec.type, b->u.var->declspec.type); case EXPR_VOID: return 0; } diff --git a/tools/widl/header.c b/tools/widl/header.c index e2ce883b788..0b188a832fe 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -1589,7 +1589,7 @@ static void write_apicontract_guard_start(FILE *header, const expr_t *expr) char *name; int ver; if (!winrt_mode) return; - type = expr->u.tref.type; + type = expr->u.var->declspec.type; write_apicontract( header, type ); ver = expr->ref->u.integer.value; name = format_apicontract_macro(type); @@ -1603,7 +1603,7 @@ static void write_apicontract_guard_end(FILE *header, const expr_t *expr) char *name; int ver; if (!winrt_mode) return; - type = expr->u.tref.type; + type = expr->u.var->declspec.type; ver = expr->ref->u.integer.value; name = format_apicontract_macro(type); fprintf(header, "#endif /* %s_VERSION >= %#x */\n", name, ver); diff --git a/tools/widl/metadata.c b/tools/widl/metadata.c index 42a8a953a21..a9924a8a8da 100644 --- a/tools/widl/metadata.c +++ b/tools/widl/metadata.c @@ -1700,9 +1700,10 @@ static UINT make_deprecated_sig( UINT token, BYTE *buf )
static UINT make_contract_value( const type_t *type, BYTE *buf ) { - const expr_t *contract = get_attrp( type->attrs, ATTR_CONTRACT ); - char *name = format_namespace( contract->u.tref.type->namespace, "", ".", contract->u.tref.type->name, NULL ); - UINT version = contract->ref->u.integer.value, len = strlen( name ); + const expr_t *attr = get_attrp( type->attrs, ATTR_CONTRACT ); + const type_t *contract = attr->u.var->declspec.type; + char *name = format_namespace( contract->namespace, "", ".", contract->name, NULL ); + UINT version = attr->ref->u.integer.value, len = strlen( name );
buf[0] = 1; buf[1] = 0; @@ -2070,6 +2071,7 @@ static UINT make_deprecated_value( const var_t *method, BYTE **ret_buf ) { static const BYTE zero[] = { 0x00, 0x00, 0x00, 0x00 }, one[] = { 0x01, 0x00, 0x00, 0x00 }; const expr_t *attr = get_attrp( method->attrs, ATTR_DEPRECATED ); + const type_t *type = attr->ext2->u.var->declspec.type; const char *text = attr->ref->u.sval; const char *kind = attr->u.ext->u.sval; BYTE encoded[4]; @@ -2091,7 +2093,7 @@ static UINT make_deprecated_value( const var_t *method, BYTE **ret_buf )
buf[len++] = 1; buf[len++] = 0; - contract = format_namespace( attr->ext2->u.tref.type->namespace, "", ".", attr->ext2->u.tref.type->name, NULL ); + contract = format_namespace( type->namespace, "", ".", type->name, NULL ); len_text = strlen( contract ); buf[len++] = len_text; memcpy( buf + len, contract, len_text ); @@ -2643,8 +2645,9 @@ static void add_method_contract_attrs( const type_t *class, const type_t *iface, static UINT make_static_value( const expr_t *attr, BYTE *buf ) { const expr_t *contract = attr->ref; - char *name_iface = format_namespace( attr->u.tref.type->namespace, "", ".", attr->u.tref.type->name, NULL ); - char *name_contract = format_namespace( contract->u.tref.type->namespace, "", ".", contract->u.tref.type->name, NULL ); + const type_t *type_iface = attr->u.var->declspec.type, *type_contract = contract->u.var->declspec.type; + char *name_iface = format_namespace( type_iface->namespace, "", ".", type_iface->name, NULL ); + char *name_contract = format_namespace( type_contract->namespace, "", ".", type_contract->name, NULL ); UINT len_iface = strlen( name_iface ), len_contract = strlen( name_contract ); BYTE *ptr = buf;
@@ -2709,18 +2712,18 @@ static UINT make_activatable_value( const expr_t *attr, BYTE *buf ) { char *name_iface = NULL, *name_contract; UINT len_iface = 0, len_contract, len_extra = 5; - const type_t *contract; + const type_t *type_iface = attr->u.var->declspec.type, *type_contract; BYTE *ptr = buf;
- if (attr->u.tref.type->type_type != TYPE_INTERFACE) contract = attr->u.tref.type; + if (attr->type != EXPR_MEMBER) type_contract = attr->u.var->declspec.type; else { - name_iface = format_namespace( attr->u.tref.type->namespace, "", ".", attr->u.tref.type->name, NULL ); + name_iface = format_namespace( type_iface->namespace, "", ".", type_iface->name, NULL ); len_iface = strlen( name_iface ); - contract = attr->ref->u.tref.type; + type_contract = attr->ref->u.var->declspec.type; }
- name_contract = format_namespace( contract->namespace, "", ".", contract->name, NULL ); + name_contract = format_namespace( type_contract->namespace, "", ".", type_contract->name, NULL ); len_contract = strlen( name_contract );
if (len_iface) @@ -2768,7 +2771,7 @@ static void add_activatable_attr_step1( type_t *type )
class = memberref_parent( TABLE_TYPEREF, typeref );
- if (value->u.tref.type->type_type == TYPE_INTERFACE) + if (value->type == EXPR_MEMBER) sig_size = make_member_sig3( typedef_or_ref(TABLE_TYPEREF, typeref_type), sig ); else { diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index 620a3857bc9..9aaf103f2b8 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -365,7 +365,7 @@ struct _expr_t { double dval; const char *sval; const expr_t *ext; - decl_spec_t tref; + var_t *var; } u; const expr_t *ext2; int is_const;
From: Hans Leidekker hans@codeweavers.com
This makes the runtimeclass available when metadata for the constructor interface is generated. --- tools/widl/typetree.c | 17 +++++++++++++++++ tools/widl/widltypes.h | 1 + 2 files changed, 18 insertions(+)
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c index c6c2a5bfc0f..c030cea85df 100644 --- a/tools/widl/typetree.c +++ b/tools/widl/typetree.c @@ -748,6 +748,7 @@ type_t *type_interface_define(type_t *iface, attr_list_t *attrs, type_t *inherit iface->details.iface->inherit = inherit; iface->details.iface->disp_inherit = NULL; iface->details.iface->async_iface = NULL; + iface->details.iface->runtime_class = NULL; iface->details.iface->requires = requires; define_type(iface, where); compute_method_indexes(iface); @@ -845,6 +846,21 @@ type_t *type_runtimeclass_declare(char *name, struct namespace *namespace) return type; }
+static void set_constructor_runtimeclass(type_t *runtimeclass, attr_list_t *attrs) +{ + const attr_t *attr; + if (!attrs) return; + LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry) + { + if (attr->type == ATTR_ACTIVATABLE || attr->type == ATTR_COMPOSABLE) + { + const expr_t *value = attr->u.pval; + if (value->type == EXPR_MEMBER) + value->u.var->declspec.type->details.iface->runtime_class = runtimeclass; + } + } +} + type_t *type_runtimeclass_define(type_t *runtimeclass, attr_list_t *attrs, typeref_list_t *ifaces, const struct location *where) { @@ -853,6 +869,7 @@ type_t *type_runtimeclass_define(type_t *runtimeclass, attr_list_t *attrs,
runtimeclass->attrs = check_runtimeclass_attrs(runtimeclass->name, attrs); runtimeclass->details.runtimeclass.ifaces = ifaces; + set_constructor_runtimeclass(runtimeclass, attrs); define_type(runtimeclass, where); if (!type_runtimeclass_get_ifaces(runtimeclass) && !get_attrp(runtimeclass->attrs, ATTR_STATIC)) error_loc("runtimeclass %s must have at least one interface or static factory\n", runtimeclass->name); diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index 9aaf103f2b8..1706f392670 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -403,6 +403,7 @@ struct iface_details struct _type_t *inherit; struct _type_t *disp_inherit; struct _type_t *async_iface; + struct _type_t *runtime_class; typeref_list_t *requires; };
v2: Relax runtimeclass check, store a variable pointer and check expression type.