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