⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flowanalysis.cs

📁 C#编译器源代码。Micorsoft开放源代码
💻 CS
📖 第 1 页 / 共 4 页
字号:
			public void SetFieldAssigned (VariableInfo var, string name)			{				if (!var.IsParameter && Reachability.IsUnreachable)					return;				IsDirty = true;				var.SetFieldAssigned (var.IsParameter ? parameters : locals, name);			}			public Reachability Reachability {				get {					return reachability;				}			}			public void Return ()			{				if (!reachability.IsUnreachable) {					IsDirty = true;					reachability.SetReturns ();				}			}			public void Break ()			{				if (!reachability.IsUnreachable) {					IsDirty = true;					reachability.SetBreaks ();				}			}			public void Throw ()			{				if (!reachability.IsUnreachable) {					IsDirty = true;					reachability.SetThrows ();				}			}			public void Goto ()			{				if (!reachability.IsUnreachable) {					IsDirty = true;					reachability.SetBarrier ();				}			}			// <summary>			//   Merges a child branching.			// </summary>			public UsageVector MergeChild (FlowBranching branching)			{				UsageVector result = branching.Merge ();				Report.Debug (2, "  MERGING CHILD", this, branching, IsDirty,					      result.ParameterVector, result.LocalVector,					      result.Reachability, reachability, Type);				Reachability new_r = result.Reachability;				if (branching.Type == BranchingType.Loop) {					bool may_leave_loop = new_r.MayBreak;					new_r.ResetBreaks ();					if (branching.Infinite && !may_leave_loop) {						if (new_r.Returns == FlowReturns.Sometimes) {							// If we're an infinite loop and do not break,							// the code after the loop can never be reached.							// However, if we may return from the loop,							// then we do always return (or stay in the							// loop forever).							new_r.SetReturns ();						}						new_r.SetBarrier ();					}					if (may_leave_loop)						new_r.ResetBarrier ();				} 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				// 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_r.IsUnreachable) {					Report.Error (163, Location,						      "Control cannot fall through from one " +						      "case label to another");					return result;				}				if (locals != null && result.LocalVector != null)					locals.Or (result.LocalVector);				if (result.ParameterVector != null)					parameters.Or (result.ParameterVector);				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);				IsDirty = true;				return result;			}			protected void MergeFinally (FlowBranching branching, UsageVector f_origins,						     MyBitVector f_params)			{				for (UsageVector vector = f_origins; vector != null; vector = vector.Next) {					MyBitVector temp_params = f_params.Clone ();					temp_params.Or (vector.Parameters);				}			}			public void MergeFinally (FlowBranching branching, UsageVector f_vector,						  UsageVector f_origins)			{				if (parameters != null) {					if (f_vector != null) {						MergeFinally (branching, f_origins, f_vector.Parameters);						MyBitVector.Or (ref parameters, f_vector.ParameterVector);					} else						MergeFinally (branching, f_origins, parameters);				}				if (f_vector != null && f_vector.LocalVector != null)					MyBitVector.Or (ref locals, f_vector.LocalVector);			}			// <summary>			//   Tells control flow analysis that the current code position may be reached with			//   a forward jump from any of the origins listed in `origin_vectors' which is a			//   list of UsageVectors.			//			//   This is used when resolving forward gotos - in the following example, the			//   variable `a' is uninitialized in line 8 becase this line may be reached via			//   the goto in line 4:			//			//      1     int a;			//			//      3     if (something)			//      4        goto World;			//			//      6     a = 5;			//			//      7  World:			//      8     Console.WriteLine (a);			//			// </summary>			public void MergeJumpOrigins (UsageVector o_vectors)			{				Report.Debug (1, "  MERGING JUMP ORIGINS", this);				reachability = Reachability.Never ();				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,						      first, locals, vector.Locals);					if (first) {						if (locals != null && vector.Locals != null)							locals.Or (vector.locals);												if (parameters != null)							parameters.Or (vector.parameters);						first = false;					} else {						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);			}			// <summary>			//   This is used at the beginning of a finally block if there were			//   any return statements in the try block or one of the catch blocks.			// </summary>			public void MergeFinallyOrigins (UsageVector f_origins)			{				Report.Debug (1, "  MERGING FINALLY ORIGIN", this);				reachability = Reachability.Never ();				for (UsageVector vector = f_origins; vector != null; vector = vector.Next) {					Report.Debug (1, "    MERGING FINALLY ORIGIN", vector);					if (parameters != null)						parameters.And (vector.parameters);					Reachability.And (ref reachability, vector.Reachability, true);				}				Report.Debug (1, "  MERGING FINALLY ORIGIN DONE", this);			}			public void MergeBreakOrigins (FlowBranching branching, UsageVector o_vectors)			{				Report.Debug (1, "  MERGING BREAK ORIGINS", this);				if (o_vectors == null)					return;				bool first = branching.Infinite;				for (UsageVector vector = o_vectors; vector != null;				     vector = vector.Next) {					Report.Debug (1, "    MERGING BREAK ORIGIN", vector, first);					if (first) {						if (locals != null && vector.Locals != null)							locals.Or (vector.locals);												if (parameters != null)							parameters.Or (vector.parameters);						first = false;					} else {						if (locals != null && vector.Locals != null)							locals.And (vector.locals);						if (parameters != null)							parameters.And (vector.parameters);					}					reachability.And (vector.Reachability, false);				}				Report.Debug (1, "  MERGING BREAK ORIGINS DONE", this);			}			public void CheckOutParameters (FlowBranching branching)			{				if (parameters != null)					branching.CheckOutParameters (parameters, branching.Location);			}			// <summary>			//   Performs an `or' operation on the locals and the parameters.			// </summary>			public void Or (UsageVector new_vector)			{				IsDirty = true;				locals.Or (new_vector.locals);				if (parameters != null)					parameters.Or (new_vector.parameters);			}			// <summary>			//   Performs an `and' operation on the locals.			// </summary>			public void AndLocals (UsageVector new_vector)			{				IsDirty = true;				locals.And (new_vector.locals);			}			public bool HasParameters {				get {					return parameters != null;				}			}			public bool HasLocals {				get {					return locals != null;				}			}			// <summary>			//   Returns a deep copy of the parameters.			// </summary>			public MyBitVector Parameters {				get {					if (parameters != null)						return parameters.Clone ();					else						return null;				}			}			// <summary>			//   Returns a deep copy of the locals.			// </summary>			public MyBitVector Locals {				get {					if (locals != null)						return locals.Clone ();					else						return null;				}			}			public MyBitVector ParameterVector {				get {					return parameters;				}			}			public MyBitVector LocalVector {				get {					return locals;				}			}			//			// Debugging stuff.			//			public override string ToString ()			{				StringBuilder sb = new StringBuilder ();				sb.Append ("Vector (");				sb.Append (Type);				sb.Append (",");				sb.Append (id);				sb.Append (",");				sb.Append (IsDirty);				sb.Append (",");				sb.Append (reachability);				if (parameters != null) {					sb.Append (" - ");					sb.Append (parameters);				}				sb.Append (" - ");				sb.Append (locals);				sb.Append (")");				return sb.ToString ();			}		}		// <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) {				param_map = Block.ParameterMap;				local_map = Block.LocalMap;				UsageVector parent_vector = parent != null ? parent.CurrentUsageVector : null;				vector = new UsageVector (					stype, parent_vector, Block, loc,					param_map.Length, local_map.Length);			} else {				param_map = Parent.param_map;				local_map = Parent.local_map;				vector = new UsageVector (					stype, Parent.CurrentUsageVector, null, loc);			}			AddSibling (vector);		}		public abstract UsageVector CurrentUsageVector {			get;		}						// <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);		}		public void CreateSibling ()		{			CreateSibling (null, SiblingType.Conditional);		}		protected abstract void AddSibling (UsageVector uv);		public virtual LabeledStatement LookupLabel (string name, Location loc)		{			if (Parent != null)				return Parent.LookupLabel (name, loc);			Report.Error (				159, loc,				"No such label `" + name + "' in this scope");			return null;		}		public abstract void Label (UsageVector origin_vectors);		// <summary>		//   Check whether all `out' parameters have been assigned.		// </summary>		public void CheckOutParameters (MyBitVector parameters, Location loc)		{			for (int i = 0; i < param_map.Count; i++) {				VariableInfo var = param_map [i];				if (var == null)					continue;				if (var.IsAssigned (parameters))					continue;				Report.Error (177, loc, "The out parameter `{0}' must be assigned to before control leaves the current method",					var.Name);			}		}		protected UsageVector Merge (UsageVector sibling_list)		{			if (sibling_list.Next == null)				return sibling_list;			MyBitVector locals = null;			MyBitVector parameters = null;			Reachability reachability = null;			Report.Debug (2, "  MERGING SIBLINGS", this, Name);			for (UsageVector child = sibling_list; child != null; child = child.Next) {				bool do_break = (Type != BranchingType.Switch) &&					(Type != BranchingType.Loop);				Report.Debug (2, "    MERGING SIBLING   ", child,					      child.ParameterVector, child.LocalVector,					      reachability, child.Reachability, do_break);				Reachability.And (ref reachability, child.Reachability, do_break);				// A local variable is initialized after a flow branching if it				// has been initialized in all its branches which do neither				// always return or always throw an exception.				//				// If a branch may return, but does not always return, then we				// can treat it like a never-returning branch here: control will				// only reach the code position after the branching if we did not				// return here.				//				// It's important to distinguish between always and sometimes				// returning branches here:				//				//    1   int a;				//    2   if (something) {				//    3      return;				//    4      a = 5;				//    5   }				//    6   Console.WriteLine (a);				//				// The if block in lines 3-4 always returns, so we must not look				// at the initialization of `a' in line 4 - thus it'll still be				// uninitialized in line 6.				//				// On the other hand, the following is allowed:				//				//    1   int a;				//    2   if (something)				//    3      a = 5;				//    4   else				//    5      return;				//    6   Console.WriteLine (a);				//				// Here, `a' is initialized in line 3 and we must not look at				// line 5 since it always returns.				// 				bool do_break_2 = (child.Type != SiblingType.Block) &&					(child.Type != SiblingType.SwitchSection);				bool always_throws = (child.Type != SiblingType.Try) &&					child.Reachability.AlwaysThrows;				bool unreachable = always_throws ||					(do_break_2 && child.Reachability.AlwaysBreaks) ||					child.Reachability.AlwaysReturns ||					child.Reachability.AlwaysHasBarrier;				Report.Debug (2, "    MERGING SIBLING #1", reachability,					      Type, child.Type, child.Reachability.IsUnreachable,					      do_break_2, always_throws, unreachable);				if (!unreachable && (child.LocalVector != null))					MyBitVector.And (ref locals, child.LocalVector);				// An `out' parameter must be assigned in all branches which do				// not always throw an exception.				if ((child.ParameterVector != null) && !child.Reachability.AlwaysThrows)					MyBitVector.And (ref parameters, child.ParameterVector);				Report.Debug (2, "    MERGING SIBLING #2", parameters, locals);			}			if (reachability == null)				reachability = Reachability.Never ();			Report.Debug (2, "  MERGING SIBLINGS DONE", parameters, locals,				      reachability, Infinite);			return new UsageVector (				parameters, locals, reachability, null, Location);		}		protected abstract UsageVector Merge ();		// <summary>		//   Merge a child branching.		// </summary>		public UsageVector MergeChild (FlowBranching child)		{			return CurrentUsageVector.MergeChild (child); 		}		// <summary>		//   Does the toplevel merging.		// </summary>		public Reachability MergeTopBlock ()		{			if ((Type != BranchingType.Block) || (Block == null))				throw new NotSupportedException ();			UsageVector vector = new UsageVector (				SiblingType.Block, null, Block, Location,				param_map.Length, local_map.Length);			UsageVector result = vector.MergeChild (this);			Report.Debug (4, "MERGE TOP BLOCK", Location, vector, result.Reachability);			if ((vector.Reachability.Throws != FlowReturns.Always) &&			    (vector.Reachability.Barrier != FlowReturns.Always))				CheckOutParameters (vector.Parameters, Location);			return result.Reachability;		}		//		// Checks whether we're in a `try' block.		//		public virtual bool InTryOrCatch (bool is_return)		{			if ((Block != null) && Block.IsDestructor)				return true;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -