/////////////////////////////////////////////////////////////////////////////////
        // Expression types.

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

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

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

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

            call.PredefinedMethod = PREDEFMETH.PM_EXPRESSION_LAMBDA;
            return(ExprFactory.CreateSequence(createParameters, call));
        }
 static public BindingContext CreateInstance(
         CSemanticChecker pSemanticChecker,
         ExprFactory exprFactory,
         OutputContext outputContext,
         NameGenerator nameGenerator,
         bool bflushLocalVariableTypesForEachStatement,
         bool bAllowUnsafeBlocks,
         bool bIsOptimizingSwitchAndArrayInit,
         bool bShowReachability,
         bool bWrapNonExceptionThrows,
         bool bInRefactoring,
         KAID aidLookupContext
     )
 {
     return new BindingContext(
         pSemanticChecker,
         exprFactory,
         outputContext,
         nameGenerator,
         bflushLocalVariableTypesForEachStatement,
         bAllowUnsafeBlocks,
         bIsOptimizingSwitchAndArrayInit,
         bShowReachability,
         bWrapNonExceptionThrows,
         bInRefactoring,
         aidLookupContext);
 }
        private static Expr CreateWraps(ExprBoundLambda anonmeth)
        {
            Expr sequence = null;

            for (Symbol sym = anonmeth.ArgumentScope.firstChild; sym != null; sym = sym.nextChild)
            {
                if (!(sym is LocalVariableSymbol local))
                {
                    continue;
                }

                Debug.Assert(anonmeth.Expression != null);
                Expr create = GenerateParameter(local.name.Text, local.GetType());
                local.wrap = ExprFactory.CreateWrap(create);
                Expr save = ExprFactory.CreateSave(local.wrap);
                if (sequence == null)
                {
                    sequence = save;
                }
                else
                {
                    sequence = ExprFactory.CreateSequence(sequence, save);
                }
            }

            return(sequence);
        }
 static public BindingContext CreateInstance(
     CSemanticChecker pSemanticChecker,
     ExprFactory exprFactory,
     OutputContext outputContext,
     NameGenerator nameGenerator,
     bool bflushLocalVariableTypesForEachStatement,
     bool bAllowUnsafeBlocks,
     bool bIsOptimizingSwitchAndArrayInit,
     bool bShowReachability,
     bool bWrapNonExceptionThrows,
     bool bInRefactoring,
     KAID aidLookupContext
     )
 {
     return(new BindingContext(
                pSemanticChecker,
                exprFactory,
                outputContext,
                nameGenerator,
                bflushLocalVariableTypesForEachStatement,
                bAllowUnsafeBlocks,
                bIsOptimizingSwitchAndArrayInit,
                bShowReachability,
                bWrapNonExceptionThrows,
                bInRefactoring,
                aidLookupContext));
 }
