Exemplo n.º 1
0
        // TypeParameter
        public TypeParameterType CreateTypeParameter(TypeParameterSymbol pSymbol)
        {
            TypeParameterType type = new TypeParameterType();
            type.SetTypeParameterSymbol(pSymbol);
            type.SetUnresolved(pSymbol.parent != null && pSymbol.parent.IsAggregateSymbol() && pSymbol.parent.AsAggregateSymbol().IsUnresolved());
            type.SetName(pSymbol.name);

#if CSEE
            type.typeRes = type;
            if (!type.IsUnresolved())
            {
                type.tsRes = ktsImportMax;
            }
#endif // CSEE

            Debug.Assert(pSymbol.GetTypeParameterType() == null);
            pSymbol.SetTypeParameterType(type);

            type.SetTypeKind(TypeKind.TK_TypeParameterType);
            return type;
        }
Exemplo n.º 2
0
        public TypeParameterType GetTypeParameter(TypeParameterSymbol pSymbol)
        {
            // These guys should be singletons for each.

            TypeParameterType pTypeParameter = _typeTable.LookupTypeParameter(pSymbol);
            if (pTypeParameter == null)
            {
                pTypeParameter = _typeFactory.CreateTypeParameter(pSymbol);
                _typeTable.InsertTypeParameter(pSymbol, pTypeParameter);
            }

            return pTypeParameter;
        }
Exemplo n.º 3
0
            ////////////////////////////////////////////////////////////////////////////////
            // Get the standard type variable (eg, !0, !1, or !!0, !!1).
            //
            //      iv is the index.
            //      pbsm is the containing symbol manager
            //      fMeth designates whether this is a method type var or class type var
            //
            // The standard class type variables are useful during emit, but not for type 
            // comparison when binding. The standard method type variables are useful during
            // binding for signature comparison.

            public TypeParameterType GetTypeVarSym(int iv, TypeManager pTypeManager, bool fMeth)
            {
                Debug.Assert(iv >= 0);

                TypeParameterType tpt = null;
                if (iv >= this.prgptvs.Count)
                {
                    TypeParameterSymbol pTypeParameter = new TypeParameterSymbol();
                    pTypeParameter.SetIsMethodTypeParameter(fMeth);
                    pTypeParameter.SetIndexInOwnParameters(iv);
                    pTypeParameter.SetIndexInTotalParameters(iv);
                    pTypeParameter.SetAccess(ACCESS.ACC_PRIVATE);
                    tpt = pTypeManager.GetTypeParameter(pTypeParameter);
                    this.prgptvs.Add(tpt);
                }
                else
                {
                    tpt = this.prgptvs[iv];
                }
                Debug.Assert(tpt != null);
                return tpt;
            }
Exemplo n.º 4
0
        protected Symbol newBasicSym(
            SYMKIND kind,
            Name name,
            ParentSymbol parent)
        {
            // The parser creates names with PN_MISSING when attempting to recover from errors
            // To prevent spurious errors, we create SYMs with a different name (PN_MISSINGSYM)
            // so that they are never found when doing lookup.
            if (name == m_pMissingNameNode)
            {
                name = m_pMissingNameSym;
            }

            Symbol sym;
            switch (kind)
            {
                case SYMKIND.SK_NamespaceSymbol:
                    sym = new NamespaceSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_NamespaceDeclaration:
                    sym = new NamespaceDeclaration();
                    sym.name = name;
                    break;
                case SYMKIND.SK_AssemblyQualifiedNamespaceSymbol:
                    sym = new AssemblyQualifiedNamespaceSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_AggregateSymbol:
                    sym = new AggregateSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_AggregateDeclaration:
                    sym = new AggregateDeclaration();
                    sym.name = name;
                    break;
                case SYMKIND.SK_TypeParameterSymbol:
                    sym = new TypeParameterSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_FieldSymbol:
                    sym = new FieldSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_LocalVariableSymbol:
                    sym = new LocalVariableSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_MethodSymbol:
                    sym = new MethodSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_PropertySymbol:
                    sym = new PropertySymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_EventSymbol:
                    sym = new EventSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_TransparentIdentifierMemberSymbol:
                    sym = new TransparentIdentifierMemberSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_Scope:
                    sym = new Scope();
                    sym.name = name;
                    break;
                case SYMKIND.SK_LabelSymbol:
                    sym = new LabelSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_GlobalAttributeDeclaration:
                    sym = new GlobalAttributeDeclaration();
                    sym.name = name;
                    break;
                case SYMKIND.SK_UnresolvedAggregateSymbol:
                    sym = new UnresolvedAggregateSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_InterfaceImplementationMethodSymbol:
                    sym = new InterfaceImplementationMethodSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_IndexerSymbol:
                    sym = new IndexerSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_ParentSymbol:
                    sym = new ParentSymbol();
                    sym.name = name;
                    break;
                case SYMKIND.SK_IteratorFinallyMethodSymbol:
                    sym = new IteratorFinallyMethodSymbol();
                    sym.name = name;
                    break;
                default:
                    throw Error.InternalCompilerError();
            }

            sym.setKind(kind);

            if (parent != null)
            {
                // Set the parent element of the child symbol.
                parent.AddToChildList(sym);
                m_pSymTable.InsertChild(parent, sym);
            }

            return (sym);
        }
