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@seznam.cz)
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-2008 Novell, Inc.
15 using System.Globalization;
16 using System.Collections.Generic;
23 // All compiler built-in types (they have to exist otherwise the compiler will not work)
25 public class BuiltinTypes
27 public readonly BuiltinTypeSpec Object;
28 public readonly BuiltinTypeSpec ValueType;
29 public readonly BuiltinTypeSpec Attribute;
31 public readonly BuiltinTypeSpec Int;
32 public readonly BuiltinTypeSpec UInt;
33 public readonly BuiltinTypeSpec Long;
34 public readonly BuiltinTypeSpec ULong;
35 public readonly BuiltinTypeSpec Float;
36 public readonly BuiltinTypeSpec Double;
37 public readonly BuiltinTypeSpec Char;
38 public readonly BuiltinTypeSpec Short;
39 public readonly BuiltinTypeSpec Decimal;
40 public readonly BuiltinTypeSpec Bool;
41 public readonly BuiltinTypeSpec SByte;
42 public readonly BuiltinTypeSpec Byte;
43 public readonly BuiltinTypeSpec UShort;
44 public readonly BuiltinTypeSpec String;
46 public readonly BuiltinTypeSpec Enum;
47 public readonly BuiltinTypeSpec Delegate;
48 public readonly BuiltinTypeSpec MulticastDelegate;
49 public readonly BuiltinTypeSpec Void;
50 public readonly BuiltinTypeSpec Array;
51 public readonly BuiltinTypeSpec Type;
52 public readonly BuiltinTypeSpec IEnumerator;
53 public readonly BuiltinTypeSpec IEnumerable;
54 public readonly BuiltinTypeSpec IDisposable;
55 public readonly BuiltinTypeSpec IntPtr;
56 public readonly BuiltinTypeSpec UIntPtr;
57 public readonly BuiltinTypeSpec RuntimeFieldHandle;
58 public readonly BuiltinTypeSpec RuntimeTypeHandle;
59 public readonly BuiltinTypeSpec Exception;
62 // These are internal buil-in types which depend on other
63 // build-in type (mostly object)
65 public readonly BuiltinTypeSpec Dynamic;
67 // Predefined operators tables
68 public readonly Binary.PredefinedOperator[] OperatorsBinaryStandard;
69 public readonly Binary.PredefinedOperator[] OperatorsBinaryEquality;
70 public readonly Binary.PredefinedOperator[] OperatorsBinaryUnsafe;
71 public readonly TypeSpec[][] OperatorsUnary;
72 public readonly TypeSpec[] OperatorsUnaryMutator;
74 public readonly TypeSpec[] BinaryPromotionsTypes;
75 public readonly TypeSpec[] SwitchUserTypes;
77 readonly BuiltinTypeSpec[] types;
79 public BuiltinTypes ()
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);
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);
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);
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);
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);
117 // TODO: Maybe I should promote it to different kind for faster compares
118 Dynamic = new BuiltinTypeSpec ("dynamic", BuiltinTypeSpec.Type.Dynamic);
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);
126 BinaryPromotionsTypes = ConstantFold.CreateBinaryPromotionsTypes (this);
127 SwitchUserTypes = Switch.CreateSwitchUserTypes (this);
129 types = new BuiltinTypeSpec[] {
130 Object, ValueType, Attribute,
131 Int, UInt, Long, ULong, Float, Double, Char, Short, Decimal, Bool, SByte, Byte, UShort, String,
132 Enum, Delegate, MulticastDelegate, Void, Array, Type, IEnumerator, IEnumerable, IDisposable,
133 IntPtr, UIntPtr, RuntimeFieldHandle, RuntimeTypeHandle, Exception };
136 public BuiltinTypeSpec[] AllTypes {
142 public bool CheckDefinitions (ModuleContainer module)
144 var ctx = module.Compiler;
145 foreach (var p in types) {
146 var found = PredefinedType.Resolve (module, p.Kind, p.Namespace, p.Name, p.Arity);
147 if (found == null || found == p)
150 var tc = found.MemberDefinition as TypeContainer;
152 var ns = module.GlobalRootNamespace.GetNamespace (p.Namespace, false);
153 ns.SetBuiltinType (p);
155 tc.SetPredefinedSpec (p);
156 p.SetDefinition (found);
160 if (ctx.Report.Errors != 0)
163 // Set internal build-in types
164 Dynamic.SetDefinition (Object);
171 // Compiler predefined types. Usually used for compiler generated
172 // code or for comparison against well known framework type. They
173 // may not exist as they are optional
175 class PredefinedTypes
177 public readonly PredefinedType ArgIterator;
178 public readonly PredefinedType TypedReference;
179 public readonly PredefinedType MarshalByRefObject;
180 public readonly PredefinedType RuntimeHelpers;
181 public readonly PredefinedType IAsyncResult;
182 public readonly PredefinedType AsyncCallback;
183 public readonly PredefinedType RuntimeArgumentHandle;
184 public readonly PredefinedType CharSet;
185 public readonly PredefinedType IsVolatile;
186 public readonly PredefinedType IEnumeratorGeneric;
187 public readonly PredefinedType IListGeneric;
188 public readonly PredefinedType ICollectionGeneric;
189 public readonly PredefinedType IEnumerableGeneric;
190 public readonly PredefinedType Nullable;
191 public readonly PredefinedType Activator;
192 public readonly PredefinedType Interlocked;
193 public readonly PredefinedType Monitor;
194 public readonly PredefinedType NotSupportedException;
195 public readonly PredefinedType RuntimeFieldHandle;
196 public readonly PredefinedType RuntimeMethodHandle;
197 public readonly PredefinedType SecurityAction;
198 public readonly PredefinedType Dictionary;
199 public readonly PredefinedType Hashtable;
204 public readonly PredefinedType Expression;
205 public readonly PredefinedType ExpressionGeneric;
206 public readonly PredefinedType ParameterExpression;
207 public readonly PredefinedType FieldInfo;
208 public readonly PredefinedType MethodBase;
209 public readonly PredefinedType MethodInfo;
210 public readonly PredefinedType ConstructorInfo;
215 public readonly PredefinedType Binder;
216 public readonly PredefinedType CallSite;
217 public readonly PredefinedType CallSiteGeneric;
218 public readonly PredefinedType BinderFlags;
220 public PredefinedTypes (ModuleContainer module)
222 TypedReference = new PredefinedType (module, MemberKind.Struct, "System", "TypedReference");
223 ArgIterator = new PredefinedType (module, MemberKind.Struct, "System", "ArgIterator");
225 MarshalByRefObject = new PredefinedType (module, MemberKind.Class, "System", "MarshalByRefObject");
226 RuntimeHelpers = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "RuntimeHelpers");
227 IAsyncResult = new PredefinedType (module, MemberKind.Interface, "System", "IAsyncResult");
228 AsyncCallback = new PredefinedType (module, MemberKind.Delegate, "System", "AsyncCallback");
229 RuntimeArgumentHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeArgumentHandle");
230 CharSet = new PredefinedType (module, MemberKind.Enum, "System.Runtime.InteropServices", "CharSet");
231 IsVolatile = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "IsVolatile");
232 IEnumeratorGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IEnumerator", 1);
233 IListGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IList", 1);
234 ICollectionGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "ICollection", 1);
235 IEnumerableGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IEnumerable", 1);
236 Nullable = new PredefinedType (module, MemberKind.Struct, "System", "Nullable", 1);
237 Activator = new PredefinedType (module, MemberKind.Class, "System", "Activator");
238 Interlocked = new PredefinedType (module, MemberKind.Class, "System.Threading", "Interlocked");
239 Monitor = new PredefinedType (module, MemberKind.Class, "System.Threading", "Monitor");
240 NotSupportedException = new PredefinedType (module, MemberKind.Class, "System", "NotSupportedException");
241 RuntimeFieldHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeFieldHandle");
242 RuntimeMethodHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeMethodHandle");
243 SecurityAction = new PredefinedType (module, MemberKind.Enum, "System.Security.Permissions", "SecurityAction");
244 Dictionary = new PredefinedType (module, MemberKind.Class, "System.Collections.Generic", "Dictionary", 2);
245 Hashtable = new PredefinedType (module, MemberKind.Class, "System.Collections", "Hashtable");
247 Expression = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "Expression");
248 ExpressionGeneric = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "Expression", 1);
249 ParameterExpression = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "ParameterExpression");
250 FieldInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "FieldInfo");
251 MethodBase = new PredefinedType (module, MemberKind.Class, "System.Reflection", "MethodBase");
252 MethodInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "MethodInfo");
253 ConstructorInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "ConstructorInfo");
255 CallSite = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "CallSite");
256 CallSiteGeneric = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "CallSite", 1);
257 Binder = new PredefinedType (module, MemberKind.Class, "Microsoft.CSharp.RuntimeBinder", "Binder");
258 BinderFlags = new PredefinedType (module, MemberKind.Enum, "Microsoft.CSharp.RuntimeBinder", "CSharpBinderFlags");
261 // Define types which are used for comparison. It does not matter
262 // if they don't exist as no error report is needed
264 if (TypedReference.Define ())
265 TypedReference.TypeSpec.IsSpecialRuntimeType = true;
267 if (ArgIterator.Define ())
268 ArgIterator.TypeSpec.IsSpecialRuntimeType = true;
270 if (IEnumerableGeneric.Define ())
271 IEnumerableGeneric.TypeSpec.IsGenericIterateInterface = true;
273 if (IListGeneric.Define ())
274 IListGeneric.TypeSpec.IsGenericIterateInterface = true;
276 if (ICollectionGeneric.Define ())
277 ICollectionGeneric.TypeSpec.IsGenericIterateInterface = true;
279 if (Nullable.Define ())
280 Nullable.TypeSpec.IsNullableType = true;
282 if (ExpressionGeneric.Define ())
283 ExpressionGeneric.TypeSpec.IsExpressionTreeType = true;
287 class PredefinedMembers
289 public readonly PredefinedMember<MethodSpec> ActivatorCreateInstance;
290 public readonly PredefinedMember<MethodSpec> DecimalCtor;
291 public readonly PredefinedMember<MethodSpec> DecimalCtorInt;
292 public readonly PredefinedMember<MethodSpec> DecimalCtorLong;
293 public readonly PredefinedMember<MethodSpec> DecimalConstantAttributeCtor;
294 public readonly PredefinedMember<MethodSpec> DefaultMemberAttributeCtor;
295 public readonly PredefinedMember<MethodSpec> DelegateCombine;
296 public readonly PredefinedMember<MethodSpec> DelegateEqual;
297 public readonly PredefinedMember<MethodSpec> DelegateInequal;
298 public readonly PredefinedMember<MethodSpec> DelegateRemove;
299 public readonly PredefinedMember<MethodSpec> DynamicAttributeCtor;
300 public readonly PredefinedMember<MethodSpec> FieldInfoGetFieldFromHandle;
301 public readonly PredefinedMember<MethodSpec> FieldInfoGetFieldFromHandle2;
302 public readonly PredefinedMember<MethodSpec> IDisposableDispose;
303 public readonly PredefinedMember<MethodSpec> IEnumerableGetEnumerator;
304 public readonly PredefinedMember<MethodSpec> InterlockedCompareExchange;
305 public readonly PredefinedMember<MethodSpec> InterlockedCompareExchange_T;
306 public readonly PredefinedMember<MethodSpec> FixedBufferAttributeCtor;
307 public readonly PredefinedMember<MethodSpec> MethodInfoGetMethodFromHandle;
308 public readonly PredefinedMember<MethodSpec> MethodInfoGetMethodFromHandle2;
309 public readonly PredefinedMember<MethodSpec> MonitorEnter;
310 public readonly PredefinedMember<MethodSpec> MonitorEnter_v4;
311 public readonly PredefinedMember<MethodSpec> MonitorExit;
312 public readonly PredefinedMember<PropertySpec> RuntimeCompatibilityWrapNonExceptionThrows;
313 public readonly PredefinedMember<MethodSpec> RuntimeHelpersInitializeArray;
314 public readonly PredefinedMember<PropertySpec> RuntimeHelpersOffsetToStringData;
315 public readonly PredefinedMember<ConstSpec> SecurityActionRequestMinimum;
316 public readonly PredefinedMember<FieldSpec> StringEmpty;
317 public readonly PredefinedMember<MethodSpec> StringEqual;
318 public readonly PredefinedMember<MethodSpec> StringInequal;
319 public readonly PredefinedMember<MethodSpec> StructLayoutAttributeCtor;
320 public readonly PredefinedMember<FieldSpec> StructLayoutCharSet;
321 public readonly PredefinedMember<FieldSpec> StructLayoutPack;
322 public readonly PredefinedMember<FieldSpec> StructLayoutSize;
323 public readonly PredefinedMember<MethodSpec> TypeGetTypeFromHandle;
325 public PredefinedMembers (ModuleContainer module)
327 var types = module.PredefinedTypes;
328 var atypes = module.PredefinedAttributes;
329 var btypes = module.Compiler.BuiltinTypes;
331 ActivatorCreateInstance = new PredefinedMember<MethodSpec> (module, types.Activator,
332 MemberFilter.Method ("CreateInstance", 1, ParametersCompiled.EmptyReadOnlyParameters, null));
334 DecimalCtor = new PredefinedMember<MethodSpec> (module, btypes.Decimal,
335 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
336 btypes.Int, btypes.Int, btypes.Int, btypes.Bool, btypes.Byte)));
338 DecimalCtorInt = new PredefinedMember<MethodSpec> (module, btypes.Decimal,
339 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Int)));
341 DecimalCtorLong = new PredefinedMember<MethodSpec> (module, btypes.Decimal,
342 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Long)));
344 DecimalConstantAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.DecimalConstant,
345 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
346 btypes.Byte, btypes.Byte, btypes.UInt, btypes.UInt, btypes.UInt)));
348 DefaultMemberAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.DefaultMember,
349 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.String)));
351 DelegateCombine = new PredefinedMember<MethodSpec> (module, btypes.Delegate, "Combine", btypes.Delegate, btypes.Delegate);
352 DelegateRemove = new PredefinedMember<MethodSpec> (module, btypes.Delegate, "Remove", btypes.Delegate, btypes.Delegate);
354 DelegateEqual = new PredefinedMember<MethodSpec> (module, btypes.Delegate,
355 new MemberFilter (Operator.GetMetadataName (Operator.OpType.Equality), 0, MemberKind.Operator, null, btypes.Bool));
357 DelegateInequal = new PredefinedMember<MethodSpec> (module, btypes.Delegate,
358 new MemberFilter (Operator.GetMetadataName (Operator.OpType.Inequality), 0, MemberKind.Operator, null, btypes.Bool));
360 DynamicAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.Dynamic,
361 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
362 ArrayContainer.MakeType (module, btypes.Bool))));
364 FieldInfoGetFieldFromHandle = new PredefinedMember<MethodSpec> (module, types.FieldInfo,
365 "GetFieldFromHandle", MemberKind.Method, types.RuntimeFieldHandle);
367 FieldInfoGetFieldFromHandle2 = new PredefinedMember<MethodSpec> (module, types.FieldInfo,
368 "GetFieldFromHandle", MemberKind.Method, types.RuntimeFieldHandle, new PredefinedType (btypes.RuntimeTypeHandle));
370 FixedBufferAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.FixedBuffer,
371 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Type, btypes.Int)));
373 IDisposableDispose = new PredefinedMember<MethodSpec> (module, btypes.IDisposable, "Dispose", TypeSpec.EmptyTypes);
375 IEnumerableGetEnumerator = new PredefinedMember<MethodSpec> (module, btypes.IEnumerable,
376 "GetEnumerator", TypeSpec.EmptyTypes);
378 InterlockedCompareExchange = new PredefinedMember<MethodSpec> (module, types.Interlocked,
379 MemberFilter.Method ("CompareExchange", 0,
380 new ParametersImported (
382 new ParameterData (null, Parameter.Modifier.REF),
383 new ParameterData (null, Parameter.Modifier.NONE),
384 new ParameterData (null, Parameter.Modifier.NONE)
387 btypes.Int, btypes.Int, btypes.Int
392 InterlockedCompareExchange_T = new PredefinedMember<MethodSpec> (module, types.Interlocked,
393 MemberFilter.Method ("CompareExchange", 1,
394 new ParametersImported (
396 new ParameterData (null, Parameter.Modifier.REF),
397 new ParameterData (null, Parameter.Modifier.NONE),
398 new ParameterData (null, Parameter.Modifier.NONE)
401 new TypeParameterSpec (0, null, SpecialConstraint.None, Variance.None, null),
402 new TypeParameterSpec (0, null, SpecialConstraint.None, Variance.None, null),
403 new TypeParameterSpec (0, null, SpecialConstraint.None, Variance.None, null),
407 MethodInfoGetMethodFromHandle = new PredefinedMember<MethodSpec> (module, types.MethodBase,
408 "GetMethodFromHandle", MemberKind.Method, types.RuntimeMethodHandle);
410 MethodInfoGetMethodFromHandle2 = new PredefinedMember<MethodSpec> (module, types.MethodBase,
411 "GetMethodFromHandle", MemberKind.Method, types.RuntimeMethodHandle, new PredefinedType (btypes.RuntimeTypeHandle));
413 MonitorEnter = new PredefinedMember<MethodSpec> (module, types.Monitor, "Enter", btypes.Object);
415 MonitorEnter_v4 = new PredefinedMember<MethodSpec> (module, types.Monitor,
416 MemberFilter.Method ("Enter", 0,
417 new ParametersImported (new[] {
418 new ParameterData (null, Parameter.Modifier.NONE),
419 new ParameterData (null, Parameter.Modifier.REF)
422 btypes.Object, btypes.Bool
425 MonitorExit = new PredefinedMember<MethodSpec> (module, types.Monitor, "Exit", btypes.Object);
427 RuntimeCompatibilityWrapNonExceptionThrows = new PredefinedMember<PropertySpec> (module, atypes.RuntimeCompatibility,
428 MemberFilter.Property ("WrapNonExceptionThrows", btypes.Bool));
430 RuntimeHelpersInitializeArray = new PredefinedMember<MethodSpec> (module, types.RuntimeHelpers,
431 "InitializeArray", btypes.Array, btypes.RuntimeFieldHandle);
433 RuntimeHelpersOffsetToStringData = new PredefinedMember<PropertySpec> (module, types.RuntimeHelpers,
434 MemberFilter.Property ("OffsetToStringData", btypes.Int));
436 SecurityActionRequestMinimum = new PredefinedMember<ConstSpec> (module, types.SecurityAction, "RequestMinimum",
437 MemberKind.Field, types.SecurityAction);
439 StringEmpty = new PredefinedMember<FieldSpec> (module, btypes.String, MemberFilter.Field ("Empty", btypes.String));
441 StringEqual = new PredefinedMember<MethodSpec> (module, btypes.String,
442 new MemberFilter (Operator.GetMetadataName (Operator.OpType.Equality), 0, MemberKind.Operator, null, btypes.Bool));
444 StringInequal = new PredefinedMember<MethodSpec> (module, btypes.String,
445 new MemberFilter (Operator.GetMetadataName (Operator.OpType.Inequality), 0, MemberKind.Operator, null, btypes.Bool));
447 StructLayoutAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.StructLayout,
448 MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Short)));
450 StructLayoutCharSet = new PredefinedMember<FieldSpec> (module, atypes.StructLayout, "CharSet",
451 MemberKind.Field, types.CharSet);
453 StructLayoutPack = new PredefinedMember<FieldSpec> (module, atypes.StructLayout,
454 MemberFilter.Field ("Pack", btypes.Int));
456 StructLayoutSize = new PredefinedMember<FieldSpec> (module, atypes.StructLayout,
457 MemberFilter.Field ("Size", btypes.Int));
459 TypeGetTypeFromHandle = new PredefinedMember<MethodSpec> (module, btypes.Type, "GetTypeFromHandle", btypes.RuntimeTypeHandle);
463 public class PredefinedType
465 readonly string name;
468 readonly MemberKind kind;
469 protected readonly ModuleContainer module;
470 protected TypeSpec type;
472 public PredefinedType (ModuleContainer module, MemberKind kind, string ns, string name, int arity)
473 : this (module, kind, ns, name)
478 public PredefinedType (ModuleContainer module, MemberKind kind, string ns, string name)
480 this.module = module;
486 public PredefinedType (BuiltinTypeSpec type)
488 this.kind = type.Kind;
489 this.name = type.Name;
490 this.ns = type.Namespace;
502 public bool IsDefined {
514 public string Namespace {
520 public TypeSpec TypeSpec {
528 public bool Define ()
533 type = Resolve (module, kind, ns, name, arity, false);
537 public string GetSignatureForError ()
539 return ns + "." + name;
542 public static TypeSpec Resolve (ModuleContainer module, MemberKind kind, string ns, string name, int arity)
544 return Resolve (module, kind, ns, name, arity, true);
547 public static TypeSpec Resolve (ModuleContainer module, MemberKind kind, string ns, string name, int arity, bool reportErrors)
549 Namespace type_ns = module.GlobalRootNamespace.GetNamespace (ns, true);
550 var found = type_ns.GetAllTypes (name);
553 module.Compiler.Report.Error (518, "The predefined type `{0}.{1}' is not defined or imported", ns, name);
558 TypeSpec best_match = null;
559 foreach (var candidate in found) {
560 if (candidate.Kind != kind) {
561 if (candidate.Kind == MemberKind.Struct && kind == MemberKind.Void && candidate.MemberDefinition is TypeContainer) {
562 // Void is declared as struct but we keep it internally as
563 // special kind, the swap will be done by caller
569 if (candidate.Arity != arity)
572 if ((candidate.Modifiers & Modifiers.INTERNAL) != 0 && !candidate.MemberDefinition.IsInternalAsPublic (module.DeclaringAssembly))
575 if (best_match == null) {
576 best_match = candidate;
580 var other_match = best_match;
581 if (!best_match.MemberDefinition.IsImported &&
582 module.Compiler.BuiltinTypes.Object.MemberDefinition.DeclaringAssembly == candidate.MemberDefinition.DeclaringAssembly) {
583 best_match = candidate;
587 if (best_match.MemberDefinition is MemberCore) {
588 location = ((MemberCore) best_match.MemberDefinition).Location.Name;
590 var assembly = (ImportedAssemblyDefinition) best_match.MemberDefinition.DeclaringAssembly;
591 location = Path.GetFileName (assembly.Location);
594 module.Compiler.Report.SymbolRelatedToPreviousError (other_match);
595 module.Compiler.Report.SymbolRelatedToPreviousError (candidate);
597 module.Compiler.Report.Warning (1685, 1,
598 "The predefined type `{0}.{1}' is defined multiple times. Using definition from `{2}'",
604 if (best_match == null && reportErrors) {
606 if (found[0].MemberDefinition is MemberCore) {
607 loc = ((MemberCore) found[0].MemberDefinition).Location;
610 module.Compiler.Report.SymbolRelatedToPreviousError (found[0]);
613 module.Compiler.Report.Error (520, loc, "The predefined type `{0}.{1}' is not declared correctly", ns, name);
619 public TypeSpec Resolve ()
622 type = Resolve (module, kind, ns, name, arity);
628 class PredefinedMember<T> where T : MemberSpec
630 readonly ModuleContainer module;
632 TypeSpec declaring_type;
633 readonly PredefinedType declaring_type_predefined;
634 readonly PredefinedType[] parameters_predefined;
637 public PredefinedMember (ModuleContainer module, PredefinedType type, MemberFilter filter)
639 this.module = module;
640 this.declaring_type_predefined = type;
641 this.filter = filter;
644 public PredefinedMember (ModuleContainer module, TypeSpec type, MemberFilter filter)
646 this.module = module;
647 this.declaring_type = type;
648 this.filter = filter;
651 public PredefinedMember (ModuleContainer module, PredefinedType type, string name, params TypeSpec[] types)
652 : this (module, type, MemberFilter.Method (name, 0, ParametersCompiled.CreateFullyResolved (types), null))
656 public PredefinedMember (ModuleContainer module, PredefinedType type, string name, MemberKind kind, params PredefinedType[] types)
657 : this (module, type, new MemberFilter (name, 0, kind, null, null))
659 parameters_predefined = types;
662 public PredefinedMember (ModuleContainer module, BuiltinTypeSpec type, string name, params TypeSpec[] types)
663 : this (module, type, MemberFilter.Method (name, 0, ParametersCompiled.CreateFullyResolved (types), null))
672 if (declaring_type == null) {
673 if (!declaring_type_predefined.Define ())
676 declaring_type = declaring_type_predefined.TypeSpec;
679 if (parameters_predefined != null) {
680 TypeSpec[] types = new TypeSpec [parameters_predefined.Length];
681 for (int i = 0; i < types.Length; ++i) {
682 var p = parameters_predefined [i];
686 types[i] = p.TypeSpec;
689 if (filter.Kind == MemberKind.Field)
690 filter = new MemberFilter (filter.Name, filter.Arity, filter.Kind, null, types [0]);
692 filter = new MemberFilter (filter.Name, filter.Arity, filter.Kind, ParametersCompiled.CreateFullyResolved (types), filter.MemberType);
695 member = MemberCache.FindMember (declaring_type, filter, BindingRestriction.DeclaredOnly) as T;
699 if (!member.IsAccessible (module))
705 public T Resolve (Location loc)
713 if (declaring_type == null) {
714 if (declaring_type_predefined.Resolve () == null)
718 if (parameters_predefined != null) {
719 TypeSpec[] types = new TypeSpec[parameters_predefined.Length];
720 for (int i = 0; i < types.Length; ++i) {
721 var p = parameters_predefined[i];
722 types[i] = p.Resolve ();
723 if (types[i] == null)
727 filter = new MemberFilter (filter.Name, filter.Arity, filter.Kind, ParametersCompiled.CreateFullyResolved (types), filter.MemberType);
730 string method_args = null;
731 if (filter.Parameters != null)
732 method_args = filter.Parameters.GetSignatureForError ();
734 module.Compiler.Report.Error (656, loc, "The compiler required member `{0}.{1}{2}' could not be found or is inaccessible",
735 declaring_type.GetSignatureForError (), filter.Name, method_args);
741 partial class TypeManager {
744 /// Returns the C# name of a type if possible, or the full type name otherwise
746 static public string CSharpName (TypeSpec t)
748 return t.GetSignatureForError ();
751 static public string CSharpName (IList<TypeSpec> types)
753 if (types.Count == 0)
756 StringBuilder sb = new StringBuilder ();
757 for (int i = 0; i < types.Count; ++i) {
761 sb.Append (CSharpName (types [i]));
763 return sb.ToString ();
766 static public string GetFullNameSignature (MemberSpec mi)
768 return mi.GetSignatureForError ();
771 static public string CSharpSignature (MemberSpec mb)
773 return mb.GetSignatureForError ();
777 public static bool IsDelegateType (TypeSpec t)
783 public static bool IsEnumType (TypeSpec t)
789 // Whether a type is unmanaged. This is used by the unsafe code (25.2)
791 public static bool IsUnmanagedType (TypeSpec t)
793 var ds = t.MemberDefinition as DeclSpace;
795 return ds.IsUnmanagedType ();
797 if (t.Kind == MemberKind.Void)
800 // Someone did the work of checking if the ElementType of t is unmanaged. Let's not repeat it.
802 return IsUnmanagedType (GetElementType (t));
804 if (!IsValueType (t))
807 if (t.IsNested && t.DeclaringType.IsGenericOrParentIsGeneric)
814 // Null is considered to be a reference type
816 public static bool IsReferenceType (TypeSpec t)
818 if (t.IsGenericParameter)
819 return ((TypeParameterSpec) t).IsReferenceType;
821 return !t.IsStruct && !IsEnumType (t);
824 public static bool IsValueType (TypeSpec t)
826 if (t.IsGenericParameter)
827 return ((TypeParameterSpec) t).IsValueType;
829 return t.IsStruct || IsEnumType (t);
832 public static bool IsFamilyAccessible (TypeSpec type, TypeSpec parent)
834 // TypeParameter tparam = LookupTypeParameter (type);
835 // TypeParameter pparam = LookupTypeParameter (parent);
837 if (type.Kind == MemberKind.TypeParameter && parent.Kind == MemberKind.TypeParameter) { // (tparam != null) && (pparam != null)) {
841 throw new NotImplementedException ("net");
842 // return tparam.IsSubclassOf (parent);
846 if (IsInstantiationOfSameGenericType (type, parent))
849 type = type.BaseType;
850 } while (type != null);
856 // Checks whether `type' is a nested child of `parent'.
858 public static bool IsNestedChildOf (TypeSpec type, ITypeDefinition parent)
863 if (type.MemberDefinition == parent)
866 type = type.DeclaringType;
867 while (type != null) {
868 if (type.MemberDefinition == parent)
871 type = type.DeclaringType;
877 public static TypeSpec GetElementType (TypeSpec t)
879 return ((ElementTypeSpec)t).Element;
883 /// This method is not implemented by MS runtime for dynamic types
885 public static bool HasElementType (TypeSpec t)
887 return t is ElementTypeSpec;
891 /// Utility function that can be used to probe whether a type
892 /// is managed or not.
894 public static bool VerifyUnmanaged (ModuleContainer rc, TypeSpec t, Location loc)
897 t = GetElementType (t);
899 if (IsUnmanagedType (t))
902 rc.Compiler.Report.SymbolRelatedToPreviousError (t);
903 rc.Compiler.Report.Error (208, loc,
904 "Cannot take the address of, get the size of, or declare a pointer to a managed type `{0}'",
910 // This method always return false for non-generic compiler,
911 // while Type.IsGenericParameter is returned if it is supported.
912 public static bool IsGenericParameter (TypeSpec type)
914 return type.IsGenericParameter;
917 public static bool IsGenericType (TypeSpec type)
919 return type.IsGeneric;
922 public static TypeSpec[] GetTypeArguments (TypeSpec t)
924 // TODO: return empty array !!
925 return t.TypeArguments;
929 /// Check whether `type' and `parent' are both instantiations of the same
930 /// generic type. Note that we do not check the type parameters here.
932 public static bool IsInstantiationOfSameGenericType (TypeSpec type, TypeSpec parent)
934 return type == parent || type.MemberDefinition == parent.MemberDefinition;