Esempio n. 1
0
        // <summary>
        //   Creates a new flow branching which is contained in `parent'.
        //   You should only pass non-null for the `block' argument if this block
        //   introduces any new variables - in this case, we need to create a new
        //   usage vector with a different size than our parent's one.
        // </summary>
        protected FlowBranching(FlowBranching parent, BranchingType type, SiblingType stype,
            Block block, Location loc)
        {
            Parent = parent;
            Block = block;
            Location = loc;
            Type = type;
            id = ++next_id;

            UsageVector vector;
            if (Block != null) {
                UsageVector parent_vector = parent != null ? parent.CurrentUsageVector : null;
                vector = new UsageVector (stype, parent_vector, Block, loc, Block.AssignableSlots);
            } else {
                vector = new UsageVector (stype, Parent.CurrentUsageVector, null, loc);
            }

            AddSibling (vector);
        }
Esempio n. 2
0
			public static UsageVector MergeSiblings (UsageVector sibling_list, Location loc)
			{
				if (sibling_list.Next == null)
					return sibling_list;

				MyBitVector locals = null;
				bool is_unreachable = sibling_list.is_unreachable;

				if (!sibling_list.IsUnreachable)
					locals &= sibling_list.locals;

				for (UsageVector child = sibling_list.Next; child != null; child = child.Next) {
					is_unreachable &= child.is_unreachable;

					if (!child.IsUnreachable)
						locals &= child.locals;
				}

				return new UsageVector (locals, is_unreachable, null, loc);
			}
Esempio n. 3
0
		protected override void AddSibling (UsageVector sibling)
		{
			switch (sibling.Type) {
			case SiblingType.Try:
				try_vector = sibling;
				break;
			case SiblingType.Finally:
				finally_vector = sibling;
				break;
			default:
				throw new InvalidOperationException ();
			}
			current_vector = sibling;
		}
Esempio n. 4
0
			public ReturnOrigin (SavedOrigin next, UsageVector vector, ExitStatement stmt)
				: base (next, vector)
			{
				Stmt = stmt;
			}
Esempio n. 5
0
			public BreakOrigin (SavedOrigin next, UsageVector vector, Location loc)
				: base (next, vector)
			{
				Loc = loc;
			}
Esempio n. 6
0
			protected SavedOrigin (SavedOrigin next, UsageVector vector)
			{
				Next = next;
				Vector = vector.Clone ();
			}
Esempio n. 7
0
		public override bool AddReturnOrigin (UsageVector vector, ExitStatement exit_stmt)
		{
			Parent.AddReturnOrigin (vector, exit_stmt);
			return true;
		}
Esempio n. 8
0
		public override bool AddBreakOrigin (UsageVector vector, Location loc)
		{
			Parent.AddBreakOrigin (vector, loc);
			tc.SomeCodeFollows ();
			return true;
		}
Esempio n. 9
0
		// returns true if we crossed an unwind-protected region (try/catch/finally, lock, using, ...)
		public virtual bool AddGotoOrigin (UsageVector vector, Goto goto_stmt)
		{
			return Parent.AddGotoOrigin (vector, goto_stmt);
		}
Esempio n. 10
0
		// returns true if we crossed an unwind-protected region (try/catch/finally, lock, using, ...)
		public virtual bool AddReturnOrigin (UsageVector vector, ExitStatement stmt)
		{
			return Parent.AddReturnOrigin (vector, stmt);
		}
Esempio n. 11
0
		// returns true if we crossed an unwind-protected region (try/catch/finally, lock, using, ...)
		public virtual bool AddContinueOrigin (UsageVector vector, Location loc)
		{
			return Parent.AddContinueOrigin (vector, loc);
		}
Esempio n. 12
0
		protected abstract void AddSibling (UsageVector uv);
Esempio n. 13
0
		// <summary>
		//   Creates a sibling of the current usage vector.
		// </summary>
		public virtual void CreateSibling (Block block, SiblingType type)
		{
			UsageVector vector = new UsageVector (
				type, Parent.CurrentUsageVector, block, Location);
			AddSibling (vector);

			Report.Debug (1, "  CREATED SIBLING", CurrentUsageVector);
		}
Esempio n. 14
0
			public void MergeOrigins (UsageVector o_vectors)
			{
				Report.Debug (1, "  MERGING BREAK ORIGINS", this);

				if (o_vectors == null)
					return;

				if (IsUnreachable && locals != null)
					locals.SetAll (true);

				for (UsageVector vector = o_vectors; vector != null; vector = vector.Next) {
					Report.Debug (1, "    MERGING BREAK ORIGIN", vector);
					if (vector.IsUnreachable)
						continue;
					locals &= vector.locals;
					is_unreachable &= vector.is_unreachable;
				}

				Report.Debug (1, "  MERGING BREAK ORIGINS DONE", this);
			}
