////////////////////////////////////////////////////////////////////////////////
        // Check the constraints on the method instantiation.
        public static void CheckMethConstraints(MethWithInst mwi)
        {
            Debug.Assert(mwi.Meth() != null && mwi.GetType() != null && mwi.TypeArgs != null);
            Debug.Assert(mwi.Meth().typeVars.Count == mwi.TypeArgs.Count);
            Debug.Assert(mwi.GetType().OwningAggregate == mwi.Meth().getClass());

            if (mwi.TypeArgs.Count > 0)
            {
                CheckConstraintsCore(mwi.Meth(), mwi.Meth().typeVars, mwi.TypeArgs, mwi.GetType().TypeArgsAll, mwi.TypeArgs, CheckConstraintsFlags.None);
            }
        }
示例#2
0
        ////////////////////////////////////////////////////////////////////////////////
        // Check the constraints on the method instantiation.
        public static void CheckMethConstraints(CSemanticChecker checker, ErrorHandling errCtx, MethWithInst mwi)
        {
            Debug.Assert(mwi.Meth() != null && mwi.GetType() != null && mwi.TypeArgs != null);
            Debug.Assert(mwi.Meth().typeVars.Count == mwi.TypeArgs.Count);
            Debug.Assert(mwi.GetType().getAggregate() == mwi.Meth().getClass());

            if (mwi.TypeArgs.Count > 0)
            {
                CheckConstraintsCore(checker, errCtx, mwi.Meth(), mwi.Meth().typeVars, mwi.TypeArgs, mwi.GetType().GetTypeArgsAll(), mwi.TypeArgs, CheckConstraintsFlags.None);
            }
        }
示例#3
0
        /////////////////////////////////////////////////////////////////////////////////
        // Expression types.

        private ExprBinOp VisitBoundLambda(ExprBoundLambda anonmeth)
        {
            Debug.Assert(anonmeth != null);

            MethodSymbol  lambdaMethod     = GetPreDefMethod(PREDEFMETH.PM_EXPRESSION_LAMBDA);
            AggregateType delegateType     = anonmeth.DelegateType;
            TypeArray     lambdaTypeParams = TypeArray.Allocate(delegateType);
            AggregateType expressionType   = SymbolLoader.GetPredefindType(PredefinedType.PT_EXPRESSION);
            MethWithInst  mwi = new MethWithInst(lambdaMethod, expressionType, lambdaTypeParams);
            Expr          createParameters = CreateWraps(anonmeth);

            Debug.Assert(createParameters != null);
            Debug.Assert(anonmeth.Expression != null);
            Expr body = Visit(anonmeth.Expression);

            Debug.Assert(anonmeth.ArgumentScope.nextChild == null);
            Expr            parameters = GenerateParamsArray(null, PredefinedType.PT_PARAMETEREXPRESSION);
            Expr            args       = ExprFactory.CreateList(body, parameters);
            CType           typeRet    = TypeManager.SubstType(mwi.Meth().RetType, mwi.GetType(), mwi.TypeArgs);
            ExprMemberGroup pMemGroup  = ExprFactory.CreateMemGroup(null, mwi);
            ExprCall        call       = ExprFactory.CreateCall(0, typeRet, args, pMemGroup, mwi);

            call.PredefinedMethod = PREDEFMETH.PM_EXPRESSION_LAMBDA;
            return(ExprFactory.CreateSequence(createParameters, call));
        }
示例#4
0
        private ExprCall GenerateCall(PREDEFMETH pdm, Expr arg1, Expr arg2, Expr arg3, Expr arg4)
        {
            MethodSymbol method = GetPreDefMethod(pdm);

            if (method == null)
            {
                return(null);
            }
            AggregateType   expressionType = GetSymbolLoader().GetPredefindType(PredefinedType.PT_EXPRESSION);
            Expr            args           = GetExprFactory().CreateList(arg1, arg2, arg3, arg4);
            MethWithInst    mwi            = new MethWithInst(method, expressionType);
            ExprMemberGroup pMemGroup      = GetExprFactory().CreateMemGroup(null, mwi);
            ExprCall        call           = GetExprFactory().CreateCall(0, mwi.Meth().RetType, args, pMemGroup, mwi);

            call.PredefinedMethod = pdm;
            return(call);
        }
示例#5
0
        private ExprCall GenerateCall(PREDEFMETH pdm, Expr arg1)
        {
            MethodSymbol method = GetPreDefMethod(pdm);

            // this should be enforced in an earlier pass and the transform pass should not
            // be handling this error
            if (method == null)
            {
                return(null);
            }
            AggregateType   expressionType = GetSymbolLoader().GetPredefindType(PredefinedType.PT_EXPRESSION);
            MethWithInst    mwi            = new MethWithInst(method, expressionType);
            ExprMemberGroup pMemGroup      = GetExprFactory().CreateMemGroup(null, mwi);
            ExprCall        call           = GetExprFactory().CreateCall(0, mwi.Meth().RetType, arg1, pMemGroup, mwi);

            call.PredefinedMethod = pdm;
            return(call);
        }
