Пример #1
0
 public static EXPR StripNullableConstructor(EXPR pExpr)
 {
     while (IsNullableConstructor(pExpr))
     {
         Debug.Assert(pExpr.isCALL());
         pExpr = pExpr.asCALL().GetOptionalArguments();
         Debug.Assert(pExpr != null && !pExpr.isLIST());
     }
     return pExpr;
 }
Пример #2
0
 public static EXPR StripNullableConstructor(EXPR pExpr)
 {
     while (IsNullableConstructor(pExpr))
     {
         Debug.Assert(pExpr.isCALL());
         pExpr = pExpr.asCALL().GetOptionalArguments();
         Debug.Assert(pExpr != null && !pExpr.isLIST());
     }
     return(pExpr);
 }
Пример #3
0
        public static bool IsNullableConstructor(EXPR expr)
        {
            Debug.Assert(expr != null);

            if (!expr.isCALL())
            {
                return false;
            }

            EXPRCALL pCall = expr.asCALL();
            if (pCall.GetMemberGroup().GetOptionalObject() != null)
            {
                return false;
            }

            MethodSymbol meth = pCall.mwi.Meth();
            if (meth == null)
            {
                return false;
            }
            return meth.IsNullableConstructor();
        }
Пример #4
0
        public static bool IsNullableConstructor(EXPR expr)
        {
            Debug.Assert(expr != null);

            if (!expr.isCALL())
            {
                return(false);
            }

            EXPRCALL pCall = expr.asCALL();

            if (pCall.GetMemberGroup().GetOptionalObject() != null)
            {
                return(false);
            }

            MethodSymbol meth = pCall.mwi.Meth();

            if (meth == null)
            {
                return(false);
            }
            return(meth.IsNullableConstructor());
        }
Пример #5
0
 protected bool IsDelegateConstructorCall(EXPR pExpr)
 {
     Debug.Assert(pExpr != null);
     if (!pExpr.isCALL())
     {
         return false;
     }
     EXPRCALL pCall = pExpr.asCALL();
     return pCall.mwi.Meth() != null &&
         pCall.mwi.Meth().IsConstructor() &&
         pCall.type.isDelegateType() &&
         pCall.GetOptionalArguments() != null &&
         pCall.GetOptionalArguments().isLIST() &&
         pCall.GetOptionalArguments().asLIST().GetOptionalNextListNode().kind == ExpressionKind.EK_FUNCPTR;
 }
        // Return true if we actually report a failure.
        protected bool TryReportLvalueFailure(EXPR expr, CheckLvalueKind kind)
        {
            Debug.Assert(expr != null);

            // We have a lvalue failure. Was the reason because this field
            // was marked readonly? Give special messages for this case.

            bool isNested = false; // Did we recurse on a field or property to give a better error?

            EXPR walk = expr;

            while (true)
            {
                Debug.Assert(walk != null);

                if (walk.isANYLOCAL_OK())
                {
                    ReportLocalError(walk.asANYLOCAL().local, kind, isNested);
                    return(true);
                }

                EXPR pObject = null;

                if (walk.isPROP())
                {
                    // We've already reported read-only-property errors.
                    Debug.Assert(walk.asPROP().mwtSet != null);
                    pObject = walk.asPROP().GetMemberGroup().GetOptionalObject();
                }
                else if (walk.isFIELD())
                {
                    EXPRFIELD field = walk.asFIELD();
                    if (field.fwt.Field().isReadOnly)
                    {
                        ReportReadOnlyError(field, kind, isNested);
                        return(true);
                    }
                    if (!field.fwt.Field().isStatic)
                    {
                        pObject = field.GetOptionalObject();
                    }
                }

                if (pObject != null && pObject.type.isStructOrEnum())
                {
                    if (pObject.isCALL() || pObject.isPROP())
                    {
                        // assigning to RHS of method or property getter returning a value-type on the stack or
                        // passing RHS of method or property getter returning a value-type on the stack, as ref or out
                        ErrorContext.Error(ErrorCode.ERR_ReturnNotLValue, pObject.GetSymWithType());
                        return(true);
                    }
                    if (pObject.isCAST())
                    {
                        // An unboxing conversion.
                        //
                        // In the static compiler, we give the following error here:
                        // ErrorContext.Error(pObject.GetTree(), ErrorCode.ERR_UnboxNotLValue);
                        //
                        // But in the runtime, we allow this - mark that we're doing an
                        // unbox here, so that we gen the correct expression tree for it.
                        pObject.flags |= EXPRFLAG.EXF_UNBOXRUNTIME;
                        return(false);
                    }
                }

                // everything else
                if (pObject != null && !pObject.isLvalue() && (walk.isFIELD() || (!isNested && walk.isPROP())))
                {
                    Debug.Assert(pObject.type.isStructOrEnum());
                    walk = pObject;
                }
                else
                {
                    ErrorContext.Error(GetStandardLvalueError(kind));
                    return(true);
                }
                isNested = true;
            }
        }
