Added widl-winrt-support patchset

This commit is contained in:
Alistair Leslie-Hughes 2020-10-14 17:33:30 +11:00
parent 3cea972271
commit ae8bdc6121
32 changed files with 6362 additions and 58 deletions

View File

@ -268,10 +268,9 @@ patch_enable_all ()
enable_uxtheme_GTK_Theming="$1"
enable_version_VerQueryValue="$1"
enable_widl_SLTG_Typelib_Support="$1"
enable_widl_winrt_support="$1"
enable_windows_gaming_input_dll="$1"
enable_windows_globalization_dll="$1"
enable_windows_media_speech_dll="$1"
enable_windows_networking_connectivity_dll="$1"
enable_windowscodecs_GIF_Encoder="$1"
enable_windowscodecs_TIFF_Support="$1"
enable_wine_inf_Directory_ContextMenuHandlers="$1"
@ -893,18 +892,15 @@ patch_enable ()
widl-SLTG_Typelib_Support)
enable_widl_SLTG_Typelib_Support="$2"
;;
widl-winrt-support)
enable_widl_winrt_support="$2"
;;
windows.gaming.input-dll)
enable_windows_gaming_input_dll="$2"
;;
windows.globalization-dll)
enable_windows_globalization_dll="$2"
;;
windows.media.speech.dll)
enable_windows_media_speech_dll="$2"
;;
windows.networking.connectivity.dll)
enable_windows_networking_connectivity_dll="$2"
;;
windowscodecs-GIF_Encoder)
enable_windowscodecs_GIF_Encoder="$2"
;;
@ -1455,20 +1451,6 @@ if test "$enable_wineboot_ProxySettings" -eq 1; then
enable_wineboot_drivers_etc_Stubs=1
fi
if test "$enable_windows_networking_connectivity_dll" -eq 1; then
if test "$enable_windows_globalization_dll" -gt 1; then
abort "Patchset windows.globalization-dll disabled, but windows.networking.connectivity.dll depends on that."
fi
enable_windows_globalization_dll=1
fi
if test "$enable_windows_globalization_dll" -eq 1; then
if test "$enable_windows_media_speech_dll" -gt 1; then
abort "Patchset windows.media.speech.dll disabled, but windows.globalization-dll depends on that."
fi
enable_windows_media_speech_dll=1
fi
if test "$enable_windows_media_speech_dll" -eq 1; then
if test "$enable_windows_gaming_input_dll" -gt 1; then
abort "Patchset windows.gaming.input-dll disabled, but windows.media.speech.dll depends on that."
@ -4332,6 +4314,48 @@ if test "$enable_version_VerQueryValue" -eq 1; then
patch_apply version-VerQueryValue/0001-version-Test-for-VerQueryValueA-try-2.patch
fi
# Patchset widl-winrt-support
# |
# | This patchset fixes the following Wine bugs:
# | * [#68403] widl - Support WinRT idls
# |
# | Modified files:
# | * include/Makefile.in, include/windows.foundation.idl, include/windows.media.speechsynthesis.idl,
# | include/windowscontracts.idl, tools/widl/expr.c, tools/widl/hash.c, tools/widl/hash.h, tools/widl/header.c,
# | tools/widl/parser.l, tools/widl/parser.y, tools/widl/typegen.c, tools/widl/typelib.c, tools/widl/typetree.c,
# | tools/widl/typetree.h, tools/widl/widltypes.h
# |
if test "$enable_widl_winrt_support" -eq 1; then
patch_apply widl-winrt-support/0001-include-Add-windows.media.speechsynthesis.idl-draft.patch
patch_apply widl-winrt-support/0002-widl-Restrict-some-keywords-to-WinRT-mode-only.patch
patch_apply widl-winrt-support/0003-widl-Introduce-format_namespace_buffer-helper.patch
patch_apply widl-winrt-support/0004-widl-Support-WinRT-contractversion-attribute-parsing.patch
patch_apply widl-winrt-support/0005-widl-Support-WinRT-apicontract-type.patch
patch_apply widl-winrt-support/0006-widl-Prefer-mangled-name-over-typedef-in-WinRT-mode.patch
patch_apply widl-winrt-support/0007-widl-Don-t-output-typedef-statement-in-WinRT-mode.patch
patch_apply widl-winrt-support/0008-widl-Support-WinRT-contract-attribute.patch
patch_apply widl-winrt-support/0009-widl-Support-WinRT-marshaling_behavior-attribute-par.patch
patch_apply widl-winrt-support/0010-widl-Support-WinRT-mta-threading-attribute-parsing.patch
patch_apply widl-winrt-support/0011-widl-Support-WinRT-exclusiveto-attribute-parsing.patch
patch_apply widl-winrt-support/0012-widl-Support-WinRT-runtimeclass-type.patch
patch_apply widl-winrt-support/0013-widl-Support-WinRT-eventadd-eventremove-attributes.patch
patch_apply widl-winrt-support/0014-widl-Support-WinRT-flags-attribute-parsing.patch
patch_apply widl-winrt-support/0015-widl-Support-using-qualified-names-for-interfaces.patch
patch_apply widl-winrt-support/0016-widl-Support-repeated-attributes-for-WinRT-static.patch
patch_apply widl-winrt-support/0017-widl-Support-WinRT-static-attribute-parsing.patch
patch_apply widl-winrt-support/0018-widl-Support-WinRT-requires-keyword.patch
patch_apply widl-winrt-support/0019-widl-Support-WinRT-activatable-attribute.patch
patch_apply widl-winrt-support/0020-widl-Support-WinRT-parameterized-type-parsing.patch
patch_apply widl-winrt-support/0021-widl-Support-partially-specialized-parameterized-typ.patch
patch_apply widl-winrt-support/0022-widl-Support-WinRT-parameterized-interface-type.patch
patch_apply widl-winrt-support/0023-widl-Support-WinRT-delegate-type.patch
patch_apply widl-winrt-support/0024-widl-Support-WinRT-parameterized-delegate-type.patch
patch_apply widl-winrt-support/0025-widl-Compute-signatures-for-parameterized-types.patch
patch_apply widl-winrt-support/0026-widl-Compute-uuids-for-parameterized-types.patch
patch_apply widl-winrt-support/0027-widl-Generate-helper-macros-for-WinRT-implementation.patch
patch_apply widl-winrt-support/0028-include-Add-IVectorView-HSTRING-declaration-to-windo.patch
fi
# Patchset windows.gaming.input-dll
# |
# | This patchset fixes the following Wine bugs:
@ -4364,42 +4388,6 @@ if test "$enable_windows_media_speech_dll" -eq 1; then
patch_apply windows.media.speech.dll/0001-windows.media.speech-Add-stub-dll.patch
fi
# Patchset windows.globalization-dll
# |
# | This patchset has the following (direct or indirect) dependencies:
# | * windows.gaming.input-dll, windows.media.speech.dll
# |
# | This patchset fixes the following Wine bugs:
# | * [#49740] windows.globalization: New DLL
# |
# | Modified files:
# | * configure.ac, dlls/windows.globalization.dll/Makefile.in, dlls/windows.globalization.dll/windows.globalization.spec,
# | dlls/windows.globalization.dll/windows.globalization_main.c, include/Makefile.in, include/windows.globalization.idl,
# | loader/wine.inf.in
# |
if test "$enable_windows_globalization_dll" -eq 1; then
patch_apply windows.globalization-dll/0001-windows.globalization-Add-stub-dll.patch
fi
# Patchset windows.networking.connectivity.dll
# |
# | This patchset has the following (direct or indirect) dependencies:
# | * windows.gaming.input-dll, windows.media.speech.dll, windows.globalization-dll
# |
# | This patchset fixes the following Wine bugs:
# | * [#46534] windows.networking.connectivity: New DLL
# |
# | Modified files:
# | * configure.ac, dlls/windows.networking.connectivity.dll/Makefile.in,
# | dlls/windows.networking.connectivity.dll/windows.networking.connectivity.spec,
# | dlls/windows.networking.connectivity.dll/windows.networking.connectivity_main.c, loader/wine.inf.in
# |
if test "$enable_windows_networking_connectivity_dll" -eq 1; then
patch_apply windows.networking.connectivity.dll/0001-windows.networking.connectivity-Add-stub-dll.patch
patch_apply windows.networking.connectivity.dll/0002-windows.networking.connectivity-Implement-IActivatio.patch
patch_apply windows.networking.connectivity.dll/0003-windows.networking.connectivity-Implement-INetworkIn.patch
fi
# Patchset windowscodecs-GIF_Encoder
# |
# | Modified files:

View File

