internal CppType( IEnvironment env, CppBackend backend, DataType dt) { EmitTypeObject = !env.HasProperty(dt, "TypeOfFunction"); IsOpaque = backend.IsOpaque(dt); ReflectedName = dt.IsIntrinsic ? dt.QualifiedName : dt.ToString(); StructName = backend.GetStaticName(dt, dt); TypeOfFunction = StructName + "_typeof"; TypeOfType = StructName + "_type"; if (dt.IsGenericMethodType) { TypeOfType = "uClassType"; return; } EmitTypeOfDeclaration = true; switch (dt.TypeType) { case TypeType.Class: case TypeType.Struct: { foreach (var m in dt.Methods) { AddClassMethod(env, m); } foreach (var m in dt.Properties) { AddClassMethod(env, m.GetMethod); AddClassMethod(env, m.SetMethod); } foreach (var m in dt.Events) { AddClassMethod(env, m.AddMethod); AddClassMethod(env, m.RemoveMethod); } foreach (var f in Functions) { if (f.IsConstructor || !f.IsStatic && !f.IsVirtualBase || f.IsVirtual && ( backend.IsTemplate(f.DeclaringType) || f.DeclaringType.Base == null )) { continue; } StaticMethods.Add(f); } Fields.AddRange(dt.EnumerateFields()); for (var bt = dt.Base; bt != null; bt = bt.Base) { foreach (var f in bt.EnumerateFields()) { if (!f.IsStatic) { FlattenedFields.Add(f); } } } InheritedFieldCount = FlattenedFields.Count; foreach (var f in Fields) { if (!f.IsStatic) { FlattenedFields.Add(f); } } // Strategically add static fields last foreach (var f in Fields) { if (f.IsStatic) { FlattenedFields.Add(f); } } // Early out unless reflection is enabled if (!backend.EnableReflection || (!backend.EnableDebugDumps && !dt.IsPublic)) { break; } foreach (var f in dt.EnumerateFunctions()) { var prototype = f.Prototype; if (!prototype.IsPublic || env.GetBool(f, "IsIntrinsic")) { continue; } switch (prototype.MemberType) { case MemberType.Cast: case MemberType.Operator: case MemberType.Finalizer: continue; case MemberType.Constructor: { if (prototype.IsStatic || f.ReturnType.IsVoid) { continue; } break; } case MemberType.Method: { var method = (Method)prototype; if (method.ImplementedMethod != null || method.OverriddenMethod != null || method.IsGenerated && method.DeclaringMember == null) { continue; } break; } } ReflectedFunctions.Add(f); } foreach (var f in backend.EnableDebugDumps ? dt.EnumerateFields() : dt.Fields) { var prototype = f.Prototype; if (!backend.EnableDebugDumps && (!prototype.IsPublic || prototype.IsGenerated)) { continue; } ReflectedFields.Add(f); } break; } case TypeType.Interface: { foreach (var m in dt.Methods) { AddInterfaceMethod(m); } foreach (var m in dt.Properties) { AddInterfaceMethod(m.GetMethod); AddInterfaceMethod(m.SetMethod); } foreach (var m in dt.Events) { AddInterfaceMethod(m.AddMethod); AddInterfaceMethod(m.RemoveMethod); } // Early out unless reflection is enabled if (!backend.EnableReflection || !dt.IsPublic) { break; } ReflectedFunctions.AddRange(dt.EnumerateFunctions()); break; } } // Clear fields on structs where TypeName is overridden, // to avoid invalid offsetof() in generated code. if (dt.IsStruct && env.HasProperty(dt, "TypeName")) { FlattenedFields.Clear(); ReflectedFields.Clear(); } EmitTypeStruct = EmitTypeObject && ( VTable.Any(x => x.OverriddenMethod == null) || dt.Base == null && dt.Interfaces.Length > 0 || dt.Base != null && dt.Interfaces.Length > dt.Base.Interfaces.Length ); if (!EmitTypeStruct) { TypeOfType = dt.IsValueType ? "uStructType" : backend.GetTypeOfType(dt.Base, dt); } Functions.Sort(); ReflectedFields.Sort(); ReflectedFunctions.Sort(); InstanceMethods.Sort(); VTable.Sort(); }
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; } }