static public Type indexer_name_type;
static public Type exception_type;
static public Type invalid_operation_exception_type;
- static public object obsolete_attribute_type;
+ static public Type obsolete_attribute_type;
static public object conditional_attribute_type;
static public Type in_attribute_type;
+ static public Type cls_compliant_attribute_type;
+ static public Type typed_reference_type;
+ static public Type arg_iterator_type;
+ static public Type mbr_type;
+ static public Type struct_layout_attribute_type;
+ static public Type field_offset_attribute_type;
//
// An empty array of types
static public MethodInfo string_concat_string_string;
static public MethodInfo string_concat_string_string_string;
static public MethodInfo string_concat_string_string_string_string;
+ static public MethodInfo string_concat_string_dot_dot_dot;
static public MethodInfo string_concat_object_object;
+ static public MethodInfo string_concat_object_object_object;
+ static public MethodInfo string_concat_object_dot_dot_dot;
static public MethodInfo string_isinterneted_string;
static public MethodInfo system_type_get_type_from_handle;
static public MethodInfo object_getcurrent_void;
static Hashtable method_internal_params;
// <remarks>
- // Keeps track of attribute types
+ // Keeps track of methods
// </remarks>
- static Hashtable builder_to_attr;
+ static Hashtable builder_to_method;
+ static Hashtable builder_to_method_2;
// <remarks>
- // Keeps track of methods
+ // Contains all public types from referenced assemblies.
+ // This member is used only if CLS Compliance verification is required.
// </remarks>
-
- static Hashtable builder_to_method;
+ public static Hashtable all_imported_types;
struct Signature {
public string name;
method_arguments = null;
indexer_arguments = null;
method_internal_params = null;
- builder_to_attr = null;
builder_to_method = null;
fields = null;
references = null;
negative_hits = null;
- attr_to_allowmult = null;
builder_to_constant = null;
fieldbuilders_to_fields = null;
events = null;
typecontainers = new Hashtable ();
builder_to_declspace = new PtrHashtable ();
- builder_to_attr = new PtrHashtable ();
builder_to_method = new PtrHashtable ();
+ builder_to_method_2 = new PtrHashtable ();
method_arguments = new PtrHashtable ();
method_internal_params = new PtrHashtable ();
indexer_arguments = new PtrHashtable ();
builder_to_declspace.Add (t, i);
}
+
+ [Obsolete("Will be removed very soon")]
public static void AddMethod (MethodBuilder builder, MethodData method)
{
builder_to_method.Add (builder, method);
}
- public static void RegisterAttrType (Type t, TypeContainer tc)
+ public static void AddMethod2 (MethodBase builder, IMethodData method)
+ {
+ builder_to_method_2.Add (builder, method);
+ }
+
+ public static IMethodData GetMethod (MethodBase builder)
{
- builder_to_attr.Add (t, tc);
+ return (IMethodData) builder_to_method_2 [builder];
}
/// <summary>
{
return builder_to_declspace [t] as Enum;
}
-
- public static TypeContainer LookupAttr (Type t)
+
+ public static Class LookupClass (Type t)
{
- return (TypeContainer) builder_to_attr [t];
+ return (Class) builder_to_declspace [t];
}
/// <summary>
modules = n;
}
+ public static Module[] Modules {
+ get {
+ return modules;
+ }
+ }
+
static Hashtable references = new Hashtable ();
//
//
if (ret == null){
if (references [t] == null)
- references [t] = CodeGen.ModuleBuilder.GetType (tname);
+ references [t] = CodeGen.Module.Builder.GetType (tname);
ret = (Type) references [t];
}
//
if (ret == null){
if (pointers [t] == null)
- pointers [t] = CodeGen.ModuleBuilder.GetType (tname);
+ pointers [t] = CodeGen.Module.Builder.GetType (tname);
ret = (Type) pointers [t];
}
}
}
} else {
- foreach (Assembly a in assemblies){
- foreach (Type t in a.GetTypes ()){
+ Hashtable cache = new Hashtable ();
+ cache.Add ("", null);
+ foreach (Assembly a in assemblies) {
+ foreach (Type t in a.GetExportedTypes ()) {
string ns = t.Namespace;
-
- // t.Namespace returns null for <PrivateImplDetails>
- if (ns == ""|| ns == null)
+ if (ns == null || cache.Contains (ns))
continue;
+
Namespace.LookupNamespace (ns, true);
+ cache.Add (ns, null);
}
}
}
}
+ /// <summary>
+ /// Fills static table with exported types from all referenced assemblies.
+ /// This information is required for CLS Compliance tests.
+ /// </summary>
+ public static void LoadAllImportedTypes ()
+ {
+ if (!CodeGen.Assembly.IsClsCompliant)
+ return;
+
+ all_imported_types = new Hashtable ();
+ foreach (Assembly a in assemblies) {
+ foreach (Type t in a.GetExportedTypes ()) {
+ all_imported_types [t.FullName] = t;
+ }
+ }
+ }
+
public static bool NamespaceClash (string name, Location loc)
{
if (Namespace.LookupNamespace (name, false) == null)
+ match.Groups [2].Captures [0].Value;
}
+ /// <summary>
+ /// Returns the signature of the method with full namespace classification
+ /// </summary>
+ static public string GetFullNameSignature (MemberInfo mi)
+ {
+ string n = mi.Name;
+ if (n == ".ctor")
+ n = mi.DeclaringType.Name;
+
+ return mi.DeclaringType.FullName.Replace ('+', '.') + '.' + n;
+ }
+
+ /// <summary>
+ /// Returns the signature of the property and indexer
+ /// </summary>
+ static public string CSharpSignature (PropertyBuilder pb, bool is_indexer)
+ {
+ if (!is_indexer) {
+ return GetFullNameSignature (pb);
+ }
+
+ MethodBase mb = pb.GetSetMethod (true) != null ? pb.GetSetMethod (true) : pb.GetGetMethod (true);
+ string signature = GetFullNameSignature (mb);
+ string arg = TypeManager.LookupParametersByBuilder (mb).ParameterDesc (0);
+ return String.Format ("{0}.this[{1}]", signature.Substring (0, signature.LastIndexOf ('.')), arg);
+ }
+
/// <summary>
/// Returns the signature of the method
/// </summary>
}
sig += ")";
- return mb.DeclaringType.Name + "." + mb.Name + sig;
+ return GetFullNameSignature (mb) + sig;
}
/// <summary>
if (t == null){
Report.Error (518, "The predefined type `" + name + "' is not defined or imported");
- Environment.Exit (0);
+ Environment.Exit (1);
}
return t;
marshal_as_attr_type = CoreLookupType ("System.Runtime.InteropServices.MarshalAsAttribute");
param_array_type = CoreLookupType ("System.ParamArrayAttribute");
in_attribute_type = CoreLookupType ("System.Runtime.InteropServices.InAttribute");
+ typed_reference_type = CoreLookupType ("System.TypedReference");
+ arg_iterator_type = CoreLookupType ("System.ArgIterator");
+ mbr_type = CoreLookupType ("System.MarshalByRefObject");
//
// Sigh. Remove this before the release. Wonder what versions of Mono
//
obsolete_attribute_type = CoreLookupType ("System.ObsoleteAttribute");
conditional_attribute_type = CoreLookupType ("System.Diagnostics.ConditionalAttribute");
+ cls_compliant_attribute_type = CoreLookupType ("System.CLSCompliantAttribute");
+ struct_layout_attribute_type = CoreLookupType ("System.Runtime.InteropServices.StructLayoutAttribute");
+ field_offset_attribute_type = CoreLookupType ("System.Runtime.InteropServices.FieldOffsetAttribute");
//
// When compiling corlib, store the "real" types here.
args [2] = enum_type;
args [3] = void_type;
- set_corlib_type_builders.Invoke (CodeGen.AssemblyBuilder, args);
+ set_corlib_type_builders.Invoke (CodeGen.Assembly.Builder, args);
} else {
// Compatibility for an older version of the class libs.
set_corlib_type_builders = GetMethod (
args [1] = value_type;
args [2] = enum_type;
- set_corlib_type_builders.Invoke (CodeGen.AssemblyBuilder, args);
+ set_corlib_type_builders.Invoke (CodeGen.Assembly.Builder, args);
}
}
Type [] string_string_string_string = { string_type, string_type, string_type, string_type };
string_concat_string_string_string_string = GetMethod (
string_type, "Concat", string_string_string_string);
+ Type[] params_string = { TypeManager.LookupType ("System.String[]") };
+ string_concat_string_dot_dot_dot = GetMethod (
+ string_type, "Concat", params_string);
Type [] object_object = { object_type, object_type };
string_concat_object_object = GetMethod (
string_type, "Concat", object_object);
+ Type [] object_object_object = { object_type, object_type, object_type };
+ string_concat_object_object_object = GetMethod (
+ string_type, "Concat", object_object_object);
+ Type[] params_object = { TypeManager.LookupType ("System.Object[]") };
+ string_concat_object_dot_dot_dot = GetMethod (
+ string_type, "Concat", params_object);
Type [] string_ = { string_type };
string_isinterneted_string = GetMethod (
/// our return value will already contain all inherited members and the caller don't need
/// to check base classes and interfaces anymore.
/// </summary>
- private static MemberList MemberLookup_FindMembers (Type t, MemberTypes mt, BindingFlags bf,
+ private static MemberInfo [] MemberLookup_FindMembers (Type t, MemberTypes mt, BindingFlags bf,
string name, out bool used_cache)
{
//
}
// If there is no MemberCache, we need to use the "normal" FindMembers.
-
+ // Note, this is a VERY uncommon route!
+
MemberList list;
Timer.StartTimer (TimerType.FindMembers);
list = decl.FindMembers (mt, bf | BindingFlags.DeclaredOnly,
Timer.StopTimer (TimerType.FindMembers);
used_cache = false;
- return list;
+ return (MemberInfo []) list;
}
//
return false;
}
+ public static bool IsBuiltinType (TypeContainer tc)
+ {
+ return IsBuiltinType (tc.TypeBuilder);
+ }
+
//
// This is like IsBuiltinType, but lacks decimal_type, we should also clean up
// the pieces in the code where we use IsBuiltinType and special case decimal_type.
if (t is TypeBuilder){
TypeContainer tc = LookupTypeContainer (t);
- foreach (Field f in tc.Fields){
- if (f.FieldBuilder.IsStatic)
- continue;
- if (!IsUnmanagedType (f.FieldBuilder.FieldType))
- return false;
- }
+ if (tc.Fields != null){
+ foreach (Field f in tc.Fields){
+ if (f.FieldBuilder.IsStatic)
+ continue;
+ if (!IsUnmanagedType (f.FieldBuilder.FieldType))
+ return false;
+ }
+ } else
+ return true;
} else {
FieldInfo [] fields = t.GetFields ();
}
}
- static Hashtable attr_to_allowmult;
-
- public static void RegisterAttributeAllowMultiple (Type attr_type, bool allow)
- {
- if (attr_to_allowmult == null)
- attr_to_allowmult = new PtrHashtable ();
-
- if (attr_to_allowmult.Contains (attr_type))
- return;
-
- attr_to_allowmult.Add (attr_type, allow);
-
- }
-
- public static bool AreMultipleAllowed (Type attr_type)
- {
- if (!(attr_type is TypeBuilder)) {
- System.Attribute [] attrs = System.Attribute.GetCustomAttributes (attr_type);
-
- foreach (System.Attribute tmp in attrs)
- if (tmp is AttributeUsageAttribute) {
- return ((AttributeUsageAttribute) tmp).AllowMultiple;
- }
-
- return false;
- }
-
- if (attr_to_allowmult == null)
- return false;
-
- return (bool) attr_to_allowmult [attr_type];
- }
-
static Hashtable builder_to_constant;
public static void RegisterConstant (FieldBuilder fb, Const c)
return true;
}
+ public static bool CheckStructCycles (TypeContainer tc, Hashtable seen)
+ {
+ Hashtable hash = new Hashtable ();
+ return CheckStructCycles (tc, seen, hash);
+ }
+
+ public static bool CheckStructCycles (TypeContainer tc, Hashtable seen,
+ Hashtable hash)
+ {
+ if (!(tc is Struct) || IsBuiltinType (tc))
+ return true;
+
+ //
+ // `seen' contains all types we've already visited.
+ //
+ if (seen.Contains (tc))
+ return true;
+ seen.Add (tc, null);
+
+ if (tc.Fields == null)
+ return true;
+
+ foreach (Field field in tc.Fields) {
+ if (field.FieldBuilder.IsStatic)
+ continue;
+
+ Type ftype = field.FieldBuilder.FieldType;
+ TypeContainer ftc = LookupTypeContainer (ftype);
+ if (ftc == null)
+ continue;
+
+ if (hash.Contains (ftc)) {
+ Report.Error (523, tc.Location,
+ "Struct member `{0}.{1}' of type `{2}' " +
+ "causes a cycle in the struct layout",
+ tc.Name, field.Name, ftc.Name);
+ return false;
+ }
+
+ //
+ // `hash' contains all types in the current path.
+ //
+ hash.Add (tc, null);
+
+ bool ok = CheckStructCycles (ftc, seen, hash);
+
+ hash.Remove (tc);
+
+ if (!ok)
+ return false;
+
+ if (!seen.Contains (ftc))
+ seen.Add (ftc, null);
+ }
+
+ return true;
+ }
+
/// <summary>
/// Given an array of interface types, expand and eliminate repeated ocurrences
/// of an interface.
return TypeManager.object_type;
if (t == typeof (System.Type))
return TypeManager.type_type;
+ if (t == typeof (System.IntPtr))
+ return TypeManager.intptr_type;
return t;
}
}
return "Item";
}
+ static MethodInfo pinned_method = null;
public static void MakePinned (LocalBuilder builder)
{
- //
- // FIXME: Flag the "LocalBuilder" type as being
- // pinned. Figure out API.
- //
+ if (pinned_method == null) {
+ pinned_method = typeof (LocalBuilder).GetMethod ("MakePinned", BindingFlags.Instance | BindingFlags.NonPublic);
+ if (pinned_method == null) {
+ Report.Warning (-24, new Location (-1), "Microsoft.NET does not support making pinned variables." +
+ "This code may cause errors on a runtime with a moving GC");
+
+ return;
+ }
+ }
+
+ pinned_method.Invoke (builder, null);
}
//
// The name is assumed to be the same.
//
- public static ArrayList CopyNewMethods (ArrayList target_list, MemberList new_members)
+ public static ArrayList CopyNewMethods (ArrayList target_list, IList new_members)
{
if (target_list == null){
target_list = new ArrayList ();
[Flags]
public enum MethodFlags {
- IsObsolete = 1,
- IsObsoleteError = 1 << 1,
ShouldIgnore = 1 << 2
}
continue;
}
System.Attribute a = (System.Attribute) ta;
- if (a.TypeId == TypeManager.obsolete_attribute_type){
- ObsoleteAttribute oa = (ObsoleteAttribute) a;
-
- string method_desc = TypeManager.CSharpSignature (mb);
-
- if (oa.IsError) {
- Report.Error (619, loc, "Method `" + method_desc +
- "' is obsolete: `" + oa.Message + "'");
- return MethodFlags.IsObsoleteError;
- } else
- Report.Warning (618, loc, "Method `" + method_desc +
- "' is obsolete: `" + oa.Message + "'");
-
- flags |= MethodFlags.IsObsolete;
-
- continue;
- }
//
// Skip over conditional code.
// it cannot do so through an instance of the base class (CS1540).
if (!mb.IsStatic && (closure_invocation_type != closure_qualifier_type) &&
(closure_qualifier_type != null) &&
- closure_invocation_type.IsSubclassOf (closure_qualifier_type))
+ closure_invocation_type.IsSubclassOf (closure_qualifier_type) &&
+ !TypeManager.IsNestedChildOf (closure_invocation_type, closure_qualifier_type))
return false;
return true;
// it cannot do so through an instance of the base class (CS1540).
if (!fi.IsStatic && (closure_invocation_type != closure_qualifier_type) &&
(closure_qualifier_type != null) &&
- closure_invocation_type.IsSubclassOf (closure_qualifier_type))
+ closure_invocation_type.IsSubclassOf (closure_qualifier_type) &&
+ !TypeManager.IsNestedChildOf (closure_invocation_type, closure_qualifier_type))
return false;
return true;
}
}
+ // This is from the first time we find a method
+ // in most cases, we do not actually find a method in the base class
+ // so we can just ignore it, and save the arraylist allocation
+ MemberInfo [] first_members_list = null;
+ bool use_first_members_list = false;
+
do {
- MemberList list;
+ MemberInfo [] list;
//
// `NonPublic' is lame, because it includes both protected and
current_type = TypeManager.object_type;
}
- if (list.Count == 0)
+ if (list.Length == 0)
continue;
//
// searches, which means that our above FindMembers will
// return two copies of the same.
//
- if (list.Count == 1 && !(list [0] is MethodBase)){
- return (MemberInfo []) list;
+ if (list.Length == 1 && !(list [0] is MethodBase)){
+ return list;
}
//
// name
//
if (list [0] is PropertyInfo)
- return (MemberInfo []) list;
+ return list;
//
// We found an event: the cache lookup returns both the event and
// its private field.
//
if (list [0] is EventInfo) {
- if ((list.Count == 2) && (list [1] is FieldInfo))
+ if ((list.Length == 2) && (list [1] is FieldInfo))
return new MemberInfo [] { list [0] };
// Oooops
// mode.
//
- method_list = CopyNewMethods (method_list, list);
- mt &= (MemberTypes.Method | MemberTypes.Constructor);
+ if (first_members_list != null) {
+ if (use_first_members_list) {
+ method_list = CopyNewMethods (method_list, first_members_list);
+ use_first_members_list = false;
+ }
+
+ method_list = CopyNewMethods (method_list, list);
+ } else {
+ first_members_list = list;
+ use_first_members_list = true;
+ mt &= (MemberTypes.Method | MemberTypes.Constructor);
+ }
} while (searching);
+
+ if (use_first_members_list) {
+ foreach (MemberInfo mi in first_members_list) {
+ if (! (mi is MethodBase)) {
+ method_list = CopyNewMethods (method_list, first_members_list);
+ return (MemberInfo []) method_list.ToArray (typeof (MemberInfo));
+ }
+ }
+ return (MemberInfo []) first_members_list;
+ }
if (method_list != null && method_list.Count > 0)
return (MemberInfo []) method_list.ToArray (typeof (MemberInfo));
public MemberList FindMembers (MemberTypes mt, BindingFlags bf, string name,
MemberFilter filter, object criteria)
{
- return member_cache.FindMembers (mt, bf, name, filter, criteria);
+ return new MemberList (member_cache.FindMembers (mt, bf, name, filter, criteria));
}
public MemberCache MemberCache {