2 // typemanager.cs: C# type manager
4 // Author: Miguel de Icaza (miguel@gnu.org)
5 // Ravi Pratap (ravi@ximian.com)
6 // Marek Safar (marek.safar@gmail.com)
8 // Dual licensed under the terms of the MIT X11 or GNU GPL
10 // Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
11 // Copyright 2003-2011 Novell, Inc.
12 // Copyright 2011 Xamarin Inc
16 using System.Globalization;
17 using System.Collections.Generic;
24 // All compiler built-in types (they have to exist otherwise the compiler will not work)
26 public class BuiltinTypes
28 public readonly BuiltinTypeSpec Object;
29 public readonly BuiltinTypeSpec ValueType;
30 public readonly BuiltinTypeSpec Attribute;
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;
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;
63 // These are internal buil-in types which depend on other
64 // build-in type (mostly object)
66 public readonly BuiltinTypeSpec Dynamic;
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;
75 public readonly TypeSpec[] BinaryPromotionsTypes;
76 public readonly TypeSpec[] SwitchUserTypes;
78 readonly BuiltinTypeSpec[] types;
80 public BuiltinTypes ()
82 Object = new BuiltinTypeSpec (MemberKind.Class, "System", "Object", BuiltinTypeSpec.Type.Object);
83 ValueType = new BuiltinTypeSpec (MemberKind.Class, "System", "ValueType", BuiltinTypeSpec.Type.ValueType);
84 Attribute = new BuiltinTypeSpec (MemberKind.Class, "System", "Attribute", BuiltinTypeSpec.Type.Attribute);
86 Int = new BuiltinTypeSpec (MemberKind.Struct, "System", "Int32", BuiltinTypeSpec.Type.Int);
87 Long = new BuiltinTypeSpec (MemberKind.Struct, "System", "Int64", BuiltinTypeSpec.Type.Long);
88 UInt = new BuiltinTypeSpec (MemberKind.Struct, "System", "UInt32", BuiltinTypeSpec.Type.UInt);
89 ULong = new BuiltinTypeSpec (MemberKind.Struct, "System", "UInt64", BuiltinTypeSpec.Type.ULong);
90 Byte = new BuiltinTypeSpec (MemberKind.Struct, "System", "Byte", BuiltinTypeSpec.Type.Byte);
91 SByte = new BuiltinTypeSpec (MemberKind.Struct, "System", "SByte", BuiltinTypeSpec.Type.SByte);
92 Short = new BuiltinTypeSpec (MemberKind.Struct, "System", "Int16", BuiltinTypeSpec.Type.Short);
93 UShort = new BuiltinTypeSpec (MemberKind.Struct, "System", "UInt16", BuiltinTypeSpec.Type.UShort);
95 IEnumerator = new BuiltinTypeSpec (MemberKind.Interface, "System.Collections", "IEnumerator", BuiltinTypeSpec.Type.IEnumerator);
96 IEnumerable = new BuiltinTypeSpec (MemberKind.Interface, "System.Collections", "IEnumerable", BuiltinTypeSpec.Type.IEnumerable);
97 IDisposable = new BuiltinTypeSpec (MemberKind.Interface, "System", "IDisposable", BuiltinTypeSpec.Type.IDisposable);
99 Char = new BuiltinTypeSpec (MemberKind.Struct, "System", "Char", BuiltinTypeSpec.Type.Char);
100 String = new BuiltinTypeSpec (MemberKind.Class, "System", "String", BuiltinTypeSpec.Type.String);
101 Float = new BuiltinTypeSpec (MemberKind.Struct, "System", "Single", BuiltinTypeSpec.Type.Float);
102 Double = new BuiltinTypeSpec (MemberKind.Struct, "System", "Double", BuiltinTypeSpec.Type.Double);
103 Decimal = new BuiltinTypeSpec (MemberKind.Struct, "System", "Decimal", BuiltinTypeSpec.Type.Decimal);
104 Bool = new BuiltinTypeSpec (MemberKind.Struct, "System", "Boolean", BuiltinTypeSpec.Type.Bool);
105 IntPtr = new BuiltinTypeSpec (MemberKind.Struct, "System", "IntPtr", BuiltinTypeSpec.Type.IntPtr);
106 UIntPtr = new BuiltinTypeSpec (MemberKind.Struct, "System", "UIntPtr", BuiltinTypeSpec.Type.UIntPtr);
108 MulticastDelegate = new BuiltinTypeSpec (MemberKind.Class, "System", "MulticastDelegate", BuiltinTypeSpec.Type.MulticastDelegate);
109 Delegate = new BuiltinTypeSpec (MemberKind.Class, "System", "Delegate", BuiltinTypeSpec.Type.Delegate);
110 Enum = new BuiltinTypeSpec (MemberKind.Class, "System", "Enum", BuiltinTypeSpec.Type.Enum);
111 Array = new BuiltinTypeSpec (MemberKind.Class, "System", "Array", BuiltinTypeSpec.Type.Array);
112 Void = new BuiltinTypeSpec (MemberKind.Void, "System", "Void", BuiltinTypeSpec.Type.Other);
113 Type = new BuiltinTypeSpec (MemberKind.Class, "System", "Type", BuiltinTypeSpec.Type.Type);
114 Exception = new BuiltinTypeSpec (MemberKind.Class, "System", "Exception", BuiltinTypeSpec.Type.Exception);
115 RuntimeFieldHandle = new BuiltinTypeSpec (MemberKind.Struct, "System", "RuntimeFieldHandle", BuiltinTypeSpec.Type.Other);
116 RuntimeTypeHandle = new BuiltinTypeSpec (MemberKind.Struct, "System", "RuntimeTypeHandle", BuiltinTypeSpec.Type.Other);
118 // TODO: Maybe I should promote it to different kind for faster compares
119 Dynamic = new BuiltinTypeSpec ("dynamic", BuiltinTypeSpec.Type.Dynamic);
121 OperatorsBinaryStandard = Binary.CreateStandardOperatorsTable (this);
122 OperatorsBinaryEquality = Binary.CreateEqualityOperatorsTable (this);
123 OperatorsBinaryUnsafe = Binary.CreatePointerOperatorsTable (this);
124 OperatorsUnary = Unary.CreatePredefinedOperatorsTable (this);
125 OperatorsUnaryMutator = UnaryMutator.CreatePredefinedOperatorsTable (this);
127 BinaryPromotionsTypes = ConstantFold.CreateBinaryPromotionsTypes (this);
128 SwitchUserTypes = Switch.CreateSwitchUserTypes (this);
130 types = new BuiltinTypeSpec[] {
131 Object, ValueType, Attribute,
132 Int, UInt, Long, ULong, Float, Double, Char, Short, Decimal, Bool, SByte, Byte, UShort, String,
133 Enum, Delegate, MulticastDelegate, Void, Array, Type, IEnumerator, IEnumerable, IDisposable,
134 IntPtr, UIntPtr, RuntimeFieldHandle, RuntimeTypeHandle, Exception };
137 public BuiltinTypeSpec[] AllTypes {
143 public bool CheckDefinitions (ModuleContainer module)
145 var ctx = module.Compiler;
146 foreach (var p in types) {
147 var found = PredefinedType.Resolve (module, p.Kind, p.Namespace, p.Name, p.Arity);
148 if (found == null || found == p)
151 var tc = found.MemberDefinition as TypeContainer;
153 var ns = module.GlobalRootNamespace.GetNamespace (p.Namespace, false);
154 ns.SetBuiltinType (p);
156 tc.SetPredefinedSpec (p);
157 p.SetDefinition (found);
161 if (ctx.Report.Errors != 0)
164 // Set internal build-in types
165 Dynamic.SetDefinition (Object);
172 // Compiler predefined types. Usually used for compiler generated
173 // code or for comparison against well known framework type. They
174 // may not exist as they are optional
176 class PredefinedTypes
178 public readonly PredefinedType ArgIterator;
179 public readonly PredefinedType TypedReference;
180 public readonly PredefinedType MarshalByRefObject;
181 public readonly PredefinedType RuntimeHelpers;
182 public readonly PredefinedType IAsyncResult;
183 public readonly PredefinedType AsyncCallback;
184 public readonly PredefinedType RuntimeArgumentHandle;
185 public readonly PredefinedType CharSet;
186 public readonly PredefinedType IsVolatile;
187 public readonly PredefinedType IEnumeratorGeneric;
188 public readonly PredefinedType IListGeneric;
189 public readonly PredefinedType ICollectionGeneric;
190 public readonly PredefinedType IEnumerableGeneric;
191 public readonly PredefinedType Nullable;
192 public readonly PredefinedType Activator;
193 public readonly PredefinedType Interlocked;
194 public readonly PredefinedType Monitor;
195 public readonly PredefinedType NotSupportedException;
196 public readonly PredefinedType RuntimeFieldHandle;
197 public readonly PredefinedType RuntimeMethodHandle;
198 public readonly PredefinedType SecurityAction;
199 public readonly PredefinedType Dictionary;
200 public readonly PredefinedType Hashtable;
205 public readonly PredefinedType Expression;
206 public readonly PredefinedType ExpressionGeneric;
207 public readonly PredefinedType ParameterExpression;
208 public readonly PredefinedType FieldInfo;
209 public readonly PredefinedType MethodBase;
210 public readonly PredefinedType MethodInfo;
211 public readonly PredefinedType ConstructorInfo;
212 public readonly PredefinedType MemberBinding;
217 public readonly PredefinedType Binder;
218 public readonly PredefinedType CallSite;
219 public readonly PredefinedType CallSiteGeneric;
220 public readonly PredefinedType BinderFlags;
225 public readonly PredefinedType AsyncVoidMethodBuilder;
226 public readonly PredefinedType AsyncTaskMethodBuilder;
227 public readonly PredefinedType AsyncTaskMethodBuilderGeneric;
228 public readonly PredefinedType Action;
229 public readonly PredefinedType Task;
230 public readonly PredefinedType TaskGeneric;
232 public PredefinedTypes (ModuleContainer module)
234 TypedReference = new PredefinedType (module, MemberKind.Struct, "System", "TypedReference");
235 ArgIterator = new PredefinedType (module, MemberKind.Struct, "System", "ArgIterator");
237 MarshalByRefObject = new PredefinedType (module, MemberKind.Class, "System", "MarshalByRefObject");
238 RuntimeHelpers = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "RuntimeHelpers");
239 IAsyncResult = new PredefinedType (module, MemberKind.Interface, "System", "IAsyncResult");
240 AsyncCallback = new PredefinedType (module, MemberKind.Delegate, "System", "AsyncCallback");
241 RuntimeArgumentHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeArgumentHandle");
242 CharSet = new PredefinedType (module, MemberKind.Enum, "System.Runtime.InteropServices", "CharSet");
243 IsVolatile = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "IsVolatile");
244 IEnumeratorGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IEnumerator", 1);
245 IListGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IList", 1);
246 ICollectionGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "ICollection", 1);
247 IEnumerableGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IEnumerable", 1);
248 Nullable = new PredefinedType (module, MemberKind.Struct, "System", "Nullable", 1);
249 Activator = new PredefinedType (module, MemberKind.Class, "System", "Activator");
250 Interlocked = new PredefinedType (module, MemberKind.Class, "System.Threading", "Interlocked");
251 Monitor = new PredefinedType (module, MemberKind.Class, "System.Threading", "Monitor");
252 NotSupportedException = new PredefinedType (module, MemberKind.Class, "System", "NotSupportedException");
253 RuntimeFieldHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeFieldHandle");
254 RuntimeMethodHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeMethodHandle");
255 SecurityAction = new PredefinedType (module, MemberKind.Enum, "System.Security.Permissions", "SecurityAction");
256 Dictionary = new PredefinedType (module, MemberKind.Class, "System.Collections.Generic", "Dictionary", 2);
257 Hashtable = new PredefinedType (module, MemberKind.Class, "System.Collections", "Hashtable");
259 Expression = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "Expression");
260 ExpressionGeneric = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "Expression", 1);
261 MemberBinding = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "MemberBinding");
262 ParameterExpression = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "ParameterExpression");
263 FieldInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "FieldInfo");
264 MethodBase = new PredefinedType (module, MemberKind.Class, "System.Reflection", "MethodBase");
265 MethodInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "MethodInfo");
266 ConstructorInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "ConstructorInfo");
268 CallSite = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "CallSite");
269 CallSiteGeneric = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "CallSite", 1);
270 Binder = new PredefinedType (module, MemberKind.Class, "Microsoft.CSharp.RuntimeBinder", "Binder");
271 BinderFlags = new PredefinedType (module, MemberKind.Enum, "Microsoft.CSharp.RuntimeBinder", "CSharpBinderFlags");
273 Action = new PredefinedType (module, MemberKind.Delegate, "System", "Action");
274 AsyncVoidMethodBuilder = new PredefinedType (module, MemberKind.Struct, "System.Runtime.CompilerServices", "AsyncVoidMethodBuilder");
275 AsyncTaskMethodBuilder = new PredefinedType (module, MemberKind.Struct, "System.Runtime.CompilerServices", "AsyncTaskMethodBuilder");
276 AsyncTaskMethodBuilderGeneric = new PredefinedType (module, MemberKind.Struct, "System.Runtime.CompilerServices", "AsyncTaskMethodBuilder", 1);
277 Task = new PredefinedType (module, MemberKind.Class, "System.Threading.Tasks", "Task");
278 TaskGeneric = new PredefinedType (module, MemberKind.Class, "System.Threading.Tasks", "Task", 1);
281 // Define types which are used for comparison. It does not matter
282 // if they don't exist as no error report is needed
284 if (TypedReference.Define ())
285 TypedReference.TypeSpec.IsSpecialRuntimeType = true;
287 if (ArgIterator.Define ())
288 ArgIterator.TypeSpec.IsSpecialRuntimeType = true;
290 if (IEnumerableGeneric.Define ())
291 IEnumerableGeneric.TypeSpec.IsGenericIterateInterface = true;
293 if (IListGeneric.Define ())
294 IListGeneric.TypeSpec.IsGenericIterateInterface = true;
296 if (ICollectionGeneric.Define ())
297 ICollectionGeneric.TypeSpec.IsGenericIterateInterface = true;
299 if (Nullable.Define ())
300 Nullable.TypeSpec.IsNullableType = true;
302 if (ExpressionGeneric.Define ())
303 ExpressionGeneric.TypeSpec.IsExpressionTreeType = true;
306 if (TaskGeneric.Define ())
307 TaskGeneric.TypeSpec.IsGenericTask = true;
311 class PredefinedMembers
313 public readonly PredefinedMember<MethodSpec> ActivatorCreateInstance;
314 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderCreate;
315 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderSetResult;
316 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderSetException;
317 public readonly PredefinedMember<PropertySpec> AsyncTaskMethodBuilderTask;
318 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericCreate;
319 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericSetResult;
320 public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericSetException;
321 public readonly PredefinedMember<PropertySpec> AsyncTaskMethodBuilderGenericTask;
322 public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderCreate;
323 public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderSetException;
324 public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderSetResult;
325 public readonly PredefinedMember<MethodSpec> DecimalCtor;
326 public readonly PredefinedMember<MethodSpec> DecimalCtorInt;
327 public readonly PredefinedMember<MethodSpec> DecimalCtorLong;
328 public readonly PredefinedMember<MethodSpec> DecimalConstantAttributeCtor;
329 public readonly PredefinedMember<MethodSpec> DefaultMemberAttributeCtor;
330 public readonly PredefinedMember<MethodSpec> DelegateCombine;
331 public readonly PredefinedMember<MethodSpec> DelegateEqual;
332 public readonly PredefinedMember<MethodSpec> DelegateInequal;
333 public readonly PredefinedMember<MethodSpec> DelegateRemove;
334 public readonly PredefinedMember<MethodSpec> DynamicAttributeCtor;
335 public readonly PredefinedMember<MethodSpec> FieldInfoGetFieldFromHandle;
336 public readonly PredefinedMember<MethodSpec> FieldInfoGetFieldFromHandle2;
337 public readonly PredefinedMember<MethodSpec> IDisposableDispose;
338 public readonly PredefinedMember<MethodSpec> IEnumerableGetEnumerator;
339 public readonly PredefinedMember<MethodSpec> InterlockedCompareExchange;
340 public readonly PredefinedMember<MethodSpec> InterlockedCompareExchange_T;
341 public readonly PredefinedMember<MethodSpec> FixedBufferAttributeCtor;
342 public readonly PredefinedMember<MethodSpec> MethodInfoGetMethodFromHandle;
343 public readonly PredefinedMember<MethodSpec> MethodInfoGetMethodFromHandle2;
344 public readonly PredefinedMember<MethodSpec> MonitorEnter;
345 public readonly PredefinedMember<MethodSpec> MonitorEnter_v4;
346 public readonly PredefinedMember<MethodSpec> MonitorExit;
347 public readonly PredefinedMember<PropertySpec> RuntimeCompatibilityWrapNonExceptionThrows;
348 public readonly PredefinedMember<MethodSpec> RuntimeHelpersInitializeArray;
349 public readonly PredefinedMember<PropertySpec> RuntimeHelpersOffsetToStringData;
350 public readonly PredefinedMember<ConstSpec> SecurityActionRequestMinimum;
351 public readonly PredefinedMember<FieldSpec> StringEmpty;
352 public readonly PredefinedMember<MethodSpec> StringEqual;
353 public readonly PredefinedMember<MethodSpec> StringInequal;
354 public readonly PredefinedMember<MethodSpec> StructLayoutAttributeCtor;
355 public readonly PredefinedMember<FieldSpec> StructLayoutCharSet;
356 public readonly PredefinedMember<FieldSpec> StructLayoutSize;
357 public readonly PredefinedMember<MethodSpec> TypeGetTypeFromHandle;
359 public PredefinedMembers (ModuleContainer module)
361 var types = module.PredefinedTypes;
362 var atypes = module.PredefinedAttributes;
363 var btypes = module.Compiler.BuiltinTypes;
365 ActivatorCreateInstance = new PredefinedMember<MethodSpec> (module, types.Activator,
366 MemberFilter.Method ("CreateInstance", 1, ParametersCompiled.EmptyReadOnlyParameters, null));
368 AsyncTaskMethodBuilderCreate = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
369 MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, types.AsyncTaskMethodBuilder.TypeSpec));
371 AsyncTaskMethodBuilderSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
372 MemberFilter.Method ("SetResult", 0, ParametersCompiled.EmptyReadOnlyParameters, btypes.Void));
374 AsyncTaskMethodBuilderSetException = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
375 MemberFilter.Method ("SetException", 0,
376 ParametersCompiled.CreateFullyResolved (btypes.Exception), btypes.Void));
378 AsyncTaskMethodBuilderTask = new PredefinedMember<PropertySpec> (module, types.AsyncTaskMethodBuilder,
379 MemberFilter.Property ("Task", null));
381 AsyncTaskMethodBuilderGenericCreate = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
382 MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, types.AsyncVoidMethodBuilder.TypeSpec));
384 AsyncTaskMethodBuilderGenericSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
385 "SetResult", MemberKind.Method, () => new TypeSpec[] {
386 types.AsyncTaskMethodBuilderGeneric.TypeSpec.MemberDefinition.TypeParameters[0]
389 AsyncTaskMethodBuilderGenericSetException = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
390 MemberFilter.Method ("SetException", 0,
391 ParametersCompiled.CreateFullyResolved (btypes.Exception), btypes.Void));
393 AsyncTaskMethodBuilderGenericTask = new PredefinedMember<PropertySpec> (module, types.AsyncTaskMethodBuilderGeneric,
394 MemberFilter.Property ("Task", null));
396 AsyncVoidMethodBuilderCreate = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
397 MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, types.AsyncVoidMethodBuilder.TypeSpec));
399 AsyncVoidMethodBuilderSetException = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
400 MemberFilter.Method ("SetException", 0, null, btypes.Void));
402 AsyncVoidMethodBuilderSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
403 MemberFilter.Method ("SetResult", 0, ParametersCompiled.EmptyReadOnlyParameters, btypes.Void));
405 DecimalCtor = new PredefinedMember<MethodSpec> (module, btypes.Decimal,
406 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
407 btypes.Int, btypes.Int, btypes.Int, btypes.Bool, btypes.Byte)));
409 DecimalCtorInt = new PredefinedMember<MethodSpec> (module, btypes.Decimal,
410 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Int)));
412 DecimalCtorLong = new PredefinedMember<MethodSpec> (module, btypes.Decimal,
413 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Long)));
415 DecimalConstantAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.DecimalConstant,
416 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
417 btypes.Byte, btypes.Byte, btypes.UInt, btypes.UInt, btypes.UInt)));
419 DefaultMemberAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.DefaultMember,
420 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.String)));
422 DelegateCombine = new PredefinedMember<MethodSpec> (module, btypes.Delegate, "Combine", btypes.Delegate, btypes.Delegate);
423 DelegateRemove = new PredefinedMember<MethodSpec> (module, btypes.Delegate, "Remove", btypes.Delegate, btypes.Delegate);
425 DelegateEqual = new PredefinedMember<MethodSpec> (module, btypes.Delegate,
426 new MemberFilter (Operator.GetMetadataName (Operator.OpType.Equality), 0, MemberKind.Operator, null, btypes.Bool));
428 DelegateInequal = new PredefinedMember<MethodSpec> (module, btypes.Delegate,
429 new MemberFilter (Operator.GetMetadataName (Operator.OpType.Inequality), 0, MemberKind.Operator, null, btypes.Bool));
431 DynamicAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.Dynamic,
432 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
433 ArrayContainer.MakeType (module, btypes.Bool))));
435 FieldInfoGetFieldFromHandle = new PredefinedMember<MethodSpec> (module, types.FieldInfo,
436 "GetFieldFromHandle", MemberKind.Method, types.RuntimeFieldHandle);
438 FieldInfoGetFieldFromHandle2 = new PredefinedMember<MethodSpec> (module, types.FieldInfo,
439 "GetFieldFromHandle", MemberKind.Method, types.RuntimeFieldHandle, new PredefinedType (btypes.RuntimeTypeHandle));
441 FixedBufferAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.FixedBuffer,
442 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Type, btypes.Int)));
444 IDisposableDispose = new PredefinedMember<MethodSpec> (module, btypes.IDisposable, "Dispose", TypeSpec.EmptyTypes);
446 IEnumerableGetEnumerator = new PredefinedMember<MethodSpec> (module, btypes.IEnumerable,
447 "GetEnumerator", TypeSpec.EmptyTypes);
449 InterlockedCompareExchange = new PredefinedMember<MethodSpec> (module, types.Interlocked,
450 MemberFilter.Method ("CompareExchange", 0,
451 new ParametersImported (
453 new ParameterData (null, Parameter.Modifier.REF),
454 new ParameterData (null, Parameter.Modifier.NONE),
455 new ParameterData (null, Parameter.Modifier.NONE)
458 btypes.Int, btypes.Int, btypes.Int
463 InterlockedCompareExchange_T = new PredefinedMember<MethodSpec> (module, types.Interlocked,
464 MemberFilter.Method ("CompareExchange", 1,
465 new ParametersImported (
467 new ParameterData (null, Parameter.Modifier.REF),
468 new ParameterData (null, Parameter.Modifier.NONE),
469 new ParameterData (null, Parameter.Modifier.NONE)
472 new TypeParameterSpec (0, null, SpecialConstraint.None, Variance.None, null),
473 new TypeParameterSpec (0, null, SpecialConstraint.None, Variance.None, null),
474 new TypeParameterSpec (0, null, SpecialConstraint.None, Variance.None, null),
478 MethodInfoGetMethodFromHandle = new PredefinedMember<MethodSpec> (module, types.MethodBase,
479 "GetMethodFromHandle", MemberKind.Method, types.RuntimeMethodHandle);
481 MethodInfoGetMethodFromHandle2 = new PredefinedMember<MethodSpec> (module, types.MethodBase,
482 "GetMethodFromHandle", MemberKind.Method, types.RuntimeMethodHandle, new PredefinedType (btypes.RuntimeTypeHandle));
484 MonitorEnter = new PredefinedMember<MethodSpec> (module, types.Monitor, "Enter", btypes.Object);
486 MonitorEnter_v4 = new PredefinedMember<MethodSpec> (module, types.Monitor,
487 MemberFilter.Method ("Enter", 0,
488 new ParametersImported (new[] {
489 new ParameterData (null, Parameter.Modifier.NONE),
490 new ParameterData (null, Parameter.Modifier.REF)
493 btypes.Object, btypes.Bool
496 MonitorExit = new PredefinedMember<MethodSpec> (module, types.Monitor, "Exit", btypes.Object);
498 RuntimeCompatibilityWrapNonExceptionThrows = new PredefinedMember<PropertySpec> (module, atypes.RuntimeCompatibility,
499 MemberFilter.Property ("WrapNonExceptionThrows", btypes.Bool));
501 RuntimeHelpersInitializeArray = new PredefinedMember<MethodSpec> (module, types.RuntimeHelpers,
502 "InitializeArray", btypes.Array, btypes.RuntimeFieldHandle);
504 RuntimeHelpersOffsetToStringData = new PredefinedMember<PropertySpec> (module, types.RuntimeHelpers,
505 MemberFilter.Property ("OffsetToStringData", btypes.Int));
507 SecurityActionRequestMinimum = new PredefinedMember<ConstSpec> (module, types.SecurityAction, "RequestMinimum",
508 MemberKind.Field, types.SecurityAction);
510 StringEmpty = new PredefinedMember<FieldSpec> (module, btypes.String, MemberFilter.Field ("Empty", btypes.String));
512 StringEqual = new PredefinedMember<MethodSpec> (module, btypes.String,
513 new MemberFilter (Operator.GetMetadataName (Operator.OpType.Equality), 0, MemberKind.Operator, null, btypes.Bool));
515 StringInequal = new PredefinedMember<MethodSpec> (module, btypes.String,
516 new MemberFilter (Operator.GetMetadataName (Operator.OpType.Inequality), 0, MemberKind.Operator, null, btypes.Bool));
518 StructLayoutAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.StructLayout,
519 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Short)));
521 StructLayoutCharSet = new PredefinedMember<FieldSpec> (module, atypes.StructLayout, "CharSet",
522 MemberKind.Field, types.CharSet);
524 StructLayoutSize = new PredefinedMember<FieldSpec> (module, atypes.StructLayout,
525 MemberFilter.Field ("Size", btypes.Int));
527 TypeGetTypeFromHandle = new PredefinedMember<MethodSpec> (module, btypes.Type, "GetTypeFromHandle", btypes.RuntimeTypeHandle);
531 public class PredefinedType
533 readonly string name;
536 readonly MemberKind kind;
537 protected readonly ModuleContainer module;
538 protected TypeSpec type;
540 public PredefinedType (ModuleContainer module, MemberKind kind, string ns, string name, int arity)
541 : this (module, kind, ns, name)
546 public PredefinedType (ModuleContainer module, MemberKind kind, string ns, string name)
548 this.module = module;
554 public PredefinedType (BuiltinTypeSpec type)
556 this.kind = type.Kind;
557 this.name = type.Name;
558 this.ns = type.Namespace;
570 public bool IsDefined {
582 public string Namespace {
588 public TypeSpec TypeSpec {
596 public bool Define ()
601 type = Resolve (module, kind, ns, name, arity, false);
605 public string GetSignatureForError ()
607 return ns + "." + name;
610 public static TypeSpec Resolve (ModuleContainer module, MemberKind kind, string ns, string name, int arity)
612 return Resolve (module, kind, ns, name, arity, true);
615 public static TypeSpec Resolve (ModuleContainer module, MemberKind kind, string ns, string name, int arity, bool reportErrors)
617 Namespace type_ns = module.GlobalRootNamespace.GetNamespace (ns, true);
618 var found = type_ns.GetAllTypes (name);
621 module.Compiler.Report.Error (518, "The predefined type `{0}.{1}' is not defined or imported", ns, name);
626 TypeSpec best_match = null;
627 foreach (var candidate in found) {
628 if (candidate.Kind != kind) {
629 if (candidate.Kind == MemberKind.Struct && kind == MemberKind.Void && candidate.MemberDefinition is TypeContainer) {
630 // Void is declared as struct but we keep it internally as
631 // special kind, the swap will be done by caller
637 if (candidate.Arity != arity)
640 if ((candidate.Modifiers & Modifiers.INTERNAL) != 0 && !candidate.MemberDefinition.IsInternalAsPublic (module.DeclaringAssembly))
643 if (best_match == null) {
644 best_match = candidate;
648 var other_match = best_match;
649 if (!best_match.MemberDefinition.IsImported &&
650 module.Compiler.BuiltinTypes.Object.MemberDefinition.DeclaringAssembly == candidate.MemberDefinition.DeclaringAssembly) {
651 best_match = candidate;
655 if (best_match.MemberDefinition is MemberCore) {
656 location = ((MemberCore) best_match.MemberDefinition).Location.Name;
658 var assembly = (ImportedAssemblyDefinition) best_match.MemberDefinition.DeclaringAssembly;
659 location = Path.GetFileName (assembly.Location);
662 module.Compiler.Report.SymbolRelatedToPreviousError (other_match);
663 module.Compiler.Report.SymbolRelatedToPreviousError (candidate);
665 module.Compiler.Report.Warning (1685, 1,
666 "The predefined type `{0}.{1}' is defined multiple times. Using definition from `{2}'",
672 if (best_match == null && reportErrors) {
674 if (found[0].MemberDefinition is MemberCore) {
675 loc = ((MemberCore) found[0].MemberDefinition).Location;
678 module.Compiler.Report.SymbolRelatedToPreviousError (found[0]);
681 module.Compiler.Report.Error (520, loc, "The predefined type `{0}.{1}' is not declared correctly", ns, name);
687 public TypeSpec Resolve ()
690 type = Resolve (module, kind, ns, name, arity);
696 class PredefinedMember<T> where T : MemberSpec
698 readonly ModuleContainer module;
700 TypeSpec declaring_type;
701 readonly PredefinedType declaring_type_predefined;
703 readonly Func<TypeSpec[]> filter_builder;
705 public PredefinedMember (ModuleContainer module, PredefinedType type, MemberFilter filter)
707 this.module = module;
708 this.declaring_type_predefined = type;
709 this.filter = filter;
712 public PredefinedMember (ModuleContainer module, TypeSpec type, MemberFilter filter)
714 this.module = module;
715 this.declaring_type = type;
716 this.filter = filter;
719 public PredefinedMember (ModuleContainer module, PredefinedType type, string name, params TypeSpec[] types)
720 : this (module, type, MemberFilter.Method (name, 0, ParametersCompiled.CreateFullyResolved (types), null))
724 public PredefinedMember (ModuleContainer module, PredefinedType type, string name, MemberKind kind, params PredefinedType[] types)
725 : this (module, type, new MemberFilter (name, 0, kind, null, null))
727 filter_builder = () => {
728 var ptypes = new TypeSpec[types.Length];
729 for (int i = 0; i < ptypes.Length; ++i) {
734 ptypes[i] = p.TypeSpec;
741 public PredefinedMember (ModuleContainer module, PredefinedType type, string name, MemberKind kind, Func<TypeSpec[]> typesBuilder)
742 : this (module, type, new MemberFilter (name, 0, kind, null, null))
744 filter_builder = typesBuilder;
747 public PredefinedMember (ModuleContainer module, BuiltinTypeSpec type, string name, params TypeSpec[] types)
748 : this (module, type, MemberFilter.Method (name, 0, ParametersCompiled.CreateFullyResolved (types), null))
757 if (declaring_type == null) {
758 if (!declaring_type_predefined.Define ())
761 declaring_type = declaring_type_predefined.TypeSpec;
764 if (filter_builder != null) {
765 var types = filter_builder ();
767 if (filter.Kind == MemberKind.Field)
768 filter = new MemberFilter (filter.Name, filter.Arity, filter.Kind, null, types [0]);
770 filter = new MemberFilter (filter.Name, filter.Arity, filter.Kind,
771 ParametersCompiled.CreateFullyResolved (types), filter.MemberType);
774 member = MemberCache.FindMember (declaring_type, filter, BindingRestriction.DeclaredOnly) as T;
778 if (!member.IsAccessible (module))
784 public T Resolve (Location loc)
792 if (declaring_type == null) {
793 if (declaring_type_predefined.Resolve () == null)
797 if (filter_builder != null) {
798 filter = new MemberFilter (filter.Name, filter.Arity, filter.Kind,
799 ParametersCompiled.CreateFullyResolved (filter_builder ()), filter.MemberType);
802 string method_args = null;
803 if (filter.Parameters != null)
804 method_args = filter.Parameters.GetSignatureForError ();
806 module.Compiler.Report.Error (656, loc, "The compiler required member `{0}.{1}{2}' could not be found or is inaccessible",
807 declaring_type.GetSignatureForError (), filter.Name, method_args);
813 partial class TypeManager {
816 /// Returns the C# name of a type if possible, or the full type name otherwise
818 static public string CSharpName (TypeSpec t)
820 return t.GetSignatureForError ();
823 static public string CSharpName (IList<TypeSpec> types)
825 if (types.Count == 0)
828 StringBuilder sb = new StringBuilder ();
829 for (int i = 0; i < types.Count; ++i) {
833 sb.Append (CSharpName (types [i]));
835 return sb.ToString ();
838 static public string GetFullNameSignature (MemberSpec mi)
840 return mi.GetSignatureForError ();
843 static public string CSharpSignature (MemberSpec mb)
845 return mb.GetSignatureForError ();
848 public static bool IsFamilyAccessible (TypeSpec type, TypeSpec parent)
850 // TypeParameter tparam = LookupTypeParameter (type);
851 // TypeParameter pparam = LookupTypeParameter (parent);
853 if (type.Kind == MemberKind.TypeParameter && parent.Kind == MemberKind.TypeParameter) { // (tparam != null) && (pparam != null)) {
857 throw new NotImplementedException ("net");
858 // return tparam.IsSubclassOf (parent);
862 if (IsInstantiationOfSameGenericType (type, parent))
865 type = type.BaseType;
866 } while (type != null);
872 // Checks whether `type' is a nested child of `parent'.
874 public static bool IsNestedChildOf (TypeSpec type, ITypeDefinition parent)
879 if (type.MemberDefinition == parent)
882 type = type.DeclaringType;
883 while (type != null) {
884 if (type.MemberDefinition == parent)
887 type = type.DeclaringType;
893 public static TypeSpec GetElementType (TypeSpec t)
895 return ((ElementTypeSpec)t).Element;
899 /// This method is not implemented by MS runtime for dynamic types
901 public static bool HasElementType (TypeSpec t)
903 return t is ElementTypeSpec;
907 /// Utility function that can be used to probe whether a type
908 /// is managed or not.
910 public static bool VerifyUnmanaged (ModuleContainer rc, TypeSpec t, Location loc)
916 t = ((ElementTypeSpec) t).Element;
918 rc.Compiler.Report.SymbolRelatedToPreviousError (t);
919 rc.Compiler.Report.Error (208, loc,
920 "Cannot take the address of, get the size of, or declare a pointer to a managed type `{0}'",
926 // This method always return false for non-generic compiler,
927 // while Type.IsGenericParameter is returned if it is supported.
928 public static bool IsGenericParameter (TypeSpec type)
930 return type.IsGenericParameter;
933 public static bool IsGenericType (TypeSpec type)
935 return type.IsGeneric;
938 public static TypeSpec[] GetTypeArguments (TypeSpec t)
940 // TODO: return empty array !!
941 return t.TypeArguments;
945 /// Check whether `type' and `parent' are both instantiations of the same
946 /// generic type. Note that we do not check the type parameters here.
948 public static bool IsInstantiationOfSameGenericType (TypeSpec type, TypeSpec parent)
950 return type == parent || type.MemberDefinition == parent.MemberDefinition;