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