private static EETypeElementType ComputeEETypeElementType(TypeDesc type) { // Enums are represented as their underlying type type = type.UnderlyingType; if (type.IsWellKnownType(WellKnownType.Array)) { // SystemArray is a special EETypeElementType that doesn't exist in TypeFlags return(EETypeElementType.SystemArray); } else { // The rest of TypeFlags should be directly castable to EETypeElementType. // Spot check the enums match. Debug.Assert((int)TypeFlags.Void == (int)EETypeElementType.Void); Debug.Assert((int)TypeFlags.IntPtr == (int)EETypeElementType.IntPtr); Debug.Assert((int)TypeFlags.Single == (int)EETypeElementType.Single); Debug.Assert((int)TypeFlags.UInt32 == (int)EETypeElementType.UInt32); Debug.Assert((int)TypeFlags.Pointer == (int)EETypeElementType.Pointer); Debug.Assert((int)TypeFlags.Array == (int)EETypeElementType.Array); EETypeElementType elementType = (EETypeElementType)type.Category; // Would be surprising to get these here though. Debug.Assert(elementType != EETypeElementType.SystemArray); Debug.Assert(elementType <= EETypeElementType.Pointer); return(elementType); } }
protected override TypeFlags ComputeTypeFlags(TypeFlags mask) { TypeFlags flags = 0; if ((mask & TypeFlags.CategoryMask) != 0) { unsafe { EEType * eetype = _genericTypeDefinition.ToEETypePtr(); EETypeElementType elementType = eetype->ElementType; if (elementType == EETypeElementType.SystemArray) { // System.Array is a regular class in the type system flags |= TypeFlags.Class; } else if (elementType <= EETypeElementType.Double && (eetype->IsGenericTypeDefinition || eetype->BaseType == typeof(System.Enum).TypeHandle.ToEETypePtr())) { // Enums are represented as their underlying type in the runtime type system // Note: we check for IsGenericDefinition above to cover generic enums (base types are not set // on generic definition EEType) flags |= TypeFlags.Enum; } else { // Paranoid check that we handled enums above Debug.Assert(eetype->IsGenericTypeDefinition || eetype->BaseType != typeof(System.Enum).TypeHandle.ToEETypePtr()); // The rest of values should be directly castable to TypeFlags Debug.Assert((int)EETypeElementType.Void == (int)TypeFlags.Void); Debug.Assert((int)EETypeElementType.Int32 == (int)TypeFlags.Int32); Debug.Assert((int)EETypeElementType.IntPtr == (int)TypeFlags.IntPtr); Debug.Assert((int)EETypeElementType.Double == (int)TypeFlags.Double); Debug.Assert((int)EETypeElementType.Pointer == (int)TypeFlags.Pointer); Debug.Assert((int)EETypeElementType.Class == (int)TypeFlags.Class); Debug.Assert((int)EETypeElementType.Nullable == (int)TypeFlags.Nullable); flags |= (TypeFlags)elementType; } } } if ((mask & TypeFlags.AttributeCacheComputed) != 0) { flags |= TypeFlags.AttributeCacheComputed; unsafe { EEType *eetype = _genericTypeDefinition.ToEETypePtr(); if (eetype->IsByRefLike) { flags |= TypeFlags.IsByRefLike; } } } return(flags); }
public static UInt16 ComputeElementTypeFlags(TypeDesc type) { UInt16 flags = 0; // The top 5 bits of flags are used to convey enum underlying type, primitive type, or mark the type as being System.Array EETypeElementType elementType = ComputeEETypeElementType(type); flags |= (UInt16)((UInt16)elementType << (UInt16)EETypeFlags.ElementTypeShift); return(flags); }
public static ushort ComputeFlags(TypeDesc type) { ushort flags = type.IsParameterizedType ? (ushort)EETypeKind.ParameterizedEEType : (ushort)EETypeKind.CanonicalEEType; // The top 5 bits of flags are used to convey enum underlying type, primitive type, or mark the type as being System.Array EETypeElementType elementType = ComputeEETypeElementType(type); flags |= (ushort)((ushort)elementType << (ushort)EETypeFlags.ElementTypeShift); if (type.IsGenericDefinition) { flags |= (ushort)EETypeKind.GenericTypeDefEEType; // Generic type definition EETypes don't set the other flags. return(flags); } if (type.HasFinalizer) { flags |= (ushort)EETypeFlags.HasFinalizerFlag; } if (type.IsDefType && !type.IsCanonicalSubtype(CanonicalFormKind.Universal) && ((DefType)type).ContainsGCPointers) { flags |= (ushort)EETypeFlags.HasPointersFlag; } else if (type.IsArray && !type.IsCanonicalSubtype(CanonicalFormKind.Universal)) { var arrayElementType = ((ArrayType)type).ElementType; if ((arrayElementType.IsValueType && ((DefType)arrayElementType).ContainsGCPointers) || arrayElementType.IsGCPointer) { flags |= (ushort)EETypeFlags.HasPointersFlag; } } if (type.HasInstantiation) { flags |= (ushort)EETypeFlags.IsGenericFlag; if (type.HasVariance) { flags |= (ushort)EETypeFlags.GenericVarianceFlag; } } return(flags); }