Example #1
0
        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);
            }
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }