{
switch (type) {
case BranchingType.Exception:
- return new FlowBranchingException (parent, block, loc);
+ throw new InvalidOperationException ();
case BranchingType.Switch:
return new FlowBranchingBlock (parent, type, SiblingType.SwitchSection, block, loc);
if (!new_r.MayReturn && !new_r.MayThrow)
new_r.ResetBarrier ();
}
- } else if (branching.Type == BranchingType.Switch)
+ } else if (branching.Type == BranchingType.Switch) {
+ if (new_r.MayBreak || new_r.MayReturn)
+ new_r.ResetBarrier ();
+
new_r.ResetBreaks ();
+ }
//
// We've now either reached the point after the branching or we will
if (result.ParameterVector != null)
parameters.Or (result.ParameterVector);
- reachability.Or (new_r);
+ if ((branching.Type == BranchingType.Block) && branching.Block.Implicit)
+ reachability = new_r.Clone ();
+ else
+ reachability.Or (new_r);
Report.Debug (2, " MERGING CHILD DONE", this, result,
new_r, reachability);
reachability = Reachability.Never ();
- if (o_vectors == null)
+ if (o_vectors == null) {
+ reachability.SetBarrier ();
return;
+ }
bool first = true;
for (UsageVector vector = o_vectors; vector != null;
vector = vector.Next) {
- Report.Debug (1, " MERGING JUMP ORIGIN", vector);
+ Report.Debug (1, " MERGING JUMP ORIGIN", vector,
+ first, locals, vector.Locals);
if (first) {
if (locals != null && vector.Locals != null)
parameters.Or (vector.parameters);
first = false;
} else {
- if (locals != null && vector.Locals != null)
+ if (locals != null)
locals.And (vector.locals);
if (parameters != null)
parameters.And (vector.parameters);
}
Reachability.And (ref reachability, vector.Reachability, true);
+
+ Report.Debug (1, " MERGING JUMP ORIGIN #1", vector);
}
Report.Debug (1, " MERGING JUMP ORIGINS DONE", this);
Report.Debug (1, " MERGING FINALLY ORIGIN DONE", this);
}
- public void MergeBreakOrigins (UsageVector o_vectors)
+ public void MergeBreakOrigins (FlowBranching branching, UsageVector o_vectors)
{
Report.Debug (1, " MERGING BREAK ORIGINS", this);
if (o_vectors == null)
return;
- bool first = true;
+ bool first = branching.Infinite;
for (UsageVector vector = o_vectors; vector != null;
vector = vector.Next) {
throw new NotSupportedException ();
UsageVector vector = new UsageVector (
- SiblingType.Conditional, null, Block, Location,
+ SiblingType.Block, null, Block, Location,
param_map.Length, local_map.Length);
UsageVector result = vector.MergeChild (this);
return false;
}
- //
- // Checks whether we're in a `catch' block.
- //
- public virtual bool InCatch ()
+ public virtual bool InTryWithCatch ()
{
if (Parent != null)
- return Parent.InCatch ();
- else
- return false;
- }
-
- //
- // Checks whether we're in a `finally' block.
- //
- public virtual bool InFinally (bool is_return)
- {
- if (!is_return &&
- ((Type == BranchingType.Loop) || (Type == BranchingType.Switch)))
- return false;
- else if (Parent != null)
- return Parent.InFinally (is_return);
- else
- return false;
+ return Parent.InTryWithCatch ();
+ return false;
}
public virtual bool InLoop ()
throw new NotSupportedException ();
}
+ public virtual void StealFinallyClauses (ref ArrayList list)
+ {
+ if (Parent != null)
+ Parent.StealFinallyClauses (ref list);
+ }
+
public bool IsAssigned (VariableInfo vi)
{
return CurrentUsageVector.IsAssigned (vi);
{
UsageVector vector = base.Merge ();
- vector.MergeBreakOrigins (break_origins);
+ vector.MergeBreakOrigins (this, break_origins);
return vector;
}
public class FlowBranchingException : FlowBranching
{
+ ExceptionStatement stmt;
UsageVector current_vector;
UsageVector catch_vectors;
UsageVector finally_vector;
UsageVector finally_origins;
- bool in_try;
+ bool emit_finally;
- public FlowBranchingException (FlowBranching parent, Block block, Location loc)
- : base (parent, BranchingType.Exception, SiblingType.Try, block, loc)
- { }
+ public FlowBranchingException (FlowBranching parent,
+ ExceptionStatement stmt)
+ : base (parent, BranchingType.Exception, SiblingType.Try,
+ null, stmt.loc)
+ {
+ this.stmt = stmt;
+ this.emit_finally = true;
+ }
protected override void AddSibling (UsageVector sibling)
{
if (sibling.Type == SiblingType.Try) {
sibling.Next = catch_vectors;
catch_vectors = sibling;
- in_try = true;
} else if (sibling.Type == SiblingType.Catch) {
sibling.Next = catch_vectors;
catch_vectors = sibling;
- in_try = false;
} else if (sibling.Type == SiblingType.Finally) {
sibling.MergeFinallyOrigins (finally_origins);
finally_vector = sibling;
- in_try = false;
} else
throw new InvalidOperationException ();
return finally_vector == null;
}
- public override bool InCatch ()
+ public override bool InTryWithCatch ()
{
- return !in_try && (finally_vector == null);
- }
+ if (finally_vector == null) {
+ Try t = stmt as Try;
+ if (t != null && t.HasCatch)
+ return true;
+ }
- public override bool InFinally (bool is_return)
- {
- return finally_vector != null;
+ if (Parent != null)
+ return Parent.InTryWithCatch ();
+
+ return false;
}
public override bool BreakCrossesTryCatchBoundary ()
finally_origins = vector;
}
+ public override void StealFinallyClauses (ref ArrayList list)
+ {
+ if (list == null)
+ list = new ArrayList ();
+ list.Add (stmt);
+ emit_finally = false;
+ base.StealFinallyClauses (ref list);
+ }
+
+ public bool EmitFinally {
+ get { return emit_finally; }
+ }
+
public override LabeledStatement LookupLabel (string name, Location loc)
{
if (current_vector.Block == null)
if (type is TypeBuilder) {
TypeContainer tc = TypeManager.LookupTypeContainer (type);
- ArrayList fields = tc.Fields;
+ ArrayList fields = null;
+ if (tc != null)
+ fields = tc.Fields;
ArrayList public_fields = new ArrayList ();
ArrayList non_public_fields = new ArrayList ();
if (fields != null) {
- foreach (Field field in fields) {
+ foreach (FieldMember field in fields) {
if ((field.ModFlags & Modifiers.STATIC) != 0)
continue;
if ((field.ModFlags & Modifiers.PUBLIC) != 0)
// </summary>
public void And (MyBitVector new_vector)
{
- BitArray new_array = new_vector.Vector;
+ BitArray new_array;
+
+ if (new_vector != null)
+ new_array = new_vector.Vector;
+ else
+ new_array = new BitArray (Count, false);
initialize_vector ();