internal override void Emit(Expr expr, TypeSymbol type, ILGenerator ilg) { Conversion.Emit(expr, type, ilg); var loc = new LocalSymbol(Type); loc.Declare(ilg); loc.EmitSet(ilg); Expr = IdExpr.Bound(loc); }
internal override void Emit(Expr expr, TypeSymbol type, ILGenerator ilg) { if (Expr == null) { Conversion.Emit(expr, type, ilg); Local.Declare(ilg); Local.EmitSet(ilg); Expr = IdExpr.Bound(Local); } }
Arg ApplyUsualConversions(ArgList args, out Expr writeBack) { writeBack = null; bool hasRefArgs = false; for (int i = 0; i < args.Args.Count; i++) { var e = args.Args[i].Expr; Convert(ref e, Compilation.Get(NativeType.Usual)); if (args.Args[i].RefKind != RefKind.None) { hasRefArgs = true; } } var arguments = new Arg(LiteralArray.Bound(args.Args)); if (hasRefArgs) { var conv = ConversionSymbol.Create(ConversionSymbol.Create(ConversionKind.Identity), new ConversionToTemp(arguments.Expr.Datatype)); Convert(ref arguments.Expr, arguments.Expr.Datatype, conv); for (int i = 0; i < args.Args.Count; i++) { if (args.Args[i].RefKind != RefKind.None) { HandleVarArgWriteBack(conv, args.Args[i].Expr, i, ref writeBack); } } } return(arguments); void HandleVarArgWriteBack(ConversionSymbol conv, Expr e, int i, ref Expr wb) { if (e.Symbol?.HasSetAccess == true || e is AutoVarExpr || e is AliasExpr) { // Handle writeBack Expr t = IdExpr.Bound(conv.IndirectRefConversionTempLocal()); t = ArrayAccessExpr.Bound(t, ArgList.Bound(LiteralExpr.Bound(Constant.Create(i + 1))), this); var wc = Conversion(t, e.Datatype, BindOptions.Default); if (wc.Exists) { Convert(ref t, e.Datatype, wc); SymbolExtensions.AddExpr(ref wb, AssignExpr.Bound(e, t, BindOptions.Default)); } } } }
void ApplyConversions(ArgList args, OverloadResult ovRes, out Expr writeBack) { writeBack = null; var parameters = ovRes.Parameters.Parameters; for (int i = 0; i < ovRes.FixedArgs; i++) { var conv = ovRes.Conversions[i]; var e = args.Args[i].Expr; if (conv.Kind != ConversionKind.Identity) { Convert(ref args.Args[i].Expr, FindType(parameters[i].ParameterType), conv); } if (conv is ConversionSymbolToConstant) { Convert(ref args.Args[i].Expr, FindType(parameters[i].ParameterType), BindOptions.Default); } HandleArgWriteBack(conv, e, ref writeBack); } if (ovRes.MissingArgs > 0) { for (int i = ovRes.FixedArgs; i < ovRes.FixedArgs + ovRes.MissingArgs; i++) { var conv = ovRes.Conversions[i]; var a = new Arg(LiteralExpr.Bound(((ConversionSymbolToConstant)conv).Constant)); Convert(ref a.Expr, FindType(parameters[i].ParameterType), BindOptions.Default); args.Args.Add(a); } } else if (ovRes.Parameters.HasParamArray) { var varArgs = new List <Expr>(ovRes.VarArgs); var varArgType = FindType(parameters[ovRes.FixedArgs].ParameterType.GetElementType()); bool hasRefArgs = false; for (int i = ovRes.FixedArgs; i < ovRes.FixedArgs + ovRes.VarArgs; i++) { var conv = ovRes.Conversions[i]; var e = args.Args[i].Expr; Convert(ref e, varArgType, conv); varArgs.Add(e); if (args.Args[i].RefKind != RefKind.None) { hasRefArgs = true; } } var varArg = new Arg(LiteralArray.Bound(varArgs, varArgType)); if (hasRefArgs) { var conv = ConversionSymbol.Create(ConversionSymbol.Create(ConversionKind.Identity), new ConversionToTemp(varArg.Expr.Datatype)); Convert(ref varArg.Expr, varArg.Expr.Datatype, conv); for (int i = ovRes.FixedArgs; i < ovRes.FixedArgs + ovRes.VarArgs; i++) { if (args.Args[i].RefKind != RefKind.None) { HandleVarArgWriteBack(conv, args.Args[i].Expr, i - ovRes.FixedArgs, ref writeBack); } } } while (args.Args.Count > ovRes.FixedArgs) { args.Args.RemoveAt(args.Args.Count - 1); } args.Args.Add(varArg); } void HandleArgWriteBack(ConversionSymbol conv, Expr e, ref Expr wb) { if (conv.IsIndirectRefConversion()) { if (e.Symbol?.HasSetAccess == true || e is AutoVarExpr || e is AliasExpr) { // Handle writeBack Expr t = IdExpr.Bound(conv.IndirectRefConversionTempLocal()); var wc = Conversion(t, e.Datatype, BindOptions.Default); if (wc.Exists) { Convert(ref t, e.Datatype, wc); SymbolExtensions.AddExpr(ref wb, AssignExpr.Bound(e, t, BindOptions.Default)); } } } } void HandleVarArgWriteBack(ConversionSymbol conv, Expr e, int i, ref Expr wb) { if (e.Symbol?.HasSetAccess == true || e is AutoVarExpr || e is AliasExpr) { // Handle writeBack Expr t = IdExpr.Bound(conv.IndirectRefConversionTempLocal()); t = ArrayAccessExpr.Bound(t, ArgList.Bound(LiteralExpr.Bound(Constant.Create(i + 1))), this); var wc = Conversion(t, e.Datatype, BindOptions.Default); if (wc.Exists) { Convert(ref t, e.Datatype, wc); SymbolExtensions.AddExpr(ref wb, AssignExpr.Bound(e, t, BindOptions.Default)); } } } }