summaryrefslogtreecommitdiff
path: root/src/md/winmd/inc/adapter.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/md/winmd/inc/adapter.h')
-rw-r--r--src/md/winmd/inc/adapter.h951
1 files changed, 951 insertions, 0 deletions
diff --git a/src/md/winmd/inc/adapter.h b/src/md/winmd/inc/adapter.h
new file mode 100644
index 0000000000..e69b620938
--- /dev/null
+++ b/src/md/winmd/inc/adapter.h
@@ -0,0 +1,951 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+#ifndef __MDWinMDAdapter__h__
+#define __MDWinMDAdapter__h__
+
+#include "memotable.h"
+#include "../../inc/winmdinterfaces.h"
+#include "thekey.h"
+#include "ecmakey.h"
+
+// Instantiation of template in holder.h
+template void DoNothing<ULONG>(ULONG);
+
+class SigBuilder;
+class SigParser;
+
+typedef const BYTE * PCBYTE;
+static const BYTE s_pbContractPublicKeyToken[] = {0xB0,0x3F,0x5F,0x7F,0x11,0xD5,0x0A,0x3A};
+static const BYTE s_pbContractPublicKey[] = {0x00, 0x24, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x06, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x07, 0xD1, 0xFA, 0x57, 0xC4, 0xAE, 0xD9, 0xF0, 0xA3, 0x2E, 0x84, 0xAA, 0x0F, 0xAE, 0xFD, 0x0D, 0xE9, 0xE8, 0xFD, 0x6A, 0xEC, 0x8F, 0x87, 0xFB, 0x03, 0x76, 0x6C, 0x83, 0x4C, 0x99, 0x92, 0x1E, 0xB2, 0x3B, 0xE7, 0x9A, 0xD9, 0xD5, 0xDC, 0xC1, 0xDD, 0x9A, 0xD2, 0x36, 0x13, 0x21, 0x02, 0x90, 0x0B, 0x72, 0x3C, 0xF9, 0x80, 0x95, 0x7F, 0xC4, 0xE1, 0x77, 0x10, 0x8F, 0xC6, 0x07, 0x77, 0x4F, 0x29, 0xE8, 0x32, 0x0E, 0x92, 0xEA, 0x05, 0xEC, 0xE4, 0xE8, 0x21, 0xC0, 0xA5, 0xEF, 0xE8, 0xF1, 0x64, 0x5C, 0x4C, 0x0C, 0x93, 0xC1, 0xAB, 0x99, 0x28, 0x5D, 0x62, 0x2C, 0xAA, 0x65, 0x2C, 0x1D, 0xFA, 0xD6, 0x3D, 0x74, 0x5D, 0x6F, 0x2D, 0xE5, 0xF1, 0x7E, 0x5E, 0xAF, 0x0F, 0xC4, 0x96, 0x3D, 0x26, 0x1C, 0x8A, 0x12, 0x43, 0x65, 0x18, 0x20, 0x6D, 0xC0, 0x93, 0x34, 0x4D, 0x5A, 0xD2, 0x93};
+
+class DECLSPEC_UUID("996AA908-5606-476d-9985-48607B2DA076") IWinMDImport : public IUnknown
+{
+public :
+ STDMETHOD(IsScenarioWinMDExp)(BOOL *pbResult) = 0;
+ STDMETHOD(IsRuntimeClassImplementation)(mdTypeDef tkTypeDef, BOOL *pbResult) = 0;
+};
+
+//========================================================================================
+// Only IWinMDImport and IWinMDImportInternalRO QI successfully for this guid - for cases where we need to
+// tell the difference between the classic MD importers and the WinMD wrappers.
+//========================================================================================
+// {996AA908-5606-476d-9985-48607B2DA076}
+extern const IID DECLSPEC_SELECTANY IID_IWinMDImport = __uuidof(IWinMDImport);
+
+//========================================================================================
+// Popup an assert box if COMPLUS_MD_WinMD_AssertOnIllegalUsage=1
+//========================================================================================
+#if defined(_DEBUG) && !defined(DACCESS_COMPILE)
+#define WINMD_COMPAT_ASSERT(assertMsg) if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MD_WinMD_AssertOnIllegalUsage)) DbgAssertDialog(__FILE__, __LINE__, assertMsg)
+#else
+#define WINMD_COMPAT_ASSERT(assertMsg)
+#endif
+
+
+//========================================================================================
+// class WinMDAdapter
+//
+// This object performs typeref redirection and any other chores involved in
+// masquerading WinMD files as .NET assemblies.
+//
+// WinMDAdapters act as internal helper objects to WinMDImport and WinMDInternalImportRO
+// and factor out as much common code as is practical given that these two importers
+// expose wildly different interfaces.
+//
+// The main input to this object is a standard .NET metadata importer (the "raw" importer.) Since
+// the two importers have no common public interface, we use the internal (non-COM) IMetaModelCommon
+// interface that both imports have internally and expose through the private IMDCommon
+// interface.
+//
+// Methods on this class follow the IMDInternalImport philosophy (i.e. validation? what validation?,
+// return strings as direct UTF8 pointers to internal strings allocated for the lifetime
+// of WinMDAdapter.) When used by the public IMetaDataImport adapter, it's important that the caller
+// validate parameters before invoking WinMDAdapter.
+//========================================================================================
+class WinMDAdapter
+{
+public:
+#define DEFINE_PROJECTED_TYPE(szWinRTNS, szWinRTName, szClrNS, szClrName, ClrAsmIdx, nContractAsmIdx, WinRTIndex, ClrIndex, TypeKind) \
+ RedirectedTypeIndex_ ## WinRTIndex, \
+ RedirectedTypeIndex_ ## ClrIndex = RedirectedTypeIndex_ ## WinRTIndex, \
+
+ // Indexes of well-known redirected types into array code:g_rgRedirectedTypes
+ enum RedirectedTypeIndex
+ {
+#include "WinRTProjectedTypes.h"
+ RedirectedTypeIndex_Count,
+ RedirectedTypeIndex_Invalid = -1,
+ };
+#undef DEFINE_PROJECTED_TYPE
+
+ enum FrameworkAssemblyIndex
+ {
+ FrameworkAssembly_Mscorlib,
+ FrameworkAssembly_SystemObjectModel,
+ FrameworkAssembly_SystemRuntime,
+ FrameworkAssembly_SystemRuntimeWindowsRuntime,
+ FrameworkAssembly_SystemRuntimeWindowsRuntimeUIXaml,
+ FrameworkAssembly_SystemNumericsVectors,
+
+ FrameworkAssembly_Count,
+ };
+
+ // If new contract assemblies need to be added, they must be appended to the end of the following list.
+ // Also, don't remove or change any existing assemblies in this list.
+ // Not following these rules will break existing MDIL images generated in the Store.
+ enum ContractAssemblyIndex
+ {
+ ContractAssembly_SystemRuntime,
+ ContractAssembly_SystemRuntimeInteropServicesWindowsRuntime,
+ ContractAssembly_SystemObjectModel,
+ ContractAssembly_SystemRuntimeWindowsRuntime,
+ ContractAssembly_SystemRuntimeWindowsRuntimeUIXaml,
+ ContractAssembly_SystemNumericsVectors, // GetExtraAssemblyRefCount assumes SystemNumericsVectors is the last assembly.
+ // If you add an assembly you must update GetActualExtraAssemblyRefCount.
+
+ ContractAssembly_Count,
+ };
+
+
+ enum WinMDTypeKind
+ {
+ WinMDTypeKind_Attribute,
+ WinMDTypeKind_Enum,
+ WinMDTypeKind_Delegate,
+ WinMDTypeKind_Interface,
+ WinMDTypeKind_PDelegate,
+ WinMDTypeKind_PInterface,
+ WinMDTypeKind_Struct,
+ WinMDTypeKind_Runtimeclass,
+ };
+
+ int GetExtraAssemblyRefCount();
+
+ // Factory and destructor
+ static HRESULT Create(IMDCommon *pRawMDCommon, /*[out]*/ WinMDAdapter **ppAdapter);
+ ~WinMDAdapter();
+
+ // Map a well-known WinRT typename to CLR typename
+ static BOOL ConvertWellKnownTypeNameFromWinRTToClr(LPCSTR *pszNamespace, LPCSTR *pszName);
+
+ // Map a well-known WinRT full typename to CLR full typename
+ static BOOL ConvertWellKnownFullTypeNameFromWinRTToClr(LPCWSTR *pszFullName, RedirectedTypeIndex *pIndex);
+
+ // Map a well-known CLR typename to WinRT typename
+ static BOOL ConvertWellKnownTypeNameFromClrToWinRT(LPCSTR *pszFullName);
+
+ // Map a well-known CLR typename to WinRT typename
+ static BOOL WinMDAdapter::ConvertWellKnownTypeNameFromClrToWinRT(LPCSTR *pszNamespace, LPCSTR *pszName);
+
+ // Returns names of redirected type 'index'.
+ static void GetRedirectedTypeInfo(
+ RedirectedTypeIndex index,
+ LPCSTR * pszClrNamespace,
+ LPCSTR * pszClrName,
+ LPCSTR * pszFullWinRTName,
+ FrameworkAssemblyIndex * pFrameworkAssemblyIdx,
+ ContractAssemblyIndex * pContractAssemblyIdx,
+ WinMDTypeKind * pWinMDTypeKind);
+
+ // Returns name of redirected type 'index'.
+ static LPCWSTR GetRedirectedTypeFullWinRTName(RedirectedTypeIndex index);
+ static LPCSTR GetRedirectedTypeFullCLRName(RedirectedTypeIndex index);
+
+ // Returns renamed typedefs
+ HRESULT GetTypeDefProps(
+ mdTypeDef typeDef, // [IN] given typedef
+ LPCUTF8 *pszNameSpace, // [OUT] return typedef namespace
+ LPCUTF8 *pszName, // [OUT] return typedef name
+ DWORD *pdwFlags, // [OUT] return typedef flags
+ mdToken *ptkExtends // [OUT] Put base class TypeDef/TypeRef here.
+ );
+
+ // Find TypeDef by name
+ HRESULT FindTypeDef(
+ LPCSTR szTypeDefNamespace, // [IN] Namespace for the TypeDef.
+ LPCSTR szTypeDefName, // [IN] Name of the TypeDef.
+ mdToken tkEnclosingClass, // [IN] TypeDef/TypeRef of enclosing class.
+ mdTypeDef * ptkTypeDef // [OUT] return typedef
+ );
+
+ // Returns redirected typerefs
+ HRESULT GetTypeRefProps(
+ mdTypeRef typeref, // [IN] given typeref
+ LPCSTR *psznamespace, // [OUT] return typeref namespace
+ LPCSTR *pszname, // [OUT] return typeref name
+ mdToken *ptkResolutionScope // [OUT] return typeref resolutionscope
+ );
+
+ // Find TypeRef by name
+ HRESULT FindTypeRef(
+ LPCSTR szNamespace, // [IN] Namespace for the TypeRef (NULL for standalone names)
+ LPCSTR szName, // [IN] Name of the TypeRef.
+ mdToken tkResolutionScope, // [IN] Resolution Scope fo the TypeRef.
+ mdTypeRef *ptk // [OUT] TypeRef token returned.
+ );
+
+ // Modify an ExportedType name
+ HRESULT ModifyExportedTypeName(
+ mdExportedType tkExportedType, // [IN] exportedType token
+ LPCSTR *pszNamespace, // [IN,OUT,OPTIONAL] namespace to modify
+ LPCSTR *pszName // [IN,OUT,OPTIONAL] name to modify
+ );
+
+ // Find ExportedType by name
+ HRESULT FindExportedType(
+ LPCUTF8 szNamespace, // [IN] expected namespace
+ LPCUTF8 szName, // [IN] expected name
+ mdToken tkEnclosingType, // [IN] expected tkEnclosingType
+ mdExportedType *ptkExportedType // [OUT] ExportedType token returned.
+ );
+
+ // Returns rewritten metadata version string
+ HRESULT GetVersionString(
+ LPCSTR *pszVersion // [OUT] return metadata version string
+ )
+ {
+ _ASSERTE(pszVersion != NULL);
+ *pszVersion = m_pRedirectedVersionString;
+ return S_OK;
+ }
+
+ void ModifyAssemblyRefProps(
+ mdAssemblyRef mdar,
+ const void **ppbPublicKeyOrToken,
+ ULONG *pcbPublicKeyOrToken,
+ LPCSTR *pszName,
+ USHORT *pusMajorVersion,
+ USHORT *pusMinorVersion,
+ USHORT *pusBuildNumber,
+ USHORT *pusRevisionNumber,
+ const void **ppbHashValue,
+ ULONG *pcbHashValue)
+ {
+ _ASSERTE(TypeFromToken(mdar) == mdtAssemblyRef);
+
+ // The version of the mscorlib should be 4.0.0.0
+ if (m_assemblyRefMscorlib == mdar)
+ {
+ if (pusMajorVersion != nullptr)
+ *pusMajorVersion = VER_ASSEMBLYMAJORVERSION;
+ if (pusMinorVersion != nullptr)
+ *pusMinorVersion = VER_ASSEMBLYMINORVERSION;
+ if (pusBuildNumber != nullptr)
+ *pusBuildNumber = VER_ASSEMBLYBUILD;
+ if (pusRevisionNumber != nullptr)
+ *pusRevisionNumber = VER_ASSEMBLYBUILD_QFE;
+
+#ifdef FEATURE_CORECLR
+ // Under CoreCLR, we replace the ECMA key in the mscorlib assembly ref with the CoreCLR platform public key token
+ if (ppbPublicKeyOrToken != nullptr)
+ {
+ *ppbPublicKeyOrToken = g_rbTheSilverlightPlatformKeyToken;
+ *pcbPublicKeyOrToken = _countof(g_rbTheSilverlightPlatformKeyToken);
+ }
+#endif
+ }
+ else if (RidFromToken(mdar) > m_rawAssemblyRefCount)
+ {
+ // This is one of the assemblies that we inject
+ UINT index = RidFromToken(mdar) - m_rawAssemblyRefCount - 1;
+
+ if (ppbPublicKeyOrToken != nullptr)
+ {
+ if (index != ContractAssemblyIndex::ContractAssembly_SystemRuntimeWindowsRuntime &&
+ index != ContractAssemblyIndex::ContractAssembly_SystemRuntimeWindowsRuntimeUIXaml)
+ {
+ // The assembly ref is a contract/facade assembly. System.Runtime.WindowsRuntime and
+ // System.Runtime.WindowsRuntime.UI.Xaml are special cased because the contract and the implementation
+ // assembly share the same identity and use mscorlib's public key/token that ppbPublicKeyOrToken
+ // alredy contains since the raw GetAssemblyRefProps was called with mscorlib's token before this
+ // function was called.
+ if (*pcbPublicKeyOrToken == sizeof(s_pbContractPublicKeyToken))
+ *ppbPublicKeyOrToken = s_pbContractPublicKeyToken;
+ else if (*pcbPublicKeyOrToken == sizeof(s_pbContractPublicKey))
+ *ppbPublicKeyOrToken = s_pbContractPublicKey;
+ }
+#ifdef FEATURE_WINDOWSPHONE
+ // System.Runtime.WindowsRuntime uses the ECMA key on Windows Phone.
+ // The WinRT adapter's policy of using mscorlib's assembly references for all the additional
+ // assembly references doesn't work here since mscorlib uses the Silverlight Platform key.
+ else
+ {
+ if (*pcbPublicKeyOrToken == sizeof(g_rbNeutralPublicKeyToken))
+ *ppbPublicKeyOrToken = g_rbNeutralPublicKeyToken;
+ else if (*pcbPublicKeyOrToken == sizeof(g_rbNeutralPublicKey))
+ *ppbPublicKeyOrToken = g_rbNeutralPublicKey;
+ }
+#endif
+ }
+
+ if (pszName != nullptr)
+ *pszName = GetExtraAssemblyRefName(mdar);
+
+ if (pusMajorVersion != nullptr)
+ *pusMajorVersion = VER_ASSEMBLYMAJORVERSION;
+ if (pusMinorVersion != nullptr)
+ *pusMinorVersion = VER_ASSEMBLYMINORVERSION;
+ if (pusBuildNumber != nullptr)
+ *pusBuildNumber = VER_ASSEMBLYBUILD;
+ if (pusRevisionNumber != nullptr)
+ *pusRevisionNumber = VER_ASSEMBLYBUILD_QFE;
+
+ if (ppbHashValue)
+ *ppbHashValue = NULL;
+
+ if (pcbHashValue)
+ *pcbHashValue = 0;
+ }
+ }
+
+ // Modifes the FieldDefProps.
+ HRESULT ModifyFieldDefProps (mdFieldDef tkFielddDef, DWORD *pdwFlags);
+
+ // Modifies FieldProps
+ HRESULT ModifyFieldProps (mdToken tkField, mdToken tkParent, LPCSTR szFieldName, DWORD *pdwFlags);
+
+ // Modifies methodDef flags and RVA
+ HRESULT ModifyMethodProps(mdMethodDef tkMethodDef, /*[in, out]*/ DWORD *pdwAttr, /* [in,out] */ DWORD *pdwImplFlags, /* [in,out] */ ULONG *pulRVA, LPCSTR *pszName);
+
+ // Modifies member flags and RVA
+ HRESULT ModifyMemberProps(mdToken tkMember, /*[in, out]*/ DWORD *pdwAttr, /* [in,out] */ DWORD *pdwImplFlags, /* [in,out] */ ULONG *pulRVA, LPCSTR *pszNewName);
+
+ // Modifies CA's
+ HRESULT GetCustomAttributeByName( // S_OK or error.
+ mdToken tkObj, // [IN] Object with Custom Attribute.
+ LPCUTF8 szName, // [IN] Name of desired Custom Attribute.
+ mdCustomAttribute *ptkCA, // [OUT] Put custom attribute token here
+ const void **ppData, // [OUT] Put pointer to data here.
+ ULONG *pcbData); // [OUT] Put size of data here.
+
+ // Modify CA blobs
+ HRESULT GetCustomAttributeBlob(
+ mdCustomAttribute tkCA,
+ const void **ppData, // [OUT] Put pointer to data here.
+ ULONG *pcbData); // [OUT] Put size of data here.
+
+ // Gets the GUID used for COM interop purposes.
+ HRESULT GetItemGuid(mdToken tkObj, CLSID *pGuid);
+
+ // Gets filtered methodImpl list
+ HRESULT AddMethodImplsToEnum(mdTypeDef tkTypeDef, HENUMInternal *henum);
+
+ //-----------------------------------------------------------------------------------
+ // For each token, we cache the signature that the adapter reports to callers.
+ //-----------------------------------------------------------------------------------
+ struct SigData
+ {
+ ULONG cbSig; // Length of sig in bytes
+ BYTE data[1]; // Signature
+
+ static SigData* Create(ULONG cbSig, PCCOR_SIGNATURE pSig);
+ static void Destroy(SigData *pSigData);
+
+ // Sentinel value meaning we did not need to rewrite the signature; use the underlying importer's signature
+ static SigData* const NOREDIRECT;
+ };
+
+ // Gets a method/field/TypeSpec/MethodSpec signature, with appropriate WinMD changes.
+ HRESULT ReinterpretMethodSignature (ULONG cbOrigSigBlob, PCCOR_SIGNATURE pOrigSig, SigData **ppSigData);
+ HRESULT ReinterpretFieldSignature (ULONG cbOrigSigBlob, PCCOR_SIGNATURE pOrigSig, SigData **ppSigData);
+ HRESULT ReinterpretTypeSpecSignature (ULONG cbOrigSigBlob, PCCOR_SIGNATURE pOrigSig, SigData **ppSigData);
+ HRESULT ReinterpretMethodSpecSignature (ULONG cbOrigSigBlob, PCCOR_SIGNATURE pOrigSig, SigData **ppSigData);
+
+ template<mdToken TOKENTYPE>
+ HRESULT ReinterpretSignature(
+ ULONG cbOrigSigBlob, // [IN] count of bytes in original signature blob
+ PCCOR_SIGNATURE pOrigSig, // [IN] original signature
+ SigData **ppSigData // [OUT] new signature or SigData::NOREDIRECT
+ )
+ {
+ UNREACHABLE_MSG("You should create a specialized version of ReinterpretSignature for this token type");
+ }
+
+ // Explicit specializations of ReinterpretSignature for all supported token types
+ template<> // mdMethodDef
+ HRESULT ReinterpretSignature<mdtMethodDef>(ULONG cbOrigSigBlob, PCCOR_SIGNATURE pOrigSig, SigData **ppSigData)
+ {
+ return ReinterpretMethodSignature(cbOrigSigBlob, pOrigSig, ppSigData);
+ }
+
+ template<> // mdFieldDef
+ HRESULT ReinterpretSignature<mdtFieldDef>(ULONG cbOrigSigBlob, PCCOR_SIGNATURE pOrigSig, SigData **ppSigData)
+ {
+ return ReinterpretFieldSignature(cbOrigSigBlob, pOrigSig, ppSigData);
+ }
+
+ template<> // mdMemberRef
+ HRESULT ReinterpretSignature<mdtMemberRef>(ULONG cbOrigSigBlob, PCCOR_SIGNATURE pOrigSig, SigData **ppSigData)
+ {
+ if (cbOrigSigBlob == 0)
+ {
+ *ppSigData = SigData::NOREDIRECT;
+
+ return META_E_BAD_SIGNATURE;
+ }
+
+ // MemberRef references either a field or a method
+ return (*pOrigSig == IMAGE_CEE_CS_CALLCONV_FIELD) ?
+ ReinterpretFieldSignature(cbOrigSigBlob, pOrigSig, ppSigData) :
+ ReinterpretMethodSignature(cbOrigSigBlob, pOrigSig, ppSigData);
+ }
+
+ template<> // mdProperty
+ HRESULT ReinterpretSignature<mdtProperty>(ULONG cbOrigSigBlob, PCCOR_SIGNATURE pOrigSig, SigData **ppSigData)
+ {
+ // Per ECMA CLI spec, section 23.2.5 PropertySig is just an ordinary method (getter) signature
+ return ReinterpretMethodSignature(cbOrigSigBlob, pOrigSig, ppSigData);
+ }
+
+ template<> // mdTypeSpec
+ HRESULT ReinterpretSignature<mdtTypeSpec>(ULONG cbOrigSigBlob, PCCOR_SIGNATURE pOrigSig, SigData **ppSigData)
+ {
+ return ReinterpretTypeSpecSignature(cbOrigSigBlob, pOrigSig, ppSigData);
+ }
+
+ template<> // mdMethodSpec
+ HRESULT ReinterpretSignature<mdtMethodSpec>(ULONG cbOrigSigBlob, PCCOR_SIGNATURE pOrigSig, SigData **ppSigData)
+ {
+ return ReinterpretMethodSpecSignature(cbOrigSigBlob, pOrigSig, ppSigData);
+ }
+
+ // Note: This method will look in a cache for the reinterpreted signature, but does not add any values to
+ // the cache or do any work on failure. If we can't find it then it returns S_FALSE.
+ static HRESULT GetCachedSigForToken(
+ mdToken token, // [IN] given token
+ MemoTable<SigData*, SigData::Destroy> &memoTable, // [IN] the MemoTable to use
+ ULONG *pcbSigBlob, // [OUT] count of bytes in the signature blob
+ PCCOR_SIGNATURE *ppSig, // [OUT] new signature
+ BOOL *pfPassThrough // [OUT] did the cache say we don't need to reinterpret this sig?
+ );
+
+ static HRESULT InsertCachedSigForToken(
+ mdToken token, // [IN] given token
+ MemoTable<SigData*, SigData::Destroy> &memoTable, // [IN] the MemoTable to use
+ SigData **ppSigData // [IN, OUT] new signature or SigData::NOREDIRECT if the signature didn't need to be reparsed,
+ ); // will be updated with another (but identical) SigData* if this thread lost the race
+
+ template<typename T, mdToken TOKENTYPE>
+ HRESULT GetOriginalSigForToken(
+ T *pImport,
+ mdToken token, // [IN] Token.
+ PCCOR_SIGNATURE *ppvSig, // [OUT] return pointer to signature.
+ ULONG *pcbSig // [OUT] return size of signature.
+ )
+ {
+ UNREACHABLE_MSG("You should create a specialized version of GetOriginalSigForToken for this interface/token type");
+ }
+
+ template<mdToken TOKENTYPE>
+ MemoTable<SigData*, SigData::Destroy> &GetSignatureMemoTable()
+ {
+ UNREACHABLE_MSG("You should create a specialized version of GetSignatureMemoTable for this token type");
+ }
+
+ // Explicit specializations of GetOriginalSigForToken for all supported token types (IMetaDataImport2)
+ template<> // mdMethodDef
+ HRESULT GetOriginalSigForToken<IMetaDataImport2, mdtMethodDef>(IMetaDataImport2 *pImport, mdMethodDef tk, PCCOR_SIGNATURE *ppvSig, ULONG *pcbSig)
+ {
+ return pImport->GetMethodProps(tk, NULL, NULL, 0, NULL, NULL, ppvSig, pcbSig, NULL, NULL);
+ }
+
+ template<> // mdFieldDef
+ HRESULT GetOriginalSigForToken<IMetaDataImport2, mdtFieldDef>(IMetaDataImport2 *pImport, mdFieldDef tk, PCCOR_SIGNATURE *ppvSig, ULONG *pcbSig)
+ {
+ return pImport->GetFieldProps(tk, NULL, NULL, 0, NULL, NULL, ppvSig, pcbSig, NULL, NULL, NULL);
+ }
+
+ template<> // mdMemberRef
+ HRESULT GetOriginalSigForToken<IMetaDataImport2, mdtMemberRef>(IMetaDataImport2 *pImport, mdMemberRef tk, PCCOR_SIGNATURE *ppvSig, ULONG *pcbSig)
+ {
+ return pImport->GetMemberRefProps(tk, NULL, NULL, 0, NULL, ppvSig, pcbSig);
+ }
+
+ template<> // mdProperty
+ HRESULT GetOriginalSigForToken<IMetaDataImport2, mdtProperty>(IMetaDataImport2 *pImport, mdProperty tk, PCCOR_SIGNATURE *ppvSig, ULONG *pcbSig)
+ {
+ return pImport->GetPropertyProps(tk, NULL, NULL, 0, NULL, NULL, ppvSig, pcbSig, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL);
+ }
+
+ template<> // mdTypeSpec
+ HRESULT GetOriginalSigForToken<IMetaDataImport2, mdtTypeSpec>(IMetaDataImport2 *pImport, mdTypeSpec tk, PCCOR_SIGNATURE *ppvSig, ULONG *pcbSig)
+ {
+ return pImport->GetTypeSpecFromToken(tk, ppvSig, pcbSig);
+ }
+
+ template<> // mdMethodSpec
+ HRESULT GetOriginalSigForToken<IMetaDataImport2, mdtMethodSpec>(IMetaDataImport2 *pImport, mdMethodSpec tk, PCCOR_SIGNATURE *ppvSig, ULONG *pcbSig)
+ {
+ return pImport->GetMethodSpecProps(tk, NULL, ppvSig, pcbSig);
+ }
+
+ // Explicit specializations of GetOriginalSigForToken for all supported token types (IMDInternalImport)
+ template<> // mdMethodDef
+ HRESULT GetOriginalSigForToken<IMDInternalImport, mdtMethodDef>(IMDInternalImport *pImport, mdMethodDef tk, PCCOR_SIGNATURE *ppvSig, ULONG *pcbSig)
+ {
+ return pImport->GetSigOfMethodDef(tk, pcbSig, ppvSig);
+ }
+
+ template<> // mdFieldDef
+ HRESULT GetOriginalSigForToken<IMDInternalImport, mdtFieldDef>(IMDInternalImport *pImport, mdFieldDef tk, PCCOR_SIGNATURE *ppvSig, ULONG *pcbSig)
+ {
+ return pImport->GetSigOfFieldDef(tk, pcbSig, ppvSig);
+ }
+
+ template<> // mdMemberRef
+ HRESULT GetOriginalSigForToken<IMDInternalImport, mdtMemberRef>(IMDInternalImport *pImport, mdMemberRef tk, PCCOR_SIGNATURE *ppvSig, ULONG *pcbSig)
+ {
+ LPCSTR szMemberRefName;
+ return pImport->GetNameAndSigOfMemberRef(tk, ppvSig, pcbSig, &szMemberRefName);
+ }
+
+ template<> // mdProperty
+ HRESULT GetOriginalSigForToken<IMDInternalImport, mdtProperty>(IMDInternalImport *pImport, mdProperty tk, PCCOR_SIGNATURE *ppvSig, ULONG *pcbSig)
+ {
+ return pImport->GetPropertyProps(tk, NULL, NULL, ppvSig, pcbSig);
+ }
+
+ template<> // mdTypeSpec
+ HRESULT GetOriginalSigForToken<IMDInternalImport, mdtTypeSpec>(IMDInternalImport *pImport, mdTypeSpec tk, PCCOR_SIGNATURE *ppvSig, ULONG *pcbSig)
+ {
+ return pImport->GetSigFromToken(tk, pcbSig, ppvSig);
+ }
+
+ template<> // mdMethodSpec
+ HRESULT GetOriginalSigForToken<IMDInternalImport, mdtMethodSpec>(IMDInternalImport *pImport, mdMethodSpec tk, PCCOR_SIGNATURE *ppvSig, ULONG *pcbSig)
+ {
+ return pImport->GetMethodSpecProps(tk, NULL, ppvSig, pcbSig);
+ }
+
+
+ // Returns signature for the given MethodDef, FieldDef, MemberRef, standalone Signature, Property, TypeSpec, or MethodSpec token.
+ // Performs cache lookup, computes the new reinterpreted signature if needed, and inserts it into the cache. Be sure to instantiate
+ // the method with right template arguments. T is the underlying metadata interface that should be used to retrieve the original
+ // signature if not passed in ppOrigSig/pcbOrigSigBlob. TOKENTYPE an mdt* constants corresponding to the type of the token.
+ template<typename T, mdToken TOKENTYPE>
+ HRESULT GetSignatureForToken(
+ mdToken token,
+ PCCOR_SIGNATURE *ppOrigSig, // [IN] pointer to count of bytes in the original signature blob, NULL if we need to retrieve from GetOriginalSigForToken
+ ULONG *pcbOrigSigBlob, // [IN] pointer to original signature, NULL if we need to retrieve from GetOriginalSigForToken
+ PCCOR_SIGNATURE *ppSig, // [OUT] new signature
+ ULONG *pcbSigBlob, // [OUT] count of bytes in the signature blob
+ T *pImport)
+ {
+ _ASSERTE(TypeFromToken(token) == TOKENTYPE);
+ if ((ppSig == NULL) && (pcbSigBlob == NULL))
+ {
+ return S_OK;
+ }
+
+ // When loading NGen images we go through code paths that expect no faults and no
+ // throws. We will need to take a look at how we use the winmd metadata with ngen,
+ // potentially storing the post-mangled metadata in the NI because as the adapter grows
+ // we'll see more of these.
+ CONTRACT_VIOLATION(ThrowsViolation | FaultViolation);
+
+ HRESULT hr = S_OK;
+ ULONG cbOrigSigBlob = (ULONG)(-1);
+ PCCOR_SIGNATURE pOrigSig = NULL;
+ BOOL fPassThrough = FALSE;
+
+ MemoTable<SigData*, SigData::Destroy> &memoTable = GetSignatureMemoTable<TOKENTYPE>();
+
+ // Get from cache
+ IfFailRet(GetCachedSigForToken(token, memoTable, pcbSigBlob, ppSig, &fPassThrough));
+ if (hr == S_FALSE)
+ {
+ // We do not want to leak S_FALSE from this function
+ hr = S_OK;
+
+ // Original signature has already been provided?
+ if ((pcbOrigSigBlob == NULL) || (ppOrigSig == NULL))
+ {
+ // Not provided, we need to get one by ourselves
+ IfFailRet((GetOriginalSigForToken<T, TOKENTYPE>(pImport, token, &pOrigSig, &cbOrigSigBlob)));
+ }
+ else
+ {
+ // Provided, use that
+ pOrigSig = *ppOrigSig;
+ cbOrigSigBlob = *pcbOrigSigBlob;
+ }
+
+ if (fPassThrough) // We cached that we don't need to reinterpret anything.
+ {
+ if (ppSig != NULL)
+ *ppSig = pOrigSig;
+ if (pcbSigBlob != NULL)
+ *pcbSigBlob = cbOrigSigBlob;
+ }
+ else
+ {
+ SigData *pSigData;
+ IfFailRet(ReinterpretSignature<TOKENTYPE>(cbOrigSigBlob, pOrigSig, &pSigData));
+ IfFailRet(InsertCachedSigForToken(token, memoTable, &pSigData));
+
+ fPassThrough = (pSigData == SigData::NOREDIRECT);
+
+ if (ppSig != NULL)
+ *ppSig = (fPassThrough ? pOrigSig : (PCCOR_SIGNATURE)pSigData->data);
+ if (pcbSigBlob != NULL)
+ *pcbSigBlob = (fPassThrough ? cbOrigSigBlob : pSigData->cbSig);
+ }
+ }
+ else
+ {
+ _ASSERTE(!fPassThrough);
+ // Already wrote to our output parameters.
+ }
+ // We should return error (via IfFailRet macro) or S_OK here
+ _ASSERTE(hr == S_OK);
+
+ return hr;
+ }
+
+ //
+ // Support for extra assembly refs inserted into this assembly
+ //
+ ULONG GetRawAssemblyRefCount() { return m_rawAssemblyRefCount; }
+
+ mdAssemblyRef GetAssemblyRefMscorlib() { return m_assemblyRefMscorlib; }
+
+ LPCSTR GetExtraAssemblyRefName(mdAssemblyRef mda)
+ {
+ UINT index = RidFromToken(mda) - m_rawAssemblyRefCount - 1;
+ return WinMDAdapter::GetExtraAssemblyRefNameFromIndex((ContractAssemblyIndex)index);
+ }
+
+
+ static LPCSTR GetExtraAssemblyRefNameFromIndex(FrameworkAssemblyIndex index)
+ {
+ _ASSERTE(index >= 0 && index < FrameworkAssembly_Count);
+ _ASSERTE(index != FrameworkAssembly_Mscorlib);
+ switch(index)
+ {
+ case FrameworkAssembly_SystemObjectModel:
+ return "System.ObjectModel";
+ case FrameworkAssembly_SystemRuntime:
+ return "System.Runtime";
+ case FrameworkAssembly_SystemRuntimeWindowsRuntime:
+ return "System.Runtime.WindowsRuntime";
+ case FrameworkAssembly_SystemRuntimeWindowsRuntimeUIXaml:
+ return "System.Runtime.WindowsRuntime.UI.Xaml";
+ case FrameworkAssembly_SystemNumericsVectors:
+#ifdef FEATURE_CORECLR
+ return "System.Numerics.Vectors";
+#else
+ return "System.Numerics";
+#endif
+ default:
+ _ASSERTE(!"Invalid AssemblyRef token!");
+ return NULL;
+ }
+ }
+
+ static LPCSTR GetExtraAssemblyRefNameFromIndex(ContractAssemblyIndex index)
+ {
+ _ASSERTE(index >= 0 && index < ContractAssembly_Count);
+ switch(index)
+ {
+ case ContractAssembly_SystemRuntime:
+ return "System.Runtime";
+ case ContractAssembly_SystemRuntimeInteropServicesWindowsRuntime:
+ return "System.Runtime.InteropServices.WindowsRuntime";
+ case ContractAssembly_SystemObjectModel:
+ return "System.ObjectModel";
+ case ContractAssembly_SystemRuntimeWindowsRuntime:
+ return "System.Runtime.WindowsRuntime";
+ case ContractAssembly_SystemRuntimeWindowsRuntimeUIXaml:
+ return "System.Runtime.WindowsRuntime.UI.Xaml";
+ case ContractAssembly_SystemNumericsVectors:
+ return "System.Numerics.Vectors";
+ default:
+ _ASSERTE(!"Invalid AssemblyRef token!");
+ return NULL;
+ }
+ }
+
+ LPCWSTR GetExtraAssemblyRefNameW(mdAssemblyRef mda)
+ {
+ UINT index = RidFromToken(mda) - m_rawAssemblyRefCount - 1;
+ return WinMDAdapter::GetExtraAssemblyRefNameFromIndexW((ContractAssemblyIndex)index);
+ }
+
+ static LPCWSTR GetExtraAssemblyRefNameFromIndexW(ContractAssemblyIndex index)
+ {
+ _ASSERTE(index >= 0 && index < ContractAssembly_Count);
+ switch(index)
+ {
+ case ContractAssembly_SystemRuntime:
+ return W("System.Runtime");
+ case ContractAssembly_SystemRuntimeInteropServicesWindowsRuntime:
+ return W("System.Runtime.InteropServices.WindowsRuntime");
+ case ContractAssembly_SystemObjectModel:
+ return W("System.ObjectModel");
+ case ContractAssembly_SystemRuntimeWindowsRuntime:
+ return W("System.Runtime.WindowsRuntime");
+ case ContractAssembly_SystemRuntimeWindowsRuntimeUIXaml:
+ return W("System.Runtime.WindowsRuntime.UI.Xaml");
+ case ContractAssembly_SystemNumericsVectors:
+ return W("System.Numerics.Vectors");
+ default:
+ _ASSERTE(!"Invalid AssemblyRef token!");
+ return NULL;
+ }
+ }
+
+ BOOL IsValidAssemblyRefToken(mdAssemblyRef tk)
+ {
+ _ASSERTE(TypeFromToken(tk) == mdtAssemblyRef);
+
+ RID rid = RidFromToken(tk);
+ if (rid > 0 &&
+ rid <= m_rawAssemblyRefCount + GetExtraAssemblyRefCount())
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+
+ static void GetExtraAssemblyRefProps(FrameworkAssemblyIndex index,
+ LPCSTR* ppName,
+ AssemblyMetaDataInternal* pContext,
+ PCBYTE * ppPublicKeytoken,
+ DWORD* pTokenLength,
+ DWORD* pdwFlags);
+
+ BOOL IsScenarioWinMDExp()
+ {
+ return (m_scenario == kWinMDExp);
+ }
+
+ HRESULT IsRuntimeClassImplementation(mdTypeDef tkTypeDef, BOOL *pbResult)
+ {
+ _ASSERTE(pbResult != NULL);
+
+ ULONG typeDefTreatment;
+ HRESULT hr = GetTypeDefTreatment(tkTypeDef, &typeDefTreatment);
+
+ if (SUCCEEDED(hr))
+ {
+ // kTdUnmangleWinRTName treatment means it is a <CLR> implementation class
+ *pbResult = (typeDefTreatment == kTdUnmangleWinRTName);
+ }
+
+ return hr;
+ }
+
+private:
+ struct CABlob;
+
+private:
+
+ WinMDAdapter(IMDCommon * pRawMDCommon);
+
+ // S_OK if this is a CLR implementation type that was mangled and hidden by WinMDExp
+ HRESULT CheckIfClrImplementationType(LPCSTR szName, DWORD dwAttr, LPCSTR *pszUnmangledName);
+
+ // Get TypeRefTreatment value for a typeRef
+ HRESULT GetTypeRefTreatment(mdTypeRef typeRef, ULONG *ppTypeRefTreatment);
+
+ // Get TypeRef's index in array code:g_rgRedirectedTypes or return S_FALSE.
+ HRESULT GetTypeRefRedirectedInfo(
+ mdTypeRef tkTypeRef,
+ RedirectedTypeIndex * pIndex);
+
+ // Get TypeDefTreatment value for a typeDef
+ HRESULT GetTypeDefTreatment(mdTypeDef typeDef, ULONG *ppTypeRefTreatment);
+
+ // Get MethodTreatment value for a methodDef
+ HRESULT GetMethodDefTreatment(mdMethodDef methodDef, ULONG *ppMethodDefTreatment);
+
+ // Compute MethodTreatment value for a methodDef (unlike GetMethodDefTreatment, this
+ // does not cache.)
+ HRESULT ComputeMethodDefTreatment(mdMethodDef tkMethodDef, mdTypeDef tkDeclaringTypeDef, ULONG *ppMethodDefTreatment);
+
+ HRESULT CheckIfMethodImplImplementsARedirectedInterface(mdToken tkDecl, UINT *pIndex);
+
+ HRESULT TranslateWinMDAttributeUsageAttribute(mdTypeDef tkTypeDefOfCA, DWORD *pClrTargetValue, BOOL *pAllowMultiple);
+
+ static HRESULT CreateClrAttributeUsageAttributeCABlob(DWORD clrTargetValue, BOOL allowMultiple, CABlob **ppCABlob);
+
+ // Whether the WinRT type should be hidden from managed code
+ // Example: helper class/interface for projected jupiter structs
+ static BOOL IsHiddenWinRTType(LPCSTR szWinRTNamespace, LPCSTR szWinRTName);
+
+ // Map a WinRT typename to CLR typename
+ static BOOL ConvertWellKnownTypeNameFromWinRTToClr(LPCSTR *pszNamespace, LPCSTR *pszName, UINT *pIndex);
+
+ static HRESULT CreatePrefixedName(LPCSTR szPrefix, LPCSTR szName, LPCSTR *ppOut);
+
+ template <typename T> static void Delete(T* ptr)
+ {
+ delete [] ptr;
+ }
+
+ HRESULT RewriteTypeInSignature(SigParser * pSigParser, SigBuilder * pSigBuilder, BOOL * pfChangedSig);
+
+ private:
+ //-----------------------------------------------------------------------------------
+ // Pointer to the raw view of the metadata.
+ //-----------------------------------------------------------------------------------
+ IMetaModelCommonRO *m_pRawMetaModelCommonRO;
+
+
+ private:
+ //-----------------------------------------------------------------------------------
+ // Stores whether the file is a pure .winmd file or one that combines WinRT and CLR code.
+ //-----------------------------------------------------------------------------------
+ enum WinMDScenario
+ {
+ kWinMDNormal = 1, // File is normal Windows .winmd file (Version string = "Windows Runtime nnn")
+ kWinMDExp = 2, // File is output of winmdexp (Version string = "Windows Runtime nnn;<dotnetVersion>")
+ };
+
+ WinMDScenario m_scenario;
+
+
+ private:
+
+ //-----------------------------------------------------------------------------------
+ // Every WinMD file is required to have an assemblyRef to mscorlib - this field caches that assemblyRef
+ //-----------------------------------------------------------------------------------
+ mdAssemblyRef m_assemblyRefMscorlib;
+ BOOL m_fReferencesMscorlibV4; // m_assemblyRefMscorlib is a version=4.0.0.0 AssemblyRef
+ ULONG m_rawAssemblyRefCount; // the raw assembly ref count not including the extra ones.
+ LONG m_extraAssemblyRefCount; // the assembly ref count to return from IMetaDataAssemblyImport::EnumAssemblyRefs
+
+
+ private:
+ //-----------------------------------------------------------------------------------
+ // For each typeref token, we cache an enum that determines how the adapter treats it.
+ //-----------------------------------------------------------------------------------
+ enum TypeRefTreatment
+ {
+ // The upper 8 bits determine how to interpret the lower 24-bits:
+ kTrClassMask = 0xff000000,
+
+ // Lower 24-bits represent fixed values (defined in rest of enum)
+ kTrClassMisc = 0x00000000,
+
+ // TypeRef is one of a small # of hard-coded Windows.Foundation types that we redirect to mscorlib counterparts.
+ // Lower 24-bits is index into typeref redirection table.
+ kTrClassWellKnownRedirected = 0x01000000,
+
+ kTrNotYetInitialized = kTrClassMisc|0x000000, // Entry has not yet been initialized.
+ kTrNoRewriteNeeded = kTrClassMisc|0x000001, // Do not mangle the name.
+ kTrSystemDelegate = kTrClassMisc|0x000002, // Fast-recognition code for System.Delegate
+ kTrSystemAttribute = kTrClassMisc|0x000003, // Fast-recognition code for System.Attribute
+ kTrSystemEnum = kTrClassMisc|0x000004, // Fast-recognition code for System.Enum
+ kTrSystemValueType = kTrClassMisc|0x000005, // Fast-recognition code for System.ValueType
+ };
+ MemoTable<ULONG, DoNothing<ULONG> > m_typeRefTreatmentMemoTable; // Holds index into typeRef rename array or member of TypeRefTreatment enum
+
+ private:
+ //-----------------------------------------------------------------------------------
+ // For each typedef token, we cache an enum that determines how the adapter treats it.
+ //-----------------------------------------------------------------------------------
+ enum TypeDefTreatment
+ {
+ kTdNotYetInitialized = 0x00,
+
+ kTdTreatmentMask = 0x0f,
+ kTdOther = 0x01, // Anything not covered below, and not affected by the treatment flags
+ kTdNormalNonAttribute = 0x02, // non-attribute TypeDef from non-managed winmd assembly
+ kTdNormalAttribute = 0x03, // Attribute TypeDef from non-managed winmd assembly
+ kTdUnmangleWinRTName = 0x04, // Type in managed winmd that should be renamed from <CLR>Foo to Foo
+ kTdPrefixWinRTName = 0x05, // Type in managed winmd that should be renamed from Foo to <WinRT>Foo
+ kTdRedirectedToCLRType = 0x06, // Type is redirected to a CLR type implementation.
+ kTdRedirectedToCLRAttribute = 0x07, // Type is redirected to a CLR type implementation that is an attribute.
+
+ kTdMarkAbstractFlag = 0x10, // Type should be marked as abstract
+ kTdMarkInternalFlag = 0x20, // Type should be hidden from managed code - examples are struct helpers
+ // for redirected Jupiter structs
+ kTdEnum = 0x40, // Type is an enum from managed\non-managed winmd assembly.
+ };
+ MemoTable<ULONG, DoNothing<ULONG> > m_typeDefTreatmentMemoTable; // Holds member of TypeDefTreatment enum
+
+ private:
+ //-----------------------------------------------------------------------------------
+ // For each methoddef token, we cache an enum that determines how the adapter treats it.
+ //-----------------------------------------------------------------------------------
+ enum MethodDefTreatment
+ {
+ kMdNotYetInitialized = 0x00,
+ kMdTreatmentMask = 0x0f, // Mask of various options
+ kMdOther = 0x01, // Anything not covered below
+ kMdDelegate = 0x02, // Declared by delegate
+ kMdAttribute = 0x03, // Declared by an attribute
+ kMdInterface = 0x04, // Is member of interface
+ kMdImplementation = 0x05, // CLR implementation of RuntimeClass
+ kMdHiddenImpl = 0x06, // Implements a redirected (hidden) interface
+ kMdtUnusedFlag = 0x07, // UnUnsed flag.
+ kMdRenameToDisposeMethod = 0x08, // Rename IClosable.Close to Dispose
+
+ kMdMarkAbstractFlag = 0x10, // Method should be marked as abstract
+ kMdMarkPublicFlag = 0x20, // Method visibility should be marked as public
+ };
+ MemoTable<ULONG, DoNothing<ULONG> > m_methodDefTreatmentMemoTable; // Holds member of MethodDefTreatment enum
+
+ private:
+ //-----------------------------------------------------------------------------------
+ // The version string we report to callers.
+ //-----------------------------------------------------------------------------------
+ LPSTR m_pRedirectedVersionString;
+
+ private:
+ //-----------------------------------------------------------------------------------
+ // For each customattribute token, we cache the blob that the adapter reports to callers.
+ // The special pointer value CABlob::NOREDIRECT indicates that the raw blob is to be
+ // passed unchanged.
+ //-----------------------------------------------------------------------------------
+
+ // Represents a custom attribute blob
+ struct CABlob
+ {
+ ULONG cbBlob; // Length of blob in bytes.
+ BYTE data[1]; // Start of variable-length blob (cbBlob indicates length in bytes.)
+
+ static CABlob* Create(const BYTE *pBlob, ULONG cbBlob);
+ static void Destroy(CABlob *pCABlob);
+
+ // Sentinel value in m_redirectedCABlobsMemoTable table. Means "do no blob rewriting. Return the one from the underlying importer."
+ static CABlob* const NOREDIRECT;
+ };
+
+ MemoTable<CABlob*, CABlob::Destroy> m_redirectedCABlobsMemoTable; // Array of rewritten CA blobs
+
+ private:
+ //-----------------------------------------------------------------------------------
+ // For each token, we cache the signature that the adapter reports to callers.
+ //-----------------------------------------------------------------------------------
+ MemoTable<SigData*, SigData::Destroy> m_redirectedMethodDefSigMemoTable; // Array of rewritten MethodDef signatures
+ MemoTable<SigData*, SigData::Destroy> m_redirectedFieldDefSigMemoTable; // Array of rewritten FieldDef signatures
+ MemoTable<SigData*, SigData::Destroy> m_redirectedMemberRefSigMemoTable; // Array of rewritten MemberRef signatures
+ MemoTable<SigData*, SigData::Destroy> m_redirectedPropertySigMemoTable; // Array of rewritten Property signatures
+ MemoTable<SigData*, SigData::Destroy> m_redirectedTypeSpecSigMemoTable; // Array of rewritten TypeSpec signatures
+ MemoTable<SigData*, SigData::Destroy> m_redirectedMethodSpecSigMemoTable; // Array of rewritten MethodSpec signatures
+
+ // Explicit specializations of GetSignatureMemoTable for all supported token types
+ template<> MemoTable<SigData*, SigData::Destroy> &GetSignatureMemoTable<mdtMethodDef>() { return m_redirectedMethodDefSigMemoTable; }
+ template<> MemoTable<SigData*, SigData::Destroy> &GetSignatureMemoTable<mdtFieldDef>() { return m_redirectedFieldDefSigMemoTable; }
+ template<> MemoTable<SigData*, SigData::Destroy> &GetSignatureMemoTable<mdtMemberRef>() { return m_redirectedMemberRefSigMemoTable; }
+ template<> MemoTable<SigData*, SigData::Destroy> &GetSignatureMemoTable<mdtProperty>() { return m_redirectedPropertySigMemoTable; }
+ template<> MemoTable<SigData*, SigData::Destroy> &GetSignatureMemoTable<mdtTypeSpec>() { return m_redirectedTypeSpecSigMemoTable; }
+ template<> MemoTable<SigData*, SigData::Destroy> &GetSignatureMemoTable<mdtMethodSpec>() { return m_redirectedMethodSpecSigMemoTable; }
+
+ private:
+ //-----------------------------------------------------------------------------------
+ // For each typedef whose name we mangle, we cache the mangled name that we report to callers. (The "name"
+ // is the "name" half of the namespace/name pair. We don't mangle namespaces.)
+ //
+ // Currently, the adapter used the tdAttr value to determine whether a typedef name needs
+ // be mangled at all - thus, we don't have a sentinel for "don't mangle."
+ //-----------------------------------------------------------------------------------
+ MemoTable<LPCSTR, Delete<const char> > m_mangledTypeNameTable; // Array of mangled typedef names
+};
+
+
+#endif // __MDWinMDAdapter__h__