Exemple #1
0
        public TypeManager()
        {
            _predefTypes = null; // Initialized via the Init call.
            _BSymmgr = null; // Initialized via the Init call.
            _typeFactory = new TypeFactory();
            _typeTable = new TypeTable();

            // special types with their own symbol kind.
            _errorType = _typeFactory.CreateError(null, null, null, null, null);
            _voidType = _typeFactory.CreateVoid();
            _nullType = _typeFactory.CreateNull();
            _typeUnit = _typeFactory.CreateUnit();
            _typeAnonMeth = _typeFactory.CreateAnonMethod();
            _typeMethGrp = _typeFactory.CreateMethodGroup();
            _argListType = _typeFactory.CreateArgList();

            InitType(_errorType);
            _errorType.SetErrors(true);

            InitType(_voidType);
            InitType(_nullType);
            InitType(_typeUnit);
            InitType(_typeAnonMeth);
            InitType(_typeMethGrp);

            _stvcMethod = new StdTypeVarColl();
            _stvcClass = new StdTypeVarColl();
        }
Exemple #2
0
        public ErrorType CreateError(
            Name name,
            CType parent,
            AssemblyQualifiedNamespaceSymbol pParentNS,
            Name nameText,
            TypeArray typeArgs)
        {
            ErrorType e = new ErrorType();
            e.SetName(name);
            e.nameText = nameText;
            e.typeArgs = typeArgs;
            e.SetTypeParent(parent);
            e.SetNSParent(pParentNS);

            e.SetTypeKind(TypeKind.TK_ErrorType);
            return e;
        }
Exemple #3
0
        public static bool TypeContainsTyVars(CType type, TypeArray typeVars)
        {
LRecurse:   // Label used for "tail" recursion.
            switch (type.GetTypeKind())
            {
            default:
                Debug.Assert(false, "Bad Symbol kind in TypeContainsTyVars");
                return(false);

            case TypeKind.TK_NullType:
            case TypeKind.TK_VoidType:
            case TypeKind.TK_OpenTypePlaceholderType:
            case TypeKind.TK_MethodGroupType:
                return(false);

            case TypeKind.TK_ArrayType:
            case TypeKind.TK_NullableType:
            case TypeKind.TK_ParameterModifierType:
            case TypeKind.TK_PointerType:
                type = type.GetBaseOrParameterOrElementType();
                goto LRecurse;

            case TypeKind.TK_AggregateType:
            {         // BLOCK
                AggregateType ats = (AggregateType)type;

                for (int i = 0; i < ats.GetTypeArgsAll().Count; i++)
                {
                    if (TypeContainsTyVars(ats.GetTypeArgsAll()[i], typeVars))
                    {
                        return(true);
                    }
                }
            }
                return(false);

            case TypeKind.TK_ErrorType:
                ErrorType err = (ErrorType)type;
                if (err.HasParent())
                {
                    Debug.Assert(err.nameText != null && err.typeArgs != null);

                    for (int i = 0; i < err.typeArgs.Count; i++)
                    {
                        if (TypeContainsTyVars(err.typeArgs[i], typeVars))
                        {
                            return(true);
                        }
                    }
                    if (err.HasTypeParent())
                    {
                        type = err.GetTypeParent();
                        goto LRecurse;
                    }
                }
                return(false);

            case TypeKind.TK_TypeParameterType:
                if (typeVars != null && typeVars.Count > 0)
                {
                    int ivar = ((TypeParameterType)type).GetIndexInTotalParameters();
                    return(ivar < typeVars.Count && type == typeVars[ivar]);
                }
                return(true);
            }
        }
Exemple #4
0
        public static bool TypeContainsType(CType type, CType typeFind)
        {
LRecurse:   // Label used for "tail" recursion.

            if (type == typeFind || type.Equals(typeFind))
            {
                return(true);
            }

            switch (type.GetTypeKind())
            {
            default:
                Debug.Assert(false, "Bad Symbol kind in TypeContainsType");
                return(false);

            case TypeKind.TK_NullType:
            case TypeKind.TK_VoidType:
            case TypeKind.TK_OpenTypePlaceholderType:
                // There should only be a single instance of these.
                Debug.Assert(typeFind.GetTypeKind() != type.GetTypeKind());
                return(false);

            case TypeKind.TK_ArrayType:
            case TypeKind.TK_NullableType:
            case TypeKind.TK_ParameterModifierType:
            case TypeKind.TK_PointerType:
                type = type.GetBaseOrParameterOrElementType();
                goto LRecurse;

            case TypeKind.TK_AggregateType:
            {         // BLOCK
                AggregateType ats = (AggregateType)type;

                for (int i = 0; i < ats.GetTypeArgsAll().Count; i++)
                {
                    if (TypeContainsType(ats.GetTypeArgsAll()[i], typeFind))
                    {
                        return(true);
                    }
                }
            }
                return(false);

            case TypeKind.TK_ErrorType:
                ErrorType err = (ErrorType)type;
                if (err.HasParent())
                {
                    Debug.Assert(err.nameText != null && err.typeArgs != null);

                    for (int i = 0; i < err.typeArgs.Count; i++)
                    {
                        if (TypeContainsType(err.typeArgs[i], typeFind))
                        {
                            return(true);
                        }
                    }
                    if (err.HasTypeParent())
                    {
                        type = err.GetTypeParent();
                        goto LRecurse;
                    }
                }
                return(false);

            case TypeKind.TK_TypeParameterType:
                return(false);
            }
        }
