Пример #1
0
        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));
                    }
                }
            }
        }
Пример #2
0
        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));
                    }
                }
            }
        }