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