[xbuild] Fix bug #674337.
[mono.git] / mcs / mcs / typemanager.cs
1 //
2 // typemanager.cs: C# type manager
3 //
4 // Author: Miguel de Icaza (miguel@gnu.org)
5 //         Ravi Pratap     (ravi@ximian.com)
6 //         Marek Safar     (marek.safar@seznam.cz)
7 //
8 // Dual licensed under the terms of the MIT X11 or GNU GPL
9 //
10 // Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
11 // Copyright 2003-2008 Novell, Inc.
12 //
13
14 using System;
15 using System.Globalization;
16 using System.Collections.Generic;
17 using System.Text;
18
19 namespace Mono.CSharp
20 {
21         //
22         // All compiler build-in types (they have to exist otherwise the compile will not work)
23         //
24         public class BuildinTypes
25         {
26                 public readonly BuildinTypeSpec Object;
27                 public readonly BuildinTypeSpec ValueType;
28                 public readonly BuildinTypeSpec Attribute;
29
30                 public readonly BuildinTypeSpec Int;
31                 public readonly BuildinTypeSpec UInt;
32                 public readonly BuildinTypeSpec Long;
33                 public readonly BuildinTypeSpec ULong;
34                 public readonly BuildinTypeSpec Float;
35                 public readonly BuildinTypeSpec Double;
36                 public readonly BuildinTypeSpec Char;
37                 public readonly BuildinTypeSpec Short;
38                 public readonly BuildinTypeSpec Decimal;
39                 public readonly BuildinTypeSpec Bool;
40                 public readonly BuildinTypeSpec SByte;
41                 public readonly BuildinTypeSpec Byte;
42                 public readonly BuildinTypeSpec UShort;
43                 public readonly BuildinTypeSpec String;
44
45                 public readonly BuildinTypeSpec Enum;
46                 public readonly BuildinTypeSpec Delegate;
47                 public readonly BuildinTypeSpec MulticastDelegate;
48                 public readonly BuildinTypeSpec Void;
49                 public readonly BuildinTypeSpec Array;
50                 public readonly BuildinTypeSpec Type;
51                 public readonly BuildinTypeSpec IEnumerator;
52                 public readonly BuildinTypeSpec IEnumerable;
53                 public readonly BuildinTypeSpec IDisposable;
54                 public readonly BuildinTypeSpec IntPtr;
55                 public readonly BuildinTypeSpec UIntPtr;
56                 public readonly BuildinTypeSpec RuntimeFieldHandle;
57                 public readonly BuildinTypeSpec RuntimeTypeHandle;
58                 public readonly BuildinTypeSpec Exception;
59
60                 //
61                 // These are internal buil-in types which depend on other
62                 // build-in type (mostly object)
63                 //
64                 public readonly BuildinTypeSpec Dynamic;
65                 public readonly BuildinTypeSpec Null;
66
67                 readonly BuildinTypeSpec[] types;
68
69                 public BuildinTypes ()
70                 {
71                         Object = new BuildinTypeSpec (MemberKind.Class, "System", "Object", BuildinTypeSpec.Type.Object);
72                         ValueType = new BuildinTypeSpec (MemberKind.Class, "System", "ValueType", BuildinTypeSpec.Type.ValueType);
73                         Attribute = new BuildinTypeSpec (MemberKind.Class, "System", "Attribute", BuildinTypeSpec.Type.Attribute);
74
75                         Int = new BuildinTypeSpec (MemberKind.Struct, "System", "Int32", BuildinTypeSpec.Type.Int);
76                         Long = new BuildinTypeSpec (MemberKind.Struct, "System", "Int64", BuildinTypeSpec.Type.Long);
77                         UInt = new BuildinTypeSpec (MemberKind.Struct, "System", "UInt32", BuildinTypeSpec.Type.UInt);
78                         ULong = new BuildinTypeSpec (MemberKind.Struct, "System", "UInt64", BuildinTypeSpec.Type.ULong);
79                         Byte = new BuildinTypeSpec (MemberKind.Struct, "System", "Byte", BuildinTypeSpec.Type.Byte);
80                         SByte = new BuildinTypeSpec (MemberKind.Struct, "System", "SByte", BuildinTypeSpec.Type.SByte);
81                         Short = new BuildinTypeSpec (MemberKind.Struct, "System", "Int16", BuildinTypeSpec.Type.Short);
82                         UShort = new BuildinTypeSpec (MemberKind.Struct, "System", "UInt16", BuildinTypeSpec.Type.UShort);
83
84                         IEnumerator = new BuildinTypeSpec (MemberKind.Interface, "System.Collections", "IEnumerator", BuildinTypeSpec.Type.IEnumerator);
85                         IEnumerable = new BuildinTypeSpec (MemberKind.Interface, "System.Collections", "IEnumerable", BuildinTypeSpec.Type.IEnumerable);
86                         IDisposable = new BuildinTypeSpec (MemberKind.Interface, "System", "IDisposable", BuildinTypeSpec.Type.IDisposable);
87
88                         Char = new BuildinTypeSpec (MemberKind.Struct, "System", "Char", BuildinTypeSpec.Type.Char);
89                         String = new BuildinTypeSpec (MemberKind.Class, "System", "String", BuildinTypeSpec.Type.String);
90                         Float = new BuildinTypeSpec (MemberKind.Struct, "System", "Single", BuildinTypeSpec.Type.Float);
91                         Double = new BuildinTypeSpec (MemberKind.Struct, "System", "Double", BuildinTypeSpec.Type.Double);
92                         Decimal = new BuildinTypeSpec (MemberKind.Struct, "System", "Decimal", BuildinTypeSpec.Type.Decimal);
93                         Bool = new BuildinTypeSpec (MemberKind.Struct, "System", "Boolean", BuildinTypeSpec.Type.Bool);
94                         IntPtr = new BuildinTypeSpec (MemberKind.Struct, "System", "IntPtr", BuildinTypeSpec.Type.IntPtr);
95                         UIntPtr = new BuildinTypeSpec (MemberKind.Struct, "System", "UIntPtr", BuildinTypeSpec.Type.UIntPtr);
96
97                         MulticastDelegate = new BuildinTypeSpec (MemberKind.Class, "System", "MulticastDelegate", BuildinTypeSpec.Type.MulticastDelegate);
98                         Delegate = new BuildinTypeSpec (MemberKind.Class, "System", "Delegate", BuildinTypeSpec.Type.Delegate);
99                         Enum = new BuildinTypeSpec (MemberKind.Class, "System", "Enum", BuildinTypeSpec.Type.Enum);
100                         Array = new BuildinTypeSpec (MemberKind.Class, "System", "Array", BuildinTypeSpec.Type.Array);
101                         Void = new BuildinTypeSpec (MemberKind.Struct, "System", "Void", BuildinTypeSpec.Type.Void);
102                         Type = new BuildinTypeSpec (MemberKind.Class, "System", "Type", BuildinTypeSpec.Type.Type);
103                         Exception = new BuildinTypeSpec (MemberKind.Class, "System", "Exception", BuildinTypeSpec.Type.Exception);
104                         RuntimeFieldHandle = new BuildinTypeSpec (MemberKind.Struct, "System", "RuntimeFieldHandle", BuildinTypeSpec.Type.RuntimeFieldHandle);
105                         RuntimeTypeHandle = new BuildinTypeSpec (MemberKind.Struct, "System", "RuntimeTypeHandle", BuildinTypeSpec.Type.RuntimeTypeHandle);
106
107                         Dynamic = new BuildinTypeSpec ("dynamic", BuildinTypeSpec.Type.Dynamic);
108                         Null = new BuildinTypeSpec ("null", BuildinTypeSpec.Type.Null);
109                         Null.MemberCache = MemberCache.Empty;
110
111                         types = new BuildinTypeSpec[] {
112                                 Object, ValueType, Attribute,
113                                 Int, UInt, Long, ULong, Float, Double, Char, Short, Decimal, Bool, SByte, Byte, UShort, String,
114                                 Enum, Delegate, MulticastDelegate, Void, Array, Type, IEnumerator, IEnumerable, IDisposable,
115                                 IntPtr, UIntPtr, RuntimeFieldHandle, RuntimeTypeHandle, Exception };
116
117                         // Deal with obsolete static types
118                         // TODO: remove
119                         TypeManager.object_type = Object;
120                         TypeManager.value_type = ValueType;
121                         TypeManager.string_type = String;
122                         TypeManager.int32_type = Int;
123                         TypeManager.uint32_type = UInt;
124                         TypeManager.int64_type = Long;
125                         TypeManager.uint64_type = ULong;
126                         TypeManager.float_type = Float;
127                         TypeManager.double_type = Double;
128                         TypeManager.char_type = Char;
129                         TypeManager.short_type = Short;
130                         TypeManager.decimal_type = Decimal;
131                         TypeManager.bool_type = Bool;
132                         TypeManager.sbyte_type = SByte;
133                         TypeManager.byte_type = Byte;
134                         TypeManager.ushort_type = UShort;
135                         TypeManager.enum_type = Enum;
136                         TypeManager.delegate_type = Delegate;
137                         TypeManager.multicast_delegate_type = MulticastDelegate; ;
138                         TypeManager.void_type = Void;
139                         TypeManager.array_type = Array; ;
140                         TypeManager.runtime_handle_type = RuntimeTypeHandle;
141                         TypeManager.type_type = Type;
142                         TypeManager.ienumerator_type = IEnumerator;
143                         TypeManager.ienumerable_type = IEnumerable;
144                         TypeManager.idisposable_type = IDisposable;
145                         TypeManager.intptr_type = IntPtr;
146                         TypeManager.uintptr_type = UIntPtr;
147                         TypeManager.runtime_field_handle_type = RuntimeFieldHandle;
148                         TypeManager.attribute_type = Attribute;
149                         TypeManager.exception_type = Exception;
150
151                         InternalType.Dynamic = Dynamic;
152                         InternalType.Null = Null;
153                 }
154
155                 public BuildinTypeSpec[] AllTypes {
156                         get {
157                                 return types;
158                         }
159                 }
160
161                 public bool CheckDefinitions (ModuleContainer module)
162                 {
163                         var ctx = module.Compiler;
164                         foreach (var p in types) {
165                                 var found = PredefinedType.Resolve (module, p.Kind, p.Namespace, p.Name, p.Arity, Location.Null);
166                                 if (found == null || found == p)
167                                         continue;
168
169                                 var tc = found.MemberDefinition as TypeContainer;
170                                 if (tc != null) {
171                                         var ns = module.GlobalRootNamespace.GetNamespace (p.Namespace, false);
172                                         ns.ReplaceTypeWithPredefined (found, p);
173
174                                         tc.SetPredefinedSpec (p);
175                                         p.SetDefinition (found);
176                                 }
177                         }
178
179                         if (ctx.Report.Errors != 0)
180                                 return false;
181
182                         // Set internal build-in types
183                         Dynamic.SetDefinition (Object);
184                         Null.SetDefinition (Object);
185
186                         return true;
187                 }
188         }
189
190         //
191         // Compiler predefined types. Usually used for compiler generated
192         // code or for comparison against well known framework type
193         //
194         class PredefinedTypes
195         {
196                 // TODO: These two exist only to reject type comparison
197                 public readonly PredefinedType TypedReference;
198                 public readonly PredefinedType ArgIterator;
199
200                 public readonly PredefinedType MarshalByRefObject;
201                 public readonly PredefinedType RuntimeHelpers;
202                 public readonly PredefinedType IAsyncResult;
203                 public readonly PredefinedType AsyncCallback;
204                 public readonly PredefinedType RuntimeArgumentHandle;
205                 public readonly PredefinedType CharSet;
206                 public readonly PredefinedType IsVolatile;
207                 public readonly PredefinedType IEnumeratorGeneric;
208                 public readonly PredefinedType IListGeneric;
209                 public readonly PredefinedType ICollectionGeneric;
210                 public readonly PredefinedType IEnumerableGeneric;
211                 public readonly PredefinedType Nullable;
212                 public readonly PredefinedType Activator;
213                 public readonly PredefinedType Interlocked;
214                 public readonly PredefinedType Monitor;
215                 public readonly PredefinedType NotSupportedException;
216                 public readonly PredefinedType RuntimeFieldHandle;
217                 public readonly PredefinedType RuntimeMethodHandle;
218                 public readonly PredefinedType SecurityAction;
219
220                 //
221                 // C# 3.0
222                 //
223                 public readonly PredefinedType Expression;
224                 public readonly PredefinedType ExpressionGeneric;
225                 public readonly PredefinedType ParameterExpression;
226                 public readonly PredefinedType FieldInfo;
227                 public readonly PredefinedType MethodBase;
228                 public readonly PredefinedType MethodInfo;
229                 public readonly PredefinedType ConstructorInfo;
230
231                 //
232                 // C# 4.0
233                 //
234                 public readonly PredefinedType Binder;
235                 public readonly PredefinedType CallSite;
236                 public readonly PredefinedType CallSiteGeneric;
237                 public readonly PredefinedType BinderFlags;
238
239                 public PredefinedTypes (ModuleContainer module)
240                 {
241                         TypedReference = new PredefinedType (module, MemberKind.Struct, "System", "TypedReference");
242                         ArgIterator = new PredefinedType (module, MemberKind.Struct, "System", "ArgIterator");
243                         MarshalByRefObject = new PredefinedType (module, MemberKind.Class, "System", "MarshalByRefObject");
244                         RuntimeHelpers = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "RuntimeHelpers");
245                         IAsyncResult = new PredefinedType (module, MemberKind.Interface, "System", "IAsyncResult");
246                         AsyncCallback = new PredefinedType (module, MemberKind.Delegate, "System", "AsyncCallback");
247                         RuntimeArgumentHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeArgumentHandle");
248                         CharSet = new PredefinedType (module, MemberKind.Enum, "System.Runtime.InteropServices", "CharSet");
249                         IsVolatile = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "IsVolatile");
250                         IEnumeratorGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IEnumerator", 1);
251                         IListGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IList", 1);
252                         ICollectionGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "ICollection", 1);
253                         IEnumerableGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IEnumerable", 1);
254                         Nullable = new PredefinedType (module, MemberKind.Struct, "System", "Nullable", 1);
255                         Activator = new PredefinedType (module, MemberKind.Class, "System", "Activator");
256                         Interlocked = new PredefinedType (module, MemberKind.Class, "System.Threading", "Interlocked");
257                         Monitor = new PredefinedType (module, MemberKind.Class, "System.Threading", "Monitor");
258                         NotSupportedException = new PredefinedType (module, MemberKind.Class, "System", "NotSupportedException");
259                         RuntimeFieldHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeFieldHandle");
260                         RuntimeMethodHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeMethodHandle");
261                         SecurityAction = new PredefinedType (module, MemberKind.Enum, "System.Security.Permissions", "SecurityAction");
262
263                         Expression = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "Expression");
264                         ExpressionGeneric = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "Expression", 1);
265                         ParameterExpression = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "ParameterExpression");
266                         FieldInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "FieldInfo");
267                         MethodBase = new PredefinedType (module, MemberKind.Class, "System.Reflection", "MethodBase");
268                         MethodInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "MethodInfo");
269                         ConstructorInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "ConstructorInfo");
270
271                         CallSite = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "CallSite");
272                         CallSiteGeneric = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "CallSite", 1);
273                         Binder = new PredefinedType (module, MemberKind.Class, "Microsoft.CSharp.RuntimeBinder", "Binder");
274                         BinderFlags = new PredefinedType (module, MemberKind.Enum, "Microsoft.CSharp.RuntimeBinder", "CSharpBinderFlags");
275
276                         //
277                         // Define types which are used for comparison. It does not matter
278                         // if they don't exist as no error report is needed
279                         //
280                         TypedReference.Define ();
281                         ArgIterator.Define ();
282                         MarshalByRefObject.Define ();
283                         CharSet.Define ();
284
285                         IEnumerableGeneric.Define ();
286                         IListGeneric.Define ();
287                         ICollectionGeneric.Define ();
288                         IEnumerableGeneric.Define ();
289                         IEnumeratorGeneric.Define ();
290                         Nullable.Define ();
291                         ExpressionGeneric.Define ();
292
293                         // Deal with obsolete static types
294                         // TODO: remove
295                         TypeManager.typed_reference_type = TypedReference.TypeSpec;
296                         TypeManager.arg_iterator_type = ArgIterator.TypeSpec;
297                         TypeManager.mbr_type = MarshalByRefObject.TypeSpec;
298                         TypeManager.generic_ilist_type = IListGeneric.TypeSpec;
299                         TypeManager.generic_icollection_type = ICollectionGeneric.TypeSpec;
300                         TypeManager.generic_ienumerator_type = IEnumeratorGeneric.TypeSpec;
301                         TypeManager.generic_ienumerable_type = IEnumerableGeneric.TypeSpec;
302                         TypeManager.generic_nullable_type = Nullable.TypeSpec;
303                         TypeManager.expression_type = ExpressionGeneric.TypeSpec;
304                 }
305         }
306
307         public class PredefinedType
308         {
309                 string name;
310                 string ns;
311                 int arity;
312                 MemberKind kind;
313                 protected readonly ModuleContainer module;
314                 protected TypeSpec type;
315
316                 public PredefinedType (ModuleContainer module, MemberKind kind, string ns, string name, int arity)
317                         : this (module, kind, ns, name)
318                 {
319                         this.arity = arity;
320                 }
321
322                 public PredefinedType (ModuleContainer module, MemberKind kind, string ns, string name)
323                 {
324                         this.module = module;
325                         this.kind = kind;
326                         this.name = name;
327                         this.ns = ns;
328                 }
329
330                 #region Properties
331
332                 public int Arity {
333                         get {
334                                 return arity;
335                         }
336                 }
337
338                 public bool IsDefined {
339                         get {
340                                 return type != null;
341                         }
342                 }
343
344                 public string Name {
345                         get {
346                                 return name;
347                         }
348                 }
349
350                 public string Namespace {
351                         get {
352                                 return ns;
353                         }
354                 }
355
356                 public TypeSpec TypeSpec {
357                         get {
358                                 return type;
359                         }
360                 }
361
362                 #endregion
363
364                 public bool Define ()
365                 {
366                         if (type != null)
367                                 return true;
368
369                         Namespace type_ns = module.GlobalRootNamespace.GetNamespace (ns, true);
370                         var te = type_ns.LookupType (module, name, arity, true, Location.Null);
371                         if (te == null)
372                                 return false;
373
374                         if (te.Type.Kind != kind)
375                                 return false;
376
377                         type = te.Type;
378                         return true;
379                 }
380
381                 public FieldSpec GetField (string name, TypeSpec memberType, Location loc)
382                 {
383                         return TypeManager.GetPredefinedField (type, name, loc, memberType);
384                 }
385
386                 public string GetSignatureForError ()
387                 {
388                         return ns + "." + name;
389                 }
390
391                 public static TypeSpec Resolve (ModuleContainer module, MemberKind kind, string ns, string name, int arity, Location loc)
392                 {
393                         Namespace type_ns = module.GlobalRootNamespace.GetNamespace (ns, true);
394                         var te = type_ns.LookupType (module, name, arity, false, Location.Null);
395                         if (te == null) {
396                                 module.Compiler.Report.Error (518, loc, "The predefined type `{0}.{1}' is not defined or imported", ns, name);
397                                 return null;
398                         }
399
400                         var type = te.Type;
401                         if (type.Kind != kind) {
402                                 module.Compiler.Report.Error (520, loc, "The predefined type `{0}.{1}' is not declared correctly", ns, name);
403                                 return null;
404                         }
405
406                         return type;
407                 }
408
409                 public TypeSpec Resolve (Location loc)
410                 {
411                         if (type == null)
412                                 type = Resolve (module, kind, ns, name, arity, loc);
413
414                         return type;
415                 }
416         }
417
418         partial class TypeManager {
419         //
420         // A list of core types that the compiler requires or uses
421         //
422         static public BuildinTypeSpec object_type;
423         static public BuildinTypeSpec value_type;
424         static public BuildinTypeSpec string_type;
425         static public BuildinTypeSpec int32_type;
426         static public BuildinTypeSpec uint32_type;
427         static public BuildinTypeSpec int64_type;
428         static public BuildinTypeSpec uint64_type;
429         static public BuildinTypeSpec float_type;
430         static public BuildinTypeSpec double_type;
431         static public BuildinTypeSpec char_type;
432         static public BuildinTypeSpec short_type;
433         static public BuildinTypeSpec decimal_type;
434         static public BuildinTypeSpec bool_type;
435         static public BuildinTypeSpec sbyte_type;
436         static public BuildinTypeSpec byte_type;
437         static public BuildinTypeSpec ushort_type;
438         static public BuildinTypeSpec enum_type;
439         static public BuildinTypeSpec delegate_type;
440         static public BuildinTypeSpec multicast_delegate_type;
441         static public BuildinTypeSpec void_type;
442         static public BuildinTypeSpec array_type;
443         static public BuildinTypeSpec runtime_handle_type;
444         static public BuildinTypeSpec type_type;
445         static public BuildinTypeSpec ienumerator_type;
446         static public BuildinTypeSpec ienumerable_type;
447         static public BuildinTypeSpec idisposable_type;
448         static public BuildinTypeSpec intptr_type;
449         static public BuildinTypeSpec uintptr_type;
450         static public BuildinTypeSpec runtime_field_handle_type;
451         static public BuildinTypeSpec attribute_type;
452         static public BuildinTypeSpec exception_type;
453
454
455         static public TypeSpec typed_reference_type;
456         static public TypeSpec arg_iterator_type;
457         static public TypeSpec mbr_type;
458         static public TypeSpec generic_ilist_type;
459         static public TypeSpec generic_icollection_type;
460         static public TypeSpec generic_ienumerator_type;
461         static public TypeSpec generic_ienumerable_type;
462         static public TypeSpec generic_nullable_type;
463         static internal TypeSpec expression_type;
464
465         //
466         // These methods are called by code generated by the compiler
467         //
468         static public FieldSpec string_empty;
469         static public MethodSpec system_type_get_type_from_handle;
470         static public MethodSpec bool_movenext_void;
471         static public MethodSpec void_dispose_void;
472         static public MethodSpec void_monitor_enter_object;
473         static public MethodSpec void_monitor_exit_object;
474         static public MethodSpec void_initializearray_array_fieldhandle;
475         static public MethodSpec delegate_combine_delegate_delegate;
476         static public MethodSpec delegate_remove_delegate_delegate;
477         static public PropertySpec int_get_offset_to_string_data;
478         static public MethodSpec int_interlocked_compare_exchange;
479         public static MethodSpec gen_interlocked_compare_exchange;
480         static public PropertySpec ienumerator_getcurrent;
481         public static MethodSpec methodbase_get_type_from_handle;
482         public static MethodSpec methodbase_get_type_from_handle_generic;
483         public static MethodSpec fieldinfo_get_field_from_handle;
484         public static MethodSpec fieldinfo_get_field_from_handle_generic;
485         public static MethodSpec activator_create_instance;
486
487         //
488         // The constructors.
489         //
490         static public MethodSpec void_decimal_ctor_five_args;
491         static public MethodSpec void_decimal_ctor_int_arg;
492         public static MethodSpec void_decimal_ctor_long_arg;
493
494         static TypeManager ()
495         {
496                 Reset ();
497         }
498
499         static public void Reset ()
500         {
501 //              object_type = null;
502         
503                 // TODO: I am really bored by all this static stuff
504                 system_type_get_type_from_handle =
505                 bool_movenext_void =
506                 void_dispose_void =
507                 void_monitor_enter_object =
508                 void_monitor_exit_object =
509                 void_initializearray_array_fieldhandle =
510                 int_interlocked_compare_exchange =
511                 gen_interlocked_compare_exchange =
512                 methodbase_get_type_from_handle =
513                 methodbase_get_type_from_handle_generic =
514                 fieldinfo_get_field_from_handle =
515                 fieldinfo_get_field_from_handle_generic =
516                 activator_create_instance =
517                 delegate_combine_delegate_delegate =
518                 delegate_remove_delegate_delegate = null;
519
520                 int_get_offset_to_string_data =
521                 ienumerator_getcurrent = null;
522
523                 void_decimal_ctor_five_args =
524                 void_decimal_ctor_int_arg =
525                 void_decimal_ctor_long_arg = null;
526
527                 string_empty = null;
528
529                 typed_reference_type = arg_iterator_type = mbr_type =
530                 generic_ilist_type = generic_icollection_type = generic_ienumerator_type =
531                 generic_ienumerable_type = generic_nullable_type = expression_type = null;
532         }
533
534         /// <summary>
535         ///   Returns the C# name of a type if possible, or the full type name otherwise
536         /// </summary>
537         static public string CSharpName (TypeSpec t)
538         {
539                 return t.GetSignatureForError ();
540         }
541
542         static public string CSharpName (IList<TypeSpec> types)
543         {
544                 if (types.Count == 0)
545                         return string.Empty;
546
547                 StringBuilder sb = new StringBuilder ();
548                 for (int i = 0; i < types.Count; ++i) {
549                         if (i > 0)
550                                 sb.Append (",");
551
552                         sb.Append (CSharpName (types [i]));
553                 }
554                 return sb.ToString ();
555         }
556
557         static public string GetFullNameSignature (MemberSpec mi)
558         {
559                 return mi.GetSignatureForError ();
560         }
561
562         static public string CSharpSignature (MemberSpec mb)
563         {
564                 return mb.GetSignatureForError ();
565         }
566
567         static MemberSpec GetPredefinedMember (TypeSpec t, MemberFilter filter, bool optional, Location loc)
568         {
569                 var member = MemberCache.FindMember (t, filter, BindingRestriction.DeclaredOnly);
570
571                 if (member != null && member.IsAccessible (InternalType.FakeInternalType))
572                         return member;
573
574                 if (optional)
575                         return member;
576
577                 string method_args = null;
578                 if (filter.Parameters != null)
579                         method_args = filter.Parameters.GetSignatureForError ();
580
581                 RootContext.ToplevelTypes.Compiler.Report.Error (656, loc, "The compiler required member `{0}.{1}{2}' could not be found or is inaccessible",
582                         TypeManager.CSharpName (t), filter.Name, method_args);
583
584                 return null;
585         }
586
587         //
588         // Returns the ConstructorInfo for "args"
589         //
590         public static MethodSpec GetPredefinedConstructor (TypeSpec t, Location loc, params TypeSpec [] args)
591         {
592                 var pc = ParametersCompiled.CreateFullyResolved (args);
593                 return GetPredefinedMember (t, MemberFilter.Constructor (pc), false, loc) as MethodSpec;
594         }
595
596         //
597         // Returns the method specification for a method named `name' defined
598         // in type `t' which takes arguments of types `args'
599         //
600         public static MethodSpec GetPredefinedMethod (TypeSpec t, string name, Location loc, params TypeSpec [] args)
601         {
602                 var pc = ParametersCompiled.CreateFullyResolved (args);
603                 return GetPredefinedMethod (t, MemberFilter.Method (name, 0, pc, null), false, loc);
604         }
605
606         public static MethodSpec GetPredefinedMethod (TypeSpec t, MemberFilter filter, Location loc)
607         {
608                 return GetPredefinedMethod (t, filter, false, loc);
609         }
610
611         public static MethodSpec GetPredefinedMethod (TypeSpec t, MemberFilter filter, bool optional, Location loc)
612         {
613                 return GetPredefinedMember (t, filter, optional, loc) as MethodSpec;
614         }
615
616         public static FieldSpec GetPredefinedField (TypeSpec t, string name, Location loc, TypeSpec type)
617         {
618                 return GetPredefinedMember (t, MemberFilter.Field (name, type), false, loc) as FieldSpec;
619         }
620
621         public static PropertySpec GetPredefinedProperty (TypeSpec t, string name, Location loc, TypeSpec type)
622         {
623                 return GetPredefinedMember (t, MemberFilter.Property (name, type), false, loc) as PropertySpec;
624         }
625
626         public static bool IsBuiltinType (TypeSpec t)
627         {
628                 if (t == object_type || t == string_type || t == int32_type || t == uint32_type ||
629                     t == int64_type || t == uint64_type || t == float_type || t == double_type ||
630                     t == char_type || t == short_type || t == decimal_type || t == bool_type ||
631                     t == sbyte_type || t == byte_type || t == ushort_type || t == void_type)
632                         return true;
633                 else
634                         return false;
635         }
636
637         //
638         // This is like IsBuiltinType, but lacks decimal_type, we should also clean up
639         // the pieces in the code where we use IsBuiltinType and special case decimal_type.
640         // 
641         public static bool IsPrimitiveType (TypeSpec t)
642         {
643                 return (t == int32_type || t == uint32_type ||
644                     t == int64_type || t == uint64_type || t == float_type || t == double_type ||
645                     t == char_type || t == short_type || t == bool_type ||
646                     t == sbyte_type || t == byte_type || t == ushort_type);
647         }
648
649         // Obsolete
650         public static bool IsDelegateType (TypeSpec t)
651         {
652                 return t.IsDelegate;
653         }
654         
655         // Obsolete
656         public static bool IsEnumType (TypeSpec t)
657         {
658                 return t.IsEnum;
659         }
660
661         public static bool IsBuiltinOrEnum (TypeSpec t)
662         {
663                 if (IsBuiltinType (t))
664                         return true;
665                 
666                 if (IsEnumType (t))
667                         return true;
668
669                 return false;
670         }
671
672         //
673         // Whether a type is unmanaged.  This is used by the unsafe code (25.2)
674         //
675         public static bool IsUnmanagedType (TypeSpec t)
676         {
677                 var ds = t.MemberDefinition as DeclSpace;
678                 if (ds != null)
679                         return ds.IsUnmanagedType ();
680
681                 // some builtins that are not unmanaged types
682                 if (t == TypeManager.object_type || t == TypeManager.string_type)
683                         return false;
684
685                 if (IsBuiltinOrEnum (t))
686                         return true;
687
688                 // Someone did the work of checking if the ElementType of t is unmanaged.  Let's not repeat it.
689                 if (t.IsPointer)
690                         return IsUnmanagedType (GetElementType (t));
691
692                 if (!IsValueType (t))
693                         return false;
694
695                 if (t.IsNested && t.DeclaringType.IsGenericOrParentIsGeneric)
696                         return false;
697
698                 return true;
699         }
700
701         //
702         // Null is considered to be a reference type
703         //                      
704         public static bool IsReferenceType (TypeSpec t)
705         {
706                 if (t.IsGenericParameter)
707                         return ((TypeParameterSpec) t).IsReferenceType;
708
709                 return !t.IsStruct && !IsEnumType (t);
710         }                       
711                 
712         public static bool IsValueType (TypeSpec t)
713         {
714                 if (t.IsGenericParameter)
715                         return ((TypeParameterSpec) t).IsValueType;
716
717                 return t.IsStruct || IsEnumType (t);
718         }
719
720         public static bool IsStruct (TypeSpec t)
721         {
722                 return t.IsStruct;
723         }
724
725         public static bool IsFamilyAccessible (TypeSpec type, TypeSpec parent)
726         {
727 //              TypeParameter tparam = LookupTypeParameter (type);
728 //              TypeParameter pparam = LookupTypeParameter (parent);
729
730                 if (type.Kind == MemberKind.TypeParameter && parent.Kind == MemberKind.TypeParameter) { // (tparam != null) && (pparam != null)) {
731                         if (type == parent)
732                                 return true;
733
734                         throw new NotImplementedException ("net");
735 //                      return tparam.IsSubclassOf (parent);
736                 }
737
738                 do {
739                         if (IsInstantiationOfSameGenericType (type, parent))
740                                 return true;
741
742                         type = type.BaseType;
743                 } while (type != null);
744
745                 return false;
746         }
747
748         //
749         // Checks whether `type' is a subclass or nested child of `base_type'.
750         //
751         public static bool IsNestedFamilyAccessible (TypeSpec type, TypeSpec base_type)
752         {
753                 do {
754                         if (IsFamilyAccessible (type, base_type))
755                                 return true;
756
757                         // Handle nested types.
758                         type = type.DeclaringType;
759                 } while (type != null);
760
761                 return false;
762         }
763
764         //
765         // Checks whether `type' is a nested child of `parent'.
766         //
767         public static bool IsNestedChildOf (TypeSpec type, ITypeDefinition parent)
768         {
769                 if (type == null)
770                         return false;
771
772                 if (type.MemberDefinition == parent)
773                         return false;
774
775                 type = type.DeclaringType;
776                 while (type != null) {
777                         if (type.MemberDefinition == parent)
778                                 return true;
779
780                         type = type.DeclaringType;
781                 }
782
783                 return false;
784         }
785
786         public static bool IsSpecialType (TypeSpec t)
787         {
788                 return t == arg_iterator_type || t == typed_reference_type;
789         }
790
791         public static TypeSpec GetElementType (TypeSpec t)
792         {
793                 return ((ElementTypeSpec)t).Element;
794         }
795
796         /// <summary>
797         /// This method is not implemented by MS runtime for dynamic types
798         /// </summary>
799         public static bool HasElementType (TypeSpec t)
800         {
801                 return t is ElementTypeSpec;
802         }
803
804         static NumberFormatInfo nf_provider = CultureInfo.CurrentCulture.NumberFormat;
805
806         // This is a custom version of Convert.ChangeType() which works
807         // with the TypeBuilder defined types when compiling corlib.
808         public static object ChangeType (object value, TypeSpec targetType, out bool error)
809         {
810                 IConvertible convert_value = value as IConvertible;
811                 
812                 if (convert_value == null){
813                         error = true;
814                         return null;
815                 }
816                 
817                 //
818                 // We cannot rely on build-in type conversions as they are
819                 // more limited than what C# supports.
820                 // See char -> float/decimal/double conversion
821                 //
822                 error = false;
823                 try {
824                         if (targetType == TypeManager.bool_type)
825                                 return convert_value.ToBoolean (nf_provider);
826                         if (targetType == TypeManager.byte_type)
827                                 return convert_value.ToByte (nf_provider);
828                         if (targetType == TypeManager.char_type)
829                                 return convert_value.ToChar (nf_provider);
830                         if (targetType == TypeManager.short_type)
831                                 return convert_value.ToInt16 (nf_provider);
832                         if (targetType == TypeManager.int32_type)
833                                 return convert_value.ToInt32 (nf_provider);
834                         if (targetType == TypeManager.int64_type)
835                                 return convert_value.ToInt64 (nf_provider);
836                         if (targetType == TypeManager.sbyte_type)
837                                 return convert_value.ToSByte (nf_provider);
838
839                         if (targetType == TypeManager.decimal_type) {
840                                 if (convert_value.GetType () == typeof (char))
841                                         return (decimal) convert_value.ToInt32 (nf_provider);
842                                 return convert_value.ToDecimal (nf_provider);
843                         }
844
845                         if (targetType == TypeManager.double_type) {
846                                 if (convert_value.GetType () == typeof (char))
847                                         return (double) convert_value.ToInt32 (nf_provider);
848                                 return convert_value.ToDouble (nf_provider);
849                         }
850
851                         if (targetType == TypeManager.float_type) {
852                                 if (convert_value.GetType () == typeof (char))
853                                         return (float)convert_value.ToInt32 (nf_provider);
854                                 return convert_value.ToSingle (nf_provider);
855                         }
856
857                         if (targetType == TypeManager.string_type)
858                                 return convert_value.ToString (nf_provider);
859                         if (targetType == TypeManager.ushort_type)
860                                 return convert_value.ToUInt16 (nf_provider);
861                         if (targetType == TypeManager.uint32_type)
862                                 return convert_value.ToUInt32 (nf_provider);
863                         if (targetType == TypeManager.uint64_type)
864                                 return convert_value.ToUInt64 (nf_provider);
865                         if (targetType == TypeManager.object_type)
866                                 return value;
867
868                         error = true;
869                 } catch {
870                         error = true;
871                 }
872                 return null;
873         }
874
875         /// <summary>
876         ///   Utility function that can be used to probe whether a type
877         ///   is managed or not.  
878         /// </summary>
879         public static bool VerifyUnmanaged (ModuleContainer rc, TypeSpec t, Location loc)
880         {
881                 while (t.IsPointer)
882                         t = GetElementType (t);
883
884                 if (IsUnmanagedType (t))
885                         return true;
886
887                 rc.Compiler.Report.SymbolRelatedToPreviousError (t);
888                 rc.Compiler.Report.Error (208, loc,
889                         "Cannot take the address of, get the size of, or declare a pointer to a managed type `{0}'",
890                         CSharpName (t));
891
892                 return false;   
893         }
894 #region Generics
895         // This method always return false for non-generic compiler,
896         // while Type.IsGenericParameter is returned if it is supported.
897         public static bool IsGenericParameter (TypeSpec type)
898         {
899                 return type.IsGenericParameter;
900         }
901
902         public static bool IsGenericType (TypeSpec type)
903         {
904                 return type.IsGeneric;
905         }
906
907         public static TypeSpec[] GetTypeArguments (TypeSpec t)
908         {
909                 // TODO: return empty array !!
910                 return t.TypeArguments;
911         }
912
913         /// <summary>
914         ///   Check whether `type' and `parent' are both instantiations of the same
915         ///   generic type.  Note that we do not check the type parameters here.
916         /// </summary>
917         public static bool IsInstantiationOfSameGenericType (TypeSpec type, TypeSpec parent)
918         {
919                 return type == parent || type.MemberDefinition == parent.MemberDefinition;
920         }
921
922         public static bool IsNullableType (TypeSpec t)
923         {
924                 return generic_nullable_type == t.GetDefinition ();
925         }
926 #endregion
927 }
928
929 }