Merge pull request #537 from madewokherd/ccwmarshal
[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
695                 public PredefinedType (ModuleContainer module, MemberKind kind, string ns, string name, int arity)
696                         : this (module, kind, ns, name)
697                 {
698                         this.arity = arity;
699                 }
700
701                 public PredefinedType (ModuleContainer module, MemberKind kind, string ns, string name)
702                 {
703                         this.module = module;
704                         this.kind = kind;
705                         this.name = name;
706                         this.ns = ns;
707                 }
708
709                 public PredefinedType (BuiltinTypeSpec type)
710                 {
711                         this.kind = type.Kind;
712                         this.name = type.Name;
713                         this.ns = type.Namespace;
714                         this.type = type;
715                 }
716
717                 #region Properties
718
719                 public int Arity {
720                         get {
721                                 return arity;
722                         }
723                 }
724
725                 public bool IsDefined {
726                         get {
727                                 return type != null;
728                         }
729                 }
730
731                 public string Name {
732                         get {
733                                 return name;
734                         }
735                 }
736
737                 public string Namespace {
738                         get {
739                                 return ns;
740                         }
741                 }
742
743                 public TypeSpec TypeSpec {
744                         get {
745                                 return type;
746                         }
747                 }
748
749                 #endregion
750
751                 public bool Define ()
752                 {
753                         if (type != null)
754                                 return true;
755
756                         type = Resolve (module, kind, ns, name, arity, false, false);
757                         return type != null;
758                 }
759
760                 public string GetSignatureForError ()
761                 {
762                         return ns + "." + name;
763                 }
764
765                 public static TypeSpec Resolve (ModuleContainer module, MemberKind kind, string ns, string name, int arity, bool required, bool reportErrors)
766                 {
767                         //
768                         // Cannot call it with true because it could create non-existent namespaces for
769                         // predefined types. It's set to true only for build-in types which all must
770                         // exist therefore it does not matter, for predefined types we don't want to create
771                         // fake namespaces when type is optional and does not exist (e.g. System.Linq).
772                         //
773                         Namespace type_ns = module.GlobalRootNamespace.GetNamespace (ns, required);
774                         IList<TypeSpec> found = null;
775                         if (type_ns != null)
776                                 found = type_ns.GetAllTypes (name);
777
778                         if (found == null) {
779                                 if (reportErrors )
780                                         module.Compiler.Report.Error (518, "The predefined type `{0}.{1}' is not defined or imported", ns, name);
781
782                                 return null;
783                         }
784
785                         TypeSpec best_match = null;
786                         foreach (var candidate in found) {
787                                 if (candidate.Kind != kind) {
788                                         if (candidate.Kind == MemberKind.Struct && kind == MemberKind.Void && candidate.MemberDefinition is TypeContainer) {
789                                                 // Void is declared as struct but we keep it internally as
790                                                 // special kind, the swap will be done by caller
791                                         } else {
792                                                 continue;
793                                         }
794                                 }
795
796                                 if (candidate.Arity != arity)
797                                         continue;
798
799                                 if ((candidate.Modifiers & Modifiers.INTERNAL) != 0 && !candidate.MemberDefinition.IsInternalAsPublic (module.DeclaringAssembly))
800                                         continue;
801
802                                 if (best_match == null) {
803                                         best_match = candidate;
804                                         continue;
805                                 }
806
807                                 var other_match = best_match;
808                                 if (!best_match.MemberDefinition.IsImported &&
809                                         module.Compiler.BuiltinTypes.Object.MemberDefinition.DeclaringAssembly == candidate.MemberDefinition.DeclaringAssembly) {
810                                         best_match = candidate;
811                                 }
812
813                                 string location;
814                                 if (best_match.MemberDefinition is MemberCore) {
815                                         location = ((MemberCore) best_match.MemberDefinition).Location.Name;
816                                 } else {
817                                         var assembly = (ImportedAssemblyDefinition) best_match.MemberDefinition.DeclaringAssembly;
818                                         location = Path.GetFileName (assembly.Location);
819                                 }
820
821                                 module.Compiler.Report.SymbolRelatedToPreviousError (other_match);
822                                 module.Compiler.Report.SymbolRelatedToPreviousError (candidate);
823
824                                 module.Compiler.Report.Warning (1685, 1,
825                                         "The predefined type `{0}.{1}' is defined multiple times. Using definition from `{2}'",
826                                         ns, name, location);
827
828                                 break;
829                         }
830
831                         if (best_match == null && reportErrors) {
832                                 Location loc;
833                                 if (found[0].MemberDefinition is MemberCore) {
834                                         loc = ((MemberCore) found[0].MemberDefinition).Location;
835                                 } else {
836                                         loc = Location.Null;
837                                         module.Compiler.Report.SymbolRelatedToPreviousError (found[0]);
838                                 }
839
840                                 module.Compiler.Report.Error (520, loc, "The predefined type `{0}.{1}' is not declared correctly", ns, name);
841                         }
842
843                         return best_match;
844                 }
845
846                 public TypeSpec Resolve ()
847                 {
848                         if (type == null)
849                                 type = Resolve (module, kind, ns, name, arity, false, true);
850
851                         return type;
852                 }
853         }
854
855         public class PredefinedMember<T> where T : MemberSpec
856         {
857                 readonly ModuleContainer module;
858                 T member;
859                 TypeSpec declaring_type;
860                 readonly PredefinedType declaring_type_predefined;
861                 MemberFilter filter;
862                 readonly Func<TypeSpec[]> filter_builder;
863
864                 public PredefinedMember (ModuleContainer module, PredefinedType type, MemberFilter filter)
865                 {
866                         this.module = module;
867                         this.declaring_type_predefined = type;
868                         this.filter = filter;
869                 }
870
871                 public PredefinedMember (ModuleContainer module, TypeSpec type, MemberFilter filter)
872                 {
873                         this.module = module;
874                         this.declaring_type = type;
875                         this.filter = filter;
876                 }
877
878                 public PredefinedMember (ModuleContainer module, PredefinedType type, string name, params TypeSpec[] types)
879                         : this (module, type, MemberFilter.Method (name, 0, ParametersCompiled.CreateFullyResolved (types), null))
880                 {
881                 }
882
883                 public PredefinedMember (ModuleContainer module, PredefinedType type, string name, MemberKind kind, params PredefinedType[] types)
884                         : this (module, type, new MemberFilter (name, 0, kind, null, null))
885                 {
886                         filter_builder = () => {
887                                 var ptypes = new TypeSpec[types.Length];
888                                 for (int i = 0; i < ptypes.Length; ++i) {
889                                         var p = types[i];
890                                         if (!p.Define ())
891                                                 return null;
892
893                                         ptypes[i] = p.TypeSpec;
894                                 }
895
896                                 return ptypes;
897                         };
898                 }
899
900                 public PredefinedMember (ModuleContainer module, PredefinedType type, string name, MemberKind kind, Func<TypeSpec[]> typesBuilder, TypeSpec returnType)
901                         : this (module, type, new MemberFilter (name, 0, kind, null, returnType))
902                 {
903                         filter_builder = typesBuilder;
904                 }
905
906                 public PredefinedMember (ModuleContainer module, BuiltinTypeSpec type, string name, params TypeSpec[] types)
907                         : this (module, type, MemberFilter.Method (name, 0, ParametersCompiled.CreateFullyResolved (types), null))
908                 {
909                 }
910
911                 public T Get ()
912                 {
913                         if (member != null)
914                                 return member;
915
916                         if (declaring_type == null) {
917                                 if (!declaring_type_predefined.Define ())
918                                         return null;
919
920                                 declaring_type = declaring_type_predefined.TypeSpec;
921                         }
922
923                         if (filter_builder != null) {
924                                 var types = filter_builder ();
925
926                                 if (filter.Kind == MemberKind.Field)
927                                         filter = new MemberFilter (filter.Name, filter.Arity, filter.Kind, null, types [0]);
928                                 else
929                                         filter = new MemberFilter (filter.Name, filter.Arity, filter.Kind,
930                                                 ParametersCompiled.CreateFullyResolved (types), filter.MemberType);
931                         }
932
933                         member = MemberCache.FindMember (declaring_type, filter, BindingRestriction.DeclaredOnly) as T;
934                         if (member == null)
935                                 return null;
936
937                         if (!member.IsAccessible (module))
938                                 return null;
939
940                         return member;
941                 }
942
943                 public T Resolve (Location loc)
944                 {
945                         if (member != null)
946                                 return member;
947
948                         if (Get () != null)
949                                 return member;
950
951                         if (declaring_type == null) {
952                                 if (declaring_type_predefined.Resolve () == null)
953                                         return null;
954                         }
955
956                         if (filter_builder != null) {
957                                 filter = new MemberFilter (filter.Name, filter.Arity, filter.Kind,
958                                         ParametersCompiled.CreateFullyResolved (filter_builder ()), filter.MemberType);
959                         }
960
961                         string method_args = null;
962                         if (filter.Parameters != null)
963                                 method_args = filter.Parameters.GetSignatureForError ();
964
965                         module.Compiler.Report.Error (656, loc, "The compiler required member `{0}.{1}{2}' could not be found or is inaccessible",
966                                 declaring_type.GetSignatureForError (), filter.Name, method_args);
967
968                         return null;
969                 }
970         }
971
972         public class AwaiterDefinition
973         {
974                 public PropertySpec IsCompleted { get; set; }
975                 public MethodSpec GetResult { get; set; }
976                 public bool INotifyCompletion { get; set; }
977
978                 public bool IsValidPattern {
979                         get {
980                                 return IsCompleted != null && GetResult != null && IsCompleted.HasGet;
981                         }
982                 }
983         }
984
985         partial class TypeManager {
986
987         /// <summary>
988         ///   Returns the C# name of a type if possible, or the full type name otherwise
989         /// </summary>
990         static public string CSharpName (TypeSpec t)
991         {
992                 return t.GetSignatureForError ();
993         }
994
995         static public string CSharpName (IList<TypeSpec> types)
996         {
997                 if (types.Count == 0)
998                         return string.Empty;
999
1000                 StringBuilder sb = new StringBuilder ();
1001                 for (int i = 0; i < types.Count; ++i) {
1002                         if (i > 0)
1003                                 sb.Append (",");
1004
1005                         sb.Append (CSharpName (types [i]));
1006                 }
1007                 return sb.ToString ();
1008         }
1009
1010         static public string GetFullNameSignature (MemberSpec mi)
1011         {
1012                 return mi.GetSignatureForError ();
1013         }
1014
1015         static public string CSharpSignature (MemberSpec mb)
1016         {
1017                 return mb.GetSignatureForError ();
1018         }
1019                 
1020         public static bool IsFamilyAccessible (TypeSpec type, TypeSpec parent)
1021         {
1022 //              TypeParameter tparam = LookupTypeParameter (type);
1023 //              TypeParameter pparam = LookupTypeParameter (parent);
1024
1025                 if (type.Kind == MemberKind.TypeParameter && parent.Kind == MemberKind.TypeParameter) { // (tparam != null) && (pparam != null)) {
1026                         if (type == parent)
1027                                 return true;
1028
1029                         throw new NotImplementedException ("net");
1030 //                      return tparam.IsSubclassOf (parent);
1031                 }
1032
1033                 do {
1034                         if (IsInstantiationOfSameGenericType (type, parent))
1035                                 return true;
1036
1037                         type = type.BaseType;
1038                 } while (type != null);
1039
1040                 return false;
1041         }
1042
1043         //
1044         // Checks whether `type' is a nested child of `parent'.
1045         //
1046         public static bool IsNestedChildOf (TypeSpec type, ITypeDefinition parent)
1047         {
1048                 if (type == null)
1049                         return false;
1050
1051                 if (type.MemberDefinition == parent)
1052                         return false;
1053
1054                 type = type.DeclaringType;
1055                 while (type != null) {
1056                         if (type.MemberDefinition == parent)
1057                                 return true;
1058
1059                         type = type.DeclaringType;
1060                 }
1061
1062                 return false;
1063         }
1064
1065         public static TypeSpec GetElementType (TypeSpec t)
1066         {
1067                 return ((ElementTypeSpec)t).Element;
1068         }
1069
1070         /// <summary>
1071         /// This method is not implemented by MS runtime for dynamic types
1072         /// </summary>
1073         public static bool HasElementType (TypeSpec t)
1074         {
1075                 return t is ElementTypeSpec;
1076         }
1077
1078         /// <summary>
1079         ///   Utility function that can be used to probe whether a type
1080         ///   is managed or not.  
1081         /// </summary>
1082         public static bool VerifyUnmanaged (ModuleContainer rc, TypeSpec t, Location loc)
1083         {
1084                 if (t.IsUnmanaged)
1085                         return true;
1086
1087                 while (t.IsPointer)
1088                         t = ((ElementTypeSpec) t).Element;
1089
1090                 rc.Compiler.Report.SymbolRelatedToPreviousError (t);
1091                 rc.Compiler.Report.Error (208, loc,
1092                         "Cannot take the address of, get the size of, or declare a pointer to a managed type `{0}'",
1093                         CSharpName (t));
1094
1095                 return false;   
1096         }
1097 #region Generics
1098         // This method always return false for non-generic compiler,
1099         // while Type.IsGenericParameter is returned if it is supported.
1100         public static bool IsGenericParameter (TypeSpec type)
1101         {
1102                 return type.IsGenericParameter;
1103         }
1104
1105         public static bool IsGenericType (TypeSpec type)
1106         {
1107                 return type.IsGeneric;
1108         }
1109
1110         public static TypeSpec[] GetTypeArguments (TypeSpec t)
1111         {
1112                 // TODO: return empty array !!
1113                 return t.TypeArguments;
1114         }
1115
1116         /// <summary>
1117         ///   Check whether `type' and `parent' are both instantiations of the same
1118         ///   generic type.  Note that we do not check the type parameters here.
1119         /// </summary>
1120         public static bool IsInstantiationOfSameGenericType (TypeSpec type, TypeSpec parent)
1121         {
1122                 return type == parent || type.MemberDefinition == parent.MemberDefinition;
1123         }
1124 #endregion
1125 }
1126
1127 }