Inheritance: MethPropWithInst
Ejemplo n.º 1
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 = GetSymbolLoader().getBSymmgr().AllocParams(1, new CType[] { delegateType });
            AggregateType expressionType   = GetSymbolLoader().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       = GetExprFactory().CreateList(body, parameters);
            CType           typeRet    = GetSymbolLoader().GetTypeManager().SubstType(mwi.Meth().RetType, mwi.GetType(), mwi.TypeArgs);
            ExprMemberGroup pMemGroup  = GetExprFactory().CreateMemGroup(null, mwi);
            ExprCall        call       = GetExprFactory().CreateCall(0, typeRet, args, pMemGroup, mwi);

            call.PredefinedMethod = PREDEFMETH.PM_EXPRESSION_LAMBDA;
            return(GetExprFactory().CreateSequence(createParameters, call));
        }
Ejemplo n.º 2
0
 public ExprMethodInfo(CType type, MethodSymbol method, AggregateType methodType, TypeArray methodParameters)
     : base(ExpressionKind.MethodInfo, type)
 {
     Debug.Assert(method != null);
     Debug.Assert(methodType != null);
     Method = new MethWithInst(method, methodType, methodParameters);
 }
Ejemplo n.º 3
0
 public ExprFuncPtr(CType type, EXPRFLAG flags, Expr optionalObject, MethWithInst method) 
     : base(ExpressionKind.FunctionPointer, type)
 {
     Debug.Assert((flags & ~EXPRFLAG.EXF_BASECALL) == 0);
     Flags = flags;
     OptionalObject = optionalObject;
     MethWithInst = new MethWithInst(method);
 }
 public ExprUserDefinedConversion(Expr argument, Expr call, MethWithInst method)
     : base(ExpressionKind.UserDefinedConversion)
 {
     Debug.Assert(argument != null);
     Debug.Assert(call != null);
     Argument              = argument;
     UserDefinedCall       = call;
     UserDefinedCallMethod = method;
 }
        ////////////////////////////////////////////////////////////////////////////////
        // 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);
            }
        }
Ejemplo n.º 6
0
 public EXPRFUNCPTR CreateFunctionPointer(EXPRFLAG nFlags, CType pType, EXPR pObject, MethWithInst MWI)
 {
     Debug.Assert(0 == (nFlags & ~(EXPRFLAG.EXF_BASECALL)));
     EXPRFUNCPTR rval = new EXPRFUNCPTR();
     rval.kind = ExpressionKind.EK_FUNCPTR;
     rval.type = pType;
     rval.flags = nFlags;
     rval.OptionalObject = pObject;
     rval.mwi = new MethWithInst(MWI);
     Debug.Assert(rval != null);
     return (rval);
 }
Ejemplo n.º 7
0
        // Create an expr for new T?(exprSrc) where T is exprSrc.type.
        private static ExprCall BindNubNew(Expr exprSrc)
        {
            Debug.Assert(exprSrc != null);

            NullableType    pNubSourceType = TypeManager.GetNullable(exprSrc.Type);
            AggregateType   pSourceType    = pNubSourceType.GetAts();
            MethodSymbol    meth           = PredefinedMembers.GetMethod(PREDEFMETH.PM_G_OPTIONAL_CTOR);
            MethWithInst    methwithinst   = new MethWithInst(meth, pSourceType, TypeArray.Empty);
            ExprMemberGroup memgroup       = ExprFactory.CreateMemGroup(null, methwithinst);

            return(ExprFactory.CreateCall(EXPRFLAG.EXF_NEWOBJCALL | EXPRFLAG.EXF_CANTBENULL, pNubSourceType, exprSrc, memgroup, methwithinst));
        }
Ejemplo n.º 8
0
 public ExprCall(CType type, EXPRFLAG flags, Expr arguments, ExprMemberGroup member, MethWithInst method)
     : base(ExpressionKind.Call, type)
 {
     Debug.Assert(
         (flags & ~(EXPRFLAG.EXF_NEWOBJCALL | EXPRFLAG.EXF_CONSTRAINED
                    | EXPRFLAG.EXF_NEWSTRUCTASSG | EXPRFLAG.EXF_IMPLICITSTRUCTASSG | EXPRFLAG.EXF_MASK_ANY)) == 0);
     Flags                = flags;
     OptionalArguments    = arguments;
     MemberGroup          = member;
     NullableCallLiftKind = NullableCallLiftKind.NotLifted;
     MethWithInst         = method;
 }
Ejemplo n.º 9
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);
        }
Ejemplo n.º 10
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);
        }
Ejemplo n.º 11
0
        public ExprCall BindNew(Expr pExprSrc)
        {
            Debug.Assert(pExprSrc != null);

            NullableType pNubSourceType = GetSymbolLoader().GetTypeManager().GetNullable(pExprSrc.Type);

            AggregateType pSourceType = pNubSourceType.GetAts();
            MethodSymbol  meth        = GetSymbolLoader().getBSymmgr().methNubCtor;

            if (meth == null)
            {
                meth = GetSymbolLoader().getPredefinedMembers().GetMethod(PREDEFMETH.PM_G_OPTIONAL_CTOR);
                Debug.Assert(meth != null);
                GetSymbolLoader().getBSymmgr().methNubCtor = meth;
            }

            MethWithInst    methwithinst = new MethWithInst(meth, pSourceType, BSYMMGR.EmptyTypeArray());
            ExprMemberGroup memgroup     = GetExprFactory().CreateMemGroup(null, methwithinst);

            return(GetExprFactory().CreateCall(EXPRFLAG.EXF_NEWOBJCALL | EXPRFLAG.EXF_CANTBENULL, pNubSourceType, pExprSrc, memgroup, methwithinst));
        }
Ejemplo n.º 12
0
        public EXPRCALL CreateCall(EXPRFLAG nFlags, CType pType, EXPR pOptionalArguments, EXPRMEMGRP pMemberGroup, MethWithInst MWI)
        {
            Debug.Assert(0 == (nFlags &
               ~(
                   EXPRFLAG.EXF_NEWOBJCALL | EXPRFLAG.EXF_CONSTRAINED | EXPRFLAG.EXF_BASECALL |
                   EXPRFLAG.EXF_NEWSTRUCTASSG |
                   EXPRFLAG.EXF_IMPLICITSTRUCTASSG | EXPRFLAG.EXF_MASK_ANY
               )
              ));

            EXPRCALL rval = new EXPRCALL();
            rval.kind = ExpressionKind.EK_CALL;
            rval.type = pType;
            rval.flags = nFlags;
            rval.SetOptionalArguments(pOptionalArguments);
            rval.SetMemberGroup(pMemberGroup);
            rval.nubLiftKind = NullableCallLiftKind.NotLifted;
            rval.castOfNonLiftedResultToLiftedType = null;

            rval.mwi = MWI;
            Debug.Assert(rval != null);
            return (rval);
        }
