From c5413e12587d0e31d1db2f1c5774f6345e912627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Bernon?= Date: Thu, 18 Feb 2021 10:39:01 +0100 Subject: [PATCH] widl: Compute signatures for parameterized types. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RĂ©mi Bernon Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- tools/widl/typetree.c | 149 +++++++++++++++++++++++++++++++++++++++++ tools/widl/widltypes.h | 1 + 2 files changed, 150 insertions(+) diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c index 0a63b7ebf7f..3db88945058 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,128 @@ 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 + { + if (!(uuid = get_attrp(type->attrs, ATTR_UUID))) + error_loc_info(&type->loc_info, "cannot compute type signature, no uuid found for type %s.\n", type->name); + + 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_loc_info(&type->loc_info, "unimplemented type signature for basic type %d.\n", type_basic_get_type(type)); + 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: + case TYPE_VOID: + case TYPE_FUNCTION: + case TYPE_BITFIELD: + case TYPE_MODULE: + case TYPE_APICONTRACT: + error_loc_info(&type->loc_info, "unimplemented type signature for type %s of type %d.\n", type->name, type->type_type); + break; + case TYPE_PARAMETERIZED_TYPE: + case TYPE_PARAMETER: + 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; @@ -171,6 +294,30 @@ static char *format_parameterized_type_c_name(type_t *type, typeref_list_t *para return buf; } +static char *format_parameterized_type_signature(type_t *type, typeref_list_t *params) +{ + size_t len = 0, pos = 0; + char *buf = NULL; + typeref_t *ref; + const GUID *uuid; + + if (!(uuid = get_attrp(type->attrs, ATTR_UUID))) + error_loc_info(&type->loc_info, "cannot compute type signature, no uuid found for type %s.\n", type->name); + + 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]); + if (params) LIST_FOR_EACH_ENTRY(ref, params, typeref_t, entry) + { + pos += strappend(&buf, &len, pos, ";"); + pos += append_type_signature(&buf, &len, pos, ref->type); + } + pos += strappend(&buf, &len, pos, ")"); + + return buf; +} + type_t *type_new_function(var_list_t *args) { var_t *arg; @@ -1019,10 +1166,12 @@ 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", iface->name, iface->loc_info.input_name, iface->loc_info.line_number); + iface->signature = format_parameterized_type_signature(type, repl); iface->defined = TRUE; if (iface->type_type == TYPE_DELEGATE) { iface = iface->details.delegate.iface; + iface->signature = format_parameterized_type_signature(type, repl); iface->defined = TRUE; } compute_method_indexes(iface); diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index e07aeddf511..e01bd122b45 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -502,6 +502,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;