Merge pull request #234 from kripper/master
[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);
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
232                 public PredefinedTypes (ModuleContainer module)
233                 {
234                         TypedReference = new PredefinedType (module, MemberKind.Struct, "System", "TypedReference");
235                         ArgIterator = new PredefinedType (module, MemberKind.Struct, "System", "ArgIterator");
236
237                         MarshalByRefObject = new PredefinedType (module, MemberKind.Class, "System", "MarshalByRefObject");
238                         RuntimeHelpers = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "RuntimeHelpers");
239                         IAsyncResult = new PredefinedType (module, MemberKind.Interface, "System", "IAsyncResult");
240                         AsyncCallback = new PredefinedType (module, MemberKind.Delegate, "System", "AsyncCallback");
241                         RuntimeArgumentHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeArgumentHandle");
242                         CharSet = new PredefinedType (module, MemberKind.Enum, "System.Runtime.InteropServices", "CharSet");
243                         IsVolatile = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "IsVolatile");
244                         IEnumeratorGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IEnumerator", 1);
245                         IListGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IList", 1);
246                         ICollectionGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "ICollection", 1);
247                         IEnumerableGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IEnumerable", 1);
248                         Nullable = new PredefinedType (module, MemberKind.Struct, "System", "Nullable", 1);
249                         Activator = new PredefinedType (module, MemberKind.Class, "System", "Activator");
250                         Interlocked = new PredefinedType (module, MemberKind.Class, "System.Threading", "Interlocked");
251                         Monitor = new PredefinedType (module, MemberKind.Class, "System.Threading", "Monitor");
252                         NotSupportedException = new PredefinedType (module, MemberKind.Class, "System", "NotSupportedException");
253                         RuntimeFieldHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeFieldHandle");
254                         RuntimeMethodHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeMethodHandle");
255                         SecurityAction = new PredefinedType (module, MemberKind.Enum, "System.Security.Permissions", "SecurityAction");
256                         Dictionary = new PredefinedType (module, MemberKind.Class, "System.Collections.Generic", "Dictionary", 2);
257                         Hashtable = new PredefinedType (module, MemberKind.Class, "System.Collections", "Hashtable");
258
259                         Expression = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "Expression");
260                         ExpressionGeneric = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "Expression", 1);
261                         MemberBinding = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "MemberBinding");
262                         ParameterExpression = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "ParameterExpression");
263                         FieldInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "FieldInfo");
264                         MethodBase = new PredefinedType (module, MemberKind.Class, "System.Reflection", "MethodBase");
265                         MethodInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "MethodInfo");
266                         ConstructorInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "ConstructorInfo");
267
268                         CallSite = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "CallSite");
269                         CallSiteGeneric = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "CallSite", 1);
270                         Binder = new PredefinedType (module, MemberKind.Class, "Microsoft.CSharp.RuntimeBinder", "Binder");
271                         BinderFlags = new PredefinedType (module, MemberKind.Enum, "Microsoft.CSharp.RuntimeBinder", "CSharpBinderFlags");
272
273                         Action = new PredefinedType (module, MemberKind.Delegate, "System", "Action");
274                         AsyncVoidMethodBuilder = new PredefinedType (module, MemberKind.Struct, "System.Runtime.CompilerServices", "AsyncVoidMethodBuilder");
275                         AsyncTaskMethodBuilder = new PredefinedType (module, MemberKind.Struct, "System.Runtime.CompilerServices", "AsyncTaskMethodBuilder");
276                         AsyncTaskMethodBuilderGeneric = new PredefinedType (module, MemberKind.Struct, "System.Runtime.CompilerServices", "AsyncTaskMethodBuilder", 1);
277                         Task = new PredefinedType (module, MemberKind.Class, "System.Threading.Tasks", "Task");
278                         TaskGeneric = new PredefinedType (module, MemberKind.Class, "System.Threading.Tasks", "Task", 1);
279
280                         //
281                         // Define types which are used for comparison. It does not matter
282                         // if they don't exist as no error report is needed
283                         //
284                         if (TypedReference.Define ())
285                                 TypedReference.TypeSpec.IsSpecialRuntimeType = true;
286
287                         if (ArgIterator.Define ())
288                                 ArgIterator.TypeSpec.IsSpecialRuntimeType = true;
289
290                         if (IEnumerableGeneric.Define ())
291                                 IEnumerableGeneric.TypeSpec.IsGenericIterateInterface = true;
292
293                         if (IListGeneric.Define ())
294                                 IListGeneric.TypeSpec.IsGenericIterateInterface = true;
295
296                         if (ICollectionGeneric.Define ())
297                                 ICollectionGeneric.TypeSpec.IsGenericIterateInterface = true;
298
299                         if (Nullable.Define ())
300                                 Nullable.TypeSpec.IsNullableType = true;
301
302                         if (ExpressionGeneric.Define ())
303                                 ExpressionGeneric.TypeSpec.IsExpressionTreeType = true;
304
305                         Task.Define ();
306                         if (TaskGeneric.Define ())
307                                 TaskGeneric.TypeSpec.IsGenericTask = true;
308                 }
309         }
310
311         class PredefinedMembers
312         {
313                 public readonly PredefinedMember<MethodSpec> ActivatorCreateInstance;
314                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderCreate;
315                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderSetResult;
316                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderSetException;
317                 public readonly PredefinedMember<PropertySpec> AsyncTaskMethodBuilderTask;
318                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericCreate;
319                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericSetResult;
320                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericSetException;
321                 public readonly PredefinedMember<PropertySpec> AsyncTaskMethodBuilderGenericTask;
322                 public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderCreate;
323                 public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderSetException;
324                 public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderSetResult;
325                 public readonly PredefinedMember<MethodSpec> DebuggerBrowsableAttributeCtor;
326                 public readonly PredefinedMember<MethodSpec> DecimalCtor;
327                 public readonly PredefinedMember<MethodSpec> DecimalCtorInt;
328                 public readonly PredefinedMember<MethodSpec> DecimalCtorLong;
329                 public readonly PredefinedMember<MethodSpec> DecimalConstantAttributeCtor;
330                 public readonly PredefinedMember<MethodSpec> DefaultMemberAttributeCtor;
331                 public readonly PredefinedMember<MethodSpec> DelegateCombine;
332                 public readonly PredefinedMember<MethodSpec> DelegateEqual;
333                 public readonly PredefinedMember<MethodSpec> DelegateInequal;
334                 public readonly PredefinedMember<MethodSpec> DelegateRemove;
335                 public readonly PredefinedMember<MethodSpec> DynamicAttributeCtor;
336                 public readonly PredefinedMember<MethodSpec> FieldInfoGetFieldFromHandle;
337                 public readonly PredefinedMember<MethodSpec> FieldInfoGetFieldFromHandle2;
338                 public readonly PredefinedMember<MethodSpec> IDisposableDispose;
339                 public readonly PredefinedMember<MethodSpec> IEnumerableGetEnumerator;
340                 public readonly PredefinedMember<MethodSpec> InterlockedCompareExchange;
341                 public readonly PredefinedMember<MethodSpec> InterlockedCompareExchange_T;
342                 public readonly PredefinedMember<MethodSpec> FixedBufferAttributeCtor;
343                 public readonly PredefinedMember<MethodSpec> MethodInfoGetMethodFromHandle;
344                 public readonly PredefinedMember<MethodSpec> MethodInfoGetMethodFromHandle2;
345                 public readonly PredefinedMember<MethodSpec> MonitorEnter;
346                 public readonly PredefinedMember<MethodSpec> MonitorEnter_v4;
347                 public readonly PredefinedMember<MethodSpec> MonitorExit;
348                 public readonly PredefinedMember<PropertySpec> RuntimeCompatibilityWrapNonExceptionThrows;
349                 public readonly PredefinedMember<MethodSpec> RuntimeHelpersInitializeArray;
350                 public readonly PredefinedMember<PropertySpec> RuntimeHelpersOffsetToStringData;
351                 public readonly PredefinedMember<ConstSpec> SecurityActionRequestMinimum;
352                 public readonly PredefinedMember<FieldSpec> StringEmpty;
353                 public readonly PredefinedMember<MethodSpec> StringEqual;
354                 public readonly PredefinedMember<MethodSpec> StringInequal;
355                 public readonly PredefinedMember<MethodSpec> StructLayoutAttributeCtor;
356                 public readonly PredefinedMember<FieldSpec> StructLayoutCharSet;
357                 public readonly PredefinedMember<FieldSpec> StructLayoutSize;
358                 public readonly PredefinedMember<MethodSpec> TypeGetTypeFromHandle;
359
360                 public PredefinedMembers (ModuleContainer module)
361                 {
362                         var types = module.PredefinedTypes;
363                         var atypes = module.PredefinedAttributes;
364                         var btypes = module.Compiler.BuiltinTypes;
365
366                         ActivatorCreateInstance = new PredefinedMember<MethodSpec> (module, types.Activator,
367                                 MemberFilter.Method ("CreateInstance", 1, ParametersCompiled.EmptyReadOnlyParameters, null));
368
369                         AsyncTaskMethodBuilderCreate = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
370                                 MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, types.AsyncTaskMethodBuilder.TypeSpec));
371
372                         AsyncTaskMethodBuilderSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
373                                 MemberFilter.Method ("SetResult", 0, ParametersCompiled.EmptyReadOnlyParameters, btypes.Void));
374
375                         AsyncTaskMethodBuilderSetException = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
376                                 MemberFilter.Method ("SetException", 0,
377                                 ParametersCompiled.CreateFullyResolved (btypes.Exception), btypes.Void));
378
379                         AsyncTaskMethodBuilderTask = new PredefinedMember<PropertySpec> (module, types.AsyncTaskMethodBuilder,
380                                 MemberFilter.Property ("Task", null));
381
382                         AsyncTaskMethodBuilderGenericCreate = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
383                                 MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, types.AsyncVoidMethodBuilder.TypeSpec));
384
385                         AsyncTaskMethodBuilderGenericSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
386                                 "SetResult", MemberKind.Method, () => new TypeSpec[] {
387                                                 types.AsyncTaskMethodBuilderGeneric.TypeSpec.MemberDefinition.TypeParameters[0]
388                                 });
389
390                         AsyncTaskMethodBuilderGenericSetException = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
391                                 MemberFilter.Method ("SetException", 0,
392                                 ParametersCompiled.CreateFullyResolved (btypes.Exception), btypes.Void));
393
394                         AsyncTaskMethodBuilderGenericTask = new PredefinedMember<PropertySpec> (module, types.AsyncTaskMethodBuilderGeneric,
395                                 MemberFilter.Property ("Task", null));
396
397                         AsyncVoidMethodBuilderCreate = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
398                                 MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, types.AsyncVoidMethodBuilder.TypeSpec));
399
400                         AsyncVoidMethodBuilderSetException = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
401                                 MemberFilter.Method ("SetException", 0, null, btypes.Void));
402
403                         AsyncVoidMethodBuilderSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
404                                 MemberFilter.Method ("SetResult", 0, ParametersCompiled.EmptyReadOnlyParameters, btypes.Void));
405
406                         DebuggerBrowsableAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.DebuggerBrowsable,
407                                 MemberFilter.Constructor (null));
408
409                         DecimalCtor = new PredefinedMember<MethodSpec> (module, btypes.Decimal,
410                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
411                                         btypes.Int, btypes.Int, btypes.Int, btypes.Bool, btypes.Byte)));
412
413                         DecimalCtorInt = new PredefinedMember<MethodSpec> (module, btypes.Decimal,
414                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Int)));
415
416                         DecimalCtorLong = new PredefinedMember<MethodSpec> (module, btypes.Decimal,
417                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Long)));
418
419                         DecimalConstantAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.DecimalConstant,
420                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
421                                         btypes.Byte, btypes.Byte, btypes.UInt, btypes.UInt, btypes.UInt)));
422
423                         DefaultMemberAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.DefaultMember,
424                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.String)));
425
426                         DelegateCombine = new PredefinedMember<MethodSpec> (module, btypes.Delegate, "Combine", btypes.Delegate, btypes.Delegate);
427                         DelegateRemove = new PredefinedMember<MethodSpec> (module, btypes.Delegate, "Remove", btypes.Delegate, btypes.Delegate);
428
429                         DelegateEqual = new PredefinedMember<MethodSpec> (module, btypes.Delegate,
430                                 new MemberFilter (Operator.GetMetadataName (Operator.OpType.Equality), 0, MemberKind.Operator, null, btypes.Bool));
431
432                         DelegateInequal = new PredefinedMember<MethodSpec> (module, btypes.Delegate,
433                                 new MemberFilter (Operator.GetMetadataName (Operator.OpType.Inequality), 0, MemberKind.Operator, null, btypes.Bool));
434
435                         DynamicAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.Dynamic,
436                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
437                                         ArrayContainer.MakeType (module, btypes.Bool))));
438
439                         FieldInfoGetFieldFromHandle = new PredefinedMember<MethodSpec> (module, types.FieldInfo,
440                                 "GetFieldFromHandle", MemberKind.Method, types.RuntimeFieldHandle);
441
442                         FieldInfoGetFieldFromHandle2 = new PredefinedMember<MethodSpec> (module, types.FieldInfo,
443                                 "GetFieldFromHandle", MemberKind.Method, types.RuntimeFieldHandle, new PredefinedType (btypes.RuntimeTypeHandle));
444
445                         FixedBufferAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.FixedBuffer,
446                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Type, btypes.Int)));
447
448                         IDisposableDispose = new PredefinedMember<MethodSpec> (module, btypes.IDisposable, "Dispose", TypeSpec.EmptyTypes);
449
450                         IEnumerableGetEnumerator = new PredefinedMember<MethodSpec> (module, btypes.IEnumerable,
451                                 "GetEnumerator", TypeSpec.EmptyTypes);
452
453                         InterlockedCompareExchange = new PredefinedMember<MethodSpec> (module, types.Interlocked,
454                                 MemberFilter.Method ("CompareExchange", 0,
455                                         new ParametersImported (
456                                                 new[] {
457                                                                 new ParameterData (null, Parameter.Modifier.REF),
458                                                                 new ParameterData (null, Parameter.Modifier.NONE),
459                                                                 new ParameterData (null, Parameter.Modifier.NONE)
460                                                         },
461                                                 new[] {
462                                                                 btypes.Int, btypes.Int, btypes.Int
463                                                         },
464                                                 false),
465                                 btypes.Int));
466
467                         var tp = new TypeParameter(0, new MemberName("T"), null, null, Variance.None);
468                         InterlockedCompareExchange_T = new PredefinedMember<MethodSpec> (module, types.Interlocked,
469                                 MemberFilter.Method ("CompareExchange", 1,
470                                         new ParametersImported (
471                                                 new[] {
472                                                                 new ParameterData (null, Parameter.Modifier.REF),
473                                                                 new ParameterData (null, Parameter.Modifier.NONE),
474                                                                 new ParameterData (null, Parameter.Modifier.NONE)
475                                                         },
476                                                 new[] {
477                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
478                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
479                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
480                                                         }, false),
481                                         null));
482
483                         MethodInfoGetMethodFromHandle = new PredefinedMember<MethodSpec> (module, types.MethodBase,
484                                 "GetMethodFromHandle", MemberKind.Method, types.RuntimeMethodHandle);
485
486                         MethodInfoGetMethodFromHandle2 = new PredefinedMember<MethodSpec> (module, types.MethodBase,
487                                 "GetMethodFromHandle", MemberKind.Method, types.RuntimeMethodHandle, new PredefinedType (btypes.RuntimeTypeHandle));
488
489                         MonitorEnter = new PredefinedMember<MethodSpec> (module, types.Monitor, "Enter", btypes.Object);
490
491                         MonitorEnter_v4 = new PredefinedMember<MethodSpec> (module, types.Monitor,
492                                 MemberFilter.Method ("Enter", 0,
493                                         new ParametersImported (new[] {
494                                                         new ParameterData (null, Parameter.Modifier.NONE),
495                                                         new ParameterData (null, Parameter.Modifier.REF)
496                                                 },
497                                         new[] {
498                                                         btypes.Object, btypes.Bool
499                                                 }, false), null));
500
501                         MonitorExit = new PredefinedMember<MethodSpec> (module, types.Monitor, "Exit", btypes.Object);
502
503                         RuntimeCompatibilityWrapNonExceptionThrows = new PredefinedMember<PropertySpec> (module, atypes.RuntimeCompatibility,
504                                 MemberFilter.Property ("WrapNonExceptionThrows", btypes.Bool));
505
506                         RuntimeHelpersInitializeArray = new PredefinedMember<MethodSpec> (module, types.RuntimeHelpers,
507                                 "InitializeArray", btypes.Array, btypes.RuntimeFieldHandle);
508
509                         RuntimeHelpersOffsetToStringData = new PredefinedMember<PropertySpec> (module, types.RuntimeHelpers,
510                                 MemberFilter.Property ("OffsetToStringData", btypes.Int));
511
512                         SecurityActionRequestMinimum = new PredefinedMember<ConstSpec> (module, types.SecurityAction, "RequestMinimum",
513                                 MemberKind.Field, types.SecurityAction);
514
515                         StringEmpty = new PredefinedMember<FieldSpec> (module, btypes.String, MemberFilter.Field ("Empty", btypes.String));
516
517                         StringEqual = new PredefinedMember<MethodSpec> (module, btypes.String,
518                                 new MemberFilter (Operator.GetMetadataName (Operator.OpType.Equality), 0, MemberKind.Operator, null, btypes.Bool));
519
520                         StringInequal = new PredefinedMember<MethodSpec> (module, btypes.String,
521                                 new MemberFilter (Operator.GetMetadataName (Operator.OpType.Inequality), 0, MemberKind.Operator, null, btypes.Bool));
522
523                         StructLayoutAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.StructLayout,
524                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Short)));
525
526                         StructLayoutCharSet = new PredefinedMember<FieldSpec> (module, atypes.StructLayout, "CharSet",
527                                 MemberKind.Field, types.CharSet);
528
529                         StructLayoutSize = new PredefinedMember<FieldSpec> (module, atypes.StructLayout,
530                                 MemberFilter.Field ("Size", btypes.Int));
531
532                         TypeGetTypeFromHandle = new PredefinedMember<MethodSpec> (module, btypes.Type, "GetTypeFromHandle", btypes.RuntimeTypeHandle);
533                 }
534         }
535
536         public class PredefinedType
537         {
538                 readonly string name;
539                 readonly string ns;
540                 readonly int arity;
541                 readonly MemberKind kind;
542                 protected readonly ModuleContainer module;
543                 protected TypeSpec type;
544
545                 public PredefinedType (ModuleContainer module, MemberKind kind, string ns, string name, int arity)
546                         : this (module, kind, ns, name)
547                 {
548                         this.arity = arity;
549                 }
550
551                 public PredefinedType (ModuleContainer module, MemberKind kind, string ns, string name)
552                 {
553                         this.module = module;
554                         this.kind = kind;
555                         this.name = name;
556                         this.ns = ns;
557                 }
558
559                 public PredefinedType (BuiltinTypeSpec type)
560                 {
561                         this.kind = type.Kind;
562                         this.name = type.Name;
563                         this.ns = type.Namespace;
564                         this.type = type;
565                 }
566
567                 #region Properties
568
569                 public int Arity {
570                         get {
571                                 return arity;
572                         }
573                 }
574
575                 public bool IsDefined {
576                         get {
577                                 return type != null;
578                         }
579                 }
580
581                 public string Name {
582                         get {
583                                 return name;
584                         }
585                 }
586
587                 public string Namespace {
588                         get {
589                                 return ns;
590                         }
591                 }
592
593                 public TypeSpec TypeSpec {
594                         get {
595                                 return type;
596                         }
597                 }
598
599                 #endregion
600
601                 public bool Define ()
602                 {
603                         if (type != null)
604                                 return true;
605
606                         type = Resolve (module, kind, ns, name, arity, false);
607                         return type != null;
608                 }
609
610                 public string GetSignatureForError ()
611                 {
612                         return ns + "." + name;
613                 }
614
615                 public static TypeSpec Resolve (ModuleContainer module, MemberKind kind, string ns, string name, int arity)
616                 {
617                         return Resolve (module, kind, ns, name, arity, true);
618                 }
619
620                 public static TypeSpec Resolve (ModuleContainer module, MemberKind kind, string ns, string name, int arity, bool reportErrors)
621                 {
622                         Namespace type_ns = module.GlobalRootNamespace.GetNamespace (ns, true);
623                         var found = type_ns.GetAllTypes (name);
624                         if (found == null) {
625                                 if (reportErrors)
626                                         module.Compiler.Report.Error (518, "The predefined type `{0}.{1}' is not defined or imported", ns, name);
627
628                                 return null;
629                         }
630
631                         TypeSpec best_match = null;
632                         foreach (var candidate in found) {
633                                 if (candidate.Kind != kind) {
634                                         if (candidate.Kind == MemberKind.Struct && kind == MemberKind.Void && candidate.MemberDefinition is TypeContainer) {
635                                                 // Void is declared as struct but we keep it internally as
636                                                 // special kind, the swap will be done by caller
637                                         } else {
638                                                 continue;
639                                         }
640                                 }
641
642                                 if (candidate.Arity != arity)
643                                         continue;
644
645                                 if ((candidate.Modifiers & Modifiers.INTERNAL) != 0 && !candidate.MemberDefinition.IsInternalAsPublic (module.DeclaringAssembly))
646                                         continue;
647
648                                 if (best_match == null) {
649                                         best_match = candidate;
650                                         continue;
651                                 }
652
653                                 var other_match = best_match;
654                                 if (!best_match.MemberDefinition.IsImported &&
655                                         module.Compiler.BuiltinTypes.Object.MemberDefinition.DeclaringAssembly == candidate.MemberDefinition.DeclaringAssembly) {
656                                         best_match = candidate;
657                                 }
658
659                                 string location;
660                                 if (best_match.MemberDefinition is MemberCore) {
661                                         location = ((MemberCore) best_match.MemberDefinition).Location.Name;
662                                 } else {
663                                         var assembly = (ImportedAssemblyDefinition) best_match.MemberDefinition.DeclaringAssembly;
664                                         location = Path.GetFileName (assembly.Location);
665                                 }
666
667                                 module.Compiler.Report.SymbolRelatedToPreviousError (other_match);
668                                 module.Compiler.Report.SymbolRelatedToPreviousError (candidate);
669
670                                 module.Compiler.Report.Warning (1685, 1,
671                                         "The predefined type `{0}.{1}' is defined multiple times. Using definition from `{2}'",
672                                         ns, name, location);
673
674                                 break;
675                         }
676
677                         if (best_match == null && reportErrors) {
678                                 Location loc;
679                                 if (found[0].MemberDefinition is MemberCore) {
680                                         loc = ((MemberCore) found[0].MemberDefinition).Location;
681                                 } else {
682                                         loc = Location.Null;
683                                         module.Compiler.Report.SymbolRelatedToPreviousError (found[0]);
684                                 }
685
686                                 module.Compiler.Report.Error (520, loc, "The predefined type `{0}.{1}' is not declared correctly", ns, name);
687                         }
688
689                         return best_match;
690                 }
691
692                 public TypeSpec Resolve ()
693                 {
694                         if (type == null)
695                                 type = Resolve (module, kind, ns, name, arity);
696
697                         return type;
698                 }
699         }
700
701         class PredefinedMember<T> where T : MemberSpec
702         {
703                 readonly ModuleContainer module;
704                 T member;
705                 TypeSpec declaring_type;
706                 readonly PredefinedType declaring_type_predefined;
707                 MemberFilter filter;
708                 readonly Func<TypeSpec[]> filter_builder;
709
710                 public PredefinedMember (ModuleContainer module, PredefinedType type, MemberFilter filter)
711                 {
712                         this.module = module;
713                         this.declaring_type_predefined = type;
714                         this.filter = filter;
715                 }
716
717                 public PredefinedMember (ModuleContainer module, TypeSpec type, MemberFilter filter)
718                 {
719                         this.module = module;
720                         this.declaring_type = type;
721                         this.filter = filter;
722                 }
723
724                 public PredefinedMember (ModuleContainer module, PredefinedType type, string name, params TypeSpec[] types)
725                         : this (module, type, MemberFilter.Method (name, 0, ParametersCompiled.CreateFullyResolved (types), null))
726                 {
727                 }
728
729                 public PredefinedMember (ModuleContainer module, PredefinedType type, string name, MemberKind kind, params PredefinedType[] types)
730                         : this (module, type, new MemberFilter (name, 0, kind, null, null))
731                 {
732                         filter_builder = () => {
733                                 var ptypes = new TypeSpec[types.Length];
734                                 for (int i = 0; i < ptypes.Length; ++i) {
735                                         var p = types[i];
736                                         if (!p.Define ())
737                                                 return null;
738
739                                         ptypes[i] = p.TypeSpec;
740                                 }
741
742                                 return ptypes;
743                         };
744                 }
745
746                 public PredefinedMember (ModuleContainer module, PredefinedType type, string name, MemberKind kind, Func<TypeSpec[]> typesBuilder)
747                         : this (module, type, new MemberFilter (name, 0, kind, null, null))
748                 {
749                         filter_builder = typesBuilder;
750                 }
751
752                 public PredefinedMember (ModuleContainer module, BuiltinTypeSpec type, string name, params TypeSpec[] types)
753                         : this (module, type, MemberFilter.Method (name, 0, ParametersCompiled.CreateFullyResolved (types), null))
754                 {
755                 }
756
757                 public T Get ()
758                 {
759                         if (member != null)
760                                 return member;
761
762                         if (declaring_type == null) {
763                                 if (!declaring_type_predefined.Define ())
764                                         return null;
765
766                                 declaring_type = declaring_type_predefined.TypeSpec;
767                         }
768
769                         if (filter_builder != null) {
770                                 var types = filter_builder ();
771
772                                 if (filter.Kind == MemberKind.Field)
773                                         filter = new MemberFilter (filter.Name, filter.Arity, filter.Kind, null, types [0]);
774                                 else
775                                         filter = new MemberFilter (filter.Name, filter.Arity, filter.Kind,
776                                                 ParametersCompiled.CreateFullyResolved (types), filter.MemberType);
777                         }
778
779                         member = MemberCache.FindMember (declaring_type, filter, BindingRestriction.DeclaredOnly) as T;
780                         if (member == null)
781                                 return null;
782
783                         if (!member.IsAccessible (module))
784                                 return null;
785
786                         return member;
787                 }
788
789                 public T Resolve (Location loc)
790                 {
791                         if (member != null)
792                                 return member;
793
794                         if (Get () != null)
795                                 return member;
796
797                         if (declaring_type == null) {
798                                 if (declaring_type_predefined.Resolve () == null)
799                                         return null;
800                         }
801
802                         if (filter_builder != null) {
803                                 filter = new MemberFilter (filter.Name, filter.Arity, filter.Kind,
804                                         ParametersCompiled.CreateFullyResolved (filter_builder ()), filter.MemberType);
805                         }
806
807                         string method_args = null;
808                         if (filter.Parameters != null)
809                                 method_args = filter.Parameters.GetSignatureForError ();
810
811                         module.Compiler.Report.Error (656, loc, "The compiler required member `{0}.{1}{2}' could not be found or is inaccessible",
812                                 declaring_type.GetSignatureForError (), filter.Name, method_args);
813
814                         return null;
815                 }
816         }
817
818         partial class TypeManager {
819
820         /// <summary>
821         ///   Returns the C# name of a type if possible, or the full type name otherwise
822         /// </summary>
823         static public string CSharpName (TypeSpec t)
824         {
825                 return t.GetSignatureForError ();
826         }
827
828         static public string CSharpName (IList<TypeSpec> types)
829         {
830                 if (types.Count == 0)
831                         return string.Empty;
832
833                 StringBuilder sb = new StringBuilder ();
834                 for (int i = 0; i < types.Count; ++i) {
835                         if (i > 0)
836                                 sb.Append (",");
837
838                         sb.Append (CSharpName (types [i]));
839                 }
840                 return sb.ToString ();
841         }
842
843         static public string GetFullNameSignature (MemberSpec mi)
844         {
845                 return mi.GetSignatureForError ();
846         }
847
848         static public string CSharpSignature (MemberSpec mb)
849         {
850                 return mb.GetSignatureForError ();
851         }
852                 
853         public static bool IsFamilyAccessible (TypeSpec type, TypeSpec parent)
854         {
855 //              TypeParameter tparam = LookupTypeParameter (type);
856 //              TypeParameter pparam = LookupTypeParameter (parent);
857
858                 if (type.Kind == MemberKind.TypeParameter && parent.Kind == MemberKind.TypeParameter) { // (tparam != null) && (pparam != null)) {
859                         if (type == parent)
860                                 return true;
861
862                         throw new NotImplementedException ("net");
863 //                      return tparam.IsSubclassOf (parent);
864                 }
865
866                 do {
867                         if (IsInstantiationOfSameGenericType (type, parent))
868                                 return true;
869
870                         type = type.BaseType;
871                 } while (type != null);
872
873                 return false;
874         }
875
876         //
877         // Checks whether `type' is a nested child of `parent'.
878         //
879         public static bool IsNestedChildOf (TypeSpec type, ITypeDefinition parent)
880         {
881                 if (type == null)
882                         return false;
883
884                 if (type.MemberDefinition == parent)
885                         return false;
886
887                 type = type.DeclaringType;
888                 while (type != null) {
889                         if (type.MemberDefinition == parent)
890                                 return true;
891
892                         type = type.DeclaringType;
893                 }
894
895                 return false;
896         }
897
898         public static TypeSpec GetElementType (TypeSpec t)
899         {
900                 return ((ElementTypeSpec)t).Element;
901         }
902
903         /// <summary>
904         /// This method is not implemented by MS runtime for dynamic types
905         /// </summary>
906         public static bool HasElementType (TypeSpec t)
907         {
908                 return t is ElementTypeSpec;
909         }
910
911         /// <summary>
912         ///   Utility function that can be used to probe whether a type
913         ///   is managed or not.  
914         /// </summary>
915         public static bool VerifyUnmanaged (ModuleContainer rc, TypeSpec t, Location loc)
916         {
917                 if (t.IsUnmanaged)
918                         return true;
919
920                 while (t.IsPointer)
921                         t = ((ElementTypeSpec) t).Element;
922
923                 rc.Compiler.Report.SymbolRelatedToPreviousError (t);
924                 rc.Compiler.Report.Error (208, loc,
925                         "Cannot take the address of, get the size of, or declare a pointer to a managed type `{0}'",
926                         CSharpName (t));
927
928                 return false;   
929         }
930 #region Generics
931         // This method always return false for non-generic compiler,
932         // while Type.IsGenericParameter is returned if it is supported.
933         public static bool IsGenericParameter (TypeSpec type)
934         {
935                 return type.IsGenericParameter;
936         }
937
938         public static bool IsGenericType (TypeSpec type)
939         {
940                 return type.IsGeneric;
941         }
942
943         public static TypeSpec[] GetTypeArguments (TypeSpec t)
944         {
945                 // TODO: return empty array !!
946                 return t.TypeArguments;
947         }
948
949         /// <summary>
950         ///   Check whether `type' and `parent' are both instantiations of the same
951         ///   generic type.  Note that we do not check the type parameters here.
952         /// </summary>
953         public static bool IsInstantiationOfSameGenericType (TypeSpec type, TypeSpec parent)
954         {
955                 return type == parent || type.MemberDefinition == parent.MemberDefinition;
956         }
957 #endregion
958 }
959
960 }