Esempio n. 15
0
			// <summary>
			//   Merges a child branching.
			// </summary>
			public UsageVector MergeChild (UsageVector child, bool overwrite)
			{
				Report.Debug (2, "    MERGING CHILD EFFECTS", this, child, Type);

				bool new_isunr = child.is_unreachable;

				//
				// We've now either reached the point after the branching or we will
				// never get there since we always return or always throw an exception.
				//
				// If we can reach the point after the branching, mark all locals and
				// parameters as initialized which have been initialized in all branches
				// we need to look at (see above).
				//

				if ((Type == SiblingType.SwitchSection) && !new_isunr) {
					Report.Error (163, Location,
						      "Control cannot fall through from one " +
						      "case label to another");
					return child;
				}

				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
					is_unreachable |= new_isunr;

				return child;
			}
Esempio n. 16
0
		public override bool AddReturnOrigin (UsageVector vector, ExitStatement stmt)
		{
			vector = vector.Clone ();
			vector.Location = stmt.loc;
			vector.Next = return_origins;
			return_origins = vector;
			return false;
		}
Esempio n. 17
0
		public override bool AddGotoOrigin (UsageVector vector, Goto goto_stmt)
		{
			string name = goto_stmt.Target;
			LabeledStatement s = Block.LookupLabel (name);
			if (s != null)
				throw new InternalErrorException ("Shouldn't get here");

			if (Parent == null) {
				Error_UnknownLabel (goto_stmt.loc, name, Report);
				return false;
			}

			int errors = Report.Errors;
			Parent.AddGotoOrigin (vector, goto_stmt);
			if (errors == Report.Errors)
				Report.Error (1632, goto_stmt.loc, "Control cannot leave the body of an anonymous method");
			return false;
		}
Esempio n. 18
0
		protected override void AddSibling (UsageVector sibling)
		{
			if (sibling_list != null && sibling_list.Type == SiblingType.Block)
				throw new InternalErrorException ("Blocks don't have sibling flow paths");
			sibling.Next = sibling_list;
			sibling_list = sibling;
		}
Esempio n. 19
0
		public override bool AddContinueOrigin (UsageVector vector, Location loc)
		{
			Parent.AddContinueOrigin (vector, loc);
			return true;
		}
Esempio n. 20
0
		public override bool AddGotoOrigin (UsageVector vector, Goto goto_stmt)
		{
			LabeledStatement stmt = Block == null ? null : Block.LookupLabel (goto_stmt.Target);
			if (stmt == null)
				return Parent.AddGotoOrigin (vector, goto_stmt);

			// forward jump
			goto_stmt.SetResolvedTarget (stmt);
			stmt.AddUsageVector (vector);
			return false;
		}
Esempio n. 21
0
		public override bool AddGotoOrigin (UsageVector vector, Goto goto_stmt)
		{
			Parent.AddGotoOrigin (vector, goto_stmt);
			return true;
		}
Esempio n. 22
0
		public override bool AddBreakOrigin (UsageVector vector, Location loc)
		{
			vector = vector.Clone ();
			vector.Next = break_origins;
			break_origins = vector;
			return false;
		}
Esempio n. 23
0
			public void PropagateFinally (UsageVector finally_vector, FlowBranching parent)
			{
				if (finally_vector != null)
					Vector.MergeChild (finally_vector, false);
				DoPropagateFinally (parent);
			}
Esempio n. 24
0
		public override bool AddContinueOrigin (UsageVector vector, Location loc)
		{
			vector = vector.Clone ();
			vector.Next = continue_origins;
			continue_origins = vector;
			return false;
		}
Esempio n. 25
0
			public ContinueOrigin (SavedOrigin next, UsageVector vector, Location loc)
				: base (next, vector)
			{
				Loc = loc;
			}
Esempio n. 26
0
		public FlowBranchingLabeled (FlowBranching parent, LabeledStatement stmt)
			: base (parent, BranchingType.Labeled, SiblingType.Conditional, null, stmt.loc)
		{
			this.stmt = stmt;
			CurrentUsageVector.MergeOrigins (stmt.JumpOrigins);
			actual = CurrentUsageVector.Clone ();

			// stand-in for backward jumps
			CurrentUsageVector.ResetBarrier ();
		}
Esempio n. 27
0
			public GotoOrigin (SavedOrigin next, UsageVector vector, Goto stmt)
				: base (next, vector)
			{
				Stmt = stmt;
			}
Esempio n. 28
0
		public override bool AddGotoOrigin (UsageVector vector, Goto goto_stmt)
		{
			if (goto_stmt.Target != stmt.Name)
				return Parent.AddGotoOrigin (vector, goto_stmt);

			// backward jump
			goto_stmt.SetResolvedTarget (stmt);
			actual.MergeOrigins (vector.Clone ());

			return false;
		}
Esempio n. 29
0
		public override bool AddBreakOrigin (UsageVector vector, Location loc)
		{
			if (finally_vector != null) {
				int errors = Report.Errors;
				Parent.AddBreakOrigin (vector, loc);
				if (errors == Report.Errors)
					Report.Error (157, loc, "Control cannot leave the body of a finally clause");
			} else {
				saved_origins = new BreakOrigin (saved_origins, vector, loc);
			}

			// either the loop test or a back jump will follow code
			stmt.SomeCodeFollows ();
			return true;
		}
Esempio n. 30
0
		public override bool AddContinueOrigin (UsageVector vector, Location loc)
		{
			Report.Error (139, loc, "No enclosing loop out of which to break or continue");
			return false;
		}