mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-01-28 22:04:43 -08:00
Added widl-winrt-support patchset
This commit is contained in:
parent
3cea972271
commit
ae8bdc6121
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -0,0 +1,551 @@
|
||||
From 70534016bc2963703a003e9a0888ad21f5bf026e Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Tue, 13 Oct 2020 13:37:19 +0200
|
||||
Subject: [PATCH 05/28] widl: Support WinRT apicontract type.
|
||||
|
||||
---
|
||||
include/Makefile.in | 1 +
|
||||
include/windows.foundation.idl | 1 +
|
||||
include/windowscontracts.idl | 33 +++++
|
||||
tools/widl/expr.c | 1 +
|
||||
tools/widl/header.c | 24 ++++
|
||||
tools/widl/parser.l | 1 +
|
||||
tools/widl/parser.y | 235 +++++++++++++++++++--------------
|
||||
tools/widl/typegen.c | 6 +
|
||||
tools/widl/typelib.c | 3 +-
|
||||
tools/widl/typetree.h | 3 +
|
||||
tools/widl/widltypes.h | 1 +
|
||||
11 files changed, 206 insertions(+), 103 deletions(-)
|
||||
create mode 100644 include/windowscontracts.idl
|
||||
|
||||
diff --git a/include/Makefile.in b/include/Makefile.in
|
||||
index d59b0be715d..91297753b12 100644
|
||||
--- a/include/Makefile.in
|
||||
+++ b/include/Makefile.in
|
||||
@@ -737,6 +737,7 @@ SOURCES = \
|
||||
windows.foundation.idl \
|
||||
windows.media.speechsynthesis.idl \
|
||||
windows.h \
|
||||
+ windowscontracts.idl \
|
||||
windowsx.h \
|
||||
wine/debug.h \
|
||||
wine/exception.h \
|
||||
diff --git a/include/windows.foundation.idl b/include/windows.foundation.idl
|
||||
index 2c16fa2da22..2a38e9f671b 100644
|
||||
--- a/include/windows.foundation.idl
|
||||
+++ b/include/windows.foundation.idl
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
import "inspectable.idl";
|
||||
/* import "asyncinfo.idl"; */
|
||||
+import "windowscontracts.idl";
|
||||
/* import "eventtoken.idl"; */
|
||||
/* import "ivectorchangedeventargs.idl"; */
|
||||
|
||||
diff --git a/include/windowscontracts.idl b/include/windowscontracts.idl
|
||||
new file mode 100644
|
||||
index 00000000000..6bcf80ac954
|
||||
--- /dev/null
|
||||
+++ b/include/windowscontracts.idl
|
||||
@@ -0,0 +1,33 @@
|
||||
+/*
|
||||
+ * 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
|
||||
+
|
||||
+namespace Windows {
|
||||
+ namespace Foundation {
|
||||
+ [contractversion(4)]
|
||||
+ apicontract FoundationContract
|
||||
+ {};
|
||||
+
|
||||
+ [contractversion(10)]
|
||||
+ apicontract UniversalApiContract
|
||||
+ {};
|
||||
+ }
|
||||
+}
|
||||
diff --git a/tools/widl/expr.c b/tools/widl/expr.c
|
||||
index d1ee599a39e..be8311cfb7f 100644
|
||||
--- a/tools/widl/expr.c
|
||||
+++ b/tools/widl/expr.c
|
||||
@@ -462,6 +462,7 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type,
|
||||
case TYPE_POINTER:
|
||||
case TYPE_ARRAY:
|
||||
case TYPE_BITFIELD:
|
||||
+ case TYPE_APICONTRACT:
|
||||
/* nothing to do */
|
||||
break;
|
||||
case TYPE_ALIAS:
|
||||
diff --git a/tools/widl/header.c b/tools/widl/header.c
|
||||
index d67fea4cc95..607d156ccf4 100644
|
||||
--- a/tools/widl/header.c
|
||||
+++ b/tools/widl/header.c
|
||||
@@ -464,6 +464,7 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i
|
||||
break;
|
||||
}
|
||||
case TYPE_ALIAS:
|
||||
+ case TYPE_APICONTRACT:
|
||||
/* handled elsewhere */
|
||||
assert(0);
|
||||
break;
|
||||
@@ -529,6 +530,10 @@ void write_type_right(FILE *h, type_t *t, int is_field)
|
||||
case TYPE_COCLASS:
|
||||
case TYPE_INTERFACE:
|
||||
break;
|
||||
+ case TYPE_APICONTRACT:
|
||||
+ /* not supposed to be here */
|
||||
+ assert(0);
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1446,6 +1451,14 @@ static void write_forward(FILE *header, type_t *iface)
|
||||
fprintf(header, "#endif\n\n" );
|
||||
}
|
||||
|
||||
+static char *format_apicontract_macro(const type_t *type)
|
||||
+{
|
||||
+ char *name = format_namespace(type->namespace, "", "_", type->name, NULL);
|
||||
+ int i;
|
||||
+ for (i = strlen(name); i > 0; --i) name[i - 1] = toupper(name[i - 1]);
|
||||
+ return name;
|
||||
+}
|
||||
+
|
||||
static void write_com_interface_start(FILE *header, const type_t *iface)
|
||||
{
|
||||
int dispinterface = is_attr(iface->attrs, ATTR_DISPINTERFACE);
|
||||
@@ -1610,6 +1623,15 @@ static void write_coclass_forward(FILE *header, type_t *cocl)
|
||||
fprintf(header, "#endif /* defined __%s_FWD_DEFINED__ */\n\n", cocl->name );
|
||||
}
|
||||
|
||||
+static void write_apicontract(FILE *header, type_t *apicontract)
|
||||
+{
|
||||
+ char *name = format_apicontract_macro(apicontract);
|
||||
+ fprintf(header, "#if !defined(%s_VERSION)\n", name);
|
||||
+ fprintf(header, "#define %s_VERSION %#x\n", name, get_attrv(apicontract->attrs, ATTR_CONTRACTVERSION));
|
||||
+ fprintf(header, "#endif // defined(%s_VERSION)\n\n", name);
|
||||
+ free(name);
|
||||
+}
|
||||
+
|
||||
static void write_import(FILE *header, const char *fname)
|
||||
{
|
||||
char *hname, *p;
|
||||
@@ -1728,6 +1750,8 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
|
||||
}
|
||||
else if (type_get_type(stmt->u.type) == TYPE_COCLASS)
|
||||
write_coclass(header, stmt->u.type);
|
||||
+ else if (type_get_type(stmt->u.type) == TYPE_APICONTRACT)
|
||||
+ write_apicontract(header, stmt->u.type);
|
||||
else
|
||||
{
|
||||
write_type_definition(header, stmt->u.type, stmt->declonly);
|
||||
diff --git a/tools/widl/parser.l b/tools/widl/parser.l
|
||||
index dafd17ab2f9..11debca2ebd 100644
|
||||
--- a/tools/widl/parser.l
|
||||
+++ b/tools/widl/parser.l
|
||||
@@ -267,6 +267,7 @@ static const struct keyword keywords[] = {
|
||||
{"_fastcall", tFASTCALL, 0},
|
||||
{"_pascal", tPASCAL, 0},
|
||||
{"_stdcall", tSTDCALL, 0},
|
||||
+ {"apicontract", tAPICONTRACT, 1},
|
||||
{"boolean", tBOOLEAN, 0},
|
||||
{"byte", tBYTE, 0},
|
||||
{"case", tCASE, 0},
|
||||
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
|
||||
index 88cb9a10863..bdd019a2880 100644
|
||||
--- a/tools/widl/parser.y
|
||||
+++ b/tools/widl/parser.y
|
||||
@@ -99,6 +99,7 @@ static attr_list_t *check_library_attrs(const char *name, attr_list_t *attrs);
|
||||
static attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs);
|
||||
static attr_list_t *check_module_attrs(const char *name, attr_list_t *attrs);
|
||||
static attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs);
|
||||
+static attr_list_t *check_apicontract_attrs(const char *name, attr_list_t *attrs);
|
||||
const char *get_attr_display_name(enum attr_type type);
|
||||
static void add_explicit_handle_if_necessary(const type_t *iface, var_t *func);
|
||||
static void check_def(const type_t *t);
|
||||
@@ -172,7 +173,9 @@ static typelib_t *current_typelib;
|
||||
%token GREATEREQUAL LESSEQUAL
|
||||
%token LOGICALOR LOGICALAND
|
||||
%token ELLIPSIS
|
||||
-%token tAGGREGATABLE tALLOCATE tANNOTATION tAPPOBJECT tASYNC tASYNCUUID
|
||||
+%token tAGGREGATABLE tALLOCATE tANNOTATION
|
||||
+%token tAPICONTRACT
|
||||
+%token tAPPOBJECT tASYNC tASYNCUUID
|
||||
%token tAUTOHANDLE tBINDABLE tBOOLEAN tBROADCAST tBYTE tBYTECOUNT
|
||||
%token tCALLAS tCALLBACK tCASE tCDECL tCHAR tCOCLASS tCODE tCOMMSTATUS
|
||||
%token tCONST tCONTEXTHANDLE tCONTEXTHANDLENOSERIALIZE
|
||||
@@ -290,6 +293,7 @@ static typelib_t *current_typelib;
|
||||
%type <declarator> m_abstract_declarator abstract_declarator abstract_declarator_no_direct abstract_direct_declarator
|
||||
%type <declarator_list> declarator_list struct_declarator_list
|
||||
%type <type> coclass coclasshdr coclassdef
|
||||
+%type <type> apicontract
|
||||
%type <num> contract_ver
|
||||
%type <num> pointer_type threading_type version
|
||||
%type <str> libraryhdr callconv cppquote importlib import t_ident
|
||||
@@ -346,6 +350,8 @@ gbl_statements: { $$ = NULL; }
|
||||
| gbl_statements coclassdef { $$ = append_statement($1, make_statement_type_decl($2));
|
||||
reg_type($2, $2->name, current_namespace, 0);
|
||||
}
|
||||
+ | gbl_statements apicontract ';' { $$ = append_statement($1, make_statement_type_decl($2));
|
||||
+ reg_type($2, $2->name, current_namespace, 0); }
|
||||
| gbl_statements moduledef { $$ = append_statement($1, make_statement_module($2)); }
|
||||
| gbl_statements librarydef { $$ = append_statement($1, make_statement_library($2)); }
|
||||
| gbl_statements statement { $$ = append_statement($1, $2); }
|
||||
@@ -360,6 +366,8 @@ imp_statements: { $$ = NULL; }
|
||||
| imp_statements coclassdef { $$ = append_statement($1, make_statement_type_decl($2));
|
||||
reg_type($2, $2->name, current_namespace, 0);
|
||||
}
|
||||
+ | imp_statements apicontract ';' { $$ = append_statement($1, make_statement_type_decl($2));
|
||||
+ reg_type($2, $2->name, current_namespace, 0); }
|
||||
| imp_statements moduledef { $$ = append_statement($1, make_statement_module($2)); }
|
||||
| imp_statements statement { $$ = append_statement($1, $2); }
|
||||
| imp_statements importlib { $$ = append_statement($1, make_statement_importlib($2)); }
|
||||
@@ -864,6 +872,13 @@ coclassdef: coclasshdr '{' coclass_ints '}' semicolon_opt
|
||||
{ $$ = type_coclass_define($1, $3); }
|
||||
;
|
||||
|
||||
+apicontract: attributes tAPICONTRACT aIDENTIFIER '{' '}'
|
||||
+ { $$ = get_type(TYPE_APICONTRACT, $3, current_namespace, 0);
|
||||
+ check_def($$);
|
||||
+ $$->attrs = check_apicontract_attrs($$->name, $1);
|
||||
+ }
|
||||
+ ;
|
||||
+
|
||||
namespacedef: tNAMESPACE aIDENTIFIER { $$ = $2; }
|
||||
| tNAMESPACE aNAMESPACE { $$ = $2; }
|
||||
;
|
||||
@@ -2124,112 +2139,113 @@ struct allowed_attr
|
||||
unsigned int on_dispinterface : 1;
|
||||
unsigned int on_module : 1;
|
||||
unsigned int on_coclass : 1;
|
||||
+ unsigned int on_apicontract : 1;
|
||||
const char *display_name;
|
||||
};
|
||||
|
||||
struct allowed_attr allowed_attr[] =
|
||||
{
|
||||
- /* attr { D ACF I Fn ARG T En Enm St Un Fi L DI M C <display name> } */
|
||||
- /* ATTR_AGGREGATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "aggregatable" },
|
||||
- /* ATTR_ANNOTATION */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "annotation" },
|
||||
- /* ATTR_APPOBJECT */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "appobject" },
|
||||
- /* ATTR_ASYNC */ { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "async" },
|
||||
- /* ATTR_ASYNCUUID */ { 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, "async_uuid" },
|
||||
- /* ATTR_AUTO_HANDLE */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "auto_handle" },
|
||||
- /* ATTR_BINDABLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "bindable" },
|
||||
- /* ATTR_BROADCAST */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "broadcast" },
|
||||
- /* ATTR_CALLAS */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "call_as" },
|
||||
- /* ATTR_CALLCONV */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL },
|
||||
- /* ATTR_CASE */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "case" },
|
||||
- /* ATTR_CODE */ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" },
|
||||
- /* ATTR_COMMSTATUS */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" },
|
||||
- /* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" },
|
||||
- /* ATTR_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" },
|
||||
- /* ATTR_DEFAULTBIND */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultbind" },
|
||||
- /* ATTR_DEFAULTCOLLELEM */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultcollelem" },
|
||||
- /* ATTR_DEFAULTVALUE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultvalue" },
|
||||
- /* ATTR_DEFAULTVTABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "defaultvtable" },
|
||||
- /* ATTR_DISABLECONSISTENCYCHECK */{ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "disable_consistency_check" },
|
||||
- /* ATTR_DISPINTERFACE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL },
|
||||
- /* ATTR_DISPLAYBIND */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "displaybind" },
|
||||
- /* ATTR_DLLNAME */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "dllname" },
|
||||
- /* ATTR_DUAL */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "dual" },
|
||||
- /* ATTR_ENABLEALLOCATE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "enable_allocate" },
|
||||
- /* ATTR_ENCODE */ { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "encode" },
|
||||
- /* ATTR_ENDPOINT */ { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "endpoint" },
|
||||
- /* ATTR_ENTRY */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "entry" },
|
||||
- /* ATTR_EXPLICIT_HANDLE */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "explicit_handle" },
|
||||
- /* ATTR_FAULTSTATUS */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "fault_status" },
|
||||
- /* ATTR_FORCEALLOCATE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "force_allocate" },
|
||||
- /* ATTR_HANDLE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "handle" },
|
||||
- /* ATTR_HELPCONTEXT */ { 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, "helpcontext" },
|
||||
- /* ATTR_HELPFILE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "helpfile" },
|
||||
- /* ATTR_HELPSTRING */ { 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, "helpstring" },
|
||||
- /* ATTR_HELPSTRINGCONTEXT */ { 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, "helpstringcontext" },
|
||||
- /* ATTR_HELPSTRINGDLL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "helpstringdll" },
|
||||
- /* ATTR_HIDDEN */ { 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, "hidden" },
|
||||
- /* ATTR_ID */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, "id" },
|
||||
- /* ATTR_IDEMPOTENT */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "idempotent" },
|
||||
- /* ATTR_IGNORE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "ignore" },
|
||||
- /* ATTR_IIDIS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "iid_is" },
|
||||
- /* ATTR_IMMEDIATEBIND */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "immediatebind" },
|
||||
- /* ATTR_IMPLICIT_HANDLE */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" },
|
||||
- /* ATTR_IN */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "in" },
|
||||
- /* ATTR_INPUTSYNC */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" },
|
||||
- /* ATTR_LENGTHIS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "length_is" },
|
||||
- /* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "lcid" },
|
||||
- /* ATTR_LICENSED */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "licensed" },
|
||||
- /* ATTR_LOCAL */ { 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "local" },
|
||||
- /* ATTR_MAYBE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "maybe" },
|
||||
- /* ATTR_MESSAGE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "message" },
|
||||
- /* ATTR_NOCODE */ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nocode" },
|
||||
- /* ATTR_NONBROWSABLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonbrowsable" },
|
||||
- /* ATTR_NONCREATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "noncreatable" },
|
||||
- /* ATTR_NONEXTENSIBLE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonextensible" },
|
||||
- /* ATTR_NOTIFY */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify" },
|
||||
- /* ATTR_NOTIFYFLAG */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify_flag" },
|
||||
- /* ATTR_OBJECT */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "object" },
|
||||
- /* ATTR_ODL */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "odl" },
|
||||
- /* ATTR_OLEAUTOMATION */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "oleautomation" },
|
||||
- /* ATTR_OPTIMIZE */ { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optimize" },
|
||||
- /* ATTR_OPTIONAL */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optional" },
|
||||
- /* ATTR_OUT */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "out" },
|
||||
- /* ATTR_PARAMLCID */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "lcid" },
|
||||
- /* ATTR_PARTIALIGNORE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "partial_ignore" },
|
||||
- /* ATTR_POINTERDEFAULT */ { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "pointer_default" },
|
||||
- /* ATTR_POINTERTYPE */ { 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, "ref, unique or ptr" },
|
||||
- /* ATTR_PROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "progid" },
|
||||
- /* ATTR_PROPGET */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propget" },
|
||||
- /* ATTR_PROPPUT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propput" },
|
||||
- /* ATTR_PROPPUTREF */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propputref" },
|
||||
- /* ATTR_PROXY */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "proxy" },
|
||||
- /* ATTR_PUBLIC */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "public" },
|
||||
- /* ATTR_RANGE */ { 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, "range" },
|
||||
- /* ATTR_READONLY */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "readonly" },
|
||||
- /* ATTR_REPRESENTAS */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "represent_as" },
|
||||
- /* ATTR_REQUESTEDIT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "requestedit" },
|
||||
- /* ATTR_RESTRICTED */ { 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, "restricted" },
|
||||
- /* ATTR_RETVAL */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "retval" },
|
||||
- /* ATTR_SIZEIS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "size_is" },
|
||||
- /* ATTR_SOURCE */ { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "source" },
|
||||
- /* ATTR_STRICTCONTEXTHANDLE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "strict_context_handle" },
|
||||
- /* ATTR_STRING */ { 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, "string" },
|
||||
- /* ATTR_SWITCHIS */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "switch_is" },
|
||||
- /* ATTR_SWITCHTYPE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, "switch_type" },
|
||||
- /* ATTR_THREADING */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "threading" },
|
||||
- /* ATTR_TRANSMITAS */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "transmit_as" },
|
||||
- /* ATTR_UIDEFAULT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "uidefault" },
|
||||
- /* ATTR_USESGETLASTERROR */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "usesgetlasterror" },
|
||||
- /* ATTR_USERMARSHAL */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "user_marshal" },
|
||||
- /* ATTR_UUID */ { 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, "uuid" },
|
||||
- /* ATTR_V1ENUM */ { 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, "v1_enum" },
|
||||
- /* ATTR_VARARG */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "vararg" },
|
||||
- /* ATTR_VERSION */ { 1, 0, 1, 0, 0, 1, 1, 0, 2, 0, 0, 1, 0, 0, 1, "version" },
|
||||
- /* ATTR_VIPROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "vi_progid" },
|
||||
- /* ATTR_WIREMARSHAL */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "wire_marshal" },
|
||||
+ /* attr { D ACF I Fn ARG T En Enm St Un Fi L DI M C AC <display name> } */
|
||||
+ /* ATTR_AGGREGATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "aggregatable" },
|
||||
+ /* ATTR_ANNOTATION */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "annotation" },
|
||||
+ /* ATTR_APPOBJECT */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "appobject" },
|
||||
+ /* ATTR_ASYNC */ { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "async" },
|
||||
+ /* ATTR_ASYNCUUID */ { 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, "async_uuid" },
|
||||
+ /* ATTR_AUTO_HANDLE */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "auto_handle" },
|
||||
+ /* ATTR_BINDABLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "bindable" },
|
||||
+ /* ATTR_BROADCAST */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "broadcast" },
|
||||
+ /* ATTR_CALLAS */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "call_as" },
|
||||
+ /* ATTR_CALLCONV */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL },
|
||||
+ /* ATTR_CASE */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "case" },
|
||||
+ /* ATTR_CODE */ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" },
|
||||
+ /* ATTR_COMMSTATUS */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" },
|
||||
+ /* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" },
|
||||
+ /* ATTR_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" },
|
||||
+ /* ATTR_DEFAULT */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, "default" },
|
||||
+ /* ATTR_DEFAULTBIND */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultbind" },
|
||||
+ /* ATTR_DEFAULTCOLLELEM */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultcollelem" },
|
||||
+ /* ATTR_DEFAULTVALUE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultvalue" },
|
||||
+ /* ATTR_DEFAULTVTABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "defaultvtable" },
|
||||
+ /* ATTR_DISABLECONSISTENCYCHECK */{ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "disable_consistency_check" },
|
||||
+ /* ATTR_DISPINTERFACE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL },
|
||||
+ /* ATTR_DISPLAYBIND */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "displaybind" },
|
||||
+ /* ATTR_DLLNAME */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "dllname" },
|
||||
+ /* ATTR_DUAL */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "dual" },
|
||||
+ /* ATTR_ENABLEALLOCATE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "enable_allocate" },
|
||||
+ /* ATTR_ENCODE */ { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "encode" },
|
||||
+ /* ATTR_ENDPOINT */ { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "endpoint" },
|
||||
+ /* ATTR_ENTRY */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "entry" },
|
||||
+ /* ATTR_EXPLICIT_HANDLE */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "explicit_handle" },
|
||||
+ /* ATTR_FAULTSTATUS */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "fault_status" },
|
||||
+ /* ATTR_FORCEALLOCATE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "force_allocate" },
|
||||
+ /* ATTR_HANDLE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "handle" },
|
||||
+ /* ATTR_HELPCONTEXT */ { 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, "helpcontext" },
|
||||
+ /* ATTR_HELPFILE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "helpfile" },
|
||||
+ /* ATTR_HELPSTRING */ { 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, "helpstring" },
|
||||
+ /* ATTR_HELPSTRINGCONTEXT */ { 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, "helpstringcontext" },
|
||||
+ /* ATTR_HELPSTRINGDLL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "helpstringdll" },
|
||||
+ /* ATTR_HIDDEN */ { 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, "hidden" },
|
||||
+ /* ATTR_ID */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, "id" },
|
||||
+ /* ATTR_IDEMPOTENT */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "idempotent" },
|
||||
+ /* ATTR_IGNORE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "ignore" },
|
||||
+ /* ATTR_IIDIS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "iid_is" },
|
||||
+ /* ATTR_IMMEDIATEBIND */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "immediatebind" },
|
||||
+ /* ATTR_IMPLICIT_HANDLE */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" },
|
||||
+ /* ATTR_IN */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "in" },
|
||||
+ /* ATTR_INPUTSYNC */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" },
|
||||
+ /* ATTR_LENGTHIS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "length_is" },
|
||||
+ /* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "lcid" },
|
||||
+ /* ATTR_LICENSED */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "licensed" },
|
||||
+ /* ATTR_LOCAL */ { 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "local" },
|
||||
+ /* ATTR_MAYBE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "maybe" },
|
||||
+ /* ATTR_MESSAGE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "message" },
|
||||
+ /* ATTR_NOCODE */ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nocode" },
|
||||
+ /* ATTR_NONBROWSABLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonbrowsable" },
|
||||
+ /* ATTR_NONCREATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "noncreatable" },
|
||||
+ /* ATTR_NONEXTENSIBLE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonextensible" },
|
||||
+ /* ATTR_NOTIFY */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify" },
|
||||
+ /* ATTR_NOTIFYFLAG */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify_flag" },
|
||||
+ /* ATTR_OBJECT */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "object" },
|
||||
+ /* ATTR_ODL */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "odl" },
|
||||
+ /* ATTR_OLEAUTOMATION */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "oleautomation" },
|
||||
+ /* ATTR_OPTIMIZE */ { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optimize" },
|
||||
+ /* ATTR_OPTIONAL */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optional" },
|
||||
+ /* ATTR_OUT */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "out" },
|
||||
+ /* ATTR_PARAMLCID */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "lcid" },
|
||||
+ /* ATTR_PARTIALIGNORE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "partial_ignore" },
|
||||
+ /* ATTR_POINTERDEFAULT */ { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "pointer_default" },
|
||||
+ /* ATTR_POINTERTYPE */ { 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "ref, unique or ptr" },
|
||||
+ /* ATTR_PROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "progid" },
|
||||
+ /* ATTR_PROPGET */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propget" },
|
||||
+ /* ATTR_PROPPUT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propput" },
|
||||
+ /* ATTR_PROPPUTREF */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propputref" },
|
||||
+ /* ATTR_PROXY */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "proxy" },
|
||||
+ /* ATTR_PUBLIC */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "public" },
|
||||
+ /* ATTR_RANGE */ { 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, "range" },
|
||||
+ /* ATTR_READONLY */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "readonly" },
|
||||
+ /* ATTR_REPRESENTAS */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "represent_as" },
|
||||
+ /* ATTR_REQUESTEDIT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "requestedit" },
|
||||
+ /* ATTR_RESTRICTED */ { 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, "restricted" },
|
||||
+ /* ATTR_RETVAL */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "retval" },
|
||||
+ /* ATTR_SIZEIS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "size_is" },
|
||||
+ /* ATTR_SOURCE */ { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "source" },
|
||||
+ /* ATTR_STRICTCONTEXTHANDLE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "strict_context_handle" },
|
||||
+ /* ATTR_STRING */ { 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "string" },
|
||||
+ /* ATTR_SWITCHIS */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "switch_is" },
|
||||
+ /* ATTR_SWITCHTYPE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "switch_type" },
|
||||
+ /* ATTR_THREADING */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "threading" },
|
||||
+ /* ATTR_TRANSMITAS */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "transmit_as" },
|
||||
+ /* ATTR_UIDEFAULT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "uidefault" },
|
||||
+ /* ATTR_USESGETLASTERROR */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "usesgetlasterror" },
|
||||
+ /* ATTR_USERMARSHAL */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "user_marshal" },
|
||||
+ /* ATTR_UUID */ { 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, "uuid" },
|
||||
+ /* ATTR_V1ENUM */ { 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "v1_enum" },
|
||||
+ /* ATTR_VARARG */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "vararg" },
|
||||
+ /* ATTR_VERSION */ { 1, 0, 1, 0, 0, 1, 1, 0, 2, 0, 0, 1, 0, 0, 1, 0, "version" },
|
||||
+ /* ATTR_VIPROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "vi_progid" },
|
||||
+ /* ATTR_WIREMARSHAL */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "wire_marshal" },
|
||||
};
|
||||
|
||||
const char *get_attr_display_name(enum attr_type type)
|
||||
@@ -2420,6 +2436,17 @@ static attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs)
|
||||
return attrs;
|
||||
}
|
||||
|
||||
+static attr_list_t *check_apicontract_attrs(const char *name, attr_list_t *attrs)
|
||||
+{
|
||||
+ const attr_t *attr;
|
||||
+ if (!attrs) return attrs;
|
||||
+ LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
|
||||
+ if (!allowed_attr[attr->type].on_apicontract)
|
||||
+ error_loc("inapplicable attribute %s for apicontract %s\n",
|
||||
+ allowed_attr[attr->type].display_name, name);
|
||||
+ return attrs;
|
||||
+}
|
||||
+
|
||||
static int is_allowed_conf_type(const type_t *type)
|
||||
{
|
||||
switch (type_get_type(type))
|
||||
@@ -2459,6 +2486,10 @@ static int is_allowed_conf_type(const type_t *type)
|
||||
case TYPE_INTERFACE:
|
||||
case TYPE_BITFIELD:
|
||||
return FALSE;
|
||||
+ case TYPE_APICONTRACT:
|
||||
+ /* not supposed to be here */
|
||||
+ assert(0);
|
||||
+ break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
|
||||
index 04280cbb722..46aae9b69e9 100644
|
||||
--- a/tools/widl/typegen.c
|
||||
+++ b/tools/widl/typegen.c
|
||||
@@ -374,6 +374,10 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att
|
||||
case TYPE_ALIAS:
|
||||
case TYPE_BITFIELD:
|
||||
break;
|
||||
+ case TYPE_APICONTRACT:
|
||||
+ /* not supposed to be here */
|
||||
+ assert(0);
|
||||
+ break;
|
||||
}
|
||||
return TGT_INVALID;
|
||||
}
|
||||
@@ -1966,6 +1970,7 @@ unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *align)
|
||||
case TYPE_MODULE:
|
||||
case TYPE_FUNCTION:
|
||||
case TYPE_BITFIELD:
|
||||
+ case TYPE_APICONTRACT:
|
||||
/* these types should not be encountered here due to language
|
||||
* restrictions (interface, void, coclass, module), logical
|
||||
* restrictions (alias - due to type_get_type call above) or
|
||||
@@ -2067,6 +2072,7 @@ static unsigned int type_buffer_alignment(const type_t *t)
|
||||
case TYPE_MODULE:
|
||||
case TYPE_FUNCTION:
|
||||
case TYPE_BITFIELD:
|
||||
+ case TYPE_APICONTRACT:
|
||||
/* these types should not be encountered here due to language
|
||||
* restrictions (interface, void, coclass, module), logical
|
||||
* restrictions (alias - due to type_get_type call above) or
|
||||
diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c
|
||||
index cf027558d0a..faf76440f93 100644
|
||||
--- a/tools/widl/typelib.c
|
||||
+++ b/tools/widl/typelib.c
|
||||
@@ -224,7 +224,8 @@ unsigned short get_type_vt(type_t *t)
|
||||
return VT_VOID;
|
||||
|
||||
case TYPE_ALIAS:
|
||||
- /* aliases should be filtered out by the type_get_type call above */
|
||||
+ case TYPE_APICONTRACT:
|
||||
+ /* not supposed to be here */
|
||||
assert(0);
|
||||
break;
|
||||
|
||||
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
|
||||
index e288c574002..7abec41a8fd 100644
|
||||
--- a/tools/widl/typetree.h
|
||||
+++ b/tools/widl/typetree.h
|
||||
@@ -223,6 +223,9 @@ static inline int type_is_complete(const type_t *type)
|
||||
case TYPE_ARRAY:
|
||||
case TYPE_BITFIELD:
|
||||
return TRUE;
|
||||
+ case TYPE_APICONTRACT:
|
||||
+ assert(0);
|
||||
+ break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
|
||||
index 1b00b8da002..add7cedfacc 100644
|
||||
--- a/tools/widl/widltypes.h
|
||||
+++ b/tools/widl/widltypes.h
|
||||
@@ -432,6 +432,7 @@ enum type_type
|
||||
TYPE_POINTER,
|
||||
TYPE_ARRAY,
|
||||
TYPE_BITFIELD,
|
||||
+ TYPE_APICONTRACT,
|
||||
};
|
||||
|
||||
struct _type_t {
|
||||
--
|
||||
2.28.0
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -0,0 +1,742 @@
|
||||
From ef00d7d2e0178d9f3ad3405613c6c4a1ddd3c2b1 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Tue, 13 Oct 2020 15:57:04 +0200
|
||||
Subject: [PATCH 12/28] widl: Support WinRT runtimeclass type.
|
||||
|
||||
MIDL doesn't generate anything special in the header files for these
|
||||
types. They can however be used instead of interfaces as function
|
||||
arguments or type parameters, but pointer to their default interface
|
||||
type is instead used in the generated code.
|
||||
---
|
||||
include/windows.media.speechsynthesis.idl | 25 ++
|
||||
tools/widl/expr.c | 1 +
|
||||
tools/widl/header.c | 65 +++++-
|
||||
tools/widl/parser.l | 1 +
|
||||
tools/widl/parser.y | 265 +++++++++++++---------
|
||||
tools/widl/typegen.c | 4 +
|
||||
tools/widl/typelib.c | 1 +
|
||||
tools/widl/typetree.c | 17 ++
|
||||
tools/widl/typetree.h | 24 ++
|
||||
tools/widl/widltypes.h | 7 +
|
||||
10 files changed, 298 insertions(+), 112 deletions(-)
|
||||
|
||||
diff --git a/include/windows.media.speechsynthesis.idl b/include/windows.media.speechsynthesis.idl
|
||||
index 7a1de5fcba6..90bc9f279c6 100644
|
||||
--- a/include/windows.media.speechsynthesis.idl
|
||||
+++ b/include/windows.media.speechsynthesis.idl
|
||||
@@ -29,6 +29,8 @@ namespace Windows {
|
||||
typedef enum VoiceGender VoiceGender;
|
||||
interface IInstalledVoicesStatic;
|
||||
interface IVoiceInformation;
|
||||
+ runtimeclass VoiceInformation;
|
||||
+ runtimeclass SpeechSynthesizer;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,6 +44,29 @@ namespace Windows {
|
||||
Male = 0,
|
||||
Female = 1
|
||||
};
|
||||
+
|
||||
+ [
|
||||
+ contract(Windows.Foundation.UniversalApiContract, 1.0),
|
||||
+ exclusiveto(Windows.Media.SpeechSynthesis.VoiceInformation),
|
||||
+ uuid(b127d6a4-1291-4604-aa9c-83134083352c)
|
||||
+ ]
|
||||
+ interface IVoiceInformation : IInspectable
|
||||
+ {
|
||||
+ [propget] HRESULT DisplayName([out] [retval] HSTRING* value);
|
||||
+ [propget] HRESULT Id([out] [retval] HSTRING* value);
|
||||
+ [propget] HRESULT Language([out] [retval] HSTRING* value);
|
||||
+ [propget] HRESULT Description([out] [retval] HSTRING* value);
|
||||
+ [propget] HRESULT Gender([out] [retval] VoiceGender* value);
|
||||
+ }
|
||||
+
|
||||
+ [
|
||||
+ contract(Windows.Foundation.UniversalApiContract, 1.0),
|
||||
+ marshaling_behavior(agile)
|
||||
+ ]
|
||||
+ runtimeclass VoiceInformation
|
||||
+ {
|
||||
+ [default] interface IVoiceInformation;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/tools/widl/expr.c b/tools/widl/expr.c
|
||||
index be8311cfb7f..13bd5a889aa 100644
|
||||
--- a/tools/widl/expr.c
|
||||
+++ b/tools/widl/expr.c
|
||||
@@ -463,6 +463,7 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type,
|
||||
case TYPE_ARRAY:
|
||||
case TYPE_BITFIELD:
|
||||
case TYPE_APICONTRACT:
|
||||
+ case TYPE_RUNTIMECLASS:
|
||||
/* nothing to do */
|
||||
break;
|
||||
case TYPE_ALIAS:
|
||||
diff --git a/tools/widl/header.c b/tools/widl/header.c
|
||||
index 8aed9be3f57..065a82ea384 100644
|
||||
--- a/tools/widl/header.c
|
||||
+++ b/tools/widl/header.c
|
||||
@@ -465,6 +465,9 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i
|
||||
case TYPE_COCLASS:
|
||||
fprintf(h, "%s", name);
|
||||
break;
|
||||
+ case TYPE_RUNTIMECLASS:
|
||||
+ fprintf(h, "%s", type_get_name(type_runtimeclass_get_default_iface(t), name_type));
|
||||
+ break;
|
||||
case TYPE_VOID:
|
||||
fprintf(h, "void");
|
||||
break;
|
||||
@@ -547,6 +550,7 @@ void write_type_right(FILE *h, type_t *t, int is_field)
|
||||
case TYPE_MODULE:
|
||||
case TYPE_COCLASS:
|
||||
case TYPE_INTERFACE:
|
||||
+ case TYPE_RUNTIMECLASS:
|
||||
break;
|
||||
case TYPE_APICONTRACT:
|
||||
/* not supposed to be here */
|
||||
@@ -1033,7 +1037,8 @@ static int is_aggregate_return(const var_t *func)
|
||||
{
|
||||
enum type_type type = type_get_type(type_function_get_rettype(func->declspec.type));
|
||||
return type == TYPE_STRUCT || type == TYPE_UNION ||
|
||||
- type == TYPE_COCLASS || type == TYPE_INTERFACE;
|
||||
+ type == TYPE_COCLASS || type == TYPE_INTERFACE ||
|
||||
+ type == TYPE_RUNTIMECLASS;
|
||||
}
|
||||
|
||||
static char *get_vtbl_entry_name(const type_t *iface, const var_t *func)
|
||||
@@ -1501,6 +1506,21 @@ 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 (type_get_type(type) == TYPE_RUNTIMECLASS)
|
||||
+ {
|
||||
+ ifref_list_t *ifaces = type_runtimeclass_get_ifaces(type);
|
||||
+ ifref_t *entry;
|
||||
+ fprintf(header, " * Class implements the following interfaces:\n");
|
||||
+ LIST_FOR_EACH_ENTRY(entry, ifaces, ifref_t, entry)
|
||||
+ {
|
||||
+ char *name = format_namespace(entry->iface->namespace, "", ".", entry->iface->name, NULL);
|
||||
+ fprintf(header, " * %s", name);
|
||||
+ if (is_attr(entry->attrs, ATTR_DEFAULT)) fprintf(header, " ** Default Interface **");
|
||||
+ fprintf(header, "\n");
|
||||
+ free(name);
|
||||
+ }
|
||||
+ fprintf(header, " *\n");
|
||||
+ }
|
||||
switch (get_attrv(type->attrs, ATTR_THREADING))
|
||||
{
|
||||
case THREADING_SINGLE: fprintf(header, " * Class Threading Model: Single Threaded Apartment\n *\n"); break;
|
||||
@@ -1728,6 +1748,45 @@ static void write_apicontract(FILE *header, type_t *apicontract)
|
||||
free(name);
|
||||
}
|
||||
|
||||
+static void write_runtimeclass(FILE *header, type_t *runtimeclass)
|
||||
+{
|
||||
+ expr_t *contract = get_attrp(runtimeclass->attrs, ATTR_CONTRACT);
|
||||
+ size_t i, len;
|
||||
+ char *name, *c_name;
|
||||
+ name = format_namespace(runtimeclass->namespace, "", ".", runtimeclass->name, NULL);
|
||||
+ c_name = format_namespace(runtimeclass->namespace, "", "_", runtimeclass->name, NULL);
|
||||
+ fprintf(header, "/*\n");
|
||||
+ fprintf(header, " * Class %s\n", name);
|
||||
+ write_winrt_type_comments(header, runtimeclass);
|
||||
+ fprintf(header, " */\n");
|
||||
+ if (contract) write_apicontract_guard_start(header, contract);
|
||||
+ fprintf(header, "#ifndef RUNTIMECLASS_%s_DEFINED\n", c_name);
|
||||
+ fprintf(header, "#define RUNTIMECLASS_%s_DEFINED\n", c_name);
|
||||
+ /* MIDL generates extern const here */
|
||||
+ fprintf(header, "static const DECLSPEC_SELECTANY WCHAR RuntimeClass_%s[] = {", c_name);
|
||||
+ for (i = 0, len = strlen(name); i < len; ++i) fprintf(header, "'%c',", name[i]);
|
||||
+ fprintf(header, "0};\n");
|
||||
+ fprintf(header, "#endif /* RUNTIMECLASS_%s_DEFINED */\n", c_name);
|
||||
+ free(c_name);
|
||||
+ free(name);
|
||||
+ if (contract) write_apicontract_guard_end(header, contract);
|
||||
+ fprintf(header, "\n");
|
||||
+}
|
||||
+
|
||||
+static void write_runtimeclass_forward(FILE *header, type_t *runtimeclass)
|
||||
+{
|
||||
+ fprintf(header, "#ifndef __%s_FWD_DEFINED__\n", runtimeclass->c_name);
|
||||
+ fprintf(header, "#define __%s_FWD_DEFINED__\n", runtimeclass->c_name);
|
||||
+ fprintf(header, "#ifdef __cplusplus\n");
|
||||
+ write_namespace_start(header, runtimeclass->namespace);
|
||||
+ write_line(header, 0, "class %s;", runtimeclass->name);
|
||||
+ write_namespace_end(header, runtimeclass->namespace);
|
||||
+ fprintf(header, "#else\n");
|
||||
+ fprintf(header, "typedef struct %s %s;\n", runtimeclass->c_name, runtimeclass->c_name);
|
||||
+ fprintf(header, "#endif /* defined __cplusplus */\n");
|
||||
+ fprintf(header, "#endif /* defined __%s_FWD_DEFINED__ */\n\n", runtimeclass->c_name);
|
||||
+}
|
||||
+
|
||||
static void write_import(FILE *header, const char *fname)
|
||||
{
|
||||
char *hname, *p;
|
||||
@@ -1792,6 +1851,8 @@ static void write_forward_decls(FILE *header, const statement_list_t *stmts)
|
||||
}
|
||||
else if (type_get_type(stmt->u.type) == TYPE_COCLASS)
|
||||
write_coclass_forward(header, stmt->u.type);
|
||||
+ else if (type_get_type(stmt->u.type) == TYPE_RUNTIMECLASS)
|
||||
+ write_runtimeclass_forward(header, stmt->u.type);
|
||||
break;
|
||||
case STMT_TYPEREF:
|
||||
case STMT_IMPORTLIB:
|
||||
@@ -1848,6 +1909,8 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
|
||||
write_coclass(header, stmt->u.type);
|
||||
else if (type_get_type(stmt->u.type) == TYPE_APICONTRACT)
|
||||
write_apicontract(header, stmt->u.type);
|
||||
+ else if (type_get_type(stmt->u.type) == TYPE_RUNTIMECLASS)
|
||||
+ write_runtimeclass(header, stmt->u.type);
|
||||
else
|
||||
{
|
||||
write_type_definition(header, stmt->u.type, stmt->declonly);
|
||||
diff --git a/tools/widl/parser.l b/tools/widl/parser.l
|
||||
index 498071a1992..31b97951b31 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},
|
||||
+ {"runtimeclass", tRUNTIMECLASS, 1},
|
||||
{"short", tSHORT, 0},
|
||||
{"signed", tSIGNED, 0},
|
||||
{"sizeof", tSIZEOF, 0},
|
||||
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
|
||||
index 88cc029c3ae..8b88e031fb5 100644
|
||||
--- a/tools/widl/parser.y
|
||||
+++ b/tools/widl/parser.y
|
||||
@@ -99,6 +99,7 @@ static attr_list_t *check_library_attrs(const char *name, attr_list_t *attrs);
|
||||
static attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs);
|
||||
static attr_list_t *check_module_attrs(const char *name, attr_list_t *attrs);
|
||||
static attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs);
|
||||
+static attr_list_t *check_runtimeclass_attrs(const char *name, attr_list_t *attrs);
|
||||
static attr_list_t *check_apicontract_attrs(const char *name, attr_list_t *attrs);
|
||||
const char *get_attr_display_name(enum attr_type type);
|
||||
static void add_explicit_handle_if_necessary(const type_t *iface, var_t *func);
|
||||
@@ -245,6 +246,7 @@ static typelib_t *current_typelib;
|
||||
%token tREQUESTEDIT
|
||||
%token tRESTRICTED
|
||||
%token tRETVAL
|
||||
+%token tRUNTIMECLASS
|
||||
%token tSAFEARRAY
|
||||
%token tSHORT
|
||||
%token tSIGNED
|
||||
@@ -290,8 +292,8 @@ static typelib_t *current_typelib;
|
||||
%type <type> base_type int_std
|
||||
%type <type> enumdef structdef uniondef typedecl
|
||||
%type <type> type qualified_seq qualified_type
|
||||
-%type <ifref> coclass_int
|
||||
-%type <ifref_list> coclass_ints
|
||||
+%type <ifref> class_interface
|
||||
+%type <ifref_list> class_interfaces
|
||||
%type <var> arg ne_union_field union_field s_field case enum enum_member declaration
|
||||
%type <var> funcdef
|
||||
%type <var_list> m_args arg_list args dispint_meths
|
||||
@@ -302,6 +304,7 @@ static typelib_t *current_typelib;
|
||||
%type <declarator> m_abstract_declarator abstract_declarator abstract_declarator_no_direct abstract_direct_declarator
|
||||
%type <declarator_list> declarator_list struct_declarator_list
|
||||
%type <type> coclass coclasshdr coclassdef
|
||||
+%type <type> runtimeclass runtimeclass_hdr runtimeclass_def
|
||||
%type <type> apicontract
|
||||
%type <num> contract_ver
|
||||
%type <num> pointer_type threading_type marshaling_behavior version
|
||||
@@ -361,6 +364,9 @@ gbl_statements: { $$ = NULL; }
|
||||
}
|
||||
| gbl_statements apicontract ';' { $$ = append_statement($1, make_statement_type_decl($2));
|
||||
reg_type($2, $2->name, current_namespace, 0); }
|
||||
+ | gbl_statements runtimeclass ';' { $$ = $1; reg_type($2, $2->name, current_namespace, 0); }
|
||||
+ | gbl_statements runtimeclass_def { $$ = append_statement($1, make_statement_type_decl($2));
|
||||
+ reg_type($2, $2->name, current_namespace, 0); }
|
||||
| gbl_statements moduledef { $$ = append_statement($1, make_statement_module($2)); }
|
||||
| gbl_statements librarydef { $$ = append_statement($1, make_statement_library($2)); }
|
||||
| gbl_statements statement { $$ = append_statement($1, $2); }
|
||||
@@ -377,6 +383,9 @@ imp_statements: { $$ = NULL; }
|
||||
}
|
||||
| imp_statements apicontract ';' { $$ = append_statement($1, make_statement_type_decl($2));
|
||||
reg_type($2, $2->name, current_namespace, 0); }
|
||||
+ | imp_statements runtimeclass ';' { $$ = $1; reg_type($2, $2->name, current_namespace, 0); }
|
||||
+ | imp_statements runtimeclass_def { $$ = append_statement($1, make_statement_type_decl($2));
|
||||
+ reg_type($2, $2->name, current_namespace, 0); }
|
||||
| imp_statements moduledef { $$ = append_statement($1, make_statement_module($2)); }
|
||||
| imp_statements statement { $$ = append_statement($1, $2); }
|
||||
| imp_statements importlib { $$ = append_statement($1, make_statement_importlib($2)); }
|
||||
@@ -558,7 +567,9 @@ 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); }
|
||||
+ | 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); }
|
||||
| tEXPLICITHANDLE { $$ = make_attr(ATTR_EXPLICIT_HANDLE); }
|
||||
| tFAULTSTATUS { $$ = make_attr(ATTR_FAULTSTATUS); }
|
||||
| tFORCEALLOCATE { $$ = make_attr(ATTR_FORCEALLOCATE); }
|
||||
@@ -893,10 +904,29 @@ coclasshdr: attributes coclass { $$ = $2;
|
||||
}
|
||||
;
|
||||
|
||||
-coclassdef: coclasshdr '{' coclass_ints '}' semicolon_opt
|
||||
+coclassdef: coclasshdr '{' class_interfaces '}' semicolon_opt
|
||||
{ $$ = type_coclass_define($1, $3); }
|
||||
;
|
||||
|
||||
+runtimeclass:
|
||||
+ tRUNTIMECLASS aIDENTIFIER { $$ = type_new_runtimeclass($2, current_namespace); }
|
||||
+ | tRUNTIMECLASS aKNOWNTYPE { $$ = find_type($2, NULL, 0);
|
||||
+ if (type_get_type_detect_alias($$) != TYPE_RUNTIMECLASS)
|
||||
+ error_loc("%s was not declared a runtimeclass at %s:%d\n", $2,
|
||||
+ $$->loc_info.input_name, $$->loc_info.line_number);
|
||||
+ }
|
||||
+ ;
|
||||
+
|
||||
+runtimeclass_hdr: attributes runtimeclass { $$ = $2;
|
||||
+ check_def($$);
|
||||
+ $$->attrs = check_runtimeclass_attrs($2->name, $1);
|
||||
+ }
|
||||
+ ;
|
||||
+
|
||||
+runtimeclass_def: runtimeclass_hdr '{' class_interfaces '}' semicolon_opt
|
||||
+ { $$ = type_runtimeclass_define($1, $3); }
|
||||
+ ;
|
||||
+
|
||||
apicontract: attributes tAPICONTRACT aIDENTIFIER '{' '}'
|
||||
{ $$ = get_type(TYPE_APICONTRACT, $3, current_namespace, 0);
|
||||
check_def($$);
|
||||
@@ -908,11 +938,11 @@ namespacedef: tNAMESPACE aIDENTIFIER { $$ = $2; }
|
||||
| tNAMESPACE aNAMESPACE { $$ = $2; }
|
||||
;
|
||||
|
||||
-coclass_ints: { $$ = NULL; }
|
||||
- | coclass_ints coclass_int { $$ = append_ifref( $1, $2 ); }
|
||||
+class_interfaces: { $$ = NULL; }
|
||||
+ | class_interfaces class_interface { $$ = append_ifref( $1, $2 ); }
|
||||
;
|
||||
|
||||
-coclass_int:
|
||||
+class_interface:
|
||||
m_attributes interfacedec { $$ = make_ifref($2); $$->attrs = $1; }
|
||||
;
|
||||
|
||||
@@ -2166,115 +2196,116 @@ struct allowed_attr
|
||||
unsigned int on_module : 1;
|
||||
unsigned int on_coclass : 1;
|
||||
unsigned int on_apicontract : 1;
|
||||
+ unsigned int on_runtimeclass : 1;
|
||||
const char *display_name;
|
||||
};
|
||||
|
||||
struct allowed_attr allowed_attr[] =
|
||||
{
|
||||
- /* attr { D ACF I Fn ARG T En Enm St Un Fi L DI M C AC <display name> } */
|
||||
- /* ATTR_AGGREGATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "aggregatable" },
|
||||
- /* ATTR_ANNOTATION */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "annotation" },
|
||||
- /* ATTR_APPOBJECT */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "appobject" },
|
||||
- /* ATTR_ASYNC */ { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "async" },
|
||||
- /* ATTR_ASYNCUUID */ { 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, "async_uuid" },
|
||||
- /* ATTR_AUTO_HANDLE */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "auto_handle" },
|
||||
- /* ATTR_BINDABLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "bindable" },
|
||||
- /* ATTR_BROADCAST */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "broadcast" },
|
||||
- /* ATTR_CALLAS */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "call_as" },
|
||||
- /* ATTR_CALLCONV */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL },
|
||||
- /* ATTR_CASE */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "case" },
|
||||
- /* ATTR_CODE */ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" },
|
||||
- /* ATTR_COMMSTATUS */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" },
|
||||
- /* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" },
|
||||
- /* ATTR_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" },
|
||||
- /* ATTR_DEFAULT */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, "default" },
|
||||
- /* ATTR_DEFAULTBIND */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultbind" },
|
||||
- /* ATTR_DEFAULTCOLLELEM */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultcollelem" },
|
||||
- /* ATTR_DEFAULTVALUE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultvalue" },
|
||||
- /* ATTR_DEFAULTVTABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "defaultvtable" },
|
||||
- /* ATTR_DISABLECONSISTENCYCHECK */{ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "disable_consistency_check" },
|
||||
- /* ATTR_DISPINTERFACE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL },
|
||||
- /* ATTR_DISPLAYBIND */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "displaybind" },
|
||||
- /* ATTR_DLLNAME */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "dllname" },
|
||||
- /* ATTR_DUAL */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "dual" },
|
||||
- /* ATTR_ENABLEALLOCATE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "enable_allocate" },
|
||||
- /* ATTR_ENCODE */ { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "encode" },
|
||||
- /* ATTR_ENDPOINT */ { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "endpoint" },
|
||||
- /* ATTR_ENTRY */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "entry" },
|
||||
- /* ATTR_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" },
|
||||
- /* ATTR_HANDLE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "handle" },
|
||||
- /* ATTR_HELPCONTEXT */ { 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, "helpcontext" },
|
||||
- /* ATTR_HELPFILE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "helpfile" },
|
||||
- /* ATTR_HELPSTRING */ { 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, "helpstring" },
|
||||
- /* ATTR_HELPSTRINGCONTEXT */ { 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, "helpstringcontext" },
|
||||
- /* ATTR_HELPSTRINGDLL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "helpstringdll" },
|
||||
- /* ATTR_HIDDEN */ { 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, "hidden" },
|
||||
- /* ATTR_ID */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, "id" },
|
||||
- /* ATTR_IDEMPOTENT */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "idempotent" },
|
||||
- /* ATTR_IGNORE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "ignore" },
|
||||
- /* ATTR_IIDIS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "iid_is" },
|
||||
- /* ATTR_IMMEDIATEBIND */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "immediatebind" },
|
||||
- /* ATTR_IMPLICIT_HANDLE */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" },
|
||||
- /* ATTR_IN */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "in" },
|
||||
- /* ATTR_INPUTSYNC */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" },
|
||||
- /* ATTR_LENGTHIS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "length_is" },
|
||||
- /* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "lcid" },
|
||||
- /* ATTR_LICENSED */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "licensed" },
|
||||
- /* ATTR_LOCAL */ { 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "local" },
|
||||
- /* ATTR_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" },
|
||||
- /* ATTR_NONBROWSABLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonbrowsable" },
|
||||
- /* ATTR_NONCREATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "noncreatable" },
|
||||
- /* ATTR_NONEXTENSIBLE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonextensible" },
|
||||
- /* ATTR_NOTIFY */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify" },
|
||||
- /* ATTR_NOTIFYFLAG */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify_flag" },
|
||||
- /* ATTR_OBJECT */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "object" },
|
||||
- /* ATTR_ODL */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "odl" },
|
||||
- /* ATTR_OLEAUTOMATION */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "oleautomation" },
|
||||
- /* ATTR_OPTIMIZE */ { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optimize" },
|
||||
- /* ATTR_OPTIONAL */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optional" },
|
||||
- /* ATTR_OUT */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "out" },
|
||||
- /* ATTR_PARAMLCID */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "lcid" },
|
||||
- /* ATTR_PARTIALIGNORE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "partial_ignore" },
|
||||
- /* ATTR_POINTERDEFAULT */ { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "pointer_default" },
|
||||
- /* ATTR_POINTERTYPE */ { 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "ref, unique or ptr" },
|
||||
- /* ATTR_PROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "progid" },
|
||||
- /* ATTR_PROPGET */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propget" },
|
||||
- /* ATTR_PROPPUT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propput" },
|
||||
- /* ATTR_PROPPUTREF */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propputref" },
|
||||
- /* ATTR_PROXY */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "proxy" },
|
||||
- /* ATTR_PUBLIC */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "public" },
|
||||
- /* ATTR_RANGE */ { 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, "range" },
|
||||
- /* ATTR_READONLY */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "readonly" },
|
||||
- /* ATTR_REPRESENTAS */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "represent_as" },
|
||||
- /* ATTR_REQUESTEDIT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "requestedit" },
|
||||
- /* ATTR_RESTRICTED */ { 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, "restricted" },
|
||||
- /* ATTR_RETVAL */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "retval" },
|
||||
- /* ATTR_SIZEIS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "size_is" },
|
||||
- /* ATTR_SOURCE */ { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "source" },
|
||||
- /* ATTR_STRICTCONTEXTHANDLE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "strict_context_handle" },
|
||||
- /* ATTR_STRING */ { 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "string" },
|
||||
- /* ATTR_SWITCHIS */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "switch_is" },
|
||||
- /* ATTR_SWITCHTYPE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "switch_type" },
|
||||
- /* ATTR_THREADING */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "threading" },
|
||||
- /* ATTR_TRANSMITAS */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "transmit_as" },
|
||||
- /* ATTR_UIDEFAULT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "uidefault" },
|
||||
- /* ATTR_USESGETLASTERROR */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "usesgetlasterror" },
|
||||
- /* ATTR_USERMARSHAL */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "user_marshal" },
|
||||
- /* ATTR_UUID */ { 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, "uuid" },
|
||||
- /* ATTR_V1ENUM */ { 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "v1_enum" },
|
||||
- /* ATTR_VARARG */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "vararg" },
|
||||
- /* ATTR_VERSION */ { 1, 0, 1, 0, 0, 1, 1, 0, 2, 0, 0, 1, 0, 0, 1, 0, "version" },
|
||||
- /* ATTR_VIPROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "vi_progid" },
|
||||
- /* ATTR_WIREMARSHAL */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "wire_marshal" },
|
||||
+ /* 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_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_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" },
|
||||
};
|
||||
|
||||
const char *get_attr_display_name(enum attr_type type)
|
||||
@@ -2465,6 +2496,17 @@ static attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs)
|
||||
return attrs;
|
||||
}
|
||||
|
||||
+static attr_list_t *check_runtimeclass_attrs(const char *name, attr_list_t *attrs)
|
||||
+{
|
||||
+ const attr_t *attr;
|
||||
+ if (!attrs) return attrs;
|
||||
+ LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
|
||||
+ if (!allowed_attr[attr->type].on_runtimeclass)
|
||||
+ error_loc("inapplicable attribute %s for runtimeclass %s\n",
|
||||
+ allowed_attr[attr->type].display_name, name);
|
||||
+ return attrs;
|
||||
+}
|
||||
+
|
||||
static attr_list_t *check_apicontract_attrs(const char *name, attr_list_t *attrs)
|
||||
{
|
||||
const attr_t *attr;
|
||||
@@ -2514,6 +2556,7 @@ static int is_allowed_conf_type(const type_t *type)
|
||||
case TYPE_FUNCTION:
|
||||
case TYPE_INTERFACE:
|
||||
case TYPE_BITFIELD:
|
||||
+ case TYPE_RUNTIMECLASS:
|
||||
return FALSE;
|
||||
case TYPE_APICONTRACT:
|
||||
/* not supposed to be here */
|
||||
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
|
||||
index 46aae9b69e9..86c010aa6ae 100644
|
||||
--- a/tools/widl/typegen.c
|
||||
+++ b/tools/widl/typegen.c
|
||||
@@ -353,6 +353,7 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att
|
||||
return TGT_ENUM;
|
||||
case TYPE_POINTER:
|
||||
if (type_get_type(type_pointer_get_ref_type(type)) == TYPE_INTERFACE ||
|
||||
+ type_get_type(type_pointer_get_ref_type(type)) == TYPE_RUNTIMECLASS ||
|
||||
(type_get_type(type_pointer_get_ref_type(type)) == TYPE_VOID && is_attr(attrs, ATTR_IIDIS)))
|
||||
return TGT_IFACE_POINTER;
|
||||
else if (is_aliaschain_attr(type_pointer_get_ref_type(type), ATTR_CONTEXTHANDLE))
|
||||
@@ -373,6 +374,7 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att
|
||||
case TYPE_VOID:
|
||||
case TYPE_ALIAS:
|
||||
case TYPE_BITFIELD:
|
||||
+ case TYPE_RUNTIMECLASS:
|
||||
break;
|
||||
case TYPE_APICONTRACT:
|
||||
/* not supposed to be here */
|
||||
@@ -1971,6 +1973,7 @@ unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *align)
|
||||
case TYPE_FUNCTION:
|
||||
case TYPE_BITFIELD:
|
||||
case TYPE_APICONTRACT:
|
||||
+ case TYPE_RUNTIMECLASS:
|
||||
/* these types should not be encountered here due to language
|
||||
* restrictions (interface, void, coclass, module), logical
|
||||
* restrictions (alias - due to type_get_type call above) or
|
||||
@@ -2073,6 +2076,7 @@ static unsigned int type_buffer_alignment(const type_t *t)
|
||||
case TYPE_FUNCTION:
|
||||
case TYPE_BITFIELD:
|
||||
case TYPE_APICONTRACT:
|
||||
+ case TYPE_RUNTIMECLASS:
|
||||
/* these types should not be encountered here due to language
|
||||
* restrictions (interface, void, coclass, module), logical
|
||||
* restrictions (alias - due to type_get_type call above) or
|
||||
diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c
|
||||
index faf76440f93..ace6424e3a0 100644
|
||||
--- a/tools/widl/typelib.c
|
||||
+++ b/tools/widl/typelib.c
|
||||
@@ -218,6 +218,7 @@ unsigned short get_type_vt(type_t *t)
|
||||
case TYPE_MODULE:
|
||||
case TYPE_UNION:
|
||||
case TYPE_ENCAPSULATED_UNION:
|
||||
+ case TYPE_RUNTIMECLASS:
|
||||
return VT_USERDEFINED;
|
||||
|
||||
case TYPE_VOID:
|
||||
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
|
||||
index d8dcd5d80b0..d075619448d 100644
|
||||
--- a/tools/widl/typetree.c
|
||||
+++ b/tools/widl/typetree.c
|
||||
@@ -211,6 +211,16 @@ type_t *type_new_coclass(char *name)
|
||||
return type;
|
||||
}
|
||||
|
||||
+type_t *type_new_runtimeclass(char *name, struct namespace *namespace)
|
||||
+{
|
||||
+ type_t *type = get_type(TYPE_RUNTIMECLASS, name, NULL, 0);
|
||||
+ if (type->type_type != TYPE_RUNTIMECLASS || type->defined)
|
||||
+ error_loc("%s: redefinition error; original definition was at %s:%d\n",
|
||||
+ type->name, type->loc_info.input_name, type->loc_info.line_number);
|
||||
+ type->name = name;
|
||||
+ type->namespace = namespace;
|
||||
+ return type;
|
||||
+}
|
||||
|
||||
type_t *type_new_array(const char *name, const decl_spec_t *element, int declptr,
|
||||
unsigned int dim, expr_t *size_is, expr_t *length_is)
|
||||
@@ -505,6 +515,13 @@ type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces)
|
||||
return coclass;
|
||||
}
|
||||
|
||||
+type_t *type_runtimeclass_define(type_t *runtimeclass, ifref_list_t *ifaces)
|
||||
+{
|
||||
+ runtimeclass->details.runtimeclass.ifaces = ifaces;
|
||||
+ runtimeclass->defined = TRUE;
|
||||
+ return runtimeclass;
|
||||
+}
|
||||
+
|
||||
int type_is_equal(const type_t *type1, const type_t *type2)
|
||||
{
|
||||
if (type_get_type_detect_alias(type1) != type_get_type_detect_alias(type2))
|
||||
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
|
||||
index 7abec41a8fd..951084cf875 100644
|
||||
--- a/tools/widl/typetree.h
|
||||
+++ b/tools/widl/typetree.h
|
||||
@@ -44,11 +44,13 @@ type_t *type_new_struct(char *name, struct namespace *namespace, int defined, va
|
||||
type_t *type_new_nonencapsulated_union(const char *name, int defined, var_list_t *fields);
|
||||
type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases);
|
||||
type_t *type_new_bitfield(type_t *field_type, const expr_t *bits);
|
||||
+type_t *type_new_runtimeclass(char *name, struct namespace *namespace);
|
||||
void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts);
|
||||
void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *methods);
|
||||
void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface);
|
||||
void type_module_define(type_t *module, statement_list_t *stmts);
|
||||
type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces);
|
||||
+type_t *type_runtimeclass_define(type_t *runtimeclass, ifref_list_t *ifaces);
|
||||
int type_is_equal(const type_t *type1, const type_t *type2);
|
||||
const char *type_get_name(const type_t *type, enum name_type name_type);
|
||||
char *gen_name(void);
|
||||
@@ -222,6 +224,7 @@ static inline int type_is_complete(const type_t *type)
|
||||
case TYPE_POINTER:
|
||||
case TYPE_ARRAY:
|
||||
case TYPE_BITFIELD:
|
||||
+ case TYPE_RUNTIMECLASS:
|
||||
return TRUE;
|
||||
case TYPE_APICONTRACT:
|
||||
assert(0);
|
||||
@@ -322,6 +325,27 @@ static inline ifref_list_t *type_coclass_get_ifaces(const type_t *type)
|
||||
return type->details.coclass.ifaces;
|
||||
}
|
||||
|
||||
+static inline ifref_list_t *type_runtimeclass_get_ifaces(const type_t *type)
|
||||
+{
|
||||
+ type = type_get_real_type(type);
|
||||
+ assert(type_get_type(type) == TYPE_RUNTIMECLASS);
|
||||
+ return type->details.runtimeclass.ifaces;
|
||||
+}
|
||||
+
|
||||
+static inline type_t *type_runtimeclass_get_default_iface(const type_t *type)
|
||||
+{
|
||||
+ ifref_list_t *ifaces = type_runtimeclass_get_ifaces(type);
|
||||
+ ifref_t *entry;
|
||||
+ attr_t *attr;
|
||||
+
|
||||
+ LIST_FOR_EACH_ENTRY(entry, ifaces, ifref_t, entry)
|
||||
+ LIST_FOR_EACH_ENTRY(attr, entry->attrs, attr_t, entry)
|
||||
+ if (attr->type == ATTR_DEFAULT) return entry->iface;
|
||||
+
|
||||
+ assert(0);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
static inline const decl_spec_t *type_pointer_get_ref(const type_t *type)
|
||||
{
|
||||
type = type_get_real_type(type);
|
||||
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
|
||||
index e945cad33b2..0a2088574d3 100644
|
||||
--- a/tools/widl/widltypes.h
|
||||
+++ b/tools/widl/widltypes.h
|
||||
@@ -418,6 +418,11 @@ struct alias_details
|
||||
struct _decl_spec_t aliasee;
|
||||
};
|
||||
|
||||
+struct runtimeclass_details
|
||||
+{
|
||||
+ ifref_list_t *ifaces;
|
||||
+};
|
||||
+
|
||||
#define HASHMAX 64
|
||||
|
||||
struct namespace {
|
||||
@@ -445,6 +450,7 @@ enum type_type
|
||||
TYPE_ARRAY,
|
||||
TYPE_BITFIELD,
|
||||
TYPE_APICONTRACT,
|
||||
+ TYPE_RUNTIMECLASS,
|
||||
};
|
||||
|
||||
struct _type_t {
|
||||
@@ -465,6 +471,7 @@ struct _type_t {
|
||||
struct pointer_details pointer;
|
||||
struct bitfield_details bitfield;
|
||||
struct alias_details alias;
|
||||
+ struct runtimeclass_details runtimeclass;
|
||||
} details;
|
||||
const char *c_name;
|
||||
unsigned int typestring_offset;
|
||||
--
|
||||
2.28.0
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -0,0 +1,391 @@
|
||||
From 46f497692aa6da875d56764538eefaadb9a8ec38 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Tue, 13 Oct 2020 16:31:16 +0200
|
||||
Subject: [PATCH 20/28] widl: Support WinRT parameterized type parsing.
|
||||
|
||||
And add IVectorView<T> and IIterator<T> parameterized interfaces to
|
||||
windows.foundation.idl for illustration and future use. They won't
|
||||
generate any additional code until they are fully specialized.
|
||||
|
||||
This is a WIDL-specific feature, but MIDL has some magic knowledge of
|
||||
these Windows.Foundation.Collections interface templates, and we need a
|
||||
way to instruct WIDL about them too.
|
||||
|
||||
Having these interfaces declared in the IDL, guarded with __WIDL__ ifdef
|
||||
is easier and more flexible than re-creating the types by hand in WIDL
|
||||
source.
|
||||
---
|
||||
include/windows.foundation.idl | 29 +++++++++++++++++
|
||||
tools/widl/expr.c | 2 ++
|
||||
tools/widl/header.c | 10 +++---
|
||||
tools/widl/parser.y | 57 ++++++++++++++++++++++++++++++++--
|
||||
tools/widl/typegen.c | 6 ++++
|
||||
tools/widl/typelib.c | 2 ++
|
||||
tools/widl/typetree.c | 30 ++++++++++++++++++
|
||||
tools/widl/typetree.h | 4 +++
|
||||
tools/widl/widltypes.h | 9 ++++++
|
||||
9 files changed, 143 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/include/windows.foundation.idl b/include/windows.foundation.idl
|
||||
index 5e17062f399..ab7c4753c3b 100644
|
||||
--- a/include/windows.foundation.idl
|
||||
+++ b/include/windows.foundation.idl
|
||||
@@ -111,5 +111,34 @@ namespace Windows {
|
||||
{
|
||||
HRESULT ToString([out, retval] HSTRING *value);
|
||||
}
|
||||
+
|
||||
+#ifdef __WIDL__
|
||||
+ namespace Collections
|
||||
+ {
|
||||
+ [
|
||||
+ contract(Windows.Foundation.FoundationContract, 1.0),
|
||||
+ uuid(6a79e863-4300-459a-9966-cbb660963ee1)
|
||||
+ ]
|
||||
+ interface IIterator<T> : IInspectable
|
||||
+ {
|
||||
+ [propget] HRESULT Current([out, retval] T *value);
|
||||
+ [propget] HRESULT HasCurrent([out, retval] BOOL *value);
|
||||
+ HRESULT MoveNext([out, retval] BOOL *value);
|
||||
+ HRESULT GetMany([in] UINT32 count, [out] T *items, [out, retval] UINT32 *value);
|
||||
+ }
|
||||
+
|
||||
+ [
|
||||
+ contract(Windows.Foundation.FoundationContract, 1.0),
|
||||
+ uuid(bbe1fa4c-b0e3-4583-baef-1f1b2e483e56)
|
||||
+ ]
|
||||
+ interface IVectorView<T> : IInspectable
|
||||
+ {
|
||||
+ HRESULT GetAt([in] ULONG index, [out, retval] T *value);
|
||||
+ [propget] HRESULT Size([out, retval] ULONG *value);
|
||||
+ HRESULT IndexOf([in, optional] T element, [out] ULONG *index, [out, retval] BOOLEAN *value);
|
||||
+ HRESULT GetMany([in] ULONG start_index, [out] T *items, [out, retval] ULONG *value);
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
}
|
||||
}
|
||||
diff --git a/tools/widl/expr.c b/tools/widl/expr.c
|
||||
index 13bd5a889aa..c83e9aa5ec0 100644
|
||||
--- a/tools/widl/expr.c
|
||||
+++ b/tools/widl/expr.c
|
||||
@@ -464,6 +464,8 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type,
|
||||
case TYPE_BITFIELD:
|
||||
case TYPE_APICONTRACT:
|
||||
case TYPE_RUNTIMECLASS:
|
||||
+ case TYPE_PARAMETERIZED_TYPE:
|
||||
+ case TYPE_PARAMETER:
|
||||
/* nothing to do */
|
||||
break;
|
||||
case TYPE_ALIAS:
|
||||
diff --git a/tools/widl/header.c b/tools/widl/header.c
|
||||
index 5c87a997349..283f2372fee 100644
|
||||
--- a/tools/widl/header.c
|
||||
+++ b/tools/widl/header.c
|
||||
@@ -501,7 +501,9 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i
|
||||
break;
|
||||
}
|
||||
case TYPE_APICONTRACT:
|
||||
- /* handled elsewhere */
|
||||
+ case TYPE_PARAMETERIZED_TYPE:
|
||||
+ case TYPE_PARAMETER:
|
||||
+ /* handled elsewhere / shouldn't be here */
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
@@ -568,6 +570,8 @@ void write_type_right(FILE *h, type_t *t, int is_field)
|
||||
case TYPE_RUNTIMECLASS:
|
||||
break;
|
||||
case TYPE_APICONTRACT:
|
||||
+ case TYPE_PARAMETERIZED_TYPE:
|
||||
+ case TYPE_PARAMETER:
|
||||
/* not supposed to be here */
|
||||
assert(0);
|
||||
break;
|
||||
@@ -1969,10 +1973,8 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
|
||||
write_apicontract(header, stmt->u.type);
|
||||
else if (type_get_type(stmt->u.type) == TYPE_RUNTIMECLASS)
|
||||
write_runtimeclass(header, stmt->u.type);
|
||||
- else
|
||||
- {
|
||||
+ else if (type_get_type(stmt->u.type) != TYPE_PARAMETERIZED_TYPE)
|
||||
write_type_definition(header, stmt->u.type, stmt->declonly);
|
||||
- }
|
||||
break;
|
||||
case STMT_TYPEREF:
|
||||
/* FIXME: shouldn't write out forward declarations for undefined
|
||||
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
|
||||
index d24f8881147..aa6ded5ba89 100644
|
||||
--- a/tools/widl/parser.y
|
||||
+++ b/tools/widl/parser.y
|
||||
@@ -80,6 +80,8 @@ static var_t *reg_const(var_t *var);
|
||||
static void push_namespace(const char *name);
|
||||
static void pop_namespace(const char *name);
|
||||
static void push_lookup_namespace(const char *name);
|
||||
+static void push_parameters_namespace(const char *name);
|
||||
+static void pop_parameters_namespace(const char *name);
|
||||
|
||||
static void check_arg_attrs(const var_t *arg);
|
||||
static void check_statements(const statement_list_t *stmts, int is_inside_library);
|
||||
@@ -125,6 +127,7 @@ static struct namespace global_namespace = {
|
||||
|
||||
static struct namespace *current_namespace = &global_namespace;
|
||||
static struct namespace *lookup_namespace = &global_namespace;
|
||||
+static struct namespace *parameters_namespace = NULL;
|
||||
|
||||
static typelib_t *current_typelib;
|
||||
|
||||
@@ -295,6 +298,8 @@ static typelib_t *current_typelib;
|
||||
%type <type> base_type int_std
|
||||
%type <type> enumdef structdef uniondef typedecl
|
||||
%type <type> type qualified_type
|
||||
+%type <type> type_parameter
|
||||
+%type <typelist> type_parameters
|
||||
%type <typelist> requires required_types
|
||||
%type <ifref> class_interface
|
||||
%type <ifref_list> class_interfaces
|
||||
@@ -1010,6 +1015,15 @@ interfacehdr: attributes interface { $$ = $2;
|
||||
}
|
||||
;
|
||||
|
||||
+type_parameter: aIDENTIFIER { $$ = get_type(TYPE_PARAMETER, $1, parameters_namespace, 0); }
|
||||
+ | aKNOWNTYPE { $$ = get_type(TYPE_PARAMETER, $1, parameters_namespace, 0); }
|
||||
+ ;
|
||||
+
|
||||
+type_parameters:
|
||||
+ type_parameter { $$ = append_type(NULL, $1); }
|
||||
+ | type_parameters ',' type_parameter { $$ = append_type($1, $3); }
|
||||
+ ;
|
||||
+
|
||||
required_types:
|
||||
qualified_type { $$ = append_type(NULL, $1); }
|
||||
| required_types ',' required_types { $$ = append_types($1, $3); }
|
||||
@@ -1025,6 +1039,13 @@ interfacedef: interfacehdr inherit requires
|
||||
type_interface_define($$, $2, $5, $3);
|
||||
check_async_uuid($$);
|
||||
}
|
||||
+ | interfacehdr '<' { push_parameters_namespace($1->name); } type_parameters '>' inherit
|
||||
+ '{' int_statements '}' semicolon_opt { $$ = $1;
|
||||
+ if($$ == $6) error_loc("Interface can't inherit from itself\n");
|
||||
+ type_parameterized_interface_define($$, $4, $6, $8);
|
||||
+ check_async_uuid($$);
|
||||
+ pop_parameters_namespace($1->name);
|
||||
+ }
|
||||
/* 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 requires
|
||||
@@ -1037,6 +1058,11 @@ interfacedef: interfacehdr inherit requires
|
||||
|
||||
interfacedec:
|
||||
interface ';' { $$ = $1; }
|
||||
+ | interface '<' { push_parameters_namespace($1->name); } type_parameters '>' ';'
|
||||
+ { $$ = $1;
|
||||
+ type_parameterized_interface_declare($$, $4);
|
||||
+ pop_parameters_namespace($1->name);
|
||||
+ }
|
||||
| dispinterface ';' { $$ = $1; }
|
||||
;
|
||||
|
||||
@@ -1979,6 +2005,29 @@ static void push_lookup_namespace(const char *name)
|
||||
lookup_namespace = namespace;
|
||||
}
|
||||
|
||||
+static void push_parameters_namespace(const char *name)
|
||||
+{
|
||||
+ struct namespace *namespace;
|
||||
+
|
||||
+ if (!(namespace = find_sub_namespace(current_namespace, name)))
|
||||
+ {
|
||||
+ namespace = xmalloc(sizeof(*namespace));
|
||||
+ namespace->name = xstrdup(name);
|
||||
+ namespace->parent = current_namespace;
|
||||
+ list_add_tail(¤t_namespace->children, &namespace->entry);
|
||||
+ list_init(&namespace->children);
|
||||
+ memset(namespace->type_hash, 0, sizeof(namespace->type_hash));
|
||||
+ }
|
||||
+
|
||||
+ parameters_namespace = namespace;
|
||||
+}
|
||||
+
|
||||
+static void pop_parameters_namespace(const char *name)
|
||||
+{
|
||||
+ assert(!strcmp(parameters_namespace->name, name) && parameters_namespace->parent);
|
||||
+ parameters_namespace = NULL;
|
||||
+}
|
||||
+
|
||||
struct rtype {
|
||||
const char *name;
|
||||
type_t *type;
|
||||
@@ -2110,7 +2159,8 @@ 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)
|
||||
{
|
||||
type_t *type;
|
||||
- if (!(type = find_type(name, current_namespace, t)))
|
||||
+ if (!(type = find_type(name, current_namespace, t)) &&
|
||||
+ !(type = find_type(name, parameters_namespace, t)))
|
||||
{
|
||||
error_loc("type '%s' not found\n", name);
|
||||
return NULL;
|
||||
@@ -2130,7 +2180,8 @@ int is_type(const char *name)
|
||||
if (lookup_namespace != &global_namespace)
|
||||
return find_type(name, lookup_namespace, 0) != NULL;
|
||||
else
|
||||
- return find_type(name, current_namespace, 0) != NULL;
|
||||
+ return find_type(name, current_namespace, 0) != NULL ||
|
||||
+ find_type(name, parameters_namespace, 0) != NULL;
|
||||
}
|
||||
|
||||
int is_namespace(const char *name)
|
||||
@@ -2623,6 +2674,8 @@ static int is_allowed_conf_type(const type_t *type)
|
||||
case TYPE_RUNTIMECLASS:
|
||||
return FALSE;
|
||||
case TYPE_APICONTRACT:
|
||||
+ case TYPE_PARAMETERIZED_TYPE:
|
||||
+ case TYPE_PARAMETER:
|
||||
/* not supposed to be here */
|
||||
assert(0);
|
||||
break;
|
||||
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
|
||||
index 86c010aa6ae..f37b54eb65d 100644
|
||||
--- a/tools/widl/typegen.c
|
||||
+++ b/tools/widl/typegen.c
|
||||
@@ -377,6 +377,8 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att
|
||||
case TYPE_RUNTIMECLASS:
|
||||
break;
|
||||
case TYPE_APICONTRACT:
|
||||
+ case TYPE_PARAMETERIZED_TYPE:
|
||||
+ case TYPE_PARAMETER:
|
||||
/* not supposed to be here */
|
||||
assert(0);
|
||||
break;
|
||||
@@ -1974,6 +1976,8 @@ unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *align)
|
||||
case TYPE_BITFIELD:
|
||||
case TYPE_APICONTRACT:
|
||||
case TYPE_RUNTIMECLASS:
|
||||
+ case TYPE_PARAMETERIZED_TYPE:
|
||||
+ case TYPE_PARAMETER:
|
||||
/* these types should not be encountered here due to language
|
||||
* restrictions (interface, void, coclass, module), logical
|
||||
* restrictions (alias - due to type_get_type call above) or
|
||||
@@ -2077,6 +2081,8 @@ static unsigned int type_buffer_alignment(const type_t *t)
|
||||
case TYPE_BITFIELD:
|
||||
case TYPE_APICONTRACT:
|
||||
case TYPE_RUNTIMECLASS:
|
||||
+ case TYPE_PARAMETERIZED_TYPE:
|
||||
+ case TYPE_PARAMETER:
|
||||
/* these types should not be encountered here due to language
|
||||
* restrictions (interface, void, coclass, module), logical
|
||||
* restrictions (alias - due to type_get_type call above) or
|
||||
diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c
|
||||
index ace6424e3a0..6f6c5f3ccc8 100644
|
||||
--- a/tools/widl/typelib.c
|
||||
+++ b/tools/widl/typelib.c
|
||||
@@ -226,6 +226,8 @@ unsigned short get_type_vt(type_t *t)
|
||||
|
||||
case TYPE_ALIAS:
|
||||
case TYPE_APICONTRACT:
|
||||
+ case TYPE_PARAMETERIZED_TYPE:
|
||||
+ case TYPE_PARAMETER:
|
||||
/* not supposed to be here */
|
||||
assert(0);
|
||||
break;
|
||||
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
|
||||
index 3d26fd23b26..bbd519d98ab 100644
|
||||
--- a/tools/widl/typetree.c
|
||||
+++ b/tools/widl/typetree.c
|
||||
@@ -459,6 +459,36 @@ static unsigned int compute_method_indexes(type_t *iface)
|
||||
return idx;
|
||||
}
|
||||
|
||||
+void type_parameterized_interface_declare(type_t *type, type_list_t *params)
|
||||
+{
|
||||
+ type_t *iface = make_type(TYPE_INTERFACE);
|
||||
+ type->type_type = TYPE_PARAMETERIZED_TYPE;
|
||||
+ type->details.parameterized.type = iface;
|
||||
+ type->details.parameterized.params = params;
|
||||
+}
|
||||
+
|
||||
+void type_parameterized_interface_define(type_t *type, type_list_t *params, type_t *inherit, statement_list_t *stmts)
|
||||
+{
|
||||
+ type_t *iface;
|
||||
+
|
||||
+ if (type->type_type != TYPE_PARAMETERIZED_TYPE) type_parameterized_interface_declare(type, params);
|
||||
+ iface = type->details.parameterized.type;
|
||||
+
|
||||
+ /* The parameterized type UUID is actually a PIID that is then used as a seed to generate
|
||||
+ * a new type GUID with the rules described in:
|
||||
+ * https://docs.microsoft.com/en-us/uwp/winrt-cref/winrt-type-system#parameterized-types
|
||||
+ * FIXME: store type signatures for generated interfaces, and generate their GUIDs
|
||||
+ */
|
||||
+ iface->details.iface = xmalloc(sizeof(*iface->details.iface));
|
||||
+ iface->details.iface->disp_props = NULL;
|
||||
+ iface->details.iface->disp_methods = NULL;
|
||||
+ iface->details.iface->stmts = stmts;
|
||||
+ iface->details.iface->inherit = inherit;
|
||||
+ iface->details.iface->disp_inherit = NULL;
|
||||
+ iface->details.iface->async_iface = NULL;
|
||||
+ iface->details.iface->requires = NULL;
|
||||
+}
|
||||
+
|
||||
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));
|
||||
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
|
||||
index 8c555b91656..b04a67f6b47 100644
|
||||
--- a/tools/widl/typetree.h
|
||||
+++ b/tools/widl/typetree.h
|
||||
@@ -45,6 +45,8 @@ 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_parameterized_interface_declare(type_t *type, type_list_t *params);
|
||||
+void type_parameterized_interface_define(type_t *type, type_list_t *params, 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);
|
||||
@@ -234,6 +236,8 @@ static inline int type_is_complete(const type_t *type)
|
||||
case TYPE_RUNTIMECLASS:
|
||||
return TRUE;
|
||||
case TYPE_APICONTRACT:
|
||||
+ case TYPE_PARAMETERIZED_TYPE:
|
||||
+ case TYPE_PARAMETER:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
|
||||
index 7ca770b67ea..e2ffec6da8a 100644
|
||||
--- a/tools/widl/widltypes.h
|
||||
+++ b/tools/widl/widltypes.h
|
||||
@@ -429,6 +429,12 @@ struct runtimeclass_details
|
||||
ifref_list_t *ifaces;
|
||||
};
|
||||
|
||||
+struct parameterized_details
|
||||
+{
|
||||
+ type_t *type;
|
||||
+ type_list_t *params;
|
||||
+};
|
||||
+
|
||||
#define HASHMAX 64
|
||||
|
||||
struct namespace {
|
||||
@@ -457,6 +463,8 @@ enum type_type
|
||||
TYPE_BITFIELD,
|
||||
TYPE_APICONTRACT,
|
||||
TYPE_RUNTIMECLASS,
|
||||
+ TYPE_PARAMETERIZED_TYPE,
|
||||
+ TYPE_PARAMETER,
|
||||
};
|
||||
|
||||
struct _type_t {
|
||||
@@ -478,6 +486,7 @@ struct _type_t {
|
||||
struct bitfield_details bitfield;
|
||||
struct alias_details alias;
|
||||
struct runtimeclass_details runtimeclass;
|
||||
+ struct parameterized_details parameterized;
|
||||
} details;
|
||||
const char *c_name;
|
||||
unsigned int typestring_offset;
|
||||
--
|
||||
2.28.0
|
||||
|
@ -0,0 +1,203 @@
|
||||
From dfec9f64f5f1058ce394c8a39ae759ea027106a8 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Mon, 12 Oct 2020 23:23:18 +0200
|
||||
Subject: [PATCH 21/28] widl: Support partially specialized parameterized type.
|
||||
|
||||
This allows parameterized types to reference each other with a different
|
||||
set of parameters. This is required for instance for IIterable<T>, that
|
||||
needs to reference IIterator<T>.
|
||||
|
||||
The partial specialization is recorded by adding a new parameterized
|
||||
type, referencing the original one as its template. The parameterized
|
||||
type chain will be resolved all at once when the type is declared.
|
||||
---
|
||||
include/windows.foundation.idl | 9 +++++++++
|
||||
tools/widl/parser.y | 35 ++++++++++++++++++++++++++++++++++
|
||||
tools/widl/typetree.c | 32 +++++++++++++++++++++++++++++++
|
||||
tools/widl/typetree.h | 2 ++
|
||||
tools/widl/widltypes.h | 1 +
|
||||
5 files changed, 79 insertions(+)
|
||||
|
||||
diff --git a/include/windows.foundation.idl b/include/windows.foundation.idl
|
||||
index ab7c4753c3b..5f7a49c38e4 100644
|
||||
--- a/include/windows.foundation.idl
|
||||
+++ b/include/windows.foundation.idl
|
||||
@@ -127,6 +127,15 @@ namespace Windows {
|
||||
HRESULT GetMany([in] UINT32 count, [out] T *items, [out, retval] UINT32 *value);
|
||||
}
|
||||
|
||||
+ [
|
||||
+ contract(Windows.Foundation.FoundationContract, 1.0),
|
||||
+ uuid(faa585ea-6214-4217-afda-7f46de5869b3)
|
||||
+ ]
|
||||
+ interface IIterable<T> : IInspectable
|
||||
+ {
|
||||
+ HRESULT First([out, retval] Windows.Foundation.Collections.IIterator<T> **value);
|
||||
+ }
|
||||
+
|
||||
[
|
||||
contract(Windows.Foundation.FoundationContract, 1.0),
|
||||
uuid(bbe1fa4c-b0e3-4583-baef-1f1b2e483e56)
|
||||
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
|
||||
index aa6ded5ba89..c9806ced633 100644
|
||||
--- a/tools/widl/parser.y
|
||||
+++ b/tools/widl/parser.y
|
||||
@@ -300,6 +300,8 @@ static typelib_t *current_typelib;
|
||||
%type <type> type qualified_type
|
||||
%type <type> type_parameter
|
||||
%type <typelist> type_parameters
|
||||
+%type <type> parameterized_type
|
||||
+%type <typelist> parameterized_types
|
||||
%type <typelist> requires required_types
|
||||
%type <ifref> class_interface
|
||||
%type <ifref_list> class_interfaces
|
||||
@@ -908,6 +910,20 @@ qualified_type:
|
||||
| namespace_pfx aKNOWNTYPE { $$ = find_qualified_type_or_error($2, 0); }
|
||||
;
|
||||
|
||||
+parameterized_type: qualified_type '<' parameterized_types '>'
|
||||
+ { $$ = find_parameterized_type($1, $3, 0); }
|
||||
+ ;
|
||||
+
|
||||
+parameterized_types:
|
||||
+ base_type { $$ = append_type(NULL, $1); }
|
||||
+ | qualified_type { $$ = append_type(NULL, $1); }
|
||||
+ | qualified_type '*' { $$ = append_type(NULL, type_new_pointer($1)); }
|
||||
+ | parameterized_type { $$ = append_type(NULL, $1); }
|
||||
+ | parameterized_type '*' { $$ = append_type(NULL, type_new_pointer($1)); }
|
||||
+ | parameterized_types ',' parameterized_types
|
||||
+ { $$ = append_types($1, $3); }
|
||||
+ ;
|
||||
+
|
||||
coclass: tCOCLASS aIDENTIFIER { $$ = type_new_coclass($2); }
|
||||
| tCOCLASS aKNOWNTYPE { $$ = find_type($2, NULL, 0);
|
||||
if (type_get_type_detect_alias($$) != TYPE_COCLASS)
|
||||
@@ -1000,6 +1016,7 @@ dispinterfacedef: dispinterfacehdr '{'
|
||||
|
||||
inherit: { $$ = NULL; }
|
||||
| ':' qualified_type { $$ = $2; }
|
||||
+ | ':' parameterized_type { $$ = $2; }
|
||||
;
|
||||
|
||||
interface: tINTERFACE aIDENTIFIER { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); }
|
||||
@@ -1026,6 +1043,7 @@ type_parameters:
|
||||
|
||||
required_types:
|
||||
qualified_type { $$ = append_type(NULL, $1); }
|
||||
+ | parameterized_type { $$ = append_type(NULL, $1); }
|
||||
| required_types ',' required_types { $$ = append_types($1, $3); }
|
||||
|
||||
requires: { $$ = NULL; }
|
||||
@@ -1247,6 +1265,7 @@ structdef: tSTRUCT t_ident '{' fields '}' { $$ = type_new_struct($2, current_nam
|
||||
|
||||
type: tVOID { $$ = type_new_void(); }
|
||||
| qualified_type { $$ = $1; }
|
||||
+ | parameterized_type { $$ = $1; }
|
||||
| base_type { $$ = $1; }
|
||||
| enumdef { $$ = $1; }
|
||||
| tENUM aIDENTIFIER { $$ = type_new_enum($2, current_namespace, FALSE, NULL); }
|
||||
@@ -3324,3 +3343,19 @@ static void check_def(const type_t *t)
|
||||
error_loc("%s: redefinition error; original definition was at %s:%d\n",
|
||||
t->name, t->loc_info.input_name, t->loc_info.line_number);
|
||||
}
|
||||
+
|
||||
+type_t *find_parameterized_type(type_t *type, type_list_t *params, int t)
|
||||
+{
|
||||
+ char *name = format_parameterized_type_name(type, params);
|
||||
+
|
||||
+ if (parameters_namespace)
|
||||
+ {
|
||||
+ assert(type->type_type == TYPE_PARAMETERIZED_TYPE);
|
||||
+ type = type_parameterized_type_specialize_partial(type, params);
|
||||
+ }
|
||||
+ /* FIXME: If not in another parameterized type, we'll have to look for the declared specialization. */
|
||||
+ else error_loc("parameterized type '%s' not declared\n", name);
|
||||
+
|
||||
+ free(name);
|
||||
+ return type;
|
||||
+}
|
||||
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
|
||||
index bbd519d98ab..9d50cabf172 100644
|
||||
--- a/tools/widl/typetree.c
|
||||
+++ b/tools/widl/typetree.c
|
||||
@@ -112,6 +112,22 @@ static int format_namespace_buffer(char *buf, size_t len, struct namespace *name
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int format_parameterized_type_name_buffer(char *buf, size_t len, type_t *type, type_list_t *params)
|
||||
+{
|
||||
+ type_list_t *entry;
|
||||
+ int ret = 0;
|
||||
+ append_buf(snprintf, "%s<", type->name);
|
||||
+ for (entry = params; entry; entry = entry->next)
|
||||
+ {
|
||||
+ for (type = entry->type; type->type_type == TYPE_POINTER; type = type_pointer_get_ref_type(type)) {}
|
||||
+ append_buf(format_namespace_buffer, type->namespace, "", "::", type->name, use_abi_namespace ? "ABI" : NULL);
|
||||
+ for (type = entry->type; type->type_type == TYPE_POINTER; type = type_pointer_get_ref_type(type)) append_buf(snprintf, "*");
|
||||
+ if (entry->next) append_buf(snprintf, ",");
|
||||
+ }
|
||||
+ append_buf(snprintf, ">");
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
#undef append_buf
|
||||
|
||||
char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix, const char *abi_prefix)
|
||||
@@ -122,6 +138,14 @@ char *format_namespace(struct namespace *namespace, const char *prefix, const ch
|
||||
return buf;
|
||||
}
|
||||
|
||||
+char *format_parameterized_type_name(type_t *type, type_list_t *params)
|
||||
+{
|
||||
+ int len = format_parameterized_type_name_buffer(NULL, 0, type, params);
|
||||
+ char *buf = xmalloc(len + 1);
|
||||
+ format_parameterized_type_name_buffer(buf, len + 1, type, params);
|
||||
+ return buf;
|
||||
+}
|
||||
+
|
||||
type_t *type_new_function(var_list_t *args)
|
||||
{
|
||||
var_t *arg;
|
||||
@@ -459,6 +483,14 @@ static unsigned int compute_method_indexes(type_t *iface)
|
||||
return idx;
|
||||
}
|
||||
|
||||
+type_t *type_parameterized_type_specialize_partial(type_t *type, type_list_t *params)
|
||||
+{
|
||||
+ type_t *new_type = duptype(type, 0);
|
||||
+ new_type->details.parameterized.type = type;
|
||||
+ new_type->details.parameterized.params = params;
|
||||
+ return new_type;
|
||||
+}
|
||||
+
|
||||
void type_parameterized_interface_declare(type_t *type, type_list_t *params)
|
||||
{
|
||||
type_t *iface = make_type(TYPE_INTERFACE);
|
||||
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
|
||||
index b04a67f6b47..472fdf2d5fc 100644
|
||||
--- a/tools/widl/typetree.h
|
||||
+++ b/tools/widl/typetree.h
|
||||
@@ -45,6 +45,8 @@ 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);
|
||||
+type_t *type_parameterized_type_specialize_partial(type_t *type, type_list_t *params);
|
||||
+type_t *find_parameterized_type(type_t *type, type_list_t *params, int t);
|
||||
void type_parameterized_interface_declare(type_t *type, type_list_t *params);
|
||||
void type_parameterized_interface_define(type_t *type, type_list_t *params, 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);
|
||||
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
|
||||
index e2ffec6da8a..9863c4f72ff 100644
|
||||
--- a/tools/widl/widltypes.h
|
||||
+++ b/tools/widl/widltypes.h
|
||||
@@ -643,6 +643,7 @@ void init_loc_info(loc_info_t *);
|
||||
|
||||
char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix,
|
||||
const char *abi_prefix);
|
||||
+char *format_parameterized_type_name(type_t *type, type_list_t *params);
|
||||
|
||||
static inline enum type_type type_get_type_detect_alias(const type_t *type)
|
||||
{
|
||||
--
|
||||
2.28.0
|
||||
|
@ -0,0 +1,542 @@
|
||||
From dfbafe5f504cc35003199e63716c9ce5c6a5729e Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Mon, 12 Oct 2020 17:38:53 +0200
|
||||
Subject: [PATCH 22/28] widl: Support WinRT parameterized interface type.
|
||||
|
||||
This allows parameterized interfaces to be instanciated in declare
|
||||
blocks, in the same way MIDL does, generating a new interface to the
|
||||
header from the parameterized type template, replacing its parameters
|
||||
with the given types.
|
||||
---
|
||||
include/windows.media.speechsynthesis.idl | 23 ++
|
||||
tools/widl/header.c | 7 +-
|
||||
tools/widl/parser.l | 1 +
|
||||
tools/widl/parser.y | 63 +++++-
|
||||
tools/widl/typetree.c | 243 ++++++++++++++++++++++
|
||||
tools/widl/typetree.h | 2 +
|
||||
6 files changed, 334 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/include/windows.media.speechsynthesis.idl b/include/windows.media.speechsynthesis.idl
|
||||
index 89fe616b9b3..40c45c82051 100644
|
||||
--- a/include/windows.media.speechsynthesis.idl
|
||||
+++ b/include/windows.media.speechsynthesis.idl
|
||||
@@ -35,6 +35,18 @@ namespace Windows {
|
||||
}
|
||||
}
|
||||
|
||||
+namespace Windows {
|
||||
+ namespace Media {
|
||||
+ namespace SpeechSynthesis {
|
||||
+ declare {
|
||||
+ interface Windows.Foundation.Collections.IIterator<Windows.Media.SpeechSynthesis.VoiceInformation*>;
|
||||
+ interface Windows.Foundation.Collections.IIterable<Windows.Media.SpeechSynthesis.VoiceInformation*>;
|
||||
+ interface Windows.Foundation.Collections.IVectorView<Windows.Media.SpeechSynthesis.VoiceInformation*>;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
namespace Windows {
|
||||
namespace Media {
|
||||
namespace SpeechSynthesis {
|
||||
@@ -59,6 +71,17 @@ namespace Windows {
|
||||
[propget] HRESULT Gender([out] [retval] VoiceGender* value);
|
||||
}
|
||||
|
||||
+ [
|
||||
+ contract(Windows.Foundation.UniversalApiContract, 1.0),
|
||||
+ exclusiveto(Windows.Media.SpeechSynthesis.SpeechSynthesizer),
|
||||
+ uuid(7d526ecc-7533-4c3f-85be-888c2baeebdc)
|
||||
+ ]
|
||||
+ interface IInstalledVoicesStatic : IInspectable
|
||||
+ {
|
||||
+ [propget] HRESULT AllVoices([out, retval] Windows.Foundation.Collections.IVectorView<VoiceInformation*>** value);
|
||||
+ [propget] HRESULT DefaultVoice([out, retval] VoiceInformation** value);
|
||||
+ }
|
||||
+
|
||||
[
|
||||
contract(Windows.Foundation.UniversalApiContract, 1.0),
|
||||
marshaling_behavior(agile)
|
||||
diff --git a/tools/widl/header.c b/tools/widl/header.c
|
||||
index 283f2372fee..db83f3aac13 100644
|
||||
--- a/tools/widl/header.c
|
||||
+++ b/tools/widl/header.c
|
||||
@@ -1492,7 +1492,8 @@ static void write_forward(FILE *header, type_t *iface)
|
||||
fprintf(header, "typedef interface %s %s;\n", iface->c_name, iface->c_name);
|
||||
fprintf(header, "#ifdef __cplusplus\n");
|
||||
write_namespace_start(header, iface->namespace);
|
||||
- write_line(header, 0, "interface %s;", iface->name);
|
||||
+ if (strchr(iface->name, '<')) write_line(header, 0, "template<> struct %s;", iface->name);
|
||||
+ else write_line(header, 0, "interface %s;", iface->name);
|
||||
write_namespace_end(header, iface->namespace);
|
||||
fprintf(header, "#endif /* __cplusplus */\n");
|
||||
fprintf(header, "#endif\n\n" );
|
||||
@@ -1655,11 +1656,13 @@ static void write_com_interface_end(FILE *header, type_t *iface)
|
||||
write_namespace_start(header, iface->namespace);
|
||||
}
|
||||
if (uuid) {
|
||||
+ if (strchr(iface->name, '<')) write_line(header, 0, "template<>");
|
||||
write_line(header, 0, "MIDL_INTERFACE(\"%s\")", uuid_string(uuid));
|
||||
indent(header, 0);
|
||||
}else {
|
||||
indent(header, 0);
|
||||
- fprintf(header, "interface ");
|
||||
+ if (strchr(iface->name, '<')) fprintf(header, "template<> struct ");
|
||||
+ else fprintf(header, "interface ");
|
||||
}
|
||||
if (type_iface_get_inherit(iface))
|
||||
{
|
||||
diff --git a/tools/widl/parser.l b/tools/widl/parser.l
|
||||
index a47c490ec4c..b7f8844c7a9 100644
|
||||
--- a/tools/widl/parser.l
|
||||
+++ b/tools/widl/parser.l
|
||||
@@ -276,6 +276,7 @@ static const struct keyword keywords[] = {
|
||||
{"coclass", tCOCLASS, 0},
|
||||
{"const", tCONST, 0},
|
||||
{"cpp_quote", tCPPQUOTE, 0},
|
||||
+ {"declare", tDECLARE, 1},
|
||||
{"default", tDEFAULT, 0},
|
||||
{"dispinterface", tDISPINTERFACE, 0},
|
||||
{"double", tDOUBLE, 0},
|
||||
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
|
||||
index c9806ced633..2fb73a46dc1 100644
|
||||
--- a/tools/widl/parser.y
|
||||
+++ b/tools/widl/parser.y
|
||||
@@ -83,6 +83,7 @@ static void push_lookup_namespace(const char *name);
|
||||
static void push_parameters_namespace(const char *name);
|
||||
static void pop_parameters_namespace(const char *name);
|
||||
|
||||
+static statement_list_t *append_parameterized_type_stmts(statement_list_t *stmts);
|
||||
static void check_arg_attrs(const var_t *arg);
|
||||
static void check_statements(const statement_list_t *stmts, int is_inside_library);
|
||||
static void check_all_user_types(const statement_list_t *stmts);
|
||||
@@ -117,6 +118,7 @@ static statement_t *make_statement_importlib(const char *str);
|
||||
static statement_t *make_statement_module(type_t *type);
|
||||
static statement_t *make_statement_typedef(var_list_t *names, int declonly);
|
||||
static statement_t *make_statement_import(const char *str);
|
||||
+static statement_t *make_statement_parameterized_type(type_t *type, type_list_t *params);
|
||||
static statement_list_t *append_statement(statement_list_t *list, statement_t *stmt);
|
||||
static statement_list_t *append_statements(statement_list_t *, statement_list_t *);
|
||||
static attr_list_t *append_attribs(attr_list_t *, attr_list_t *);
|
||||
@@ -128,6 +130,7 @@ static struct namespace global_namespace = {
|
||||
static struct namespace *current_namespace = &global_namespace;
|
||||
static struct namespace *lookup_namespace = &global_namespace;
|
||||
static struct namespace *parameters_namespace = NULL;
|
||||
+static statement_list_t *parameterized_type_stmts = NULL;
|
||||
|
||||
static typelib_t *current_typelib;
|
||||
|
||||
@@ -188,6 +191,7 @@ static typelib_t *current_typelib;
|
||||
%token tCONTRACT
|
||||
%token tCONTRACTVERSION
|
||||
%token tCONTROL tCPPQUOTE
|
||||
+%token tDECLARE
|
||||
%token tDECODE tDEFAULT tDEFAULTBIND
|
||||
%token tDEFAULTCOLLELEM
|
||||
%token tDEFAULTVALUE
|
||||
@@ -325,6 +329,8 @@ static typelib_t *current_typelib;
|
||||
%type <typelib> library_start librarydef
|
||||
%type <statement> statement typedef pragma_warning
|
||||
%type <stmt_list> gbl_statements imp_statements int_statements
|
||||
+%type <stmt_list> decl_block decl_statements
|
||||
+%type <stmt_list> imp_decl_block imp_decl_statements
|
||||
%type <warning_list> warnings
|
||||
|
||||
%left ','
|
||||
@@ -346,7 +352,8 @@ static typelib_t *current_typelib;
|
||||
|
||||
%%
|
||||
|
||||
-input: gbl_statements m_acf { check_statements($1, FALSE);
|
||||
+input: gbl_statements m_acf { $1 = append_parameterized_type_stmts($1);
|
||||
+ check_statements($1, FALSE);
|
||||
check_all_user_types($1);
|
||||
write_header($1);
|
||||
write_id_data($1);
|
||||
@@ -362,6 +369,22 @@ input: gbl_statements m_acf { check_statements($1, FALSE);
|
||||
|
||||
m_acf: /* empty */ | aACF acf_statements
|
||||
|
||||
+decl_statements: { $$ = NULL; }
|
||||
+ | decl_statements tINTERFACE qualified_type '<' parameterized_types '>' ';'
|
||||
+ { parameterized_type_stmts = append_statement(parameterized_type_stmts, make_statement_parameterized_type($3, $5));
|
||||
+ $$ = append_statement($1, make_statement_reference(type_parameterized_type_specialize_declare($3, $5)));
|
||||
+ }
|
||||
+ ;
|
||||
+
|
||||
+decl_block: tDECLARE '{' decl_statements '}' { $$ = $3; }
|
||||
+
|
||||
+imp_decl_statements: { $$ = NULL; }
|
||||
+ | imp_decl_statements tINTERFACE qualified_type '<' parameterized_types '>' ';'
|
||||
+ { $$ = append_statement($1, make_statement_reference(type_parameterized_type_specialize_declare($3, $5))); }
|
||||
+ ;
|
||||
+
|
||||
+imp_decl_block: tDECLARE '{' imp_decl_statements '}' { $$ = $3; }
|
||||
+
|
||||
gbl_statements: { $$ = NULL; }
|
||||
| gbl_statements namespacedef '{' { push_namespace($2); } gbl_statements '}'
|
||||
{ pop_namespace($2); $$ = append_statements($1, $5); }
|
||||
@@ -381,6 +404,7 @@ gbl_statements: { $$ = NULL; }
|
||||
| gbl_statements moduledef { $$ = append_statement($1, make_statement_module($2)); }
|
||||
| gbl_statements librarydef { $$ = append_statement($1, make_statement_library($2)); }
|
||||
| gbl_statements statement { $$ = append_statement($1, $2); }
|
||||
+ | gbl_statements decl_block { $$ = append_statements($1, $2); }
|
||||
;
|
||||
|
||||
imp_statements: { $$ = NULL; }
|
||||
@@ -401,6 +425,7 @@ imp_statements: { $$ = NULL; }
|
||||
| imp_statements statement { $$ = append_statement($1, $2); }
|
||||
| imp_statements importlib { $$ = append_statement($1, make_statement_importlib($2)); }
|
||||
| imp_statements librarydef { $$ = append_statement($1, make_statement_library($2)); }
|
||||
+ | imp_statements imp_decl_block { $$ = append_statements($1, $2); }
|
||||
;
|
||||
|
||||
int_statements: { $$ = NULL; }
|
||||
@@ -3121,6 +3146,27 @@ static void check_async_uuid(type_t *iface)
|
||||
iface->details.iface->async_iface = async_iface->details.iface->async_iface = async_iface;
|
||||
}
|
||||
|
||||
+static statement_list_t *append_parameterized_type_stmts(statement_list_t *stmts)
|
||||
+{
|
||||
+ statement_t *stmt, *next;
|
||||
+ if (stmts && parameterized_type_stmts) LIST_FOR_EACH_ENTRY_SAFE(stmt, next, parameterized_type_stmts, statement_t, entry)
|
||||
+ {
|
||||
+ switch(stmt->type) {
|
||||
+ case STMT_TYPE:
|
||||
+ stmt->u.type = type_parameterized_type_specialize_define(stmt->u.type_list->type, stmt->u.type_list->next);
|
||||
+ stmt->declonly = FALSE;
|
||||
+ list_remove(&stmt->entry);
|
||||
+ stmts = append_statement(stmts, stmt);
|
||||
+ break;
|
||||
+ default:
|
||||
+ assert(0); /* should not be there */
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return stmts;
|
||||
+}
|
||||
+
|
||||
static void check_statements(const statement_list_t *stmts, int is_inside_library)
|
||||
{
|
||||
const statement_t *stmt;
|
||||
@@ -3302,6 +3348,15 @@ static statement_t *make_statement_typedef(declarator_list_t *decls, int declonl
|
||||
return stmt;
|
||||
}
|
||||
|
||||
+static statement_t *make_statement_parameterized_type(type_t *type, type_list_t *params)
|
||||
+{
|
||||
+ statement_t *stmt = make_statement(STMT_TYPE);
|
||||
+ stmt->u.type_list = xmalloc(sizeof(type_list_t));
|
||||
+ stmt->u.type_list->type = type;
|
||||
+ stmt->u.type_list->next = params;
|
||||
+ return stmt;
|
||||
+}
|
||||
+
|
||||
static statement_list_t *append_statements(statement_list_t *l1, statement_list_t *l2)
|
||||
{
|
||||
if (!l2) return l1;
|
||||
@@ -3353,8 +3408,10 @@ type_t *find_parameterized_type(type_t *type, type_list_t *params, int t)
|
||||
assert(type->type_type == TYPE_PARAMETERIZED_TYPE);
|
||||
type = type_parameterized_type_specialize_partial(type, params);
|
||||
}
|
||||
- /* FIXME: If not in another parameterized type, we'll have to look for the declared specialization. */
|
||||
- else error_loc("parameterized type '%s' not declared\n", name);
|
||||
+ else if ((type = find_type(name, type->namespace, t)))
|
||||
+ assert(type->type_type != TYPE_PARAMETERIZED_TYPE);
|
||||
+ else
|
||||
+ error_loc("parameterized type '%s' not declared\n", name);
|
||||
|
||||
free(name);
|
||||
return type;
|
||||
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
|
||||
index 9d50cabf172..8f1e2d71aff 100644
|
||||
--- a/tools/widl/typetree.c
|
||||
+++ b/tools/widl/typetree.c
|
||||
@@ -128,6 +128,21 @@ static int format_parameterized_type_name_buffer(char *buf, size_t len, type_t *
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int format_parameterized_type_c_name_buffer(char *buf, size_t len, type_t *type, type_list_t *params)
|
||||
+{
|
||||
+ type_list_t *entry;
|
||||
+ int ret = 0, count = 0;
|
||||
+ append_buf(format_namespace_buffer, type->namespace, "__x_", "_C", type->name, use_abi_namespace ? "ABI" : NULL);
|
||||
+ for (entry = params; entry; entry = entry->next) count++;
|
||||
+ append_buf(snprintf, "_%d", count);
|
||||
+ for (entry = params; entry; entry = entry->next)
|
||||
+ {
|
||||
+ for (type = entry->type; type->type_type == TYPE_POINTER; type = type_pointer_get_ref_type(type)) {}
|
||||
+ append_buf(format_namespace_buffer, type->namespace, "_", "__C", type->name, NULL);
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
#undef append_buf
|
||||
|
||||
char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix, const char *abi_prefix)
|
||||
@@ -146,6 +161,31 @@ char *format_parameterized_type_name(type_t *type, type_list_t *params)
|
||||
return buf;
|
||||
}
|
||||
|
||||
+static char const *parameterized_type_shorthands[][2] = {
|
||||
+ {"Windows_CFoundation_CCollections_C", "__F"},
|
||||
+ {"Windows_CFoundation_C", "__F"},
|
||||
+};
|
||||
+
|
||||
+static char *format_parameterized_type_c_name(type_t *type, type_list_t *params)
|
||||
+{
|
||||
+ int i, len = format_parameterized_type_c_name_buffer(NULL, 0, type, params);
|
||||
+ char *buf = xmalloc(len + 1), *tmp;
|
||||
+ format_parameterized_type_c_name_buffer(buf, len + 1, type, params);
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(parameterized_type_shorthands); ++i)
|
||||
+ {
|
||||
+ if ((tmp = strstr(buf, parameterized_type_shorthands[i][0])) &&
|
||||
+ (tmp - buf) == strlen(use_abi_namespace ? "__x_ABI_C" : "__x_C"))
|
||||
+ {
|
||||
+ tmp += strlen(parameterized_type_shorthands[i][0]);
|
||||
+ strcpy(buf, parameterized_type_shorthands[i][1]);
|
||||
+ memmove(buf + 3, tmp, len - (tmp - buf) + 1);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return buf;
|
||||
+}
|
||||
+
|
||||
type_t *type_new_function(var_list_t *args)
|
||||
{
|
||||
var_t *arg;
|
||||
@@ -483,6 +523,177 @@ static unsigned int compute_method_indexes(type_t *iface)
|
||||
return idx;
|
||||
}
|
||||
|
||||
+static type_t *replace_type_parameters_in_type(type_t *type, type_list_t *orig, type_list_t *repl);
|
||||
+
|
||||
+static type_list_t *replace_type_parameters_in_type_list(type_list_t *type_list, type_list_t *orig, type_list_t *repl)
|
||||
+{
|
||||
+ type_list_t *entry, *new_entry, **next, *first = NULL;
|
||||
+
|
||||
+ if (!type_list) return type_list;
|
||||
+
|
||||
+ next = &first;
|
||||
+ for (entry = type_list; entry; entry = entry->next)
|
||||
+ {
|
||||
+ new_entry = xmalloc(sizeof(*new_entry));
|
||||
+ new_entry->type = replace_type_parameters_in_type(entry->type, orig, repl);
|
||||
+ new_entry->next = NULL;
|
||||
+ *next = new_entry;
|
||||
+ next = &new_entry->next;
|
||||
+ }
|
||||
+
|
||||
+ return first;
|
||||
+}
|
||||
+
|
||||
+static var_t *replace_type_parameters_in_var(var_t *var, type_list_t *orig, type_list_t *repl)
|
||||
+{
|
||||
+ var_t *new_var = xmalloc(sizeof(*new_var));
|
||||
+ *new_var = *var;
|
||||
+ list_init(&new_var->entry);
|
||||
+ new_var->declspec.type = replace_type_parameters_in_type(var->declspec.type, orig, repl);
|
||||
+ return new_var;
|
||||
+}
|
||||
+
|
||||
+static var_list_t *replace_type_parameters_in_var_list(var_list_t *var_list, type_list_t *orig, type_list_t *repl)
|
||||
+{
|
||||
+ var_list_t *new_var_list;
|
||||
+ var_t *var, *new_var;
|
||||
+
|
||||
+ if (!var_list) return var_list;
|
||||
+
|
||||
+ new_var_list = xmalloc(sizeof(*new_var_list));
|
||||
+ list_init(new_var_list);
|
||||
+
|
||||
+ LIST_FOR_EACH_ENTRY(var, var_list, var_t, entry)
|
||||
+ {
|
||||
+ new_var = replace_type_parameters_in_var(var, orig, repl);
|
||||
+ list_add_tail(new_var_list, &new_var->entry);
|
||||
+ }
|
||||
+
|
||||
+ return new_var_list;
|
||||
+}
|
||||
+
|
||||
+static statement_t *replace_type_parameters_in_statement(statement_t *stmt, type_list_t *orig, type_list_t *repl)
|
||||
+{
|
||||
+ statement_t *new_stmt = xmalloc(sizeof(*new_stmt));
|
||||
+ *new_stmt = *stmt;
|
||||
+ list_init(&new_stmt->entry);
|
||||
+
|
||||
+ switch (stmt->type)
|
||||
+ {
|
||||
+ case STMT_DECLARATION:
|
||||
+ new_stmt->u.var = replace_type_parameters_in_var(stmt->u.var, orig, repl);
|
||||
+ break;
|
||||
+ case STMT_LIBRARY:
|
||||
+ case STMT_TYPE:
|
||||
+ case STMT_TYPEREF:
|
||||
+ case STMT_MODULE:
|
||||
+ case STMT_TYPEDEF:
|
||||
+ new_stmt->u.type_list = replace_type_parameters_in_type_list(stmt->u.type_list, orig, repl);
|
||||
+ break;
|
||||
+ case STMT_IMPORT:
|
||||
+ case STMT_IMPORTLIB:
|
||||
+ case STMT_PRAGMA:
|
||||
+ case STMT_CPPQUOTE:
|
||||
+ fprintf(stderr, "%d\n", stmt->type);
|
||||
+ assert(0);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return new_stmt;
|
||||
+}
|
||||
+
|
||||
+static statement_list_t *replace_type_parameters_in_statement_list(statement_list_t *stmt_list, type_list_t *orig, type_list_t *repl)
|
||||
+{
|
||||
+ statement_list_t *new_stmt_list;
|
||||
+ statement_t *stmt, *new_stmt;
|
||||
+
|
||||
+ if (!stmt_list) return stmt_list;
|
||||
+
|
||||
+ new_stmt_list = xmalloc(sizeof(*new_stmt_list));
|
||||
+ list_init(new_stmt_list);
|
||||
+
|
||||
+ LIST_FOR_EACH_ENTRY(stmt, stmt_list, statement_t, entry)
|
||||
+ {
|
||||
+ new_stmt = replace_type_parameters_in_statement(stmt, orig, repl);
|
||||
+ list_add_tail(new_stmt_list, &new_stmt->entry);
|
||||
+ }
|
||||
+
|
||||
+ return new_stmt_list;
|
||||
+}
|
||||
+
|
||||
+static type_t *replace_type_parameters_in_type(type_t *type, type_list_t *orig, type_list_t *repl)
|
||||
+{
|
||||
+ type_list_t *o, *r;
|
||||
+ type_t *t;
|
||||
+
|
||||
+ if (!type) return type;
|
||||
+ switch (type->type_type)
|
||||
+ {
|
||||
+ case TYPE_VOID:
|
||||
+ case TYPE_BASIC:
|
||||
+ case TYPE_ENUM:
|
||||
+ case TYPE_BITFIELD:
|
||||
+ case TYPE_INTERFACE:
|
||||
+ case TYPE_RUNTIMECLASS:
|
||||
+ return type;
|
||||
+ case TYPE_PARAMETER:
|
||||
+ for (o = orig, r = repl; o && r; o = o->next, r = r->next)
|
||||
+ if (type == o->type) return r->type;
|
||||
+ return type;
|
||||
+ case TYPE_POINTER:
|
||||
+ t = replace_type_parameters_in_type(type->details.pointer.ref.type, orig, repl);
|
||||
+ if (t == type->details.pointer.ref.type) return type;
|
||||
+ type = duptype(type, 0);
|
||||
+ type->details.pointer.ref.type = t;
|
||||
+ return type;
|
||||
+ case TYPE_ALIAS:
|
||||
+ t = replace_type_parameters_in_type(type->details.alias.aliasee.type, orig, repl);
|
||||
+ if (t == type->details.alias.aliasee.type) return type;
|
||||
+ type = duptype(type, 0);
|
||||
+ type->details.alias.aliasee.type = t;
|
||||
+ return type;
|
||||
+ case TYPE_ARRAY:
|
||||
+ t = replace_type_parameters_in_type(type->details.array.elem.type, orig, repl);
|
||||
+ if (t == t->details.array.elem.type) return type;
|
||||
+ type = duptype(type, 0);
|
||||
+ t->details.array.elem.type = t;
|
||||
+ return type;
|
||||
+ case TYPE_FUNCTION:
|
||||
+ t = duptype(type, 0);
|
||||
+ t->details.function = xmalloc(sizeof(*t->details.function));
|
||||
+ t->details.function->args = replace_type_parameters_in_var_list(type->details.function->args, orig, repl);
|
||||
+ t->details.function->retval = replace_type_parameters_in_var(type->details.function->retval, orig, repl);
|
||||
+ return t;
|
||||
+ case TYPE_PARAMETERIZED_TYPE:
|
||||
+ t = type->details.parameterized.type;
|
||||
+ if (t->type_type != TYPE_PARAMETERIZED_TYPE) return find_parameterized_type(type, repl, 0);
|
||||
+ repl = replace_type_parameters_in_type_list(type->details.parameterized.params, orig, repl);
|
||||
+ return replace_type_parameters_in_type(t, t->details.parameterized.params, repl);
|
||||
+ case TYPE_STRUCT:
|
||||
+ case TYPE_ENCAPSULATED_UNION:
|
||||
+ case TYPE_UNION:
|
||||
+ case TYPE_MODULE:
|
||||
+ case TYPE_COCLASS:
|
||||
+ case TYPE_APICONTRACT:
|
||||
+ assert(0); /* FIXME: implement when needed */
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return type;
|
||||
+}
|
||||
+
|
||||
+static void type_parameterized_interface_specialize(type_t *tmpl, type_t *iface, type_list_t *orig, type_list_t *repl)
|
||||
+{
|
||||
+ iface->details.iface = xmalloc(sizeof(*iface->details.iface));
|
||||
+ iface->details.iface->disp_methods = NULL;
|
||||
+ iface->details.iface->disp_props = NULL;
|
||||
+ iface->details.iface->stmts = replace_type_parameters_in_statement_list(tmpl->details.iface->stmts, orig, repl);
|
||||
+ iface->details.iface->inherit = replace_type_parameters_in_type(tmpl->details.iface->inherit, orig, repl);
|
||||
+ iface->details.iface->disp_inherit = NULL;
|
||||
+ iface->details.iface->async_iface = NULL;
|
||||
+ iface->details.iface->requires = NULL;
|
||||
+}
|
||||
+
|
||||
type_t *type_parameterized_type_specialize_partial(type_t *type, type_list_t *params)
|
||||
{
|
||||
type_t *new_type = duptype(type, 0);
|
||||
@@ -491,6 +702,38 @@ type_t *type_parameterized_type_specialize_partial(type_t *type, type_list_t *pa
|
||||
return new_type;
|
||||
}
|
||||
|
||||
+type_t *type_parameterized_type_specialize_declare(type_t *type, type_list_t *params)
|
||||
+{
|
||||
+ type_t *tmpl = type->details.parameterized.type;
|
||||
+ type_t *new_type = duptype(tmpl, 0);
|
||||
+
|
||||
+ new_type->namespace = type->namespace;
|
||||
+ new_type->name = format_parameterized_type_name(type, params);
|
||||
+ reg_type(new_type, new_type->name, new_type->namespace, 0);
|
||||
+ new_type->c_name = format_parameterized_type_c_name(type, params);
|
||||
+
|
||||
+ return new_type;
|
||||
+}
|
||||
+
|
||||
+type_t *type_parameterized_type_specialize_define(type_t *type, type_list_t *params)
|
||||
+{
|
||||
+ type_list_t *orig = type->details.parameterized.params;
|
||||
+ type_t *tmpl = type->details.parameterized.type;
|
||||
+ type_t *iface = find_parameterized_type(type, params, 0);
|
||||
+
|
||||
+ if (tmpl->type_type == TYPE_INTERFACE)
|
||||
+ type_parameterized_interface_specialize(tmpl, iface, orig, params);
|
||||
+ else
|
||||
+ {
|
||||
+ error_loc("Unsupported parameterized type template %d\n", tmpl->type_type);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ iface->defined = TRUE;
|
||||
+ compute_method_indexes(iface);
|
||||
+ return iface;
|
||||
+}
|
||||
+
|
||||
void type_parameterized_interface_declare(type_t *type, type_list_t *params)
|
||||
{
|
||||
type_t *iface = make_type(TYPE_INTERFACE);
|
||||
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
|
||||
index 472fdf2d5fc..e1a52d21d09 100644
|
||||
--- a/tools/widl/typetree.h
|
||||
+++ b/tools/widl/typetree.h
|
||||
@@ -46,6 +46,8 @@ type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *unio
|
||||
type_t *type_new_bitfield(type_t *field_type, const expr_t *bits);
|
||||
type_t *type_new_runtimeclass(char *name, struct namespace *namespace);
|
||||
type_t *type_parameterized_type_specialize_partial(type_t *type, type_list_t *params);
|
||||
+type_t *type_parameterized_type_specialize_declare(type_t *type, type_list_t *params);
|
||||
+type_t *type_parameterized_type_specialize_define(type_t *type, type_list_t *params);
|
||||
type_t *find_parameterized_type(type_t *type, type_list_t *params, int t);
|
||||
void type_parameterized_interface_declare(type_t *type, type_list_t *params);
|
||||
void type_parameterized_interface_define(type_t *type, type_list_t *params, type_t *inherit, statement_list_t *stmts);
|
||||
--
|
||||
2.28.0
|
||||
|
@ -0,0 +1,346 @@
|
||||
From 82c354b2275a33863181fc7660f8e63db51c131a Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Thu, 24 Sep 2020 00:00:54 +0200
|
||||
Subject: [PATCH 23/28] widl: Support WinRT delegate type.
|
||||
|
||||
---
|
||||
tools/widl/expr.c | 1 +
|
||||
tools/widl/header.c | 14 ++++++++++----
|
||||
tools/widl/parser.l | 1 +
|
||||
tools/widl/parser.y | 25 +++++++++++++++++++++++++
|
||||
tools/widl/typegen.c | 4 ++++
|
||||
tools/widl/typelib.c | 1 +
|
||||
tools/widl/typetree.c | 29 +++++++++++++++++++++++++++++
|
||||
tools/widl/typetree.h | 9 +++++++++
|
||||
tools/widl/widltypes.h | 7 +++++++
|
||||
9 files changed, 87 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/tools/widl/expr.c b/tools/widl/expr.c
|
||||
index c83e9aa5ec0..88d59290d6b 100644
|
||||
--- a/tools/widl/expr.c
|
||||
+++ b/tools/widl/expr.c
|
||||
@@ -466,6 +466,7 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type,
|
||||
case TYPE_RUNTIMECLASS:
|
||||
case TYPE_PARAMETERIZED_TYPE:
|
||||
case TYPE_PARAMETER:
|
||||
+ case TYPE_DELEGATE:
|
||||
/* nothing to do */
|
||||
break;
|
||||
case TYPE_ALIAS:
|
||||
diff --git a/tools/widl/header.c b/tools/widl/header.c
|
||||
index db83f3aac13..64faf89c36a 100644
|
||||
--- a/tools/widl/header.c
|
||||
+++ b/tools/widl/header.c
|
||||
@@ -483,6 +483,9 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i
|
||||
case TYPE_RUNTIMECLASS:
|
||||
fprintf(h, "%s", type_get_name(type_runtimeclass_get_default_iface(t), name_type));
|
||||
break;
|
||||
+ case TYPE_DELEGATE:
|
||||
+ fprintf(h, "%s", type_get_name(type_delegate_get_iface(t), name_type));
|
||||
+ break;
|
||||
case TYPE_VOID:
|
||||
fprintf(h, "void");
|
||||
break;
|
||||
@@ -568,6 +571,7 @@ void write_type_right(FILE *h, type_t *t, int is_field)
|
||||
case TYPE_COCLASS:
|
||||
case TYPE_INTERFACE:
|
||||
case TYPE_RUNTIMECLASS:
|
||||
+ case TYPE_DELEGATE:
|
||||
break;
|
||||
case TYPE_APICONTRACT:
|
||||
case TYPE_PARAMETERIZED_TYPE:
|
||||
@@ -1904,9 +1908,10 @@ static void write_forward_decls(FILE *header, const statement_list_t *stmts)
|
||||
switch (stmt->type)
|
||||
{
|
||||
case STMT_TYPE:
|
||||
- if (type_get_type(stmt->u.type) == TYPE_INTERFACE)
|
||||
+ if (type_get_type(stmt->u.type) == TYPE_INTERFACE || type_get_type(stmt->u.type) == TYPE_DELEGATE)
|
||||
{
|
||||
type_t *iface = stmt->u.type;
|
||||
+ if (type_get_type(iface) == TYPE_DELEGATE) iface = type_delegate_get_iface(iface);
|
||||
if (is_object(iface) || is_attr(iface->attrs, ATTR_DISPINTERFACE))
|
||||
{
|
||||
write_forward(header, iface);
|
||||
@@ -1946,10 +1951,11 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
|
||||
switch (stmt->type)
|
||||
{
|
||||
case STMT_TYPE:
|
||||
- if (type_get_type(stmt->u.type) == TYPE_INTERFACE)
|
||||
+ if (type_get_type(stmt->u.type) == TYPE_INTERFACE || type_get_type(stmt->u.type) == TYPE_DELEGATE)
|
||||
{
|
||||
- type_t *iface = stmt->u.type;
|
||||
- type_t *async_iface = type_iface_get_async_iface(iface);
|
||||
+ type_t *iface = stmt->u.type, *async_iface;
|
||||
+ if (type_get_type(stmt->u.type) == TYPE_DELEGATE) iface = type_delegate_get_iface(iface);
|
||||
+ async_iface = type_iface_get_async_iface(iface);
|
||||
if (is_object(iface)) is_object_interface++;
|
||||
if (is_attr(stmt->u.type->attrs, ATTR_DISPINTERFACE) || is_object(stmt->u.type))
|
||||
{
|
||||
diff --git a/tools/widl/parser.l b/tools/widl/parser.l
|
||||
index b7f8844c7a9..5de85e43a94 100644
|
||||
--- a/tools/widl/parser.l
|
||||
+++ b/tools/widl/parser.l
|
||||
@@ -278,6 +278,7 @@ static const struct keyword keywords[] = {
|
||||
{"cpp_quote", tCPPQUOTE, 0},
|
||||
{"declare", tDECLARE, 1},
|
||||
{"default", tDEFAULT, 0},
|
||||
+ {"delegate", tDELEGATE, 1},
|
||||
{"dispinterface", tDISPINTERFACE, 0},
|
||||
{"double", tDOUBLE, 0},
|
||||
{"enum", tENUM, 0},
|
||||
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
|
||||
index 2fb73a46dc1..d0166eb3af2 100644
|
||||
--- a/tools/widl/parser.y
|
||||
+++ b/tools/widl/parser.y
|
||||
@@ -119,6 +119,7 @@ static statement_t *make_statement_module(type_t *type);
|
||||
static statement_t *make_statement_typedef(var_list_t *names, int declonly);
|
||||
static statement_t *make_statement_import(const char *str);
|
||||
static statement_t *make_statement_parameterized_type(type_t *type, type_list_t *params);
|
||||
+static statement_t *make_statement_delegate(type_t *ret, var_list_t *args);
|
||||
static statement_list_t *append_statement(statement_list_t *list, statement_t *stmt);
|
||||
static statement_list_t *append_statements(statement_list_t *, statement_list_t *);
|
||||
static attr_list_t *append_attribs(attr_list_t *, attr_list_t *);
|
||||
@@ -193,6 +194,7 @@ static typelib_t *current_typelib;
|
||||
%token tCONTROL tCPPQUOTE
|
||||
%token tDECLARE
|
||||
%token tDECODE tDEFAULT tDEFAULTBIND
|
||||
+%token tDELEGATE
|
||||
%token tDEFAULTCOLLELEM
|
||||
%token tDEFAULTVALUE
|
||||
%token tDEFAULTVTABLE
|
||||
@@ -291,6 +293,7 @@ static typelib_t *current_typelib;
|
||||
%type <expr> contract_req
|
||||
%type <expr> static_attr
|
||||
%type <type> interfacehdr
|
||||
+%type <type> delegatedef
|
||||
%type <stgclass> storage_cls_spec
|
||||
%type <type_qualifier> type_qualifier m_type_qual_list
|
||||
%type <function_specifier> function_specifier
|
||||
@@ -390,6 +393,7 @@ gbl_statements: { $$ = NULL; }
|
||||
{ pop_namespace($2); $$ = append_statements($1, $5); }
|
||||
| gbl_statements interfacedec { $$ = append_statement($1, make_statement_reference($2)); }
|
||||
| gbl_statements interfacedef { $$ = append_statement($1, make_statement_type_decl($2)); }
|
||||
+ | gbl_statements delegatedef { $$ = append_statement($1, make_statement_type_decl($2)); }
|
||||
| gbl_statements coclass ';' { $$ = $1;
|
||||
reg_type($2, $2->name, current_namespace, 0);
|
||||
}
|
||||
@@ -412,6 +416,7 @@ imp_statements: { $$ = NULL; }
|
||||
| imp_statements namespacedef '{' { push_namespace($2); } imp_statements '}'
|
||||
{ pop_namespace($2); $$ = append_statements($1, $5); }
|
||||
| imp_statements interfacedef { $$ = append_statement($1, make_statement_type_decl($2)); }
|
||||
+ | imp_statements delegatedef { $$ = append_statement($1, make_statement_type_decl($2)); }
|
||||
| imp_statements coclass ';' { $$ = $1; reg_type($2, $2->name, current_namespace, 0); }
|
||||
| imp_statements coclassdef { $$ = append_statement($1, make_statement_type_decl($2));
|
||||
reg_type($2, $2->name, current_namespace, 0);
|
||||
@@ -1066,6 +1071,17 @@ type_parameters:
|
||||
| type_parameters ',' type_parameter { $$ = append_type($1, $3); }
|
||||
;
|
||||
|
||||
+delegatedef:
|
||||
+ m_attributes tDELEGATE type ident '(' m_args ')'
|
||||
+ semicolon_opt { $$ = get_type(TYPE_DELEGATE, $4->name, current_namespace, 0);
|
||||
+ check_def($$);
|
||||
+ $$->attrs = check_iface_attrs($$->name, $1);
|
||||
+ $$->defined = TRUE;
|
||||
+ type_delegate_define($$, append_statement(NULL, make_statement_delegate($3, $6)));
|
||||
+ check_async_uuid($$);
|
||||
+ }
|
||||
+ ;
|
||||
+
|
||||
required_types:
|
||||
qualified_type { $$ = append_type(NULL, $1); }
|
||||
| parameterized_type { $$ = append_type(NULL, $1); }
|
||||
@@ -2716,6 +2732,7 @@ static int is_allowed_conf_type(const type_t *type)
|
||||
case TYPE_INTERFACE:
|
||||
case TYPE_BITFIELD:
|
||||
case TYPE_RUNTIMECLASS:
|
||||
+ case TYPE_DELEGATE:
|
||||
return FALSE;
|
||||
case TYPE_APICONTRACT:
|
||||
case TYPE_PARAMETERIZED_TYPE:
|
||||
@@ -3357,6 +3374,14 @@ static statement_t *make_statement_parameterized_type(type_t *type, type_list_t
|
||||
return stmt;
|
||||
}
|
||||
|
||||
+static statement_t *make_statement_delegate(type_t *ret, var_list_t *args)
|
||||
+{
|
||||
+ declarator_t *decl = make_declarator(make_var(xstrdup("Invoke")));
|
||||
+ decl_spec_t *spec = make_decl_spec(ret, NULL, NULL, STG_NONE, 0, 0);
|
||||
+ append_chain_type(decl, type_new_function(args), 0);
|
||||
+ return make_statement_declaration(declare_var(NULL, spec, decl, FALSE));
|
||||
+}
|
||||
+
|
||||
static statement_list_t *append_statements(statement_list_t *l1, statement_list_t *l2)
|
||||
{
|
||||
if (!l2) return l1;
|
||||
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
|
||||
index f37b54eb65d..4557d24b3ff 100644
|
||||
--- a/tools/widl/typegen.c
|
||||
+++ b/tools/widl/typegen.c
|
||||
@@ -354,6 +354,7 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att
|
||||
case TYPE_POINTER:
|
||||
if (type_get_type(type_pointer_get_ref_type(type)) == TYPE_INTERFACE ||
|
||||
type_get_type(type_pointer_get_ref_type(type)) == TYPE_RUNTIMECLASS ||
|
||||
+ type_get_type(type_pointer_get_ref_type(type)) == TYPE_DELEGATE ||
|
||||
(type_get_type(type_pointer_get_ref_type(type)) == TYPE_VOID && is_attr(attrs, ATTR_IIDIS)))
|
||||
return TGT_IFACE_POINTER;
|
||||
else if (is_aliaschain_attr(type_pointer_get_ref_type(type), ATTR_CONTEXTHANDLE))
|
||||
@@ -375,6 +376,7 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att
|
||||
case TYPE_ALIAS:
|
||||
case TYPE_BITFIELD:
|
||||
case TYPE_RUNTIMECLASS:
|
||||
+ case TYPE_DELEGATE:
|
||||
break;
|
||||
case TYPE_APICONTRACT:
|
||||
case TYPE_PARAMETERIZED_TYPE:
|
||||
@@ -1978,6 +1980,7 @@ unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *align)
|
||||
case TYPE_RUNTIMECLASS:
|
||||
case TYPE_PARAMETERIZED_TYPE:
|
||||
case TYPE_PARAMETER:
|
||||
+ case TYPE_DELEGATE:
|
||||
/* these types should not be encountered here due to language
|
||||
* restrictions (interface, void, coclass, module), logical
|
||||
* restrictions (alias - due to type_get_type call above) or
|
||||
@@ -2083,6 +2086,7 @@ static unsigned int type_buffer_alignment(const type_t *t)
|
||||
case TYPE_RUNTIMECLASS:
|
||||
case TYPE_PARAMETERIZED_TYPE:
|
||||
case TYPE_PARAMETER:
|
||||
+ case TYPE_DELEGATE:
|
||||
/* these types should not be encountered here due to language
|
||||
* restrictions (interface, void, coclass, module), logical
|
||||
* restrictions (alias - due to type_get_type call above) or
|
||||
diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c
|
||||
index 6f6c5f3ccc8..8b2a2401367 100644
|
||||
--- a/tools/widl/typelib.c
|
||||
+++ b/tools/widl/typelib.c
|
||||
@@ -219,6 +219,7 @@ unsigned short get_type_vt(type_t *t)
|
||||
case TYPE_UNION:
|
||||
case TYPE_ENCAPSULATED_UNION:
|
||||
case TYPE_RUNTIMECLASS:
|
||||
+ case TYPE_DELEGATE:
|
||||
return VT_USERDEFINED;
|
||||
|
||||
case TYPE_VOID:
|
||||
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
|
||||
index 8f1e2d71aff..15629113cec 100644
|
||||
--- a/tools/widl/typetree.c
|
||||
+++ b/tools/widl/typetree.c
|
||||
@@ -523,6 +523,13 @@ static unsigned int compute_method_indexes(type_t *iface)
|
||||
return idx;
|
||||
}
|
||||
|
||||
+static void compute_delegate_iface_name(type_t *delegate)
|
||||
+{
|
||||
+ char *name = xmalloc(strlen(delegate->name) + 2);
|
||||
+ sprintf(name, "I%s", delegate->name);
|
||||
+ delegate->details.delegate.iface->name = name;
|
||||
+}
|
||||
+
|
||||
static type_t *replace_type_parameters_in_type(type_t *type, type_list_t *orig, type_list_t *repl);
|
||||
|
||||
static type_list_t *replace_type_parameters_in_type_list(type_list_t *type_list, type_list_t *orig, type_list_t *repl)
|
||||
@@ -635,6 +642,7 @@ static type_t *replace_type_parameters_in_type(type_t *type, type_list_t *orig,
|
||||
case TYPE_BITFIELD:
|
||||
case TYPE_INTERFACE:
|
||||
case TYPE_RUNTIMECLASS:
|
||||
+ case TYPE_DELEGATE:
|
||||
return type;
|
||||
case TYPE_PARAMETER:
|
||||
for (o = orig, r = repl; o && r; o = o->next, r = r->next)
|
||||
@@ -778,6 +786,27 @@ void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stm
|
||||
compute_method_indexes(iface);
|
||||
}
|
||||
|
||||
+void type_delegate_define(type_t *delegate, statement_list_t *stmts)
|
||||
+{
|
||||
+ type_t *iface = make_type(TYPE_INTERFACE);
|
||||
+
|
||||
+ iface->namespace = delegate->namespace;
|
||||
+ iface->details.iface = xmalloc(sizeof(*iface->details.iface));
|
||||
+ iface->details.iface->disp_props = NULL;
|
||||
+ iface->details.iface->disp_methods = NULL;
|
||||
+ iface->details.iface->stmts = stmts;
|
||||
+ iface->details.iface->inherit = find_type("IUnknown", NULL, 0);
|
||||
+ if (!iface->details.iface->inherit) error_loc("IUnknown 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);
|
||||
+
|
||||
+ delegate->details.delegate.iface = iface;
|
||||
+ compute_delegate_iface_name(delegate);
|
||||
+}
|
||||
+
|
||||
void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *methods)
|
||||
{
|
||||
iface->details.iface = xmalloc(sizeof(*iface->details.iface));
|
||||
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
|
||||
index e1a52d21d09..de3db4e7c7e 100644
|
||||
--- a/tools/widl/typetree.h
|
||||
+++ b/tools/widl/typetree.h
|
||||
@@ -52,6 +52,7 @@ type_t *find_parameterized_type(type_t *type, type_list_t *params, int t);
|
||||
void type_parameterized_interface_declare(type_t *type, type_list_t *params);
|
||||
void type_parameterized_interface_define(type_t *type, type_list_t *params, 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_delegate_define(type_t *iface, statement_list_t *stmts);
|
||||
void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *methods);
|
||||
void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface);
|
||||
void type_module_define(type_t *module, statement_list_t *stmts);
|
||||
@@ -238,6 +239,7 @@ static inline int type_is_complete(const type_t *type)
|
||||
case TYPE_ARRAY:
|
||||
case TYPE_BITFIELD:
|
||||
case TYPE_RUNTIMECLASS:
|
||||
+ case TYPE_DELEGATE:
|
||||
return TRUE;
|
||||
case TYPE_APICONTRACT:
|
||||
case TYPE_PARAMETERIZED_TYPE:
|
||||
@@ -361,6 +363,13 @@ static inline type_t *type_runtimeclass_get_default_iface(const type_t *type)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+static inline type_t *type_delegate_get_iface(const type_t *type)
|
||||
+{
|
||||
+ type = type_get_real_type(type);
|
||||
+ assert(type_get_type(type) == TYPE_DELEGATE);
|
||||
+ return type->details.delegate.iface;
|
||||
+}
|
||||
+
|
||||
static inline const decl_spec_t *type_pointer_get_ref(const type_t *type)
|
||||
{
|
||||
type = type_get_real_type(type);
|
||||
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
|
||||
index 9863c4f72ff..3938d0d5294 100644
|
||||
--- a/tools/widl/widltypes.h
|
||||
+++ b/tools/widl/widltypes.h
|
||||
@@ -435,6 +435,11 @@ struct parameterized_details
|
||||
type_list_t *params;
|
||||
};
|
||||
|
||||
+struct delegate_details
|
||||
+{
|
||||
+ type_t *iface;
|
||||
+};
|
||||
+
|
||||
#define HASHMAX 64
|
||||
|
||||
struct namespace {
|
||||
@@ -465,6 +470,7 @@ enum type_type
|
||||
TYPE_RUNTIMECLASS,
|
||||
TYPE_PARAMETERIZED_TYPE,
|
||||
TYPE_PARAMETER,
|
||||
+ TYPE_DELEGATE,
|
||||
};
|
||||
|
||||
struct _type_t {
|
||||
@@ -487,6 +493,7 @@ struct _type_t {
|
||||
struct alias_details alias;
|
||||
struct runtimeclass_details runtimeclass;
|
||||
struct parameterized_details parameterized;
|
||||
+ struct delegate_details delegate;
|
||||
} details;
|
||||
const char *c_name;
|
||||
unsigned int typestring_offset;
|
||||
--
|
||||
2.28.0
|
||||
|
@ -0,0 +1,181 @@
|
||||
From f8fa58f5bdfac8adc9fba4af5ff294a11f48b556 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Mon, 28 Sep 2020 16:46:34 +0200
|
||||
Subject: [PATCH 24/28] widl: Support WinRT parameterized delegate type.
|
||||
|
||||
---
|
||||
include/windows.foundation.idl | 6 ++++
|
||||
tools/widl/parser.y | 11 +++++++
|
||||
tools/widl/typetree.c | 56 +++++++++++++++++++++++++++++-----
|
||||
tools/widl/typetree.h | 1 +
|
||||
4 files changed, 67 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/include/windows.foundation.idl b/include/windows.foundation.idl
|
||||
index 5f7a49c38e4..9583fa5bcc8 100644
|
||||
--- a/include/windows.foundation.idl
|
||||
+++ b/include/windows.foundation.idl
|
||||
@@ -113,6 +113,12 @@ namespace Windows {
|
||||
}
|
||||
|
||||
#ifdef __WIDL__
|
||||
+ [
|
||||
+ contract(Windows.Foundation.FoundationContract, 1.0),
|
||||
+ uuid(9de1c535-6ae1-11e0-84e1-18a905bcc53f)
|
||||
+ ]
|
||||
+ delegate void EventHandler<T>([in] IInspectable *sender, [in] T args);
|
||||
+
|
||||
namespace Collections
|
||||
{
|
||||
[
|
||||
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
|
||||
index d0166eb3af2..f7fb7a303a8 100644
|
||||
--- a/tools/widl/parser.y
|
||||
+++ b/tools/widl/parser.y
|
||||
@@ -1080,6 +1080,17 @@ delegatedef:
|
||||
type_delegate_define($$, append_statement(NULL, make_statement_delegate($3, $6)));
|
||||
check_async_uuid($$);
|
||||
}
|
||||
+ | m_attributes tDELEGATE type ident
|
||||
+ '<' { push_parameters_namespace($4->name); } type_parameters '>'
|
||||
+ '(' m_args ')'
|
||||
+ semicolon_opt { $$ = get_type(TYPE_DELEGATE, $4->name, current_namespace, 0);
|
||||
+ check_def($$);
|
||||
+ $$->attrs = check_iface_attrs($$->name, $1);
|
||||
+ $$->defined = TRUE;
|
||||
+ type_parameterized_delegate_define($$, $7, append_statement(NULL, make_statement_delegate($3, $10)));
|
||||
+ check_async_uuid($$);
|
||||
+ pop_parameters_namespace($4->name);
|
||||
+ }
|
||||
;
|
||||
|
||||
required_types:
|
||||
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
|
||||
index 15629113cec..03778aa75c3 100644
|
||||
--- a/tools/widl/typetree.c
|
||||
+++ b/tools/widl/typetree.c
|
||||
@@ -128,13 +128,13 @@ static int format_parameterized_type_name_buffer(char *buf, size_t len, type_t *
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int format_parameterized_type_c_name_buffer(char *buf, size_t len, type_t *type, type_list_t *params)
|
||||
+static int format_parameterized_type_c_name_buffer(char *buf, size_t len, type_t *type, type_list_t *params, const char *prefix)
|
||||
{
|
||||
type_list_t *entry;
|
||||
int ret = 0, count = 0;
|
||||
- append_buf(format_namespace_buffer, type->namespace, "__x_", "_C", type->name, use_abi_namespace ? "ABI" : NULL);
|
||||
+ append_buf(format_namespace_buffer, type->namespace, "__x_", "_C", "", use_abi_namespace ? "ABI" : NULL);
|
||||
for (entry = params; entry; entry = entry->next) count++;
|
||||
- append_buf(snprintf, "_%d", count);
|
||||
+ append_buf(snprintf, "%s%s_%d", prefix, type->name, count);
|
||||
for (entry = params; entry; entry = entry->next)
|
||||
{
|
||||
for (type = entry->type; type->type_type == TYPE_POINTER; type = type_pointer_get_ref_type(type)) {}
|
||||
@@ -166,11 +166,11 @@ static char const *parameterized_type_shorthands[][2] = {
|
||||
{"Windows_CFoundation_C", "__F"},
|
||||
};
|
||||
|
||||
-static char *format_parameterized_type_c_name(type_t *type, type_list_t *params)
|
||||
+static char *format_parameterized_type_c_name(type_t *type, type_list_t *params, const char *prefix)
|
||||
{
|
||||
- int i, len = format_parameterized_type_c_name_buffer(NULL, 0, type, params);
|
||||
+ int i, len = format_parameterized_type_c_name_buffer(NULL, 0, type, params, prefix);
|
||||
char *buf = xmalloc(len + 1), *tmp;
|
||||
- format_parameterized_type_c_name_buffer(buf, len + 1, type, params);
|
||||
+ format_parameterized_type_c_name_buffer(buf, len + 1, type, params, prefix);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(parameterized_type_shorthands); ++i)
|
||||
{
|
||||
@@ -702,6 +702,11 @@ static void type_parameterized_interface_specialize(type_t *tmpl, type_t *iface,
|
||||
iface->details.iface->requires = NULL;
|
||||
}
|
||||
|
||||
+static void type_parameterized_delegate_specialize(type_t *tmpl, type_t *delegate, type_list_t *orig, type_list_t *repl)
|
||||
+{
|
||||
+ type_parameterized_interface_specialize(tmpl->details.delegate.iface, delegate->details.delegate.iface, orig, repl);
|
||||
+}
|
||||
+
|
||||
type_t *type_parameterized_type_specialize_partial(type_t *type, type_list_t *params)
|
||||
{
|
||||
type_t *new_type = duptype(type, 0);
|
||||
@@ -718,7 +723,15 @@ type_t *type_parameterized_type_specialize_declare(type_t *type, type_list_t *pa
|
||||
new_type->namespace = type->namespace;
|
||||
new_type->name = format_parameterized_type_name(type, params);
|
||||
reg_type(new_type, new_type->name, new_type->namespace, 0);
|
||||
- new_type->c_name = format_parameterized_type_c_name(type, params);
|
||||
+ new_type->c_name = format_parameterized_type_c_name(type, params, "");
|
||||
+
|
||||
+ if (new_type->type_type == TYPE_DELEGATE)
|
||||
+ {
|
||||
+ new_type->details.delegate.iface = duptype(tmpl->details.delegate.iface, 0);
|
||||
+ compute_delegate_iface_name(new_type);
|
||||
+ new_type->details.delegate.iface->namespace = new_type->namespace;
|
||||
+ new_type->details.delegate.iface->c_name = format_parameterized_type_c_name(type, params, "I");
|
||||
+ }
|
||||
|
||||
return new_type;
|
||||
}
|
||||
@@ -731,6 +744,8 @@ type_t *type_parameterized_type_specialize_define(type_t *type, type_list_t *par
|
||||
|
||||
if (tmpl->type_type == TYPE_INTERFACE)
|
||||
type_parameterized_interface_specialize(tmpl, iface, orig, params);
|
||||
+ else if (tmpl->type_type == TYPE_DELEGATE)
|
||||
+ type_parameterized_delegate_specialize(tmpl, iface, orig, params);
|
||||
else
|
||||
{
|
||||
error_loc("Unsupported parameterized type template %d\n", tmpl->type_type);
|
||||
@@ -738,6 +753,11 @@ type_t *type_parameterized_type_specialize_define(type_t *type, type_list_t *par
|
||||
}
|
||||
|
||||
iface->defined = TRUE;
|
||||
+ if (iface->type_type == TYPE_DELEGATE)
|
||||
+ {
|
||||
+ iface = iface->details.delegate.iface;
|
||||
+ iface->defined = TRUE;
|
||||
+ }
|
||||
compute_method_indexes(iface);
|
||||
return iface;
|
||||
}
|
||||
@@ -807,6 +827,28 @@ void type_delegate_define(type_t *delegate, statement_list_t *stmts)
|
||||
compute_delegate_iface_name(delegate);
|
||||
}
|
||||
|
||||
+void type_parameterized_delegate_define(type_t *type, type_list_t *params, statement_list_t *stmts)
|
||||
+{
|
||||
+ type_t *delegate = make_type(TYPE_DELEGATE);
|
||||
+ type_t *iface = make_type(TYPE_INTERFACE);
|
||||
+
|
||||
+ type->type_type = TYPE_PARAMETERIZED_TYPE;
|
||||
+ type->details.parameterized.type = delegate;
|
||||
+ type->details.parameterized.params = params;
|
||||
+
|
||||
+ delegate->details.delegate.iface = iface;
|
||||
+
|
||||
+ iface->details.iface = xmalloc(sizeof(*iface->details.iface));
|
||||
+ iface->details.iface->disp_props = NULL;
|
||||
+ iface->details.iface->disp_methods = NULL;
|
||||
+ iface->details.iface->stmts = stmts;
|
||||
+ iface->details.iface->inherit = find_type("IUnknown", NULL, 0);
|
||||
+ if (!iface->details.iface->inherit) error_loc("IUnknown is undefined\n");
|
||||
+ iface->details.iface->disp_inherit = NULL;
|
||||
+ iface->details.iface->async_iface = NULL;
|
||||
+ iface->details.iface->requires = NULL;
|
||||
+}
|
||||
+
|
||||
void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *methods)
|
||||
{
|
||||
iface->details.iface = xmalloc(sizeof(*iface->details.iface));
|
||||
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
|
||||
index de3db4e7c7e..939bc5b412e 100644
|
||||
--- a/tools/widl/typetree.h
|
||||
+++ b/tools/widl/typetree.h
|
||||
@@ -53,6 +53,7 @@ void type_parameterized_interface_declare(type_t *type, type_list_t *params);
|
||||
void type_parameterized_interface_define(type_t *type, type_list_t *params, 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_delegate_define(type_t *iface, statement_list_t *stmts);
|
||||
+void type_parameterized_delegate_define(type_t *type, type_list_t *params, statement_list_t *stmts);
|
||||
void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *methods);
|
||||
void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface);
|
||||
void type_module_define(type_t *module, statement_list_t *stmts);
|
||||
--
|
||||
2.28.0
|
||||
|
@ -0,0 +1,253 @@
|
||||
From c98f225368cdeac02b7c67b14d1e448f80c645e4 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Fri, 25 Sep 2020 13:39:08 +0200
|
||||
Subject: [PATCH 25/28] widl: Compute signatures for parameterized types.
|
||||
|
||||
---
|
||||
tools/widl/typetree.c | 155 +++++++++++++++++++++++++++++++++++++++++
|
||||
tools/widl/typetree.h | 10 +++
|
||||
tools/widl/widltypes.h | 2 +
|
||||
3 files changed, 167 insertions(+)
|
||||
|
||||
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
|
||||
index 03778aa75c3..b3718b5dc6d 100644
|
||||
--- a/tools/widl/typetree.c
|
||||
+++ b/tools/widl/typetree.c
|
||||
@@ -49,6 +49,7 @@ type_t *make_type(enum type_type type)
|
||||
t->type_type = type;
|
||||
t->attrs = NULL;
|
||||
t->c_name = NULL;
|
||||
+ t->signature = NULL;
|
||||
memset(&t->details, 0, sizeof(t->details));
|
||||
t->typestring_offset = 0;
|
||||
t->ptrdesc = 0;
|
||||
@@ -143,6 +144,142 @@ static int format_parameterized_type_c_name_buffer(char *buf, size_t len, type_t
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int format_type_signature_buffer(char *buf, size_t len, type_t *type);
|
||||
+
|
||||
+static int format_var_list_signature_buffer(char *buf, size_t len, var_list_t *var_list)
|
||||
+{
|
||||
+ var_t *var;
|
||||
+ int ret = 0;
|
||||
+ if (!var_list) append_buf(snprintf, ";");
|
||||
+ else LIST_FOR_EACH_ENTRY(var, var_list, var_t, entry)
|
||||
+ {
|
||||
+ append_buf(snprintf, ";");
|
||||
+ append_buf(format_type_signature_buffer, var->declspec.type);
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int format_type_signature_buffer(char *buf, size_t len, type_t *type)
|
||||
+{
|
||||
+ const GUID *uuid;
|
||||
+ int ret = 0;
|
||||
+ if (!type) return 0;
|
||||
+ switch (type->type_type)
|
||||
+ {
|
||||
+ case TYPE_INTERFACE:
|
||||
+ if (type->signature) append_buf(snprintf, "%s", type->signature);
|
||||
+ else
|
||||
+ {
|
||||
+ uuid = type_get_uuid(type);
|
||||
+ append_buf(snprintf, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
|
||||
+ uuid->Data1, uuid->Data2, uuid->Data3,
|
||||
+ uuid->Data4[0], uuid->Data4[1], uuid->Data4[2], uuid->Data4[3],
|
||||
+ uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], uuid->Data4[7]);
|
||||
+ }
|
||||
+ return ret;
|
||||
+ case TYPE_DELEGATE:
|
||||
+ append_buf(snprintf, "delegate(");
|
||||
+ append_buf(format_type_signature_buffer, type_delegate_get_iface(type));
|
||||
+ append_buf(snprintf, ")");
|
||||
+ return ret;
|
||||
+ case TYPE_RUNTIMECLASS:
|
||||
+ append_buf(snprintf, "rc(");
|
||||
+ append_buf(format_namespace_buffer, type->namespace, "", ".", type->name, NULL);
|
||||
+ append_buf(snprintf, ";");
|
||||
+ append_buf(format_type_signature_buffer, type_runtimeclass_get_default_iface(type));
|
||||
+ append_buf(snprintf, ")");
|
||||
+ return ret;
|
||||
+ case TYPE_POINTER:
|
||||
+ return format_type_signature_buffer(buf, len, type->details.pointer.ref.type);
|
||||
+ case TYPE_ALIAS:
|
||||
+ if (!strcmp(type->name, "boolean")) append_buf(snprintf, "b1");
|
||||
+ else ret = format_type_signature_buffer(buf, len, type->details.alias.aliasee.type);
|
||||
+ return ret;
|
||||
+ case TYPE_STRUCT:
|
||||
+ append_buf(snprintf, "struct(");
|
||||
+ append_buf(format_namespace_buffer, type->namespace, "", ".", type->name, NULL);
|
||||
+ append_buf(format_var_list_signature_buffer, type->details.structure->fields);
|
||||
+ append_buf(snprintf, ")");
|
||||
+ return ret;
|
||||
+ case TYPE_BASIC:
|
||||
+ switch (type_basic_get_type(type))
|
||||
+ {
|
||||
+ case TYPE_BASIC_INT:
|
||||
+ case TYPE_BASIC_INT32:
|
||||
+ append_buf(snprintf, type_basic_get_sign(type) < 0 ? "i4" : "u4");
|
||||
+ return ret;
|
||||
+ case TYPE_BASIC_INT64:
|
||||
+ append_buf(snprintf, type_basic_get_sign(type) < 0 ? "i8" : "u8");
|
||||
+ return ret;
|
||||
+ case TYPE_BASIC_INT8:
|
||||
+ assert(type_basic_get_sign(type) >= 0); /* signature string for signed char isn't specified */
|
||||
+ append_buf(snprintf, "u1");
|
||||
+ return ret;
|
||||
+ case TYPE_BASIC_FLOAT:
|
||||
+ append_buf(snprintf, "f4");
|
||||
+ return ret;
|
||||
+ case TYPE_BASIC_DOUBLE:
|
||||
+ append_buf(snprintf, "f8");
|
||||
+ return ret;
|
||||
+ case TYPE_BASIC_INT16:
|
||||
+ case TYPE_BASIC_INT3264:
|
||||
+ case TYPE_BASIC_LONG:
|
||||
+ case TYPE_BASIC_CHAR:
|
||||
+ case TYPE_BASIC_HYPER:
|
||||
+ case TYPE_BASIC_BYTE:
|
||||
+ case TYPE_BASIC_WCHAR:
|
||||
+ case TYPE_BASIC_ERROR_STATUS_T:
|
||||
+ case TYPE_BASIC_HANDLE:
|
||||
+ error("basic type '%d' signature not implemented\n", type_basic_get_type(type));
|
||||
+ assert(0); /* FIXME: implement when needed */
|
||||
+ break;
|
||||
+ }
|
||||
+ case TYPE_ENUM:
|
||||
+ append_buf(snprintf, "enum(");
|
||||
+ append_buf(format_namespace_buffer, type->namespace, "", ".", type->name, NULL);
|
||||
+ if (is_attr(type->attrs, ATTR_FLAGS)) append_buf(snprintf, ";u4");
|
||||
+ else append_buf(snprintf, ";i4");
|
||||
+ append_buf(snprintf, ")");
|
||||
+ return ret;
|
||||
+ case TYPE_ARRAY:
|
||||
+ case TYPE_ENCAPSULATED_UNION:
|
||||
+ case TYPE_UNION:
|
||||
+ case TYPE_COCLASS:
|
||||
+ error("type '%d' signature for '%s' not implemented\n", type->type_type, type->name);
|
||||
+ assert(0); /* FIXME: implement when needed */
|
||||
+ break;
|
||||
+ case TYPE_VOID:
|
||||
+ case TYPE_FUNCTION:
|
||||
+ case TYPE_BITFIELD:
|
||||
+ case TYPE_MODULE:
|
||||
+ case TYPE_PARAMETERIZED_TYPE:
|
||||
+ case TYPE_PARAMETER:
|
||||
+ case TYPE_APICONTRACT:
|
||||
+ assert(0); /* should not be there */
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int format_parameterized_type_signature_buffer(char *buf, size_t len, type_t *type, type_list_t *params)
|
||||
+{
|
||||
+ type_list_t *entry;
|
||||
+ const GUID *uuid = type_get_uuid(type);
|
||||
+ int ret = 0;
|
||||
+ append_buf(snprintf, "pinterface({%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
|
||||
+ uuid->Data1, uuid->Data2, uuid->Data3,
|
||||
+ uuid->Data4[0], uuid->Data4[1], uuid->Data4[2], uuid->Data4[3],
|
||||
+ uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], uuid->Data4[7]);
|
||||
+ for (entry = params; entry; entry = entry->next)
|
||||
+ {
|
||||
+ append_buf(snprintf, ";");
|
||||
+ append_buf(format_type_signature_buffer, entry->type);
|
||||
+ }
|
||||
+ append_buf(snprintf, ")");
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
#undef append_buf
|
||||
|
||||
char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix, const char *abi_prefix)
|
||||
@@ -161,6 +298,14 @@ char *format_parameterized_type_name(type_t *type, type_list_t *params)
|
||||
return buf;
|
||||
}
|
||||
|
||||
+char *format_type_signature(type_t *type)
|
||||
+{
|
||||
+ int len = format_type_signature_buffer(NULL, 0, type);
|
||||
+ char *buf = xmalloc(len + 1);
|
||||
+ format_type_signature_buffer(buf, len + 1, type);
|
||||
+ return buf;
|
||||
+}
|
||||
+
|
||||
static char const *parameterized_type_shorthands[][2] = {
|
||||
{"Windows_CFoundation_CCollections_C", "__F"},
|
||||
{"Windows_CFoundation_C", "__F"},
|
||||
@@ -186,6 +331,14 @@ static char *format_parameterized_type_c_name(type_t *type, type_list_t *params,
|
||||
return buf;
|
||||
}
|
||||
|
||||
+static char *format_parameterized_type_signature(type_t *type, type_list_t *params)
|
||||
+{
|
||||
+ int len = format_parameterized_type_signature_buffer(NULL, 0, type, params);
|
||||
+ char *buf = xmalloc(len + 1);
|
||||
+ format_parameterized_type_signature_buffer(buf, len + 1, type, params);
|
||||
+ return buf;
|
||||
+}
|
||||
+
|
||||
type_t *type_new_function(var_list_t *args)
|
||||
{
|
||||
var_t *arg;
|
||||
@@ -752,10 +905,12 @@ type_t *type_parameterized_type_specialize_define(type_t *type, type_list_t *par
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+ iface->signature = format_parameterized_type_signature(type, params);
|
||||
iface->defined = TRUE;
|
||||
if (iface->type_type == TYPE_DELEGATE)
|
||||
{
|
||||
iface = iface->details.delegate.iface;
|
||||
+ iface->signature = format_parameterized_type_signature(type, params);
|
||||
iface->defined = TRUE;
|
||||
}
|
||||
compute_method_indexes(iface);
|
||||
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
|
||||
index 939bc5b412e..b4257fe615f 100644
|
||||
--- a/tools/widl/typetree.h
|
||||
+++ b/tools/widl/typetree.h
|
||||
@@ -80,6 +80,16 @@ static inline enum type_type type_get_type(const type_t *type)
|
||||
return type_get_type_detect_alias(type_get_real_type(type));
|
||||
}
|
||||
|
||||
+static inline const GUID *type_get_uuid(const type_t *type)
|
||||
+{
|
||||
+ static const GUID empty;
|
||||
+ attr_t *attr;
|
||||
+ LIST_FOR_EACH_ENTRY(attr, type->attrs, attr_t, entry)
|
||||
+ if (attr->type == ATTR_UUID) return attr->u.pval;
|
||||
+ error("type '%s' uuid not found\n", type->name);
|
||||
+ return ∅
|
||||
+}
|
||||
+
|
||||
static inline enum type_basic_type type_basic_get_type(const type_t *type)
|
||||
{
|
||||
type = type_get_real_type(type);
|
||||
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
|
||||
index 3938d0d5294..58828a4f8e2 100644
|
||||
--- a/tools/widl/widltypes.h
|
||||
+++ b/tools/widl/widltypes.h
|
||||
@@ -496,6 +496,7 @@ struct _type_t {
|
||||
struct delegate_details delegate;
|
||||
} details;
|
||||
const char *c_name;
|
||||
+ const char *signature;
|
||||
unsigned int typestring_offset;
|
||||
unsigned int ptrdesc; /* used for complex structs */
|
||||
int typelib_idx;
|
||||
@@ -651,6 +652,7 @@ void init_loc_info(loc_info_t *);
|
||||
char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix,
|
||||
const char *abi_prefix);
|
||||
char *format_parameterized_type_name(type_t *type, type_list_t *params);
|
||||
+char *format_type_signature(type_t *type);
|
||||
|
||||
static inline enum type_type type_get_type_detect_alias(const type_t *type)
|
||||
{
|
||||
--
|
||||
2.28.0
|
||||
|
@ -0,0 +1,317 @@
|
||||
From a8e1b96947308faf90d1686bf14743c5da7b90bd Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Mon, 28 Sep 2020 17:00:41 +0200
|
||||
Subject: [PATCH 26/28] widl: Compute uuids for parameterized types.
|
||||
|
||||
---
|
||||
tools/widl/hash.c | 178 ++++++++++++++++++++++++++++++++++++++++++
|
||||
tools/widl/hash.h | 14 ++++
|
||||
tools/widl/typetree.c | 53 +++++++++++++
|
||||
tools/widl/typetree.h | 2 +-
|
||||
4 files changed, 246 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/widl/hash.c b/tools/widl/hash.c
|
||||
index 15ec88001d6..df6133866e0 100644
|
||||
--- a/tools/widl/hash.c
|
||||
+++ b/tools/widl/hash.c
|
||||
@@ -639,3 +639,181 @@ unsigned int lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr)
|
||||
|
||||
return nHiWord | nLoWord;
|
||||
}
|
||||
+
|
||||
+/* SHA1 algorithm
|
||||
+ *
|
||||
+ * Based on public domain SHA code by Steve Reid <steve@edmweb.com>
|
||||
+ */
|
||||
+
|
||||
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
|
||||
+/* FIXME: This definition of DWORD2BE is little endian specific! */
|
||||
+#define DWORD2BE(x) (((x) >> 24) & 0xff) | (((x) >> 8) & 0xff00) | (((x) << 8) & 0xff0000) | (((x) << 24) & 0xff000000);
|
||||
+/* FIXME: This definition of blk0 is little endian specific! */
|
||||
+#define blk0(i) (Block[i] = (rol(Block[i],24)&0xFF00FF00)|(rol(Block[i],8)&0x00FF00FF))
|
||||
+#define blk1(i) (Block[i&15] = rol(Block[(i+13)&15]^Block[(i+8)&15]^Block[(i+2)&15]^Block[i&15],1))
|
||||
+#define f1(x,y,z) (z^(x&(y^z)))
|
||||
+#define f2(x,y,z) (x^y^z)
|
||||
+#define f3(x,y,z) ((x&y)|(z&(x|y)))
|
||||
+#define f4(x,y,z) (x^y^z)
|
||||
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
|
||||
+#define R0(v,w,x,y,z,i) z+=f1(w,x,y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
|
||||
+#define R1(v,w,x,y,z,i) z+=f1(w,x,y)+blk1(i)+0x5A827999+rol(v,5);w=rol(w,30);
|
||||
+#define R2(v,w,x,y,z,i) z+=f2(w,x,y)+blk1(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
|
||||
+#define R3(v,w,x,y,z,i) z+=f3(w,x,y)+blk1(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
|
||||
+#define R4(v,w,x,y,z,i) z+=f4(w,x,y)+blk1(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
|
||||
+
|
||||
+/* Hash a single 512-bit block. This is the core of the algorithm. */
|
||||
+static void SHA1Transform(ULONG State[5], UCHAR Buffer[64])
|
||||
+{
|
||||
+ ULONG a, b, c, d, e;
|
||||
+ ULONG *Block;
|
||||
+
|
||||
+ Block = (ULONG*)Buffer;
|
||||
+
|
||||
+ /* Copy Context->State[] to working variables */
|
||||
+ a = State[0];
|
||||
+ b = State[1];
|
||||
+ c = State[2];
|
||||
+ d = State[3];
|
||||
+ e = State[4];
|
||||
+
|
||||
+ /* 4 rounds of 20 operations each. Loop unrolled. */
|
||||
+ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
|
||||
+ R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
|
||||
+ R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
|
||||
+ R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
|
||||
+ R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
|
||||
+ R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
|
||||
+ R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
|
||||
+ R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
|
||||
+ R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
|
||||
+ R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
|
||||
+ R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
|
||||
+ R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
|
||||
+ R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
|
||||
+ R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
|
||||
+ R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
|
||||
+ R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
|
||||
+ R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
|
||||
+ R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
|
||||
+ R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
|
||||
+ R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
|
||||
+
|
||||
+ /* Add the working variables back into Context->State[] */
|
||||
+ State[0] += a;
|
||||
+ State[1] += b;
|
||||
+ State[2] += c;
|
||||
+ State[3] += d;
|
||||
+ State[4] += e;
|
||||
+
|
||||
+ /* Wipe variables */
|
||||
+ a = b = c = d = e = 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/******************************************************************************
|
||||
+ * A_SHAInit (ntdll.@)
|
||||
+ *
|
||||
+ * Initialize a SHA context structure.
|
||||
+ *
|
||||
+ * PARAMS
|
||||
+ * Context [O] SHA context
|
||||
+ *
|
||||
+ * RETURNS
|
||||
+ * Nothing
|
||||
+ */
|
||||
+void A_SHAInit(SHA_CTX *Context)
|
||||
+{
|
||||
+ /* SHA1 initialization constants */
|
||||
+ Context->State[0] = 0x67452301;
|
||||
+ Context->State[1] = 0xEFCDAB89;
|
||||
+ Context->State[2] = 0x98BADCFE;
|
||||
+ Context->State[3] = 0x10325476;
|
||||
+ Context->State[4] = 0xC3D2E1F0;
|
||||
+ Context->Count[0] =
|
||||
+ Context->Count[1] = 0;
|
||||
+}
|
||||
+
|
||||
+/******************************************************************************
|
||||
+ * A_SHAUpdate (ntdll.@)
|
||||
+ *
|
||||
+ * Update a SHA context with a hashed data from supplied buffer.
|
||||
+ *
|
||||
+ * PARAMS
|
||||
+ * Context [O] SHA context
|
||||
+ * Buffer [I] hashed data
|
||||
+ * BufferSize [I] hashed data size
|
||||
+ *
|
||||
+ * RETURNS
|
||||
+ * Nothing
|
||||
+ */
|
||||
+void A_SHAUpdate(SHA_CTX *Context, const unsigned char *Buffer, UINT BufferSize)
|
||||
+{
|
||||
+ ULONG BufferContentSize;
|
||||
+
|
||||
+ BufferContentSize = Context->Count[1] & 63;
|
||||
+ Context->Count[1] += BufferSize;
|
||||
+ if (Context->Count[1] < BufferSize)
|
||||
+ Context->Count[0]++;
|
||||
+ Context->Count[0] += (BufferSize >> 29);
|
||||
+
|
||||
+ if (BufferContentSize + BufferSize < 64)
|
||||
+ {
|
||||
+ RtlCopyMemory(&Context->Buffer[BufferContentSize], Buffer,
|
||||
+ BufferSize);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ while (BufferContentSize + BufferSize >= 64)
|
||||
+ {
|
||||
+ RtlCopyMemory(Context->Buffer + BufferContentSize, Buffer,
|
||||
+ 64 - BufferContentSize);
|
||||
+ Buffer += 64 - BufferContentSize;
|
||||
+ BufferSize -= 64 - BufferContentSize;
|
||||
+ SHA1Transform(Context->State, Context->Buffer);
|
||||
+ BufferContentSize = 0;
|
||||
+ }
|
||||
+ RtlCopyMemory(Context->Buffer + BufferContentSize, Buffer, BufferSize);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/******************************************************************************
|
||||
+ * A_SHAFinal (ntdll.@)
|
||||
+ *
|
||||
+ * Finalize SHA context and return the resulting hash.
|
||||
+ *
|
||||
+ * PARAMS
|
||||
+ * Context [I/O] SHA context
|
||||
+ * Result [O] resulting hash
|
||||
+ *
|
||||
+ * RETURNS
|
||||
+ * Nothing
|
||||
+ */
|
||||
+void A_SHAFinal(SHA_CTX *Context, PULONG Result)
|
||||
+{
|
||||
+ INT Pad, Index;
|
||||
+ UCHAR Buffer[72];
|
||||
+ ULONG *Count;
|
||||
+ ULONG BufferContentSize, LengthHi, LengthLo;
|
||||
+
|
||||
+ BufferContentSize = Context->Count[1] & 63;
|
||||
+ if (BufferContentSize >= 56)
|
||||
+ Pad = 56 + 64 - BufferContentSize;
|
||||
+ else
|
||||
+ Pad = 56 - BufferContentSize;
|
||||
+
|
||||
+ LengthHi = (Context->Count[0] << 3) | (Context->Count[1] >> (32 - 3));
|
||||
+ LengthLo = (Context->Count[1] << 3);
|
||||
+
|
||||
+ RtlZeroMemory(Buffer + 1, Pad - 1);
|
||||
+ Buffer[0] = 0x80;
|
||||
+ Count = (ULONG*)(Buffer + Pad);
|
||||
+ Count[0] = DWORD2BE(LengthHi);
|
||||
+ Count[1] = DWORD2BE(LengthLo);
|
||||
+ A_SHAUpdate(Context, Buffer, Pad + 8);
|
||||
+
|
||||
+ for (Index = 0; Index < 5; Index++)
|
||||
+ Result[Index] = DWORD2BE(Context->State[Index]);
|
||||
+
|
||||
+ A_SHAInit(Context);
|
||||
+}
|
||||
diff --git a/tools/widl/hash.h b/tools/widl/hash.h
|
||||
index 3c2fd2914bf..208b193ac87 100644
|
||||
--- a/tools/widl/hash.h
|
||||
+++ b/tools/widl/hash.h
|
||||
@@ -22,6 +22,20 @@
|
||||
#ifndef __WIDL_HASH_H
|
||||
#define __WIDL_HASH_H
|
||||
|
||||
+#include "windef.h"
|
||||
+
|
||||
extern unsigned int lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr);
|
||||
|
||||
+typedef struct
|
||||
+{
|
||||
+ ULONG Unknown[6];
|
||||
+ ULONG State[5];
|
||||
+ ULONG Count[2];
|
||||
+ UCHAR Buffer[64];
|
||||
+} SHA_CTX;
|
||||
+
|
||||
+VOID A_SHAInit(SHA_CTX *ctx);
|
||||
+VOID A_SHAUpdate(SHA_CTX *ctx, const UCHAR *buffer, UINT size);
|
||||
+VOID A_SHAFinal(SHA_CTX *ctx, PULONG result);
|
||||
+
|
||||
#endif
|
||||
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
|
||||
index b3718b5dc6d..2d060363d8e 100644
|
||||
--- a/tools/widl/typetree.c
|
||||
+++ b/tools/widl/typetree.c
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "parser.h"
|
||||
#include "typetree.h"
|
||||
#include "header.h"
|
||||
+#include "hash.h"
|
||||
|
||||
type_t *duptype(type_t *t, int dupname)
|
||||
{
|
||||
@@ -683,6 +684,57 @@ static void compute_delegate_iface_name(type_t *delegate)
|
||||
delegate->details.delegate.iface->name = name;
|
||||
}
|
||||
|
||||
+static void compute_interface_signature_uuid(type_t *iface)
|
||||
+{
|
||||
+ static unsigned char const wrt_pinterface_namespace[] = {0x11,0xf4,0x7a,0xd5,0x7b,0x73,0x42,0xc0,0xab,0xae,0x87,0x8b,0x1e,0x16,0xad,0xee};
|
||||
+ static const int version = 5;
|
||||
+ unsigned char hash[20];
|
||||
+ SHA_CTX sha_ctx;
|
||||
+ attr_t *attr;
|
||||
+ GUID *uuid;
|
||||
+
|
||||
+ if (!iface->attrs)
|
||||
+ {
|
||||
+ iface->attrs = xmalloc( sizeof(*iface->attrs) );
|
||||
+ list_init( iface->attrs );
|
||||
+ }
|
||||
+
|
||||
+ LIST_FOR_EACH_ENTRY(attr, iface->attrs, attr_t, entry)
|
||||
+ if (attr->type == ATTR_UUID) break;
|
||||
+
|
||||
+ if (&attr->entry == iface->attrs)
|
||||
+ {
|
||||
+ attr = xmalloc( sizeof(*attr) );
|
||||
+ attr->type = ATTR_UUID;
|
||||
+ attr->u.pval = xmalloc( sizeof(GUID) );
|
||||
+ list_add_tail( iface->attrs, &attr->entry );
|
||||
+ }
|
||||
+
|
||||
+ A_SHAInit(&sha_ctx);
|
||||
+ A_SHAUpdate(&sha_ctx, wrt_pinterface_namespace, sizeof(wrt_pinterface_namespace));
|
||||
+ A_SHAUpdate(&sha_ctx, (const UCHAR *)iface->signature, strlen(iface->signature));
|
||||
+ A_SHAFinal(&sha_ctx, (ULONG *)hash);
|
||||
+
|
||||
+ /* https://tools.ietf.org/html/rfc4122:
|
||||
+
|
||||
+ * Set the four most significant bits (bits 12 through 15) of the
|
||||
+ time_hi_and_version field to the appropriate 4-bit version number
|
||||
+ from Section 4.1.3.
|
||||
+
|
||||
+ * Set the two most significant bits (bits 6 and 7) of the
|
||||
+ clock_seq_hi_and_reserved to zero and one, respectively.
|
||||
+ */
|
||||
+
|
||||
+ hash[6] = ((hash[6] & 0x0f) | (version << 4));
|
||||
+ hash[8] = ((hash[8] & 0x3f) | 0x80);
|
||||
+
|
||||
+ uuid = attr->u.pval;
|
||||
+ uuid->Data1 = ((DWORD)hash[0] << 24)|((DWORD)hash[1] << 16)|((DWORD)hash[2] << 8)|(DWORD)hash[3];
|
||||
+ uuid->Data2 = ((WORD)hash[4] << 8)|(WORD)hash[5];
|
||||
+ uuid->Data3 = ((WORD)hash[6] << 8)|(WORD)hash[7];
|
||||
+ memcpy(&uuid->Data4, hash + 8, sizeof(*uuid) - offsetof(GUID, Data4));
|
||||
+}
|
||||
+
|
||||
static type_t *replace_type_parameters_in_type(type_t *type, type_list_t *orig, type_list_t *repl);
|
||||
|
||||
static type_list_t *replace_type_parameters_in_type_list(type_list_t *type_list, type_list_t *orig, type_list_t *repl)
|
||||
@@ -913,6 +965,7 @@ type_t *type_parameterized_type_specialize_define(type_t *type, type_list_t *par
|
||||
iface->signature = format_parameterized_type_signature(type, params);
|
||||
iface->defined = TRUE;
|
||||
}
|
||||
+ compute_interface_signature_uuid(iface);
|
||||
compute_method_indexes(iface);
|
||||
return iface;
|
||||
}
|
||||
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
|
||||
index b4257fe615f..46a223d50e3 100644
|
||||
--- a/tools/widl/typetree.h
|
||||
+++ b/tools/widl/typetree.h
|
||||
@@ -84,7 +84,7 @@ static inline const GUID *type_get_uuid(const type_t *type)
|
||||
{
|
||||
static const GUID empty;
|
||||
attr_t *attr;
|
||||
- LIST_FOR_EACH_ENTRY(attr, type->attrs, attr_t, entry)
|
||||
+ if (type->attrs) LIST_FOR_EACH_ENTRY(attr, type->attrs, attr_t, entry)
|
||||
if (attr->type == ATTR_UUID) return attr->u.pval;
|
||||
error("type '%s' uuid not found\n", type->name);
|
||||
return ∅
|
||||
--
|
||||
2.28.0
|
||||
|
@ -0,0 +1,206 @@
|
||||
From d517b9b5856840f19b3a805b812153d5c0f6d0d9 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Wed, 26 Aug 2020 22:46:02 +0200
|
||||
Subject: [PATCH 27/28] widl: Generate helper macros for WinRT implementation.
|
||||
|
||||
This generates additional macros to help keeping implementation simple,
|
||||
guarded with WIDL_USING ifdefs, like this:
|
||||
|
||||
#ifdef WIDL_USING_WINDOWS_FOO_IFOO
|
||||
#define IFooVtbl __x_ABI_CWindows_CFoo_CIFooVtbl
|
||||
#define IFoo __x_ABI_CWindows_CFoo_CIFoo
|
||||
#define IFoo_DoFoo __x_ABI_CWindows_CFoo_CIFoo_DoFoo
|
||||
#endif /* WIDL_USING_WINDOWS_FOO_IFOO */
|
||||
|
||||
Implementation files can define the desired WIDL_USING preprocessor
|
||||
macros before including the header, and then implement or use the
|
||||
interface methods with the simple non-prefixed names instead.
|
||||
---
|
||||
tools/widl/header.c | 71 ++++++++++++++++++++++++++++++++++++++++--
|
||||
tools/widl/typetree.c | 24 ++++++++++++++
|
||||
tools/widl/widltypes.h | 1 +
|
||||
3 files changed, 94 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/tools/widl/header.c b/tools/widl/header.c
|
||||
index 64faf89c36a..4aa6844ee99 100644
|
||||
--- a/tools/widl/header.c
|
||||
+++ b/tools/widl/header.c
|
||||
@@ -50,6 +50,8 @@ 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 write_widl_using_macros(FILE *header, type_t *iface);
|
||||
+
|
||||
static void indent(FILE *h, int delta)
|
||||
{
|
||||
int c;
|
||||
@@ -616,10 +618,11 @@ static void write_type_definition(FILE *f, type_t *t, int declonly)
|
||||
t->written = save_written;
|
||||
write_namespace_end(f, t->namespace);
|
||||
fprintf(f, "extern \"C\" {\n");
|
||||
- fprintf(f, "#else\n");
|
||||
+ fprintf(f, "#else /* __cplusplus */\n");
|
||||
write_type_left(f, &ds, NAME_C, declonly, TRUE);
|
||||
fprintf(f, ";\n");
|
||||
- fprintf(f, "#endif\n\n");
|
||||
+ if (winrt_mode) write_widl_using_macros(f, t);
|
||||
+ fprintf(f, "#endif /* __cplusplus */\n\n");
|
||||
}
|
||||
if (contract) write_apicontract_guard_end(f, contract);
|
||||
}
|
||||
@@ -1643,6 +1646,69 @@ static void write_com_interface_start(FILE *header, const type_t *iface)
|
||||
fprintf(header,"#define __%s_%sINTERFACE_DEFINED__\n\n", iface->c_name, dispinterface ? "DISP" : "");
|
||||
}
|
||||
|
||||
+static char *get_winrt_guard_macro(type_t *iface)
|
||||
+{
|
||||
+ unsigned int len;
|
||||
+ char *macro, *tmp = (char *)iface->c_name;
|
||||
+ int i;
|
||||
+
|
||||
+ if (!strncmp(tmp, "__x", 3)) tmp += 3;
|
||||
+ if (!strncmp(tmp, "_ABI", 4)) tmp += 4;
|
||||
+ macro = xstrdup(tmp);
|
||||
+
|
||||
+ len = strlen(macro) + 1;
|
||||
+ for (tmp = strstr(macro, "__F"); tmp; tmp = strstr(tmp, "__F"))
|
||||
+ memmove(tmp + 1, tmp + 3, len - (tmp - macro) - 3);
|
||||
+ for (tmp = strstr(macro, "__C"); tmp; tmp = strstr(tmp, "__C"))
|
||||
+ memmove(tmp + 1, tmp + 3, len - (tmp - macro) - 3);
|
||||
+ for (tmp = strstr(macro, "_C"); tmp; tmp = strstr(tmp, "_C"))
|
||||
+ memmove(tmp + 1, tmp + 2, len - (tmp - macro) - 2);
|
||||
+
|
||||
+ for (i = strlen(macro); i > 0; --i) macro[i - 1] = toupper(macro[i - 1]);
|
||||
+
|
||||
+ return macro;
|
||||
+}
|
||||
+
|
||||
+static void write_widl_using_method_macros(FILE *header, const type_t *iface, const type_t *top_iface)
|
||||
+{
|
||||
+ const statement_t *stmt;
|
||||
+ const char *name = top_iface->short_name ? top_iface->short_name : top_iface->name;
|
||||
+
|
||||
+ if (type_iface_get_inherit(iface)) write_widl_using_method_macros(header, type_iface_get_inherit(iface), top_iface);
|
||||
+
|
||||
+ STATEMENTS_FOR_EACH_FUNC(stmt, type_iface_get_stmts(iface))
|
||||
+ {
|
||||
+ const var_t *func = stmt->u.var;
|
||||
+ const char *func_name = get_name(func);
|
||||
+
|
||||
+ if (is_override_method(iface, top_iface, func)) continue;
|
||||
+
|
||||
+ if (!is_callas(func->attrs))
|
||||
+ fprintf(header, "#define %s_%s %s_%s\n", name, func_name, top_iface->c_name, func_name);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void write_widl_using_macros(FILE *header, type_t *iface)
|
||||
+{
|
||||
+ const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID);
|
||||
+ const char *name = iface->short_name ? iface->short_name : iface->name;
|
||||
+ char *macro;
|
||||
+
|
||||
+ if (!strcmp(iface->name, iface->c_name)) return;
|
||||
+
|
||||
+ macro = get_winrt_guard_macro(iface);
|
||||
+ fprintf(header, "#ifdef WIDL_USING%s\n", macro);
|
||||
+
|
||||
+ if (uuid) fprintf(header, "#define IID_%s IID_%s\n", name, iface->c_name);
|
||||
+ if (iface->type_type == TYPE_INTERFACE) fprintf(header, "#define %sVtbl %sVtbl\n", name, iface->c_name);
|
||||
+ fprintf(header, "#define %s %s\n", name, iface->c_name);
|
||||
+
|
||||
+ if (iface->type_type == TYPE_INTERFACE) write_widl_using_method_macros(header, iface, iface);
|
||||
+
|
||||
+ fprintf(header, "#endif /* WIDL_USING_%s */\n", macro);
|
||||
+ free(macro);
|
||||
+}
|
||||
+
|
||||
static void write_com_interface_end(FILE *header, type_t *iface)
|
||||
{
|
||||
int dispinterface = is_attr(iface->attrs, ATTR_DISPINTERFACE);
|
||||
@@ -1715,6 +1781,7 @@ static void write_com_interface_end(FILE *header, type_t *iface)
|
||||
fprintf(header, "#else\n");
|
||||
write_inline_wrappers(header, type, type, iface->c_name);
|
||||
fprintf(header, "#endif\n");
|
||||
+ if (winrt_mode) write_widl_using_macros(header, iface);
|
||||
fprintf(header, "#endif\n");
|
||||
fprintf(header, "\n");
|
||||
fprintf(header, "#endif\n");
|
||||
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
|
||||
index 2d060363d8e..f62d0eb51dc 100644
|
||||
--- a/tools/widl/typetree.c
|
||||
+++ b/tools/widl/typetree.c
|
||||
@@ -51,6 +51,7 @@ type_t *make_type(enum type_type type)
|
||||
t->attrs = NULL;
|
||||
t->c_name = NULL;
|
||||
t->signature = NULL;
|
||||
+ t->short_name = NULL;
|
||||
memset(&t->details, 0, sizeof(t->details));
|
||||
t->typestring_offset = 0;
|
||||
t->ptrdesc = 0;
|
||||
@@ -281,6 +282,19 @@ static int format_parameterized_type_signature_buffer(char *buf, size_t len, typ
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int format_parameterized_type_short_name_buffer(char *buf, size_t len, type_t *type, type_list_t *params, const char *prefix)
|
||||
+{
|
||||
+ type_list_t *entry;
|
||||
+ int ret = 0;
|
||||
+ append_buf(snprintf, "%s%s", prefix, type->name);
|
||||
+ for (entry = params; entry; entry = entry->next)
|
||||
+ {
|
||||
+ for (type = entry->type; type->type_type == TYPE_POINTER; type = type_pointer_get_ref_type(type)) {}
|
||||
+ append_buf(snprintf, "_%s", type->name);
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
#undef append_buf
|
||||
|
||||
char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix, const char *abi_prefix)
|
||||
@@ -340,6 +354,14 @@ static char *format_parameterized_type_signature(type_t *type, type_list_t *para
|
||||
return buf;
|
||||
}
|
||||
|
||||
+static char *format_parameterized_type_short_name(type_t *type, type_list_t *params, const char *prefix)
|
||||
+{
|
||||
+ int len = format_parameterized_type_short_name_buffer(NULL, 0, type, params, prefix);
|
||||
+ char *buf = xmalloc(len + 1);
|
||||
+ format_parameterized_type_short_name_buffer(buf, len + 1, type, params, prefix);
|
||||
+ return buf;
|
||||
+}
|
||||
+
|
||||
type_t *type_new_function(var_list_t *args)
|
||||
{
|
||||
var_t *arg;
|
||||
@@ -929,6 +951,7 @@ type_t *type_parameterized_type_specialize_declare(type_t *type, type_list_t *pa
|
||||
new_type->name = format_parameterized_type_name(type, params);
|
||||
reg_type(new_type, new_type->name, new_type->namespace, 0);
|
||||
new_type->c_name = format_parameterized_type_c_name(type, params, "");
|
||||
+ new_type->short_name = format_parameterized_type_short_name(type, params, "");
|
||||
|
||||
if (new_type->type_type == TYPE_DELEGATE)
|
||||
{
|
||||
@@ -936,6 +959,7 @@ type_t *type_parameterized_type_specialize_declare(type_t *type, type_list_t *pa
|
||||
compute_delegate_iface_name(new_type);
|
||||
new_type->details.delegate.iface->namespace = new_type->namespace;
|
||||
new_type->details.delegate.iface->c_name = format_parameterized_type_c_name(type, params, "I");
|
||||
+ new_type->details.delegate.iface->short_name = format_parameterized_type_short_name(type, params, "I");
|
||||
}
|
||||
|
||||
return new_type;
|
||||
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
|
||||
index 58828a4f8e2..d80e9c04d51 100644
|
||||
--- a/tools/widl/widltypes.h
|
||||
+++ b/tools/widl/widltypes.h
|
||||
@@ -497,6 +497,7 @@ struct _type_t {
|
||||
} details;
|
||||
const char *c_name;
|
||||
const char *signature;
|
||||
+ const char *short_name;
|
||||
unsigned int typestring_offset;
|
||||
unsigned int ptrdesc; /* used for complex structs */
|
||||
int typelib_idx;
|
||||
--
|
||||
2.28.0
|
||||
|
@ -0,0 +1,29 @@
|
||||
From 5609ada48132040965e84cdbdd95cea9492a471d Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
||||
Date: Fri, 25 Sep 2020 17:05:17 +0200
|
||||
Subject: [PATCH 28/28] include: Add IVectorView<HSTRING> declaration to
|
||||
windows.foundation.idl.
|
||||
|
||||
---
|
||||
include/windows.foundation.idl | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/include/windows.foundation.idl b/include/windows.foundation.idl
|
||||
index 9583fa5bcc8..9b9b40897be 100644
|
||||
--- a/include/windows.foundation.idl
|
||||
+++ b/include/windows.foundation.idl
|
||||
@@ -157,3 +157,11 @@ namespace Windows {
|
||||
#endif
|
||||
}
|
||||
}
|
||||
+
|
||||
+namespace Windows {
|
||||
+ namespace Foundation {
|
||||
+ declare {
|
||||
+ interface Windows.Foundation.Collections.IVectorView<HSTRING>;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
2.28.0
|
||||
|
1
patches/widl-winrt-support/definition
Normal file
1
patches/widl-winrt-support/definition
Normal file
@ -0,0 +1 @@
|
||||
Fixes: [68403] widl - Support WinRT idls
|
@ -1,2 +1,3 @@
|
||||
Fixes: [49740] windows.globalization: New DLL
|
||||
Depends: windows.media.speech.dll
|
||||
Disabled: True
|
||||
|
@ -1,2 +1,3 @@
|
||||
Fixes: [46534] windows.networking.connectivity: New DLL
|
||||
Depends: windows.globalization-dll
|
||||
Disabled: True
|
||||
|
Loading…
x
Reference in New Issue
Block a user