public override bool Resolve (BlockContext ec) { bool ok = true; ec.StartFlowBranching (this); if (!stmt.Resolve (ec)) ok = false; if (ok) ec.CurrentBranching.CreateSibling (fini, FlowBranching.SiblingType.Finally); using (ec.With (ResolveContext.Options.FinallyScope, true)) { if (!fini.Resolve (ec)) ok = false; } ec.EndFlowBranching (); ok &= base.Resolve (ec); return ok; }
public override bool Resolve (BlockContext ec) { using (ec.With (ResolveContext.Options.AllCheckStateFlags, true)) return Block.Resolve (ec); }
public override bool Resolve (BlockContext ec) { using (ec.With (ResolveContext.Options.CatchScope, true)) { if (type_expr != null) { TypeExpr te = type_expr.ResolveAsTypeTerminal (ec, false); if (te == null) return false; type = te.Type; if (type != TypeManager.exception_type && !TypeSpec.IsBaseClass (type, TypeManager.exception_type, false)) { 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); // source variable is at the top of the stack Expression source = new EmptyExpression (li.Type); if (li.Type.IsGenericParameter) source = new UnboxCast (source, li.Type); assign = new CompilerAssign (new LocalVariableReference (li, loc), source, loc); Block.AddScopeStatement (new StatementExpression (assign)); } } return Block.Resolve (ec); } }
public bool Resolve (FlowBranching parent, BlockContext rc, IMethodData md) { if (resolved) return true; resolved = true; if (rc.HasSet (ResolveContext.Options.ExpressionTreeConversion)) flags |= Flags.IsExpressionTree; try { ResolveMeta (rc); 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 e) { if (e is CompletionResult || rc.Report.IsDisabled) throw; if (rc.CurrentBlock != null) { rc.Report.Error (584, rc.CurrentBlock.StartLocation, "Internal compiler error: {0}", e.Message); } else { rc.Report.Error (587, "Internal compiler error: {0}", e.Message); } if (Report.DebugFlags > 0) throw; } if (rc.ReturnType != TypeManager.void_type && !unreachable) { if (rc.CurrentAnonymousMethod == null) { // FIXME: Missing FlowAnalysis for generated iterator MoveNext method if (md is IteratorMethod) { unreachable = true; } else { rc.Report.Error (161, md.Location, "`{0}': not all code paths return a value", md.GetSignatureForError ()); return false; } } else { 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; }
public override bool Resolve (BlockContext ec) { using (ec.With (ResolveContext.Options.CatchScope, true)) { if (type_expr != null) { TypeExpr te = type_expr.ResolveAsTypeTerminal (ec, false); if (te == null) return false; type = te.Type; if (type != TypeManager.exception_type && !TypeManager.IsSubclassOf (type, TypeManager.exception_type)){ ec.Report.Error (155, loc, "The type caught or thrown must be derived from System.Exception"); return false; } } else type = null; if (!Block.Resolve (ec)) return false; // Even though VarBlock surrounds 'Block' we resolve it later, so that we can correctly // emit the "unused variable" warnings. if (VarBlock != null) return VarBlock.Resolve (ec); return true; } }
protected void ResolveMeta (BlockContext ec, int offset) { Report.Debug (64, "BLOCK RESOLVE META", this, Parent); // If some parent block was unsafe, we remain unsafe even if this block // isn't explicitly marked as such. using (ec.With (ResolveContext.Options.UnsafeScope, ec.IsUnsafe | Unsafe)) { flags |= Flags.VariablesInitialized; if (variables != null) { foreach (LocalInfo li in variables.Values) { if (!li.Resolve (ec)) continue; li.VariableInfo = new VariableInfo (li, offset); offset += li.VariableInfo.Length; } } assignable_slots = offset; DoResolveConstants (ec); if (children == null) return; foreach (Block b in children) b.ResolveMeta (ec, offset); } }
void DoResolveConstants (BlockContext ec) { if (constants == null) return; if (variables == null) throw new InternalErrorException ("cannot happen"); foreach (var de in variables) { string name = de.Key; LocalInfo vi = de.Value; TypeSpec variable_type = vi.VariableType; if (variable_type == null) { if (vi.Type is VarExpr) ec.Report.Error (822, vi.Type.Location, "An implicitly typed local variable cannot be a constant"); continue; } Expression cv; if (!constants.TryGetValue (name, out cv)) continue; // Don't let 'const int Foo = Foo;' succeed. // Removing the name from 'constants' ensures that we get a LocalVariableReference below, // which in turn causes the 'must be constant' error to be triggered. constants.Remove (name); if (!variable_type.IsConstantCompatible) { Const.Error_InvalidConstantType (variable_type, loc, ec.Report); continue; } ec.CurrentBlock = this; Expression e; using (ec.With (ResolveContext.Options.ConstantCheckState, (flags & Flags.Unchecked) == 0)) { using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) { e = cv.Resolve (ec); } } if (e == null) continue; Constant ce = e as Constant; if (ce == null) { e.Error_ExpressionMustBeConstant (ec, vi.Location, name); continue; } e = ce.ConvertImplicitly (ec, variable_type); if (e == null) { if (TypeManager.IsReferenceType (variable_type)) ce.Error_ConstantCanBeInitializedWithNullOnly (ec, variable_type, vi.Location, vi.Name); else ce.Error_ValueCannotBeConverted (ec, vi.Location, variable_type, false); continue; } constants.Add (name, e); vi.IsConstant = true; } }
public bool Resolve (FlowBranching parent, BlockContext rc, ParametersCompiled ip, IMethodData md) { if (resolved) return true; resolved = true; 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; }