[mono/mono] d2b12124: The first definite assignment cleanup

"Marek Safar ([email protected])" <[email protected]>
Newsgroups gmane.comp.gnome.mono.patches
Message-ID <00000141a7bbf472-64d3b67d-89d9-4864-b76c-1671101dd9cc-000000@email.amazonses.com>
   Branch: refs/heads/master
     Home: https://github.com/mono/mono
  Compare: https://github.com/mono/mono/compare/ace1e095ce0c...d2b121244a06

   Commit: d2b121244a067146f84deb77dc2c632b10b572b8
   Author: Marek Safar <[email protected]> (marek-safar)
     Date: 2013-10-11 13:35:28 GMT
      URL: https://github.com/mono/mono/commit/d2b121244a067146f84deb77dc2c632b10b572b8

The first definite assignment cleanup

Changed paths:
  M mcs/mcs/anonymous.cs
  M mcs/mcs/context.cs
  M mcs/mcs/ecore.cs
  M mcs/mcs/expression.cs
  M mcs/mcs/flowanalysis.cs
  M mcs/mcs/statement.cs

Modified: mcs/mcs/anonymous.cs
===================================================================
@@ -1522,7 +1522,7 @@ public AnonymousExpression Compatible (ResolveContext ec, AnonymousExpression ae
 
 			var bc = ec as BlockContext;
 			if (bc != null)
-				aec.FlowOffset = bc.FlowOffset;
+				aec.AssignmentInfoOffset = bc.AssignmentInfoOffset;
 
 			var errors = ec.Report.Errors;
 

Modified: mcs/mcs/context.cs
===================================================================
@@ -73,7 +73,10 @@ public class BlockContext : ResolveContext
 
 		readonly TypeSpec return_type;
 
-		public int FlowOffset;
+		//
+		// Tracks the last offset used by VariableInfo
+		//
+		public int AssignmentInfoOffset;
 
 		public BlockContext (IMemberContext mc, ExplicitBlock block, TypeSpec returnType)
 			: base (mc)

Modified: mcs/mcs/ecore.cs
===================================================================
@@ -6808,7 +6808,7 @@ public override void SetHasAddressTaken ()
 			get { return null; }
 		}
 
-		public override void VerifyAssigned (ResolveContext rc)
+		public override void VerifyDefiniteAssignment (ResolveContext rc)
 		{
 		}
 	}

Modified: mcs/mcs/expression.cs
===================================================================
@@ -5397,7 +5397,7 @@ public abstract class VariableReference : Expression, IAssignMethod, IMemoryLoca
 		#region Abstract
 		public abstract HoistedVariable GetHoistedVariable (AnonymousExpression ae);
 		public abstract void SetHasAddressTaken ();
-		public abstract void VerifyAssigned (ResolveContext rc);
+		public abstract void VerifyDefiniteAssignment (ResolveContext rc);
 
 		public abstract bool IsLockedByStatement { get; set; }
 
@@ -5630,9 +5630,9 @@ public override HoistedVariable GetHoistedVariable (AnonymousExpression ae)
 
 		#endregion
 
-		public override void VerifyAssigned (ResolveContext rc)
+		public override void VerifyDefiniteAssignment (ResolveContext rc)
 		{
-			VariableInfo variable_info = local_info.VariableInfo;
+			VariableInfo variable_info = VariableInfo;
 			if (variable_info == null)
 				return;
 
@@ -5677,7 +5677,7 @@ protected override Expression DoResolve (ResolveContext ec)
 		{
 			local_info.SetIsUsed ();
 
-			VerifyAssigned (ec);
+			VerifyDefiniteAssignment (ec);
 
 			DoResolveBase (ec);
 			return this;
@@ -5897,24 +5897,12 @@ public override Expression CreateExpressionTree (ResolveContext ec)
 			return Parameter.ExpressionTreeVariableReference ();
 		}
 
-		//
-		// Notice that for ref/out parameters, the type exposed is not the
-		// same type exposed externally.
-		//
-		// for "ref int a":
-		//   externally we expose "int&"
-		//   here we expose       "int".
-		//
-		// We record this in "is_ref".  This means that the type system can treat
-		// the type as it is expected, but when we generate the code, we generate
-		// the alternate kind of code.
-		//
 		protected override Expression DoResolve (ResolveContext ec)
 		{
 			if (!DoResolveBase (ec))
 				return null;
 
-			VerifyAssigned (ec);
+			VerifyDefiniteAssignment (ec);
 			return this;
 		}
 
@@ -5927,15 +5915,17 @@ public override Expression DoResolveLValue (ResolveContext ec, Expression right_
 			return base.DoResolveLValue (ec, right_side);
 		}
 
-		public override void VerifyAssigned (ResolveContext rc)
+		public override void VerifyDefiniteAssignment (ResolveContext rc)
 		{
-			// HACK: Variables are not captured in probing mode
-			if (rc.IsInProbingMode)
+			VariableInfo variable_info = VariableInfo;
+			if (variable_info == null)
 				return;
 
-			if (HasOutModifier && !VariableInfo.IsAssigned (rc)) {
-				rc.Report.Error (269, loc, "Use of unassigned out parameter `{0}'", Name);
-			}
+			if (variable_info.IsAssigned (rc))
+				return;
+
+			rc.Report.Error (269, loc, "Use of unassigned out parameter `{0}'", Name);
+			variable_info.SetAssigned (rc);
 		}
 	}
 	