Ejemplo n.º 13
0
        public EXPRCALL BindNew(EXPR pExprSrc)
        {
            Debug.Assert(pExprSrc != null);

            NullableType pNubSourceType = GetSymbolLoader().GetTypeManager().GetNullable(pExprSrc.type);

            AggregateType pSourceType = pNubSourceType.GetAts(GetErrorContext());

            if (pSourceType == null)
            {
                MethWithInst mwi       = new MethWithInst(null, null);
                EXPRMEMGRP   pMemGroup = GetExprFactory().CreateMemGroup(pExprSrc, mwi);
                EXPRCALL     rval      = GetExprFactory().CreateCall(0, pNubSourceType, null, pMemGroup, null);
                rval.SetError();
                return(rval);
            }

            // UNDONE: move this to transform pass
            MethodSymbol meth = GetSymbolLoader().getBSymmgr().methNubCtor;

            if (meth == null)
            {
                meth = GetSymbolLoader().getPredefinedMembers().GetMethod(PREDEFMETH.PM_G_OPTIONAL_CTOR);
                GetSymbolLoader().getBSymmgr().methNubCtor = meth;
            }

            MethWithInst methwithinst = new MethWithInst(meth, pSourceType, BSYMMGR.EmptyTypeArray());
            EXPRMEMGRP   memgroup     = GetExprFactory().CreateMemGroup(null, methwithinst);
            EXPRCALL     pExprRes     = GetExprFactory().CreateCall(EXPRFLAG.EXF_NEWOBJCALL | EXPRFLAG.EXF_CANTBENULL, pNubSourceType, pExprSrc, memgroup, methwithinst);

            if (meth == null)
            {
                pExprRes.SetError();
            }

            return(pExprRes);
        }
Ejemplo n.º 14
0
        public ExprUserDefinedConversion CreateUserDefinedConversion(Expr arg, Expr call, MethWithInst mwi)
        {
            Debug.Assert(arg != null);
            Debug.Assert(call != null);
            ExprUserDefinedConversion rval = new ExprUserDefinedConversion();

            rval.Kind                  = ExpressionKind.EK_USERDEFINEDCONVERSION;
            rval.Type                  = call.Type;
            rval.Flags                 = 0;
            rval.Argument              = arg;
            rval.UserDefinedCall       = call;
            rval.UserDefinedCallMethod = mwi;
            if (call.HasError)
            {
                rval.SetError();
            }
            Debug.Assert(rval != null);
            return(rval);
        }
Ejemplo n.º 15
0
        protected virtual EXPR GenerateDelegateConstructor(EXPRCALL expr)
        {
            // In:
            //
            // new DELEGATE(obj, &FUNC)
            //
            // Out:
            //
            //  Cast(
            //      Call(
            //          null,
            //          (MethodInfo)GetMethodFromHandle(&CreateDelegate),
            //          new Expression[3]{
            //              Constant(typeof(DELEGATE)),
            //              transformed-object,
            //              Constant((MethodInfo)GetMethodFromHandle(&FUNC)}),
            //      typeof(DELEGATE))
            //

            Debug.Assert(expr != null);
            Debug.Assert(expr.mwi.Meth().IsConstructor());
            Debug.Assert(expr.type.isDelegateType());
            Debug.Assert(expr.GetOptionalArguments() != null);
            Debug.Assert(expr.GetOptionalArguments().isLIST());
            EXPRLIST origArgs = expr.GetOptionalArguments().asLIST();
            EXPR target = origArgs.GetOptionalElement();
            Debug.Assert(origArgs.GetOptionalNextListNode().kind == ExpressionKind.EK_FUNCPTR);
            EXPRFUNCPTR funcptr = origArgs.GetOptionalNextListNode().asFUNCPTR();
            MethodSymbol createDelegateMethod = GetPreDefMethod(PREDEFMETH.PM_METHODINFO_CREATEDELEGATE_TYPE_OBJECT);
            AggregateType delegateType = GetSymbolLoader().GetOptPredefTypeErr(PredefinedType.PT_DELEGATE, true);
            MethWithInst mwi = new MethWithInst(createDelegateMethod, delegateType);

            EXPR instance = GenerateConstant(GetExprFactory().CreateMethodInfo(funcptr.mwi));
            EXPR methinfo = GetExprFactory().CreateMethodInfo(mwi);
            EXPR param1 = GenerateConstant(CreateTypeOf(expr.type));
            EXPR param2 = Visit(target);
            EXPR paramsList = GetExprFactory().CreateList(param1, param2);
            EXPR Params = GenerateParamsArray(paramsList, PredefinedType.PT_EXPRESSION);
            EXPR call = GenerateCall(PREDEFMETH.PM_EXPRESSION_CALL, instance, methinfo, Params);
            EXPR pTypeOf = CreateTypeOf(expr.type);
            return GenerateCall(PREDEFMETH.PM_EXPRESSION_CONVERT, call, pTypeOf);
        }
Ejemplo n.º 16
0
 protected virtual EXPR GenerateUserDefinedConversion(EXPR arg, CType type, MethWithInst method)
 {
     EXPR target = Visit(arg);
     return GenerateUserDefinedConversion(arg, type, target, method);
 }
Ejemplo n.º 17
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;
 }
Ejemplo n.º 18
0
        ////////////////////////////////////////////////////////////////////////////////
        // This finds a method  and binds it to the args provided.

        internal EXPRCALL BindPredefMethToArgs(PREDEFMETH predefMethod, EXPR obj, EXPR args, TypeArray clsTypeArgs, TypeArray methTypeArgs)
        {
            MethodSymbol methSym = GetSymbolLoader().getPredefinedMembers().GetMethod(predefMethod);
            if (methSym == null)
            {
                MethWithInst mwi = new MethWithInst(null, null);
                EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(obj, mwi);
                EXPRCALL rval = GetExprFactory().CreateCall(0, null, args, pMemGroup, null);
                rval.SetError();
                return rval;
            }

            AggregateSymbol agg = methSym.getClass();
            if (clsTypeArgs == null)
            {
                clsTypeArgs = BSYMMGR.EmptyTypeArray();
            }
            AggregateType aggType = GetTypes().GetAggregate(agg, clsTypeArgs);

            MethPropWithInst mpwiBest = new MethPropWithInst(methSym, aggType, methTypeArgs);
            EXPRMEMGRP memgroup = GetExprFactory().CreateMemGroup(obj, mpwiBest);

            EXPRCALL exprRes = BindToMethod(new MethWithInst(mpwiBest), args, memgroup, (MemLookFlags)MemLookFlags.None);

            return exprRes;
        }
Ejemplo n.º 19
0
        private Expr GenerateUserDefinedConversion(Expr arg, CType type, MethWithInst method)
        {
            Expr target = Visit(arg);

            return(GenerateUserDefinedConversion(arg, type, target, method));
        }
