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