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