Merge pull request #565 from rneatherway/master
[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, true, true);
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 IReadOnlyListGeneric;
190                 public readonly PredefinedType ICollectionGeneric;
191                 public readonly PredefinedType IReadOnlyCollectionGeneric;
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                 public readonly PredefinedType Dictionary;
202                 public readonly PredefinedType Hashtable;
203
204                 //
205                 // C# 3.0
206                 //
207                 public readonly PredefinedType Expression;
208                 public readonly PredefinedType ExpressionGeneric;
209                 public readonly PredefinedType ParameterExpression;
210                 public readonly PredefinedType FieldInfo;
211                 public readonly PredefinedType MethodBase;
212                 public readonly PredefinedType MethodInfo;
213                 public readonly PredefinedType ConstructorInfo;
214                 public readonly PredefinedType MemberBinding;
215
216                 //
217                 // C# 4.0
218                 //
219                 public readonly PredefinedType Binder;
220                 public readonly PredefinedType CallSite;
221                 public readonly PredefinedType CallSiteGeneric;
222                 public readonly PredefinedType BinderFlags;
223
224                 //
225                 // C# 5.0
226                 //
227                 public readonly PredefinedType AsyncVoidMethodBuilder;
228                 public readonly PredefinedType AsyncTaskMethodBuilder;
229                 public readonly PredefinedType AsyncTaskMethodBuilderGeneric;
230                 public readonly PredefinedType Action;
231                 public readonly PredefinedType Task;
232                 public readonly PredefinedType TaskGeneric;
233                 public readonly PredefinedType IAsyncStateMachine;
234                 public readonly PredefinedType INotifyCompletion;
235                 public readonly PredefinedType ICriticalNotifyCompletion;
236
237                 public PredefinedTypes (ModuleContainer module)
238                 {
239                         TypedReference = new PredefinedType (module, MemberKind.Struct, "System", "TypedReference");
240                         ArgIterator = new PredefinedType (module, MemberKind.Struct, "System", "ArgIterator");
241
242                         MarshalByRefObject = new PredefinedType (module, MemberKind.Class, "System", "MarshalByRefObject");
243                         RuntimeHelpers = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "RuntimeHelpers");
244                         IAsyncResult = new PredefinedType (module, MemberKind.Interface, "System", "IAsyncResult");
245                         AsyncCallback = new PredefinedType (module, MemberKind.Delegate, "System", "AsyncCallback");
246                         RuntimeArgumentHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeArgumentHandle");
247                         CharSet = new PredefinedType (module, MemberKind.Enum, "System.Runtime.InteropServices", "CharSet");
248                         IsVolatile = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "IsVolatile");
249                         IEnumeratorGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IEnumerator", 1);
250                         IListGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IList", 1);
251                         IReadOnlyListGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IReadOnlyList", 1);
252                         ICollectionGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "ICollection", 1);
253                         IReadOnlyCollectionGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IReadOnlyCollection", 1);
254                         IEnumerableGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IEnumerable", 1);
255                         Nullable = new PredefinedType (module, MemberKind.Struct, "System", "Nullable", 1);
256                         Activator = new PredefinedType (module, MemberKind.Class, "System", "Activator");
257                         Interlocked = new PredefinedType (module, MemberKind.Class, "System.Threading", "Interlocked");
258                         Monitor = new PredefinedType (module, MemberKind.Class, "System.Threading", "Monitor");
259                         NotSupportedException = new PredefinedType (module, MemberKind.Class, "System", "NotSupportedException");
260                         RuntimeFieldHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeFieldHandle");
261                         RuntimeMethodHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeMethodHandle");
262                         SecurityAction = new PredefinedType (module, MemberKind.Enum, "System.Security.Permissions", "SecurityAction");
263                         Dictionary = new PredefinedType (module, MemberKind.Class, "System.Collections.Generic", "Dictionary", 2);
264                         Hashtable = new PredefinedType (module, MemberKind.Class, "System.Collections", "Hashtable");
265
266                         Expression = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "Expression");
267                         ExpressionGeneric = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "Expression", 1);
268                         MemberBinding = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "MemberBinding");
269                         ParameterExpression = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "ParameterExpression");
270                         FieldInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "FieldInfo");
271                         MethodBase = new PredefinedType (module, MemberKind.Class, "System.Reflection", "MethodBase");
272                         MethodInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "MethodInfo");
273                         ConstructorInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "ConstructorInfo");
274
275                         CallSite = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "CallSite");
276                         CallSiteGeneric = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "CallSite", 1);
277                         Binder = new PredefinedType (module, MemberKind.Class, "Microsoft.CSharp.RuntimeBinder", "Binder");
278                         BinderFlags = new PredefinedType (module, MemberKind.Enum, "Microsoft.CSharp.RuntimeBinder", "CSharpBinderFlags");
279
280                         Action = new PredefinedType (module, MemberKind.Delegate, "System", "Action");
281                         AsyncVoidMethodBuilder = new PredefinedType (module, MemberKind.Struct, "System.Runtime.CompilerServices", "AsyncVoidMethodBuilder");
282                         AsyncTaskMethodBuilder = new PredefinedType (module, MemberKind.Struct, "System.Runtime.CompilerServices", "AsyncTaskMethodBuilder");
283                         AsyncTaskMethodBuilderGeneric = new PredefinedType (module, MemberKind.Struct, "System.Runtime.CompilerServices", "AsyncTaskMethodBuilder", 1);
284                         Task = new PredefinedType (module, MemberKind.Class, "System.Threading.Tasks", "Task");
285                         TaskGeneric = new PredefinedType (module, MemberKind.Class, "System.Threading.Tasks", "Task", 1);
286                         IAsyncStateMachine = new PredefinedType (module, MemberKind.Interface, "System.Runtime.CompilerServices", "IAsyncStateMachine");
287                         INotifyCompletion = new PredefinedType (module, MemberKind.Interface, "System.Runtime.CompilerServices", "INotifyCompletion");
288                         ICriticalNotifyCompletion = new PredefinedType (module, MemberKind.Interface, "System.Runtime.CompilerServices", "ICriticalNotifyCompletion");
289
290                         //
291                         // Define types which are used for comparison. It does not matter
292                         // if they don't exist as no error report is needed
293                         //
294                         if (TypedReference.Define ())
295                                 TypedReference.TypeSpec.IsSpecialRuntimeType = true;
296
297                         if (ArgIterator.Define ())
298                                 ArgIterator.TypeSpec.IsSpecialRuntimeType = true;
299
300                         if (IEnumerableGeneric.Define ())
301                                 IEnumerableGeneric.TypeSpec.IsArrayGenericInterface = true;
302
303                         if (IListGeneric.Define ())
304                                 IListGeneric.TypeSpec.IsArrayGenericInterface = true;
305
306                         if (IReadOnlyListGeneric.Define ())
307                                 IReadOnlyListGeneric.TypeSpec.IsArrayGenericInterface = true;
308
309                         if (ICollectionGeneric.Define ())
310                                 ICollectionGeneric.TypeSpec.IsArrayGenericInterface = true;
311
312                         if (IReadOnlyCollectionGeneric.Define ())
313                                 IReadOnlyCollectionGeneric.TypeSpec.IsArrayGenericInterface = true;
314
315                         if (Nullable.Define ())
316                                 Nullable.TypeSpec.IsNullableType = true;
317
318                         if (ExpressionGeneric.Define ())
319                                 ExpressionGeneric.TypeSpec.IsExpressionTreeType = true;
320
321                         Task.Define ();
322                         if (TaskGeneric.Define ())
323                                 TaskGeneric.TypeSpec.IsGenericTask = true;
324                 }
325         }
326
327         class PredefinedMembers
328         {
329                 public readonly PredefinedMember<MethodSpec> ActivatorCreateInstance;
330                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderCreate;
331                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderStart;
332                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderSetResult;
333                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderSetException;
334                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderSetStateMachine;
335                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderOnCompleted;
336                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderOnCompletedUnsafe;
337                 public readonly PredefinedMember<PropertySpec> AsyncTaskMethodBuilderTask;
338                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericCreate;
339                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericStart;
340                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericSetResult;
341                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericSetException;
342                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericSetStateMachine;
343                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericOnCompleted;
344                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericOnCompletedUnsafe;
345                 public readonly PredefinedMember<PropertySpec> AsyncTaskMethodBuilderGenericTask;
346                 public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderCreate;
347                 public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderStart;
348                 public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderSetException;
349                 public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderSetResult;
350                 public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderSetStateMachine;
351                 public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderOnCompleted;
352                 public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderOnCompletedUnsafe;
353                 public readonly PredefinedMember<MethodSpec> AsyncStateMachineAttributeCtor;
354                 public readonly PredefinedMember<MethodSpec> DebuggerBrowsableAttributeCtor;
355                 public readonly PredefinedMember<MethodSpec> DecimalCtor;
356                 public readonly PredefinedMember<MethodSpec> DecimalCtorInt;
357                 public readonly PredefinedMember<MethodSpec> DecimalCtorLong;
358                 public readonly PredefinedMember<MethodSpec> DecimalConstantAttributeCtor;
359                 public readonly PredefinedMember<MethodSpec> DefaultMemberAttributeCtor;
360                 public readonly PredefinedMember<MethodSpec> DelegateCombine;
361                 public readonly PredefinedMember<MethodSpec> DelegateEqual;
362                 public readonly PredefinedMember<MethodSpec> DelegateInequal;
363                 public readonly PredefinedMember<MethodSpec> DelegateRemove;
364                 public readonly PredefinedMember<MethodSpec> DynamicAttributeCtor;
365                 public readonly PredefinedMember<MethodSpec> FieldInfoGetFieldFromHandle;
366                 public readonly PredefinedMember<MethodSpec> FieldInfoGetFieldFromHandle2;
367                 public readonly PredefinedMember<MethodSpec> IDisposableDispose;
368                 public readonly PredefinedMember<MethodSpec> IEnumerableGetEnumerator;
369                 public readonly PredefinedMember<MethodSpec> InterlockedCompareExchange;
370                 public readonly PredefinedMember<MethodSpec> InterlockedCompareExchange_T;
371                 public readonly PredefinedMember<MethodSpec> FixedBufferAttributeCtor;
372                 public readonly PredefinedMember<MethodSpec> MethodInfoGetMethodFromHandle;
373                 public readonly PredefinedMember<MethodSpec> MethodInfoGetMethodFromHandle2;
374                 public readonly PredefinedMember<MethodSpec> MonitorEnter;
375                 public readonly PredefinedMember<MethodSpec> MonitorEnter_v4;
376                 public readonly PredefinedMember<MethodSpec> MonitorExit;
377                 public readonly PredefinedMember<PropertySpec> RuntimeCompatibilityWrapNonExceptionThrows;
378                 public readonly PredefinedMember<MethodSpec> RuntimeHelpersInitializeArray;
379                 public readonly PredefinedMember<PropertySpec> RuntimeHelpersOffsetToStringData;
380                 public readonly PredefinedMember<ConstSpec> SecurityActionRequestMinimum;
381                 public readonly PredefinedMember<FieldSpec> StringEmpty;
382                 public readonly PredefinedMember<MethodSpec> StringEqual;
383                 public readonly PredefinedMember<MethodSpec> StringInequal;
384                 public readonly PredefinedMember<MethodSpec> StructLayoutAttributeCtor;
385                 public readonly PredefinedMember<FieldSpec> StructLayoutCharSet;
386                 public readonly PredefinedMember<FieldSpec> StructLayoutSize;
387                 public readonly PredefinedMember<MethodSpec> TypeGetTypeFromHandle;
388
389                 public PredefinedMembers (ModuleContainer module)
390                 {
391                         var types = module.PredefinedTypes;
392                         var atypes = module.PredefinedAttributes;
393                         var btypes = module.Compiler.BuiltinTypes;
394
395                         var tp = new TypeParameter (0, new MemberName ("T"), null, null, Variance.None);
396
397                         ActivatorCreateInstance = new PredefinedMember<MethodSpec> (module, types.Activator,
398                                 MemberFilter.Method ("CreateInstance", 1, ParametersCompiled.EmptyReadOnlyParameters, null));
399
400                         AsyncTaskMethodBuilderCreate = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
401                                 MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, types.AsyncTaskMethodBuilder.TypeSpec));
402
403                         AsyncTaskMethodBuilderSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
404                                 MemberFilter.Method ("SetResult", 0, ParametersCompiled.EmptyReadOnlyParameters, btypes.Void));
405
406                         AsyncTaskMethodBuilderSetStateMachine = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
407                                 "SetStateMachine", MemberKind.Method, () => new[] {
408                                                 types.IAsyncStateMachine.TypeSpec
409                                 }, btypes.Void);
410
411                         AsyncTaskMethodBuilderSetException = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
412                                 MemberFilter.Method ("SetException", 0,
413                                 ParametersCompiled.CreateFullyResolved (btypes.Exception), btypes.Void));
414
415                         AsyncTaskMethodBuilderOnCompleted = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
416                                 MemberFilter.Method ("AwaitOnCompleted", 2,
417                                         new ParametersImported (
418                                                 new[] {
419                                                                 new ParameterData (null, Parameter.Modifier.REF),
420                                                                 new ParameterData (null, Parameter.Modifier.REF)
421                                                         },
422                                                 new[] {
423                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
424                                                                 new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
425                                                         }, false),
426                                         btypes.Void));
427
428                         AsyncTaskMethodBuilderOnCompletedUnsafe = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
429                                 MemberFilter.Method ("AwaitUnsafeOnCompleted", 2,
430                                         new ParametersImported (
431                                                 new[] {
432                                                                 new ParameterData (null, Parameter.Modifier.REF),
433                                                                 new ParameterData (null, Parameter.Modifier.REF)
434                                                         },
435                                                 new[] {
436                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
437                                                                 new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
438                                                         }, false),
439                                         btypes.Void));
440
441                         AsyncTaskMethodBuilderStart = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
442                                 MemberFilter.Method ("Start", 1,
443                                         new ParametersImported (
444                                                 new[] {
445                                                                 new ParameterData (null, Parameter.Modifier.REF),
446                                                         },
447                                                 new[] {
448                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
449                                                         }, false),
450                                         btypes.Void));
451
452                         AsyncTaskMethodBuilderTask = new PredefinedMember<PropertySpec> (module, types.AsyncTaskMethodBuilder,
453                                 MemberFilter.Property ("Task", null));
454
455                         AsyncTaskMethodBuilderGenericCreate = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
456                                 MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, types.AsyncVoidMethodBuilder.TypeSpec));
457
458                         AsyncTaskMethodBuilderGenericSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
459                                 "SetResult", MemberKind.Method, () => new TypeSpec[] {
460                                                 types.AsyncTaskMethodBuilderGeneric.TypeSpec.MemberDefinition.TypeParameters[0]
461                                 }, btypes.Void);
462
463                         AsyncTaskMethodBuilderGenericSetStateMachine = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
464                                 "SetStateMachine", MemberKind.Method, () => new[] {
465                                                 types.IAsyncStateMachine.TypeSpec
466                                 }, btypes.Void);
467
468                         AsyncTaskMethodBuilderGenericSetException = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
469                                 MemberFilter.Method ("SetException", 0,
470                                 ParametersCompiled.CreateFullyResolved (btypes.Exception), btypes.Void));
471
472                         AsyncTaskMethodBuilderGenericOnCompleted = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
473                                 MemberFilter.Method ("AwaitOnCompleted", 2,
474                                         new ParametersImported (
475                                                 new[] {
476                                                                 new ParameterData (null, Parameter.Modifier.REF),
477                                                                 new ParameterData (null, Parameter.Modifier.REF)
478                                                         },
479                                                 new[] {
480                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
481                                                                 new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
482                                                         }, false),
483                                         btypes.Void));
484
485                         AsyncTaskMethodBuilderGenericOnCompletedUnsafe = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
486                                 MemberFilter.Method ("AwaitUnsafeOnCompleted", 2,
487                                         new ParametersImported (
488                                                 new[] {
489                                                                 new ParameterData (null, Parameter.Modifier.REF),
490                                                                 new ParameterData (null, Parameter.Modifier.REF)
491                                                         },
492                                                 new[] {
493                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
494                                                                 new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
495                                                         }, false),
496                                         btypes.Void));
497
498                         AsyncTaskMethodBuilderGenericStart = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
499                                 MemberFilter.Method ("Start", 1,
500                                         new ParametersImported (
501                                                 new[] {
502                                                                 new ParameterData (null, Parameter.Modifier.REF),
503                                                         },
504                                                 new[] {
505                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
506                                                         }, false),
507                                         btypes.Void));
508
509                         AsyncTaskMethodBuilderGenericTask = new PredefinedMember<PropertySpec> (module, types.AsyncTaskMethodBuilderGeneric,
510                                 MemberFilter.Property ("Task", null));
511
512                         AsyncVoidMethodBuilderCreate = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
513                                 MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, types.AsyncVoidMethodBuilder.TypeSpec));
514
515                         AsyncVoidMethodBuilderSetException = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
516                                 MemberFilter.Method ("SetException", 0, null, btypes.Void));
517
518                         AsyncVoidMethodBuilderSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
519                                 MemberFilter.Method ("SetResult", 0, ParametersCompiled.EmptyReadOnlyParameters, btypes.Void));
520
521                         AsyncVoidMethodBuilderSetStateMachine = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
522                                 "SetStateMachine", MemberKind.Method, () => new[] {
523                                                 types.IAsyncStateMachine.TypeSpec
524                                 }, btypes.Void);
525
526                         AsyncVoidMethodBuilderOnCompleted = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
527                                 MemberFilter.Method ("AwaitOnCompleted", 2,
528                                         new ParametersImported (
529                                                 new[] {
530                                                                 new ParameterData (null, Parameter.Modifier.REF),
531                                                                 new ParameterData (null, Parameter.Modifier.REF)
532                                                         },
533                                                 new[] {
534                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
535                                                                 new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
536                                                         }, false),
537                                         btypes.Void));
538
539                         AsyncVoidMethodBuilderOnCompletedUnsafe = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
540                                 MemberFilter.Method ("AwaitUnsafeOnCompleted", 2,
541                                         new ParametersImported (
542                                                 new[] {
543                                                                 new ParameterData (null, Parameter.Modifier.REF),
544                                                                 new ParameterData (null, Parameter.Modifier.REF)
545                                                         },
546                                                 new[] {
547                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
548                                                                 new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
549                                                         }, false),
550                                         btypes.Void));
551
552                         AsyncVoidMethodBuilderStart = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
553                                 MemberFilter.Method ("Start", 1,
554                                         new ParametersImported (
555                                                 new[] {
556                                                                 new ParameterData (null, Parameter.Modifier.REF),
557                                                         },
558                                                 new[] {
559                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
560                                                         }, false),
561                                         btypes.Void));
562
563                         AsyncStateMachineAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.AsyncStateMachine,
564                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
565                                         btypes.Type)));
566
567                         DebuggerBrowsableAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.DebuggerBrowsable,
568                                 MemberFilter.Constructor (null));
569
570                         DecimalCtor = new PredefinedMember<MethodSpec> (module, btypes.Decimal,
571                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
572                                         btypes.Int, btypes.Int, btypes.Int, btypes.Bool, btypes.Byte)));
573
574                         DecimalCtorInt = new PredefinedMember<MethodSpec> (module, btypes.Decimal,
575                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Int)));
576
577                         DecimalCtorLong = new PredefinedMember<MethodSpec> (module, btypes.Decimal,
578                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Long)));
579
580                         DecimalConstantAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.DecimalConstant,
581                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
582                                         btypes.Byte, btypes.Byte, btypes.UInt, btypes.UInt, btypes.UInt)));
583
584                         DefaultMemberAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.DefaultMember,
585                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.String)));
586
587                         DelegateCombine = new PredefinedMember<MethodSpec> (module, btypes.Delegate, "Combine", btypes.Delegate, btypes.Delegate);
588                         DelegateRemove = new PredefinedMember<MethodSpec> (module, btypes.Delegate, "Remove", btypes.Delegate, btypes.Delegate);
589
590                         DelegateEqual = new PredefinedMember<MethodSpec> (module, btypes.Delegate,
591                                 new MemberFilter (Operator.GetMetadataName (Operator.OpType.Equality), 0, MemberKind.Operator, null, btypes.Bool));
592
593                         DelegateInequal = new PredefinedMember<MethodSpec> (module, btypes.Delegate,
594                                 new MemberFilter (Operator.GetMetadataName (Operator.OpType.Inequality), 0, MemberKind.Operator, null, btypes.Bool));
595
596                         DynamicAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.Dynamic,
597                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
598                                         ArrayContainer.MakeType (module, btypes.Bool))));
599
600                         FieldInfoGetFieldFromHandle = new PredefinedMember<MethodSpec> (module, types.FieldInfo,
601                                 "GetFieldFromHandle", MemberKind.Method, types.RuntimeFieldHandle);
602
603                         FieldInfoGetFieldFromHandle2 = new PredefinedMember<MethodSpec> (module, types.FieldInfo,
604                                 "GetFieldFromHandle", MemberKind.Method, types.RuntimeFieldHandle, new PredefinedType (btypes.RuntimeTypeHandle));
605
606                         FixedBufferAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.FixedBuffer,
607                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Type, btypes.Int)));
608
609                         IDisposableDispose = new PredefinedMember<MethodSpec> (module, btypes.IDisposable, "Dispose", TypeSpec.EmptyTypes);
610
611                         IEnumerableGetEnumerator = new PredefinedMember<MethodSpec> (module, btypes.IEnumerable,
612                                 "GetEnumerator", TypeSpec.EmptyTypes);
613
614                         InterlockedCompareExchange = new PredefinedMember<MethodSpec> (module, types.Interlocked,
615                                 MemberFilter.Method ("CompareExchange", 0,
616                                         new ParametersImported (
617                                                 new[] {
618                                                                 new ParameterData (null, Parameter.Modifier.REF),
619                                                                 new ParameterData (null, Parameter.Modifier.NONE),
620                                                                 new ParameterData (null, Parameter.Modifier.NONE)
621                                                         },
622                                                 new[] {
623                                                                 btypes.Int, btypes.Int, btypes.Int
624                                                         },
625                                                 false),
626                                 btypes.Int));
627
628                         InterlockedCompareExchange_T = new PredefinedMember<MethodSpec> (module, types.Interlocked,
629                                 MemberFilter.Method ("CompareExchange", 1,
630                                         new ParametersImported (
631                                                 new[] {
632                                                                 new ParameterData (null, Parameter.Modifier.REF),
633                                                                 new ParameterData (null, Parameter.Modifier.NONE),
634                                                                 new ParameterData (null, Parameter.Modifier.NONE)
635                                                         },
636                                                 new[] {
637                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
638                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
639                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
640                                                         }, false),
641                                         null));
642
643                         MethodInfoGetMethodFromHandle = new PredefinedMember<MethodSpec> (module, types.MethodBase,
644                                 "GetMethodFromHandle", MemberKind.Method, types.RuntimeMethodHandle);
645
646                         MethodInfoGetMethodFromHandle2 = new PredefinedMember<MethodSpec> (module, types.MethodBase,
647                                 "GetMethodFromHandle", MemberKind.Method, types.RuntimeMethodHandle, new PredefinedType (btypes.RuntimeTypeHandle));
648
649                         MonitorEnter = new PredefinedMember<MethodSpec> (module, types.Monitor, "Enter", btypes.Object);
650
651                         MonitorEnter_v4 = new PredefinedMember<MethodSpec> (module, types.Monitor,
652                                 MemberFilter.Method ("Enter", 0,
653                                         new ParametersImported (new[] {
654                                                         new ParameterData (null, Parameter.Modifier.NONE),
655                                                         new ParameterData (null, Parameter.Modifier.REF)
656                                                 },
657                                         new[] {
658                                                         btypes.Object, btypes.Bool
659                                                 }, false), null));
660
661                         MonitorExit = new PredefinedMember<MethodSpec> (module, types.Monitor, "Exit", btypes.Object);
662
663                         RuntimeCompatibilityWrapNonExceptionThrows = new PredefinedMember<PropertySpec> (module, atypes.RuntimeCompatibility,
664                                 MemberFilter.Property ("WrapNonExceptionThrows", btypes.Bool));
665
666                         RuntimeHelpersInitializeArray = new PredefinedMember<MethodSpec> (module, types.RuntimeHelpers,
667                                 "InitializeArray", btypes.Array, btypes.RuntimeFieldHandle);
668
669                         RuntimeHelpersOffsetToStringData = new PredefinedMember<PropertySpec> (module, types.RuntimeHelpers,
670                                 MemberFilter.Property ("OffsetToStringData", btypes.Int));
671
672                         SecurityActionRequestMinimum = new PredefinedMember<ConstSpec> (module, types.SecurityAction, "RequestMinimum",
673                                 MemberKind.Field, types.SecurityAction);
674
675                         StringEmpty = new PredefinedMember<FieldSpec> (module, btypes.String, MemberFilter.Field ("Empty", btypes.String));
676
677                         StringEqual = new PredefinedMember<MethodSpec> (module, btypes.String,
678                                 new MemberFilter (Operator.GetMetadataName (Operator.OpType.Equality), 0, MemberKind.Operator, null, btypes.Bool));
679
680                         StringInequal = new PredefinedMember<MethodSpec> (module, btypes.String,
681                                 new MemberFilter (Operator.GetMetadataName (Operator.OpType.Inequality), 0, MemberKind.Operator, null, btypes.Bool));
682
683                         StructLayoutAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.StructLayout,
684                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Short)));
685
686                         StructLayoutCharSet = new PredefinedMember<FieldSpec> (module, atypes.StructLayout, "CharSet",
687                                 MemberKind.Field, types.CharSet);
688
689                         StructLayoutSize = new PredefinedMember<FieldSpec> (module, atypes.StructLayout,
690                                 MemberFilter.Field ("Size", btypes.Int));
691
692                         TypeGetTypeFromHandle = new PredefinedMember<MethodSpec> (module, btypes.Type, "GetTypeFromHandle", btypes.RuntimeTypeHandle);
693                 }
694         }
695
696         public class PredefinedType
697         {
698                 readonly string name;
699                 readonly string ns;
700                 readonly int arity;
701                 readonly MemberKind kind;
702                 protected readonly ModuleContainer module;
703                 protected TypeSpec type;
704                 bool defined;
705
706                 public PredefinedType (ModuleContainer module, MemberKind kind, string ns, string name, int arity)
707                         : this (module, kind, ns, name)
708                 {
709                         this.arity = arity;
710                 }
711
712                 public PredefinedType (ModuleContainer module, MemberKind kind, string ns, string name)
713                 {
714                         this.module = module;
715                         this.kind = kind;
716                         this.name = name;
717                         this.ns = ns;
718                 }
719
720                 public PredefinedType (BuiltinTypeSpec type)
721                 {
722                         this.kind = type.Kind;
723                         this.name = type.Name;
724                         this.ns = type.Namespace;
725                         this.type = type;
726                 }
727
728                 #region Properties
729
730                 public int Arity {
731                         get {
732                                 return arity;
733                         }
734                 }
735
736                 public bool IsDefined {
737                         get {
738                                 return type != null;
739                         }
740                 }
741
742                 public string Name {
743                         get {
744                                 return name;
745                         }
746                 }
747
748                 public string Namespace {
749                         get {
750                                 return ns;
751                         }
752                 }
753
754                 public TypeSpec TypeSpec {
755                         get {
756                                 return type;
757                         }
758                 }
759
760                 #endregion
761
762                 public bool Define ()
763                 {
764                         if (type != null)
765                                 return true;
766
767                         if (!defined) {
768                                 defined = true;
769                                 type = Resolve (module, kind, ns, name, arity, false, false);
770                         }
771
772                         return type != null;
773                 }
774
775                 public string GetSignatureForError ()
776                 {
777                         return ns + "." + name;
778                 }
779
780                 public static TypeSpec Resolve (ModuleContainer module, MemberKind kind, string ns, string name, int arity, bool required, bool reportErrors)
781                 {
782                         //
783                         // Cannot call it with true because it could create non-existent namespaces for
784                         // predefined types. It's set to true only for build-in types which all must
785                         // exist therefore it does not matter, for predefined types we don't want to create
786                         // fake namespaces when type is optional and does not exist (e.g. System.Linq).
787                         //
788                         Namespace type_ns = module.GlobalRootNamespace.GetNamespace (ns, required);
789
790                         IList<TypeSpec> found = null;
791                         if (type_ns != null)
792                                 found = type_ns.GetAllTypes (name);
793
794                         if (found == null) {
795                                 if (reportErrors)
796                                         module.Compiler.Report.Error (518, "The predefined type `{0}.{1}' is not defined or imported", ns, name);
797
798                                 return null;
799                         }
800
801                         TypeSpec best_match = null;
802                         foreach (var candidate in found) {
803                                 if (candidate.Kind != kind) {
804                                         if (candidate.Kind == MemberKind.Struct && kind == MemberKind.Void && candidate.MemberDefinition is TypeContainer) {
805                                                 // Void is declared as struct but we keep it internally as
806                                                 // special kind, the swap will be done by caller
807                                         } else {
808                                                 continue;
809                                         }
810                                 }
811
812                                 if (candidate.Arity != arity)
813                                         continue;
814
815                                 if ((candidate.Modifiers & Modifiers.INTERNAL) != 0 && !candidate.MemberDefinition.IsInternalAsPublic (module.DeclaringAssembly))
816                                         continue;
817
818                                 if (best_match == null) {
819                                         best_match = candidate;
820                                         continue;
821                                 }
822
823                                 var other_match = best_match;
824                                 if (!best_match.MemberDefinition.IsImported &&
825                                         module.Compiler.BuiltinTypes.Object.MemberDefinition.DeclaringAssembly == candidate.MemberDefinition.DeclaringAssembly) {
826                                         best_match = candidate;
827                                 }
828
829                                 string location;
830                                 if (best_match.MemberDefinition is MemberCore) {
831                                         location = ((MemberCore) best_match.MemberDefinition).Location.Name;
832                                 } else {
833                                         var assembly = (ImportedAssemblyDefinition) best_match.MemberDefinition.DeclaringAssembly;
834                                         location = Path.GetFileName (assembly.Location);
835                                 }
836
837                                 module.Compiler.Report.SymbolRelatedToPreviousError (other_match);
838                                 module.Compiler.Report.SymbolRelatedToPreviousError (candidate);
839
840                                 module.Compiler.Report.Warning (1685, 1,
841                                         "The predefined type `{0}.{1}' is defined multiple times. Using definition from `{2}'",
842                                         ns, name, location);
843
844                                 break;
845                         }
846
847                         if (best_match == null && reportErrors) {
848                                 var found_member = found[0];
849
850                                 if (found_member.Kind == MemberKind.MissingType) {
851                                         // CSC: should be different error number
852                                         module.Compiler.Report.Error (518, "The predefined type `{0}.{1}' is defined in an assembly that is not referenced.", ns, name);
853                                 } else {
854                                         Location loc;
855                                         if (found_member.MemberDefinition is MemberCore) {
856                                                 loc = ((MemberCore) found_member.MemberDefinition).Location;
857                                         } else {
858                                                 loc = Location.Null;
859                                                 module.Compiler.Report.SymbolRelatedToPreviousError (found_member);
860                                         }
861
862                                         module.Compiler.Report.Error (520, loc, "The predefined type `{0}.{1}' is not declared correctly", ns, name);
863                                 }
864                         }
865
866                         return best_match;
867                 }
868
869                 public TypeSpec Resolve ()
870                 {
871                         if (type == null)
872                                 type = Resolve (module, kind, ns, name, arity, false, true);
873
874                         return type;
875                 }
876         }
877
878         public class PredefinedMember<T> where T : MemberSpec
879         {
880                 readonly ModuleContainer module;
881                 T member;
882                 TypeSpec declaring_type;
883                 readonly PredefinedType declaring_type_predefined;
884                 MemberFilter filter;
885                 readonly Func<TypeSpec[]> filter_builder;
886
887                 public PredefinedMember (ModuleContainer module, PredefinedType type, MemberFilter filter)
888                 {
889                         this.module = module;
890                         this.declaring_type_predefined = type;
891                         this.filter = filter;
892                 }
893
894                 public PredefinedMember (ModuleContainer module, TypeSpec type, MemberFilter filter)
895                 {
896                         this.module = module;
897                         this.declaring_type = type;
898                         this.filter = filter;
899                 }
900
901                 public PredefinedMember (ModuleContainer module, PredefinedType type, string name, params TypeSpec[] types)
902                         : this (module, type, MemberFilter.Method (name, 0, ParametersCompiled.CreateFullyResolved (types), null))
903                 {
904                 }
905
906                 public PredefinedMember (ModuleContainer module, PredefinedType type, string name, MemberKind kind, params PredefinedType[] types)
907                         : this (module, type, new MemberFilter (name, 0, kind, null, null))
908                 {
909                         filter_builder = () => {
910                                 var ptypes = new TypeSpec[types.Length];
911                                 for (int i = 0; i < ptypes.Length; ++i) {
912                                         var p = types[i];
913                                         if (!p.Define ())
914                                                 return null;
915
916                                         ptypes[i] = p.TypeSpec;
917                                 }
918
919                                 return ptypes;
920                         };
921                 }
922
923                 public PredefinedMember (ModuleContainer module, PredefinedType type, string name, MemberKind kind, Func<TypeSpec[]> typesBuilder, TypeSpec returnType)
924                         : this (module, type, new MemberFilter (name, 0, kind, null, returnType))
925                 {
926                         filter_builder = typesBuilder;
927                 }
928
929                 public PredefinedMember (ModuleContainer module, BuiltinTypeSpec type, string name, params TypeSpec[] types)
930                         : this (module, type, MemberFilter.Method (name, 0, ParametersCompiled.CreateFullyResolved (types), null))
931                 {
932                 }
933
934                 public T Get ()
935                 {
936                         if (member != null)
937                                 return member;
938
939                         if (declaring_type == null) {
940                                 if (!declaring_type_predefined.Define ())
941                                         return null;
942
943                                 declaring_type = declaring_type_predefined.TypeSpec;
944                         }
945
946                         if (filter_builder != null) {
947                                 var types = filter_builder ();
948
949                                 if (filter.Kind == MemberKind.Field)
950                                         filter = new MemberFilter (filter.Name, filter.Arity, filter.Kind, null, types [0]);
951                                 else
952                                         filter = new MemberFilter (filter.Name, filter.Arity, filter.Kind,
953                                                 ParametersCompiled.CreateFullyResolved (types), filter.MemberType);
954                         }
955
956                         member = MemberCache.FindMember (declaring_type, filter, BindingRestriction.DeclaredOnly) as T;
957                         if (member == null)
958                                 return null;
959
960                         if (!member.IsAccessible (module))
961                                 return null;
962
963                         return member;
964                 }
965
966                 public T Resolve (Location loc)
967                 {
968                         if (member != null)
969                                 return member;
970
971                         if (Get () != null)
972                                 return member;
973
974                         if (declaring_type == null) {
975                                 if (declaring_type_predefined.Resolve () == null)
976                                         return null;
977                         }
978
979                         if (filter_builder != null) {
980                                 filter = new MemberFilter (filter.Name, filter.Arity, filter.Kind,
981                                         ParametersCompiled.CreateFullyResolved (filter_builder ()), filter.MemberType);
982                         }
983
984                         string method_args = null;
985                         if (filter.Parameters != null)
986                                 method_args = filter.Parameters.GetSignatureForError ();
987
988                         module.Compiler.Report.Error (656, loc, "The compiler required member `{0}.{1}{2}' could not be found or is inaccessible",
989                                 declaring_type.GetSignatureForError (), filter.Name, method_args);
990
991                         return null;
992                 }
993         }
994
995         public class AwaiterDefinition
996         {
997                 public PropertySpec IsCompleted { get; set; }
998                 public MethodSpec GetResult { get; set; }
999                 public bool INotifyCompletion { get; set; }
1000
1001                 public bool IsValidPattern {
1002                         get {
1003                                 return IsCompleted != null && GetResult != null && IsCompleted.HasGet;
1004                         }
1005                 }
1006         }
1007
1008         partial class TypeManager {
1009
1010         static public string CSharpName(IList<TypeSpec> types)
1011         {
1012                 if (types.Count == 0)
1013                         return string.Empty;
1014
1015                 StringBuilder sb = new StringBuilder ();
1016                 for (int i = 0; i < types.Count; ++i) {
1017                         if (i > 0)
1018                                 sb.Append (",");
1019
1020                         sb.Append (types [i].GetSignatureForError ());
1021                 }
1022                 return sb.ToString ();
1023         }
1024
1025         static public string GetFullNameSignature (MemberSpec mi)
1026         {
1027                 return mi.GetSignatureForError ();
1028         }
1029
1030         static public string CSharpSignature (MemberSpec mb)
1031         {
1032                 return mb.GetSignatureForError ();
1033         }
1034                 
1035         public static bool IsFamilyAccessible (TypeSpec type, TypeSpec parent)
1036         {
1037 //              TypeParameter tparam = LookupTypeParameter (type);
1038 //              TypeParameter pparam = LookupTypeParameter (parent);
1039
1040                 if (type.Kind == MemberKind.TypeParameter && parent.Kind == MemberKind.TypeParameter) { // (tparam != null) && (pparam != null)) {
1041                         if (type == parent)
1042                                 return true;
1043
1044                         throw new NotImplementedException ("net");
1045 //                      return tparam.IsSubclassOf (parent);
1046                 }
1047
1048                 do {
1049                         if (IsInstantiationOfSameGenericType (type, parent))
1050                                 return true;
1051
1052                         type = type.BaseType;
1053                 } while (type != null);
1054
1055                 return false;
1056         }
1057
1058         //
1059         // Checks whether `type' is a nested child of `parent'.
1060         //
1061         public static bool IsNestedChildOf (TypeSpec type, ITypeDefinition parent)
1062         {
1063                 if (type == null)
1064                         return false;
1065
1066                 if (type.MemberDefinition == parent)
1067                         return false;
1068
1069                 type = type.DeclaringType;
1070                 while (type != null) {
1071                         if (type.MemberDefinition == parent)
1072                                 return true;
1073
1074                         type = type.DeclaringType;
1075                 }
1076
1077                 return false;
1078         }
1079
1080         public static TypeSpec GetElementType (TypeSpec t)
1081         {
1082                 return ((ElementTypeSpec)t).Element;
1083         }
1084
1085         /// <summary>
1086         /// This method is not implemented by MS runtime for dynamic types
1087         /// </summary>
1088         public static bool HasElementType (TypeSpec t)
1089         {
1090                 return t is ElementTypeSpec;
1091         }
1092
1093         /// <summary>
1094         ///   Utility function that can be used to probe whether a type
1095         ///   is managed or not.  
1096         /// </summary>
1097         public static bool VerifyUnmanaged (ModuleContainer rc, TypeSpec t, Location loc)
1098         {
1099                 if (t.IsUnmanaged)
1100                         return true;
1101
1102                 while (t.IsPointer)
1103                         t = ((ElementTypeSpec) t).Element;
1104
1105                 rc.Compiler.Report.SymbolRelatedToPreviousError (t);
1106                 rc.Compiler.Report.Error (208, loc,
1107                         "Cannot take the address of, get the size of, or declare a pointer to a managed type `{0}'",
1108                         t.GetSignatureForError ());
1109
1110                 return false;   
1111         }
1112 #region Generics
1113         // This method always return false for non-generic compiler,
1114         // while Type.IsGenericParameter is returned if it is supported.
1115         public static bool IsGenericParameter (TypeSpec type)
1116         {
1117                 return type.IsGenericParameter;
1118         }
1119
1120         public static bool IsGenericType (TypeSpec type)
1121         {
1122                 return type.IsGeneric;
1123         }
1124
1125         public static TypeSpec[] GetTypeArguments (TypeSpec t)
1126         {
1127                 // TODO: return empty array !!
1128                 return t.TypeArguments;
1129         }
1130
1131         /// <summary>
1132         ///   Check whether `type' and `parent' are both instantiations of the same
1133         ///   generic type.  Note that we do not check the type parameters here.
1134         /// </summary>
1135         public static bool IsInstantiationOfSameGenericType (TypeSpec type, TypeSpec parent)
1136         {
1137                 return type == parent || type.MemberDefinition == parent.MemberDefinition;
1138         }
1139 #endregion
1140 }
1141
1142 }