Ejemplo n.º 20
0
        public ExprUserDefinedConversion CreateUserDefinedConversion(Expr arg, Expr call, MethWithInst mwi)
        {
            Debug.Assert(arg != null);
            Debug.Assert(call != null);
            ExprUserDefinedConversion rval = new ExprUserDefinedConversion();

            rval.Argument              = arg;
            rval.UserDefinedCall       = call;
            rval.UserDefinedCallMethod = mwi;
            if (call.HasError)
            {
                rval.SetError();
            }
            return(rval);
        }
Ejemplo n.º 21
0
 public static ExprUserDefinedConversion CreateUserDefinedConversion(Expr arg, Expr call, MethWithInst method) =>
 new ExprUserDefinedConversion(arg, call, method);
Ejemplo n.º 22
0
        public ExprFuncPtr CreateFunctionPointer(EXPRFLAG nFlags, CType pType, Expr pObject, MethWithInst MWI)
        {
            Debug.Assert(0 == (nFlags & ~(EXPRFLAG.EXF_BASECALL)));
            ExprFuncPtr rval = new ExprFuncPtr(pType);

            rval.Flags          = nFlags;
            rval.OptionalObject = pObject;
            rval.MethWithInst   = new MethWithInst(MWI);
            return(rval);
        }
Ejemplo n.º 23
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);
                    }
                }
            }
        }
Ejemplo n.º 24
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);
            }
        }
Ejemplo n.º 25
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;
        }
Ejemplo n.º 26
0
        protected EXPR bindIndexer(EXPR pObject, EXPR args, BindingFlag bindFlags)
        {
            CType type = pObject.type;

            if (!type.IsAggregateType() && !type.IsTypeParameterType())
            {
                ErrorContext.Error(ErrorCode.ERR_BadIndexLHS, type);
                MethWithInst mwi = new MethWithInst(null, null);
                EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(pObject, mwi);
                EXPRCALL rval = GetExprFactory().CreateCall(0, type, args, pMemGroup, null);
                rval.SetError();
                return rval;
            }

            Name pName = GetSymbolLoader().GetNameManager().GetPredefName(PredefinedName.PN_INDEXERINTERNAL);

            MemberLookup mem = new MemberLookup();
            if (!mem.Lookup(GetSemanticChecker(), type, pObject, ContextForMemberLookup(), pName, 0,
                            (bindFlags & BindingFlag.BIND_BASECALL) != 0 ? (MemLookFlags.BaseCall | MemLookFlags.Indexer) : MemLookFlags.Indexer))
            {
                mem.ReportErrors();
                type = GetTypes().GetErrorSym();
                Symbol pSymbol = null;

                if (mem.SwtInaccessible().Sym != null)
                {
                    Debug.Assert(mem.SwtInaccessible().Sym.IsMethodOrPropertySymbol());
                    type = mem.SwtInaccessible().MethProp().RetType;
                    pSymbol = mem.SwtInaccessible().Sym;
                }

                EXPRMEMGRP memgrp = null;

                if (pSymbol != null)
                {
                    memgrp = GetExprFactory().CreateMemGroup((EXPRFLAG)mem.GetFlags(),
                        pName, BSYMMGR.EmptyTypeArray(), pSymbol.getKind(), mem.GetSourceType(), null/*pMPS*/, mem.GetObject(), mem.GetResults());
                    memgrp.SetInaccessibleBit();
                }
                else
                {
                    MethWithInst mwi = new MethWithInst(null, null);
                    memgrp = GetExprFactory().CreateMemGroup(mem.GetObject(), mwi);
                }

                EXPRCALL rval = GetExprFactory().CreateCall(0, type, args, memgrp, null);
                rval.SetError();
                return rval;
            }

            Debug.Assert(mem.SymFirst().IsPropertySymbol() && mem.SymFirst().AsPropertySymbol().isIndexer());

            EXPRMEMGRP grp = GetExprFactory().CreateMemGroup((EXPRFLAG)mem.GetFlags(),
                pName, BSYMMGR.EmptyTypeArray(), mem.SymFirst().getKind(), mem.GetSourceType(), null/*pMPS*/, mem.GetObject(), mem.GetResults());

            EXPR pResult = BindMethodGroupToArguments(bindFlags, grp, args);
            Debug.Assert(pResult.HasObject());
            if (pResult.getObject() == null)
            {
                // We must be in an error scenario where the object was not allowed. 
                // This can happen if the user tries to access the indexer off the
                // type and not an instance or if the incorrect type/number of arguments 
                // were passed for binding.
                pResult.SetObject(pObject);
                pResult.SetError();
            }
            return pResult;
        }
Ejemplo n.º 27
0
 public static ExprCall CreateCall(EXPRFLAG flags, CType type, Expr arguments, ExprMemberGroup memberGroup, MethWithInst method) =>
 new ExprCall(type, flags, arguments, memberGroup, method);
Ejemplo n.º 28
0
        public ExprCall CreateCall(EXPRFLAG nFlags, CType pType, Expr pOptionalArguments, ExprMemberGroup pMemberGroup, MethWithInst MWI)
        {
            Debug.Assert(0 == (nFlags &
                               ~(
                                   EXPRFLAG.EXF_NEWOBJCALL | EXPRFLAG.EXF_CONSTRAINED | EXPRFLAG.EXF_BASECALL |
                                   EXPRFLAG.EXF_NEWSTRUCTASSG |
                                   EXPRFLAG.EXF_IMPLICITSTRUCTASSG | EXPRFLAG.EXF_MASK_ANY
                                   )
                               ));

            ExprCall rval = new ExprCall();

            rval.Kind                 = ExpressionKind.EK_CALL;
            rval.Type                 = pType;
            rval.Flags                = nFlags;
            rval.OptionalArguments    = pOptionalArguments;
            rval.MemberGroup          = pMemberGroup;
            rval.NullableCallLiftKind = NullableCallLiftKind.NotLifted;
            rval.CastOfNonLiftedResultToLiftedType = null;

            rval.MethWithInst = MWI;
            Debug.Assert(rval != null);
            return(rval);
        }
