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