Clean up handling of few special runtime types
[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
66                 // Predefined operators tables
67                 public readonly Binary.PredefinedOperator[] OperatorsBinaryStandard;
68                 public readonly Binary.PredefinedOperator[] OperatorsBinaryEquality;
69                 public readonly Binary.PredefinedOperator[] OperatorsBinaryUnsafe;
70                 public readonly TypeSpec[][] OperatorsUnary;
71                 public readonly TypeSpec[] OperatorsUnaryMutator;
72
73                 public readonly TypeSpec[] BinaryPromotionsTypes;
74                 public readonly TypeSpec[] SwitchUserTypes;
75
76                 readonly BuildinTypeSpec[] types;
77
78                 public BuildinTypes ()
79                 {
80                         Object = new BuildinTypeSpec (MemberKind.Class, "System", "Object", BuildinTypeSpec.Type.Object);
81                         ValueType = new BuildinTypeSpec (MemberKind.Class, "System", "ValueType", BuildinTypeSpec.Type.ValueType);
82                         Attribute = new BuildinTypeSpec (MemberKind.Class, "System", "Attribute", BuildinTypeSpec.Type.Attribute);
83
84                         Int = new BuildinTypeSpec (MemberKind.Struct, "System", "Int32", BuildinTypeSpec.Type.Int);
85                         Long = new BuildinTypeSpec (MemberKind.Struct, "System", "Int64", BuildinTypeSpec.Type.Long);
86                         UInt = new BuildinTypeSpec (MemberKind.Struct, "System", "UInt32", BuildinTypeSpec.Type.UInt);
87                         ULong = new BuildinTypeSpec (MemberKind.Struct, "System", "UInt64", BuildinTypeSpec.Type.ULong);
88                         Byte = new BuildinTypeSpec (MemberKind.Struct, "System", "Byte", BuildinTypeSpec.Type.Byte);
89                         SByte = new BuildinTypeSpec (MemberKind.Struct, "System", "SByte", BuildinTypeSpec.Type.SByte);
90                         Short = new BuildinTypeSpec (MemberKind.Struct, "System", "Int16", BuildinTypeSpec.Type.Short);
91                         UShort = new BuildinTypeSpec (MemberKind.Struct, "System", "UInt16", BuildinTypeSpec.Type.UShort);
92
93                         IEnumerator = new BuildinTypeSpec (MemberKind.Interface, "System.Collections", "IEnumerator", BuildinTypeSpec.Type.IEnumerator);
94                         IEnumerable = new BuildinTypeSpec (MemberKind.Interface, "System.Collections", "IEnumerable", BuildinTypeSpec.Type.IEnumerable);
95                         IDisposable = new BuildinTypeSpec (MemberKind.Interface, "System", "IDisposable", BuildinTypeSpec.Type.IDisposable);
96
97                         Char = new BuildinTypeSpec (MemberKind.Struct, "System", "Char", BuildinTypeSpec.Type.Char);
98                         String = new BuildinTypeSpec (MemberKind.Class, "System", "String", BuildinTypeSpec.Type.String);
99                         Float = new BuildinTypeSpec (MemberKind.Struct, "System", "Single", BuildinTypeSpec.Type.Float);
100                         Double = new BuildinTypeSpec (MemberKind.Struct, "System", "Double", BuildinTypeSpec.Type.Double);
101                         Decimal = new BuildinTypeSpec (MemberKind.Struct, "System", "Decimal", BuildinTypeSpec.Type.Decimal);
102                         Bool = new BuildinTypeSpec (MemberKind.Struct, "System", "Boolean", BuildinTypeSpec.Type.Bool);
103                         IntPtr = new BuildinTypeSpec (MemberKind.Struct, "System", "IntPtr", BuildinTypeSpec.Type.IntPtr);
104                         UIntPtr = new BuildinTypeSpec (MemberKind.Struct, "System", "UIntPtr", BuildinTypeSpec.Type.UIntPtr);
105
106                         MulticastDelegate = new BuildinTypeSpec (MemberKind.Class, "System", "MulticastDelegate", BuildinTypeSpec.Type.MulticastDelegate);
107                         Delegate = new BuildinTypeSpec (MemberKind.Class, "System", "Delegate", BuildinTypeSpec.Type.Delegate);
108                         Enum = new BuildinTypeSpec (MemberKind.Class, "System", "Enum", BuildinTypeSpec.Type.Enum);
109                         Array = new BuildinTypeSpec (MemberKind.Class, "System", "Array", BuildinTypeSpec.Type.Array);
110                         Void = new BuildinTypeSpec (MemberKind.Void, "System", "Void", BuildinTypeSpec.Type.Other);
111                         Type = new BuildinTypeSpec (MemberKind.Class, "System", "Type", BuildinTypeSpec.Type.Type);
112                         Exception = new BuildinTypeSpec (MemberKind.Class, "System", "Exception", BuildinTypeSpec.Type.Exception);
113                         RuntimeFieldHandle = new BuildinTypeSpec (MemberKind.Struct, "System", "RuntimeFieldHandle", BuildinTypeSpec.Type.Other);
114                         RuntimeTypeHandle = new BuildinTypeSpec (MemberKind.Struct, "System", "RuntimeTypeHandle", BuildinTypeSpec.Type.Other);
115
116                         // TODO: Maybe I should promote it to different kind for faster compares
117                         Dynamic = new BuildinTypeSpec ("dynamic", BuildinTypeSpec.Type.Dynamic);
118
119                         OperatorsBinaryStandard = Binary.CreateStandardOperatorsTable (this);
120                         OperatorsBinaryEquality = Binary.CreateEqualityOperatorsTable (this);
121                         OperatorsBinaryUnsafe = Binary.CreatePointerOperatorsTable (this);
122                         OperatorsUnary = Unary.CreatePredefinedOperatorsTable (this);
123                         OperatorsUnaryMutator = UnaryMutator.CreatePredefinedOperatorsTable (this);
124
125                         BinaryPromotionsTypes = ConstantFold.CreateBinaryPromotionsTypes (this);
126                         SwitchUserTypes = Switch.CreateSwitchUserTypes (this);
127
128                         types = new BuildinTypeSpec[] {
129                                 Object, ValueType, Attribute,
130                                 Int, UInt, Long, ULong, Float, Double, Char, Short, Decimal, Bool, SByte, Byte, UShort, String,
131                                 Enum, Delegate, MulticastDelegate, Void, Array, Type, IEnumerator, IEnumerable, IDisposable,
132                                 IntPtr, UIntPtr, RuntimeFieldHandle, RuntimeTypeHandle, Exception };
133
134                         // Deal with obsolete static types
135                         // TODO: remove
136                         TypeManager.object_type = Object;
137                         TypeManager.value_type = ValueType;
138                 }
139
140                 public BuildinTypeSpec[] AllTypes {
141                         get {
142                                 return types;
143                         }
144                 }
145
146                 public bool CheckDefinitions (ModuleContainer module)
147                 {
148                         var ctx = module.Compiler;
149                         foreach (var p in types) {
150                                 var found = PredefinedType.Resolve (module, p.Kind, p.Namespace, p.Name, p.Arity, Location.Null);
151                                 if (found == null || found == p)
152                                         continue;
153
154                                 var tc = found.MemberDefinition as TypeContainer;
155                                 if (tc != null) {
156                                         var ns = module.GlobalRootNamespace.GetNamespace (p.Namespace, false);
157                                         ns.ReplaceTypeWithPredefined (found, p);
158
159                                         tc.SetPredefinedSpec (p);
160                                         p.SetDefinition (found);
161                                 }
162                         }
163
164                         if (ctx.Report.Errors != 0)
165                                 return false;
166
167                         // Set internal build-in types
168                         Dynamic.SetDefinition (Object);
169
170                         return true;
171                 }
172         }
173
174         //
175         // Compiler predefined types. Usually used for compiler generated
176         // code or for comparison against well known framework type. They
177         // may not exist as they are optional
178         //
179         class PredefinedTypes
180         {
181                 public readonly PredefinedType ArgIterator;
182                 public readonly PredefinedType MarshalByRefObject;
183                 public readonly PredefinedType RuntimeHelpers;
184                 public readonly PredefinedType IAsyncResult;
185                 public readonly PredefinedType AsyncCallback;
186                 public readonly PredefinedType RuntimeArgumentHandle;
187                 public readonly PredefinedType CharSet;
188                 public readonly PredefinedType IsVolatile;
189                 public readonly PredefinedType IEnumeratorGeneric;
190                 public readonly PredefinedType IListGeneric;
191                 public readonly PredefinedType ICollectionGeneric;
192                 public readonly PredefinedType IEnumerableGeneric;
193                 public readonly PredefinedType Nullable;
194                 public readonly PredefinedType Activator;
195                 public readonly PredefinedType Interlocked;
196                 public readonly PredefinedType Monitor;
197                 public readonly PredefinedType NotSupportedException;
198                 public readonly PredefinedType RuntimeFieldHandle;
199                 public readonly PredefinedType RuntimeMethodHandle;
200                 public readonly PredefinedType SecurityAction;
201
202                 //
203                 // C# 3.0
204                 //
205                 public readonly PredefinedType Expression;
206                 public readonly PredefinedType ExpressionGeneric;
207                 public readonly PredefinedType ParameterExpression;
208                 public readonly PredefinedType FieldInfo;
209                 public readonly PredefinedType MethodBase;
210                 public readonly PredefinedType MethodInfo;
211                 public readonly PredefinedType ConstructorInfo;
212
213                 //
214                 // C# 4.0
215                 //
216                 public readonly PredefinedType Binder;
217                 public readonly PredefinedType CallSite;
218                 public readonly PredefinedType CallSiteGeneric;
219                 public readonly PredefinedType BinderFlags;
220
221                 public PredefinedTypes (ModuleContainer module)
222                 {
223                         var TypedReference = new PredefinedType (module, MemberKind.Struct, "System", "TypedReference");
224                         ArgIterator = new PredefinedType (module, MemberKind.Struct, "System", "ArgIterator");
225
226                         MarshalByRefObject = new PredefinedType (module, MemberKind.Class, "System", "MarshalByRefObject");
227                         RuntimeHelpers = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "RuntimeHelpers");
228                         IAsyncResult = new PredefinedType (module, MemberKind.Interface, "System", "IAsyncResult");
229                         AsyncCallback = new PredefinedType (module, MemberKind.Delegate, "System", "AsyncCallback");
230                         RuntimeArgumentHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeArgumentHandle");
231                         CharSet = new PredefinedType (module, MemberKind.Enum, "System.Runtime.InteropServices", "CharSet");
232                         IsVolatile = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "IsVolatile");
233                         IEnumeratorGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IEnumerator", 1);
234                         IListGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IList", 1);
235                         ICollectionGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "ICollection", 1);
236                         IEnumerableGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IEnumerable", 1);
237                         Nullable = new PredefinedType (module, MemberKind.Struct, "System", "Nullable", 1);
238                         Activator = new PredefinedType (module, MemberKind.Class, "System", "Activator");
239                         Interlocked = new PredefinedType (module, MemberKind.Class, "System.Threading", "Interlocked");
240                         Monitor = new PredefinedType (module, MemberKind.Class, "System.Threading", "Monitor");
241                         NotSupportedException = new PredefinedType (module, MemberKind.Class, "System", "NotSupportedException");
242                         RuntimeFieldHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeFieldHandle");
243                         RuntimeMethodHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeMethodHandle");
244                         SecurityAction = new PredefinedType (module, MemberKind.Enum, "System.Security.Permissions", "SecurityAction");
245
246                         Expression = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "Expression");
247                         ExpressionGeneric = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "Expression", 1);
248                         ParameterExpression = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "ParameterExpression");
249                         FieldInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "FieldInfo");
250                         MethodBase = new PredefinedType (module, MemberKind.Class, "System.Reflection", "MethodBase");
251                         MethodInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "MethodInfo");
252                         ConstructorInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "ConstructorInfo");
253
254                         CallSite = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "CallSite");
255                         CallSiteGeneric = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "CallSite", 1);
256                         Binder = new PredefinedType (module, MemberKind.Class, "Microsoft.CSharp.RuntimeBinder", "Binder");
257                         BinderFlags = new PredefinedType (module, MemberKind.Enum, "Microsoft.CSharp.RuntimeBinder", "CSharpBinderFlags");
258
259                         //
260                         // Define types which are used for comparison. It does not matter
261                         // if they don't exist as no error report is needed
262                         //
263                         if (TypedReference.Define ())
264                                 TypedReference.TypeSpec.IsSpecialRuntimeType = true;
265                         if (ArgIterator.Define ())
266                                 ArgIterator.TypeSpec.IsSpecialRuntimeType = true;
267                         MarshalByRefObject.Define ();
268                         CharSet.Define ();
269
270                         IEnumerableGeneric.Define ();
271                         IListGeneric.Define ();
272                         ICollectionGeneric.Define ();
273                         IEnumerableGeneric.Define ();
274                         IEnumeratorGeneric.Define ();
275                         Nullable.Define ();
276                         ExpressionGeneric.Define ();
277
278                         // Deal with obsolete static types
279                         // TODO: remove
280                         TypeManager.generic_ilist_type = IListGeneric.TypeSpec;
281                         TypeManager.generic_icollection_type = ICollectionGeneric.TypeSpec;
282                         TypeManager.generic_ienumerator_type = IEnumeratorGeneric.TypeSpec;
283                         TypeManager.generic_ienumerable_type = IEnumerableGeneric.TypeSpec;
284                         TypeManager.generic_nullable_type = Nullable.TypeSpec;
285                         TypeManager.expression_type = ExpressionGeneric.TypeSpec;
286                 }
287         }
288
289         public class PredefinedType
290         {
291                 string name;
292                 string ns;
293                 int arity;
294                 MemberKind kind;
295                 protected readonly ModuleContainer module;
296                 protected TypeSpec type;
297
298                 public PredefinedType (ModuleContainer module, MemberKind kind, string ns, string name, int arity)
299                         : this (module, kind, ns, name)
300                 {
301                         this.arity = arity;
302                 }
303
304                 public PredefinedType (ModuleContainer module, MemberKind kind, string ns, string name)
305                 {
306                         this.module = module;
307                         this.kind = kind;
308                         this.name = name;
309                         this.ns = ns;
310                 }
311
312                 #region Properties
313
314                 public int Arity {
315                         get {
316                                 return arity;
317                         }
318                 }
319
320                 public bool IsDefined {
321                         get {
322                                 return type != null;
323                         }
324                 }
325
326                 public string Name {
327                         get {
328                                 return name;
329                         }
330                 }
331
332                 public string Namespace {
333                         get {
334                                 return ns;
335                         }
336                 }
337
338                 public TypeSpec TypeSpec {
339                         get {
340                                 return type;
341                         }
342                 }
343
344                 #endregion
345
346                 public bool Define ()
347                 {
348                         if (type != null)
349                                 return true;
350
351                         Namespace type_ns = module.GlobalRootNamespace.GetNamespace (ns, true);
352                         var te = type_ns.LookupType (module, name, arity, true, Location.Null);
353                         if (te == null || te.Type.Kind != kind) {
354                                 return false;
355                         }
356
357                         type = te.Type;
358                         return true;
359                 }
360
361                 public FieldSpec GetField (string name, TypeSpec memberType, Location loc)
362                 {
363                         return TypeManager.GetPredefinedField (type, name, loc, memberType);
364                 }
365
366                 public string GetSignatureForError ()
367                 {
368                         return ns + "." + name;
369                 }
370
371                 public static TypeSpec Resolve (ModuleContainer module, MemberKind kind, string ns, string name, int arity, Location loc)
372                 {
373                         Namespace type_ns = module.GlobalRootNamespace.GetNamespace (ns, true);
374                         var te = type_ns.LookupType (module, name, arity, false, Location.Null);
375                         if (te == null) {
376                                 module.Compiler.Report.Error (518, loc, "The predefined type `{0}.{1}' is not defined or imported", ns, name);
377                                 return null;
378                         }
379
380                         var type = te.Type;
381                         if (type.Kind != kind) {
382                                 if (type.Kind == MemberKind.Struct && kind == MemberKind.Void && type.MemberDefinition is TypeContainer) {
383                                         // Void is declared as struct but we keep it internally as
384                                         // special kind, the swap will be done by caller
385                                 } else {
386                                         module.Compiler.Report.Error (520, loc, "The predefined type `{0}.{1}' is not declared correctly", ns, name);
387                                         return null;
388                                 }
389                         }
390
391                         return type;
392                 }
393
394                 public TypeSpec Resolve (Location loc)
395                 {
396                         if (type == null)
397                                 type = Resolve (module, kind, ns, name, arity, loc);
398
399                         return type;
400                 }
401         }
402
403         partial class TypeManager {
404         //
405         // A list of core types that the compiler requires or uses
406         //
407         static public BuildinTypeSpec object_type;
408         static public BuildinTypeSpec value_type;
409
410         static public TypeSpec generic_ilist_type;
411         static public TypeSpec generic_icollection_type;
412         static public TypeSpec generic_ienumerator_type;
413         static public TypeSpec generic_ienumerable_type;
414         static public TypeSpec generic_nullable_type;
415         static internal TypeSpec expression_type;
416
417         //
418         // These methods are called by code generated by the compiler
419         //
420         static public FieldSpec string_empty;
421         static public MethodSpec system_type_get_type_from_handle;
422         static public MethodSpec bool_movenext_void;
423         static public MethodSpec void_dispose_void;
424         static public MethodSpec void_monitor_enter_object;
425         static public MethodSpec void_monitor_exit_object;
426         static public MethodSpec void_initializearray_array_fieldhandle;
427         static public MethodSpec delegate_combine_delegate_delegate;
428         static public MethodSpec delegate_remove_delegate_delegate;
429         static public PropertySpec int_get_offset_to_string_data;
430         static public MethodSpec int_interlocked_compare_exchange;
431         public static MethodSpec gen_interlocked_compare_exchange;
432         static public PropertySpec ienumerator_getcurrent;
433         public static MethodSpec methodbase_get_type_from_handle;
434         public static MethodSpec methodbase_get_type_from_handle_generic;
435         public static MethodSpec fieldinfo_get_field_from_handle;
436         public static MethodSpec fieldinfo_get_field_from_handle_generic;
437         public static MethodSpec activator_create_instance;
438
439         //
440         // The constructors.
441         //
442         static public MethodSpec void_decimal_ctor_five_args;
443         static public MethodSpec void_decimal_ctor_int_arg;
444         public static MethodSpec void_decimal_ctor_long_arg;
445
446         static TypeManager ()
447         {
448                 Reset ();
449         }
450
451         static public void Reset ()
452         {
453 //              object_type = null;
454         
455                 // TODO: I am really bored by all this static stuff
456                 system_type_get_type_from_handle =
457                 bool_movenext_void =
458                 void_dispose_void =
459                 void_monitor_enter_object =
460                 void_monitor_exit_object =
461                 void_initializearray_array_fieldhandle =
462                 int_interlocked_compare_exchange =
463                 gen_interlocked_compare_exchange =
464                 methodbase_get_type_from_handle =
465                 methodbase_get_type_from_handle_generic =
466                 fieldinfo_get_field_from_handle =
467                 fieldinfo_get_field_from_handle_generic =
468                 activator_create_instance =
469                 delegate_combine_delegate_delegate =
470                 delegate_remove_delegate_delegate = null;
471
472                 int_get_offset_to_string_data =
473                 ienumerator_getcurrent = null;
474
475                 void_decimal_ctor_five_args =
476                 void_decimal_ctor_int_arg =
477                 void_decimal_ctor_long_arg = null;
478
479                 string_empty = null;
480
481                 generic_ilist_type = generic_icollection_type = generic_ienumerator_type =
482                 generic_ienumerable_type = generic_nullable_type = expression_type = null;
483         }
484
485         /// <summary>
486         ///   Returns the C# name of a type if possible, or the full type name otherwise
487         /// </summary>
488         static public string CSharpName (TypeSpec t)
489         {
490                 return t.GetSignatureForError ();
491         }
492
493         static public string CSharpName (IList<TypeSpec> types)
494         {
495                 if (types.Count == 0)
496                         return string.Empty;
497
498                 StringBuilder sb = new StringBuilder ();
499                 for (int i = 0; i < types.Count; ++i) {
500                         if (i > 0)
501                                 sb.Append (",");
502
503                         sb.Append (CSharpName (types [i]));
504                 }
505                 return sb.ToString ();
506         }
507
508         static public string GetFullNameSignature (MemberSpec mi)
509         {
510                 return mi.GetSignatureForError ();
511         }
512
513         static public string CSharpSignature (MemberSpec mb)
514         {
515                 return mb.GetSignatureForError ();
516         }
517
518         static MemberSpec GetPredefinedMember (TypeSpec t, MemberFilter filter, bool optional, Location loc)
519         {
520                 var member = MemberCache.FindMember (t, filter, BindingRestriction.DeclaredOnly);
521
522                 if (member != null && member.IsAccessible (InternalType.FakeInternalType))
523                         return member;
524
525                 if (optional)
526                         return member;
527
528                 string method_args = null;
529                 if (filter.Parameters != null)
530                         method_args = filter.Parameters.GetSignatureForError ();
531
532                 RootContext.ToplevelTypes.Compiler.Report.Error (656, loc, "The compiler required member `{0}.{1}{2}' could not be found or is inaccessible",
533                         TypeManager.CSharpName (t), filter.Name, method_args);
534
535                 return null;
536         }
537
538         //
539         // Returns the ConstructorInfo for "args"
540         //
541         public static MethodSpec GetPredefinedConstructor (TypeSpec t, Location loc, params TypeSpec [] args)
542         {
543                 var pc = ParametersCompiled.CreateFullyResolved (args);
544                 return GetPredefinedMember (t, MemberFilter.Constructor (pc), false, loc) as MethodSpec;
545         }
546
547         //
548         // Returns the method specification for a method named `name' defined
549         // in type `t' which takes arguments of types `args'
550         //
551         public static MethodSpec GetPredefinedMethod (TypeSpec t, string name, Location loc, params TypeSpec [] args)
552         {
553                 var pc = ParametersCompiled.CreateFullyResolved (args);
554                 return GetPredefinedMethod (t, MemberFilter.Method (name, 0, pc, null), false, loc);
555         }
556
557         public static MethodSpec GetPredefinedMethod (TypeSpec t, MemberFilter filter, Location loc)
558         {
559                 return GetPredefinedMethod (t, filter, false, loc);
560         }
561
562         public static MethodSpec GetPredefinedMethod (TypeSpec t, MemberFilter filter, bool optional, Location loc)
563         {
564                 return GetPredefinedMember (t, filter, optional, loc) as MethodSpec;
565         }
566
567         public static FieldSpec GetPredefinedField (TypeSpec t, string name, Location loc, TypeSpec type)
568         {
569                 return GetPredefinedMember (t, MemberFilter.Field (name, type), false, loc) as FieldSpec;
570         }
571
572         public static PropertySpec GetPredefinedProperty (TypeSpec t, string name, Location loc, TypeSpec type)
573         {
574                 return GetPredefinedMember (t, MemberFilter.Property (name, type), false, loc) as PropertySpec;
575         }
576
577         // Obsolete
578         public static bool IsDelegateType (TypeSpec t)
579         {
580                 return t.IsDelegate;
581         }
582         
583         // Obsolete
584         public static bool IsEnumType (TypeSpec t)
585         {
586                 return t.IsEnum;
587         }
588
589         //
590         // Whether a type is unmanaged.  This is used by the unsafe code (25.2)
591         //
592         public static bool IsUnmanagedType (TypeSpec t)
593         {
594                 var ds = t.MemberDefinition as DeclSpace;
595                 if (ds != null)
596                         return ds.IsUnmanagedType ();
597
598                 if (t.Kind == MemberKind.Void)
599                         return true;
600
601                 // Someone did the work of checking if the ElementType of t is unmanaged.  Let's not repeat it.
602                 if (t.IsPointer)
603                         return IsUnmanagedType (GetElementType (t));
604
605                 if (!IsValueType (t))
606                         return false;
607
608                 if (t.IsNested && t.DeclaringType.IsGenericOrParentIsGeneric)
609                         return false;
610
611                 return true;
612         }
613
614         //
615         // Null is considered to be a reference type
616         //                      
617         public static bool IsReferenceType (TypeSpec t)
618         {
619                 if (t.IsGenericParameter)
620                         return ((TypeParameterSpec) t).IsReferenceType;
621
622                 return !t.IsStruct && !IsEnumType (t);
623         }                       
624                 
625         public static bool IsValueType (TypeSpec t)
626         {
627                 if (t.IsGenericParameter)
628                         return ((TypeParameterSpec) t).IsValueType;
629
630                 return t.IsStruct || IsEnumType (t);
631         }
632
633         public static bool IsStruct (TypeSpec t)
634         {
635                 return t.IsStruct;
636         }
637
638         public static bool IsFamilyAccessible (TypeSpec type, TypeSpec parent)
639         {
640 //              TypeParameter tparam = LookupTypeParameter (type);
641 //              TypeParameter pparam = LookupTypeParameter (parent);
642
643                 if (type.Kind == MemberKind.TypeParameter && parent.Kind == MemberKind.TypeParameter) { // (tparam != null) && (pparam != null)) {
644                         if (type == parent)
645                                 return true;
646
647                         throw new NotImplementedException ("net");
648 //                      return tparam.IsSubclassOf (parent);
649                 }
650
651                 do {
652                         if (IsInstantiationOfSameGenericType (type, parent))
653                                 return true;
654
655                         type = type.BaseType;
656                 } while (type != null);
657
658                 return false;
659         }
660
661         //
662         // Checks whether `type' is a subclass or nested child of `base_type'.
663         //
664         public static bool IsNestedFamilyAccessible (TypeSpec type, TypeSpec base_type)
665         {
666                 do {
667                         if (IsFamilyAccessible (type, base_type))
668                                 return true;
669
670                         // Handle nested types.
671                         type = type.DeclaringType;
672                 } while (type != null);
673
674                 return false;
675         }
676
677         //
678         // Checks whether `type' is a nested child of `parent'.
679         //
680         public static bool IsNestedChildOf (TypeSpec type, ITypeDefinition parent)
681         {
682                 if (type == null)
683                         return false;
684
685                 if (type.MemberDefinition == parent)
686                         return false;
687
688                 type = type.DeclaringType;
689                 while (type != null) {
690                         if (type.MemberDefinition == parent)
691                                 return true;
692
693                         type = type.DeclaringType;
694                 }
695
696                 return false;
697         }
698
699         public static TypeSpec GetElementType (TypeSpec t)
700         {
701                 return ((ElementTypeSpec)t).Element;
702         }
703
704         /// <summary>
705         /// This method is not implemented by MS runtime for dynamic types
706         /// </summary>
707         public static bool HasElementType (TypeSpec t)
708         {
709                 return t is ElementTypeSpec;
710         }
711
712         /// <summary>
713         ///   Utility function that can be used to probe whether a type
714         ///   is managed or not.  
715         /// </summary>
716         public static bool VerifyUnmanaged (ModuleContainer rc, TypeSpec t, Location loc)
717         {
718                 while (t.IsPointer)
719                         t = GetElementType (t);
720
721                 if (IsUnmanagedType (t))
722                         return true;
723
724                 rc.Compiler.Report.SymbolRelatedToPreviousError (t);
725                 rc.Compiler.Report.Error (208, loc,
726                         "Cannot take the address of, get the size of, or declare a pointer to a managed type `{0}'",
727                         CSharpName (t));
728
729                 return false;   
730         }
731 #region Generics
732         // This method always return false for non-generic compiler,
733         // while Type.IsGenericParameter is returned if it is supported.
734         public static bool IsGenericParameter (TypeSpec type)
735         {
736                 return type.IsGenericParameter;
737         }
738
739         public static bool IsGenericType (TypeSpec type)
740         {
741                 return type.IsGeneric;
742         }
743
744         public static TypeSpec[] GetTypeArguments (TypeSpec t)
745         {
746                 // TODO: return empty array !!
747                 return t.TypeArguments;
748         }
749
750         /// <summary>
751         ///   Check whether `type' and `parent' are both instantiations of the same
752         ///   generic type.  Note that we do not check the type parameters here.
753         /// </summary>
754         public static bool IsInstantiationOfSameGenericType (TypeSpec type, TypeSpec parent)
755         {
756                 return type == parent || type.MemberDefinition == parent.MemberDefinition;
757         }
758
759         public static bool IsNullableType (TypeSpec t)
760         {
761                 return generic_nullable_type == t.GetDefinition ();
762         }
763 #endregion
764 }
765
766 }