Rebase against b8719736c5a022fa9c50f64adfc3ef58b40460f2.

This commit is contained in:
Zebediah Figura
2021-02-18 20:16:43 -06:00
parent 811467bf6a
commit aa8a3d90cb
33 changed files with 301 additions and 3157 deletions

View File

@@ -1,364 +0,0 @@
From bb8fd38219aa4696173b859eeefcea793a4738b3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 4 Feb 2021 17:16:55 +0100
Subject: [PATCH] widl: Support WinRT delegate type.
---
tools/widl/expr.c | 1 +
tools/widl/header.c | 16 +++++++++-----
tools/widl/parser.l | 1 +
tools/widl/parser.y | 20 +++++++++++++++++
tools/widl/typegen.c | 4 ++++
tools/widl/typelib.c | 1 +
tools/widl/typetree.c | 49 ++++++++++++++++++++++++++++++++++++++++++
tools/widl/typetree.h | 10 +++++++++
tools/widl/widltypes.h | 7 ++++++
9 files changed, 104 insertions(+), 5 deletions(-)
diff --git a/tools/widl/expr.c b/tools/widl/expr.c
index c83e9aa5ec0..88d59290d6b 100644
--- a/tools/widl/expr.c
+++ b/tools/widl/expr.c
@@ -466,6 +466,7 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type,
case TYPE_RUNTIMECLASS:
case TYPE_PARAMETERIZED_TYPE:
case TYPE_PARAMETER:
+ case TYPE_DELEGATE:
/* nothing to do */
break;
case TYPE_ALIAS:
diff --git a/tools/widl/header.c b/tools/widl/header.c
index a4f1db56a01..7ab79d3b6e1 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -470,6 +470,9 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i
case TYPE_RUNTIMECLASS:
fprintf(h, "%s", type_get_name(type_runtimeclass_get_default_iface(t), name_type));
break;
+ case TYPE_DELEGATE:
+ fprintf(h, "%s", type_get_name(type_delegate_get_iface(t), name_type));
+ break;
case TYPE_VOID:
fprintf(h, "void");
break;
@@ -555,6 +558,7 @@ void write_type_right(FILE *h, type_t *t, int is_field)
case TYPE_COCLASS:
case TYPE_INTERFACE:
case TYPE_RUNTIMECLASS:
+ case TYPE_DELEGATE:
break;
case TYPE_APICONTRACT:
case TYPE_PARAMETERIZED_TYPE:
@@ -974,7 +978,7 @@ int has_out_arg_or_return(const var_t *func)
int is_object(const type_t *iface)
{
const attr_t *attr;
- if (type_is_defined(iface) && type_iface_get_inherit(iface))
+ if (type_is_defined(iface) && (type_get_type(iface) == TYPE_DELEGATE || type_iface_get_inherit(iface)))
return 1;
if (iface->attrs) LIST_FOR_EACH_ENTRY( attr, iface->attrs, const attr_t, entry )
if (attr->type == ATTR_OBJECT || attr->type == ATTR_ODL) return 1;
@@ -1799,9 +1803,10 @@ static void write_forward_decls(FILE *header, const statement_list_t *stmts)
switch (stmt->type)
{
case STMT_TYPE:
- if (type_get_type(stmt->u.type) == TYPE_INTERFACE)
+ if (type_get_type(stmt->u.type) == TYPE_INTERFACE || type_get_type(stmt->u.type) == TYPE_DELEGATE)
{
type_t *iface = stmt->u.type;
+ if (type_get_type(iface) == TYPE_DELEGATE) iface = type_delegate_get_iface(iface);
if (is_object(iface) || is_attr(iface->attrs, ATTR_DISPINTERFACE))
{
write_forward(header, iface);
@@ -1841,10 +1846,11 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
switch (stmt->type)
{
case STMT_TYPE:
- if (type_get_type(stmt->u.type) == TYPE_INTERFACE)
+ if (type_get_type(stmt->u.type) == TYPE_INTERFACE || type_get_type(stmt->u.type) == TYPE_DELEGATE)
{
- type_t *iface = stmt->u.type;
- type_t *async_iface = type_iface_get_async_iface(iface);
+ type_t *iface = stmt->u.type, *async_iface;
+ if (type_get_type(stmt->u.type) == TYPE_DELEGATE) iface = type_delegate_get_iface(iface);
+ async_iface = type_iface_get_async_iface(iface);
if (is_object(iface)) is_object_interface++;
if (is_attr(stmt->u.type->attrs, ATTR_DISPINTERFACE) || is_object(stmt->u.type))
{
diff --git a/tools/widl/parser.l b/tools/widl/parser.l
index d319954edd3..f5e91dc741a 100644
--- a/tools/widl/parser.l
+++ b/tools/widl/parser.l
@@ -278,6 +278,7 @@ static const struct keyword keywords[] = {
{"cpp_quote", tCPPQUOTE, 0},
{"declare", tDECLARE, 1},
{"default", tDEFAULT, 0},
+ {"delegate", tDELEGATE, 1},
{"dispinterface", tDISPINTERFACE, 0},
{"double", tDOUBLE, 0},
{"enum", tENUM, 0},
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 7ab825b612b..5c3eae7bf82 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -110,6 +110,7 @@ static statement_t *make_statement_module(type_t *type);
static statement_t *make_statement_typedef(var_list_t *names, int declonly);
static statement_t *make_statement_import(const char *str);
static statement_t *make_statement_parameterized_type(type_t *type, type_list_t *params);
+static statement_t *make_statement_delegate(type_t *ret, var_list_t *args);
static statement_list_t *append_statement(statement_list_t *list, statement_t *stmt);
static statement_list_t *append_statements(statement_list_t *, statement_list_t *);
static attr_list_t *append_attribs(attr_list_t *, attr_list_t *);
@@ -185,6 +186,7 @@ static typelib_t *current_typelib;
%token tCUSTOM
%token tDECLARE
%token tDECODE tDEFAULT tDEFAULTBIND
+%token tDELEGATE
%token tDEFAULTCOLLELEM
%token tDEFAULTVALUE
%token tDEFAULTVTABLE
@@ -283,6 +285,7 @@ static typelib_t *current_typelib;
%type <expr_list> m_exprs /* exprs expr_list */ expr_list_int_const
%type <expr> contract_req
%type <expr> static_attr
+%type <type> delegatedef
%type <stgclass> storage_cls_spec
%type <type_qualifier> type_qualifier m_type_qual_list
%type <function_specifier> function_specifier
@@ -388,6 +391,7 @@ gbl_statements: { $$ = NULL; }
| gbl_statements interface ';' { $$ = append_statement($1, make_statement_reference($2)); }
| gbl_statements dispinterface ';' { $$ = append_statement($1, make_statement_reference($2)); }
| gbl_statements interfacedef { $$ = append_statement($1, make_statement_type_decl($2)); }
+ | gbl_statements delegatedef { $$ = append_statement($1, make_statement_type_decl($2)); }
| gbl_statements coclass ';' { $$ = $1;
reg_type($2, $2->name, current_namespace, 0);
}
@@ -412,6 +416,7 @@ imp_statements: { $$ = NULL; }
| imp_statements namespacedef '{' { push_namespace($2); } imp_statements '}'
{ pop_namespace($2); $$ = append_statements($1, $5); }
| imp_statements interfacedef { $$ = append_statement($1, make_statement_type_decl($2)); }
+ | imp_statements delegatedef { $$ = append_statement($1, make_statement_type_decl($2)); }
| imp_statements coclass ';' { $$ = $1; reg_type($2, $2->name, current_namespace, 0); }
| imp_statements coclassdef { $$ = append_statement($1, make_statement_type_decl($2));
reg_type($2, $2->name, current_namespace, 0);
@@ -1024,6 +1029,12 @@ interface:
{ $$ = type_parameterized_interface_declare($2, current_namespace, $5); }
;
+delegatedef: m_attributes tDELEGATE type ident '(' m_args ')' semicolon_opt
+ { $$ = type_delegate_declare($4->name, current_namespace);
+ $$ = type_delegate_define($$, $1, append_statement(NULL, make_statement_delegate($3, $6)));
+ }
+ ;
+
required_types:
qualified_type { $$ = append_type(NULL, $1); }
| parameterized_type { $$ = append_type(NULL, $1); }
@@ -2677,6 +2688,7 @@ static int is_allowed_conf_type(const type_t *type)
case TYPE_INTERFACE:
case TYPE_BITFIELD:
case TYPE_RUNTIMECLASS:
+ case TYPE_DELEGATE:
return FALSE;
case TYPE_APICONTRACT:
case TYPE_PARAMETERIZED_TYPE:
@@ -3319,6 +3331,14 @@ static statement_t *make_statement_parameterized_type(type_t *type, type_list_t
return stmt;
}
+static statement_t *make_statement_delegate(type_t *ret, var_list_t *args)
+{
+ declarator_t *decl = make_declarator(make_var(xstrdup("Invoke")));
+ decl_spec_t *spec = make_decl_spec(ret, NULL, NULL, STG_NONE, 0, 0);
+ append_chain_type(decl, type_new_function(args), 0);
+ return make_statement_declaration(declare_var(NULL, spec, decl, FALSE));
+}
+
static statement_list_t *append_statements(statement_list_t *l1, statement_list_t *l2)
{
if (!l2) return l1;
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index 1b5fe16b6ec..ec85f149da1 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -354,6 +354,7 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att
case TYPE_POINTER:
if (type_get_type(type_pointer_get_ref_type(type)) == TYPE_INTERFACE ||
type_get_type(type_pointer_get_ref_type(type)) == TYPE_RUNTIMECLASS ||
+ type_get_type(type_pointer_get_ref_type(type)) == TYPE_DELEGATE ||
(type_get_type(type_pointer_get_ref_type(type)) == TYPE_VOID && is_attr(attrs, ATTR_IIDIS)))
return TGT_IFACE_POINTER;
else if (is_aliaschain_attr(type_pointer_get_ref_type(type), ATTR_CONTEXTHANDLE))
@@ -375,6 +376,7 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att
case TYPE_ALIAS:
case TYPE_BITFIELD:
case TYPE_RUNTIMECLASS:
+ case TYPE_DELEGATE:
break;
case TYPE_APICONTRACT:
case TYPE_PARAMETERIZED_TYPE:
@@ -1978,6 +1980,7 @@ unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *align)
case TYPE_RUNTIMECLASS:
case TYPE_PARAMETERIZED_TYPE:
case TYPE_PARAMETER:
+ case TYPE_DELEGATE:
/* these types should not be encountered here due to language
* restrictions (interface, void, coclass, module), logical
* restrictions (alias - due to type_get_type call above) or
@@ -2083,6 +2086,7 @@ static unsigned int type_buffer_alignment(const type_t *t)
case TYPE_RUNTIMECLASS:
case TYPE_PARAMETERIZED_TYPE:
case TYPE_PARAMETER:
+ case TYPE_DELEGATE:
/* these types should not be encountered here due to language
* restrictions (interface, void, coclass, module), logical
* restrictions (alias - due to type_get_type call above) or
diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c
index 6f6c5f3ccc8..8b2a2401367 100644
--- a/tools/widl/typelib.c
+++ b/tools/widl/typelib.c
@@ -219,6 +219,7 @@ unsigned short get_type_vt(type_t *t)
case TYPE_UNION:
case TYPE_ENCAPSULATED_UNION:
case TYPE_RUNTIMECLASS:
+ case TYPE_DELEGATE:
return VT_USERDEFINED;
case TYPE_VOID:
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
index 77148de8d0f..08f9a0e0c09 100644
--- a/tools/widl/typetree.c
+++ b/tools/widl/typetree.c
@@ -640,6 +640,54 @@ type_t *type_apicontract_define(type_t *apicontract, attr_list_t *attrs)
return apicontract;
}
+static void compute_delegate_iface_names(type_t *delegate)
+{
+ type_t *iface = delegate->details.delegate.iface;
+ iface->namespace = delegate->namespace;
+ iface->name = strmake("I%s", delegate->name);
+ iface->c_name = format_namespace(delegate->namespace, "__x_", "_C", iface->name, use_abi_namespace ? "ABI" : NULL);
+}
+
+type_t *type_delegate_declare(char *name, struct namespace *namespace)
+{
+ type_t *type = get_type(TYPE_DELEGATE, name, NULL, 0);
+ if (type_get_type_detect_alias(type) != TYPE_DELEGATE)
+ error_loc("delegate %s previously not declared a delegate at %s:%d\n",
+ type->name, type->loc_info.input_name, type->loc_info.line_number);
+ return type;
+}
+
+type_t *type_delegate_define(type_t *delegate, attr_list_t *attrs, statement_list_t *stmts)
+{
+ type_t *iface;
+
+ if (delegate->defined)
+ error_loc("delegate %s already defined at %s:%d\n",
+ delegate->name, delegate->loc_info.input_name, delegate->loc_info.line_number);
+
+ delegate->attrs = check_interface_attrs(delegate->name, attrs);
+
+ iface = make_type(TYPE_INTERFACE);
+ iface->attrs = delegate->attrs;
+ iface->details.iface = xmalloc(sizeof(*iface->details.iface));
+ iface->details.iface->disp_props = NULL;
+ iface->details.iface->disp_methods = NULL;
+ iface->details.iface->stmts = stmts;
+ iface->details.iface->inherit = find_type("IUnknown", NULL, 0);
+ if (!iface->details.iface->inherit) error_loc("IUnknown is undefined\n");
+ iface->details.iface->disp_inherit = NULL;
+ iface->details.iface->async_iface = NULL;
+ iface->details.iface->requires = NULL;
+ iface->defined = TRUE;
+ compute_method_indexes(iface);
+
+ delegate->details.delegate.iface = iface;
+ delegate->defined = TRUE;
+ compute_delegate_iface_names(delegate);
+
+ return delegate;
+}
+
type_t *type_parameterized_interface_declare(char *name, struct namespace *namespace, type_list_t *params)
{
type_t *type = get_type(TYPE_PARAMETERIZED_TYPE, name, namespace, 0);
@@ -799,6 +847,7 @@ static type_t *replace_type_parameters_in_type(type_t *type, type_list_t *orig,
case TYPE_BITFIELD:
case TYPE_INTERFACE:
case TYPE_RUNTIMECLASS:
+ case TYPE_DELEGATE:
return type;
case TYPE_PARAMETER:
for (o = orig, r = repl; o && r; o = o->next, r = r->next)
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
index b3812649f59..413f1f9e41b 100644
--- a/tools/widl/typetree.h
+++ b/tools/widl/typetree.h
@@ -64,6 +64,8 @@ type_t *type_coclass_define(type_t *coclass, attr_list_t *attrs, ifref_list_t *i
type_t *type_runtimeclass_define(type_t *runtimeclass, attr_list_t *attrs, ifref_list_t *ifaces);
type_t *type_apicontract_declare(char *name, struct namespace *namespace);
type_t *type_apicontract_define(type_t *apicontract, attr_list_t *attrs);
+type_t *type_delegate_declare(char *name, struct namespace *namespace);
+type_t *type_delegate_define(type_t *delegate, attr_list_t *attrs, statement_list_t *stmts);
type_t *type_parameterized_interface_declare(char *name, struct namespace *namespace, type_list_t *params);
type_t *type_parameterized_interface_define(type_t *type, attr_list_t *attrs, type_t *inherit, statement_list_t *stmts, type_list_t *requires);
type_t *type_parameterized_type_specialize_partial(type_t *type, type_list_t *params);
@@ -251,6 +253,7 @@ static inline int type_is_complete(const type_t *type)
case TYPE_ARRAY:
case TYPE_BITFIELD:
case TYPE_RUNTIMECLASS:
+ case TYPE_DELEGATE:
return TRUE;
case TYPE_APICONTRACT:
case TYPE_PARAMETERIZED_TYPE:
@@ -373,6 +376,13 @@ static inline type_t *type_runtimeclass_get_default_iface(const type_t *type)
return NULL;
}
+static inline type_t *type_delegate_get_iface(const type_t *type)
+{
+ type = type_get_real_type(type);
+ assert(type_get_type(type) == TYPE_DELEGATE);
+ return type->details.delegate.iface;
+}
+
static inline const decl_spec_t *type_pointer_get_ref(const type_t *type)
{
type = type_get_real_type(type);
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index be82342e31a..d55922b72e9 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -442,6 +442,11 @@ struct parameterized_details
type_list_t *params;
};
+struct delegate_details
+{
+ type_t *iface;
+};
+
#define HASHMAX 64
struct namespace {
@@ -472,6 +477,7 @@ enum type_type
TYPE_RUNTIMECLASS,
TYPE_PARAMETERIZED_TYPE,
TYPE_PARAMETER,
+ TYPE_DELEGATE,
};
struct _type_t {
@@ -494,6 +500,7 @@ struct _type_t {
struct alias_details alias;
struct runtimeclass_details runtimeclass;
struct parameterized_details parameterized;
+ struct delegate_details delegate;
} details;
const char *c_name;
unsigned int typestring_offset;
--
2.20.1

View File

@@ -1,206 +0,0 @@
From bb804812bf6bd0e15e3c2474f1ef2c0d24873fac Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 4 Feb 2021 17:19:39 +0100
Subject: [PATCH] widl: Support WinRT parameterized delegate type.
---
include/windows.foundation.idl | 6 +++
tools/widl/parser.y | 6 +++
tools/widl/typetree.c | 73 ++++++++++++++++++++++++++++++----
tools/widl/typetree.h | 2 +
4 files changed, 80 insertions(+), 7 deletions(-)
diff --git a/include/windows.foundation.idl b/include/windows.foundation.idl
index 5f7a49c38e4..9583fa5bcc8 100644
--- a/include/windows.foundation.idl
+++ b/include/windows.foundation.idl
@@ -113,6 +113,12 @@ namespace Windows {
}
#ifdef __WIDL__
+ [
+ contract(Windows.Foundation.FoundationContract, 1.0),
+ uuid(9de1c535-6ae1-11e0-84e1-18a905bcc53f)
+ ]
+ delegate void EventHandler<T>([in] IInspectable *sender, [in] T args);
+
namespace Collections
{
[
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 5c3eae7bf82..d8ab4a24ced 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -1033,6 +1033,12 @@ delegatedef: m_attributes tDELEGATE type ident '(' m_args ')' semicolon_opt
{ $$ = type_delegate_declare($4->name, current_namespace);
$$ = type_delegate_define($$, $1, append_statement(NULL, make_statement_delegate($3, $6)));
}
+ | m_attributes tDELEGATE type ident
+ '<' { push_parameters_namespace($4->name); } type_parameters '>'
+ '(' m_args ')' { pop_parameters_namespace($4->name); } semicolon_opt
+ { $$ = type_parameterized_delegate_declare($4->name, current_namespace, $7);
+ $$ = type_parameterized_delegate_define($$, $1, append_statement(NULL, make_statement_delegate($3, $10)));
+ }
;
required_types:
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
index 08f9a0e0c09..a83e175d288 100644
--- a/tools/widl/typetree.c
+++ b/tools/widl/typetree.c
@@ -142,16 +142,16 @@ static char const *parameterized_type_shorthands[][2] = {
{"Windows_CFoundation_C", "__F"},
};
-static char *format_parameterized_type_c_name(type_t *type, type_list_t *params)
+static char *format_parameterized_type_c_name(type_t *type, type_list_t *params, const char *prefix)
{
size_t len = 0, pos = 0;
char *buf = NULL, *tmp;
type_list_t *entry;
int i, count = 0;
- pos += append_namespaces(&buf, &len, pos, type->namespace, "__x_", "_C", type->name, use_abi_namespace ? "ABI" : NULL);
+ pos += append_namespaces(&buf, &len, pos, type->namespace, "__x_", "_C", "", use_abi_namespace ? "ABI" : NULL);
for (entry = params; entry; entry = entry->next) count++;
- pos += strappend(&buf, &len, pos, "_%d", count);
+ pos += strappend(&buf, &len, pos, "%s%s_%d", prefix, type->name, count);
for (entry = params; entry; entry = entry->next)
{
for (type = entry->type; type->type_type == TYPE_POINTER; type = type_pointer_get_ref_type(type)) {}
@@ -640,12 +640,13 @@ type_t *type_apicontract_define(type_t *apicontract, attr_list_t *attrs)
return apicontract;
}
-static void compute_delegate_iface_names(type_t *delegate)
+static void compute_delegate_iface_names(type_t *delegate, type_t *type, type_list_t *params)
{
type_t *iface = delegate->details.delegate.iface;
iface->namespace = delegate->namespace;
iface->name = strmake("I%s", delegate->name);
- iface->c_name = format_namespace(delegate->namespace, "__x_", "_C", iface->name, use_abi_namespace ? "ABI" : NULL);
+ if (type) iface->c_name = format_parameterized_type_c_name(type, params, "I");
+ else iface->c_name = format_namespace(delegate->namespace, "__x_", "_C", iface->name, use_abi_namespace ? "ABI" : NULL);
}
type_t *type_delegate_declare(char *name, struct namespace *namespace)
@@ -683,7 +684,7 @@ type_t *type_delegate_define(type_t *delegate, attr_list_t *attrs, statement_lis
delegate->details.delegate.iface = iface;
delegate->defined = TRUE;
- compute_delegate_iface_names(delegate);
+ compute_delegate_iface_names(delegate, NULL, NULL);
return delegate;
}
@@ -727,6 +728,46 @@ type_t *type_parameterized_interface_define(type_t *type, attr_list_t *attrs, ty
return type;
}
+type_t *type_parameterized_delegate_declare(char *name, struct namespace *namespace, type_list_t *params)
+{
+ type_t *type = get_type(TYPE_PARAMETERIZED_TYPE, name, namespace, 0);
+ if (type_get_type_detect_alias(type) != TYPE_PARAMETERIZED_TYPE)
+ error_loc("pdelegate %s previously not declared a pdelegate at %s:%d\n",
+ type->name, type->loc_info.input_name, type->loc_info.line_number);
+ type->details.parameterized.type = make_type(TYPE_DELEGATE);
+ type->details.parameterized.params = params;
+ return type;
+}
+
+type_t *type_parameterized_delegate_define(type_t *type, attr_list_t *attrs, statement_list_t *stmts)
+{
+ type_t *iface, *delegate;
+
+ if (type->defined)
+ error_loc("pdelegate %s already defined at %s:%d\n",
+ type->name, type->loc_info.input_name, type->loc_info.line_number);
+
+ type->attrs = check_interface_attrs(type->name, attrs);
+
+ delegate = type->details.parameterized.type;
+ delegate->attrs = type->attrs;
+ delegate->details.delegate.iface = make_type(TYPE_INTERFACE);
+
+ iface = delegate->details.delegate.iface;
+ iface->details.iface = xmalloc(sizeof(*iface->details.iface));
+ iface->details.iface->disp_props = NULL;
+ iface->details.iface->disp_methods = NULL;
+ iface->details.iface->stmts = stmts;
+ iface->details.iface->inherit = find_type("IUnknown", NULL, 0);
+ if (!iface->details.iface->inherit) error_loc("IUnknown is undefined\n");
+ iface->details.iface->disp_inherit = NULL;
+ iface->details.iface->async_iface = NULL;
+ iface->details.iface->requires = NULL;
+
+ type->defined = TRUE;
+ return type;
+}
+
type_t *type_parameterized_type_specialize_partial(type_t *type, type_list_t *params)
{
type_t *new_type = duptype(type, 0);
@@ -907,6 +948,11 @@ static void type_parameterized_interface_specialize(type_t *tmpl, type_t *iface,
iface->details.iface->requires = NULL;
}
+static void type_parameterized_delegate_specialize(type_t *tmpl, type_t *delegate, type_list_t *orig, type_list_t *repl)
+{
+ type_parameterized_interface_specialize(tmpl->details.delegate.iface, delegate->details.delegate.iface, orig, repl);
+}
+
type_t *type_parameterized_type_specialize_declare(type_t *type, type_list_t *params)
{
type_t *tmpl = type->details.parameterized.type;
@@ -915,7 +961,13 @@ type_t *type_parameterized_type_specialize_declare(type_t *type, type_list_t *pa
new_type->namespace = type->namespace;
new_type->name = format_parameterized_type_name(type, params);
reg_type(new_type, new_type->name, new_type->namespace, 0);
- new_type->c_name = format_parameterized_type_c_name(type, params);
+ new_type->c_name = format_parameterized_type_c_name(type, params, "");
+
+ if (new_type->type_type == TYPE_DELEGATE)
+ {
+ new_type->details.delegate.iface = duptype(tmpl->details.delegate.iface, 0);
+ compute_delegate_iface_names(new_type, type, params);
+ }
return new_type;
}
@@ -928,6 +980,8 @@ type_t *type_parameterized_type_specialize_define(type_t *type, type_list_t *par
if (tmpl->type_type == TYPE_INTERFACE)
type_parameterized_interface_specialize(tmpl, iface, orig, params);
+ else if (tmpl->type_type == TYPE_DELEGATE)
+ type_parameterized_delegate_specialize(tmpl, iface, orig, params);
else
{
error_loc("Unsupported parameterized type template %d\n", tmpl->type_type);
@@ -935,6 +989,11 @@ type_t *type_parameterized_type_specialize_define(type_t *type, type_list_t *par
}
iface->defined = TRUE;
+ if (iface->type_type == TYPE_DELEGATE)
+ {
+ iface = iface->details.delegate.iface;
+ iface->defined = TRUE;
+ }
compute_method_indexes(iface);
return iface;
}
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
index 413f1f9e41b..b2592473c8c 100644
--- a/tools/widl/typetree.h
+++ b/tools/widl/typetree.h
@@ -68,6 +68,8 @@ type_t *type_delegate_declare(char *name, struct namespace *namespace);
type_t *type_delegate_define(type_t *delegate, attr_list_t *attrs, statement_list_t *stmts);
type_t *type_parameterized_interface_declare(char *name, struct namespace *namespace, type_list_t *params);
type_t *type_parameterized_interface_define(type_t *type, attr_list_t *attrs, type_t *inherit, statement_list_t *stmts, type_list_t *requires);
+type_t *type_parameterized_delegate_declare(char *name, struct namespace *namespace, type_list_t *params);
+type_t *type_parameterized_delegate_define(type_t *type, attr_list_t *attrs, statement_list_t *stmts);
type_t *type_parameterized_type_specialize_partial(type_t *type, type_list_t *params);
type_t *type_parameterized_type_specialize_declare(type_t *type, type_list_t *params);
type_t *type_parameterized_type_specialize_define(type_t *type, type_list_t *params);
--
2.20.1

View File

@@ -1,249 +0,0 @@
From 4280840f7593bfdcd5d20891640271617d570801 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Tue, 1 Dec 2020 17:44:43 +0100
Subject: [PATCH] widl: Compute signatures for parameterized types.
---
tools/widl/typetree.c | 151 +++++++++++++++++++++++++++++++++++++++++
tools/widl/typetree.h | 10 +++
tools/widl/widltypes.h | 2 +
3 files changed, 163 insertions(+)
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
index a83e175d288..de7f24aeed5 100644
--- a/tools/widl/typetree.c
+++ b/tools/widl/typetree.c
@@ -49,6 +49,7 @@ type_t *make_type(enum type_type type)
t->type_type = type;
t->attrs = NULL;
t->c_name = NULL;
+ t->signature = NULL;
memset(&t->details, 0, sizeof(t->details));
t->typestring_offset = 0;
t->ptrdesc = 0;
@@ -110,6 +111,125 @@ static size_t append_namespaces(char **buf, size_t *len, size_t pos, struct name
return n;
}
+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)
+{
+ var_t *var;
+ size_t n = 0;
+ if (!var_list) n += strappend(buf, len, pos + n, ";");
+ else LIST_FOR_EACH_ENTRY(var, var_list, var_t, entry)
+ {
+ n += strappend(buf, len, pos + n, ";");
+ n += append_type_signature(buf, len, pos + n, var->declspec.type);
+ }
+ return n;
+}
+
+static size_t append_type_signature(char **buf, size_t *len, size_t pos, type_t *type)
+{
+ const GUID *uuid;
+ size_t n = 0;
+ if (!type) return 0;
+ switch (type->type_type)
+ {
+ case TYPE_INTERFACE:
+ if (type->signature) n += strappend(buf, len, pos + n, "%s", type->signature);
+ else
+ {
+ uuid = type_get_uuid(type);
+ n += strappend(buf, len, pos + n, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
+ uuid->Data1, uuid->Data2, uuid->Data3,
+ uuid->Data4[0], uuid->Data4[1], uuid->Data4[2], uuid->Data4[3],
+ uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], uuid->Data4[7]);
+ }
+ return n;
+ case TYPE_DELEGATE:
+ n += strappend(buf, len, pos + n, "delegate(");
+ n += append_type_signature(buf, len, pos + n, type_delegate_get_iface(type));
+ n += strappend(buf, len, pos + n, ")");
+ return n;
+ case TYPE_RUNTIMECLASS:
+ 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 += strappend(buf, len, pos + n, ")");
+ return n;
+ case TYPE_POINTER:
+ n += append_type_signature(buf, len, pos + n, type->details.pointer.ref.type);
+ return n;
+ case TYPE_ALIAS:
+ if (!strcmp(type->name, "boolean")) n += strappend(buf, len, pos + n, "b1");
+ else n += append_type_signature(buf, len, pos + n, type->details.alias.aliasee.type);
+ return n;
+ case TYPE_STRUCT:
+ n += strappend(buf, len, pos + n, "struct(");
+ n += append_namespaces(buf, len, pos + n, type->namespace, "", ".", type->name, NULL);
+ n += append_var_list_signature(buf, len, pos + n, type->details.structure->fields);
+ n += strappend(buf, len, pos + n, ")");
+ return n;
+ case TYPE_BASIC:
+ switch (type_basic_get_type(type))
+ {
+ case TYPE_BASIC_INT:
+ case TYPE_BASIC_INT32:
+ n += strappend(buf, len, pos + n, type_basic_get_sign(type) < 0 ? "i4" : "u4");
+ return n;
+ case TYPE_BASIC_INT64:
+ n += strappend(buf, len, pos + n, type_basic_get_sign(type) < 0 ? "i8" : "u8");
+ return n;
+ case TYPE_BASIC_INT8:
+ assert(type_basic_get_sign(type) >= 0); /* signature string for signed char isn't specified */
+ n += strappend(buf, len, pos + n, "u1");
+ return n;
+ case TYPE_BASIC_FLOAT:
+ n += strappend(buf, len, pos + n, "f4");
+ return n;
+ case TYPE_BASIC_DOUBLE:
+ n += strappend(buf, len, pos + n, "f8");
+ return n;
+ case TYPE_BASIC_INT16:
+ case TYPE_BASIC_INT3264:
+ case TYPE_BASIC_LONG:
+ case TYPE_BASIC_CHAR:
+ case TYPE_BASIC_HYPER:
+ case TYPE_BASIC_BYTE:
+ case TYPE_BASIC_WCHAR:
+ case TYPE_BASIC_ERROR_STATUS_T:
+ case TYPE_BASIC_HANDLE:
+ error("basic type '%d' signature not implemented\n", type_basic_get_type(type));
+ assert(0); /* FIXME: implement when needed */
+ break;
+ }
+ case TYPE_ENUM:
+ n += strappend(buf, len, pos + n, "enum(");
+ n += append_namespaces(buf, len, pos + n, type->namespace, "", ".", type->name, NULL);
+ if (is_attr(type->attrs, ATTR_FLAGS)) n += strappend(buf, len, pos + n, ";u4");
+ else n += strappend(buf, len, pos + n, ";i4");
+ n += strappend(buf, len, pos + n, ")");
+ return n;
+ case TYPE_ARRAY:
+ case TYPE_ENCAPSULATED_UNION:
+ case TYPE_UNION:
+ case TYPE_COCLASS:
+ error("type '%d' signature for '%s' not implemented\n", type->type_type, type->name);
+ assert(0); /* FIXME: implement when needed */
+ break;
+ case TYPE_VOID:
+ case TYPE_FUNCTION:
+ case TYPE_BITFIELD:
+ case TYPE_MODULE:
+ case TYPE_PARAMETERIZED_TYPE:
+ case TYPE_PARAMETER:
+ case TYPE_APICONTRACT:
+ assert(0); /* should not be there */
+ break;
+ }
+
+ return n;
+}
+
char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix, const char *abi_prefix)
{
size_t len = 0;
@@ -137,6 +257,14 @@ char *format_parameterized_type_name(type_t *type, type_list_t *params)
return buf;
}
+char *format_type_signature(type_t *type)
+{
+ size_t len = 0;
+ char *buf = NULL;
+ append_type_signature(&buf, &len, 0, type);
+ return buf;
+}
+
static char const *parameterized_type_shorthands[][2] = {
{"Windows_CFoundation_CCollections_C", "__F"},
{"Windows_CFoundation_C", "__F"},
@@ -172,6 +300,27 @@ static char *format_parameterized_type_c_name(type_t *type, type_list_t *params,
return buf;
}
+static char *format_parameterized_type_signature(type_t *type, type_list_t *params)
+{
+ size_t len = 0, pos = 0;
+ char *buf = NULL;
+ type_list_t *entry;
+
+ const GUID *uuid = type_get_uuid(type);
+ pos += strappend(&buf, &len, pos, "pinterface({%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
+ uuid->Data1, uuid->Data2, uuid->Data3,
+ uuid->Data4[0], uuid->Data4[1], uuid->Data4[2], uuid->Data4[3],
+ uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], uuid->Data4[7]);
+ for (entry = params; entry; entry = entry->next)
+ {
+ pos += strappend(&buf, &len, pos, ";");
+ pos += append_type_signature(&buf, &len, pos, entry->type);
+ }
+ pos += strappend(&buf, &len, pos, ")");
+
+ return buf;
+}
+
type_t *type_new_function(var_list_t *args)
{
var_t *arg;
@@ -988,10 +1137,12 @@ type_t *type_parameterized_type_specialize_define(type_t *type, type_list_t *par
return NULL;
}
+ iface->signature = format_parameterized_type_signature(type, params);
iface->defined = TRUE;
if (iface->type_type == TYPE_DELEGATE)
{
iface = iface->details.delegate.iface;
+ iface->signature = format_parameterized_type_signature(type, params);
iface->defined = TRUE;
}
compute_method_indexes(iface);
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
index b2592473c8c..9697c4a639f 100644
--- a/tools/widl/typetree.h
+++ b/tools/widl/typetree.h
@@ -95,6 +95,16 @@ static inline enum type_type type_get_type(const type_t *type)
return type_get_type_detect_alias(type_get_real_type(type));
}
+static inline const GUID *type_get_uuid(const type_t *type)
+{
+ static const GUID empty;
+ attr_t *attr;
+ LIST_FOR_EACH_ENTRY(attr, type->attrs, attr_t, entry)
+ if (attr->type == ATTR_UUID) return attr->u.pval;
+ error("type '%s' uuid not found\n", type->name);
+ return &empty;
+}
+
static inline enum type_basic_type type_basic_get_type(const type_t *type)
{
type = type_get_real_type(type);
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index d55922b72e9..a1fce0ef87d 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -503,6 +503,7 @@ struct _type_t {
struct delegate_details delegate;
} details;
const char *c_name;
+ const char *signature;
unsigned int typestring_offset;
unsigned int ptrdesc; /* used for complex structs */
int typelib_idx;
@@ -658,6 +659,7 @@ void init_loc_info(loc_info_t *);
char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix,
const char *abi_prefix);
char *format_parameterized_type_name(type_t *type, type_list_t *params);
+char *format_type_signature(type_t *type);
static inline enum type_type type_get_type_detect_alias(const type_t *type)
{
--
2.20.1

View File

@@ -1,317 +0,0 @@
From 9da07acdf882567f4f1e6c3fd017af96ba11348e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Mon, 28 Sep 2020 17:00:41 +0200
Subject: [PATCH] widl: Compute uuids for parameterized types.
---
tools/widl/hash.c | 178 ++++++++++++++++++++++++++++++++++++++++++
tools/widl/hash.h | 14 ++++
tools/widl/typetree.c | 53 +++++++++++++
tools/widl/typetree.h | 2 +-
4 files changed, 246 insertions(+), 1 deletion(-)
diff --git a/tools/widl/hash.c b/tools/widl/hash.c
index 15ec88001d6..df6133866e0 100644
--- a/tools/widl/hash.c
+++ b/tools/widl/hash.c
@@ -639,3 +639,181 @@ unsigned int lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr)
return nHiWord | nLoWord;
}
+
+/* SHA1 algorithm
+ *
+ * Based on public domain SHA code by Steve Reid <steve@edmweb.com>
+ */
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+/* FIXME: This definition of DWORD2BE is little endian specific! */
+#define DWORD2BE(x) (((x) >> 24) & 0xff) | (((x) >> 8) & 0xff00) | (((x) << 8) & 0xff0000) | (((x) << 24) & 0xff000000);
+/* FIXME: This definition of blk0 is little endian specific! */
+#define blk0(i) (Block[i] = (rol(Block[i],24)&0xFF00FF00)|(rol(Block[i],8)&0x00FF00FF))
+#define blk1(i) (Block[i&15] = rol(Block[(i+13)&15]^Block[(i+8)&15]^Block[(i+2)&15]^Block[i&15],1))
+#define f1(x,y,z) (z^(x&(y^z)))
+#define f2(x,y,z) (x^y^z)
+#define f3(x,y,z) ((x&y)|(z&(x|y)))
+#define f4(x,y,z) (x^y^z)
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v,w,x,y,z,i) z+=f1(w,x,y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R1(v,w,x,y,z,i) z+=f1(w,x,y)+blk1(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R2(v,w,x,y,z,i) z+=f2(w,x,y)+blk1(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
+#define R3(v,w,x,y,z,i) z+=f3(w,x,y)+blk1(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
+#define R4(v,w,x,y,z,i) z+=f4(w,x,y)+blk1(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
+
+/* Hash a single 512-bit block. This is the core of the algorithm. */
+static void SHA1Transform(ULONG State[5], UCHAR Buffer[64])
+{
+ ULONG a, b, c, d, e;
+ ULONG *Block;
+
+ Block = (ULONG*)Buffer;
+
+ /* Copy Context->State[] to working variables */
+ a = State[0];
+ b = State[1];
+ c = State[2];
+ d = State[3];
+ e = State[4];
+
+ /* 4 rounds of 20 operations each. Loop unrolled. */
+ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+ R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+ R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+ R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+ R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+ R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+ R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+ R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+ R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+ R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+ R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+ R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+ R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+ R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+ R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+ R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+ R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+ R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+ R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+ R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+
+ /* Add the working variables back into Context->State[] */
+ State[0] += a;
+ State[1] += b;
+ State[2] += c;
+ State[3] += d;
+ State[4] += e;
+
+ /* Wipe variables */
+ a = b = c = d = e = 0;
+}
+
+
+/******************************************************************************
+ * A_SHAInit (ntdll.@)
+ *
+ * Initialize a SHA context structure.
+ *
+ * PARAMS
+ * Context [O] SHA context
+ *
+ * RETURNS
+ * Nothing
+ */
+void A_SHAInit(SHA_CTX *Context)
+{
+ /* SHA1 initialization constants */
+ Context->State[0] = 0x67452301;
+ Context->State[1] = 0xEFCDAB89;
+ Context->State[2] = 0x98BADCFE;
+ Context->State[3] = 0x10325476;
+ Context->State[4] = 0xC3D2E1F0;
+ Context->Count[0] =
+ Context->Count[1] = 0;
+}
+
+/******************************************************************************
+ * A_SHAUpdate (ntdll.@)
+ *
+ * Update a SHA context with a hashed data from supplied buffer.
+ *
+ * PARAMS
+ * Context [O] SHA context
+ * Buffer [I] hashed data
+ * BufferSize [I] hashed data size
+ *
+ * RETURNS
+ * Nothing
+ */
+void A_SHAUpdate(SHA_CTX *Context, const unsigned char *Buffer, UINT BufferSize)
+{
+ ULONG BufferContentSize;
+
+ BufferContentSize = Context->Count[1] & 63;
+ Context->Count[1] += BufferSize;
+ if (Context->Count[1] < BufferSize)
+ Context->Count[0]++;
+ Context->Count[0] += (BufferSize >> 29);
+
+ if (BufferContentSize + BufferSize < 64)
+ {
+ RtlCopyMemory(&Context->Buffer[BufferContentSize], Buffer,
+ BufferSize);
+ }
+ else
+ {
+ while (BufferContentSize + BufferSize >= 64)
+ {
+ RtlCopyMemory(Context->Buffer + BufferContentSize, Buffer,
+ 64 - BufferContentSize);
+ Buffer += 64 - BufferContentSize;
+ BufferSize -= 64 - BufferContentSize;
+ SHA1Transform(Context->State, Context->Buffer);
+ BufferContentSize = 0;
+ }
+ RtlCopyMemory(Context->Buffer + BufferContentSize, Buffer, BufferSize);
+ }
+}
+
+/******************************************************************************
+ * A_SHAFinal (ntdll.@)
+ *
+ * Finalize SHA context and return the resulting hash.
+ *
+ * PARAMS
+ * Context [I/O] SHA context
+ * Result [O] resulting hash
+ *
+ * RETURNS
+ * Nothing
+ */
+void A_SHAFinal(SHA_CTX *Context, PULONG Result)
+{
+ INT Pad, Index;
+ UCHAR Buffer[72];
+ ULONG *Count;
+ ULONG BufferContentSize, LengthHi, LengthLo;
+
+ BufferContentSize = Context->Count[1] & 63;
+ if (BufferContentSize >= 56)
+ Pad = 56 + 64 - BufferContentSize;
+ else
+ Pad = 56 - BufferContentSize;
+
+ LengthHi = (Context->Count[0] << 3) | (Context->Count[1] >> (32 - 3));
+ LengthLo = (Context->Count[1] << 3);
+
+ RtlZeroMemory(Buffer + 1, Pad - 1);
+ Buffer[0] = 0x80;
+ Count = (ULONG*)(Buffer + Pad);
+ Count[0] = DWORD2BE(LengthHi);
+ Count[1] = DWORD2BE(LengthLo);
+ A_SHAUpdate(Context, Buffer, Pad + 8);
+
+ for (Index = 0; Index < 5; Index++)
+ Result[Index] = DWORD2BE(Context->State[Index]);
+
+ A_SHAInit(Context);
+}
diff --git a/tools/widl/hash.h b/tools/widl/hash.h
index 3c2fd2914bf..208b193ac87 100644
--- a/tools/widl/hash.h
+++ b/tools/widl/hash.h
@@ -22,6 +22,20 @@
#ifndef __WIDL_HASH_H
#define __WIDL_HASH_H
+#include "windef.h"
+
extern unsigned int lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr);
+typedef struct
+{
+ ULONG Unknown[6];
+ ULONG State[5];
+ ULONG Count[2];
+ UCHAR Buffer[64];
+} SHA_CTX;
+
+VOID A_SHAInit(SHA_CTX *ctx);
+VOID A_SHAUpdate(SHA_CTX *ctx, const UCHAR *buffer, UINT size);
+VOID A_SHAFinal(SHA_CTX *ctx, PULONG result);
+
#endif
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
index de7f24aeed5..ae11a7cb171 100644
--- a/tools/widl/typetree.c
+++ b/tools/widl/typetree.c
@@ -29,6 +29,7 @@
#include "parser.h"
#include "typetree.h"
#include "header.h"
+#include "hash.h"
type_t *duptype(type_t *t, int dupname)
{
@@ -1121,6 +1122,57 @@ type_t *type_parameterized_type_specialize_declare(type_t *type, type_list_t *pa
return new_type;
}
+static void compute_interface_signature_uuid(type_t *iface)
+{
+ static unsigned char const wrt_pinterface_namespace[] = {0x11,0xf4,0x7a,0xd5,0x7b,0x73,0x42,0xc0,0xab,0xae,0x87,0x8b,0x1e,0x16,0xad,0xee};
+ static const int version = 5;
+ unsigned char hash[20];
+ SHA_CTX sha_ctx;
+ attr_t *attr;
+ GUID *uuid;
+
+ if (!iface->attrs)
+ {
+ iface->attrs = xmalloc( sizeof(*iface->attrs) );
+ list_init( iface->attrs );
+ }
+
+ LIST_FOR_EACH_ENTRY(attr, iface->attrs, attr_t, entry)
+ if (attr->type == ATTR_UUID) break;
+
+ if (&attr->entry == iface->attrs)
+ {
+ attr = xmalloc( sizeof(*attr) );
+ attr->type = ATTR_UUID;
+ attr->u.pval = xmalloc( sizeof(GUID) );
+ list_add_tail( iface->attrs, &attr->entry );
+ }
+
+ A_SHAInit(&sha_ctx);
+ A_SHAUpdate(&sha_ctx, wrt_pinterface_namespace, sizeof(wrt_pinterface_namespace));
+ A_SHAUpdate(&sha_ctx, (const UCHAR *)iface->signature, strlen(iface->signature));
+ A_SHAFinal(&sha_ctx, (ULONG *)hash);
+
+ /* https://tools.ietf.org/html/rfc4122:
+
+ * Set the four most significant bits (bits 12 through 15) of the
+ time_hi_and_version field to the appropriate 4-bit version number
+ from Section 4.1.3.
+
+ * Set the two most significant bits (bits 6 and 7) of the
+ clock_seq_hi_and_reserved to zero and one, respectively.
+ */
+
+ hash[6] = ((hash[6] & 0x0f) | (version << 4));
+ hash[8] = ((hash[8] & 0x3f) | 0x80);
+
+ uuid = attr->u.pval;
+ uuid->Data1 = ((DWORD)hash[0] << 24)|((DWORD)hash[1] << 16)|((DWORD)hash[2] << 8)|(DWORD)hash[3];
+ uuid->Data2 = ((WORD)hash[4] << 8)|(WORD)hash[5];
+ uuid->Data3 = ((WORD)hash[6] << 8)|(WORD)hash[7];
+ memcpy(&uuid->Data4, hash + 8, sizeof(*uuid) - offsetof(GUID, Data4));
+}
+
type_t *type_parameterized_type_specialize_define(type_t *type, type_list_t *params)
{
type_list_t *orig = type->details.parameterized.params;
@@ -1145,6 +1197,7 @@ type_t *type_parameterized_type_specialize_define(type_t *type, type_list_t *par
iface->signature = format_parameterized_type_signature(type, params);
iface->defined = TRUE;
}
+ compute_interface_signature_uuid(iface);
compute_method_indexes(iface);
return iface;
}
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
index 9697c4a639f..db43a9aa456 100644
--- a/tools/widl/typetree.h
+++ b/tools/widl/typetree.h
@@ -99,7 +99,7 @@ static inline const GUID *type_get_uuid(const type_t *type)
{
static const GUID empty;
attr_t *attr;
- LIST_FOR_EACH_ENTRY(attr, type->attrs, attr_t, entry)
+ if (type->attrs) LIST_FOR_EACH_ENTRY(attr, type->attrs, attr_t, entry)
if (attr->type == ATTR_UUID) return attr->u.pval;
error("type '%s' uuid not found\n", type->name);
return &empty;
--
2.20.1