- public bool Resolve (FlowBranching parent, BlockContext rc, ParametersCompiled ip, IMethodData md)
- {
- if (resolved)
- return true;
-
- resolved = true;
-
- if (rc.HasSet (ResolveContext.Options.ExpressionTreeConversion))
- flags |= Flags.IsExpressionTree;
-
- try {
- if (!ResolveMeta (rc, ip))
- return false;
-
- 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) {
-#if PRODUCTION
- if (rc.CurrentBlock != null) {
- ec.Report.Error (584, rc.CurrentBlock.StartLocation, "Internal compiler error: Phase Resolve");
- } else {
- ec.Report.Error (587, "Internal compiler error: Phase Resolve");
- }
-#endif
- throw;
- }
-
- if (rc.ReturnType != TypeManager.void_type && !unreachable) {
- if (rc.CurrentAnonymousMethod == null) {
- rc.Report.Error (161, md.Location, "`{0}': not all code paths return a value", md.GetSignatureForError ());
- return false;
- } else if (!rc.CurrentAnonymousMethod.IsIterator) {
- 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;
- }
-
- bool ResolveMeta (BlockContext ec, ParametersCompiled ip)
- {
- int errors = ec.Report.Errors;
- int orig_count = parameters.Count;
-
- if (ip != null)
- parameters = ip;
-
- // Assert: orig_count != parameter.Count => orig_count == 0
- if (orig_count != 0 && orig_count != parameters.Count)
- throw new InternalErrorException ("parameter information mismatch");
-
- int offset = Parent == null ? 0 : Parent.AssignableSlots;
-
- for (int i = 0; i < orig_count; ++i) {
- Parameter.Modifier mod = parameters.FixedParameters [i].ModFlags;
-
- if ((mod & Parameter.Modifier.OUT) != Parameter.Modifier.OUT)
- continue;
-
- VariableInfo vi = new VariableInfo (ip, i, offset);
- parameter_info [i].VariableInfo = vi;
- offset += vi.Length;
- }
-
- ResolveMeta (ec, offset);
-
- return ec.Report.Errors == errors;
- }
-
- // <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;
-
- Report.Error (177, loc, "The out parameter `{0}' must be assigned to before control leaves the current method",
- var.Name);
- }
- }
-