Beispiel #5
0
 public BindingContext(CSemanticChecker semanticChecker, ExprFactory exprFactory)
 {
     Debug.Assert(semanticChecker != null);
     ExprFactory     = exprFactory;
     SemanticChecker = semanticChecker;
     SymbolLoader    = semanticChecker.SymbolLoader;
 }
        protected BindingContext(
            CSemanticChecker pSemanticChecker,
            ExprFactory exprFactory,
            OutputContext outputContext,
            NameGenerator nameGenerator,
            bool bflushLocalVariableTypesForEachStatement,
            bool bAllowUnsafeBlocks,
            bool bIsOptimizingSwitchAndArrayInit,
            bool bShowReachability,
            bool bWrapNonExceptionThrows,
            bool bInRefactoring,
            KAID aidLookupContext
            )
        {
            m_ExprFactory            = exprFactory;
            m_outputContext          = outputContext;
            m_pNameGenerator         = nameGenerator;
            m_pInputFile             = null;
            m_pParentDecl            = null;
            m_pContainingAgg         = null;
            m_pCurrentSwitchType     = null;
            m_pOriginalConstantField = null;
            m_pCurrentFieldSymbol    = null;
            m_pImplicitlyTypedLocal  = null;
            m_pOuterScope            = null;
            m_pFinallyScope          = null;
            m_pTryScope                                = null;
            m_pCatchScope                              = null;
            m_pCurrentScope                            = null;
            m_pSwitchScope                             = null;
            m_pCurrentBlock                            = null;
            m_UnsafeState                              = UNSAFESTATES.UNSAFESTATES_Unknown;
            m_FinallyNestingCount                      = 0;
            m_bInsideTryOfCatch                        = false;
            m_bInFieldInitializer                      = false;
            m_bInBaseConstructorCall                   = false;
            m_bAllowUnsafeBlocks                       = bAllowUnsafeBlocks;
            m_bIsOptimizingSwitchAndArrayInit          = bIsOptimizingSwitchAndArrayInit;
            m_bShowReachability                        = bShowReachability;
            m_bWrapNonExceptionThrows                  = bWrapNonExceptionThrows;
            m_bInRefactoring                           = bInRefactoring;
            m_bInAttribute                             = false;
            m_bRespectSemanticsAndReportErrors         = true;
            m_bflushLocalVariableTypesForEachStatement = bflushLocalVariableTypesForEachStatement;
            m_ppamis          = null;
            m_pamiCurrent     = null;
            m_pInitType       = null;
            m_returnErrorSink = null;

            Debug.Assert(pSemanticChecker != null);
            this.SemanticChecker                   = pSemanticChecker;
            this.SymbolLoader                      = SemanticChecker.GetSymbolLoader();
            m_outputContext.m_pThisPointer         = null;
            m_outputContext.m_pCurrentMethodSymbol = null;

            m_aidExternAliasLookupContext = aidLookupContext;
            CheckedNormal   = false;
            CheckedConstant = false;
        }
        protected BindingContext(
            CSemanticChecker pSemanticChecker,
            ExprFactory exprFactory,
            OutputContext outputContext,
            NameGenerator nameGenerator,
            bool bflushLocalVariableTypesForEachStatement,
            bool bAllowUnsafeBlocks,
            bool bIsOptimizingSwitchAndArrayInit,
            bool bShowReachability,
            bool bWrapNonExceptionThrows,
            bool bInRefactoring,
            KAID aidLookupContext
            )
        {
            m_ExprFactory = exprFactory;
            m_outputContext = outputContext;
            m_pNameGenerator = nameGenerator;
            m_pInputFile = null;
            m_pParentDecl = null;
            m_pContainingAgg = null;
            m_pCurrentSwitchType = null;
            m_pOriginalConstantField = null;
            m_pCurrentFieldSymbol = null;
            m_pImplicitlyTypedLocal = null;
            m_pOuterScope = null;
            m_pFinallyScope = null;
            m_pTryScope = null;
            m_pCatchScope = null;
            m_pCurrentScope = null;
            m_pSwitchScope = null;
            m_pCurrentBlock = null;
            m_UnsafeState = UNSAFESTATES.UNSAFESTATES_Unknown;
            m_FinallyNestingCount = 0;
            m_bInsideTryOfCatch = false;
            m_bInFieldInitializer = false;
            m_bInBaseConstructorCall = false;
            m_bAllowUnsafeBlocks = bAllowUnsafeBlocks;
            m_bIsOptimizingSwitchAndArrayInit = bIsOptimizingSwitchAndArrayInit;
            m_bShowReachability = bShowReachability;
            m_bWrapNonExceptionThrows = bWrapNonExceptionThrows;
            m_bInRefactoring = bInRefactoring;
            m_bInAttribute = false;
            m_bRespectSemanticsAndReportErrors = true;
            m_bflushLocalVariableTypesForEachStatement = bflushLocalVariableTypesForEachStatement;
            m_ppamis = null;
            m_pamiCurrent = null;
            m_pInitType = null;
            m_returnErrorSink = null;

            Debug.Assert(pSemanticChecker != null);
            this.SemanticChecker = pSemanticChecker;
            this.SymbolLoader = SemanticChecker.GetSymbolLoader();
            m_outputContext.m_pThisPointer = null;
            m_outputContext.m_pCurrentMethodSymbol = null;

            m_aidExternAliasLookupContext = aidLookupContext;
            CheckedNormal = false;
            CheckedConstant = false;
        }
        private static Expr GenerateParameter(string name, CType CType)
        {
            SymbolLoader.GetPredefindType(PredefinedType.PT_STRING);  // force an ensure state
            ExprConstant nameString = ExprFactory.CreateStringConstant(name);
            ExprTypeOf   pTypeOf    = CreateTypeOf(CType);

            return(GenerateCall(PREDEFMETH.PM_EXPRESSION_PARAMETER, pTypeOf, nameString));
        }
        private static ExprArrayInit GenerateParamsArray(Expr args, PredefinedType pt)
        {
            int           parameterCount         = ExpressionIterator.Count(args);
            AggregateType paramsArrayElementType = SymbolLoader.GetPredefindType(pt);
            ArrayType     paramsArrayType        = TypeManager.GetArray(paramsArrayElementType, 1, true);
            ExprConstant  paramsArrayArg         = ExprFactory.CreateIntegerConstant(parameterCount);

            return(ExprFactory.CreateArrayInit(paramsArrayType, args, paramsArrayArg, new int[] { parameterCount }));
        }
        private Expr GenerateConstructor(ExprCall expr)
        {
            Debug.Assert(expr != null);
            Debug.Assert(expr.MethWithInst.Meth().IsConstructor());
            Expr constructorInfo = ExprFactory.CreateMethodInfo(expr.MethWithInst);
            Expr args            = GenerateArgsList(expr.OptionalArguments);
            Expr Params          = GenerateParamsArray(args, PredefinedType.PT_EXPRESSION);

            return(GenerateCall(PREDEFMETH.PM_EXPRESSION_NEW, constructorInfo, Params));
        }
        private Expr GenerateUserDefinedUnaryOperator(ExprUnaryOp expr)
        {
            Debug.Assert(expr != null);
            PREDEFMETH pdm;
            Expr       arg  = expr.Child;
            ExprCall   call = (ExprCall)expr.OptionalUserDefinedCall;

            if (call != null)
            {
                // Use the actual argument of the call; it may contain user-defined
                // conversions or be a bound lambda, and that will not be in the original
                // argument stashed away in the left child of the operator.
                arg = call.OptionalArguments;
            }
            Debug.Assert(arg != null && arg.Kind != ExpressionKind.List);
            switch (expr.Kind)
            {
            case ExpressionKind.True:
            case ExpressionKind.False:
                return(Visit(call));

            case ExpressionKind.UnaryPlus:
                pdm = PREDEFMETH.PM_EXPRESSION_UNARYPLUS_USER_DEFINED;
                break;

            case ExpressionKind.BitwiseNot: pdm = PREDEFMETH.PM_EXPRESSION_NOT_USER_DEFINED; break;

            case ExpressionKind.LogicalNot: pdm = PREDEFMETH.PM_EXPRESSION_NOT_USER_DEFINED; break;

            case ExpressionKind.DecimalNegate:
            case ExpressionKind.Negate:
                pdm = expr.isChecked() ? PREDEFMETH.PM_EXPRESSION_NEGATECHECKED_USER_DEFINED : PREDEFMETH.PM_EXPRESSION_NEGATE_USER_DEFINED;
                break;

            case ExpressionKind.Inc:
            case ExpressionKind.Dec:
            case ExpressionKind.DecimalInc:
            case ExpressionKind.DecimalDec:
                pdm = PREDEFMETH.PM_EXPRESSION_CALL;
                break;

            default:
                throw Error.InternalCompilerError();
            }
            Expr op         = Visit(arg);
            Expr methodInfo = ExprFactory.CreateMethodInfo(expr.UserDefinedCallMethod);

            if (expr.Kind == ExpressionKind.Inc || expr.Kind == ExpressionKind.Dec ||
                expr.Kind == ExpressionKind.DecimalInc || expr.Kind == ExpressionKind.DecimalDec)
            {
                return(GenerateCall(pdm, null, methodInfo, GenerateParamsArray(op, PredefinedType.PT_EXPRESSION)));
            }
            return(GenerateCall(pdm, op, methodInfo));
        }