@ -0,0 +1,69 @@
From 5dc312c4a09e51410c217919511b84323923607e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Wed, 23 Sep 2020 19:23:45 +0200
Subject: [PATCH 01/28] include: Add windows.media.speechsynthesis.idl draft.
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.
---
include/Makefile.in | 1 +
include/windows.media.speechsynthesis.idl | 34 +++++++++++++++++++++++
2 files changed, 35 insertions(+)
create mode 100644 include/windows.media.speechsynthesis.idl
diff --git a/include/Makefile.in b/include/Makefile.in
index 23306689cab..d59b0be715d 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -735,6 +735,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..d3dedfe0709
--- /dev/null
+++ b/include/windows.media.speechsynthesis.idl
@@ -0,0 +1,34 @@
+/*
+ * 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;
+ }
+ }
+}
--
2.28.0

View File

@ -0,0 +1,381 @@
From 58eea69462505e4ea88675adcbe85b49b9cf2e35 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Tue, 22 Sep 2020 18:03:23 +0200
Subject: [PATCH 02/28] widl: Restrict some keywords to WinRT mode only.
---
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;
}
--
2.28.0

View File

@ -0,0 +1,129 @@
From ee1ce628835376e5054972ef3c39996a2b015309 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Wed, 23 Sep 2020 14:14:01 +0200
Subject: [PATCH 03/28] widl: Introduce format_namespace_buffer helper.
To compute format_namespace length and write to an existing buffer.
Also add explicit abi_prefix parameter.
---
tools/widl/header.c | 2 +-
tools/widl/parser.y | 2 +-
tools/widl/typetree.c | 54 +++++++++++++++++++-----------------------
tools/widl/widltypes.h | 3 ++-
4 files changed, 29 insertions(+), 32 deletions(-)
diff --git a/tools/widl/header.c b/tools/widl/header.c
index 743d86f0ee9..d67fea4cc95 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -132,7 +132,7 @@ static void write_guid(FILE *f, const char *guid_prefix, const char *name, const
static void write_uuid_decl(FILE *f, type_t *type, const UUID *uuid)
{
- char *name = format_namespace(type->namespace, "", "::", type->name);
+ char *name = format_namespace(type->namespace, "", "::", type->name, use_abi_namespace ? "ABI" : NULL);
fprintf(f, "#ifdef __CRT_UUID_DECL\n");
fprintf(f, "__CRT_UUID_DECL(%s, 0x%08x, 0x%04x, 0x%04x, 0x%02x,0x%02x, 0x%02x,"
"0x%02x,0x%02x,0x%02x,0x%02x,0x%02x)\n",
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 5bc0d82703e..306e5194467 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -1905,7 +1905,7 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in
if (is_global_namespace(namespace))
type->c_name = name;
else
- type->c_name = format_namespace(namespace, "__x_", "_C", name);
+ type->c_name = format_namespace(namespace, "__x_", "_C", name, use_abi_namespace ? "ABI" : NULL);
nt->type = type;
nt->t = t;
nt->next = namespace->type_hash[hash];
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
index e9afc6fdd28..ebba2c4c6bb 100644
--- a/tools/widl/typetree.c
+++ b/tools/widl/typetree.c
@@ -89,41 +89,37 @@ const char *type_get_name(const type_t *type, enum name_type name_type)
return NULL;
}
-static char *append_namespace(char *ptr, struct namespace *namespace, const char *separator)
-{
- if(is_global_namespace(namespace)) {
- if(!use_abi_namespace)
- return ptr;
- strcpy(ptr, "ABI");
- strcat(ptr, separator);
- return ptr + strlen(ptr);
- }
+#define append_buf(f, ...) \
+ do { int r = f(buf + ret, max(ret, len) - ret, __VA_ARGS__); assert(r >= 0); ret += r; } while(0)
- ptr = append_namespace(ptr, namespace->parent, separator);
- strcpy(ptr, namespace->name);
- strcat(ptr, separator);
- return ptr + strlen(ptr);
+static int append_namespace(char *buf, size_t len, struct namespace *namespace, const char *separator, const char *abi_prefix)
+{
+ const char *name = namespace && !is_global_namespace(namespace) ? namespace->name : abi_prefix;
+ int ret = 0;
+ if (!name) return 0;
+ if (namespace && !is_global_namespace(namespace)) append_buf(append_namespace, namespace->parent, separator, abi_prefix);
+ append_buf(snprintf, "%s%s", name, separator);
+ return ret;
}
-char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix)
+static int format_namespace_buffer(char *buf, size_t len, struct namespace *namespace, const char *prefix,
+ const char *separator, const char *suffix, const char *abi_prefix)
{
- unsigned len = strlen(prefix) + strlen(suffix);
- unsigned sep_len = strlen(separator);
- struct namespace *iter;
- char *ret, *ptr;
-
- if(use_abi_namespace && !is_global_namespace(namespace))
- len += 3 /* strlen("ABI") */ + sep_len;
-
- for(iter = namespace; !is_global_namespace(iter); iter = iter->parent)
- len += strlen(iter->name) + sep_len;
+ int ret = 0;
+ append_buf(snprintf, "%s", prefix);
+ append_buf(append_namespace, namespace, separator, abi_prefix);
+ append_buf(snprintf, "%s", suffix);
+ return ret;
+}
- ret = xmalloc(len+1);
- strcpy(ret, prefix);
- ptr = append_namespace(ret + strlen(ret), namespace, separator);
- strcpy(ptr, suffix);
+#undef append_buf
- return ret;
+char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix, const char *abi_prefix)
+{
+ int len = format_namespace_buffer(NULL, 0, namespace, prefix, separator, suffix, abi_prefix);
+ char *buf = xmalloc(len + 1);
+ format_namespace_buffer(buf, len + 1, namespace, prefix, separator, suffix, abi_prefix);
+ return buf;
}
type_t *type_new_function(var_list_t *args)
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index 085a0ff55f5..630f42860f1 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -605,7 +605,8 @@ var_list_t *append_var(var_list_t *list, var_t *var);
void init_loc_info(loc_info_t *);
-char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix);
+char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix,
+ const char *abi_prefix);
static inline enum type_type type_get_type_detect_alias(const type_t *type)
{
--
2.28.0

View File

@ -0,0 +1,89 @@
From 8f57c43dd3adceb5baf529a6e42a1e813c024e20 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Tue, 13 Oct 2020 14:04:28 +0200
Subject: [PATCH 04/28] widl: Support WinRT contractversion attribute parsing.
---
tools/widl/parser.l | 1 +
tools/widl/parser.y | 12 +++++++++++-
tools/widl/widltypes.h | 1 +
3 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/tools/widl/parser.l b/tools/widl/parser.l
index eb1782d32f5..dafd17ab2f9 100644
--- a/tools/widl/parser.l
+++ b/tools/widl/parser.l
@@ -337,6 +337,7 @@ static const struct keyword attr_keywords[] =
{"context_handle", tCONTEXTHANDLE, 0},
{"context_handle_noserialize", tCONTEXTHANDLENOSERIALIZE, 0},
{"context_handle_serialize", tCONTEXTHANDLENOSERIALIZE, 0},
+ {"contractversion", tCONTRACTVERSION, 1},
{"control", tCONTROL, 0},
{"decode", tDECODE, 0},
{"defaultbind", tDEFAULTBIND, 0},
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 306e5194467..88cb9a10863 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -176,7 +176,9 @@ static typelib_t *current_typelib;
%token tAUTOHANDLE tBINDABLE tBOOLEAN tBROADCAST tBYTE tBYTECOUNT
%token tCALLAS tCALLBACK tCASE tCDECL tCHAR tCOCLASS tCODE tCOMMSTATUS
%token tCONST tCONTEXTHANDLE tCONTEXTHANDLENOSERIALIZE
-%token tCONTEXTHANDLESERIALIZE tCONTROL tCPPQUOTE
+%token tCONTEXTHANDLESERIALIZE
+%token tCONTRACTVERSION
+%token tCONTROL tCPPQUOTE
%token tDECODE tDEFAULT tDEFAULTBIND
%token tDEFAULTCOLLELEM
%token tDEFAULTVALUE
@@ -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 <num> contract_ver
%type <num> pointer_type threading_type version
%type <str> libraryhdr callconv cppquote importlib import t_ident
%type <uuid> uuid_string
@@ -489,6 +492,11 @@ str_list: aSTRING { $$ = append_str( NULL, $1 ); }
| str_list ',' aSTRING { $$ = append_str( $1, $3 ); }
;
+contract_ver:
+ aNUM { $$ = MAKEVERSION(0, $1); }
+ | aNUM '.' aNUM { $$ = MAKEVERSION($3, $1); }
+ ;
+
attribute: { $$ = NULL; }
| tAGGREGATABLE { $$ = make_attr(ATTR_AGGREGATABLE); }
| tANNOTATION '(' aSTRING ')' { $$ = make_attrp(ATTR_ANNOTATION, $3); }
@@ -504,6 +512,7 @@ attribute: { $$ = NULL; }
| tCONTEXTHANDLE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); }
| tCONTEXTHANDLENOSERIALIZE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ }
| tCONTEXTHANDLESERIALIZE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ }
+ | tCONTRACTVERSION '(' contract_ver ')' { $$ = make_attrv(ATTR_CONTRACTVERSION, $3); }
| tCONTROL { $$ = make_attr(ATTR_CONTROL); }
| tDECODE { $$ = make_attr(ATTR_DECODE); }
| tDEFAULT { $$ = make_attr(ATTR_DEFAULT); }
@@ -2135,6 +2144,7 @@ struct allowed_attr allowed_attr[] =
/* 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_CONTRACTVERSION */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "contractversion" },
/* 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" },
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index 630f42860f1..1b00b8da002 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -82,6 +82,7 @@ enum attr_type
ATTR_CODE,
ATTR_COMMSTATUS,
ATTR_CONTEXTHANDLE,
+ ATTR_CONTRACTVERSION,
ATTR_CONTROL,
ATTR_DECODE,
ATTR_DEFAULT,
--
2.28.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,74 @@
From 9e4292bb0ed2953f71ebe6c835db790d3cd5f954 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Mon, 12 Oct 2020 19:11:44 +0200
Subject: [PATCH 06/28] widl: Prefer mangled name over typedef in WinRT mode.
MIDL generates prefixed mangled name for every use of enum, struct and
union types, in fields types as well as function arguments. When the
types are in the global namespace, the typedef name is used instead.
---
tools/widl/header.c | 13 ++++++++++---
tools/widl/typetree.c | 2 +-
2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/tools/widl/header.c b/tools/widl/header.c
index 607d156ccf4..d8dfcf4f4c3 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -250,7 +250,7 @@ static void write_fields(FILE *h, var_list_t *fields)
default:
;
}
- write_type_v(h, &v->declspec, TRUE, v->declonly, name, NAME_DEFAULT);
+ write_type_v(h, &v->declspec, TRUE, v->declonly, name, NAME_C);
fprintf(h, ";\n");
}
}
@@ -322,7 +322,7 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i
if ((ds->qualifier & TYPE_QUALIFIER_CONST) && (type_is_alias(t) || !is_ptr(t)))
fprintf(h, "const ");
- if (type_is_alias(t)) fprintf(h, "%s", t->name);
+ if (!winrt_mode && type_is_alias(t)) fprintf(h, "%s", t->name);
else {
switch (type_get_type_detect_alias(t)) {
case TYPE_ENUM:
@@ -464,6 +464,13 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i
break;
}
case TYPE_ALIAS:
+ {
+ const decl_spec_t *ds = type_alias_get_aliasee(t);
+ int in_namespace = ds && ds->type && ds->type->namespace && !is_global_namespace(ds->type->namespace);
+ if (!in_namespace) fprintf(h, "%s", t->name);
+ else write_type_left(h, ds, name_type, declonly, write_callconv);
+ break;
+ }
case TYPE_APICONTRACT:
/* handled elsewhere */
assert(0);
@@ -807,7 +814,7 @@ static void write_generic_handle_routines(FILE *header)
static void write_typedef(FILE *header, type_t *type, int declonly)
{
fprintf(header, "typedef ");
- write_type_v(header, type_alias_get_aliasee(type), FALSE, declonly, type->name, NAME_DEFAULT);
+ write_type_v(header, type_alias_get_aliasee(type), FALSE, declonly, type->name, NAME_C);
fprintf(header, ";\n");
}
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
index ebba2c4c6bb..d8dcd5d80b0 100644
--- a/tools/widl/typetree.c
+++ b/tools/widl/typetree.c
@@ -82,7 +82,7 @@ const char *type_get_name(const type_t *type, enum name_type name_type)
case NAME_DEFAULT:
return type->name;
case NAME_C:
- return type->c_name;
+ return type->c_name ? type->c_name : type->name;
}
assert(0);
--
2.28.0

View File

