public void Error (int error, string s)
{
- if (!Location.IsNull (loc))
+ if (!loc.IsNull)
Report.Error (error, loc, s);
else
Report.Error (error, s);
Expression Test;
readonly Statement InitStatement;
readonly Statement Increment;
- readonly Statement Statement;
+ public readonly Statement Statement;
bool infinite, empty;
public For (Statement initStatement,
public class StatementExpression : Statement {
ExpressionStatement expr;
- public StatementExpression (ExpressionStatement expr, Location l)
+ public StatementExpression (ExpressionStatement expr)
{
this.expr = expr;
- loc = l;
+ loc = expr.Location;
}
public override bool Resolve (EmitContext ec)
if (expr == null)
return false;
- if (!(expr is Constant)){
+ Constant c = expr as Constant;
+ if (c == null) {
Error (150, "A constant value is expected");
return false;
}
- object val = Expression.ConvertIntLiteral (
- (Constant) expr, ec.Switch.SwitchType, loc);
+ c = c.ToType (ec.Switch.SwitchType, loc);
+ if (c == null)
+ return false;
+ object val = c.GetValue ();
if (val == null)
- return false;
+ val = SwitchLabel.NullStringCase;
sl = (SwitchLabel) ec.Switch.Elements [val];
if (sl == null){
- Report.Error (159, loc, "No such label `case {0}:' within the scope of the goto statement", val);
+ Report.Error (159, loc, "No such label `case {0}:' within the scope of the goto statement", c.GetValue () == null ? "null" : val);
return false;
}
public override bool Resolve (EmitContext ec)
{
- if (!ec.CurrentBranching.InLoop () && !ec.CurrentBranching.InSwitch ()){
+ if (!ec.CurrentBranching.InLoop ()){
Error (139, "No enclosing loop out of which to break or continue");
return false;
} else if (ec.InFinally) {
// treat it as if the variable declaration was in error.
//
Report.SymbolRelatedToPreviousError (loc, name);
- Error_AlreadyDeclared (kvi.Location, name, "child");
+ Error_AlreadyDeclared (kvi.Location, name, "parent or current");
return false;
}
continue;
}
- if (e.Type != variable_type){
- e = Const.ChangeType (vi.Location, ce, variable_type);
- if (e == null)
- continue;
- }
+ e = ce.ToType (variable_type, vi.Location);
+ if (e == null)
+ continue;
constants.Remove (name);
constants.Add (name, e);
bool unreachable_shown;
bool unreachable;
+ private void CheckPossibleMistakenEmptyStatement (Statement s)
+ {
+ Statement body;
+
+ // Some statements are wrapped by a Block. Since
+ // others' internal could be changed, here I treat
+ // them as possibly wrapped by Block equally.
+ Block b = s as Block;
+ if (b != null && b.statements.Count == 1)
+ s = (Statement) b.statements [0];
+
+ if (s is Lock)
+ body = ((Lock) s).Statement;
+ else if (s is For)
+ body = ((For) s).Statement;
+ else if (s is Foreach)
+ body = ((Foreach) s).Statement;
+ else if (s is While)
+ body = ((While) s).Statement;
+ else if (s is Using)
+ body = ((Using) s).Statement;
+ else if (s is Fixed)
+ body = ((Fixed) s).Statement;
+ else
+ return;
+
+ if (body == null || body is EmptyStatement)
+ Report.Warning (642, 3, s.loc, "Possible mistaken empty statement");
+ }
+
public override bool Resolve (EmitContext ec)
{
Block prev_block = ec.CurrentBlock;
int statement_count = statements.Count;
for (int ix = 0; ix < statement_count; ix++){
Statement s = (Statement) statements [ix];
+ // Check possible empty statement (CS0642)
+ if (RootContext.WarningLevel >= 3 &&
+ ix + 1 < statement_count &&
+ statements [ix + 1] is Block)
+ CheckPossibleMistakenEmptyStatement (s);
//
// Warn if we detect unreachable code.
if (!unreachable_shown && (RootContext.WarningLevel >= 2)) {
Report.Warning (
- 162, loc, "Unreachable code detected");
+ 162, s.loc, "Unreachable code detected");
unreachable_shown = true;
}
}
Label il_label_code;
bool il_label_code_set;
+ public static readonly object NullStringCase = new object ();
+
//
// if expr == null, then it is the default case.
//
return false;
}
- if (required_type == TypeManager.string_type) {
- if (c.Type == TypeManager.string_type) {
- converted = c.GetValue ();
- return true;
- }
-
- if (e is NullLiteral) {
- converted = e;
- return true;
- }
+ if (required_type == TypeManager.string_type && e is NullLiteral) {
+ converted = NullStringCase;
+ return true;
}
- converted = Expression.ConvertIntLiteral (c, required_type, loc);
- return converted != null;
+ c = c.ToType (required_type, loc);
+ if (c == null)
+ return false;
+
+ converted = c.GetValue ();
+ return true;
}
public void Erorr_AlreadyOccurs ()
ig.Emit (OpCodes.Ldloc, val);
- if (Elements.Contains (NullLiteral.Null)){
+ if (Elements.Contains (SwitchLabel.NullStringCase)){
ig.Emit (OpCodes.Brfalse, null_target);
} else
ig.Emit (OpCodes.Brfalse, default_target);
if (sl.Label != null){
object lit = sl.Converted;
- if (lit is NullLiteral){
+ if (lit == SwitchLabel.NullStringCase){
null_found = true;
if (label_count == 1)
ig.Emit (OpCodes.Br, next_test);
public class Lock : ExceptionStatement {
Expression expr;
- Statement Statement;
+ public Statement Statement;
LocalBuilder temp;
public Lock (Expression expr, Statement stmt, Location l)
loc = l;
}
+ public Statement Statement {
+ get { return statement; }
+ }
+
public override bool Resolve (EmitContext ec)
{
if (!ec.InUnsafe){
throw new Exception ("Variable does not exist in this block");
ig.Emit (OpCodes.Stloc, vi.LocalBuilder);
+ if (vi.IsCaptured){
+ ec.EmitCapturedVariableInstance (vi);
+ ig.Emit (OpCodes.Ldloc, vi.LocalBuilder);
+ ig.Emit (OpCodes.Stfld, vi.FieldBuilder);
+ }
} else
ig.Emit (OpCodes.Pop);
public class Using : ExceptionStatement {
object expression_or_block;
- Statement Statement;
+ public Statement Statement;
ArrayList var_list;
Expression expr;
Type expr_type;
{
if (!TypeManager.ImplementsInterface (expr_type, TypeManager.idisposable_type)){
if (Convert.ImplicitConversion (ec, expr, TypeManager.idisposable_type, loc) == null) {
- Report.Error (1674, loc, "`{0}': type used in a using statement must be implicitly convertible to 'System.IDisposable'",
+ Report.Error (1674, loc, "`{0}': type used in a using statement must be implicitly convertible to `System.IDisposable'",
TypeManager.CSharpName (expr_type));
return false;
}
statement = stmt;
loc = l;
}
-
+
+ public Statement Statement {
+ get { return statement; }
+ }
+
public override bool Resolve (EmitContext ec)
{
expr = expr.Resolve (ec);
list.Add (counter [i]);
}
- access = new ElementAccess (copy, list, loc).Resolve (ec);
+ access = new ElementAccess (copy, list).Resolve (ec);
if (access == null)
return false;
enumerator = new TemporaryVariable (enumerator_type, loc);
enumerator.Resolve (ec);
- init = new Invocation (get_enumerator, new ArrayList (), loc);
+ init = new Invocation (get_enumerator, new ArrayList ());
init = init.Resolve (ec);
if (init == null)
return false;
MethodGroupExpr mg = new MethodGroupExpr (mi, loc);
mg.InstanceExpression = enumerator;
- move_next_expr = new Invocation (mg, new ArrayList (), loc);
+ move_next_expr = new Invocation (mg, new ArrayList ());
}
get_current.InstanceExpression = enumerator;