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