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

📄 flowanalysis.cs

📁 C#编译器源代码。Micorsoft开放源代码
💻 CS
📖 第 1 页 / 共 4 页
字号:
			else if (!is_return &&			    ((Type == BranchingType.Loop) || (Type == BranchingType.Switch)))				return false;			else if (Parent != null)				return Parent.InTryOrCatch (is_return);			else				return false;		}		public virtual bool InTryWithCatch ()		{			if (Parent != null)				return Parent.InTryWithCatch ();			return false;		}		public virtual bool InLoop ()		{			if (Type == BranchingType.Loop)				return true;			else if (Parent != null)				return Parent.InLoop ();			else				return false;		}		public virtual bool InSwitch ()		{			if (Type == BranchingType.Switch)				return true;			else if (Parent != null)				return Parent.InSwitch ();			else				return false;		}		public virtual bool BreakCrossesTryCatchBoundary ()		{			if ((Type == BranchingType.Loop) || (Type == BranchingType.Switch))				return false;			else if (Parent != null)				return Parent.BreakCrossesTryCatchBoundary ();			else				return false;		}		public virtual void AddFinallyVector (UsageVector vector)		{			if (Parent != null)				Parent.AddFinallyVector (vector);			else if ((Block == null) || !Block.IsDestructor)				throw new NotSupportedException ();		}		public virtual void AddBreakVector (UsageVector vector)		{			if (Parent != null)				Parent.AddBreakVector (vector);			else if ((Block == null) || !Block.IsDestructor)				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);		}		public bool IsFieldAssigned (VariableInfo vi, string field_name)		{			if (CurrentUsageVector.IsAssigned (vi))				return true;			return CurrentUsageVector.IsFieldAssigned (vi, field_name);		}		public void SetAssigned (VariableInfo vi)		{			CurrentUsageVector.SetAssigned (vi);		}		public void SetFieldAssigned (VariableInfo vi, string name)		{			CurrentUsageVector.SetFieldAssigned (vi, name);		}		public override string ToString ()		{			StringBuilder sb = new StringBuilder ();			sb.Append (GetType ());			sb.Append (" (");			sb.Append (id);			sb.Append (",");			sb.Append (Type);			if (Block != null) {				sb.Append (" - ");				sb.Append (Block.ID);				sb.Append (" - ");				sb.Append (Block.StartLocation);			}			sb.Append (" - ");			// sb.Append (Siblings.Length);			// sb.Append (" - ");			sb.Append (CurrentUsageVector);			sb.Append (")");			return sb.ToString ();		}		public string Name {			get {				return String.Format ("{0} ({1}:{2}:{3})",						      GetType (), id, Type, Location);			}		}	}	public class FlowBranchingBlock : FlowBranching	{		UsageVector sibling_list = null;		public FlowBranchingBlock (FlowBranching parent, BranchingType type,					   SiblingType stype, Block block, Location loc)			: base (parent, type, stype, block, loc)		{ }		public override UsageVector CurrentUsageVector {			get { return sibling_list; }		}		protected override void AddSibling (UsageVector sibling)		{			sibling.Next = sibling_list;			sibling_list = sibling;		}		public override LabeledStatement LookupLabel (string name, Location loc)		{			if (Block == null)				return base.LookupLabel (name, loc);			LabeledStatement s = Block.LookupLabel (name);			if (s != null)				return s;			return base.LookupLabel (name, loc);		}		public override void Label (UsageVector origin_vectors)		{			if (!CurrentUsageVector.Reachability.IsUnreachable) {				UsageVector vector = CurrentUsageVector.Clone ();				vector.Next = origin_vectors;				origin_vectors = vector;			}			CurrentUsageVector.MergeJumpOrigins (origin_vectors);		}		protected override UsageVector Merge ()		{			return Merge (sibling_list);		}	}	public class FlowBranchingLoop : FlowBranchingBlock	{		UsageVector break_origins;		public FlowBranchingLoop (FlowBranching parent, Block block, Location loc)			: base (parent, BranchingType.Loop, SiblingType.Conditional, block, loc)		{ }		public override void AddBreakVector (UsageVector vector)		{			vector = vector.Clone ();			vector.Next = break_origins;			break_origins = vector;		}		protected override UsageVector Merge ()		{			UsageVector vector = base.Merge ();			vector.MergeBreakOrigins (this, break_origins);			return vector;		}	}	public class FlowBranchingSwitch : FlowBranchingBlock	{		UsageVector break_origins;		public FlowBranchingSwitch (FlowBranching parent, Block block, Location loc)			: base (parent, BranchingType.Switch, SiblingType.SwitchSection, block, loc)		{ }		public override void AddBreakVector (UsageVector vector)		{			vector = vector.Clone ();			vector.Next = break_origins;			break_origins = vector;		}		protected override UsageVector Merge ()		{			UsageVector vector = base.Merge ();			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 emit_finally;		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;			} else if (sibling.Type == SiblingType.Catch) {				sibling.Next = catch_vectors;				catch_vectors = sibling;			} else if (sibling.Type == SiblingType.Finally) {				sibling.MergeFinallyOrigins (finally_origins);				finally_vector = sibling;			} else				throw new InvalidOperationException ();			current_vector = sibling;		}		public override UsageVector CurrentUsageVector {			get { return current_vector; }		}		public override bool InTryOrCatch (bool is_return)		{			return finally_vector == null;		}		public override bool InTryWithCatch ()		{			if (finally_vector == null) {				Try t = stmt as Try;				if (t != null && t.HasCatch)					return true;			}			if (Parent != null)				return Parent.InTryWithCatch ();			return false;		}		public override bool BreakCrossesTryCatchBoundary ()		{			return true;		}		public override void AddFinallyVector (UsageVector vector)		{			vector = vector.Clone ();			vector.Next = finally_origins;			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)				return base.LookupLabel (name, loc);			LabeledStatement s = current_vector.Block.LookupLabel (name);			if (s != null)				return s;			if (finally_vector != null) {				Report.Error (157, loc,					"Control cannot leave the body of a finally clause");				return null;			}			return base.LookupLabel (name, loc);		}		public override void Label (UsageVector origin_vectors)		{			CurrentUsageVector.MergeJumpOrigins (origin_vectors);		}		protected override UsageVector Merge ()		{			UsageVector vector = Merge (catch_vectors);			vector.MergeFinally (this, finally_vector, finally_origins);			return vector;		}	}	// <summary>	//   This is used by the flow analysis code to keep track of the type of local variables	//   and variables.	//	//   The flow code uses a BitVector to keep track of whether a variable has been assigned	//   or not.  This is easy for fundamental types (int, char etc.) or reference types since	//   you can only assign the whole variable as such.	//	//   For structs, we also need to keep track of all its fields.  To do this, we allocate one	//   bit for the struct itself (it's used if you assign/access the whole struct) followed by	//   one bit for each of its fields.	//	//   This class computes this `layout' for each type.	// </summary>	public class TypeInfo	{		public readonly Type Type;		// <summary>		//   Total number of bits a variable of this type consumes in the flow vector.		// </summary>		public readonly int TotalLength;		// <summary>		//   Number of bits the simple fields of a variable of this type consume		//   in the flow vector.		// </summary>		public readonly int Length;		// <summary>		//   This is only used by sub-structs.		// </summary>		public readonly int Offset;		// <summary>		//   If this is a struct.		// </summary>		public readonly bool IsStruct;	     		// <summary>		//   If this is a struct, all fields which are structs theirselves.		// </summary>		public TypeInfo[] SubStructInfo;		protected readonly StructInfo struct_info;		private static Hashtable type_hash = new Hashtable ();		public static TypeInfo GetTypeInfo (Type type)		{			TypeInfo info = (TypeInfo) type_hash [type];			if (info != null)				return info;			info = new TypeInfo (type);			type_hash.Add (type, info);			return info;		}		public static TypeInfo GetTypeInfo (TypeContainer tc)		{			TypeInfo info = (TypeInfo) type_hash [tc.TypeBuilder];			if (info != null)				return info;			info = new TypeInfo (tc);			type_hash.Add (tc.TypeBuilder, info);			return info;		}		private TypeInfo (Type type)		{			this.Type = type;			struct_info = StructInfo.GetStructInfo (type);			if (struct_info != null) {				Length = struct_info.Length;				TotalLength = struct_info.TotalLength;				SubStructInfo = struct_info.StructFields;				IsStruct = true;			} else {				Length = 0;				TotalLength = 1;				IsStruct = false;			}		}		private TypeInfo (TypeContainer tc)		{			this.Type = tc.TypeBuilder;			struct_info = StructInfo.GetStructInfo (tc);			if (struct_info != null) {				Length = struct_info.Length;				TotalLength = struct_info.TotalLength;				SubStructInfo = struct_info.StructFields;				IsStruct = true;			} else {				Length = 0;				TotalLength = 1;				IsStruct = false;			}		}		protected TypeInfo (StructInfo struct_info, int offset)		{			this.struct_info = struct_info;			this.Offset = offset;			this.Length = struct_info.Length;			this.TotalLength = struct_info.TotalLength;			this.SubStructInfo = struct_info.StructFields;			this.Type = struct_info.Type;			this.IsStruct = true;		}		public int GetFieldIndex (string name)		{			if (struct_info == null)				return 0;			return struct_info [name];		}		public TypeInfo GetSubStruct (string name)		{			if (struct_info == null)				return null;			return struct_info.GetStructField (name);		}		// <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)) {					Report.Error (171, loc,						"Field `{0}' must be fully assigned before control leaves the constructor",						TypeManager.GetFullNameSignature (field));					ok = false;				}			}			return ok;		}		public override string ToString ()		{			return String.Format ("TypeInfo ({0}:{1}:{2}:{3})",					      Type, Offset, Length, TotalLength);		}		protected class StructInfo {			public readonly Type Type;			public readonly FieldInfo[] Fields;			public readonly TypeInfo[] StructFields;			public readonly int Count;			public readonly int CountPublic;			public readonly int CountNonPublic;			public readonly int Length;			public readonly int TotalLength;			public readonly bool HasStructFields;			private static Hashtable field_type_hash = new Hashtable ();			private Hashtable struct_field_hash;			private Hashtable field_hash;			protected bool InTransit = false;			// Private constructor.  To save memory usage, we only need to create one instance			// of this class per struct type.			private StructInfo (Type type)			{				this.Type = type;				field_type_hash.Add (type, this);				if (type is TypeBuilder) {					TypeContainer tc = TypeManager.LookupTypeContainer (type);					ArrayList fields = null;					if (tc != null)						fields = tc.Fields;					ArrayList public_fields = new ArrayList ();					ArrayList non_public_fields = new ArrayList ();					if (fields != null) {						foreach (FieldMember field in fields) {							if ((field.ModFlags & Modifiers.STATIC) != 0)								continue;							if ((field.ModFlags & Modifiers.PUBLIC) != 0)								public_fields.Add (field.FieldBuilder);							else								non_public_fields.Add (field.FieldBuilder);						}					}					CountPublic = public_fields.Count;					CountNonPublic = non_public_fields.Count;					Count = CountPublic + CountNonPublic;					Fields = new FieldInfo [Count];					public_fields.CopyTo (Fields, 0);					non_public_fields.CopyTo (Fields, CountPublic);				} else {					FieldInfo[] public_fields = type.GetFields (						BindingFlags.Instance|BindingFlags.Public);					FieldInfo[] non_public_fields = type.GetFields (						BindingFlags.Instance|BindingFlags.NonPublic);					CountPublic = public_fields.Length;					CountNonPublic = non_public_fields.Length;					Count = CountPublic + CountNonPublic;					Fields = new FieldInfo [Count];					public_fields.CopyTo (Fields, 0);					non_public_fields.CopyTo (Fields, CountPublic);				}				struct_field_hash = new Hashtable ();				field_hash = new Hashtable ();				Length = 0;				StructFields = new TypeInfo [Count];				StructInfo[] sinfo = new StructInfo [Count];				InTransit = true;				for (int i = 0; i < Count; i++) {					FieldInfo field = (FieldInfo) Fields [i];					sinfo [i] = GetStructInfo (field.FieldType);					if (sinfo [i] == null)						field_hash.Add (field.Name, ++Length);					else if (sinfo [i].InTransit) {						Report.Error (523, String.Format (								      "Struct member `{0}.{1}' of type `{2}' causes " +

⌨️ 快捷键说明

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