Module: wine Branch: master Commit: bc6c2eb907e90cf29abcedb77f4bb840abea0231 URL: https://source.winehq.org/git/wine.git/?a=commit;h=bc6c2eb907e90cf29abcedb77...
Author: Jacek Caban jacek@codeweavers.com Date: Fri Aug 24 12:12:02 2018 +0200
widl: Allow defaultvalue() attribute on any pointer type.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
tools/widl/write_msft.c | 130 +++++++++++++++++++++--------------------------- 1 file changed, 56 insertions(+), 74 deletions(-)
diff --git a/tools/widl/write_msft.c b/tools/widl/write_msft.c index 98a788c..913e1a6 100644 --- a/tools/widl/write_msft.c +++ b/tools/widl/write_msft.c @@ -1160,39 +1160,17 @@ static unsigned int get_ulong_val(unsigned int val, int vt)
static void write_int_value(msft_typelib_t *typelib, int *out, int vt, int value) { - switch(vt) { - case VT_I2: - case VT_I4: - case VT_R4: - case VT_BOOL: - case VT_I1: - case VT_UI1: - case VT_UI2: - case VT_UI4: - case VT_INT: - case VT_UINT: - case VT_HRESULT: - case VT_PTR: - case VT_UNKNOWN: - case VT_DISPATCH: - { - const unsigned int lv = get_ulong_val(value, vt); - if((lv & 0x3ffffff) == lv) { - *out = 0x80000000; - *out |= vt << 26; - *out |= lv; - } else { - int offset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATA, 8, 0); - *((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset]) = vt; - memcpy(&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+2], &value, 4); - *((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+6]) = 0x5757; - *out = offset; - } - return; - } - - default: - warning("can't write value of type %d yet\n", vt); + const unsigned int lv = get_ulong_val(value, vt); + if ((lv & 0x3ffffff) == lv) { + *out = 0x80000000; + *out |= vt << 26; + *out |= lv; + } else { + int offset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATA, 8, 0); + *((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset]) = vt; + memcpy(&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+2], &value, 4); + *((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+6]) = 0x5757; + *out = offset; } }
@@ -1211,6 +1189,50 @@ static void write_string_value(msft_typelib_t *typelib, int *out, const char *va *out = offset; }
+static void write_default_value(msft_typelib_t *typelib, type_t *type, expr_t *expr, int *out) +{ + int vt; + + if (expr->type == EXPR_STRLIT || expr->type == EXPR_WSTRLIT) { + if (get_type_vt(type) != VT_BSTR) + error("string default value applied to non-string type\n"); + chat("default value '%s'\n", expr->u.sval); + write_string_value(typelib, out, expr->u.sval); + return; + } + + if (type_get_type(type) == TYPE_ENUM) { + vt = VT_I4; + } else if (is_ptr(type)) { + vt = get_type_vt(type_pointer_get_ref(type)); + if (vt == VT_USERDEFINED) + vt = VT_I4; + if (expr->cval) + warning("non-null pointer default value\n"); + } else { + vt = get_type_vt(type); + switch(vt) { + case VT_I2: + case VT_I4: + case VT_R4: + case VT_BOOL: + case VT_I1: + case VT_UI1: + case VT_UI2: + case VT_UI4: + case VT_INT: + case VT_UINT: + case VT_HRESULT: + break; + default: + warning("can't write value of type %d yet\n", vt); + return; + } + } + + write_int_value(typelib, out, vt, expr->cval); +} + static HRESULT set_custdata(msft_typelib_t *typelib, REFGUID guid, int vt, const void *value, int *offset) { @@ -1242,33 +1264,6 @@ static HRESULT set_custdata(msft_typelib_t *typelib, REFGUID guid, return S_OK; }
-/* It's possible to have a default value for pointer arguments too. - In this case default value has a referenced type, e.g. - 'LONG*' argument gets VT_I4, 'DOUBLE*' - VT_R8. IUnknown* and IDispatch* - are recognised too and stored as VT_UNKNOWN and VT_DISPATCH. - But IUnknown/IDispatch arguments can only have default value of 0 - (or expression that resolves to zero) while other pointers can have - any default value. */ -static int get_defaultvalue_vt(type_t *type) -{ - int vt; - if (type_get_type(type) == TYPE_ENUM) - vt = VT_I4; - else - { - vt = get_type_vt(type); - if (vt == VT_PTR && is_ptr(type)) { - vt = get_type_vt(type_pointer_get_ref(type)); - /* The only acceptable value for pointers to non-basic types - is NULL, it's stored as VT_I4 for both 32 and 64 bit typelibs. */ - if (vt == VT_USERDEFINED) - vt = VT_I4; - } - } - - return vt; -} - static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index) { int offset, name_offset; @@ -1492,21 +1487,8 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index) switch(attr->type) { case ATTR_DEFAULTVALUE: { - int vt; - expr_t *expr = (expr_t *)attr->u.pval; - vt = get_defaultvalue_vt(arg->type); paramflags |= 0x30; /* PARAMFLAG_FHASDEFAULT | PARAMFLAG_FOPT */ - if (expr->type == EXPR_STRLIT || expr->type == EXPR_WSTRLIT) - { - if (vt != VT_BSTR) error("string default value applied to non-string type\n"); - chat("default value '%s'\n", expr->u.sval); - write_string_value(typeinfo->typelib, defaultdata, expr->u.sval); - } - else - { - chat("default value %d\n", expr->cval); - write_int_value(typeinfo->typelib, defaultdata, vt, expr->cval); - } + write_default_value(typeinfo->typelib, arg->type, (expr_t *)attr->u.pval, defaultdata); break; } case ATTR_IN: