BindingFlags.Public needed here as Exception.HResult is now public in .NET 4.5. This...
[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@gmail.com)
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-2011 Novell, Inc.
12 // Copyright 2011 Xamarin Inc
13 //
14
15 using System;
16 using System.Globalization;
17 using System.Collections.Generic;
18 using System.Text;
19 using System.IO;
20
21 namespace Mono.CSharp
22 {
23         //
24         // All compiler built-in types (they have to exist otherwise the compiler will not work)
25         //
26         public class BuiltinTypes
27         {
28                 public readonly BuiltinTypeSpec Object;
29                 public readonly BuiltinTypeSpec ValueType;
30                 public readonly BuiltinTypeSpec Attribute;
31
32                 public readonly BuiltinTypeSpec Int;
33                 public readonly BuiltinTypeSpec UInt;
34                 public readonly BuiltinTypeSpec Long;
35                 public readonly BuiltinTypeSpec ULong;
36                 public readonly BuiltinTypeSpec Float;
37                 public readonly BuiltinTypeSpec Double;
38                 public readonly BuiltinTypeSpec Char;
39                 public readonly BuiltinTypeSpec Short;
40                 public readonly BuiltinTypeSpec Decimal;
41                 public readonly BuiltinTypeSpec Bool;
42                 public readonly BuiltinTypeSpec SByte;
43                 public readonly BuiltinTypeSpec Byte;
44                 public readonly BuiltinTypeSpec UShort;
45                 public readonly BuiltinTypeSpec String;
46
47                 public readonly BuiltinTypeSpec Enum;
48                 public readonly BuiltinTypeSpec Delegate;
49                 public readonly BuiltinTypeSpec MulticastDelegate;
50                 public readonly BuiltinTypeSpec Void;
51                 public readonly BuiltinTypeSpec Array;
52                 public readonly BuiltinTypeSpec Type;
53                 public readonly BuiltinTypeSpec IEnumerator;
54                 public readonly BuiltinTypeSpec IEnumerable;
55                 public readonly BuiltinTypeSpec IDisposable;
56                 public readonly BuiltinTypeSpec IntPtr;
57                 public readonly BuiltinTypeSpec UIntPtr;
58                 public readonly BuiltinTypeSpec RuntimeFieldHandle;
59                 public readonly BuiltinTypeSpec RuntimeTypeHandle;
60                 public readonly BuiltinTypeSpec Exception;
61
62                 //
63                 // These are internal buil-in types which depend on other
64                 // build-in type (mostly object)
65                 //
66                 public readonly BuiltinTypeSpec Dynamic;
67
68                 // Predefined operators tables
69                 public readonly Binary.PredefinedOperator[] OperatorsBinaryStandard;
70                 public readonly Binary.PredefinedOperator[] OperatorsBinaryEquality;
71                 public readonly Binary.PredefinedOperator[] OperatorsBinaryUnsafe;
72                 public readonly TypeSpec[][] OperatorsUnary;
73                 public readonly TypeSpec[] OperatorsUnaryMutator;
74
75                 public readonly TypeSpec[] BinaryPromotionsTypes;
76                 public readonly TypeSpec[] SwitchUserTypes;
77
78                 readonly BuiltinTypeSpec[] types;
79
80                 public BuiltinTypes ()
81                 {
82                         Object = new BuiltinTypeSpec (MemberKind.Class, "System", "Object", BuiltinTypeSpec.Type.Object);
83                         ValueType = new BuiltinTypeSpec (MemberKind.Class, "System", "ValueType", BuiltinTypeSpec.Type.ValueType);
84                         Attribute = new BuiltinTypeSpec (MemberKind.Class, "System", "Attribute", BuiltinTypeSpec.Type.Attribute);
85
86                         Int = new BuiltinTypeSpec (MemberKind.Struct, "System", "Int32", BuiltinTypeSpec.Type.Int);
87                         Long = new BuiltinTypeSpec (MemberKind.Struct, "System", "Int64", BuiltinTypeSpec.Type.Long);
88                         UInt = new BuiltinTypeSpec (MemberKind.Struct, "System", "UInt32", BuiltinTypeSpec.Type.UInt);
89                         ULong = new BuiltinTypeSpec (MemberKind.Struct, "System", "UInt64", BuiltinTypeSpec.Type.ULong);
90                         Byte = new BuiltinTypeSpec (MemberKind.Struct, "System", "Byte", BuiltinTypeSpec.Type.Byte);
91                         SByte = new BuiltinTypeSpec (MemberKind.Struct, "System", "SByte", BuiltinTypeSpec.Type.SByte);
92                         Short = new BuiltinTypeSpec (MemberKind.Struct, "System", "Int16", BuiltinTypeSpec.Type.Short);
93                         UShort = new BuiltinTypeSpec (MemberKind.Struct, "System", "UInt16", BuiltinTypeSpec.Type.UShort);
94
95                         IEnumerator = new BuiltinTypeSpec (MemberKind.Interface, "System.Collections", "IEnumerator", BuiltinTypeSpec.Type.IEnumerator);
96                         IEnumerable = new BuiltinTypeSpec (MemberKind.Interface, "System.Collections", "IEnumerable", BuiltinTypeSpec.Type.IEnumerable);
97                         IDisposable = new BuiltinTypeSpec (MemberKind.Interface, "System", "IDisposable", BuiltinTypeSpec.Type.IDisposable);
98
99                         Char = new BuiltinTypeSpec (MemberKind.Struct, "System", "Char", BuiltinTypeSpec.Type.Char);
100                         String = new BuiltinTypeSpec (MemberKind.Class, "System", "String", BuiltinTypeSpec.Type.String);
101                         Float = new BuiltinTypeSpec (MemberKind.Struct, "System", "Single", BuiltinTypeSpec.Type.Float);
102                         Double = new BuiltinTypeSpec (MemberKind.Struct, "System", "Double", BuiltinTypeSpec.Type.Double);
103                         Decimal = new BuiltinTypeSpec (MemberKind.Struct, "System", "Decimal", BuiltinTypeSpec.Type.Decimal);
104                         Bool = new BuiltinTypeSpec (MemberKind.Struct, "System", "Boolean", BuiltinTypeSpec.Type.Bool);
105                         IntPtr = new BuiltinTypeSpec (MemberKind.Struct, "System", "IntPtr", BuiltinTypeSpec.Type.IntPtr);
106                         UIntPtr = new BuiltinTypeSpec (MemberKind.Struct, "System", "UIntPtr", BuiltinTypeSpec.Type.UIntPtr);
107
108                         MulticastDelegate = new BuiltinTypeSpec (MemberKind.Class, "System", "MulticastDelegate", BuiltinTypeSpec.Type.MulticastDelegate);
109                         Delegate = new BuiltinTypeSpec (MemberKind.Class, "System", "Delegate", BuiltinTypeSpec.Type.Delegate);
110                         Enum = new BuiltinTypeSpec (MemberKind.Class, "System", "Enum", BuiltinTypeSpec.Type.Enum);
111                         Array = new BuiltinTypeSpec (MemberKind.Class, "System", "Array", BuiltinTypeSpec.Type.Array);
112                         Void = new BuiltinTypeSpec (MemberKind.Void, "System", "Void", BuiltinTypeSpec.Type.Other);
113                         Type = new BuiltinTypeSpec (MemberKind.Class, "System", "Type", BuiltinTypeSpec.Type.Type);
114                         Exception = new BuiltinTypeSpec (MemberKind.Class, "System", "Exception", BuiltinTypeSpec.Type.Exception);
115                         RuntimeFieldHandle = new BuiltinTypeSpec (MemberKind.Struct, "System", "RuntimeFieldHandle", BuiltinTypeSpec.Type.Other);
116                         RuntimeTypeHandle = new BuiltinTypeSpec (MemberKind.Struct, "System", "RuntimeTypeHandle", BuiltinTypeSpec.Type.Other);
117
118                         // TODO: Maybe I should promote it to different kind for faster compares
119                         Dynamic = new BuiltinTypeSpec ("dynamic", BuiltinTypeSpec.Type.Dynamic);
120
121                         OperatorsBinaryStandard = Binary.CreateStandardOperatorsTable (this);
122                         OperatorsBinaryEquality = Binary.CreateEqualityOperatorsTable (this);
123                         OperatorsBinaryUnsafe = Binary.CreatePointerOperatorsTable (this);
124                         OperatorsUnary = Unary.CreatePredefinedOperatorsTable (this);
125                         OperatorsUnaryMutator = UnaryMutator.CreatePredefinedOperatorsTable (this);
126
127                         BinaryPromotionsTypes = ConstantFold.CreateBinaryPromotionsTypes (this);
128                         SwitchUserTypes = Switch.CreateSwitchUserTypes (this);
129
130                         types = new BuiltinTypeSpec[] {
131                                 Object, ValueType, Attribute,
132                                 Int, UInt, Long, ULong, Float, Double, Char, Short, Decimal, Bool, SByte, Byte, UShort, String,
133                                 Enum, Delegate, MulticastDelegate, Void, Array, Type, IEnumerator, IEnumerable, IDisposable,
134                                 IntPtr, UIntPtr, RuntimeFieldHandle, RuntimeTypeHandle, Exception };
135                 }
136
137                 public BuiltinTypeSpec[] AllTypes {
138                         get {
139                                 return types;
140                         }
141                 }
142
143                 public bool CheckDefinitions (ModuleContainer module)
144                 {
145                         var ctx = module.Compiler;
146                         foreach (var p in types) {
147                                 var found = PredefinedType.Resolve (module, p.Kind, p.Namespace, p.Name, p.Arity);
148                                 if (found == null || found == p)
149                                         continue;
150
151                                 var tc = found.MemberDefinition as TypeDefinition;
152                                 if (tc != null) {
153                                         var ns = module.GlobalRootNamespace.GetNamespace (p.Namespace, false);
154                                         ns.SetBuiltinType (p);
155
156                                         tc.SetPredefinedSpec (p);
157                                         p.SetDefinition (found);
158                                 }
159                         }
160
161                         if (ctx.Report.Errors != 0)
162                                 return false;
163
164                         // Set internal build-in types
165                         Dynamic.SetDefinition (Object);
166
167                         return true;
168                 }
169         }
170
171         //
172         // Compiler predefined types. Usually used for compiler generated
173         // code or for comparison against well known framework type. They
174         // may not exist as they are optional
175         //
176         class PredefinedTypes
177         {
178                 public readonly PredefinedType ArgIterator;
179                 public readonly PredefinedType TypedReference;
180                 public readonly PredefinedType MarshalByRefObject;
181                 public readonly PredefinedType RuntimeHelpers;
182                 public readonly PredefinedType IAsyncResult;
183                 public readonly PredefinedType AsyncCallback;
184                 public readonly PredefinedType RuntimeArgumentHandle;
185                 public readonly PredefinedType CharSet;
186                 public readonly PredefinedType IsVolatile;
187                 public readonly PredefinedType IEnumeratorGeneric;
188                 public readonly PredefinedType IListGeneric;
189                 public readonly PredefinedType ICollectionGeneric;
190                 public readonly PredefinedType IEnumerableGeneric;
191                 public readonly PredefinedType Nullable;
192                 public readonly PredefinedType Activator;
193                 public readonly PredefinedType Interlocked;
194                 public readonly PredefinedType Monitor;
195                 public readonly PredefinedType NotSupportedException;
196                 public readonly PredefinedType RuntimeFieldHandle;
197                 public readonly PredefinedType RuntimeMethodHandle;
198                 public readonly PredefinedType SecurityAction;
199                 public readonly PredefinedType Dictionary;
200                 public readonly PredefinedType Hashtable;
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                 public readonly PredefinedType MemberBinding;
213
214                 //
215                 // C# 4.0
216                 //
217                 public readonly PredefinedType Binder;
218                 public readonly PredefinedType CallSite;
219                 public readonly PredefinedType CallSiteGeneric;
220                 public readonly PredefinedType BinderFlags;
221
222                 //
223                 // C# 5.0
224                 //
225                 public readonly PredefinedType AsyncVoidMethodBuilder;
226                 public readonly PredefinedType AsyncTaskMethodBuilder;
227                 public readonly PredefinedType AsyncTaskMethodBuilderGeneric;
228                 public readonly PredefinedType Action;
229                 public readonly PredefinedType Task;
230                 public readonly PredefinedType TaskGeneric;
231                 public readonly PredefinedType IAsyncStateMachine;
232                 public readonly PredefinedType INotifyCompletion;
233                 public readonly PredefinedType ICriticalNotifyCompletion;
234
235                 public PredefinedTypes (ModuleContainer module)
236                 {
237                         TypedReference = new PredefinedType (module, MemberKind.Struct, "System", "TypedReference");
238                         ArgIterator = new PredefinedType (module, MemberKind.Struct, "System", "ArgIterator");
239
240                         MarshalByRefObject = new PredefinedType (module, MemberKind.Class, "System", "MarshalByRefObject");
241                         RuntimeHelpers = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "RuntimeHelpers");
242                         IAsyncResult = new PredefinedType (module, MemberKind.Interface, "System", "IAsyncResult");
243                         AsyncCallback = new PredefinedType (module, MemberKind.Delegate, "System", "AsyncCallback");
244                         RuntimeArgumentHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeArgumentHandle");
245                         CharSet = new PredefinedType (module, MemberKind.Enum, "System.Runtime.InteropServices", "CharSet");
246                         IsVolatile = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "IsVolatile");
247                         IEnumeratorGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IEnumerator", 1);
248                         IListGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IList", 1);
249                         ICollectionGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "ICollection", 1);
250                         IEnumerableGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IEnumerable", 1);
251                         Nullable = new PredefinedType (module, MemberKind.Struct, "System", "Nullable", 1);
252                         Activator = new PredefinedType (module, MemberKind.Class, "System", "Activator");
253                         Interlocked = new PredefinedType (module, MemberKind.Class, "System.Threading", "Interlocked");
254                         Monitor = new PredefinedType (module, MemberKind.Class, "System.Threading", "Monitor");
255                         NotSupportedException = new PredefinedType (module, MemberKind.Class, "System", "NotSupportedException");
256                         RuntimeFieldHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeFieldHandle");
257                         RuntimeMethodHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeMethodHandle");
258                         SecurityAction = new PredefinedType (module, MemberKind.Enum, "System.Security.Permissions", "SecurityAction");
259                         Dictionary = new PredefinedType (module, MemberKind.Class, "System.Collections.Generic", "Dictionary", 2);
260                         Hashtable = new PredefinedType (module, MemberKind.Class, "System.Collections", "Hashtable");
261
262                         Expression = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "Expression");
263                         ExpressionGeneric = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "Expression", 1);
264                         MemberBinding = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "MemberBinding");
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                         Action = new PredefinedType (module, MemberKind.Delegate, "System", "Action");
277                         AsyncVoidMethodBuilder = new PredefinedType (module, MemberKind.Struct, "System.Runtime.CompilerServices", "AsyncVoidMethodBuilder");
278                         AsyncTaskMethodBuilder = new PredefinedType (module, MemberKind.Struct, "System.Runtime.CompilerServices", "AsyncTaskMethodBuilder");
279                         AsyncTaskMethodBuilderGeneric = new PredefinedType (module, MemberKind.Struct, "System.Runtime.CompilerServices", "AsyncTaskMethodBuilder", 1);
280                         Task = new PredefinedType (module, MemberKind.Class, "System.Threading.Tasks", "Task");
281                         TaskGeneric = new PredefinedType (module, MemberKind.Class, "System.Threading.Tasks", "Task", 1);
282                         IAsyncStateMachine = new PredefinedType (module, MemberKind.Interface, "System.Runtime.CompilerServices", "IAsyncStateMachine");
283                         INotifyCompletion = new PredefinedType (module, MemberKind.Interface, "System.Runtime.CompilerServices", "INotifyCompletion");
284                         ICriticalNotifyCompletion = new PredefinedType (module, MemberKind.Interface, "System.Runtime.CompilerServices", "ICriticalNotifyCompletion");
285
286                         //
287                         // Define types which are used for comparison. It does not matter
288                         // if they don't exist as no error report is needed
289                         //
290                         if (TypedReference.Define ())
291                                 TypedReference.TypeSpec.IsSpecialRuntimeType = true;
292
293                         if (ArgIterator.Define ())
294                                 ArgIterator.TypeSpec.IsSpecialRuntimeType = true;
295
296                         if (IEnumerableGeneric.Define ())
297                                 IEnumerableGeneric.TypeSpec.IsGenericIterateInterface = true;
298
299                         if (IListGeneric.Define ())
300                                 IListGeneric.TypeSpec.IsGenericIterateInterface = true;
301
302                         if (ICollectionGeneric.Define ())
303                                 ICollectionGeneric.TypeSpec.IsGenericIterateInterface = true;
304
305                         if (Nullable.Define ())
306                                 Nullable.TypeSpec.IsNullableType = true;
307
308                         if (ExpressionGeneric.Define ())
309                                 ExpressionGeneric.TypeSpec.IsExpressionTreeType = true;
310
311                         Task.Define ();
312                         if (TaskGeneric.Define ())
313                                 TaskGeneric.TypeSpec.IsGenericTask = true;
314                 }
315         }
316
317         class PredefinedMembers
318         {
319                 public readonly PredefinedMember<MethodSpec> ActivatorCreateInstance;
320                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderCreate;
321                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderStart;
322                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderSetResult;
323                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderSetException;
324                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderSetStateMachine;
325                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderOnCompleted;
326                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderOnCompletedUnsafe;
327                 public readonly PredefinedMember<PropertySpec> AsyncTaskMethodBuilderTask;
328                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericCreate;
329                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericStart;
330                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericSetResult;
331                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericSetException;
332                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericSetStateMachine;
333                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericOnCompleted;
334                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericOnCompletedUnsafe;
335                 public readonly PredefinedMember<PropertySpec> AsyncTaskMethodBuilderGenericTask;
336                 public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderCreate;
337                 public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderStart;
338                 public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderSetException;
339                 public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderSetResult;
340                 public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderSetStateMachine;
341                 public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderOnCompleted;
342                 public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderOnCompletedUnsafe;
343                 public readonly PredefinedMember<MethodSpec> DebuggerBrowsableAttributeCtor;
344                 public readonly PredefinedMember<MethodSpec> DecimalCtor;
345                 public readonly PredefinedMember<MethodSpec> DecimalCtorInt;
346                 public readonly PredefinedMember<MethodSpec> DecimalCtorLong;
347                 public readonly PredefinedMember<MethodSpec> DecimalConstantAttributeCtor;
348                 public readonly PredefinedMember<MethodSpec> DefaultMemberAttributeCtor;
349                 public readonly PredefinedMember<MethodSpec> DelegateCombine;
350                 public readonly PredefinedMember<MethodSpec> DelegateEqual;
351                 public readonly PredefinedMember<MethodSpec> DelegateInequal;
352                 public readonly PredefinedMember<MethodSpec> DelegateRemove;
353                 public readonly PredefinedMember<MethodSpec> DynamicAttributeCtor;
354                 public readonly PredefinedMember<MethodSpec> FieldInfoGetFieldFromHandle;
355                 public readonly PredefinedMember<MethodSpec> FieldInfoGetFieldFromHandle2;
356                 public readonly PredefinedMember<MethodSpec> IDisposableDispose;
357                 public readonly PredefinedMember<MethodSpec> IEnumerableGetEnumerator;
358                 public readonly PredefinedMember<MethodSpec> InterlockedCompareExchange;
359                 public readonly PredefinedMember<MethodSpec> InterlockedCompareExchange_T;
360                 public readonly PredefinedMember<MethodSpec> FixedBufferAttributeCtor;
361                 public readonly PredefinedMember<MethodSpec> MethodInfoGetMethodFromHandle;
362                 public readonly PredefinedMember<MethodSpec> MethodInfoGetMethodFromHandle2;
363                 public readonly PredefinedMember<MethodSpec> MonitorEnter;
364                 public readonly PredefinedMember<MethodSpec> MonitorEnter_v4;
365                 public readonly PredefinedMember<MethodSpec> MonitorExit;
366                 public readonly PredefinedMember<PropertySpec> RuntimeCompatibilityWrapNonExceptionThrows;
367                 public readonly PredefinedMember<MethodSpec> RuntimeHelpersInitializeArray;
368                 public readonly PredefinedMember<PropertySpec> RuntimeHelpersOffsetToStringData;
369                 public readonly PredefinedMember<ConstSpec> SecurityActionRequestMinimum;
370                 public readonly PredefinedMember<FieldSpec> StringEmpty;
371                 public readonly PredefinedMember<MethodSpec> StringEqual;
372                 public readonly PredefinedMember<MethodSpec> StringInequal;
373                 public readonly PredefinedMember<MethodSpec> StructLayoutAttributeCtor;
374                 public readonly PredefinedMember<FieldSpec> StructLayoutCharSet;
375                 public readonly PredefinedMember<FieldSpec> StructLayoutSize;
376                 public readonly PredefinedMember<MethodSpec> TypeGetTypeFromHandle;
377
378                 public PredefinedMembers (ModuleContainer module)
379                 {
380                         var types = module.PredefinedTypes;
381                         var atypes = module.PredefinedAttributes;
382                         var btypes = module.Compiler.BuiltinTypes;
383
384                         var tp = new TypeParameter (0, new MemberName ("T"), null, null, Variance.None);
385
386                         ActivatorCreateInstance = new PredefinedMember<MethodSpec> (module, types.Activator,
387                                 MemberFilter.Method ("CreateInstance", 1, ParametersCompiled.EmptyReadOnlyParameters, null));
388
389                         AsyncTaskMethodBuilderCreate = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
390                                 MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, types.AsyncTaskMethodBuilder.TypeSpec));
391
392                         AsyncTaskMethodBuilderSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
393                                 MemberFilter.Method ("SetResult", 0, ParametersCompiled.EmptyReadOnlyParameters, btypes.Void));
394
395                         AsyncTaskMethodBuilderSetStateMachine = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
396                                 "SetStateMachine", MemberKind.Method, () => new[] {
397                                                 types.IAsyncStateMachine.TypeSpec
398                                 }, btypes.Void);
399
400                         AsyncTaskMethodBuilderSetException = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
401                                 MemberFilter.Method ("SetException", 0,
402                                 ParametersCompiled.CreateFullyResolved (btypes.Exception), btypes.Void));
403
404                         AsyncTaskMethodBuilderOnCompleted = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
405                                 MemberFilter.Method ("AwaitOnCompleted", 2,
406                                         new ParametersImported (
407                                                 new[] {
408                                                                 new ParameterData (null, Parameter.Modifier.REF),
409                                                                 new ParameterData (null, Parameter.Modifier.REF)
410                                                         },
411                                                 new[] {
412                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
413                                                                 new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
414                                                         }, false),
415                                         btypes.Void));
416
417                         AsyncTaskMethodBuilderOnCompletedUnsafe = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
418                                 MemberFilter.Method ("AwaitUnsafeOnCompleted", 2,
419                                         new ParametersImported (
420                                                 new[] {
421                                                                 new ParameterData (null, Parameter.Modifier.REF),
422                                                                 new ParameterData (null, Parameter.Modifier.REF)
423                                                         },
424                                                 new[] {
425                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
426                                                                 new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
427                                                         }, false),
428                                         btypes.Void));
429
430                         AsyncTaskMethodBuilderStart = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
431                                 MemberFilter.Method ("Start", 1,
432                                         new ParametersImported (
433                                                 new[] {
434                                                                 new ParameterData (null, Parameter.Modifier.REF),
435                                                         },
436                                                 new[] {
437                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
438                                                         }, false),
439                                         btypes.Void));
440
441                         AsyncTaskMethodBuilderTask = new PredefinedMember<PropertySpec> (module, types.AsyncTaskMethodBuilder,
442                                 MemberFilter.Property ("Task", null));
443
444                         AsyncTaskMethodBuilderGenericCreate = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
445                                 MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, types.AsyncVoidMethodBuilder.TypeSpec));
446
447                         AsyncTaskMethodBuilderGenericSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
448                                 "SetResult", MemberKind.Method, () => new TypeSpec[] {
449                                                 types.AsyncTaskMethodBuilderGeneric.TypeSpec.MemberDefinition.TypeParameters[0]
450                                 }, btypes.Void);
451
452                         AsyncTaskMethodBuilderGenericSetStateMachine = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
453                                 "SetStateMachine", MemberKind.Method, () => new[] {
454                                                 types.IAsyncStateMachine.TypeSpec
455                                 }, btypes.Void);
456
457                         AsyncTaskMethodBuilderGenericSetException = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
458                                 MemberFilter.Method ("SetException", 0,
459                                 ParametersCompiled.CreateFullyResolved (btypes.Exception), btypes.Void));
460
461                         AsyncTaskMethodBuilderGenericOnCompleted = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
462                                 MemberFilter.Method ("AwaitOnCompleted", 2,
463                                         new ParametersImported (
464                                                 new[] {
465                                                                 new ParameterData (null, Parameter.Modifier.REF),
466                                                                 new ParameterData (null, Parameter.Modifier.REF)
467                                                         },
468                                                 new[] {
469                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
470                                                                 new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
471                                                         }, false),
472                                         btypes.Void));
473
474                         AsyncTaskMethodBuilderGenericOnCompletedUnsafe = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
475                                 MemberFilter.Method ("AwaitUnsafeOnCompleted", 2,
476                                         new ParametersImported (
477                                                 new[] {
478                                                                 new ParameterData (null, Parameter.Modifier.REF),
479                                                                 new ParameterData (null, Parameter.Modifier.REF)
480                                                         },
481                                                 new[] {
482                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
483                                                                 new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
484                                                         }, false),
485                                         btypes.Void));
486
487                         AsyncTaskMethodBuilderGenericStart = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
488                                 MemberFilter.Method ("Start", 1,
489                                         new ParametersImported (
490                                                 new[] {
491                                                                 new ParameterData (null, Parameter.Modifier.REF),
492                                                         },
493                                                 new[] {
494                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
495                                                         }, false),
496                                         btypes.Void));
497
498                         AsyncTaskMethodBuilderGenericTask = new PredefinedMember<PropertySpec> (module, types.AsyncTaskMethodBuilderGeneric,
499                                 MemberFilter.Property ("Task", null));
500
501                         AsyncVoidMethodBuilderCreate = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
502                                 MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, types.AsyncVoidMethodBuilder.TypeSpec));
503
504                         AsyncVoidMethodBuilderSetException = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
505                                 MemberFilter.Method ("SetException", 0, null, btypes.Void));
506
507                         AsyncVoidMethodBuilderSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
508                                 MemberFilter.Method ("SetResult", 0, ParametersCompiled.EmptyReadOnlyParameters, btypes.Void));
509
510                         AsyncVoidMethodBuilderSetStateMachine = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
511                                 "SetStateMachine", MemberKind.Method, () => new[] {
512                                                 types.IAsyncStateMachine.TypeSpec
513                                 }, btypes.Void);
514
515                         AsyncVoidMethodBuilderOnCompleted = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
516                                 MemberFilter.Method ("AwaitOnCompleted", 2,
517                                         new ParametersImported (
518                                                 new[] {
519                                                                 new ParameterData (null, Parameter.Modifier.REF),
520                                                                 new ParameterData (null, Parameter.Modifier.REF)
521                                                         },
522                                                 new[] {
523                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
524                                                                 new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
525                                                         }, false),
526                                         btypes.Void));
527
528                         AsyncVoidMethodBuilderOnCompletedUnsafe = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
529                                 MemberFilter.Method ("AwaitUnsafeOnCompleted", 2,
530                                         new ParametersImported (
531                                                 new[] {
532                                                                 new ParameterData (null, Parameter.Modifier.REF),
533                                                                 new ParameterData (null, Parameter.Modifier.REF)
534                                                         },
535                                                 new[] {
536                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
537                                                                 new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
538                                                         }, false),
539                                         btypes.Void));
540
541                         AsyncVoidMethodBuilderStart = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
542                                 MemberFilter.Method ("Start", 1,
543                                         new ParametersImported (
544                                                 new[] {
545                                                                 new ParameterData (null, Parameter.Modifier.REF),
546                                                         },
547                                                 new[] {
548                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
549                                                         }, false),
550                                         btypes.Void));
551
552                         DebuggerBrowsableAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.DebuggerBrowsable,
553                                 MemberFilter.Constructor (null));
554
555                         DecimalCtor = new PredefinedMember<MethodSpec> (module, btypes.Decimal,
556                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
557                                         btypes.Int, btypes.Int, btypes.Int, btypes.Bool, btypes.Byte)));
558
559                         DecimalCtorInt = new PredefinedMember<MethodSpec> (module, btypes.Decimal,
560                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Int)));
561
562                         DecimalCtorLong = new PredefinedMember<MethodSpec> (module, btypes.Decimal,
563                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Long)));
564
565                         DecimalConstantAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.DecimalConstant,
566                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
567                                         btypes.Byte, btypes.Byte, btypes.UInt, btypes.UInt, btypes.UInt)));
568
569                         DefaultMemberAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.DefaultMember,
570                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.String)));
571
572                         DelegateCombine = new PredefinedMember<MethodSpec> (module, btypes.Delegate, "Combine", btypes.Delegate, btypes.Delegate);
573                         DelegateRemove = new PredefinedMember<MethodSpec> (module, btypes.Delegate, "Remove", btypes.Delegate, btypes.Delegate);
574
575                         DelegateEqual = new PredefinedMember<MethodSpec> (module, btypes.Delegate,
576                                 new MemberFilter (Operator.GetMetadataName (Operator.OpType.Equality), 0, MemberKind.Operator, null, btypes.Bool));
577
578                         DelegateInequal = new PredefinedMember<MethodSpec> (module, btypes.Delegate,
579                                 new MemberFilter (Operator.GetMetadataName (Operator.OpType.Inequality), 0, MemberKind.Operator, null, btypes.Bool));
580
581                         DynamicAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.Dynamic,
582                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
583                                         ArrayContainer.MakeType (module, btypes.Bool))));
584
585                         FieldInfoGetFieldFromHandle = new PredefinedMember<MethodSpec> (module, types.FieldInfo,
586                                 "GetFieldFromHandle", MemberKind.Method, types.RuntimeFieldHandle);
587
588                         FieldInfoGetFieldFromHandle2 = new PredefinedMember<MethodSpec> (module, types.FieldInfo,
589                                 "GetFieldFromHandle", MemberKind.Method, types.RuntimeFieldHandle, new PredefinedType (btypes.RuntimeTypeHandle));
590
591                         FixedBufferAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.FixedBuffer,
592                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Type, btypes.Int)));
593
594                         IDisposableDispose = new PredefinedMember<MethodSpec> (module, btypes.IDisposable, "Dispose", TypeSpec.EmptyTypes);
595
596                         IEnumerableGetEnumerator = new PredefinedMember<MethodSpec> (module, btypes.IEnumerable,
597                                 "GetEnumerator", TypeSpec.EmptyTypes);
598
599                         InterlockedCompareExchange = new PredefinedMember<MethodSpec> (module, types.Interlocked,
600                                 MemberFilter.Method ("CompareExchange", 0,
601                                         new ParametersImported (
602                                                 new[] {
603                                                                 new ParameterData (null, Parameter.Modifier.REF),
604                                                                 new ParameterData (null, Parameter.Modifier.NONE),
605                                                                 new ParameterData (null, Parameter.Modifier.NONE)
606                                                         },
607                                                 new[] {
608                                                                 btypes.Int, btypes.Int, btypes.Int
609                                                         },
610                                                 false),
611                                 btypes.Int));
612
613                         InterlockedCompareExchange_T = new PredefinedMember<MethodSpec> (module, types.Interlocked,
614                                 MemberFilter.Method ("CompareExchange", 1,
615                                         new ParametersImported (
616                                                 new[] {
617                                                                 new ParameterData (null, Parameter.Modifier.REF),
618                                                                 new ParameterData (null, Parameter.Modifier.NONE),
619                                                                 new ParameterData (null, Parameter.Modifier.NONE)
620                                                         },
621                                                 new[] {
622                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
623                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
624                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
625                                                         }, false),
626                                         null));
627
628                         MethodInfoGetMethodFromHandle = new PredefinedMember<MethodSpec> (module, types.MethodBase,
629                                 "GetMethodFromHandle", MemberKind.Method, types.RuntimeMethodHandle);
630
631                         MethodInfoGetMethodFromHandle2 = new PredefinedMember<MethodSpec> (module, types.MethodBase,
632                                 "GetMethodFromHandle", MemberKind.Method, types.RuntimeMethodHandle, new PredefinedType (btypes.RuntimeTypeHandle));
633
634                         MonitorEnter = new PredefinedMember<MethodSpec> (module, types.Monitor, "Enter", btypes.Object);
635
636                         MonitorEnter_v4 = new PredefinedMember<MethodSpec> (module, types.Monitor,
637                                 MemberFilter.Method ("Enter", 0,
638                                         new ParametersImported (new[] {
639                                                         new ParameterData (null, Parameter.Modifier.NONE),
640                                                         new ParameterData (null, Parameter.Modifier.REF)
641                                                 },
642                                         new[] {
643                                                         btypes.Object, btypes.Bool
644                                                 }, false), null));
645
646                         MonitorExit = new PredefinedMember<MethodSpec> (module, types.Monitor, "Exit", btypes.Object);
647
648                         RuntimeCompatibilityWrapNonExceptionThrows = new PredefinedMember<PropertySpec> (module, atypes.RuntimeCompatibility,
649                                 MemberFilter.Property ("WrapNonExceptionThrows", btypes.Bool));
650
651                         RuntimeHelpersInitializeArray = new PredefinedMember<MethodSpec> (module, types.RuntimeHelpers,
652                                 "InitializeArray", btypes.Array, btypes.RuntimeFieldHandle);
653
654                         RuntimeHelpersOffsetToStringData = new PredefinedMember<PropertySpec> (module, types.RuntimeHelpers,
655                                 MemberFilter.Property ("OffsetToStringData", btypes.Int));
656
657                         SecurityActionRequestMinimum = new PredefinedMember<ConstSpec> (module, types.SecurityAction, "RequestMinimum",
658                                 MemberKind.Field, types.SecurityAction);
659
660                         StringEmpty = new PredefinedMember<FieldSpec> (module, btypes.String, MemberFilter.Field ("Empty", btypes.String));
661
662                         StringEqual = new PredefinedMember<MethodSpec> (module, btypes.String,
663                                 new MemberFilter (Operator.GetMetadataName (Operator.OpType.Equality), 0, MemberKind.Operator, null, btypes.Bool));
664
665                         StringInequal = new PredefinedMember<MethodSpec> (module, btypes.String,
666                                 new MemberFilter (Operator.GetMetadataName (Operator.OpType.Inequality), 0, MemberKind.Operator, null, btypes.Bool));
667
668                         StructLayoutAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.StructLayout,
669                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Short)));
670
671                         StructLayoutCharSet = new PredefinedMember<FieldSpec> (module, atypes.StructLayout, "CharSet",
672                                 MemberKind.Field, types.CharSet);
673
674                         StructLayoutSize = new PredefinedMember<FieldSpec> (module, atypes.StructLayout,
675                                 MemberFilter.Field ("Size", btypes.Int));
676
677                         TypeGetTypeFromHandle = new PredefinedMember<MethodSpec> (module, btypes.Type, "GetTypeFromHandle", btypes.RuntimeTypeHandle);
678                 }
679         }
680
681         public class PredefinedType
682         {
683                 readonly string name;
684                 readonly string ns;
685                 readonly int arity;
686                 readonly MemberKind kind;
687                 protected readonly ModuleContainer module;
688                 protected TypeSpec type;
689
690                 public PredefinedType (ModuleContainer module, MemberKind kind, string ns, string name, int arity)
691                         : this (module, kind, ns, name)
692                 {
693                         this.arity = arity;
694                 }
695
696                 public PredefinedType (ModuleContainer module, MemberKind kind, string ns, string name)
697                 {
698                         this.module = module;
699                         this.kind = kind;
700                         this.name = name;
701                         this.ns = ns;
702                 }
703
704                 public PredefinedType (BuiltinTypeSpec type)
705                 {
706                         this.kind = type.Kind;
707                         this.name = type.Name;
708                         this.ns = type.Namespace;
709                         this.type = type;
710                 }
711
712                 #region Properties
713
714                 public int Arity {
715                         get {
716                                 return arity;
717                         }
718                 }
719
720                 public bool IsDefined {
721                         get {
722                                 return type != null;
723                         }
724                 }
725
726                 public string Name {
727                         get {
728                                 return name;
729                         }
730                 }
731
732                 public string Namespace {
733                         get {
734                                 return ns;
735                         }
736                 }
737
738                 public TypeSpec TypeSpec {
739                         get {
740                                 return type;
741                         }
742                 }
743
744                 #endregion
745
746                 public bool Define ()
747                 {
748                         if (type != null)
749                                 return true;
750
751                         type = Resolve (module, kind, ns, name, arity, false);
752                         return type != null;
753                 }
754
755                 public string GetSignatureForError ()
756                 {
757                         return ns + "." + name;
758                 }
759
760                 public static TypeSpec Resolve (ModuleContainer module, MemberKind kind, string ns, string name, int arity)
761                 {
762                         return Resolve (module, kind, ns, name, arity, true);
763                 }
764
765                 public static TypeSpec Resolve (ModuleContainer module, MemberKind kind, string ns, string name, int arity, bool reportErrors)
766                 {
767                         Namespace type_ns = module.GlobalRootNamespace.GetNamespace (ns, true);
768                         var found = type_ns.GetAllTypes (name);
769                         if (found == null) {
770                                 if (reportErrors)
771                                         module.Compiler.Report.Error (518, "The predefined type `{0}.{1}' is not defined or imported", ns, name);
772
773                                 return null;
774                         }
775
776                         TypeSpec best_match = null;
777                         foreach (var candidate in found) {
778                                 if (candidate.Kind != kind) {
779                                         if (candidate.Kind == MemberKind.Struct && kind == MemberKind.Void && candidate.MemberDefinition is TypeContainer) {
780                                                 // Void is declared as struct but we keep it internally as
781                                                 // special kind, the swap will be done by caller
782                                         } else {
783                                                 continue;
784                                         }
785                                 }
786
787                                 if (candidate.Arity != arity)
788                                         continue;
789
790                                 if ((candidate.Modifiers & Modifiers.INTERNAL) != 0 && !candidate.MemberDefinition.IsInternalAsPublic (module.DeclaringAssembly))
791                                         continue;
792
793                                 if (best_match == null) {
794                                         best_match = candidate;
795                                         continue;
796                                 }
797
798                                 var other_match = best_match;
799                                 if (!best_match.MemberDefinition.IsImported &&
800                                         module.Compiler.BuiltinTypes.Object.MemberDefinition.DeclaringAssembly == candidate.MemberDefinition.DeclaringAssembly) {
801                                         best_match = candidate;
802                                 }
803
804                                 string location;
805                                 if (best_match.MemberDefinition is MemberCore) {
806                                         location = ((MemberCore) best_match.MemberDefinition).Location.Name;
807                                 } else {
808                                         var assembly = (ImportedAssemblyDefinition) best_match.MemberDefinition.DeclaringAssembly;
809                                         location = Path.GetFileName (assembly.Location);
810                                 }
811
812                                 module.Compiler.Report.SymbolRelatedToPreviousError (other_match);
813                                 module.Compiler.Report.SymbolRelatedToPreviousError (candidate);
814
815                                 module.Compiler.Report.Warning (1685, 1,
816                                         "The predefined type `{0}.{1}' is defined multiple times. Using definition from `{2}'",
817                                         ns, name, location);
818
819                                 break;
820                         }
821
822                         if (best_match == null && reportErrors) {
823                                 Location loc;
824                                 if (found[0].MemberDefinition is MemberCore) {
825                                         loc = ((MemberCore) found[0].MemberDefinition).Location;
826                                 } else {
827                                         loc = Location.Null;
828                                         module.Compiler.Report.SymbolRelatedToPreviousError (found[0]);
829                                 }
830
831                                 module.Compiler.Report.Error (520, loc, "The predefined type `{0}.{1}' is not declared correctly", ns, name);
832                         }
833
834                         return best_match;
835                 }
836
837                 public TypeSpec Resolve ()
838                 {
839                         if (type == null)
840                                 type = Resolve (module, kind, ns, name, arity);
841
842                         return type;
843                 }
844         }
845
846         class PredefinedMember<T> where T : MemberSpec
847         {
848                 readonly ModuleContainer module;
849                 T member;
850                 TypeSpec declaring_type;
851                 readonly PredefinedType declaring_type_predefined;
852                 MemberFilter filter;
853                 readonly Func<TypeSpec[]> filter_builder;
854
855                 public PredefinedMember (ModuleContainer module, PredefinedType type, MemberFilter filter)
856                 {
857                         this.module = module;
858                         this.declaring_type_predefined = type;
859                         this.filter = filter;
860                 }
861
862                 public PredefinedMember (ModuleContainer module, TypeSpec type, MemberFilter filter)
863                 {
864                         this.module = module;
865                         this.declaring_type = type;
866                         this.filter = filter;
867                 }
868
869                 public PredefinedMember (ModuleContainer module, PredefinedType type, string name, params TypeSpec[] types)
870                         : this (module, type, MemberFilter.Method (name, 0, ParametersCompiled.CreateFullyResolved (types), null))
871                 {
872                 }
873
874                 public PredefinedMember (ModuleContainer module, PredefinedType type, string name, MemberKind kind, params PredefinedType[] types)
875                         : this (module, type, new MemberFilter (name, 0, kind, null, null))
876                 {
877                         filter_builder = () => {
878                                 var ptypes = new TypeSpec[types.Length];
879                                 for (int i = 0; i < ptypes.Length; ++i) {
880                                         var p = types[i];
881                                         if (!p.Define ())
882                                                 return null;
883
884                                         ptypes[i] = p.TypeSpec;
885                                 }
886
887                                 return ptypes;
888                         };
889                 }
890
891                 public PredefinedMember (ModuleContainer module, PredefinedType type, string name, MemberKind kind, Func<TypeSpec[]> typesBuilder, TypeSpec returnType)
892                         : this (module, type, new MemberFilter (name, 0, kind, null, returnType))
893                 {
894                         filter_builder = typesBuilder;
895                 }
896
897                 public PredefinedMember (ModuleContainer module, BuiltinTypeSpec type, string name, params TypeSpec[] types)
898                         : this (module, type, MemberFilter.Method (name, 0, ParametersCompiled.CreateFullyResolved (types), null))
899                 {
900                 }
901
902                 public T Get ()
903                 {
904                         if (member != null)
905                                 return member;
906
907                         if (declaring_type == null) {
908                                 if (!declaring_type_predefined.Define ())
909                                         return null;
910
911                                 declaring_type = declaring_type_predefined.TypeSpec;
912                         }
913
914                         if (filter_builder != null) {
915                                 var types = filter_builder ();
916
917                                 if (filter.Kind == MemberKind.Field)
918                                         filter = new MemberFilter (filter.Name, filter.Arity, filter.Kind, null, types [0]);
919                                 else
920                                         filter = new MemberFilter (filter.Name, filter.Arity, filter.Kind,
921                                                 ParametersCompiled.CreateFullyResolved (types), filter.MemberType);
922                         }
923
924                         member = MemberCache.FindMember (declaring_type, filter, BindingRestriction.DeclaredOnly) as T;
925                         if (member == null)
926                                 return null;
927
928                         if (!member.IsAccessible (module))
929                                 return null;
930
931                         return member;
932                 }
933
934                 public T Resolve (Location loc)
935                 {
936                         if (member != null)
937                                 return member;
938
939                         if (Get () != null)
940                                 return member;
941
942                         if (declaring_type == null) {
943                                 if (declaring_type_predefined.Resolve () == null)
944                                         return null;
945                         }
946
947                         if (filter_builder != null) {
948                                 filter = new MemberFilter (filter.Name, filter.Arity, filter.Kind,
949                                         ParametersCompiled.CreateFullyResolved (filter_builder ()), filter.MemberType);
950                         }
951
952                         string method_args = null;
953                         if (filter.Parameters != null)
954                                 method_args = filter.Parameters.GetSignatureForError ();
955
956                         module.Compiler.Report.Error (656, loc, "The compiler required member `{0}.{1}{2}' could not be found or is inaccessible",
957                                 declaring_type.GetSignatureForError (), filter.Name, method_args);
958
959                         return null;
960                 }
961         }
962
963         partial class TypeManager {
964
965         /// <summary>
966         ///   Returns the C# name of a type if possible, or the full type name otherwise
967         /// </summary>
968         static public string CSharpName (TypeSpec t)
969         {
970                 return t.GetSignatureForError ();
971         }
972
973         static public string CSharpName (IList<TypeSpec> types)
974         {
975                 if (types.Count == 0)
976                         return string.Empty;
977
978                 StringBuilder sb = new StringBuilder ();
979                 for (int i = 0; i < types.Count; ++i) {
980                         if (i > 0)
981                                 sb.Append (",");
982
983                         sb.Append (CSharpName (types [i]));
984                 }
985                 return sb.ToString ();
986         }
987
988         static public string GetFullNameSignature (MemberSpec mi)
989         {
990                 return mi.GetSignatureForError ();
991         }
992
993         static public string CSharpSignature (MemberSpec mb)
994         {
995                 return mb.GetSignatureForError ();
996         }
997                 
998         public static bool IsFamilyAccessible (TypeSpec type, TypeSpec parent)
999         {
1000 //              TypeParameter tparam = LookupTypeParameter (type);
1001 //              TypeParameter pparam = LookupTypeParameter (parent);
1002
1003                 if (type.Kind == MemberKind.TypeParameter && parent.Kind == MemberKind.TypeParameter) { // (tparam != null) && (pparam != null)) {
1004                         if (type == parent)
1005                                 return true;
1006
1007                         throw new NotImplementedException ("net");
1008 //                      return tparam.IsSubclassOf (parent);
1009                 }
1010
1011                 do {
1012                         if (IsInstantiationOfSameGenericType (type, parent))
1013                                 return true;
1014
1015                         type = type.BaseType;
1016                 } while (type != null);
1017
1018                 return false;
1019         }
1020
1021         //
1022         // Checks whether `type' is a nested child of `parent'.
1023         //
1024         public static bool IsNestedChildOf (TypeSpec type, ITypeDefinition parent)
1025         {
1026                 if (type == null)
1027                         return false;
1028
1029                 if (type.MemberDefinition == parent)
1030                         return false;
1031
1032                 type = type.DeclaringType;
1033                 while (type != null) {
1034                         if (type.MemberDefinition == parent)
1035                                 return true;
1036
1037                         type = type.DeclaringType;
1038                 }
1039
1040                 return false;
1041         }
1042
1043         public static TypeSpec GetElementType (TypeSpec t)
1044         {
1045                 return ((ElementTypeSpec)t).Element;
1046         }
1047
1048         /// <summary>
1049         /// This method is not implemented by MS runtime for dynamic types
1050         /// </summary>
1051         public static bool HasElementType (TypeSpec t)
1052         {
1053                 return t is ElementTypeSpec;
1054         }
1055
1056         /// <summary>
1057         ///   Utility function that can be used to probe whether a type
1058         ///   is managed or not.  
1059         /// </summary>
1060         public static bool VerifyUnmanaged (ModuleContainer rc, TypeSpec t, Location loc)
1061         {
1062                 if (t.IsUnmanaged)
1063                         return true;
1064
1065                 while (t.IsPointer)
1066                         t = ((ElementTypeSpec) t).Element;
1067
1068                 rc.Compiler.Report.SymbolRelatedToPreviousError (t);
1069                 rc.Compiler.Report.Error (208, loc,
1070                         "Cannot take the address of, get the size of, or declare a pointer to a managed type `{0}'",
1071                         CSharpName (t));
1072
1073                 return false;   
1074         }
1075 #region Generics
1076         // This method always return false for non-generic compiler,
1077         // while Type.IsGenericParameter is returned if it is supported.
1078         public static bool IsGenericParameter (TypeSpec type)
1079         {
1080                 return type.IsGenericParameter;
1081         }
1082
1083         public static bool IsGenericType (TypeSpec type)
1084         {
1085                 return type.IsGeneric;
1086         }
1087
1088         public static TypeSpec[] GetTypeArguments (TypeSpec t)
1089         {
1090                 // TODO: return empty array !!
1091                 return t.TypeArguments;
1092         }
1093
1094         /// <summary>
1095         ///   Check whether `type' and `parent' are both instantiations of the same
1096         ///   generic type.  Note that we do not check the type parameters here.
1097         /// </summary>
1098         public static bool IsInstantiationOfSameGenericType (TypeSpec type, TypeSpec parent)
1099         {
1100                 return type == parent || type.MemberDefinition == parent.MemberDefinition;
1101         }
1102 #endregion
1103 }
1104
1105 }