Wrap always_inline and noinline attributes in compiler checks and use MSVC equivalent.
[mono.git] / mcs / class / IKVM.Reflection / Emit / TypeBuilder.cs
1 /*
2   Copyright (C) 2008-2011 Jeroen Frijters
3
4   This software is provided 'as-is', without any express or implied
5   warranty.  In no event will the authors be held liable for any damages
6   arising from the use of this software.
7
8   Permission is granted to anyone to use this software for any purpose,
9   including commercial applications, and to alter it and redistribute it
10   freely, subject to the following restrictions:
11
12   1. The origin of this software must not be misrepresented; you must not
13      claim that you wrote the original software. If you use this software
14      in a product, an acknowledgment in the product documentation would be
15      appreciated but is not required.
16   2. Altered source versions must be plainly marked as such, and must not be
17      misrepresented as being the original software.
18   3. This notice may not be removed or altered from any source distribution.
19
20   Jeroen Frijters
21   jeroen@frijters.net
22   
23 */
24 using System;
25 using System.Collections.Generic;
26 using System.Diagnostics;
27 using System.Runtime.InteropServices;
28 using IKVM.Reflection.Impl;
29 using IKVM.Reflection.Metadata;
30 using IKVM.Reflection.Writer;
31
32 namespace IKVM.Reflection.Emit
33 {
34         public sealed class GenericTypeParameterBuilder : Type
35         {
36                 private readonly string name;
37                 private readonly TypeBuilder type;
38                 private readonly MethodBuilder method;
39                 private readonly int paramPseudoIndex;
40                 private readonly int position;
41                 private int typeToken;
42                 private Type baseType;
43                 private GenericParameterAttributes attr;
44
45                 internal GenericTypeParameterBuilder(string name, TypeBuilder type, MethodBuilder method, int position)
46                 {
47                         this.name = name;
48                         this.type = type;
49                         this.method = method;
50                         this.position = position;
51                         GenericParamTable.Record rec = new GenericParamTable.Record();
52                         rec.Number = (short)position;
53                         rec.Flags = 0;
54                         rec.Owner = type != null ? type.MetadataToken : method.MetadataToken;
55                         rec.Name = this.ModuleBuilder.Strings.Add(name);
56                         this.paramPseudoIndex = this.ModuleBuilder.GenericParam.AddRecord(rec);
57                 }
58
59                 public override string AssemblyQualifiedName
60                 {
61                         get { return null; }
62                 }
63
64                 public override bool IsValueType
65                 {
66                         get { return (this.GenericParameterAttributes & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0; }
67                 }
68
69                 public override Type BaseType
70                 {
71                         get { return baseType; }
72                 }
73
74                 public override Type[] __GetDeclaredInterfaces()
75                 {
76                         throw new NotImplementedException();
77                 }
78
79                 public override TypeAttributes Attributes
80                 {
81                         get { return TypeAttributes.Public; }
82                 }
83
84                 public override string Namespace
85                 {
86                         get { return DeclaringType.Namespace; }
87                 }
88
89                 public override string Name
90                 {
91                         get { return name; }
92                 }
93
94                 public override string FullName
95                 {
96                         get { return null; }
97                 }
98
99                 public override string ToString()
100                 {
101                         return this.Name;
102                 }
103
104                 private ModuleBuilder ModuleBuilder
105                 {
106                         get { return type != null ? type.ModuleBuilder : method.ModuleBuilder; }
107                 }
108
109                 public override Module Module
110                 {
111                         get { return ModuleBuilder; }
112                 }
113
114                 public override bool IsGenericParameter
115                 {
116                         get { return true; }
117                 }
118
119                 public override int GenericParameterPosition
120                 {
121                         get { return position; }
122                 }
123
124                 public override Type DeclaringType
125                 {
126                         get { return type; }
127                 }
128
129                 public override MethodBase DeclaringMethod
130                 {
131                         get { return method; }
132                 }
133
134                 public override Type[] GetGenericParameterConstraints()
135                 {
136                         throw new NotImplementedException();
137                 }
138
139                 public override GenericParameterAttributes GenericParameterAttributes
140                 {
141                         get
142                         {
143                                 CheckBaked();
144                                 return attr;
145                         }
146                 }
147
148                 internal override void CheckBaked()
149                 {
150                         if (type != null)
151                         {
152                                 type.CheckBaked();
153                         }
154                         else
155                         {
156                                 method.CheckBaked();
157                         }
158                 }
159
160                 private void AddConstraint(Type type)
161                 {
162                         GenericParamConstraintTable.Record rec = new GenericParamConstraintTable.Record();
163                         rec.Owner = paramPseudoIndex;
164                         rec.Constraint = this.ModuleBuilder.GetTypeTokenForMemberRef(type);
165                         this.ModuleBuilder.GenericParamConstraint.AddRecord(rec);
166                 }
167
168                 public void SetBaseTypeConstraint(Type baseTypeConstraint)
169                 {
170                         this.baseType = baseTypeConstraint;
171                         AddConstraint(baseTypeConstraint);
172                 }
173
174                 public void SetInterfaceConstraints(params Type[] interfaceConstraints)
175                 {
176                         foreach (Type type in interfaceConstraints)
177                         {
178                                 AddConstraint(type);
179                         }
180                 }
181
182                 public void SetGenericParameterAttributes(GenericParameterAttributes genericParameterAttributes)
183                 {
184                         this.attr = genericParameterAttributes;
185                         // for now we'll back patch the table
186                         this.ModuleBuilder.GenericParam.PatchAttribute(paramPseudoIndex, genericParameterAttributes);
187                 }
188
189                 public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
190                 {
191                         this.ModuleBuilder.SetCustomAttribute((GenericParamTable.Index << 24) | paramPseudoIndex, customBuilder);
192                 }
193
194                 public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
195                 {
196                         SetCustomAttribute(new CustomAttributeBuilder(con, binaryAttribute));
197                 }
198
199                 public override int MetadataToken
200                 {
201                         get
202                         {
203                                 CheckBaked();
204                                 return (GenericParamTable.Index << 24) | paramPseudoIndex;
205                         }
206                 }
207
208                 internal override int GetModuleBuilderToken()
209                 {
210                         if (typeToken == 0)
211                         {
212                                 ByteBuffer spec = new ByteBuffer(5);
213                                 Signature.WriteTypeSpec(this.ModuleBuilder, spec, this);
214                                 typeToken = 0x1B000000 | this.ModuleBuilder.TypeSpec.AddRecord(this.ModuleBuilder.Blobs.Add(spec));
215                         }
216                         return typeToken;
217                 }
218
219                 internal override Type BindTypeParameters(IGenericBinder binder)
220                 {
221                         if (type != null)
222                         {
223                                 return binder.BindTypeParameter(this);
224                         }
225                         else
226                         {
227                                 return binder.BindMethodParameter(this);
228                         }
229                 }
230
231                 internal override int GetCurrentToken()
232                 {
233                         if (this.ModuleBuilder.IsSaved)
234                         {
235                                 return (GenericParamTable.Index << 24) | this.Module.GenericParam.GetIndexFixup()[paramPseudoIndex - 1] + 1;
236                         }
237                         else
238                         {
239                                 return (GenericParamTable.Index << 24) | paramPseudoIndex;
240                         }
241                 }
242
243                 internal override bool IsBaked
244                 {
245                         get { return ((MemberInfo)type ?? method).IsBaked; }
246                 }
247         }
248
249         public sealed class TypeBuilder : Type, ITypeOwner
250         {
251                 public const int UnspecifiedTypeSize = 0;
252                 private readonly ITypeOwner owner;
253                 private readonly int token;
254                 private int extends;
255                 private Type lazyBaseType;              // (lazyBaseType == null && attribs & TypeAttributes.Interface) == 0) => BaseType == System.Object
256                 private readonly int typeName;
257                 private readonly int typeNameSpace;
258                 private readonly string ns;
259                 private readonly string name;
260                 private readonly List<MethodBuilder> methods = new List<MethodBuilder>();
261                 private readonly List<FieldBuilder> fields = new List<FieldBuilder>();
262                 private List<PropertyBuilder> properties;
263                 private List<EventBuilder> events;
264                 private TypeAttributes attribs;
265                 private GenericTypeParameterBuilder[] gtpb;
266                 private List<CustomAttributeBuilder> declarativeSecurity;
267                 private List<Type> interfaces;
268                 private int size;
269                 private short pack;
270                 private bool hasLayout;
271
272                 internal TypeBuilder(ITypeOwner owner, string ns, string name)
273                 {
274                         this.owner = owner;
275                         this.token = this.ModuleBuilder.TypeDef.AllocToken();
276                         this.ns = ns;
277                         this.name = name;
278                         this.typeNameSpace = ns == null ? 0 : this.ModuleBuilder.Strings.Add(ns);
279                         this.typeName = this.ModuleBuilder.Strings.Add(name);
280                         MarkEnumOrValueType(ns, name);
281                 }
282
283                 public ConstructorBuilder DefineDefaultConstructor(MethodAttributes attributes)
284                 {
285                         ConstructorBuilder cb = DefineConstructor(attributes, CallingConventions.Standard, Type.EmptyTypes);
286                         ILGenerator ilgen = cb.GetILGenerator();
287                         ilgen.Emit(OpCodes.Ldarg_0);
288                         ilgen.Emit(OpCodes.Call, BaseType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null));
289                         ilgen.Emit(OpCodes.Ret);
290                         return cb;
291                 }
292
293                 public ConstructorBuilder DefineConstructor(MethodAttributes attribs, CallingConventions callConv, Type[] parameterTypes)
294                 {
295                         return DefineConstructor(attribs, callConv, parameterTypes, null, null);
296                 }
297
298                 public ConstructorBuilder DefineConstructor(MethodAttributes attribs, CallingConventions callingConvention, Type[] parameterTypes, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)
299                 {
300                         attribs |= MethodAttributes.RTSpecialName | MethodAttributes.SpecialName;
301                         string name = (attribs & MethodAttributes.Static) == 0 ? ConstructorInfo.ConstructorName : ConstructorInfo.TypeConstructorName;
302                         MethodBuilder mb = DefineMethod(name, attribs, callingConvention, null, null, null, parameterTypes, requiredCustomModifiers, optionalCustomModifiers);
303                         return new ConstructorBuilder(mb);
304                 }
305
306                 public ConstructorBuilder DefineTypeInitializer()
307                 {
308                         MethodBuilder mb = DefineMethod(ConstructorInfo.TypeConstructorName, MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName, null, Type.EmptyTypes);
309                         return new ConstructorBuilder(mb);
310                 }
311
312                 private MethodBuilder CreateMethodBuilder(string name, MethodAttributes attributes, CallingConventions callingConvention)
313                 {
314                         this.ModuleBuilder.MethodDef.AddVirtualRecord();
315                         MethodBuilder mb = new MethodBuilder(this, name, attributes, callingConvention);
316                         methods.Add(mb);
317                         return mb;
318                 }
319
320                 public MethodBuilder DefineMethod(string name, MethodAttributes attribs)
321                 {
322                         return DefineMethod(name, attribs, CallingConventions.Standard);
323                 }
324
325                 public MethodBuilder DefineMethod(string name, MethodAttributes attribs, CallingConventions callingConvention)
326                 {
327                         return CreateMethodBuilder(name, attribs, callingConvention);
328                 }
329
330                 public MethodBuilder DefineMethod(string name, MethodAttributes attribs, Type returnType, Type[] parameterTypes)
331                 {
332                         return DefineMethod(name, attribs, CallingConventions.Standard, returnType, null, null, parameterTypes, null, null);
333                 }
334
335                 public MethodBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes)
336                 {
337                         return DefineMethod(name, attributes, callingConvention, returnType, null, null, parameterTypes, null, null);
338                 }
339
340                 public MethodBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
341                 {
342                         MethodBuilder mb = CreateMethodBuilder(name, attributes, callingConvention);
343                         mb.SetSignature(returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers);
344                         return mb;
345                 }
346
347                 public MethodBuilder DefinePInvokeMethod(string name, string dllName, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet)
348                 {
349                         return DefinePInvokeMethod(name, dllName, null, attributes, callingConvention, returnType, null, null, parameterTypes, null, null, nativeCallConv, nativeCharSet);
350                 }
351
352                 public MethodBuilder DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet)
353                 {
354                         return DefinePInvokeMethod(name, dllName, entryName, attributes, callingConvention, returnType, null, null, parameterTypes, null, null, nativeCallConv, nativeCharSet);
355                 }
356
357                 public MethodBuilder DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention,
358                         Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
359                         Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers,
360                         CallingConvention nativeCallConv, CharSet nativeCharSet)
361                 {
362                         MethodBuilder mb = DefineMethod(name, attributes | MethodAttributes.PinvokeImpl, callingConvention,
363                                 returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers,
364                                 parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers);
365                         mb.SetDllImportPseudoCustomAttribute(dllName, entryName, nativeCallConv, nativeCharSet, null, null, null, null, null);
366                         return mb;
367                 }
368
369                 public void DefineMethodOverride(MethodInfo methodInfoBody, MethodInfo methodInfoDeclaration)
370                 {
371                         MethodImplTable.Record rec = new MethodImplTable.Record();
372                         rec.Class = token;
373                         rec.MethodBody = this.ModuleBuilder.GetMethodToken(methodInfoBody).Token;
374                         rec.MethodDeclaration = this.ModuleBuilder.GetMethodTokenWinRT(methodInfoDeclaration);
375                         this.ModuleBuilder.MethodImpl.AddRecord(rec);
376                 }
377
378                 public FieldBuilder DefineField(string name, Type fieldType, FieldAttributes attribs)
379                 {
380                         return DefineField(name, fieldType, null, null, attribs);
381                 }
382
383                 public FieldBuilder DefineField(string fieldName, Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers, FieldAttributes attributes)
384                 {
385                         return __DefineField(fieldName, type, CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers), attributes);
386                 }
387
388                 public FieldBuilder __DefineField(string fieldName, Type type, CustomModifiers customModifiers, FieldAttributes attributes)
389                 {
390                         FieldBuilder fb = new FieldBuilder(this, fieldName, type, customModifiers, attributes);
391                         fields.Add(fb);
392                         return fb;
393                 }
394
395                 public PropertyBuilder DefineProperty(string name, PropertyAttributes attributes, Type returnType, Type[] parameterTypes)
396                 {
397                         return DefineProperty(name, attributes, returnType, null, null, parameterTypes, null, null);
398                 }
399
400                 public PropertyBuilder DefineProperty(string name, PropertyAttributes attributes, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
401                         Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
402                 {
403                         return DefinePropertyImpl(name, attributes, CallingConventions.Standard, true, returnType, parameterTypes,
404                                 PackedCustomModifiers.CreateFromExternal(returnTypeOptionalCustomModifiers, returnTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers, parameterTypeRequiredCustomModifiers, Util.NullSafeLength(parameterTypes)));
405                 }
406
407                 public PropertyBuilder DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention,
408                         Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
409                         Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
410                 {
411                         return DefinePropertyImpl(name, attributes, callingConvention, false, returnType, parameterTypes,
412                                 PackedCustomModifiers.CreateFromExternal(returnTypeOptionalCustomModifiers, returnTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers, parameterTypeRequiredCustomModifiers, Util.NullSafeLength(parameterTypes)));
413                 }
414
415                 public PropertyBuilder __DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention,
416                         Type returnType, CustomModifiers returnTypeCustomModifiers, Type[] parameterTypes, CustomModifiers[] parameterTypeCustomModifiers)
417                 {
418                         return DefinePropertyImpl(name, attributes, callingConvention, false, returnType, parameterTypes,
419                                 PackedCustomModifiers.CreateFromExternal(returnTypeCustomModifiers, parameterTypeCustomModifiers, Util.NullSafeLength(parameterTypes)));
420                 }
421
422                 private PropertyBuilder DefinePropertyImpl(string name, PropertyAttributes attributes, CallingConventions callingConvention, bool patchCallingConvention,
423                         Type returnType, Type[] parameterTypes, PackedCustomModifiers customModifiers)
424                 {
425                         if (properties == null)
426                         {
427                                 properties = new List<PropertyBuilder>();
428                         }
429                         PropertySignature sig = PropertySignature.Create(callingConvention, returnType, parameterTypes, customModifiers);
430                         PropertyBuilder pb = new PropertyBuilder(this, name, attributes, sig, patchCallingConvention);
431                         properties.Add(pb);
432                         return pb;
433                 }
434
435                 public EventBuilder DefineEvent(string name, EventAttributes attributes, Type eventtype)
436                 {
437                         if (events == null)
438                         {
439                                 events = new List<EventBuilder>();
440                         }
441                         EventBuilder eb = new EventBuilder(this, name, attributes, eventtype);
442                         events.Add(eb);
443                         return eb;
444                 }
445
446                 public TypeBuilder DefineNestedType(string name)
447                 {
448                         return DefineNestedType(name, TypeAttributes.Class | TypeAttributes.NestedPrivate);
449                 }
450
451                 public TypeBuilder DefineNestedType(string name, TypeAttributes attribs)
452                 {
453                         return DefineNestedType(name, attribs, null);
454                 }
455
456                 public TypeBuilder DefineNestedType(string name, TypeAttributes attr, Type parent, Type[] interfaces)
457                 {
458                         TypeBuilder tb = DefineNestedType(name, attr, parent);
459                         if (interfaces != null)
460                         {
461                                 foreach (Type iface in interfaces)
462                                 {
463                                         tb.AddInterfaceImplementation(iface);
464                                 }
465                         }
466                         return tb;
467                 }
468
469                 public TypeBuilder DefineNestedType(string name, TypeAttributes attr, Type parent)
470                 {
471                         return DefineNestedType(name, attr, parent, 0);
472                 }
473
474                 public TypeBuilder DefineNestedType(string name, TypeAttributes attr, Type parent, int typeSize)
475                 {
476                         return DefineNestedType(name, attr, parent, PackingSize.Unspecified, typeSize);
477                 }
478
479                 public TypeBuilder DefineNestedType(string name, TypeAttributes attr, Type parent, PackingSize packSize)
480                 {
481                         return DefineNestedType(name, attr, parent, packSize, 0);
482                 }
483
484                 private TypeBuilder DefineNestedType(string name, TypeAttributes attr, Type parent, PackingSize packSize, int typeSize)
485                 {
486                         string ns = null;
487                         int lastdot = name.LastIndexOf('.');
488                         if (lastdot > 0)
489                         {
490                                 ns = name.Substring(0, lastdot);
491                                 name = name.Substring(lastdot + 1);
492                         }
493                         TypeBuilder typeBuilder = __DefineNestedType(ns, name);
494                         typeBuilder.__SetAttributes(attr);
495                         typeBuilder.SetParent(parent);
496                         if (packSize != PackingSize.Unspecified || typeSize != 0)
497                         {
498                                 typeBuilder.__SetLayout((int)packSize, typeSize);
499                         }
500                         return typeBuilder;
501                 }
502
503                 public TypeBuilder __DefineNestedType(string ns, string name)
504                 {
505                         this.typeFlags |= TypeFlags.HasNestedTypes;
506                         TypeBuilder typeBuilder = this.ModuleBuilder.DefineType(this, ns, name);
507                         NestedClassTable.Record rec = new NestedClassTable.Record();
508                         rec.NestedClass = typeBuilder.MetadataToken;
509                         rec.EnclosingClass = this.MetadataToken;
510                         this.ModuleBuilder.NestedClass.AddRecord(rec);
511                         return typeBuilder;
512                 }
513
514                 public void SetParent(Type parent)
515                 {
516                         lazyBaseType = parent;
517                 }
518
519                 public void AddInterfaceImplementation(Type interfaceType)
520                 {
521                         if (interfaces == null)
522                         {
523                                 interfaces = new List<Type>();
524                         }
525                         interfaces.Add(interfaceType);
526                 }
527
528                 public void __SetInterfaceImplementationCustomAttribute(Type interfaceType, CustomAttributeBuilder cab)
529                 {
530                         this.ModuleBuilder.SetInterfaceImplementationCustomAttribute(this, interfaceType, cab);
531                 }
532
533                 public int Size
534                 {
535                         get { return size; }
536                 }
537
538                 public PackingSize PackingSize
539                 {
540                         get { return (PackingSize)pack; }
541                 }
542
543                 public override bool __GetLayout(out int packingSize, out int typeSize)
544                 {
545                         packingSize = this.pack;
546                         typeSize = this.size;
547                         return hasLayout;
548                 }
549
550                 public void __SetLayout(int packingSize, int typesize)
551                 {
552                         this.pack = (short)packingSize;
553                         this.size = typesize;
554                         this.hasLayout = true;
555                 }
556
557                 private void SetStructLayoutPseudoCustomAttribute(CustomAttributeBuilder customBuilder)
558                 {
559                         object val = customBuilder.GetConstructorArgument(0);
560                         LayoutKind layout;
561                         if (val is short)
562                         {
563                                 layout = (LayoutKind)(short)val;
564                         }
565                         else
566                         {
567                                 layout = (LayoutKind)val;
568                         }
569                         StructLayoutAttribute attr = new StructLayoutAttribute(layout);
570                         attr.Pack = (int?)customBuilder.GetFieldValue("Pack") ?? 0;
571                         attr.Size = (int?)customBuilder.GetFieldValue("Size") ?? 0;
572                         attr.CharSet = customBuilder.GetFieldValue<CharSet>("CharSet") ?? CharSet.None;
573                         attribs &= ~TypeAttributes.LayoutMask;
574                         switch (attr.Value)
575                         {
576                                 case LayoutKind.Auto:
577                                         attribs |= TypeAttributes.AutoLayout;
578                                         break;
579                                 case LayoutKind.Explicit:
580                                         attribs |= TypeAttributes.ExplicitLayout;
581                                         break;
582                                 case LayoutKind.Sequential:
583                                         attribs |= TypeAttributes.SequentialLayout;
584                                         break;
585                         }
586                         attribs &= ~TypeAttributes.StringFormatMask;
587                         switch (attr.CharSet)
588                         {
589                                 case CharSet.None:
590                                 case CharSet.Ansi:
591                                         attribs |= TypeAttributes.AnsiClass;
592                                         break;
593                                 case CharSet.Auto:
594                                         attribs |= TypeAttributes.AutoClass;
595                                         break;
596                                 case CharSet.Unicode:
597                                         attribs |= TypeAttributes.UnicodeClass;
598                                         break;
599                         }
600                         pack = (short)attr.Pack;
601                         size = attr.Size;
602                         hasLayout = pack != 0 || size != 0;
603                 }
604
605                 public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
606                 {
607                         SetCustomAttribute(new CustomAttributeBuilder(con, binaryAttribute));
608                 }
609
610                 public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
611                 {
612                         Universe u = this.ModuleBuilder.universe;
613                         Type type = customBuilder.Constructor.DeclaringType;
614                         if (type == u.System_Runtime_InteropServices_StructLayoutAttribute)
615                         {
616                                 SetStructLayoutPseudoCustomAttribute(customBuilder.DecodeBlob(this.Assembly));
617                         }
618                         else if (type == u.System_SerializableAttribute)
619                         {
620                                 attribs |= TypeAttributes.Serializable;
621                         }
622                         else if (type == u.System_Runtime_InteropServices_ComImportAttribute)
623                         {
624                                 attribs |= TypeAttributes.Import;
625                         }
626                         else if (type == u.System_Runtime_CompilerServices_SpecialNameAttribute)
627                         {
628                                 attribs |= TypeAttributes.SpecialName;
629                         }
630                         else
631                         {
632                                 if (type == u.System_Security_SuppressUnmanagedCodeSecurityAttribute)
633                                 {
634                                         attribs |= TypeAttributes.HasSecurity;
635                                 }
636                                 this.ModuleBuilder.SetCustomAttribute(token, customBuilder);
637                         }
638                 }
639
640                 public void __AddDeclarativeSecurity(CustomAttributeBuilder customBuilder)
641                 {
642                         attribs |= TypeAttributes.HasSecurity;
643                         if (declarativeSecurity == null)
644                         {
645                                 declarativeSecurity = new List<CustomAttributeBuilder>();
646                         }
647                         declarativeSecurity.Add(customBuilder);
648                 }
649
650                 public void AddDeclarativeSecurity(System.Security.Permissions.SecurityAction securityAction, System.Security.PermissionSet permissionSet)
651                 {
652                         this.ModuleBuilder.AddDeclarativeSecurity(token, securityAction, permissionSet);
653                         this.attribs |= TypeAttributes.HasSecurity;
654                 }
655
656                 public GenericTypeParameterBuilder[] DefineGenericParameters(params string[] names)
657                 {
658                         typeFlags |= TypeFlags.IsGenericTypeDefinition;
659                         gtpb = new GenericTypeParameterBuilder[names.Length];
660                         for (int i = 0; i < names.Length; i++)
661                         {
662                                 gtpb[i] = new GenericTypeParameterBuilder(names[i], this, null, i);
663                         }
664                         return (GenericTypeParameterBuilder[])gtpb.Clone();
665                 }
666
667                 public override Type[] GetGenericArguments()
668                 {
669                         return Util.Copy(gtpb);
670                 }
671
672                 public override CustomModifiers[] __GetGenericArgumentsCustomModifiers()
673                 {
674                         return gtpb == null ? Empty<CustomModifiers>.Array : new CustomModifiers[gtpb.Length];
675                 }
676
677                 internal override Type GetGenericTypeArgument(int index)
678                 {
679                         return gtpb[index];
680                 }
681
682                 public override bool ContainsGenericParameters
683                 {
684                         get { return gtpb != null; }
685                 }
686
687                 public override Type GetGenericTypeDefinition()
688                 {
689                         return this;
690                 }
691
692                 public Type CreateType()
693                 {
694                         if ((typeFlags & TypeFlags.Baked) != 0)
695                         {
696                                 // .NET allows multiple invocations (subsequent invocations return the same baked type)
697                                 throw new NotImplementedException();
698                         }
699                         typeFlags |= TypeFlags.Baked;
700                         if (hasLayout)
701                         {
702                                 ClassLayoutTable.Record rec = new ClassLayoutTable.Record();
703                                 rec.PackingSize = pack;
704                                 rec.ClassSize = size;
705                                 rec.Parent = token;
706                                 this.ModuleBuilder.ClassLayout.AddRecord(rec);
707                         }
708                         foreach (MethodBuilder mb in methods)
709                         {
710                                 mb.Bake();
711                         }
712                         if (declarativeSecurity != null)
713                         {
714                                 this.ModuleBuilder.AddDeclarativeSecurity(token, declarativeSecurity);
715                         }
716                         if (!IsModulePseudoType)
717                         {
718                                 Type baseType = this.BaseType;
719                                 if (baseType != null)
720                                 {
721                                         extends = this.ModuleBuilder.GetTypeToken(baseType).Token;
722                                 }
723                         }
724                         if (interfaces != null)
725                         {
726                                 foreach (Type interfaceType in interfaces)
727                                 {
728                                         InterfaceImplTable.Record rec = new InterfaceImplTable.Record();
729                                         rec.Class = token;
730                                         rec.Interface = this.ModuleBuilder.GetTypeToken(interfaceType).Token;
731                                         this.ModuleBuilder.InterfaceImpl.AddRecord(rec);
732                                 }
733                         }
734                         return new BakedType(this);
735                 }
736
737                 internal void PopulatePropertyAndEventTables()
738                 {
739                         if (properties != null)
740                         {
741                                 PropertyMapTable.Record rec = new PropertyMapTable.Record();
742                                 rec.Parent = token;
743                                 rec.PropertyList = this.ModuleBuilder.Property.RowCount + 1;
744                                 this.ModuleBuilder.PropertyMap.AddRecord(rec);
745                                 foreach (PropertyBuilder pb in properties)
746                                 {
747                                         pb.Bake();
748                                 }
749                         }
750                         if (events != null)
751                         {
752                                 EventMapTable.Record rec = new EventMapTable.Record();
753                                 rec.Parent = token;
754                                 rec.EventList = this.ModuleBuilder.Event.RowCount + 1;
755                                 this.ModuleBuilder.EventMap.AddRecord(rec);
756                                 foreach (EventBuilder eb in events)
757                                 {
758                                         eb.Bake();
759                                 }
760                         }
761                 }
762
763                 public override Type BaseType
764                 {
765                         get
766                         {
767                                 if (lazyBaseType == null && !IsInterface)
768                                 {
769                                         Type obj = Module.universe.System_Object;
770                                         if (this != obj)
771                                         {
772                                                 lazyBaseType = obj;
773                                         }
774                                 }
775                                 return lazyBaseType;
776                         }
777                 }
778
779                 public override string FullName
780                 {
781                         get
782                         {
783                                 if (this.IsNested)
784                                 {
785                                         return this.DeclaringType.FullName + "+" + TypeNameParser.Escape(name);
786                                 }
787                                 if (ns == null)
788                                 {
789                                         return TypeNameParser.Escape(name);
790                                 }
791                                 else
792                                 {
793                                         return TypeNameParser.Escape(ns) + "." + TypeNameParser.Escape(name);
794                                 }
795                         }
796                 }
797
798                 public override string __Name
799                 {
800                         get { return name; }
801                 }
802
803                 public override string __Namespace
804                 {
805                         get { return ns; }
806                 }
807
808                 public override string Name
809                 {
810                         // FXBUG for a TypeBuilder the name is not escaped
811                         get { return name; }
812                 }
813
814                 public override string Namespace
815                 {
816                         get
817                         {
818                                 // for some reason, TypeBuilder doesn't return null (and mcs depends on this)
819                                 // note also that we don't return the declaring type namespace for nested types
820                                 return ns ?? "";
821                         }
822                 }
823
824                 public override TypeAttributes Attributes
825                 {
826                         get { return attribs; }
827                 }
828
829                 public void __SetAttributes(TypeAttributes attributes)
830                 {
831                         this.attribs = attributes;
832                 }
833
834                 public override Type[] __GetDeclaredInterfaces()
835                 {
836                         return Util.ToArray(interfaces, Type.EmptyTypes);
837                 }
838
839                 public override MethodBase[] __GetDeclaredMethods()
840                 {
841                         MethodBase[] methods = new MethodBase[this.methods.Count];
842                         for (int i = 0; i < methods.Length; i++)
843                         {
844                                 MethodBuilder mb = this.methods[i];
845                                 if (mb.IsConstructor)
846                                 {
847                                         methods[i] = new ConstructorInfoImpl(mb);
848                                 }
849                                 else
850                                 {
851                                         methods[i] = mb;
852                                 }
853                         }
854                         return methods;
855                 }
856
857                 public override StructLayoutAttribute StructLayoutAttribute
858                 {
859                         get
860                         {
861                                 LayoutKind layout;
862                                 switch (attribs & TypeAttributes.LayoutMask)
863                                 {
864                                         case TypeAttributes.ExplicitLayout:
865                                                 layout = LayoutKind.Explicit;
866                                                 break;
867                                         case TypeAttributes.SequentialLayout:
868                                                 layout = LayoutKind.Sequential;
869                                                 break;
870                                         default:
871                                                 layout = LayoutKind.Auto;
872                                                 break;
873                                 }
874                                 StructLayoutAttribute attr = new StructLayoutAttribute(layout);
875                                 attr.Pack = (ushort)pack;
876                                 attr.Size = size;
877                                 switch (attribs & TypeAttributes.StringFormatMask)
878                                 {
879                                         case TypeAttributes.AutoClass:
880                                                 attr.CharSet = CharSet.Auto;
881                                                 break;
882                                         case TypeAttributes.UnicodeClass:
883                                                 attr.CharSet = CharSet.Unicode;
884                                                 break;
885                                         case TypeAttributes.AnsiClass:
886                                                 attr.CharSet = CharSet.Ansi;
887                                                 break;
888                                         default:
889                                                 attr.CharSet = CharSet.None;
890                                                 break;
891                                 }
892                                 return attr;
893                         }
894                 }
895
896                 public override Type DeclaringType
897                 {
898                         get { return owner as TypeBuilder; }
899                 }
900
901                 public override bool IsGenericType
902                 {
903                         get { return IsGenericTypeDefinition; }
904                 }
905
906                 public override bool IsGenericTypeDefinition
907                 {
908                         get { return (typeFlags & TypeFlags.IsGenericTypeDefinition) != 0; }
909                 }
910
911                 public override int MetadataToken
912                 {
913                         get { return token; }
914                 }
915
916                 public FieldBuilder DefineUninitializedData(string name, int size, FieldAttributes attributes)
917                 {
918                         return DefineInitializedData(name, new byte[size], attributes);
919                 }
920
921                 public FieldBuilder DefineInitializedData(string name, byte[] data, FieldAttributes attributes)
922                 {
923                         Type fieldType = this.ModuleBuilder.GetType("$ArrayType$" + data.Length);
924                         if (fieldType == null)
925                         {
926                                 TypeBuilder tb = this.ModuleBuilder.DefineType("$ArrayType$" + data.Length, TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.ExplicitLayout, this.Module.universe.System_ValueType, PackingSize.Size1, data.Length);
927                                 tb.CreateType();
928                                 fieldType = tb;
929                         }
930                         FieldBuilder fb = DefineField(name, fieldType, attributes | FieldAttributes.Static);
931                         fb.__SetDataAndRVA(data);
932                         return fb;
933                 }
934
935                 public static MethodInfo GetMethod(Type type, MethodInfo method)
936                 {
937                         return new GenericMethodInstance(type, method, null);
938                 }
939
940                 public static ConstructorInfo GetConstructor(Type type, ConstructorInfo constructor)
941                 {
942                         return new ConstructorInfoImpl(GetMethod(type, constructor.GetMethodInfo()));
943                 }
944
945                 public static FieldInfo GetField(Type type, FieldInfo field)
946                 {
947                         return new GenericFieldInstance(type, field);
948                 }
949
950                 public override Module Module
951                 {
952                         get { return owner.ModuleBuilder; }
953                 }
954
955                 public TypeToken TypeToken
956                 {
957                         get { return new TypeToken(token); }
958                 }
959
960                 internal void WriteTypeDefRecord(MetadataWriter mw, ref int fieldList, ref int methodList)
961                 {
962                         mw.Write((int)attribs);
963                         mw.WriteStringIndex(typeName);
964                         mw.WriteStringIndex(typeNameSpace);
965                         mw.WriteTypeDefOrRef(extends);
966                         mw.WriteField(fieldList);
967                         mw.WriteMethodDef(methodList);
968                         methodList += methods.Count;
969                         fieldList += fields.Count;
970                 }
971
972                 internal void WriteMethodDefRecords(int baseRVA, MetadataWriter mw, ref int paramList)
973                 {
974                         foreach (MethodBuilder mb in methods)
975                         {
976                                 mb.WriteMethodDefRecord(baseRVA, mw, ref paramList);
977                         }
978                 }
979
980                 internal void ResolveMethodAndFieldTokens(ref int methodToken, ref int fieldToken, ref int parameterToken)
981                 {
982                         foreach (MethodBuilder method in methods)
983                         {
984                                 method.FixupToken(methodToken++, ref parameterToken);
985                         }
986                         foreach (FieldBuilder field in fields)
987                         {
988                                 field.FixupToken(fieldToken++);
989                         }
990                 }
991
992                 internal void WriteParamRecords(MetadataWriter mw)
993                 {
994                         foreach (MethodBuilder mb in methods)
995                         {
996                                 mb.WriteParamRecords(mw);
997                         }
998                 }
999
1000                 internal void WriteFieldRecords(MetadataWriter mw)
1001                 {
1002                         foreach (FieldBuilder fb in fields)
1003                         {
1004                                 fb.WriteFieldRecords(mw);
1005                         }
1006                 }
1007
1008                 internal ModuleBuilder ModuleBuilder
1009                 {
1010                         get { return owner.ModuleBuilder; }
1011                 }
1012
1013                 ModuleBuilder ITypeOwner.ModuleBuilder
1014                 {
1015                         get { return owner.ModuleBuilder; }
1016                 }
1017
1018                 internal override int GetModuleBuilderToken()
1019                 {
1020                         return token;
1021                 }
1022
1023                 internal bool HasNestedTypes
1024                 {
1025                         get { return (typeFlags & TypeFlags.HasNestedTypes) != 0; }
1026                 }
1027
1028                 // helper for ModuleBuilder.ResolveMethod()
1029                 internal MethodBase LookupMethod(int token)
1030                 {
1031                         foreach (MethodBuilder method in methods)
1032                         {
1033                                 if (method.MetadataToken == token)
1034                                 {
1035                                         return method;
1036                                 }
1037                         }
1038                         return null;
1039                 }
1040
1041                 public bool IsCreated()
1042                 {
1043                         return (typeFlags & TypeFlags.Baked) != 0;
1044                 }
1045
1046                 internal override void CheckBaked()
1047                 {
1048                         if ((typeFlags & TypeFlags.Baked) == 0)
1049                         {
1050                                 throw new NotSupportedException();
1051                         }
1052                 }
1053
1054                 public override Type[] __GetDeclaredTypes()
1055                 {
1056                         if (this.HasNestedTypes)
1057                         {
1058                                 List<Type> types = new List<Type>();
1059                                 List<int> classes = this.ModuleBuilder.NestedClass.GetNestedClasses(token);
1060                                 foreach (int nestedClass in classes)
1061                                 {
1062                                         types.Add(this.ModuleBuilder.ResolveType(nestedClass));
1063                                 }
1064                                 return types.ToArray();
1065                         }
1066                         else
1067                         {
1068                                 return Type.EmptyTypes;
1069                         }
1070                 }
1071
1072                 public override FieldInfo[] __GetDeclaredFields()
1073                 {
1074                         return Util.ToArray(fields, Empty<FieldInfo>.Array);
1075                 }
1076
1077                 public override EventInfo[] __GetDeclaredEvents()
1078                 {
1079                         return Util.ToArray(events, Empty<EventInfo>.Array);
1080                 }
1081
1082                 public override PropertyInfo[] __GetDeclaredProperties()
1083                 {
1084                         return Util.ToArray(properties, Empty<PropertyInfo>.Array);
1085                 }
1086
1087                 internal override bool IsModulePseudoType
1088                 {
1089                         get { return token == 0x02000001; }
1090                 }
1091
1092                 internal override bool IsBaked
1093                 {
1094                         get { return IsCreated(); }
1095                 }
1096         }
1097
1098         sealed class BakedType : Type
1099         {
1100                 internal BakedType(TypeBuilder typeBuilder)
1101                         : base(typeBuilder)
1102                 {
1103                 }
1104
1105                 public override string AssemblyQualifiedName
1106                 {
1107                         get { return underlyingType.AssemblyQualifiedName; }
1108                 }
1109
1110                 public override Type BaseType
1111                 {
1112                         get { return underlyingType.BaseType; }
1113                 }
1114
1115                 public override string __Name
1116                 {
1117                         get { return underlyingType.__Name; }
1118                 }
1119
1120                 public override string __Namespace
1121                 {
1122                         get { return underlyingType.__Namespace; }
1123                 }
1124
1125                 public override string Name
1126                 {
1127                         // we need to escape here, because TypeBuilder.Name does not escape
1128                         get { return TypeNameParser.Escape(underlyingType.__Name); }
1129                 }
1130
1131                 public override string FullName
1132                 {
1133                         get { return GetFullName(); }
1134                 }
1135
1136                 public override TypeAttributes Attributes
1137                 {
1138                         get { return underlyingType.Attributes; }
1139                 }
1140
1141                 public override Type[] __GetDeclaredInterfaces()
1142                 {
1143                         return underlyingType.__GetDeclaredInterfaces();
1144                 }
1145
1146                 public override MethodBase[] __GetDeclaredMethods()
1147                 {
1148                         return underlyingType.__GetDeclaredMethods();
1149                 }
1150
1151                 public override __MethodImplMap __GetMethodImplMap()
1152                 {
1153                         return underlyingType.__GetMethodImplMap();
1154                 }
1155
1156                 public override FieldInfo[] __GetDeclaredFields()
1157                 {
1158                         return underlyingType.__GetDeclaredFields();
1159                 }
1160
1161                 public override EventInfo[] __GetDeclaredEvents()
1162                 {
1163                         return underlyingType.__GetDeclaredEvents();
1164                 }
1165
1166                 public override PropertyInfo[] __GetDeclaredProperties()
1167                 {
1168                         return underlyingType.__GetDeclaredProperties();
1169                 }
1170
1171                 public override Type[] __GetDeclaredTypes()
1172                 {
1173                         return underlyingType.__GetDeclaredTypes();
1174                 }
1175
1176                 public override Type DeclaringType
1177                 {
1178                         get { return underlyingType.DeclaringType; }
1179                 }
1180
1181                 public override StructLayoutAttribute StructLayoutAttribute
1182                 {
1183                         get { return underlyingType.StructLayoutAttribute; }
1184                 }
1185
1186                 public override Type[] GetGenericArguments()
1187                 {
1188                         return underlyingType.GetGenericArguments();
1189                 }
1190
1191                 internal override Type GetGenericTypeArgument(int index)
1192                 {
1193                         return underlyingType.GetGenericTypeArgument(index);
1194                 }
1195
1196                 public override CustomModifiers[] __GetGenericArgumentsCustomModifiers()
1197                 {
1198                         return underlyingType.__GetGenericArgumentsCustomModifiers();
1199                 }
1200
1201                 public override bool IsGenericType
1202                 {
1203                         get { return underlyingType.IsGenericType; }
1204                 }
1205
1206                 public override bool IsGenericTypeDefinition
1207                 {
1208                         get { return underlyingType.IsGenericTypeDefinition; }
1209                 }
1210
1211                 public override bool ContainsGenericParameters
1212                 {
1213                         get { return underlyingType.ContainsGenericParameters; }
1214                 }
1215
1216                 public override int MetadataToken
1217                 {
1218                         get { return underlyingType.MetadataToken; }
1219                 }
1220
1221                 public override Module Module
1222                 {
1223                         get { return underlyingType.Module; }
1224                 }
1225
1226                 internal override int GetModuleBuilderToken()
1227                 {
1228                         return underlyingType.GetModuleBuilderToken();
1229                 }
1230
1231                 internal override bool IsBaked
1232                 {
1233                         get { return true; }
1234                 }
1235         }
1236 }