@ -0,0 +1,27 @@
From 98a3b25143161e249102eceef6face6833ba19ea Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Mon, 12 Oct 2020 19:11:44 +0200
Subject: [PATCH 07/28] widl: Don't output typedef statement in WinRT mode.
For types under a non-global namespace, since we reference them with
their prefixed mangled names.
---
tools/widl/header.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tools/widl/header.c b/tools/widl/header.c
index d8dfcf4f4c3..0a8272fdbb4 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -813,6 +813,8 @@ static void write_generic_handle_routines(FILE *header)
static void write_typedef(FILE *header, type_t *type, int declonly)
{
+ type_t *t = type_alias_get_aliasee_type(type);
+ if (winrt_mode && t->namespace && !is_global_namespace(t->namespace)) return;
fprintf(header, "typedef ");
write_type_v(header, type_alias_get_aliasee(type), FALSE, declonly, type->name, NAME_C);
fprintf(header, ";\n");
--
2.28.0

View File

@ -0,0 +1,341 @@
From 9b5039017bd7072164042bf7b739f373134978ea Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Wed, 23 Sep 2020 19:23:45 +0200
Subject: [PATCH 08/28] widl: Support WinRT contract attribute.
---
include/windows.foundation.idl | 14 ++---
include/windows.media.speechsynthesis.idl | 13 ++++
tools/widl/header.c | 72 ++++++++++++++++++++++-
tools/widl/parser.l | 1 +
tools/widl/parser.y | 10 ++++
tools/widl/widltypes.h | 1 +
6 files changed, 101 insertions(+), 10 deletions(-)
diff --git a/include/windows.foundation.idl b/include/windows.foundation.idl
index 2a38e9f671b..5e17062f399 100644
--- a/include/windows.foundation.idl
+++ b/include/windows.foundation.idl
@@ -28,7 +28,7 @@ import "windowscontracts.idl";
namespace Windows {
namespace Foundation {
- [version(0x06020000)]
+ [contract(Windows.Foundation.FoundationContract, 1.0)]
enum PropertyType {
Empty = 0,
UInt8 = 1,
@@ -73,19 +73,19 @@ namespace Windows {
OtherTypeArray = 1044
};
- [version(0x06020000)]
+ [contract(Windows.Foundation.FoundationContract, 1.0)]
struct Point {
FLOAT X;
FLOAT Y;
};
- [version(0x06020000)]
+ [contract(Windows.Foundation.FoundationContract, 1.0)]
struct Size {
FLOAT Width;
FLOAT Height;
};
- [version(0x06020000)]
+ [contract(Windows.Foundation.FoundationContract, 1.0)]
struct Rect {
FLOAT X;
FLOAT Y;
@@ -93,18 +93,18 @@ namespace Windows {
FLOAT Height;
};
- [version(0x06020000)]
+ [contract(Windows.Foundation.FoundationContract, 1.0)]
struct DateTime {
INT64 UniversalTime;
};
- [version(0x06020000)]
+ [contract(Windows.Foundation.FoundationContract, 1.0)]
struct TimeSpan {
INT64 Duration;
};
[
- version(0x06030000),
+ contract(Windows.Foundation.FoundationContract, 1.0),
uuid(96369f54-8eb6-48f0-abce-c1b211e627c3)
]
interface IStringable : IInspectable
diff --git a/include/windows.media.speechsynthesis.idl b/include/windows.media.speechsynthesis.idl
index d3dedfe0709..7a1de5fcba6 100644
--- a/include/windows.media.speechsynthesis.idl
+++ b/include/windows.media.speechsynthesis.idl
@@ -32,3 +32,16 @@ namespace Windows {
}
}
}
+
+namespace Windows {
+ namespace Media {
+ namespace SpeechSynthesis {
+ [contract(Windows.Foundation.UniversalApiContract, 1.0)]
+ enum VoiceGender
+ {
+ Male = 0,
+ Female = 1
+ };
+ }
+ }
+}
diff --git a/tools/widl/header.c b/tools/widl/header.c
index 0a8272fdbb4..0fd3eb917ea 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -45,6 +45,11 @@ generic_handle_list_t generic_handle_list = LIST_INIT(generic_handle_list);
static void write_type_v(FILE *f, const decl_spec_t *t, int is_field, int declonly, const char *name, enum name_type name_type);
+static void write_winrt_type_comments(FILE *header, const type_t *type);
+
+static void write_apicontract_guard_start(FILE *header, const expr_t *expr);
+static void write_apicontract_guard_end(FILE *header, const expr_t *expr);
+
static void indent(FILE *h, int delta)
{
int c;
@@ -218,7 +223,9 @@ static void write_fields(FILE *h, var_list_t *fields)
}
LIST_FOR_EACH_ENTRY( v, fields, var_t, entry ) {
+ expr_t *contract = get_attrp(v->attrs, ATTR_CONTRACT);
if (!v || !v->declspec.type) continue;
+ if (contract) write_apicontract_guard_start(h, contract);
indent(h, 0);
name = v->name;
@@ -252,6 +259,7 @@ static void write_fields(FILE *h, var_list_t *fields)
}
write_type_v(h, &v->declspec, TRUE, v->declonly, name, NAME_C);
fprintf(h, ";\n");
+ if (contract) write_apicontract_guard_end(h, contract);
}
}
@@ -261,6 +269,8 @@ static void write_enums(FILE *h, var_list_t *enums, const char *enum_name)
if (!enums) return;
LIST_FOR_EACH_ENTRY( v, enums, var_t, entry )
{
+ expr_t *contract = get_attrp(v->attrs, ATTR_CONTRACT);
+ if (contract) write_apicontract_guard_start(h, contract);
if (v->name) {
indent(h, 0);
if(!enum_name)
@@ -273,8 +283,9 @@ static void write_enums(FILE *h, var_list_t *enums, const char *enum_name)
}
}
if (list_next( enums, &v->entry )) fprintf(h, ",\n");
+ else fprintf(h, "\n");
+ if (contract) write_apicontract_guard_end(h, contract);
}
- fprintf(h, "\n");
}
int needs_space_after(type_t *t)
@@ -563,7 +574,9 @@ static void write_type_definition(FILE *f, type_t *t, int declonly)
int in_namespace = t->namespace && !is_global_namespace(t->namespace);
int save_written = t->written;
decl_spec_t ds = {.type = t};
+ expr_t *contract = get_attrp(t->attrs, ATTR_CONTRACT);
+ if (contract) write_apicontract_guard_start(f, contract);
if(in_namespace) {
fprintf(f, "#ifdef __cplusplus\n");
fprintf(f, "} /* extern \"C\" */\n");
@@ -581,6 +594,7 @@ static void write_type_definition(FILE *f, type_t *t, int declonly)
fprintf(f, ";\n");
fprintf(f, "#endif\n\n");
}
+ if (contract) write_apicontract_guard_end(f, contract);
}
void write_type_decl(FILE *f, const decl_spec_t *t, const char *name)
@@ -1468,12 +1482,55 @@ static char *format_apicontract_macro(const type_t *type)
return name;
}
+static void write_winrt_type_comments(FILE *header, const type_t *type)
+{
+ expr_t *contract = get_attrp(type->attrs, ATTR_CONTRACT);
+ fprintf(header, " *\n");
+ if (contract)
+ {
+ const type_t *type = contract->u.tref.type;
+ char *name = format_namespace(type->namespace, "", ".", type->name, NULL);
+ int ver = contract->ref->u.lval;
+ fprintf(header, " * Introduced to %s in version %d.%d\n *\n", name, (ver >> 16) & 0xffff, ver & 0xffff);
+ free(name);
+ }
+}
+
+static void write_apicontract_guard_start(FILE *header, const expr_t *expr)
+{
+ const type_t *type;
+ char *name;
+ int ver;
+ if (!winrt_mode) return;
+ type = expr->u.tref.type;
+ ver = expr->ref->u.lval;
+ name = format_apicontract_macro(type);
+ fprintf(header, "#if %s_VERSION >= %#x\n", name, ver);
+ free(name);
+}
+
+static void write_apicontract_guard_end(FILE *header, const expr_t *expr)
+{
+ const type_t *type;
+ char *name;
+ int ver;
+ if (!winrt_mode) return;
+ type = expr->u.tref.type;
+ ver = expr->ref->u.lval;
+ name = format_apicontract_macro(type);
+ fprintf(header, "#endif /* %s_VERSION >= %#x */\n", name, ver);
+ free(name);
+}
+
static void write_com_interface_start(FILE *header, const type_t *iface)
{
int dispinterface = is_attr(iface->attrs, ATTR_DISPINTERFACE);
+ expr_t *contract = get_attrp(iface->attrs, ATTR_CONTRACT);
fprintf(header, "/*****************************************************************************\n");
fprintf(header, " * %s %sinterface\n", iface->name, dispinterface ? "disp" : "");
+ if (winrt_mode) write_winrt_type_comments(header, iface);
fprintf(header, " */\n");
+ if (contract) write_apicontract_guard_start(header, contract);
fprintf(header,"#ifndef __%s_%sINTERFACE_DEFINED__\n", iface->c_name, dispinterface ? "DISP" : "");
fprintf(header,"#define __%s_%sINTERFACE_DEFINED__\n\n", iface->c_name, dispinterface ? "DISP" : "");
}
@@ -1482,6 +1539,7 @@ static void write_com_interface_end(FILE *header, type_t *iface)
{
int dispinterface = is_attr(iface->attrs, ATTR_DISPINTERFACE);
const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID);
+ expr_t *contract = get_attrp(iface->attrs, ATTR_CONTRACT);
type_t *type;
if (uuid)
@@ -1559,17 +1617,22 @@ static void write_com_interface_end(FILE *header, type_t *iface)
write_locals(header, iface, FALSE);
fprintf(header, "\n");
}
- fprintf(header,"#endif /* __%s_%sINTERFACE_DEFINED__ */\n\n", iface->c_name, dispinterface ? "DISP" : "");
+ fprintf(header, "#endif /* __%s_%sINTERFACE_DEFINED__ */\n", iface->c_name, dispinterface ? "DISP" : "");
+ if (contract) write_apicontract_guard_end(header, contract);
+ fprintf(header, "\n");
}
static void write_rpc_interface_start(FILE *header, const type_t *iface)
{
unsigned int ver = get_attrv(iface->attrs, ATTR_VERSION);
const var_t *var = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
+ expr_t *contract = get_attrp(iface->attrs, ATTR_CONTRACT);
fprintf(header, "/*****************************************************************************\n");
fprintf(header, " * %s interface (v%d.%d)\n", iface->name, MAJORVERSION(ver), MINORVERSION(ver));
+ if (winrt_mode) write_winrt_type_comments(header, iface);
fprintf(header, " */\n");
+ if (contract) write_apicontract_guard_start(header, contract);
fprintf(header,"#ifndef __%s_INTERFACE_DEFINED__\n", iface->name);
fprintf(header,"#define __%s_INTERFACE_DEFINED__\n\n", iface->name);
if (var)
@@ -1594,7 +1657,10 @@ static void write_rpc_interface_start(FILE *header, const type_t *iface)
static void write_rpc_interface_end(FILE *header, const type_t *iface)
{
- fprintf(header,"\n#endif /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name);
+ expr_t *contract = get_attrp(iface->attrs, ATTR_CONTRACT);
+ fprintf(header, "\n#endif /* __%s_INTERFACE_DEFINED__ */\n", iface->name);
+ if (contract) write_apicontract_guard_end(header, contract);
+ fprintf(header, "\n");
}
static void write_coclass(FILE *header, type_t *cocl)
diff --git a/tools/widl/parser.l b/tools/widl/parser.l
index 11debca2ebd..c3d0e9e2746 100644
--- a/tools/widl/parser.l
+++ b/tools/widl/parser.l
@@ -338,6 +338,7 @@ static const struct keyword attr_keywords[] =
{"context_handle", tCONTEXTHANDLE, 0},
{"context_handle_noserialize", tCONTEXTHANDLENOSERIALIZE, 0},
{"context_handle_serialize", tCONTEXTHANDLENOSERIALIZE, 0},
+ {"contract", tCONTRACT, 1},
{"contractversion", tCONTRACTVERSION, 1},
{"control", tCONTROL, 0},
{"decode", tDECODE, 0},
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index bdd019a2880..28d7e16dad4 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -180,6 +180,7 @@ static typelib_t *current_typelib;
%token tCALLAS tCALLBACK tCASE tCDECL tCHAR tCOCLASS tCODE tCOMMSTATUS
%token tCONST tCONTEXTHANDLE tCONTEXTHANDLENOSERIALIZE
%token tCONTEXTHANDLESERIALIZE
+%token tCONTRACT
%token tCONTRACTVERSION
%token tCONTROL tCPPQUOTE
%token tDECODE tDEFAULT tDEFAULTBIND
@@ -269,6 +270,7 @@ static typelib_t *current_typelib;
%type <str_list> str_list
%type <expr> m_expr expr expr_const expr_int_const array m_bitfield
%type <expr_list> m_exprs /* exprs expr_list */ expr_list_int_const
+%type <expr> contract_req
%type <type> interfacehdr
%type <stgclass> storage_cls_spec
%type <type_qualifier> type_qualifier m_type_qual_list
@@ -505,6 +507,12 @@ contract_ver:
| aNUM '.' aNUM { $$ = MAKEVERSION($3, $1); }
;
+contract_req: decl_spec ',' contract_ver { if ($1->type->type_type != TYPE_APICONTRACT)
+ error_loc("type %s is not an apicontract\n", $1->type->name);
+ $$ = make_exprl(EXPR_NUM, $3);
+ $$ = make_exprt(EXPR_GTREQL, declare_var(NULL, $1, make_declarator(NULL), 0), $$);
+ }
+
attribute: { $$ = NULL; }
| tAGGREGATABLE { $$ = make_attr(ATTR_AGGREGATABLE); }
| tANNOTATION '(' aSTRING ')' { $$ = make_attrp(ATTR_ANNOTATION, $3); }
@@ -520,6 +528,7 @@ attribute: { $$ = NULL; }
| tCONTEXTHANDLE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); }
| tCONTEXTHANDLENOSERIALIZE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ }
| tCONTEXTHANDLESERIALIZE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ }
+ | tCONTRACT '(' contract_req ')' { $$ = make_attrp(ATTR_CONTRACT, $3); }
| tCONTRACTVERSION '(' contract_ver ')' { $$ = make_attrv(ATTR_CONTRACTVERSION, $3); }
| tCONTROL { $$ = make_attr(ATTR_CONTROL); }
| tDECODE { $$ = make_attr(ATTR_DECODE); }
@@ -2160,6 +2169,7 @@ struct allowed_attr allowed_attr[] =
/* 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_CONTRACT */ { 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, "contract" },
/* ATTR_CONTRACTVERSION */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "contractversion" },
/* 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" },
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index add7cedfacc..3f358efecd1 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -82,6 +82,7 @@ enum attr_type
ATTR_CODE,
ATTR_COMMSTATUS,
ATTR_CONTEXTHANDLE,
+ ATTR_CONTRACT,
ATTR_CONTRACTVERSION,
ATTR_CONTROL,
ATTR_DECODE,
--
2.28.0

View File

@ -0,0 +1,173 @@
From 1a75069e45df24a09e8f364c61ad5d77115d48cd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Mon, 12 Oct 2020 20:34:28 +0200
Subject: [PATCH 09/28] widl: Support WinRT marshaling_behavior attribute
parsing.
---
tools/widl/header.c | 7 +++++++
tools/widl/parser.l | 4 ++++
tools/widl/parser.y | 18 ++++++++++++++++--
tools/widl/widltypes.h | 9 +++++++++
4 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/tools/widl/header.c b/tools/widl/header.c
index 0fd3eb917ea..6d5987bd4c1 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -1494,6 +1494,13 @@ static void write_winrt_type_comments(FILE *header, const type_t *type)
fprintf(header, " * Introduced to %s in version %d.%d\n *\n", name, (ver >> 16) & 0xffff, ver & 0xffff);
free(name);
}
+ switch (get_attrv(type->attrs, ATTR_MARSHALING_BEHAVIOR))
+ {
+ case MARSHALING_AGILE: fprintf(header, " * Class Marshaling Behavior: Agile - Class is agile\n *\n"); break;
+ case MARSHALING_STANDARD: fprintf(header, " * Class Marshaling Behavior: Standard - Class marshals using the standard marshaler\n *\n"); break;
+ case MARSHALING_NONE: fprintf(header, " * Class Marshaling Behavior: None - Class cannot be marshaled\n *\n"); break;
+ default: break;
+ }
}
static void write_apicontract_guard_start(FILE *header, const expr_t *expr)
diff --git a/tools/widl/parser.l b/tools/widl/parser.l
index c3d0e9e2746..39a19a3c1de 100644
--- a/tools/widl/parser.l
+++ b/tools/widl/parser.l
@@ -320,6 +320,7 @@ static const struct keyword keywords[] = {
static const struct keyword attr_keywords[] =
{
{"aggregatable", tAGGREGATABLE, 0},
+ {"agile", tAGILE, 1},
{"allocate", tALLOCATE, 0},
{"annotation", tANNOTATION, 0},
{"apartment", tAPARTMENT, 0},
@@ -378,12 +379,14 @@ static const struct keyword attr_keywords[] =
{"length_is", tLENGTHIS, 0},
{"licensed", tLICENSED, 0},
{"local", tLOCAL, 0},
+ {"marshaling_behavior", tMARSHALINGBEHAVIOR, 1},
{"maybe", tMAYBE, 0},
{"message", tMESSAGE, 0},
{"neutral", tNEUTRAL, 0},
{"nocode", tNOCODE, 0},
{"nonbrowsable", tNONBROWSABLE, 0},
{"noncreatable", tNONCREATABLE, 0},
+ {"none", tNONE, 1},
{"nonextensible", tNONEXTENSIBLE, 0},
{"notify", tNOTIFY, 0},
{"notify_flag", tNOTIFYFLAG, 0},
@@ -412,6 +415,7 @@ static const struct keyword attr_keywords[] =
{"single", tSINGLE, 0},
{"size_is", tSIZEIS, 0},
{"source", tSOURCE, 0},
+ {"standard", tSTANDARD, 1},
{"strict_context_handle", tSTRICTCONTEXTHANDLE, 0},
{"string", tSTRING, 0},
{"switch_is", tSWITCHIS, 0},
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 28d7e16dad4..ebaa0fc514b 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -173,7 +173,9 @@ static typelib_t *current_typelib;
%token GREATEREQUAL LESSEQUAL
%token LOGICALOR LOGICALAND
%token ELLIPSIS
-%token tAGGREGATABLE tALLOCATE tANNOTATION
+%token tAGGREGATABLE
+%token tAGILE
+%token tALLOCATE tANNOTATION
%token tAPICONTRACT
%token tAPPOBJECT tASYNC tASYNCUUID
%token tAUTOHANDLE tBINDABLE tBOOLEAN tBROADCAST tBYTE tBYTECOUNT
@@ -214,12 +216,14 @@ static typelib_t *current_typelib;
%token tLENGTHIS tLIBRARY
%token tLICENSED tLOCAL
%token tLONG
+%token tMARSHALINGBEHAVIOR
%token tMAYBE tMESSAGE
%token tMETHODS
%token tMODULE
%token tNAMESPACE
%token tNOCODE tNONBROWSABLE
%token tNONCREATABLE
+%token tNONE
%token tNONEXTENSIBLE
%token tNOTIFY tNOTIFYFLAG
%token tNULL
@@ -245,6 +249,7 @@ static typelib_t *current_typelib;
%token tSIZEIS tSIZEOF
%token tSMALL
%token tSOURCE
+%token tSTANDARD
%token tSTATIC
%token tSTDCALL
%token tSTRICTCONTEXTHANDLE
@@ -297,7 +302,7 @@ static typelib_t *current_typelib;
%type <type> coclass coclasshdr coclassdef
%type <type> apicontract
%type <num> contract_ver
-%type <num> pointer_type threading_type version
+%type <num> pointer_type threading_type marshaling_behavior version
%type <str> libraryhdr callconv cppquote importlib import t_ident
%type <uuid> uuid_string
%type <import> import_start
@@ -502,6 +507,12 @@ str_list: aSTRING { $$ = append_str( NULL, $1 ); }
| str_list ',' aSTRING { $$ = append_str( $1, $3 ); }
;
+marshaling_behavior:
+ tAGILE { $$ = MARSHALING_AGILE; }
+ | tNONE { $$ = MARSHALING_NONE; }
+ | tSTANDARD { $$ = MARSHALING_STANDARD; }
+ ;
+
contract_ver:
aNUM { $$ = MAKEVERSION(0, $1); }
| aNUM '.' aNUM { $$ = MAKEVERSION($3, $1); }
@@ -568,6 +579,8 @@ attribute: { $$ = NULL; }
| tLCID { $$ = make_attr(ATTR_PARAMLCID); }
| tLICENSED { $$ = make_attr(ATTR_LICENSED); }
| tLOCAL { $$ = make_attr(ATTR_LOCAL); }
+ | tMARSHALINGBEHAVIOR '(' marshaling_behavior ')'
+ { $$ = make_attrv(ATTR_MARSHALING_BEHAVIOR, $3); }
| tMAYBE { $$ = make_attr(ATTR_MAYBE); }
| tMESSAGE { $$ = make_attr(ATTR_MESSAGE); }
| tNOCODE { $$ = make_attr(ATTR_NOCODE); }
@@ -2209,6 +2222,7 @@ struct allowed_attr allowed_attr[] =
/* 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_MARSHALING_BEHAVIOR */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "marshaling_behavior" },
/* 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" },
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index 3f358efecd1..62a018ab5a5 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -122,6 +122,7 @@ enum attr_type
ATTR_LIBLCID,
ATTR_LICENSED,
ATTR_LOCAL,
+ ATTR_MARSHALING_BEHAVIOR,
ATTR_MAYBE,
ATTR_MESSAGE,
ATTR_NOCODE,
@@ -268,6 +269,14 @@ enum threading_type
THREADING_BOTH
};
+enum marshaling_type
+{
+ MARSHALING_INVALID = 0,
+ MARSHALING_NONE,
+ MARSHALING_AGILE,
+ MARSHALING_STANDARD,
+};
+
enum type_basic_type
{
TYPE_BASIC_INT8 = 1,
--
2.28.0

View File

@ -0,0 +1,79 @@
From d2013864b6a28fabca3678172ab95b95ab2bb9af Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Tue, 13 Oct 2020 11:35:49 +0200
Subject: [PATCH 10/28] widl: Support WinRT mta threading attribute parsing.
---
tools/widl/header.c | 7 +++++++
tools/widl/parser.l | 1 +
tools/widl/parser.y | 2 ++
tools/widl/widltypes.h | 3 ++-
4 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/tools/widl/header.c b/tools/widl/header.c
index 6d5987bd4c1..843aba214a4 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -1494,6 +1494,13 @@ static void write_winrt_type_comments(FILE *header, const type_t *type)
fprintf(header, " * Introduced to %s in version %d.%d\n *\n", name, (ver >> 16) & 0xffff, ver & 0xffff);
free(name);
}
+ switch (get_attrv(type->attrs, ATTR_THREADING))
+ {
+ case THREADING_SINGLE: fprintf(header, " * Class Threading Model: Single Threaded Apartment\n *\n"); break;
+ case THREADING_BOTH: fprintf(header, " * Class Threading Model: Both Single and Multi Threaded Apartment\n *\n"); break;
+ case THREADING_MTA: fprintf(header, " * Class Threading Model: Multi Threaded Apartment\n *\n"); break;
+ default: break;
+ }
switch (get_attrv(type->attrs, ATTR_MARSHALING_BEHAVIOR))
{
case MARSHALING_AGILE: fprintf(header, " * Class Marshaling Behavior: Agile - Class is agile\n *\n"); break;
diff --git a/tools/widl/parser.l b/tools/widl/parser.l
index 39a19a3c1de..c99feffb5d6 100644
--- a/tools/widl/parser.l
+++ b/tools/widl/parser.l
@@ -382,6 +382,7 @@ static const struct keyword attr_keywords[] =
{"marshaling_behavior", tMARSHALINGBEHAVIOR, 1},
{"maybe", tMAYBE, 0},
{"message", tMESSAGE, 0},
+ {"mta" , tMTA, 1},
{"neutral", tNEUTRAL, 0},
{"nocode", tNOCODE, 0},
{"nonbrowsable", tNONBROWSABLE, 0},
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index ebaa0fc514b..a4ad03ef037 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -220,6 +220,7 @@ static typelib_t *current_typelib;
%token tMAYBE tMESSAGE
%token tMETHODS
%token tMODULE
+%token tMTA
%token tNAMESPACE
%token tNOCODE tNONBROWSABLE
%token tNONCREATABLE
@@ -1150,6 +1151,7 @@ threading_type:
| tSINGLE { $$ = THREADING_SINGLE; }
| tFREE { $$ = THREADING_FREE; }
| tBOTH { $$ = THREADING_BOTH; }
+ | tMTA { $$ = THREADING_MTA; }
;
pointer_type:
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index 62a018ab5a5..26634fa7f7d 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -266,7 +266,8 @@ enum threading_type
THREADING_NEUTRAL,
THREADING_SINGLE,
THREADING_FREE,
- THREADING_BOTH
+ THREADING_BOTH,
+ THREADING_MTA,
};
enum marshaling_type
--
2.28.0

View File

@ -0,0 +1,92 @@
From 1d70d60ab7af24ba47e98c00d4673347883f065b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Tue, 13 Oct 2020 00:11:08 +0200
Subject: [PATCH 11/28] widl: Support WinRT exclusiveto attribute parsing.
---
tools/widl/header.c | 7 +++++++
tools/widl/parser.l | 1 +
tools/widl/parser.y | 3 +++
tools/widl/widltypes.h | 1 +
4 files changed, 12 insertions(+)
diff --git a/tools/widl/header.c b/tools/widl/header.c
index 843aba214a4..8aed9be3f57 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -1485,6 +1485,7 @@ static char *format_apicontract_macro(const type_t *type)
static void write_winrt_type_comments(FILE *header, const type_t *type)
{
expr_t *contract = get_attrp(type->attrs, ATTR_CONTRACT);
+ type_t *exclusiveto = get_attrp(type->attrs, ATTR_EXCLUSIVETO);
fprintf(header, " *\n");
if (contract)
{
@@ -1494,6 +1495,12 @@ static void write_winrt_type_comments(FILE *header, const type_t *type)
fprintf(header, " * Introduced to %s in version %d.%d\n *\n", name, (ver >> 16) & 0xffff, ver & 0xffff);
free(name);
}
+ if (exclusiveto)
+ {
+ char *name = format_namespace(exclusiveto->namespace, "", ".", exclusiveto->name, NULL);
+ fprintf(header, " * Interface is a part of the implementation of type %s\n *\n", name);
+ free(name);
+ }
switch (get_attrv(type->attrs, ATTR_THREADING))
{
case THREADING_SINGLE: fprintf(header, " * Class Threading Model: Single Threaded Apartment\n *\n"); break;
diff --git a/tools/widl/parser.l b/tools/widl/parser.l
index c99feffb5d6..498071a1992 100644
--- a/tools/widl/parser.l
+++ b/tools/widl/parser.l
@@ -355,6 +355,7 @@ static const struct keyword attr_keywords[] =
{"encode", tENCODE, 0},
{"endpoint", tENDPOINT, 0},
{"entry", tENTRY, 0},
+ {"exclusiveto", tEXCLUSIVETO, 1},
{"explicit_handle", tEXPLICITHANDLE, 0},
{"fault_status", tFAULTSTATUS, 0},
{"force_allocate", tFORCEALLOCATE, 0},
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index a4ad03ef037..88cc029c3ae 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -194,6 +194,7 @@ static typelib_t *current_typelib;
%token tDLLNAME tDOUBLE tDUAL
%token tENABLEALLOCATE tENCODE tENDPOINT
%token tENTRY tENUM tERRORSTATUST
+%token tEXCLUSIVETO
%token tEXPLICITHANDLE tEXTERN
%token tFALSE
%token tFASTCALL tFAULTSTATUS
@@ -557,6 +558,7 @@ attribute: { $$ = NULL; }
| tENCODE { $$ = make_attr(ATTR_ENCODE); }
| tENDPOINT '(' str_list ')' { $$ = make_attrp(ATTR_ENDPOINT, $3); }
| tENTRY '(' expr_const ')' { $$ = make_attrp(ATTR_ENTRY, $3); }
+ | tEXCLUSIVETO '(' decl_spec ')' { $$ = make_attrp(ATTR_EXCLUSIVETO, $3->type); }
| tEXPLICITHANDLE { $$ = make_attr(ATTR_EXPLICIT_HANDLE); }
| tFAULTSTATUS { $$ = make_attr(ATTR_FAULTSTATUS); }
| tFORCEALLOCATE { $$ = make_attr(ATTR_FORCEALLOCATE); }
@@ -2202,6 +2204,7 @@ struct allowed_attr allowed_attr[] =
/* 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_EXCLUSIVETO */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "exclusive_to" },
/* 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" },
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index 26634fa7f7d..e945cad33b2 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -100,6 +100,7 @@ enum attr_type
ATTR_ENCODE,
ATTR_ENDPOINT,
ATTR_ENTRY,
+ ATTR_EXCLUSIVETO,
ATTR_EXPLICIT_HANDLE,
ATTR_FAULTSTATUS,
ATTR_FORCEALLOCATE,
--
2.28.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,95 @@
From 4f9ad72a4381348591151271107caea8a83cef84 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 1 Oct 2020 20:10:02 +0200
Subject: [PATCH 13/28] widl: Support WinRT eventadd/eventremove attributes.
---
tools/widl/header.c | 4 ++++
tools/widl/parser.l | 2 ++
tools/widl/parser.y | 7 +++++++
tools/widl/widltypes.h | 2 ++
4 files changed, 15 insertions(+)
diff --git a/tools/widl/header.c b/tools/widl/header.c
index 065a82ea384..812becad63b 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -187,6 +187,10 @@ const char *get_name(const var_t *v)
{
static char *buffer;
free( buffer );
+ if (is_attr( v->attrs, ATTR_EVENTADD ))
+ return buffer = strmake( "add_%s", v->name );
+ if (is_attr( v->attrs, ATTR_EVENTREMOVE ))
+ return buffer = strmake( "remove_%s", v->name );
if (is_attr( v->attrs, ATTR_PROPGET ))
return buffer = strmake( "get_%s", v->name );
if (is_attr( v->attrs, ATTR_PROPPUT ))
diff --git a/tools/widl/parser.l b/tools/widl/parser.l
index 31b97951b31..02a6b47e225 100644
--- a/tools/widl/parser.l
+++ b/tools/widl/parser.l
@@ -356,6 +356,8 @@ static const struct keyword attr_keywords[] =
{"encode", tENCODE, 0},
{"endpoint", tENDPOINT, 0},
{"entry", tENTRY, 0},
+ {"eventadd", tEVENTADD, 1},
+ {"eventremove", tEVENTREMOVE, 1},
{"exclusiveto", tEXCLUSIVETO, 1},
{"explicit_handle", tEXPLICITHANDLE, 0},
{"fault_status", tFAULTSTATUS, 0},
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 8b88e031fb5..b1b3201042f 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -195,6 +195,7 @@ static typelib_t *current_typelib;
%token tDLLNAME tDOUBLE tDUAL
%token tENABLEALLOCATE tENCODE tENDPOINT
%token tENTRY tENUM tERRORSTATUST
+%token tEVENTADD tEVENTREMOVE
%token tEXCLUSIVETO
%token tEXPLICITHANDLE tEXTERN
%token tFALSE
@@ -567,6 +568,8 @@ attribute: { $$ = NULL; }
| tENCODE { $$ = make_attr(ATTR_ENCODE); }
| tENDPOINT '(' str_list ')' { $$ = make_attrp(ATTR_ENDPOINT, $3); }
| tENTRY '(' expr_const ')' { $$ = make_attrp(ATTR_ENTRY, $3); }
+ | tEVENTADD { $$ = make_attr(ATTR_EVENTADD); }
+ | tEVENTREMOVE { $$ = make_attr(ATTR_EVENTREMOVE); }
| tEXCLUSIVETO '(' decl_spec ')' { if ($3->type->type_type != TYPE_RUNTIMECLASS)
error_loc("type %s is not a runtimeclass\n", $3->type->name);
$$ = make_attrp(ATTR_EXCLUSIVETO, $3->type); }
@@ -2235,6 +2238,8 @@ struct allowed_attr allowed_attr[] =
/* ATTR_ENCODE */ { 0, 0, 1, 1, 0, 1, 0, 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, 0, "endpoint" },
/* ATTR_ENTRY */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "entry" },
+ /* ATTR_EVENTADD */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "eventadd" },
+ /* ATTR_EVENTREMOVE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "eventremove" },
/* ATTR_EXCLUSIVETO */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "exclusive_to" },
/* ATTR_EXPLICIT_HANDLE */ { 1, 1, 1, 0, 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, 0, "fault_status" },
@@ -2884,6 +2889,8 @@ static void check_functions(const type_t *iface, int is_inside_library)
{
if (func == func_iter) break;
if (strcmp(func->name, func_iter->name)) continue;
+ if (is_attr(func->attrs, ATTR_EVENTADD) != is_attr(func_iter->attrs, ATTR_EVENTADD)) continue;
+ if (is_attr(func->attrs, ATTR_EVENTREMOVE) != is_attr(func_iter->attrs, ATTR_EVENTREMOVE)) continue;
if (is_attr(func->attrs, ATTR_PROPGET) != is_attr(func_iter->attrs, ATTR_PROPGET)) continue;
if (is_attr(func->attrs, ATTR_PROPPUT) != is_attr(func_iter->attrs, ATTR_PROPPUT)) continue;
if (is_attr(func->attrs, ATTR_PROPPUTREF) != is_attr(func_iter->attrs, ATTR_PROPPUTREF)) continue;
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index 0a2088574d3..da70a8f97d5 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -100,6 +100,8 @@ enum attr_type
ATTR_ENCODE,
ATTR_ENDPOINT,
ATTR_ENTRY,
+ ATTR_EVENTADD,
+ ATTR_EVENTREMOVE,
ATTR_EXCLUSIVETO,
ATTR_EXPLICIT_HANDLE,
ATTR_FAULTSTATUS,
--
2.28.0

View File

@ -0,0 +1,66 @@
From c64bd2a13a6ec07122d08bc81d4933b38eec5edf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Mon, 12 Oct 2020 18:02:59 +0200
Subject: [PATCH 14/28] widl: Support WinRT flags attribute parsing.
---
tools/widl/parser.l | 1 +
tools/widl/parser.y | 3 +++
tools/widl/widltypes.h | 1 +
3 files changed, 5 insertions(+)
diff --git a/tools/widl/parser.l b/tools/widl/parser.l
index 02a6b47e225..f5a57db4797 100644
--- a/tools/widl/parser.l
+++ b/tools/widl/parser.l
@@ -361,6 +361,7 @@ static const struct keyword attr_keywords[] =
{"exclusiveto", tEXCLUSIVETO, 1},
{"explicit_handle", tEXPLICITHANDLE, 0},
{"fault_status", tFAULTSTATUS, 0},
+ {"flags", tFLAGS, 1},
{"force_allocate", tFORCEALLOCATE, 0},
{"free", tFREE, 0},
{"handle", tHANDLE, 0},
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index b1b3201042f..131226ba7be 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -200,6 +200,7 @@ static typelib_t *current_typelib;
%token tEXPLICITHANDLE tEXTERN
%token tFALSE
%token tFASTCALL tFAULTSTATUS
+%token tFLAGS
%token tFLOAT tFORCEALLOCATE
%token tHANDLE
%token tHANDLET
@@ -575,6 +576,7 @@ attribute: { $$ = NULL; }
$$ = make_attrp(ATTR_EXCLUSIVETO, $3->type); }
| tEXPLICITHANDLE { $$ = make_attr(ATTR_EXPLICIT_HANDLE); }
| tFAULTSTATUS { $$ = make_attr(ATTR_FAULTSTATUS); }
+ | tFLAGS { $$ = make_attr(ATTR_FLAGS); }
| tFORCEALLOCATE { $$ = make_attr(ATTR_FORCEALLOCATE); }
| tHANDLE { $$ = make_attr(ATTR_HANDLE); }
| tHELPCONTEXT '(' expr_int_const ')' { $$ = make_attrp(ATTR_HELPCONTEXT, $3); }
@@ -2243,6 +2245,7 @@ struct allowed_attr allowed_attr[] =
/* ATTR_EXCLUSIVETO */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "exclusive_to" },
/* ATTR_EXPLICIT_HANDLE */ { 1, 1, 1, 0, 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, 0, "fault_status" },
+ /* ATTR_FLAGS */ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "flags" },
/* ATTR_FORCEALLOCATE */ { 0, 0, 0, 0, 1, 0, 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, 0, "handle" },
/* ATTR_HELPCONTEXT */ { 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "helpcontext" },
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index da70a8f97d5..0bf7b644fff 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -105,6 +105,7 @@ enum attr_type
ATTR_EXCLUSIVETO,
ATTR_EXPLICIT_HANDLE,
ATTR_FAULTSTATUS,
+ ATTR_FLAGS,
ATTR_FORCEALLOCATE,
ATTR_HANDLE,
ATTR_HELPCONTEXT,
--
2.28.0

