示例#1
0
		public static FlowBranching CreateBranching (FlowBranching parent, BranchingType type, Block block, Location loc)
		{
			switch (type) {
			case BranchingType.Exception:
			case BranchingType.Labeled:
			case BranchingType.Toplevel:
			case BranchingType.TryCatch:
				throw new InvalidOperationException ();

			case BranchingType.Switch:
				return new FlowBranchingBreakable (parent, type, SiblingType.SwitchSection, block, loc);

			case BranchingType.Block:
				return new FlowBranchingBlock (parent, type, SiblingType.Block, block, loc);

			case BranchingType.Loop:
				return new FlowBranchingBreakable (parent, type, SiblingType.Conditional, block, loc);

			case BranchingType.Embedded:
				return new FlowBranchingContinuable (parent, type, SiblingType.Conditional, block, loc);

			default:
				return new FlowBranchingBlock (parent, type, SiblingType.Conditional, block, loc);
			}
		}
示例#2
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);
        }
示例#3
0
			protected override void DoPropagateFinally (FlowBranching parent)
			{
				parent.AddContinueOrigin (Vector, Loc);
			}
示例#4
0
		// <summary>
		//   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)
		{
			if (struct_info == null)
				return true;

			bool ok = true;
			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,
							"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,
							"Field `{0}' must be fully assigned before control leaves the constructor",
							TypeManager.GetFullNameSignature (field));
					}
					ok = false;
				}
			}

			return ok;
		}
示例#5
0
			public void PropagateFinally (UsageVector finally_vector, FlowBranching parent)
			{
				if (finally_vector != null)
					Vector.MergeChild (finally_vector, false);
				DoPropagateFinally (parent);
			}
示例#6
0
文件: context.cs 项目: jkells/mono
		public FlowBranchingIterator StartFlowBranching (StateMachineInitializer iterator, FlowBranching parent)
		{
			FlowBranchingIterator branching = new FlowBranchingIterator (parent, iterator);
			current_flow_branching = branching;
			return branching;
		}
示例#7
0
		// <summary>
		//   Ends a code branching.  Merges the state of locals and parameters
		//   from all the children of the ending branching.
		// </summary>
		public bool EndFlowBranching ()
		{
			FlowBranching old = current_flow_branching;
			current_flow_branching = current_flow_branching.Parent;

			FlowBranching.UsageVector vector = current_flow_branching.MergeChild (old);
			return vector.IsUnreachable;
		}
示例#8
0
		// <summary>
		//   Starts a new code branching.  This inherits the state of all local
		//   variables and parameters from the current branching.
		// </summary>
		public FlowBranching StartFlowBranching (FlowBranching.BranchingType type, Location loc)
		{
			current_flow_branching = FlowBranching.CreateBranching (CurrentBranching, type, null, loc);
			return current_flow_branching;
		}
示例#9
0
		public FlowBranchingTryCatch StartFlowBranching (TryCatch stmt)
		{
			FlowBranchingTryCatch branching = new FlowBranchingTryCatch (CurrentBranching, stmt);
			current_flow_branching = branching;
			return branching;
		}
示例#10
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 ();
		}
示例#11
0
		public FlowBranchingIterator (FlowBranching parent, Iterator iterator)
			: base (parent, BranchingType.Iterator, SiblingType.Block, iterator.Block, iterator.Location)
		{
			this.iterator = iterator;
		}
示例#12
0
		public UsageVector MergeChild (FlowBranching child)
		{
			return CurrentUsageVector.MergeChild (child.Merge (), true);
 		}
示例#13
0
		public FlowBranchingContinuable (FlowBranching parent, BranchingType type, SiblingType stype, Block block, Location loc)
			: base (parent, type, stype, block, loc)
		{ }
示例#14
0
		public void AddUsageVector (FlowBranching.UsageVector vector)
		{
			vector = vector.Clone ();
			vector.Next = vectors;
			vectors = vector;
		}
示例#15
0
		public bool Resolve (FlowBranching parent, BlockContext rc, IMethodData md)
		{
			if (resolved)
				return true;

			resolved = true;

			if (rc.HasSet (ResolveContext.Options.ExpressionTreeConversion))
				flags |= Flags.IsExpressionTree;

			try {
				ResolveMeta (rc);

				using (rc.With (ResolveContext.Options.DoFlowAnalysis, true)) {
					FlowBranchingToplevel top_level = rc.StartFlowBranching (this, parent);

					if (!Resolve (rc))
						return false;

					unreachable = top_level.End ();
				}
			} catch (Exception e) {
				if (e is CompletionResult || rc.Report.IsDisabled)
					throw;

				if (rc.CurrentBlock != null) {
					rc.Report.Error (584, rc.CurrentBlock.StartLocation, "Internal compiler error: {0}", e.Message);
				} else {
					rc.Report.Error (587, "Internal compiler error: {0}", e.Message);
				}

				if (Report.DebugFlags > 0)
					throw;
			}

			if (rc.ReturnType != TypeManager.void_type && !unreachable) {
				if (rc.CurrentAnonymousMethod == null) {
					// FIXME: Missing FlowAnalysis for generated iterator MoveNext method
					if (md is IteratorMethod) {
						unreachable = true;
					} else {
						rc.Report.Error (161, md.Location, "`{0}': not all code paths return a value", md.GetSignatureForError ());
						return false;
					}
				} else {
					rc.Report.Error (1643, rc.CurrentAnonymousMethod.Location, "Not all code paths return a value in anonymous method of type `{0}'",
							  rc.CurrentAnonymousMethod.GetSignatureForError ());
					return false;
				}
			}

			return true;
		}
