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;
22 // All compiler build-in types (they have to exist otherwise the compile will not work)
24 public class BuildinTypes
26 public readonly BuildinTypeSpec Object;
27 public readonly BuildinTypeSpec ValueType;
28 public readonly BuildinTypeSpec Attribute;
30 public readonly BuildinTypeSpec Int;
31 public readonly BuildinTypeSpec UInt;
32 public readonly BuildinTypeSpec Long;
33 public readonly BuildinTypeSpec ULong;
34 public readonly BuildinTypeSpec Float;
35 public readonly BuildinTypeSpec Double;
36 public readonly BuildinTypeSpec Char;
37 public readonly BuildinTypeSpec Short;
38 public readonly BuildinTypeSpec Decimal;
39 public readonly BuildinTypeSpec Bool;
40 public readonly BuildinTypeSpec SByte;
41 public readonly BuildinTypeSpec Byte;
42 public readonly BuildinTypeSpec UShort;
43 public readonly BuildinTypeSpec String;
45 public readonly BuildinTypeSpec Enum;
46 public readonly BuildinTypeSpec Delegate;
47 public readonly BuildinTypeSpec MulticastDelegate;
48 public readonly BuildinTypeSpec Void;
49 public readonly BuildinTypeSpec Array;
50 public readonly BuildinTypeSpec Type;
51 public readonly BuildinTypeSpec IEnumerator;
52 public readonly BuildinTypeSpec IEnumerable;
53 public readonly BuildinTypeSpec IDisposable;
54 public readonly BuildinTypeSpec IntPtr;
55 public readonly BuildinTypeSpec UIntPtr;
56 public readonly BuildinTypeSpec RuntimeFieldHandle;
57 public readonly BuildinTypeSpec RuntimeTypeHandle;
58 public readonly BuildinTypeSpec Exception;
61 // These are internal buil-in types which depend on other
62 // build-in type (mostly object)
64 public readonly BuildinTypeSpec Dynamic;
65 public readonly BuildinTypeSpec Null;
67 readonly BuildinTypeSpec[] types;
69 public BuildinTypes ()
71 Object = new BuildinTypeSpec (MemberKind.Class, "System", "Object", BuildinTypeSpec.Type.Object);
72 ValueType = new BuildinTypeSpec (MemberKind.Class, "System", "ValueType", BuildinTypeSpec.Type.ValueType);
73 Attribute = new BuildinTypeSpec (MemberKind.Class, "System", "Attribute", BuildinTypeSpec.Type.Attribute);
75 Int = new BuildinTypeSpec (MemberKind.Struct, "System", "Int32", BuildinTypeSpec.Type.Int);
76 Long = new BuildinTypeSpec (MemberKind.Struct, "System", "Int64", BuildinTypeSpec.Type.Long);
77 UInt = new BuildinTypeSpec (MemberKind.Struct, "System", "UInt32", BuildinTypeSpec.Type.UInt);
78 ULong = new BuildinTypeSpec (MemberKind.Struct, "System", "UInt64", BuildinTypeSpec.Type.ULong);
79 Byte = new BuildinTypeSpec (MemberKind.Struct, "System", "Byte", BuildinTypeSpec.Type.Byte);
80 SByte = new BuildinTypeSpec (MemberKind.Struct, "System", "SByte", BuildinTypeSpec.Type.SByte);
81 Short = new BuildinTypeSpec (MemberKind.Struct, "System", "Int16", BuildinTypeSpec.Type.Short);
82 UShort = new BuildinTypeSpec (MemberKind.Struct, "System", "UInt16", BuildinTypeSpec.Type.UShort);
84 IEnumerator = new BuildinTypeSpec (MemberKind.Interface, "System.Collections", "IEnumerator", BuildinTypeSpec.Type.IEnumerator);
85 IEnumerable = new BuildinTypeSpec (MemberKind.Interface, "System.Collections", "IEnumerable", BuildinTypeSpec.Type.IEnumerable);
86 IDisposable = new BuildinTypeSpec (MemberKind.Interface, "System", "IDisposable", BuildinTypeSpec.Type.IDisposable);
88 Char = new BuildinTypeSpec (MemberKind.Struct, "System", "Char", BuildinTypeSpec.Type.Char);
89 String = new BuildinTypeSpec (MemberKind.Class, "System", "String", BuildinTypeSpec.Type.String);
90 Float = new BuildinTypeSpec (MemberKind.Struct, "System", "Single", BuildinTypeSpec.Type.Float);
91 Double = new BuildinTypeSpec (MemberKind.Struct, "System", "Double", BuildinTypeSpec.Type.Double);
92 Decimal = new BuildinTypeSpec (MemberKind.Struct, "System", "Decimal", BuildinTypeSpec.Type.Decimal);
93 Bool = new BuildinTypeSpec (MemberKind.Struct, "System", "Boolean", BuildinTypeSpec.Type.Bool);
94 IntPtr = new BuildinTypeSpec (MemberKind.Struct, "System", "IntPtr", BuildinTypeSpec.Type.IntPtr);
95 UIntPtr = new BuildinTypeSpec (MemberKind.Struct, "System", "UIntPtr", BuildinTypeSpec.Type.UIntPtr);
97 MulticastDelegate = new BuildinTypeSpec (MemberKind.Class, "System", "MulticastDelegate", BuildinTypeSpec.Type.MulticastDelegate);
98 Delegate = new BuildinTypeSpec (MemberKind.Class, "System", "Delegate", BuildinTypeSpec.Type.Delegate);
99 Enum = new BuildinTypeSpec (MemberKind.Class, "System", "Enum", BuildinTypeSpec.Type.Enum);
100 Array = new BuildinTypeSpec (MemberKind.Class, "System", "Array", BuildinTypeSpec.Type.Array);
101 Void = new BuildinTypeSpec (MemberKind.Struct, "System", "Void", BuildinTypeSpec.Type.Void);
102 Type = new BuildinTypeSpec (MemberKind.Class, "System", "Type", BuildinTypeSpec.Type.Type);
103 Exception = new BuildinTypeSpec (MemberKind.Class, "System", "Exception", BuildinTypeSpec.Type.Exception);
104 RuntimeFieldHandle = new BuildinTypeSpec (MemberKind.Struct, "System", "RuntimeFieldHandle", BuildinTypeSpec.Type.RuntimeFieldHandle);
105 RuntimeTypeHandle = new BuildinTypeSpec (MemberKind.Struct, "System", "RuntimeTypeHandle", BuildinTypeSpec.Type.RuntimeTypeHandle);
107 Dynamic = new BuildinTypeSpec ("dynamic", BuildinTypeSpec.Type.Dynamic);
108 Null = new BuildinTypeSpec ("null", BuildinTypeSpec.Type.Null);
109 Null.MemberCache = MemberCache.Empty;
111 types = new BuildinTypeSpec[] {
112 Object, ValueType, Attribute,
113 Int, UInt, Long, ULong, Float, Double, Char, Short, Decimal, Bool, SByte, Byte, UShort, String,
114 Enum, Delegate, MulticastDelegate, Void, Array, Type, IEnumerator, IEnumerable, IDisposable,
115 IntPtr, UIntPtr, RuntimeFieldHandle, RuntimeTypeHandle, Exception };
117 // Deal with obsolete static types
119 TypeManager.object_type = Object;
120 TypeManager.value_type = ValueType;
121 TypeManager.string_type = String;
122 TypeManager.int32_type = Int;
123 TypeManager.uint32_type = UInt;
124 TypeManager.int64_type = Long;
125 TypeManager.uint64_type = ULong;
126 TypeManager.float_type = Float;
127 TypeManager.double_type = Double;
128 TypeManager.char_type = Char;
129 TypeManager.short_type = Short;
130 TypeManager.decimal_type = Decimal;
131 TypeManager.bool_type = Bool;
132 TypeManager.sbyte_type = SByte;
133 TypeManager.byte_type = Byte;
134 TypeManager.ushort_type = UShort;
135 TypeManager.enum_type = Enum;
136 TypeManager.delegate_type = Delegate;
137 TypeManager.multicast_delegate_type = MulticastDelegate; ;
138 TypeManager.void_type = Void;
139 TypeManager.array_type = Array; ;
140 TypeManager.runtime_handle_type = RuntimeTypeHandle;
141 TypeManager.type_type = Type;
142 TypeManager.ienumerator_type = IEnumerator;
143 TypeManager.ienumerable_type = IEnumerable;
144 TypeManager.idisposable_type = IDisposable;
145 TypeManager.intptr_type = IntPtr;
146 TypeManager.uintptr_type = UIntPtr;
147 TypeManager.runtime_field_handle_type = RuntimeFieldHandle;
148 TypeManager.attribute_type = Attribute;
149 TypeManager.exception_type = Exception;
151 InternalType.Dynamic = Dynamic;
152 InternalType.Null = Null;
155 public BuildinTypeSpec[] AllTypes {
161 public bool CheckDefinitions (ModuleContainer module)
163 var ctx = module.Compiler;
164 foreach (var p in types) {
165 var found = PredefinedType.Resolve (module, p.Kind, p.Namespace, p.Name, p.Arity, Location.Null);
166 if (found == null || found == p)
169 var tc = found.MemberDefinition as TypeContainer;
171 var ns = module.GlobalRootNamespace.GetNamespace (p.Namespace, false);
172 ns.ReplaceTypeWithPredefined (found, p);
174 tc.SetPredefinedSpec (p);
175 p.SetDefinition (found);
179 if (ctx.Report.Errors != 0)
182 // Set internal build-in types
183 Dynamic.SetDefinition (Object);
184 Null.SetDefinition (Object);
191 // Compiler predefined types. Usually used for compiler generated
192 // code or for comparison against well known framework type
194 class PredefinedTypes
196 // TODO: These two exist only to reject type comparison
197 public readonly PredefinedType TypedReference;
198 public readonly PredefinedType ArgIterator;
200 public readonly PredefinedType MarshalByRefObject;
201 public readonly PredefinedType RuntimeHelpers;
202 public readonly PredefinedType IAsyncResult;
203 public readonly PredefinedType AsyncCallback;
204 public readonly PredefinedType RuntimeArgumentHandle;
205 public readonly PredefinedType CharSet;
206 public readonly PredefinedType IsVolatile;
207 public readonly PredefinedType IEnumeratorGeneric;
208 public readonly PredefinedType IListGeneric;
209 public readonly PredefinedType ICollectionGeneric;
210 public readonly PredefinedType IEnumerableGeneric;
211 public readonly PredefinedType Nullable;
212 public readonly PredefinedType Activator;
213 public readonly PredefinedType Interlocked;
214 public readonly PredefinedType Monitor;
215 public readonly PredefinedType NotSupportedException;
216 public readonly PredefinedType RuntimeFieldHandle;
217 public readonly PredefinedType RuntimeMethodHandle;
218 public readonly PredefinedType SecurityAction;
223 public readonly PredefinedType Expression;
224 public readonly PredefinedType ExpressionGeneric;
225 public readonly PredefinedType ParameterExpression;
226 public readonly PredefinedType FieldInfo;
227 public readonly PredefinedType MethodBase;
228 public readonly PredefinedType MethodInfo;
229 public readonly PredefinedType ConstructorInfo;
234 public readonly PredefinedType Binder;
235 public readonly PredefinedType CallSite;
236 public readonly PredefinedType CallSiteGeneric;
237 public readonly PredefinedType BinderFlags;
239 public PredefinedTypes (ModuleContainer module)
241 TypedReference = new PredefinedType (module, MemberKind.Struct, "System", "TypedReference");
242 ArgIterator = new PredefinedType (module, MemberKind.Struct, "System", "ArgIterator");
243 MarshalByRefObject = new PredefinedType (module, MemberKind.Class, "System", "MarshalByRefObject");
244 RuntimeHelpers = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "RuntimeHelpers");
245 IAsyncResult = new PredefinedType (module, MemberKind.Interface, "System", "IAsyncResult");
246 AsyncCallback = new PredefinedType (module, MemberKind.Delegate, "System", "AsyncCallback");
247 RuntimeArgumentHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeArgumentHandle");
248 CharSet = new PredefinedType (module, MemberKind.Enum, "System.Runtime.InteropServices", "CharSet");
249 IsVolatile = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "IsVolatile");
250 IEnumeratorGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IEnumerator", 1);
251 IListGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IList", 1);
252 ICollectionGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "ICollection", 1);
253 IEnumerableGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IEnumerable", 1);
254 Nullable = new PredefinedType (module, MemberKind.Struct, "System", "Nullable", 1);
255 Activator = new PredefinedType (module, MemberKind.Class, "System", "Activator");
256 Interlocked = new PredefinedType (module, MemberKind.Class, "System.Threading", "Interlocked");
257 Monitor = new PredefinedType (module, MemberKind.Class, "System.Threading", "Monitor");
258 NotSupportedException = new PredefinedType (module, MemberKind.Class, "System", "NotSupportedException");
259 RuntimeFieldHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeFieldHandle");
260 RuntimeMethodHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeMethodHandle");
261 SecurityAction = new PredefinedType (module, MemberKind.Enum, "System.Security.Permissions", "SecurityAction");
263 Expression = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "Expression");
264 ExpressionGeneric = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "Expression", 1);
265 ParameterExpression = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "ParameterExpression");
266 FieldInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "FieldInfo");
267 MethodBase = new PredefinedType (module, MemberKind.Class, "System.Reflection", "MethodBase");
268 MethodInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "MethodInfo");
269 ConstructorInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "ConstructorInfo");
271 CallSite = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "CallSite");
272 CallSiteGeneric = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "CallSite", 1);
273 Binder = new PredefinedType (module, MemberKind.Class, "Microsoft.CSharp.RuntimeBinder", "Binder");
274 BinderFlags = new PredefinedType (module, MemberKind.Enum, "Microsoft.CSharp.RuntimeBinder", "CSharpBinderFlags");
277 // Define types which are used for comparison. It does not matter
278 // if they don't exist as no error report is needed
280 TypedReference.Define ();
281 ArgIterator.Define ();
282 MarshalByRefObject.Define ();
285 IEnumerableGeneric.Define ();
286 IListGeneric.Define ();
287 ICollectionGeneric.Define ();
288 IEnumerableGeneric.Define ();
289 IEnumeratorGeneric.Define ();
291 ExpressionGeneric.Define ();
293 // Deal with obsolete static types
295 TypeManager.typed_reference_type = TypedReference.TypeSpec;
296 TypeManager.arg_iterator_type = ArgIterator.TypeSpec;
297 TypeManager.mbr_type = MarshalByRefObject.TypeSpec;
298 TypeManager.generic_ilist_type = IListGeneric.TypeSpec;
299 TypeManager.generic_icollection_type = ICollectionGeneric.TypeSpec;
300 TypeManager.generic_ienumerator_type = IEnumeratorGeneric.TypeSpec;
301 TypeManager.generic_ienumerable_type = IEnumerableGeneric.TypeSpec;
302 TypeManager.generic_nullable_type = Nullable.TypeSpec;
303 TypeManager.expression_type = ExpressionGeneric.TypeSpec;
307 public class PredefinedType
313 protected readonly ModuleContainer module;
314 protected TypeSpec type;
316 public PredefinedType (ModuleContainer module, MemberKind kind, string ns, string name, int arity)
317 : this (module, kind, ns, name)
322 public PredefinedType (ModuleContainer module, MemberKind kind, string ns, string name)
324 this.module = module;
338 public bool IsDefined {
350 public string Namespace {
356 public TypeSpec TypeSpec {
364 public bool Define ()
369 Namespace type_ns = module.GlobalRootNamespace.GetNamespace (ns, true);
370 var te = type_ns.LookupType (module, name, arity, true, Location.Null);
374 if (te.Type.Kind != kind)
381 public FieldSpec GetField (string name, TypeSpec memberType, Location loc)
383 return TypeManager.GetPredefinedField (type, name, loc, memberType);
386 public string GetSignatureForError ()
388 return ns + "." + name;
391 public static TypeSpec Resolve (ModuleContainer module, MemberKind kind, string ns, string name, int arity, Location loc)
393 Namespace type_ns = module.GlobalRootNamespace.GetNamespace (ns, true);
394 var te = type_ns.LookupType (module, name, arity, false, Location.Null);
396 module.Compiler.Report.Error (518, loc, "The predefined type `{0}.{1}' is not defined or imported", ns, name);
401 if (type.Kind != kind) {
402 module.Compiler.Report.Error (520, loc, "The predefined type `{0}.{1}' is not declared correctly", ns, name);
409 public TypeSpec Resolve (Location loc)
412 type = Resolve (module, kind, ns, name, arity, loc);
418 partial class TypeManager {
420 // A list of core types that the compiler requires or uses
422 static public BuildinTypeSpec object_type;
423 static public BuildinTypeSpec value_type;
424 static public BuildinTypeSpec string_type;
425 static public BuildinTypeSpec int32_type;
426 static public BuildinTypeSpec uint32_type;
427 static public BuildinTypeSpec int64_type;
428 static public BuildinTypeSpec uint64_type;
429 static public BuildinTypeSpec float_type;
430 static public BuildinTypeSpec double_type;
431 static public BuildinTypeSpec char_type;
432 static public BuildinTypeSpec short_type;
433 static public BuildinTypeSpec decimal_type;
434 static public BuildinTypeSpec bool_type;
435 static public BuildinTypeSpec sbyte_type;
436 static public BuildinTypeSpec byte_type;
437 static public BuildinTypeSpec ushort_type;
438 static public BuildinTypeSpec enum_type;
439 static public BuildinTypeSpec delegate_type;
440 static public BuildinTypeSpec multicast_delegate_type;
441 static public BuildinTypeSpec void_type;
442 static public BuildinTypeSpec array_type;
443 static public BuildinTypeSpec runtime_handle_type;
444 static public BuildinTypeSpec type_type;
445 static public BuildinTypeSpec ienumerator_type;
446 static public BuildinTypeSpec ienumerable_type;
447 static public BuildinTypeSpec idisposable_type;
448 static public BuildinTypeSpec intptr_type;
449 static public BuildinTypeSpec uintptr_type;
450 static public BuildinTypeSpec runtime_field_handle_type;
451 static public BuildinTypeSpec attribute_type;
452 static public BuildinTypeSpec exception_type;
455 static public TypeSpec typed_reference_type;
456 static public TypeSpec arg_iterator_type;
457 static public TypeSpec mbr_type;
458 static public TypeSpec generic_ilist_type;
459 static public TypeSpec generic_icollection_type;
460 static public TypeSpec generic_ienumerator_type;
461 static public TypeSpec generic_ienumerable_type;
462 static public TypeSpec generic_nullable_type;
463 static internal TypeSpec expression_type;
466 // These methods are called by code generated by the compiler
468 static public FieldSpec string_empty;
469 static public MethodSpec system_type_get_type_from_handle;
470 static public MethodSpec bool_movenext_void;
471 static public MethodSpec void_dispose_void;
472 static public MethodSpec void_monitor_enter_object;
473 static public MethodSpec void_monitor_exit_object;
474 static public MethodSpec void_initializearray_array_fieldhandle;
475 static public MethodSpec delegate_combine_delegate_delegate;
476 static public MethodSpec delegate_remove_delegate_delegate;
477 static public PropertySpec int_get_offset_to_string_data;
478 static public MethodSpec int_interlocked_compare_exchange;
479 public static MethodSpec gen_interlocked_compare_exchange;
480 static public PropertySpec ienumerator_getcurrent;
481 public static MethodSpec methodbase_get_type_from_handle;
482 public static MethodSpec methodbase_get_type_from_handle_generic;
483 public static MethodSpec fieldinfo_get_field_from_handle;
484 public static MethodSpec fieldinfo_get_field_from_handle_generic;
485 public static MethodSpec activator_create_instance;
490 static public MethodSpec void_decimal_ctor_five_args;
491 static public MethodSpec void_decimal_ctor_int_arg;
492 public static MethodSpec void_decimal_ctor_long_arg;
494 static TypeManager ()
499 static public void Reset ()
501 // object_type = null;
503 // TODO: I am really bored by all this static stuff
504 system_type_get_type_from_handle =
507 void_monitor_enter_object =
508 void_monitor_exit_object =
509 void_initializearray_array_fieldhandle =
510 int_interlocked_compare_exchange =
511 gen_interlocked_compare_exchange =
512 methodbase_get_type_from_handle =
513 methodbase_get_type_from_handle_generic =
514 fieldinfo_get_field_from_handle =
515 fieldinfo_get_field_from_handle_generic =
516 activator_create_instance =
517 delegate_combine_delegate_delegate =
518 delegate_remove_delegate_delegate = null;
520 int_get_offset_to_string_data =
521 ienumerator_getcurrent = null;
523 void_decimal_ctor_five_args =
524 void_decimal_ctor_int_arg =
525 void_decimal_ctor_long_arg = null;
529 typed_reference_type = arg_iterator_type = mbr_type =
530 generic_ilist_type = generic_icollection_type = generic_ienumerator_type =
531 generic_ienumerable_type = generic_nullable_type = expression_type = null;
535 /// Returns the C# name of a type if possible, or the full type name otherwise
537 static public string CSharpName (TypeSpec t)
539 return t.GetSignatureForError ();
542 static public string CSharpName (IList<TypeSpec> types)
544 if (types.Count == 0)
547 StringBuilder sb = new StringBuilder ();
548 for (int i = 0; i < types.Count; ++i) {
552 sb.Append (CSharpName (types [i]));
554 return sb.ToString ();
557 static public string GetFullNameSignature (MemberSpec mi)
559 return mi.GetSignatureForError ();
562 static public string CSharpSignature (MemberSpec mb)
564 return mb.GetSignatureForError ();
567 static MemberSpec GetPredefinedMember (TypeSpec t, MemberFilter filter, bool optional, Location loc)
569 var member = MemberCache.FindMember (t, filter, BindingRestriction.DeclaredOnly);
571 if (member != null && member.IsAccessible (InternalType.FakeInternalType))
577 string method_args = null;
578 if (filter.Parameters != null)
579 method_args = filter.Parameters.GetSignatureForError ();
581 RootContext.ToplevelTypes.Compiler.Report.Error (656, loc, "The compiler required member `{0}.{1}{2}' could not be found or is inaccessible",
582 TypeManager.CSharpName (t), filter.Name, method_args);
588 // Returns the ConstructorInfo for "args"
590 public static MethodSpec GetPredefinedConstructor (TypeSpec t, Location loc, params TypeSpec [] args)
592 var pc = ParametersCompiled.CreateFullyResolved (args);
593 return GetPredefinedMember (t, MemberFilter.Constructor (pc), false, loc) as MethodSpec;
597 // Returns the method specification for a method named `name' defined
598 // in type `t' which takes arguments of types `args'
600 public static MethodSpec GetPredefinedMethod (TypeSpec t, string name, Location loc, params TypeSpec [] args)
602 var pc = ParametersCompiled.CreateFullyResolved (args);
603 return GetPredefinedMethod (t, MemberFilter.Method (name, 0, pc, null), false, loc);
606 public static MethodSpec GetPredefinedMethod (TypeSpec t, MemberFilter filter, Location loc)
608 return GetPredefinedMethod (t, filter, false, loc);
611 public static MethodSpec GetPredefinedMethod (TypeSpec t, MemberFilter filter, bool optional, Location loc)
613 return GetPredefinedMember (t, filter, optional, loc) as MethodSpec;
616 public static FieldSpec GetPredefinedField (TypeSpec t, string name, Location loc, TypeSpec type)
618 return GetPredefinedMember (t, MemberFilter.Field (name, type), false, loc) as FieldSpec;
621 public static PropertySpec GetPredefinedProperty (TypeSpec t, string name, Location loc, TypeSpec type)
623 return GetPredefinedMember (t, MemberFilter.Property (name, type), false, loc) as PropertySpec;
626 public static bool IsBuiltinType (TypeSpec t)
628 if (t == object_type || t == string_type || t == int32_type || t == uint32_type ||
629 t == int64_type || t == uint64_type || t == float_type || t == double_type ||
630 t == char_type || t == short_type || t == decimal_type || t == bool_type ||
631 t == sbyte_type || t == byte_type || t == ushort_type || t == void_type)
638 // This is like IsBuiltinType, but lacks decimal_type, we should also clean up
639 // the pieces in the code where we use IsBuiltinType and special case decimal_type.
641 public static bool IsPrimitiveType (TypeSpec t)
643 return (t == int32_type || t == uint32_type ||
644 t == int64_type || t == uint64_type || t == float_type || t == double_type ||
645 t == char_type || t == short_type || t == bool_type ||
646 t == sbyte_type || t == byte_type || t == ushort_type);
650 public static bool IsDelegateType (TypeSpec t)
656 public static bool IsEnumType (TypeSpec t)
661 public static bool IsBuiltinOrEnum (TypeSpec t)
663 if (IsBuiltinType (t))
673 // Whether a type is unmanaged. This is used by the unsafe code (25.2)
675 public static bool IsUnmanagedType (TypeSpec t)
677 var ds = t.MemberDefinition as DeclSpace;
679 return ds.IsUnmanagedType ();
681 // some builtins that are not unmanaged types
682 if (t == TypeManager.object_type || t == TypeManager.string_type)
685 if (IsBuiltinOrEnum (t))
688 // Someone did the work of checking if the ElementType of t is unmanaged. Let's not repeat it.
690 return IsUnmanagedType (GetElementType (t));
692 if (!IsValueType (t))
695 if (t.IsNested && t.DeclaringType.IsGenericOrParentIsGeneric)
702 // Null is considered to be a reference type
704 public static bool IsReferenceType (TypeSpec t)
706 if (t.IsGenericParameter)
707 return ((TypeParameterSpec) t).IsReferenceType;
709 return !t.IsStruct && !IsEnumType (t);
712 public static bool IsValueType (TypeSpec t)
714 if (t.IsGenericParameter)
715 return ((TypeParameterSpec) t).IsValueType;
717 return t.IsStruct || IsEnumType (t);
720 public static bool IsStruct (TypeSpec t)
725 public static bool IsFamilyAccessible (TypeSpec type, TypeSpec parent)
727 // TypeParameter tparam = LookupTypeParameter (type);
728 // TypeParameter pparam = LookupTypeParameter (parent);
730 if (type.Kind == MemberKind.TypeParameter && parent.Kind == MemberKind.TypeParameter) { // (tparam != null) && (pparam != null)) {
734 throw new NotImplementedException ("net");
735 // return tparam.IsSubclassOf (parent);
739 if (IsInstantiationOfSameGenericType (type, parent))
742 type = type.BaseType;
743 } while (type != null);
749 // Checks whether `type' is a subclass or nested child of `base_type'.
751 public static bool IsNestedFamilyAccessible (TypeSpec type, TypeSpec base_type)
754 if (IsFamilyAccessible (type, base_type))
757 // Handle nested types.
758 type = type.DeclaringType;
759 } while (type != null);
765 // Checks whether `type' is a nested child of `parent'.
767 public static bool IsNestedChildOf (TypeSpec type, ITypeDefinition parent)
772 if (type.MemberDefinition == parent)
775 type = type.DeclaringType;
776 while (type != null) {
777 if (type.MemberDefinition == parent)
780 type = type.DeclaringType;
786 public static bool IsSpecialType (TypeSpec t)
788 return t == arg_iterator_type || t == typed_reference_type;
791 public static TypeSpec GetElementType (TypeSpec t)
793 return ((ElementTypeSpec)t).Element;
797 /// This method is not implemented by MS runtime for dynamic types
799 public static bool HasElementType (TypeSpec t)
801 return t is ElementTypeSpec;
804 static NumberFormatInfo nf_provider = CultureInfo.CurrentCulture.NumberFormat;
806 // This is a custom version of Convert.ChangeType() which works
807 // with the TypeBuilder defined types when compiling corlib.
808 public static object ChangeType (object value, TypeSpec targetType, out bool error)
810 IConvertible convert_value = value as IConvertible;
812 if (convert_value == null){
818 // We cannot rely on build-in type conversions as they are
819 // more limited than what C# supports.
820 // See char -> float/decimal/double conversion
824 if (targetType == TypeManager.bool_type)
825 return convert_value.ToBoolean (nf_provider);
826 if (targetType == TypeManager.byte_type)
827 return convert_value.ToByte (nf_provider);
828 if (targetType == TypeManager.char_type)
829 return convert_value.ToChar (nf_provider);
830 if (targetType == TypeManager.short_type)
831 return convert_value.ToInt16 (nf_provider);
832 if (targetType == TypeManager.int32_type)
833 return convert_value.ToInt32 (nf_provider);
834 if (targetType == TypeManager.int64_type)
835 return convert_value.ToInt64 (nf_provider);
836 if (targetType == TypeManager.sbyte_type)
837 return convert_value.ToSByte (nf_provider);
839 if (targetType == TypeManager.decimal_type) {
840 if (convert_value.GetType () == typeof (char))
841 return (decimal) convert_value.ToInt32 (nf_provider);
842 return convert_value.ToDecimal (nf_provider);
845 if (targetType == TypeManager.double_type) {
846 if (convert_value.GetType () == typeof (char))
847 return (double) convert_value.ToInt32 (nf_provider);
848 return convert_value.ToDouble (nf_provider);
851 if (targetType == TypeManager.float_type) {
852 if (convert_value.GetType () == typeof (char))
853 return (float)convert_value.ToInt32 (nf_provider);
854 return convert_value.ToSingle (nf_provider);
857 if (targetType == TypeManager.string_type)
858 return convert_value.ToString (nf_provider);
859 if (targetType == TypeManager.ushort_type)
860 return convert_value.ToUInt16 (nf_provider);
861 if (targetType == TypeManager.uint32_type)
862 return convert_value.ToUInt32 (nf_provider);
863 if (targetType == TypeManager.uint64_type)
864 return convert_value.ToUInt64 (nf_provider);
865 if (targetType == TypeManager.object_type)
876 /// Utility function that can be used to probe whether a type
877 /// is managed or not.
879 public static bool VerifyUnmanaged (ModuleContainer rc, TypeSpec t, Location loc)
882 t = GetElementType (t);
884 if (IsUnmanagedType (t))
887 rc.Compiler.Report.SymbolRelatedToPreviousError (t);
888 rc.Compiler.Report.Error (208, loc,
889 "Cannot take the address of, get the size of, or declare a pointer to a managed type `{0}'",
895 // This method always return false for non-generic compiler,
896 // while Type.IsGenericParameter is returned if it is supported.
897 public static bool IsGenericParameter (TypeSpec type)
899 return type.IsGenericParameter;
902 public static bool IsGenericType (TypeSpec type)
904 return type.IsGeneric;
907 public static TypeSpec[] GetTypeArguments (TypeSpec t)
909 // TODO: return empty array !!
910 return t.TypeArguments;
914 /// Check whether `type' and `parent' are both instantiations of the same
915 /// generic type. Note that we do not check the type parameters here.
917 public static bool IsInstantiationOfSameGenericType (TypeSpec type, TypeSpec parent)
919 return type == parent || type.MemberDefinition == parent.MemberDefinition;
922 public static bool IsNullableType (TypeSpec t)
924 return generic_nullable_type == t.GetDefinition ();