Пример #7
0
        private EXPR ReorderArgumentsForNamedAndOptional(EXPR callingObject, EXPR pResult)
        {
            EXPR arguments;
            AggregateType type;
            MethodOrPropertySymbol methprop;
            EXPRMEMGRP memgroup;
            TypeArray typeArgs;

            if (pResult.isCALL())
            {
                EXPRCALL call = pResult.asCALL();
                arguments = call.GetOptionalArguments();
                type = call.mwi.Ats;
                methprop = call.mwi.Meth();
                memgroup = call.GetMemberGroup();
                typeArgs = call.mwi.TypeArgs;
            }
            else
            {
                Debug.Assert(pResult.isPROP());
                EXPRPROP prop = pResult.asPROP();
                arguments = prop.GetOptionalArguments();
                type = prop.pwtSlot.Ats;
                methprop = prop.pwtSlot.Prop();
                memgroup = prop.GetMemberGroup();
                typeArgs = null;
            }

            ArgInfos argInfo = new ArgInfos();
            bool b;
            argInfo.carg = ExpressionBinder.CountArguments(arguments, out b);
            _binder.FillInArgInfoFromArgList(argInfo, arguments);

            // We need to substitute type parameters BEFORE getting the most derived one because
            // we're binding against the base method, and the derived method may change the 
            // generic arguments. 
            TypeArray parameters = SymbolLoader.GetTypeManager().SubstTypeArray(methprop.Params, type, typeArgs);
            methprop = ExpressionBinder.GroupToArgsBinder.FindMostDerivedMethod(SymbolLoader, methprop, callingObject.type);
            ExpressionBinder.GroupToArgsBinder.ReOrderArgsForNamedArguments(
                methprop,
                parameters,
                type,
                memgroup,
                argInfo,
                _semanticChecker.GetTypeManager(),
                _exprFactory,
                SymbolLoader);
            {
                EXPR pList = null;

                // We reordered, so make a new list of them and set them on the constructor.
                // Go backwards cause lists are right-flushed.
                // Also perform the conversions to the right types.
                for (int i = argInfo.carg - 1; i >= 0; i--)
                {
                    EXPR pArg = argInfo.prgexpr[i];

                    // Strip the name-ness away, since we don't need it.
                    pArg = StripNamedArgument(pArg);

                    // Perform the correct conversion.
                    pArg = _binder.tryConvert(pArg, parameters[i]);
                    if (pList == null)
                    {
                        pList = pArg;
                    }
                    else
                    {
                        pList = _exprFactory.CreateList(pArg, pList);
                    }
                }
                if (pResult.isCALL())
                {
                    pResult.asCALL().SetOptionalArguments(pList);
                }
                else
                {
                    pResult.asPROP().SetOptionalArguments(pList);
                }
            }
            return pResult;
        }
Пример #8
0
        private void CheckForConditionalMethodError(EXPR pExpr)
        {
            Debug.Assert(pExpr.isCALL());
            if (pExpr.isCALL())
            {
                // This mimics the behavior of the native CompilerSymbolLoader in GetConditionalSymbols. Override
                // methods cannot have the conditional attribute, but implicitly acquire it from their slot.

                EXPRCALL call = pExpr.asCALL();

                MethodSymbol method = call.mwi.Meth();
                if (method.isOverride)
                {
                    method = method.swtSlot.Meth();
                }

                object[] conditions = method.AssociatedMemberInfo.GetCustomAttributes(typeof(ConditionalAttribute), false).ToArray();
                if (conditions.Length > 0)
                {
                    throw Error.BindCallToConditionalMethod(method.name);
                }
            }
        }