Ejemplo n.º 29
0
            /***************************************************************************************************
            *   Called by BindImplicitConversion when the destination type is Nullable<T>. The following
            *   conversions are handled by this method:
            *
            * For S in { object, ValueType, interfaces implemented by underlying type} there is an explicit
            *     unboxing conversion S => T?
            * System.Enum => T? there is an unboxing conversion if T is an enum type
            * null => T? implemented as default(T?)
            *
            * Implicit T?* => T?+ implemented by either wrapping or calling GetValueOrDefault the
            *     appropriate number of times.
            * If imp/exp S => T then imp/exp S => T?+ implemented by converting to T then wrapping the
            *     appropriate number of times.
            * If imp/exp S => T then imp/exp S?+ => T?+ implemented by calling GetValueOrDefault (m-1) times
            *     then calling HasValue, producing a null if it returns false, otherwise calling Value,
            *     converting to T then wrapping the appropriate number of times.
            *
            *   The 3 rules above can be summarized with the following recursive rules:
            *
            * If imp/exp S => T? then imp/exp S? => T? implemented as
            *     qs.HasValue ? (T?)(qs.Value) : default(T?)
            * If imp/exp S => T then imp/exp S => T? implemented as new T?((T)s)
            *
            *   This method also handles calling bindUserDefinedConverion. This method does NOT handle
            *   the following conversions:
            *
            * Implicit boxing conversion from S? to { object, ValueType, Enum, ifaces implemented by S }. (Handled by BindImplicitConversion.)
            * If imp/exp S => T then explicit S?+ => T implemented by calling Value the appropriate number
            *     of times. (Handled by BindExplicitConversion.)
            *
            *   The recursive equivalent is:
            *
            * If imp/exp S => T and T is not nullable then explicit S? => T implemented as qs.Value
            *
            *   Some nullable conversion are NOT standard conversions. In particular, if S => T is implicit
            *   then S? => T is not standard. Similarly if S => T is not implicit then S => T? is not standard.
            ***************************************************************************************************/
            private bool BindNubConversion(NullableType nubDst)
            {
                // This code assumes that STANDARD and ISEXPLICIT are never both set.
                // bindUserDefinedConversion should ensure this!
                Debug.Assert(0 != (~flags & (CONVERTTYPE.STANDARD | CONVERTTYPE.ISEXPLICIT)));
                Debug.Assert(exprSrc == null || exprSrc.type == typeSrc);
                Debug.Assert(!needsExprDest || exprSrc != null);
                Debug.Assert(typeSrc != nubDst); // BindImplicitConversion should have taken care of this already.
                AggregateType atsDst = nubDst.GetAts(GetErrorContext());

                if (atsDst == null)
                {
                    return(false);
                }

                // Check for the unboxing conversion. This takes precedence over the wrapping conversions.
                if (GetSymbolLoader().HasBaseConversion(nubDst.GetUnderlyingType(), typeSrc) && !CConversions.FWrappingConv(typeSrc, nubDst))
                {
                    // These should be different! Fix the caller if typeSrc is an AggregateType of Nullable.
                    Debug.Assert(atsDst != typeSrc);

                    // typeSrc is a base type of the destination nullable type so there is an explicit
                    // unboxing conversion.
                    if (0 == (flags & CONVERTTYPE.ISEXPLICIT))
                    {
                        return(false);
                    }

                    if (needsExprDest)
                    {
                        binder.bindSimpleCast(exprSrc, exprTypeDest, out exprDest, EXPRFLAG.EXF_UNBOX);
                    }
                    return(true);
                }

                int       cnubDst;
                int       cnubSrc;
                CType     typeDstBase     = nubDst.StripNubs(out cnubDst);
                EXPRCLASS exprTypeDstBase = GetExprFactory().MakeClass(typeDstBase);
                CType     typeSrcBase     = typeSrc.StripNubs(out cnubSrc);

                ConversionFunc pfn = (flags & CONVERTTYPE.ISEXPLICIT) != 0 ?
                                     (ConversionFunc)binder.BindExplicitConversion :
                                     (ConversionFunc)binder.BindImplicitConversion;

                if (cnubSrc == 0)
                {
                    Debug.Assert(typeSrc == typeSrcBase);

                    // The null type can be implicitly converted to T? as the default value.
                    if (typeSrc.IsNullType())
                    {
                        // If we have the constant null, generate it as a default value of T?.  If we have
                        // some crazy expression which has been determined to be always null, like (null??null)
                        // keep it in its expression form and transform it in the nullable rewrite pass.
                        if (needsExprDest)
                        {
                            if (exprSrc.isCONSTANT_OK())
                            {
                                exprDest = GetExprFactory().CreateZeroInit(nubDst);
                            }
                            else
                            {
                                exprDest = GetExprFactory().CreateCast(0x00, typeDest, exprSrc);
                            }
                        }
                        return(true);
                    }

                    EXPR exprTmp = exprSrc;

                    // If there is an implicit/explicit S => T then there is an implicit/explicit S => T?
                    if (typeSrc == typeDstBase || pfn(exprSrc, typeSrc, exprTypeDstBase, nubDst, needsExprDest, out exprTmp, flags | CONVERTTYPE.NOUDC))
                    {
                        if (needsExprDest)
                        {
                            // UNDONE: This is a premature realization of the nullable conversion as
                            // UNDONE: a constructor.  Rather than flagging this, can we simply emit it
                            // UNDONE: as a cast node and have the operator rewrite pass turn it into
                            // UNDONE: a constructor call?
                            EXPRUSERDEFINEDCONVERSION exprUDC = exprTmp.kind == ExpressionKind.EK_USERDEFINEDCONVERSION ? exprTmp.asUSERDEFINEDCONVERSION() : null;
                            if (exprUDC != null)
                            {
                                exprTmp = exprUDC.UserDefinedCall;
                            }

                            // This logic is left over from the days when T?? was legal. However there are error/LAF cases that necessitates the loop.
                            // typeSrc is not nullable so just wrap the required number of times. For legal code (cnubDst <= 0).

                            for (int i = 0; i < cnubDst; i++)
                            {
                                exprTmp = binder.BindNubNew(exprTmp);
                                exprTmp.asCALL().nubLiftKind = NullableCallLiftKind.NullableConversionConstructor;
                            }
                            if (exprUDC != null)
                            {
                                exprUDC.UserDefinedCall = exprTmp;
                                exprUDC.setType((CType)exprTmp.type);
                                exprTmp = exprUDC;
                            }
                            Debug.Assert(exprTmp.type == nubDst);
                            exprDest = exprTmp;
                        }
                        return(true);
                    }

                    // No builtin conversion. Maybe there is a user defined conversion....
                    return(0 == (flags & CONVERTTYPE.NOUDC) && binder.bindUserDefinedConversion(exprSrc, typeSrc, nubDst, needsExprDest, out exprDest, 0 == (flags & CONVERTTYPE.ISEXPLICIT)));
                }

                // Both are Nullable so there is only a conversion if there is a conversion between the base types.
                // That is, if there is an implicit/explicit S => T then there is an implicit/explicit S?+ => T?+.
                if (typeSrcBase != typeDstBase && !pfn(null, typeSrcBase, exprTypeDstBase, nubDst, false, out exprDest, flags | CONVERTTYPE.NOUDC))
                {
                    // No builtin conversion. Maybe there is a user defined conversion....
                    return(0 == (flags & CONVERTTYPE.NOUDC) && binder.bindUserDefinedConversion(exprSrc, typeSrc, nubDst, needsExprDest, out exprDest, 0 == (flags & CONVERTTYPE.ISEXPLICIT)));
                }

                if (needsExprDest)
                {
                    MethWithInst mwi       = new MethWithInst(null, null);
                    EXPRMEMGRP   pMemGroup = GetExprFactory().CreateMemGroup(null, mwi);
                    EXPRCALL     exprDst   = GetExprFactory().CreateCall(0, nubDst, exprSrc, pMemGroup, null);

                    // Here we want to first check whether or not the conversions work on the base types.

                    EXPR      arg1 = binder.mustCast(exprSrc, typeSrcBase);
                    EXPRCLASS arg2 = GetExprFactory().MakeClass(typeDstBase);

                    bool convertible;
                    if (0 != (flags & CONVERTTYPE.ISEXPLICIT))
                    {
                        convertible = binder.BindExplicitConversion(arg1, arg1.type, arg2, typeDstBase, out arg1, flags | CONVERTTYPE.NOUDC);
                    }
                    else
                    {
                        convertible = binder.BindImplicitConversion(arg1, arg1.type, arg2, typeDstBase, out arg1, flags | CONVERTTYPE.NOUDC);
                    }
                    if (!convertible)
                    {
                        VSFAIL("bind(Im|Ex)plicitConversion failed unexpectedly");
                        return(false);
                    }

                    exprDst.castOfNonLiftedResultToLiftedType = binder.mustCast(arg1, nubDst, 0);
                    exprDst.nubLiftKind  = NullableCallLiftKind.NullableConversion;
                    exprDst.pConversions = exprDst.castOfNonLiftedResultToLiftedType;
                    exprDest             = exprDst;
                }

                return(true);
            }
