protected virtual void VisitRoutineCall(BoundRoutineCall x) { x.ArgumentsInSourceOrder.ForEach(VisitArgument); }
protected virtual TResult VisitRoutineCall(BoundRoutineCall x) => DefaultVisitOperation(x);
protected override BoundOperation VisitRoutineCall(BoundRoutineCall x) { VisitAndUpdate(x.ArgumentsInSourceOrder, v => x.ArgumentsInSourceOrder = v); return(x); }
void VisitRoutineCallEpilogue(BoundRoutineCall x) { // if (x.TargetMethod != null) { TypeRefMask result_type = 0; var args = x.ArgumentsInSourceOrder.Select(a => a.Value).ToImmutableArray(); // reanalyse candidates foreach (var m in new[] { x.TargetMethod }) // TODO: all candidates { // analyze TargetMethod with x.Arguments // require method result type if access != none var enqueued = this.Worklist.EnqueueRoutine(m, CurrentBlock, args); if (enqueued) // => target has to be reanalysed { // note: continuing current block may be waste of time } // process arguments by ref var expectedparams = m.GetExpectedArguments(this.TypeCtx); for (int i = 0; i < expectedparams.Length; i ++) { if (i < args.Length) { var ep = expectedparams[i]; if (ep.IsAlias || ep.IsByRef) // args[i] must be a variable { var refexpr = args[i] as BoundReferenceExpression; if (refexpr != null) { var refvar = refexpr as BoundVariableRef; if (refvar.Name.IsDirect) { State.SetVar(refvar.Name.NameValue.Value, expectedparams[i].Type); if (ep.IsAlias) { State.SetVarRef(refvar.Name.NameValue.Value); } } else { // TODO: indirect variable -> all may be aliases of any type } } else { // TODO: Err, variable or field must be passed into byref argument. foo("hello") where function foo(&$x){} Debug.Fail($"TODO: Err. Argument {i} must be passed as a variable."); } } } } // result_type |= m.GetResultType(TypeCtx); } x.TypeRefMask = result_type; } // if (x.Access.IsReadRef) { x.TypeRefMask = x.TypeRefMask.WithRefFlag; } }
protected override void VisitRoutineCall(BoundRoutineCall x) { x.TypeRefMask = TypeRefMask.AnyType; // TODO: write arguments Access // TODO: visit invocation member of // TODO: 2 pass, analyze arguments -> resolve method -> assign argument to parameter -> write arguments access -> analyze arguments again // visit arguments: base.VisitRoutineCall(x); }