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