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