Ejemplo n.º 30
0
        public ExprFuncPtr CreateFunctionPointer(EXPRFLAG nFlags, CType pType, Expr pObject, MethWithInst MWI)
        {
            Debug.Assert(0 == (nFlags & ~(EXPRFLAG.EXF_BASECALL)));
            ExprFuncPtr rval = new ExprFuncPtr();

            rval.Kind           = ExpressionKind.EK_FUNCPTR;
            rval.Type           = pType;
            rval.Flags          = nFlags;
            rval.OptionalObject = pObject;
            rval.MethWithInst   = new MethWithInst(MWI);
            Debug.Assert(rval != null);
            return(rval);
        }
Ejemplo n.º 31
0
            /***************************************************************************************************
            *   Called by BindImplicitConversion when the destination type is Nullable<T>. The following
            *   conversions are handled by this method:
            *
            * For S in { object, ValueType, interfaces implemented by underlying type} there is an explicit
            *     unboxing conversion S => T?
            * System.Enum => T? there is an unboxing conversion if T is an enum type
            * null => T? implemented as default(T?)
            *
            * Implicit T?* => T?+ implemented by either wrapping or calling GetValueOrDefault the
            *     appropriate number of times.
            * If imp/exp S => T then imp/exp S => T?+ implemented by converting to T then wrapping the
            *     appropriate number of times.
            * If imp/exp S => T then imp/exp S?+ => T?+ implemented by calling GetValueOrDefault (m-1) times
            *     then calling HasValue, producing a null if it returns false, otherwise calling Value,
            *     converting to T then wrapping the appropriate number of times.
            *
            *   The 3 rules above can be summarized with the following recursive rules:
            *
            * If imp/exp S => T? then imp/exp S? => T? implemented as
            *     qs.HasValue ? (T?)(qs.Value) : default(T?)
            * If imp/exp S => T then imp/exp S => T? implemented as new T?((T)s)
            *
            *   This method also handles calling bindUserDefinedConverion. This method does NOT handle
            *   the following conversions:
            *
            * Implicit boxing conversion from S? to { object, ValueType, Enum, ifaces implemented by S }. (Handled by BindImplicitConversion.)
            * If imp/exp S => T then explicit S?+ => T implemented by calling Value the appropriate number
            *     of times. (Handled by BindExplicitConversion.)
            *
            *   The recursive equivalent is:
            *
            * If imp/exp S => T and T is not nullable then explicit S? => T implemented as qs.Value
            *
            *   Some nullable conversion are NOT standard conversions. In particular, if S => T is implicit
            *   then S? => T is not standard. Similarly if S => T is not implicit then S => T? is not standard.
            ***************************************************************************************************/
            private bool BindNubConversion(NullableType nubDst)
            {
                // This code assumes that STANDARD and ISEXPLICIT are never both set.
                // bindUserDefinedConversion should ensure this!
                Debug.Assert(0 != (~_flags & (CONVERTTYPE.STANDARD | CONVERTTYPE.ISEXPLICIT)));
                Debug.Assert(_exprSrc == null || _exprSrc.Type == _typeSrc);
                Debug.Assert(!_needsExprDest || _exprSrc != null);
                Debug.Assert(_typeSrc != nubDst); // BindImplicitConversion should have taken care of this already.
                AggregateType atsDst = nubDst.GetAts();

                // Check for the unboxing conversion. This takes precedence over the wrapping conversions.
                if (GetSymbolLoader().HasBaseConversion(nubDst.GetUnderlyingType(), _typeSrc) && !CConversions.FWrappingConv(_typeSrc, nubDst))
                {
                    // These should be different! Fix the caller if typeSrc is an AggregateType of Nullable.
                    Debug.Assert(atsDst != _typeSrc);

                    // typeSrc is a base type of the destination nullable type so there is an explicit
                    // unboxing conversion.
                    if (0 == (_flags & CONVERTTYPE.ISEXPLICIT))
                    {
                        return(false);
                    }

                    if (_needsExprDest)
                    {
                        _binder.bindSimpleCast(_exprSrc, _typeDest, out _exprDest, EXPRFLAG.EXF_UNBOX);
                    }
                    return(true);
                }

                bool           dstWasNullable;
                bool           srcWasNullable;
                CType          typeDstBase = nubDst.StripNubs(out dstWasNullable);
                CType          typeSrcBase = _typeSrc.StripNubs(out srcWasNullable);
                ConversionFunc pfn         = (_flags & CONVERTTYPE.ISEXPLICIT) != 0 ?
                                             (ConversionFunc)_binder.BindExplicitConversion :
                                             (ConversionFunc)_binder.BindImplicitConversion;

                if (!srcWasNullable)
                {
                    Debug.Assert(_typeSrc == typeSrcBase);

                    // The null type can be implicitly converted to T? as the default value.
                    if (_typeSrc is NullType)
                    {
                        // If we have the constant null, generate it as a default value of T?.  If we have
                        // some crazy expression which has been determined to be always null, like (null??null)
                        // keep it in its expression form and transform it in the nullable rewrite pass.
                        if (_needsExprDest)
                        {
                            if (_exprSrc.isCONSTANT_OK())
                            {
                                _exprDest = GetExprFactory().CreateZeroInit(nubDst);
                            }
                            else
                            {
                                _exprDest = GetExprFactory().CreateCast(_typeDest, _exprSrc);
                            }
                        }
                        return(true);
                    }

                    Expr exprTmp = _exprSrc;

                    // If there is an implicit/explicit S => T then there is an implicit/explicit S => T?
                    if (_typeSrc == typeDstBase || pfn(_exprSrc, _typeSrc, typeDstBase, _needsExprDest, out exprTmp, _flags | CONVERTTYPE.NOUDC))
                    {
                        if (_needsExprDest)
                        {
                            ExprUserDefinedConversion exprUDC = exprTmp as ExprUserDefinedConversion;
                            if (exprUDC != null)
                            {
                                exprTmp = exprUDC.UserDefinedCall;
                            }

                            if (dstWasNullable)
                            {
                                ExprCall call = _binder.BindNubNew(exprTmp);
                                exprTmp = call;
                                call.NullableCallLiftKind = NullableCallLiftKind.NullableConversionConstructor;
                            }

                            if (exprUDC != null)
                            {
                                exprUDC.UserDefinedCall = exprTmp;
                                exprTmp = exprUDC;
                            }

                            Debug.Assert(exprTmp.Type == nubDst);
                            _exprDest = exprTmp;
                        }
                        return(true);
                    }

                    // No builtin conversion. Maybe there is a user defined conversion....
                    return(0 == (_flags & CONVERTTYPE.NOUDC) && _binder.bindUserDefinedConversion(_exprSrc, _typeSrc, nubDst, _needsExprDest, out _exprDest, 0 == (_flags & CONVERTTYPE.ISEXPLICIT)));
                }

                // Both are Nullable so there is only a conversion if there is a conversion between the base types.
                // That is, if there is an implicit/explicit S => T then there is an implicit/explicit S?+ => T?+.
                if (typeSrcBase != typeDstBase && !pfn(null, typeSrcBase, typeDstBase, false, out _exprDest, _flags | CONVERTTYPE.NOUDC))
                {
                    // No builtin conversion. Maybe there is a user defined conversion....
                    return(0 == (_flags & CONVERTTYPE.NOUDC) && _binder.bindUserDefinedConversion(_exprSrc, _typeSrc, nubDst, _needsExprDest, out _exprDest, 0 == (_flags & CONVERTTYPE.ISEXPLICIT)));
                }

                if (_needsExprDest)
                {
                    MethWithInst    mwi       = new MethWithInst(null, null);
                    ExprMemberGroup pMemGroup = GetExprFactory().CreateMemGroup(null, mwi);
                    ExprCall        exprDst   = GetExprFactory().CreateCall(0, nubDst, _exprSrc, pMemGroup, null);

                    // Here we want to first check whether or not the conversions work on the base types.

                    Expr arg1        = _binder.mustCast(_exprSrc, typeSrcBase);
                    bool convertible = (_flags & CONVERTTYPE.ISEXPLICIT) != 0
                        ? _binder.BindExplicitConversion(
                        arg1, arg1.Type, typeDstBase, out arg1, _flags | CONVERTTYPE.NOUDC)
                        : _binder.BindImplicitConversion(
                        arg1, arg1.Type, typeDstBase, out arg1, _flags | CONVERTTYPE.NOUDC);

                    if (!convertible)
                    {
                        Debug.Fail("bind(Im|Ex)plicitConversion failed unexpectedly");
                        return(false);
                    }

                    exprDst.CastOfNonLiftedResultToLiftedType = _binder.mustCast(arg1, nubDst, 0);
                    exprDst.NullableCallLiftKind = NullableCallLiftKind.NullableConversion;
                    exprDst.PConversions         = exprDst.CastOfNonLiftedResultToLiftedType;
                    _exprDest = exprDst;
                }

                return(true);
            }