示例#16
0
		// <summary>
		//   Check whether all `out' parameters have been assigned.
		// </summary>
		public void CheckOutParameters (FlowBranching.UsageVector vector, Location loc)
		{
			if (vector.IsUnreachable)
				return;

			int n = parameter_info == null ? 0 : parameter_info.Length;

			for (int i = 0; i < n; i++) {
				VariableInfo var = parameter_info[i].VariableInfo;

				if (var == null)
					continue;

				if (vector.IsAssigned (var, false))
					continue;

				TopBlock.Report.Error (177, loc, "The out parameter `{0}' must be assigned to before control leaves the current method",
					var.Name);
			}
		}
示例#17
0
			protected override void DoPropagateFinally (FlowBranching parent)
			{
				parent.AddGotoOrigin (Vector, Stmt);
			}
示例#18
0
		public FlowBranchingToplevel (FlowBranching parent, ParametersBlock stmt)
			: base (parent, BranchingType.Toplevel, SiblingType.Conditional, stmt, stmt.loc)
		{
		}
示例#19
0
		public FlowBranchingTryFinally (FlowBranching parent,
					       ExceptionStatement stmt)
			: base (parent, BranchingType.Exception, SiblingType.Try,
				null, stmt.loc)
		{
			this.stmt = stmt;
		}
示例#20
0
		public FlowBranchingLabeled StartFlowBranching (LabeledStatement stmt)
		{
			FlowBranchingLabeled branching = new FlowBranchingLabeled (CurrentBranching, stmt);
			current_flow_branching = branching;
			return branching;
		}
示例#21
0
		// <summary>
		//   Starts a new code branching for block `block'.
		// </summary>
		public FlowBranching StartFlowBranching (Block block)
		{
			Set (Options.DoFlowAnalysis);

			current_flow_branching = FlowBranching.CreateBranching (
				CurrentBranching, FlowBranching.BranchingType.Block, block, block.StartLocation);
			return current_flow_branching;
		}
示例#22
0
		public FlowBranchingAsync StartFlowBranching (AsyncInitializer asyncBody, FlowBranching parent)
		{
			var branching = new FlowBranchingAsync (parent, asyncBody);
			current_flow_branching = branching;
			return branching;
		}
示例#23
0
		public FlowBranchingTryFinally StartFlowBranching (TryFinallyBlock stmt)
		{
			FlowBranchingTryFinally branching = new FlowBranchingTryFinally (CurrentBranching, stmt);
			current_flow_branching = branching;
			return branching;
		}
示例#24
0
文件: context.cs 项目: jkells/mono
		public FlowBranchingException StartFlowBranching (ExceptionStatement stmt)
		{
			FlowBranchingException branching = new FlowBranchingException (CurrentBranching, stmt);
			current_flow_branching = branching;
			return branching;
		}
示例#25
0
		public FlowBranchingIterator StartFlowBranching (Iterator iterator, FlowBranching parent)
		{
			FlowBranchingIterator branching = new FlowBranchingIterator (parent, iterator);
			current_flow_branching = branching;
			return branching;
		}
示例#26
0
		public FlowBranchingTryCatch (FlowBranching parent, TryCatch stmt)
			: base (parent, BranchingType.Block, SiblingType.Try, null, stmt.loc)
		{
			this.tc = stmt;
		}
示例#27
0
		public FlowBranchingToplevel StartFlowBranching (ParametersBlock stmt, FlowBranching parent)
		{
			FlowBranchingToplevel branching = new FlowBranchingToplevel (parent, stmt);
			current_flow_branching = branching;
			return branching;
		}
示例#28
0
		public FlowBranchingAsync (FlowBranching parent, AsyncInitializer async_init)
			: base (parent, BranchingType.Block, SiblingType.Try, null, async_init.Location)
		{
			this.async_init = async_init;
		}
示例#29
0
		// <summary>
		//   Kills the current code branching.  This throws away any changed state
		//   information and should only be used in case of an error.
		// </summary>
		// FIXME: this is evil
		public void KillFlowBranching ()
		{
			current_flow_branching = current_flow_branching.Parent;
		}
示例#30
0
			protected abstract void DoPropagateFinally (FlowBranching parent);