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