Exemplo n.º 5
0
 public void SetTypeParameterSymbol(TypeParameterSymbol pTypePArameterSymbol) { _pTypeParameterSymbol = pTypePArameterSymbol; }
Exemplo n.º 6
0
 public void InsertTypeParameter(
     TypeParameterSymbol pTypeParameterSymbol,
     TypeParameterType pTypeParameter)
 {
     _pTypeParameterTable.Add(pTypeParameterSymbol, pTypeParameter);
 }
Exemplo n.º 7
0
        private Symbol NewBasicSymbol(
            SYMKIND kind,
            Name name,
            ParentSymbol parent)
        {
            Symbol sym;

            switch (kind)
            {
            case SYMKIND.SK_NamespaceSymbol:
                sym      = new NamespaceSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_AggregateSymbol:
                sym      = new AggregateSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_AggregateDeclaration:
                sym      = new AggregateDeclaration();
                sym.name = name;
                break;

            case SYMKIND.SK_TypeParameterSymbol:
                sym      = new TypeParameterSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_FieldSymbol:
                sym      = new FieldSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_LocalVariableSymbol:
                sym      = new LocalVariableSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_MethodSymbol:
                sym      = new MethodSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_PropertySymbol:
                sym      = new PropertySymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_EventSymbol:
                sym      = new EventSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_Scope:
                sym      = new Scope();
                sym.name = name;
                break;

            case SYMKIND.SK_IndexerSymbol:
                sym      = new IndexerSymbol();
                sym.name = name;
                break;

            default:
                throw Error.InternalCompilerError();
            }

            sym.setKind(kind);

            if (parent != null)
            {
                // Set the parent element of the child symbol.
                parent.AddToChildList(sym);
                _symbolTable.InsertChild(parent, sym);
            }

            return(sym);
        }
Exemplo n.º 8
0
        protected Symbol newBasicSym(
            SYMKIND kind,
            Name name,
            ParentSymbol parent)
        {
            // The parser creates names with PN_MISSING when attempting to recover from errors
            // To prevent spurious errors, we create SYMs with a different name (PN_MISSINGSYM)
            // so that they are never found when doing lookup.
            if (name == m_pMissingNameNode)
            {
                name = m_pMissingNameSym;
            }

            Symbol sym;

            switch (kind)
            {
            case SYMKIND.SK_NamespaceSymbol:
                sym      = new NamespaceSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_NamespaceDeclaration:
                sym      = new NamespaceDeclaration();
                sym.name = name;
                break;

            case SYMKIND.SK_AssemblyQualifiedNamespaceSymbol:
                sym      = new AssemblyQualifiedNamespaceSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_AggregateSymbol:
                sym      = new AggregateSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_AggregateDeclaration:
                sym      = new AggregateDeclaration();
                sym.name = name;
                break;

            case SYMKIND.SK_TypeParameterSymbol:
                sym      = new TypeParameterSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_FieldSymbol:
                sym      = new FieldSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_LocalVariableSymbol:
                sym      = new LocalVariableSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_MethodSymbol:
                sym      = new MethodSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_PropertySymbol:
                sym      = new PropertySymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_EventSymbol:
                sym      = new EventSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_TransparentIdentifierMemberSymbol:
                sym      = new TransparentIdentifierMemberSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_Scope:
                sym      = new Scope();
                sym.name = name;
                break;

            case SYMKIND.SK_LabelSymbol:
                sym      = new LabelSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_GlobalAttributeDeclaration:
                sym      = new GlobalAttributeDeclaration();
                sym.name = name;
                break;

            case SYMKIND.SK_UnresolvedAggregateSymbol:
                sym      = new UnresolvedAggregateSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_InterfaceImplementationMethodSymbol:
                sym      = new InterfaceImplementationMethodSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_IndexerSymbol:
                sym      = new IndexerSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_ParentSymbol:
                sym      = new ParentSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_IteratorFinallyMethodSymbol:
                sym      = new IteratorFinallyMethodSymbol();
                sym.name = name;
                break;

            default:
                throw Error.InternalCompilerError();
            }

            sym.setKind(kind);

            if (parent != null)
            {
                // Set the parent element of the child symbol.
                parent.AddToChildList(sym);
                m_pSymTable.InsertChild(parent, sym);
            }

            return(sym);
        }
