X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fflowanalysis.cs;h=267879c043b75ef8dc40f3df4f150503cd69317c;hb=f98d0799d89401853f59e4427764932d633b8935;hp=183250cde8bf01f673318052672c0e1b67efa68d;hpb=e4aa060bea5bc82362b9ea2c66de4c8da782a061;p=mono.git diff --git a/mcs/mcs/flowanalysis.cs b/mcs/mcs/flowanalysis.cs index 183250cde8b..267879c043b 100644 --- a/mcs/mcs/flowanalysis.cs +++ b/mcs/mcs/flowanalysis.cs @@ -59,10 +59,9 @@ namespace Mono.CSharp public TypeInfo[] SubStructInfo; readonly StructInfo struct_info; - private static Dictionary type_hash; static readonly TypeInfo simple_type = new TypeInfo (1); - + static TypeInfo () { Reset (); @@ -70,7 +69,6 @@ namespace Mono.CSharp public static void Reset () { - type_hash = new Dictionary (); StructInfo.field_type_hash = new Dictionary (); } @@ -105,23 +103,34 @@ namespace Mono.CSharp return struct_info.GetStructField (name); } - public static TypeInfo GetTypeInfo (TypeSpec type) + public static TypeInfo GetTypeInfo (TypeSpec type, IMemberContext context) { if (!type.IsStruct) return simple_type; TypeInfo info; - if (type_hash.TryGetValue (type, out info)) - return info; + Dictionary type_hash; + if (type.BuiltinType > 0) { + // Don't cache built-in types, they are null in most cases except for + // corlib compilation when we need to distinguish between declaration + // and referencing + type_hash = null; + } else { + type_hash = context.Module.TypeInfoCache; + if (type_hash.TryGetValue (type, out info)) + return info; + } - var struct_info = StructInfo.GetStructInfo (type); + var struct_info = StructInfo.GetStructInfo (type, context); if (struct_info != null) { info = new TypeInfo (struct_info, 0); } else { info = simple_type; } - type_hash.Add (type, info); + if (type_hash != null) + type_hash.Add (type, info); + return info; } @@ -184,11 +193,11 @@ namespace Mono.CSharp // // We only need one instance per type // - StructInfo (TypeSpec type) + StructInfo (TypeSpec type, IMemberContext context) { field_type_hash.Add (type, this); - fields = MemberCache.GetAllFieldsForDefiniteAssignment (type); + fields = MemberCache.GetAllFieldsForDefiniteAssignment (type, context); struct_field_hash = new Dictionary (); field_hash = new Dictionary (fields.Count); @@ -202,7 +211,7 @@ namespace Mono.CSharp var field = fields [i]; if (field.MemberType.IsStruct) - sinfo [i] = GetStructInfo (field.MemberType); + sinfo [i] = GetStructInfo (field.MemberType, context); if (sinfo [i] == null) field_hash.Add (field.Name, ++Length); @@ -260,16 +269,16 @@ namespace Mono.CSharp return null; } - public static StructInfo GetStructInfo (TypeSpec type) + public static StructInfo GetStructInfo (TypeSpec type, IMemberContext context) { - if (type.BuiltinType > 0) + if (type.BuiltinType > 0 && type != context.CurrentType) return null; StructInfo info; if (field_type_hash.TryGetValue (type, out info)) return info; - return new StructInfo (type); + return new StructInfo (type, context); } } } @@ -305,11 +314,11 @@ namespace Mono.CSharp VariableInfo[] sub_info; - VariableInfo (string name, TypeSpec type, int offset) + VariableInfo (string name, TypeSpec type, int offset, IMemberContext context) { this.Name = name; this.Offset = offset; - this.TypeInfo = TypeInfo.GetTypeInfo (type); + this.TypeInfo = TypeInfo.GetTypeInfo (type, context); Length = TypeInfo.TotalLength; @@ -343,14 +352,14 @@ namespace Mono.CSharp public static VariableInfo Create (BlockContext bc, LocalVariable variable) { - var info = new VariableInfo (variable.Name, variable.Type, bc.AssignmentInfoOffset); + var info = new VariableInfo (variable.Name, variable.Type, bc.AssignmentInfoOffset, bc); bc.AssignmentInfoOffset += info.Length; return info; } public static VariableInfo Create (BlockContext bc, Parameter parameter) { - var info = new VariableInfo (parameter.Name, parameter.Type, bc.AssignmentInfoOffset) { + var info = new VariableInfo (parameter.Name, parameter.Type, bc.AssignmentInfoOffset, bc) { IsParameter = true }; @@ -543,7 +552,7 @@ namespace Mono.CSharp public static DefiniteAssignmentBitSet operator & (DefiniteAssignmentBitSet a, DefiniteAssignmentBitSet b) { - if (AreEqual (a, b)) + if (IsEqual (a, b)) return a; DefiniteAssignmentBitSet res; @@ -566,7 +575,7 @@ namespace Mono.CSharp public static DefiniteAssignmentBitSet operator | (DefiniteAssignmentBitSet a, DefiniteAssignmentBitSet b) { - if (AreEqual (a, b)) + if (IsEqual (a, b)) return a; DefiniteAssignmentBitSet res; @@ -669,7 +678,7 @@ namespace Mono.CSharp large_bits[index >> 5] |= (1 << (index & 31)); } - public static bool AreEqual (DefiniteAssignmentBitSet a, DefiniteAssignmentBitSet b) + static bool IsEqual (DefiniteAssignmentBitSet a, DefiniteAssignmentBitSet b) { if (a.large_bits == null) return (a.bits & ~copy_on_write_flag) == (b.bits & ~copy_on_write_flag); @@ -681,5 +690,20 @@ namespace Mono.CSharp return true; } + + public static bool IsIncluded (DefiniteAssignmentBitSet set, DefiniteAssignmentBitSet test) + { + var set_bits = set.large_bits; + if (set_bits == null) + return (set.bits & test.bits & ~copy_on_write_flag) == (set.bits & ~copy_on_write_flag); + + var test_bits = test.large_bits; + for (int i = 0; i < set_bits.Length; ++i) { + if ((set_bits[i] & test_bits[i]) != set_bits[i]) + return false; + } + + return true; + } } }