Beispiel #12
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));
        }
        private Expr GenerateArgsList(Expr oldArgs)
        {
            Expr newArgs     = null;
            Expr newArgsTail = newArgs;

            for (ExpressionIterator it = new ExpressionIterator(oldArgs); !it.AtEnd(); it.MoveNext())
            {
                Expr oldArg = it.Current();
                ExprFactory.AppendItemToList(Visit(oldArg), ref newArgs, ref newArgsTail);
            }
            return(newArgs);
        }
        private Expr GenerateUserDefinedComparisonOperator(ExprBinOp expr)
        {
            Debug.Assert(expr != null);
            PREDEFMETH pdm;

            switch (expr.Kind)
            {
            case ExpressionKind.StringEq: pdm = PREDEFMETH.PM_EXPRESSION_EQUAL_USER_DEFINED; break;

            case ExpressionKind.StringNotEq: pdm = PREDEFMETH.PM_EXPRESSION_NOTEQUAL_USER_DEFINED; break;

            case ExpressionKind.DelegateEq: pdm = PREDEFMETH.PM_EXPRESSION_EQUAL_USER_DEFINED; break;

            case ExpressionKind.DelegateNotEq: pdm = PREDEFMETH.PM_EXPRESSION_NOTEQUAL_USER_DEFINED; break;

            case ExpressionKind.Eq: pdm = PREDEFMETH.PM_EXPRESSION_EQUAL_USER_DEFINED; break;

            case ExpressionKind.NotEq: pdm = PREDEFMETH.PM_EXPRESSION_NOTEQUAL_USER_DEFINED; break;

            case ExpressionKind.LessThanOrEqual: pdm = PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL_USER_DEFINED; break;

            case ExpressionKind.LessThan: pdm = PREDEFMETH.PM_EXPRESSION_LESSTHAN_USER_DEFINED; break;

            case ExpressionKind.GreaterThanOrEqual: pdm = PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL_USER_DEFINED; break;

            case ExpressionKind.GreaterThan: pdm = PREDEFMETH.PM_EXPRESSION_GREATERTHAN_USER_DEFINED; break;

            default:
                throw Error.InternalCompilerError();
            }
            Expr p1 = expr.OptionalLeftChild;
            Expr p2 = expr.OptionalRightChild;

            if (expr.OptionalUserDefinedCall != null)
            {
                ExprCall udcall = (ExprCall)expr.OptionalUserDefinedCall;
                ExprList args   = (ExprList)udcall.OptionalArguments;
                Debug.Assert(args.OptionalNextListNode.Kind != ExpressionKind.List);

                p1 = args.OptionalElement;
                p2 = args.OptionalNextListNode;
            }
            p1 = Visit(p1);
            p2 = Visit(p2);
            FixLiftedUserDefinedBinaryOperators(expr, ref p1, ref p2);
            Expr lift       = ExprFactory.CreateBoolConstant(false); // We never lift to null in C#.
            Expr methodInfo = ExprFactory.CreateMethodInfo(expr.UserDefinedCallMethod);

            return(GenerateCall(pdm, p1, p2, lift, methodInfo));
        }
        protected override Expr VisitFIELD(ExprField expr)
        {
            Debug.Assert(expr != null);
            Expr pObject;

            if (expr.OptionalObject == null)
            {
                pObject = ExprFactory.CreateNull();
            }
            else
            {
                pObject = Visit(expr.OptionalObject);
            }
            ExprFieldInfo pFieldInfo = ExprFactory.CreateFieldInfo(expr.FieldWithType.Field(), expr.FieldWithType.GetType());

            return(GenerateCall(PREDEFMETH.PM_EXPRESSION_FIELD, pObject, pFieldInfo));
        }
        private static ExprCall GenerateCall(PREDEFMETH pdm, Expr arg1, Expr arg2, Expr arg3, Expr arg4)
        {
            MethodSymbol method = GetPreDefMethod(pdm);

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

            call.PredefinedMethod = pdm;
            return(call);
        }