View File

@ -0,0 +1,156 @@
From 65fefdad1ecb8bc45a89bee1393acf2cfcbb63b8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Fri, 25 Sep 2020 17:13:47 +0200
Subject: [PATCH 15/28] widl: Support using qualified names for interfaces.
And make qualified name lookup more robust, only looking for types in
the lookup namespace if it's active.
---
include/windows.media.speechsynthesis.idl | 2 +-
tools/widl/parser.y | 58 +++++++++++++++--------
2 files changed, 38 insertions(+), 22 deletions(-)
diff --git a/include/windows.media.speechsynthesis.idl b/include/windows.media.speechsynthesis.idl
index 90bc9f279c6..89fe616b9b3 100644
--- a/include/windows.media.speechsynthesis.idl
+++ b/include/windows.media.speechsynthesis.idl
@@ -65,7 +65,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 131226ba7be..8e79ce3660f 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -74,6 +74,8 @@ static void append_chain_callconv(type_t *chain, char *callconv);
static warning_list_t *append_warning(warning_list_t *, int);
static type_t *reg_typedefs(decl_spec_t *decl_spec, var_list_t *names, attr_list_t *attrs);
+static type_t *get_qualified_type(enum type_type type, char *name, int t);
+static type_t *find_qualified_type_or_error(const char *name, int t);
static type_t *find_type_or_error(const char *name, int t);
static type_t *find_type_or_error2(char *name, int t);
@@ -81,7 +83,6 @@ static var_t *reg_const(var_t *var);
static void push_namespace(const char *name);
static void pop_namespace(const char *name);
-static void init_lookup_namespace(const char *name);
static void push_lookup_namespace(const char *name);
static void check_arg_attrs(const var_t *arg);
@@ -293,7 +294,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
@@ -884,15 +885,15 @@ 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_pfx:
+ aNAMESPACE '.' { push_lookup_namespace($1); }
+ | namespace_pfx aNAMESPACE '.' { push_lookup_namespace($2); }
+ ;
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_pfx aKNOWNTYPE { $$ = find_qualified_type_or_error($2, 0); }
+ ;
coclass: tCOCLASS aIDENTIFIER { $$ = type_new_coclass($2); }
| tCOCLASS aKNOWNTYPE { $$ = find_type($2, NULL, 0);
@@ -990,6 +991,8 @@ 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_pfx aIDENTIFIER { $$ = get_qualified_type(TYPE_INTERFACE, $3, 0); }
+ | tINTERFACE namespace_pfx aKNOWNTYPE { $$ = get_qualified_type(TYPE_INTERFACE, $3, 0); }
;
interfacehdr: attributes interface { $$ = $2;
@@ -1953,12 +1956,6 @@ static void pop_namespace(const char *name)
current_namespace = current_namespace->parent;
}
-static void init_lookup_namespace(const char *name)
-{
- if (!(lookup_namespace = find_sub_namespace(&global_namespace, name)))
- error_loc("namespace '%s' not found\n", name);
-}
-
static void push_lookup_namespace(const char *name)
{
struct namespace *namespace;
@@ -2076,11 +2073,29 @@ type_t *find_type(const char *name, struct namespace *namespace, int t)
return NULL;
}
+static type_t *get_qualified_type(enum type_type type_type, char *name, int t)
+{
+ type_t *type = get_type(type_type, name, lookup_namespace, t);
+ lookup_namespace = &global_namespace;
+ return type;
+}
+
+static type_t *find_qualified_type_or_error(const char *name, int t)
+{
+ type_t *type;
+ if (!(type = find_type(name, lookup_namespace, t)))
+ {
+ error_loc("type '%s' not found\n", name);
+ return NULL;
+ }
+ lookup_namespace = &global_namespace;
+ return type;
+}
+
static type_t *find_type_or_error(const char *name, int t)
{
type_t *type;
- if (!(type = find_type(name, current_namespace, t)) &&
- !(type = find_type(name, lookup_namespace, t)))
+ if (!(type = find_type(name, current_namespace, t)))
{
error_loc("type '%s' not found\n", name);
return NULL;
@@ -2097,15 +2112,16 @@ static type_t *find_type_or_error2(char *name, int t)
int is_type(const char *name)
{
- return find_type(name, current_namespace, 0) != NULL ||
- find_type(name, lookup_namespace, 0) != NULL;
+ if (lookup_namespace != &global_namespace)
+ return find_type(name, lookup_namespace, 0) != NULL;
+ else
+ return find_type(name, current_namespace, 0) != NULL;
}
int is_namespace(const char *name)
{
if (!winrt_mode) return 0;
- return find_sub_namespace(current_namespace, name) != NULL ||
- find_sub_namespace(&global_namespace, name) != NULL;
+ return find_sub_namespace(lookup_namespace, name) != NULL;
}
type_t *get_type(enum type_type type, char *name, struct namespace *namespace, int t)
--
2.28.0

View File

@ -0,0 +1,297 @@
From 734f1257696ef221883e92d23f653dc7188b1fcd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Tue, 13 Oct 2020 13:52:34 +0200
Subject: [PATCH 16/28] widl: Support repeated attributes for WinRT static.
---
tools/widl/parser.y | 258 ++++++++++++++++++++++----------------------
1 file changed, 130 insertions(+), 128 deletions(-)
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 8e79ce3660f..1727b5bb396 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -1310,27 +1310,6 @@ static str_list_t *append_str(str_list_t *list, char *str)
return list;
}
-static attr_list_t *append_attr(attr_list_t *list, attr_t *attr)
-{
- attr_t *attr_existing;
- if (!attr) return list;
- if (!list)
- {
- list = xmalloc( sizeof(*list) );
- list_init( list );
- }
- LIST_FOR_EACH_ENTRY(attr_existing, list, attr_t, entry)
- if (attr_existing->type == attr->type)
- {
- parser_warning("duplicate attribute %s\n", get_attr_display_name(attr->type));
- /* use the last attribute, like MIDL does */
- list_remove(&attr_existing->entry);
- break;
- }
- list_add_tail( list, &attr->entry );
- return list;
-}
-
static attr_list_t *move_attr(attr_list_t *dst, attr_list_t *src, enum attr_type type)
{
attr_t *attr;
@@ -2203,6 +2182,8 @@ struct allowed_attr
{
unsigned int dce_compatible : 1;
unsigned int acf : 1;
+ unsigned int multiple : 1;
+
unsigned int on_interface : 1;
unsigned int on_function : 1;
unsigned int on_arg : 1;
@@ -2223,115 +2204,136 @@ struct allowed_attr
struct allowed_attr allowed_attr[] =
{
- /* attr { D ACF I Fn ARG T En Enm St Un Fi L DI M C AC R <display name> } */
- /* ATTR_AGGREGATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "aggregatable" },
- /* ATTR_ANNOTATION */ { 0, 0, 0, 0, 1, 0, 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, 0, "appobject" },
- /* ATTR_ASYNC */ { 0, 1, 0, 1, 0, 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, 0, "async_uuid" },
- /* ATTR_AUTO_HANDLE */ { 1, 1, 1, 0, 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, 0, "bindable" },
- /* ATTR_BROADCAST */ { 1, 0, 0, 1, 0, 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, 0, "call_as" },
- /* ATTR_CALLCONV */ { 0, 0, 0, 1, 0, 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, 0, "case" },
- /* ATTR_CODE */ { 0, 1, 1, 1, 0, 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, 0, "comm_status" },
- /* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" },
- /* ATTR_CONTRACT */ { 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, "contract" },
- /* ATTR_CONTRACTVERSION */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "contractversion" },
- /* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, "control" },
- /* ATTR_DECODE */ { 0, 0, 1, 1, 0, 1, 0, 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, 0, "default" },
- /* ATTR_DEFAULTBIND */ { 0, 0, 0, 1, 0, 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, 0, "defaultcollelem" },
- /* ATTR_DEFAULTVALUE */ { 0, 0, 0, 0, 1, 0, 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, 0, "defaultvtable" },
- /* ATTR_DISABLECONSISTENCYCHECK */{ 0, 0, 0, 0, 1, 0, 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, 0, NULL },
- /* ATTR_DISPLAYBIND */ { 0, 0, 0, 1, 0, 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, 0, "dllname" },
- /* ATTR_DUAL */ { 0, 0, 1, 0, 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, 0, "enable_allocate" },
- /* ATTR_ENCODE */ { 0, 0, 1, 1, 0, 1, 0, 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, 0, "endpoint" },
- /* ATTR_ENTRY */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "entry" },
- /* ATTR_EVENTADD */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "eventadd" },
- /* ATTR_EVENTREMOVE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "eventremove" },
- /* ATTR_EXCLUSIVETO */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "exclusive_to" },
- /* ATTR_EXPLICIT_HANDLE */ { 1, 1, 1, 0, 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, 0, "fault_status" },
- /* ATTR_FLAGS */ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "flags" },
- /* ATTR_FORCEALLOCATE */ { 0, 0, 0, 0, 1, 0, 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, 0, "handle" },
- /* ATTR_HELPCONTEXT */ { 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "helpcontext" },
- /* ATTR_HELPFILE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "helpfile" },
- /* ATTR_HELPSTRING */ { 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "helpstring" },
- /* ATTR_HELPSTRINGCONTEXT */ { 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "helpstringcontext" },
- /* ATTR_HELPSTRINGDLL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "helpstringdll" },
- /* ATTR_HIDDEN */ { 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, "hidden" },
- /* ATTR_ID */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, "id" },
- /* ATTR_IDEMPOTENT */ { 1, 0, 0, 1, 0, 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, 0, "ignore" },
- /* ATTR_IIDIS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 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, 0, "immediatebind" },
- /* ATTR_IMPLICIT_HANDLE */ { 1, 1, 1, 0, 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, 0, "in" },
- /* ATTR_INPUTSYNC */ { 0, 0, 0, 1, 0, 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, 0, "length_is" },
- /* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "lcid" },
- /* ATTR_LICENSED */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "licensed" },
- /* ATTR_LOCAL */ { 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "local" },
- /* ATTR_MARSHALING_BEHAVIOR */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "marshaling_behavior" },
- /* ATTR_MAYBE */ { 0, 0, 0, 1, 0, 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, 0, "message" },
- /* ATTR_NOCODE */ { 0, 1, 1, 1, 0, 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, 0, "nonbrowsable" },
- /* ATTR_NONCREATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "noncreatable" },
- /* ATTR_NONEXTENSIBLE */ { 0, 0, 1, 0, 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, 0, "notify" },
- /* ATTR_NOTIFYFLAG */ { 0, 0, 0, 1, 0, 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, 0, "object" },
- /* ATTR_ODL */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "odl" },
- /* ATTR_OLEAUTOMATION */ { 0, 0, 1, 0, 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, 0, "optimize" },
- /* ATTR_OPTIONAL */ { 0, 0, 0, 0, 1, 0, 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, 0, "out" },
- /* ATTR_PARAMLCID */ { 0, 0, 0, 0, 1, 0, 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, 0, "partial_ignore" },
- /* ATTR_POINTERDEFAULT */ { 1, 0, 1, 0, 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, 0, "ref, unique or ptr" },
- /* ATTR_PROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "progid" },
- /* ATTR_PROPGET */ { 0, 0, 0, 1, 0, 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, 0, "propput" },
- /* ATTR_PROPPUTREF */ { 0, 0, 0, 1, 0, 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, 0, "proxy" },
- /* ATTR_PUBLIC */ { 0, 0, 0, 0, 0, 1, 0, 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, 0, "range" },
- /* ATTR_READONLY */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "readonly" },
- /* ATTR_REPRESENTAS */ { 1, 0, 0, 0, 0, 1, 0, 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, 0, "requestedit" },
- /* ATTR_RESTRICTED */ { 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, "restricted" },
- /* ATTR_RETVAL */ { 0, 0, 0, 0, 1, 0, 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, 0, "size_is" },
- /* ATTR_SOURCE */ { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "source" },
- /* ATTR_STRICTCONTEXTHANDLE */ { 0, 0, 1, 0, 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, 0, "string" },
- /* ATTR_SWITCHIS */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 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, 0, "switch_type" },
- /* ATTR_THREADING */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, "threading" },
- /* ATTR_TRANSMITAS */ { 1, 0, 0, 0, 0, 1, 0, 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, 0, "uidefault" },
- /* ATTR_USESGETLASTERROR */ { 0, 0, 0, 1, 0, 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, 0, "user_marshal" },
- /* ATTR_UUID */ { 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, "uuid" },
- /* ATTR_V1ENUM */ { 0, 0, 0, 0, 0, 1, 1, 0, 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, 0, "vararg" },
- /* ATTR_VERSION */ { 1, 0, 1, 0, 0, 1, 1, 0, 2, 0, 0, 1, 0, 0, 1, 0, 1, "version" },
- /* ATTR_VIPROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "vi_progid" },
- /* ATTR_WIREMARSHAL */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "wire_marshal" },
+ /* attr { D ACF M I Fn ARG T En Enm St Un Fi L DI M C AC R <display name> } */
+ /* ATTR_AGGREGATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "aggregatable" },
+ /* ATTR_ANNOTATION */ { 0, 0, 0, 0, 0, 1, 0, 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, 0, 1, 0, 0, "appobject" },
+ /* ATTR_ASYNC */ { 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "async" },
+ /* ATTR_ASYNCUUID */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "async_uuid" },
+ /* ATTR_AUTO_HANDLE */ { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "auto_handle" },
+ /* ATTR_BINDABLE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "bindable" },
+ /* ATTR_BROADCAST */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "broadcast" },
+ /* ATTR_CALLAS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "call_as" },
+ /* ATTR_CALLCONV */ { 0, 0, 0, 0, 1, 0, 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, 0, 1, 0, 0, 0, 0, 0, 0, "case" },
+ /* ATTR_CODE */ { 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" },
+ /* ATTR_COMMSTATUS */ { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" },
+ /* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" },
+ /* ATTR_CONTRACT */ { 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, "contract" },
+ /* ATTR_CONTRACTVERSION */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "contractversion" },
+ /* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, "control" },
+ /* ATTR_DECODE */ { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "decode" },
+ /* ATTR_DEFAULT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, "default" },
+ /* ATTR_DEFAULTBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultbind" },
+ /* ATTR_DEFAULTCOLLELEM */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultcollelem" },
+ /* ATTR_DEFAULTVALUE */ { 0, 0, 0, 0, 0, 1, 0, 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, 0, 1, 0, 0, "defaultvtable" },
+ /* ATTR_DISABLECONSISTENCYCHECK */{ 0, 0, 0, 0, 0, 1, 0, 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, 0, 0, NULL },
+ /* ATTR_DISPLAYBIND */ { 0, 0, 0, 0, 1, 0, 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, 0, 1, 0, 0, 0, "dllname" },
+ /* ATTR_DUAL */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "dual" },
+ /* ATTR_ENABLEALLOCATE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "enable_allocate" },
+ /* ATTR_ENCODE */ { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "encode" },
+ /* ATTR_ENDPOINT */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "endpoint" },
+ /* ATTR_ENTRY */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "entry" },
+ /* ATTR_EVENTADD */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "eventadd" },
+ /* ATTR_EVENTREMOVE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "eventremove" },
+ /* ATTR_EXCLUSIVETO */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "exclusive_to" },
+ /* ATTR_EXPLICIT_HANDLE */ { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "explicit_handle" },
+ /* ATTR_FAULTSTATUS */ { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "fault_status" },
+ /* ATTR_FLAGS */ { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "flags" },
+ /* ATTR_FORCEALLOCATE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "force_allocate" },
+ /* ATTR_HANDLE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "handle" },
+ /* ATTR_HELPCONTEXT */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "helpcontext" },
+ /* ATTR_HELPFILE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "helpfile" },
+ /* ATTR_HELPSTRING */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "helpstring" },
+ /* ATTR_HELPSTRINGCONTEXT */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "helpstringcontext" },
+ /* ATTR_HELPSTRINGDLL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "helpstringdll" },
+ /* ATTR_HIDDEN */ { 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, "hidden" },
+ /* ATTR_ID */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, "id" },
+ /* ATTR_IDEMPOTENT */ { 1, 0, 0, 0, 1, 0, 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, 0, 1, 0, 0, 0, 0, 0, 0, "ignore" },
+ /* ATTR_IIDIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "iid_is" },
+ /* ATTR_IMMEDIATEBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "immediatebind" },
+ /* ATTR_IMPLICIT_HANDLE */ { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" },
+ /* ATTR_IN */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "in" },
+ /* ATTR_INPUTSYNC */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" },
+ /* ATTR_LENGTHIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "length_is" },
+ /* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "lcid" },
+ /* ATTR_LICENSED */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "licensed" },
+ /* ATTR_LOCAL */ { 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "local" },
+ /* ATTR_MARSHALING_BEHAVIOR */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "marshaling_behavior" },
+ /* ATTR_MAYBE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "maybe" },
+ /* ATTR_MESSAGE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "message" },
+ /* ATTR_NOCODE */ { 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nocode" },
+ /* ATTR_NONBROWSABLE */ { 0, 0, 0, 0, 1, 0, 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, 0, 1, 0, 0, "noncreatable" },
+ /* ATTR_NONEXTENSIBLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonextensible" },
+ /* ATTR_NOTIFY */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify" },
+ /* ATTR_NOTIFYFLAG */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify_flag" },
+ /* ATTR_OBJECT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "object" },
+ /* ATTR_ODL */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "odl" },
+ /* ATTR_OLEAUTOMATION */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "oleautomation" },
+ /* ATTR_OPTIMIZE */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optimize" },
+ /* ATTR_OPTIONAL */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optional" },
+ /* ATTR_OUT */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "out" },
+ /* ATTR_PARAMLCID */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "lcid" },
+ /* ATTR_PARTIALIGNORE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "partial_ignore" },
+ /* ATTR_POINTERDEFAULT */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "pointer_default" },
+ /* ATTR_POINTERTYPE */ { 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 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, 0, 1, 0, 0, "progid" },
+ /* ATTR_PROPGET */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propget" },
+ /* ATTR_PROPPUT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propput" },
+ /* ATTR_PROPPUTREF */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propputref" },
+ /* ATTR_PROXY */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "proxy" },
+ /* ATTR_PUBLIC */ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "public" },
+ /* ATTR_RANGE */ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "range" },
+ /* ATTR_READONLY */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "readonly" },
+ /* ATTR_REPRESENTAS */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "represent_as" },
+ /* ATTR_REQUESTEDIT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "requestedit" },
+ /* ATTR_RESTRICTED */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, "restricted" },
+ /* ATTR_RETVAL */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "retval" },
+ /* ATTR_SIZEIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "size_is" },
+ /* ATTR_SOURCE */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "source" },
+ /* ATTR_STRICTCONTEXTHANDLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "strict_context_handle" },
+ /* ATTR_STRING */ { 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "string" },
+ /* ATTR_SWITCHIS */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "switch_is" },
+ /* ATTR_SWITCHTYPE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "switch_type" },
+ /* ATTR_THREADING */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, "threading" },
+ /* ATTR_TRANSMITAS */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "transmit_as" },
+ /* ATTR_UIDEFAULT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "uidefault" },
+ /* ATTR_USESGETLASTERROR */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "usesgetlasterror" },
+ /* ATTR_USERMARSHAL */ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "user_marshal" },
+ /* ATTR_UUID */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, "uuid" },
+ /* ATTR_V1ENUM */ { 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "v1_enum" },
+ /* ATTR_VARARG */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "vararg" },
+ /* ATTR_VERSION */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 2, 0, 0, 1, 0, 0, 1, 0, 1, "version" },
+ /* ATTR_VIPROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "vi_progid" },
+ /* ATTR_WIREMARSHAL */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "wire_marshal" },
};
+static attr_list_t *append_attr(attr_list_t *list, attr_t *attr)
+{
+ attr_t *attr_existing;
+ if (!attr) return list;
+ if (!list)
+ {
+ list = xmalloc( sizeof(*list) );
+ list_init( list );
+ }
+ LIST_FOR_EACH_ENTRY(attr_existing, list, attr_t, entry)
+ if (attr_existing->type == attr->type && !allowed_attr[attr->type].multiple)
+ {
+ parser_warning("duplicate attribute %s\n", get_attr_display_name(attr->type));
+ /* use the last attribute, like MIDL does */
+ list_remove(&attr_existing->entry);
+ break;
+ }
+ list_add_tail( list, &attr->entry );
+ return list;
+}
+
const char *get_attr_display_name(enum attr_type type)
{
return allowed_attr[type].display_name;
--
2.28.0

View File

@ -0,0 +1,134 @@
From ca0364f1bd90bb35821c6ffb620e502f2b4afb7a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Tue, 13 Oct 2020 14:30:32 +0200
Subject: [PATCH 17/28] widl: Support WinRT static attribute parsing.
---
tools/widl/header.c | 30 ++++++++++++++++++++++++++++++
tools/widl/parser.l | 1 +
tools/widl/parser.y | 8 ++++++++
tools/widl/widltypes.h | 1 +
4 files changed, 40 insertions(+)
diff --git a/tools/widl/header.c b/tools/widl/header.c
index 812becad63b..3bc6b452177 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -109,6 +109,17 @@ int is_attr(const attr_list_t *list, enum attr_type t)
return 0;
}
+static void get_attr_statics(const attr_list_t *attrs, expr_list_t *list)
+{
+ const attr_t *attr;
+ if (!attrs) return;
+ LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
+ {
+ if (attr->type != ATTR_STATIC) continue;
+ list_add_tail(list, &((expr_t *)attr->u.pval)->entry);
+ }
+}
+
void *get_attrp(const attr_list_t *list, enum attr_type t)
{
const attr_t *attr;
@@ -1495,6 +1506,8 @@ static void write_winrt_type_comments(FILE *header, const type_t *type)
{
expr_t *contract = get_attrp(type->attrs, ATTR_CONTRACT);
type_t *exclusiveto = get_attrp(type->attrs, ATTR_EXCLUSIVETO);
+ expr_list_t statics = LIST_INIT(statics);
+ get_attr_statics(type->attrs, &statics);
fprintf(header, " *\n");
if (contract)
{
@@ -1510,6 +1523,23 @@ static void write_winrt_type_comments(FILE *header, const type_t *type)
fprintf(header, " * Interface is a part of the implementation of type %s\n *\n", name);
free(name);
}
+ if (!list_empty(&statics))
+ {
+ expr_t *expr;
+ fprintf(header, " * RuntimeClass contains static methods.\n");
+ LIST_FOR_EACH_ENTRY(expr, &statics, expr_t, entry)
+ {
+ const type_t *iface = expr->u.tref.type, *apicontract = expr->ref->u.tref.type;
+ int version_req = expr->ref->ref->u.lval;
+ char *iface_name = format_namespace(iface->namespace, "", ".", iface->name, NULL);
+ char *name = format_namespace(apicontract->namespace, "", ".", apicontract->name, NULL);
+ fprintf(header, " * Static Methods exist on the %s interface starting with version %d.%d of the %s API contract\n",
+ iface_name, (version_req >> 16) & 0xffff, version_req & 0xffff, name);
+ free(iface_name);
+ free(name);
+ }
+ fprintf(header, " *\n");
+ }
if (type_get_type(type) == TYPE_RUNTIMECLASS)
{
ifref_list_t *ifaces = type_runtimeclass_get_ifaces(type);
diff --git a/tools/widl/parser.l b/tools/widl/parser.l
index f5a57db4797..90791543db2 100644
--- a/tools/widl/parser.l
+++ b/tools/widl/parser.l
@@ -422,6 +422,7 @@ static const struct keyword attr_keywords[] =
{"size_is", tSIZEIS, 0},
{"source", tSOURCE, 0},
{"standard", tSTANDARD, 1},
+ {"static", tSTATIC, 1},
{"strict_context_handle", tSTRICTCONTEXTHANDLE, 0},
{"string", tSTRING, 0},
{"switch_is", tSWITCHIS, 0},
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 1727b5bb396..e6e67826a8f 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -283,6 +283,7 @@ static typelib_t *current_typelib;
%type <expr> m_expr expr expr_const expr_int_const array m_bitfield
%type <expr_list> m_exprs /* exprs expr_list */ expr_list_int_const
%type <expr> contract_req
+%type <expr> static_attr
%type <type> interfacehdr
%type <stgclass> storage_cls_spec
%type <type_qualifier> type_qualifier m_type_qual_list
@@ -538,6 +539,11 @@ contract_req: decl_spec ',' contract_ver { if ($1->type->type_type != TYPE_APICO
$$ = make_exprt(EXPR_GTREQL, declare_var(NULL, $1, make_declarator(NULL), 0), $$);
}
+static_attr: decl_spec ',' contract_req { if ($1->type->type_type != TYPE_INTERFACE)
+ error_loc("type %s is not an interface\n", $1->type->name);
+ $$ = make_exprt(EXPR_MEMBER, declare_var(NULL, $1, make_declarator(NULL), 0), $3);
+ }
+
attribute: { $$ = NULL; }
| tAGGREGATABLE { $$ = make_attr(ATTR_AGGREGATABLE); }
| tANNOTATION '(' aSTRING ')' { $$ = make_attrp(ATTR_ANNOTATION, $3); }
@@ -634,6 +640,7 @@ attribute: { $$ = NULL; }
| tRETVAL { $$ = make_attr(ATTR_RETVAL); }
| tSIZEIS '(' m_exprs ')' { $$ = make_attrp(ATTR_SIZEIS, $3); }
| tSOURCE { $$ = make_attr(ATTR_SOURCE); }
+ | tSTATIC '(' static_attr ')' { $$ = make_attrp(ATTR_STATIC, $3); }
| tSTRICTCONTEXTHANDLE { $$ = make_attr(ATTR_STRICTCONTEXTHANDLE); }
| tSTRING { $$ = make_attr(ATTR_STRING); }
| tSWITCHIS '(' expr ')' { $$ = make_attrp(ATTR_SWITCHIS, $3); }
@@ -2296,6 +2303,7 @@ struct allowed_attr allowed_attr[] =
/* ATTR_RETVAL */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "retval" },
/* ATTR_SIZEIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "size_is" },
/* ATTR_SOURCE */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "source" },
+ /* ATTR_STATIC */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "static" },
/* ATTR_STRICTCONTEXTHANDLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "strict_context_handle" },
/* ATTR_STRING */ { 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "string" },
/* ATTR_SWITCHIS */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "switch_is" },
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index 0bf7b644fff..aa3e6e75898 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -159,6 +159,7 @@ enum attr_type
ATTR_RETVAL,
ATTR_SIZEIS,
ATTR_SOURCE,
+ ATTR_STATIC,
ATTR_STRICTCONTEXTHANDLE,
ATTR_STRING,
ATTR_SWITCHIS,
--
2.28.0