Ejemplo n.º 32
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);
            }
        }
Ejemplo n.º 33
0
        private EXPR BindUserBoolOp(ExpressionKind kind, EXPRCALL pCall)
        {
            RETAILVERIFY(pCall != null);
            RETAILVERIFY(pCall.mwi.Meth() != null);
            RETAILVERIFY(pCall.GetOptionalArguments() != null);
            Debug.Assert(kind == ExpressionKind.EK_LOGAND || kind == ExpressionKind.EK_LOGOR);

            CType typeRet = pCall.type;

            Debug.Assert(pCall.mwi.Meth().Params.size == 2);
            if (!GetTypes().SubstEqualTypes(typeRet, pCall.mwi.Meth().Params.Item(0), typeRet) ||
                !GetTypes().SubstEqualTypes(typeRet, pCall.mwi.Meth().Params.Item(1), typeRet))
            {
                MethWithInst mwi = new MethWithInst(null, null);
                EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(null, mwi);
                EXPRCALL pCallTF = GetExprFactory().CreateCall(0, null, null, pMemGroup, null);
                pCallTF.SetError();
                GetErrorContext().Error(ErrorCode.ERR_BadBoolOp, pCall.mwi);
                return GetExprFactory().CreateUserLogOpError(typeRet, pCallTF, pCall);
            }

            Debug.Assert(pCall.GetOptionalArguments().isLIST());

            EXPR pExpr = pCall.GetOptionalArguments().asLIST().GetOptionalElement();
            EXPR pExprWrap = WrapShortLivedExpression(pExpr);
            pCall.GetOptionalArguments().asLIST().SetOptionalElement(pExprWrap);

            // Reflection load the true and false methods.
            SymbolLoader.RuntimeBinderSymbolTable.PopulateSymbolTableWithName(SpecialNames.CLR_True, null, pExprWrap.type.AssociatedSystemType);
            SymbolLoader.RuntimeBinderSymbolTable.PopulateSymbolTableWithName(SpecialNames.CLR_False, null, pExprWrap.type.AssociatedSystemType);

            EXPR pCallT = bindUDUnop(ExpressionKind.EK_TRUE, pExprWrap);
            EXPR pCallF = bindUDUnop(ExpressionKind.EK_FALSE, pExprWrap);

            if (pCallT == null || pCallF == null)
            {
                EXPR pCallTorF = pCallT != null ? pCallT : pCallF;
                if (pCallTorF == null)
                {
                    MethWithInst mwi = new MethWithInst(null, null);
                    EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(null, mwi);
                    pCallTorF = GetExprFactory().CreateCall(0, null, pExprWrap, pMemGroup, null);
                    pCall.SetError();
                }
                GetErrorContext().Error(ErrorCode.ERR_MustHaveOpTF, typeRet);
                return GetExprFactory().CreateUserLogOpError(typeRet, pCallTorF, pCall);
            }
            pCallT = mustConvert(pCallT, GetReqPDT(PredefinedType.PT_BOOL));
            pCallF = mustConvert(pCallF, GetReqPDT(PredefinedType.PT_BOOL));
            return GetExprFactory().CreateUserLogOp(typeRet, kind == ExpressionKind.EK_LOGAND ? pCallF : pCallT, pCall);
        }
Ejemplo n.º 34
0
 public ExprFuncPtr CreateFunctionPointer(EXPRFLAG flags, CType type, Expr obj, MethWithInst method) =>
 new ExprFuncPtr(type, flags, obj, method);
Ejemplo n.º 35
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));
        }