Beispiel #17
0
        public static EXPR Map(this EXPR expr, ExprFactory factory, Func<EXPR, EXPR> f)
        {
            Debug.Assert(f != null);
            Debug.Assert(factory != null);

            if (expr == null)
                return f(expr);

            EXPR result = null;
            EXPR tail = null;
            foreach (EXPR item in expr.ToEnumerable())
            {
                EXPR mappedItem = f(item);
                factory.AppendItemToList(mappedItem, ref result, ref tail);
            }
            return result;
        }
        private static 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 = SymbolLoader.GetPredefindType(PredefinedType.PT_EXPRESSION);
            MethWithInst    mwi            = new MethWithInst(method, expressionType);
            ExprMemberGroup pMemGroup      = ExprFactory.CreateMemGroup(null, mwi);
            ExprCall        call           = ExprFactory.CreateCall(0, mwi.Meth().RetType, arg1, pMemGroup, mwi);

            call.PredefinedMethod = pdm;
            return(call);
        }
Beispiel #19
0
            private bool bindImplicitConversionToEnum(AggregateType aggTypeSrc)
            {
                // The spec states:
                // *****************
                // 13.1.3 Implicit enumeration conversions
                //
                // An implicit enumeration conversion permits the decimal-integer-literal 0 to be converted to any
                // enum-type.
                // *****************
                // However, we actually allow any constant zero, not just the integer literal zero, to be converted
                // to enum.  The reason for this is for backwards compatibility with a premature optimization
                // that used to be in the binding layer.  We would optimize away expressions such as 0 | blah to be
                // just 0, but not erase the "is literal" bit.  This meant that expression such as 0 | 0 | E.X
                // would succeed rather than correctly producing an error pointing out that 0 | 0 is not a literal
                // zero and therefore does not convert to any enum.
                //
                // We have removed the premature optimization but want old code to continue to compile. Rather than
                // try to emulate the somewhat complex behaviour of the previous optimizer, it is easier to simply
                // say that any compile time constant zero is convertible to any enum.  This means unfortunately
                // expressions such as (7-7) * 12 are convertible to enum, but frankly, that's better than having
                // some terribly complex rule about what constitutes a legal zero and what doesn't.

                // Note: Don't use GetConst here since the conversion only applies to bona-fide compile time constants.
                if (
                    aggTypeSrc.OwningAggregate.GetPredefType() != PredefinedType.PT_BOOL &&
                    _exprSrc != null &&
                    _exprSrc.IsZero() &&
                    _exprSrc.Type.IsNumericType &&
                    /*(exprSrc.flags & EXF_LITERALCONST) &&*/
                    0 == (_flags & CONVERTTYPE.STANDARD))
                {
                    // NOTE: This allows conversions from uint, long, ulong, float, double, and hexadecimal int
                    // NOTE: This is for backwards compatibility with Everett

                    // This is another place where we lose Expr fidelity. We shouldn't fold this
                    // into a constant here - we should move this to a later pass.
                    if (_needsExprDest)
                    {
                        _exprDest = ExprFactory.CreateConstant(_typeDest, ConstVal.GetDefaultValue(_typeDest.ConstValKind));
                    }
                    return(true);
                }
                return(false);
            }
Beispiel #20
0
        public static Expr Map(this Expr expr, Func <Expr, Expr> f)
        {
            Debug.Assert(f != null);

            if (expr == null)
            {
                return(f(null));
            }

            Expr result = null;
            Expr tail   = null;

            foreach (Expr item in expr.ToEnumerable())
            {
                Expr mappedItem = f(item);
                ExprFactory.AppendItemToList(mappedItem, ref result, ref tail);
            }
            return(result);
        }
        private static 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   = TypeManager.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 = TypeManager.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  = ExprFactory.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));
        }