Exemple #5
0
        private bool SubstEqualTypesCore(CType typeDst, CType typeSrc, SubstContext pctx)
        {
LRecurse:   // Label used for "tail" recursion.

            if (typeDst == typeSrc || typeDst.Equals(typeSrc))
            {
                return(true);
            }

            switch (typeSrc.GetTypeKind())
            {
            default:
                Debug.Assert(false, "Bad Symbol kind in SubstEqualTypesCore");
                return(false);

            case TypeKind.TK_NullType:
            case TypeKind.TK_VoidType:
            case TypeKind.TK_OpenTypePlaceholderType:
                // There should only be a single instance of these.
                Debug.Assert(typeDst.GetTypeKind() != typeSrc.GetTypeKind());
                return(false);

            case TypeKind.TK_ArrayType:
                ArrayType arrSrc = (ArrayType)typeSrc;
                if (!(typeDst is ArrayType arrDst) || arrDst.rank != arrSrc.rank || arrDst.IsSZArray != arrSrc.IsSZArray)
                {
                    return(false);
                }
                goto LCheckBases;

            case TypeKind.TK_ParameterModifierType:
                if (!(typeDst is ParameterModifierType modDest) ||
                    ((pctx.grfst & SubstTypeFlags.NoRefOutDifference) == 0 &&
                     modDest.isOut != ((ParameterModifierType)typeSrc).isOut))
                {
                    return(false);
                }
                goto LCheckBases;

            case TypeKind.TK_PointerType:
            case TypeKind.TK_NullableType:
                if (typeDst.GetTypeKind() != typeSrc.GetTypeKind())
                {
                    return(false);
                }
LCheckBases:
                typeSrc = typeSrc.GetBaseOrParameterOrElementType();
                typeDst = typeDst.GetBaseOrParameterOrElementType();
                goto LRecurse;

            case TypeKind.TK_AggregateType:
                if (!(typeDst is AggregateType atsDst))
                {
                    return(false);
                }
                {     // BLOCK
                    AggregateType atsSrc = (AggregateType)typeSrc;

                    if (atsSrc.getAggregate() != atsDst.getAggregate())
                    {
                        return(false);
                    }

                    Debug.Assert(atsSrc.GetTypeArgsAll().Count == atsDst.GetTypeArgsAll().Count);

                    // All the args must unify.
                    for (int i = 0; i < atsSrc.GetTypeArgsAll().Count; i++)
                    {
                        if (!SubstEqualTypesCore(atsDst.GetTypeArgsAll()[i], atsSrc.GetTypeArgsAll()[i], pctx))
                        {
                            return(false);
                        }
                    }
                }
                return(true);

            case TypeKind.TK_ErrorType:
                ErrorType errSrc = (ErrorType)typeSrc;
                if (!(typeDst is ErrorType errDst) || !errSrc.HasParent() || !errDst.HasParent())
                {
                    return(false);
                }
                {
                    Debug.Assert(errSrc.nameText != null && errSrc.typeArgs != null);
                    Debug.Assert(errDst.nameText != null && errDst.typeArgs != null);

                    if (errSrc.nameText != errDst.nameText || errSrc.typeArgs.Count != errDst.typeArgs.Count)
                    {
                        return(false);
                    }

                    if (errSrc.HasTypeParent() != errDst.HasTypeParent())
                    {
                        return(false);
                    }
                    if (errSrc.HasTypeParent())
                    {
                        if (errSrc.GetTypeParent() != errDst.GetTypeParent())
                        {
                            return(false);
                        }
                        if (!SubstEqualTypesCore(errDst.GetTypeParent(), errSrc.GetTypeParent(), pctx))
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        if (errSrc.GetNSParent() != errDst.GetNSParent())
                        {
                            return(false);
                        }
                    }

                    // All the args must unify.
                    for (int i = 0; i < errSrc.typeArgs.Count; i++)
                    {
                        if (!SubstEqualTypesCore(errDst.typeArgs[i], errSrc.typeArgs[i], pctx))
                        {
                            return(false);
                        }
                    }
                }
                return(true);

            case TypeKind.TK_TypeParameterType:
            {         // BLOCK
                TypeParameterSymbol tvs = ((TypeParameterType)typeSrc).GetTypeParameterSymbol();
                int index = tvs.GetIndexInTotalParameters();

                if (tvs.IsMethodTypeParameter())
                {
                    if ((pctx.grfst & SubstTypeFlags.DenormMeth) != 0 && tvs.parent != null)
                    {
                        // typeDst == typeSrc was handled above.
                        Debug.Assert(typeDst != typeSrc);
                        return(false);
                    }
                    Debug.Assert(tvs.GetIndexInOwnParameters() == tvs.GetIndexInTotalParameters());
                    Debug.Assert(pctx.prgtypeMeth == null || tvs.GetIndexInTotalParameters() < pctx.ctypeMeth);
                    if (index < pctx.ctypeMeth && pctx.prgtypeMeth != null)
                    {
                        return(typeDst == pctx.prgtypeMeth[index]);
                    }
                    if ((pctx.grfst & SubstTypeFlags.NormMeth) != 0)
                    {
                        return(typeDst == GetStdMethTypeVar(index));
                    }
                }
                else
                {
                    if ((pctx.grfst & SubstTypeFlags.DenormClass) != 0 && tvs.parent != null)
                    {
                        // typeDst == typeSrc was handled above.
                        Debug.Assert(typeDst != typeSrc);
                        return(false);
                    }
                    Debug.Assert(pctx.prgtypeCls == null || tvs.GetIndexInTotalParameters() < pctx.ctypeCls);
                    if (index < pctx.ctypeCls)
                    {
                        return(typeDst == pctx.prgtypeCls[index]);
                    }
                    if ((pctx.grfst & SubstTypeFlags.NormClass) != 0)
                    {
                        return(typeDst == GetStdClsTypeVar(index));
                    }
                }
            }
                return(false);
            }
        }
