2008-03-27 Marek Safar <marek.safar@gmail.com>
[mono.git] / mcs / mcs / statement.cs
index 83ee638cc010245b80b227eabec3001c54ff2d80..9a3121ecae27fc9f2cd6ecef0fde5f0eaae55588 100644 (file)
@@ -103,6 +103,12 @@ namespace Mono.CSharp {
                        return s;
                }
 
+               public virtual Expression CreateExpressionTree (EmitContext ec)
+               {
+                       Report.Error (834, loc, "A lambda expression with statement body cannot be converted to an expresion tree");
+                       return null;
+               }
+
                public Statement PerformClone ()
                {
                        CloneContext clonectx = new CloneContext ();
@@ -209,21 +215,21 @@ namespace Mono.CSharp {
 
                bool is_true_ret;
                
-               public If (Expression expr, Statement trueStatement, Location l)
+               public If (Expression expr, Statement true_statement, Location l)
                {
                        this.expr = expr;
-                       TrueStatement = trueStatement;
+                       TrueStatement = true_statement;
                        loc = l;
                }
 
                public If (Expression expr,
-                          Statement trueStatement,
-                          Statement falseStatement,
+                          Statement true_statement,
+                          Statement false_statement,
                           Location l)
                {
                        this.expr = expr;
-                       TrueStatement = trueStatement;
-                       FalseStatement = falseStatement;
+                       TrueStatement = true_statement;
+                       FalseStatement = false_statement;
                        loc = l;
                }
 
@@ -247,8 +253,8 @@ namespace Mono.CSharp {
                        //
                        // Dead code elimination
                        //
-                       if (expr is BoolConstant){
-                               bool take = ((BoolConstant) expr).Value;
+                       if (expr is Constant){
+                               bool take = !((Constant) expr).IsDefaultValue;
 
                                if (take){
                                        if (!TrueStatement.Resolve (ec))
@@ -296,15 +302,34 @@ namespace Mono.CSharp {
                        Label end;
 
                        //
-                       // If we're a boolean expression, Resolve() already
+                       // If we're a boolean constant, Resolve() already
                        // eliminated dead code for us.
                        //
-                       if (expr is BoolConstant){
-                               bool take = ((BoolConstant) expr).Value;
+                       if (expr is Constant){
+                               
+                               //
+                               // Simple bool constant
+                               //
+                               if (expr is BoolConstant) {
+                                       bool take = ((BoolConstant) expr).Value;
+
+                                       if (take)
+                                               TrueStatement.Emit (ec);
+                                       else if (FalseStatement != null)
+                                               FalseStatement.Emit (ec);
+                                       
+                                       return;
+                               }
+
+                               //
+                               // Bool constant with side-effects
+                               //
+                               expr.Emit (ec);
+                               ig.Emit (OpCodes.Pop);
 
-                               if (take)
+                               if (TrueStatement != null)
                                        TrueStatement.Emit (ec);
-                               else if (FalseStatement != null)
+                               if (FalseStatement != null)
                                        FalseStatement.Emit (ec);
 
                                return;
@@ -349,9 +374,9 @@ namespace Mono.CSharp {
                public Statement  EmbeddedStatement;
                bool infinite;
                
-               public Do (Statement statement, Expression boolExpr, Location l)
+               public Do (Statement statement, Expression bool_expr, Location l)
                {
-                       expr = boolExpr;
+                       expr = bool_expr;
                        EmbeddedStatement = statement;
                        loc = l;
                }
@@ -434,9 +459,9 @@ namespace Mono.CSharp {
                public Statement Statement;
                bool infinite, empty;
                
-               public While (Expression boolExpr, Statement statement, Location l)
+               public While (Expression bool_expr, Statement statement, Location l)
                {
-                       this.expr = boolExpr;
+                       this.expr = bool_expr;
                        Statement = statement;
                        loc = l;
                }
@@ -515,6 +540,7 @@ namespace Mono.CSharp {
                                Statement.Emit (ec);
                        
                                ig.MarkLabel (ec.LoopBegin);
+                               ec.Mark (loc, true);
 
                                expr.EmitBranchable (ec, while_loop, true);
                                
@@ -525,6 +551,11 @@ namespace Mono.CSharp {
                        ec.LoopEnd = old_end;
                }
 
+               public override void Emit (EmitContext ec)
+               {
+                       DoEmit (ec);
+               }
+
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        While target = (While) t;
@@ -541,13 +572,13 @@ namespace Mono.CSharp {
                public Statement Statement;
                bool infinite, empty;
                
-               public For (Statement initStatement,
+               public For (Statement init_statement,
                            Expression test,
                            Statement increment,
                            Statement statement,
                            Location l)
                {
-                       InitStatement = initStatement;
+                       InitStatement = init_statement;
                        Test = test;
                        Increment = increment;
                        Statement = statement;
@@ -714,7 +745,7 @@ namespace Mono.CSharp {
        ///   Implements the return statement
        /// </summary>
        public class Return : Statement {
-               Expression Expr;
+               protected Expression Expr;
                bool unwind_protect;
                
                public Return (Expression expr, Location l)
@@ -753,6 +784,12 @@ namespace Mono.CSharp {
 
                        if (Expr.Type != ec.ReturnType) {
                                if (ec.InferReturnType) {
+                                       //
+                                       // void cannot be used in contextual return
+                                       //
+                                       if (Expr.Type == TypeManager.void_type)
+                                               return false;
+
                                        ec.ReturnType = Expr.Type;
                                } else {
                                        Expr = Convert.ImplicitConversionRequired (
@@ -761,7 +798,7 @@ namespace Mono.CSharp {
                                        if (Expr == null) {
                                                if (am != null) {
                                                        Report.Error (1662, loc,
-                                                               "Cannot convert `{0}' to delegate type `D' because some of the return types in the block are not implicitly convertible to the delegate return type",
+                                                               "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 ());
                                                }
                                                return false;
@@ -1089,7 +1126,8 @@ namespace Mono.CSharp {
                {
                        Throw target = (Throw) t;
 
-                       target.expr = expr.Clone (clonectx);
+                       if (expr != null)
+                               target.expr = expr.Clone (clonectx);
                }
        }
 
@@ -1255,7 +1293,7 @@ namespace Mono.CSharp {
                public void EmitSymbolInfo (EmitContext ec, string name)
                {
                        if (builder != null)
-                               ec.DefineLocalVariable (name, builder);
+                               ec.DefineLocalVariable (Name, builder);
                }
 
                public bool IsThisAssigned (EmitContext ec)
@@ -1431,8 +1469,18 @@ namespace Mono.CSharp {
 
                public LocalInfo Clone (CloneContext clonectx)
                {
-                       // Only this kind is created by the parser.
-                       return new LocalInfo (Type.Clone (clonectx), Name, clonectx.LookupBlock (Block), Location);
+                       //
+                       // Variables in anonymous block are not resolved yet
+                       //
+                       if (VariableType == null)
+                               return new LocalInfo (Type.Clone (clonectx), Name, clonectx.LookupBlock (Block), Location);
+
+                       //
+                       // Variables in method block are resolved
+                       //
+                       LocalInfo li = new LocalInfo (null, Name, clonectx.LookupBlock (Block), Location);
+                       li.VariableType = VariableType;
+                       return li;                      
                }
        }
 
@@ -1499,7 +1547,7 @@ namespace Mono.CSharp {
                //
                // Labels.  (label, block) pairs.
                //
-               Hashtable labels;
+               HybridDictionary labels;
 
                //
                // Keeps track of (name, type) pairs
@@ -1508,7 +1556,7 @@ namespace Mono.CSharp {
 
                //
                // Keeps track of constants
-               Hashtable constants;
+               HybridDictionary constants;
 
                //
                // Temporary variables.
@@ -1520,7 +1568,9 @@ namespace Mono.CSharp {
                //
                Block switch_block;
 
+               // TODO: merge with scope_initializers
                ExpressionStatement scope_init;
+               ArrayList scope_initializers;
 
                ArrayList anonymous_children;
 
@@ -1561,7 +1611,7 @@ namespace Mono.CSharp {
                        this.EndLocation = end;
                        this.loc = start;
                        this_id = id++;
-                       statements = new ArrayList ();
+                       statements = new ArrayList (4);
                }
 
                public Block CreateSwitchBlock (Location start)
@@ -1587,7 +1637,7 @@ namespace Mono.CSharp {
                void AddChild (Block b)
                {
                        if (children == null)
-                               children = new ArrayList ();
+                               children = new ArrayList (1);
                        
                        children.Add (b);
                }
@@ -1658,7 +1708,7 @@ namespace Mono.CSharp {
                        Toplevel.CheckError158 (name, target.loc);
 
                        if (labels == null)
-                               labels = new Hashtable ();
+                               labels = new HybridDictionary();
 
                        labels.Add (name, target);
                        return true;
@@ -1757,8 +1807,7 @@ namespace Mono.CSharp {
                        if (vi != null) {
                                Report.SymbolRelatedToPreviousError (vi.Location, name);
                                if (Explicit == vi.Block.Explicit)
-                                       Report.Error (128, l,
-                                               "A local variable named `{0}' is already defined in this scope", name);
+                                       Error_AlreadyDeclared (l, name, null);
                                else
                                        Error_AlreadyDeclared (l, name, "parent");
                                return null;
@@ -1769,7 +1818,18 @@ namespace Mono.CSharp {
                                Report.SymbolRelatedToPreviousError (pi.Location, name);
                                Error_AlreadyDeclared (loc, name,
                                        pi.Block == Toplevel ? "method argument" : "parent or current");
+                               return null;
                        }
+                       
+                       if (Toplevel.GenericMethod != null) {
+                               foreach (TypeParameter tp in Toplevel.GenericMethod.CurrentTypeParameters) {
+                                       if (tp.Name == name) {
+                                               Report.SymbolRelatedToPreviousError (tp);
+                                               Error_AlreadyDeclaredTypeParameter (loc, name);
+                                               return null;
+                                       }
+                               }
+                       }                       
 
                        IKnownVariable kvi = Explicit.GetKnownVariable (name);
                        if (kvi != null) {
@@ -1779,30 +1839,51 @@ namespace Mono.CSharp {
                        }
 
                        vi = new LocalInfo (type, name, this, l);
-                       Variables.Add (name, vi);
-                       Explicit.AddKnownVariable (name, vi);
+                       AddVariable (vi);
 
                        if ((flags & Flags.VariablesInitialized) != 0)
                                throw new InternalErrorException ("block has already been resolved");
 
                        return vi;
                }
+               
+               protected virtual void AddVariable (LocalInfo li)
+               {
+                       Variables.Add (li.Name, li);
+                       Explicit.AddKnownVariable (li.Name, li);
+               }
 
-               protected static void Error_AlreadyDeclared (Location loc, string var, string reason)
+               protected virtual void Error_AlreadyDeclared (Location loc, string var, string reason)
                {
+                       if (reason == null) {
+                               Error_AlreadyDeclared (loc, var);
+                               return;
+                       }
+                       
                        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,
+                               "A local variable named `{0}' is already defined in this scope", name);
+               }
+                                       
+               protected virtual void Error_AlreadyDeclaredTypeParameter (Location loc, string name)
+               {
+                       GenericMethod.Error_ParameterNameCollision (loc, name, "local variable");
+               }                                       
+
                public bool AddConstant (Expression type, string name, Expression value, Location l)
                {
                        if (AddVariable (type, name, l) == null)
                                return false;
                        
                        if (constants == null)
-                               constants = new Hashtable ();
+                               constants = new HybridDictionary();
 
                        constants.Add (name, value);
 
@@ -1858,6 +1939,18 @@ namespace Mono.CSharp {
                        }
                        return null;
                }
+
+               //
+               // It should be used by expressions which require to
+               // register a statement during resolve process.
+               //
+               public void AddScopeStatement (StatementExpression s)
+               {
+                       if (scope_initializers == null)
+                               scope_initializers = new ArrayList ();
+
+                       scope_initializers.Add (s);
+               }
                
                public void AddStatement (Statement s)
                {
@@ -1932,8 +2025,12 @@ namespace Mono.CSharp {
                                LocalInfo vi = (LocalInfo) de.Value;
                                Type variable_type = vi.VariableType;
 
-                               if (variable_type == null)
+                               if (variable_type == null) {
+                                       if (vi.Type is VarExpr)
+                                               Report.Error (822, vi.Type.Location, "An implicitly typed local variable cannot be a constant");
+
                                        continue;
+                               }
 
                                Expression cv = (Expression) constants [name];
                                if (cv == null)
@@ -2023,13 +2120,13 @@ namespace Mono.CSharp {
                        }
 
                        if (temporary_variables != null) {
-                               foreach (LocalInfo vi in temporary_variables)
-                                       vi.ResolveVariable (ec);
+                               for (int i = 0; i < temporary_variables.Count; i++)
+                                       ((LocalInfo)temporary_variables[i]).ResolveVariable(ec);
                        }
 
                        if (children != null){
-                               foreach (Block b in children)
-                                       b.EmitMeta (ec);
+                               for (int i = 0; i < children.Count; i++)
+                                       ((Block)children[i]).EmitMeta(ec);
                        }
                }
 
@@ -2138,10 +2235,10 @@ namespace Mono.CSharp {
                                //
 
                                if (!s.Resolve (ec)) {
+                                       ok = false;
                                        if (ec.IsInProbingMode)
-                                               return false;
+                                               break;
 
-                                       ok = false;
                                        statements [ix] = EmptyStatement.Value;
                                        continue;
                                }
@@ -2159,9 +2256,6 @@ namespace Mono.CSharp {
                        Report.Debug (4, "RESOLVE BLOCK DONE", StartLocation,
                                      ec.CurrentBranching, statement_count, num_statements);
 
-                       if (!ok)
-                               return false;
-
                        while (ec.CurrentBranching is FlowBranchingLabeled)
                                ec.EndFlowBranching ();
 
@@ -2222,34 +2316,58 @@ namespace Mono.CSharp {
 
                        ec.CurrentBlock = this;
 
-                       bool emit_debug_info = (CodeGen.SymbolWriter != null);
-                       bool is_lexical_block = this == Explicit && Parent != null;
+                       bool emit_debug_info = SymbolWriter.HasSymbolWriter;
+                       bool is_lexical_block = (this == Explicit) && (Parent != null) &&
+                               ((flags & Flags.IsIterator) == 0);
+
+                       bool omit_debug_info = ec.OmitDebuggingInfo;
 
                        if (emit_debug_info) {
                                if (is_lexical_block)
                                        ec.BeginScope ();
                        }
-                       ec.Mark (StartLocation, true);
-                       if (scope_init != null)
+
+                       if ((scope_init != null) || (scope_initializers != null))
+                               SymbolWriter.OpenCompilerGeneratedBlock (ec.ig);
+
+                       if (scope_init != null) {
+                               ec.OmitDebuggingInfo = true;
                                scope_init.EmitStatement (ec);
+                               ec.OmitDebuggingInfo = omit_debug_info;
+                       }
+                       if (scope_initializers != null) {
+                               ec.OmitDebuggingInfo = true;
+                               foreach (StatementExpression s in scope_initializers)
+                                       s.Emit (ec);
+                               ec.OmitDebuggingInfo = omit_debug_info;
+                       }
+
+                       if ((scope_init != null) || (scope_initializers != null))
+                               SymbolWriter.CloseCompilerGeneratedBlock (ec.ig);
+
+                       ec.Mark (StartLocation, true);
                        DoEmit (ec);
-                       ec.Mark (EndLocation, true); 
 
                        if (emit_debug_info) {
+                               EmitSymbolInfo (ec);
+
                                if (is_lexical_block)
                                        ec.EndScope ();
+                       }
 
-                               if (variables != null) {
-                                       foreach (DictionaryEntry de in variables) {
-                                               string name = (string) de.Key;
-                                               LocalInfo vi = (LocalInfo) de.Value;
+                       ec.CurrentBlock = prev_block;
+               }
 
-                                               vi.EmitSymbolInfo (ec, name);
-                                       }
+               protected virtual void EmitSymbolInfo (EmitContext ec)
+               {
+                       if (variables != null) {
+                               foreach (DictionaryEntry de in variables) {
+                                       string name = (string) de.Key;
+                                       LocalInfo vi = (LocalInfo) de.Value;
+
+                                       vi.EmitSymbolInfo (ec, name);
                                }
                        }
-
-                       ec.CurrentBlock = prev_block;
                }
 
                public override string ToString ()
@@ -2307,7 +2425,11 @@ namespace Mono.CSharp {
                        this.Explicit = this;
                }
 
-               Hashtable known_variables;
+               public bool IsIterator {
+                       get { return (flags & Flags.IsIterator) != 0; }
+               }
+
+               HybridDictionary known_variables;
 
                // <summary>
                //   Marks a variable with name @name as being used in this or a child block.
@@ -2317,7 +2439,7 @@ namespace Mono.CSharp {
                internal void AddKnownVariable (string name, IKnownVariable info)
                {
                        if (known_variables == null)
-                               known_variables = new Hashtable ();
+                               known_variables = new HybridDictionary();
 
                        known_variables [name] = info;
 
@@ -2381,10 +2503,6 @@ namespace Mono.CSharp {
                        set { flags |= Flags.HasVarargs; }
                }
 
-               public bool IsIterator {
-                       get { return (flags & Flags.IsIterator) != 0; }
-               }
-
                //
                // The parameters for the block.
                //
@@ -2497,6 +2615,11 @@ namespace Mono.CSharp {
                        return true;
                }
 
+               public virtual Expression GetTransparentIdentifier (string name)
+               {
+                       return null;
+               }
+
                void ProcessParameters ()
                {
                        int n = parameters.Count;
@@ -2559,6 +2682,11 @@ namespace Mono.CSharp {
                        return root_scope;
                }
 
+               public override Expression CreateExpressionTree (EmitContext ec)
+               {
+                       return ((Statement) statements [0]).CreateExpressionTree (ec);
+               }
+
                public void CreateIteratorHost (RootScopeInfo root)
                {
                        Report.Debug (64, "CREATE ITERATOR HOST", this, root, Parent, root_scope);
@@ -2622,27 +2750,6 @@ namespace Mono.CSharp {
                        return null;
                }
 
-               //
-               // Whether the parameter named `name' is local to this block, 
-               // or false, if the parameter belongs to an encompassing block.
-               //
-               public bool IsLocalParameter (string name)
-               {
-                       return Parameters.GetParameterByName (name) != null;
-               }
-               
-               //
-               // Whether the `name' is a parameter reference
-               //
-               public bool IsParameterReference (string name)
-               {
-                       for (ToplevelBlock t = this; t != null; t = t.Container) {
-                               if (t.IsLocalParameter (name))
-                                       return true;
-                       }
-                       return false;
-               }
-
                LocalInfo this_variable = null;
 
                // <summary>
@@ -2740,15 +2847,27 @@ namespace Mono.CSharp {
 
                public override void EmitMeta (EmitContext ec)
                {
+                       // Avoid declaring an IL variable for this_variable since it is not accessed
+                       // from the generated IL
+                       if (this_variable != null)
+                               Variables.Remove ("this");
                        base.EmitMeta (ec);
                        parameters.ResolveVariable (this);
                }
 
+               protected override void EmitSymbolInfo (EmitContext ec)
+               {
+                       if ((AnonymousContainer != null) && (AnonymousContainer.Scope != null))
+                               SymbolWriter.DefineScopeVariable (AnonymousContainer.Scope.ID);
+
+                       base.EmitSymbolInfo (ec);
+               }
+
                public void MakeIterator (Iterator iterator)
                {
                        flags |= Flags.IsIterator;
 
-                       Block block = new ExplicitBlock (this, StartLocation, EndLocation);
+                       Block block = new ExplicitBlock (this, flags, StartLocation, EndLocation);
                        foreach (Statement stmt in statements)
                                block.AddStatement (stmt);
                        statements.Clear ();
@@ -2862,7 +2981,7 @@ namespace Mono.CSharp {
                                converted = NullStringCase;
                                return true;
                        }
-
+                       
                        c = c.ImplicitConversionRequired (required_type, loc);
                        if (c == null)
                                return false;
@@ -2871,19 +2990,19 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               public void Erorr_AlreadyOccurs (Type switchType, SwitchLabel collisionWith)
+               public void Error_AlreadyOccurs (Type switch_type, SwitchLabel collision_with)
                {
                        string label;
                        if (converted == null)
                                label = "default";
                        else if (converted == NullStringCase)
                                label = "null";
-                       else if (TypeManager.IsEnumType (switchType)) 
-                               label = TypeManager.CSharpEnumValue (switchType, converted);
+                       else if (TypeManager.IsEnumType (switch_type)) 
+                               label = TypeManager.CSharpEnumValue (switch_type, converted);
                        else
                                label = converted.ToString ();
                        
-                       Report.SymbolRelatedToPreviousError (collisionWith.loc, null);
+                       Report.SymbolRelatedToPreviousError (collision_with.loc, null);
                        Report.Error (152, loc, "The label `case {0}:' already occurs in this switch statement", label);
                }
 
@@ -2987,7 +3106,7 @@ namespace Mono.CSharp {
                //
                Expression SwitchGoverningType (EmitContext ec, Expression expr)
                {
-                       Type t = TypeManager.DropGenericTypeArguments (expr.Type);
+                       Type t = expr.Type;
 
                        if (t == TypeManager.byte_type ||
                            t == TypeManager.sbyte_type ||
@@ -3000,7 +3119,7 @@ namespace Mono.CSharp {
                            t == TypeManager.char_type ||
                            t == TypeManager.string_type ||
                            t == TypeManager.bool_type ||
-                           t.IsSubclassOf (TypeManager.enum_type))
+                           TypeManager.IsEnumType (t))
                                return expr;
 
                        if (allowed_types == null){
@@ -3071,7 +3190,7 @@ namespace Mono.CSharp {
                                foreach (SwitchLabel sl in ss.Labels){
                                        if (sl.Label == null){
                                                if (default_section != null){
-                                                       sl.Erorr_AlreadyOccurs (SwitchType, (SwitchLabel)default_section.Labels [0]);
+                                                       sl.Error_AlreadyOccurs (SwitchType, (SwitchLabel)default_section.Labels [0]);
                                                        error = true;
                                                }
                                                default_section = ss;
@@ -3087,7 +3206,7 @@ namespace Mono.CSharp {
                                        try {
                                                Elements.Add (key, sl);
                                        } catch (ArgumentException) {
-                                               sl.Erorr_AlreadyOccurs (SwitchType, (SwitchLabel)Elements [key]);
+                                               sl.Error_AlreadyOccurs (SwitchType, (SwitchLabel)Elements [key]);
                                                error = true;
                                        }
                                }
@@ -3146,22 +3265,22 @@ namespace Mono.CSharp {
                // structure used to hold blocks of keys while calculating table switch
                class KeyBlock : IComparable
                {
-                       public KeyBlock (long _nFirst)
+                       public KeyBlock (long _first)
                        {
-                               nFirst = nLast = _nFirst;
+                               first = last = _first;
                        }
-                       public long nFirst;
-                       public long nLast;
-                       public ArrayList rgKeys = null;
+                       public long first;
+                       public long last;
+                       public ArrayList element_keys = null;
                        // how many items are in the bucket
                        public int Size = 1;
                        public int Length
                        {
-                               get { return (int) (nLast - nFirst + 1); }
+                               get { return (int) (last - first + 1); }
                        }
-                       public static long TotalLength (KeyBlock kbFirst, KeyBlock kbLast)
+                       public static long TotalLength (KeyBlock kb_first, KeyBlock kb_last)
                        {
-                               return kbLast.nLast - kbFirst.nFirst + 1;
+                               return kb_last.last - kb_first.first + 1;
                        }
                        public int CompareTo (object obj)
                        {
@@ -3169,7 +3288,7 @@ namespace Mono.CSharp {
                                int nLength = Length;
                                int nLengthOther = kb.Length;
                                if (nLengthOther == nLength)
-                                       return (int) (kb.nFirst - nFirst);
+                                       return (int) (kb.first - first);
                                return nLength - nLengthOther;
                        }
                }
@@ -3186,89 +3305,89 @@ namespace Mono.CSharp {
                /// <returns></returns>
                void TableSwitchEmit (EmitContext ec, LocalBuilder val)
                {
-                       int cElements = Elements.Count;
-                       object [] rgKeys = new object [cElements];
-                       Elements.Keys.CopyTo (rgKeys, 0);
-                       Array.Sort (rgKeys);
+                       int element_count = Elements.Count;
+                       object [] element_keys = new object [element_count];
+                       Elements.Keys.CopyTo (element_keys, 0);
+                       Array.Sort (element_keys);
 
                        // initialize the block list with one element per key
-                       ArrayList rgKeyBlocks = new ArrayList ();
-                       foreach (object key in rgKeys)
-                               rgKeyBlocks.Add (new KeyBlock (System.Convert.ToInt64 (key)));
+                       ArrayList key_blocks = new ArrayList ();
+                       foreach (object key in element_keys)
+                               key_blocks.Add (new KeyBlock (System.Convert.ToInt64 (key)));
 
-                       KeyBlock kbCurr;
+                       KeyBlock current_kb;
                        // iteratively merge the blocks while they are at least half full
                        // there's probably a really cool way to do this with a tree...
-                       while (rgKeyBlocks.Count > 1)
+                       while (key_blocks.Count > 1)
                        {
-                               ArrayList rgKeyBlocksNew = new ArrayList ();
-                               kbCurr = (KeyBlock) rgKeyBlocks [0];
-                               for (int ikb = 1; ikb < rgKeyBlocks.Count; ikb++)
+                               ArrayList key_blocks_new = new ArrayList ();
+                               current_kb = (KeyBlock) key_blocks [0];
+                               for (int ikb = 1; ikb < key_blocks.Count; ikb++)
                                {
-                                       KeyBlock kb = (KeyBlock) rgKeyBlocks [ikb];
-                                       if ((kbCurr.Size + kb.Size) * 2 >=  KeyBlock.TotalLength (kbCurr, kb))
+                                       KeyBlock kb = (KeyBlock) key_blocks [ikb];
+                                       if ((current_kb.Size + kb.Size) * 2 >=  KeyBlock.TotalLength (current_kb, kb))
                                        {
                                                // merge blocks
-                                               kbCurr.nLast = kb.nLast;
-                                               kbCurr.Size += kb.Size;
+                                               current_kb.last = kb.last;
+                                               current_kb.Size += kb.Size;
                                        }
                                        else
                                        {
                                                // start a new block
-                                               rgKeyBlocksNew.Add (kbCurr);
-                                               kbCurr = kb;
+                                               key_blocks_new.Add (current_kb);
+                                               current_kb = kb;
                                        }
                                }
-                               rgKeyBlocksNew.Add (kbCurr);
-                               if (rgKeyBlocks.Count == rgKeyBlocksNew.Count)
+                               key_blocks_new.Add (current_kb);
+                               if (key_blocks.Count == key_blocks_new.Count)
                                        break;
-                               rgKeyBlocks = rgKeyBlocksNew;
+                               key_blocks = key_blocks_new;
                        }
 
                        // initialize the key lists
-                       foreach (KeyBlock kb in rgKeyBlocks)
-                               kb.rgKeys = new ArrayList ();
+                       foreach (KeyBlock kb in key_blocks)
+                               kb.element_keys = new ArrayList ();
 
                        // fill the key lists
                        int iBlockCurr = 0;
-                       if (rgKeyBlocks.Count > 0) {
-                               kbCurr = (KeyBlock) rgKeyBlocks [0];
-                               foreach (object key in rgKeys)
+                       if (key_blocks.Count > 0) {
+                               current_kb = (KeyBlock) key_blocks [0];
+                               foreach (object key in element_keys)
                                {
-                                       bool fNextBlock = (key is UInt64) ? (ulong) key > (ulong) kbCurr.nLast :
-                                               System.Convert.ToInt64 (key) > kbCurr.nLast;
-                                       if (fNextBlock)
-                                               kbCurr = (KeyBlock) rgKeyBlocks [++iBlockCurr];
-                                       kbCurr.rgKeys.Add (key);
+                                       bool next_block = (key is UInt64) ? (ulong) key > (ulong) current_kb.last :
+                                               System.Convert.ToInt64 (key) > current_kb.last;
+                                       if (next_block)
+                                               current_kb = (KeyBlock) key_blocks [++iBlockCurr];
+                                       current_kb.element_keys.Add (key);
                                }
                        }
 
                        // sort the blocks so we can tackle the largest ones first
-                       rgKeyBlocks.Sort ();
+                       key_blocks.Sort ();
 
                        // okay now we can start...
                        ILGenerator ig = ec.ig;
-                       Label lblEnd = ig.DefineLabel ();       // at the end ;-)
-                       Label lblDefault = ig.DefineLabel ();
+                       Label lbl_end = ig.DefineLabel ();      // at the end ;-)
+                       Label lbl_default = ig.DefineLabel ();
 
-                       Type typeKeys = null;
-                       if (rgKeys.Length > 0)
-                               typeKeys = rgKeys [0].GetType ();       // used for conversions
+                       Type type_keys = null;
+                       if (element_keys.Length > 0)
+                               type_keys = element_keys [0].GetType ();        // used for conversions
 
                        Type compare_type;
                        
                        if (TypeManager.IsEnumType (SwitchType))
-                               compare_type = TypeManager.EnumToUnderlying (SwitchType);
+                               compare_type = TypeManager.GetEnumUnderlyingType (SwitchType);
                        else
                                compare_type = SwitchType;
                        
-                       for (int iBlock = rgKeyBlocks.Count - 1; iBlock >= 0; --iBlock)
+                       for (int iBlock = key_blocks.Count - 1; iBlock >= 0; --iBlock)
                        {
-                               KeyBlock kb = ((KeyBlock) rgKeyBlocks [iBlock]);
-                               lblDefault = (iBlock == 0) ? DefaultTarget : ig.DefineLabel ();
+                               KeyBlock kb = ((KeyBlock) key_blocks [iBlock]);
+                               lbl_default = (iBlock == 0) ? DefaultTarget : ig.DefineLabel ();
                                if (kb.Length <= 2)
                                {
-                                       foreach (object key in kb.rgKeys)
+                                       foreach (object key in kb.element_keys)
                                        {
                                                ig.Emit (OpCodes.Ldloc, val);
                                                EmitObjectInteger (ig, key);
@@ -3287,17 +3406,17 @@ namespace Mono.CSharp {
 
                                                // check block range (could be > 2^31)
                                                ig.Emit (OpCodes.Ldloc, val);
-                                               EmitObjectInteger (ig, System.Convert.ChangeType (kb.nFirst, typeKeys));
-                                               ig.Emit (OpCodes.Blt, lblDefault);
+                                               EmitObjectInteger (ig, System.Convert.ChangeType (kb.first, type_keys));
+                                               ig.Emit (OpCodes.Blt, lbl_default);
                                                ig.Emit (OpCodes.Ldloc, val);
-                                               EmitObjectInteger (ig, System.Convert.ChangeType (kb.nLast, typeKeys));
-                                               ig.Emit (OpCodes.Bgt, lblDefault);
+                                               EmitObjectInteger (ig, System.Convert.ChangeType (kb.last, type_keys));
+                                               ig.Emit (OpCodes.Bgt, lbl_default);
 
                                                // normalize range
                                                ig.Emit (OpCodes.Ldloc, val);
-                                               if (kb.nFirst != 0)
+                                               if (kb.first != 0)
                                                {
-                                                       EmitObjectInteger (ig, System.Convert.ChangeType (kb.nFirst, typeKeys));
+                                                       EmitObjectInteger (ig, System.Convert.ChangeType (kb.first, type_keys));
                                                        ig.Emit (OpCodes.Sub);
                                                }
                                                ig.Emit (OpCodes.Conv_I4);      // assumes < 2^31 labels!
@@ -3306,15 +3425,15 @@ namespace Mono.CSharp {
                                        {
                                                // normalize range
                                                ig.Emit (OpCodes.Ldloc, val);
-                                               int nFirst = (int) kb.nFirst;
-                                               if (nFirst > 0)
+                                               int first = (int) kb.first;
+                                               if (first > 0)
                                                {
-                                                       IntConstant.EmitInt (ig, nFirst);
+                                                       IntConstant.EmitInt (ig, first);
                                                        ig.Emit (OpCodes.Sub);
                                                }
-                                               else if (nFirst < 0)
+                                               else if (first < 0)
                                                {
-                                                       IntConstant.EmitInt (ig, -nFirst);
+                                                       IntConstant.EmitInt (ig, -first);
                                                        ig.Emit (OpCodes.Add);
                                                }
                                        }
@@ -3322,26 +3441,26 @@ namespace Mono.CSharp {
                                        // first, build the list of labels for the switch
                                        int iKey = 0;
                                        int cJumps = kb.Length;
-                                       Label [] rgLabels = new Label [cJumps];
+                                       Label [] switch_labels = new Label [cJumps];
                                        for (int iJump = 0; iJump < cJumps; iJump++)
                                        {
-                                               object key = kb.rgKeys [iKey];
-                                               if (System.Convert.ToInt64 (key) == kb.nFirst + iJump)
+                                               object key = kb.element_keys [iKey];
+                                               if (System.Convert.ToInt64 (key) == kb.first + iJump)
                                                {
                                                        SwitchLabel sl = (SwitchLabel) Elements [key];
-                                                       rgLabels [iJump] = sl.GetILLabel (ec);
+                                                       switch_labels [iJump] = sl.GetILLabel (ec);
                                                        iKey++;
                                                }
                                                else
-                                                       rgLabels [iJump] = lblDefault;
+                                                       switch_labels [iJump] = lbl_default;
                                        }
                                        // emit the switch opcode
-                                       ig.Emit (OpCodes.Switch, rgLabels);
+                                       ig.Emit (OpCodes.Switch, switch_labels);
                                }
 
                                // mark the default for this block
                                if (iBlock != 0)
-                                       ig.MarkLabel (lblDefault);
+                                       ig.MarkLabel (lbl_default);
                        }
 
                        // TODO: find the default case and emit it here,
@@ -3349,16 +3468,16 @@ namespace Mono.CSharp {
                        //       make sure to mark other labels in the default section
 
                        // the last default just goes to the end
-                       ig.Emit (OpCodes.Br, lblDefault);
+                       ig.Emit (OpCodes.Br, lbl_default);
 
                        // now emit the code for the sections
-                       bool fFoundDefault = false;
-                       bool fFoundNull = false;
+                       bool found_default = false;
+                       bool found_null = false;
                        foreach (SwitchSection ss in Sections)
                        {
                                foreach (SwitchLabel sl in ss.Labels)
                                        if (sl.Converted == SwitchLabel.NullStringCase)
-                                               fFoundNull = true;
+                                               found_null = true;
                        }
 
                        foreach (SwitchSection ss in Sections)
@@ -3370,23 +3489,23 @@ namespace Mono.CSharp {
                                        if (sl.Converted == SwitchLabel.NullStringCase)
                                                ig.MarkLabel (null_target);
                                        else if (sl.Label == null) {
-                                               ig.MarkLabel (lblDefault);
-                                               fFoundDefault = true;
-                                               if (!fFoundNull)
+                                               ig.MarkLabel (lbl_default);
+                                               found_default = true;
+                                               if (!found_null)
                                                        ig.MarkLabel (null_target);
                                        }
                                }
                                ss.Block.Emit (ec);
                        }
                        
-                       if (!fFoundDefault) {
-                               ig.MarkLabel (lblDefault);
-                               if (HaveUnwrap && !fFoundNull) {
+                       if (!found_default) {
+                               ig.MarkLabel (lbl_default);
+                               if (HaveUnwrap && !found_null) {
                                        ig.MarkLabel (null_target);
                                }
                        }
                        
-                       ig.MarkLabel (lblEnd);
+                       ig.MarkLabel (lbl_end);
                }
                //
                // This simple emit switch works, but does not take advantage of the
@@ -3528,7 +3647,7 @@ namespace Mono.CSharp {
                        SwitchType = new_expr.Type;
 
                        if (RootContext.Version == LanguageVersion.ISO_1 && SwitchType == TypeManager.bool_type) {
-                               Report.FeatureIsNotISO1 (loc, "switch expression of boolean type");
+                               Report.FeatureIsNotAvailable (loc, "switch expression of boolean type");
                                return false;
                        }
 
@@ -3556,6 +3675,7 @@ namespace Mono.CSharp {
                        }
 
                        bool first = true;
+                       bool ok = true;
                        foreach (SwitchSection ss in Sections){
                                if (!first)
                                        ec.CurrentBranching.CreateSibling (
@@ -3568,11 +3688,12 @@ namespace Mono.CSharp {
                                        // one single section - mark all the others as
                                        // unreachable.
                                        ec.CurrentBranching.CurrentUsageVector.Goto ();
-                                       if (!ss.Block.ResolveUnreachable (ec, true))
-                                               return false;
+                                       if (!ss.Block.ResolveUnreachable (ec, true)) {
+                                               ok = false;
+                                       }
                                } else {
                                        if (!ss.Block.Resolve (ec))
-                                               return false;
+                                               ok = false;
                                }
                        }
 
@@ -3585,7 +3706,12 @@ namespace Mono.CSharp {
 
                        Report.Debug (1, "END OF SWITCH BLOCK", loc, ec.CurrentBranching);
 
-                       return true;
+                       if (TypeManager.string_isinterned_string == null) {
+                               TypeManager.string_isinterned_string = TypeManager.GetPredefinedMethod (TypeManager.string_type,
+                                       "IsInterned", loc, TypeManager.string_type);
+                       }
+
+                       return ok;
                }
                
                protected override void DoEmit (EmitContext ec)
@@ -3720,6 +3846,14 @@ namespace Mono.CSharp {
                        
                        temp = new TemporaryVariable (t, loc);
                        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);
+                               TypeManager.void_monitor_enter_object = TypeManager.GetPredefinedMethod (
+                                       monitor_type, "Enter", loc, TypeManager.object_type);
+                               TypeManager.void_monitor_exit_object = TypeManager.GetPredefinedMethod (
+                                       monitor_type, "Exit", loc, TypeManager.object_type);
+                       }
                        
                        return ok;
                }
@@ -3947,9 +4081,13 @@ namespace Mono.CSharp {
                                return false;
                        }
                        
-                       TypeExpr texpr = type.ResolveAsTypeTerminal (ec, false);
-                       if (texpr == null)
+                       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");
+
                                return false;
+                       }
 
                        expr_type = texpr.Type;
 
@@ -4049,6 +4187,17 @@ namespace Mono.CSharp {
                                                ec, array_ptr, vi.VariableType, loc);
                                        if (converted == null)
                                                return false;
+                                       
+                                       //
+                                       // fixed (T* e_ptr = (e == null || e.Length == 0) ? null : converted [0])
+                                       //
+                                       converted = new Conditional (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))),
+                                                       NullPointer.Null,
+                                                       converted);
+
+                                       converted = converted.Resolve (ec);                                     
 
                                        data [i] = new ExpressionEmitter (converted, vi);
                                        i++;
@@ -4118,9 +4267,15 @@ namespace Mono.CSharp {
                        Fixed target = (Fixed) t;
 
                        target.type = type.Clone (clonectx);
-                       target.declarators = new ArrayList ();
-                       foreach (LocalInfo var in declarators)
-                               target.declarators.Add (clonectx.LookupVariable (var));
+                       target.declarators = new ArrayList (declarators.Count);
+                       foreach (Pair p in declarators) {
+                               LocalInfo vi = (LocalInfo) p.First;
+                               Expression e = (Expression) p.Second;
+
+                               target.declarators.Add (
+                                       new Pair (clonectx.LookupVariable (vi), e.Clone (clonectx)));                           
+                       }
+                       
                        target.statement = statement.Clone (clonectx);
                }
        }
@@ -4196,7 +4351,7 @@ namespace Mono.CSharp {
 
                                        type = te.Type;
 
-                                       if (type != TypeManager.exception_type && !type.IsSubclassOf (TypeManager.exception_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");
                                                return false;
                                        }
@@ -4219,8 +4374,10 @@ namespace Mono.CSharp {
                {
                        Catch target = (Catch) t;
 
-                       target.type_expr = type_expr.Clone (clonectx);
-                       target.VarBlock = clonectx.LookupBlock (VarBlock);                      
+                       if (type_expr != null)
+                               target.type_expr = type_expr.Clone (clonectx);
+                       if (VarBlock != null)
+                               target.VarBlock = clonectx.LookupBlock (VarBlock);                      
                        target.Block = clonectx.LookupBlock (Block);
                }
        }
@@ -4263,7 +4420,7 @@ namespace Mono.CSharp {
 
                        Report.Debug (1, "START OF CATCH BLOCKS", vector);
 
-                       Type[] prevCatches = new Type [Specific.Count];
+                       Type[] prev_catches = new Type [Specific.Count];
                        int last_index = 0;
                        foreach (Catch c in Specific){
                                ec.CurrentBranching.CreateSibling (
@@ -4282,15 +4439,15 @@ namespace Mono.CSharp {
                                if (!c.Resolve (ec))
                                        return false;
 
-                               Type resolvedType = c.CatchType;
+                               Type resolved_type = c.CatchType;
                                for (int ii = 0; ii < last_index; ++ii) {
-                                       if (resolvedType == prevCatches [ii] || resolvedType.IsSubclassOf (prevCatches [ii])) {
-                                               Report.Error (160, c.loc, "A previous catch clause already catches all exceptions of this or a super type `{0}'", prevCatches [ii].FullName);
+                                       if (resolved_type == prev_catches [ii] || TypeManager.IsSubclassOf (resolved_type, prev_catches [ii])) {
+                                               Report.Error (160, c.loc, "A previous catch clause already catches all exceptions of this or a super type `{0}'", prev_catches [ii].FullName);
                                                return false;
                                        }
                                }
 
-                               prevCatches [last_index++] = resolvedType;
+                               prev_catches [last_index++] = resolved_type;
                                need_exc_block = true;
                        }
 
@@ -4656,6 +4813,11 @@ namespace Mono.CSharp {
                        // So, ensure there's some IL code after the finally block.
                        ec.NeedReturnLabel ();
 
+                       if (TypeManager.void_dispose_void == null) {
+                               TypeManager.void_dispose_void = TypeManager.GetPredefinedMethod (
+                                       TypeManager.idisposable_type, "Dispose", loc, Type.EmptyTypes);
+                       }
+
                        return ok;
                }
                
@@ -4679,10 +4841,22 @@ namespace Mono.CSharp {
                {
                        Using target = (Using) t;
 
-                       if (expression_or_block is Expression)
+                       if (expression_or_block is Expression) {
                                target.expression_or_block = ((Expression) expression_or_block).Clone (clonectx);
-                       else
-                               target.expression_or_block = ((Statement) expression_or_block).Clone (clonectx);
+                       } else {
+                               DictionaryEntry de = (DictionaryEntry) expression_or_block;
+                               ArrayList var_list = (ArrayList) de.Value;
+                               ArrayList target_var_list = new ArrayList (var_list.Count);
+
+                               foreach (DictionaryEntry de_variable in var_list)
+                                       target_var_list.Add (new DictionaryEntry (
+                                               ((Expression) de_variable.Key).Clone (clonectx),
+                                               ((Expression) de_variable.Value).Clone (clonectx)));
+
+                               target.expression_or_block = new DictionaryEntry (
+                                       ((Expression) de.Key).Clone (clonectx),
+                                       target_var_list);
+                       }
                        
                        target.Statement = Statement.Clone (clonectx);
                }
@@ -4719,7 +4893,7 @@ namespace Mono.CSharp {
                        if (expr == null)
                                return false;
 
-                       if (expr.Type == TypeManager.null_type) {
+                       if (expr.IsNull) {
                                Report.Error (186, loc, "Use of null is not valid in this context");
                                return false;
                        }
@@ -4983,6 +5157,16 @@ namespace Mono.CSharp {
                                        // way I could do this without a goto
                                        //
 
+                                       if (TypeManager.bool_movenext_void == null) {
+                                               TypeManager.bool_movenext_void = TypeManager.GetPredefinedMethod (
+                                                       TypeManager.ienumerator_type, "MoveNext", loc, Type.EmptyTypes);
+                                       }
+
+                                       if (TypeManager.ienumerator_getcurrent == null) {
+                                               TypeManager.ienumerator_getcurrent = TypeManager.GetPredefinedProperty (
+                                                       TypeManager.ienumerator_type, "Current", loc, TypeManager.object_type);
+                                       }
+
 #if GMCS_SOURCE
                                        //
                                        // Prefer a generic enumerator over a non-generic one.
@@ -5186,7 +5370,7 @@ namespace Mono.CSharp {
                                        get_current = tmp_get_cur;
                                        enumerator_type = tmp_enumerator_type;
                                        MethodInfo[] mi = new MethodInfo[] { (MethodInfo) result };
-                                       get_enumerator = new MethodGroupExpr (mi, loc);
+                                       get_enumerator = new MethodGroupExpr (mi, enumerator_type, loc);
 
                                        if (t != expr.Type) {
                                                expr = Convert.ExplicitConversion (
@@ -5259,7 +5443,7 @@ namespace Mono.CSharp {
                                Expression move_next_expr;
                                {
                                        MemberInfo[] mi = new MemberInfo[] { move_next };
-                                       MethodGroupExpr mg = new MethodGroupExpr (mi, loc);
+                                       MethodGroupExpr mg = new MethodGroupExpr (mi, var_type.Type, loc);
                                        mg.InstanceExpression = enumerator;
 
                                        move_next_expr = new Invocation (mg, null);
@@ -5284,6 +5468,11 @@ namespace Mono.CSharp {
                                if (is_disposable) {
                                        ResolveFinally (branching);
                                        ec.EndFlowBranching ();
+
+                                       if (TypeManager.void_dispose_void == null) {
+                                               TypeManager.void_dispose_void = TypeManager.GetPredefinedMethod (
+                                                       TypeManager.idisposable_type, "Dispose", loc, Type.EmptyTypes);
+                                       }
                                } else
                                        emit_finally = true;