Beispiel #22
0
        public static EXPR Map(this EXPR expr, ExprFactory factory, Func <EXPR, EXPR> f)
        {
            Debug.Assert(f != null);
            Debug.Assert(factory != null);

            if (expr == null)
            {
                return(f(expr));
            }

            EXPR result = null;
            EXPR tail   = null;

            foreach (EXPR item in expr.ToEnumerable())
            {
                EXPR mappedItem = f(item);
                factory.AppendItemToList(mappedItem, ref result, ref tail);
            }
            return(result);
        }
        private Expr GenerateIndexList(Expr oldIndices)
        {
            CType intType = SymbolLoader.GetPredefindType(PredefinedType.PT_INT);

            Expr newIndices     = null;
            Expr newIndicesTail = newIndices;

            for (ExpressionIterator it = new ExpressionIterator(oldIndices); !it.AtEnd(); it.MoveNext())
            {
                Expr newIndex = it.Current();
                if (newIndex.Type != intType)
                {
                    newIndex        = ExprFactory.CreateCast(EXPRFLAG.EXF_INDEXEXPR, intType, newIndex);
                    newIndex.Flags |= EXPRFLAG.EXF_CHECKOVERFLOW;
                }
                Expr rewrittenIndex = Visit(newIndex);
                ExprFactory.AppendItemToList(rewrittenIndex, ref newIndices, ref newIndicesTail);
            }
            return(newIndices);
        }
        protected override Expr VisitCONCAT(ExprConcat expr)
        {
            Debug.Assert(expr != null);
            PREDEFMETH pdm;

            if (expr.FirstArgument.Type.IsPredefType(PredefinedType.PT_STRING) && expr.SecondArgument.Type.IsPredefType(PredefinedType.PT_STRING))
            {
                pdm = PREDEFMETH.PM_STRING_CONCAT_STRING_2;
            }
            else
            {
                pdm = PREDEFMETH.PM_STRING_CONCAT_OBJECT_2;
            }
            Expr         p1         = Visit(expr.FirstArgument);
            Expr         p2         = Visit(expr.SecondArgument);
            MethodSymbol method     = GetPreDefMethod(pdm);
            Expr         methodInfo = ExprFactory.CreateMethodInfo(method, SymbolLoader.GetPredefindType(PredefinedType.PT_STRING), null);

            return(GenerateCall(PREDEFMETH.PM_EXPRESSION_ADD_USER_DEFINED, p1, p2, methodInfo));
        }
