protected virtual EXPR GenerateIndexList(EXPR oldIndices) { CType intType = symbolLoader.GetReqPredefType(PredefinedType.PT_INT, true); EXPR newIndices = null; EXPR newIndicesTail = newIndices; for (ExpressionIterator it = new ExpressionIterator(oldIndices); !it.AtEnd(); it.MoveNext()) { EXPR newIndex = it.Current(); if (newIndex.type != intType) { EXPRCLASS exprType = expressionFactory.CreateClass(intType, null, null); newIndex = expressionFactory.CreateCast(EXPRFLAG.EXF_INDEXEXPR, exprType, newIndex); newIndex.flags |= EXPRFLAG.EXF_CHECKOVERFLOW; } EXPR rewrittenIndex = Visit(newIndex); expressionFactory.AppendItemToList(rewrittenIndex, ref newIndices, ref newIndicesTail); } return newIndices; }
protected virtual EXPR GenerateArgsList(EXPR oldArgs) { EXPR newArgs = null; EXPR newArgsTail = newArgs; for (ExpressionIterator it = new ExpressionIterator(oldArgs); !it.AtEnd(); it.MoveNext()) { EXPR oldArg = it.Current(); GetExprFactory().AppendItemToList(Visit(oldArg), ref newArgs, ref newArgsTail); } return newArgs; }
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(); GetExprFactory().AppendItemToList(Visit(oldArg), ref newArgs, ref newArgsTail); } return(newArgs); }
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 = expressionFactory.CreateCast(EXPRFLAG.EXF_INDEXEXPR, intType, newIndex); newIndex.Flags |= EXPRFLAG.EXF_CHECKOVERFLOW; } Expr rewrittenIndex = Visit(newIndex); expressionFactory.AppendItemToList(rewrittenIndex, ref newIndices, ref newIndicesTail); } return(newIndices); }
protected void AdjustCallArgumentsForParams(CType callingObjectType, CType type, MethodOrPropertySymbol mp, TypeArray pTypeArgs, EXPR argsPtr, out EXPR newArgs) { Debug.Assert(mp != null); Debug.Assert(mp.Params != null); newArgs = null; EXPR newArgsTail = null; MethodOrPropertySymbol mostDerivedMethod = GroupToArgsBinder.FindMostDerivedMethod(GetSymbolLoader(), mp, callingObjectType); int paramCount = mp.Params.size; TypeArray @params = mp.Params; int iDst = 0; bool markTypeFromExternCall = mp.IsFMETHSYM() && mp.AsFMETHSYM().isExternal; int argCount = ExpressionIterator.Count(argsPtr); if (mp.IsFMETHSYM() && mp.AsFMETHSYM().isVarargs) { paramCount--; // we don't care about the vararg sentinel } bool bDontFixParamArray = false; ExpressionIterator it = new ExpressionIterator(argsPtr); if (argsPtr == null) { if (mp.isParamArray) goto FIXUPPARAMLIST; return; } for (; !it.AtEnd(); it.MoveNext()) { EXPR indir = it.Current(); // this will splice the optional arguments into the list if (indir.type.IsParameterModifierType()) { if (paramCount != 0) paramCount--; if (markTypeFromExternCall) SetExternalRef(indir.type); GetExprFactory().AppendItemToList(indir, ref newArgs, ref newArgsTail); } else if (paramCount != 0) { if (paramCount == 1 && mp.isParamArray && argCount > mp.Params.size) { // we arrived at the last formal, and we have more than one actual, so // we need to put the rest in an array... goto FIXUPPARAMLIST; } EXPR argument = indir; EXPR rval; if (argument.isNamedArgumentSpecification()) { int index = 0; // If we're named, look for the type of the matching name. foreach (Name i in mostDerivedMethod.ParameterNames) { if (i == argument.asNamedArgumentSpecification().Name) { break; } index++; } Debug.Assert(index != mp.Params.size); CType substDestType = GetTypes().SubstType(@params.Item(index), type, pTypeArgs); // If we cant convert the argument and we're the param array argument, then deal with it. if (!canConvert(argument.asNamedArgumentSpecification().Value, substDestType) && mp.isParamArray && index == mp.Params.size - 1) { // We have a param array, but we're not at the end yet. This will happen // with named arguments when the user specifies a name for the param array, // and its not an actual array. // // For example: // void Foo(int y, params int[] x); // ... // Foo(x:1, y:1); CType arrayType = GetTypes().SubstType(mp.Params.Item(mp.Params.size - 1), type, pTypeArgs); CType elemType = arrayType.AsArrayType().GetElementType(); // Use an EK_ARRINIT even in the empty case so empty param arrays in attributes work. EXPRARRINIT arrayInit = GetExprFactory().CreateArrayInit(0, arrayType, null, null, null); arrayInit.GeneratedForParamArray = true; arrayInit.dimSizes = new int[] { arrayInit.dimSize }; arrayInit.dimSize = 1; arrayInit.SetOptionalArguments(argument.asNamedArgumentSpecification().Value); argument.asNamedArgumentSpecification().Value = arrayInit; bDontFixParamArray = true; } else { // Otherwise, force the conversion and get errors if needed. argument.asNamedArgumentSpecification().Value = tryConvert( argument.asNamedArgumentSpecification().Value, substDestType); } rval = argument; } else { CType substDestType = GetTypes().SubstType(@params.Item(iDst), type, pTypeArgs); rval = tryConvert(indir, substDestType); } if (rval == null) { // the last arg failed to fix up, so it must fixup into the array element // if we have a param array (we will be passing a 1 element array...) if (mp.isParamArray && paramCount == 1 && argCount >= mp.Params.size) { goto FIXUPPARAMLIST; } else { // This is either the error case that the args are of the wrong type, // or that we have some optional arguments being used. Either way, // we wont need to expand the param array. return; } } Debug.Assert(rval != null); indir = rval; GetExprFactory().AppendItemToList(rval, ref newArgs, ref newArgsTail); paramCount--; } // note that destype might not be valid if we are in varargs, but then we won't ever use it... iDst++; if (paramCount != 0 && mp.isParamArray && iDst == argCount) { // we run out of actuals, but we still have formals, so this is an empty array being passed // into the last param... indir = null; it.MoveNext(); goto FIXUPPARAMLIST; } } return; FIXUPPARAMLIST: if (bDontFixParamArray) { // We've already fixed the param array for named arguments. return; } // we need to create an array and put it as the last arg... CType substitutedArrayType = GetTypes().SubstType(mp.Params.Item(mp.Params.size - 1), type, pTypeArgs); if (!substitutedArrayType.IsArrayType() || substitutedArrayType.AsArrayType().rank != 1) { // Invalid type for params array parameter. Happens in LAF scenarios, e.g. // // void Foo(int i, params int ar = null) { } // ... // Foo(1); return; } CType elementType = substitutedArrayType.AsArrayType().GetElementType(); // Use an EK_ARRINIT even in the empty case so empty param arrays in attributes work. EXPRARRINIT exprArrayInit = GetExprFactory().CreateArrayInit(0, substitutedArrayType, null, null, null); exprArrayInit.GeneratedForParamArray = true; exprArrayInit.dimSizes = new int[] { exprArrayInit.dimSize }; if (it.AtEnd()) { exprArrayInit.dimSize = 0; exprArrayInit.dimSizes[0] = 0; exprArrayInit.SetOptionalArguments(null); if (argsPtr == null) { argsPtr = exprArrayInit; } else { argsPtr = GetExprFactory().CreateList(argsPtr, exprArrayInit); } GetExprFactory().AppendItemToList(exprArrayInit, ref newArgs, ref newArgsTail); } else { // Go through the list - for each argument, do the conversion and append it to the new list. EXPR newList = null; EXPR newListTail = null; int count = 0; for (; !it.AtEnd(); it.MoveNext()) { EXPR expr = it.Current(); count++; if (expr.isNamedArgumentSpecification()) { expr.asNamedArgumentSpecification().Value = tryConvert( expr.asNamedArgumentSpecification().Value, elementType); } else { expr = tryConvert(expr, elementType); } GetExprFactory().AppendItemToList(expr, ref newList, ref newListTail); } exprArrayInit.dimSize = count; exprArrayInit.dimSizes[0] = count; exprArrayInit.SetOptionalArguments(newList); GetExprFactory().AppendItemToList(exprArrayInit, ref newArgs, ref newArgsTail); } }