locals |= child.locals;
+ // throw away un-necessary information about variables in child blocks
+ if (locals.Count != CountLocals)
+ locals = new MyBitVector (locals, CountLocals);
+
if (overwrite)
is_unreachable = new_isunr;
else
return CurrentUsageVector.IsAssigned (vi, false) || CurrentUsageVector.IsFieldAssigned (vi, field_name);
}
+ protected static Report Report {
+ get { return RootContext.ToplevelTypes.Compiler.Report; }
+ }
+
public void SetAssigned (VariableInfo vi)
{
CurrentUsageVector.SetAssigned (vi);
return false;
}
- public static void Error_UnknownLabel (Location loc, string label)
+ public static void Error_UnknownLabel (Location loc, string label, Report Report)
{
Report.Error(159, loc, "The label `{0}:' could not be found within the scope of the goto statement",
label);
throw new InternalErrorException ("Shouldn't get here");
if (Parent == null) {
- Error_UnknownLabel (goto_stmt.loc, name);
+ Error_UnknownLabel (goto_stmt.loc, name, Report);
return false;
}
int errors = Report.Errors;
Parent.AddReturnOrigin (vector, exit_stmt);
if (errors == Report.Errors)
- exit_stmt.Error_FinallyClause ();
+ exit_stmt.Error_FinallyClause (Report);
} else {
saved_origins = new ReturnOrigin (saved_origins, vector, exit_stmt);
}
// </summary>
public TypeInfo[] SubStructInfo;
- protected readonly StructInfo struct_info;
- private static Hashtable type_hash = new Hashtable ();
+ readonly StructInfo struct_info;
+ private static Hashtable type_hash;
+
+ static TypeInfo ()
+ {
+ Reset ();
+ }
+
+ public static void Reset ()
+ {
+ type_hash = new Hashtable ();
+ StructInfo.field_type_hash = new Hashtable ();
+ }
public static TypeInfo GetTypeInfo (Type type)
{
}
}
- protected TypeInfo (StructInfo struct_info, int offset)
+ TypeInfo (StructInfo struct_info, int offset)
{
this.struct_info = struct_info;
this.Offset = offset;
// A struct's constructor must always assign all fields.
// This method checks whether it actually does so.
// </summary>
- public bool IsFullyInitialized (FlowBranching branching, VariableInfo vi, Location loc)
+ public bool IsFullyInitialized (BlockContext ec, VariableInfo vi, Location loc)
{
if (struct_info == null)
return true;
bool ok = true;
+ FlowBranching branching = ec.CurrentBranching;
for (int i = 0; i < struct_info.Count; i++) {
FieldInfo field = struct_info.Fields [i];
if (!branching.IsFieldAssigned (vi, field.Name)) {
FieldBase fb = TypeManager.GetField (field);
- if (fb != null && (fb.ModFlags & Modifiers.BACKING_FIELD) != 0) {
- Report.Error (843, loc,
+ if (fb is Property.BackingField) {
+ ec.Report.Error (843, loc,
"An automatically implemented property `{0}' must be fully assigned before control leaves the constructor. Consider calling default contructor",
fb.GetSignatureForError ());
} else {
- Report.Error (171, loc,
+ ec.Report.Error (171, loc,
"Field `{0}' must be fully assigned before control leaves the constructor",
TypeManager.GetFullNameSignature (field));
}
Type, Offset, Length, TotalLength);
}
- protected class StructInfo {
+ class StructInfo {
public readonly Type Type;
public readonly FieldInfo[] Fields;
public readonly TypeInfo[] StructFields;
public readonly int TotalLength;
public readonly bool HasStructFields;
- private static Hashtable field_type_hash = new Hashtable ();
+ public static Hashtable field_type_hash;
private Hashtable struct_field_hash;
private Hashtable field_hash;
field_type_hash.Add (type, this);
- if (type.Module == CodeGen.Module.Builder) {
+ if (TypeManager.IsBeingCompiled (type)) {
TypeContainer tc = TypeManager.LookupTypeContainer (TypeManager.DropGenericTypeArguments (type));
ArrayList public_fields = new ArrayList ();
non_public_fields.Add (field.FieldBuilder);
}
}
-
- if (tc.Events != null) {
- foreach (Event e in tc.Events) {
- if ((e.ModFlags & Modifiers.STATIC) != 0)
- continue;
-
- EventField ef = e as EventField;
- if (ef == null)
- continue;
-
- if ((ef.ModFlags & Modifiers.PUBLIC) != 0)
- public_fields.Add (ef.FieldBuilder);
- else
- non_public_fields.Add (ef.FieldBuilder);
- }
- }
}
CountPublic = public_fields.Count;
Fields = new FieldInfo [Count];
public_fields.CopyTo (Fields, 0);
non_public_fields.CopyTo (Fields, CountPublic);
-#if GMCS_SOURCE
} else if (type is GenericTypeParameterBuilder) {
CountPublic = CountNonPublic = Count = 0;
Fields = new FieldInfo [0];
-#endif
} else {
FieldInfo[] public_fields = type.GetFields (
BindingFlags.Instance|BindingFlags.Public);
if (sinfo [i] == null)
field_hash.Add (field.Name, ++Length);
else if (sinfo [i].InTransit) {
- Report.Error (523, String.Format (
+ RootContext.ToplevelTypes.Compiler.Report.Error (523, String.Format (
"Struct member `{0}.{1}' of type `{2}' causes " +
"a cycle in the structure layout",
type, field.Name, sinfo [i].Type));
this.IsParameter = false;
}
- public VariableInfo (Parameters ip, int i, int offset)
+ public VariableInfo (ParametersCompiled ip, int i, int offset)
: this (ip.FixedParameters [i].Name, ip.Types [i], offset)
{
this.IsParameter = true;
}
- public bool IsAssigned (EmitContext ec)
+ public bool IsAssigned (ResolveContext ec)
{
return !ec.DoFlowAnalysis ||
ec.OmitStructFlowAnalysis && TypeInfo.IsStruct ||
ec.CurrentBranching.IsAssigned (this);
}
- public bool IsAssigned (EmitContext ec, Location loc)
+ public bool IsAssigned (ResolveContext ec, Location loc)
{
if (IsAssigned (ec))
return true;
- Report.Error (165, loc,
+ ec.Report.Error (165, loc,
"Use of unassigned local variable `" + Name + "'");
ec.CurrentBranching.SetAssigned (this);
return false;
return true;
}
- public void SetAssigned (EmitContext ec)
+ public void SetAssigned (ResolveContext ec)
{
if (ec.DoFlowAnalysis)
ec.CurrentBranching.SetAssigned (this);
is_ever_assigned = true;
}
- public bool IsFieldAssigned (EmitContext ec, string name, Location loc)
+ public bool IsFieldAssigned (ResolveContext ec, string name, Location loc)
{
if (!ec.DoFlowAnalysis ||
ec.OmitStructFlowAnalysis && TypeInfo.IsStruct ||
ec.CurrentBranching.IsFieldAssigned (this, name))
return true;
- Report.Error (170, loc,
+ ec.Report.Error (170, loc,
"Use of possibly unassigned field `" + name + "'");
ec.CurrentBranching.SetFieldAssigned (this, name);
return false;
return vector [Offset + field_idx];
}
- public void SetFieldAssigned (EmitContext ec, string name)
+ public void SetFieldAssigned (ResolveContext ec, string name)
{
if (ec.DoFlowAnalysis)
ec.CurrentBranching.SetFieldAssigned (this, name);
public MyBitVector (MyBitVector InheritsFrom, int Count)
{
if (InheritsFrom != null)
- shared = InheritsFrom.Shared;
+ shared = InheritsFrom.MakeShared (Count);
this.Count = Count;
}
- // Use this accessor to get a shareable copy of the underlying BitArray representation
- BitArray Shared {
- get {
- // Post-condition: vector == null
- if (shared == null) {
- shared = vector;
- vector = null;
- }
- return shared;
+ BitArray MakeShared (int new_count)
+ {
+ // Post-condition: vector == null
+
+ // ensure we don't leak out dirty bits from the BitVector we inherited from
+ if (new_count > Count &&
+ ((shared != null && shared.Count > Count) ||
+ (shared == null && vector == null)))
+ initialize_vector ();
+
+ if (vector != null) {
+ shared = vector;
+ vector = null;
}
+
+ return shared;
}
// <summary>
public bool this [int index] {
get {
if (index >= Count)
- throw new ArgumentOutOfRangeException ();
+ // FIXME: Disabled due to missing anonymous method flow analysis
+ // throw new ArgumentOutOfRangeException ();
+ return true;
if (vector != null)
return vector [index];
if (Count == o.Count) {
if (vector == null) {
if (shared == null) {
- shared = new_vector.Shared;
+ shared = new_vector.MakeShared (Count);
return this;
}
initialize_vector ();
// Don't clobber Empty
if (Count == 0)
return;
- shared = value ? null : Empty.Shared;
+ shared = value ? null : Empty.MakeShared (Count);
vector = null;
}