Rémi Bernon : widl: Compute signatures for parameterized types.
Alexandre Julliard
julliard at winehq.org
Thu Feb 18 16:06:07 CST 2021
Module: wine
Branch: master
Commit: c5413e12587d0e31d1db2f1c5774f6345e912627
URL: https://source.winehq.org/git/wine.git/?a=commit;h=c5413e12587d0e31d1db2f1c5774f6345e912627
Author: Rémi Bernon <rbernon at codeweavers.com>
Date: Thu Feb 18 10:39:01 2021 +0100
widl: Compute signatures for parameterized types.
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Jacek Caban<jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
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;
More information about the wine-cvs
mailing list