widl-SLTG_Typelib_Support: Add support for function parameter flags to SLTG typelib generator.

This commit is contained in:
Sebastian Lackner 2016-01-25 21:34:35 +01:00
parent cd8442e4c4
commit 8981e5a344
2 changed files with 147 additions and 0 deletions

View File

@ -6027,6 +6027,7 @@ if test "$enable_widl_SLTG_Typelib_Support" -eq 1; then
patch_apply widl-SLTG_Typelib_Support/0019-widl-Avoid-relying-on-side-effects-when-marking-func.patch
patch_apply widl-SLTG_Typelib_Support/0020-widl-Set-the-lowest-bit-in-the-param-name-to-indicat.patch
patch_apply widl-SLTG_Typelib_Support/0021-oleaut32-Fix-logic-for-deciding-whether-type-descrip.patch
patch_apply widl-SLTG_Typelib_Support/0022-widl-Add-support-for-function-parameter-flags-to-SLT.patch
(
echo '+ { "Dmitry Timoshkov", "widl: Add initial implementation of SLTG typelib generator.", 1 },';
echo '+ { "Dmitry Timoshkov", "widl: Add support for structures.", 1 },';
@ -6049,6 +6050,7 @@ if test "$enable_widl_SLTG_Typelib_Support" -eq 1; then
echo '+ { "Dmitry Timoshkov", "widl: Avoid relying on side effects when marking function index as the last one.", 1 },';
echo '+ { "Dmitry Timoshkov", "widl: Set the lowest bit in the param name to indicate whether type description follows the name.", 1 },';
echo '+ { "Dmitry Timoshkov", "oleaut32: Fix logic for deciding whether type description follows the name.", 2 },';
echo '+ { "Dmitry Timoshkov", "widl: Add support for function parameter flags to SLTG typelib generator.", 1 },';
) >> "$patchlist"
fi

View File

@ -0,0 +1,145 @@
From 95352b40a973bc72e3cd32e1a02b6842f15deea9 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Mon, 25 Jan 2016 15:26:12 +0800
Subject: widl: Add support for function parameter flags to SLTG typelib
generator.
This makes stdole32.tlb generated by widl have proper [in,out,retval]
parameter flags.
---
tools/widl/write_sltg.c | 70 ++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 60 insertions(+), 10 deletions(-)
diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c
index 2ec1770..3cb137c 100644
--- a/tools/widl/write_sltg.c
+++ b/tools/widl/write_sltg.c
@@ -794,8 +794,8 @@ static int local_href(struct sltg_hrefmap *hrefmap, int typelib_href)
return href << 2;
}
-static short write_var_desc(struct sltg_typelib *typelib, struct sltg_data *data, type_t *type, short flags,
- short base_offset, int *size_instance, struct sltg_hrefmap *hrefmap)
+static short write_var_desc(struct sltg_typelib *typelib, struct sltg_data *data, type_t *type, short param_flags,
+ short flags, short base_offset, int *size_instance, struct sltg_hrefmap *hrefmap)
{
short vt, vt_flags, desc_offset;
@@ -887,19 +887,20 @@ static short write_var_desc(struct sltg_typelib *typelib, struct sltg_data *data
if (is_ptr(ref))
{
- chat("write_var_desc: vt VT_PTR | 0x0400\n");
- vt = VT_PTR | 0x0400;
+ chat("write_var_desc: vt VT_PTR | 0x0400 | %04x\n", param_flags);
+ vt = VT_PTR | 0x0400 | param_flags;
+ param_flags = 0;
append_data(data, &vt, sizeof(vt));
- write_var_desc(typelib, data, ref, 0, base_offset, size_instance, hrefmap);
+ write_var_desc(typelib, data, ref, param_flags, 0, base_offset, size_instance, hrefmap);
}
else
- write_var_desc(typelib, data, ref, 0x0e00, base_offset, size_instance, hrefmap);
+ write_var_desc(typelib, data, ref, param_flags, 0x0e00, base_offset, size_instance, hrefmap);
return desc_offset;
}
chat("write_var_desc: vt %d, flags %04x\n", vt, flags);
- vt_flags = vt | flags;
+ vt_flags = vt | flags | param_flags;
append_data(data, &vt_flags, sizeof(vt_flags));
if (vt == VT_USERDEFINED)
@@ -994,7 +995,8 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, type_t *type)
init_sltg_data(&var_data[i]);
base_offset = var_data_size + (i + 1) * sizeof(struct sltg_variable);
- type_desc_offset[i] = write_var_desc(typelib, &var_data[i], var->type, 0, base_offset, &size_instance, &hrefmap);
+ type_desc_offset[i] = write_var_desc(typelib, &var_data[i], var->type, 0, 0,
+ base_offset, &size_instance, &hrefmap);
dump_var_desc(var_data[i].data, var_data[i].size);
if (var_data[i].size > sizeof(short))
@@ -1177,6 +1179,52 @@ static int get_func_flags(const var_t *func, int *dispid, int *invokekind, int *
return flags;
}
+static int get_param_flags(const var_t *param)
+{
+ const attr_t *attr;
+ int flags, in, out;
+
+ if (!param->attrs) return 0;
+
+ flags = 0;
+ in = out = 0;
+
+ LIST_FOR_EACH_ENTRY(attr, param->attrs, const attr_t, entry)
+ {
+ switch(attr->type)
+ {
+ case ATTR_IN:
+ in++;
+ break;
+ case ATTR_OUT:
+ out++;
+ break;
+ case ATTR_PARAMLCID:
+ flags |= 0x2000;
+ break;
+ case ATTR_RETVAL:
+ flags |= 0x80;
+ break;
+ default:
+ chat("unhandled param attr %d\n", attr->type);
+ break;
+ }
+ }
+
+ if (out)
+ {
+ if (in)
+ flags |= 0x8000;
+ else
+ flags |= 0x4000;
+ }
+ else if (!in)
+ flags |= 0xc000;
+
+ return flags;
+}
+
+
static int add_func_desc(struct sltg_typelib *typelib, struct sltg_data *data, var_t *func,
int idx, int dispid, short base_offset, struct sltg_hrefmap *hrefmap)
{
@@ -1194,7 +1242,7 @@ static int add_func_desc(struct sltg_typelib *typelib, struct sltg_data *data, v
init_sltg_data(&ret_data);
ret_desc_offset = write_var_desc(typelib, &ret_data, type_function_get_rettype(func->type),
- 0, base_offset, NULL, hrefmap);
+ 0, 0, base_offset, NULL, hrefmap);
dump_var_desc(ret_data.data, ret_data.size);
arg_data_size = 0;
@@ -1220,13 +1268,15 @@ static int add_func_desc(struct sltg_typelib *typelib, struct sltg_data *data, v
LIST_FOR_EACH_ENTRY(arg, type_get_function_args(func->type), const var_t, entry)
{
const attr_t *attr;
+ short param_flags = get_param_flags(arg);
chat("add_func_desc: arg[%d] %p (%s), type %p (%s)\n",
i, arg, arg->name, arg->type, arg->type->name);
init_sltg_data(&arg_data[i]);
- arg_desc_offset[i] = write_var_desc(typelib, &arg_data[i], arg->type, 0, arg_offset, NULL, hrefmap);
+ arg_desc_offset[i] = write_var_desc(typelib, &arg_data[i], arg->type, param_flags, 0,
+ arg_offset, NULL, hrefmap);
dump_var_desc(arg_data[i].data, arg_data[i].size);
if (arg_data[i].size > sizeof(short))
--
2.6.4