@@ -7817,7 +7807,7 @@ public override void SetHasAddressTaken ()
 			// Nothing
 		}
 
-		public override void VerifyAssigned (ResolveContext rc)
+		public override void VerifyDefiniteAssignment (ResolveContext rc)
 		{
 		}
 		
@@ -8730,7 +8720,7 @@ public override Expression LookupNameExpression (ResolveContext rc, MemberLookup
 				if (sn != null) {
 					var vr = expr as VariableReference;
 					if (vr != null)
-						vr.VerifyAssigned (rc);
+						vr.VerifyDefiniteAssignment (rc);
 				}
 
 				Arguments args = new Arguments (1);
@@ -8770,7 +8760,7 @@ public override Expression LookupNameExpression (ResolveContext rc, MemberLookup
 							if (sn != null && !errorMode) {
 								var vr = expr as VariableReference;
 								if (vr != null)
-									vr.VerifyAssigned (rc);
+									vr.VerifyDefiniteAssignment (rc);
 							}
 
 							// TODO: it should really skip the checks bellow
@@ -8852,7 +8842,7 @@ public override Expression LookupNameExpression (ResolveContext rc, MemberLookup
 			if (sn != null && !(me is FieldExpr && TypeSpec.IsValueType (expr_type))) {
 				var vr = expr as VariableReference;
 				if (vr != null)
-					vr.VerifyAssigned (rc);
+					vr.VerifyDefiniteAssignment (rc);
 			}
 
 			return me;

Modified: mcs/mcs/flowanalysis.cs
===================================================================
@@ -1317,14 +1317,16 @@ public static StructInfo GetStructInfo (TypeSpec type)
 		}
 	}
 
-	// <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 {
+	//
+	// This is used by definite assignment analysis code to store information about a 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.
+	//
+	public class VariableInfo
+	{
 		readonly string Name;
+
 		readonly TypeInfo TypeInfo;
 
 		// <summary>
@@ -1337,12 +1339,12 @@ public class VariableInfo {
 		//   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;
+		readonly int Length;
 
 		// <summary>
 		//   If this is a parameter of local variable.
 		// </summary>
-		public readonly bool IsParameter;
+		public bool IsParameter;
 
 		VariableInfo[] sub_info;
 
@@ -1369,7 +1371,7 @@ public class VariableInfo {
 			Initialize ();
 		}
 
-		protected void Initialize ()
+		void Initialize ()
 		{
 			TypeInfo[] sub_fields = TypeInfo.SubStructInfo;
 			if (sub_fields != null) {
@@ -1382,16 +1384,21 @@ protected void Initialize ()
 				sub_info = new VariableInfo [0];
 		}
 
-		public VariableInfo (LocalVariable local_info, int offset)
-			: this (local_info.Name, local_info.Type, offset)
+		public static VariableInfo Create (BlockContext bc, LocalVariable variable)
 		{
-			this.IsParameter = false;
+			var info = new VariableInfo (variable.Name, variable.Type, bc.AssignmentInfoOffset);
+			bc.AssignmentInfoOffset += info.Length;
+			return info;
 		}
 
-		public VariableInfo (ParametersCompiled ip, int i, int offset)
-			: this (ip.FixedParameters [i].Name, ip.Types [i], offset)
+		public static VariableInfo Create (BlockContext bc, Parameter parameter)
 		{
-			this.IsParameter = true;
+			var info = new VariableInfo (parameter.Name, parameter.Type, bc.AssignmentInfoOffset) {
+				IsParameter = true
+			};
+
+			bc.AssignmentInfoOffset += info.Length;
+			return info;
 		}
 
 		public bool IsAssigned (ResolveContext ec)

Modified: mcs/mcs/statement.cs
===================================================================
@@ -1628,7 +1628,7 @@ public bool Resolve (BlockContext bc, bool resolveDeclaratorInitializers)
 			if (eval_global) {
 				CreateEvaluatorVariable (bc, li);
 			} else if (type != InternalType.ErrorType) {
-				li.PrepareForFlowAnalysis (bc);
+				li.PrepareAssignmentAnalysis (bc);
 			}
 
 			if (initializer != null) {
@@ -1642,7 +1642,7 @@ public bool Resolve (BlockContext bc, bool resolveDeclaratorInitializers)
 					if (eval_global) {
 						CreateEvaluatorVariable (bc, d.Variable);
 					} else if (type != InternalType.ErrorType) {
-						d.Variable.PrepareForFlowAnalysis (bc);
+						d.Variable.PrepareAssignmentAnalysis (bc);
 					}
 
 					if (d.Initializer != null && resolveDeclaratorInitializers) {
@@ -2020,16 +2020,15 @@ public bool IsAssigned (BlockContext ec)
 			return !ec.DoFlowAnalysis || ec.CurrentBranching.IsAssigned (VariableInfo);
 		}
 
-		public void PrepareForFlowAnalysis (BlockContext bc)
+		public void PrepareAssignmentAnalysis (BlockContext bc)
 		{
 			//
-			// No need for definitely assigned check for these guys
+			// No need to run assignment analysis for these guys
 			//
 			if ((flags & (Flags.Constant | Flags.ReadonlyMask | Flags.CompilerGenerated)) != 0)
 				return;
 
-			VariableInfo = new VariableInfo (this, bc.FlowOffset);
-			bc.FlowOffset += VariableInfo.Length;
+			VariableInfo = VariableInfo.Create (bc, this);
 		}
 
 		//
@@ -3094,7 +3093,7 @@ public bool Resolve (FlowBranching parent, BlockContext rc, IMethodData md)
 				flags |= Flags.IsExpressionTree;
 
 			try {
-				ResolveMeta (rc);
+				PrepareAssignmentAnalysis (rc);
 
 				using (rc.With (ResolveContext.Options.DoFlowAnalysis, true)) {
 					FlowBranchingToplevel top_level = rc.StartFlowBranching (this, parent);
@@ -3150,19 +3149,15 @@ public bool Resolve (FlowBranching parent, BlockContext rc, IMethodData md)
 			return true;
 		}
 
-		void ResolveMeta (BlockContext ec)
+		void PrepareAssignmentAnalysis (BlockContext bc)
 		{
-			int orig_count = parameters.Count;
-
-			for (int i = 0; i < orig_count; ++i) {
-				Parameter.Modifier mod = parameters.FixedParameters[i].ModFlags;
+			for (int i = 0; i < parameters.Count; ++i) {
+				var par = parameters.FixedParameters[i];
 
-				if ((mod & Parameter.Modifier.OUT) == 0)
+				if ((par.ModFlags & Parameter.Modifier.OUT) == 0)
 					continue;
 
-				VariableInfo vi = new VariableInfo (parameters, i, ec.FlowOffset);
-				parameter_info[i].VariableInfo = vi;
-				ec.FlowOffset += vi.Length;
+				parameter_info [i].VariableInfo = VariableInfo.Create (bc, (Parameter) par);
 			}
 		}
 
@@ -3576,7 +3571,7 @@ public void AddThisVariable (BlockContext bc)
 
 			this_variable = new LocalVariable (this, "this", LocalVariable.Flags.IsThis | LocalVariable.Flags.Used, StartLocation);
 			this_variable.Type = bc.CurrentType;
-			this_variable.PrepareForFlowAnalysis (bc);
+			this_variable.PrepareAssignmentAnalysis (bc);
 		}
 
 		public bool IsThisAssigned (BlockContext ec)
@@ -5462,7 +5457,7 @@ public override bool Resolve (BlockContext ec)
 						ec.Report.Error (155, loc, "The type caught or thrown must be derived from System.Exception");
 					} else if (li != null) {
 						li.Type = type;
-						li.PrepareForFlowAnalysis (ec);
+						li.PrepareAssignmentAnalysis (ec);
 
 						// source variable is at the top of the stack
 						Expression source = new EmptyExpression (li.Type);


_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.