This IDL is used by windows.media.speech.dll, which is itself required by Flight Simulator. It will here be used as an illustration and test case for WIDL WinRT features.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
This is the beginning of a series to correctly support parameterized interfaces in WIDL in WinRT mode. I'm using this new idl file as well as windows.foundation.idl to illustrate and test the parsing features, and the generated headers.
The generated code should closely match MIDL this time, at least on the C side. The C++ side of the WinRT generated headers are based template implementation classes from internal WinRT headers, which we don't have and that will require a lot more work to figure how to do it properly.
include/Makefile.in | 1 + include/windows.media.speechsynthesis.idl | 61 +++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 include/windows.media.speechsynthesis.idl
diff --git a/include/Makefile.in b/include/Makefile.in index 91a02645c33..dd13656392e 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -733,6 +733,7 @@ SOURCES = \ windef.h \ windns.h \ windows.foundation.idl \ + windows.media.speechsynthesis.idl \ windows.h \ windowsx.h \ wine/debug.h \ diff --git a/include/windows.media.speechsynthesis.idl b/include/windows.media.speechsynthesis.idl new file mode 100644 index 00000000000..a0a4c9cbf50 --- /dev/null +++ b/include/windows.media.speechsynthesis.idl @@ -0,0 +1,61 @@ +/* + * Copyright 2020 Rémi Bernon for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifdef __WIDL__ +#pragma winrt ns_prefix +#endif + +import "inspectable.idl"; +import "windows.foundation.idl"; + +namespace Windows { + namespace Media { + namespace SpeechSynthesis { + typedef enum VoiceGender VoiceGender; + interface IInstalledVoicesStatic; + interface IVoiceInformation; + } + } +} + +namespace Windows { + namespace Media { + namespace SpeechSynthesis { + /* [contract(Windows.Foundation.UniversalApiContract, 1.0)] */ + enum VoiceGender + { + Male = 0, + Female = 1 + }; + + [ + /* contract(Windows.Foundation.UniversalApiContract, 1.0), */ + /* exclusiveto(Windows.Media.SpeechSynthesis.VoiceInformation), */ + uuid(b127d6a4-1291-4604-aa9c-83134083352c) + ] + interface IVoiceInformation : IInspectable + { + [propget] HRESULT DisplayName([out] [retval] HSTRING* value); + [propget] HRESULT Id([out] [retval] HSTRING* value); + [propget] HRESULT Language([out] [retval] HSTRING* value); + [propget] HRESULT Description([out] [retval] HSTRING* value); + [propget] HRESULT Gender([out] [retval] VoiceGender* value); + } + } + } +}
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- tools/widl/parser.l | 333 ++++++++++++++++++++++---------------------- 1 file changed, 167 insertions(+), 166 deletions(-)
diff --git a/tools/widl/parser.l b/tools/widl/parser.l index 925265d00db..eb1782d32f5 100644 --- a/tools/widl/parser.l +++ b/tools/widl/parser.l @@ -248,67 +248,68 @@ int parser_wrap(void) struct keyword { const char *kw; int token; + int winrt_only : 1; };
/* This table MUST be alphabetically sorted on the kw field */ static const struct keyword keywords[] = { - {"FALSE", tFALSE}, - {"NULL", tNULL}, - {"TRUE", tTRUE}, - {"__cdecl", tCDECL}, - {"__fastcall", tFASTCALL}, - {"__int32", tINT32}, - {"__int3264", tINT3264}, - {"__int64", tINT64}, - {"__pascal", tPASCAL}, - {"__stdcall", tSTDCALL}, - {"_cdecl", tCDECL}, - {"_fastcall", tFASTCALL}, - {"_pascal", tPASCAL}, - {"_stdcall", tSTDCALL}, - {"boolean", tBOOLEAN}, - {"byte", tBYTE}, - {"case", tCASE}, - {"cdecl", tCDECL}, - {"char", tCHAR}, - {"coclass", tCOCLASS}, - {"const", tCONST}, - {"cpp_quote", tCPPQUOTE}, - {"default", tDEFAULT}, - {"dispinterface", tDISPINTERFACE}, - {"double", tDOUBLE}, - {"enum", tENUM}, - {"error_status_t", tERRORSTATUST}, - {"extern", tEXTERN}, - {"float", tFLOAT}, - {"handle_t", tHANDLET}, - {"hyper", tHYPER}, - {"import", tIMPORT}, - {"importlib", tIMPORTLIB}, - {"inline", tINLINE}, - {"int", tINT}, - {"interface", tINTERFACE}, - {"library", tLIBRARY}, - {"long", tLONG}, - {"methods", tMETHODS}, - {"module", tMODULE}, - {"namespace", tNAMESPACE}, - {"pascal", tPASCAL}, - {"properties", tPROPERTIES}, - {"register", tREGISTER}, - {"short", tSHORT}, - {"signed", tSIGNED}, - {"sizeof", tSIZEOF}, - {"small", tSMALL}, - {"static", tSTATIC}, - {"stdcall", tSTDCALL}, - {"struct", tSTRUCT}, - {"switch", tSWITCH}, - {"typedef", tTYPEDEF}, - {"union", tUNION}, - {"unsigned", tUNSIGNED}, - {"void", tVOID}, - {"wchar_t", tWCHAR}, + {"FALSE", tFALSE, 0}, + {"NULL", tNULL, 0}, + {"TRUE", tTRUE, 0}, + {"__cdecl", tCDECL, 0}, + {"__fastcall", tFASTCALL, 0}, + {"__int32", tINT32, 0}, + {"__int3264", tINT3264, 0}, + {"__int64", tINT64, 0}, + {"__pascal", tPASCAL, 0}, + {"__stdcall", tSTDCALL, 0}, + {"_cdecl", tCDECL, 0}, + {"_fastcall", tFASTCALL, 0}, + {"_pascal", tPASCAL, 0}, + {"_stdcall", tSTDCALL, 0}, + {"boolean", tBOOLEAN, 0}, + {"byte", tBYTE, 0}, + {"case", tCASE, 0}, + {"cdecl", tCDECL, 0}, + {"char", tCHAR, 0}, + {"coclass", tCOCLASS, 0}, + {"const", tCONST, 0}, + {"cpp_quote", tCPPQUOTE, 0}, + {"default", tDEFAULT, 0}, + {"dispinterface", tDISPINTERFACE, 0}, + {"double", tDOUBLE, 0}, + {"enum", tENUM, 0}, + {"error_status_t", tERRORSTATUST, 0}, + {"extern", tEXTERN, 0}, + {"float", tFLOAT, 0}, + {"handle_t", tHANDLET, 0}, + {"hyper", tHYPER, 0}, + {"import", tIMPORT, 0}, + {"importlib", tIMPORTLIB, 0}, + {"inline", tINLINE, 0}, + {"int", tINT, 0}, + {"interface", tINTERFACE, 0}, + {"library", tLIBRARY, 0}, + {"long", tLONG, 0}, + {"methods", tMETHODS, 0}, + {"module", tMODULE, 0}, + {"namespace", tNAMESPACE, 1}, + {"pascal", tPASCAL, 0}, + {"properties", tPROPERTIES, 0}, + {"register", tREGISTER, 0}, + {"short", tSHORT, 0}, + {"signed", tSIGNED, 0}, + {"sizeof", tSIZEOF, 0}, + {"small", tSMALL, 0}, + {"static", tSTATIC, 0}, + {"stdcall", tSTDCALL, 0}, + {"struct", tSTRUCT, 0}, + {"switch", tSWITCH, 0}, + {"typedef", tTYPEDEF, 0}, + {"union", tUNION, 0}, + {"unsigned", tUNSIGNED, 0}, + {"void", tVOID, 0}, + {"wchar_t", tWCHAR, 0}, }; #define NKEYWORDS (sizeof(keywords)/sizeof(keywords[0]))
@@ -317,113 +318,113 @@ static const struct keyword keywords[] = { */ static const struct keyword attr_keywords[] = { - {"aggregatable", tAGGREGATABLE}, - {"allocate", tALLOCATE}, - {"annotation", tANNOTATION}, - {"apartment", tAPARTMENT}, - {"appobject", tAPPOBJECT}, - {"async", tASYNC}, - {"async_uuid", tASYNCUUID}, - {"auto_handle", tAUTOHANDLE}, - {"bindable", tBINDABLE}, - {"both", tBOTH}, - {"broadcast", tBROADCAST}, - {"byte_count", tBYTECOUNT}, - {"call_as", tCALLAS}, - {"callback", tCALLBACK}, - {"code", tCODE}, - {"comm_status", tCOMMSTATUS}, - {"context_handle", tCONTEXTHANDLE}, - {"context_handle_noserialize", tCONTEXTHANDLENOSERIALIZE}, - {"context_handle_serialize", tCONTEXTHANDLENOSERIALIZE}, - {"control", tCONTROL}, - {"decode", tDECODE}, - {"defaultbind", tDEFAULTBIND}, - {"defaultcollelem", tDEFAULTCOLLELEM}, - {"defaultvalue", tDEFAULTVALUE}, - {"defaultvtable", tDEFAULTVTABLE}, - {"disable_consistency_check", tDISABLECONSISTENCYCHECK}, - {"displaybind", tDISPLAYBIND}, - {"dllname", tDLLNAME}, - {"dual", tDUAL}, - {"enable_allocate", tENABLEALLOCATE}, - {"encode", tENCODE}, - {"endpoint", tENDPOINT}, - {"entry", tENTRY}, - {"explicit_handle", tEXPLICITHANDLE}, - {"fault_status", tFAULTSTATUS}, - {"force_allocate", tFORCEALLOCATE}, - {"free", tFREE}, - {"handle", tHANDLE}, - {"helpcontext", tHELPCONTEXT}, - {"helpfile", tHELPFILE}, - {"helpstring", tHELPSTRING}, - {"helpstringcontext", tHELPSTRINGCONTEXT}, - {"helpstringdll", tHELPSTRINGDLL}, - {"hidden", tHIDDEN}, - {"id", tID}, - {"idempotent", tIDEMPOTENT}, - {"ignore", tIGNORE}, - {"iid_is", tIIDIS}, - {"immediatebind", tIMMEDIATEBIND}, - {"implicit_handle", tIMPLICITHANDLE}, - {"in", tIN}, - {"in_line", tIN_LINE}, - {"input_sync", tINPUTSYNC}, - {"lcid", tLCID}, - {"length_is", tLENGTHIS}, - {"licensed", tLICENSED}, - {"local", tLOCAL}, - {"maybe", tMAYBE}, - {"message", tMESSAGE}, - {"neutral", tNEUTRAL}, - {"nocode", tNOCODE}, - {"nonbrowsable", tNONBROWSABLE}, - {"noncreatable", tNONCREATABLE}, - {"nonextensible", tNONEXTENSIBLE}, - {"notify", tNOTIFY}, - {"notify_flag", tNOTIFYFLAG}, - {"object", tOBJECT}, - {"odl", tODL}, - {"oleautomation", tOLEAUTOMATION}, - {"optimize", tOPTIMIZE}, - {"optional", tOPTIONAL}, - {"out", tOUT}, - {"partial_ignore", tPARTIALIGNORE}, - {"pointer_default", tPOINTERDEFAULT}, - {"progid", tPROGID}, - {"propget", tPROPGET}, - {"propput", tPROPPUT}, - {"propputref", tPROPPUTREF}, - {"proxy", tPROXY}, - {"ptr", tPTR}, - {"public", tPUBLIC}, - {"range", tRANGE}, - {"readonly", tREADONLY}, - {"ref", tREF}, - {"represent_as", tREPRESENTAS}, - {"requestedit", tREQUESTEDIT}, - {"restricted", tRESTRICTED}, - {"retval", tRETVAL}, - {"single", tSINGLE}, - {"size_is", tSIZEIS}, - {"source", tSOURCE}, - {"strict_context_handle", tSTRICTCONTEXTHANDLE}, - {"string", tSTRING}, - {"switch_is", tSWITCHIS}, - {"switch_type", tSWITCHTYPE}, - {"threading", tTHREADING}, - {"transmit_as", tTRANSMITAS}, - {"uidefault", tUIDEFAULT}, - {"unique", tUNIQUE}, - {"user_marshal", tUSERMARSHAL}, - {"usesgetlasterror", tUSESGETLASTERROR}, - {"uuid", tUUID}, - {"v1_enum", tV1ENUM}, - {"vararg", tVARARG}, - {"version", tVERSION}, - {"vi_progid", tVIPROGID}, - {"wire_marshal", tWIREMARSHAL}, + {"aggregatable", tAGGREGATABLE, 0}, + {"allocate", tALLOCATE, 0}, + {"annotation", tANNOTATION, 0}, + {"apartment", tAPARTMENT, 0}, + {"appobject", tAPPOBJECT, 0}, + {"async", tASYNC, 0}, + {"async_uuid", tASYNCUUID, 0}, + {"auto_handle", tAUTOHANDLE, 0}, + {"bindable", tBINDABLE, 0}, + {"both", tBOTH, 0}, + {"broadcast", tBROADCAST, 0}, + {"byte_count", tBYTECOUNT, 0}, + {"call_as", tCALLAS, 0}, + {"callback", tCALLBACK, 0}, + {"code", tCODE, 0}, + {"comm_status", tCOMMSTATUS, 0}, + {"context_handle", tCONTEXTHANDLE, 0}, + {"context_handle_noserialize", tCONTEXTHANDLENOSERIALIZE, 0}, + {"context_handle_serialize", tCONTEXTHANDLENOSERIALIZE, 0}, + {"control", tCONTROL, 0}, + {"decode", tDECODE, 0}, + {"defaultbind", tDEFAULTBIND, 0}, + {"defaultcollelem", tDEFAULTCOLLELEM, 0}, + {"defaultvalue", tDEFAULTVALUE, 0}, + {"defaultvtable", tDEFAULTVTABLE, 0}, + {"disable_consistency_check", tDISABLECONSISTENCYCHECK, 0}, + {"displaybind", tDISPLAYBIND, 0}, + {"dllname", tDLLNAME, 0}, + {"dual", tDUAL, 0}, + {"enable_allocate", tENABLEALLOCATE, 0}, + {"encode", tENCODE, 0}, + {"endpoint", tENDPOINT, 0}, + {"entry", tENTRY, 0}, + {"explicit_handle", tEXPLICITHANDLE, 0}, + {"fault_status", tFAULTSTATUS, 0}, + {"force_allocate", tFORCEALLOCATE, 0}, + {"free", tFREE, 0}, + {"handle", tHANDLE, 0}, + {"helpcontext", tHELPCONTEXT, 0}, + {"helpfile", tHELPFILE, 0}, + {"helpstring", tHELPSTRING, 0}, + {"helpstringcontext", tHELPSTRINGCONTEXT, 0}, + {"helpstringdll", tHELPSTRINGDLL, 0}, + {"hidden", tHIDDEN, 0}, + {"id", tID, 0}, + {"idempotent", tIDEMPOTENT, 0}, + {"ignore", tIGNORE, 0}, + {"iid_is", tIIDIS, 0}, + {"immediatebind", tIMMEDIATEBIND, 0}, + {"implicit_handle", tIMPLICITHANDLE, 0}, + {"in", tIN, 0}, + {"in_line", tIN_LINE, 0}, + {"input_sync", tINPUTSYNC, 0}, + {"lcid", tLCID, 0}, + {"length_is", tLENGTHIS, 0}, + {"licensed", tLICENSED, 0}, + {"local", tLOCAL, 0}, + {"maybe", tMAYBE, 0}, + {"message", tMESSAGE, 0}, + {"neutral", tNEUTRAL, 0}, + {"nocode", tNOCODE, 0}, + {"nonbrowsable", tNONBROWSABLE, 0}, + {"noncreatable", tNONCREATABLE, 0}, + {"nonextensible", tNONEXTENSIBLE, 0}, + {"notify", tNOTIFY, 0}, + {"notify_flag", tNOTIFYFLAG, 0}, + {"object", tOBJECT, 0}, + {"odl", tODL, 0}, + {"oleautomation", tOLEAUTOMATION, 0}, + {"optimize", tOPTIMIZE, 0}, + {"optional", tOPTIONAL, 0}, + {"out", tOUT, 0}, + {"partial_ignore", tPARTIALIGNORE, 0}, + {"pointer_default", tPOINTERDEFAULT, 0}, + {"progid", tPROGID, 0}, + {"propget", tPROPGET, 0}, + {"propput", tPROPPUT, 0}, + {"propputref", tPROPPUTREF, 0}, + {"proxy", tPROXY, 0}, + {"ptr", tPTR, 0}, + {"public", tPUBLIC, 0}, + {"range", tRANGE, 0}, + {"readonly", tREADONLY, 0}, + {"ref", tREF, 0}, + {"represent_as", tREPRESENTAS, 0}, + {"requestedit", tREQUESTEDIT, 0}, + {"restricted", tRESTRICTED, 0}, + {"retval", tRETVAL, 0}, + {"single", tSINGLE, 0}, + {"size_is", tSIZEIS, 0}, + {"source", tSOURCE, 0}, + {"strict_context_handle", tSTRICTCONTEXTHANDLE, 0}, + {"string", tSTRING, 0}, + {"switch_is", tSWITCHIS, 0}, + {"switch_type", tSWITCHTYPE, 0}, + {"threading", tTHREADING, 0}, + {"transmit_as", tTRANSMITAS, 0}, + {"uidefault", tUIDEFAULT, 0}, + {"unique", tUNIQUE, 0}, + {"user_marshal", tUSERMARSHAL, 0}, + {"usesgetlasterror", tUSESGETLASTERROR, 0}, + {"uuid", tUUID, 0}, + {"v1_enum", tV1ENUM, 0}, + {"vararg", tVARARG, 0}, + {"version", tVERSION, 0}, + {"vi_progid", tVIPROGID, 0}, + {"wire_marshal", tWIREMARSHAL, 0}, };
/* attributes TODO: @@ -446,7 +447,7 @@ static int kw_token(const char *kw) struct keyword key, *kwp; key.kw = kw; kwp = bsearch(&key, keywords, NKEYWORDS, sizeof(keywords[0]), kw_cmp_func); - if (kwp && (winrt_mode || kwp->token != tNAMESPACE)) { + if (kwp && (!kwp->winrt_only || winrt_mode)) { parser_lval.str = xstrdup(kwp->kw); return kwp->token; } @@ -460,7 +461,7 @@ static int attr_token(const char *kw) key.kw = kw; kwp = bsearch(&key, attr_keywords, sizeof(attr_keywords)/sizeof(attr_keywords[0]), sizeof(attr_keywords[0]), kw_cmp_func); - if (kwp) { + if (kwp && (!kwp->winrt_only || winrt_mode)) { parser_lval.str = xstrdup(kwp->kw); return kwp->token; }
MIDL doesn't generate anything special in the header files for these types. They can however be used instead of interfaces as function arguments or type parameters, but pointer to their default interface type is instead used in the generated code.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
It also doesn't seem that MIDL WinRT mode supports generating typelib. Instead, it has some new .winmd metadata files, that we don't support for now.
include/windows.media.speechsynthesis.idl | 10 + tools/widl/expr.c | 1 + tools/widl/header.c | 33 ++- tools/widl/parser.l | 1 + tools/widl/parser.y | 253 +++++++++++++--------- tools/widl/typegen.c | 4 + tools/widl/typelib.c | 1 + tools/widl/typetree.c | 17 ++ tools/widl/typetree.h | 24 ++ tools/widl/widltypes.h | 7 + 10 files changed, 244 insertions(+), 107 deletions(-)
diff --git a/include/windows.media.speechsynthesis.idl b/include/windows.media.speechsynthesis.idl index a0a4c9cbf50..9173f981958 100644 --- a/include/windows.media.speechsynthesis.idl +++ b/include/windows.media.speechsynthesis.idl @@ -29,6 +29,7 @@ namespace Windows { typedef enum VoiceGender VoiceGender; interface IInstalledVoicesStatic; interface IVoiceInformation; + runtimeclass VoiceInformation; } } } @@ -56,6 +57,15 @@ namespace Windows { [propget] HRESULT Description([out] [retval] HSTRING* value); [propget] HRESULT Gender([out] [retval] VoiceGender* value); } + + [ + /* contract(Windows.Foundation.UniversalApiContract, 1.0), */ + /* marshaling_behavior(agile) */ + ] + runtimeclass VoiceInformation + { + [default] interface IVoiceInformation; + } } } } diff --git a/tools/widl/expr.c b/tools/widl/expr.c index d1ee599a39e..36a396bcc59 100644 --- a/tools/widl/expr.c +++ b/tools/widl/expr.c @@ -460,6 +460,7 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type, case TYPE_COCLASS: case TYPE_INTERFACE: case TYPE_POINTER: + case TYPE_RUNTIMECLASS: case TYPE_ARRAY: case TYPE_BITFIELD: /* nothing to do */ diff --git a/tools/widl/header.c b/tools/widl/header.c index 743d86f0ee9..05416f2f911 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -454,6 +454,9 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i case TYPE_COCLASS: fprintf(h, "%s", name); break; + case TYPE_RUNTIMECLASS: + fprintf(h, "%s", type_get_name(type_runtimeclass_get_default_iface(t), name_type)); + break; case TYPE_VOID: fprintf(h, "void"); break; @@ -528,6 +531,7 @@ void write_type_right(FILE *h, type_t *t, int is_field) case TYPE_MODULE: case TYPE_COCLASS: case TYPE_INTERFACE: + case TYPE_RUNTIMECLASS: break; } } @@ -1005,7 +1009,8 @@ static int is_aggregate_return(const var_t *func) { enum type_type type = type_get_type(type_function_get_rettype(func->declspec.type)); return type == TYPE_STRUCT || type == TYPE_UNION || - type == TYPE_COCLASS || type == TYPE_INTERFACE; + type == TYPE_COCLASS || type == TYPE_INTERFACE || + type == TYPE_RUNTIMECLASS; }
static char *get_vtbl_entry_name(const type_t *iface, const var_t *func) @@ -1610,6 +1615,28 @@ static void write_coclass_forward(FILE *header, type_t *cocl) fprintf(header, "#endif /* defined __%s_FWD_DEFINED__ */\n\n", cocl->name ); }
+static void write_runtimeclass(FILE *header, type_t *runtimeclass) +{ + fprintf(header, "/*****************************************************************************\n"); + fprintf(header, " * %s runtimeclass\n", runtimeclass->name); + fprintf(header, " */\n\n"); + fprintf(header, "\n"); +} + +static void write_runtimeclass_forward(FILE *header, type_t *runtimeclass) +{ + fprintf(header, "#ifndef __%s_FWD_DEFINED__\n", runtimeclass->c_name); + fprintf(header, "#define __%s_FWD_DEFINED__\n", runtimeclass->c_name); + fprintf(header, "#ifdef __cplusplus\n"); + write_namespace_start(header, runtimeclass->namespace); + write_line(header, 0, "class %s;", runtimeclass->name); + write_namespace_end(header, runtimeclass->namespace); + fprintf(header, "#else\n"); + fprintf(header, "typedef struct %s %s;\n", runtimeclass->c_name, runtimeclass->c_name); + fprintf(header, "#endif /* defined __cplusplus */\n"); + fprintf(header, "#endif /* defined __%s_FWD_DEFINED__ */\n\n", runtimeclass->c_name); +} + static void write_import(FILE *header, const char *fname) { char *hname, *p; @@ -1674,6 +1701,8 @@ static void write_forward_decls(FILE *header, const statement_list_t *stmts) } else if (type_get_type(stmt->u.type) == TYPE_COCLASS) write_coclass_forward(header, stmt->u.type); + else if (type_get_type(stmt->u.type) == TYPE_RUNTIMECLASS) + write_runtimeclass_forward(header, stmt->u.type); break; case STMT_TYPEREF: case STMT_IMPORTLIB: @@ -1728,6 +1757,8 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons } else if (type_get_type(stmt->u.type) == TYPE_COCLASS) write_coclass(header, stmt->u.type); + else if (type_get_type(stmt->u.type) == TYPE_RUNTIMECLASS) + write_runtimeclass(header, stmt->u.type); else { write_type_definition(header, stmt->u.type, stmt->declonly); diff --git a/tools/widl/parser.l b/tools/widl/parser.l index eb1782d32f5..1223c6422db 100644 --- a/tools/widl/parser.l +++ b/tools/widl/parser.l @@ -297,6 +297,7 @@ static const struct keyword keywords[] = { {"pascal", tPASCAL, 0}, {"properties", tPROPERTIES, 0}, {"register", tREGISTER, 0}, + {"runtimeclass", tRUNTIMECLASS, 1}, {"short", tSHORT, 0}, {"signed", tSIGNED, 0}, {"sizeof", tSIZEOF, 0}, diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 5bc0d82703e..f20c9845ffb 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -99,6 +99,7 @@ static attr_list_t *check_library_attrs(const char *name, attr_list_t *attrs); static attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs); static attr_list_t *check_module_attrs(const char *name, attr_list_t *attrs); static attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs); +static attr_list_t *check_runtimeclass_attrs(const char *name, attr_list_t *attrs); const char *get_attr_display_name(enum attr_type type); static void add_explicit_handle_if_necessary(const type_t *iface, var_t *func); static void check_def(const type_t *t); @@ -233,6 +234,7 @@ static typelib_t *current_typelib; %token tREQUESTEDIT %token tRESTRICTED %token tRETVAL +%token tRUNTIMECLASS %token tSAFEARRAY %token tSHORT %token tSIGNED @@ -276,8 +278,8 @@ static typelib_t *current_typelib; %type <type> base_type int_std %type <type> enumdef structdef uniondef typedecl %type <type> type qualified_seq qualified_type -%type <ifref> coclass_int -%type <ifref_list> coclass_ints +%type <ifref> class_interface +%type <ifref_list> class_interfaces %type <var> arg ne_union_field union_field s_field case enum enum_member declaration %type <var> funcdef %type <var_list> m_args arg_list args dispint_meths @@ -288,6 +290,7 @@ static typelib_t *current_typelib; %type <declarator> m_abstract_declarator abstract_declarator abstract_declarator_no_direct abstract_direct_declarator %type <declarator_list> declarator_list struct_declarator_list %type <type> coclass coclasshdr coclassdef +%type <type> runtimeclass runtimeclass_hdr runtimeclass_def %type <num> pointer_type threading_type version %type <str> libraryhdr callconv cppquote importlib import t_ident %type <uuid> uuid_string @@ -343,6 +346,9 @@ gbl_statements: { $$ = NULL; } | gbl_statements coclassdef { $$ = append_statement($1, make_statement_type_decl($2)); reg_type($2, $2->name, current_namespace, 0); } + | gbl_statements runtimeclass ';' { $$ = $1; reg_type($2, $2->name, current_namespace, 0); } + | gbl_statements runtimeclass_def { $$ = append_statement($1, make_statement_type_decl($2)); + reg_type($2, $2->name, current_namespace, 0); } | gbl_statements moduledef { $$ = append_statement($1, make_statement_module($2)); } | gbl_statements librarydef { $$ = append_statement($1, make_statement_library($2)); } | gbl_statements statement { $$ = append_statement($1, $2); } @@ -357,6 +363,9 @@ imp_statements: { $$ = NULL; } | imp_statements coclassdef { $$ = append_statement($1, make_statement_type_decl($2)); reg_type($2, $2->name, current_namespace, 0); } + | imp_statements runtimeclass ';' { $$ = $1; reg_type($2, $2->name, current_namespace, 0); } + | imp_statements runtimeclass_def { $$ = append_statement($1, make_statement_type_decl($2)); + reg_type($2, $2->name, current_namespace, 0); } | imp_statements moduledef { $$ = append_statement($1, make_statement_module($2)); } | imp_statements statement { $$ = append_statement($1, $2); } | imp_statements importlib { $$ = append_statement($1, make_statement_importlib($2)); } @@ -851,19 +860,38 @@ coclasshdr: attributes coclass { $$ = $2; } ;
-coclassdef: coclasshdr '{' coclass_ints '}' semicolon_opt +coclassdef: coclasshdr '{' class_interfaces '}' semicolon_opt { $$ = type_coclass_define($1, $3); } ;
+runtimeclass: + tRUNTIMECLASS aIDENTIFIER { $$ = type_new_runtimeclass($2, current_namespace); } + | tRUNTIMECLASS aKNOWNTYPE { $$ = find_type($2, NULL, 0); + if (type_get_type_detect_alias($$) != TYPE_RUNTIMECLASS) + error_loc("%s was not declared a runtimeclass at %s:%d\n", $2, + $$->loc_info.input_name, $$->loc_info.line_number); + } + ; + +runtimeclass_hdr: attributes runtimeclass { $$ = $2; + check_def($$); + $$->attrs = check_runtimeclass_attrs($2->name, $1); + } + ; + +runtimeclass_def: runtimeclass_hdr '{' class_interfaces '}' semicolon_opt + { $$ = type_runtimeclass_define($1, $3); } + ; + namespacedef: tNAMESPACE aIDENTIFIER { $$ = $2; } | tNAMESPACE aNAMESPACE { $$ = $2; } ;
-coclass_ints: { $$ = NULL; } - | coclass_ints coclass_int { $$ = append_ifref( $1, $2 ); } +class_interfaces: { $$ = NULL; } + | class_interfaces class_interface { $$ = append_ifref( $1, $2 ); } ;
-coclass_int: +class_interface: m_attributes interfacedec { $$ = make_ifref($2); $$->attrs = $1; } ;
@@ -2115,111 +2143,112 @@ struct allowed_attr unsigned int on_dispinterface : 1; unsigned int on_module : 1; unsigned int on_coclass : 1; + unsigned int on_runtimeclass : 1; const char *display_name; };
struct allowed_attr allowed_attr[] = { - /* attr { D ACF I Fn ARG T En Enm St Un Fi L DI M C <display name> } */ - /* ATTR_AGGREGATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "aggregatable" }, - /* ATTR_ANNOTATION */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "annotation" }, - /* ATTR_APPOBJECT */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "appobject" }, - /* ATTR_ASYNC */ { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "async" }, - /* ATTR_ASYNCUUID */ { 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, "async_uuid" }, - /* ATTR_AUTO_HANDLE */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "auto_handle" }, - /* ATTR_BINDABLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "bindable" }, - /* ATTR_BROADCAST */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "broadcast" }, - /* ATTR_CALLAS */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "call_as" }, - /* ATTR_CALLCONV */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL }, - /* ATTR_CASE */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "case" }, - /* ATTR_CODE */ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" }, - /* ATTR_COMMSTATUS */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" }, - /* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" }, - /* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, "control" }, - /* ATTR_DECODE */ { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "decode" }, - /* ATTR_DEFAULT */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, "default" }, - /* ATTR_DEFAULTBIND */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultbind" }, - /* ATTR_DEFAULTCOLLELEM */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultcollelem" }, - /* ATTR_DEFAULTVALUE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultvalue" }, - /* ATTR_DEFAULTVTABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "defaultvtable" }, - /* ATTR_DISABLECONSISTENCYCHECK */{ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "disable_consistency_check" }, - /* ATTR_DISPINTERFACE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL }, - /* ATTR_DISPLAYBIND */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "displaybind" }, - /* ATTR_DLLNAME */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "dllname" }, - /* ATTR_DUAL */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "dual" }, - /* ATTR_ENABLEALLOCATE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "enable_allocate" }, - /* ATTR_ENCODE */ { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "encode" }, - /* ATTR_ENDPOINT */ { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "endpoint" }, - /* ATTR_ENTRY */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "entry" }, - /* ATTR_EXPLICIT_HANDLE */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "explicit_handle" }, - /* ATTR_FAULTSTATUS */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "fault_status" }, - /* ATTR_FORCEALLOCATE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "force_allocate" }, - /* ATTR_HANDLE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "handle" }, - /* ATTR_HELPCONTEXT */ { 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, "helpcontext" }, - /* ATTR_HELPFILE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "helpfile" }, - /* ATTR_HELPSTRING */ { 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, "helpstring" }, - /* ATTR_HELPSTRINGCONTEXT */ { 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, "helpstringcontext" }, - /* ATTR_HELPSTRINGDLL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "helpstringdll" }, - /* ATTR_HIDDEN */ { 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, "hidden" }, - /* ATTR_ID */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, "id" }, - /* ATTR_IDEMPOTENT */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "idempotent" }, - /* ATTR_IGNORE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "ignore" }, - /* ATTR_IIDIS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "iid_is" }, - /* ATTR_IMMEDIATEBIND */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "immediatebind" }, - /* ATTR_IMPLICIT_HANDLE */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" }, - /* ATTR_IN */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "in" }, - /* ATTR_INPUTSYNC */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" }, - /* ATTR_LENGTHIS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "length_is" }, - /* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "lcid" }, - /* ATTR_LICENSED */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "licensed" }, - /* ATTR_LOCAL */ { 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "local" }, - /* ATTR_MAYBE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "maybe" }, - /* ATTR_MESSAGE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "message" }, - /* ATTR_NOCODE */ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nocode" }, - /* ATTR_NONBROWSABLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonbrowsable" }, - /* ATTR_NONCREATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "noncreatable" }, - /* ATTR_NONEXTENSIBLE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonextensible" }, - /* ATTR_NOTIFY */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify" }, - /* ATTR_NOTIFYFLAG */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify_flag" }, - /* ATTR_OBJECT */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "object" }, - /* ATTR_ODL */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "odl" }, - /* ATTR_OLEAUTOMATION */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "oleautomation" }, - /* ATTR_OPTIMIZE */ { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optimize" }, - /* ATTR_OPTIONAL */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optional" }, - /* ATTR_OUT */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "out" }, - /* ATTR_PARAMLCID */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "lcid" }, - /* ATTR_PARTIALIGNORE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "partial_ignore" }, - /* ATTR_POINTERDEFAULT */ { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "pointer_default" }, - /* ATTR_POINTERTYPE */ { 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, "ref, unique or ptr" }, - /* ATTR_PROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "progid" }, - /* ATTR_PROPGET */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propget" }, - /* ATTR_PROPPUT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propput" }, - /* ATTR_PROPPUTREF */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propputref" }, - /* ATTR_PROXY */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "proxy" }, - /* ATTR_PUBLIC */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "public" }, - /* ATTR_RANGE */ { 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, "range" }, - /* ATTR_READONLY */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "readonly" }, - /* ATTR_REPRESENTAS */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "represent_as" }, - /* ATTR_REQUESTEDIT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "requestedit" }, - /* ATTR_RESTRICTED */ { 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, "restricted" }, - /* ATTR_RETVAL */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "retval" }, - /* ATTR_SIZEIS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "size_is" }, - /* ATTR_SOURCE */ { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "source" }, - /* ATTR_STRICTCONTEXTHANDLE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "strict_context_handle" }, - /* ATTR_STRING */ { 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, "string" }, - /* ATTR_SWITCHIS */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "switch_is" }, - /* ATTR_SWITCHTYPE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, "switch_type" }, - /* ATTR_THREADING */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "threading" }, - /* ATTR_TRANSMITAS */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "transmit_as" }, - /* ATTR_UIDEFAULT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "uidefault" }, - /* ATTR_USESGETLASTERROR */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "usesgetlasterror" }, - /* ATTR_USERMARSHAL */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "user_marshal" }, - /* ATTR_UUID */ { 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, "uuid" }, - /* ATTR_V1ENUM */ { 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, "v1_enum" }, - /* ATTR_VARARG */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "vararg" }, - /* ATTR_VERSION */ { 1, 0, 1, 0, 0, 1, 1, 0, 2, 0, 0, 1, 0, 0, 1, "version" }, - /* ATTR_VIPROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "vi_progid" }, - /* ATTR_WIREMARSHAL */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "wire_marshal" }, + /* attr { D ACF I Fn ARG T En Enm St Un Fi L DI M C R <display name> } */ + /* ATTR_AGGREGATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "aggregatable" }, + /* ATTR_ANNOTATION */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "annotation" }, + /* ATTR_APPOBJECT */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "appobject" }, + /* ATTR_ASYNC */ { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "async" }, + /* ATTR_ASYNCUUID */ { 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, "async_uuid" }, + /* ATTR_AUTO_HANDLE */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "auto_handle" }, + /* ATTR_BINDABLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "bindable" }, + /* ATTR_BROADCAST */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "broadcast" }, + /* ATTR_CALLAS */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "call_as" }, + /* ATTR_CALLCONV */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL }, + /* ATTR_CASE */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "case" }, + /* ATTR_CODE */ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" }, + /* ATTR_COMMSTATUS */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" }, + /* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" }, + /* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, "control" }, + /* ATTR_DECODE */ { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "decode" }, + /* ATTR_DEFAULT */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, "default" }, + /* ATTR_DEFAULTBIND */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultbind" }, + /* ATTR_DEFAULTCOLLELEM */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultcollelem" }, + /* ATTR_DEFAULTVALUE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultvalue" }, + /* ATTR_DEFAULTVTABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "defaultvtable" }, + /* ATTR_DISABLECONSISTENCYCHECK */{ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "disable_consistency_check" }, + /* ATTR_DISPINTERFACE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL }, + /* ATTR_DISPLAYBIND */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "displaybind" }, + /* ATTR_DLLNAME */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "dllname" }, + /* ATTR_DUAL */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "dual" }, + /* ATTR_ENABLEALLOCATE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "enable_allocate" }, + /* ATTR_ENCODE */ { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "encode" }, + /* ATTR_ENDPOINT */ { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "endpoint" }, + /* ATTR_ENTRY */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "entry" }, + /* ATTR_EXPLICIT_HANDLE */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "explicit_handle" }, + /* ATTR_FAULTSTATUS */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "fault_status" }, + /* ATTR_FORCEALLOCATE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "force_allocate" }, + /* ATTR_HANDLE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "handle" }, + /* ATTR_HELPCONTEXT */ { 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, "helpcontext" }, + /* ATTR_HELPFILE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "helpfile" }, + /* ATTR_HELPSTRING */ { 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, "helpstring" }, + /* ATTR_HELPSTRINGCONTEXT */ { 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, "helpstringcontext" }, + /* ATTR_HELPSTRINGDLL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "helpstringdll" }, + /* ATTR_HIDDEN */ { 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, "hidden" }, + /* ATTR_ID */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, "id" }, + /* ATTR_IDEMPOTENT */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "idempotent" }, + /* ATTR_IGNORE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "ignore" }, + /* ATTR_IIDIS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "iid_is" }, + /* ATTR_IMMEDIATEBIND */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "immediatebind" }, + /* ATTR_IMPLICIT_HANDLE */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" }, + /* ATTR_IN */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "in" }, + /* ATTR_INPUTSYNC */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" }, + /* ATTR_LENGTHIS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "length_is" }, + /* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "lcid" }, + /* ATTR_LICENSED */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "licensed" }, + /* ATTR_LOCAL */ { 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "local" }, + /* ATTR_MAYBE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "maybe" }, + /* ATTR_MESSAGE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "message" }, + /* ATTR_NOCODE */ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nocode" }, + /* ATTR_NONBROWSABLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonbrowsable" }, + /* ATTR_NONCREATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "noncreatable" }, + /* ATTR_NONEXTENSIBLE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonextensible" }, + /* ATTR_NOTIFY */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify" }, + /* ATTR_NOTIFYFLAG */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify_flag" }, + /* ATTR_OBJECT */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "object" }, + /* ATTR_ODL */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "odl" }, + /* ATTR_OLEAUTOMATION */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "oleautomation" }, + /* ATTR_OPTIMIZE */ { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optimize" }, + /* ATTR_OPTIONAL */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optional" }, + /* ATTR_OUT */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "out" }, + /* ATTR_PARAMLCID */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "lcid" }, + /* ATTR_PARTIALIGNORE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "partial_ignore" }, + /* ATTR_POINTERDEFAULT */ { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "pointer_default" }, + /* ATTR_POINTERTYPE */ { 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "ref, unique or ptr" }, + /* ATTR_PROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "progid" }, + /* ATTR_PROPGET */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propget" }, + /* ATTR_PROPPUT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propput" }, + /* ATTR_PROPPUTREF */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propputref" }, + /* ATTR_PROXY */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "proxy" }, + /* ATTR_PUBLIC */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "public" }, + /* ATTR_RANGE */ { 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, "range" }, + /* ATTR_READONLY */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "readonly" }, + /* ATTR_REPRESENTAS */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "represent_as" }, + /* ATTR_REQUESTEDIT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "requestedit" }, + /* ATTR_RESTRICTED */ { 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, "restricted" }, + /* ATTR_RETVAL */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "retval" }, + /* ATTR_SIZEIS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "size_is" }, + /* ATTR_SOURCE */ { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "source" }, + /* ATTR_STRICTCONTEXTHANDLE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "strict_context_handle" }, + /* ATTR_STRING */ { 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "string" }, + /* ATTR_SWITCHIS */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "switch_is" }, + /* ATTR_SWITCHTYPE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "switch_type" }, + /* ATTR_THREADING */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, "threading" }, + /* ATTR_TRANSMITAS */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "transmit_as" }, + /* ATTR_UIDEFAULT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "uidefault" }, + /* ATTR_USESGETLASTERROR */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "usesgetlasterror" }, + /* ATTR_USERMARSHAL */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "user_marshal" }, + /* ATTR_UUID */ { 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, "uuid" }, + /* ATTR_V1ENUM */ { 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "v1_enum" }, + /* ATTR_VARARG */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "vararg" }, + /* ATTR_VERSION */ { 1, 0, 1, 0, 0, 1, 1, 0, 2, 0, 0, 1, 0, 0, 1, 1, "version" }, + /* ATTR_VIPROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "vi_progid" }, + /* ATTR_WIREMARSHAL */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "wire_marshal" }, };
const char *get_attr_display_name(enum attr_type type) @@ -2410,6 +2439,17 @@ static attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs) return attrs; }
+static attr_list_t *check_runtimeclass_attrs(const char *name, attr_list_t *attrs) +{ + const attr_t *attr; + if (!attrs) return attrs; + LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry) + if (!allowed_attr[attr->type].on_runtimeclass) + error_loc("inapplicable attribute %s for runtimeclass %s\n", + allowed_attr[attr->type].display_name, name); + return attrs; +} + static int is_allowed_conf_type(const type_t *type) { switch (type_get_type(type)) @@ -2445,6 +2485,7 @@ static int is_allowed_conf_type(const type_t *type) case TYPE_VOID: case TYPE_MODULE: case TYPE_COCLASS: + case TYPE_RUNTIMECLASS: case TYPE_FUNCTION: case TYPE_INTERFACE: case TYPE_BITFIELD: diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c index 04280cbb722..425b65942de 100644 --- a/tools/widl/typegen.c +++ b/tools/widl/typegen.c @@ -353,6 +353,7 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att return TGT_ENUM; case TYPE_POINTER: if (type_get_type(type_pointer_get_ref_type(type)) == TYPE_INTERFACE || + type_get_type(type_pointer_get_ref_type(type)) == TYPE_RUNTIMECLASS || (type_get_type(type_pointer_get_ref_type(type)) == TYPE_VOID && is_attr(attrs, ATTR_IIDIS))) return TGT_IFACE_POINTER; else if (is_aliaschain_attr(type_pointer_get_ref_type(type), ATTR_CONTEXTHANDLE)) @@ -373,6 +374,7 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att case TYPE_VOID: case TYPE_ALIAS: case TYPE_BITFIELD: + case TYPE_RUNTIMECLASS: break; } return TGT_INVALID; @@ -1966,6 +1968,7 @@ unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *align) case TYPE_MODULE: case TYPE_FUNCTION: case TYPE_BITFIELD: + case TYPE_RUNTIMECLASS: /* these types should not be encountered here due to language * restrictions (interface, void, coclass, module), logical * restrictions (alias - due to type_get_type call above) or @@ -2067,6 +2070,7 @@ static unsigned int type_buffer_alignment(const type_t *t) case TYPE_MODULE: case TYPE_FUNCTION: case TYPE_BITFIELD: + case TYPE_RUNTIMECLASS: /* these types should not be encountered here due to language * restrictions (interface, void, coclass, module), logical * restrictions (alias - due to type_get_type call above) or diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c index cf027558d0a..7b946319a72 100644 --- a/tools/widl/typelib.c +++ b/tools/widl/typelib.c @@ -218,6 +218,7 @@ unsigned short get_type_vt(type_t *t) case TYPE_MODULE: case TYPE_UNION: case TYPE_ENCAPSULATED_UNION: + case TYPE_RUNTIMECLASS: return VT_USERDEFINED;
case TYPE_VOID: diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c index e9afc6fdd28..76bb06c2b39 100644 --- a/tools/widl/typetree.c +++ b/tools/widl/typetree.c @@ -215,6 +215,16 @@ type_t *type_new_coclass(char *name) return type; }
+type_t *type_new_runtimeclass(char *name, struct namespace *namespace) +{ + type_t *type = get_type(TYPE_RUNTIMECLASS, name, NULL, 0); + if (type->type_type != TYPE_RUNTIMECLASS || type->defined) + error_loc("%s: redefinition error; original definition was at %s:%d\n", + type->name, type->loc_info.input_name, type->loc_info.line_number); + type->name = name; + type->namespace = namespace; + return type; +}
type_t *type_new_array(const char *name, const decl_spec_t *element, int declptr, unsigned int dim, expr_t *size_is, expr_t *length_is) @@ -509,6 +519,13 @@ type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces) return coclass; }
+type_t *type_runtimeclass_define(type_t *runtimeclass, ifref_list_t *ifaces) +{ + runtimeclass->details.runtimeclass.ifaces = ifaces; + runtimeclass->defined = TRUE; + return runtimeclass; +} + int type_is_equal(const type_t *type1, const type_t *type2) { if (type_get_type_detect_alias(type1) != type_get_type_detect_alias(type2)) diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h index e288c574002..c6dd38f0d9c 100644 --- a/tools/widl/typetree.h +++ b/tools/widl/typetree.h @@ -44,11 +44,13 @@ type_t *type_new_struct(char *name, struct namespace *namespace, int defined, va type_t *type_new_nonencapsulated_union(const char *name, int defined, var_list_t *fields); type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases); type_t *type_new_bitfield(type_t *field_type, const expr_t *bits); +type_t *type_new_runtimeclass(char *name, struct namespace *namespace); void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts); void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *methods); void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface); void type_module_define(type_t *module, statement_list_t *stmts); type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces); +type_t *type_runtimeclass_define(type_t *runtimeclass, ifref_list_t *ifaces); int type_is_equal(const type_t *type1, const type_t *type2); const char *type_get_name(const type_t *type, enum name_type name_type); char *gen_name(void); @@ -222,6 +224,7 @@ static inline int type_is_complete(const type_t *type) case TYPE_POINTER: case TYPE_ARRAY: case TYPE_BITFIELD: + case TYPE_RUNTIMECLASS: return TRUE; } return FALSE; @@ -319,6 +322,27 @@ static inline ifref_list_t *type_coclass_get_ifaces(const type_t *type) return type->details.coclass.ifaces; }
+static inline ifref_list_t *type_runtimeclass_get_ifaces(const type_t *type) +{ + type = type_get_real_type(type); + assert(type_get_type(type) == TYPE_RUNTIMECLASS); + return type->details.runtimeclass.ifaces; +} + +static inline type_t *type_runtimeclass_get_default_iface(const type_t *type) +{ + ifref_list_t *ifaces = type_runtimeclass_get_ifaces(type); + ifref_t *entry; + attr_t *attr; + + LIST_FOR_EACH_ENTRY(entry, ifaces, ifref_t, entry) + LIST_FOR_EACH_ENTRY(attr, entry->attrs, attr_t, entry) + if (attr->type == ATTR_DEFAULT) return entry->iface; + + assert(0); + return NULL; +} + static inline const decl_spec_t *type_pointer_get_ref(const type_t *type) { type = type_get_real_type(type); diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index 085a0ff55f5..a5b4ffc7acb 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -405,6 +405,11 @@ struct alias_details struct _decl_spec_t aliasee; };
+struct runtimeclass_details +{ + ifref_list_t *ifaces; +}; + #define HASHMAX 64
struct namespace { @@ -431,6 +436,7 @@ enum type_type TYPE_POINTER, TYPE_ARRAY, TYPE_BITFIELD, + TYPE_RUNTIMECLASS, };
struct _type_t { @@ -451,6 +457,7 @@ struct _type_t { struct pointer_details pointer; struct bitfield_details bitfield; struct alias_details alias; + struct runtimeclass_details runtimeclass; } details; const char *c_name; unsigned int typestring_offset;
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- include/windows.media.speechsynthesis.idl | 2 +- tools/widl/parser.y | 21 +++++++++++++-------- 2 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/include/windows.media.speechsynthesis.idl b/include/windows.media.speechsynthesis.idl index 9173f981958..9566697b42a 100644 --- a/include/windows.media.speechsynthesis.idl +++ b/include/windows.media.speechsynthesis.idl @@ -64,7 +64,7 @@ namespace Windows { ] runtimeclass VoiceInformation { - [default] interface IVoiceInformation; + [default] interface Windows.Media.SpeechSynthesis.IVoiceInformation; } } } diff --git a/tools/widl/parser.y b/tools/widl/parser.y index f20c9845ffb..8149b0c7ad9 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -277,7 +277,7 @@ static typelib_t *current_typelib; %type <str> namespacedef %type <type> base_type int_std %type <type> enumdef structdef uniondef typedecl -%type <type> type qualified_seq qualified_type +%type <type> type qualified_type %type <ifref> class_interface %type <ifref_list> class_interfaces %type <var> arg ne_union_field union_field s_field case enum enum_member declaration @@ -835,15 +835,19 @@ int_std: tINT { $$ = type_new_int(TYPE_BASIC_INT, 0); } | tINT3264 { $$ = type_new_int(TYPE_BASIC_INT3264, 0); } ;
-qualified_seq: - aKNOWNTYPE { $$ = find_type_or_error($1, 0); } - | aIDENTIFIER '.' { push_lookup_namespace($1); } qualified_seq { $$ = $4; } - ; +namespace_seq: + | aIDENTIFIER '.' { push_lookup_namespace($1); } namespace_seq + | aNAMESPACE '.' { push_lookup_namespace($1); } namespace_seq + ; + +namespace_qual: + aNAMESPACE '.' { init_lookup_namespace($1); } namespace_seq + ;
qualified_type: - aKNOWNTYPE { $$ = find_type_or_error($1, 0); } - | aNAMESPACE '.' { init_lookup_namespace($1); } qualified_seq { $$ = $4; } - ; + aKNOWNTYPE { $$ = find_type_or_error($1, 0); } + | namespace_qual aKNOWNTYPE { $$ = find_type_or_error($2, 0); } + ;
coclass: tCOCLASS aIDENTIFIER { $$ = type_new_coclass($2); } | tCOCLASS aKNOWNTYPE { $$ = find_type($2, NULL, 0); @@ -934,6 +938,7 @@ inherit: { $$ = NULL; }
interface: tINTERFACE aIDENTIFIER { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); } | tINTERFACE aKNOWNTYPE { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); } + | tINTERFACE namespace_qual aKNOWNTYPE { $$ = get_type(TYPE_INTERFACE, $3, lookup_namespace, 0); } ;
interfacehdr: attributes interface { $$ = $2;
The whole branch with some WinRT DLLs stubs using it is here:
https://gitlab.com/rbernon/wine/-/commits/wip/death-stranding/v1