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