Пример #9
0
        protected void verifyMethodArgs(EXPR call, CType callingObjectType)
        {
            Debug.Assert(call.isCALL() || call.isPROP());

            EXPR argsPtr = call.getArgs();
            SymWithType swt = call.GetSymWithType();
            MethodOrPropertySymbol mp = swt.Sym.AsMethodOrPropertySymbol();
            TypeArray pTypeArgs = call.isCALL() ? call.asCALL().mwi.TypeArgs : null;
            EXPR newArgs;
            AdjustCallArgumentsForParams(callingObjectType, swt.GetType(), mp, pTypeArgs, argsPtr, out newArgs);
            call.setArgs(newArgs);
        }
Пример #10
0
        /////////////////////////////////////////////////////////////////////////////////

        private Expression GetExpression(EXPR pExpr)
        {
            if (pExpr.isWRAP())
            {
                return _DictionaryOfParameters[pExpr.asWRAP().GetOptionalExpression().asCALL()];
            }
            else if (pExpr.isCONSTANT())
            {
                Debug.Assert(pExpr.type.IsNullType());
                return null;
            }
            else
            {
                // We can have a convert node or a call of a user defined conversion.
                Debug.Assert(pExpr.isCALL());
                EXPRCALL call = pExpr.asCALL();
                PREDEFMETH pm = call.PredefinedMethod;
                Debug.Assert(pm == PREDEFMETH.PM_EXPRESSION_CONVERT ||
                    pm == PREDEFMETH.PM_EXPRESSION_CONVERT_USER_DEFINED ||
                    pm == PREDEFMETH.PM_EXPRESSION_NEWARRAYINIT ||
                    pm == PREDEFMETH.PM_EXPRESSION_CALL ||
                    pm == PREDEFMETH.PM_EXPRESSION_PROPERTY ||
                    pm == PREDEFMETH.PM_EXPRESSION_FIELD ||
                    pm == PREDEFMETH.PM_EXPRESSION_ARRAYINDEX ||
                    pm == PREDEFMETH.PM_EXPRESSION_ARRAYINDEX2 ||
                    pm == PREDEFMETH.PM_EXPRESSION_CONSTANT_OBJECT_TYPE ||
                    pm == PREDEFMETH.PM_EXPRESSION_NEW ||

                    // Binary operators.
                    pm == PREDEFMETH.PM_EXPRESSION_ASSIGN ||
                    pm == PREDEFMETH.PM_EXPRESSION_ADD ||
                    pm == PREDEFMETH.PM_EXPRESSION_AND ||
                    pm == PREDEFMETH.PM_EXPRESSION_DIVIDE ||
                    pm == PREDEFMETH.PM_EXPRESSION_EQUAL ||
                    pm == PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR ||
                    pm == PREDEFMETH.PM_EXPRESSION_GREATERTHAN ||
                    pm == PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL ||
                    pm == PREDEFMETH.PM_EXPRESSION_LEFTSHIFT ||
                    pm == PREDEFMETH.PM_EXPRESSION_LESSTHAN ||
                    pm == PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL ||
                    pm == PREDEFMETH.PM_EXPRESSION_MODULO ||
                    pm == PREDEFMETH.PM_EXPRESSION_MULTIPLY ||
                    pm == PREDEFMETH.PM_EXPRESSION_NOTEQUAL ||
                    pm == PREDEFMETH.PM_EXPRESSION_OR ||
                    pm == PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT ||
                    pm == PREDEFMETH.PM_EXPRESSION_SUBTRACT ||
                    pm == PREDEFMETH.PM_EXPRESSION_ORELSE ||
                    pm == PREDEFMETH.PM_EXPRESSION_ANDALSO ||
                    pm == PREDEFMETH.PM_EXPRESSION_ADD_USER_DEFINED ||
                    pm == PREDEFMETH.PM_EXPRESSION_AND_USER_DEFINED ||
                    pm == PREDEFMETH.PM_EXPRESSION_DIVIDE_USER_DEFINED ||
                    pm == PREDEFMETH.PM_EXPRESSION_EQUAL_USER_DEFINED ||
                    pm == PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR_USER_DEFINED ||
                    pm == PREDEFMETH.PM_EXPRESSION_GREATERTHAN_USER_DEFINED ||
                    pm == PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL_USER_DEFINED ||
                    pm == PREDEFMETH.PM_EXPRESSION_LEFTSHIFT_USER_DEFINED ||
                    pm == PREDEFMETH.PM_EXPRESSION_LESSTHAN_USER_DEFINED ||
                    pm == PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL_USER_DEFINED ||
                    pm == PREDEFMETH.PM_EXPRESSION_MODULO_USER_DEFINED ||
                    pm == PREDEFMETH.PM_EXPRESSION_MULTIPLY_USER_DEFINED ||
                    pm == PREDEFMETH.PM_EXPRESSION_NOTEQUAL_USER_DEFINED ||
                    pm == PREDEFMETH.PM_EXPRESSION_OR_USER_DEFINED ||
                    pm == PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT_USER_DEFINED ||
                    pm == PREDEFMETH.PM_EXPRESSION_SUBTRACT_USER_DEFINED ||
                    pm == PREDEFMETH.PM_EXPRESSION_ORELSE_USER_DEFINED ||
                    pm == PREDEFMETH.PM_EXPRESSION_ANDALSO_USER_DEFINED ||

                    // Checked binary
                    pm == PREDEFMETH.PM_EXPRESSION_ADDCHECKED ||
                    pm == PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED ||
                    pm == PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED ||
                    pm == PREDEFMETH.PM_EXPRESSION_ADDCHECKED_USER_DEFINED ||
                    pm == PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED_USER_DEFINED ||
                    pm == PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED_USER_DEFINED ||

                    // Unary operators.
                    pm == PREDEFMETH.PM_EXPRESSION_NOT ||
                    pm == PREDEFMETH.PM_EXPRESSION_NEGATE ||
                    pm == PREDEFMETH.PM_EXPRESSION_NOT_USER_DEFINED ||
                    pm == PREDEFMETH.PM_EXPRESSION_NEGATE_USER_DEFINED ||
                    pm == PREDEFMETH.PM_EXPRESSION_UNARYPLUS_USER_DEFINED ||

                    // Checked unary
                    pm == PREDEFMETH.PM_EXPRESSION_NEGATECHECKED ||
                    pm == PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED ||
                    pm == PREDEFMETH.PM_EXPRESSION_NEGATECHECKED_USER_DEFINED ||
                    pm == PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED_USER_DEFINED
                    );

                switch (pm)
                {
                    case PREDEFMETH.PM_EXPRESSION_CALL:
                        return GenerateCall(call).Expression;

                    case PREDEFMETH.PM_EXPRESSION_CONVERT:
                    case PREDEFMETH.PM_EXPRESSION_CONVERT_USER_DEFINED:
                    case PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED:
                    case PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED_USER_DEFINED:
                        return GenerateConvert(call).Expression;

                    case PREDEFMETH.PM_EXPRESSION_NEWARRAYINIT:
                        {
                            EXPRLIST list = call.GetOptionalArguments().asLIST();
                            return Expression.NewArrayInit(
                                list.GetOptionalElement().asTYPEOF().SourceType.type.AssociatedSystemType,
                                GetArgumentsFromArrayInit(list.GetOptionalNextListNode().asARRINIT()));
                        }

                    case PREDEFMETH.PM_EXPRESSION_ARRAYINDEX:
                    case PREDEFMETH.PM_EXPRESSION_ARRAYINDEX2:
                        return GenerateArrayIndex(call).Expression;

                    case PREDEFMETH.PM_EXPRESSION_NEW:
                        return GenerateNew(call).Expression;

                    case PREDEFMETH.PM_EXPRESSION_PROPERTY:
                        return GenerateProperty(call).Expression;

                    case PREDEFMETH.PM_EXPRESSION_FIELD:
                        return GenerateField(call).Expression;

                    case PREDEFMETH.PM_EXPRESSION_CONSTANT_OBJECT_TYPE:
                        return GenerateConstantType(call).Expression;

                    case PREDEFMETH.PM_EXPRESSION_ASSIGN:
                        return GenerateAssignment(call).Expression;

                    case PREDEFMETH.PM_EXPRESSION_ADD:
                    case PREDEFMETH.PM_EXPRESSION_AND:
                    case PREDEFMETH.PM_EXPRESSION_DIVIDE:
                    case PREDEFMETH.PM_EXPRESSION_EQUAL:
                    case PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR:
                    case PREDEFMETH.PM_EXPRESSION_GREATERTHAN:
                    case PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL:
                    case PREDEFMETH.PM_EXPRESSION_LEFTSHIFT:
                    case PREDEFMETH.PM_EXPRESSION_LESSTHAN:
                    case PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL:
                    case PREDEFMETH.PM_EXPRESSION_MODULO:
                    case PREDEFMETH.PM_EXPRESSION_MULTIPLY:
                    case PREDEFMETH.PM_EXPRESSION_NOTEQUAL:
                    case PREDEFMETH.PM_EXPRESSION_OR:
                    case PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT:
                    case PREDEFMETH.PM_EXPRESSION_SUBTRACT:
                    case PREDEFMETH.PM_EXPRESSION_ORELSE:
                    case PREDEFMETH.PM_EXPRESSION_ANDALSO:
                    // Checked
                    case PREDEFMETH.PM_EXPRESSION_ADDCHECKED:
                    case PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED:
                    case PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED:
                        return GenerateBinaryOperator(call).Expression;

                    case PREDEFMETH.PM_EXPRESSION_ADD_USER_DEFINED:
                    case PREDEFMETH.PM_EXPRESSION_AND_USER_DEFINED:
                    case PREDEFMETH.PM_EXPRESSION_DIVIDE_USER_DEFINED:
                    case PREDEFMETH.PM_EXPRESSION_EQUAL_USER_DEFINED:
                    case PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR_USER_DEFINED:
                    case PREDEFMETH.PM_EXPRESSION_GREATERTHAN_USER_DEFINED:
                    case PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL_USER_DEFINED:
                    case PREDEFMETH.PM_EXPRESSION_LEFTSHIFT_USER_DEFINED:
                    case PREDEFMETH.PM_EXPRESSION_LESSTHAN_USER_DEFINED:
                    case PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL_USER_DEFINED:
                    case PREDEFMETH.PM_EXPRESSION_MODULO_USER_DEFINED:
                    case PREDEFMETH.PM_EXPRESSION_MULTIPLY_USER_DEFINED:
                    case PREDEFMETH.PM_EXPRESSION_NOTEQUAL_USER_DEFINED:
                    case PREDEFMETH.PM_EXPRESSION_OR_USER_DEFINED:
                    case PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT_USER_DEFINED:
                    case PREDEFMETH.PM_EXPRESSION_SUBTRACT_USER_DEFINED:
                    case PREDEFMETH.PM_EXPRESSION_ORELSE_USER_DEFINED:
                    case PREDEFMETH.PM_EXPRESSION_ANDALSO_USER_DEFINED:
                    // Checked
                    case PREDEFMETH.PM_EXPRESSION_ADDCHECKED_USER_DEFINED:
                    case PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED_USER_DEFINED:
                    case PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED_USER_DEFINED:
                        return GenerateUserDefinedBinaryOperator(call).Expression;

                    case PREDEFMETH.PM_EXPRESSION_NOT:
                    case PREDEFMETH.PM_EXPRESSION_NEGATE:
                    case PREDEFMETH.PM_EXPRESSION_NEGATECHECKED:
                        return GenerateUnaryOperator(call).Expression;

                    case PREDEFMETH.PM_EXPRESSION_NOT_USER_DEFINED:
                    case PREDEFMETH.PM_EXPRESSION_NEGATE_USER_DEFINED:
                    case PREDEFMETH.PM_EXPRESSION_UNARYPLUS_USER_DEFINED:
                    case PREDEFMETH.PM_EXPRESSION_NEGATECHECKED_USER_DEFINED:
                        return GenerateUserDefinedUnaryOperator(call).Expression;

                    default:
                        Debug.Assert(false, "Invalid Predefined Method in GetExpression");
                        throw Error.InternalCompilerError();
                }
            }
        }