2006-08-13 Miguel de Icaza <miguel@novell.com>
[mono.git] / mcs / mbas / statement.cs
index 35cf58dcc530570e310a6c7043b3a6f41eaa38fb..0914861a26983cae60906917d5bd93e3f00365eb 100644 (file)
@@ -812,6 +812,7 @@ namespace Mono.MonoBASIC {
                
                public Return (Expression expr, Location l)
                {
+                       expr = Parser.SetValueRequiredFlag (expr);
                        Expr = expr;
                        loc = l;
                }
@@ -829,8 +830,10 @@ namespace Mono.MonoBASIC {
                        if (ec.CurrentBranching.InTryBlock ())
                                ec.CurrentBranching.AddFinallyVector (vector);
 
-                       vector.Returns = FlowReturns.ALWAYS;
-                       vector.Breaks = FlowReturns.ALWAYS;
+                       if (! ec.InTry && ! ec.InCatch) {
+                               vector.Returns = FlowReturns.ALWAYS;
+                               vector.Breaks = FlowReturns.ALWAYS;
+                       }
                        return true;
                }
                
@@ -932,7 +935,7 @@ namespace Mono.MonoBASIC {
 
        public class LabeledStatement : Statement {
                public readonly Location Location;
-               //string label_name;
+               string label_name;
                bool defined;
                bool referenced;
                Label label;
@@ -941,9 +944,15 @@ namespace Mono.MonoBASIC {
                
                public LabeledStatement (string label_name, Location l)
                {
-                       //this.label_name = label_name;
+                       this.label_name = label_name;
                        this.Location = l;
                }
+               
+               public string LabelName {
+                       get {
+                               return label_name;
+                       }
+               }
 
                public Label LabelTarget (EmitContext ec)
                {
@@ -1280,11 +1289,8 @@ namespace Mono.MonoBASIC {
                                }
                        
                                if (ec.InTry || ec.InCatch) {
-                                       if (!ec.HasReturnLabel) {
-                                               ec.ReturnLabel = ec.ig.DefineLabel ();
-                                               ec.HasReturnLabel = true;
-                                       }
-                                       ec.ig.Emit (OpCodes.Leave, ec.ReturnLabel);
+                                       if (ec.HasExitLabel)
+                                               ec.ig.Emit (OpCodes.Leave, ec.ExitLabel);
                                } else {
                                        if(type == ExitType.SUB) {   
                                                 ec.ig.Emit (OpCodes.Ret);
@@ -2672,16 +2678,24 @@ namespace Mono.MonoBASIC {
                public Expression Type;
                public LocalBuilder LocalBuilder;
                public Type VariableType;
+               public string Alias;
+               FieldBase FieldAlias;
                public readonly string Name;
                public readonly Location Location;
                public readonly int Block;
-
+               
                public int Number;
                
                public bool Used;
                public bool Assigned;
                public bool ReadOnly;
                
+               public VariableInfo (Expression type, string name, int block, Location l, string Alias)
+                       : this (type, name, block, l)
+               {
+                       this.Alias = Alias;
+               }
+               
                public VariableInfo (Expression type, string name, int block, Location l)
                {
                        Type = type;
@@ -2691,6 +2705,12 @@ namespace Mono.MonoBASIC {
                        Location = l;
                }
 
+               public VariableInfo (TypeContainer tc, int block, Location l, string Alias)
+                       : this (tc, block, l)
+               {
+                       this.Alias = Alias;
+               }
+               
                public VariableInfo (TypeContainer tc, int block, Location l)
                {
                        VariableType = tc.TypeBuilder;
@@ -2739,865 +2759,88 @@ namespace Mono.MonoBASIC {
                                        return false;
                                }
                        }
-*/
-                       return true;
-               }
-
-               public bool IsFieldAssigned (EmitContext ec, string name, Location loc)
-               {
-                       if (!ec.DoFlowAnalysis || ec.CurrentBranching.IsVariableAssigned (this) ||
-                           (struct_info == null))
-                               return true;
-
-                       int field_idx = StructInfo [name];
-                       if (field_idx == 0)
-                               return true;
-
-                       if (!ec.CurrentBranching.IsVariableAssigned (this, field_idx)) {
-                               Report.Error (170, loc,
-                                             "Use of possibly unassigned field '" + name + "'");
-                               ec.CurrentBranching.SetVariableAssigned (this, field_idx);
-                               return false;
-                       }
-
-                       return true;
-               }
-
-               public void SetAssigned (EmitContext ec)
-               {
-                       if (ec.DoFlowAnalysis)
-                               ec.CurrentBranching.SetVariableAssigned (this);
-               }
-
-               public void SetFieldAssigned (EmitContext ec, string name)
-               {
-                       if (ec.DoFlowAnalysis && (struct_info != null))
-                               ec.CurrentBranching.SetVariableAssigned (this, StructInfo [name]);
-               }
-
-               public bool Resolve (DeclSpace decl)
-               {
-                       if (struct_info != null)
-                               return true;
-
-                       if (VariableType == null)
-                               VariableType = decl.ResolveType (Type, false, Location);
-
-                       if (VariableType == null)
-                               return false;
-
-                       struct_info = MyStructInfo.GetStructInfo (VariableType);
-
-                       return true;
-               }
-
-               public void MakePinned ()
-               {
-                       TypeManager.MakePinned (LocalBuilder);
-               }
-
-               public override string ToString ()
-               {
-                       return "VariableInfo (" + Number + "," + Type + "," + Location + ")";
-               }
-       }
-               
-       /// <summary>
-       ///   Block represents a C# block.
-       /// </summary>
-       ///
-       /// <remarks>
-       ///   This class is used in a number of places: either to represent
-       ///   explicit blocks that the programmer places or implicit blocks.
-       ///
-       ///   Implicit blocks are used as labels or to introduce variable
-       ///   declarations.
-       /// </remarks>
-       public class Block : Statement {
-               public readonly Block     Parent;
-               public readonly bool      Implicit;
-               public readonly Location  StartLocation;
-               public Location           EndLocation;
-
-               //
-               // The statements in this block
-               //
-               public ArrayList statements;
-
-               //
-               // An array of Blocks.  We keep track of children just
-               // to generate the local variable declarations.
-               //
-               // Statements and child statements are handled through the
-               // statements.
-               //
-               ArrayList children;
-               
-               //
-               // Labels.  (label, block) pairs.
-               //
-               CaseInsensitiveHashtable labels;
-
-               //
-               // Keeps track of (name, type) pairs
-               //
-               CaseInsensitiveHashtable variables;
-
-               //
-               // Keeps track of constants
-               CaseInsensitiveHashtable constants;
-
-               //
-               // Maps variable names to ILGenerator.LocalBuilders
-               //
-               //CaseInsensitiveHashtable local_builders;
-
-               // to hold names of variables required for late binding
-               public const string lateBindingArgs = "1_LBArgs";
-               public const string lateBindingArgNames = "1_LBArgsNames";
-               public const string lateBindingCopyBack = "1_LBCopyBack";
-
-               bool isLateBindingRequired = false;
-
-               bool used = false;
-
-               static int id;
-
-               int this_id;
-               
-               public Block (Block parent)
-                       : this (parent, false, Location.Null, Location.Null)
-               { }
-
-               public Block (Block parent, bool implicit_block)
-                       : this (parent, implicit_block, Location.Null, Location.Null)
-               { }
-
-               public Block (Block parent, bool implicit_block, Parameters parameters)
-                       : this (parent, implicit_block, parameters, Location.Null, Location.Null)
-               { }
-
-               public Block (Block parent, Location start, Location end)
-                       : this (parent, false, start, end)
-               { }
-
-               public Block (Block parent, Parameters parameters, Location start, Location end)
-                       : this (parent, false, parameters, start, end)
-               { }
-
-               public Block (Block parent, bool implicit_block, Location start, Location end)
-                       : this (parent, implicit_block, Parameters.EmptyReadOnlyParameters,
-                               start, end)
-               { }
-
-               public Block (Block parent, bool implicit_block, Parameters parameters,
-                             Location start, Location end)
-               {
-                       if (parent != null)
-                               parent.AddChild (this);
-                       else {
-                               // Top block
-                               // Add variables that may be required for late binding
-                               variables = new CaseInsensitiveHashtable ();
-                               ArrayList rank_specifier = new ArrayList ();
-                               ArrayList element = new ArrayList ();
-                               element.Add (new EmptyExpression ());
-                               rank_specifier.Add (element);
-                               Expression e = Mono.MonoBASIC.Parser.DecomposeQI ("System.Object[]", start);
-                               AddVariable (e, Block.lateBindingArgs, null, start);
-                               e = Mono.MonoBASIC.Parser.DecomposeQI ("System.String[]", start);
-                               AddVariable (e, Block.lateBindingArgNames, null, start);
-                               e = Mono.MonoBASIC.Parser.DecomposeQI ("System.Boolean[]", start);
-                               AddVariable (e, Block.lateBindingCopyBack, null, start);
-                       }
-                       
-                       this.Parent = parent;
-                       this.Implicit = implicit_block;
-                       this.parameters = parameters;
-                       this.StartLocation = start;
-                       this.EndLocation = end;
-                       this.loc = start;
-                       this_id = id++;
-                       statements = new ArrayList ();
-               }
-
-               public bool IsLateBindingRequired {
-                       get {
-                               return isLateBindingRequired;
-                       }
-                       set {
-                               isLateBindingRequired = value;
-                       }
-               }
-
-               public int ID {
-                       get {
-                               return this_id;
-                       }
-               }
-
-               void AddChild (Block b)
-               {
-                       if (children == null)
-                               children = new ArrayList ();
-                       
-                       children.Add (b);
-               }
-
-               public void SetEndLocation (Location loc)
-               {
-                       EndLocation = loc;
-               }
-
-               /// <summary>
-               ///   Adds a label to the current block. 
-               /// </summary>
-               ///
-               /// <returns>
-               ///   false if the name already exists in this block. true
-               ///   otherwise.
-               /// </returns>
-               ///
-/**
-               public bool AddLabel (string name, LabeledStatement target)
-               {
-                       if (labels == null)
-                               labels = new CaseInsensitiveHashtable ();
-                       if (labels.Contains (name))
-                               return false;
-                       
-                       labels.Add (name, target);
-                       return true;
-               }
-**/
-
-
-                public bool AddLabel (string name, LabeledStatement target, Location loc)
-                {
-/**
-                        if (switch_block != null)
-                                return switch_block.AddLabel (name, target, loc);
-**/
-                        Block cur = this;
-                        while (cur != null) {
-
-                                if (cur.DoLookupLabel (name) != null) {
-                                        Report.Error (
-                                                140, loc, "The label '" + name +"' is a duplicate");
-                                        return false;
-                                }
-
-                                if (!Implicit)
-                                        break;
-
-                                cur = cur.Parent;
-                        }
-
-                        while (cur != null) {
-                                if (cur.DoLookupLabel (name) != null) {
-                                        Report.Error (
-                                                158, loc,
-                                                "The label '"+ name +"' shadows another label " +
-                                                "by the same name in a containing scope.");
-                                        return false;
-                                }
-
-                                if (children != null) {
-                                        foreach (Block b in children) {
-                                                LabeledStatement s = b.DoLookupLabel (name);
-                                                if (s == null)
-                                                        continue;
-                                                Report.Error (
-                                                        158, s.Location,
-                                                        "The label '"+ name +"' shadows another " +
-                                                        "label by the same name in a " +
-                                                        "containing scope.");
-                                                return false;
-                                        }
-                                }
-                               cur = cur.Parent;
-                        }
-                        if (labels == null)
-                                labels = new CaseInsensitiveHashtable ();
-                        if (labels.Contains (name))
-                                return false;
-
-                        labels.Add (name, target);
-                        return true;
-
-                }
-               
-               public LabeledStatement LookupLabel (string name)
-                {
-                       Block cur = this;
-                        LabeledStatement s = DoLookupLabel (name);
-                        if (s != null) {
-                                return s;
-}
-                        if (children == null)
-                                return null;
-
-                        foreach (Block child in children) {
-                                if (!child.Implicit)
-                                        continue;
-
-                                s = child.LookupLabel (name);
-                                if (s != null) {
-                               cur = child;
-                                        return s;
-}
-                        }
-
-                        return null;
-                }
-
-               public LabeledStatement DoLookupLabel (string name)
-               {
-                       if (labels != null){
-                               if (labels.Contains (name))
-                                       return ((LabeledStatement) labels [name]);
-                       }
-/**
-                       if (Parent != null)
-                               return Parent.LookupLabel (name);
-**/
-                       return null;
-               }
-
-               VariableInfo this_variable = null;
-
-               // <summary>
-               //   Returns the "this" instance variable of this block.
-               //   See AddThisVariable() for more information.
-               // </summary>
-               public VariableInfo ThisVariable {
-                       get {
-                               if (this_variable != null)
-                                       return this_variable;
-                               else if (Parent != null)
-                                       return Parent.ThisVariable;
-                               else
-                                       return null;
-                       }
-               }
-
-               Hashtable child_variable_names;
-
-               // <summary>
-               //   Marks a variable with name @name as being used in a child block.
-               //   If a variable name has been used in a child block, it's illegal to
-               //   declare a variable with the same name in the current block.
-               // </summary>
-               public void AddChildVariableName (string name)
-               {
-                       if (child_variable_names == null)
-                               child_variable_names = new CaseInsensitiveHashtable ();
-
-                       if (!child_variable_names.Contains (name))
-                               child_variable_names.Add (name, true);
-               }
-
-               // <summary>
-               //   Marks all variables from block @block and all its children as being
-               //   used in a child block.
-               // </summary>
-               public void AddChildVariableNames (Block block)
-               {
-                       if (block.Variables != null) {
-                               foreach (string name in block.Variables.Keys)
-                                       AddChildVariableName (name);
-                       }
-
-                       foreach (Block child in block.children) {
-                               if (child.Variables != null) {
-                                       foreach (string name in child.Variables.Keys)
-                                               AddChildVariableName (name);
-                               }
-                       }
-               }
-
-               // <summary>
-               //   Checks whether a variable name has already been used in a child block.
-               // </summary>
-               public bool IsVariableNameUsedInChildBlock (string name)
-               {
-                       if (child_variable_names == null)
-                               return false;
-
-                       return child_variable_names.Contains (name);
-               }
-
-               // <summary>
-               //   This is used by non-static 'struct' constructors which do not have an
-               //   initializer - in this case, the constructor must initialize all of the
-               //   struct's fields.  To do this, we add a "this" variable and use the flow
-               //   analysis code to ensure that it's been fully initialized before control
-               //   leaves the constructor.
-               // </summary>
-               public VariableInfo AddThisVariable (TypeContainer tc, Location l)
-               {
-                       if (this_variable != null)
-                               return this_variable;
-
-                       this_variable = new VariableInfo (tc, ID, l);
-
-                       if (variables == null)
-                               variables = new CaseInsensitiveHashtable ();
-                       variables.Add ("this", this_variable);
-
-                       return this_variable;
-               }
-
-               public VariableInfo AddVariable (EmitContext ec, Expression type, string name, Location l)
-               {
-                       if (!variables_initialized)
-                               throw new InvalidOperationException();
-                               
-                       VariableInfo vi = AddVariable(type, name, null, loc);
-
-                       int priorCount = count_variables;
-                       DeclSpace ds = ec.DeclSpace;
-
-                       if (!vi.Resolve (ds)) {
-                               vi.Number = -1;
-                       } else {
-                               vi.Number = ++count_variables;
-                               if (vi.StructInfo != null)
-                                       count_variables += vi.StructInfo.Count;
-                       }
-                       if (priorCount < count_variables)
-                               ec.CurrentBranching.CurrentUsageVector.AddExtraLocals(count_variables - priorCount);
-                               
-                       return vi;
-               }
-               
-               public VariableInfo AddVariable (Expression type, string name, Parameters pars, Location l)
-               {
-                       if (variables == null)
-                               variables = new CaseInsensitiveHashtable ();
-
-                       VariableInfo vi = GetVariableInfo (name);
-                       if (vi != null) {
-                               if (vi.Block != ID)
-                                       Report.Error (30616, l, "A local variable named '" + name + "' " +
-                                                     "cannot be declared in this scope since it would " +
-                                                     "give a different meaning to '" + name + "', which " +
-                                                     "is already used in a 'parent or current' scope to " +
-                                                     "denote something else");
-                               else
-                                       Report.Error (30290, l, "A local variable '" + name + "' is already " +
-                                                     "defined in this scope");
-                               return null;
-                       }
-
-                       if (IsVariableNameUsedInChildBlock (name)) {
-                               Report.Error (136, l, "A local variable named '" + name + "' " +
-                                             "cannot be declared in this scope since it would " +
-                                             "give a different meaning to '" + name + "', which " +
-                                             "is already used in a 'child' scope to denote something " +
-                                             "else");
-                               return null;
-                       }
-
-                       if (pars != null) {
-                               int idx = 0;
-                               Parameter p = pars.GetParameterByName (name, out idx);
-                               if (p != null) {
-                                       Report.Error (30616, l, "A local variable named '" + name + "' " +
-                                                     "cannot be declared in this scope since it would " +
-                                                     "give a different meaning to '" + name + "', which " +
-                                                     "is already used in a 'parent or current' scope to " +
-                                                     "denote something else");
-                                       return null;
-                               }
-                       }
-                       
-                       vi = new VariableInfo (type, name, ID, l);
-
-                       variables.Add (name, vi);
-
-                       return vi;
-               }
-
-               public bool AddConstant (Expression type, string name, Expression value, Parameters pars, Location l)
-               {
-                       if (AddVariable (type, name, pars, l) == null)
-                               return false;
-                       
-                       if (constants == null)
-                               constants = new CaseInsensitiveHashtable ();
-
-                       constants.Add (name, value);
-                       return true;
-               }
-
-               public Hashtable Variables {
-                       get {
-                               return variables;
-                       }
-               }
-
-               public VariableInfo GetVariableInfo (string name)
-               {
-                       if (variables != null) {
-                               object temp;
-                               temp = variables [name];
-
-                               if (temp != null){
-                                       return (VariableInfo) temp;
-                               }
-                       }
-
-                       if (Parent != null)
-                               return Parent.GetVariableInfo (name);
-
-                       return null;
-               }
-               
-               public Expression GetVariableType (string name)
-               {
-                       VariableInfo vi = GetVariableInfo (name);
-
-                       if (vi != null)
-                               return vi.Type;
-
-                       return null;
-               }
-
-               public Expression GetConstantExpression (string name)
-               {
-                       if (constants != null) {
-                               object temp;
-                               temp = constants [name];
-                               
-                               if (temp != null)
-                                       return (Expression) temp;
-                       }
-                       
-                       if (Parent != null)
-                               return Parent.GetConstantExpression (name);
-
-                       return null;
-               }
-               
-               /// <summary>
-               ///   True if the variable named @name has been defined
-               ///   in this block
-               /// </summary>
-               public bool IsVariableDefined (string name)
-               {
-                       // Console.WriteLine ("Looking up {0} in {1}", name, ID);
-                       if (variables != null) {
-                               if (variables.Contains (name))
-                                       return true;
-                       }
-                       
-                       if (Parent != null)
-                               return Parent.IsVariableDefined (name);
-
-                       return false;
-               }
-
-               /// <summary>
-               ///   True if the variable named @name is a constant
-               ///  </summary>
-               public bool IsConstant (string name)
-               {
-                       Expression e = null;
-                       
-                       e = GetConstantExpression (name);
-                       
-                       return e != null;
-               }
-               
-               /// <summary>
-               ///   Use to fetch the statement associated with this label
-               /// </summary>
-               public Statement this [string name] {
-                       get {
-                               return (Statement) labels [name];
-                       }
-               }
-
-               Parameters parameters = null;
-               public Parameters Parameters {
-                       get {
-                               if (Parent != null)
-                                       return Parent.Parameters;
-
-                               return parameters;
-                       }
-               }
-
-               /// <returns>
-               ///   A list of labels that were not used within this block
-               /// </returns>
-               public string [] GetUnreferenced ()
-               {
-                       // FIXME: Implement me
-                       return null;
-               }
-
-               public void AddStatement (Statement s)
-               {
-                       statements.Add (s);
-                       used = true;
-               }
-
-               public bool Used {
-                       get {
-                               return used;
-                       }
-               }
-
-               public void Use ()
-               {
-                       used = true;
-               }
-
-               bool variables_initialized = false;
-               int count_variables = 0, first_variable = 0;
-
-               void UpdateVariableInfo (EmitContext ec)
-               {
-                       DeclSpace ds = ec.DeclSpace;
-
-                       first_variable = 0;
-
-                       if (Parent != null)
-                               first_variable += Parent.CountVariables;
-
-                       count_variables = first_variable;
-                       if (variables != null) {
-                               foreach (VariableInfo vi in variables.Values) {
-                                       if (!vi.Resolve (ds)) {
-                                               vi.Number = -1;
-                                               continue;
-                                       }
-
-                                       vi.Number = ++count_variables;
-
-                                       if (vi.StructInfo != null)
-                                               count_variables += vi.StructInfo.Count;
-                               }
-                       }
-
-                       variables_initialized = true;
-               }
-
-               //
-               // <returns>
-               //   The number of local variables in this block
-               // </returns>
-               public int CountVariables
-               {
-                       get {
-                               if (!variables_initialized)
-                                       throw new Exception ();
-
-                               return count_variables;
-                       }
-               }
-
-               /// <summary>
-               ///   Emits the variable declarations and labels.
-               /// </summary>
-               /// <remarks>
-               ///   tc: is our typecontainer (to resolve type references)
-               ///   ig: is the code generator:
-               ///   toplevel: the toplevel block.  This is used for checking 
-               ///             that no two labels with the same name are used.
-               /// </remarks>
-               public void EmitMeta (EmitContext ec, Block toplevel)
-               {
-                       //DeclSpace ds = ec.DeclSpace;
-                       ILGenerator ig = ec.ig;
-
-                       if (!variables_initialized)
-                               UpdateVariableInfo (ec);
-
-                       //
-                       // Process this block variables
-                       //
-                       if (variables != null){
-                               //local_builders = new CaseInsensitiveHashtable ();
-                               
-                               foreach (DictionaryEntry de in variables){
-                                       string name = (string) de.Key;
-                                       /*
-                                       if (!isLateBindingRequired) {
-                                               if (name.Equals (Block.lateBindingArgs) || 
-                                                   name.Equals (Block.lateBindingArgNames) ||
-                                                   name.Equals (Block.lateBindingCopyBack))
-                                                       continue;
-                                       }
-                                       */
-                                       VariableInfo vi = (VariableInfo) de.Value;
-
-                                       if (vi.VariableType == null)
-                                               continue;
-
-                                       vi.LocalBuilder = ig.DeclareLocal (vi.VariableType);
-
-                                       if (CodeGen.SymbolWriter != null)
-                                               vi.LocalBuilder.SetLocalSymInfo (name);
-
-                                       if (constants == null)
-                                               continue;
-
-                                       Expression cv = (Expression) constants [name];
-                                       if (cv == null)
-                                               continue;
-
-                                       Expression e = cv.Resolve (ec);
-                                       if (e == null)
-                                               continue;
-
-                                       if (!(e is Constant)){
-                                               Report.Error (133, vi.Location,
-                                                             "The expression being assigned to '" +
-                                                             name + "' must be constant (" + e + ")");
-                                               continue;
-                                       }
-
-                                       constants.Remove (name);
-                                       constants.Add (name, e);
-                               }
-                       }
-
-                       //
-                       // Now, handle the children
-                       //
-                       if (children != null){
-                               foreach (Block b in children)
-                                       b.EmitMeta (ec, toplevel);
-                       }
-               }
-
-               public void UsageWarning ()
-               {
-                       string name;
-                       
-                       if (variables != null){
-                               foreach (DictionaryEntry de in variables){
-                                       VariableInfo vi = (VariableInfo) de.Value;
-                                       
-                                       if (vi.Used)
-                                               continue;
-                                       
-                                       name = (string) de.Key;
-                                               
-                                       if (vi.Assigned){
-                                               Report.Warning (
-                                                       219, vi.Location, "The variable '" + name +
-                                                       "' is assigned but its value is never used");
-                                       } else {
-                                               if (!(name.Equals(lateBindingArgs)||name.Equals(lateBindingArgNames)||name.Equals(lateBindingCopyBack)))
-                                               Report.Warning (
-                                                       168, vi.Location, "The variable '" +
-                                                       name +"' is declared but never used");
-                                       } 
-                               }
-                       }
-
-                       if (children != null)
-                               foreach (Block b in children)
-                                       b.UsageWarning ();
+*/
+                       return true;
                }
 
-               bool has_ret = false;
-
-               public override bool Resolve (EmitContext ec)
+               public bool IsFieldAssigned (EmitContext ec, string name, Location loc)
                {
-                       Block prev_block = ec.CurrentBlock;
-                       bool ok = true;
+                       if (!ec.DoFlowAnalysis || ec.CurrentBranching.IsVariableAssigned (this) ||
+                           (struct_info == null))
+                               return true;
 
-                       ec.CurrentBlock = this;
+                       int field_idx = StructInfo [name];
+                       if (field_idx == 0)
+                               return true;
 
-                       if (!variables_initialized)
-                               UpdateVariableInfo (ec);
-                               
-                       ec.StartFlowBranching (this);
+                       if (!ec.CurrentBranching.IsVariableAssigned (this, field_idx)) {
+                               Report.Error (170, loc,
+                                             "Use of possibly unassigned field '" + name + "'");
+                               ec.CurrentBranching.SetVariableAssigned (this, field_idx);
+                               return false;
+                       }
 
-                       Report.Debug (1, "RESOLVE BLOCK", StartLocation, ec.CurrentBranching);
+                       return true;
+               }
 
-                       ArrayList new_statements = new ArrayList ();
-                       bool unreachable = false, warning_shown = false;
+               public void SetAssigned (EmitContext ec)
+               {
+                       if (ec.DoFlowAnalysis)
+                               ec.CurrentBranching.SetVariableAssigned (this);
+               }
 
-                       foreach (Statement s in statements){
+               public void SetFieldAssigned (EmitContext ec, string name)
+               {
+                       if (ec.DoFlowAnalysis && (struct_info != null))
+                               ec.CurrentBranching.SetVariableAssigned (this, StructInfo [name]);
+               }
 
-                               if (unreachable && !(s is LabeledStatement)) {
-                                       if (!warning_shown && !(s is EmptyStatement)) {
-                                               warning_shown = true;
-                                               Warning_DeadCodeFound (s.loc);
+               public FieldBase GetFieldAlias (EmitContext ec)  {
+                       if ( this.FieldAlias != null )
+                               return this.FieldAlias;
+                       else
+                       {
+                               ArrayList fields = ec.TypeContainer.Fields;
+                                for (int i = 0; i < fields.Count; i++) 
+                               {
+                                       if (((Field) fields[i]).Name == this.Alias) 
+                                       {
+                                               this.FieldAlias = (Field) fields[i];
+                                               break;
                                        }
-                                       continue;
-                               }
-
-                               if (s.Resolve (ec) == false) {
-                                       ok = false;
-                                       continue;
-                               }
-
-                               if (s is LabeledStatement)
-                                       unreachable = false;
-                               else
-                                       unreachable = ! ec.CurrentBranching.IsReachable ();
-
-                               new_statements.Add (s);
-                       }
-
-                       statements = new_statements;
-
-                       Report.Debug (1, "RESOLVE BLOCK DONE", StartLocation, ec.CurrentBranching);
-
-                       FlowReturns returns = ec.EndFlowBranching ();
-                       ec.CurrentBlock = prev_block;
+                               }
+                               return this.FieldAlias;
+                       }
+               }
+               
+               public bool Resolve (DeclSpace decl)
+               {
+                       if (struct_info != null)
+                               return true;
 
-                       // If we're a non-static 'struct' constructor which doesn't have an
-                       // initializer, then we must initialize all of the struct's fields.
-                       if ((this_variable != null) && (returns != FlowReturns.EXCEPTION) &&
-                           !this_variable.IsAssigned (ec, loc))
-                               ok = false;
+                       if (VariableType == null)
+                               VariableType = decl.ResolveType (Type, false, Location);
 
-                       if ((labels != null) && (RootContext.WarningLevel >= 2)) {
-                               foreach (LabeledStatement label in labels.Values)
-                                       if (!label.HasBeenReferenced)
-                                               Report.Warning (164, label.Location,
-                                                               "This label has not been referenced");
-                       }
+                       if (VariableType == null)
+                               return false;
 
-                       if ((returns == FlowReturns.ALWAYS) ||
-                           (returns == FlowReturns.EXCEPTION) ||
-                           (returns == FlowReturns.UNREACHABLE))
-                               has_ret = true;
+                       struct_info = MyStructInfo.GetStructInfo (VariableType);
 
-                       return ok;
+                       return true;
                }
-               
-               protected override bool DoEmit (EmitContext ec)
-               {
-                       Block prev_block = ec.CurrentBlock;
-
-                       ec.CurrentBlock = this;
 
-                       ec.Mark (StartLocation);
-                       foreach (Statement s in statements)
-                               s.Emit (ec);
-                               
-                       ec.Mark (EndLocation); 
-                       
-                       ec.CurrentBlock = prev_block;
-                       return has_ret;
+               public void MakePinned ()
+               {
+                       TypeManager.MakePinned (LocalBuilder);
                }
-               
-               public override string ToString ()
-                {
-                        return String.Format ("{0} ({1}:{2})", GetType (),ID, StartLocation);
-                }
 
+               public override string ToString ()
+               {
+                       return "VariableInfo (" + Number + "," + Type + "," + Location + ")";
+               }
        }
 
+               
        public class StatementSequence : Expression {
                Block stmtBlock;
                ArrayList args, originalArgs;
@@ -3607,6 +2850,7 @@ namespace Mono.MonoBASIC {
                bool isIndexerAccess;
                string memberName;
                Expression type_expr;
+               bool is_resolved = false;
 
                public StatementSequence (Block parent, Location loc, Expression expr) 
                        : this (parent, loc, expr, null)
@@ -3683,10 +2927,13 @@ namespace Mono.MonoBASIC {
                
                public override Expression DoResolve (EmitContext ec)
                {
+                       if (is_resolved)
+                               return this;
                        if (!stmtBlock.Resolve (ec))
                                return null;
                        eclass = ExprClass.Value;
                        type = TypeManager.object_type;
+                       is_resolved = true;
                        return this;
                }
 
@@ -5220,11 +4467,13 @@ namespace Mono.MonoBASIC {
                protected override bool DoEmit (EmitContext ec)
                {
                        ILGenerator ig = ec.ig;
-                       Label finish = ig.DefineLabel ();;
                        bool returns;
 
                        ec.TryCatchLevel++;
-                       ig.BeginExceptionBlock ();
+                       Label finish = ig.BeginExceptionBlock ();
+                       ec.HasExitLabel = true;
+                       ec.ExitLabel = finish;
+
                        bool old_in_try = ec.InTry;
                        ec.InTry = true;
                        returns = Block.Emit (ec);
@@ -5294,7 +4543,6 @@ namespace Mono.MonoBASIC {
 
                        ec.InCatch = old_in_catch;
 
-                       ig.MarkLabel (finish);
                        if (Fini != null){
                                ig.BeginFinallyBlock ();
                                bool old_in_finally = ec.InFinally;
@@ -5309,6 +4557,202 @@ namespace Mono.MonoBASIC {
                        if (!returns || ec.InTry || ec.InCatch)
                                return returns;
 
+                       return true;
+               }
+       }
+       
+       public  class Pending_Assign {
+               Statement assign;
+               Block block_to_be_inserted;
+               int statement_index;
+               
+               public Pending_Assign (Block block, Statement assign, int index)
+               {
+                       this.assign = assign;
+                       this.block_to_be_inserted = block;
+                       this.statement_index = index;
+               }
+
+               public  void AddAssign()
+               {
+                       block_to_be_inserted.statements.Insert( statement_index, assign );
+               }       
+       }
+       
+       public class On_Error : Statement {
+               public readonly Block method_block;
+               ArrayList targets;
+               LabeledStatement[] labeledstatements;
+               
+               public On_Error (Block method_block, Location l)
+               {       
+                       //Goto
+                       this.method_block = method_block;
+                       base.loc = l;
+                       targets = new ArrayList();
+               }
+
+               public int AddTarget ( string target )
+               {                               
+                       int i = targets.IndexOf( target ) ;
+                       
+                       if ( i == -1 ) 
+                               return targets.Add ( target );
+                       else
+                               return i;
+               }
+
+               public ArrayList Targets {
+                       get {
+                               return targets;
+                       }
+               }
+
+               public override bool Resolve (EmitContext ec)
+               {
+                       this.labeledstatements = new LabeledStatement[targets.Count];
+                       
+                       bool ok = true;
+                       
+                       ec.StartFlowBranching (FlowBranchingType.EXCEPTION, method_block.StartLocation);
+
+                       Report.Debug (1, "START OF TRY BLOCK", method_block.StartLocation);
+
+                       bool old_in_try = ec.InTry;
+                       ec.InTry = true;
+
+                       if (!method_block.Resolve (ec))
+                               ok = false;
+
+                       ec.InTry = old_in_try;
+
+                       FlowBranching.UsageVector vector = ec.CurrentBranching.CurrentUsageVector;
+
+                       ec.EndFlowBranching ();
+
+                       ec.CurrentBranching.CurrentUsageVector.Or (vector);
+
+                       Report.Debug (1, "END OF TRY", ec.CurrentBranching);
+
+                       //This statement has more than one label in cases of more than one 'on error goto' specification.
+                       for ( int i = 0 ; i < targets.Count ; i++ )
+                       {
+                               labeledstatements[i] = method_block.Parent.LookupLabel ((string) targets[i]);
+
+                               // If this is a forward goto.
+                               if (!labeledstatements[i].IsDefined)
+                                       labeledstatements[i].AddUsageVector (ec.CurrentBranching.CurrentUsageVector);
+
+                               labeledstatements[i].AddReference ();
+                       }
+                       ec.CurrentBranching.CurrentUsageVector.Breaks = FlowReturns.ALWAYS;
+                       
+                       return ok;
+               }
+               protected override bool DoEmit (EmitContext ec)
+               {       
+                       ILGenerator ig = ec.ig;
+                               
+                       //Try
+
+                       bool returns;
+
+                       ec.TryCatchLevel++;
+                       
+                       Label finish = ig.BeginExceptionBlock ();
+                               ec.HasExitLabel = true;
+                               ec.ExitLabel = finish;
+                               
+                               bool old_in_try = ec.InTry;
+                               ec.InTry = true;
+                               returns = method_block.Emit (ec);
+                               ec.InTry = old_in_try;
+                               bool old_in_catch = ec.InCatch;
+                               ec.InCatch = true;
+
+                       Label error = ig.DefineLabel();
+                       Label endfilter = ig.DefineLabel();
+                       Label verification = ig.DefineLabel();
+                       
+                       ig.BeginExceptFilterBlock();
+                               ig.Emit (OpCodes.Isinst, Type.GetType("System.Exception") );
+                               ig.Emit (OpCodes.Brtrue_S, verification );
+
+                               ig.Emit (OpCodes.Br_S, error);
+                       
+                               ig.MarkLabel ( verification );  
+                               ig.Emit (OpCodes.Ldloc_0);
+                               ig.Emit (OpCodes.Brfalse_S, error);
+                               
+                               ig.Emit (OpCodes.Ldloc_1);
+                               ig.Emit (OpCodes.Brtrue_S, error);
+
+                               ig.Emit (OpCodes.Ldc_I4_1);
+                               ig.Emit (OpCodes.Br_S, endfilter);
+                               
+                               ig.MarkLabel (error);   
+                               ig.Emit (OpCodes.Ldc_I4_0);
+
+                               ig.MarkLabel ( endfilter );     
+                       
+                       
+                       Label endcatch = ig.DefineLabel();              
+                       Label verification2 = ig.DefineLabel();
+                       
+                       ig.BeginCatchBlock (null);
+                               ig.Emit (OpCodes.Castclass, Type.GetType("System.Exception"));
+                               ig.Emit (OpCodes.Dup);
+
+                               Type t = typeof(Microsoft.VisualBasic.CompilerServices.ProjectData);
+                               MethodInfo mi = t.GetMethod("SetProjectError", new Type[] { typeof(System.Exception) } );
+                               ig.Emit (OpCodes.Call, mi);
+                               ig.Emit (OpCodes.Stloc_3);
+                               ig.Emit (OpCodes.Ldloc_1);
+                               ig.Emit (OpCodes.Brfalse_S, verification2 );
+                               ig.Emit (OpCodes.Leave_S, finish );
+                               ig.MarkLabel ( verification2 );
+                               ig.Emit (OpCodes.Ldc_I4_M1);
+                               ig.Emit (OpCodes.Stloc_1);
+                               ig.Emit (OpCodes.Ldloc_0);
+
+                               Label[] lbswitch = new Label[targets.Count + 1];
+                               for ( int i = 0; i <= targets.Count; i++ )
+                                       lbswitch[i] = ig.DefineLabel();
+                               
+                               ig.Emit (OpCodes.Switch, lbswitch);     
+                               ig.MarkLabel ( lbswitch[0] ) ;
+                               ig.Emit (OpCodes.Leave_S, endcatch);    
+                                                               
+                               Label[] labels = new Label[targets.Count];
+                               for ( int i = 0; i < targets.Count; i++ )
+                               {
+                                       labels[i] = labeledstatements[i].LabelTarget(ec);
+
+                                       ig.MarkLabel ( lbswitch[i+1] ) ;
+                                       ig.Emit ( OpCodes.Leave, labels[i] );
+                               }
+
+                               ig.MarkLabel ( endcatch );
+                               ig.Emit ( OpCodes.Rethrow );    
+
+                       ec.InCatch = old_in_catch;
+
+                       ig.EndExceptionBlock ();
+                       ec.TryCatchLevel--;
+
+                       Label end = ig.DefineLabel();
+                       //ig.MarkLabel ( finish ) ;
+                       ig.Emit (OpCodes.Ldloc_1);
+                       ig.Emit (OpCodes.Brfalse_S, end );
+                               
+                       mi = t.GetMethod("ClearProjectError");
+                       ig.Emit (OpCodes.Call, mi);
+
+                       ig.MarkLabel(end) ;
+                       
+                       if (!returns)
+                               return returns;
+
                        // Unfortunately, System.Reflection.Emit automatically emits a leave
                        // to the end of the finally block.  This is a problem if 'returns'
                        // is true since we may jump to a point after the end of the method.
@@ -5320,6 +4764,7 @@ namespace Mono.MonoBASIC {
 
                        return true;
                }
+               
        }
 
        public class Using : Statement {
@@ -5553,6 +4998,19 @@ namespace Mono.MonoBASIC {
                        if (expr == null)
                                return false;
 
+                       if ( variable.VariableInfo.Alias != null )
+                       {
+                               FieldBase fb = variable.VariableInfo.GetFieldAlias(ec);
+
+                               if ( fb == null )
+                               {
+                                       Report.Error (451, loc,"Name '" + variable.VariableInfo.Name  + "' is not declared.");
+                                       return false;
+                               }
+                               else
+                               type = fb.Type;
+                       }
+                                               
                        var_type = ec.DeclSpace.ResolveType (type, false, loc);
                        if (var_type == null)
                                return false;
@@ -5894,9 +5352,25 @@ namespace Mono.MonoBASIC {
                        ig.Emit (OpCodes.Ldloc, enumerator);
                        ig.Emit (OpCodes.Callvirt, hm.move_next);
                        ig.Emit (OpCodes.Brfalse, end_try);
+                       
+                       
+                       FieldBase fb = null;
+                       if ( variable.VariableInfo.Alias != null )
+                       {
+                               fb = variable.VariableInfo.GetFieldAlias(ec);
+                               
+                               if( (fb.ModFlags & Modifiers.STATIC) == 0 )
+                                       ig.Emit (OpCodes.Ldarg_0);
+                       }       
+                                       
                        ig.Emit (OpCodes.Ldloc, enumerator);
                        ig.Emit (OpCodes.Callvirt, hm.get_current);
-                       variable.EmitAssign (ec, conv);
+                       
+                       if ( fb == null)
+                               variable.EmitAssign (ec, conv);
+                       else
+                               variable.EmitAssign (ec, conv, fb);
+                       
                        statement.Emit (ec);
                        ig.Emit (OpCodes.Br, ec.LoopBegin);
                        ig.MarkLabel (end_try);
@@ -5964,11 +5438,23 @@ namespace Mono.MonoBASIC {
                                loop = ig.DefineLabel ();
                                ig.MarkLabel (loop);
 
+                               FieldBase fb = null;
+                               if ( variable.VariableInfo.Alias != null )
+                               {
+                                       fb = variable.VariableInfo.GetFieldAlias(ec);
+
+                                       if( (fb.ModFlags & Modifiers.STATIC) == 0 )
+                                               ig.Emit (OpCodes.Ldarg_0);
+                               }       
+                                       
                                ig.Emit (OpCodes.Ldloc, copy);
                                ig.Emit (OpCodes.Ldloc, counter);
                                ArrayAccess.EmitLoadOpcode (ig, var_type);
 
-                               variable.EmitAssign (ec, conv);
+                               if ( fb == null)
+                                       variable.EmitAssign (ec, conv);
+                               else
+                                       variable.EmitAssign (ec, conv, fb);
 
                                statement.Emit (ec);
 
@@ -6094,7 +5580,7 @@ namespace Mono.MonoBASIC {
                public AddHandler (Expression evt_id, Expression evt_handler, Location l)
                {
                        EvtId = evt_id;
-                       EvtHandler = evt_handler;
+                       EvtHandler = Parser.SetAddressOf (evt_handler);
                        loc = l;
                        resolved = false;
                        //Console.WriteLine ("Adding handler '" + evt_handler + "' for Event '" + evt_id +"'");
@@ -6176,7 +5662,7 @@ namespace Mono.MonoBASIC {
                public RemoveHandler (Expression evt_id, Expression evt_handler, Location l)
                {
                        EvtId = evt_id;
-                       EvtHandler = evt_handler;
+                       EvtHandler = Parser.SetAddressOf (evt_handler);
                        loc = l;
                }
 
@@ -6230,23 +5716,100 @@ namespace Mono.MonoBASIC {
        }
 
        public class RedimClause {
-               public Expression Expr;
-               public ArrayList NewIndexes;
+               private Expression RedimTarget;
+               private ArrayList NewIndexes;
+               private Expression AsType;
                
-               public RedimClause (Expression e, ArrayList args)
+               private LocalTemporary localTmp = null;
+               private Expression origRedimTarget = null;
+               private StatementExpression ReDimExpr;
+
+               public RedimClause (Expression e, ArrayList args, Expression e_as)
                {
-                       Expr = e;
+                       if (e is SimpleName)
+                               ((SimpleName) e).IsInvocation = false;
+                       if (e is MemberAccess)
+                               ((MemberAccess) e).IsInvocation = false;
+               
+                       RedimTarget = e;
+                       NewIndexes = args;
+                       AsType = e_as;
+               }
+
+               public bool Resolve (EmitContext ec, bool Preserve, Location loc)
+               {
+                       RedimTarget = RedimTarget.Resolve (ec);
+
+                       if (AsType != null) {
+                               Report.Error (30811, loc, "'ReDim' statements can no longer be used to declare array variables");
+                               return false;
+                       }
+                       
+                       if (!RedimTarget.Type.IsArray) {
+                               Report.Error (49, loc, "'ReDim' statement requires an array");
+                               return false;
+                       }
+
+                       ArrayList args = new ArrayList();
+                       foreach (Argument a in NewIndexes) {
+                               if (a.Resolve(ec, loc))
+                                       args.Add (a.Expr);
+                       }
+
+                       for (int x = 0; x < args.Count; x++) {
+                               args[x] = new Binary (Binary.Operator.Addition,
+                                                       (Expression) args[x], new IntLiteral (1), Location.Null);       
+                       }
+
                        NewIndexes = args;
+                       if (RedimTarget.Type.GetArrayRank() != NewIndexes.Count) {
+                               Report.Error (30415, loc, "'ReDim' cannot change the number of dimensions of an array.");
+                               return false;
+                       }
+                       
+                       Type BaseType = RedimTarget.Type.GetElementType();
+                       Expression BaseTypeExpr = MonoBASIC.Parser.DecomposeQI(BaseType.FullName.ToString(), Location.Null);
+                       ArrayCreation acExpr = new ArrayCreation (BaseTypeExpr, NewIndexes, "", null, Location.Null);   
+                       if (Preserve)
+                       {
+                               ExpressionStatement PreserveExpr = null;
+                               if (RedimTarget is PropertyGroupExpr) {
+                                       localTmp = new LocalTemporary (ec, RedimTarget.Type);
+                                       PropertyGroupExpr pe = RedimTarget as PropertyGroupExpr;
+                                       origRedimTarget = new PropertyGroupExpr (pe.Properties, pe.Arguments, pe.InstanceExpression, loc);
+                                       if ((origRedimTarget = origRedimTarget.Resolve (ec)) == null)  {
+                                               Report.Error (-1, loc, "'ReDim' vs PropertyGroup");
+                                               return false;
+                                       }
+                                       PreserveExpr = (ExpressionStatement) new Preserve(localTmp, acExpr, loc);
+                               } else
+                                       PreserveExpr = (ExpressionStatement) new Preserve(RedimTarget, acExpr, loc);
+                               ReDimExpr = (StatementExpression) new StatementExpression ((ExpressionStatement) new Assign (RedimTarget, PreserveExpr, loc), loc);
+                       }
+                       else
+                               ReDimExpr = (StatementExpression) new StatementExpression ((ExpressionStatement) new Assign (RedimTarget, acExpr, loc), loc);
+                       ReDimExpr.Resolve(ec);  
+                       return true;            
                }
+
+               public void DoEmit (EmitContext ec)
+               {
+                       if (ReDimExpr == null)
+                               return;
+                               
+                       if (localTmp != null && origRedimTarget != null) {
+                               origRedimTarget.Emit (ec);
+                               localTmp.Store (ec);
+                       }
+                       ReDimExpr.Emit(ec);
+               }               
+
        }
 
        public class ReDim : Statement {
                ArrayList RedimTargets;
-               Type BaseType;
                bool Preserve;
 
-               private StatementExpression ReDimExpr;
-
                public ReDim (ArrayList targets, bool opt_preserve, Location l)
                {
                        loc = l;
@@ -6256,51 +5819,16 @@ namespace Mono.MonoBASIC {
 
                public override bool Resolve (EmitContext ec)
                {
-                       Expression RedimTarget;
-                       ArrayList NewIndexes;
-
-                       foreach (RedimClause rc in RedimTargets) {
-                               RedimTarget = rc.Expr;
-                               NewIndexes = rc.NewIndexes;
-
-                               RedimTarget = RedimTarget.Resolve (ec);
-                               if (!RedimTarget.Type.IsArray)
-                                       Report.Error (49, "'ReDim' statement requires an array");
-
-                               ArrayList args = new ArrayList();
-                               foreach (Argument a in NewIndexes) {
-                                       if (a.Resolve(ec, loc))
-                                               args.Add (a.Expr);
-                               }
-
-                               for (int x = 0; x < args.Count; x++) {
-                                       args[x] = new Binary (Binary.Operator.Addition,
-                                                               (Expression) args[x], new IntLiteral (1), Location.Null);       
-                               }
-
-                               NewIndexes = args;
-                               if (RedimTarget.Type.GetArrayRank() != args.Count)
-                                       Report.Error (30415, "'ReDim' cannot change the number of dimensions of an array.");
-
-                               BaseType = RedimTarget.Type.GetElementType();
-                               Expression BaseTypeExpr = MonoBASIC.Parser.DecomposeQI(BaseType.FullName.ToString(), Location.Null);
-                               ArrayCreation acExpr = new ArrayCreation (BaseTypeExpr, NewIndexes, "", null, Location.Null);   
-                               // TODO: we are in a foreach we probably can't reuse ReDimExpr, must turn it into an array(list)
-                               if (Preserve)
-                               {
-                                       ExpressionStatement PreserveExpr = (ExpressionStatement) new Preserve(RedimTarget, acExpr, loc);
-                                       ReDimExpr = (StatementExpression) new StatementExpression ((ExpressionStatement) new Assign (RedimTarget, PreserveExpr, loc), loc);
-                               }
-                               else
-                                       ReDimExpr = (StatementExpression) new StatementExpression ((ExpressionStatement) new Assign (RedimTarget, acExpr, loc), loc);
-                               ReDimExpr.Resolve(ec);
-                       }
-                       return true;
+                       bool result = true;
+                       foreach (RedimClause rc in RedimTargets)
+                               result = rc.Resolve(ec, Preserve, loc) && result;
+                       return result;
                }
                                
                protected override bool DoEmit (EmitContext ec)
                {
-                       ReDimExpr.Emit(ec);
+                       foreach (RedimClause rc in RedimTargets)
+                               rc.DoEmit(ec);
                        return false;
                }