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;
60 readonly BuildinTypeSpec[] types;
62 public BuildinTypes ()
64 Object = new BuildinTypeSpec (MemberKind.Class, "System", "Object", BuildinTypeSpec.Type.Object);
65 ValueType = new BuildinTypeSpec (MemberKind.Class, "System", "ValueType", BuildinTypeSpec.Type.ValueType);
66 Attribute = new BuildinTypeSpec (MemberKind.Class, "System", "Attribute", BuildinTypeSpec.Type.Attribute);
68 Int = new BuildinTypeSpec (MemberKind.Struct, "System", "Int32", BuildinTypeSpec.Type.Int);
69 Long = new BuildinTypeSpec (MemberKind.Struct, "System", "Int64", BuildinTypeSpec.Type.Long);
70 UInt = new BuildinTypeSpec (MemberKind.Struct, "System", "UInt32", BuildinTypeSpec.Type.UInt);
71 ULong = new BuildinTypeSpec (MemberKind.Struct, "System", "UInt64", BuildinTypeSpec.Type.ULong);
72 Byte = new BuildinTypeSpec (MemberKind.Struct, "System", "Byte", BuildinTypeSpec.Type.Byte);
73 SByte = new BuildinTypeSpec (MemberKind.Struct, "System", "SByte", BuildinTypeSpec.Type.SByte);
74 Short = new BuildinTypeSpec (MemberKind.Struct, "System", "Int16", BuildinTypeSpec.Type.Short);
75 UShort = new BuildinTypeSpec (MemberKind.Struct, "System", "UInt16", BuildinTypeSpec.Type.UShort);
77 IEnumerator = new BuildinTypeSpec (MemberKind.Interface, "System.Collections", "IEnumerator", BuildinTypeSpec.Type.IEnumerator);
78 IEnumerable = new BuildinTypeSpec (MemberKind.Interface, "System.Collections", "IEnumerable", BuildinTypeSpec.Type.IEnumerable);
79 IDisposable = new BuildinTypeSpec (MemberKind.Interface, "System", "IDisposable", BuildinTypeSpec.Type.IDisposable);
81 Char = new BuildinTypeSpec (MemberKind.Struct, "System", "Char", BuildinTypeSpec.Type.Char);
82 String = new BuildinTypeSpec (MemberKind.Class, "System", "String", BuildinTypeSpec.Type.String);
83 Float = new BuildinTypeSpec (MemberKind.Struct, "System", "Single", BuildinTypeSpec.Type.Float);
84 Double = new BuildinTypeSpec (MemberKind.Struct, "System", "Double", BuildinTypeSpec.Type.Double);
85 Decimal = new BuildinTypeSpec (MemberKind.Struct, "System", "Decimal", BuildinTypeSpec.Type.Decimal);
86 Bool = new BuildinTypeSpec (MemberKind.Struct, "System", "Boolean", BuildinTypeSpec.Type.Bool);
87 IntPtr = new BuildinTypeSpec (MemberKind.Struct, "System", "IntPtr", BuildinTypeSpec.Type.IntPtr);
88 UIntPtr = new BuildinTypeSpec (MemberKind.Struct, "System", "UIntPtr", BuildinTypeSpec.Type.UIntPtr);
90 MulticastDelegate = new BuildinTypeSpec (MemberKind.Class, "System", "MulticastDelegate", BuildinTypeSpec.Type.MulticastDelegate);
91 Delegate = new BuildinTypeSpec (MemberKind.Class, "System", "Delegate", BuildinTypeSpec.Type.Delegate);
92 Enum = new BuildinTypeSpec (MemberKind.Class, "System", "Enum", BuildinTypeSpec.Type.Enum);
93 Array = new BuildinTypeSpec (MemberKind.Class, "System", "Array", BuildinTypeSpec.Type.Array);
94 Void = new BuildinTypeSpec (MemberKind.Struct, "System", "Void", BuildinTypeSpec.Type.Void);
95 Type = new BuildinTypeSpec (MemberKind.Class, "System", "Type", BuildinTypeSpec.Type.Type);
96 Exception = new BuildinTypeSpec (MemberKind.Class, "System", "Exception", BuildinTypeSpec.Type.Exception);
97 RuntimeFieldHandle = new BuildinTypeSpec (MemberKind.Struct, "System", "RuntimeFieldHandle", BuildinTypeSpec.Type.RuntimeFieldHandle);
98 RuntimeTypeHandle = new BuildinTypeSpec (MemberKind.Struct, "System", "RuntimeTypeHandle", BuildinTypeSpec.Type.RuntimeTypeHandle);
100 types = new BuildinTypeSpec[] {
101 Object, ValueType, Attribute,
102 Int, UInt, Long, ULong, Float, Double, Char, Short, Decimal, Bool, SByte, Byte, UShort, String,
103 Enum, Delegate, MulticastDelegate, Void, Array, Type, IEnumerator, IEnumerable, IDisposable,
104 IntPtr, UIntPtr, RuntimeFieldHandle, RuntimeTypeHandle, Exception };
106 // Deal with obsolete static types
108 TypeManager.object_type = Object;
109 TypeManager.value_type = ValueType;
110 TypeManager.string_type = String;
111 TypeManager.int32_type = Int;
112 TypeManager.uint32_type = UInt;
113 TypeManager.int64_type = Long;
114 TypeManager.uint64_type = ULong;
115 TypeManager.float_type = Float;
116 TypeManager.double_type = Double;
117 TypeManager.char_type = Char;
118 TypeManager.short_type = Short;
119 TypeManager.decimal_type = Decimal;
120 TypeManager.bool_type = Bool;
121 TypeManager.sbyte_type = SByte;
122 TypeManager.byte_type = Byte;
123 TypeManager.ushort_type = UShort;
124 TypeManager.enum_type = Enum;
125 TypeManager.delegate_type = Delegate;
126 TypeManager.multicast_delegate_type = MulticastDelegate; ;
127 TypeManager.void_type = Void;
128 TypeManager.array_type = Array; ;
129 TypeManager.runtime_handle_type = RuntimeTypeHandle;
130 TypeManager.type_type = Type;
131 TypeManager.ienumerator_type = IEnumerator;
132 TypeManager.ienumerable_type = IEnumerable;
133 TypeManager.idisposable_type = IDisposable;
134 TypeManager.intptr_type = IntPtr;
135 TypeManager.uintptr_type = UIntPtr;
136 TypeManager.runtime_field_handle_type = RuntimeFieldHandle;
137 TypeManager.attribute_type = Attribute;
138 TypeManager.exception_type = Exception;
143 public BuildinTypeSpec[] Types {
153 // Compiler predefined types. Usually used for compiler generated
154 // code or for comparison against well known framework type
156 class PredefinedTypes
158 // TODO: These two exist only to reject type comparison
159 public readonly PredefinedType TypedReference;
160 public readonly PredefinedType ArgIterator;
162 public readonly PredefinedType MarshalByRefObject;
163 public readonly PredefinedType RuntimeHelpers;
164 public readonly PredefinedType IAsyncResult;
165 public readonly PredefinedType AsyncCallback;
166 public readonly PredefinedType RuntimeArgumentHandle;
167 public readonly PredefinedType CharSet;
168 public readonly PredefinedType IsVolatile;
169 public readonly PredefinedType IEnumeratorGeneric;
170 public readonly PredefinedType IListGeneric;
171 public readonly PredefinedType ICollectionGeneric;
172 public readonly PredefinedType IEnumerableGeneric;
173 public readonly PredefinedType Nullable;
174 public readonly PredefinedType Activator;
175 public readonly PredefinedType Interlocked;
176 public readonly PredefinedType Monitor;
177 public readonly PredefinedType NotSupportedException;
178 public readonly PredefinedType RuntimeFieldHandle;
179 public readonly PredefinedType RuntimeMethodHandle;
184 public readonly PredefinedType Expression;
185 public readonly PredefinedType ExpressionGeneric;
186 public readonly PredefinedType ParameterExpression;
187 public readonly PredefinedType FieldInfo;
188 public readonly PredefinedType MethodBase;
189 public readonly PredefinedType MethodInfo;
190 public readonly PredefinedType ConstructorInfo;
195 public readonly PredefinedType Binder;
196 public readonly PredefinedType CallSite;
197 public readonly PredefinedType CallSiteGeneric;
198 public readonly PredefinedType BinderFlags;
200 public PredefinedTypes (ModuleContainer module)
202 TypedReference = new PredefinedType (module, MemberKind.Struct, "System", "TypedReference");
203 ArgIterator = new PredefinedType (module, MemberKind.Struct, "System", "ArgIterator");
204 MarshalByRefObject = new PredefinedType (module, MemberKind.Class, "System", "MarshalByRefObject");
205 RuntimeHelpers = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "RuntimeHelpers");
206 IAsyncResult = new PredefinedType (module, MemberKind.Interface, "System", "IAsyncResult");
207 AsyncCallback = new PredefinedType (module, MemberKind.Delegate, "System", "AsyncCallback");
208 RuntimeArgumentHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeArgumentHandle");
209 CharSet = new PredefinedType (module, MemberKind.Enum, "System.Runtime.InteropServices", "CharSet");
210 IsVolatile = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "IsVolatile");
211 IEnumeratorGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IEnumerator", 1);
212 IListGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IList", 1);
213 ICollectionGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "ICollection", 1);
214 IEnumerableGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IEnumerable", 1);
215 Nullable = new PredefinedType (module, MemberKind.Struct, "System", "Nullable", 1);
216 Activator = new PredefinedType (module, MemberKind.Class, "System", "Activator");
217 Interlocked = new PredefinedType (module, MemberKind.Class, "System.Threading", "Interlocked");
218 Monitor = new PredefinedType (module, MemberKind.Class, "System.Threading", "Monitor");
219 NotSupportedException = new PredefinedType (module, MemberKind.Class, "System", "NotSupportedException");
220 RuntimeFieldHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeFieldHandle");
221 RuntimeMethodHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeMethodHandle");
223 Expression = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "Expression");
224 ExpressionGeneric = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "Expression", 1);
225 ParameterExpression = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "ParameterExpression");
226 FieldInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "FieldInfo");
227 MethodBase = new PredefinedType (module, MemberKind.Class, "System.Reflection", "MethodBase");
228 MethodInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "MethodInfo");
229 ConstructorInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "ConstructorInfo");
231 CallSite = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "CallSite");
232 CallSiteGeneric = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "CallSite", 1);
233 Binder = new PredefinedType (module, MemberKind.Class, "Microsoft.CSharp.RuntimeBinder", "Binder");
234 BinderFlags = new PredefinedType (module, MemberKind.Enum, "Microsoft.CSharp.RuntimeBinder", "CSharpBinderFlags");
237 // Define types which are used for comparison. It does not matter
238 // if they don't exist as no error report is needed
240 TypedReference.Define ();
241 ArgIterator.Define ();
242 MarshalByRefObject.Define ();
245 IEnumerableGeneric.Define ();
246 IListGeneric.Define ();
247 ICollectionGeneric.Define ();
248 IEnumerableGeneric.Define ();
249 IEnumeratorGeneric.Define ();
251 ExpressionGeneric.Define ();
253 // Deal with obsolete static types
255 TypeManager.typed_reference_type = TypedReference.TypeSpec;
256 TypeManager.arg_iterator_type = ArgIterator.TypeSpec;
257 TypeManager.mbr_type = MarshalByRefObject.TypeSpec;
258 TypeManager.generic_ilist_type = IListGeneric.TypeSpec;
259 TypeManager.generic_icollection_type = ICollectionGeneric.TypeSpec;
260 TypeManager.generic_ienumerator_type = IEnumeratorGeneric.TypeSpec;
261 TypeManager.generic_ienumerable_type = IEnumerableGeneric.TypeSpec;
262 TypeManager.generic_nullable_type = Nullable.TypeSpec;
263 TypeManager.expression_type = ExpressionGeneric.TypeSpec;
267 public class PredefinedType
273 ModuleContainer module;
274 protected TypeSpec type;
276 public PredefinedType (ModuleContainer module, MemberKind kind, string ns, string name, int arity)
277 : this (module, kind, ns, name)
282 public PredefinedType (ModuleContainer module, MemberKind kind, string ns, string name)
284 this.module = module;
298 public bool IsDefined {
310 public string Namespace {
316 public TypeSpec TypeSpec {
324 public bool Define ()
329 Namespace type_ns = module.GlobalRootNamespace.GetNamespace (ns, true);
330 var te = type_ns.LookupType (module.Compiler, name, arity, true, Location.Null);
334 if (te.Type.Kind != kind)
341 public string GetSignatureForError ()
343 return ns + "." + name;
346 public static TypeSpec Resolve (ModuleContainer module, MemberKind kind, string ns, string name, int arity, Location loc)
348 Namespace type_ns = module.GlobalRootNamespace.GetNamespace (ns, true);
349 var te = type_ns.LookupType (module.Compiler, name, arity, false, Location.Null);
351 module.Compiler.Report.Error (518, loc, "The predefined type `{0}.{1}' is not defined or imported", ns, name);
356 if (type.Kind != kind) {
357 module.Compiler.Report.Error (520, loc, "The predefined type `{0}.{1}' is not declared correctly", ns, name);
364 public TypeSpec Resolve (Location loc)
367 type = Resolve (module, kind, ns, name, arity, loc);
373 partial class TypeManager {
375 // A list of core types that the compiler requires or uses
377 static public BuildinTypeSpec object_type;
378 static public BuildinTypeSpec value_type;
379 static public BuildinTypeSpec string_type;
380 static public BuildinTypeSpec int32_type;
381 static public BuildinTypeSpec uint32_type;
382 static public BuildinTypeSpec int64_type;
383 static public BuildinTypeSpec uint64_type;
384 static public BuildinTypeSpec float_type;
385 static public BuildinTypeSpec double_type;
386 static public BuildinTypeSpec char_type;
387 static public BuildinTypeSpec short_type;
388 static public BuildinTypeSpec decimal_type;
389 static public BuildinTypeSpec bool_type;
390 static public BuildinTypeSpec sbyte_type;
391 static public BuildinTypeSpec byte_type;
392 static public BuildinTypeSpec ushort_type;
393 static public BuildinTypeSpec enum_type;
394 static public BuildinTypeSpec delegate_type;
395 static public BuildinTypeSpec multicast_delegate_type;
396 static public BuildinTypeSpec void_type;
397 static public BuildinTypeSpec array_type;
398 static public BuildinTypeSpec runtime_handle_type;
399 static public BuildinTypeSpec type_type;
400 static public BuildinTypeSpec ienumerator_type;
401 static public BuildinTypeSpec ienumerable_type;
402 static public BuildinTypeSpec idisposable_type;
403 static public BuildinTypeSpec intptr_type;
404 static public BuildinTypeSpec uintptr_type;
405 static public BuildinTypeSpec runtime_field_handle_type;
406 static public BuildinTypeSpec attribute_type;
407 static public BuildinTypeSpec exception_type;
410 static public TypeSpec typed_reference_type;
411 static public TypeSpec arg_iterator_type;
412 static public TypeSpec mbr_type;
413 static public TypeSpec generic_ilist_type;
414 static public TypeSpec generic_icollection_type;
415 static public TypeSpec generic_ienumerator_type;
416 static public TypeSpec generic_ienumerable_type;
417 static public TypeSpec generic_nullable_type;
418 static internal TypeSpec expression_type;
421 // These methods are called by code generated by the compiler
423 static public FieldSpec string_empty;
424 static public MethodSpec system_type_get_type_from_handle;
425 static public MethodSpec bool_movenext_void;
426 static public MethodSpec void_dispose_void;
427 static public MethodSpec void_monitor_enter_object;
428 static public MethodSpec void_monitor_exit_object;
429 static public MethodSpec void_initializearray_array_fieldhandle;
430 static public MethodSpec delegate_combine_delegate_delegate;
431 static public MethodSpec delegate_remove_delegate_delegate;
432 static public PropertySpec int_get_offset_to_string_data;
433 static public MethodSpec int_interlocked_compare_exchange;
434 public static MethodSpec gen_interlocked_compare_exchange;
435 static public PropertySpec ienumerator_getcurrent;
436 public static MethodSpec methodbase_get_type_from_handle;
437 public static MethodSpec methodbase_get_type_from_handle_generic;
438 public static MethodSpec fieldinfo_get_field_from_handle;
439 public static MethodSpec fieldinfo_get_field_from_handle_generic;
440 public static MethodSpec activator_create_instance;
445 static public MethodSpec void_decimal_ctor_five_args;
446 static public MethodSpec void_decimal_ctor_int_arg;
447 public static MethodSpec void_decimal_ctor_long_arg;
449 static TypeManager ()
454 static public void Reset ()
456 // object_type = null;
458 // TODO: I am really bored by all this static stuff
459 system_type_get_type_from_handle =
462 void_monitor_enter_object =
463 void_monitor_exit_object =
464 void_initializearray_array_fieldhandle =
465 int_interlocked_compare_exchange =
466 gen_interlocked_compare_exchange =
467 methodbase_get_type_from_handle =
468 methodbase_get_type_from_handle_generic =
469 fieldinfo_get_field_from_handle =
470 fieldinfo_get_field_from_handle_generic =
471 activator_create_instance =
472 delegate_combine_delegate_delegate =
473 delegate_remove_delegate_delegate = null;
475 int_get_offset_to_string_data =
476 ienumerator_getcurrent = null;
478 void_decimal_ctor_five_args =
479 void_decimal_ctor_int_arg =
480 void_decimal_ctor_long_arg = null;
484 typed_reference_type = arg_iterator_type = mbr_type =
485 generic_ilist_type = generic_icollection_type = generic_ienumerator_type =
486 generic_ienumerable_type = generic_nullable_type = expression_type = null;
490 /// Returns the C# name of a type if possible, or the full type name otherwise
492 static public string CSharpName (TypeSpec t)
494 return t.GetSignatureForError ();
497 static public string CSharpName (IList<TypeSpec> types)
499 if (types.Count == 0)
502 StringBuilder sb = new StringBuilder ();
503 for (int i = 0; i < types.Count; ++i) {
507 sb.Append (CSharpName (types [i]));
509 return sb.ToString ();
512 static public string GetFullNameSignature (MemberSpec mi)
514 return mi.GetSignatureForError ();
517 static public string CSharpSignature (MemberSpec mb)
519 return mb.GetSignatureForError ();
522 static MemberSpec GetPredefinedMember (TypeSpec t, MemberFilter filter, bool optional, Location loc)
524 var member = MemberCache.FindMember (t, filter, BindingRestriction.DeclaredOnly);
526 if (member != null && member.IsAccessible (InternalType.FakeInternalType))
532 string method_args = null;
533 if (filter.Parameters != null)
534 method_args = filter.Parameters.GetSignatureForError ();
536 RootContext.ToplevelTypes.Compiler.Report.Error (656, loc, "The compiler required member `{0}.{1}{2}' could not be found or is inaccessible",
537 TypeManager.CSharpName (t), filter.Name, method_args);
543 // Returns the ConstructorInfo for "args"
545 public static MethodSpec GetPredefinedConstructor (TypeSpec t, Location loc, params TypeSpec [] args)
547 var pc = ParametersCompiled.CreateFullyResolved (args);
548 return GetPredefinedMember (t, MemberFilter.Constructor (pc), false, loc) as MethodSpec;
552 // Returns the method specification for a method named `name' defined
553 // in type `t' which takes arguments of types `args'
555 public static MethodSpec GetPredefinedMethod (TypeSpec t, string name, Location loc, params TypeSpec [] args)
557 var pc = ParametersCompiled.CreateFullyResolved (args);
558 return GetPredefinedMethod (t, MemberFilter.Method (name, 0, pc, null), false, loc);
561 public static MethodSpec GetPredefinedMethod (TypeSpec t, MemberFilter filter, Location loc)
563 return GetPredefinedMethod (t, filter, false, loc);
566 public static MethodSpec GetPredefinedMethod (TypeSpec t, MemberFilter filter, bool optional, Location loc)
568 return GetPredefinedMember (t, filter, optional, loc) as MethodSpec;
571 public static FieldSpec GetPredefinedField (TypeSpec t, string name, Location loc, TypeSpec type)
573 return GetPredefinedMember (t, MemberFilter.Field (name, type), false, loc) as FieldSpec;
576 public static PropertySpec GetPredefinedProperty (TypeSpec t, string name, Location loc, TypeSpec type)
578 return GetPredefinedMember (t, MemberFilter.Property (name, type), false, loc) as PropertySpec;
582 /// The types have to be initialized after the initial
583 /// population of the type has happened (for example, to
584 /// bootstrap the corlib.dll
586 public static bool InitCoreTypes (ModuleContainer module, BuildinTypes buildin)
588 var ctx = module.Compiler;
589 foreach (var p in buildin.Types) {
590 var found = PredefinedType.Resolve (module, p.Kind, p.Namespace, p.Name, p.Arity, Location.Null);
591 if (found == null || found == p)
594 if (!RootContext.StdLib) {
595 var ns = module.GlobalRootNamespace.GetNamespace (p.Namespace, false);
596 ns.ReplaceTypeWithPredefined (found, p);
598 var tc = found.MemberDefinition as TypeContainer;
599 tc.SetPredefinedSpec (p);
600 p.SetDefinition (found);
604 if (InternalType.Dynamic.GetMetaInfo () == null) {
605 InternalType.Dynamic.SetMetaInfo (object_type.GetMetaInfo ());
607 if (object_type.MemberDefinition.IsImported)
608 InternalType.Dynamic.MemberCache = object_type.MemberCache;
610 InternalType.Null.SetMetaInfo (object_type.GetMetaInfo ());
613 return ctx.Report.Errors == 0;
616 public static bool IsBuiltinType (TypeSpec t)
618 if (t == object_type || t == string_type || t == int32_type || t == uint32_type ||
619 t == int64_type || t == uint64_type || t == float_type || t == double_type ||
620 t == char_type || t == short_type || t == decimal_type || t == bool_type ||
621 t == sbyte_type || t == byte_type || t == ushort_type || t == void_type)
628 // This is like IsBuiltinType, but lacks decimal_type, we should also clean up
629 // the pieces in the code where we use IsBuiltinType and special case decimal_type.
631 public static bool IsPrimitiveType (TypeSpec t)
633 return (t == int32_type || t == uint32_type ||
634 t == int64_type || t == uint64_type || t == float_type || t == double_type ||
635 t == char_type || t == short_type || t == bool_type ||
636 t == sbyte_type || t == byte_type || t == ushort_type);
640 public static bool IsDelegateType (TypeSpec t)
646 public static bool IsEnumType (TypeSpec t)
651 public static bool IsBuiltinOrEnum (TypeSpec t)
653 if (IsBuiltinType (t))
663 // Whether a type is unmanaged. This is used by the unsafe code (25.2)
665 public static bool IsUnmanagedType (TypeSpec t)
667 var ds = t.MemberDefinition as DeclSpace;
669 return ds.IsUnmanagedType ();
671 // some builtins that are not unmanaged types
672 if (t == TypeManager.object_type || t == TypeManager.string_type)
675 if (IsBuiltinOrEnum (t))
678 // Someone did the work of checking if the ElementType of t is unmanaged. Let's not repeat it.
680 return IsUnmanagedType (GetElementType (t));
682 if (!IsValueType (t))
685 if (t.IsNested && t.DeclaringType.IsGenericOrParentIsGeneric)
692 // Null is considered to be a reference type
694 public static bool IsReferenceType (TypeSpec t)
696 if (t.IsGenericParameter)
697 return ((TypeParameterSpec) t).IsReferenceType;
699 return !t.IsStruct && !IsEnumType (t);
702 public static bool IsValueType (TypeSpec t)
704 if (t.IsGenericParameter)
705 return ((TypeParameterSpec) t).IsValueType;
707 return t.IsStruct || IsEnumType (t);
710 public static bool IsStruct (TypeSpec t)
715 public static bool IsFamilyAccessible (TypeSpec type, TypeSpec parent)
717 // TypeParameter tparam = LookupTypeParameter (type);
718 // TypeParameter pparam = LookupTypeParameter (parent);
720 if (type.Kind == MemberKind.TypeParameter && parent.Kind == MemberKind.TypeParameter) { // (tparam != null) && (pparam != null)) {
724 throw new NotImplementedException ("net");
725 // return tparam.IsSubclassOf (parent);
729 if (IsInstantiationOfSameGenericType (type, parent))
732 type = type.BaseType;
733 } while (type != null);
739 // Checks whether `type' is a subclass or nested child of `base_type'.
741 public static bool IsNestedFamilyAccessible (TypeSpec type, TypeSpec base_type)
744 if (IsFamilyAccessible (type, base_type))
747 // Handle nested types.
748 type = type.DeclaringType;
749 } while (type != null);
755 // Checks whether `type' is a nested child of `parent'.
757 public static bool IsNestedChildOf (TypeSpec type, TypeSpec parent)
762 type = type.GetDefinition (); // DropGenericTypeArguments (type);
763 parent = parent.GetDefinition (); // DropGenericTypeArguments (parent);
768 type = type.DeclaringType;
769 while (type != null) {
770 if (type.GetDefinition () == parent)
773 type = type.DeclaringType;
779 public static bool IsSpecialType (TypeSpec t)
781 return t == arg_iterator_type || t == typed_reference_type;
784 public static TypeSpec GetElementType (TypeSpec t)
786 return ((ElementTypeSpec)t).Element;
790 /// This method is not implemented by MS runtime for dynamic types
792 public static bool HasElementType (TypeSpec t)
794 return t is ElementTypeSpec;
797 static NumberFormatInfo nf_provider = CultureInfo.CurrentCulture.NumberFormat;
799 // This is a custom version of Convert.ChangeType() which works
800 // with the TypeBuilder defined types when compiling corlib.
801 public static object ChangeType (object value, TypeSpec targetType, out bool error)
803 IConvertible convert_value = value as IConvertible;
805 if (convert_value == null){
811 // We cannot rely on build-in type conversions as they are
812 // more limited than what C# supports.
813 // See char -> float/decimal/double conversion
817 if (targetType == TypeManager.bool_type)
818 return convert_value.ToBoolean (nf_provider);
819 if (targetType == TypeManager.byte_type)
820 return convert_value.ToByte (nf_provider);
821 if (targetType == TypeManager.char_type)
822 return convert_value.ToChar (nf_provider);
823 if (targetType == TypeManager.short_type)
824 return convert_value.ToInt16 (nf_provider);
825 if (targetType == TypeManager.int32_type)
826 return convert_value.ToInt32 (nf_provider);
827 if (targetType == TypeManager.int64_type)
828 return convert_value.ToInt64 (nf_provider);
829 if (targetType == TypeManager.sbyte_type)
830 return convert_value.ToSByte (nf_provider);
832 if (targetType == TypeManager.decimal_type) {
833 if (convert_value.GetType () == typeof (char))
834 return (decimal) convert_value.ToInt32 (nf_provider);
835 return convert_value.ToDecimal (nf_provider);
838 if (targetType == TypeManager.double_type) {
839 if (convert_value.GetType () == typeof (char))
840 return (double) convert_value.ToInt32 (nf_provider);
841 return convert_value.ToDouble (nf_provider);
844 if (targetType == TypeManager.float_type) {
845 if (convert_value.GetType () == typeof (char))
846 return (float)convert_value.ToInt32 (nf_provider);
847 return convert_value.ToSingle (nf_provider);
850 if (targetType == TypeManager.string_type)
851 return convert_value.ToString (nf_provider);
852 if (targetType == TypeManager.ushort_type)
853 return convert_value.ToUInt16 (nf_provider);
854 if (targetType == TypeManager.uint32_type)
855 return convert_value.ToUInt32 (nf_provider);
856 if (targetType == TypeManager.uint64_type)
857 return convert_value.ToUInt64 (nf_provider);
858 if (targetType == TypeManager.object_type)
869 /// Utility function that can be used to probe whether a type
870 /// is managed or not.
872 public static bool VerifyUnmanaged (CompilerContext ctx, TypeSpec t, Location loc)
875 t = GetElementType (t);
877 if (IsUnmanagedType (t))
880 ctx.Report.SymbolRelatedToPreviousError (t);
881 ctx.Report.Error (208, loc,
882 "Cannot take the address of, get the size of, or declare a pointer to a managed type `{0}'",
888 // This method always return false for non-generic compiler,
889 // while Type.IsGenericParameter is returned if it is supported.
890 public static bool IsGenericParameter (TypeSpec type)
892 return type.IsGenericParameter;
895 public static bool IsGenericType (TypeSpec type)
897 return type.IsGeneric;
900 // TODO: Implement correctly
901 public static bool ContainsGenericParameters (TypeSpec type)
903 return type.GetMetaInfo ().ContainsGenericParameters;
906 public static TypeSpec[] GetTypeArguments (TypeSpec t)
908 // TODO: return empty array !!
909 return t.TypeArguments;
913 /// Check whether `type' and `parent' are both instantiations of the same
914 /// generic type. Note that we do not check the type parameters here.
916 public static bool IsInstantiationOfSameGenericType (TypeSpec type, TypeSpec parent)
918 return type == parent || type.MemberDefinition == parent.MemberDefinition;
921 public static bool IsNullableType (TypeSpec t)
923 return generic_nullable_type == t.GetDefinition ();