//
-// typegen.cs: type generation
+// typemanager.cs: C# type manager
//
// Author: Miguel de Icaza (miguel@gnu.org)
//
using System.Reflection;
using System.Reflection.Emit;
-namespace CIR {
+namespace Mono.CSharp {
public class TypeManager {
//
static public Type float_type;
static public Type double_type;
static public Type char_type;
+ static public Type char_ptr_type;
static public Type short_type;
static public Type decimal_type;
static public Type bool_type;
static public Type ushort_type;
static public Type enum_type;
static public Type delegate_type;
+ static public Type multicast_delegate_type;
static public Type void_type;
static public Type enumeration_type;
static public Type array_type;
static public Type asynccallback_type;
static public Type intptr_type;
static public Type monitor_type;
+ static public Type runtime_field_handle_type;
+ static public Type attribute_usage_type;
+ static public Type dllimport_type;
+ static public Type unverifiable_code_type;
+ static public Type methodimpl_attr_type;
+ static public Type param_array_type;
+ static public Type void_ptr_type;
+
+ static public Type [] NoTypes;
+
+ //
+ // Internal, not really used outside
+ //
+ Type runtime_helpers_type;
//
// These methods are called by code generated by the compiler
//
static public MethodInfo string_concat_string_string;
static public MethodInfo string_concat_object_object;
+ static public MethodInfo string_isinterneted_string;
static public MethodInfo system_type_get_type_from_handle;
static public MethodInfo object_getcurrent_void;
static public MethodInfo bool_movenext_void;
static public MethodInfo void_dispose_void;
static public MethodInfo void_monitor_enter_object;
static public MethodInfo void_monitor_exit_object;
+ static public MethodInfo void_initializearray_array_fieldhandle;
+ static public MethodInfo int_getlength_int;
+ static public MethodInfo delegate_combine_delegate_delegate;
+ static public MethodInfo delegate_remove_delegate_delegate;
+ static public MethodInfo int_get_offset_to_string_data;
+
+ //
+ // The attribute constructors.
+ //
+ static public ConstructorInfo cons_param_array_attribute;
// <remarks>
// Holds the Array of Assemblies that have been loaded
// (either because it is the default or the user used the
// -r command line option)
// </remarks>
- ArrayList assemblies;
+ Assembly [] assemblies;
// <remarks>
// Keeps a list of module builders. We used this to do lookups
// on the modulebuilder using GetType -- needed for arrays
// </remarks>
- ArrayList modules;
+ ModuleBuilder [] modules;
// <remarks>
// This is the type_cache from the assemblies to avoid
// <remarks>
// Keeps a mapping between TypeBuilders and their TypeContainers
// </remarks>
- static Hashtable builder_to_container;
+ static PtrHashtable builder_to_container;
// <remarks>
// Maps MethodBase.RuntimeTypeHandle to a Type array that contains
// </remarks>
static Hashtable method_arguments;
- static Hashtable builder_to_interface;
+ // <remarks>
+ // Maybe `method_arguments' should be replaced and only
+ // method_internal_params should be kept?
+ // <remarks>
+ static Hashtable method_internal_params;
+
+ static PtrHashtable builder_to_interface;
// <remarks>
// Keeps track of delegate types
// </remarks>
- static Hashtable delegate_types;
-
+ static Hashtable builder_to_delegate;
+
+ // <remarks>
+ // Keeps track of enum types
+ // </remarks>
+
+ static Hashtable builder_to_enum;
+
+ // <remarks>
+ // Keeps track of attribute types
+ // </remarks>
+
+ static Hashtable builder_to_attr;
+
public TypeManager ()
{
- assemblies = new ArrayList ();
- modules = new ArrayList ();
+ assemblies = null;
+ modules = null;
user_types = new ArrayList ();
types = new Hashtable ();
typecontainers = new Hashtable ();
- builder_to_interface = new Hashtable ();
- delegate_types = new Hashtable ();
+ builder_to_interface = new PtrHashtable ();
+ builder_to_delegate = new PtrHashtable ();
+ builder_to_enum = new PtrHashtable ();
+ builder_to_attr = new PtrHashtable ();
}
static TypeManager ()
{
- method_arguments = new Hashtable ();
- builder_to_container = new Hashtable ();
- type_interface_cache = new Hashtable ();
+ method_arguments = new PtrHashtable ();
+ method_internal_params = new PtrHashtable ();
+ builder_to_container = new PtrHashtable ();
+ type_interface_cache = new PtrHashtable ();
+ NoTypes = new Type [0];
}
-
+
public void AddUserType (string name, TypeBuilder t)
{
types.Add (name, t);
public void AddDelegateType (string name, TypeBuilder t, Delegate del)
{
types.Add (name, t);
- delegate_types.Add (t, del);
+ builder_to_delegate.Add (t, del);
+ }
+
+ public void AddEnumType (string name, TypeBuilder t, Enum en)
+ {
+ types.Add (name, t);
+ builder_to_enum.Add (t, en);
}
public void AddUserInterface (string name, TypeBuilder t, Interface i)
AddUserType (name, t);
builder_to_interface.Add (t, i);
}
+
+ public void RegisterAttrType (Type t, TypeContainer tc)
+ {
+ builder_to_attr.Add (t, tc);
+ }
- // <summary>
- // Returns the TypeContainer whose Type is `t' or null if there is no
- // TypeContainer for `t' (ie, the Type comes from a library)
- // </summary>
+ /// <summary>
+ /// Returns the TypeContainer whose Type is `t' or null if there is no
+ /// TypeContainer for `t' (ie, the Type comes from a library)
+ /// </summary>
public static TypeContainer LookupTypeContainer (Type t)
{
return (TypeContainer) builder_to_container [t];
public static Delegate LookupDelegate (Type t)
{
- return (Delegate) delegate_types [t];
+ return (Delegate) builder_to_delegate [t];
+ }
+
+ public static Enum LookupEnum (Type t)
+ {
+ return (Enum) builder_to_enum [t];
}
- // <summary>
- // Registers an assembly to load types from.
- // </summary>
+ public static TypeContainer LookupAttr (Type t)
+ {
+ return (TypeContainer) builder_to_attr [t];
+ }
+
+ /// <summary>
+ /// Registers an assembly to load types from.
+ /// </summary>
public void AddAssembly (Assembly a)
{
- assemblies.Add (a);
+ int top = assemblies != null ? assemblies.Length : 0;
+ Assembly [] n = new Assembly [top + 1];
+
+ if (assemblies != null)
+ assemblies.CopyTo (n, 0);
+ n [top] = a;
+ assemblies = n;
}
- // <summary>
- // Registers a module builder to lookup types from
- // </summary>
+ /// <summary>
+ /// Registers a module builder to lookup types from
+ /// </summary>
public void AddModule (ModuleBuilder mb)
{
- modules.Add (mb);
+ int top = modules != null ? modules.Length : 0;
+ ModuleBuilder [] n = new ModuleBuilder [top + 1];
+
+ if (modules != null)
+ modules.CopyTo (n, 0);
+ n [top] = mb;
+ modules = n;
}
- // <summary>
- // Returns the Type associated with @name
- // </summary>
+ /// <summary>
+ /// Returns the Type associated with @name
+ /// </summary>
public Type LookupType (string name)
{
Type t;
return null;
}
- // <summary>
- // Returns the C# name of a type if possible, or the full type name otherwise
- // </summary>
+ /// <summary>
+ /// Returns the C# name of a type if possible, or the full type name otherwise
+ /// </summary>
static public string CSharpName (Type t)
{
if (t == int32_type)
return "string";
else if (t == object_type)
return "object";
+ else if (t == void_type)
+ return "void";
else
return t.FullName;
}
- // <summary>
- // Looks up a type, and aborts if it is not found. This is used
- // by types required by the compiler
- // </summary>
+ /// <summary>
+ /// Looks up a type, and aborts if it is not found. This is used
+ /// by types required by the compiler
+ /// </summary>
Type CoreLookupType (string name)
{
Type t = LookupType (name);
- if (t == null)
- throw new Exception ("Can not find core type " + name);
+ if (t == null){
+ Report.Error (518, "The predefined type `" + name + "' is not defined or imported");
+ Environment.Exit (0);
+ }
return t;
}
- // <summary>
- // Returns the MethodInfo for a method named `name' defined
- // in type `t' which takes arguments of types `args'
- // </summary>
+ /// <summary>
+ /// Returns the MethodInfo for a method named `name' defined
+ /// in type `t' which takes arguments of types `args'
+ /// </summary>
MethodInfo GetMethod (Type t, string name, Type [] args)
{
MethodInfo mi = t.GetMethod (name, args);
return mi;
}
+
+ ConstructorInfo GetConstructor (Type t, Type [] args)
+ {
+ ConstructorInfo ci = t.GetConstructor (args);
+
+ if (ci == null)
+ throw new Exception ("Can not find the core constructor for `" + t.FullName + "'");
+
+ return ci;
+ }
- // <remarks>
- // The types have to be initialized after the initial
- // population of the type has happened (for example, to
- // bootstrap the corlib.dll
- // </remarks>
+ /// <remarks>
+ /// The types have to be initialized after the initial
+ /// population of the type has happened (for example, to
+ /// bootstrap the corlib.dll
+ /// </remarks>
public void InitCoreTypes ()
{
object_type = CoreLookupType ("System.Object");
byte_type = CoreLookupType ("System.Byte");
sbyte_type = CoreLookupType ("System.SByte");
char_type = CoreLookupType ("System.Char");
+ char_ptr_type = CoreLookupType ("System.Char*");
short_type = CoreLookupType ("System.Int16");
ushort_type = CoreLookupType ("System.UInt16");
decimal_type = CoreLookupType ("System.Decimal");
bool_type = CoreLookupType ("System.Boolean");
enum_type = CoreLookupType ("System.Enum");
- delegate_type = CoreLookupType ("System.MulticastDelegate");
+
+ multicast_delegate_type = CoreLookupType ("System.MulticastDelegate");
+ delegate_type = CoreLookupType ("System.Delegate");
+
array_type = CoreLookupType ("System.Array");
void_type = CoreLookupType ("System.Void");
type_type = CoreLookupType ("System.Type");
- default_member_type = CoreLookupType ("System.Reflection.DefaultMemberAttribute");
- runtime_handle_type = CoreLookupType ("System.RuntimeTypeHandle");
- ienumerator_type = CoreLookupType ("System.Collections.IEnumerator");
- icloneable_type = CoreLookupType ("System.ICloneable");
- idisposable_type = CoreLookupType ("System.IDisposable");
- iasyncresult_type = CoreLookupType ("System.IAsyncResult");
- asynccallback_type = CoreLookupType ("System.AsyncCallback");
- monitor_type = CoreLookupType ("System.Threading.Monitor");
- intptr_type = CoreLookupType ("System.IntPtr");
+ runtime_field_handle_type = CoreLookupType ("System.RuntimeFieldHandle");
+ runtime_helpers_type = CoreLookupType ("System.Runtime.CompilerServices.RuntimeHelpers");
+ default_member_type = CoreLookupType ("System.Reflection.DefaultMemberAttribute");
+ runtime_handle_type = CoreLookupType ("System.RuntimeTypeHandle");
+ asynccallback_type = CoreLookupType ("System.AsyncCallback");
+ iasyncresult_type = CoreLookupType ("System.IAsyncResult");
+ ienumerator_type = CoreLookupType ("System.Collections.IEnumerator");
+ idisposable_type = CoreLookupType ("System.IDisposable");
+ icloneable_type = CoreLookupType ("System.ICloneable");
+ monitor_type = CoreLookupType ("System.Threading.Monitor");
+ intptr_type = CoreLookupType ("System.IntPtr");
+
+ attribute_usage_type = CoreLookupType ("System.AttributeUsageAttribute");
+ dllimport_type = CoreLookupType ("System.Runtime.InteropServices.DllImportAttribute");
+ methodimpl_attr_type = CoreLookupType ("System.Runtime.CompilerServices.MethodImplAttribute");
+ param_array_type = CoreLookupType ("System.ParamArrayAttribute");
+
+ unverifiable_code_type = CoreLookupType ("System.Security.UnverifiableCodeAttribute");
+
+ void_ptr_type = CoreLookupType ("System.Void*");
//
// Now load the default methods that we use.
//
Type [] string_string = { string_type, string_type };
- Type [] object_object = { object_type, object_type };
- Type [] runtime_type_handle = { runtime_handle_type };
- Type [] void_arg = { };
- Type [] object_arg = { object_type };
-
string_concat_string_string = GetMethod (
string_type, "Concat", string_string);
+
+ Type [] object_object = { object_type, object_type };
string_concat_object_object = GetMethod (
string_type, "Concat", object_object);
+
+ Type [] string_ = { string_type };
+ string_isinterneted_string = GetMethod (
+ string_type, "IsInterned", string_);
+
+ Type [] runtime_type_handle = { runtime_handle_type };
system_type_get_type_from_handle = GetMethod (
type_type, "GetTypeFromHandle", runtime_type_handle);
+
+ Type [] delegate_delegate = { delegate_type, delegate_type };
+ delegate_combine_delegate_delegate = GetMethod (
+ delegate_type, "Combine", delegate_delegate);
+
+ delegate_remove_delegate_delegate = GetMethod (
+ delegate_type, "Remove", delegate_delegate);
+
+ //
+ // Void arguments
+ //
+ Type [] void_arg = { };
object_getcurrent_void = GetMethod (
ienumerator_type, "get_Current", void_arg);
bool_movenext_void = GetMethod (
ienumerator_type, "MoveNext", void_arg);
void_dispose_void = GetMethod (
idisposable_type, "Dispose", void_arg);
+ int_get_offset_to_string_data = GetMethod (
+ runtime_helpers_type, "get_OffsetToStringData", void_arg);
+
+ //
+ // object arguments
+ //
+ Type [] object_arg = { object_type };
void_monitor_enter_object = GetMethod (
monitor_type, "Enter", object_arg);
void_monitor_exit_object = GetMethod (
monitor_type, "Exit", object_arg);
+
+ Type [] array_field_handle_arg = { array_type, runtime_field_handle_type };
+
+ void_initializearray_array_fieldhandle = GetMethod (
+ runtime_helpers_type, "InitializeArray", array_field_handle_arg);
+
+ //
+ // Array functions
+ //
+ Type [] int_arg = { int32_type };
+ int_getlength_int = GetMethod (
+ array_type, "GetLength", int_arg);
+
+ //
+ // Attributes
+ //
+ cons_param_array_attribute = GetConstructor (
+ param_array_type, void_arg);
+
}
+
+ const BindingFlags instance_and_static = BindingFlags.Static | BindingFlags.Instance;
- public MemberInfo [] FindMembers (Type t, MemberTypes mt, BindingFlags bf, MemberFilter filter, object criteria)
+ public MemberInfo [] FindMembers (Type t, MemberTypes mt, BindingFlags bf,
+ MemberFilter filter, object criteria)
{
- TypeContainer tc;
+ //
+ // We have to take care of arrays specially, because GetType on
+ // a TypeBuilder array will return a Type, not a TypeBuilder,
+ // and we can not call FindMembers on this type.
+ //
+ if (t.IsSubclassOf (TypeManager.array_type))
+ return TypeManager.array_type.FindMembers (mt, bf, filter, criteria);
+
+ if (!(t is TypeBuilder)){
+ //
+ // Since FindMembers will not lookup both static and instance
+ // members, we emulate this behaviour here.
+ //
+ if ((bf & instance_and_static) == instance_and_static){
+ MemberInfo [] i_members = t.FindMembers (
+ mt, bf & ~BindingFlags.Static, filter, criteria);
+ MemberInfo [] s_members = t.FindMembers (
+ mt, bf & ~BindingFlags.Instance, filter, criteria);
+
+ int i_len = i_members.Length;
+ int s_len = s_members.Length;
+ if (i_len > 0 || s_len > 0){
+ MemberInfo [] both = new MemberInfo [i_len + s_len];
+
+ i_members.CopyTo (both, 0);
+ s_members.CopyTo (both, i_len);
+
+ return both;
+ } else
+ return i_members;
+ }
+ return t.FindMembers (mt, bf, filter, criteria);
+ }
+
+ //
+ // FIXME: We should not have builder_to_blah everywhere,
+ // we should just have a builder_to_findmemberizable
+ // and have them implement a new ICanFindMembers interface
+ //
+ Enum e = (Enum) builder_to_enum [t];
+
+ if (e != null)
+ return e.FindMembers (mt, bf, filter, criteria);
+
+ Delegate del = (Delegate) builder_to_delegate [t];
- if (IsDelegateType (t))
- return null;
+ if (del != null)
+ return del.FindMembers (mt, bf, filter, criteria);
Interface iface = (Interface) builder_to_interface [t];
if (iface != null)
return iface.FindMembers (mt, bf, filter, criteria);
- tc = (TypeContainer) builder_to_container [t];
-
- if (tc == null)
- return t.FindMembers (mt, bf, filter, criteria);
- else
- return tc.FindMembers (mt, bf, filter, criteria);
-
+ TypeContainer tc = (TypeContainer) builder_to_container [t];
+
+ if (tc != null)
+ return tc.FindMembers (mt, bf, filter, criteria);
+
+ return null;
}
public static bool IsBuiltinType (Type t)
public static bool IsDelegateType (Type t)
{
- Delegate del = (Delegate) delegate_types [t];
-
- if (del != null)
+ if (t.IsSubclassOf (TypeManager.delegate_type))
return true;
else
return false;
}
-
+
+ public static bool IsEnumType (Type t)
+ {
+ if (t.IsSubclassOf (TypeManager.enum_type))
+ return true;
+ else
+ return false;
+ }
+
public static bool IsInterfaceType (Type t)
{
Interface iface = (Interface) builder_to_interface [t];
else
return false;
}
-
- // <summary>
- // Returns the User Defined Types
- // </summary>
+
+ /// <summary>
+ /// Returns the User Defined Types
+ /// </summary>
public ArrayList UserTypes {
get {
return user_types;
}
}
- static string GetSig (MethodBase mb)
+ static Hashtable builder_to_constant;
+
+ public static void RegisterConstant (FieldBuilder fb, Const c)
{
- if (mb is MethodBuilder || mb is ConstructorBuilder)
- return mb.ReflectedType.FullName + ":" + mb;
- else
- return mb.MethodHandle.ToString ();
+ if (builder_to_constant == null)
+ builder_to_constant = new PtrHashtable ();
+
+ if (builder_to_constant.Contains (fb))
+ return;
+
+ builder_to_constant.Add (fb, c);
+ }
+
+ public static Const LookupConstant (FieldBuilder fb)
+ {
+ if (builder_to_constant == null)
+ return null;
+
+ return (Const) builder_to_constant [fb];
}
- //
- // Gigantic work around for stupidity in System.Reflection.Emit follows
- //
- // Since System.Reflection.Emit can not return MethodBase.GetParameters
- // for anything which is dynamic, and we need this in a number of places,
- // we register this information here, and use it afterwards.
- //
- static public void RegisterMethod (MethodBase mb, Type [] args)
+ /// <summary>
+ /// Gigantic work around for missing features in System.Reflection.Emit follows.
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Since System.Reflection.Emit can not return MethodBase.GetParameters
+ /// for anything which is dynamic, and we need this in a number of places,
+ /// we register this information here, and use it afterwards.
+ /// </remarks>
+ static public bool RegisterMethod (MethodBase mb, InternalParameters ip, Type [] args)
{
- string s;
+ if (args == null)
+ args = NoTypes;
+
+ method_arguments.Add (mb, args);
+ method_internal_params.Add (mb, ip);
- s = GetSig (mb);
- method_arguments.Add (s, args);
+ return true;
+ }
+
+ static public InternalParameters LookupParametersByBuilder (MethodBase mb)
+ {
+ if (! (mb is ConstructorBuilder || mb is MethodBuilder))
+ return null;
+
+ if (method_internal_params.Contains (mb))
+ return (InternalParameters) method_internal_params [mb];
+ else
+ throw new Exception ("Argument for Method not registered" + mb);
}
- // <summary>
- // Returns the argument types for a method based on its methodbase
- //
- // For dynamic methods, we use the compiler provided types, for
- // methods from existing assemblies we load them from GetParameters,
- // and insert them into the cache
- // </summary>
+ /// <summary>
+ /// Returns the argument types for a method based on its methodbase
+ ///
+ /// For dynamic methods, we use the compiler provided types, for
+ /// methods from existing assemblies we load them from GetParameters,
+ /// and insert them into the cache
+ /// </summary>
static public Type [] GetArgumentTypes (MethodBase mb)
{
- string sig = GetSig (mb);
- object o = method_arguments [sig];
-
- if (method_arguments.Contains (sig))
- return (Type []) method_arguments [sig];
+ if (method_arguments.Contains (mb))
+ return (Type []) method_arguments [mb];
else {
ParameterInfo [] pi = mb.GetParameters ();
int c = pi.Length;
for (int i = 0; i < c; i++)
types [i] = pi [i].ParameterType;
- method_arguments.Add (sig, types);
+ method_arguments.Add (mb, types);
return types;
}
}
+
+ // <remarks>
+ // This is a workaround the fact that GetValue is not
+ // supported for dynamic types
+ // </remarks>
+ static Hashtable fields = new Hashtable ();
+ static public bool RegisterFieldValue (FieldBuilder fb, object value)
+ {
+ if (fields.Contains (fb))
+ return false;
+
+ fields.Add (fb, value);
+
+ return true;
+ }
+
+ static public object GetValue (FieldBuilder fb)
+ {
+ return fields [fb];
+ }
+
+ static Hashtable fieldbuilders_to_fields = new Hashtable ();
+ static public bool RegisterField (FieldBuilder fb, Field f)
+ {
+ if (fieldbuilders_to_fields.Contains (fb))
+ return false;
+
+ fieldbuilders_to_fields.Add (fb, f);
+ return true;
+ }
+
+ static public Field GetField (FieldInfo fb)
+ {
+ return (Field) fieldbuilders_to_fields [fb];
+ }
+
+ static Hashtable events;
+
+ static public bool RegisterEvent (MyEventBuilder eb, MethodBase add, MethodBase remove)
+ {
+ if (events == null)
+ events = new Hashtable ();
+
+ if (events.Contains (eb))
+ return false;
+
+ events.Add (eb, new Pair (add, remove));
+
+ return true;
+ }
+
+ static public MethodInfo GetAddMethod (EventInfo ei)
+ {
+ if (ei is MyEventBuilder) {
+ Pair pair = (Pair) events [ei];
+
+ return (MethodInfo) pair.First;
+ } else
+ return ei.GetAddMethod ();
+ }
+
+ static public MethodInfo GetRemoveMethod (EventInfo ei)
+ {
+ if (ei is MyEventBuilder) {
+ Pair pair = (Pair) events [ei];
+
+ return (MethodInfo) pair.Second;
+ } else
+ return ei.GetAddMethod ();
+ }
static Hashtable properties;
- static public void RegisterProperty (PropertyBuilder pb, MethodBase get, MethodBase set)
+ static public bool RegisterProperty (PropertyBuilder pb, MethodBase get, MethodBase set)
{
if (properties == null)
properties = new Hashtable ();
- properties.Add (pb, new DictionaryEntry (get, set));
+ if (properties.Contains (pb))
+ return false;
+
+ properties.Add (pb, new Pair (get, set));
+
+ return true;
}
+ //
+ // FIXME: we need to return the accessors depending on whether
+ // they are visible or not.
+ //
static public MethodInfo [] GetAccessors (PropertyInfo pi)
{
MethodInfo [] ret;
-
+
if (pi is PropertyBuilder){
- DictionaryEntry de = (DictionaryEntry) properties [pi];
+ Pair pair = (Pair) properties [pi];
ret = new MethodInfo [2];
- ret [0] = (MethodInfo) de.Key;
- ret [1] = (MethodInfo) de.Value;
+ ret [0] = (MethodInfo) pair.First;
+ ret [1] = (MethodInfo) pair.Second;
return ret;
+ } else {
+ MethodInfo [] mi = new MethodInfo [2];
+
+ //
+ // Why this and not pi.GetAccessors?
+ // Because sometimes index 0 is the getter
+ // sometimes it is 1
+ //
+ mi [0] = pi.GetGetMethod (true);
+ mi [1] = pi.GetSetMethod (true);
+
+ return mi;
+ }
+ }
+
+ static public MethodInfo GetPropertyGetter (PropertyInfo pi)
+ {
+ if (pi is PropertyBuilder){
+ Pair de = (Pair) properties [pi];
+
+ return (MethodInfo) de.Second;
} else
- return pi.GetAccessors ();
+ return pi.GetSetMethod ();
}
+ static public MethodInfo GetPropertySetter (PropertyInfo pi)
+ {
+ if (pi is PropertyBuilder){
+ Pair de = (Pair) properties [pi];
+
+ return (MethodInfo) de.First;
+ } else
+ return pi.GetGetMethod ();
+ }
+
// <remarks>
// The following is used to check if a given type implements an interface.
// The cache helps us reduce the expense of hitting Type.GetInterfaces everytime.
// </remarks>
static Hashtable type_interface_cache;
-
public static bool ImplementsInterface (Type t, Type iface)
{
- Type [] interfaces = (Type []) type_interface_cache [t];
+ Type [] interfaces;
- if (interfaces == null) {
+ do {
interfaces = t.GetInterfaces ();
- // Note that interfaces is an empty array if the type
- // implements or inherits no interfaces so it makes sense for us to
- // store that so as to not hit the expensive lookup again.
- type_interface_cache [t] = interfaces;
+ for (int i = interfaces.Length; i > 0; ){
+ i--;
+ if (interfaces [i] == iface)
+ return true;
+ }
+ t = t.BaseType;
+ } while (t != null);
+
+ return false;
+ }
+
+ //
+ // This is needed, because enumerations from assemblies
+ // do not report their underlyingtype, but they report
+ // themselves
+ //
+ public static Type EnumToUnderlying (Type t)
+ {
+ t = t.UnderlyingSystemType;
+ if (!TypeManager.IsEnumType (t))
+ return t;
+
+ TypeCode tc = Type.GetTypeCode (t);
+
+ switch (tc){
+ case TypeCode.Boolean:
+ return TypeManager.bool_type;
+ case TypeCode.Byte:
+ return TypeManager.byte_type;
+ case TypeCode.SByte:
+ return TypeManager.sbyte_type;
+ case TypeCode.Char:
+ return TypeManager.char_type;
+ case TypeCode.Int16:
+ return TypeManager.short_type;
+ case TypeCode.UInt16:
+ return TypeManager.ushort_type;
+ case TypeCode.Int32:
+ return TypeManager.int32_type;
+ case TypeCode.UInt32:
+ return TypeManager.uint32_type;
+ case TypeCode.Int64:
+ return TypeManager.int64_type;
+ case TypeCode.UInt64:
+ return TypeManager.uint64_type;
}
+ throw new Exception ("Unhandled typecode in enum" + tc);
+ }
- for (int i = interfaces.Length; i > 0; ) {
- i--;
- if (interfaces [i] == iface)
- return true;
+ /// <summary>
+ /// Utility function that can be used to probe whether a type
+ /// is managed or not.
+ /// </summary>
+ public static bool VerifyUnManaged (Type t, Location loc)
+ {
+ if (t.IsValueType){
+ //
+ // FIXME: this is more complex, we actually need to
+ // make sure that the type does not contain any
+ // classes itself
+ //
+ return true;
}
- return false;
+ Report.Error (
+ 208, loc,
+ "Cannot take the address or size of a variable of a managed type ('" +
+ CSharpName (t) + "')");
+ return false;
}
-
- // <summary>
- // Returns the name of the indexer in a given type. The default
- // is not always `Item'. The user can change this behaviour by
- // using the DefaultMemberAttribute in the class.
- //
- // For example, the String class indexer is named `Chars' not `Item'
- // </summary>
+ /// <summary>
+ /// Returns the name of the indexer in a given type.
+ /// </summary>
+ /// <remarks>
+ /// The default is not always `Item'. The user can change this behaviour by
+ /// using the DefaultMemberAttribute in the class.
+ ///
+ /// For example, the String class indexer is named `Chars' not `Item'
+ /// </remarks>
public static string IndexerPropertyName (Type t)
{
- //
- // FIXME: Replace with something that works around S.R.E failure
- //
-#if FIXME
- System.Attribute attr;
+ if (t is TypeBuilder) {
+ TypeContainer tc = (TypeContainer) builder_to_container [t];
+
+ Attributes attrs = tc.OptAttributes;
+
+ if (attrs == null || attrs.AttributeSections == null)
+ return "Item";
+
+ foreach (AttributeSection asec in attrs.AttributeSections) {
+
+ if (asec.Attributes == null)
+ continue;
- attr = System.Attribute.GetCustomAttribute (t, TypeManager.default_member_type);
+ foreach (Attribute a in asec.Attributes) {
+ if (a.Name.IndexOf ("DefaultMember") != -1) {
+ ArrayList pos_args = (ArrayList) a.Arguments [0];
+ Expression e = ((Argument) pos_args [0]).expr;
+
+ if (e is StringConstant)
+ return ((StringConstant) e).Value;
+ }
+ }
+ }
+
+ return "Item";
+ }
+
+ System.Attribute attr = System.Attribute.GetCustomAttribute (t, TypeManager.default_member_type);
if (attr != null)
- {
- DefaultMemberAttribute dma = (DefaultMemberAttribute) attr;
-
- return dma.MemberName;
- }
-#endif
+ {
+ DefaultMemberAttribute dma = (DefaultMemberAttribute) attr;
+
+ return dma.MemberName;
+ }
+
return "Item";
}
+ public static void MakePinned (LocalBuilder builder)
+ {
+ //
+ // FIXME: Flag the "LocalBuilder" type as being
+ // pinned. Figure out API.
+ //
+ }
}
}