Beispiel #25
0
        // Create an expr for exprSrc.Value where exprSrc.type is a NullableType.
        private static Expr BindNubValue(Expr exprSrc)
        {
            Debug.Assert(exprSrc != null && exprSrc.Type is NullableType);

            // For new T?(x), the answer is x.
            if (IsNullableConstructor(exprSrc, out ExprCall call))
            {
                Expr args = call.OptionalArguments;
                Debug.Assert(args != null && !(args is ExprList));
                return(args);
            }

            NullableType     nubSrc    = (NullableType)exprSrc.Type;
            CType            typeBase  = nubSrc.UnderlyingType;
            AggregateType    ats       = nubSrc.GetAts();
            PropertySymbol   prop      = PredefinedMembers.GetProperty(PREDEFPROP.PP_G_OPTIONAL_VALUE);
            PropWithType     pwt       = new PropWithType(prop, ats);
            MethPropWithInst mpwi      = new MethPropWithInst(prop, ats);
            ExprMemberGroup  pMemGroup = ExprFactory.CreateMemGroup(exprSrc, mpwi);

            return(ExprFactory.CreateProperty(typeBase, null, null, pMemGroup, pwt, null));
        }
        /////////////////////////////////////////////////////////////////////////////////
        // Statement types.
        protected override Expr VisitASSIGNMENT(ExprAssignment assignment)
        {
            Debug.Assert(assignment != null);

            // For assignments, we either have a member assignment or an indexed assignment.
            //Debug.Assert(assignment.GetLHS().isPROP() || assignment.GetLHS().isFIELD() || assignment.GetLHS().isARRAYINDEX() || assignment.GetLHS().isLOCAL());
            Expr lhs;

            if (assignment.LHS is ExprProperty prop)
            {
                if (prop.OptionalArguments == null)
                {
                    // Regular property.
                    lhs = Visit(prop);
                }
                else
                {
                    // Indexed assignment. Here we need to find the instance of the object, create the
                    // PropInfo for the thing, and get the array of expressions that make up the index arguments.
                    //
                    // The LHS becomes Expression.Property(instance, indexerInfo, arguments).
                    Expr instance  = Visit(prop.MemberGroup.OptionalObject);
                    Expr propInfo  = ExprFactory.CreatePropertyInfo(prop.PropWithTypeSlot.Prop(), prop.PropWithTypeSlot.Ats);
                    Expr arguments = GenerateParamsArray(
                        GenerateArgsList(prop.OptionalArguments),
                        PredefinedType.PT_EXPRESSION);

                    lhs = GenerateCall(PREDEFMETH.PM_EXPRESSION_PROPERTY, instance, propInfo, arguments);
                }
            }
            else
            {
                lhs = Visit(assignment.LHS);
            }

            Expr rhs = Visit(assignment.RHS);

            return(GenerateCall(PREDEFMETH.PM_EXPRESSION_ASSIGN, lhs, rhs));
        }
            private bool bindImplicitConversionFromNull()
            {
                // null type can be implicitly converted to any reference type or pointer type or type
                // variable with reference-type constraint.

                FUNDTYPE ftDest = _typeDest.FundamentalType;
                if (ftDest != FUNDTYPE.FT_REF && ftDest != FUNDTYPE.FT_PTR &&
                    // null is convertible to System.Nullable<T>.
                    !_typeDest.IsPredefType(PredefinedType.PT_G_OPTIONAL))
                {
                    return false;
                }
                if (_needsExprDest)
                {
                    // If the conversion argument is a constant null then return a ZEROINIT.
                    // Otherwise, bind this as a cast to the destination type. In a later
                    // rewrite pass we will rewrite the cast as SEQ(side effects, ZEROINIT).
                    _exprDest = _exprSrc is ExprConstant
                        ? ExprFactory.CreateZeroInit(_typeDest)
                        : ExprFactory.CreateCast(_typeDest, _exprSrc);
                }
                return true;
            }
        protected override Expr VisitPROP(ExprProperty expr)
        {
            Debug.Assert(expr != null);
            Expr pObject;

            if (expr.PropWithTypeSlot.Prop().isStatic || expr.MemberGroup.OptionalObject == null)
            {
                pObject = ExprFactory.CreateNull();
            }
            else
            {
                pObject = Visit(expr.MemberGroup.OptionalObject);
            }
            Expr propInfo = ExprFactory.CreatePropertyInfo(expr.PropWithTypeSlot.Prop(), expr.PropWithTypeSlot.GetType());

            if (expr.OptionalArguments != null)
            {
                // It is an indexer property.  Turn it into a virtual method call.
                Expr args   = GenerateArgsList(expr.OptionalArguments);
                Expr Params = GenerateParamsArray(args, PredefinedType.PT_EXPRESSION);
                return(GenerateCall(PREDEFMETH.PM_EXPRESSION_PROPERTY, pObject, propInfo, Params));
            }
            return(GenerateCall(PREDEFMETH.PM_EXPRESSION_PROPERTY, pObject, propInfo));
        }
        private static Expr GenerateConstant(Expr expr)
        {
            EXPRFLAG flags = 0;

            AggregateType pObject = SymbolLoader.GetPredefindType(PredefinedType.PT_OBJECT);

            if (expr.Type is NullType)
            {
                ExprTypeOf pTypeOf = CreateTypeOf(pObject);
                return(GenerateCall(PREDEFMETH.PM_EXPRESSION_CONSTANT_OBJECT_TYPE, expr, pTypeOf));
            }

            AggregateType stringType = SymbolLoader.GetPredefindType(PredefinedType.PT_STRING);

            if (expr.Type != stringType)
            {
                flags = EXPRFLAG.EXF_BOX;
            }

            ExprCast   cast     = ExprFactory.CreateCast(flags, pObject, expr);
            ExprTypeOf pTypeOf2 = CreateTypeOf(expr.Type);

            return(GenerateCall(PREDEFMETH.PM_EXPRESSION_CONSTANT_OBJECT_TYPE, cast, pTypeOf2));
        }
 protected ExpressionTreeRewriter(ExprFactory expressionFactory, SymbolLoader symbolLoader)
 {
     this.expressionFactory = expressionFactory;
     this.symbolLoader = symbolLoader;
     this.alwaysRewrite = false;
 }
 public static EXPR Rewrite(EXPR expr, ExprFactory expressionFactory, SymbolLoader symbolLoader)
 {
     ExpressionTreeRewriter rewriter = new ExpressionTreeRewriter(expressionFactory, symbolLoader);
     rewriter.alwaysRewrite = true;
     return rewriter.Visit(expr);
 }
Beispiel #32
0
 private ExpressionTreeRewriter(ExprFactory expressionFactory, SymbolLoader symbolLoader)
 {
     this.expressionFactory = expressionFactory;
     this.symbolLoader      = symbolLoader;
 }
Beispiel #33
0
 public static ExprBinOp Rewrite(ExprBoundLambda expr, ExprFactory expressionFactory, SymbolLoader symbolLoader) =>
 new ExpressionTreeRewriter(expressionFactory, symbolLoader).VisitBoundLambda(expr);
Beispiel #34
0
 public CNullable(SymbolLoader symbolLoader, ErrorHandling errorContext, ExprFactory exprFactory)
 {
     _pSymbolLoader = symbolLoader;
     _pErrorContext = errorContext;
     _exprFactory   = exprFactory;
 }
