Merge pull request #5668 from kumpera/wasm-work-p4
[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
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
128                         types = new BuiltinTypeSpec[] {
129                                 Object, ValueType, Attribute,
130                                 Int, UInt, Long, ULong, Float, Double, Char, Short, Decimal, Bool, SByte, Byte, UShort, String,
131                                 Enum, Delegate, MulticastDelegate, Void, Array, Type, IEnumerator, IEnumerable, IDisposable,
132                                 IntPtr, UIntPtr, RuntimeFieldHandle, RuntimeTypeHandle, Exception };
133                 }
134
135                 public BuiltinTypeSpec[] AllTypes {
136                         get {
137                                 return types;
138                         }
139                 }
140
141                 public bool CheckDefinitions (ModuleContainer module)
142                 {
143                         var ctx = module.Compiler;
144                         foreach (var p in types) {
145                                 var found = PredefinedType.Resolve (module, p.Kind, p.Namespace, p.Name, p.Arity, true, true);
146                                 if (found == null || found == p)
147                                         continue;
148
149                                 var tc = found.MemberDefinition as TypeDefinition;
150                                 if (tc != null) {
151                                         var ns = module.GlobalRootNamespace.GetNamespace (p.Namespace, false);
152                                         ns.SetBuiltinType (p);
153
154                                         tc.SetPredefinedSpec (p);
155                                         p.SetDefinition (found);
156                                 }
157                         }
158
159                         if (ctx.Report.Errors != 0)
160                                 return false;
161
162                         // Set internal build-in types
163                         Dynamic.SetDefinition (Object);
164
165                         return true;
166                 }
167         }
168
169         //
170         // Compiler predefined types. Usually used for compiler generated
171         // code or for comparison against well known framework type. They
172         // may not exist as they are optional
173         //
174         class PredefinedTypes
175         {
176                 public readonly PredefinedType ArgIterator;
177                 public readonly PredefinedType TypedReference;
178                 public readonly PredefinedType MarshalByRefObject;
179                 public readonly PredefinedType RuntimeHelpers;
180                 public readonly PredefinedType IAsyncResult;
181                 public readonly PredefinedType AsyncCallback;
182                 public readonly PredefinedType RuntimeArgumentHandle;
183                 public readonly PredefinedType CharSet;
184                 public readonly PredefinedType IsVolatile;
185                 public readonly PredefinedType IEnumeratorGeneric;
186                 public readonly PredefinedType IListGeneric;
187                 public readonly PredefinedType IReadOnlyListGeneric;
188                 public readonly PredefinedType ICollectionGeneric;
189                 public readonly PredefinedType IReadOnlyCollectionGeneric;
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                 public readonly PredefinedType Array;
202
203                 public readonly TypeSpec[] SwitchUserTypes;
204
205                 //
206                 // C# 3.0
207                 //
208                 public readonly PredefinedType Expression;
209                 public readonly PredefinedType ExpressionGeneric;
210                 public readonly PredefinedType ParameterExpression;
211                 public readonly PredefinedType FieldInfo;
212                 public readonly PredefinedType MethodBase;
213                 public readonly PredefinedType MethodInfo;
214                 public readonly PredefinedType ConstructorInfo;
215                 public readonly PredefinedType MemberBinding;
216
217                 //
218                 // C# 4.0
219                 //
220                 public readonly PredefinedType Binder;
221                 public readonly PredefinedType CallSite;
222                 public readonly PredefinedType CallSiteGeneric;
223                 public readonly PredefinedType BinderFlags;
224
225                 //
226                 // C# 5.0
227                 //
228                 public readonly PredefinedType AsyncVoidMethodBuilder;
229                 public readonly PredefinedType AsyncTaskMethodBuilder;
230                 public readonly PredefinedType AsyncTaskMethodBuilderGeneric;
231                 public readonly PredefinedType Action;
232                 public readonly PredefinedType Task;
233                 public readonly PredefinedType TaskGeneric;
234                 public readonly PredefinedType IAsyncStateMachine;
235                 public readonly PredefinedType INotifyCompletion;
236                 public readonly PredefinedType ICriticalNotifyCompletion;
237
238                 // C# 6.0
239                 public readonly PredefinedType IFormattable;
240                 public readonly PredefinedType FormattableString;
241                 public readonly PredefinedType FormattableStringFactory;
242
243                 // C# 7.0
244                 public readonly PredefinedType[] Tuples;
245
246                 public PredefinedTypes (ModuleContainer module)
247                 {
248                         TypedReference = new PredefinedType (module, MemberKind.Struct, "System", "TypedReference");
249                         ArgIterator = new PredefinedType (module, MemberKind.Struct, "System", "ArgIterator");
250
251                         MarshalByRefObject = new PredefinedType (module, MemberKind.Class, "System", "MarshalByRefObject");
252                         RuntimeHelpers = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "RuntimeHelpers");
253                         IAsyncResult = new PredefinedType (module, MemberKind.Interface, "System", "IAsyncResult");
254                         AsyncCallback = new PredefinedType (module, MemberKind.Delegate, "System", "AsyncCallback");
255                         RuntimeArgumentHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeArgumentHandle");
256                         CharSet = new PredefinedType (module, MemberKind.Enum, "System.Runtime.InteropServices", "CharSet");
257                         IsVolatile = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "IsVolatile");
258                         IEnumeratorGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IEnumerator", 1);
259                         IListGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IList", 1);
260                         IReadOnlyListGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IReadOnlyList", 1);
261                         ICollectionGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "ICollection", 1);
262                         IReadOnlyCollectionGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IReadOnlyCollection", 1);
263                         IEnumerableGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IEnumerable", 1);
264                         Nullable = new PredefinedType (module, MemberKind.Struct, "System", "Nullable", 1);
265                         Activator = new PredefinedType (module, MemberKind.Class, "System", "Activator");
266                         Interlocked = new PredefinedType (module, MemberKind.Class, "System.Threading", "Interlocked");
267                         Monitor = new PredefinedType (module, MemberKind.Class, "System.Threading", "Monitor");
268                         NotSupportedException = new PredefinedType (module, MemberKind.Class, "System", "NotSupportedException");
269                         RuntimeFieldHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeFieldHandle");
270                         RuntimeMethodHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeMethodHandle");
271                         SecurityAction = new PredefinedType (module, MemberKind.Enum, "System.Security.Permissions", "SecurityAction");
272                         Dictionary = new PredefinedType (module, MemberKind.Class, "System.Collections.Generic", "Dictionary", 2);
273                         Hashtable = new PredefinedType (module, MemberKind.Class, "System.Collections", "Hashtable");
274                         Array = new PredefinedType (module, MemberKind.Class, "System", "Array");
275
276                         Expression = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "Expression");
277                         ExpressionGeneric = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "Expression", 1);
278                         MemberBinding = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "MemberBinding");
279                         ParameterExpression = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "ParameterExpression");
280                         FieldInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "FieldInfo");
281                         MethodBase = new PredefinedType (module, MemberKind.Class, "System.Reflection", "MethodBase");
282                         MethodInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "MethodInfo");
283                         ConstructorInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "ConstructorInfo");
284
285                         CallSite = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "CallSite");
286                         CallSiteGeneric = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "CallSite", 1);
287                         Binder = new PredefinedType (module, MemberKind.Class, "Microsoft.CSharp.RuntimeBinder", "Binder");
288                         BinderFlags = new PredefinedType (module, MemberKind.Enum, "Microsoft.CSharp.RuntimeBinder", "CSharpBinderFlags");
289
290                         Action = new PredefinedType (module, MemberKind.Delegate, "System", "Action");
291                         AsyncVoidMethodBuilder = new PredefinedType (module, MemberKind.Struct, "System.Runtime.CompilerServices", "AsyncVoidMethodBuilder");
292                         AsyncTaskMethodBuilder = new PredefinedType (module, MemberKind.Struct, "System.Runtime.CompilerServices", "AsyncTaskMethodBuilder");
293                         AsyncTaskMethodBuilderGeneric = new PredefinedType (module, MemberKind.Struct, "System.Runtime.CompilerServices", "AsyncTaskMethodBuilder", 1);
294                         Task = new PredefinedType (module, MemberKind.Class, "System.Threading.Tasks", "Task");
295                         TaskGeneric = new PredefinedType (module, MemberKind.Class, "System.Threading.Tasks", "Task", 1);
296                         IAsyncStateMachine = new PredefinedType (module, MemberKind.Interface, "System.Runtime.CompilerServices", "IAsyncStateMachine");
297                         INotifyCompletion = new PredefinedType (module, MemberKind.Interface, "System.Runtime.CompilerServices", "INotifyCompletion");
298                         ICriticalNotifyCompletion = new PredefinedType (module, MemberKind.Interface, "System.Runtime.CompilerServices", "ICriticalNotifyCompletion");
299
300                         IFormattable = new PredefinedType (module, MemberKind.Interface, "System", "IFormattable");
301                         FormattableString = new PredefinedType (module, MemberKind.Class, "System", "FormattableString");
302                         FormattableStringFactory = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "FormattableStringFactory");
303
304                         //
305                         // Define types which are used for comparison. It does not matter
306                         // if they don't exist as no error report is needed
307                         //
308                         if (TypedReference.Define ())
309                                 TypedReference.TypeSpec.IsSpecialRuntimeType = true;
310
311                         if (ArgIterator.Define ())
312                                 ArgIterator.TypeSpec.IsSpecialRuntimeType = true;
313
314                         if (IEnumerableGeneric.Define ())
315                                 IEnumerableGeneric.TypeSpec.IsArrayGenericInterface = true;
316
317                         if (IListGeneric.Define ())
318                                 IListGeneric.TypeSpec.IsArrayGenericInterface = true;
319
320                         if (IReadOnlyListGeneric.Define ())
321                                 IReadOnlyListGeneric.TypeSpec.IsArrayGenericInterface = true;
322
323                         if (ICollectionGeneric.Define ())
324                                 ICollectionGeneric.TypeSpec.IsArrayGenericInterface = true;
325
326                         if (IReadOnlyCollectionGeneric.Define ())
327                                 IReadOnlyCollectionGeneric.TypeSpec.IsArrayGenericInterface = true;
328
329                         if (Nullable.Define ())
330                                 Nullable.TypeSpec.IsNullableType = true;
331
332                         if (ExpressionGeneric.Define ())
333                                 ExpressionGeneric.TypeSpec.IsExpressionTreeType = true;
334
335                         Task.Define ();
336                         if (TaskGeneric.Define ())
337                                 TaskGeneric.TypeSpec.IsGenericTask = true;
338
339                         SwitchUserTypes = Switch.CreateSwitchUserTypes (module, Nullable.TypeSpec);
340
341                         IFormattable.Define ();
342                         FormattableString.Define ();
343
344                         Tuples = new PredefinedType [8];
345                         for (int i = 0; i < Tuples.Length; i++) {
346                                 var pt = new PredefinedType (module, MemberKind.Struct, "System", "ValueTuple", i + 1);
347                                 Tuples [i] = pt;
348                                 if (pt.Define ())
349                                         pt.TypeSpec.IsTupleType = true;
350                         }
351                 }
352         }
353
354         class PredefinedMembers
355         {
356                 public readonly PredefinedMember<MethodSpec> ActivatorCreateInstance;
357                 public readonly PredefinedMember<MethodSpec> ArrayEmpty;
358                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderCreate;
359                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderStart;
360                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderSetResult;
361                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderSetException;
362                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderSetStateMachine;
363                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderOnCompleted;
364                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderOnCompletedUnsafe;
365                 public readonly PredefinedMember<PropertySpec> AsyncTaskMethodBuilderTask;
366                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericCreate;
367                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericStart;
368                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericSetResult;
369                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericSetException;
370                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericSetStateMachine;
371                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericOnCompleted;
372                 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericOnCompletedUnsafe;
373                 public readonly PredefinedMember<PropertySpec> AsyncTaskMethodBuilderGenericTask;
374                 public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderCreate;
375                 public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderStart;
376                 public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderSetException;
377                 public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderSetResult;
378                 public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderSetStateMachine;
379                 public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderOnCompleted;
380                 public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderOnCompletedUnsafe;
381                 public readonly PredefinedMember<MethodSpec> AsyncStateMachineAttributeCtor;
382                 public readonly PredefinedMember<MethodSpec> DebuggerBrowsableAttributeCtor;
383                 public readonly PredefinedMember<MethodSpec> DecimalCtor;
384                 public readonly PredefinedMember<MethodSpec> DecimalCtorInt;
385                 public readonly PredefinedMember<MethodSpec> DecimalCtorLong;
386                 public readonly PredefinedMember<MethodSpec> DecimalConstantAttributeCtor;
387                 public readonly PredefinedMember<MethodSpec> DefaultMemberAttributeCtor;
388                 public readonly PredefinedMember<MethodSpec> DelegateCombine;
389                 public readonly PredefinedMember<MethodSpec> DelegateEqual;
390                 public readonly PredefinedMember<MethodSpec> DelegateInequal;
391                 public readonly PredefinedMember<MethodSpec> DelegateRemove;
392                 public readonly PredefinedMember<MethodSpec> DynamicAttributeCtor;
393                 public readonly PredefinedMember<MethodSpec> FieldInfoGetFieldFromHandle;
394                 public readonly PredefinedMember<MethodSpec> FieldInfoGetFieldFromHandle2;
395                 public readonly PredefinedMember<MethodSpec> IDisposableDispose;
396                 public readonly PredefinedMember<MethodSpec> IEnumerableGetEnumerator;
397                 public readonly PredefinedMember<MethodSpec> InterlockedCompareExchange;
398                 public readonly PredefinedMember<MethodSpec> InterlockedCompareExchange_T;
399                 public readonly PredefinedMember<MethodSpec> FixedBufferAttributeCtor;
400                 public readonly PredefinedMember<MethodSpec> MethodInfoGetMethodFromHandle;
401                 public readonly PredefinedMember<MethodSpec> MethodInfoGetMethodFromHandle2;
402                 public readonly PredefinedMember<MethodSpec> MethodInfoCreateDelegate;
403                 public readonly PredefinedMember<MethodSpec> MonitorEnter;
404                 public readonly PredefinedMember<MethodSpec> MonitorEnter_v4;
405                 public readonly PredefinedMember<MethodSpec> MonitorExit;
406                 public readonly PredefinedMember<PropertySpec> RuntimeCompatibilityWrapNonExceptionThrows;
407                 public readonly PredefinedMember<MethodSpec> RuntimeHelpersInitializeArray;
408                 public readonly PredefinedMember<PropertySpec> RuntimeHelpersOffsetToStringData;
409                 public readonly PredefinedMember<ConstSpec> SecurityActionRequestMinimum;
410                 public readonly PredefinedMember<FieldSpec> StringEmpty;
411                 public readonly PredefinedMember<MethodSpec> StringEqual;
412                 public readonly PredefinedMember<MethodSpec> StringInequal;
413                 public readonly PredefinedMember<MethodSpec> StructLayoutAttributeCtor;
414                 public readonly PredefinedMember<FieldSpec> StructLayoutCharSet;
415                 public readonly PredefinedMember<FieldSpec> StructLayoutSize;
416                 public readonly PredefinedMember<MethodSpec> TypeGetTypeFromHandle;
417                 public readonly PredefinedMember<MethodSpec> TupleElementNamesAttributeCtor;
418
419                 public PredefinedMembers (ModuleContainer module)
420                 {
421                         var types = module.PredefinedTypes;
422                         var atypes = module.PredefinedAttributes;
423                         var btypes = module.Compiler.BuiltinTypes;
424
425                         var tp = new TypeParameter (0, new MemberName ("T"), null, null, Variance.None);
426
427                         ActivatorCreateInstance = new PredefinedMember<MethodSpec> (module, types.Activator,
428                                 MemberFilter.Method ("CreateInstance", 1, ParametersCompiled.EmptyReadOnlyParameters, null));
429
430                         ArrayEmpty = new PredefinedMember<MethodSpec> (module, types.Array,
431                                 MemberFilter.Method ("Empty", 1, ParametersCompiled.EmptyReadOnlyParameters, null));
432
433                         AsyncTaskMethodBuilderCreate = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
434                                 MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, types.AsyncTaskMethodBuilder.TypeSpec));
435
436                         AsyncTaskMethodBuilderSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
437                                 MemberFilter.Method ("SetResult", 0, ParametersCompiled.EmptyReadOnlyParameters, btypes.Void));
438
439                         AsyncTaskMethodBuilderSetStateMachine = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
440                                 "SetStateMachine", MemberKind.Method, () => new[] {
441                                                 types.IAsyncStateMachine.TypeSpec
442                                 }, btypes.Void);
443
444                         AsyncTaskMethodBuilderSetException = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
445                                 MemberFilter.Method ("SetException", 0,
446                                 ParametersCompiled.CreateFullyResolved (btypes.Exception), btypes.Void));
447
448                         AsyncTaskMethodBuilderOnCompleted = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
449                                 MemberFilter.Method ("AwaitOnCompleted", 2,
450                                         new ParametersImported (
451                                                 new[] {
452                                                                 new ParameterData (null, Parameter.Modifier.REF),
453                                                                 new ParameterData (null, Parameter.Modifier.REF)
454                                                         },
455                                                 new[] {
456                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
457                                                                 new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
458                                                         }, false),
459                                         btypes.Void));
460
461                         AsyncTaskMethodBuilderOnCompletedUnsafe = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
462                                 MemberFilter.Method ("AwaitUnsafeOnCompleted", 2,
463                                         new ParametersImported (
464                                                 new[] {
465                                                                 new ParameterData (null, Parameter.Modifier.REF),
466                                                                 new ParameterData (null, Parameter.Modifier.REF)
467                                                         },
468                                                 new[] {
469                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
470                                                                 new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
471                                                         }, false),
472                                         btypes.Void));
473
474                         AsyncTaskMethodBuilderStart = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
475                                 MemberFilter.Method ("Start", 1,
476                                         new ParametersImported (
477                                                 new[] {
478                                                                 new ParameterData (null, Parameter.Modifier.REF),
479                                                         },
480                                                 new[] {
481                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
482                                                         }, false),
483                                         btypes.Void));
484
485                         AsyncTaskMethodBuilderTask = new PredefinedMember<PropertySpec> (module, types.AsyncTaskMethodBuilder,
486                                 MemberFilter.Property ("Task", null));
487
488                         AsyncTaskMethodBuilderGenericCreate = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
489                                 MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, types.AsyncVoidMethodBuilder.TypeSpec));
490
491                         AsyncTaskMethodBuilderGenericSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
492                                 "SetResult", MemberKind.Method, () => new TypeSpec[] {
493                                                 types.AsyncTaskMethodBuilderGeneric.TypeSpec.MemberDefinition.TypeParameters[0]
494                                 }, btypes.Void);
495
496                         AsyncTaskMethodBuilderGenericSetStateMachine = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
497                                 "SetStateMachine", MemberKind.Method, () => new[] {
498                                                 types.IAsyncStateMachine.TypeSpec
499                                 }, btypes.Void);
500
501                         AsyncTaskMethodBuilderGenericSetException = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
502                                 MemberFilter.Method ("SetException", 0,
503                                 ParametersCompiled.CreateFullyResolved (btypes.Exception), btypes.Void));
504
505                         AsyncTaskMethodBuilderGenericOnCompleted = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
506                                 MemberFilter.Method ("AwaitOnCompleted", 2,
507                                         new ParametersImported (
508                                                 new[] {
509                                                                 new ParameterData (null, Parameter.Modifier.REF),
510                                                                 new ParameterData (null, Parameter.Modifier.REF)
511                                                         },
512                                                 new[] {
513                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
514                                                                 new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
515                                                         }, false),
516                                         btypes.Void));
517
518                         AsyncTaskMethodBuilderGenericOnCompletedUnsafe = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
519                                 MemberFilter.Method ("AwaitUnsafeOnCompleted", 2,
520                                         new ParametersImported (
521                                                 new[] {
522                                                                 new ParameterData (null, Parameter.Modifier.REF),
523                                                                 new ParameterData (null, Parameter.Modifier.REF)
524                                                         },
525                                                 new[] {
526                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
527                                                                 new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
528                                                         }, false),
529                                         btypes.Void));
530
531                         AsyncTaskMethodBuilderGenericStart = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
532                                 MemberFilter.Method ("Start", 1,
533                                         new ParametersImported (
534                                                 new[] {
535                                                                 new ParameterData (null, Parameter.Modifier.REF),
536                                                         },
537                                                 new[] {
538                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
539                                                         }, false),
540                                         btypes.Void));
541
542                         AsyncTaskMethodBuilderGenericTask = new PredefinedMember<PropertySpec> (module, types.AsyncTaskMethodBuilderGeneric,
543                                 MemberFilter.Property ("Task", null));
544
545                         AsyncVoidMethodBuilderCreate = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
546                                 MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, types.AsyncVoidMethodBuilder.TypeSpec));
547
548                         AsyncVoidMethodBuilderSetException = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
549                                 MemberFilter.Method ("SetException", 0, null, btypes.Void));
550
551                         AsyncVoidMethodBuilderSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
552                                 MemberFilter.Method ("SetResult", 0, ParametersCompiled.EmptyReadOnlyParameters, btypes.Void));
553
554                         AsyncVoidMethodBuilderSetStateMachine = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
555                                 "SetStateMachine", MemberKind.Method, () => new[] {
556                                                 types.IAsyncStateMachine.TypeSpec
557                                 }, btypes.Void);
558
559                         AsyncVoidMethodBuilderOnCompleted = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
560                                 MemberFilter.Method ("AwaitOnCompleted", 2,
561                                         new ParametersImported (
562                                                 new[] {
563                                                                 new ParameterData (null, Parameter.Modifier.REF),
564                                                                 new ParameterData (null, Parameter.Modifier.REF)
565                                                         },
566                                                 new[] {
567                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
568                                                                 new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
569                                                         }, false),
570                                         btypes.Void));
571
572                         AsyncVoidMethodBuilderOnCompletedUnsafe = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
573                                 MemberFilter.Method ("AwaitUnsafeOnCompleted", 2,
574                                         new ParametersImported (
575                                                 new[] {
576                                                                 new ParameterData (null, Parameter.Modifier.REF),
577                                                                 new ParameterData (null, Parameter.Modifier.REF)
578                                                         },
579                                                 new[] {
580                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
581                                                                 new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
582                                                         }, false),
583                                         btypes.Void));
584
585                         AsyncVoidMethodBuilderStart = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
586                                 MemberFilter.Method ("Start", 1,
587                                         new ParametersImported (
588                                                 new[] {
589                                                                 new ParameterData (null, Parameter.Modifier.REF),
590                                                         },
591                                                 new[] {
592                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
593                                                         }, false),
594                                         btypes.Void));
595
596                         AsyncStateMachineAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.AsyncStateMachine,
597                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
598                                         btypes.Type)));
599
600                         DebuggerBrowsableAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.DebuggerBrowsable,
601                                 MemberFilter.Constructor (null));
602
603                         DecimalCtor = new PredefinedMember<MethodSpec> (module, btypes.Decimal,
604                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
605                                         btypes.Int, btypes.Int, btypes.Int, btypes.Bool, btypes.Byte)));
606
607                         DecimalCtorInt = new PredefinedMember<MethodSpec> (module, btypes.Decimal,
608                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Int)));
609
610                         DecimalCtorLong = new PredefinedMember<MethodSpec> (module, btypes.Decimal,
611                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Long)));
612
613                         DecimalConstantAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.DecimalConstant,
614                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
615                                         btypes.Byte, btypes.Byte, btypes.UInt, btypes.UInt, btypes.UInt)));
616
617                         DefaultMemberAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.DefaultMember,
618                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.String)));
619
620                         DelegateCombine = new PredefinedMember<MethodSpec> (module, btypes.Delegate, "Combine", btypes.Delegate, btypes.Delegate);
621                         DelegateRemove = new PredefinedMember<MethodSpec> (module, btypes.Delegate, "Remove", btypes.Delegate, btypes.Delegate);
622
623                         DelegateEqual = new PredefinedMember<MethodSpec> (module, btypes.Delegate,
624                                 new MemberFilter (Operator.GetMetadataName (Operator.OpType.Equality), 0, MemberKind.Operator, null, btypes.Bool));
625
626                         DelegateInequal = new PredefinedMember<MethodSpec> (module, btypes.Delegate,
627                                 new MemberFilter (Operator.GetMetadataName (Operator.OpType.Inequality), 0, MemberKind.Operator, null, btypes.Bool));
628
629                         DynamicAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.Dynamic,
630                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
631                                         ArrayContainer.MakeType (module, btypes.Bool))));
632
633                         FieldInfoGetFieldFromHandle = new PredefinedMember<MethodSpec> (module, types.FieldInfo,
634                                 "GetFieldFromHandle", MemberKind.Method, types.RuntimeFieldHandle);
635
636                         FieldInfoGetFieldFromHandle2 = new PredefinedMember<MethodSpec> (module, types.FieldInfo,
637                                 "GetFieldFromHandle", MemberKind.Method, types.RuntimeFieldHandle, new PredefinedType (btypes.RuntimeTypeHandle));
638
639                         FixedBufferAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.FixedBuffer,
640                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Type, btypes.Int)));
641
642                         IDisposableDispose = new PredefinedMember<MethodSpec> (module, btypes.IDisposable, "Dispose", TypeSpec.EmptyTypes);
643
644                         IEnumerableGetEnumerator = new PredefinedMember<MethodSpec> (module, btypes.IEnumerable,
645                                 "GetEnumerator", TypeSpec.EmptyTypes);
646
647                         InterlockedCompareExchange = new PredefinedMember<MethodSpec> (module, types.Interlocked,
648                                 MemberFilter.Method ("CompareExchange", 0,
649                                         new ParametersImported (
650                                                 new[] {
651                                                                 new ParameterData (null, Parameter.Modifier.REF),
652                                                                 new ParameterData (null, Parameter.Modifier.NONE),
653                                                                 new ParameterData (null, Parameter.Modifier.NONE)
654                                                         },
655                                                 new[] {
656                                                                 btypes.Int, btypes.Int, btypes.Int
657                                                         },
658                                                 false),
659                                 btypes.Int));
660
661                         InterlockedCompareExchange_T = new PredefinedMember<MethodSpec> (module, types.Interlocked,
662                                 MemberFilter.Method ("CompareExchange", 1,
663                                         new ParametersImported (
664                                                 new[] {
665                                                                 new ParameterData (null, Parameter.Modifier.REF),
666                                                                 new ParameterData (null, Parameter.Modifier.NONE),
667                                                                 new ParameterData (null, Parameter.Modifier.NONE)
668                                                         },
669                                                 new[] {
670                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
671                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
672                                                                 new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
673                                                         }, false),
674                                         null));
675
676                         MethodInfoGetMethodFromHandle = new PredefinedMember<MethodSpec> (module, types.MethodBase,
677                                 "GetMethodFromHandle", MemberKind.Method, types.RuntimeMethodHandle);
678
679                         MethodInfoGetMethodFromHandle2 = new PredefinedMember<MethodSpec> (module, types.MethodBase,
680                                 "GetMethodFromHandle", MemberKind.Method, types.RuntimeMethodHandle, new PredefinedType (btypes.RuntimeTypeHandle));
681
682                         MethodInfoCreateDelegate = new PredefinedMember<MethodSpec> (module, types.MethodInfo,
683                                                                                      "CreateDelegate", MemberKind.Method,
684                                                                                      new PredefinedType (btypes.Type), new PredefinedType (btypes.Object));
685
686                         MonitorEnter = new PredefinedMember<MethodSpec> (module, types.Monitor, "Enter", btypes.Object);
687
688                         MonitorEnter_v4 = new PredefinedMember<MethodSpec> (module, types.Monitor,
689                                 MemberFilter.Method ("Enter", 0,
690                                         new ParametersImported (new[] {
691                                                         new ParameterData (null, Parameter.Modifier.NONE),
692                                                         new ParameterData (null, Parameter.Modifier.REF)
693                                                 },
694                                         new[] {
695                                                         btypes.Object, btypes.Bool
696                                                 }, false), null));
697
698                         MonitorExit = new PredefinedMember<MethodSpec> (module, types.Monitor, "Exit", btypes.Object);
699
700                         RuntimeCompatibilityWrapNonExceptionThrows = new PredefinedMember<PropertySpec> (module, atypes.RuntimeCompatibility,
701                                 MemberFilter.Property ("WrapNonExceptionThrows", btypes.Bool));
702
703                         RuntimeHelpersInitializeArray = new PredefinedMember<MethodSpec> (module, types.RuntimeHelpers,
704                                 "InitializeArray", btypes.Array, btypes.RuntimeFieldHandle);
705
706                         RuntimeHelpersOffsetToStringData = new PredefinedMember<PropertySpec> (module, types.RuntimeHelpers,
707                                 MemberFilter.Property ("OffsetToStringData", btypes.Int));
708
709                         SecurityActionRequestMinimum = new PredefinedMember<ConstSpec> (module, types.SecurityAction, "RequestMinimum",
710                                 MemberKind.Field, types.SecurityAction);
711
712                         StringEmpty = new PredefinedMember<FieldSpec> (module, btypes.String, MemberFilter.Field ("Empty", btypes.String));
713
714                         StringEqual = new PredefinedMember<MethodSpec> (module, btypes.String,
715                                 new MemberFilter (Operator.GetMetadataName (Operator.OpType.Equality), 0, MemberKind.Operator, null, btypes.Bool));
716
717                         StringInequal = new PredefinedMember<MethodSpec> (module, btypes.String,
718                                 new MemberFilter (Operator.GetMetadataName (Operator.OpType.Inequality), 0, MemberKind.Operator, null, btypes.Bool));
719
720                         StructLayoutAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.StructLayout,
721                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Short)));
722
723                         StructLayoutCharSet = new PredefinedMember<FieldSpec> (module, atypes.StructLayout, "CharSet",
724                                 MemberKind.Field, types.CharSet);
725
726                         StructLayoutSize = new PredefinedMember<FieldSpec> (module, atypes.StructLayout,
727                                 MemberFilter.Field ("Size", btypes.Int));
728
729                         TypeGetTypeFromHandle = new PredefinedMember<MethodSpec> (module, btypes.Type, "GetTypeFromHandle", btypes.RuntimeTypeHandle);
730
731                         TupleElementNamesAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.TupleElementNames,
732                                 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
733                                         ArrayContainer.MakeType (module, btypes.String))));
734                 }
735         }
736
737         public class PredefinedType
738         {
739                 readonly string name;
740                 readonly string ns;
741                 readonly int arity;
742                 readonly MemberKind kind;
743                 protected readonly ModuleContainer module;
744                 protected TypeSpec type;
745                 bool defined;
746
747                 public PredefinedType (ModuleContainer module, MemberKind kind, string ns, string name, int arity)
748                         : this (module, kind, ns, name)
749                 {
750                         this.arity = arity;
751                 }
752
753                 public PredefinedType (ModuleContainer module, MemberKind kind, string ns, string name)
754                 {
755                         this.module = module;
756                         this.kind = kind;
757                         this.name = name;
758                         this.ns = ns;
759                 }
760
761                 public PredefinedType (BuiltinTypeSpec type)
762                 {
763                         this.kind = type.Kind;
764                         this.name = type.Name;
765                         this.ns = type.Namespace;
766                         this.type = type;
767                 }
768
769                 #region Properties
770
771                 public int Arity {
772                         get {
773                                 return arity;
774                         }
775                 }
776
777                 public bool IsDefined {
778                         get {
779                                 return type != null;
780                         }
781                 }
782
783                 public string Name {
784                         get {
785                                 return name;
786                         }
787                 }
788
789                 public string Namespace {
790                         get {
791                                 return ns;
792                         }
793                 }
794
795                 public TypeSpec TypeSpec {
796                         get {
797                                 return type;
798                         }
799                 }
800
801                 #endregion
802
803                 public bool Define ()
804                 {
805                         if (type != null)
806                                 return true;
807
808                         if (!defined) {
809                                 defined = true;
810                                 type = Resolve (module, kind, ns, name, arity, false, false);
811                         }
812
813                         return type != null;
814                 }
815
816                 public string GetSignatureForError ()
817                 {
818                         return ns + "." + name;
819                 }
820
821                 public static TypeSpec Resolve (ModuleContainer module, MemberKind kind, string ns, string name, int arity, bool required, bool reportErrors)
822                 {
823                         //
824                         // Cannot call it with true because it could create non-existent namespaces for
825                         // predefined types. It's set to true only for build-in types which all must
826                         // exist therefore it does not matter, for predefined types we don't want to create
827                         // fake namespaces when type is optional and does not exist (e.g. System.Linq).
828                         //
829                         Namespace type_ns = module.GlobalRootNamespace.GetNamespace (ns, required);
830
831                         IList<TypeSpec> found = null;
832                         if (type_ns != null)
833                                 found = type_ns.GetAllTypes (name);
834
835                         if (found == null) {
836                                 if (reportErrors)
837                                         module.Compiler.Report.Error (518, "The predefined type `{0}.{1}' is not defined or imported", ns, name);
838
839                                 return null;
840                         }
841
842                         TypeSpec best_match = null;
843                         foreach (var candidate in found) {
844                                 if (candidate.Kind != kind) {
845                                         if (candidate.Kind == MemberKind.Struct && kind == MemberKind.Void && candidate.MemberDefinition is TypeContainer) {
846                                                 // Void is declared as struct but we keep it internally as
847                                                 // special kind, the swap will be done by caller
848                                         } else {
849                                                 continue;
850                                         }
851                                 }
852
853                                 if (candidate.Arity != arity)
854                                         continue;
855
856                                 if ((candidate.Modifiers & Modifiers.INTERNAL) != 0 && !candidate.MemberDefinition.IsInternalAsPublic (module.DeclaringAssembly))
857                                         continue;
858
859                                 if (best_match == null) {
860                                         best_match = candidate;
861                                         continue;
862                                 }
863
864                                 var other_match = best_match;
865                                 if (!best_match.MemberDefinition.IsImported &&
866                                         module.Compiler.BuiltinTypes.Object.MemberDefinition.DeclaringAssembly == candidate.MemberDefinition.DeclaringAssembly) {
867                                         best_match = candidate;
868                                 }
869
870                                 string location;
871                                 if (best_match.MemberDefinition is MemberCore) {
872                                         location = ((MemberCore) best_match.MemberDefinition).Location.Name;
873                                 } else {
874                                         var assembly = (ImportedAssemblyDefinition) best_match.MemberDefinition.DeclaringAssembly;
875                                         location = Path.GetFileName (assembly.Location);
876                                 }
877
878                                 module.Compiler.Report.SymbolRelatedToPreviousError (other_match);
879                                 module.Compiler.Report.SymbolRelatedToPreviousError (candidate);
880
881                                 module.Compiler.Report.Warning (1685, 1,
882                                         "The predefined type `{0}.{1}' is defined multiple times. Using definition from `{2}'",
883                                         ns, name, location);
884
885                                 break;
886                         }
887
888                         if (best_match == null && reportErrors) {
889                                 var found_member = found[0];
890
891                                 if (found_member.Kind == MemberKind.MissingType) {
892                                         // CSC: should be different error number
893                                         module.Compiler.Report.Error (518, "The predefined type `{0}.{1}' is defined in an assembly that is not referenced.", ns, name);
894                                 } else {
895                                         Location loc;
896                                         if (found_member.MemberDefinition is MemberCore) {
897                                                 loc = ((MemberCore) found_member.MemberDefinition).Location;
898                                         } else {
899                                                 loc = Location.Null;
900                                                 module.Compiler.Report.SymbolRelatedToPreviousError (found_member);
901                                         }
902
903                                         module.Compiler.Report.Error (520, loc, "The predefined type `{0}.{1}' is not declared correctly", ns, name);
904                                 }
905                         }
906
907                         return best_match;
908                 }
909
910                 public TypeSpec Resolve ()
911                 {
912                         if (type == null)
913                                 type = Resolve (module, kind, ns, name, arity, false, true);
914
915                         return type;
916                 }
917         }
918
919         public class PredefinedMember<T> where T : MemberSpec
920         {
921                 readonly ModuleContainer module;
922                 T member;
923                 TypeSpec declaring_type;
924                 readonly PredefinedType declaring_type_predefined;
925                 MemberFilter filter;
926                 readonly Func<TypeSpec[]> filter_builder;
927
928                 public PredefinedMember (ModuleContainer module, PredefinedType type, MemberFilter filter)
929                 {
930                         this.module = module;
931                         this.declaring_type_predefined = type;
932                         this.filter = filter;
933                 }
934
935                 public PredefinedMember (ModuleContainer module, TypeSpec type, MemberFilter filter)
936                 {
937                         this.module = module;
938                         this.declaring_type = type;
939                         this.filter = filter;
940                 }
941
942                 public PredefinedMember (ModuleContainer module, PredefinedType type, string name, params TypeSpec[] types)
943                         : this (module, type, MemberFilter.Method (name, 0, ParametersCompiled.CreateFullyResolved (types), null))
944                 {
945                 }
946
947                 public PredefinedMember (ModuleContainer module, PredefinedType type, string name, MemberKind kind, params PredefinedType[] types)
948                         : this (module, type, new MemberFilter (name, 0, kind, null, null))
949                 {
950                         filter_builder = () => {
951                                 var ptypes = new TypeSpec[types.Length];
952                                 for (int i = 0; i < ptypes.Length; ++i) {
953                                         var p = types[i];
954                                         if (!p.Define ())
955                                                 return null;
956
957                                         ptypes[i] = p.TypeSpec;
958                                 }
959
960                                 return ptypes;
961                         };
962                 }
963
964                 public PredefinedMember (ModuleContainer module, PredefinedType type, string name, MemberKind kind, Func<TypeSpec[]> typesBuilder, TypeSpec returnType)
965                         : this (module, type, new MemberFilter (name, 0, kind, null, returnType))
966                 {
967                         filter_builder = typesBuilder;
968                 }
969
970                 public PredefinedMember (ModuleContainer module, BuiltinTypeSpec type, string name, params TypeSpec[] types)
971                         : this (module, type, MemberFilter.Method (name, 0, ParametersCompiled.CreateFullyResolved (types), null))
972                 {
973                 }
974
975                 public T Get ()
976                 {
977                         if (member != null)
978                                 return member;
979
980                         if (declaring_type == null) {
981                                 if (!declaring_type_predefined.Define ())
982                                         return null;
983
984                                 declaring_type = declaring_type_predefined.TypeSpec;
985                         }
986
987                         if (filter_builder != null) {
988                                 var types = filter_builder ();
989
990                                 if (filter.Kind == MemberKind.Field)
991                                         filter = new MemberFilter (filter.Name, filter.Arity, filter.Kind, null, types [0]);
992                                 else
993                                         filter = new MemberFilter (filter.Name, filter.Arity, filter.Kind,
994                                                 ParametersCompiled.CreateFullyResolved (types), filter.MemberType);
995                         }
996
997                         member = MemberCache.FindMember (declaring_type, filter, BindingRestriction.DeclaredOnly) as T;
998                         if (member == null)
999                                 return null;
1000
1001                         if (!member.IsAccessible (module))
1002                                 return null;
1003
1004                         return member;
1005                 }
1006
1007                 public T Resolve (Location loc)
1008                 {
1009                         if (member != null)
1010                                 return member;
1011
1012                         if (Get () != null)
1013                                 return member;
1014
1015                         if (declaring_type == null) {
1016                                 if (declaring_type_predefined.Resolve () == null)
1017                                         return null;
1018                         }
1019
1020                         if (filter_builder != null) {
1021                                 filter = new MemberFilter (filter.Name, filter.Arity, filter.Kind,
1022                                         ParametersCompiled.CreateFullyResolved (filter_builder ()), filter.MemberType);
1023                         }
1024
1025                         string method_args = null;
1026                         if (filter.Parameters != null)
1027                                 method_args = filter.Parameters.GetSignatureForError ();
1028
1029                         module.Compiler.Report.Error (656, loc, "The compiler required member `{0}.{1}{2}' could not be found or is inaccessible",
1030                                 declaring_type.GetSignatureForError (), filter.Name, method_args);
1031
1032                         return null;
1033                 }
1034         }
1035
1036         public class AwaiterDefinition
1037         {
1038                 public PropertySpec IsCompleted { get; set; }
1039                 public MethodSpec GetResult { get; set; }
1040                 public bool INotifyCompletion { get; set; }
1041
1042                 public bool IsValidPattern {
1043                         get {
1044                                 return IsCompleted != null && GetResult != null && IsCompleted.HasGet;
1045                         }
1046                 }
1047         }
1048
1049         partial class TypeManager {
1050
1051         static public string CSharpName(IList<TypeSpec> types)
1052         {
1053                 if (types.Count == 0)
1054                         return string.Empty;
1055
1056                 StringBuilder sb = new StringBuilder ();
1057                 for (int i = 0; i < types.Count; ++i) {
1058                         if (i > 0)
1059                                 sb.Append (",");
1060
1061                         sb.Append (types [i].GetSignatureForError ());
1062                 }
1063                 return sb.ToString ();
1064         }
1065
1066         static public string GetFullNameSignature (MemberSpec mi)
1067         {
1068                 return mi.GetSignatureForError ();
1069         }
1070
1071         static public string CSharpSignature (MemberSpec mb)
1072         {
1073                 return mb.GetSignatureForError ();
1074         }
1075                 
1076         public static bool IsFamilyAccessible (TypeSpec type, TypeSpec parent)
1077         {
1078 //              TypeParameter tparam = LookupTypeParameter (type);
1079 //              TypeParameter pparam = LookupTypeParameter (parent);
1080
1081                 if (type.Kind == MemberKind.TypeParameter && parent.Kind == MemberKind.TypeParameter) { // (tparam != null) && (pparam != null)) {
1082                         if (type == parent)
1083                                 return true;
1084
1085                         throw new NotImplementedException ("net");
1086 //                      return tparam.IsSubclassOf (parent);
1087                 }
1088
1089                 do {
1090                         if (IsInstantiationOfSameGenericType (type, parent))
1091                                 return true;
1092
1093                         type = type.BaseType;
1094                 } while (type != null);
1095
1096                 return false;
1097         }
1098
1099         //
1100         // Checks whether `type' is a nested child of `parent'.
1101         //
1102         public static bool IsNestedChildOf (TypeSpec type, ITypeDefinition parent)
1103         {
1104                 if (type == null)
1105                         return false;
1106
1107                 if (type.MemberDefinition == parent)
1108                         return false;
1109
1110                 type = type.DeclaringType;
1111                 while (type != null) {
1112                         if (type.MemberDefinition == parent)
1113                                 return true;
1114
1115                         type = type.DeclaringType;
1116                 }
1117
1118                 return false;
1119         }
1120
1121         public static TypeSpec GetElementType (TypeSpec t)
1122         {
1123                 return ((ElementTypeSpec)t).Element;
1124         }
1125
1126         /// <summary>
1127         /// This method is not implemented by MS runtime for dynamic types
1128         /// </summary>
1129         public static bool HasElementType (TypeSpec t)
1130         {
1131                 return t is ElementTypeSpec;
1132         }
1133
1134         /// <summary>
1135         ///   Utility function that can be used to probe whether a type
1136         ///   is managed or not.  
1137         /// </summary>
1138         public static bool VerifyUnmanaged (ModuleContainer rc, TypeSpec t, Location loc)
1139         {
1140                 if (t.IsUnmanaged)
1141                         return true;
1142
1143                 while (t.IsPointer)
1144                         t = ((ElementTypeSpec) t).Element;
1145
1146                 rc.Compiler.Report.SymbolRelatedToPreviousError (t);
1147                 rc.Compiler.Report.Error (208, loc,
1148                         "Cannot take the address of, get the size of, or declare a pointer to a managed type `{0}'",
1149                         t.GetSignatureForError ());
1150
1151                 return false;   
1152         }
1153 #region Generics
1154         // This method always return false for non-generic compiler,
1155         // while Type.IsGenericParameter is returned if it is supported.
1156         public static bool IsGenericParameter (TypeSpec type)
1157         {
1158                 return type.IsGenericParameter;
1159         }
1160
1161         public static bool IsGenericType (TypeSpec type)
1162         {
1163                 return type.IsGeneric;
1164         }
1165
1166         public static TypeSpec[] GetTypeArguments (TypeSpec t)
1167         {
1168                 // TODO: return empty array !!
1169                 return t.TypeArguments;
1170         }
1171
1172         /// <summary>
1173         ///   Check whether `type' and `parent' are both instantiations of the same
1174         ///   generic type.  Note that we do not check the type parameters here.
1175         /// </summary>
1176         public static bool IsInstantiationOfSameGenericType (TypeSpec type, TypeSpec parent)
1177         {
1178                 return type == parent || type.MemberDefinition == parent.MemberDefinition;
1179         }
1180 #endregion
1181 }
1182
1183 }