示例#6
0
        private Expr GenerateUserDefinedConversion(Expr arg, CType CType, Expr target, MethWithInst method)
        {
            // The user-defined explicit conversion from enum? to decimal or decimal? requires
            // that we convert the enum? to its nullable underlying CType.
            if (isEnumToDecimalConversion(arg.Type, CType))
            {
                // Special case: If we have enum? to decimal? then we need to emit
                // a conversion from enum? to its nullable underlying CType first.
                // This is unfortunate; we ought to reorganize how conversions are
                // represented in the Expr tree so that this is more transparent.

                // converting an enum to its underlying CType never fails, so no need to check it.
                CType underlyingType = arg.Type.StripNubs().underlyingEnumType();
                CType nullableType   = GetSymbolLoader().GetTypeManager().GetNullable(underlyingType);
                Expr  typeofNubEnum  = CreateTypeOf(nullableType);
                target = GenerateCall(PREDEFMETH.PM_EXPRESSION_CONVERT, target, typeofNubEnum);
            }

            // If the methodinfo does not return the target CType AND this is not a lifted conversion
            // from one value CType to another, then we need to wrap the whole thing in another conversion,
            // e.g. if we have a user-defined conversion from int to S? and we have (S)myint, then we need to generate
            // Convert(Convert(myint, typeof(S?), op_implicit), typeof(S))

            CType pMethodReturnType = GetSymbolLoader().GetTypeManager().SubstType(method.Meth().RetType,
                                                                                   method.GetType(), method.TypeArgs);
            bool fDontLiftReturnType = (pMethodReturnType == CType || (IsNullableValueType(arg.Type) && IsNullableValueType(CType)));

            Expr       typeofInner = CreateTypeOf(fDontLiftReturnType ? CType : pMethodReturnType);
            Expr       methodInfo  = GetExprFactory().CreateMethodInfo(method);
            PREDEFMETH pdmInner    = arg.isChecked() ? PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED_USER_DEFINED : PREDEFMETH.PM_EXPRESSION_CONVERT_USER_DEFINED;
            Expr       callUserDefinedConversion = GenerateCall(pdmInner, target, typeofInner, methodInfo);

            if (fDontLiftReturnType)
            {
                return(callUserDefinedConversion);
            }

            PREDEFMETH pdmOuter    = arg.isChecked() ? PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED : PREDEFMETH.PM_EXPRESSION_CONVERT;
            Expr       typeofOuter = CreateTypeOf(CType);

            return(GenerateCall(pdmOuter, callUserDefinedConversion, typeofOuter));
        }
示例#7
0
        protected virtual EXPR GenerateUserDefinedConversion(EXPR arg, CType CType, EXPR target, MethWithInst method)
        {
            // The user-defined explicit conversion from enum? to decimal or decimal? requires
            // that we convert the enum? to its nullable underlying CType.
            if (isEnumToDecimalConversion(arg.type, CType))
            {
                // Special case: If we have enum? to decimal? then we need to emit 
                // a conversion from enum? to its nullable underlying CType first.
                // This is unfortunate; we ought to reorganize how conversions are 
                // represented in the EXPR tree so that this is more transparent.

                // converting an enum to its underlying CType never fails, so no need to check it.
                CType underlyingType = arg.type.StripNubs().underlyingEnumType();
                CType nullableType = GetSymbolLoader().GetTypeManager().GetNullable(underlyingType);
                EXPR typeofNubEnum = CreateTypeOf(nullableType);
                target = GenerateCall(PREDEFMETH.PM_EXPRESSION_CONVERT, target, typeofNubEnum);
            }

            // If the methodinfo does not return the target CType AND this is not a lifted conversion
            // from one value CType to another, then we need to wrap the whole thing in another conversion,
            // e.g. if we have a user-defined conversion from int to S? and we have (S)myint, then we need to generate 
            // Convert(Convert(myint, typeof(S?), op_implicit), typeof(S))

            CType pMethodReturnType = GetSymbolLoader().GetTypeManager().SubstType(method.Meth().RetType,
                method.GetType(), method.TypeArgs);
            bool fDontLiftReturnType = (pMethodReturnType == CType || (IsNullableValueType(arg.type) && IsNullableValueType(CType)));

            EXPR typeofInner = CreateTypeOf(fDontLiftReturnType ? CType : pMethodReturnType);
            EXPR methodInfo = GetExprFactory().CreateMethodInfo(method);
            PREDEFMETH pdmInner = arg.isChecked() ? PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED_USER_DEFINED : PREDEFMETH.PM_EXPRESSION_CONVERT_USER_DEFINED;
            EXPR callUserDefinedConversion = GenerateCall(pdmInner, target, typeofInner, methodInfo);

            if (fDontLiftReturnType)
            {
                return callUserDefinedConversion;
            }

            PREDEFMETH pdmOuter = arg.isChecked() ? PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED : PREDEFMETH.PM_EXPRESSION_CONVERT;
            EXPR typeofOuter = CreateTypeOf(CType);
            return GenerateCall(pdmOuter, callUserDefinedConversion, typeofOuter);
        }
