public override void Emit() { ResolveContext rc = new ResolveContext(this); IntConstant buffer_size_const = initializer.Resolve(rc) as IntConstant; if (buffer_size_const == null) { return; } int buffer_size = buffer_size_const.Value; if (buffer_size <= 0) { Report.Error(1665, Location, "`{0}': Fixed size buffers must have a length greater than zero", GetSignatureForError()); return; } int type_size = Expression.GetTypeSize(MemberType); if (buffer_size > int.MaxValue / type_size) { Report.Error(1664, Location, "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit", GetSignatureForError(), buffer_size.ToString(), TypeManager.CSharpName(MemberType)); return; } EmitFieldSize(buffer_size); #if STATIC if (Module.HasDefaultCharSet) { fixed_buffer_type.__SetAttributes(fixed_buffer_type.Attributes | Module.DefaultCharSetType); } #endif Module.PredefinedAttributes.UnsafeValueType.EmitAttribute(fixed_buffer_type); Module.PredefinedAttributes.CompilerGenerated.EmitAttribute(fixed_buffer_type); fixed_buffer_type.CreateType(); base.Emit(); }
void EmitFieldSize(int buffer_size) { int type_size = Expression.GetTypeSize(MemberType); if (buffer_size > int.MaxValue / type_size) { Report.Error(1664, Location, "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit", GetSignatureForError(), buffer_size.ToString(), TypeManager.CSharpName(MemberType)); return; } PredefinedAttribute pa; AttributeEncoder encoder; pa = Module.PredefinedAttributes.StructLayout; if (pa.Constructor == null && !pa.ResolveConstructor(Location, TypeManager.short_type)) { return; } var char_set_type = Module.PredefinedTypes.CharSet.Resolve(Location); if (char_set_type == null) { return; } var field_size = pa.GetField("Size", TypeManager.int32_type, Location); var field_charset = pa.GetField("CharSet", char_set_type, Location); if (field_size == null || field_charset == null) { return; } var char_set = CharSet ?? Module.DefaultCharSet; encoder = new AttributeEncoder(); encoder.Encode((short)LayoutKind.Sequential); encoder.EncodeNamedArguments( new [] { field_size, field_charset }, new Constant [] { new IntConstant(buffer_size * type_size, Location), new IntConstant((int)char_set, Location) } ); pa.EmitAttribute(fixed_buffer_type, encoder); // // Don't emit FixedBufferAttribute attribute for private types // if ((ModFlags & Modifiers.PRIVATE) != 0) { return; } pa = Module.PredefinedAttributes.FixedBuffer; if (pa.Constructor == null && !pa.ResolveConstructor(Location, TypeManager.type_type, TypeManager.int32_type)) { return; } encoder = new AttributeEncoder(); encoder.EncodeTypeName(MemberType); encoder.Encode(buffer_size); encoder.EncodeEmptyNamedArguments(); pa.EmitAttribute(FieldBuilder, encoder); }