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