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