Beispiel #35
0
        private void Reset()
        {
            _controller = new RuntimeBinderController();
            _semanticChecker = new LangCompiler(_controller, new NameManager());

            BSYMMGR bsymmgr = _semanticChecker.getBSymmgr();
            NameManager nameManager = _semanticChecker.GetNameManager();

            InputFile infile = bsymmgr.GetMiscSymFactory().CreateMDInfile(nameManager.Lookup(""), (mdToken)0);
            infile.SetAssemblyID(bsymmgr.AidAlloc(infile));
            infile.AddToAlias(KAID.kaidThisAssembly);
            infile.AddToAlias(KAID.kaidGlobal);

            _symbolTable = new SymbolTable(
                bsymmgr.GetSymbolTable(),
                bsymmgr.GetSymFactory(),
                nameManager,
                _semanticChecker.GetTypeManager(),
                bsymmgr,
                _semanticChecker,
                infile);
            _semanticChecker.getPredefTypes().Init(_semanticChecker.GetErrorContext(), _symbolTable);
            _semanticChecker.GetTypeManager().InitTypeFactory(_symbolTable);
            SymbolLoader.getPredefinedMembers().RuntimeBinderSymbolTable = _symbolTable;
            SymbolLoader.SetSymbolTable(_symbolTable);

            _exprFactory = new ExprFactory(_semanticChecker.GetSymbolLoader().GetGlobalSymbolContext());
            _outputContext = new OutputContext();
            _nameGenerator = new NameGenerator();
            _bindingContext = BindingContext.CreateInstance(
                _semanticChecker,
                _exprFactory,
                _outputContext,
                _nameGenerator,
                false,
                true,
                false,
                false,
                false,
                false,
                0);
            _binder = new ExpressionBinder(_bindingContext);
        }
Beispiel #36
0
 public CNullable(SymbolLoader symbolLoader, ErrorHandling errorContext, ExprFactory exprFactory)
 {
     _pSymbolLoader = symbolLoader;
     _pErrorContext = errorContext;
     _exprFactory = exprFactory;
 }
Beispiel #37
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 (SymbolLoader.HasBaseConversion(nubDst.UnderlyingType, _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 wacky 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)
                        {
                            _exprDest = _exprSrc is ExprConstant
                                ? ExprFactory.CreateZeroInit(nubDst)
                                : ExprFactory.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 = 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 = ExprFactory.CreateMemGroup(null, mwi);
                    ExprCall        exprDst   = ExprFactory.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);
            }
Beispiel #38
0
            /////////////////////////////////////////////////////////////////////////////////

            private static EXPR GenerateOptionalArgument(
                    SymbolLoader symbolLoader,
                    ExprFactory exprFactory,
                    MethodOrPropertySymbol methprop,
                    CType type,
                    int index)
            {
                CType pParamType = type;
                CType pRawParamType = type.IsNullableType() ? type.AsNullableType().GetUnderlyingType() : type;

                EXPR optionalArgument = null;
                if (methprop.HasDefaultParameterValue(index))
                {
                    CType pConstValType = methprop.GetDefaultParameterValueConstValType(index);
                    CONSTVAL cv = methprop.GetDefaultParameterValue(index);

                    if (pConstValType.isPredefType(PredefinedType.PT_DATETIME) &&
                        (pRawParamType.isPredefType(PredefinedType.PT_DATETIME) || pRawParamType.isPredefType(PredefinedType.PT_OBJECT) || pRawParamType.isPredefType(PredefinedType.PT_VALUE)))
                    {
                        // This is the specific case where we want to create a DateTime
                        // but the constval that stores it is a long.

                        AggregateType dateTimeType = symbolLoader.GetReqPredefType(PredefinedType.PT_DATETIME);
                        optionalArgument = exprFactory.CreateConstant(dateTimeType, new CONSTVAL(DateTime.FromBinary(cv.longVal)));
                    }
                    else if (pConstValType.isSimpleOrEnumOrString())
                    {
                        // In this case, the constval is a simple type (all the numerics, including
                        // decimal), or an enum or a string. This covers all the substantial values,
                        // and everything else that can be encoded is just null or default(something).

                        // For enum parameters, we create a constant of the enum type. For everything
                        // else, we create the appropriate constant.

                        if (pRawParamType.isEnumType() && pConstValType == pRawParamType.underlyingType())
                        {
                            optionalArgument = exprFactory.CreateConstant(pRawParamType, cv);
                        }
                        else
                        {
                            optionalArgument = exprFactory.CreateConstant(pConstValType, cv);
                        }
                    }
                    else if ((pParamType.IsRefType() || pParamType.IsNullableType()) && cv.IsNullRef())
                    {
                        // We have an "= null" default value with a reference type or a nullable type.

                        optionalArgument = exprFactory.CreateNull();
                    }
                    else
                    {
                        // We have a default value that is encoded as a nullref, and that nullref is
                        // interpreted as default(something). For instance, the pParamType could be
                        // a type parameter type or a non-simple value type.

                        optionalArgument = exprFactory.CreateZeroInit(pParamType);
                    }
                }
                else
                {
                    // There was no default parameter specified, so generally use default(T),
                    // except for some cases when the parameter type in metatdata is object.

                    if (pParamType.isPredefType(PredefinedType.PT_OBJECT))
                    {
                        if (methprop.MarshalAsObject(index))
                        {
                            // For [opt] parameters of type object, if we have marshal(iunknown),
                            // marshal(idispatch), or marshal(interface), then we emit a null.

                            optionalArgument = exprFactory.CreateNull();
                        }
                        else
                        {
                            // Otherwise, we generate Type.Missing

                            AggregateSymbol agg = symbolLoader.GetOptPredefAgg(PredefinedType.PT_MISSING);
                            Name name = symbolLoader.GetNameManager().GetPredefinedName(PredefinedName.PN_CAP_VALUE);
                            FieldSymbol field = symbolLoader.LookupAggMember(name, agg, symbmask_t.MASK_FieldSymbol).AsFieldSymbol();
                            FieldWithType fwt = new FieldWithType(field, agg.getThisType());
                            EXPRFIELD exprField = exprFactory.CreateField(0, agg.getThisType(), null, 0, fwt, null);

                            if (agg.getThisType() != type)
                            {
                                optionalArgument = exprFactory.CreateCast(0, type, exprField);
                            }
                            else
                            {
                                optionalArgument = exprField;
                            }
                        }
                    }
                    else
                    {
                        // Every type aside from object that doesn't have a default value gets
                        // its default value.

                        optionalArgument = exprFactory.CreateZeroInit(pParamType);
                    }
                }

                Debug.Assert(optionalArgument != null);
                optionalArgument.IsOptionalArgument = true;
                return optionalArgument;
            }