Ejemplo n.º 36
0
 public EXPRUSERDEFINEDCONVERSION CreateUserDefinedConversion(EXPR arg, EXPR call, MethWithInst mwi)
 {
     Debug.Assert(arg != null);
     Debug.Assert(call != null);
     EXPRUSERDEFINEDCONVERSION rval = new EXPRUSERDEFINEDCONVERSION();
     rval.kind = ExpressionKind.EK_USERDEFINEDCONVERSION;
     rval.type = call.type;
     rval.flags = 0;
     rval.Argument = arg;
     rval.UserDefinedCall = call;
     rval.UserDefinedCallMethod = mwi;
     if (call.HasError())
     {
         rval.SetError();
     }
     Debug.Assert(rval != null);
     return rval;
 }
Ejemplo n.º 37
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;
        }
        public EXPRUSERDEFINEDCONVERSION CreateUserDefinedConversion(EXPR arg, EXPR call, MethWithInst mwi)
        {
            Debug.Assert(arg != null);
            Debug.Assert(call != null);
            EXPRUSERDEFINEDCONVERSION rval = new EXPRUSERDEFINEDCONVERSION();

            rval.kind                  = ExpressionKind.EK_USERDEFINEDCONVERSION;
            rval.type                  = call.type;
            rval.flags                 = 0;
            rval.Argument              = arg;
            rval.UserDefinedCall       = call;
            rval.UserDefinedCallMethod = mwi;
            if (call.HasError())
            {
                rval.SetError();
            }
            Debug.Assert(rval != null);
            return(rval);
        }
Ejemplo n.º 39
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;
 }
        public EXPRCALL CreateCall(EXPRFLAG nFlags, CType pType, EXPR pOptionalArguments, EXPRMEMGRP pMemberGroup, MethWithInst MWI)
        {
            Debug.Assert(0 == (nFlags &
                               ~(
                                   EXPRFLAG.EXF_NEWOBJCALL | EXPRFLAG.EXF_CONSTRAINED | EXPRFLAG.EXF_BASECALL |
                                   EXPRFLAG.EXF_NEWSTRUCTASSG |
                                   EXPRFLAG.EXF_IMPLICITSTRUCTASSG | EXPRFLAG.EXF_MASK_ANY
                                   )
                               ));

            EXPRCALL rval = new EXPRCALL();

            rval.kind  = ExpressionKind.EK_CALL;
            rval.type  = pType;
            rval.flags = nFlags;
            rval.SetOptionalArguments(pOptionalArguments);
            rval.SetMemberGroup(pMemberGroup);
            rval.nubLiftKind = NullableCallLiftKind.NotLifted;
            rval.castOfNonLiftedResultToLiftedType = null;

            rval.mwi = MWI;
            Debug.Assert(rval != null);
            return(rval);
        }
Ejemplo n.º 41
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);
        }
        public EXPRFUNCPTR CreateFunctionPointer(EXPRFLAG nFlags, CType pType, EXPR pObject, MethWithInst MWI)
        {
            Debug.Assert(0 == (nFlags & ~(EXPRFLAG.EXF_BASECALL)));
            EXPRFUNCPTR rval = new EXPRFUNCPTR();

            rval.kind           = ExpressionKind.EK_FUNCPTR;
            rval.type           = pType;
            rval.flags          = nFlags;
            rval.OptionalObject = pObject;
            rval.mwi            = new MethWithInst(MWI);
            Debug.Assert(rval != null);
            return(rval);
        }
