Fixme fixme fixme.
[mono.git] / mcs / gmcs / rootcontext.cs
1 //
2 // rootcontext.cs: keeps track of our tree representation, and assemblies loaded.
3 //
4 // Author: Miguel de Icaza (miguel@ximian.com)
5 //         Ravi Pratap     (ravi@ximian.com)
6 //
7 // Licensed under the terms of the GNU GPL
8 //
9 // (C) 2001 Ximian, Inc (http://www.ximian.com)
10
11 using System;
12 using System.Collections;
13 using System.Reflection;
14 using System.Reflection.Emit;
15 using System.Diagnostics;
16
17 namespace Mono.CSharp {
18
19         public class RootContext {
20
21                 //
22                 // Contains the parsed tree
23                 //
24                 static Tree tree;
25
26                 //
27                 // This hashtable contains all of the #definitions across the source code
28                 // it is used by the ConditionalAttribute handler.
29                 //
30                 public static Hashtable AllDefines = new Hashtable ();
31                 
32                 //
33                 // Whether we are being linked against the standard libraries.
34                 // This is only used to tell whether `System.Object' should
35                 // have a parent or not.
36                 //
37                 public static bool StdLib = true;
38
39                 //
40                 // This keeps track of the order in which classes were defined
41                 // so that we can poulate them in that order.
42                 //
43                 // Order is important, because we need to be able to tell by
44                 // examining the parent's list of methods which ones are virtual
45                 // or abstract as well as the parent names (to implement new, 
46                 // override).
47                 //
48                 static ArrayList type_container_resolve_order;
49                 static ArrayList attribute_types;
50
51                 //
52                 // Holds a reference to the Private Implementation Details
53                 // class.
54                 //
55                 static ArrayList helper_classes;
56                 
57                 static TypeBuilder impl_details_class;
58
59                 public static int WarningLevel = 2;
60
61                 public static Target Target = Target.Exe;
62                 public static string TargetExt = ".exe";
63
64                 public static bool VerifyClsCompliance = true;
65
66                 //
67                 // If set, enable C# version 2 features
68                 //
69                 public static bool V2 = true;
70
71                 //
72                 // We keep strongname related info here because
73                 // it's also used as complier options from CSC 8.x
74                 //
75                 public static string StrongNameKeyFile;
76                 public static string StrongNameKeyContainer;
77                 public static bool StrongNameDelaySign = false;
78
79                 //
80                 // Constructor
81                 //
82                 static RootContext ()
83                 {
84                         tree = new Tree ();
85                         type_container_resolve_order = new ArrayList ();
86                 }
87
88                 public static bool NeedsEntryPoint {
89                         get {
90                                 return RootContext.Target == Target.Exe || RootContext.Target == Target.WinExe;
91                         }
92                 }
93
94                 static public Tree Tree {
95                         get {
96                                 return tree;
97                         }
98                 }
99
100                 static public string MainClass;
101                 
102                 public static void RegisterOrder (TypeContainer tc)
103                 {
104                         type_container_resolve_order.Add (tc);
105                 }
106
107                 public static void RegisterAttribute (TypeContainer tc)
108                 {
109                         if (attribute_types == null)
110                                 attribute_types = new ArrayList ();
111                         
112                         attribute_types.Add (tc);
113                 }
114                 
115                 // 
116                 // The default compiler checked state
117                 //
118                 static public bool Checked = false;
119
120                 //
121                 // Whether to allow Unsafe code
122                 //
123                 static public bool Unsafe = false;
124                 
125                 static string MakeFQN (string nsn, string name)
126                 {
127                         if (nsn == "")
128                                 return name;
129                         return String.Concat (nsn, ".", name);
130                 }
131
132                 // <remarks>
133                 //   This function is used to resolve the hierarchy tree.
134                 //   It processes interfaces, structs and classes in that order.
135                 //
136                 //   It creates the TypeBuilder's as it processes the user defined
137                 //   types.  
138                 // </remarks>
139                 static public void ResolveTree ()
140                 {
141                         //
142                         // Process the attribute types separately and before anything else
143                         //
144                         if (attribute_types != null)
145                                 foreach (TypeContainer tc in attribute_types)
146                                         tc.DefineType ();
147                         
148                         //
149                         // Interfaces are processed next, as classes and
150                         // structs might inherit from an object or implement
151                         // a set of interfaces, we need to be able to tell
152                         // them appart by just using the TypeManager.
153                         //
154                         TypeContainer root = Tree.Types;
155
156                         ArrayList ifaces = root.Interfaces;
157                         if (ifaces != null){
158                                 foreach (Interface i in ifaces) 
159                                         i.DefineType ();
160                         }
161
162                         foreach (TypeContainer tc in root.Types)
163                                 tc.DefineType ();
164
165                         if (root.Delegates != null)
166                                 foreach (Delegate d in root.Delegates) 
167                                         d.DefineType ();
168
169                         if (root.Enums != null)
170                                 foreach (Enum e in root.Enums)
171                                         e.DefineType ();
172                 }
173
174                 static void Error_TypeConflict (string name, Location loc)
175                 {
176                         Report.Error (
177                                 520, loc, "`" + name + "' conflicts with a predefined type");
178                 }
179
180                 static void Error_TypeConflict (string name)
181                 {
182                         Report.Error (
183                                 520, "`" + name + "' conflicts with a predefined type");
184                 }
185
186                 //
187                 // Resolves a single class during the corlib bootstrap process
188                 //
189                 static TypeBuilder BootstrapCorlib_ResolveClass (TypeContainer root, string name)
190                 {
191                         object o = root.GetDefinition (name);
192                         if (o == null){
193                                 Report.Error (518, "The predefined type `" + name + "' is not defined");
194                                 return null;
195                         }
196
197                         if (!(o is Class)){
198                                 if (o is DeclSpace){
199                                         DeclSpace d = (DeclSpace) o;
200
201                                         Error_TypeConflict (name, d.Location);
202                                 } else
203                                         Error_TypeConflict (name);
204
205                                 return null;
206                         }
207
208                         return ((DeclSpace) o).DefineType ();
209                 }
210
211                 //
212                 // Resolves a struct during the corlib bootstrap process
213                 //
214                 static void BootstrapCorlib_ResolveStruct (TypeContainer root, string name)
215                 {
216                         object o = root.GetDefinition (name);
217                         if (o == null){
218                                 Report.Error (518, "The predefined type `" + name + "' is not defined");
219                                 return;
220                         }
221
222                         if (!(o is Struct)){
223                                 if (o is DeclSpace){
224                                         DeclSpace d = (DeclSpace) o;
225
226                                         Error_TypeConflict (name, d.Location);
227                                 } else
228                                         Error_TypeConflict (name);
229
230                                 return;
231                         }
232
233                         ((DeclSpace) o).DefineType ();
234                 }
235
236                 //
237                 // Resolves a struct during the corlib bootstrap process
238                 //
239                 static void BootstrapCorlib_ResolveInterface (TypeContainer root, string name)
240                 {
241                         object o = root.GetDefinition (name);
242                         if (o == null){
243                                 Report.Error (518, "The predefined type `" + name + "' is not defined");
244                                 return;
245                         }
246
247                         if (!(o is Interface)){
248                                 if (o is DeclSpace){
249                                         DeclSpace d = (DeclSpace) o;
250
251                                         Error_TypeConflict (name, d.Location);
252                                 } else
253                                         Error_TypeConflict (name);
254
255                                 return;
256                         }
257
258                         ((DeclSpace) o).DefineType ();
259                 }
260
261                 //
262                 // Resolves a delegate during the corlib bootstrap process
263                 //
264                 static void BootstrapCorlib_ResolveDelegate (TypeContainer root, string name)
265                 {
266                         object o = root.GetDefinition (name);
267                         if (o == null){
268                                 Report.Error (518, "The predefined type `" + name + "' is not defined");
269                                 Environment.Exit (1);
270                         }
271
272                         if (!(o is Delegate)){
273                                 Error_TypeConflict (name);
274                                 return;
275                         }
276
277                         ((DeclSpace) o).DefineType ();
278                 }
279                 
280
281                 /// <summary>
282                 ///    Resolves the core types in the compiler when compiling with --nostdlib
283                 /// </summary>
284                 static public void ResolveCore ()
285                 {
286                         TypeContainer root = Tree.Types;
287
288                         TypeManager.object_type = BootstrapCorlib_ResolveClass (root, "System.Object");
289                         TypeManager.value_type = BootstrapCorlib_ResolveClass (root, "System.ValueType");
290                         TypeManager.attribute_type = BootstrapCorlib_ResolveClass (root, "System.Attribute");
291                         
292                         string [] interfaces_first_stage = {
293                                 "System.IComparable", "System.ICloneable",
294                                 "System.IConvertible",
295                                 
296                                 "System.Collections.IEnumerable",
297                                 "System.Collections.ICollection",
298                                 "System.Collections.IEnumerator",
299                                 "System.Collections.IList", 
300                                 "System.IAsyncResult",
301                                 "System.IDisposable",
302                                 
303                                 "System.Runtime.Serialization.ISerializable",
304
305                                 "System.Reflection.IReflect",
306                                 "System.Reflection.ICustomAttributeProvider",
307
308                                 //
309                                 // Generic types
310                                 //
311                                 "System.Collections.Generic.IEnumerator`1",
312                                 "System.Collections.Generic.IEnumerable`1"
313                         };
314
315                         foreach (string iname in interfaces_first_stage)
316                                 BootstrapCorlib_ResolveInterface (root, iname);
317
318                         //
319                         // These are the base value types
320                         //
321                         string [] structs_first_stage = {
322                                 "System.Byte",    "System.SByte",
323                                 "System.Int16",   "System.UInt16",
324                                 "System.Int32",   "System.UInt32",
325                                 "System.Int64",   "System.UInt64",
326                         };
327
328                         foreach (string cname in structs_first_stage)
329                                 BootstrapCorlib_ResolveStruct (root, cname);
330
331                         //
332                         // Now, we can load the enumerations, after this point,
333                         // we can use enums.
334                         //
335                         TypeManager.InitEnumUnderlyingTypes ();
336
337                         string [] structs_second_stage = {
338                                 "System.Single",  "System.Double",
339                                 "System.Char",    "System.Boolean",
340                                 "System.Decimal", "System.Void",
341                                 "System.RuntimeFieldHandle",
342                                 "System.RuntimeArgumentHandle",
343                                 "System.RuntimeTypeHandle",
344                                 "System.IntPtr",
345                                 "System.TypedReference",
346                                 "System.ArgIterator"
347                         };
348                         
349                         foreach (string cname in structs_second_stage)
350                                 BootstrapCorlib_ResolveStruct (root, cname);
351                         
352                         //
353                         // These are classes that depends on the core interfaces
354                         //
355                         string [] classes_second_stage = {
356                                 "System.Reflection.MemberInfo",
357                                 "System.Type",
358                                 "System.Exception",
359                                 "System.Activator",
360
361                                 //
362                                 // These are not really important in the order, but they
363                                 // are used by the compiler later on (typemanager/CoreLookupType-d)
364                                 //
365                                 "System.Runtime.CompilerServices.RuntimeHelpers",
366                                 "System.Reflection.DefaultMemberAttribute",
367                                 "System.Threading.Monitor",
368                                 
369                                 "System.AttributeUsageAttribute",
370                                 "System.Runtime.InteropServices.DllImportAttribute",
371                                 "System.Runtime.CompilerServices.MethodImplAttribute",
372                                 "System.Runtime.InteropServices.MarshalAsAttribute",
373                                 "System.Runtime.CompilerServices.NewConstraintAttribute",
374                                 "System.Diagnostics.ConditionalAttribute",
375                                 "System.ObsoleteAttribute",
376                                 "System.ParamArrayAttribute",
377                                 "System.CLSCompliantAttribute",
378                                 "System.Security.UnverifiableCodeAttribute",
379                                 "System.Runtime.CompilerServices.IndexerNameAttribute",
380                                 "System.Runtime.InteropServices.InAttribute",
381                                 "System.Runtime.InteropServices.StructLayoutAttribute",
382                                 "System.Runtime.InteropServices.FieldOffsetAttribute",
383                                 "System.InvalidOperationException",
384                                 "System.NotSupportedException",
385                                 "System.MarshalByRefObject"
386                         };
387
388                         // We must store them here before calling BootstrapCorlib_ResolveDelegate.
389                         TypeManager.string_type = BootstrapCorlib_ResolveClass (root, "System.String");
390                         TypeManager.enum_type = BootstrapCorlib_ResolveClass (root, "System.Enum");
391                         TypeManager.array_type = BootstrapCorlib_ResolveClass (root, "System.Array");
392                         TypeManager.multicast_delegate_type = BootstrapCorlib_ResolveClass (root, "System.MulticastDelegate");
393                         TypeManager.delegate_type = BootstrapCorlib_ResolveClass (root, "System.Delegate");
394                         
395                         foreach (string cname in classes_second_stage)
396                                 BootstrapCorlib_ResolveClass (root, cname);
397
398                         BootstrapCorlib_ResolveDelegate (root, "System.AsyncCallback");
399                 }
400                         
401                 // <summary>
402                 //   Closes all open types
403                 // </summary>
404                 //
405                 // <remarks>
406                 //   We usually use TypeBuilder types.  When we are done
407                 //   creating the type (which will happen after we have added
408                 //   methods, fields, etc) we need to "Define" them before we
409                 //   can save the Assembly
410                 // </remarks>
411                 static public void CloseTypes ()
412                 {
413                         TypeContainer root = Tree.Types;
414                         
415                         if (root.Enums != null)
416                                 foreach (Enum en in root.Enums)
417                                         en.CloseType ();
418
419                         if (attribute_types != null)
420                                 foreach (TypeContainer tc in attribute_types)
421                                         tc.CloseType ();
422                         
423                         //
424                         // We do this in two passes, first we close the structs,
425                         // then the classes, because it seems the code needs it this
426                         // way.  If this is really what is going on, we should probably
427                         // make sure that we define the structs in order as well.
428                         //
429                         foreach (TypeContainer tc in type_container_resolve_order){
430                                 if (tc.Kind == Kind.Struct && tc.Parent == tree.Types){
431                                         tc.CloseType ();
432                                 }
433                         }
434
435                         foreach (TypeContainer tc in type_container_resolve_order){
436                                 if (!(tc.Kind == Kind.Struct && tc.Parent == tree.Types))
437                                         tc.CloseType ();                                        
438                         }
439                         
440                         if (root.Delegates != null)
441                                 foreach (Delegate d in root.Delegates)
442                                         d.CloseType ();
443
444
445                         //
446                         // If we have a <PrivateImplementationDetails> class, close it
447                         //
448                         if (helper_classes != null){
449                                 foreach (TypeBuilder type_builder in helper_classes)
450                                         type_builder.CreateType ();
451                         }
452                         
453                         attribute_types = null;
454                         type_container_resolve_order = null;
455                         helper_classes = null;
456                         //tree = null;
457                         TypeManager.CleanUp ();
458                 }
459
460                 /// <summary>
461                 ///   Used to register classes that need to be closed after all the
462                 ///   user defined classes
463                 /// </summary>
464                 public static void RegisterHelperClass (TypeBuilder helper_class)
465                 {
466                         if (helper_classes == null)
467                                 helper_classes = new ArrayList ();
468                         helper_classes.Add (helper_class);
469                 }
470                 
471                 //
472                 // This idea is from Felix Arrese-Igor
473                 //
474                 // Returns : the implicit parent of a composite namespace string
475                 //   eg. Implicit parent of A.B is A
476                 //
477                 static public string ImplicitParent (string ns)
478                 {
479                         int i = ns.LastIndexOf ('.');
480                         if (i < 0)
481                                 return null;
482                         
483                         return ns.Substring (0, i);
484                 }
485
486                 static TypeExpr NamespaceLookup (DeclSpace ds, string name,
487                                                  int num_type_args, bool silent, Location loc)
488                 {
489                         //
490                         // Try in the current namespace and all its implicit parents
491                         //
492                         for (NamespaceEntry ns = ds.NamespaceEntry; ns != null; ns = ns.ImplicitParent) {
493                                 IAlias result = ns.Lookup (ds, name, num_type_args, silent, loc);
494
495                                 if (result == null)
496                                         continue;
497
498                                 if (!result.IsType)
499                                         return null;
500
501                                 return result.Type;
502                         }
503
504                         return null;
505                 }
506                 
507                 static public TypeExpr LookupType (DeclSpace ds, string name, bool silent,
508                                                    Location loc)
509                 {
510                         return LookupType (ds, name, silent, 0, loc);
511                 }
512
513                 //
514                 // Public function used to locate types, this can only
515                 // be used after the ResolveTree function has been invoked.
516                 //
517                 // Returns: Type or null if they type can not be found.
518                 //
519                 // Come to think of it, this should be a DeclSpace
520                 //
521                 static public TypeExpr LookupType (DeclSpace ds, string name, bool silent,
522                                                    int num_type_params, Location loc)
523                 {
524                         TypeExpr t;
525
526                         if (ds.Cache.Contains (name)){
527                                 t = (TypeExpr) ds.Cache [name];
528                                 if (t != null)
529                                         return t;
530                         } else {
531                                 //
532                                 // For the case the type we are looking for is nested within this one
533                                 // or is in any base class
534                                 //
535                                 DeclSpace containing_ds = ds;
536                                 while (containing_ds != null){
537                                         Type current_type = containing_ds.TypeBuilder;
538                                         
539                                         while (current_type != null) {
540                                                 //
541                                                 // nested class
542                                                 //
543                                                 Type type = TypeManager.LookupType (current_type.FullName + "." + name);
544                                                 if (type != null){
545                                                         t = new TypeExpression (type, loc);
546                                                         ds.Cache [name] = t;
547                                                         return t;
548                                                 }
549                                                 
550                                                 current_type = current_type.BaseType;
551                                         }
552                                         
553                                         containing_ds = containing_ds.Parent;
554                                 }
555                                 
556                                 t = NamespaceLookup (ds, name, num_type_params, silent, loc);
557                                 if (t != null){
558                                         ds.Cache [name] = t;
559                                         return t;
560                                 }
561                         }
562
563                         if (!silent)
564                                 Report.Error (246, loc, "Cannot find type `"+name+"'");
565                         
566                         return null;
567                 }
568
569                 // <summary>
570                 //   This is the silent version of LookupType, you can use this
571                 //   to `probe' for a type
572                 // </summary>
573                 static public TypeExpr LookupType (TypeContainer tc, string name, Location loc)
574                 {
575                         return LookupType (tc, name, true, loc);
576                 }
577
578                 static void Report1530 (Location loc)
579                 {
580                         Report.Error (1530, loc, "Keyword new not allowed for namespace elements");
581                 }
582                 
583                 static public void PopulateCoreType (TypeContainer root, string name)
584                 {
585                         DeclSpace ds = (DeclSpace) root.GetDefinition (name);
586
587                         ds.DefineMembers (root);
588                         ds.Define ();
589                 }
590                 
591                 static public void BootCorlib_PopulateCoreTypes ()
592                 {
593                         TypeContainer root = tree.Types;
594
595                         PopulateCoreType (root, "System.Object");
596                         PopulateCoreType (root, "System.ValueType");
597                         PopulateCoreType (root, "System.Attribute");
598                 }
599                 
600                 // <summary>
601                 //   Populates the structs and classes with fields and methods
602                 // </summary>
603                 //
604                 // This is invoked after all interfaces, structs and classes
605                 // have been defined through `ResolveTree' 
606                 static public void PopulateTypes ()
607                 {
608                         TypeContainer root = Tree.Types;
609
610                         if (attribute_types != null)
611                                 foreach (TypeContainer tc in attribute_types)
612                                         tc.DefineMembers (root);
613
614                         if (type_container_resolve_order != null){
615                                 if (RootContext.StdLib){
616                                         foreach (TypeContainer tc in type_container_resolve_order)
617                                                 tc.DefineMembers (root);
618                                 } else {
619                                         foreach (TypeContainer tc in type_container_resolve_order) {
620                                                 // When compiling corlib, these types have already been
621                                                 // populated from BootCorlib_PopulateCoreTypes ().
622                                                 if (((tc.Name == "System.Object") ||
623                                                      (tc.Name == "System.Attribute") ||
624                                                      (tc.Name == "System.ValueType")))
625                                                 continue;
626
627                                                 tc.DefineMembers (root);
628                                         }
629                                 } 
630                         }
631
632                         ArrayList delegates = root.Delegates;
633                         if (delegates != null){
634                                 foreach (Delegate d in delegates)
635                                         if ((d.ModFlags & Modifiers.NEW) == 0)
636                                                 d.DefineMembers (root);
637                                         else
638                                                 Report1530 (d.Location);
639                         }
640
641                         ArrayList enums = root.Enums;
642                         if (enums != null){
643                                 foreach (Enum en in enums)
644                                         if ((en.ModFlags & Modifiers.NEW) == 0)
645                                                 en.DefineMembers (root);
646                                         else
647                                                 Report1530 (en.Location);
648                         }
649
650                         //
651                         // Check for cycles in the struct layout
652                         //
653                         if (type_container_resolve_order != null){
654                                 Hashtable seen = new Hashtable ();
655                                 foreach (TypeContainer tc in type_container_resolve_order)
656                                         TypeManager.CheckStructCycles (tc, seen);
657                         }
658                 }
659
660                 //
661                 // A generic hook delegate
662                 //
663                 public delegate void Hook ();
664
665                 //
666                 // A hook invoked when the code has been generated.
667                 //
668                 public static event Hook EmitCodeHook;
669
670                 //
671                 // DefineTypes is used to fill in the members of each type.
672                 //
673                 static public void DefineTypes ()
674                 {
675                         TypeContainer root = Tree.Types;
676
677                         if (attribute_types != null)
678                                 foreach (TypeContainer tc in attribute_types)
679                                         tc.Define ();
680
681                         if (type_container_resolve_order != null){
682                                 foreach (TypeContainer tc in type_container_resolve_order) {
683                                         // When compiling corlib, these types have already been
684                                         // populated from BootCorlib_PopulateCoreTypes ().
685                                         if (!RootContext.StdLib &&
686                                             ((tc.Name == "System.Object") ||
687                                              (tc.Name == "System.Attribute") ||
688                                              (tc.Name == "System.ValueType")))
689                                                 continue;
690
691                                         if ((tc.ModFlags & Modifiers.NEW) == 0)
692                                                 tc.Define ();
693                                 }
694                         }
695
696                         ArrayList delegates = root.Delegates;
697                         if (delegates != null){
698                                 foreach (Delegate d in delegates)
699                                         if ((d.ModFlags & Modifiers.NEW) == 0)
700                                                 d.Define ();
701                         }
702
703                         ArrayList enums = root.Enums;
704                         if (enums != null){
705                                 foreach (Enum en in enums)
706                                         if ((en.ModFlags & Modifiers.NEW) == 0)
707                                                 en.Define ();
708                         }
709                 }
710
711                 static public void EmitCode ()
712                 {
713                         if (attribute_types != null)
714                                 foreach (TypeContainer tc in attribute_types)
715                                         tc.EmitType ();
716
717                         CodeGen.Assembly.Emit (Tree.Types);
718                         CodeGen.Module.Emit (Tree.Types);
719                         
720                         if (Tree.Types.Enums != null) {
721                                 foreach (Enum e in Tree.Types.Enums)
722                                         e.Emit ();
723                         }
724
725                         if (type_container_resolve_order != null) {
726                                 foreach (TypeContainer tc in type_container_resolve_order)
727                                         tc.EmitConstants ();
728                                 
729                                 foreach (TypeContainer tc in type_container_resolve_order)
730                                         tc.EmitType ();
731                         }
732                         
733                         if (Tree.Types.Delegates != null) {
734                                 foreach (Delegate d in Tree.Types.Delegates)
735                                         d.Emit ();
736                         }                       
737                         //
738                         // Run any hooks after all the types have been defined.
739                         // This is used to create nested auxiliary classes for example
740                         //
741
742                         if (EmitCodeHook != null)
743                                 EmitCodeHook ();
744                 }
745                 
746                 //
747                 // Public Field, used to track which method is the public entry
748                 // point.
749                 //
750                 static public MethodInfo EntryPoint;
751
752                 //
753                 // Track the location of the entry point.
754                 //
755                 static public Location EntryPointLocation;
756
757                 //
758                 // These are used to generate unique names on the structs and fields.
759                 //
760                 static int field_count;
761                 
762                 //
763                 // Makes an initialized struct, returns the field builder that
764                 // references the data.  Thanks go to Sergey Chaban for researching
765                 // how to do this.  And coming up with a shorter mechanism than I
766                 // was able to figure out.
767                 //
768                 // This works but makes an implicit public struct $ArrayType$SIZE and
769                 // makes the fields point to it.  We could get more control if we did
770                 // use instead:
771                 //
772                 // 1. DefineNestedType on the impl_details_class with our struct.
773                 //
774                 // 2. Define the field on the impl_details_class
775                 //
776                 static public FieldBuilder MakeStaticData (byte [] data)
777                 {
778                         FieldBuilder fb;
779                         
780                         if (impl_details_class == null){
781                                 impl_details_class = CodeGen.Module.Builder.DefineType (
782                                         "<PrivateImplementationDetails>",
783                                         TypeAttributes.NotPublic,
784                                         TypeManager.object_type);
785                                 
786                                 RegisterHelperClass (impl_details_class);
787                         }
788
789                         fb = impl_details_class.DefineInitializedData (
790                                 "$$field-" + (field_count++), data,
791                                 FieldAttributes.Static | FieldAttributes.Assembly);
792                         
793                         return fb;
794                 }
795         }
796 }
797               
798