/// Resolves the statement, true means that all sub-statements
/// did resolve ok.
// </summary>
- public virtual bool Resolve (EmitContext ec)
+ public virtual bool Resolve (BlockContext ec)
{
return true;
}
/// We already know that the statement is unreachable, but we still
/// need to resolve it to catch errors.
/// </summary>
- public virtual bool ResolveUnreachable (EmitContext ec, bool warn)
+ public virtual bool ResolveUnreachable (BlockContext ec, bool warn)
{
//
// This conflicts with csc's way of doing this, but IMHO it's
//
if (warn)
- Report.Warning (162, 2, loc, "Unreachable code detected");
+ ec.Report.Warning (162, 2, loc, "Unreachable code detected");
ec.StartFlowBranching (FlowBranching.BranchingType.Block, loc);
bool ok = Resolve (ec);
/// </summary>
protected abstract void DoEmit (EmitContext ec);
- /// <summary>
- /// Utility wrapper routine for Error, just to beautify the code
- /// </summary>
- public void Error (int error, string format, params object[] args)
- {
- Error (error, String.Format (format, args));
- }
-
- public void Error (int error, string s)
- {
- if (!loc.IsNull)
- Report.Error (error, loc, s);
- else
- Report.Error (error, s);
- }
-
public virtual void Emit (EmitContext ec)
{
ec.Mark (loc);
return s;
}
- public virtual Expression CreateExpressionTree (EmitContext ec)
+ public virtual Expression CreateExpressionTree (ResolveContext ec)
{
- Report.Error (834, loc, "A lambda expression with statement body cannot be converted to an expresion tree");
+ ec.Report.Error (834, loc, "A lambda expression with statement body cannot be converted to an expresion tree");
return null;
}
public abstract void MutateHoistedGenericType (AnonymousMethodStorey storey);
}
- //
- // This class is used during the Statement.Clone operation
- // to remap objects that have been cloned.
- //
- // Since blocks are cloned by Block.Clone, we need a way for
- // expressions that must reference the block to be cloned
- // pointing to the new cloned block.
- //
- public class CloneContext {
- Hashtable block_map = new Hashtable ();
- Hashtable variable_map;
-
- public void AddBlockMap (Block from, Block to)
- {
- if (block_map.Contains (from))
- return;
- block_map [from] = to;
- }
-
- public Block LookupBlock (Block from)
- {
- Block result = (Block) block_map [from];
-
- if (result == null){
- result = (Block) from.Clone (this);
- block_map [from] = result;
- }
-
- return result;
- }
-
- ///
- /// Remaps block to cloned copy if one exists.
- ///
- public Block RemapBlockCopy (Block from)
- {
- Block mapped_to = (Block)block_map[from];
- if (mapped_to == null)
- return from;
-
- return mapped_to;
- }
-
- public void AddVariableMap (LocalInfo from, LocalInfo to)
- {
- if (variable_map == null)
- variable_map = new Hashtable ();
-
- if (variable_map.Contains (from))
- return;
- variable_map [from] = to;
- }
-
- public LocalInfo LookupVariable (LocalInfo from)
- {
- LocalInfo result = (LocalInfo) variable_map [from];
-
- if (result == null)
- throw new Exception ("LookupVariable: looking up a variable that has not been registered yet");
-
- return result;
- }
- }
-
public sealed class EmptyStatement : Statement {
private EmptyStatement () {}
public static readonly EmptyStatement Value = new EmptyStatement ();
-
- public override bool Resolve (EmitContext ec)
+
+ public override bool Resolve (BlockContext ec)
{
return true;
}
- public override bool ResolveUnreachable (EmitContext ec, bool warn)
+ public override bool ResolveUnreachable (BlockContext ec, bool warn)
{
return true;
}
public Statement FalseStatement;
bool is_true_ret;
-
- public If (Expression expr, Statement true_statement, Location l)
+
+ public If (Expression bool_expr, Statement true_statement, Location l)
+ : this (bool_expr, true_statement, null, l)
{
- this.expr = expr;
- TrueStatement = true_statement;
- loc = l;
}
- public If (Expression expr,
+ public If (Expression bool_expr,
Statement true_statement,
Statement false_statement,
Location l)
{
- this.expr = expr;
+ this.expr = bool_expr;
TrueStatement = true_statement;
FalseStatement = false_statement;
loc = l;
FalseStatement.MutateHoistedGenericType (storey);
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
bool ok = true;
Report.Debug (1, "START IF BLOCK", loc);
- expr = Expression.ResolveBoolean (ec, expr, loc);
- if (expr == null){
+ expr = expr.Resolve (ec);
+ if (expr == null) {
ok = false;
- goto skip;
- }
-
- Assign ass = expr as Assign;
- if (ass != null && ass.Source is Constant) {
- Report.Warning (665, 3, loc, "Assignment in conditional expression is always constant; did you mean to use == instead of = ?");
- }
+ } else {
+ //
+ // Dead code elimination
+ //
+ if (expr is Constant) {
+ bool take = !((Constant) expr).IsDefaultValue;
- //
- // Dead code elimination
- //
- if (expr is Constant){
- bool take = !((Constant) expr).IsDefaultValue;
+ if (take) {
+ if (!TrueStatement.Resolve (ec))
+ return false;
- if (take){
- if (!TrueStatement.Resolve (ec))
- return false;
+ if ((FalseStatement != null) &&
+ !FalseStatement.ResolveUnreachable (ec, true))
+ return false;
+ FalseStatement = null;
+ } else {
+ if (!TrueStatement.ResolveUnreachable (ec, true))
+ return false;
+ TrueStatement = null;
- if ((FalseStatement != null) &&
- !FalseStatement.ResolveUnreachable (ec, true))
- return false;
- FalseStatement = null;
- } else {
- if (!TrueStatement.ResolveUnreachable (ec, true))
- return false;
- TrueStatement = null;
+ if ((FalseStatement != null) &&
+ !FalseStatement.Resolve (ec))
+ return false;
+ }
- if ((FalseStatement != null) &&
- !FalseStatement.Resolve (ec))
- return false;
+ return true;
}
-
- return true;
}
- skip:
+
ec.StartFlowBranching (FlowBranching.BranchingType.Conditional, loc);
ok &= TrueStatement.Resolve (ec);
public class Do : Statement {
public Expression expr;
public Statement EmbeddedStatement;
-
- public Do (Statement statement, Expression bool_expr, Location l)
+
+ public Do (Statement statement, BooleanExpression bool_expr, Location l)
{
expr = bool_expr;
EmbeddedStatement = statement;
loc = l;
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
bool ok = true;
ec.EndFlowBranching ();
if (ec.CurrentBranching.CurrentUsageVector.IsUnreachable && !was_unreachable)
- Report.Warning (162, 2, expr.Location, "Unreachable code detected");
+ ec.Report.Warning (162, 2, expr.Location, "Unreachable code detected");
- expr = Expression.ResolveBoolean (ec, expr, loc);
+ expr = expr.Resolve (ec);
if (expr == null)
ok = false;
else if (expr is Constant){
public Expression expr;
public Statement Statement;
bool infinite, empty;
-
- public While (Expression bool_expr, Statement statement, Location l)
+
+ public While (BooleanExpression bool_expr, Statement statement, Location l)
{
this.expr = bool_expr;
Statement = statement;
loc = l;
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
bool ok = true;
- expr = Expression.ResolveBoolean (ec, expr, loc);
+ expr = expr.Resolve (ec);
if (expr == null)
- return false;
+ ok = false;
//
// Inform whether we are infinite or not
bool infinite, empty;
public For (Statement init_statement,
- Expression test,
+ BooleanExpression test,
Statement increment,
Statement statement,
Location l)
loc = l;
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
bool ok = true;
}
if (Test != null){
- Test = Expression.ResolveBoolean (ec, Test, loc);
+ Test = Test.Resolve (ec);
if (Test == null)
ok = false;
else if (Test is Constant){
loc = expr.Location;
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
if (expr != null && expr.eclass == ExprClass.Invalid)
expr = expr.ResolveStatement (ec);
public abstract class ExitStatement : Statement
{
protected bool unwind_protect;
- protected abstract bool DoResolve (EmitContext ec);
+ protected abstract bool DoResolve (BlockContext ec);
- public virtual void Error_FinallyClause ()
+ public virtual void Error_FinallyClause (Report Report)
{
Report.Error (157, loc, "Control cannot leave the body of a finally clause");
}
- public sealed override bool Resolve (EmitContext ec)
+ public sealed override bool Resolve (BlockContext ec)
{
if (!DoResolve (ec))
return false;
loc = l;
}
- protected override bool DoResolve (EmitContext ec)
+ protected override bool DoResolve (BlockContext ec)
{
if (Expr == null) {
if (ec.ReturnType == TypeManager.void_type)
return true;
- Error (126, "An object of a type convertible to `{0}' is required " +
- "for the return statement",
- TypeManager.CSharpName (ec.ReturnType));
+ ec.Report.Error (126, loc,
+ "An object of a type convertible to `{0}' is required for the return statement",
+ TypeManager.CSharpName (ec.ReturnType));
return false;
}
if (ec.CurrentBlock.Toplevel.IsIterator) {
- Report.Error (1622, loc, "Cannot return a value from iterators. Use the yield return " +
+ ec.Report.Error (1622, loc, "Cannot return a value from iterators. Use the yield return " +
"statement to return a value, or yield break to end the iteration");
}
AnonymousExpression am = ec.CurrentAnonymousMethod;
if (am == null && ec.ReturnType == TypeManager.void_type) {
- MemberCore mc = ec.ResolveContext as MemberCore;
- Report.Error (127, loc, "`{0}': A return keyword must not be followed by any expression when method returns void",
- mc.GetSignatureForError ());
+ ec.Report.Error (127, loc, "`{0}': A return keyword must not be followed by any expression when method returns void",
+ ec.GetSignatureForError ());
}
Expr = Expr.Resolve (ec);
if (Expr == null)
return false;
- if (ec.HasSet (EmitContext.Options.InferReturnType)) {
+ if (ec.HasSet (ResolveContext.Options.InferReturnType)) {
ec.ReturnTypeInference.AddCommonTypeBound (Expr.Type);
return true;
}
if (Expr == null) {
if (am != null) {
- Report.Error (1662, loc,
+ ec.Report.Error (1662, loc,
"Cannot convert `{0}' to delegate type `{1}' because some of the return types in the block are not implicitly convertible to the delegate return type",
am.ContainerType, am.GetSignatureForError ());
}
string target;
LabeledStatement label;
bool unwind_protect;
-
- public override bool Resolve (EmitContext ec)
+
+ public override bool Resolve (BlockContext ec)
{
- int errors = Report.Errors;
unwind_protect = ec.CurrentBranching.AddGotoOrigin (ec.CurrentBranching.CurrentUsageVector, this);
ec.CurrentBranching.CurrentUsageVector.Goto ();
- return errors == Report.Errors;
+ return true;
}
public Goto (string label, Location l)
// nothing to clone
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
// this flow-branching will be terminated when the surrounding block ends
ec.StartFlowBranching (this);
// nothing to clone
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
ec.CurrentBranching.CurrentUsageVector.Goto ();
+
+ if (ec.Switch == null) {
+ ec.Report.Error (153, loc, "A goto case is only valid inside a switch statement");
+ return false;
+ }
+
+ if (!ec.Switch.GotDefault) {
+ FlowBranchingBlock.Error_UnknownLabel (loc, "default", ec.Report);
+ return false;
+ }
+
return true;
}
protected override void DoEmit (EmitContext ec)
{
- if (ec.Switch == null){
- Report.Error (153, loc, "A goto case is only valid inside a switch statement");
- return;
- }
-
- if (!ec.Switch.GotDefault){
- FlowBranchingBlock.Error_UnknownLabel (loc, "default");
- return;
- }
ec.ig.Emit (OpCodes.Br, ec.Switch.DefaultTarget);
}
loc = l;
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
if (ec.Switch == null){
- Report.Error (153, loc, "A goto case is only valid inside a switch statement");
+ ec.Report.Error (153, loc, "A goto case is only valid inside a switch statement");
return false;
}
Constant c = expr as Constant;
if (c == null) {
- Error (150, "A constant value is expected");
+ ec.Report.Error (150, expr.Location, "A constant value is expected");
return false;
}
}
if (!Convert.ImplicitStandardConversionExists (c, type))
- Report.Warning (469, 2, loc,
+ ec.Report.Warning (469, 2, loc,
"The `goto case' value is not implicitly convertible to type `{0}'",
TypeManager.CSharpName (type));
if (sl == null){
FlowBranchingBlock.Error_UnknownLabel (loc, "case " +
- (c.GetValue () == null ? "null" : val.ToString ()));
+ (c.GetValue () == null ? "null" : val.ToString ()), ec.Report);
return false;
}
loc = l;
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
if (expr == null) {
ec.CurrentBranching.CurrentUsageVector.Goto ();
if (Convert.ImplicitConversionExists (ec, expr, TypeManager.exception_type))
expr = Convert.ImplicitConversion (ec, expr, TypeManager.exception_type, loc);
else
- Report.Error (155, expr.Location, "The type caught or thrown must be derived from System.Exception");
+ ec.Report.Error (155, expr.Location, "The type caught or thrown must be derived from System.Exception");
return true;
}
bool unwind_protect;
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
- int errors = Report.Errors;
unwind_protect = ec.CurrentBranching.AddBreakOrigin (ec.CurrentBranching.CurrentUsageVector, loc);
ec.CurrentBranching.CurrentUsageVector.Goto ();
- return errors == Report.Errors;
+ return true;
}
protected override void DoEmit (EmitContext ec)
bool unwind_protect;
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
- int errors = Report.Errors;
unwind_protect = ec.CurrentBranching.AddContinueOrigin (ec.CurrentBranching.CurrentUsageVector, loc);
ec.CurrentBranching.CurrentUsageVector.Goto ();
- return errors == Report.Errors;
+ return true;
}
protected override void DoEmit (EmitContext ec)
ec.DefineLocalVariable (Name, builder);
}
- public bool IsThisAssigned (EmitContext ec, Block block)
+ public bool IsThisAssigned (BlockContext ec, Block block)
{
if (VariableInfo == null)
throw new Exception ();
if (!ec.DoFlowAnalysis || ec.CurrentBranching.IsAssigned (VariableInfo))
return true;
- return VariableInfo.TypeInfo.IsFullyInitialized (ec.CurrentBranching, VariableInfo, block.StartLocation);
+ return VariableInfo.TypeInfo.IsFullyInitialized (ec, VariableInfo, block.StartLocation);
}
- public bool IsAssigned (EmitContext ec)
+ public bool IsAssigned (BlockContext ec)
{
if (VariableInfo == null)
throw new Exception ();
return !ec.DoFlowAnalysis || ec.CurrentBranching.IsAssigned (VariableInfo);
}
- public bool Resolve (EmitContext ec)
+ public bool Resolve (ResolveContext ec)
{
if (VariableType != null)
return true;
return true;
if (VariableType.IsAbstract && VariableType.IsSealed) {
- FieldBase.Error_VariableOfStaticClass (Location, Name, VariableType);
+ FieldBase.Error_VariableOfStaticClass (Location, Name, VariableType, ec.Report);
return false;
}
- if (VariableType.IsPointer && !ec.InUnsafe)
- Expression.UnsafeError (Location);
+ if (VariableType.IsPointer && !ec.IsUnsafe)
+ Expression.UnsafeError (ec, Location);
return true;
}
EndLocation = loc;
}
- protected static void Error_158 (string name, Location loc)
+ protected void Error_158 (string name, Location loc)
{
- Report.Error (158, loc, "The label `{0}' shadows another label " +
+ Toplevel.Report.Error (158, loc, "The label `{0}' shadows another label " +
"by the same name in a contained scope", name);
}
while (cur != null) {
LabeledStatement s = cur.DoLookupLabel (name);
if (s != null) {
- Report.SymbolRelatedToPreviousError (s.loc, s.Name);
- Report.Error (140, target.loc, "The label `{0}' is a duplicate", name);
+ Toplevel.Report.SymbolRelatedToPreviousError (s.loc, s.Name);
+ Toplevel.Report.Error (140, target.loc, "The label `{0}' is a duplicate", name);
return false;
}
if (s == null)
continue;
- Report.SymbolRelatedToPreviousError (s.loc, s.Name);
+ Toplevel.Report.SymbolRelatedToPreviousError (s.loc, s.Name);
Error_158 (name, target.loc);
return false;
}
// block, we violate the invariant meaning in a block.
//
if (b == this) {
- Report.SymbolRelatedToPreviousError (kvi.Location, name);
- Report.Error (135, loc, "`{0}' conflicts with a declaration in a child block", name);
+ Toplevel.Report.SymbolRelatedToPreviousError (kvi.Location, name);
+ Toplevel.Report.Error (135, loc, "`{0}' conflicts with a declaration in a child block", name);
return false;
}
return true;
if (this is ToplevelBlock) {
- Report.SymbolRelatedToPreviousError (kvi.Location, name);
- e.Error_VariableIsUsedBeforeItIsDeclared (name);
+ Toplevel.Report.SymbolRelatedToPreviousError (kvi.Location, name);
+ e.Error_VariableIsUsedBeforeItIsDeclared (Toplevel.Report, name);
return false;
}
// Even though we detected the error when the name is used, we
// treat it as if the variable declaration was in error.
//
- Report.SymbolRelatedToPreviousError (loc, name);
+ Toplevel.Report.SymbolRelatedToPreviousError (loc, name);
Error_AlreadyDeclared (kvi.Location, name, "parent or current");
return false;
}
{
LocalInfo vi = GetLocalInfo (name);
if (vi != null) {
- Report.SymbolRelatedToPreviousError (vi.Location, name);
+ block.Report.SymbolRelatedToPreviousError (vi.Location, name);
if (Explicit == vi.Block.Explicit) {
Error_AlreadyDeclared (l, name, null);
} else {
if (Toplevel.GenericMethod != null) {
foreach (TypeParameter tp in Toplevel.GenericMethod.CurrentTypeParameters) {
if (tp.Name == name) {
- Report.SymbolRelatedToPreviousError (tp);
- Error_AlreadyDeclaredTypeParameter (loc, name, "local variable");
+ Toplevel.Report.SymbolRelatedToPreviousError (tp);
+ Error_AlreadyDeclaredTypeParameter (Toplevel.Report, loc, name, "local variable");
return null;
}
}
IKnownVariable kvi = Explicit.GetKnownVariable (name);
if (kvi != null) {
- Report.SymbolRelatedToPreviousError (kvi.Location, name);
+ Toplevel.Report.SymbolRelatedToPreviousError (kvi.Location, name);
Error_AlreadyDeclared (l, name, "child");
return null;
}
return;
}
- Report.Error (136, loc, "A local variable named `{0}' cannot be declared " +
+ Toplevel.Report.Error (136, loc, "A local variable named `{0}' cannot be declared " +
"in this scope because it would give a different meaning " +
"to `{0}', which is already used in a `{1}' scope " +
"to denote something else", var, reason);
protected virtual void Error_AlreadyDeclared (Location loc, string name)
{
- Report.Error (128, loc,
+ Toplevel.Report.Error (128, loc,
"A local variable named `{0}' is already defined in this scope", name);
}
- public virtual void Error_AlreadyDeclaredTypeParameter (Location loc, string name, string conflict)
+ public virtual void Error_AlreadyDeclaredTypeParameter (Report r, Location loc, string name, string conflict)
{
- Report.Error (412, loc, "The type parameter name `{0}' is the same as `{1}'",
+ r.Error (412, loc, "The type parameter name `{0}' is the same as `{1}'",
name, conflict);
}
anonymous_children.Add (b);
}
- void DoResolveConstants (EmitContext ec)
+ void DoResolveConstants (BlockContext ec)
{
if (constants == null)
return;
if (variable_type == null) {
if (vi.Type is VarExpr)
- Report.Error (822, vi.Type.Location, "An implicitly typed local variable cannot be a constant");
+ ec.Report.Error (822, vi.Type.Location, "An implicitly typed local variable cannot be a constant");
continue;
}
constants.Remove (name);
if (!Const.IsConstantTypeValid (variable_type)) {
- Const.Error_InvalidConstantType (variable_type, loc);
+ Const.Error_InvalidConstantType (variable_type, loc, ec.Report);
continue;
}
ec.CurrentBlock = this;
Expression e;
- using (ec.With (EmitContext.Options.ConstantCheckState, (flags & Flags.Unchecked) == 0)) {
+ using (ec.With (ResolveContext.Options.ConstantCheckState, (flags & Flags.Unchecked) == 0)) {
e = cv.Resolve (ec);
}
if (e == null)
Constant ce = e as Constant;
if (ce == null) {
- Const.Error_ExpressionMustBeConstant (vi.Location, name);
+ Const.Error_ExpressionMustBeConstant (vi.Location, name, ec.Report);
continue;
}
e = ce.ConvertImplicitly (variable_type);
if (e == null) {
if (TypeManager.IsReferenceType (variable_type))
- Const.Error_ConstantCanBeInitializedWithNullOnly (variable_type, vi.Location, vi.Name);
+ Const.Error_ConstantCanBeInitializedWithNullOnly (variable_type, vi.Location, vi.Name, ec.Report);
else
ce.Error_ValueCannotBeConverted (ec, vi.Location, variable_type, false);
continue;
}
}
- protected void ResolveMeta (EmitContext ec, int offset)
+ 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 (EmitContext.Options.UnsafeScope, ec.InUnsafe | Unsafe)) {
+ using (ec.With (ResolveContext.Options.UnsafeScope, ec.IsUnsafe | Unsafe)) {
flags |= Flags.VariablesInitialized;
if (variables != null) {
}
}
- void UsageWarning ()
+ void UsageWarning (BlockContext ec)
{
- if (variables == null || Report.WarningLevel < 3)
+ if (variables == null || ec.Report.WarningLevel < 3)
return;
foreach (DictionaryEntry de in variables) {
// vi.VariableInfo can be null for 'catch' variables
if (vi.VariableInfo != null && vi.VariableInfo.IsEverAssigned)
- Report.Warning (219, 3, vi.Location, "The variable `{0}' is assigned but its value is never used", name);
+ ec.Report.Warning (219, 3, vi.Location, "The variable `{0}' is assigned but its value is never used", name);
else
- Report.Warning (168, 3, vi.Location, "The variable `{0}' is declared but never used", name);
+ ec.Report.Warning (168, 3, vi.Location, "The variable `{0}' is declared but never used", name);
}
}
}
- static void CheckPossibleMistakenEmptyStatement (Statement s)
+ static void CheckPossibleMistakenEmptyStatement (BlockContext ec, Statement s)
{
Statement body;
return;
if (body == null || body is EmptyStatement)
- Report.Warning (642, 3, s.loc, "Possible mistaken empty statement");
+ ec.Report.Warning (642, 3, s.loc, "Possible mistaken empty statement");
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
Block prev_block = ec.CurrentBlock;
bool ok = true;
- int errors = Report.Errors;
+ int errors = ec.Report.Errors;
ec.CurrentBlock = this;
ec.StartFlowBranching (this);
for (int ix = 0; ix < statement_count; ix++){
Statement s = (Statement) statements [ix];
// Check possible empty statement (CS0642)
- if (Report.WarningLevel >= 3 &&
- ix + 1 < statement_count &&
- statements [ix + 1] is ExplicitBlock)
- CheckPossibleMistakenEmptyStatement (s);
+ if (ix + 1 < statement_count && ec.Report.WarningLevel >= 3 &&
+ statements [ix + 1] is ExplicitBlock)
+ CheckPossibleMistakenEmptyStatement (ec, s);
//
// Warn if we detect unreachable code.
continue;
if (!unreachable_shown && !(s is LabeledStatement)) {
- Report.Warning (162, 2, s.loc, "Unreachable code detected");
+ ec.Report.Warning (162, 2, s.loc, "Unreachable code detected");
unreachable_shown = true;
}
if (this == Toplevel && !Toplevel.IsThisAssigned (ec) && !flow_unreachable)
ok = false;
- if ((labels != null) && (Report.WarningLevel >= 2)) {
+ if ((labels != null) && (ec.Report.WarningLevel >= 2)) {
foreach (LabeledStatement label in labels.Values)
if (!label.HasBeenReferenced)
- Report.Warning (164, 2, label.loc, "This label has not been referenced");
+ ec.Report.Warning (164, 2, label.loc, "This label has not been referenced");
}
- if (ok && errors == Report.Errors)
- UsageWarning ();
+ if (ok && errors == ec.Report.Errors)
+ UsageWarning (ec);
return ok;
}
- public override bool ResolveUnreachable (EmitContext ec, bool warn)
+ public override bool ResolveUnreachable (BlockContext ec, bool warn)
{
unreachable_shown = true;
unreachable = true;
if (warn)
- Report.Warning (162, 2, loc, "Unreachable code detected");
+ ec.Report.Warning (162, 2, loc, "Unreachable code detected");
ec.StartFlowBranching (FlowBranching.BranchingType.Block, loc);
bool ok = Resolve (ec);
public override void Emit (EmitContext ec)
{
- Block prev_block = ec.CurrentBlock;
- ec.CurrentBlock = this;
-
if (scope_initializers != null)
EmitScopeInitializers (ec);
if (SymbolWriter.HasSymbolWriter)
EmitSymbolInfo (ec);
-
- ec.CurrentBlock = prev_block;
}
protected void EmitScopeInitializers (EmitContext ec)
{
SymbolWriter.OpenCompilerGeneratedBlock (ec.ig);
- using (ec.Set (EmitContext.Options.OmitDebuggingInfo)) {
+ using (ec.With (EmitContext.Options.OmitDebugInfo, true)) {
foreach (Statement s in scope_initializers)
s.Emit (ec);
}
//
// Creates anonymous method storey in current block
//
- public AnonymousMethodStorey CreateAnonymousMethodStorey (EmitContext ec)
+ public AnonymousMethodStorey CreateAnonymousMethodStorey (ResolveContext ec)
{
//
// When referencing a variable in iterator storey from children anonymous method
return ec.CurrentIterator.Storey;
if (am_storey == null) {
- MemberBase mc = ec.ResolveContext as MemberBase;
+ MemberBase mc = ec.MemberContext as MemberBase;
GenericMethod gm = mc == null ? null : mc.GenericMethod;
//
this.block = block;
}
- public override Expression CreateExpressionTree (EmitContext ec)
+ public override Expression CreateExpressionTree (ResolveContext ec)
{
throw new NotSupportedException ();
}
- public override Expression DoResolve (EmitContext ec)
+ public override Expression DoResolve (ResolveContext ec)
{
if (child == null)
return null;
LocalInfo this_variable;
bool resolved;
bool unreachable;
+ CompilerContext compiler;
public HoistedVariable HoistedThisVariable;
+ public bool Resolved {
+ get {
+ return resolved;
+ }
+ }
+
//
// The parameters for the block.
//
get { return parameters; }
}
+ public Report Report {
+ get { return compiler.Report; }
+ }
+
public GenericMethod GenericMethod {
get { return generic; }
}
get { return Parent == null ? null : Parent.Toplevel; }
}
- public ToplevelBlock (Block parent, ParametersCompiled parameters, Location start) :
- this (parent, (Flags) 0, parameters, start)
+ public ToplevelBlock (CompilerContext ctx, Block parent, ParametersCompiled parameters, Location start) :
+ this (ctx, parent, (Flags) 0, parameters, start)
{
}
- public ToplevelBlock (Block parent, ParametersCompiled parameters, GenericMethod generic, Location start) :
- this (parent, parameters, start)
+ public ToplevelBlock (CompilerContext ctx, Block parent, ParametersCompiled parameters, GenericMethod generic, Location start) :
+ this (ctx, parent, parameters, start)
{
this.generic = generic;
}
-
- public ToplevelBlock (ParametersCompiled parameters, Location start) :
- this (null, (Flags) 0, parameters, start)
+
+ public ToplevelBlock (CompilerContext ctx, ParametersCompiled parameters, Location start) :
+ this (ctx, null, (Flags) 0, parameters, start)
{
}
- ToplevelBlock (Flags flags, ParametersCompiled parameters, Location start) :
- this (null, flags, parameters, start)
+ ToplevelBlock (CompilerContext ctx, Flags flags, ParametersCompiled parameters, Location start) :
+ this (ctx, null, flags, parameters, start)
{
}
// We use 'Parent' to hook up to the containing block, but don't want to register the current block as a child.
// So, we use a two-stage setup -- first pass a null parent to the base constructor, and then override 'Parent'.
- public ToplevelBlock (Block parent, Flags flags, ParametersCompiled parameters, Location start) :
+ public ToplevelBlock (CompilerContext ctx, Block parent, Flags flags, ParametersCompiled parameters, Location start) :
base (null, flags, start, Location.Null)
{
+ this.compiler = ctx;
this.Toplevel = this;
this.parameters = parameters;
ProcessParameters ();
}
- public ToplevelBlock (Location loc)
- : this (null, (Flags) 0, ParametersCompiled.EmptyReadOnlyParameters, loc)
+ public ToplevelBlock (CompilerContext ctx, Location loc)
+ : this (ctx, null, (Flags) 0, ParametersCompiled.EmptyReadOnlyParameters, loc)
{
}
return true;
}
- public override Expression CreateExpressionTree (EmitContext ec)
+ public override Expression CreateExpressionTree (ResolveContext ec)
{
if (statements.Count == 1) {
Expression expr = ((Statement) statements[0]).CreateExpressionTree (ec);
set { flags = value ? flags | Flags.IsIterator : flags & ~Flags.IsIterator; }
}
- public bool IsThisAssigned (EmitContext ec)
+ public bool IsThisAssigned (BlockContext ec)
{
return this_variable == null || this_variable.IsThisAssigned (ec, this);
}
- public bool Resolve (FlowBranching parent, EmitContext rc, ParametersCompiled ip, IMethodData md)
+ public bool Resolve (FlowBranching parent, BlockContext rc, ParametersCompiled ip, IMethodData md)
{
if (resolved)
return true;
if (!ResolveMeta (rc, ip))
return false;
- using (rc.With (EmitContext.Options.DoFlowAnalysis, true)) {
+ using (rc.With (ResolveContext.Options.DoFlowAnalysis, true)) {
FlowBranchingToplevel top_level = rc.StartFlowBranching (this, parent);
if (!Resolve (rc))
} catch (Exception) {
#if PRODUCTION
if (rc.CurrentBlock != null) {
- Report.Error (584, rc.CurrentBlock.StartLocation, "Internal compiler error: Phase Resolve");
+ ec.Report.Error (584, rc.CurrentBlock.StartLocation, "Internal compiler error: Phase Resolve");
} else {
- Report.Error (587, "Internal compiler error: Phase Resolve");
+ ec.Report.Error (587, "Internal compiler error: Phase Resolve");
}
#endif
throw;
if (rc.ReturnType != TypeManager.void_type && !unreachable) {
if (rc.CurrentAnonymousMethod == null) {
- Report.Error (161, md.Location, "`{0}': not all code paths return a value", md.GetSignatureForError ());
+ rc.Report.Error (161, md.Location, "`{0}': not all code paths return a value", md.GetSignatureForError ());
return false;
} else if (!rc.CurrentAnonymousMethod.IsIterator) {
- Report.Error (1643, rc.CurrentAnonymousMethod.Location, "Not all code paths return a value in anonymous method of type `{0}'",
+ 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 (EmitContext ec, ParametersCompiled ip)
+ bool ResolveMeta (BlockContext ec, ParametersCompiled ip)
{
- int errors = Report.Errors;
+ int errors = ec.Report.Errors;
int orig_count = parameters.Count;
if (ip != null)
ResolveMeta (ec, offset);
- return Report.Errors == errors;
+ return ec.Report.Errors == errors;
}
// <summary>
// Resolves the expression, reduces it to a literal if possible
// and then converts it to the requested type.
//
- public bool ResolveAndReduce (EmitContext ec, Type required_type, bool allow_nullable)
+ public bool ResolveAndReduce (ResolveContext ec, Type required_type, bool allow_nullable)
{
Expression e = label.Resolve (ec);
Constant c = e as Constant;
if (c == null){
- Report.Error (150, loc, "A constant value is expected");
+ ec.Report.Error (150, loc, "A constant value is expected");
return false;
}
return true;
}
- public void Error_AlreadyOccurs (Type switch_type, SwitchLabel collision_with)
+ public void Error_AlreadyOccurs (ResolveContext ec, Type switch_type, SwitchLabel collision_with)
{
string label;
if (converted == null)
else
label = converted.ToString ();
- Report.SymbolRelatedToPreviousError (collision_with.loc, null);
- Report.Error (152, loc, "The label `case {0}:' already occurs in this switch statement", label);
+ ec.Report.SymbolRelatedToPreviousError (collision_with.loc, null);
+ ec.Report.Error (152, loc, "The label `case {0}:' already occurs in this switch statement", label);
}
public SwitchLabel Clone (CloneContext clonectx)
// expression that includes any potential conversions to the
// integral types or to string.
//
- Expression SwitchGoverningType (EmitContext ec, Expression expr)
+ Expression SwitchGoverningType (ResolveContext ec, Expression expr)
{
Type t = expr.Type;
continue;
if (converted != null){
- Report.ExtraInformation (loc, "(Ambiguous implicit user defined conversion in previous ");
+ ec.Report.ExtraInformation (loc, "(Ambiguous implicit user defined conversion in previous ");
return null;
}
// It also returns a hashtable with the keys that we will later
// use to compute the switch tables
//
- bool CheckSwitch (EmitContext ec)
+ bool CheckSwitch (ResolveContext ec)
{
bool error = false;
Elements = Sections.Count > 10 ?
foreach (SwitchLabel sl in ss.Labels){
if (sl.Label == null){
if (default_section != null){
- sl.Error_AlreadyOccurs (SwitchType, (SwitchLabel)default_section.Labels [0]);
+ sl.Error_AlreadyOccurs (ec, SwitchType, (SwitchLabel)default_section.Labels [0]);
error = true;
}
default_section = ss;
try {
Elements.Add (key, sl);
} catch (ArgumentException) {
- sl.Error_AlreadyOccurs (SwitchType, (SwitchLabel)Elements [key]);
+ sl.Error_AlreadyOccurs (ec, SwitchType, (SwitchLabel)Elements [key]);
error = true;
}
}
allowed_types = null;
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
Expr = Expr.Resolve (ec);
if (Expr == null)
}
if (new_expr == null){
- Report.Error (151, loc,
+ ec.Report.Error (151, loc,
"A switch expression of type `{0}' cannot be converted to an integral type, bool, char, string, enum or nullable type",
TypeManager.CSharpName (Expr.Type));
return false;
SwitchType = new_expr.Type;
if (RootContext.Version == LanguageVersion.ISO_1 && SwitchType == TypeManager.bool_type) {
- Report.FeatureIsNotAvailable (loc, "switch expression of boolean type");
+ ec.Report.FeatureIsNotAvailable (loc, "switch expression of boolean type");
return false;
}
return true;
}
- void ResolveStringSwitchMap (EmitContext ec)
+ void ResolveStringSwitchMap (ResolveContext ec)
{
FullNamedExpression string_dictionary_type;
if (TypeManager.generic_ienumerable_type != null) {
LocalTemporary string_switch_variable = new LocalTemporary (TypeManager.int32_type);
+ ResolveContext rc = new ResolveContext (ec.MemberContext);
+
if (TypeManager.generic_ienumerable_type != null) {
Arguments get_value_args = new Arguments (2);
get_value_args.Add (new Argument (value));
get_value_args.Add (new Argument (string_switch_variable, Argument.AType.Out));
- Expression get_item = new Invocation (new MemberAccess (switch_cache_field, "TryGetValue", loc), get_value_args).Resolve (ec);
+ Expression get_item = new Invocation (new MemberAccess (switch_cache_field, "TryGetValue", loc), get_value_args).Resolve (rc);
if (get_item == null)
return;
Arguments get_value_args = new Arguments (1);
get_value_args.Add (new Argument (value));
- Expression get_item = new IndexerAccess (new ElementAccess (switch_cache_field, get_value_args), loc).Resolve (ec);
+ Expression get_item = new IndexerAccess (new ElementAccess (switch_cache_field, get_value_args), loc).Resolve (rc);
if (get_item == null)
return;
ec.ig.Emit (OpCodes.Brfalse, default_target);
ExpressionStatement get_item_int = (ExpressionStatement) new SimpleAssign (string_switch_variable,
- new Cast (new TypeExpression (TypeManager.int32_type, loc), get_item_object, loc)).Resolve (ec);
+ new Cast (new TypeExpression (TypeManager.int32_type, loc), get_item_object, loc)).Resolve (rc);
get_item_int.EmitStatement (ec);
get_item_object.Release (ec);
public abstract class ExceptionStatement : ResumableStatement
{
bool code_follows;
+ Iterator iter;
protected abstract void EmitPreTryBody (EmitContext ec);
protected abstract void EmitTryBody (EmitContext ec);
if (resume_points != null) {
IntConstant.EmitInt (ig, (int) Iterator.State.Running);
- ig.Emit (OpCodes.Stloc, ec.CurrentIterator.CurrentPC);
+ ig.Emit (OpCodes.Stloc, iter.CurrentPC);
}
ig.BeginExceptionBlock ();
// For normal control flow, we want to fall-through the Switch
// So, we use CurrentPC rather than the $PC field, and initialize it to an outside value above
- ig.Emit (OpCodes.Ldloc, ec.CurrentIterator.CurrentPC);
+ ig.Emit (OpCodes.Ldloc, iter.CurrentPC);
IntConstant.EmitInt (ig, first_resume_pc);
ig.Emit (OpCodes.Sub);
Label start_finally = ec.ig.DefineLabel ();
if (resume_points != null) {
- ig.Emit (OpCodes.Ldloc, ec.CurrentIterator.SkipFinally);
+ ig.Emit (OpCodes.Ldloc, iter.SkipFinally);
ig.Emit (OpCodes.Brfalse_S, start_finally);
ig.Emit (OpCodes.Endfinally);
}
code_follows = true;
}
- protected void ResolveReachability (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
// System.Reflection.Emit automatically emits a 'leave' at the end of a try clause
// So, ensure there's some IL code after this statement.
if (!code_follows && resume_points == null && ec.CurrentBranching.CurrentUsageVector.IsUnreachable)
ec.NeedReturnLabel ();
+ iter = ec.CurrentIterator;
+ return true;
}
ArrayList resume_points;
loc = l;
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
expr = expr.Resolve (ec);
if (expr == null)
return false;
if (!TypeManager.IsReferenceType (expr.Type)){
- Report.Error (185, loc,
+ ec.Report.Error (185, loc,
"`{0}' is not a reference type as required by the lock statement",
TypeManager.CSharpName (expr.Type));
return false;
bool ok = Statement.Resolve (ec);
ec.EndFlowBranching ();
- ResolveReachability (ec);
+ ok &= base.Resolve (ec);
// Avoid creating libraries that reference the internal
// mcs NullType:
temp.Resolve (ec);
if (TypeManager.void_monitor_enter_object == null || TypeManager.void_monitor_exit_object == null) {
- Type monitor_type = TypeManager.CoreLookupType ("System.Threading", "Monitor", Kind.Class, true);
+ Type monitor_type = TypeManager.CoreLookupType (ec.Compiler, "System.Threading", "Monitor", Kind.Class, true);
TypeManager.void_monitor_enter_object = TypeManager.GetPredefinedMethod (
monitor_type, "Enter", loc, TypeManager.object_type);
TypeManager.void_monitor_exit_object = TypeManager.GetPredefinedMethod (
b.Unchecked = true;
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
- using (ec.With (EmitContext.Options.AllCheckStateFlags, false))
+ using (ec.With (ResolveContext.Options.AllCheckStateFlags, false))
return Block.Resolve (ec);
}
b.Unchecked = false;
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
- using (ec.With (EmitContext.Options.AllCheckStateFlags, true))
- return Block.Resolve (ec);
+ using (ec.With (ResolveContext.Options.AllCheckStateFlags, true))
+ return Block.Resolve (ec);
}
protected override void DoEmit (EmitContext ec)
loc = b.StartLocation;
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
if (ec.CurrentIterator != null)
- Report.Error (1629, loc, "Unsafe code may not appear in iterators");
+ ec.Report.Error (1629, loc, "Unsafe code may not appear in iterators");
- using (ec.With (EmitContext.Options.UnsafeScope, true))
+ using (ec.Set (ResolveContext.Options.UnsafeScope))
return Block.Resolve (ec);
}
protected override void DoEmit (EmitContext ec)
{
- using (ec.With (EmitContext.Options.UnsafeScope, true))
- Block.Emit (ec);
+ Block.Emit (ec);
}
public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
pinned_string.Pinned = true;
}
- public StringEmitter Resolve (EmitContext rc)
+ public StringEmitter Resolve (ResolveContext rc)
{
pinned_string.Resolve (rc);
PropertyExpr pe = new PropertyExpr (pinned_string.VariableType, TypeManager.int_get_offset_to_string_data, pinned_string.Location);
//pe.InstanceExpression = pinned_string;
- pe.Resolve (ec).Emit (ec);
+ pe.Resolve (new ResolveContext (ec.MemberContext)).Emit (ec);
ec.ig.Emit (OpCodes.Add);
vi.EmitAssign (ec);
get { return statement; }
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
- if (!ec.InUnsafe){
- Expression.UnsafeError (loc);
+ if (!ec.IsUnsafe){
+ Expression.UnsafeError (ec, loc);
return false;
}
TypeExpr texpr = type.ResolveAsContextualType (ec, false);
if (texpr == null) {
if (type is VarExpr)
- Report.Error (821, type.Location, "A fixed statement cannot use an implicitly typed local variable");
+ ec.Report.Error (821, type.Location, "A fixed statement cannot use an implicitly typed local variable");
return false;
}
data = new Emitter [declarators.Count];
if (!expr_type.IsPointer){
- Report.Error (209, loc, "The type of locals declared in a fixed statement must be a pointer type");
+ ec.Report.Error (209, loc, "The type of locals declared in a fixed statement must be a pointer type");
return false;
}
//
if (e is Cast){
- Report.Error (254, loc, "The right hand side of a fixed statement assignment may not be a cast expression");
+ ec.Report.Error (254, loc, "The right hand side of a fixed statement assignment may not be a cast expression");
return false;
}
- using (ec.Set (EmitContext.Options.FixedInitializerScope)) {
+ using (ec.Set (ResolveContext.Options.FixedInitializerScope)) {
e = e.Resolve (ec);
}
//
// fixed (T* e_ptr = (e == null || e.Length == 0) ? null : converted [0])
//
- converted = new Conditional (new Binary (Binary.Operator.LogicalOr,
+ converted = new Conditional (new BooleanExpression (new Binary (Binary.Operator.LogicalOr,
new Binary (Binary.Operator.Equality, e, new NullLiteral (loc)),
- new Binary (Binary.Operator.Equality, new MemberAccess (e, "Length"), new IntConstant (0, loc))),
+ new Binary (Binary.Operator.Equality, new MemberAccess (e, "Length"), new IntConstant (0, loc)))),
new NullPointer (loc),
converted);
}
if (data [i++] == null)
- Report.Error (213, vi.Location, "You cannot use the fixed statement to take the address of an already fixed expression");
+ ec.Report.Error (213, vi.Location, "You cannot use the fixed statement to take the address of an already fixed expression");
e = Convert.ImplicitConversionRequired (ec, e, expr_type, loc);
}
if (Name != null) {
// TODO: Move to resolve
LocalVariableReference lvr = new LocalVariableReference (Block, Name, loc);
- lvr.Resolve (ec);
+ lvr.Resolve (new ResolveContext (ec.MemberContext));
-#if GMCS_SOURCE
// Only to make verifier happy
if (TypeManager.IsGenericParameter (lvr.Type))
ig.Emit (OpCodes.Unbox_Any, lvr.Type);
-#endif
Expression source;
if (lvr.IsHoisted) {
Block.Emit (ec);
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
- using (ec.With (EmitContext.Options.CatchScope, true)) {
+ using (ec.With (ResolveContext.Options.CatchScope, true)) {
if (type_expr != null) {
TypeExpr te = type_expr.ResolveAsTypeTerminal (ec, false);
if (te == null)
type = te.Type;
if (type != TypeManager.exception_type && !TypeManager.IsSubclassOf (type, TypeManager.exception_type)){
- Error (155, "The type caught or thrown must be derived from System.Exception");
+ ec.Report.Error (155, loc, "The type caught or thrown must be derived from System.Exception");
return false;
}
} else
loc = l;
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
bool ok = true;
if (ok)
ec.CurrentBranching.CreateSibling (fini, FlowBranching.SiblingType.Finally);
- using (ec.With (EmitContext.Options.FinallyScope, true)) {
+ using (ec.With (ResolveContext.Options.FinallyScope, true)) {
if (!fini.Resolve (ec))
ok = false;
}
ec.EndFlowBranching ();
- ResolveReachability (ec);
+ ok &= base.Resolve (ec);
return ok;
}
{
this.Block = block;
this.Specific = catch_clauses;
- this.General = null;
this.inside_try_finally = inside_try_finally;
- for (int i = 0; i < catch_clauses.Count; ++i) {
- Catch c = (Catch) catch_clauses [i];
- if (c.IsGeneral) {
- if (i != catch_clauses.Count - 1)
- Report.Error (1017, c.loc, "Try statement already has an empty catch block");
- this.General = c;
- catch_clauses.RemoveAt (i);
- i--;
- }
+ Catch c = (Catch) catch_clauses [0];
+ if (c.IsGeneral) {
+ this.General = c;
+ catch_clauses.RemoveAt (0);
}
loc = l;
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
bool ok = true;
Type resolved_type = c.CatchType;
for (int ii = 0; ii < last_index; ++ii) {
if (resolved_type == prev_catches [ii] || TypeManager.IsSubclassOf (resolved_type, prev_catches [ii])) {
- Report.Error (160, c.loc,
+ ec.Report.Error (160, c.loc,
"A previous catch clause already catches all exceptions of this or a super type `{0}'",
TypeManager.CSharpName (prev_catches [ii]));
ok = false;
if (CodeGen.Assembly.WrapNonExceptionThrows) {
foreach (Catch c in Specific){
if (c.CatchType == TypeManager.exception_type && PredefinedAttributes.Get.RuntimeCompatibility.IsDefined) {
- Report.Warning (1058, 1, c.loc, "A previous catch clause already catches all exceptions. All non-exceptions thrown will be wrapped in a `System.Runtime.CompilerServices.RuntimeWrappedException'");
+ ec.Report.Warning (1058, 1, c.loc, "A previous catch clause already catches all exceptions. All non-exceptions thrown will be wrapped in a `System.Runtime.CompilerServices.RuntimeWrappedException'");
}
}
}
loc = l;
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
expr = expr.Resolve (ec);
if (expr == null)
if (!TypeManager.ImplementsInterface (expr_type, TypeManager.idisposable_type)) {
if (Convert.ImplicitConversion (ec, expr, TypeManager.idisposable_type, loc) == null) {
- Using.Error_IsNotConvertibleToIDisposable (expr);
+ Using.Error_IsNotConvertibleToIDisposable (ec, expr);
return false;
}
}
ec.EndFlowBranching ();
- ResolveReachability (ec);
+ ok &= base.Resolve (ec);
if (TypeManager.void_dispose_void == null) {
TypeManager.void_dispose_void = TypeManager.GetPredefinedMethod (
return;
}
- Expression ml = Expression.MemberLookup (
+ Expression ml = Expression.MemberLookup (RootContext.ToplevelTypes.Compiler,
ec.CurrentType, TypeManager.idisposable_type, expr_type,
"Dispose", Location.Null);
}
if (mi == null) {
- Report.Error(-100, Mono.CSharp.Location.Null, "Internal error: No Dispose method which takes 0 parameters.");
+ RootContext.ToplevelTypes.Compiler.Report.Error(-100, Mono.CSharp.Location.Null, "Internal error: No Dispose method which takes 0 parameters.");
return;
}
loc = l;
}
- static public void Error_IsNotConvertibleToIDisposable (Expression expr)
+ static public void Error_IsNotConvertibleToIDisposable (BlockContext ec, Expression expr)
{
- Report.SymbolRelatedToPreviousError (expr.Type);
- Report.Error (1674, expr.Location, "`{0}': type used in a using statement must be implicitly convertible to `System.IDisposable'",
- expr.GetSignatureForError ());
+ ec.Report.SymbolRelatedToPreviousError (expr.Type);
+ ec.Report.Error (1674, expr.Location, "`{0}': type used in a using statement must be implicitly convertible to `System.IDisposable'",
+ TypeManager.CSharpName (expr.Type));
}
protected override void EmitPreTryBody (EmitContext ec)
stmt.MutateHoistedGenericType (storey);
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
if (!ResolveVariable (ec))
return false;
ec.EndFlowBranching ();
- ResolveReachability (ec);
+ ok &= base.Resolve (ec);
if (TypeManager.void_dispose_void == null) {
TypeManager.void_dispose_void = TypeManager.GetPredefinedMethod (
return ok;
}
- bool ResolveVariable (EmitContext ec)
+ bool ResolveVariable (BlockContext ec)
{
assign = new SimpleAssign (var, init, loc);
assign = assign.ResolveStatement (ec);
Expression e = Convert.ImplicitConversionStandard (ec, assign, TypeManager.idisposable_type, var.Location);
if (e == null) {
- Error_IsNotConvertibleToIDisposable (var);
+ Error_IsNotConvertibleToIDisposable (ec, var);
return false;
}
{
}
- public void ResolveIncrement (EmitContext ec)
+ public void ResolveIncrement (BlockContext ec)
{
increment = new StatementExpression (new UnaryMutator (UnaryMutator.Mode.PostIncrement, this));
increment.Resolve (ec);
throw new NotImplementedException ();
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
copy = new TemporaryVariable (for_each.expr.Type, loc);
copy.Resolve (ec);
throw new NotImplementedException ();
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
current = current.Resolve (ec);
if (current == null)
throw new NotImplementedException ();
}
- bool GetEnumeratorFilter (EmitContext ec, MethodInfo mi)
+ bool GetEnumeratorFilter (ResolveContext ec, MethodInfo mi)
{
Type return_type = mi.ReturnType;
//
if (TypeManager.HasElementType (return_type) || !FetchMoveNext (return_type) || !FetchGetCurrent (ec, return_type)) {
- Report.Error (202, loc, "foreach statement requires that the return type `{0}' of `{1}' must have a suitable public MoveNext method and public Current property",
+ ec.Report.Error (202, loc, "foreach statement requires that the return type `{0}' of `{1}' must have a suitable public MoveNext method and public Current property",
TypeManager.CSharpName (return_type), TypeManager.CSharpSignature (mi));
return false;
}
//
// Retrieves a `public T get_Current ()' method from the Type `t'
//
- bool FetchGetCurrent (EmitContext ec, Type t)
+ bool FetchGetCurrent (ResolveContext ec, Type t)
{
- PropertyExpr pe = Expression.MemberLookup (
+ PropertyExpr pe = Expression.MemberLookup (ec.Compiler,
ec.CurrentType, t, "Current", MemberTypes.Property,
Expression.AllBindingFlags, loc) as PropertyExpr;
if (pe == null)
return true;
}
- void Error_Enumerator ()
+ void Error_Enumerator (BlockContext ec)
{
if (enumerator_found) {
return;
}
- Report.Error (1579, loc,
+ ec.Report.Error (1579, loc,
"foreach statement cannot operate on variables of type `{0}' because it does not contain a definition for `GetEnumerator' or is not accessible",
TypeManager.CSharpName (expr.Type));
}
return base_method != m;
}
- bool TryType (EmitContext ec, Type t)
+ bool TryType (ResolveContext ec, Type t)
{
- MethodGroupExpr mg = Expression.MemberLookup (
+ MethodGroupExpr mg = Expression.MemberLookup (ec.Compiler,
ec.CurrentType, t, "GetEnumerator", MemberTypes.Method,
Expression.AllBindingFlags, loc) as MethodGroupExpr;
if (mg == null)
continue;
MethodBase mb = TypeManager.DropGenericMethodArguments (mi);
- Report.SymbolRelatedToPreviousError (t);
- Report.Error(1640, loc, "foreach statement cannot operate on variables of type `{0}' " +
+ ec.Report.SymbolRelatedToPreviousError (t);
+ ec.Report.Error(1640, loc, "foreach statement cannot operate on variables of type `{0}' " +
"because it contains multiple implementation of `{1}'. Try casting to a specific implementation",
TypeManager.CSharpName (t), TypeManager.CSharpSignature (mb));
return false;
TypeManager.ImplementsInterface (result.DeclaringType, mi.DeclaringType))
continue;
- Report.SymbolRelatedToPreviousError (result);
- Report.SymbolRelatedToPreviousError (mi);
- Report.Warning (278, 2, loc, "`{0}' contains ambiguous implementation of `{1}' pattern. Method `{2}' is ambiguous with method `{3}'",
+ ec.Report.SymbolRelatedToPreviousError (result);
+ ec.Report.SymbolRelatedToPreviousError (mi);
+ ec.Report.Warning (278, 2, loc, "`{0}' contains ambiguous implementation of `{1}' pattern. Method `{2}' is ambiguous with method `{3}'",
TypeManager.CSharpName (t), "enumerable", TypeManager.CSharpSignature (result), TypeManager.CSharpSignature (mi));
return false;
}
}
return false;
- }
+ }
- bool ProbeCollectionType (EmitContext ec, Type t)
+ bool ProbeCollectionType (ResolveContext ec, Type t)
{
- int errors = Report.Errors;
+ int errors = ec.Report.Errors;
for (Type tt = t; tt != null && tt != TypeManager.object_type;){
if (TryType (ec, tt))
return true;
tt = tt.BaseType;
}
- if (Report.Errors > errors)
+ if (ec.Report.Errors > errors)
return false;
//
return false;
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
enumerator_type = TypeManager.ienumerator_type;
if (!ProbeCollectionType (ec, expr.Type)) {
- Error_Enumerator ();
+ Error_Enumerator (ec);
return false;
}
Statement block = new CollectionForeachStatement (
var_type.Type, variable, get_current, statement, loc);
- loop = new While (move_next_expr, block, loc);
+ loop = new While (new BooleanExpression (move_next_expr), block, loc);
bool implements_idisposable = TypeManager.ImplementsInterface (enumerator_type, TypeManager.idisposable_type);
throw new NotSupportedException ();
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
return parent.ResolveLoop (ec);
}
throw new NotSupportedException ();
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
bool ok = true;
ec.EndFlowBranching ();
- ResolveReachability (ec);
+ ok &= base.Resolve (ec);
if (TypeManager.void_dispose_void == null) {
TypeManager.void_dispose_void = TypeManager.GetPredefinedMethod (
}
}
- bool ResolveLoop (EmitContext ec)
+ bool ResolveLoop (BlockContext ec)
{
return loop.Resolve (ec);
}
get { return statement; }
}
- public override bool Resolve (EmitContext ec)
+ public override bool Resolve (BlockContext ec)
{
expr = expr.Resolve (ec);
if (expr == null)
return false;
if (expr.IsNull) {
- Report.Error (186, loc, "Use of null is not valid in this context");
+ ec.Report.Error (186, loc, "Use of null is not valid in this context");
return false;
}
statement = new ArrayForeach (this, expr.Type.GetArrayRank ());
} else {
if (expr.eclass == ExprClass.MethodGroup || expr is AnonymousMethodExpression) {
- Report.Error (446, expr.Location, "Foreach statement cannot operate on a `{0}'",
+ ec.Report.Error (446, expr.Location, "Foreach statement cannot operate on a `{0}'",
expr.ExprClassName);
return false;
}