Ejemplo n.º 43
0
            /***************************************************************************************************
                Called by BindImplicitConversion when the destination type is Nullable<T>. The following
                conversions are handled by this method:
             
                * For S in { object, ValueType, interfaces implemented by underlying type} there is an explicit
                  unboxing conversion S => T?
                * System.Enum => T? there is an unboxing conversion if T is an enum type
                * null => T? implemented as default(T?)
             
                * Implicit T?* => T?+ implemented by either wrapping or calling GetValueOrDefault the
                  appropriate number of times.
                * If imp/exp S => T then imp/exp S => T?+ implemented by converting to T then wrapping the
                  appropriate number of times.
                * If imp/exp S => T then imp/exp S?+ => T?+ implemented by calling GetValueOrDefault (m-1) times
                  then calling HasValue, producing a null if it returns false, otherwise calling Value,
                  converting to T then wrapping the appropriate number of times.
             
                The 3 rules above can be summarized with the following recursive rules:
             
                * If imp/exp S => T? then imp/exp S? => T? implemented as
                  qs.HasValue ? (T?)(qs.Value) : default(T?)
                * If imp/exp S => T then imp/exp S => T? implemented as new T?((T)s)
             
                This method also handles calling bindUserDefinedConverion. This method does NOT handle
                the following conversions:
             
                * Implicit boxing conversion from S? to { object, ValueType, Enum, ifaces implemented by S }. (Handled by BindImplicitConversion.)
                * If imp/exp S => T then explicit S?+ => T implemented by calling Value the appropriate number
                  of times. (Handled by BindExplicitConversion.)
             
                The recursive equivalent is:
             
                * If imp/exp S => T and T is not nullable then explicit S? => T implemented as qs.Value
             
                Some nullable conversion are NOT standard conversions. In particular, if S => T is implicit
                then S? => T is not standard. Similarly if S => T is not implicit then S => T? is not standard.
            ***************************************************************************************************/
            private bool BindNubConversion(NullableType nubDst)
            {
                // This code assumes that STANDARD and ISEXPLICIT are never both set.
                // bindUserDefinedConversion should ensure this!
                Debug.Assert(0 != (~_flags & (CONVERTTYPE.STANDARD | CONVERTTYPE.ISEXPLICIT)));
                Debug.Assert(_exprSrc == null || _exprSrc.type == _typeSrc);
                Debug.Assert(!_needsExprDest || _exprSrc != null);
                Debug.Assert(_typeSrc != nubDst); // BindImplicitConversion should have taken care of this already.
                AggregateType atsDst = nubDst.GetAts(GetErrorContext());
                if (atsDst == null)
                    return false;

                // Check for the unboxing conversion. This takes precedence over the wrapping conversions.
                if (GetSymbolLoader().HasBaseConversion(nubDst.GetUnderlyingType(), _typeSrc) && !CConversions.FWrappingConv(_typeSrc, nubDst))
                {
                    // These should be different! Fix the caller if typeSrc is an AggregateType of Nullable.
                    Debug.Assert(atsDst != _typeSrc);

                    // typeSrc is a base type of the destination nullable type so there is an explicit
                    // unboxing conversion.
                    if (0 == (_flags & CONVERTTYPE.ISEXPLICIT))
                    {
                        return false;
                    }

                    if (_needsExprDest)
                    {
                        _binder.bindSimpleCast(_exprSrc, _exprTypeDest, out _exprDest, EXPRFLAG.EXF_UNBOX);
                    }
                    return true;
                }

                int cnubDst;
                int cnubSrc;
                CType typeDstBase = nubDst.StripNubs(out cnubDst);
                EXPRCLASS exprTypeDstBase = GetExprFactory().MakeClass(typeDstBase);
                CType typeSrcBase = _typeSrc.StripNubs(out cnubSrc);

                ConversionFunc pfn = (_flags & CONVERTTYPE.ISEXPLICIT) != 0 ?
                    (ConversionFunc)_binder.BindExplicitConversion :
                    (ConversionFunc)_binder.BindImplicitConversion;

                if (cnubSrc == 0)
                {
                    Debug.Assert(_typeSrc == typeSrcBase);

                    // The null type can be implicitly converted to T? as the default value.
                    if (_typeSrc.IsNullType())
                    {
                        // If we have the constant null, generate it as a default value of T?.  If we have 
                        // some crazy expression which has been determined to be always null, like (null??null)
                        // keep it in its expression form and transform it in the nullable rewrite pass.
                        if (_needsExprDest)
                        {
                            if (_exprSrc.isCONSTANT_OK())
                            {
                                _exprDest = GetExprFactory().CreateZeroInit(nubDst);
                            }
                            else
                            {
                                _exprDest = GetExprFactory().CreateCast(0x00, _typeDest, _exprSrc);
                            }
                        }
                        return true;
                    }

                    EXPR exprTmp = _exprSrc;

                    // If there is an implicit/explicit S => T then there is an implicit/explicit S => T?
                    if (_typeSrc == typeDstBase || pfn(_exprSrc, _typeSrc, exprTypeDstBase, nubDst, _needsExprDest, out exprTmp, _flags | CONVERTTYPE.NOUDC))
                    {
                        if (_needsExprDest)
                        {
                            EXPRUSERDEFINEDCONVERSION exprUDC = exprTmp.kind == ExpressionKind.EK_USERDEFINEDCONVERSION ? exprTmp.asUSERDEFINEDCONVERSION() : null;
                            if (exprUDC != null)
                            {
                                exprTmp = exprUDC.UserDefinedCall;
                            }

                            // This logic is left over from the days when T?? was legal. However there are error/LAF cases that necessitates the loop.
                            // typeSrc is not nullable so just wrap the required number of times. For legal code (cnubDst <= 0).

                            for (int i = 0; i < cnubDst; i++)
                            {
                                exprTmp = _binder.BindNubNew(exprTmp);
                                exprTmp.asCALL().nubLiftKind = NullableCallLiftKind.NullableConversionConstructor;
                            }
                            if (exprUDC != null)
                            {
                                exprUDC.UserDefinedCall = exprTmp;
                                exprUDC.setType((CType)exprTmp.type);
                                exprTmp = exprUDC;
                            }
                            Debug.Assert(exprTmp.type == nubDst);
                            _exprDest = exprTmp;
                        }
                        return true;
                    }

                    // No builtin conversion. Maybe there is a user defined conversion....
                    return 0 == (_flags & CONVERTTYPE.NOUDC) && _binder.bindUserDefinedConversion(_exprSrc, _typeSrc, nubDst, _needsExprDest, out _exprDest, 0 == (_flags & CONVERTTYPE.ISEXPLICIT));
                }

                // Both are Nullable so there is only a conversion if there is a conversion between the base types.
                // That is, if there is an implicit/explicit S => T then there is an implicit/explicit S?+ => T?+.
                if (typeSrcBase != typeDstBase && !pfn(null, typeSrcBase, exprTypeDstBase, nubDst, false, out _exprDest, _flags | CONVERTTYPE.NOUDC))
                {
                    // No builtin conversion. Maybe there is a user defined conversion....
                    return 0 == (_flags & CONVERTTYPE.NOUDC) && _binder.bindUserDefinedConversion(_exprSrc, _typeSrc, nubDst, _needsExprDest, out _exprDest, 0 == (_flags & CONVERTTYPE.ISEXPLICIT));
                }

                if (_needsExprDest)
                {
                    MethWithInst mwi = new MethWithInst(null, null);
                    EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(null, mwi);
                    EXPRCALL exprDst = GetExprFactory().CreateCall(0, nubDst, _exprSrc, pMemGroup, null);

                    // Here we want to first check whether or not the conversions work on the base types.

                    EXPR arg1 = _binder.mustCast(_exprSrc, typeSrcBase);
                    EXPRCLASS arg2 = GetExprFactory().MakeClass(typeDstBase);

                    bool convertible;
                    if (0 != (_flags & CONVERTTYPE.ISEXPLICIT))
                    {
                        convertible = _binder.BindExplicitConversion(arg1, arg1.type, arg2, typeDstBase, out arg1, _flags | CONVERTTYPE.NOUDC);
                    }
                    else
                    {
                        convertible = _binder.BindImplicitConversion(arg1, arg1.type, arg2, typeDstBase, out arg1, _flags | CONVERTTYPE.NOUDC);
                    }
                    if (!convertible)
                    {
                        VSFAIL("bind(Im|Ex)plicitConversion failed unexpectedly");
                        return false;
                    }

                    exprDst.castOfNonLiftedResultToLiftedType = _binder.mustCast(arg1, nubDst, 0);
                    exprDst.nubLiftKind = NullableCallLiftKind.NullableConversion;
                    exprDst.pConversions = exprDst.castOfNonLiftedResultToLiftedType;
                    _exprDest = exprDst;
                }

                return true;
            }
Ejemplo n.º 44
0
        public EXPRCALL BindNew(EXPR pExprSrc)
        {
            Debug.Assert(pExprSrc != null);

            NullableType pNubSourceType = GetSymbolLoader().GetTypeManager().GetNullable(pExprSrc.type);

            AggregateType pSourceType = pNubSourceType.GetAts(GetErrorContext());
            if (pSourceType == null)
            {
                MethWithInst mwi = new MethWithInst(null, null);
                EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(pExprSrc, mwi);
                EXPRCALL rval = GetExprFactory().CreateCall(0, pNubSourceType, null, pMemGroup, null);
                rval.SetError();
                return rval;
            }

            MethodSymbol meth = GetSymbolLoader().getBSymmgr().methNubCtor;
            if (meth == null)
            {
                meth = GetSymbolLoader().getPredefinedMembers().GetMethod(PREDEFMETH.PM_G_OPTIONAL_CTOR);
                GetSymbolLoader().getBSymmgr().methNubCtor = meth;
            }

            MethWithInst methwithinst = new MethWithInst(meth, pSourceType, BSYMMGR.EmptyTypeArray());
            EXPRMEMGRP memgroup = GetExprFactory().CreateMemGroup(null, methwithinst);
            EXPRCALL pExprRes = GetExprFactory().CreateCall(EXPRFLAG.EXF_NEWOBJCALL | EXPRFLAG.EXF_CANTBENULL, pNubSourceType, pExprSrc, memgroup, methwithinst);

            if (meth == null)
            {
                pExprRes.SetError();
            }

            return pExprRes;
        }