Method GetBoxedMethod(DataType dt, Method decl, Method impl) { if (dt.IsMasterDefinition) { var m = new Method(impl.Source, dt, impl.DocComment, Modifiers.Public | Modifiers.Generated, impl.Name + "_boxed", decl.ReturnType, decl.Parameters, new Scope(impl.Source)); Variable ret = null; if (!impl.ReturnType.IsVoid && _backend.IsConstrained(impl)) { ret = new Variable(m.Source, m, dt.GetUniqueIdentifier("ret"), impl.ReturnType); m.Body.Statements.Add(new VariableDeclaration(ret)); } var args = new Expression[m.Parameters.Length]; for (int i = 0; i < args.Length; i++) { args[i] = new LoadArgument(m.Source, m, i); } m.Body.Statements.Add( new Return(m.Source, new CastOp(m.Source, m.ReturnType, new CallMethod(m.Source, new This(m.Source, dt).Address, impl, args, ret)))); m.SetPrototype(impl); dt.Methods.Add(m); dt.InterfaceMethods[decl] = m; return(m); } foreach (var e in dt.MasterDefinition.InterfaceMethods) { if (e.Value.Modifiers != (Modifiers.Public | Modifiers.Generated) || e.Key.MasterDefinition != decl.MasterDefinition) { continue; } var m = new Method(impl.Source, dt, e.Value.DocComment, e.Value.Modifiers, e.Value.Name, decl.ReturnType, decl.Parameters, e.Value.Body); m.SetMasterDefinition(e.Value); m.SetPrototype(impl); dt.Methods.Add(m); dt.InterfaceMethods[decl] = m; return(m); } Log.Error(impl.Source, ErrorCode.I0000, "C++: Boxed method master definition was not found."); return(impl); }
public override void Begin(ref Expression e, ExpressionUsage u) { switch (e.ExpressionType) { case ExpressionType.Constant: { var str = e.ConstantValue as string; if (str != null) { _type.StringConsts.Add((string)e.ConstantValue); } break; } case ExpressionType.LoadField: case ExpressionType.StoreField: { var s = (FieldExpression)e; var field = s.Field; var obj = s.Object; if (field.IsStatic) { RegisterDependency(field.DeclaringType); } if (_backend.IsConstrained(field)) { if (!(obj is AddressOf && _backend.IsConstrained(obj.ReturnType) && obj.ActualValue.HasStorage()) && !(!field.IsStatic && field.DeclaringType.IsReferenceType)) { RegisterType(field.DeclaringType); } } else { if (!_backend.IsTemplate(field.DeclaringType) && _backend.IsConstrained(field.MasterDefinition.ReturnType) || field.IsStatic && !field.DeclaringType.MasterDefinition.IsClosed) { RegisterType(field.IsStatic, field.DeclaringType); } } break; } case ExpressionType.LoadArgument: { var s = (LoadArgument)e; if (!s.Parameter.IsReference && ( s.Parameter.Type.IsReferenceType || _flags.HasFlag(BodyFlags.ClassMember) || _backend.IsConstrained(s.Parameter.Type))) { RegisterType(u == ExpressionUsage.VarArg && s.Parameter.IsReference && _backend.IsConstrained(s.Parameter.Type), s.Parameter.Type); } break; } case ExpressionType.StoreArgument: { var s = (StoreArgument)e; if (s.Parameter.IsReference && _backend.IsConstrained(s.Parameter.Type) && !_flags.HasFlag(BodyFlags.ClassMember)) { RegisterType(s.Value is Default || !s.Value.HasStorage(), s.Parameter.Type); } break; } case ExpressionType.Base: RegisterType(Function != null && Type.IsValueType, e.ReturnType); break; case ExpressionType.AllocObject: RegisterType(((AllocObject)e).ObjectType); break; case ExpressionType.NewObject: RegisterType(((NewObject)e).Constructor.DeclaringType); break; case ExpressionType.NewDelegate: { var s = (NewDelegate)e; RegisterType(s.ReturnType); RegisterInterface(s.Method); if (_backend.HasTypeParameter(s.Method)) { RegisterType(s.Method.GenericType ?? s.Method.DeclaringType); } break; } case ExpressionType.TypeOf: RegisterType(((TypeOf)e).TypeType); break; case ExpressionType.AddListener: case ExpressionType.RemoveListener: case ExpressionType.SetProperty: case ExpressionType.GetProperty: case ExpressionType.CallMethod: { var s = (CallExpression)e; var func = s.Function; RegisterInterface(func); if (func.IsGenericMethod) { RegisterType(func.GenericType); } else if (_backend.HasTypeParameter(func)) { RegisterType(func.DeclaringType); } if (func.IsStatic && !func.Prototype.IsConstructor) { RegisterDependency(func.GenericType ?? func.DeclaringType); } break; } case ExpressionType.NewArray: RegisterType(((NewArray)e).ArrayType); break; case ExpressionType.CastOp: if (!e.ReturnType.IsInterface && ((CastOp)e).CastType == CastType.Down) { RegisterType(e.ReturnType); } break; case ExpressionType.IsOp: RegisterType(((IsOp)e).TestType); break; case ExpressionType.AsOp: RegisterType(((AsOp)e).TestType); break; } }