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