示例#8
0
 protected EXPRCALL GenerateCall(PREDEFMETH pdm, EXPR arg1, EXPR arg2, EXPR arg3, EXPR arg4)
 {
     MethodSymbol method = GetPreDefMethod(pdm);
     if (method == null)
         return null;
     AggregateType expressionType = GetSymbolLoader().GetOptPredefTypeErr(PredefinedType.PT_EXPRESSION, true);
     EXPR args = GetExprFactory().CreateList(arg1, arg2, arg3, arg4);
     MethWithInst mwi = new MethWithInst(method, expressionType);
     EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(null, mwi);
     EXPRCALL call = GetExprFactory().CreateCall(0, mwi.Meth().RetType, args, pMemGroup, mwi);
     call.PredefinedMethod = pdm;
     return call;
 }
示例#9
0
 protected EXPRCALL GenerateCall(PREDEFMETH pdm, EXPR arg1)
 {
     MethodSymbol method = GetPreDefMethod(pdm);
     // this should be enforced in an earlier pass and the tranform pass should not 
     // be handeling this error
     if (method == null)
         return null;
     AggregateType expressionType = GetSymbolLoader().GetOptPredefTypeErr(PredefinedType.PT_EXPRESSION, true);
     MethWithInst mwi = new MethWithInst(method, expressionType);
     EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(null, mwi);
     EXPRCALL call = GetExprFactory().CreateCall(0, mwi.Meth().RetType, arg1, pMemGroup, mwi);
     call.PredefinedMethod = pdm;
     return call;
 }
示例#10
0
        /////////////////////////////////////////////////////////////////////////////////
        // Expression types.

        protected override EXPR VisitBOUNDLAMBDA(EXPRBOUNDLAMBDA anonmeth)
        {
            Debug.Assert(anonmeth != null);

            EXPRBOUNDLAMBDA prevAnonMeth = currentAnonMeth;
            currentAnonMeth = anonmeth;
            MethodSymbol lambdaMethod = GetPreDefMethod(PREDEFMETH.PM_EXPRESSION_LAMBDA);

            CType delegateType = anonmeth.DelegateType();
            TypeArray lambdaTypeParams = GetSymbolLoader().getBSymmgr().AllocParams(1, new CType[] { delegateType });
            AggregateType expressionType = GetSymbolLoader().GetOptPredefTypeErr(PredefinedType.PT_EXPRESSION, true);
            MethWithInst mwi = new MethWithInst(lambdaMethod, expressionType, lambdaTypeParams);
            EXPR createParameters = CreateWraps(anonmeth);
            EXPR body = RewriteLambdaBody(anonmeth);
            EXPR parameters = RewriteLambdaParameters(anonmeth);
            EXPR args = GetExprFactory().CreateList(body, parameters);
            CType typeRet = GetSymbolLoader().GetTypeManager().SubstType(mwi.Meth().RetType, mwi.GetType(), mwi.TypeArgs);
            EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(null, mwi);
            EXPR callLambda = GetExprFactory().CreateCall(0, typeRet, args, pMemGroup, mwi);

            callLambda.asCALL().PredefinedMethod = PREDEFMETH.PM_EXPRESSION_LAMBDA;

            currentAnonMeth = prevAnonMeth;
            if (createParameters != null)
            {
                callLambda = GetExprFactory().CreateSequence(createParameters, callLambda);
            }
            EXPR expr = DestroyWraps(anonmeth, callLambda);
            // If we are already inside an expression tree rewrite and this is an expression tree lambda
            // then it needs to be quoted.
            if (currentAnonMeth != null)
            {
                expr = GenerateCall(PREDEFMETH.PM_EXPRESSION_QUOTE, expr);
            }
            return expr;
        }