View File

@ -0,0 +1,254 @@
From 0d3503123e3f0cb458ada24b052e1d39f1c4dddb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Tue, 13 Oct 2020 00:31:57 +0200
Subject: [PATCH 18/28] widl: Support WinRT requires keyword.
---
tools/widl/header.c | 13 +++++++++++
tools/widl/parser.l | 1 +
tools/widl/parser.y | 49 ++++++++++++++++++++++++++++++++----------
tools/widl/typetree.c | 5 ++++-
tools/widl/typetree.h | 9 +++++++-
tools/widl/widltypes.h | 1 +
6 files changed, 65 insertions(+), 13 deletions(-)
diff --git a/tools/widl/header.c b/tools/widl/header.c
index 3bc6b452177..5dfc5e2ff8c 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -1506,6 +1506,7 @@ static void write_winrt_type_comments(FILE *header, const type_t *type)
{
expr_t *contract = get_attrp(type->attrs, ATTR_CONTRACT);
type_t *exclusiveto = get_attrp(type->attrs, ATTR_EXCLUSIVETO);
+ type_list_t *requires = type->type_type == TYPE_INTERFACE ? type_iface_get_requires(type) : NULL;
expr_list_t statics = LIST_INIT(statics);
get_attr_statics(type->attrs, &statics);
fprintf(header, " *\n");
@@ -1523,6 +1524,18 @@ static void write_winrt_type_comments(FILE *header, const type_t *type)
fprintf(header, " * Interface is a part of the implementation of type %s\n *\n", name);
free(name);
}
+ if (requires)
+ {
+ type_list_t *req;
+ fprintf(header, " * Any object which implements this interface must also implement the following interfaces:\n");
+ for (req = requires; req; req = req->next)
+ {
+ char *name = format_namespace(req->type->namespace, "", ".", req->type->name, NULL);
+ fprintf(header, " * %s\n", name);
+ free(name);
+ }
+ fprintf(header, " *\n");
+ }
if (!list_empty(&statics))
{
expr_t *expr;
diff --git a/tools/widl/parser.l b/tools/widl/parser.l
index 90791543db2..2b41bea1bc9 100644
--- a/tools/widl/parser.l
+++ b/tools/widl/parser.l
@@ -298,6 +298,7 @@ static const struct keyword keywords[] = {
{"pascal", tPASCAL, 0},
{"properties", tPROPERTIES, 0},
{"register", tREGISTER, 0},
+ {"requires", tREQUIRES, 1},
{"runtimeclass", tRUNTIMECLASS, 1},
{"short", tSHORT, 0},
{"signed", tSIGNED, 0},
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index e6e67826a8f..1da667e0ced 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -38,12 +38,6 @@
#include "expr.h"
#include "typetree.h"
-typedef struct list typelist_t;
-struct typenode {
- type_t *type;
- struct list entry;
-};
-
struct _import_t
{
char *name;
@@ -51,6 +45,8 @@ struct _import_t
};
static str_list_t *append_str(str_list_t *list, char *str);
+static type_list_t *append_type(type_list_t *list, type_t *type);
+static type_list_t *append_types(type_list_t *list, type_list_t *types);
static attr_list_t *append_attr(attr_list_t *list, attr_t *attr);
static attr_list_t *append_attr_list(attr_list_t *new_list, attr_list_t *old_list);
static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right,
@@ -140,6 +136,7 @@ static typelib_t *current_typelib;
expr_t *expr;
expr_list_t *expr_list;
type_t *type;
+ type_list_t *typelist;
var_t *var;
var_list_t *var_list;
declarator_t *declarator;
@@ -247,6 +244,7 @@ static typelib_t *current_typelib;
%token tREADONLY tREF
%token tREGISTER tREPRESENTAS
%token tREQUESTEDIT
+%token tREQUIRES
%token tRESTRICTED
%token tRETVAL
%token tRUNTIMECLASS
@@ -296,6 +294,7 @@ static typelib_t *current_typelib;
%type <type> base_type int_std
%type <type> enumdef structdef uniondef typedecl
%type <type> type qualified_type
+%type <typelist> requires required_types
%type <ifref> class_interface
%type <ifref_list> class_interfaces
%type <var> arg ne_union_field union_field s_field case enum enum_member declaration
@@ -1009,19 +1008,27 @@ interfacehdr: attributes interface { $$ = $2;
}
;
-interfacedef: interfacehdr inherit
+required_types:
+ qualified_type { $$ = append_type(NULL, $1); }
+ | required_types ',' required_types { $$ = append_types($1, $3); }
+
+requires: { $$ = NULL; }
+ | tREQUIRES required_types { $$ = $2; }
+ ;
+
+interfacedef: interfacehdr inherit requires
'{' int_statements '}' semicolon_opt { $$ = $1;
if($$ == $2)
error_loc("Interface can't inherit from itself\n");
- type_interface_define($$, $2, $4);
+ type_interface_define($$, $2, $5, $3);
check_async_uuid($$);
}
/* MIDL is able to import the definition of a base class from inside the
* definition of a derived class, I'll try to support it with this rule */
- | interfacehdr ':' aIDENTIFIER
+ | interfacehdr ':' aIDENTIFIER requires
'{' import int_statements '}'
semicolon_opt { $$ = $1;
- type_interface_define($$, find_type_or_error2($3, 0), $6);
+ type_interface_define($$, find_type_or_error2($3, 0), $7, $4);
}
| dispinterfacedef semicolon_opt { $$ = $1; }
;
@@ -1317,6 +1324,26 @@ static str_list_t *append_str(str_list_t *list, char *str)
return list;
}
+static type_list_t *append_type(type_list_t *list, type_t *type)
+{
+ type_list_t *entry;
+ if (!type) return list;
+ entry = xmalloc( sizeof(*entry) );
+ entry->type = type;
+ entry->next = list;
+ return entry;
+}
+
+static type_list_t *append_types(type_list_t *list, type_list_t *types)
+{
+ type_list_t *entry;
+ if (!list) return types;
+ if (!types) return list;
+ for (entry = list; entry->next; entry = entry->next) {}
+ entry->next = types;
+ return list;
+}
+
static attr_list_t *move_attr(attr_list_t *dst, attr_list_t *src, enum attr_type type)
{
attr_t *attr;
@@ -3015,7 +3042,7 @@ static void check_async_uuid(type_t *iface)
stmts = append_statement(stmts, make_statement_declaration(finish_func));
}
- type_interface_define(async_iface, inherit, stmts);
+ type_interface_define(async_iface, inherit, stmts, NULL);
iface->details.iface->async_iface = async_iface->details.iface->async_iface = async_iface;
}
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
index d075619448d..3d26fd23b26 100644
--- a/tools/widl/typetree.c
+++ b/tools/widl/typetree.c
@@ -459,7 +459,7 @@ static unsigned int compute_method_indexes(type_t *iface)
return idx;
}
-void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts)
+void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts, type_list_t *requires)
{
iface->details.iface = xmalloc(sizeof(*iface->details.iface));
iface->details.iface->disp_props = NULL;
@@ -468,6 +468,7 @@ void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stm
iface->details.iface->inherit = inherit;
iface->details.iface->disp_inherit = NULL;
iface->details.iface->async_iface = NULL;
+ iface->details.iface->requires = requires;
iface->defined = TRUE;
compute_method_indexes(iface);
}
@@ -482,6 +483,7 @@ void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *met
if (!iface->details.iface->inherit) error_loc("IDispatch is undefined\n");
iface->details.iface->disp_inherit = NULL;
iface->details.iface->async_iface = NULL;
+ iface->details.iface->requires = NULL;
iface->defined = TRUE;
compute_method_indexes(iface);
}
@@ -496,6 +498,7 @@ void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface)
if (!dispiface->details.iface->inherit) error_loc("IDispatch is undefined\n");
dispiface->details.iface->disp_inherit = iface;
dispiface->details.iface->async_iface = NULL;
+ dispiface->details.iface->requires = NULL;
dispiface->defined = TRUE;
compute_method_indexes(dispiface);
}
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
index 951084cf875..8c555b91656 100644
--- a/tools/widl/typetree.h
+++ b/tools/widl/typetree.h
@@ -45,7 +45,7 @@ type_t *type_new_nonencapsulated_union(const char *name, int defined, var_list_t
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_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts, type_list_t *requires);
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);
@@ -169,6 +169,13 @@ static inline type_t *type_iface_get_inherit(const type_t *type)
return type->details.iface->inherit;
}
+static inline type_list_t *type_iface_get_requires(const type_t *type)
+{
+ type = type_get_real_type(type);
+ assert(type_get_type(type) == TYPE_INTERFACE);
+ return type->details.iface->requires;
+}
+
static inline type_t *type_iface_get_async_iface(const type_t *type)
{
type = type_get_real_type(type);
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index aa3e6e75898..be71886260b 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -378,6 +378,7 @@ struct iface_details
struct _type_t *inherit;
struct _type_t *disp_inherit;
struct _type_t *async_iface;
+ type_list_t *requires;
};
struct module_details
--
2.28.0