Exemplo n.º 9
0
 public void SetTypeParameterSymbol(TypeParameterSymbol pTypePArameterSymbol)
 {
     _pTypeParameterSymbol = pTypePArameterSymbol;
 }
Exemplo n.º 10
0
 // These are singletons for each.
 public TypeParameterType GetTypeParameter(TypeParameterSymbol pSymbol)
 {
     Debug.Assert(pSymbol.GetTypeParameterType() == null); // Should have been checked first before creating
     return(new TypeParameterType(pSymbol));
 }
Exemplo n.º 11
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.TypeKind)
            {
            default:
                Debug.Assert(false, "Bad Symbol kind in SubstEqualTypesCore");
                return(false);

            case TypeKind.TK_NullType:
            case TypeKind.TK_VoidType:
                // There should only be a single instance of these.
                Debug.Assert(typeDst.TypeKind != typeSrc.TypeKind);
                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) || modDest.IsOut != ((ParameterModifierType)typeSrc).IsOut)
                {
                    return(false);
                }

                goto LCheckBases;

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

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

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

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

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

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

                if (tvs.IsMethodTypeParameter())
                {
                    if (pctx.DenormMeth && tvs.parent != null)
                    {
                        // typeDst == typeSrc was handled above.
                        Debug.Assert(typeDst != typeSrc);
                        return(false);
                    }

                    Debug.Assert(tvs.GetIndexInOwnParameters() == index);
                    Debug.Assert(tvs.GetIndexInTotalParameters() < pctx.MethodTypes.Length);
                    if (index < pctx.MethodTypes.Length)
                    {
                        return(typeDst == pctx.MethodTypes[index]);
                    }
                }
                else
                {
                    Debug.Assert(index < pctx.ClassTypes.Length);
                    if (index < pctx.ClassTypes.Length)
                    {
                        return(typeDst == pctx.ClassTypes[index]);
                    }
                }
            }
                return(false);
            }
        }
Exemplo n.º 12
0
        private CType SubstTypeCore(CType type, SubstContext pctx)
        {
            CType typeSrc;
            CType typeDst;

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

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

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

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

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

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

            case TypeKind.TK_AggregateType:
                return(SubstTypeCore((AggregateType)type, pctx));

            case TypeKind.TK_TypeParameterType:
            {
                TypeParameterSymbol tvs = ((TypeParameterType)type).Symbol;
                int index = tvs.GetIndexInTotalParameters();
                if (tvs.IsMethodTypeParameter())
                {
                    if (pctx.DenormMeth && tvs.parent != null)
                    {
                        return(type);
                    }

                    Debug.Assert(tvs.GetIndexInOwnParameters() == tvs.GetIndexInTotalParameters());
                    if (index < pctx.MethodTypes.Length)
                    {
                        Debug.Assert(pctx.MethodTypes != null);
                        return(pctx.MethodTypes[index]);
                    }

                    return(type);
                }

                return(index < pctx.ClassTypes.Length ? pctx.ClassTypes[index] : type);
            }
            }
        }
Exemplo n.º 13
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);
            }
        }
Exemplo n.º 14
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_BoundLambdaType:
            case TypeKind.TK_UnboundLambdaType:
            case TypeKind.TK_NaturalIntegerType:
            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));
            }
            }
        }