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;
66 // Predefined operators tables
67 public readonly Binary.PredefinedOperator[] OperatorsBinaryStandard;
68 public readonly Binary.PredefinedOperator[] OperatorsBinaryEquality;
69 public readonly Binary.PredefinedOperator[] OperatorsBinaryUnsafe;
70 public readonly TypeSpec[][] OperatorsUnary;
71 public readonly TypeSpec[] OperatorsUnaryMutator;
73 public readonly TypeSpec[] BinaryPromotionsTypes;
74 public readonly TypeSpec[] SwitchUserTypes;
76 readonly BuildinTypeSpec[] types;
78 public BuildinTypes ()
80 Object = new BuildinTypeSpec (MemberKind.Class, "System", "Object", BuildinTypeSpec.Type.Object);
81 ValueType = new BuildinTypeSpec (MemberKind.Class, "System", "ValueType", BuildinTypeSpec.Type.ValueType);
82 Attribute = new BuildinTypeSpec (MemberKind.Class, "System", "Attribute", BuildinTypeSpec.Type.Attribute);
84 Int = new BuildinTypeSpec (MemberKind.Struct, "System", "Int32", BuildinTypeSpec.Type.Int);
85 Long = new BuildinTypeSpec (MemberKind.Struct, "System", "Int64", BuildinTypeSpec.Type.Long);
86 UInt = new BuildinTypeSpec (MemberKind.Struct, "System", "UInt32", BuildinTypeSpec.Type.UInt);
87 ULong = new BuildinTypeSpec (MemberKind.Struct, "System", "UInt64", BuildinTypeSpec.Type.ULong);
88 Byte = new BuildinTypeSpec (MemberKind.Struct, "System", "Byte", BuildinTypeSpec.Type.Byte);
89 SByte = new BuildinTypeSpec (MemberKind.Struct, "System", "SByte", BuildinTypeSpec.Type.SByte);
90 Short = new BuildinTypeSpec (MemberKind.Struct, "System", "Int16", BuildinTypeSpec.Type.Short);
91 UShort = new BuildinTypeSpec (MemberKind.Struct, "System", "UInt16", BuildinTypeSpec.Type.UShort);
93 IEnumerator = new BuildinTypeSpec (MemberKind.Interface, "System.Collections", "IEnumerator", BuildinTypeSpec.Type.IEnumerator);
94 IEnumerable = new BuildinTypeSpec (MemberKind.Interface, "System.Collections", "IEnumerable", BuildinTypeSpec.Type.IEnumerable);
95 IDisposable = new BuildinTypeSpec (MemberKind.Interface, "System", "IDisposable", BuildinTypeSpec.Type.IDisposable);
97 Char = new BuildinTypeSpec (MemberKind.Struct, "System", "Char", BuildinTypeSpec.Type.Char);
98 String = new BuildinTypeSpec (MemberKind.Class, "System", "String", BuildinTypeSpec.Type.String);
99 Float = new BuildinTypeSpec (MemberKind.Struct, "System", "Single", BuildinTypeSpec.Type.Float);
100 Double = new BuildinTypeSpec (MemberKind.Struct, "System", "Double", BuildinTypeSpec.Type.Double);
101 Decimal = new BuildinTypeSpec (MemberKind.Struct, "System", "Decimal", BuildinTypeSpec.Type.Decimal);
102 Bool = new BuildinTypeSpec (MemberKind.Struct, "System", "Boolean", BuildinTypeSpec.Type.Bool);
103 IntPtr = new BuildinTypeSpec (MemberKind.Struct, "System", "IntPtr", BuildinTypeSpec.Type.IntPtr);
104 UIntPtr = new BuildinTypeSpec (MemberKind.Struct, "System", "UIntPtr", BuildinTypeSpec.Type.UIntPtr);
106 MulticastDelegate = new BuildinTypeSpec (MemberKind.Class, "System", "MulticastDelegate", BuildinTypeSpec.Type.MulticastDelegate);
107 Delegate = new BuildinTypeSpec (MemberKind.Class, "System", "Delegate", BuildinTypeSpec.Type.Delegate);
108 Enum = new BuildinTypeSpec (MemberKind.Class, "System", "Enum", BuildinTypeSpec.Type.Enum);
109 Array = new BuildinTypeSpec (MemberKind.Class, "System", "Array", BuildinTypeSpec.Type.Array);
110 Void = new BuildinTypeSpec (MemberKind.Void, "System", "Void", BuildinTypeSpec.Type.Other);
111 Type = new BuildinTypeSpec (MemberKind.Class, "System", "Type", BuildinTypeSpec.Type.Type);
112 Exception = new BuildinTypeSpec (MemberKind.Class, "System", "Exception", BuildinTypeSpec.Type.Exception);
113 RuntimeFieldHandle = new BuildinTypeSpec (MemberKind.Struct, "System", "RuntimeFieldHandle", BuildinTypeSpec.Type.Other);
114 RuntimeTypeHandle = new BuildinTypeSpec (MemberKind.Struct, "System", "RuntimeTypeHandle", BuildinTypeSpec.Type.Other);
116 // TODO: Maybe I should promote it to different kind for faster compares
117 Dynamic = new BuildinTypeSpec ("dynamic", BuildinTypeSpec.Type.Dynamic);
119 OperatorsBinaryStandard = Binary.CreateStandardOperatorsTable (this);
120 OperatorsBinaryEquality = Binary.CreateEqualityOperatorsTable (this);
121 OperatorsBinaryUnsafe = Binary.CreatePointerOperatorsTable (this);
122 OperatorsUnary = Unary.CreatePredefinedOperatorsTable (this);
123 OperatorsUnaryMutator = UnaryMutator.CreatePredefinedOperatorsTable (this);
125 BinaryPromotionsTypes = ConstantFold.CreateBinaryPromotionsTypes (this);
126 SwitchUserTypes = Switch.CreateSwitchUserTypes (this);
128 types = new BuildinTypeSpec[] {
129 Object, ValueType, Attribute,
130 Int, UInt, Long, ULong, Float, Double, Char, Short, Decimal, Bool, SByte, Byte, UShort, String,
131 Enum, Delegate, MulticastDelegate, Void, Array, Type, IEnumerator, IEnumerable, IDisposable,
132 IntPtr, UIntPtr, RuntimeFieldHandle, RuntimeTypeHandle, Exception };
134 // Deal with obsolete static types
136 TypeManager.object_type = Object;
137 TypeManager.value_type = ValueType;
140 public BuildinTypeSpec[] AllTypes {
146 public bool CheckDefinitions (ModuleContainer module)
148 var ctx = module.Compiler;
149 foreach (var p in types) {
150 var found = PredefinedType.Resolve (module, p.Kind, p.Namespace, p.Name, p.Arity, Location.Null);
151 if (found == null || found == p)
154 var tc = found.MemberDefinition as TypeContainer;
156 var ns = module.GlobalRootNamespace.GetNamespace (p.Namespace, false);
157 ns.ReplaceTypeWithPredefined (found, p);
159 tc.SetPredefinedSpec (p);
160 p.SetDefinition (found);
164 if (ctx.Report.Errors != 0)
167 // Set internal build-in types
168 Dynamic.SetDefinition (Object);
175 // Compiler predefined types. Usually used for compiler generated
176 // code or for comparison against well known framework type. They
177 // may not exist as they are optional
179 class PredefinedTypes
181 public readonly PredefinedType ArgIterator;
182 public readonly PredefinedType MarshalByRefObject;
183 public readonly PredefinedType RuntimeHelpers;
184 public readonly PredefinedType IAsyncResult;
185 public readonly PredefinedType AsyncCallback;
186 public readonly PredefinedType RuntimeArgumentHandle;
187 public readonly PredefinedType CharSet;
188 public readonly PredefinedType IsVolatile;
189 public readonly PredefinedType IEnumeratorGeneric;
190 public readonly PredefinedType IListGeneric;
191 public readonly PredefinedType ICollectionGeneric;
192 public readonly PredefinedType IEnumerableGeneric;
193 public readonly PredefinedType Nullable;
194 public readonly PredefinedType Activator;
195 public readonly PredefinedType Interlocked;
196 public readonly PredefinedType Monitor;
197 public readonly PredefinedType NotSupportedException;
198 public readonly PredefinedType RuntimeFieldHandle;
199 public readonly PredefinedType RuntimeMethodHandle;
200 public readonly PredefinedType SecurityAction;
205 public readonly PredefinedType Expression;
206 public readonly PredefinedType ExpressionGeneric;
207 public readonly PredefinedType ParameterExpression;
208 public readonly PredefinedType FieldInfo;
209 public readonly PredefinedType MethodBase;
210 public readonly PredefinedType MethodInfo;
211 public readonly PredefinedType ConstructorInfo;
216 public readonly PredefinedType Binder;
217 public readonly PredefinedType CallSite;
218 public readonly PredefinedType CallSiteGeneric;
219 public readonly PredefinedType BinderFlags;
221 public PredefinedTypes (ModuleContainer module)
223 var TypedReference = new PredefinedType (module, MemberKind.Struct, "System", "TypedReference");
224 ArgIterator = new PredefinedType (module, MemberKind.Struct, "System", "ArgIterator");
226 MarshalByRefObject = new PredefinedType (module, MemberKind.Class, "System", "MarshalByRefObject");
227 RuntimeHelpers = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "RuntimeHelpers");
228 IAsyncResult = new PredefinedType (module, MemberKind.Interface, "System", "IAsyncResult");
229 AsyncCallback = new PredefinedType (module, MemberKind.Delegate, "System", "AsyncCallback");
230 RuntimeArgumentHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeArgumentHandle");
231 CharSet = new PredefinedType (module, MemberKind.Enum, "System.Runtime.InteropServices", "CharSet");
232 IsVolatile = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "IsVolatile");
233 IEnumeratorGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IEnumerator", 1);
234 IListGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IList", 1);
235 ICollectionGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "ICollection", 1);
236 IEnumerableGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IEnumerable", 1);
237 Nullable = new PredefinedType (module, MemberKind.Struct, "System", "Nullable", 1);
238 Activator = new PredefinedType (module, MemberKind.Class, "System", "Activator");
239 Interlocked = new PredefinedType (module, MemberKind.Class, "System.Threading", "Interlocked");
240 Monitor = new PredefinedType (module, MemberKind.Class, "System.Threading", "Monitor");
241 NotSupportedException = new PredefinedType (module, MemberKind.Class, "System", "NotSupportedException");
242 RuntimeFieldHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeFieldHandle");
243 RuntimeMethodHandle = new PredefinedType (module, MemberKind.Struct, "System", "RuntimeMethodHandle");
244 SecurityAction = new PredefinedType (module, MemberKind.Enum, "System.Security.Permissions", "SecurityAction");
246 Expression = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "Expression");
247 ExpressionGeneric = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "Expression", 1);
248 ParameterExpression = new PredefinedType (module, MemberKind.Class, "System.Linq.Expressions", "ParameterExpression");
249 FieldInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "FieldInfo");
250 MethodBase = new PredefinedType (module, MemberKind.Class, "System.Reflection", "MethodBase");
251 MethodInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "MethodInfo");
252 ConstructorInfo = new PredefinedType (module, MemberKind.Class, "System.Reflection", "ConstructorInfo");
254 CallSite = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "CallSite");
255 CallSiteGeneric = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "CallSite", 1);
256 Binder = new PredefinedType (module, MemberKind.Class, "Microsoft.CSharp.RuntimeBinder", "Binder");
257 BinderFlags = new PredefinedType (module, MemberKind.Enum, "Microsoft.CSharp.RuntimeBinder", "CSharpBinderFlags");
260 // Define types which are used for comparison. It does not matter
261 // if they don't exist as no error report is needed
263 if (TypedReference.Define ())
264 TypedReference.TypeSpec.IsSpecialRuntimeType = true;
265 if (ArgIterator.Define ())
266 ArgIterator.TypeSpec.IsSpecialRuntimeType = true;
267 MarshalByRefObject.Define ();
270 IEnumerableGeneric.Define ();
271 IListGeneric.Define ();
272 ICollectionGeneric.Define ();
273 IEnumerableGeneric.Define ();
274 IEnumeratorGeneric.Define ();
276 ExpressionGeneric.Define ();
278 // Deal with obsolete static types
280 TypeManager.generic_ilist_type = IListGeneric.TypeSpec;
281 TypeManager.generic_icollection_type = ICollectionGeneric.TypeSpec;
282 TypeManager.generic_ienumerator_type = IEnumeratorGeneric.TypeSpec;
283 TypeManager.generic_ienumerable_type = IEnumerableGeneric.TypeSpec;
284 TypeManager.generic_nullable_type = Nullable.TypeSpec;
285 TypeManager.expression_type = ExpressionGeneric.TypeSpec;
289 public class PredefinedType
295 protected readonly ModuleContainer module;
296 protected TypeSpec type;
298 public PredefinedType (ModuleContainer module, MemberKind kind, string ns, string name, int arity)
299 : this (module, kind, ns, name)
304 public PredefinedType (ModuleContainer module, MemberKind kind, string ns, string name)
306 this.module = module;
320 public bool IsDefined {
332 public string Namespace {
338 public TypeSpec TypeSpec {
346 public bool Define ()
351 Namespace type_ns = module.GlobalRootNamespace.GetNamespace (ns, true);
352 var te = type_ns.LookupType (module, name, arity, true, Location.Null);
353 if (te == null || te.Type.Kind != kind) {
361 public FieldSpec GetField (string name, TypeSpec memberType, Location loc)
363 return TypeManager.GetPredefinedField (type, name, loc, memberType);
366 public string GetSignatureForError ()
368 return ns + "." + name;
371 public static TypeSpec Resolve (ModuleContainer module, MemberKind kind, string ns, string name, int arity, Location loc)
373 Namespace type_ns = module.GlobalRootNamespace.GetNamespace (ns, true);
374 var te = type_ns.LookupType (module, name, arity, false, Location.Null);
376 module.Compiler.Report.Error (518, loc, "The predefined type `{0}.{1}' is not defined or imported", ns, name);
381 if (type.Kind != kind) {
382 if (type.Kind == MemberKind.Struct && kind == MemberKind.Void && type.MemberDefinition is TypeContainer) {
383 // Void is declared as struct but we keep it internally as
384 // special kind, the swap will be done by caller
386 module.Compiler.Report.Error (520, loc, "The predefined type `{0}.{1}' is not declared correctly", ns, name);
394 public TypeSpec Resolve (Location loc)
397 type = Resolve (module, kind, ns, name, arity, loc);
403 partial class TypeManager {
405 // A list of core types that the compiler requires or uses
407 static public BuildinTypeSpec object_type;
408 static public BuildinTypeSpec value_type;
410 static public TypeSpec generic_ilist_type;
411 static public TypeSpec generic_icollection_type;
412 static public TypeSpec generic_ienumerator_type;
413 static public TypeSpec generic_ienumerable_type;
414 static public TypeSpec generic_nullable_type;
415 static internal TypeSpec expression_type;
418 // These methods are called by code generated by the compiler
420 static public FieldSpec string_empty;
421 static public MethodSpec system_type_get_type_from_handle;
422 static public MethodSpec bool_movenext_void;
423 static public MethodSpec void_dispose_void;
424 static public MethodSpec void_monitor_enter_object;
425 static public MethodSpec void_monitor_exit_object;
426 static public MethodSpec void_initializearray_array_fieldhandle;
427 static public MethodSpec delegate_combine_delegate_delegate;
428 static public MethodSpec delegate_remove_delegate_delegate;
429 static public PropertySpec int_get_offset_to_string_data;
430 static public MethodSpec int_interlocked_compare_exchange;
431 public static MethodSpec gen_interlocked_compare_exchange;
432 static public PropertySpec ienumerator_getcurrent;
433 public static MethodSpec methodbase_get_type_from_handle;
434 public static MethodSpec methodbase_get_type_from_handle_generic;
435 public static MethodSpec fieldinfo_get_field_from_handle;
436 public static MethodSpec fieldinfo_get_field_from_handle_generic;
437 public static MethodSpec activator_create_instance;
442 static public MethodSpec void_decimal_ctor_five_args;
443 static public MethodSpec void_decimal_ctor_int_arg;
444 public static MethodSpec void_decimal_ctor_long_arg;
446 static TypeManager ()
451 static public void Reset ()
453 // object_type = null;
455 // TODO: I am really bored by all this static stuff
456 system_type_get_type_from_handle =
459 void_monitor_enter_object =
460 void_monitor_exit_object =
461 void_initializearray_array_fieldhandle =
462 int_interlocked_compare_exchange =
463 gen_interlocked_compare_exchange =
464 methodbase_get_type_from_handle =
465 methodbase_get_type_from_handle_generic =
466 fieldinfo_get_field_from_handle =
467 fieldinfo_get_field_from_handle_generic =
468 activator_create_instance =
469 delegate_combine_delegate_delegate =
470 delegate_remove_delegate_delegate = null;
472 int_get_offset_to_string_data =
473 ienumerator_getcurrent = null;
475 void_decimal_ctor_five_args =
476 void_decimal_ctor_int_arg =
477 void_decimal_ctor_long_arg = null;
481 generic_ilist_type = generic_icollection_type = generic_ienumerator_type =
482 generic_ienumerable_type = generic_nullable_type = expression_type = null;
486 /// Returns the C# name of a type if possible, or the full type name otherwise
488 static public string CSharpName (TypeSpec t)
490 return t.GetSignatureForError ();
493 static public string CSharpName (IList<TypeSpec> types)
495 if (types.Count == 0)
498 StringBuilder sb = new StringBuilder ();
499 for (int i = 0; i < types.Count; ++i) {
503 sb.Append (CSharpName (types [i]));
505 return sb.ToString ();
508 static public string GetFullNameSignature (MemberSpec mi)
510 return mi.GetSignatureForError ();
513 static public string CSharpSignature (MemberSpec mb)
515 return mb.GetSignatureForError ();
518 static MemberSpec GetPredefinedMember (TypeSpec t, MemberFilter filter, bool optional, Location loc)
520 var member = MemberCache.FindMember (t, filter, BindingRestriction.DeclaredOnly);
522 if (member != null && member.IsAccessible (InternalType.FakeInternalType))
528 string method_args = null;
529 if (filter.Parameters != null)
530 method_args = filter.Parameters.GetSignatureForError ();
532 RootContext.ToplevelTypes.Compiler.Report.Error (656, loc, "The compiler required member `{0}.{1}{2}' could not be found or is inaccessible",
533 TypeManager.CSharpName (t), filter.Name, method_args);
539 // Returns the ConstructorInfo for "args"
541 public static MethodSpec GetPredefinedConstructor (TypeSpec t, Location loc, params TypeSpec [] args)
543 var pc = ParametersCompiled.CreateFullyResolved (args);
544 return GetPredefinedMember (t, MemberFilter.Constructor (pc), false, loc) as MethodSpec;
548 // Returns the method specification for a method named `name' defined
549 // in type `t' which takes arguments of types `args'
551 public static MethodSpec GetPredefinedMethod (TypeSpec t, string name, Location loc, params TypeSpec [] args)
553 var pc = ParametersCompiled.CreateFullyResolved (args);
554 return GetPredefinedMethod (t, MemberFilter.Method (name, 0, pc, null), false, loc);
557 public static MethodSpec GetPredefinedMethod (TypeSpec t, MemberFilter filter, Location loc)
559 return GetPredefinedMethod (t, filter, false, loc);
562 public static MethodSpec GetPredefinedMethod (TypeSpec t, MemberFilter filter, bool optional, Location loc)
564 return GetPredefinedMember (t, filter, optional, loc) as MethodSpec;
567 public static FieldSpec GetPredefinedField (TypeSpec t, string name, Location loc, TypeSpec type)
569 return GetPredefinedMember (t, MemberFilter.Field (name, type), false, loc) as FieldSpec;
572 public static PropertySpec GetPredefinedProperty (TypeSpec t, string name, Location loc, TypeSpec type)
574 return GetPredefinedMember (t, MemberFilter.Property (name, type), false, loc) as PropertySpec;
578 public static bool IsDelegateType (TypeSpec t)
584 public static bool IsEnumType (TypeSpec t)
590 // Whether a type is unmanaged. This is used by the unsafe code (25.2)
592 public static bool IsUnmanagedType (TypeSpec t)
594 var ds = t.MemberDefinition as DeclSpace;
596 return ds.IsUnmanagedType ();
598 if (t.Kind == MemberKind.Void)
601 // Someone did the work of checking if the ElementType of t is unmanaged. Let's not repeat it.
603 return IsUnmanagedType (GetElementType (t));
605 if (!IsValueType (t))
608 if (t.IsNested && t.DeclaringType.IsGenericOrParentIsGeneric)
615 // Null is considered to be a reference type
617 public static bool IsReferenceType (TypeSpec t)
619 if (t.IsGenericParameter)
620 return ((TypeParameterSpec) t).IsReferenceType;
622 return !t.IsStruct && !IsEnumType (t);
625 public static bool IsValueType (TypeSpec t)
627 if (t.IsGenericParameter)
628 return ((TypeParameterSpec) t).IsValueType;
630 return t.IsStruct || IsEnumType (t);
633 public static bool IsStruct (TypeSpec t)
638 public static bool IsFamilyAccessible (TypeSpec type, TypeSpec parent)
640 // TypeParameter tparam = LookupTypeParameter (type);
641 // TypeParameter pparam = LookupTypeParameter (parent);
643 if (type.Kind == MemberKind.TypeParameter && parent.Kind == MemberKind.TypeParameter) { // (tparam != null) && (pparam != null)) {
647 throw new NotImplementedException ("net");
648 // return tparam.IsSubclassOf (parent);
652 if (IsInstantiationOfSameGenericType (type, parent))
655 type = type.BaseType;
656 } while (type != null);
662 // Checks whether `type' is a subclass or nested child of `base_type'.
664 public static bool IsNestedFamilyAccessible (TypeSpec type, TypeSpec base_type)
667 if (IsFamilyAccessible (type, base_type))
670 // Handle nested types.
671 type = type.DeclaringType;
672 } while (type != null);
678 // Checks whether `type' is a nested child of `parent'.
680 public static bool IsNestedChildOf (TypeSpec type, ITypeDefinition parent)
685 if (type.MemberDefinition == parent)
688 type = type.DeclaringType;
689 while (type != null) {
690 if (type.MemberDefinition == parent)
693 type = type.DeclaringType;
699 public static TypeSpec GetElementType (TypeSpec t)
701 return ((ElementTypeSpec)t).Element;
705 /// This method is not implemented by MS runtime for dynamic types
707 public static bool HasElementType (TypeSpec t)
709 return t is ElementTypeSpec;
713 /// Utility function that can be used to probe whether a type
714 /// is managed or not.
716 public static bool VerifyUnmanaged (ModuleContainer rc, TypeSpec t, Location loc)
719 t = GetElementType (t);
721 if (IsUnmanagedType (t))
724 rc.Compiler.Report.SymbolRelatedToPreviousError (t);
725 rc.Compiler.Report.Error (208, loc,
726 "Cannot take the address of, get the size of, or declare a pointer to a managed type `{0}'",
732 // This method always return false for non-generic compiler,
733 // while Type.IsGenericParameter is returned if it is supported.
734 public static bool IsGenericParameter (TypeSpec type)
736 return type.IsGenericParameter;
739 public static bool IsGenericType (TypeSpec type)
741 return type.IsGeneric;
744 public static TypeSpec[] GetTypeArguments (TypeSpec t)
746 // TODO: return empty array !!
747 return t.TypeArguments;
751 /// Check whether `type' and `parent' are both instantiations of the same
752 /// generic type. Note that we do not check the type parameters here.
754 public static bool IsInstantiationOfSameGenericType (TypeSpec type, TypeSpec parent)
756 return type == parent || type.MemberDefinition == parent.MemberDefinition;
759 public static bool IsNullableType (TypeSpec t)
761 return generic_nullable_type == t.GetDefinition ();