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.
16 using System.Globalization;
17 using System.Collections.Generic;
18 using System.Reflection;
19 using System.Reflection.Emit;
21 using System.Runtime.CompilerServices;
22 using System.Diagnostics;
25 namespace Mono.CSharp {
27 partial class TypeManager {
29 // A list of core types that the compiler requires or uses
31 static public PredefinedTypeSpec object_type;
32 static public PredefinedTypeSpec value_type;
33 static public PredefinedTypeSpec string_type;
34 static public PredefinedTypeSpec int32_type;
35 static public PredefinedTypeSpec uint32_type;
36 static public PredefinedTypeSpec int64_type;
37 static public PredefinedTypeSpec uint64_type;
38 static public PredefinedTypeSpec float_type;
39 static public PredefinedTypeSpec double_type;
40 static public PredefinedTypeSpec char_type;
41 static public PredefinedTypeSpec short_type;
42 static public PredefinedTypeSpec decimal_type;
43 static public PredefinedTypeSpec bool_type;
44 static public PredefinedTypeSpec sbyte_type;
45 static public PredefinedTypeSpec byte_type;
46 static public PredefinedTypeSpec ushort_type;
47 static public PredefinedTypeSpec enum_type;
48 static public PredefinedTypeSpec delegate_type;
49 static public PredefinedTypeSpec multicast_delegate_type;
50 static public PredefinedTypeSpec void_type;
51 static public PredefinedTypeSpec array_type;
52 static public PredefinedTypeSpec runtime_handle_type;
53 static public PredefinedTypeSpec type_type;
54 static public PredefinedTypeSpec ienumerator_type;
55 static public PredefinedTypeSpec ienumerable_type;
56 static public PredefinedTypeSpec idisposable_type;
57 static public PredefinedTypeSpec intptr_type;
58 static public PredefinedTypeSpec uintptr_type;
59 static public PredefinedTypeSpec runtime_field_handle_type;
60 static public PredefinedTypeSpec attribute_type;
61 static public PredefinedTypeSpec exception_type;
64 static public TypeSpec null_type;
65 static public TypeSpec typed_reference_type;
66 static public TypeSpec arg_iterator_type;
67 static public TypeSpec mbr_type;
68 public static TypeSpec runtime_helpers_type;
69 static public TypeSpec iasyncresult_type;
70 static public TypeSpec asynccallback_type;
71 static public TypeSpec runtime_argument_handle_type;
72 static public TypeSpec void_ptr_type;
77 static internal TypeSpec isvolatile_type;
78 static public TypeSpec generic_ilist_type;
79 static public TypeSpec generic_icollection_type;
80 static public TypeSpec generic_ienumerator_type;
81 static public TypeSpec generic_ienumerable_type;
82 static public TypeSpec generic_nullable_type;
87 static internal TypeSpec expression_type;
88 public static TypeSpec parameter_expression_type;
89 public static TypeSpec fieldinfo_type;
90 public static TypeSpec methodinfo_type;
91 public static TypeSpec ctorinfo_type;
96 public static TypeSpec call_site_type;
97 public static TypeSpec generic_call_site_type;
98 public static TypeExpr binder_type;
99 public static TypeSpec binder_flags;
101 public static TypeExpr expression_type_expr;
105 // These methods are called by code generated by the compiler
107 static public FieldSpec string_empty;
108 static public MethodSpec system_type_get_type_from_handle;
109 static public MethodSpec bool_movenext_void;
110 static public MethodSpec void_dispose_void;
111 static public MethodSpec void_monitor_enter_object;
112 static public MethodSpec void_monitor_exit_object;
113 static public MethodSpec void_initializearray_array_fieldhandle;
114 static public MethodSpec delegate_combine_delegate_delegate;
115 static public MethodSpec delegate_remove_delegate_delegate;
116 public static MethodSpec delegate_equal, delegate_inequal;
117 static public PropertySpec int_get_offset_to_string_data;
118 static public MethodSpec int_interlocked_compare_exchange;
119 static public PropertySpec ienumerator_getcurrent;
120 public static MethodSpec methodbase_get_type_from_handle;
121 public static MethodSpec methodbase_get_type_from_handle_generic;
122 public static MethodSpec fieldinfo_get_field_from_handle;
123 public static MethodSpec fieldinfo_get_field_from_handle_generic;
124 public static MethodSpec activator_create_instance;
125 public static MethodSpec string_equal, string_inequal;
130 static public MethodSpec void_decimal_ctor_five_args;
131 static public MethodSpec void_decimal_ctor_int_arg;
132 public static MethodSpec void_decimal_ctor_long_arg;
134 static Dictionary<Assembly, bool> assembly_internals_vis_attrs;
136 static TypeManager ()
141 static public void Reset ()
143 // object_type = null;
145 assembly_internals_vis_attrs = new Dictionary<Assembly, bool> ();
147 // TODO: I am really bored by all this static stuff
148 system_type_get_type_from_handle =
151 void_monitor_enter_object =
152 void_monitor_exit_object =
153 void_initializearray_array_fieldhandle =
154 int_interlocked_compare_exchange =
155 methodbase_get_type_from_handle =
156 methodbase_get_type_from_handle_generic =
157 fieldinfo_get_field_from_handle =
158 fieldinfo_get_field_from_handle_generic =
159 activator_create_instance =
160 delegate_combine_delegate_delegate =
161 delegate_remove_delegate_delegate =
165 delegate_inequal = null;
167 int_get_offset_to_string_data =
168 ienumerator_getcurrent = null;
170 void_decimal_ctor_five_args =
171 void_decimal_ctor_int_arg =
172 void_decimal_ctor_long_arg = null;
177 generic_call_site_type =
182 typed_reference_type = arg_iterator_type = mbr_type =
183 runtime_helpers_type = iasyncresult_type = asynccallback_type =
184 runtime_argument_handle_type = void_ptr_type = isvolatile_type =
185 generic_ilist_type = generic_icollection_type = generic_ienumerator_type =
186 generic_ienumerable_type = generic_nullable_type = expression_type =
187 parameter_expression_type = fieldinfo_type = methodinfo_type = ctorinfo_type = null;
189 expression_type_expr = null;
193 /// Returns the C# name of a type if possible, or the full type name otherwise
195 static public string CSharpName (TypeSpec t)
197 return t.GetSignatureForError ();
200 static public string CSharpName (IList<TypeSpec> types)
202 if (types.Count == 0)
205 StringBuilder sb = new StringBuilder ();
206 for (int i = 0; i < types.Count; ++i) {
210 sb.Append (CSharpName (types [i]));
212 return sb.ToString ();
215 static public string GetFullNameSignature (MemberSpec mi)
217 return mi.GetSignatureForError ();
220 static public string CSharpSignature (MemberSpec mb)
222 return mb.GetSignatureForError ();
226 // Looks up a type, and aborts if it is not found. This is used
227 // by predefined types required by the compiler
229 public static TypeSpec CoreLookupType (CompilerContext ctx, string ns_name, string name, MemberKind kind, bool required)
231 return CoreLookupType (ctx, ns_name, name, 0, kind, required);
234 public static TypeSpec CoreLookupType (CompilerContext ctx, string ns_name, string name, int arity, MemberKind kind, bool required)
236 Namespace ns = GlobalRootNamespace.Instance.GetNamespace (ns_name, true);
237 var te = ns.LookupType (ctx, name, arity, !required, Location.Null);
238 var ts = te == null ? null : te.Type;
244 ctx.Report.Error (518, "The predefined type `{0}.{1}' is not defined or imported",
249 if (ts.Kind != kind) {
250 ctx.Report.Error (520, "The predefined type `{0}.{1}' is not declared correctly",
258 static MemberSpec GetPredefinedMember (TypeSpec t, MemberFilter filter, Location loc)
260 const BindingRestriction restrictions = BindingRestriction.AccessibleOnly | BindingRestriction.DeclaredOnly;
261 var member = MemberCache.FindMember (t, filter, restrictions);
266 string method_args = null;
267 if (filter.Parameters != null)
268 method_args = filter.Parameters.GetSignatureForError ();
270 RootContext.ToplevelTypes.Compiler.Report.Error (656, loc, "The compiler required member `{0}.{1}{2}' could not be found or is inaccessible",
271 TypeManager.CSharpName (t), filter.Name, method_args);
277 // Returns the ConstructorInfo for "args"
279 public static MethodSpec GetPredefinedConstructor (TypeSpec t, Location loc, params TypeSpec [] args)
281 var pc = ParametersCompiled.CreateFullyResolved (args);
282 return GetPredefinedMember (t, MemberFilter.Constructor (pc), loc) as MethodSpec;
286 // Returns the method specification for a method named `name' defined
287 // in type `t' which takes arguments of types `args'
289 public static MethodSpec GetPredefinedMethod (TypeSpec t, string name, Location loc, params TypeSpec [] args)
291 var pc = ParametersCompiled.CreateFullyResolved (args);
292 return GetPredefinedMethod (t, MemberFilter.Method (name, 0, pc, null), loc);
295 public static MethodSpec GetPredefinedMethod (TypeSpec t, MemberFilter filter, Location loc)
297 return GetPredefinedMember (t, filter, loc) as MethodSpec;
300 public static FieldSpec GetPredefinedField (TypeSpec t, string name, Location loc, TypeSpec type)
302 return GetPredefinedMember (t, MemberFilter.Field (name, type), loc) as FieldSpec;
305 public static PropertySpec GetPredefinedProperty (TypeSpec t, string name, Location loc, TypeSpec type)
307 return GetPredefinedMember (t, MemberFilter.Property (name, type), loc) as PropertySpec;
310 public static IList<PredefinedTypeSpec> InitCoreTypes ()
312 var core_types = new PredefinedTypeSpec[] {
313 object_type = new PredefinedTypeSpec (MemberKind.Class, "System", "Object"),
314 value_type = new PredefinedTypeSpec (MemberKind.Class, "System", "ValueType"),
315 attribute_type = new PredefinedTypeSpec (MemberKind.Class, "System", "Attribute"),
317 int32_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Int32"),
318 int64_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Int64"),
319 uint32_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "UInt32"),
320 uint64_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "UInt64"),
321 byte_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Byte"),
322 sbyte_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "SByte"),
323 short_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Int16"),
324 ushort_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "UInt16"),
326 ienumerator_type = new PredefinedTypeSpec (MemberKind.Interface, "System.Collections", "IEnumerator"),
327 ienumerable_type = new PredefinedTypeSpec (MemberKind.Interface, "System.Collections", "IEnumerable"),
328 idisposable_type = new PredefinedTypeSpec (MemberKind.Interface, "System", "IDisposable"),
330 char_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Char"),
331 string_type = new PredefinedTypeSpec (MemberKind.Class, "System", "String"),
332 float_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Single"),
333 double_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Double"),
334 decimal_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Decimal"),
335 bool_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Boolean"),
336 intptr_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "IntPtr"),
337 uintptr_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "UIntPtr"),
339 multicast_delegate_type = new PredefinedTypeSpec (MemberKind.Class, "System", "MulticastDelegate"),
340 delegate_type = new PredefinedTypeSpec (MemberKind.Class, "System", "Delegate"),
341 enum_type = new PredefinedTypeSpec (MemberKind.Class, "System", "Enum"),
342 array_type = new PredefinedTypeSpec (MemberKind.Class, "System", "Array"),
343 void_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "Void"),
344 type_type = new PredefinedTypeSpec (MemberKind.Class, "System", "Type"),
345 exception_type = new PredefinedTypeSpec (MemberKind.Class, "System", "Exception"),
346 runtime_field_handle_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "RuntimeFieldHandle"),
347 runtime_handle_type = new PredefinedTypeSpec (MemberKind.Struct, "System", "RuntimeTypeHandle"),
354 /// The types have to be initialized after the initial
355 /// population of the type has happened (for example, to
356 /// bootstrap the corlib.dll
358 public static bool InitCoreTypes (CompilerContext ctx, IList<PredefinedTypeSpec> predefined)
360 foreach (var p in predefined) {
361 var found = CoreLookupType (ctx, p.Namespace, p.Name, p.Kind, true);
362 if (found == null || found == p)
365 if (!RootContext.StdLib) {
366 var ns = GlobalRootNamespace.Instance.GetNamespace (p.Namespace, false);
367 ns.ReplaceTypeWithPredefined (found, p);
369 var tc = found.MemberDefinition as TypeContainer;
370 tc.SetPredefinedSpec (p);
371 p.SetDefinition (found);
375 PredefinedAttributes.Get.ParamArray.Initialize (ctx, false);
376 PredefinedAttributes.Get.Out.Initialize (ctx, false);
378 return ctx.Report.Errors == 0;
382 // Initializes optional core types
384 public static void InitOptionalCoreTypes (CompilerContext ctx)
387 // These are only used for compare purposes
389 null_type = InternalType.Null;
391 void_ptr_type = PointerContainer.MakeType (void_type);
394 // Initialize InternalsVisibleTo as the very first optional type. Otherwise we would populate
395 // types cache with incorrect accessiblity when any of optional types is internal.
397 PredefinedAttributes.Get.Initialize (ctx);
399 runtime_argument_handle_type = CoreLookupType (ctx, "System", "RuntimeArgumentHandle", MemberKind.Struct, false);
400 asynccallback_type = CoreLookupType (ctx, "System", "AsyncCallback", MemberKind.Delegate, false);
401 iasyncresult_type = CoreLookupType (ctx, "System", "IAsyncResult", MemberKind.Interface, false);
402 typed_reference_type = CoreLookupType (ctx, "System", "TypedReference", MemberKind.Struct, false);
403 arg_iterator_type = CoreLookupType (ctx, "System", "ArgIterator", MemberKind.Struct, false);
404 mbr_type = CoreLookupType (ctx, "System", "MarshalByRefObject", MemberKind.Class, false);
406 generic_ienumerator_type = CoreLookupType (ctx, "System.Collections.Generic", "IEnumerator", 1, MemberKind.Interface, false);
407 generic_ilist_type = CoreLookupType (ctx, "System.Collections.Generic", "IList", 1, MemberKind.Interface, false);
408 generic_icollection_type = CoreLookupType (ctx, "System.Collections.Generic", "ICollection", 1, MemberKind.Interface, false);
409 generic_ienumerable_type = CoreLookupType (ctx, "System.Collections.Generic", "IEnumerable", 1, MemberKind.Interface, false);
410 generic_nullable_type = CoreLookupType (ctx, "System", "Nullable", 1, MemberKind.Struct, false);
413 // Optional types which are used as types and for member lookup
415 runtime_helpers_type = CoreLookupType (ctx, "System.Runtime.CompilerServices", "RuntimeHelpers", MemberKind.Class, false);
418 // Note: extension_attribute_type is already loaded
419 expression_type = CoreLookupType (ctx, "System.Linq.Expressions", "Expression", 1, MemberKind.Class, false);
422 public static bool IsBuiltinType (TypeSpec t)
424 if (t == object_type || t == string_type || t == int32_type || t == uint32_type ||
425 t == int64_type || t == uint64_type || t == float_type || t == double_type ||
426 t == char_type || t == short_type || t == decimal_type || t == bool_type ||
427 t == sbyte_type || t == byte_type || t == ushort_type || t == void_type)
434 // This is like IsBuiltinType, but lacks decimal_type, we should also clean up
435 // the pieces in the code where we use IsBuiltinType and special case decimal_type.
437 public static bool IsPrimitiveType (TypeSpec t)
439 return (t == int32_type || t == uint32_type ||
440 t == int64_type || t == uint64_type || t == float_type || t == double_type ||
441 t == char_type || t == short_type || t == bool_type ||
442 t == sbyte_type || t == byte_type || t == ushort_type);
446 public static bool IsDelegateType (TypeSpec t)
452 // When any element of the type is a dynamic type
454 // This method builds a transformation array for dynamic types
455 // used in places where DynamicAttribute cannot be applied to.
456 // It uses bool flag when type is of dynamic type and each
457 // section always starts with "false" for some reason.
459 // LAMESPEC: This should be part of C# specification !
461 // Example: Func<dynamic, int, dynamic[]>
462 // Transformation: { false, true, false, false, true }
464 public static bool[] HasDynamicTypeUsed (TypeSpec t)
466 var ac = t as ArrayContainer;
468 if (HasDynamicTypeUsed (ac.Element) != null)
469 return new bool[] { false, true };
477 if (IsGenericType (t)) {
478 List<bool> transform = null;
479 var targs = GetTypeArguments (t);
480 for (int i = 0; i < targs.Length; ++i) {
481 var element = HasDynamicTypeUsed (targs [i]);
482 if (element != null) {
483 if (transform == null) {
484 transform = new List<bool> ();
485 for (int ii = 0; ii <= i; ++ii)
486 transform.Add (false);
489 transform.AddRange (element);
490 } else if (transform != null) {
491 transform.Add (false);
495 if (transform != null)
496 return transform.ToArray ();
499 if (object.ReferenceEquals (InternalType.Dynamic, t))
500 return new bool [] { true };
506 public static bool IsEnumType (TypeSpec t)
511 public static bool IsBuiltinOrEnum (TypeSpec t)
513 if (IsBuiltinType (t))
523 // Whether a type is unmanaged. This is used by the unsafe code (25.2)
525 public static bool IsUnmanagedType (TypeSpec t)
527 var ds = t.MemberDefinition as DeclSpace;
529 return ds.IsUnmanagedType ();
531 // some builtins that are not unmanaged types
532 if (t == TypeManager.object_type || t == TypeManager.string_type)
535 if (IsBuiltinOrEnum (t))
538 // Someone did the work of checking if the ElementType of t is unmanaged. Let's not repeat it.
540 return IsUnmanagedType (GetElementType (t));
542 if (!IsValueType (t))
545 if (t.IsNested && t.DeclaringType.IsGenericOrParentIsGeneric)
552 // Null is considered to be a reference type
554 public static bool IsReferenceType (TypeSpec t)
556 if (t.IsGenericParameter)
557 return ((TypeParameterSpec) t).IsReferenceType;
559 return !t.IsStruct && !IsEnumType (t);
562 public static bool IsValueType (TypeSpec t)
564 if (t.IsGenericParameter)
565 return ((TypeParameterSpec) t).IsValueType;
567 return t.IsStruct || IsEnumType (t);
570 public static bool IsStruct (TypeSpec t)
575 public static bool IsSubclassOf (TypeSpec type, TypeSpec base_type)
578 if (type == base_type)
581 type = type.BaseType;
582 } while (type != null);
587 public static bool IsFamilyAccessible (TypeSpec type, TypeSpec parent)
589 // TypeParameter tparam = LookupTypeParameter (type);
590 // TypeParameter pparam = LookupTypeParameter (parent);
592 if (type.Kind == MemberKind.TypeParameter && parent.Kind == MemberKind.TypeParameter) { // (tparam != null) && (pparam != null)) {
596 throw new NotImplementedException ("net");
597 // return tparam.IsSubclassOf (parent);
601 if (IsInstantiationOfSameGenericType (type, parent))
604 type = type.BaseType;
605 } while (type != null);
611 // Checks whether `type' is a subclass or nested child of `base_type'.
613 public static bool IsNestedFamilyAccessible (TypeSpec type, TypeSpec base_type)
616 if (IsFamilyAccessible (type, base_type))
619 // Handle nested types.
620 type = type.DeclaringType;
621 } while (type != null);
627 // Checks whether `type' is a nested child of `parent'.
629 public static bool IsNestedChildOf (TypeSpec type, TypeSpec parent)
634 type = type.GetDefinition (); // DropGenericTypeArguments (type);
635 parent = parent.GetDefinition (); // DropGenericTypeArguments (parent);
637 if (IsEqual (type, parent))
640 type = type.DeclaringType;
641 while (type != null) {
642 if (IsEqual (type.GetDefinition (), parent))
645 type = type.DeclaringType;
651 public static bool IsSpecialType (TypeSpec t)
653 return t == arg_iterator_type || t == typed_reference_type;
657 // Checks whether `invocationAssembly' is same or a friend of the assembly
659 public static bool IsThisOrFriendAssembly (Assembly invocationAssembly, Assembly assembly)
661 if (assembly == null)
662 throw new ArgumentNullException ("assembly");
664 // TODO: This can happen for constants used at assembly level and
665 // predefined members
666 // But there is no way to test for it for now, so it could be abused
668 if (invocationAssembly == null)
669 invocationAssembly = CodeGen.Assembly.Builder;
671 if (invocationAssembly == assembly)
675 if (assembly_internals_vis_attrs.TryGetValue (assembly, out value))
678 object[] attrs = assembly.GetCustomAttributes (typeof (InternalsVisibleToAttribute), false);
679 if (attrs.Length == 0) {
680 assembly_internals_vis_attrs.Add (assembly, false);
684 bool is_friend = false;
686 AssemblyName this_name = CodeGen.Assembly.Name;
687 if (this_name == null)
690 byte [] this_token = this_name.GetPublicKeyToken ();
691 foreach (InternalsVisibleToAttribute attr in attrs) {
692 if (attr.AssemblyName == null || attr.AssemblyName.Length == 0)
695 AssemblyName aname = null;
697 aname = new AssemblyName (attr.AssemblyName);
698 } catch (FileLoadException) {
699 } catch (ArgumentException) {
702 if (aname == null || aname.Name != this_name.Name)
705 byte [] key_token = aname.GetPublicKeyToken ();
706 if (key_token != null) {
707 if (this_token.Length == 0) {
708 // Same name, but assembly is not strongnamed
709 Error_FriendAccessNameNotMatching (aname.FullName, RootContext.ToplevelTypes.Compiler.Report);
713 if (!CompareKeyTokens (this_token, key_token))
721 assembly_internals_vis_attrs.Add (assembly, is_friend);
725 static bool CompareKeyTokens (byte [] token1, byte [] token2)
727 for (int i = 0; i < token1.Length; i++)
728 if (token1 [i] != token2 [i])
734 static void Error_FriendAccessNameNotMatching (string other_name, Report Report)
737 "Friend access was granted to `{0}', but the output assembly is named `{1}'. Try adding a reference to `{0}' or change the output assembly name to match it",
738 other_name, CodeGen.Assembly.Name.FullName);
741 public static TypeSpec GetElementType (TypeSpec t)
743 return ((ElementTypeSpec)t).Element;
747 /// This method is not implemented by MS runtime for dynamic types
749 public static bool HasElementType (TypeSpec t)
751 return t is ElementTypeSpec;
754 static NumberFormatInfo nf_provider = CultureInfo.CurrentCulture.NumberFormat;
756 // This is a custom version of Convert.ChangeType() which works
757 // with the TypeBuilder defined types when compiling corlib.
758 public static object ChangeType (object value, TypeSpec targetType, out bool error)
760 IConvertible convert_value = value as IConvertible;
762 if (convert_value == null){
768 // We cannot rely on build-in type conversions as they are
769 // more limited than what C# supports.
770 // See char -> float/decimal/double conversion
774 if (targetType == TypeManager.bool_type)
775 return convert_value.ToBoolean (nf_provider);
776 if (targetType == TypeManager.byte_type)
777 return convert_value.ToByte (nf_provider);
778 if (targetType == TypeManager.char_type)
779 return convert_value.ToChar (nf_provider);
780 if (targetType == TypeManager.short_type)
781 return convert_value.ToInt16 (nf_provider);
782 if (targetType == TypeManager.int32_type)
783 return convert_value.ToInt32 (nf_provider);
784 if (targetType == TypeManager.int64_type)
785 return convert_value.ToInt64 (nf_provider);
786 if (targetType == TypeManager.sbyte_type)
787 return convert_value.ToSByte (nf_provider);
789 if (targetType == TypeManager.decimal_type) {
790 if (convert_value.GetType () == typeof (char))
791 return (decimal) convert_value.ToInt32 (nf_provider);
792 return convert_value.ToDecimal (nf_provider);
795 if (targetType == TypeManager.double_type) {
796 if (convert_value.GetType () == typeof (char))
797 return (double) convert_value.ToInt32 (nf_provider);
798 return convert_value.ToDouble (nf_provider);
801 if (targetType == TypeManager.float_type) {
802 if (convert_value.GetType () == typeof (char))
803 return (float)convert_value.ToInt32 (nf_provider);
804 return convert_value.ToSingle (nf_provider);
807 if (targetType == TypeManager.string_type)
808 return convert_value.ToString (nf_provider);
809 if (targetType == TypeManager.ushort_type)
810 return convert_value.ToUInt16 (nf_provider);
811 if (targetType == TypeManager.uint32_type)
812 return convert_value.ToUInt32 (nf_provider);
813 if (targetType == TypeManager.uint64_type)
814 return convert_value.ToUInt64 (nf_provider);
815 if (targetType == TypeManager.object_type)
826 /// Utility function that can be used to probe whether a type
827 /// is managed or not.
829 public static bool VerifyUnmanaged (CompilerContext ctx, TypeSpec t, Location loc)
832 t = GetElementType (t);
834 if (IsUnmanagedType (t))
837 ctx.Report.SymbolRelatedToPreviousError (t);
838 ctx.Report.Error (208, loc,
839 "Cannot take the address of, get the size of, or declare a pointer to a managed type `{0}'",
845 // This method always return false for non-generic compiler,
846 // while Type.IsGenericParameter is returned if it is supported.
847 public static bool IsGenericParameter (TypeSpec type)
849 return type.IsGenericParameter;
852 public static bool IsGenericType (TypeSpec type)
854 return type.IsGeneric;
857 // TODO: Implement correctly
858 public static bool ContainsGenericParameters (TypeSpec type)
860 return type.GetMetaInfo ().ContainsGenericParameters;
863 public static bool IsEqual (TypeSpec a, TypeSpec b)
865 return a == b && !(a is InternalType);
868 public static TypeSpec[] GetTypeArguments (TypeSpec t)
870 // TODO: return empty array !!
871 return t.TypeArguments;
875 /// Check whether `type' and `parent' are both instantiations of the same
876 /// generic type. Note that we do not check the type parameters here.
878 public static bool IsInstantiationOfSameGenericType (TypeSpec type, TypeSpec parent)
880 return type == parent || type.MemberDefinition == parent.MemberDefinition;
883 public static bool IsNullableType (TypeSpec t)
885 return generic_nullable_type == t.GetDefinition ();
890 // Looks up a member called `name' in the `queried_type'. This lookup
891 // is done by code that is contained in the definition for `invocation_type'
892 // through a qualifier of type `qualifier_type' (or null if there is no qualifier).
894 // `invocation_type' is used to check whether we're allowed to access the requested
895 // member wrt its protection level.
897 // When called from MemberAccess, `qualifier_type' is the type which is used to access
898 // the requested member (`class B { A a = new A (); a.foo = 5; }'; here invocation_type
899 // is B and qualifier_type is A). This is used to do the CS1540 check.
901 // When resolving a SimpleName, `qualifier_type' is null.
903 // The `qualifier_type' is used for the CS1540 check; it's normally either null or
904 // the same than `queried_type' - except when we're being called from BaseAccess;
905 // in this case, `invocation_type' is the current type and `queried_type' the base
906 // type, so this'd normally trigger a CS1540.
908 // The binding flags are `bf' and the kind of members being looked up are `mt'
910 // The return value always includes private members which code in `invocation_type'
911 // is allowed to access (using the specified `qualifier_type' if given); only use
912 // BindingFlags.NonPublic to bypass the permission check.
914 // The 'almost_match' argument is used for reporting error CS1540.
916 // Returns an array of a single element for everything but Methods/Constructors
917 // that might return multiple matches.
919 public static IList<MemberSpec> MemberLookup (TypeSpec invocation_type, TypeSpec qualifier_type,
920 TypeSpec queried_type, MemberKind mt,
921 BindingRestriction opt, string name, int arity, IList<MemberSpec> almost_match)
923 Timer.StartTimer (TimerType.MemberLookup);
925 var retval = RealMemberLookup (invocation_type, qualifier_type,
926 queried_type, mt, opt, name, arity, almost_match);
928 Timer.StopTimer (TimerType.MemberLookup);
933 static IList<MemberSpec> RealMemberLookup (TypeSpec invocation_type, TypeSpec qualifier_type,
934 TypeSpec queried_type, MemberKind mt,
935 BindingRestriction bf, string name, int arity, IList<MemberSpec> almost_match)
937 MemberFilter filter = new MemberFilter (name, arity, mt, null, null);
938 if ((bf & BindingRestriction.AccessibleOnly) != 0) {
939 filter.InvocationType = invocation_type ?? InternalType.FakeInternalType;
942 return MemberCache.FindMembers (queried_type, filter, bf);