diff options
Diffstat (limited to 'src/md/compiler/filtermanager.cpp')
-rw-r--r-- | src/md/compiler/filtermanager.cpp | 1458 |
1 files changed, 1458 insertions, 0 deletions
diff --git a/src/md/compiler/filtermanager.cpp b/src/md/compiler/filtermanager.cpp new file mode 100644 index 0000000000..c8e9ac3e07 --- /dev/null +++ b/src/md/compiler/filtermanager.cpp @@ -0,0 +1,1458 @@ +// 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. +//***************************************************************************** +// FilterManager.cpp +// + +// +// contains utility code to MD directory +// +//***************************************************************************** +#include "stdafx.h" +#include "filtermanager.h" + +#define IsGlobalTypeDef(td) (td == TokenFromRid(mdtTypeDef, 1)) + +//***************************************************************************** +// Walk up to the containing tree and +// mark the transitive closure of the root token +//***************************************************************************** +HRESULT FilterManager::Mark(mdToken tk) +{ + HRESULT hr = NOERROR; + mdTypeDef td; + + // We hard coded System.Object as mdTypeDefNil + // The backing Field of property can be NULL as well. + if (RidFromToken(tk) == mdTokenNil) + goto ErrExit; + + // We know that the filter table is not null here. Tell PREFIX that we know it. + PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); + + switch ( TypeFromToken(tk) ) + { + case mdtTypeDef: + IfFailGo( MarkTypeDef(tk) ); + break; + + case mdtMethodDef: + // Get the typedef containing the MethodDef and mark the whole type + IfFailGo( m_pMiniMd->FindParentOfMethodHelper(tk, &td) ); + + // Global function so only mark the function itself and the typedef. + // Don't call MarkTypeDef. That will trigger all of the global methods/fields + // marked. + // + if (IsGlobalTypeDef(td)) + { + IfFailGo( m_pMiniMd->GetFilterTable()->MarkTypeDef(td) ); + IfFailGo( MarkMethod(tk) ); + } + else + { + IfFailGo( MarkTypeDef(td) ); + } + break; + + case mdtFieldDef: + // Get the typedef containing the FieldDef and mark the whole type + IfFailGo( m_pMiniMd->FindParentOfFieldHelper(tk, &td) ); + if (IsGlobalTypeDef(td)) + { + IfFailGo( m_pMiniMd->GetFilterTable()->MarkTypeDef(td) ); + IfFailGo( MarkField(tk) ); + } + else + { + IfFailGo( MarkTypeDef(td) ); + } + break; + + case mdtMemberRef: + IfFailGo( MarkMemberRef(tk) ); + break; + + case mdtTypeRef: + IfFailGo( MarkTypeRef(tk) ); + break; + + case mdtTypeSpec: + IfFailGo( MarkTypeSpec(tk) ); + break; + case mdtSignature: + IfFailGo( MarkStandAloneSig(tk) ); + break; + + case mdtModuleRef: + IfFailGo( MarkModuleRef(tk) ); + break; + + case mdtAssemblyRef: + IfFailGo( MarkAssemblyRef(tk) ); + break; + + case mdtModule: + IfFailGo( MarkModule(tk) ); + break; + + case mdtString: + IfFailGo( MarkUserString(tk) ); + break; + + case mdtBaseType: + // don't need to mark any base type. + break; + + case mdtAssembly: + IfFailGo( MarkAssembly(tk) ); + break; + + case mdtMethodSpec: + IfFailGo( MarkMethodSpec(tk) ); + break; + + case mdtProperty: + case mdtEvent: + case mdtParamDef: + case mdtInterfaceImpl: + default: + _ASSERTE(!" unknown type!"); + hr = E_INVALIDARG; + break; + } +ErrExit: + return hr; +} // HRESULT FilterManager::Mark() + + + +//***************************************************************************** +// marking only module property +//***************************************************************************** +HRESULT FilterManager::MarkAssembly(mdAssembly as) +{ + HRESULT hr = NOERROR; + + if (hasAssemblyBeenMarked == false) + { + hasAssemblyBeenMarked = true; + IfFailGo( MarkCustomAttributesWithParentToken(as) ); + IfFailGo( MarkDeclSecuritiesWithParentToken(as) ); + } +ErrExit: + return hr; +} // HRESULT FilterManager::MarkAssembly() + + +//***************************************************************************** +// marking only module property +//***************************************************************************** +HRESULT FilterManager::MarkModule(mdModule mo) +{ + HRESULT hr = NOERROR; + + if (hasModuleBeenMarked == false) + { + hasModuleBeenMarked = true; + IfFailGo( MarkCustomAttributesWithParentToken(mo) ); + } +ErrExit: + return hr; +} // HRESULT FilterManager::MarkModule() + + +//***************************************************************************** +// cascading Mark of a CustomAttribute +//***************************************************************************** +HRESULT FilterManager::MarkCustomAttribute(mdCustomAttribute cv) +{ + HRESULT hr = NOERROR; + CustomAttributeRec *pRec; + + // We know that the filter table is not null here. Tell PREFIX that we know it. + PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); + + IfFailGo( m_pMiniMd->GetFilterTable()->MarkCustomAttribute( cv ) ); + + // Mark the type (and any family) of the CustomAttribue. + IfFailGo(m_pMiniMd->GetCustomAttributeRecord(RidFromToken(cv), &pRec)); + IfFailGo( Mark(m_pMiniMd->getTypeOfCustomAttribute(pRec)) ); + +ErrExit: + return hr; +} // HRESULT FilterManager::MarkCustomAttribute() + + +//***************************************************************************** +// cascading Mark of a DeclSecurity +//***************************************************************************** +HRESULT FilterManager::MarkDeclSecurity(mdPermission pe) +{ + HRESULT hr = NOERROR; + + // We know that the filter table is not null here. Tell PREFIX that we know it. + PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); + + IfFailGo( m_pMiniMd->GetFilterTable()->MarkDeclSecurity( pe ) ); +ErrExit: + return hr; +} // HRESULT FilterManager::MarkDeclSecurity() + + + +//***************************************************************************** +// cascading Mark of a signature +//***************************************************************************** +HRESULT FilterManager::MarkStandAloneSig(mdSignature sig) +{ + HRESULT hr = NOERROR; + StandAloneSigRec *pRec; + ULONG cbSize; + ULONG cbUsed; + PCCOR_SIGNATURE pbSig; + IHostFilter *pFilter = m_pMiniMd->GetHostFilter(); + + // We know that the filter table is not null here. Tell PREFIX that we know it. + PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); + + // if TypeRef is already marked, just return + if (m_pMiniMd->GetFilterTable()->IsSignatureMarked(sig)) + goto ErrExit; + + // To mark the signature, we will need to mark + // all of the embedded TypeRef or TypeDef + // + IfFailGo( m_pMiniMd->GetFilterTable()->MarkSignature( sig ) ); + + if (pFilter) + pFilter->MarkToken(sig); + + // Walk the signature and mark all of the embedded types + IfFailGo(m_pMiniMd->GetStandAloneSigRecord(RidFromToken(sig), &pRec)); + IfFailGo(m_pMiniMd->getSignatureOfStandAloneSig(pRec, &pbSig, &cbSize)); + IfFailGo( MarkSignature(pbSig, cbSize, &cbUsed) ); + + IfFailGo( MarkCustomAttributesWithParentToken(sig) ); +ErrExit: + return hr; +} // HRESULT FilterManager::MarkStandAloneSig() + + + +//***************************************************************************** +// cascading Mark of a TypeSpec +//***************************************************************************** +HRESULT FilterManager::MarkTypeSpec(mdTypeSpec ts) +{ + HRESULT hr = NOERROR; + TypeSpecRec *pRec; + ULONG cbSize; + ULONG cbUsed; + PCCOR_SIGNATURE pbSig; + IHostFilter *pFilter = m_pMiniMd->GetHostFilter(); + + // We know that the filter table is not null here. Tell PREFIX that we know it. + PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); + + // if TypeRef is already marked, just return + if (m_pMiniMd->GetFilterTable()->IsTypeSpecMarked(ts)) + goto ErrExit; + + // To mark the TypeSpec, we will need to mark + // all of the embedded TypeRef or TypeDef + // + IfFailGo( m_pMiniMd->GetFilterTable()->MarkTypeSpec( ts ) ); + + if (pFilter) + pFilter->MarkToken(ts); + + // Walk the signature and mark all of the embedded types + IfFailGo(m_pMiniMd->GetTypeSpecRecord(RidFromToken(ts), &pRec)); + IfFailGo(m_pMiniMd->getSignatureOfTypeSpec(pRec, &pbSig, &cbSize)); + IfFailGo( MarkFieldSignature(pbSig, cbSize, &cbUsed) ); + IfFailGo( MarkCustomAttributesWithParentToken(ts) ); + + +ErrExit: + return hr; +} // HRESULT FilterManager::MarkTypeSpec() + + + + +//***************************************************************************** +// cascading Mark of a TypeRef +//***************************************************************************** +HRESULT FilterManager::MarkTypeRef(mdTypeRef tr) +{ + HRESULT hr = NOERROR; + TOKENMAP *tkMap; + mdTypeDef td; + IHostFilter *pFilter = m_pMiniMd->GetHostFilter(); + TypeRefRec *pRec; + mdToken parentTk; + + // We know that the filter table is not null here. Tell PREFIX that we know it. + PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); + + // if TypeRef is already marked, just return + if (m_pMiniMd->GetFilterTable()->IsTypeRefMarked(tr)) + goto ErrExit; + + IfFailGo( m_pMiniMd->GetFilterTable()->MarkTypeRef( tr ) ); + + if (pFilter) + pFilter->MarkToken(tr); + + IfFailGo(m_pMiniMd->GetTypeRefRecord(RidFromToken(tr), &pRec)); + parentTk = m_pMiniMd->getResolutionScopeOfTypeRef(pRec); + if ( RidFromToken(parentTk) ) + { + IfFailGo( Mark( parentTk ) ); + } + + tkMap = m_pMiniMd->GetTypeRefToTypeDefMap(); + PREFIX_ASSUME(tkMap != NULL); + td = *(tkMap->Get(RidFromToken(tr))); + if ( td != mdTokenNil ) + { + // TypeRef is referring to a TypeDef within the same module. + // Mark the TypeDef as well. + // + IfFailGo( Mark(td) ); + } + + IfFailGo( MarkCustomAttributesWithParentToken(tr) ); + +ErrExit: + return hr; +} // HRESULT FilterManager::MarkTypeRef() + + +//***************************************************************************** +// cascading Mark of a MemberRef +//***************************************************************************** +HRESULT FilterManager::MarkMemberRef(mdMemberRef mr) +{ + HRESULT hr = NOERROR; + MemberRefRec *pRec; + ULONG cbSize; + ULONG cbUsed; + PCCOR_SIGNATURE pbSig; + IHostFilter *pFilter = m_pMiniMd->GetHostFilter(); + mdToken md; + TOKENMAP *tkMap; + mdToken tkParent; + + // We know that the filter table is not null here. Tell PREFIX that we know it. + PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); + + // if MemberRef is already marked, just return + if (m_pMiniMd->GetFilterTable()->IsMemberRefMarked(mr)) + goto ErrExit; + + IfFailGo( m_pMiniMd->GetFilterTable()->MarkMemberRef( mr ) ); + + if (pFilter) + pFilter->MarkToken(mr); + + IfFailGo(m_pMiniMd->GetMemberRefRecord(RidFromToken(mr), &pRec)); + + // we want to mark the parent of MemberRef as well + tkParent = m_pMiniMd->getClassOfMemberRef(pRec); + + // If the parent is the global TypeDef, mark only the TypeDef itself (low-level function). + // Other parents, do the transitive mark (ie, the high-level function). + // + if (IsGlobalTypeDef(tkParent)) + IfFailGo( m_pMiniMd->GetFilterTable()->MarkTypeDef( tkParent ) ); + else + IfFailGo( Mark( tkParent ) ); + + // Walk the signature and mark all of the embedded types + IfFailGo(m_pMiniMd->getSignatureOfMemberRef(pRec, &pbSig, &cbSize)); + IfFailGo( MarkSignature(pbSig, cbSize, &cbUsed) ); + + tkMap = m_pMiniMd->GetMemberRefToMemberDefMap(); + PREFIX_ASSUME(tkMap != NULL); + md = *(tkMap->Get(RidFromToken(mr))); // can be fielddef or methoddef + if ( RidFromToken(md) != mdTokenNil ) + { + // MemberRef is referring to either a FieldDef or MethodDef. + // If it is referring to MethodDef, we have fix the parent of MemberRef to be the MethodDef. + // However, if it is mapped to a FieldDef, the parent column does not track this information. + // Therefore we need to mark it explicitly. + // + IfFailGo( Mark(md) ); + } + + IfFailGo( MarkCustomAttributesWithParentToken(mr) ); + +ErrExit: + return hr; +} // HRESULT FilterManager::MarkMemberRef() + + +//***************************************************************************** +// cascading Mark of a UserString +//***************************************************************************** +HRESULT FilterManager::MarkUserString(mdString str) +{ + HRESULT hr = NOERROR; + + // We know that the filter table is not null here. Tell PREFIX that we know it. + PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); + + // if UserString is already marked, just return + if (m_pMiniMd->GetFilterTable()->IsUserStringMarked(str)) + goto ErrExit; + + IfFailGo( m_pMiniMd->GetFilterTable()->MarkUserString( str ) ); + +ErrExit: + return hr; +} // HRESULT FilterManager::MarkUserString() + + +//***************************************************************************** +// Mark of a new UserString +//***************************************************************************** +HRESULT FilterManager::MarkNewUserString(mdString str) +{ + HRESULT hr = NOERROR; + + // We know that the filter table is not null here. Tell PREFIX that we know it. + PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); + + IfFailGo( m_pMiniMd->GetFilterTable()->MarkNewUserString( str ) ); + +ErrExit: + return hr; +} // HRESULT FilterManager::MarkUserString() + + +//***************************************************************************** +// cascading Mark of a MethodSpec +//***************************************************************************** +HRESULT FilterManager::MarkMethodSpec(mdMethodSpec ms) +{ + HRESULT hr = NOERROR; + MethodSpecRec *pRec; + ULONG cbSize; + ULONG cbUsed; + PCCOR_SIGNATURE pbSig; + + // We know that the filter table is not null here. Tell PREFIX that we know it. + PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); + + // if MethodSpec is already marked, just return + if (m_pMiniMd->GetFilterTable()->IsMethodSpecMarked(ms)) + goto ErrExit; + + IfFailGo( m_pMiniMd->GetFilterTable()->MarkMethodSpec( ms ) ); + + // Mark MethodRef or MethodDef and embedded TypeRef and TypeDef tokens + + IfFailGo(m_pMiniMd->GetMethodSpecRecord(RidFromToken(ms), &pRec)); + + IfFailGo( Mark(m_pMiniMd->getMethodOfMethodSpec(pRec)) ); + + IfFailGo(m_pMiniMd->getInstantiationOfMethodSpec(pRec, &pbSig, &cbSize)); + IfFailGo( MarkSignature(pbSig, cbSize, &cbUsed) ); + +ErrExit: + return hr; +} // HRESULT FilterManager::MarkMethodSpec() + + +//***************************************************************************** +// cascading Mark of a ModuleRef +//***************************************************************************** +HRESULT FilterManager::MarkModuleRef(mdModuleRef mr) +{ + HRESULT hr = NOERROR; + + // We know that the filter table is not null here. Tell PREFIX that we know it. + PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); + + // if ModuleRef is already marked, just return + if (m_pMiniMd->GetFilterTable()->IsModuleRefMarked(mr)) + goto ErrExit; + + IfFailGo( m_pMiniMd->GetFilterTable()->MarkModuleRef( mr ) ); + IfFailGo( MarkCustomAttributesWithParentToken(mr) ); + +ErrExit: + return hr; +} // HRESULT FilterManager::MarkModuleRef() + + +//***************************************************************************** +// cascading Mark of a AssemblyRef +//***************************************************************************** +HRESULT FilterManager::MarkAssemblyRef(mdAssemblyRef ar) +{ + HRESULT hr = NOERROR; + + // We know that the filter table is not null here. Tell PREFIX that we know it. + PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); + + // if ModuleREf is already marked, just return + if (m_pMiniMd->GetFilterTable()->IsAssemblyRefMarked(ar)) + goto ErrExit; + + IfFailGo( m_pMiniMd->GetFilterTable()->MarkAssemblyRef( ar ) ); + IfFailGo( MarkCustomAttributesWithParentToken(ar) ); + +ErrExit: + return hr; +} // HRESULT FilterManager::MarkAssemblyRef() + + +//***************************************************************************** +// cascading Mark of all of the custom values associated with a token +//***************************************************************************** +HRESULT FilterManager::MarkCustomAttributesWithParentToken(mdToken tkParent) +{ + HRESULT hr = NOERROR; + RID ridStart, ridEnd; + RID index; + CustomAttributeRec *pRec; + + if ( m_pMiniMd->IsSorted( TBL_CustomAttribute ) ) + { + // table is sorted. ridStart to ridEnd - 1 are all CustomAttribute + // associated with tkParent + // + IfFailGo(m_pMiniMd->getCustomAttributeForToken(tkParent, &ridEnd, &ridStart)); + for (index = ridStart; index < ridEnd; index ++ ) + { + IfFailGo( MarkCustomAttribute( TokenFromRid(index, mdtCustomAttribute) ) ); + } + } + else + { + // table scan is needed + ridStart = 1; + ridEnd = m_pMiniMd->getCountCustomAttributes() + 1; + for (index = ridStart; index < ridEnd; index ++ ) + { + IfFailGo(m_pMiniMd->GetCustomAttributeRecord(index, &pRec)); + if ( tkParent == m_pMiniMd->getParentOfCustomAttribute(pRec) ) + { + // This CustomAttribute is associated with tkParent + IfFailGo( MarkCustomAttribute( TokenFromRid(index, mdtCustomAttribute) ) ); + } + } + } + +ErrExit: + return hr; +} // HRESULT FilterManager::MarkCustomAttributesWithParentToken() + + +//***************************************************************************** +// cascading Mark of all securities associated with a token +//***************************************************************************** +HRESULT FilterManager::MarkDeclSecuritiesWithParentToken(mdToken tkParent) +{ + HRESULT hr = NOERROR; + RID ridStart, ridEnd; + RID index; + DeclSecurityRec *pRec; + + // We know that the filter table is not null here. Tell PREFIX that we know it. + PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); + + if ( m_pMiniMd->IsSorted( TBL_DeclSecurity ) ) + { + // table is sorted. ridStart to ridEnd - 1 are all DeclSecurity + // associated with tkParent + // + IfFailGo(m_pMiniMd->getDeclSecurityForToken(tkParent, &ridEnd, &ridStart)); + for (index = ridStart; index < ridEnd; index ++ ) + { + IfFailGo( m_pMiniMd->GetFilterTable()->MarkDeclSecurity( TokenFromRid(index, mdtPermission) ) ); + } + } + else + { + // table scan is needed + ridStart = 1; + ridEnd = m_pMiniMd->getCountDeclSecuritys() + 1; + for (index = ridStart; index < ridEnd; index ++ ) + { + IfFailGo(m_pMiniMd->GetDeclSecurityRecord(index, &pRec)); + if ( tkParent == m_pMiniMd->getParentOfDeclSecurity(pRec) ) + { + // This DeclSecurity is associated with tkParent + IfFailGo( m_pMiniMd->GetFilterTable()->MarkDeclSecurity( TokenFromRid(index, mdtPermission) ) ); + } + } + } + +ErrExit: + return hr; +} // HRESULT FilterManager::MarkDeclSecuritiesWithParentToken() + + +//***************************************************************************** +// cascading Mark of all MemberRefs associated with a parent token +//***************************************************************************** +HRESULT FilterManager::MarkMemberRefsWithParentToken(mdToken tk) +{ + HRESULT hr = NOERROR; + RID ulEnd; + RID index; + mdToken tkParent; + MemberRefRec *pRec; + + ulEnd = m_pMiniMd->getCountMemberRefs(); + + for (index = 1; index <= ulEnd; index ++ ) + { + // memberRef table is not sorted. Table scan is needed. + IfFailGo(m_pMiniMd->GetMemberRefRecord(index, &pRec)); + tkParent = m_pMiniMd->getClassOfMemberRef(pRec); + if ( tk == tkParent ) + { + IfFailGo( MarkMemberRef( TokenFromRid(index, mdtMemberRef) ) ); + } + } +ErrExit: + return hr; +} // HRESULT FilterManager::MarkMemberRefsWithParentToken() + + +//***************************************************************************** +// cascading Mark of a ParamDef token +//***************************************************************************** +HRESULT FilterManager::MarkParam(mdParamDef pd) +{ + HRESULT hr; + + // We know that the filter table is not null here. Tell PREFIX that we know it. + PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); + + IfFailGo( m_pMiniMd->GetFilterTable()->MarkParam( pd ) ); + + IfFailGo( MarkCustomAttributesWithParentToken(pd) ); + // Parameter does not have declsecurity + // IfFailGo( MarkDeclSecuritiesWithParentToken(pd) ); + +ErrExit: + return hr; +} // HRESULT FilterManager::MarkParam() + + +//***************************************************************************** +// cascading Mark of a method token +//***************************************************************************** +HRESULT FilterManager::MarkMethod(mdMethodDef md) +{ + HRESULT hr = NOERROR; + MethodRec *pRec; + ULONG cbSize; + ULONG cbUsed; + PCCOR_SIGNATURE pbSig; + ULONG i, iCount; + ImplMapRec *pImplMapRec = NULL; + mdMethodDef mdImp; + mdModuleRef mrImp; + IHostFilter *pFilter = m_pMiniMd->GetHostFilter(); + + // We know that the filter table is not null here. Tell PREFIX that we know it. + PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); + + // if MethodDef is already marked, just return + if (m_pMiniMd->GetFilterTable()->IsMethodMarked(md)) + goto ErrExit; + + IfFailGo( m_pMiniMd->GetFilterTable()->MarkMethod( md ) ); + if (pFilter) + pFilter->MarkToken(md); + + IfFailGo( MarkParamsWithParentToken(md) ); + + // mark any GenericParam of this Method + IfFailGo( MarkGenericParamWithParentToken(md) ); + + + // Walk the signature and mark all of the embedded types + IfFailGo(m_pMiniMd->GetMethodRecord(RidFromToken(md), &pRec)); + IfFailGo(m_pMiniMd->getSignatureOfMethod(pRec, &pbSig, &cbSize)); + IfFailGo( MarkSignature(pbSig, cbSize, &cbUsed) ); + + iCount = m_pMiniMd->getCountImplMaps(); + + // loop through all ImplMaps and find the Impl map associated with this method def tokens + // and mark the Module Ref tokens in the entries + // + for (i = 1; i <= iCount; i++) + { + IfFailGo(m_pMiniMd->GetImplMapRecord(i, &pImplMapRec)); + + // Get the MethodDef that the impl map is associated with + mdImp = m_pMiniMd->getMemberForwardedOfImplMap(pImplMapRec); + + if (mdImp != md) + { + // Impl Map entry does not associated with the method def that we are marking + continue; + } + + // Get the ModuleRef token + mrImp = m_pMiniMd->getImportScopeOfImplMap(pImplMapRec); + IfFailGo( Mark(mrImp) ); + } + + // We should not mark all of the memberref with the parent of this methoddef token. + // Because not all of the call sites are needed. + // + // IfFailGo( MarkMemberRefsWithParentToken(md) ); + IfFailGo( MarkCustomAttributesWithParentToken(md) ); + IfFailGo( MarkDeclSecuritiesWithParentToken(md) ); +ErrExit: + return hr; +} // HRESULT FilterManager::MarkMethod() + + +//***************************************************************************** +// cascading Mark of a field token +//***************************************************************************** +HRESULT FilterManager::MarkField(mdFieldDef fd) +{ + HRESULT hr = NOERROR; + FieldRec *pRec; + ULONG cbSize; + ULONG cbUsed; + PCCOR_SIGNATURE pbSig; + IHostFilter *pFilter = m_pMiniMd->GetHostFilter(); + + // We know that the filter table is not null here. Tell PREFIX that we know it. + PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); + + // if FieldDef is already marked, just return + if (m_pMiniMd->GetFilterTable()->IsFieldMarked(fd)) + goto ErrExit; + + IfFailGo( m_pMiniMd->GetFilterTable()->MarkField( fd ) ); + if (pFilter) + pFilter->MarkToken(fd); + + // We should not mark all of the MemberRef with the parent of this FieldDef token. + // Because not all of the call sites are needed. + // + + // Walk the signature and mark all of the embedded types + IfFailGo(m_pMiniMd->GetFieldRecord(RidFromToken(fd), &pRec)); + IfFailGo(m_pMiniMd->getSignatureOfField(pRec, &pbSig, &cbSize)); + IfFailGo( MarkSignature(pbSig, cbSize, &cbUsed) ); + + IfFailGo( MarkCustomAttributesWithParentToken(fd) ); + // IfFailGo( MarkDeclSecuritiesWithParentToken(fd) ); + +ErrExit: + return hr; +} // HRESULT FilterManager::MarkField() + + +//***************************************************************************** +// cascading Mark of an event token +//***************************************************************************** +HRESULT FilterManager::MarkEvent(mdEvent ev) +{ + HRESULT hr = NOERROR; + EventRec *pRec; + + // We know that the filter table is not null here. Tell PREFIX that we know it. + PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); + + // if Event is already marked, just return + if (m_pMiniMd->GetFilterTable()->IsEventMarked(ev)) + goto ErrExit; + + IfFailGo( m_pMiniMd->GetFilterTable()->MarkEvent( ev ) ); + + // mark the event type as well + IfFailGo(m_pMiniMd->GetEventRecord(RidFromToken(ev), &pRec)); + IfFailGo( Mark(m_pMiniMd->getEventTypeOfEvent(pRec)) ); + + // Note that we don't need to mark the MethodSemantics. Because the association of MethodSemantics + // is marked. The Method column can only store MethodDef, ie the MethodDef has the same parent as + // this Event. + + IfFailGo( MarkCustomAttributesWithParentToken(ev) ); + // IfFailGo( MarkDeclSecuritiesWithParentToken(ev) ); + +ErrExit: + return hr; +} // HRESULT FilterManager::MarkEvent() + + + +//***************************************************************************** +// cascading Mark of a Property token +//***************************************************************************** +HRESULT FilterManager::MarkProperty(mdProperty pr) +{ + HRESULT hr = NOERROR; + PropertyRec *pRec; + ULONG cbSize; + ULONG cbUsed; + PCCOR_SIGNATURE pbSig; + + // We know that the filter table is not null here. Tell PREFIX that we know it. + PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); + + // if Property is already marked, just return + if (m_pMiniMd->GetFilterTable()->IsPropertyMarked(pr)) + goto ErrExit; + + IfFailGo( m_pMiniMd->GetFilterTable()->MarkProperty( pr ) ); + + // marking the backing field, event changing and event changed + IfFailGo(m_pMiniMd->GetPropertyRecord(RidFromToken(pr), &pRec)); + + // Walk the signature and mark all of the embedded types + IfFailGo(m_pMiniMd->getTypeOfProperty(pRec, &pbSig, &cbSize)); + IfFailGo( MarkSignature(pbSig, cbSize, &cbUsed) ); + + // Note that we don't need to mark the MethodSemantics. Because the association of MethodSemantics + // is marked. The Method column can only store MethodDef, ie the MethodDef has the same parent as + // this Property. + + IfFailGo( MarkCustomAttributesWithParentToken(pr) ); + // IfFailGo( MarkDeclSecuritiesWithParentToken(pr) ); + +ErrExit: + return hr; +} // HRESULT FilterManager::MarkProperty() + +//***************************************************************************** +// cascading Mark of all ParamDef associated with a methoddef +//***************************************************************************** +HRESULT FilterManager::MarkParamsWithParentToken(mdMethodDef md) +{ + HRESULT hr = NOERROR; + RID ulStart, ulEnd; + RID index; + MethodRec *pMethodRec; + + IfFailGo(m_pMiniMd->GetMethodRecord(RidFromToken(md), &pMethodRec)); + + // figure out the start rid and end rid of the parameter list of this methoddef + ulStart = m_pMiniMd->getParamListOfMethod(pMethodRec); + IfFailGo(m_pMiniMd->getEndParamListOfMethod(RidFromToken(md), &ulEnd)); + for (index = ulStart; index < ulEnd; index ++ ) + { + RID rid; + IfFailGo(m_pMiniMd->GetParamRid(index, &rid)); + IfFailGo(MarkParam(TokenFromRid( + rid, + mdtParamDef))); + } +ErrExit: + return hr; +} // HRESULT FilterManager::MarkParamsWithParentToken() + + +//***************************************************************************** +// cascading Mark of all methods associated with a TypeDef token +//***************************************************************************** +HRESULT FilterManager::MarkMethodsWithParentToken(mdTypeDef td) +{ + HRESULT hr = NOERROR; + RID ulStart, ulEnd; + RID index; + TypeDefRec *pTypeDefRec; + + IfFailGo(m_pMiniMd->GetTypeDefRecord(RidFromToken(td), &pTypeDefRec)); + ulStart = m_pMiniMd->getMethodListOfTypeDef( pTypeDefRec ); + IfFailGo(m_pMiniMd->getEndMethodListOfTypeDef(RidFromToken(td), &ulEnd)); + for ( index = ulStart; index < ulEnd; index ++ ) + { + RID rid; + IfFailGo(m_pMiniMd->GetMethodRid(index, &rid)); + IfFailGo(MarkMethod(TokenFromRid( + rid, + mdtMethodDef))); + } +ErrExit: + return hr; +} // HRESULT FilterManager::MarkMethodsWithParentToken() + + +//***************************************************************************** +// cascading Mark of all MethodImpls associated with a TypeDef token +//***************************************************************************** +HRESULT FilterManager::MarkMethodImplsWithParentToken(mdTypeDef td) +{ + HRESULT hr = NOERROR; + RID index; + mdToken tkBody; + mdToken tkDecl; + MethodImplRec *pMethodImplRec; + HENUMInternal hEnum; + + // We know that the filter table is not null here. Tell PREFIX that we know it. + PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); + + memset(&hEnum, 0, sizeof(HENUMInternal)); + IfFailGo( m_pMiniMd->FindMethodImplHelper(td, &hEnum) ); + + while (HENUMInternal::EnumNext(&hEnum, (mdToken *)&index)) + { + IfFailGo(m_pMiniMd->GetMethodImplRecord(index, &pMethodImplRec)); + IfFailGo(m_pMiniMd->GetFilterTable()->MarkMethodImpl(index)); + + tkBody = m_pMiniMd->getMethodBodyOfMethodImpl(pMethodImplRec); + IfFailGo( Mark(tkBody) ); + + tkDecl = m_pMiniMd->getMethodDeclarationOfMethodImpl(pMethodImplRec); + IfFailGo( Mark(tkDecl) ); + } +ErrExit: + HENUMInternal::ClearEnum(&hEnum); + return hr; +} // HRESULT FilterManager::MarkMethodImplsWithParentToken() + + +//***************************************************************************** +// cascading Mark of all fields associated with a TypeDef token +//***************************************************************************** +HRESULT FilterManager::MarkFieldsWithParentToken(mdTypeDef td) +{ + HRESULT hr = NOERROR; + RID ulStart, ulEnd; + RID index; + TypeDefRec *pTypeDefRec; + + IfFailGo(m_pMiniMd->GetTypeDefRecord(RidFromToken(td), &pTypeDefRec)); + ulStart = m_pMiniMd->getFieldListOfTypeDef( pTypeDefRec ); + IfFailGo(m_pMiniMd->getEndFieldListOfTypeDef(RidFromToken(td), &ulEnd)); + for ( index = ulStart; index < ulEnd; index ++ ) + { + RID rid; + IfFailGo(m_pMiniMd->GetFieldRid(index, &rid)); + IfFailGo(MarkField(TokenFromRid( + rid, + mdtFieldDef))); + } +ErrExit: + return hr; +} // HRESULT FilterManager::MarkFieldsWithParentToken() + + +//***************************************************************************** +// cascading Mark of all events associated with a TypeDef token +//***************************************************************************** +HRESULT FilterManager::MarkEventsWithParentToken( + mdTypeDef td) +{ + HRESULT hr = NOERROR; + RID ridEventMap; + RID ulStart, ulEnd; + RID index; + EventMapRec *pEventMapRec; + + // get the starting/ending rid of Events of this typedef + IfFailGo(m_pMiniMd->FindEventMapFor(RidFromToken(td), &ridEventMap)); + if ( !InvalidRid(ridEventMap) ) + { + IfFailGo(m_pMiniMd->GetEventMapRecord(ridEventMap, &pEventMapRec)); + ulStart = m_pMiniMd->getEventListOfEventMap( pEventMapRec ); + IfFailGo(m_pMiniMd->getEndEventListOfEventMap(ridEventMap, &ulEnd)); + for ( index = ulStart; index < ulEnd; index ++ ) + { + RID rid; + IfFailGo(m_pMiniMd->GetEventRid(index, &rid)); + IfFailGo(MarkEvent(TokenFromRid( + rid, + mdtEvent))); + } + } +ErrExit: + return hr; +} // HRESULT FilterManager::MarkEventsWithParentToken() + + + +//***************************************************************************** +// cascading Mark of all properties associated with a TypeDef token +//***************************************************************************** +HRESULT FilterManager::MarkPropertiesWithParentToken( + mdTypeDef td) +{ + HRESULT hr = NOERROR; + RID ridPropertyMap; + RID ulStart, ulEnd; + RID index; + PropertyMapRec *pPropertyMapRec; + + // get the starting/ending rid of properties of this typedef + IfFailGo(m_pMiniMd->FindPropertyMapFor(RidFromToken(td), &ridPropertyMap)); + if ( !InvalidRid(ridPropertyMap) ) + { + IfFailGo(m_pMiniMd->GetPropertyMapRecord(ridPropertyMap, &pPropertyMapRec)); + ulStart = m_pMiniMd->getPropertyListOfPropertyMap( pPropertyMapRec ); + IfFailGo(m_pMiniMd->getEndPropertyListOfPropertyMap(ridPropertyMap, &ulEnd)); + for ( index = ulStart; index < ulEnd; index ++ ) + { + RID rid; + IfFailGo(m_pMiniMd->GetPropertyRid(index, &rid)); + IfFailGo(MarkProperty(TokenFromRid( + rid, + mdtProperty))); + } + } +ErrExit: + return hr; +} // HRESULT FilterManager::MarkPropertiesWithParentToken() + + +//***************************************************************************** +// cascading Mark of all GenericPar associated with a TypeDef or MethodDef token +//***************************************************************************** +HRESULT FilterManager::MarkGenericParamWithParentToken( + mdToken tk) +{ + HRESULT hr = NOERROR; + RID ulStart, ulEnd; + RID index; + GenericParamRec *pGenericParamRec; + mdToken constraint; + HENUMInternal hEnum; // To enumerate constraints. + + // Enumerate the GenericPar + //@todo: Handle the unsorted case. + IfFailGo( m_pMiniMd->GetGenericParamsForToken(tk, &ulStart, &ulEnd) ); + + for (; ulStart < ulEnd; ++ulStart) + { + index = m_pMiniMd->GetGenericParamRid(ulStart); + IfFailGo(m_pMiniMd->GetGenericParamRecord(index, &pGenericParamRec)); + + RID ridConstraint; + IfFailGo( m_pMiniMd->FindGenericParamConstraintHelper(TokenFromRid(ulStart, mdtGenericParam), &hEnum) ); + while (HENUMInternal::EnumNext(&hEnum, (mdToken *) &ridConstraint)) + { + // Get the constraint. + GenericParamConstraintRec *pRec; + IfFailGo(m_pMiniMd->GetGenericParamConstraintRecord(RidFromToken(ridConstraint), &pRec)); + constraint = m_pMiniMd->getConstraintOfGenericParamConstraint(pRec); + + // Mark it. + IfFailGo( Mark(constraint) ); + } + HENUMInternal::ClearEnum(&hEnum); + } + +ErrExit: + HENUMInternal::ClearEnum(&hEnum); + + return hr; +} // HRESULT FilterManager::MarkGenericParamWithParentToken() + + +//***************************************************************************** +// cascading Mark of an TypeDef token +//***************************************************************************** +HRESULT FilterManager::MarkInterfaceImpls( + mdTypeDef td) +{ + HRESULT hr = NOERROR; + ULONG ridStart, ridEnd; + ULONG i; + InterfaceImplRec *pRec; + + // We know that the filter table is not null here. Tell PREFIX that we know it. + PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); + + if ( m_pMiniMd->IsSorted(TBL_InterfaceImpl) ) + { + IfFailGo(m_pMiniMd->getInterfaceImplsForTypeDef(RidFromToken(td), &ridEnd, &ridStart)); + } + else + { + ridStart = 1; + ridEnd = m_pMiniMd->getCountInterfaceImpls() + 1; + } + + // Search for the interfaceimpl with the parent of td + for (i = ridStart; i < ridEnd; i++) + { + IfFailGo(m_pMiniMd->GetInterfaceImplRecord(i, &pRec)); + if ( td != m_pMiniMd->getClassOfInterfaceImpl(pRec) ) + continue; + + // found an InterfaceImpl associate with td. Mark the interface row and the interfaceimpl type + IfFailGo( m_pMiniMd->GetFilterTable()->MarkInterfaceImpl(TokenFromRid(i, mdtInterfaceImpl)) ); + IfFailGo( MarkCustomAttributesWithParentToken(TokenFromRid(i, mdtInterfaceImpl)) ); + // IfFailGo( MarkDeclSecuritiesWithParentToken(TokenFromRid(i, mdtInterfaceImpl)) ); + IfFailGo( Mark(m_pMiniMd->getInterfaceOfInterfaceImpl(pRec)) ); + } +ErrExit: + return hr; +} // HRESULT FilterManager::MarkInterfaceImpls() + +//***************************************************************************** +// cascading Mark of an TypeDef token +//***************************************************************************** +HRESULT FilterManager::MarkTypeDef( + mdTypeDef td) +{ + HRESULT hr = NOERROR; + TypeDefRec *pRec; + IHostFilter *pFilter = m_pMiniMd->GetHostFilter(); + DWORD dwFlags; + RID iNester; + + // We know that the filter table is not null here. Tell PREFIX that we know it. + PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); + + // if TypeDef is already marked, just return + if (m_pMiniMd->GetFilterTable()->IsTypeDefMarked(td)) + goto ErrExit; + + // Mark the TypeDef first to avoid duplicate marking + IfFailGo( m_pMiniMd->GetFilterTable()->MarkTypeDef(td) ); + if (pFilter) + pFilter->MarkToken(td); + + // We don't need to mark InterfaceImpl but we need to mark the + // TypeDef/TypeRef associated with InterfaceImpl. + IfFailGo( MarkInterfaceImpls(td) ); + + // mark the base class + IfFailGo(m_pMiniMd->GetTypeDefRecord(RidFromToken(td), &pRec)); + IfFailGo( Mark(m_pMiniMd->getExtendsOfTypeDef(pRec)) ); + + // mark all of the children of this TypeDef + IfFailGo( MarkMethodsWithParentToken(td) ); + IfFailGo( MarkMethodImplsWithParentToken(td) ); + IfFailGo( MarkFieldsWithParentToken(td) ); + IfFailGo( MarkEventsWithParentToken(td) ); + IfFailGo( MarkPropertiesWithParentToken(td) ); + + // mark any GenericParam of this TypeDef + IfFailGo( MarkGenericParamWithParentToken(td) ); + + // mark custom value and permission + IfFailGo( MarkCustomAttributesWithParentToken(td) ); + IfFailGo( MarkDeclSecuritiesWithParentToken(td) ); + + // If the class is a Nested class mark the parent, recursively. + dwFlags = m_pMiniMd->getFlagsOfTypeDef(pRec); + if (IsTdNested(dwFlags)) + { + NestedClassRec *pNestClassRec; + IfFailGo(m_pMiniMd->FindNestedClassHelper(td, &iNester)); + if (InvalidRid(iNester)) + IfFailGo(CLDB_E_RECORD_NOTFOUND); + IfFailGo(m_pMiniMd->GetNestedClassRecord(iNester, &pNestClassRec)); + IfFailGo(MarkTypeDef(m_pMiniMd->getEnclosingClassOfNestedClass(pNestClassRec))); + } + +ErrExit: + return hr; +} // HRESULT FilterManager::MarkTypeDef() + + +//***************************************************************************** +// walk signature and mark tokens embedded in the signature +//***************************************************************************** + +#define VALIDATE_SIGNATURE_LEN(x) \ + do{ cb = (x); \ + cbUsed += cb; pbSig += cb; \ + if (cbUsed > cbSig) IfFailGo(META_E_BAD_SIGNATURE); \ + }while (0) + +#define VALIDATE_SIGNATURE_LEN_HR(x) \ + do{ IfFailGo(x); \ + cbUsed += cb; pbSig += cb; \ + if (cbUsed > cbSig) IfFailGo(META_E_BAD_SIGNATURE); \ + }while (0) + +HRESULT FilterManager::MarkSignature( + PCCOR_SIGNATURE pbSig, // [IN] point to the current byte to visit in the signature + ULONG cbSig, // [IN] count of bytes available. + ULONG *pcbUsed) // [OUT] count of bytes consumed. +{ + HRESULT hr = NOERROR; // A result. + ULONG cArg = 0; // count of arguments in the signature + ULONG cTypes = 0; // Count of argument types in the signature. + ULONG cb; // Bytes used in a sig element. + ULONG cbUsed = 0; // Total bytes consumed. + ULONG callingconv = IMAGE_CEE_CS_CALLCONV_MAX; + + // calling convention + VALIDATE_SIGNATURE_LEN( CorSigUncompressData(pbSig, &callingconv) ); + + if ((callingconv & IMAGE_CEE_CS_CALLCONV_MASK) >= IMAGE_CEE_CS_CALLCONV_MAX) + IfFailGo(META_E_BAD_SIGNATURE); + + // Field signature is a single element. + if (isCallConv(callingconv, IMAGE_CEE_CS_CALLCONV_FIELD)) + { + // It is a FieldDef + VALIDATE_SIGNATURE_LEN_HR( MarkFieldSignature(pbSig, cbSig - cbUsed, &cb) ); + } + else + { + // If Generic call, get count of type parameters. + //@TODO: where are the type params? + if (callingconv & IMAGE_CEE_CS_CALLCONV_GENERIC) + { + VALIDATE_SIGNATURE_LEN( CorSigUncompressData(pbSig, &cTypes) ); + } + + // Count of arguments passed in call. + VALIDATE_SIGNATURE_LEN( CorSigUncompressData(pbSig, &cArg) ); + + // Mark the return type, if there is one (LocalVarSig and GenericInst don't have return types). + if ( !( isCallConv(callingconv, IMAGE_CEE_CS_CALLCONV_LOCAL_SIG) || isCallConv(callingconv, IMAGE_CEE_CS_CALLCONV_GENERICINST)) ) + { // process the return type + VALIDATE_SIGNATURE_LEN_HR( MarkFieldSignature(pbSig, cbSig - cbUsed, &cb) ); + } + + // Iterate over the arguments, and mark each one. + while (cArg--) + { + VALIDATE_SIGNATURE_LEN_HR( MarkFieldSignature(pbSig, cbSig - cbUsed, &cb) ); + } + } + +ErrExit: + *pcbUsed = cbUsed; + return hr; +} // HRESULT FilterManager::MarkSignature() + + +//***************************************************************************** +// walk one type and mark tokens embedded in the signature +//***************************************************************************** +HRESULT FilterManager::MarkFieldSignature( + PCCOR_SIGNATURE pbSig, // [IN] point to the current byte to visit in the signature + ULONG cbSig, // [IN] count of bytes available. + ULONG *pcbUsed) // [OUT] count of bytes consumed. +{ + HRESULT hr = NOERROR; // A result. + ULONG cb; // Bytes in one signature element. + ULONG cbUsed = 0; // Total bytes consumed from signature. + CorElementType ulElementType; // ELEMENT_TYPE_xxx from signature. + ULONG ulData; // Some data (like a count) from the signature. + ULONG ulTemp; // Unused data. + mdToken token; // A token from the signature. + int iData; // Integer data from signature. + + VALIDATE_SIGNATURE_LEN( CorSigUncompressElementType(pbSig, &ulElementType) ); + + // Skip the modifiers... + while (CorIsModifierElementType((CorElementType) ulElementType)) + { + VALIDATE_SIGNATURE_LEN( CorSigUncompressElementType(pbSig, &ulElementType) ); + } + + // Examine the signature element + switch (ulElementType) + { + case ELEMENT_TYPE_SZARRAY: + // syntax: SZARRAY <BaseType> + + // conver the base type for the SZARRAY or GENERICARRAY + VALIDATE_SIGNATURE_LEN_HR( MarkFieldSignature(pbSig, cbSig - cbUsed, &cb) ); + break; + + case ELEMENT_TYPE_CMOD_REQD: + case ELEMENT_TYPE_CMOD_OPT: + // syntax: {CMOD_REQD|CMOD_OPT} <token> <signature> + + // now get the embedded token + VALIDATE_SIGNATURE_LEN( CorSigUncompressToken(pbSig, &token) ); + + // Mark the token + IfFailGo( Mark(token) ); + + // mark the base type + VALIDATE_SIGNATURE_LEN_HR( MarkFieldSignature(pbSig, cbSig - cbUsed, &cb) ); + break; + + case ELEMENT_TYPE_VAR: + case ELEMENT_TYPE_MVAR: + // syntax: VAR <index> + VALIDATE_SIGNATURE_LEN( CorSigUncompressData(pbSig, &ulData) ); + break; + + case ELEMENT_TYPE_ARRAY: + // syntax: ARRAY BaseType <rank> [i size_1... size_i] [j lowerbound_1 ... lowerbound_j] + + VALIDATE_SIGNATURE_LEN_HR( MarkFieldSignature(pbSig, cbSig - cbUsed, &cb) ); + + // Parse for the rank + VALIDATE_SIGNATURE_LEN( CorSigUncompressData(pbSig, &ulData) ); + + // if rank == 0, we are done + if (ulData == 0) + break; + + // Any size of dimension specified? + VALIDATE_SIGNATURE_LEN( CorSigUncompressData(pbSig, &ulData) ); + + // Consume sizes of dimension. + while (ulData--) + { + VALIDATE_SIGNATURE_LEN( CorSigUncompressData(pbSig, &ulTemp) ); + } + + // Any lower bounds specified? + VALIDATE_SIGNATURE_LEN( CorSigUncompressData(pbSig, &ulData) ); + + // Consume lower bounds. + while (ulData--) + { + VALIDATE_SIGNATURE_LEN( CorSigUncompressSignedInt(pbSig, &iData) ); + } + + break; + + case ELEMENT_TYPE_FNPTR: + // function pointer is followed by another complete signature + VALIDATE_SIGNATURE_LEN_HR( MarkSignature(pbSig, cbSig - cbUsed, &cb) ); + break; + + case ELEMENT_TYPE_VALUETYPE: + case ELEMENT_TYPE_CLASS: + // syntax: {CLASS | VALUECLASS} <token> + VALIDATE_SIGNATURE_LEN( CorSigUncompressToken(pbSig, &token) ); + + // Mark it. + IfFailGo( Mark(token) ); + break; + + case ELEMENT_TYPE_GENERICINST: + // syntax: ELEMENT_TYPE_GEENRICINST <ELEMENT_TYPE_CLASS | ELEMENT_TYPE_VALUECLASS> <token> <n> <n params> + VALIDATE_SIGNATURE_LEN_HR( MarkFieldSignature(pbSig, cbSig - cbUsed, &cb) ); + + // Get the number of generic parameters + VALIDATE_SIGNATURE_LEN( CorSigUncompressData(pbSig, &ulData) ); + + // Get the generic parameters + while (ulData--) + { + VALIDATE_SIGNATURE_LEN_HR( MarkFieldSignature(pbSig, cbSig - cbUsed, &cb) ); + } + break; + + default: + // If valid element (I4, etc), great. Otherwise, return error. + if ((ulElementType >= ELEMENT_TYPE_MAX) || + (ulElementType == ELEMENT_TYPE_PTR) || + (ulElementType == ELEMENT_TYPE_BYREF) || + (ulElementType == ELEMENT_TYPE_VALUEARRAY_UNSUPPORTED)) + { + IfFailGo(META_E_BAD_SIGNATURE); + } + break; + } + +ErrExit: + *pcbUsed = cbUsed; + return hr; +} // HRESULT FilterManager::MarkFieldSignature() + + + +//***************************************************************************** +// +// Unmark the TypeDef +// +//***************************************************************************** +HRESULT FilterManager::UnmarkTypeDef( + mdTypeDef td) +{ + HRESULT hr = NOERROR; + TypeDefRec *pTypeDefRec; + RID ridStart, ridEnd; + RID index; + CustomAttributeRec *pCARec; + + // We know that the filter table is not null here. Tell PREFIX that we know it. + PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL); + + // if TypeDef is already unmarked, just return + if (m_pMiniMd->GetFilterTable()->IsTypeDefMarked(td) == false) + goto ErrExit; + + // Mark the TypeDef first to avoid duplicate marking + IfFailGo( m_pMiniMd->GetFilterTable()->UnmarkTypeDef(td) ); + + // Don't need to unmark InterfaceImpl because the TypeDef is unmarked that will make + // the InterfaceImpl automatically unmarked. + + // unmark all of the children of this TypeDef + IfFailGo(m_pMiniMd->GetTypeDefRecord(RidFromToken(td), &pTypeDefRec)); + + // unmark the methods + ridStart = m_pMiniMd->getMethodListOfTypeDef(pTypeDefRec); + IfFailGo(m_pMiniMd->getEndMethodListOfTypeDef(RidFromToken(td), &ridEnd)); + for ( index = ridStart; index < ridEnd; index ++ ) + { + RID rid; + IfFailGo(m_pMiniMd->GetMethodRid(index, &rid)); + IfFailGo(m_pMiniMd->GetFilterTable()->UnmarkMethod(TokenFromRid( + rid, + mdtMethodDef))); + } + + // unmark the fields + ridStart = m_pMiniMd->getFieldListOfTypeDef(pTypeDefRec); + IfFailGo(m_pMiniMd->getEndFieldListOfTypeDef(RidFromToken(td), &ridEnd)); + for ( index = ridStart; index < ridEnd; index ++ ) + { + RID rid; + IfFailGo(m_pMiniMd->GetFieldRid(index, &rid)); + IfFailGo(m_pMiniMd->GetFilterTable()->UnmarkField(TokenFromRid( + rid, + mdtFieldDef))); + } + + // unmark custom value + if ( m_pMiniMd->IsSorted( TBL_CustomAttribute ) ) + { + // table is sorted. ridStart to ridEnd - 1 are all CustomAttribute + // associated with tkParent + // + IfFailGo(m_pMiniMd->getCustomAttributeForToken(td, &ridEnd, &ridStart)); + for (index = ridStart; index < ridEnd; index ++ ) + { + IfFailGo( m_pMiniMd->GetFilterTable()->UnmarkCustomAttribute( TokenFromRid(index, mdtCustomAttribute) ) ); + } + } + else + { + // table scan is needed + ridStart = 1; + ridEnd = m_pMiniMd->getCountCustomAttributes() + 1; + for (index = ridStart; index < ridEnd; index ++ ) + { + IfFailGo(m_pMiniMd->GetCustomAttributeRecord(index, &pCARec)); + if ( td == m_pMiniMd->getParentOfCustomAttribute(pCARec) ) + { + // This CustomAttribute is associated with tkParent + IfFailGo( m_pMiniMd->GetFilterTable()->UnmarkCustomAttribute( TokenFromRid(index, mdtCustomAttribute) ) ); + } + } + } + + // We don't support nested type!! + +ErrExit: + return hr; + +} // HRESULT FilterManager::UnmarkTypeDef() + + |