示例#11
0
        ////////////////////////////////////////////////////////////////////////////////
        // Check the constraints on the method instantiation.
        public static void CheckMethConstraints(CSemanticChecker checker, ErrorHandling errCtx, MethWithInst mwi)
        {
            Debug.Assert(mwi.Meth() != null && mwi.GetType() != null && mwi.TypeArgs != null);
            Debug.Assert(mwi.Meth().typeVars.size == mwi.TypeArgs.size);
            Debug.Assert(mwi.GetType().getAggregate() == mwi.Meth().getClass());

            if (mwi.TypeArgs.size > 0)
            {
                CheckConstraintsCore(checker, errCtx, mwi.Meth(), mwi.Meth().typeVars, mwi.TypeArgs, mwi.GetType().GetTypeArgsAll(), mwi.TypeArgs, CheckConstraintsFlags.None);
            }
        }
示例#12
0
        ////////////////////////////////////////////////////////////////////////////////
        // Binds a call to a method, return type is an error or an EXPRCALL.
        //
        // tree      - ParseTree for error messages
        // pObject    - pObject to call method on
        // pmwi      - Meth to bind to. This will be morphed when we remap to an override.
        // args      - arguments
        // exprFlags - Flags to put on the generated expr

        internal EXPRCALL BindToMethod(MethWithInst mwi, EXPR pArguments, EXPRMEMGRP pMemGroup, MemLookFlags flags)
        {
            Debug.Assert(mwi.Sym != null && mwi.Sym.IsMethodSymbol() && (!mwi.Meth().isOverride || mwi.Meth().isHideByName));
            Debug.Assert(pMemGroup != null);

            bool fConstrained;
            bool bIsMatchingStatic;
            EXPR pObject = pMemGroup.GetOptionalObject();
            CType callingObjectType = pObject != null ? pObject.type : null;
            PostBindMethod((flags & MemLookFlags.BaseCall) != 0, ref mwi, pObject);
            pObject = AdjustMemberObject(mwi, pObject, out fConstrained, out bIsMatchingStatic);
            pMemGroup.SetOptionalObject(pObject);

            CType pReturnType = null;
            if ((flags & (MemLookFlags.Ctor | MemLookFlags.NewObj)) == (MemLookFlags.Ctor | MemLookFlags.NewObj))
            {
                pReturnType = mwi.Ats;
            }
            else
            {
                pReturnType = GetTypes().SubstType(mwi.Meth().RetType, mwi.GetType(), mwi.TypeArgs);
            }

            EXPRCALL pResult = GetExprFactory().CreateCall(0, pReturnType, pArguments, pMemGroup, mwi);
            if (!bIsMatchingStatic)
            {
                pResult.SetMismatchedStaticBit();
            }

            if (!pResult.isOK())
            {
                return pResult;
            }

            // Set the return type and flags for constructors.
            if ((flags & MemLookFlags.Ctor) != 0)
            {
                if ((flags & MemLookFlags.NewObj) != 0)
                {
                    pResult.flags |= EXPRFLAG.EXF_NEWOBJCALL | EXPRFLAG.EXF_CANTBENULL;
                }
                else
                {
                    Debug.Assert(pResult.type == getVoidType());
                }
            }

            if ((flags & MemLookFlags.BaseCall) != 0)
            {
                pResult.flags |= EXPRFLAG.EXF_BASECALL;
            }
            else if (fConstrained && pObject != null)
            {
                // Use the constrained prefix.
                pResult.flags |= EXPRFLAG.EXF_CONSTRAINED;
            }

            verifyMethodArgs(pResult, callingObjectType);

            return pResult;
        }
示例#13
0
        internal void PostBindMethod(bool fBaseCall, ref MethWithInst pMWI, EXPR pObject)
        {
            MethWithInst mwiOrig = pMWI;

            // If it is virtual, find a remap of the method to something more specific.  This
            // may alter where the method is found.
            if (pObject != null && (fBaseCall || pObject.type.isSimpleType() || pObject.type.isSpecialByRefType()))
            {
                RemapToOverride(GetSymbolLoader(), pMWI, pObject.type);
            }

            if (fBaseCall && pMWI.Meth().isAbstract)
            {
                ErrorContext.Error(ErrorCode.ERR_AbstractBaseCall, pMWI);
            }

            if (pMWI.Meth().RetType != null)
            {
                checkUnsafe(pMWI.Meth().RetType);
                bool fCheckParams = false;

                if (pMWI.Meth().isExternal)
                {
                    fCheckParams = true;
                    SetExternalRef(pMWI.Meth().RetType);
                }

                // We need to check unsafe on the parameters as well, since we cannot check in conversion.
                TypeArray pParams = pMWI.Meth().Params;

                for (int i = 0; i < pParams.size; i++)
                {
                    // This is an optimization: don't call this in the vast majority of cases
                    CType type = pParams.Item(i);

                    if (type.isUnsafe())
                    {
                        checkUnsafe(type);
                    }
                    if (fCheckParams && type.IsParameterModifierType())
                    {
                        SetExternalRef(type);
                    }
                }
            }
        }