Exemple #6
0
        private CType SubstTypeCore(CType type, SubstContext pctx)
        {
            CType typeSrc;
            CType typeDst;

            switch (type.GetTypeKind())
            {
            default:
                Debug.Assert(false);
                return(type);

            case TypeKind.TK_NullType:
            case TypeKind.TK_VoidType:
            case TypeKind.TK_OpenTypePlaceholderType:
            case TypeKind.TK_MethodGroupType:
            case TypeKind.TK_ArgumentListType:
                return(type);

            case TypeKind.TK_ParameterModifierType:
                ParameterModifierType mod = (ParameterModifierType)type;
                typeDst = SubstTypeCore(typeSrc = mod.GetParameterType(), pctx);
                return((typeDst == typeSrc) ? type : GetParameterModifier(typeDst, mod.isOut));

            case TypeKind.TK_ArrayType:
                var arr = (ArrayType)type;
                typeDst = SubstTypeCore(typeSrc = arr.GetElementType(), pctx);
                return((typeDst == typeSrc) ? type : GetArray(typeDst, arr.rank, arr.IsSZArray));

            case TypeKind.TK_PointerType:
                typeDst = SubstTypeCore(typeSrc = ((PointerType)type).GetReferentType(), pctx);
                return((typeDst == typeSrc) ? type : GetPointer(typeDst));

            case TypeKind.TK_NullableType:
                typeDst = SubstTypeCore(typeSrc = ((NullableType)type).GetUnderlyingType(), pctx);
                return((typeDst == typeSrc) ? type : GetNullable(typeDst));

            case TypeKind.TK_AggregateType:
                AggregateType ats = (AggregateType)type;
                if (ats.GetTypeArgsAll().Count > 0)
                {
                    TypeArray typeArgs = SubstTypeArray(ats.GetTypeArgsAll(), pctx);
                    if (ats.GetTypeArgsAll() != typeArgs)
                    {
                        return(GetAggregate(ats.getAggregate(), typeArgs));
                    }
                }
                return(type);

            case TypeKind.TK_ErrorType:
                ErrorType err = (ErrorType)type;
                if (err.HasParent())
                {
                    Debug.Assert(err.nameText != null && err.typeArgs != null);

                    CType pParentType = null;
                    if (err.HasTypeParent())
                    {
                        pParentType = SubstTypeCore(err.GetTypeParent(), pctx);
                    }

                    TypeArray typeArgs = SubstTypeArray(err.typeArgs, pctx);
                    if (typeArgs != err.typeArgs || (err.HasTypeParent() && pParentType != err.GetTypeParent()))
                    {
                        return(GetErrorType(pParentType, err.GetNSParent(), err.nameText, typeArgs));
                    }
                }
                return(type);

            case TypeKind.TK_TypeParameterType:
            {
                TypeParameterSymbol tvs = ((TypeParameterType)type).GetTypeParameterSymbol();
                int index = tvs.GetIndexInTotalParameters();
                if (tvs.IsMethodTypeParameter())
                {
                    if ((pctx.grfst & SubstTypeFlags.DenormMeth) != 0 && tvs.parent != null)
                    {
                        return(type);
                    }
                    Debug.Assert(tvs.GetIndexInOwnParameters() == tvs.GetIndexInTotalParameters());
                    if (index < pctx.ctypeMeth)
                    {
                        Debug.Assert(pctx.prgtypeMeth != null);
                        return(pctx.prgtypeMeth[index]);
                    }
                    else
                    {
                        return((pctx.grfst & SubstTypeFlags.NormMeth) != 0 ? GetStdMethTypeVar(index) : type);
                    }
                }
                if ((pctx.grfst & SubstTypeFlags.DenormClass) != 0 && tvs.parent != null)
                {
                    return(type);
                }
                return(index < pctx.ctypeCls ? pctx.prgtypeCls[index] :
                       ((pctx.grfst & SubstTypeFlags.NormClass) != 0 ? GetStdClsTypeVar(index) : type));
            }
            }
        }