// in unreachable code, for instance.
//
- if (warn && (RootContext.WarningLevel >= 2))
- Report.Warning (162, loc, "Unreachable code detected");
+ if (warn)
+ Report.Warning (162, 2, loc, "Unreachable code detected");
ec.StartFlowBranching (FlowBranching.BranchingType.Block, loc);
bool ok = Resolve (ec);
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", c.GetValue () == null ? "null" : val);
+ Report.Error (159, loc, "No such label `case {0}:' within the scope of the goto statement", c.GetValue () == null ? "null" : val.ToString ());
return false;
}
//
// Keeps track of (name, type) pairs
//
- Hashtable variables;
+ IDictionary variables;
//
// Keeps track of constants
get { return this_id; }
}
- protected Hashtable Variables {
+ protected IDictionary Variables {
get {
if (variables == null)
- variables = new Hashtable ();
+ variables = new ListDictionary ();
return variables;
}
}
constants = new Hashtable ();
constants.Add (name, value);
+
+ // A block is considered used if we perform an initialization in a local declaration, even if it is constant.
+ Use ();
return true;
}
return null;
}
- /// <summary>
- /// True if the variable named @name is a constant
- /// </summary>
- public bool IsConstant (string name)
- {
- Expression e = GetConstantExpression (name);
- return e != null;
- }
-
public void AddStatement (Statement s)
{
statements.Add (s);
/// tc: is our typecontainer (to resolve type references)
/// ig: is the code generator:
/// </remarks>
- public void ResolveMeta (ToplevelBlock toplevel, EmitContext ec, InternalParameters ip)
+ public void ResolveMeta (ToplevelBlock toplevel, EmitContext ec, Parameters ip)
{
bool old_unsafe = ec.InUnsafe;
if (cv == null)
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);
+
ec.CurrentBlock = this;
Expression e = cv.Resolve (ec);
+ if (e == null)
+ continue;
Constant ce = e as Constant;
if (ce == null){
if (e == null)
continue;
- constants.Remove (name);
constants.Add (name, e);
}
}
name = (string) de.Key;
if (vector.IsAssigned (vi.VariableInfo)){
- Report.Warning (219, vi.Location, "The variable `{0}' is assigned but its value is never used", name);
+ Report.Warning (219, 3, vi.Location, "The variable `{0}' is assigned but its value is never used", name);
} else {
- Report.Warning (168, vi.Location, "The variable `{0}' is declared but never used", name);
+ Report.Warning (168, 3, vi.Location, "The variable `{0}' is declared but never used", name);
}
}
}
// Warn if we detect unreachable code.
//
if (unreachable) {
+ if (s is EmptyStatement)
+ continue;
+
if (s is Block)
((Block) s).unreachable = true;
- if (!unreachable_shown && (RootContext.WarningLevel >= 2)) {
- Report.Warning (
- 162, s.loc, "Unreachable code detected");
+ if (!unreachable_shown) {
+ Report.Warning (162, 2, s.loc, "Unreachable code detected");
unreachable_shown = true;
}
}
if ((labels != null) && (RootContext.WarningLevel >= 2)) {
foreach (LabeledStatement label in labels.Values)
if (!label.HasBeenReferenced)
- Report.Warning (164, label.loc,
+ Report.Warning (164, 2, label.loc,
"This label has not been referenced");
}
unreachable_shown = true;
unreachable = true;
- if (warn && (RootContext.WarningLevel >= 2))
- Report.Warning (162, loc, "Unreachable code detected");
+ if (warn)
+ Report.Warning (162, 2, loc, "Unreachable code detected");
ec.StartFlowBranching (FlowBranching.BranchingType.Block, loc);
bool ok = Resolve (ec);
Parameters pars = t.Parameters;
par = pars.GetParameterByName (name, out idx);
if (par != null)
- return new ParameterReference (pars, this, idx, name, loc);
+ return new ParameterReference (par, this, idx, loc);
}
return null;
}
return this_variable == null || this_variable.IsThisAssigned (ec, loc);
}
- public bool ResolveMeta (EmitContext ec, InternalParameters ip)
+ public bool ResolveMeta (EmitContext ec, Parameters ip)
{
int errors = Report.Errors;
return false;
}
- if (required_type == TypeManager.string_type && e is NullLiteral) {
+ if (required_type == TypeManager.string_type && c.GetValue () == null) {
converted = NullStringCase;
return true;
}
string label;
if (converted == null)
label = "default";
- else if (converted is NullLiteral)
+ else if (converted == NullStringCase)
label = "null";
else
label = converted.ToString ();
public abstract void EmitExit (ILGenerator ig);
}
- class ExpressionEmitter: Emitter {
+ class ExpressionEmitter : Emitter {
public ExpressionEmitter (Expression converted, LocalInfo li) :
base (converted, li)
{
}
}
- class StringEmitter: Emitter {
+ class StringEmitter : Emitter {
LocalBuilder pinned_string;
Location loc;
}
}
- public class Catch: Statement {
+ public class Catch : Statement {
public readonly string Name;
public readonly Block Block;
Report.Debug (1, "END OF CATCH BLOCKS", ec.CurrentBranching);
if (General != null){
+ if (CodeGen.Assembly.WrapNonExceptionThrows) {
+ foreach (Catch c in Specific){
+ if (c.CatchType == TypeManager.exception_type) {
+ 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.CurrentBranching.CreateSibling (
General.Block, FlowBranching.SiblingType.Catch);
if (vi == null)
throw new Exception ("Variable does not exist in this block");
- ig.Emit (OpCodes.Stloc, vi.LocalBuilder);
if (vi.IsCaptured){
+ LocalBuilder e = ig.DeclareLocal (vi.VariableType);
+ ig.Emit (OpCodes.Stloc, e);
+
ec.EmitCapturedVariableInstance (vi);
- ig.Emit (OpCodes.Ldloc, vi.LocalBuilder);
+ ig.Emit (OpCodes.Ldloc, e);
ig.Emit (OpCodes.Stfld, vi.FieldBuilder);
- }
+ } else
+ ig.Emit (OpCodes.Stloc, vi.LocalBuilder);
} else
ig.Emit (OpCodes.Pop);
MethodInfo mi = null;
foreach (MethodInfo mk in ((MethodGroupExpr) ml).Methods) {
- if (TypeManager.GetArgumentTypes (mk).Length == 0) {
+ if (TypeManager.GetParameterData (mk).Count == 0) {
mi = mk;
break;
}
MethodInfo mi = null;
foreach (MethodInfo mk in ((MethodGroupExpr) ml).Methods) {
- if (TypeManager.GetArgumentTypes (mk).Length == 0) {
+ if (TypeManager.GetParameterData (mk).Count == 0) {
mi = mk;
break;
}
if (expr == null)
return false;
- if (expr is NullLiteral) {
+ Constant c = expr as Constant;
+ if (c != null && c.GetValue () == null) {
Report.Error (186, loc, "Use of null is not valid in this context");
return false;
}
foreach (MemberInfo m in move_next_list){
MethodInfo mi = (MethodInfo) m;
- Type [] args;
- args = TypeManager.GetArgumentTypes (mi);
- if ((args != null) && (args.Length == 0) &&
+ if ((TypeManager.GetParameterData (mi).Count == 0) &&
TypeManager.TypeToCoreType (mi.ReturnType) == TypeManager.bool_type) {
move_next = mi;
return true;
foreach (MemberInfo m in dispose_list){
MethodInfo mi = (MethodInfo) m;
- Type [] args;
- args = TypeManager.GetArgumentTypes (mi);
- if (args != null && args.Length == 0){
+ if (TypeManager.GetParameterData (mi).Count == 0){
if (mi.ReturnType == TypeManager.void_type)
return mi;
}
return false;
foreach (MethodBase mb in mg.Methods) {
- Type [] args = TypeManager.GetArgumentTypes (mb);
- if (args != null && args.Length != 0)
+ if (TypeManager.GetParameterData (mb).Count != 0)
continue;
// Check whether GetEnumerator is public