Signed-off-by: Kevin Puetz PuetzKevinA@JohnDeere.com --- resend (no changes) because I submitted too soon after today's commits.
These two continue after 434a6444 and Marvin hadn't updated HEAD yet, so the patch did not apply cleanly. Resending to get testbot results.
--- dlls/oleaut32/tests/typelib.c | 61 +++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 6 deletions(-)
diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c index 9c341b4df8..5f1851aabf 100644 --- a/dlls/oleaut32/tests/typelib.c +++ b/dlls/oleaut32/tests/typelib.c @@ -4345,13 +4345,14 @@ static void test_dump_typelib(const WCHAR *name) ITypeLib *lib; int count; int i; + HREFTYPE hRefType = 0;
OLE_CHECK(LoadTypeLib(name, &lib));
printf("/*** Autogenerated data. Do not edit, change the generator above instead. ***/\n");
count = ITypeLib_GetTypeInfoCount(lib); - for (i = 0; i < count; i++) + for (i = 0; i < count;) { TYPEATTR *attr; BSTR name; @@ -4363,6 +4364,12 @@ static void test_dump_typelib(const WCHAR *name) " "%s",\n", dump_string(name));
OLE_CHECK(ITypeLib_GetTypeInfo(lib, i, &info)); + if(hRefType) { + ITypeInfo *refInfo; + OLE_CHECK(ITypeInfo_GetRefTypeInfo(info, hRefType, &refInfo)); + ITypeInfo_Release(info); + info = refInfo; + } OLE_CHECK(ITypeInfo_GetTypeAttr(info, &attr));
printf(" "%s",\n", wine_dbgstr_guid(&attr->guid)); @@ -4446,6 +4453,14 @@ static void test_dump_typelib(const WCHAR *name) if (attr->cVars) printf(" },\n");
printf("},\n"); + if ((attr->typekind == TKIND_DISPATCH) && (attr->wTypeFlags & TYPEFLAG_FDUAL) + && SUCCEEDED(ITypeInfo_GetRefTypeOfImplType(info, -1, &hRefType))) { + /* next iteration dumps hRefType, the TKIND_INTERFACE reference underneath this [dual] TKIND_DISPATCH */ + } else { + ++i; /* move to the next item in lib */ + hRefType = 0; + } + ITypeInfo_ReleaseTypeAttr(info, attr); ITypeInfo_Release(info); SysFreeString(name); @@ -4805,6 +4820,27 @@ static const type_info info[] = { }, { /* vars */ }, }, +{ + "IDualIface", + "{b14b6bb5-904e-4ff9-b247-bd361f7aaedd}", + /*kind*/ TKIND_INTERFACE, /*flags*/ TYPEFLAG_FDISPATCHABLE|TYPEFLAG_FOLEAUTOMATION|TYPEFLAG_FDUAL, /*align*/ TYPE_ALIGNMENT(IDualIface*), /*size*/ sizeof(IDualIface*), + /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 8, /*#func*/ 1, /*#var*/ 0, + { /* funcs */ + { + /*id*/ 0x60020000, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 7, /*#scodes*/ 0, /*flags*/ 0, + {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {-1, 0, 0} + }, + { /* names */ + "Test", + NULL, + }, + }, + }, + { /* vars */ }, +}, { "ISimpleIface", "{ec5dfcd6-eeb0-4cd6-b51e-8030e1dac009}", @@ -5271,9 +5307,9 @@ static const type_info info[] = { static void test_dump_typelib(const WCHAR *name) { ITypeLib *typelib; - int ticount = ARRAY_SIZE(info); CUSTDATA cust_data; - int iface, func, var; + int iface = 0, func, var; + HREFTYPE hRefType = 0; VARIANT v; HRESULT hr; TLIBATTR *libattr; @@ -5286,10 +5322,8 @@ static void test_dump_typelib(const WCHAR *name) skip("ignoring VARDESC::oInst, (libattr->syskind expected %d got %d)\n", info_syskind, libattr->syskind); }
- expect_eq(ITypeLib_GetTypeInfoCount(typelib), ticount, UINT, "%d"); - for (iface = 0; iface < ticount; iface++) + for (const type_info *ti = info; ti != info + ARRAY_SIZE(info); ++ti) { - const type_info *ti = &info[iface]; ITypeInfo2 *typeinfo2; ITypeInfo *typeinfo; TYPEATTR *typeattr; @@ -5298,6 +5332,12 @@ static void test_dump_typelib(const WCHAR *name)
trace("Interface %s\n", ti->name); ole_check(ITypeLib_GetTypeInfo(typelib, iface, &typeinfo)); + if(hRefType) { + ITypeInfo *refInfo; + ole_check(ITypeInfo_GetRefTypeInfo(typeinfo, hRefType, &refInfo)); + ITypeInfo_Release(typeinfo); + typeinfo = refInfo; + } ole_check(ITypeLib_GetDocumentation(typelib, iface, &bstrIfName, NULL, &help_ctx, NULL)); expect_wstr_acpval(bstrIfName, ti->name); SysFreeString(bstrIfName); @@ -5438,11 +5478,20 @@ static void test_dump_typelib(const WCHAR *name) ITypeInfo_ReleaseVarDesc(typeinfo, desc); }
+ if ((typeattr->typekind == TKIND_DISPATCH) && (typeattr->wTypeFlags & TYPEFLAG_FDUAL) + && SUCCEEDED(ITypeInfo_GetRefTypeOfImplType(typeinfo, -1, &hRefType))) { + /* next iteration dumps hRefType, the TKIND_INTERFACE reference underneath this [dual] TKIND_DISPATCH */ + } else { + ++iface; /* move to the next item in typelib */ + hRefType = 0; + } + ITypeInfo_ReleaseTypeAttr(typeinfo, typeattr);
ITypeInfo2_Release(typeinfo2); ITypeInfo_Release(typeinfo); } + expect_eq(ITypeLib_GetTypeInfoCount(typelib), iface, UINT, "%d"); ITypeLib_ReleaseTLibAttr(typelib, libattr); ITypeLib_Release(typelib); }
A [retval] parameter overwrites any return type, not just HRESULT. But HRESULT is special even without a [retval] to replace it; it's translated into pExcepInfo and so the return type becomes void.
[lcid] parameters are supplied from IDispatch::Invoke's parameters, rather than via DISPPARAMS::rgvargs[] and should also be removed from the FUNC_DISPATCH translation.
This rewriting should occur only for functions not originally defined as FUNC_DISPACH (e.g. inherited or [dual]). A FUNCDESC originally declared as a dispinterface is left as-is, and might e.g. return HRESULT.
When GetFuncDesc removes parameters in this fashion, GetNames must also omit their names to match cParams.
FUNC_DISPATCH from dispinterface should have oVft == 0 (a dispinterface has no vtbl beyond IDispatch itself)
Add examples in test_tlb which exercise FUNCDESC rewriting in: 1. dispinterface FUNC_DISPATCH declarations 2. dual interface 3. dispinterface which implements another interface
Signed-off-by: Kevin Puetz PuetzKevinA@JohnDeere.com --- dlls/oleaut32/tests/test_tlb.idl | 36 ++ dlls/oleaut32/tests/typelib.c | 653 +++++++++++++++++++++++++++++++ dlls/oleaut32/typelib.c | 96 +++-- 3 files changed, 757 insertions(+), 28 deletions(-)
diff --git a/dlls/oleaut32/tests/test_tlb.idl b/dlls/oleaut32/tests/test_tlb.idl index ad35af40c3..b8fecc9a01 100644 --- a/dlls/oleaut32/tests/test_tlb.idl +++ b/dlls/oleaut32/tests/test_tlb.idl @@ -134,4 +134,40 @@ library Test HRESULT test5(e value); HRESULT test6(f value); } + + [uuid(2d4430d5-99ea-4645-85f0-c5814b72804b)] + dispinterface ITestDispatch + { + properties: + [id(10)] int property_int; + [id(11)] HRESULT property_HRESULT; + + methods: + [id(1)] void test_void(); + [id(2)] void test_void_retval([out,retval] double* ret); + [id(3)] HRESULT test_HRESULT(); + [id(4)] HRESULT test_HRESULT_retval([out,retval] double* ret); + [id(5)] int test_int(); + [id(6)] int test_int_retval([out,retval] double* ret); + [id(7)] double parse_lcid([in] BSTR x, [lcid] long lcid); + + } + + [uuid(79ca07f9-ac22-44ac-9aaf-811f45412293), dual] + interface ITestDispDual : IDispatch + { + [id(1)] void test_void(); + [id(2)] void test_void_retval([out,retval] double* ret); + [id(3)] HRESULT test_HRESULT(); + [id(4)] HRESULT test_HRESULT_retval([out,retval] double* ret); + [id(5)] int test_int(); + [id(6)] int test_int_retval([out,retval] double* ret); + [id(7)] HRESULT parse_lcid([in] BSTR x, [lcid] long lcid, [out,retval] double *ret); + } + + [uuid(cdb105e3-24fb-4ae6-b826-801b7b2a0a07)] + dispinterface ITestDispInherit + { + interface ITestDispDual; + } } diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c index 5f1851aabf..01fbffe5ca 100644 --- a/dlls/oleaut32/tests/typelib.c +++ b/dlls/oleaut32/tests/typelib.c @@ -5278,6 +5278,659 @@ static const type_info info[] = { }, }, { /* vars */ }, +}, +{ + "ITestDispatch", + "{2d4430d5-99ea-4645-85f0-c5814b72804b}", + /*kind*/ TKIND_DISPATCH, /*flags*/ TYPEFLAG_FDISPATCHABLE, /*align*/ TYPE_ALIGNMENT(ITestDispatch*), /*size*/ sizeof(ITestDispatch*), + /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 7, /*#func*/ 7, /*#var*/ 2, + { /* funcs */ + { + /*id*/ 0x1, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 0, /*#scodes*/ 0, /*flags*/ 0, + {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {-1, 0, 0} + }, + { /* names */ + "test_void", + NULL, + }, + }, + { + /*id*/ 0x2, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 0, /*#scodes*/ 0, /*flags*/ 0, + {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {VT_PTR, -1, PARAMFLAG_FOUT|PARAMFLAG_FRETVAL}, + {-1, 0, 0} + }, + { /* names */ + "test_void_retval", + "ret", + NULL, + }, + }, + { + /*id*/ 0x3, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 0, /*#scodes*/ 0, /*flags*/ 0, + {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {-1, 0, 0} + }, + { /* names */ + "test_HRESULT", + NULL, + }, + }, + { + /*id*/ 0x4, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 0, /*#scodes*/ 0, /*flags*/ 0, + {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {VT_PTR, -1, PARAMFLAG_FOUT|PARAMFLAG_FRETVAL}, + {-1, 0, 0} + }, + { /* names */ + "test_HRESULT_retval", + "ret", + NULL, + }, + }, + { + /*id*/ 0x5, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 0, /*#scodes*/ 0, /*flags*/ 0, + {VT_INT, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {-1, 0, 0} + }, + { /* names */ + "test_int", + NULL, + }, + }, + { + /*id*/ 0x6, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 0, /*#scodes*/ 0, /*flags*/ 0, + {VT_INT, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {VT_PTR, -1, PARAMFLAG_FOUT|PARAMFLAG_FRETVAL}, + {-1, 0, 0} + }, + { /* names */ + "test_int_retval", + "ret", + NULL, + }, + }, + { + /*id*/ 0x7, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 2, /*#opt*/ 0, /*vtbl*/ 0, /*#scodes*/ 0, /*flags*/ 0, + {VT_R8, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {VT_BSTR, -1, PARAMFLAG_FIN}, + {VT_I4, -1, PARAMFLAG_FLCID}, + {-1, 0, 0} + }, + { /* names */ + "parse_lcid", + "x", + "lcid", + NULL, + }, + }, + }, + { /* vars */ + { + /*id*/ 0xa, /*name*/ "property_int", /*flags*/ 0, /*kind*/ VAR_DISPATCH, + { /* DUMMYUNIONNAME unused*/ }, + {VT_INT, -1, PARAMFLAG_NONE}, /* ret */ + }, + { + /*id*/ 0xb, /*name*/ "property_HRESULT", /*flags*/ 0, /*kind*/ VAR_DISPATCH, + { /* DUMMYUNIONNAME unused*/ }, + {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */ + }, + }, +}, +{ + "ITestDispDual", + "{79ca07f9-ac22-44ac-9aaf-811f45412293}", + /*kind*/ TKIND_DISPATCH, /*flags*/ TYPEFLAG_FDISPATCHABLE|TYPEFLAG_FDUAL, /*align*/ TYPE_ALIGNMENT(ITestDispDual*), /*size*/ sizeof(ITestDispDual*), + /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 7, /*#func*/ 14, /*#var*/ 0, + { /* funcs */ + { + /*id*/ 0x60000000, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 2, /*#opt*/ 0, /*vtbl*/ 0, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED, + {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {VT_PTR, -1, PARAMFLAG_FIN}, + {VT_PTR, -1, PARAMFLAG_FOUT}, + {-1, 0, 0} + }, + { /* names */ + "QueryInterface", + "riid", + "ppvObj", + NULL, + }, + }, + { + /*id*/ 0x60000001, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 1, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED, + {VT_UI4, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {-1, 0, 0} + }, + { /* names */ + "AddRef", + NULL, + }, + }, + { + /*id*/ 0x60000002, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 2, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED, + {VT_UI4, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {-1, 0, 0} + }, + { /* names */ + "Release", + NULL, + }, + }, + { + /*id*/ 0x60010000, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 3, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED, + {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {VT_PTR, -1, PARAMFLAG_FOUT}, + {-1, 0, 0} + }, + { /* names */ + "GetTypeInfoCount", + "pctinfo", + NULL, + }, + }, + { + /*id*/ 0x60010001, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 3, /*#opt*/ 0, /*vtbl*/ 4, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED, + {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {VT_UINT, -1, PARAMFLAG_FIN}, + {VT_UI4, -1, PARAMFLAG_FIN}, + {VT_PTR, -1, PARAMFLAG_FOUT}, + {-1, 0, 0} + }, + { /* names */ + "GetTypeInfo", + "itinfo", + "lcid", + "pptinfo", + NULL, + }, + }, + { + /*id*/ 0x60010002, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 5, /*#opt*/ 0, /*vtbl*/ 5, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED, + {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {VT_PTR, -1, PARAMFLAG_FIN}, + {VT_PTR, -1, PARAMFLAG_FIN}, + {VT_UINT, -1, PARAMFLAG_FIN}, + {VT_UI4, -1, PARAMFLAG_FIN}, + {VT_PTR, -1, PARAMFLAG_FOUT}, + {-1, 0, 0} + }, + { /* names */ + "GetIDsOfNames", + "riid", + "rgszNames", + "cNames", + "lcid", + "rgdispid", + NULL, + }, + }, + { + /*id*/ 0x60010003, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 8, /*#opt*/ 0, /*vtbl*/ 6, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED, + {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {VT_I4, -1, PARAMFLAG_FIN}, + {VT_PTR, -1, PARAMFLAG_FIN}, + {VT_UI4, -1, PARAMFLAG_FIN}, + {VT_UI2, -1, PARAMFLAG_FIN}, + {VT_PTR, -1, PARAMFLAG_FIN}, + {VT_PTR, -1, PARAMFLAG_FOUT}, + {VT_PTR, -1, PARAMFLAG_FOUT}, + {VT_PTR, -1, PARAMFLAG_FOUT}, + {-1, 0, 0} + }, + { /* names */ + "Invoke", + "dispidMember", + "riid", + "lcid", + "wFlags", + "pdispparams", + "pvarResult", + "pexcepinfo", + "puArgErr", + NULL, + }, + }, + { + /*id*/ 0x1, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 7, /*#scodes*/ 0, /*flags*/ 0, + {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {-1, 0, 0} + }, + { /* names */ + "test_void", + NULL, + }, + }, + { + /*id*/ 0x2, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 8, /*#scodes*/ 0, /*flags*/ 0, + {VT_R8, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {-1, 0, 0} + }, + { /* names */ + "test_void_retval", + NULL, + }, + }, + { + /*id*/ 0x3, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 9, /*#scodes*/ 0, /*flags*/ 0, + {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {-1, 0, 0} + }, + { /* names */ + "test_HRESULT", + NULL, + }, + }, + { + /*id*/ 0x4, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 10, /*#scodes*/ 0, /*flags*/ 0, + {VT_R8, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {-1, 0, 0} + }, + { /* names */ + "test_HRESULT_retval", + NULL, + }, + }, + { + /*id*/ 0x5, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 11, /*#scodes*/ 0, /*flags*/ 0, + {VT_INT, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {-1, 0, 0} + }, + { /* names */ + "test_int", + NULL, + }, + }, + { + /*id*/ 0x6, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 12, /*#scodes*/ 0, /*flags*/ 0, + {VT_R8, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {-1, 0, 0} + }, + { /* names */ + "test_int_retval", + NULL, + }, + }, + { + /*id*/ 0x7, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 13, /*#scodes*/ 0, /*flags*/ 0, + {VT_R8, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {VT_BSTR, -1, PARAMFLAG_FIN}, + {-1, 0, 0} + }, + { /* names */ + "parse_lcid", + "x", + NULL, + }, + }, + }, + { /* vars */ }, +}, +{ + "ITestDispDual", + "{79ca07f9-ac22-44ac-9aaf-811f45412293}", + /*kind*/ TKIND_INTERFACE, /*flags*/ TYPEFLAG_FDISPATCHABLE|TYPEFLAG_FOLEAUTOMATION|TYPEFLAG_FDUAL, /*align*/ TYPE_ALIGNMENT(ITestDispDual*), /*size*/ sizeof(ITestDispDual*), + /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 14, /*#func*/ 7, /*#var*/ 0, + { /* funcs */ + { + /*id*/ 0x1, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 7, /*#scodes*/ 0, /*flags*/ 0, + {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {-1, 0, 0} + }, + { /* names */ + "test_void", + NULL, + }, + }, + { + /*id*/ 0x2, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 8, /*#scodes*/ 0, /*flags*/ 0, + {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {VT_PTR, -1, PARAMFLAG_FOUT|PARAMFLAG_FRETVAL}, + {-1, 0, 0} + }, + { /* names */ + "test_void_retval", + "ret", + NULL, + }, + }, + { + /*id*/ 0x3, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 9, /*#scodes*/ 0, /*flags*/ 0, + {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {-1, 0, 0} + }, + { /* names */ + "test_HRESULT", + NULL, + }, + }, + { + /*id*/ 0x4, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 10, /*#scodes*/ 0, /*flags*/ 0, + {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {VT_PTR, -1, PARAMFLAG_FOUT|PARAMFLAG_FRETVAL}, + {-1, 0, 0} + }, + { /* names */ + "test_HRESULT_retval", + "ret", + NULL, + }, + }, + { + /*id*/ 0x5, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 11, /*#scodes*/ 0, /*flags*/ 0, + {VT_INT, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {-1, 0, 0} + }, + { /* names */ + "test_int", + NULL, + }, + }, + { + /*id*/ 0x6, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 12, /*#scodes*/ 0, /*flags*/ 0, + {VT_INT, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {VT_PTR, -1, PARAMFLAG_FOUT|PARAMFLAG_FRETVAL}, + {-1, 0, 0} + }, + { /* names */ + "test_int_retval", + "ret", + NULL, + }, + }, + { + /*id*/ 0x7, /*func*/ FUNC_PUREVIRTUAL, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 3, /*#opt*/ 0, /*vtbl*/ 13, /*#scodes*/ 0, /*flags*/ 0, + {VT_HRESULT, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {VT_BSTR, -1, PARAMFLAG_FIN}, + {VT_I4, -1, PARAMFLAG_FLCID}, + {VT_PTR, -1, PARAMFLAG_FOUT|PARAMFLAG_FRETVAL}, + {-1, 0, 0} + }, + { /* names */ + "parse_lcid", + "x", + "lcid", + "ret", + NULL, + }, + }, + }, + { /* vars */ }, +}, +{ + "ITestDispInherit", + "{cdb105e3-24fb-4ae6-b826-801b7b2a0a07}", + /*kind*/ TKIND_DISPATCH, /*flags*/ TYPEFLAG_FDISPATCHABLE, /*align*/ TYPE_ALIGNMENT(ITestDispInherit*), /*size*/ sizeof(ITestDispInherit*), + /*helpctx*/ 0x0000, /*version*/ 0x00000000, /*#vtbl*/ 7, /*#func*/ 14, /*#var*/ 0, + { /* funcs */ + { + /*id*/ 0x60000000, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 2, /*#opt*/ 0, /*vtbl*/ 0, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED, + {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {VT_PTR, -1, PARAMFLAG_FIN}, + {VT_PTR, -1, PARAMFLAG_FOUT}, + {-1, 0, 0} + }, + { /* names */ + "QueryInterface", + "riid", + "ppvObj", + NULL, + }, + }, + { + /*id*/ 0x60000001, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 1, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED, + {VT_UI4, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {-1, 0, 0} + }, + { /* names */ + "AddRef", + NULL, + }, + }, + { + /*id*/ 0x60000002, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 2, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED, + {VT_UI4, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {-1, 0, 0} + }, + { /* names */ + "Release", + NULL, + }, + }, + { + /*id*/ 0x60010000, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 3, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED, + {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {VT_PTR, -1, PARAMFLAG_FOUT}, + {-1, 0, 0} + }, + { /* names */ + "GetTypeInfoCount", + "pctinfo", + NULL, + }, + }, + { + /*id*/ 0x60010001, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 3, /*#opt*/ 0, /*vtbl*/ 4, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED, + {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {VT_UINT, -1, PARAMFLAG_FIN}, + {VT_UI4, -1, PARAMFLAG_FIN}, + {VT_PTR, -1, PARAMFLAG_FOUT}, + {-1, 0, 0} + }, + { /* names */ + "GetTypeInfo", + "itinfo", + "lcid", + "pptinfo", + NULL, + }, + }, + { + /*id*/ 0x60010002, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 5, /*#opt*/ 0, /*vtbl*/ 5, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED, + {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {VT_PTR, -1, PARAMFLAG_FIN}, + {VT_PTR, -1, PARAMFLAG_FIN}, + {VT_UINT, -1, PARAMFLAG_FIN}, + {VT_UI4, -1, PARAMFLAG_FIN}, + {VT_PTR, -1, PARAMFLAG_FOUT}, + {-1, 0, 0} + }, + { /* names */ + "GetIDsOfNames", + "riid", + "rgszNames", + "cNames", + "lcid", + "rgdispid", + NULL, + }, + }, + { + /*id*/ 0x60010003, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 8, /*#opt*/ 0, /*vtbl*/ 6, /*#scodes*/ 0, /*flags*/ FUNCFLAG_FRESTRICTED, + {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {VT_I4, -1, PARAMFLAG_FIN}, + {VT_PTR, -1, PARAMFLAG_FIN}, + {VT_UI4, -1, PARAMFLAG_FIN}, + {VT_UI2, -1, PARAMFLAG_FIN}, + {VT_PTR, -1, PARAMFLAG_FIN}, + {VT_PTR, -1, PARAMFLAG_FOUT}, + {VT_PTR, -1, PARAMFLAG_FOUT}, + {VT_PTR, -1, PARAMFLAG_FOUT}, + {-1, 0, 0} + }, + { /* names */ + "Invoke", + "dispidMember", + "riid", + "lcid", + "wFlags", + "pdispparams", + "pvarResult", + "pexcepinfo", + "puArgErr", + NULL, + }, + }, + { + /*id*/ 0x1, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 7, /*#scodes*/ 0, /*flags*/ 0, + {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {-1, 0, 0} + }, + { /* names */ + "test_void", + NULL, + }, + }, + { + /*id*/ 0x2, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 8, /*#scodes*/ 0, /*flags*/ 0, + {VT_R8, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {-1, 0, 0} + }, + { /* names */ + "test_void_retval", + NULL, + }, + }, + { + /*id*/ 0x3, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 9, /*#scodes*/ 0, /*flags*/ 0, + {VT_VOID, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {-1, 0, 0} + }, + { /* names */ + "test_HRESULT", + NULL, + }, + }, + { + /*id*/ 0x4, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 10, /*#scodes*/ 0, /*flags*/ 0, + {VT_R8, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {-1, 0, 0} + }, + { /* names */ + "test_HRESULT_retval", + NULL, + }, + }, + { + /*id*/ 0x5, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 11, /*#scodes*/ 0, /*flags*/ 0, + {VT_INT, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {-1, 0, 0} + }, + { /* names */ + "test_int", + NULL, + }, + }, + { + /*id*/ 0x6, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 0, /*#opt*/ 0, /*vtbl*/ 12, /*#scodes*/ 0, /*flags*/ 0, + {VT_R8, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {-1, 0, 0} + }, + { /* names */ + "test_int_retval", + NULL, + }, + }, + { + /*id*/ 0x7, /*func*/ FUNC_DISPATCH, /*inv*/ INVOKE_FUNC, /*call*/ CC_STDCALL, + /*#param*/ 1, /*#opt*/ 0, /*vtbl*/ 13, /*#scodes*/ 0, /*flags*/ 0, + {VT_R8, -1, PARAMFLAG_NONE}, /* ret */ + { /* params */ + {VT_BSTR, -1, PARAMFLAG_FIN}, + {-1, 0, 0} + }, + { /* names */ + "parse_lcid", + "x", + NULL, + }, + }, + }, + { /* vars */ }, } };
diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c index 06667850a3..2f7ce53b1c 100644 --- a/dlls/oleaut32/typelib.c +++ b/dlls/oleaut32/typelib.c @@ -2465,7 +2465,11 @@ MSFT_DoFuncs(TLBContext* pcx, ptfd->funcdesc.callconv = (pFuncRec->FKCCIC) >> 8 & 0xF; ptfd->funcdesc.cParams = pFuncRec->nrargs ; ptfd->funcdesc.cParamsOpt = pFuncRec->nroargs ; - ptfd->funcdesc.oVft = (pFuncRec->VtableOffset & ~1) * sizeof(void *) / pTI->pTypeLib->ptr_size; + if(ptfd->funcdesc.funckind == FUNC_DISPATCH) { + ptfd->funcdesc.oVft = 0; + } else { + ptfd->funcdesc.oVft = (pFuncRec->VtableOffset & ~1) * sizeof(void *) / pTI->pTypeLib->ptr_size; + } ptfd->funcdesc.wFuncFlags = LOWORD(pFuncRec->Flags) ;
/* nameoffset is sometimes -1 on the second half of a propget/propput @@ -4179,7 +4183,11 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, pFuncDesc->funcdesc.callconv = pFunc->nacc & 0x7; pFuncDesc->funcdesc.cParams = pFunc->nacc >> 3; pFuncDesc->funcdesc.cParamsOpt = (pFunc->retnextopt & 0x7e) >> 1; - pFuncDesc->funcdesc.oVft = (pFunc->vtblpos & ~1) * sizeof(void *) / pTI->pTypeLib->ptr_size; + if (pFuncDesc->funcdesc.funckind == FUNC_DISPATCH) { + pFuncDesc->funcdesc.oVft = 0; + } else { + pFuncDesc->funcdesc.oVft = (pFunc->vtblpos & ~1) * sizeof(void *) / pTI->pTypeLib->ptr_size; + }
if(pFunc->magic & SLTG_FUNCTION_FLAGS_PRESENT) pFuncDesc->funcdesc.wFuncFlags = pFunc->funcflags; @@ -5849,11 +5857,13 @@ static HRESULT TLB_AllocAndInitFuncDesc( const FUNCDESC *src, FUNCDESC **dest_pt } else dest->lprgelemdescParam = NULL;
- /* special treatment for dispinterfaces: this makes functions appear - * to return their [retval] value when it is really returning an - * HRESULT */ - if (dispinterface && dest->elemdescFunc.tdesc.vt == VT_HRESULT) + /* special treatment for dispinterface FUNCDESC based on an interface FUNCDESC. + * This accounts for several arguments that are seperate in the signature of + * IDispatch::Invoke, rather than passed in DISPPARAMS::rgvarg[] */ + if (dispinterface && (src->funckind != FUNC_DISPATCH)) { + /* functions that have a [retval] parameter return this value into pVarResult. + * [retval] is always the last parameter (if present) */ if (dest->cParams && (dest->lprgelemdescParam[dest->cParams - 1].u.paramdesc.wParamFlags & PARAMFLAG_FRETVAL)) { @@ -5866,19 +5876,28 @@ static HRESULT TLB_AllocAndInitFuncDesc( const FUNCDESC *src, FUNCDESC **dest_pt return E_UNEXPECTED; }
- /* copy last parameter to the return value. we are using a flat - * buffer so there is no danger of leaking memory in - * elemdescFunc */ + /* the type pointed to by this [retval] becomes elemdescFunc, + * i.e. functions signature's return type (replacing HRESULT/void/anything else) + * We are using a flat buffer so there is no danger of leaking memory */ dest->elemdescFunc.tdesc = *elemdesc->tdesc.u.lptdesc;
/* remove the last parameter */ dest->cParams--; } - else - /* otherwise this function is made to appear to have no return - * value */ + else if (dest->elemdescFunc.tdesc.vt == VT_HRESULT) + /* Even if not otherwise replaced (by [retval], + * HRESULT is returned in pExcepInfo->scode, not pVarResult. + * So the function signature should show no return value. */ dest->elemdescFunc.tdesc.vt = VT_VOID;
+ /* The now-last (except [retval], removed above) parameter might be labeled [lcid]. + * If so it will be supplied from Invoke(lcid), so also not via DISPPARAMS::rgvarg */ + if (dest->cParams && + (dest->lprgelemdescParam[dest->cParams - 1].u.paramdesc.wParamFlags & PARAMFLAG_FLCID)) + { + /* remove the last parameter */ + dest->cParams--; + } }
*dest_ptr = dest; @@ -6105,36 +6124,38 @@ static HRESULT WINAPI ITypeInfo_fnGetVarDesc( ITypeInfo2 *iface, UINT index, return TLB_AllocAndInitVarDesc(&pVDesc->vardesc, ppVarDesc); }
-/* ITypeInfo_GetNames - * - * Retrieves the variable with the specified member ID (or the name of the - * property or method and its parameters) that correspond to the specified - * function ID. - */ -static HRESULT WINAPI ITypeInfo_fnGetNames( ITypeInfo2 *iface, MEMBERID memid, - BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames) +/* internal function to make the inherited interfaces' methods appear + * part of the interface, remembering if the top-level was dispinterface */ +static HRESULT ITypeInfoImpl_GetNames( ITypeInfo *iface, + MEMBERID memid, BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames, + BOOL dispinterface) { - ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); + ITypeInfoImpl *This = impl_from_ITypeInfo(iface); const TLBFuncDesc *pFDesc; const TLBVarDesc *pVDesc; int i; - TRACE("(%p) memid=0x%08x Maxname=%d\n", This, memid, cMaxNames); - - if(!rgBstrNames) - return E_INVALIDARG;
*pcNames = 0;
pFDesc = TLB_get_funcdesc_by_memberid(This, memid); if(pFDesc) { + UINT cParams = pFDesc->funcdesc.cParams; if(!cMaxNames || !pFDesc->Name) return S_OK;
*rgBstrNames = SysAllocString(TLB_get_bstr(pFDesc->Name)); ++(*pcNames);
- for(i = 0; i < pFDesc->funcdesc.cParams; ++i){ + if(dispinterface && (pFDesc->funcdesc.funckind != FUNC_DISPATCH)) { + /* match the rewriting of special trailing parameters in TLB_AllocAndInitFuncDesc; */ + if ((cParams > 0) && (pFDesc->funcdesc.lprgelemdescParam[cParams - 1].u.paramdesc.wParamFlags & PARAMFLAG_FRETVAL)) + --cParams; /* Invoke(pVarResult) supplies the [retval] parameter, so its hidden from DISPPARAMS*/ + if ((cParams > 0) && (pFDesc->funcdesc.lprgelemdescParam[cParams - 1].u.paramdesc.wParamFlags & PARAMFLAG_FLCID)) + --cParams; /* Invoke(lcid) supplies the [lcid] parameter, so its hidden from DISPPARAMS */ + } + + for(i = 0; i < cParams; ++i) { if(*pcNames >= cMaxNames || !pFDesc->pParamDesc[i].Name) return S_OK; rgBstrNames[*pcNames] = SysAllocString(TLB_get_bstr(pFDesc->pParamDesc[i].Name)); @@ -6156,10 +6177,10 @@ static HRESULT WINAPI ITypeInfo_fnGetNames( ITypeInfo2 *iface, MEMBERID memid, /* recursive search */ ITypeInfo *pTInfo; HRESULT result; - result = ITypeInfo2_GetRefTypeInfo(iface, This->impltypes[0].hRef, &pTInfo); + result = ITypeInfo_GetRefTypeInfo(iface, This->impltypes[0].hRef, &pTInfo); if(SUCCEEDED(result)) { - result=ITypeInfo_GetNames(pTInfo, memid, rgBstrNames, cMaxNames, pcNames); + result=ITypeInfoImpl_GetNames(pTInfo, memid, rgBstrNames, cMaxNames, pcNames, dispinterface); ITypeInfo_Release(pTInfo); return result; } @@ -6175,6 +6196,25 @@ static HRESULT WINAPI ITypeInfo_fnGetNames( ITypeInfo2 *iface, MEMBERID memid, return S_OK; }
+/* ITypeInfo_GetNames + * + * Retrieves the variable with the specified member ID (or the name of the + * property or method and its parameters) that correspond to the specified + * function ID. + */ +static HRESULT WINAPI ITypeInfo_fnGetNames( ITypeInfo2 *iface, MEMBERID memid, + BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames) +{ + ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); + TRACE("(%p) memid=0x%08x Maxname=%d\n", This, memid, cMaxNames); + + if(!rgBstrNames) + return E_INVALIDARG; + + return ITypeInfoImpl_GetNames((ITypeInfo *)iface, + memid, rgBstrNames, cMaxNames, pcNames, + This->typeattr.typekind == TKIND_DISPATCH); +}
/* ITypeInfo::GetRefTypeOfImplType *
On Fri, Sep 18, 2020 at 09:38:24PM -0500, Kevin Puetz wrote:
A [retval] parameter overwrites any return type, not just HRESULT. But HRESULT is special even without a [retval] to replace it; it's translated into pExcepInfo and so the return type becomes void.
[lcid] parameters are supplied from IDispatch::Invoke's parameters, rather than via DISPPARAMS::rgvargs[] and should also be removed from the FUNC_DISPATCH translation.
This rewriting should occur only for functions not originally defined as FUNC_DISPACH (e.g. inherited or [dual]). A FUNCDESC originally declared as a dispinterface is left as-is, and might e.g. return HRESULT.
When GetFuncDesc removes parameters in this fashion, GetNames must also omit their names to match cParams.
FUNC_DISPATCH from dispinterface should have oVft == 0 (a dispinterface has no vtbl beyond IDispatch itself)
Add examples in test_tlb which exercise FUNCDESC rewriting in:
- dispinterface FUNC_DISPATCH declarations
- dual interface
- dispinterface which implements another interface
There are several things changing in this patch, please could you split them up? In addition to making the patch easier to review and easier to fix regressions, splitting the patch will enable more meaningful commit subject lines to be written.
-/* ITypeInfo_GetNames
- Retrieves the variable with the specified member ID (or the name of the
- property or method and its parameters) that correspond to the specified
- function ID.
- */
-static HRESULT WINAPI ITypeInfo_fnGetNames( ITypeInfo2 *iface, MEMBERID memid,
BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames)
+/* internal function to make the inherited interfaces' methods appear
- part of the interface, remembering if the top-level was dispinterface */
+static HRESULT ITypeInfoImpl_GetNames( ITypeInfo *iface,
typeinfo_getnames() might be a better name for this helper, it's less likely to be confused with ITypeInfo_fnGetNames.
Huw.
On Monday, Sep 20, 2020 at 5:55 AM, Huw Davies wrote:
On Fri, Sep 18, 2020 at 09:38:24PM -0500, Kevin Puetz wrote:
There are several things changing in this patch, please could you split them up? In addition to making the patch easier to review and easier to fix regressions, splitting the patch will enable more meaningful commit subject lines to be written.
Can do. I was trying to avoid a patch that made changes that were not yet tested, and all the fixes were needed to pass a round-trip comparison of dispinterface derived-from dual interface.
Would you prefer a series of (separate) fixes, followed by the conformance test, Or a conformance test (with todo_wine) followed by fixes gradually removing the todo_wine?
-/* ITypeInfo_GetNames
- Retrieves the variable with the specified member ID (or the name of the
- property or method and its parameters) that correspond to the
specified
- function ID.
- */
-static HRESULT WINAPI ITypeInfo_fnGetNames( ITypeInfo2 *iface,
MEMBERID memid,
BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames)
+/* internal function to make the inherited interfaces' methods appear
- part of the interface, remembering if the top-level was dispinterface */
+static HRESULT ITypeInfoImpl_GetNames( ITypeInfo *iface,
typeinfo_getnames() might be a better name for this helper; those with ITypeInfoImpl_* were helpers it's less likely to be confused with ITypeInfo_fnGetNames.
Ok. This one was like the others in that it's a helper adding a `dispinterface` arg to pass whether the top-level request was a dispinterface down the recursion into impltypes.
I indeed followed what seemed to be the naming convention of GetInternalFuncDesc That all ITypeInfoImpl_* were private helpers. But I it was unclear whether it was meant as (GetInternal)FuncDesc or Get(InternalFuncDesc), since that returned TLBFuncDesc instead of FUNCDESC, so I didn't put an "Internal" in this name.
I don't see any existing use of typelib_* naming. though I can certainly do that if it's you what you want. Should I lowercase the other helpers too, or just let this one use a different naming convention?
Or I suppose this could be ITypeInfoImpl_GetInternalNames,...
Huw.
On Monday, Sep 20, 2020 at 5:55 AM, Huw Davies wrote:
On Fri, Sep 18, 2020 at 09:38:24PM -0500, Kevin Puetz wrote:
There are several things changing in this patch, please could you split them up? In addition to making the patch easier to review and easier to fix regressions, splitting the patch will enable more meaningful commit subject lines to be written.
Can do. I was trying to avoid a patch that made changes that were not yet tested, and all the fixes were needed to pass a round-trip comparison of dispinterface derived-from dual interface.
Would you prefer a series of (separate) fixes, followed by the conformance test, Or a conformance test (with todo_wine) followed by fixes gradually removing the todo_wine?
Actually, NAK that, todo_wine won't really work since I'm adding additional test *data* (in test_tlb.idl) that exposes existing bugs, but the code doing the ok() calls is mostly not new. So there's no easy way to todo_wine the failures, the test data just has to be added last to un-squash this commit without showing broken tests in the middle of the series.
On Mon, Sep 21, 2020 at 01:49:32PM +0000, Puetz Kevin A wrote:
On Monday, Sep 20, 2020 at 5:55 AM, Huw Davies wrote:
On Fri, Sep 18, 2020 at 09:38:24PM -0500, Kevin Puetz wrote:
There are several things changing in this patch, please could you split them up? In addition to making the patch easier to review and easier to fix regressions, splitting the patch will enable more meaningful commit subject lines to be written.
Can do. I was trying to avoid a patch that made changes that were not yet tested, and all the fixes were needed to pass a round-trip comparison of dispinterface derived-from dual interface.
Would you prefer a series of (separate) fixes, followed by the conformance test, Or a conformance test (with todo_wine) followed by fixes gradually removing the todo_wine?
Actually, NAK that, todo_wine won't really work since I'm adding additional test *data* (in test_tlb.idl) that exposes existing bugs, but the code doing the ok() calls is mostly not new. So there's no easy way to todo_wine the failures, the test data just has to be added last to un-squash this commit without showing broken tests in the middle of the series.
Ideally, tests with todos, followed by a series of fixes that remove the todos. If that's not possible, then a series of fixes followed by the tests.
Huw.
On Mon, Sep 21, 2020 at 01:41:30PM +0000, Puetz Kevin A wrote:
On Monday, Sep 20, 2020 at 5:55 AM, Huw Davies wrote:
typeinfo_getnames() might be a better name for this helper; those with ITypeInfoImpl_* were helpers it's less likely to be confused with ITypeInfo_fnGetNames.
Ok. This one was like the others in that it's a helper adding a `dispinterface` arg to pass whether the top-level request was a dispinterface down the recursion into impltypes.
I indeed followed what seemed to be the naming convention of GetInternalFuncDesc That all ITypeInfoImpl_* were private helpers. But I it was unclear whether it was meant as (GetInternal)FuncDesc or Get(InternalFuncDesc), since that returned TLBFuncDesc instead of FUNCDESC, so I didn't put an "Internal" in this name.
I don't see any existing use of typelib_* naming. though I can certainly do that if it's you what you want. Should I lowercase the other helpers too, or just let this one use a different naming convention?
Or I suppose this could be ITypeInfoImpl_GetInternalNames,...
I think using typeinfo_getnames() is the moving in the right direction. There may be some scope to remain some of the other helpers at a later date.
Huw.