internal ExportedTypeRow( TypeDefFlags typeDefFlags, uint typeDefId, uint typeName, uint typeNamespace, uint implementation) { this.Flags = typeDefFlags; this.TypeDefId = typeDefId; this.TypeName = typeName; this.TypeNamespace = typeNamespace; this.Implementation = implementation; }
internal TypeDefRow( TypeDefFlags flags, uint name, uint @namespace, uint extends, uint fieldList, uint methodList) { this.Flags = flags; this.Name = name; this.Namespace = @namespace; this.Extends = extends; this.FieldList = fieldList; this.MethodList = methodList; }
private static bool ShouldFixUpCLRViewClassOrEnum( IName typeName, TypeDefFlags typeDefFlags ) { return (typeDefFlags & TypeDefFlags.PrivateAccess) == TypeDefFlags.PrivateAccess && // By design, managed winmd classes should always be sealed - however, a bug in winmdexp.exe allows non-sealed // managed winmd classes to be created if the class does not have a public constructor - see bug 188518. So we // skip the check for the sealed flag here in order to avoid breaking any apps that already depend on this // winmdexp.exe bug. This matches the CLR which also doesn't check for the sealed flag when fixing up // managed winmd types (see ndp\clr\src\md\winmd\adapter.cpp). // (typeDefFlags & TypeDefFlags.SealedSemantics) == TypeDefFlags.SealedSemantics && (typeDefFlags & TypeDefFlags.SpecialNameSemantics) == TypeDefFlags.SpecialNameSemantics && typeName.Value.StartsWith(PREFIX_CLR, StringComparison.Ordinal); }
private bool ShouldFixUpWinRTViewClassOrEnum( IAssemblyReference containingUnitMscorlibReference, IName baseTypeNamespaceName, IName baseTypeName, TypeDefFlags typeDefFlags ) { if ((typeDefFlags & TypeDefFlags.PublicAccess) == TypeDefFlags.PublicAccess && // By design, managed winmd classes should always be sealed - however, a bug in winmdexp.exe allows non-sealed // managed winmd classes to be created if the class does not have a public constructor - see bug 188518. So we // skip the check for the sealed flag here in order to avoid breaking any apps that already depend on this // winmdexp.exe bug. This matches the CLR which also doesn't check for the sealed flag when fixing up // managed winmd types (see ndp\clr\src\md\winmd\adapter.cpp). // (typeDefFlags & TypeDefFlags.SealedSemantics) == TypeDefFlags.SealedSemantics && (typeDefFlags & TypeDefFlags.IsForeign) == TypeDefFlags.IsForeign && (typeDefFlags & TypeDefFlags.InterfaceSemantics) != TypeDefFlags.InterfaceSemantics && // Not an interface !(baseTypeNamespaceName.Value == "System" && baseTypeName.Value == "ValueType") && // Not a struct !(baseTypeNamespaceName.Value == "System" && baseTypeName.Value == "MulticastDelegate") && // Not a delegate !(baseTypeNamespaceName.Value == "System" && baseTypeName.Value == "Attribute")) { // Not an attribute // We have a managed winmd class or an enum in WinRT view. bool isEnum = baseTypeNamespaceName.Value == "System" && baseTypeName.Value == "Enum"; bool referencesMscorlibv4 = containingUnitMscorlibReference != null && !(containingUnitMscorlibReference is Dummy) && containingUnitMscorlibReference.Version.Major == 4; bool isSpecialName = (typeDefFlags & TypeDefFlags.SpecialNameSemantics) == TypeDefFlags.SpecialNameSemantics; if (isEnum && referencesMscorlibv4 && !isSpecialName) { // This is a back-compat quirk. Managed winmd enums exported with an older WinMDExp.exe have only one view (i.e. no // corresponding <CLR> enum). These enums should *not* be mangled with a <WinRT> prefix and flipped to private. // The only way to check whether the older WinMDExp was used is to check the version of the mscorlib referenced // by the managed winmd (if referenced mscorlib has version 4.0 then the winmd was produced using the older WinMDExp - // otherwise (if the referenced mscorlib has version 255.255.255.255) then the winmd was produced using newer WinMDExp). // These checks are basically a copy of the checks in the CLR (see ndp\clr\src\md\winmd\adapter.cpp). return false; } return true; } return false; }
private void FixUpNameAndFlagsForManagedWinMDClassOrEnum( IUnit containingUnit, IAssemblyReference containingUnitMscorlibReference, IName baseTypeNamespaceName, IName baseTypeName, ref IName typeName, ref TypeDefFlags typeDefFlags ) { if (this.projectToCLRTypes && IsManagedWinMD(containingUnit)) { if (ShouldFixUpWinRTViewClassOrEnum(containingUnitMscorlibReference, baseTypeNamespaceName, baseTypeName, typeDefFlags)) { typeName = NameTable.GetNameFor(PREFIX_WINRT + typeName.Value); typeDefFlags = (typeDefFlags & ~TypeDefFlags.AccessMask) | TypeDefFlags.PrivateAccess; // NOTE: Ildasm /project also adds the following "import" flag on <WinRT> types - however, we omit this since // this is not required so far as .net native toolchain and mcg goes. This also avoids having to add special // case code to avoid treating this type as a real COM type in the reduced copy transform (see isComImport // check in ReducedCopyReferenceEngine.cs). // typeDefFlags = typeDefFlags | TypeDefFlags.ImportImplementation; } else if (ShouldFixUpCLRViewClassOrEnum(typeName, typeDefFlags)) { typeName = NameTable.GetNameFor(typeName.Value.Substring(PREFIX_CLR_LENGTH)); typeDefFlags = (typeDefFlags & ~TypeDefFlags.AccessMask) | TypeDefFlags.PublicAccess; typeDefFlags = typeDefFlags & ~TypeDefFlags.SpecialNameSemantics; } } }
// Fixes up names and flags for managed winmd classes if projection support is enabled in the host. // - CLR view classes and enums in managed winmds lose the '<CLR>' prefix in their name and become public. // - WinRT view classes and enums in managed winmds get a '<WinRT>' prefix in their name and become private. // This is identical to the behavior one sees when one uses ildasm's "/project" option to view the contents // of a managed winmd. void IWindowsRuntimeMetadataReaderHost.FixUpNameAndFlagsForManagedWinMDClassOrEnum( PEFileToObjectModel peFileToObjectModel, uint typeDefRowId, IUnit containingUnit, ref IName typeName, ref TypeDefFlags flags ) { IWindowsRuntimeMetadataReaderHost host = peFileToObjectModel.ModuleReader.metadataReaderHost as WindowsRuntimeMetadataReaderHost; if (this.projectToCLRTypes) { IName baseTypeNamespaceName = null; IName baseTypeName = null; uint baseTypeToken = peFileToObjectModel.PEFileReader.TypeDefTable.GetExtends(typeDefRowId); uint baseTypeRowId = baseTypeToken & TokenTypeIds.RIDMask; if (baseTypeRowId != 0) { uint tokenType = baseTypeToken & TokenTypeIds.TokenTypeMask; switch(tokenType) { case TokenTypeIds.TypeDef: TypeDefRow baseTypeDefRow = peFileToObjectModel.PEFileReader.TypeDefTable[baseTypeRowId]; baseTypeNamespaceName = peFileToObjectModel.GetNameFromOffset(baseTypeDefRow.Namespace); baseTypeName = peFileToObjectModel.GetNameFromOffset(baseTypeDefRow.Name); break; case TokenTypeIds.TypeRef: TypeRefRow baseTypeRefRow = peFileToObjectModel.PEFileReader.TypeRefTable[baseTypeRowId]; baseTypeNamespaceName = peFileToObjectModel.GetNameFromOffset(baseTypeRefRow.Namespace); baseTypeName = peFileToObjectModel.GetNameFromOffset(baseTypeRefRow.Name); break; case TokenTypeIds.TypeSpec: // We don't care about TypeSpecs because managed winmd types can never inherit generic types. default: break; } if (baseTypeName != null) { IAssemblyReference containingUnitMscorlibReference = peFileToObjectModel.GetMscorlibReference(); this.FixUpNameAndFlagsForManagedWinMDClassOrEnum(containingUnit, containingUnitMscorlibReference, baseTypeNamespaceName, baseTypeName, ref typeName, ref flags); } } } }