Beispiel #39
0
            internal static bool ReOrderArgsForNamedArguments(
                    MethodOrPropertySymbol methprop,
                    TypeArray pCurrentParameters,
                    AggregateType pCurrentType,
                    EXPRMEMGRP pGroup,
                    ArgInfos pArguments,
                    TypeManager typeManager,
                    ExprFactory exprFactory,
                    SymbolLoader symbolLoader)
            {
                // We use the param count from pCurrentParameters because they may have been resized 
                // for param arrays.
                int numParameters = pCurrentParameters.size;

                EXPR[] pExprArguments = new EXPR[numParameters];

                // Now go through the parameters. First set all positional arguments in the new argument
                // set, then for the remainder, look for a named argument with a matching name.
                int index = 0;
                EXPR paramArrayArgument = null;
                TypeArray @params = typeManager.SubstTypeArray(
                    pCurrentParameters,
                    pCurrentType,
                    pGroup.typeArgs);
                foreach (Name name in methprop.ParameterNames)
                {
                    // This can happen if we had expanded our param array to size 0.
                    if (index >= pCurrentParameters.size)
                    {
                        break;
                    }

                    // If:
                    // (1) we have a param array method
                    // (2) we're on the last arg
                    // (3) the thing we have is an array init thats generated for param array
                    // then let us through.
                    if (methprop.isParamArray &&
                        index < pArguments.carg &&
                        pArguments.prgexpr[index].isARRINIT() && pArguments.prgexpr[index].asARRINIT().GeneratedForParamArray)
                    {
                        paramArrayArgument = pArguments.prgexpr[index];
                    }

                    // Positional.
                    if (index < pArguments.carg &&
                        !pArguments.prgexpr[index].isNamedArgumentSpecification() &&
                        !(pArguments.prgexpr[index].isARRINIT() && pArguments.prgexpr[index].asARRINIT().GeneratedForParamArray))
                    {
                        pExprArguments[index] = pArguments.prgexpr[index++];
                        continue;
                    }

                    // Look for names.
                    EXPR pNewArg = FindArgumentWithName(pArguments, name);
                    if (pNewArg == null)
                    {
                        if (methprop.IsParameterOptional(index))
                        {
                            pNewArg = GenerateOptionalArgument(symbolLoader, exprFactory, methprop, @params.Item(index), index);
                        }
                        else if (paramArrayArgument != null && index == methprop.Params.Count - 1)
                        {
                            // If we have a param array argument and we're on the last one, then use it.
                            pNewArg = paramArrayArgument;
                        }
                        else
                        {
                            // No name and no default value.
                            return false;
                        }
                    }
                    pExprArguments[index++] = pNewArg;
                }

                // Here we've found all the arguments, or have default values for them.
                CType[] prgTypes = new CType[pCurrentParameters.size];
                for (int i = 0; i < numParameters; i++)
                {
                    if (i < pArguments.prgexpr.Count)
                    {
                        pArguments.prgexpr[i] = pExprArguments[i];
                    }
                    else
                    {
                        pArguments.prgexpr.Add(pExprArguments[i]);
                    }
                    prgTypes[i] = pArguments.prgexpr[i].type;
                }
                pArguments.carg = pCurrentParameters.size;
                pArguments.types = symbolLoader.getBSymmgr().AllocParams(pCurrentParameters.size, prgTypes);
                return true;
            }