View File

@ -0,0 +1,96 @@
From c0c0bfcf80077cd2b5db3f7c1fb3fa597ae57321 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Tue, 13 Oct 2020 11:35:29 +0200
Subject: [PATCH 19/28] widl: Support WinRT activatable attribute.
---
tools/widl/header.c | 11 +++++++++++
tools/widl/parser.l | 1 +
tools/widl/parser.y | 3 +++
tools/widl/widltypes.h | 1 +
4 files changed, 16 insertions(+)
diff --git a/tools/widl/header.c b/tools/widl/header.c
index 5dfc5e2ff8c..5c87a997349 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -1505,6 +1505,7 @@ static char *format_apicontract_macro(const type_t *type)
static void write_winrt_type_comments(FILE *header, const type_t *type)
{
expr_t *contract = get_attrp(type->attrs, ATTR_CONTRACT);
+ expr_t *activatable = get_attrp(type->attrs, ATTR_ACTIVATABLE);
type_t *exclusiveto = get_attrp(type->attrs, ATTR_EXCLUSIVETO);
type_list_t *requires = type->type_type == TYPE_INTERFACE ? type_iface_get_requires(type) : NULL;
expr_list_t statics = LIST_INIT(statics);
@@ -1518,6 +1519,16 @@ static void write_winrt_type_comments(FILE *header, const type_t *type)
fprintf(header, " * Introduced to %s in version %d.%d\n *\n", name, (ver >> 16) & 0xffff, ver & 0xffff);
free(name);
}
+ if (activatable)
+ {
+ const type_t *apicontract = activatable->u.tref.type;
+ int version_req = activatable->ref->u.lval;
+ char *name = format_namespace(apicontract->namespace, "", ".", apicontract->name, NULL);
+ fprintf(header, " * RuntimeClass can be activated.\n");
+ fprintf(header, " * Type can be activated via RoActivateInstance starting with version %d.%d of the %s API contract\n *\n",
+ (version_req >> 16) & 0xffff, version_req & 0xffff, name);
+ free(name);
+ }
if (exclusiveto)
{
char *name = format_namespace(exclusiveto->namespace, "", ".", exclusiveto->name, NULL);
diff --git a/tools/widl/parser.l b/tools/widl/parser.l
index 2b41bea1bc9..a47c490ec4c 100644
--- a/tools/widl/parser.l
+++ b/tools/widl/parser.l
@@ -321,6 +321,7 @@ static const struct keyword keywords[] = {
*/
static const struct keyword attr_keywords[] =
{
+ {"activatable", tACTIVATABLE, 1},
{"aggregatable", tAGGREGATABLE, 0},
{"agile", tAGILE, 1},
{"allocate", tALLOCATE, 0},
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 1da667e0ced..d24f8881147 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -172,6 +172,7 @@ static typelib_t *current_typelib;
%token GREATEREQUAL LESSEQUAL
%token LOGICALOR LOGICALAND
%token ELLIPSIS
+%token tACTIVATABLE
%token tAGGREGATABLE
%token tAGILE
%token tALLOCATE tANNOTATION
@@ -544,6 +545,7 @@ static_attr: decl_spec ',' contract_req { if ($1->type->type_type != TYPE_INTER
}
attribute: { $$ = NULL; }
+ | tACTIVATABLE '(' contract_req ')' { $$ = make_attrp(ATTR_ACTIVATABLE, $3); }
| tAGGREGATABLE { $$ = make_attr(ATTR_AGGREGATABLE); }
| tANNOTATION '(' aSTRING ')' { $$ = make_attrp(ATTR_ANNOTATION, $3); }
| tAPPOBJECT { $$ = make_attr(ATTR_APPOBJECT); }
@@ -2239,6 +2241,7 @@ struct allowed_attr
struct allowed_attr allowed_attr[] =
{
/* attr { D ACF M I Fn ARG T En Enm St Un Fi L DI M C AC R <display name> } */
+ /* ATTR_ACTIVATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "activatable" },
/* ATTR_AGGREGATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "aggregatable" },
/* ATTR_ANNOTATION */ { 0, 0, 0, 0, 0, 1, 0, 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, 0, 1, 0, 0, "appobject" },
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index be71886260b..7ca770b67ea 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -68,6 +68,7 @@ typedef struct list warning_list_t;
enum attr_type
{
+ ATTR_ACTIVATABLE,
ATTR_AGGREGATABLE,
ATTR_ANNOTATION,
ATTR_APPOBJECT,
--
2.28.0

Some files were not shown because too many files have changed in this diff Show More