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

📄 flowanalysis.cs

📁 C#编译器源代码。Micorsoft开放源代码
💻 CS
📖 第 1 页 / 共 4 页
字号:
								      "a cycle in the structure layout",								      type, field.Name, sinfo [i].Type));						sinfo [i] = null;						return;					}				}				InTransit = false;				TotalLength = Length + 1;				for (int i = 0; i < Count; i++) {					FieldInfo field = (FieldInfo) Fields [i];					if (sinfo [i] == null)						continue;					field_hash.Add (field.Name, TotalLength);					HasStructFields = true;					StructFields [i] = new TypeInfo (sinfo [i], TotalLength);					struct_field_hash.Add (field.Name, StructFields [i]);					TotalLength += sinfo [i].TotalLength;				}			}			public int this [string name] {				get {					if (field_hash.Contains (name))						return (int) field_hash [name];					else						return 0;				}			}			public TypeInfo GetStructField (string name)			{				return (TypeInfo) struct_field_hash [name];			}			public static StructInfo GetStructInfo (Type type)			{				if (!TypeManager.IsValueType (type) || TypeManager.IsEnumType (type) ||				    TypeManager.IsBuiltinType (type))					return null;				StructInfo info = (StructInfo) field_type_hash [type];				if (info != null)					return info;				return new StructInfo (type);			}			public static StructInfo GetStructInfo (TypeContainer tc)			{				StructInfo info = (StructInfo) field_type_hash [tc.TypeBuilder];				if (info != null)					return info;				return new StructInfo (tc.TypeBuilder);			}		}	}	// <summary>	//   This is used by the flow analysis code to store information about a single local variable	//   or parameter.  Depending on the variable's type, we need to allocate one or more elements	//   in the BitVector - if it's a fundamental or reference type, we just need to know whether	//   it has been assigned or not, but for structs, we need this information for each of its fields.	// </summary>	public class VariableInfo {		public readonly string Name;		public readonly TypeInfo TypeInfo;		// <summary>		//   The bit offset of this variable in the flow vector.		// </summary>		public readonly int Offset;		// <summary>		//   The number of bits this variable needs in the flow vector.		//   The first bit always specifies whether the variable as such has been assigned while		//   the remaining bits contain this information for each of a struct's fields.		// </summary>		public readonly int Length;		// <summary>		//   If this is a parameter of local variable.		// </summary>		public readonly bool IsParameter;		public readonly LocalInfo LocalInfo;		public readonly int ParameterIndex;		readonly VariableInfo Parent;		VariableInfo[] sub_info;		protected VariableInfo (string name, Type type, int offset)		{			this.Name = name;			this.Offset = offset;			this.TypeInfo = TypeInfo.GetTypeInfo (type);			Length = TypeInfo.TotalLength;			Initialize ();		}		protected VariableInfo (VariableInfo parent, TypeInfo type)		{			this.Name = parent.Name;			this.TypeInfo = type;			this.Offset = parent.Offset + type.Offset;			this.Parent = parent;			this.Length = type.TotalLength;			this.IsParameter = parent.IsParameter;			this.LocalInfo = parent.LocalInfo;			this.ParameterIndex = parent.ParameterIndex;			Initialize ();		}		protected void Initialize ()		{			TypeInfo[] sub_fields = TypeInfo.SubStructInfo;			if (sub_fields != null) {				sub_info = new VariableInfo [sub_fields.Length];				for (int i = 0; i < sub_fields.Length; i++) {					if (sub_fields [i] != null)						sub_info [i] = new VariableInfo (this, sub_fields [i]);				}			} else				sub_info = new VariableInfo [0];		}		public VariableInfo (LocalInfo local_info, int offset)			: this (local_info.Name, local_info.VariableType, offset)		{			this.LocalInfo = local_info;			this.IsParameter = false;		}		public VariableInfo (string name, Type type, int param_idx, int offset)			: this (name, type, offset)		{			this.ParameterIndex = param_idx;			this.IsParameter = true;		}		public bool IsAssigned (EmitContext ec)		{			return !ec.DoFlowAnalysis ||				ec.OmitStructFlowAnalysis && TypeInfo.IsStruct ||				ec.CurrentBranching.IsAssigned (this);		}		public bool IsAssigned (EmitContext ec, Location loc)		{			if (IsAssigned (ec))				return true;			Report.Error (165, loc,				      "Use of unassigned local variable `" + Name + "'");			ec.CurrentBranching.SetAssigned (this);			return false;		}		public bool IsAssigned (MyBitVector vector)		{			if (vector [Offset])				return true;			for (VariableInfo parent = Parent; parent != null; parent = parent.Parent)				if (vector [parent.Offset])					return true;			// Return unless this is a struct.			if (!TypeInfo.IsStruct)				return false;			// Ok, so each field must be assigned.			for (int i = 0; i < TypeInfo.Length; i++) {				if (!vector [Offset + i + 1])					return false;			}			// Ok, now check all fields which are structs.			for (int i = 0; i < sub_info.Length; i++) {				VariableInfo sinfo = sub_info [i];				if (sinfo == null)					continue;				if (!sinfo.IsAssigned (vector))					return false;			}			vector [Offset] = true;			return true;		}		public void SetAssigned (EmitContext ec)		{			if (ec.DoFlowAnalysis)				ec.CurrentBranching.SetAssigned (this);		}		public void SetAssigned (MyBitVector vector)		{			vector [Offset] = true;		}		public bool IsFieldAssigned (EmitContext ec, string name, Location loc)		{			if (!ec.DoFlowAnalysis ||				ec.OmitStructFlowAnalysis && TypeInfo.IsStruct ||				ec.CurrentBranching.IsFieldAssigned (this, name))				return true;			Report.Error (170, loc,				      "Use of possibly unassigned field `" + name + "'");			ec.CurrentBranching.SetFieldAssigned (this, name);			return false;		}		public bool IsFieldAssigned (MyBitVector vector, string field_name)		{			int field_idx = TypeInfo.GetFieldIndex (field_name);			if (field_idx == 0)				return true;			return vector [Offset + field_idx];		}		public void SetFieldAssigned (EmitContext ec, string name)		{			if (ec.DoFlowAnalysis)				ec.CurrentBranching.SetFieldAssigned (this, name);		}		public void SetFieldAssigned (MyBitVector vector, string field_name)		{			int field_idx = TypeInfo.GetFieldIndex (field_name);			if (field_idx == 0)				return;			vector [Offset + field_idx] = true;		}		public VariableInfo GetSubStruct (string name)		{			TypeInfo type = TypeInfo.GetSubStruct (name);			if (type == null)				return null;			return new VariableInfo (this, type);		}		public override string ToString ()		{			return String.Format ("VariableInfo ({0}:{1}:{2}:{3}:{4})",					      Name, TypeInfo, Offset, Length, IsParameter);		}	}	// <summary>	//   This is used by the flow code to hold the `layout' of the flow vector for	//   all locals and all parameters (ie. we create one instance of this class for the	//   locals and another one for the params).	// </summary>	public class VariableMap {		// <summary>		//   The number of variables in the map.		// </summary>		public readonly int Count;		// <summary>		//   Total length of the flow vector for this map.		// <summary>		public readonly int Length;		VariableInfo[] map;		public VariableMap (InternalParameters ip)		{			Count = ip != null ? ip.Count : 0;						// Dont bother allocating anything!			if (Count == 0)				return;						Length = 0;			for (int i = 0; i < Count; i++) {				Parameter.Modifier mod = ip.ParameterModifier (i);				if ((mod & Parameter.Modifier.OUT) == 0)					continue;								// Dont allocate till we find an out var.				if (map == null)					map = new VariableInfo [Count];				map [i] = new VariableInfo (ip.ParameterName (i),					TypeManager.GetElementType (ip.ParameterType (i)), i, Length);								Length += map [i].Length;			}		}		public VariableMap (LocalInfo[] locals)			: this (null, locals)		{ }		public VariableMap (VariableMap parent, LocalInfo[] locals)		{			int offset = 0, start = 0;			if (parent != null && parent.map != null) {				offset = parent.Length;				start = parent.Count;			}			Count = locals.Length + start;						if (Count == 0)				return;						map = new VariableInfo [Count];			Length = offset;			if (parent != null && parent.map != null) {				parent.map.CopyTo (map, 0);			}			for (int i = start; i < Count; i++) {				LocalInfo li = locals [i-start];				if (li.VariableType == null)					continue;				map [i] = li.VariableInfo = new VariableInfo (li, Length);				Length += map [i].Length;			}		}		// <summary>		//   Returns the VariableInfo for variable @index or null if we don't need to		//   compute assignment info for this variable.		// </summary>		public VariableInfo this [int index] {			get {				if (map == null)					return null;								return map [index];			}		}		public override string ToString ()		{			return String.Format ("VariableMap ({0}:{1})", Count, Length);		}	}	// <summary>	//   This is a special bit vector which can inherit from another bit vector doing a	//   copy-on-write strategy.  The inherited vector may have a smaller size than the	//   current one.	// </summary>	public class MyBitVector {		public readonly int Count;		public readonly MyBitVector InheritsFrom;		bool is_dirty;		BitArray vector;		public MyBitVector (int Count)			: this (null, Count)		{ }		public MyBitVector (MyBitVector InheritsFrom, int Count)		{			this.InheritsFrom = InheritsFrom;			this.Count = Count;		}		// <summary>		//   Checks whether this bit vector has been modified.  After setting this to true,		//   we won't use the inherited vector anymore, but our own copy of it.		// </summary>		public bool IsDirty {			get {				return is_dirty;			}			set {				if (!is_dirty)					initialize_vector ();			}		}		// <summary>		//   Get/set bit `index' in the bit vector.		// </summary>		public bool this [int index]		{			get {				if (index > Count)					throw new ArgumentOutOfRangeException ();				// We're doing a "copy-on-write" strategy here; as long				// as nobody writes to the array, we can use our parent's				// copy instead of duplicating the vector.				if (vector != null)					return vector [index];				else if (InheritsFrom != null) {					BitArray inherited = InheritsFrom.Vector;					if (index < inherited.Count)						return inherited [index];					else						return false;				} else					return false;			}			set {				if (index > Count)					throw new ArgumentOutOfRangeException ();				// Only copy the vector if we're actually modifying it.				if (this [index] != value) {					initialize_vector ();					vector [index] = value;				}			}		}		// <summary>		//   If you explicitly convert the MyBitVector to a BitArray, you will get a deep		//   copy of the bit vector.		// </summary>		public static explicit operator BitArray (MyBitVector vector)		{			vector.initialize_vector ();			return vector.Vector;		}		// <summary>		//   Performs an `or' operation on the bit vector.  The `new_vector' may have a		//   different size than the current one.		// </summary>		public void Or (MyBitVector new_vector)		{			BitArray new_array = new_vector.Vector;			initialize_vector ();			int upper;			if (vector.Count < new_array.Count)				upper = vector.Count;			else				upper = new_array.Count;			for (int i = 0; i < upper; i++)				vector [i] = vector [i] | new_array [i];		}		// <summary>		//   Perfonrms an `and' operation on the bit vector.  The `new_vector' may have		//   a different size than the current one.		// </summary>		public void And (MyBitVector new_vector)		{			BitArray new_array;			if (new_vector != null)				new_array = new_vector.Vector;			else				new_array = new BitArray (Count, false);			initialize_vector ();			int lower, upper;			if (vector.Count < new_array.Count)				lower = upper = vector.Count;			else {				lower = new_array.Count;				upper = vector.Count;			}			for (int i = 0; i < lower; i++)				vector [i] = vector [i] & new_array [i];			for (int i = lower; i < upper; i++)				vector [i] = false;		}		public static void And (ref MyBitVector target, MyBitVector vector)		{			if (target != null)				target.And (vector);			else				target = vector.Clone ();		}		public static void Or (ref MyBitVector target, MyBitVector vector)		{			if (target != null)				target.Or (vector);			else				target = vector.Clone ();		}		// <summary>		//   This does a deep copy of the bit vector.		// </summary>		public MyBitVector Clone ()		{			MyBitVector retval = new MyBitVector (Count);			retval.Vector = Vector;			return retval;		}		BitArray Vector {			get {				if (vector != null)					return vector;				else if (!is_dirty && (InheritsFrom != null))					return InheritsFrom.Vector;				initialize_vector ();				return vector;			}			set {				initialize_vector ();				for (int i = 0; i < System.Math.Min (vector.Count, value.Count); i++)					vector [i] = value [i];			}		}		void initialize_vector ()		{			if (vector != null)				return;						vector = new BitArray (Count, false);			if (InheritsFrom != null)				Vector = InheritsFrom.Vector;			is_dirty = true;		}		public override string ToString ()		{			StringBuilder sb = new StringBuilder ("{");			BitArray vector = Vector;			if (!IsDirty)				sb.Append ("=");			for (int i = 0; i < vector.Count; i++) {				sb.Append (vector [i] ? "1" : "0");			}						sb.Append ("}");			return sb.ToString ();		}	}}

⌨️ 快捷键说明

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