Fix the build
[mono.git] / mcs / mcs / codegen.cs
index 1411b756969016fafa8637f4f10e6796d6c982db..af6d336ad482c243e386e998a898f30e03de6a74 100644 (file)
@@ -7,7 +7,16 @@
 // (C) 2001, 2002, 2003 Ximian, Inc.
 // (C) 2004 Novell, Inc.
 //
+
+//
+// Please leave this defined on SVN: The idea is that when we ship the
+// compiler to end users, if the compiler crashes, they have a chance
+// to narrow down the problem.   
+//
+// Only remove it if you need to debug locally on your tree.
+//
 //#define PRODUCTION
+
 using System;
 using System.IO;
 using System.Collections;
@@ -86,7 +95,7 @@ namespace Mono.CSharp {
                        //
                        if (SymbolWriter == null) {
                                Report.Warning (
-                                       -18, "Could not find the symbol writer assembly (Mono.CompilerServices.SymbolWriter.dll). This is normally an installation problem. Please make sure to compile and install the mcs/class/Mono.CompilerServices.SymbolWriter directory.");
+                                       -18, 1, "Could not find the symbol writer assembly (Mono.CompilerServices.SymbolWriter.dll). This is normally an installation problem. Please make sure to compile and install the mcs/class/Mono.CompilerServices.SymbolWriter directory.");
                                return;
                        }
                }
@@ -104,11 +113,11 @@ namespace Mono.CSharp {
                        if (an.KeyPair != null) {
                                // If we are going to strong name our assembly make
                                // sure all its refs are strong named
-                               foreach (Assembly a in TypeManager.GetAssemblies ()) {
+                               foreach (Assembly a in RootNamespace.Global.Assemblies) {
                                        AssemblyName ref_name = a.GetName ();
                                        byte [] b = ref_name.GetPublicKeyToken ();
                                        if (b == null || b.Length == 0) {
-                                               Report.Warning (1577, "Assembly generation failed " +
+                                               Report.Error (1577, "Assembly generation failed " +
                                                                "-- Referenced assembly '" +
                                                                ref_name.Name +
                                                                "' does not have a strong name.");
@@ -140,6 +149,12 @@ namespace Mono.CSharp {
                                return false;
                        }
 
+#if GMCS_SOURCE
+                       // Get the complete AssemblyName from the builder
+                       // (We need to get the public key and token)
+                       Assembly.Name = Assembly.Builder.GetName ();
+#endif
+
                        //
                        // Pass a path-less name to DefineDynamicModule.  Wonder how
                        // this copes with output in different directories then.
@@ -161,6 +176,9 @@ namespace Mono.CSharp {
                {
                        try {
                                Assembly.Builder.Save (Basename (name));
+
+                               if (SymbolWriter != null)
+                                       SymbolWriter.WriteSymbolFile ();
                        }
                        catch (COMException) {
                                if ((RootContext.StrongNameKeyFile == null) || (!RootContext.StrongNameDelaySign))
@@ -177,40 +195,79 @@ namespace Mono.CSharp {
                        catch (System.UnauthorizedAccessException ua) {
                                Report.Error (16, "Could not write to file `"+name+"', cause: " + ua.Message);
                        }
-
-                       if (SymbolWriter != null)
-                               SymbolWriter.WriteSymbolFile ();
                }
        }
 
+
+       public interface IResolveContext
+       {
+               DeclSpace DeclContainer { get; }
+               bool IsInObsoleteScope { get; }
+               bool IsInUnsafeScope { get; }
+
+               // the declcontainer to lookup for type-parameters.  Should only use LookupGeneric on it.
+               //
+               // FIXME: This is somewhat of a hack.  We don't need a full DeclSpace for this.  We just need the
+               //        current type parameters in scope. IUIC, that will require us to rewrite GenericMethod.
+               //        Maybe we can replace this with a 'LookupGeneric (string)' instead, but we'll have to 
+               //        handle generic method overrides differently
+               DeclSpace GenericDeclContainer { get; }
+       }
+
        /// <summary>
        ///   An Emit Context is created for each body of code (from methods,
        ///   properties bodies, indexer bodies or constructor bodies)
        /// </summary>
-       public class EmitContext {
-               public readonly DeclSpace DeclSpace;
+       public class EmitContext : IResolveContext {
+
+               DeclSpace declSpace;
                public DeclSpace TypeContainer;
                public ILGenerator   ig;
 
-               /// <summary>
-               ///   This variable tracks the `checked' state of the compilation,
-               ///   it controls whether we should generate code that does overflow
-               ///   checking, or if we generate code that ignores overflows.
-               ///
-               ///   The default setting comes from the command line option to generate
-               ///   checked or unchecked code plus any source code changes using the
-               ///   checked/unchecked statements or expressions.   Contrast this with
-               ///   the ConstantCheckState flag.
-               /// </summary>
-               
-               public bool CheckState;
-
-               /// <summary>
-               ///   The constant check state is always set to `true' and cant be changed
-               ///   from the command line.  The source code can change this setting with
-               ///   the `checked' and `unchecked' statements and expressions. 
-               /// </summary>
-               public bool ConstantCheckState;
+               [Flags]
+               public enum Flags : byte {
+                       /// <summary>
+                       ///   This flag tracks the `checked' state of the compilation,
+                       ///   it controls whether we should generate code that does overflow
+                       ///   checking, or if we generate code that ignores overflows.
+                       ///
+                       ///   The default setting comes from the command line option to generate
+                       ///   checked or unchecked code plus any source code changes using the
+                       ///   checked/unchecked statements or expressions.   Contrast this with
+                       ///   the ConstantCheckState flag.
+                       /// </summary>
+                       CheckState = 1 << 0,
+
+                       /// <summary>
+                       ///   The constant check state is always set to `true' and cant be changed
+                       ///   from the command line.  The source code can change this setting with
+                       ///   the `checked' and `unchecked' statements and expressions. 
+                       /// </summary>
+                       ConstantCheckState = 1 << 1,
+
+                       AllCheckStateFlags = CheckState | ConstantCheckState,
+
+                       /// <summary>
+                       ///  Whether we are inside an unsafe block
+                       /// </summary>
+                       InUnsafe = 1 << 2,
+
+                       InCatch = 1 << 3,
+                       InFinally = 1 << 4,
+
+                       /// <summary>
+                       ///   Whether control flow analysis is enabled
+                       /// </summary>
+                       DoFlowAnalysis = 1 << 5,
+
+                       /// <summary>
+                       ///   Whether control flow analysis is disabled on structs
+                       ///   (only meaningful when DoFlowAnalysis is set)
+                       /// </summary>
+                       OmitStructFlowAnalysis = 1 << 6
+               }
+
+               Flags flags;
 
                /// <summary>
                ///   Whether we are emitting code inside a static or instance method
@@ -236,7 +293,7 @@ namespace Mono.CSharp {
                ///   The value that is allowed to be returned or NULL if there is no
                ///   return type.
                /// </summary>
-               public Type ReturnType;
+               public readonly Type ReturnType;
 
                /// <summary>
                ///   Points to the Type (extracted from the TypeContainer) that
@@ -249,11 +306,6 @@ namespace Mono.CSharp {
                /// </summary>
                public bool IsConstructor;
 
-               /// <summary>
-               ///   Whether we're control flow analysis enabled
-               /// </summary>
-               public bool DoFlowAnalysis;
-
                /// <summary>
                ///   Keeps track of the Type to LocalBuilder temporary storage created
                ///   to store structures (used to compute the address of the structure
@@ -288,21 +340,11 @@ namespace Mono.CSharp {
 
                public bool IsLastStatement;
 
-               /// <summary>
-               ///  Whether we are inside an unsafe block
-               /// </summary>
-               public bool InUnsafe;
-
                /// <summary>
                ///  Whether we are in a `fixed' initialization
                /// </summary>
                public bool InFixedInitializer;
 
-               public bool InRefOutArgumentResolving;
-
-               public bool InCatch;
-               public bool InFinally;
-
                /// <summary>
                ///  Whether we are inside an anonymous method.
                /// </summary>
@@ -323,23 +365,14 @@ namespace Mono.CSharp {
                /// </summary>
                public bool InEnumContext;
 
-               /// <summary>
-               ///   Anonymous methods can capture local variables and fields,
-               ///   this object tracks it.  It is copied from the TopLevelBlock
-               ///   field.
-               /// </summary>
-               public CaptureContext capture_context;
-
-               /// <summary>
-               /// Trace when method is called and is obsolete then this member suppress message
-               /// when call is inside next [Obsolete] method or type.
-               /// </summary>
-               public bool TestObsoleteMethodUsage = true;
+               public readonly IResolveContext ResolveContext;
 
                /// <summary>
                ///    The current iterator
                /// </summary>
-               public Iterator CurrentIterator;
+               public Iterator CurrentIterator {
+                       get { return CurrentAnonymousMethod as Iterator; }
+               }
 
                /// <summary>
                ///    Whether we are in the resolving stage or not
@@ -349,7 +382,11 @@ namespace Mono.CSharp {
                        Resolving,
                        Emitting
                }
+
+               public static EmitContext TempEc;
                
+               bool isAnonymousMethodAllowed = true;
+
                Phase current_phase;
                FlowBranching current_flow_branching;
 
@@ -358,19 +395,26 @@ namespace Mono.CSharp {
 
                public override string ToString ()
                {
-                       return String.Format ("EmitContext ({0}:{1}:{2})", id,
-                                             CurrentIterator, capture_context, loc);
+                       return String.Format ("EmitContext ({0}:{1})", id,
+                                             CurrentAnonymousMethod, loc);
                }
                
-               public EmitContext (DeclSpace parent, DeclSpace ds, Location l, ILGenerator ig,
+               public EmitContext (IResolveContext rc, DeclSpace parent, DeclSpace ds, Location l, ILGenerator ig,
                                    Type return_type, int code_flags, bool is_constructor)
                {
+                       this.ResolveContext = rc;
                        this.ig = ig;
 
                        TypeContainer = parent;
-                       DeclSpace = ds;
-                       CheckState = RootContext.Checked;
-                       ConstantCheckState = true;
+                       this.declSpace = ds;
+                       if (RootContext.Checked)
+                               flags |= Flags.CheckState;
+                       flags |= Flags.ConstantCheckState;
+
+#if GMCS_SOURCE
+                       if ((return_type is TypeBuilder) && return_type.IsGenericTypeDefinition)
+                               throw new InternalErrorException ();
+#endif
 
                        IsStatic = (code_flags & Modifiers.STATIC) != 0;
                        MethodIsStatic = IsStatic;
@@ -380,14 +424,12 @@ namespace Mono.CSharp {
                        CurrentBlock = null;
                        CurrentFile = 0;
                        current_phase = Phase.Created;
-                       
+
                        if (parent != null){
                                // Can only be null for the ResolveType contexts.
                                ContainerType = parent.TypeBuilder;
-                               if (parent.UnsafeContext)
-                                       InUnsafe = true;
-                               else
-                                       InUnsafe = (code_flags & Modifiers.UNSAFE) != 0;
+                               if (rc.IsInUnsafeScope)
+                                       flags |= Flags.InUnsafe;
                        }
                        loc = l;
 
@@ -395,30 +437,105 @@ namespace Mono.CSharp {
                                ReturnType = null;
                }
 
-               public EmitContext (TypeContainer tc, Location l, ILGenerator ig,
+               public EmitContext (IResolveContext rc, DeclSpace ds, Location l, ILGenerator ig,
                                    Type return_type, int code_flags, bool is_constructor)
-                       : this (tc, tc, l, ig, return_type, code_flags, is_constructor)
+                       : this (rc, ds, ds, l, ig, return_type, code_flags, is_constructor)
                {
                }
 
-               public EmitContext (TypeContainer tc, Location l, ILGenerator ig,
+               public EmitContext (IResolveContext rc, DeclSpace ds, Location l, ILGenerator ig,
                                    Type return_type, int code_flags)
-                       : this (tc, tc, l, ig, return_type, code_flags, false)
+                       : this (rc, ds, ds, l, ig, return_type, code_flags, false)
                {
                }
 
-               public FlowBranching CurrentBranching {
-                       get {
-                               return current_flow_branching;
-                       }
+               public DeclSpace DeclContainer { 
+                       get { return declSpace; }
+                       set { declSpace = value; }
                }
 
-               public bool HaveCaptureInfo {
-                       get {
-                               return capture_context != null;
+               public DeclSpace GenericDeclContainer {
+                       get { return DeclContainer; }
+               }
+
+               public bool CheckState {
+                       get { return (flags & Flags.CheckState) != 0; }
+               }
+
+               public bool ConstantCheckState {
+                       get { return (flags & Flags.ConstantCheckState) != 0; }
+               }
+
+               public bool InUnsafe {
+                       get { return (flags & Flags.InUnsafe) != 0; }
+               }
+
+               public bool InCatch {
+                       get { return (flags & Flags.InCatch) != 0; }
+               }
+
+               public bool InFinally {
+                       get { return (flags & Flags.InFinally) != 0; }
+               }
+
+               public bool DoFlowAnalysis {
+                       get { return (flags & Flags.DoFlowAnalysis) != 0; }
+               }
+
+               public bool OmitStructFlowAnalysis {
+                       get { return (flags & Flags.OmitStructFlowAnalysis) != 0; }
+               }
+
+               // utility helper for CheckExpr, UnCheckExpr, Checked and Unchecked statements
+               // it's public so that we can use a struct at the callsite
+               public struct FlagsHandle : IDisposable
+               {
+                       EmitContext ec;
+                       Flags invmask, oldval;
+                       internal FlagsHandle (EmitContext ec, Flags mask, Flags val)
+                       {
+                               this.ec = ec;
+                               invmask = ~mask;
+                               oldval = ec.flags & mask;
+                               ec.flags = (ec.flags & invmask) | (val & mask);
+                       }
+                       public void Dispose ()
+                       {
+                               ec.flags = (ec.flags & invmask) | oldval;
                        }
                }
 
+               // Temporarily set all the given flags to the given value.  Should be used in an 'using' statement
+               public FlagsHandle With (Flags bits, bool enable)
+               {
+                       return new FlagsHandle (this, bits, enable ? bits : 0);
+               }
+
+               public FlagsHandle WithFlowAnalysis (bool do_flow_analysis, bool omit_struct_analysis)
+               {
+                       Flags newflags = 
+                               (do_flow_analysis ? Flags.DoFlowAnalysis : 0) |
+                               (omit_struct_analysis ? Flags.OmitStructFlowAnalysis : 0);
+                       return new FlagsHandle (this, Flags.DoFlowAnalysis | Flags.OmitStructFlowAnalysis, newflags);
+               }
+
+               public bool IsInObsoleteScope {
+                       get { return ResolveContext.IsInObsoleteScope; }
+               }
+
+               public bool IsInUnsafeScope {
+                       get { return InUnsafe || ResolveContext.IsInUnsafeScope; }
+               }
+
+               public bool IsAnonymousMethodAllowed {
+                       get { return isAnonymousMethodAllowed; }
+                       set { isAnonymousMethodAllowed = value; }
+               }
+
+               public FlowBranching CurrentBranching {
+                       get { return current_flow_branching; }
+               }
+
                // <summary>
                //   Starts a new code branching.  This inherits the state of all local
                //   variables and parameters from the current branching.
@@ -442,7 +559,7 @@ namespace Mono.CSharp {
                        else
                                type = FlowBranching.BranchingType.Block;
 
-                       DoFlowAnalysis = true;
+                       flags |= Flags.DoFlowAnalysis;
 
                        current_flow_branching = FlowBranching.CreateBranching (
                                CurrentBranching, type, block, block.StartLocation);
@@ -451,8 +568,21 @@ namespace Mono.CSharp {
 
                public FlowBranchingException StartFlowBranching (ExceptionStatement stmt)
                {
-                       FlowBranchingException branching = new FlowBranchingException (
-                               CurrentBranching, stmt);
+                       FlowBranchingException branching = new FlowBranchingException (CurrentBranching, stmt);
+                       current_flow_branching = branching;
+                       return branching;
+               }
+
+               public FlowBranchingLabeled StartFlowBranching (LabeledStatement stmt)
+               {
+                       FlowBranchingLabeled branching = new FlowBranchingLabeled (CurrentBranching, stmt);
+                       current_flow_branching = branching;
+                       return branching;
+               }
+
+               public FlowBranchingToplevel StartFlowBranching (ToplevelBlock stmt)
+               {
+                       FlowBranchingToplevel branching = new FlowBranchingToplevel (CurrentBranching, stmt);
                        current_flow_branching = branching;
                        return branching;
                }
@@ -489,84 +619,17 @@ namespace Mono.CSharp {
                        current_flow_branching = current_flow_branching.Parent;
                }
 
-               public void CaptureVariable (LocalInfo li)
-               {
-                       capture_context.AddLocal (CurrentAnonymousMethod, li);
-                       li.IsCaptured = true;
-               }
-
-               public void CaptureParameter (string name, Type t, int idx)
-               {
-                       capture_context.AddParameter (this, CurrentAnonymousMethod, name, t, idx);
-               }
-
-               public void CaptureThis ()
-               {
-                       capture_context.CaptureThis ();
-               }
-               
-               
-               //
-               // Use to register a field as captured
-               //
-               public void CaptureField (FieldExpr fe)
-               {
-                       capture_context.AddField (fe);
-               }
-
-               //
-               // Whether anonymous methods have captured variables
-               //
-               public bool HaveCapturedVariables ()
-               {
-                       if (capture_context != null)
-                               return capture_context.HaveCapturedVariables;
-                       return false;
-               }
-
-               //
-               // Whether anonymous methods have captured fields or this.
-               //
-               public bool HaveCapturedFields ()
-               {
-                       if (capture_context != null)
-                               return capture_context.HaveCapturedFields;
-                       return false;
-               }
-
-               //
-               // Emits the instance pointer for the host method
-               //
-               public void EmitMethodHostInstance (EmitContext target, AnonymousMethod am)
-               {
-                       if (capture_context != null)
-                               capture_context.EmitMethodHostInstance (target, am);
-                       else if (IsStatic)
-                               target.ig.Emit (OpCodes.Ldnull);
-                       else
-                               target.ig.Emit (OpCodes.Ldarg_0);
-               }
-
-               //
-               // Returns whether the `local' variable has been captured by an anonymous
-               // method
-               //
-               public bool IsCaptured (LocalInfo local)
+               public bool MustCaptureVariable (LocalInfo local)
                {
-                       return capture_context.IsCaptured (local);
-               }
-
-               public bool IsParameterCaptured (string name)
-               {
-                       if (capture_context != null)
-                               return capture_context.IsParameterCaptured (name);
-                       return false;
+                       if (CurrentAnonymousMethod == null)
+                               return false;
+                       if (CurrentAnonymousMethod.IsIterator)
+                               return true;
+                       return local.Block.Toplevel != CurrentBlock.Toplevel;
                }
                
-               public void EmitMeta (ToplevelBlock b, InternalParameters ip)
+               public void EmitMeta (ToplevelBlock b)
                {
-                       if (capture_context != null)
-                               capture_context.EmitAnonymousHelperClasses (this);
                        b.EmitMeta (this);
 
                        if (HasReturnLabel)
@@ -578,15 +641,15 @@ namespace Mono.CSharp {
                // currently can not cope with ig == null during resolve (which must
                // be fixed for switch statements to work on anonymous methods).
                //
-               public void EmitTopBlock (IMethodData md, ToplevelBlock block, InternalParameters ip)
+               public void EmitTopBlock (IMethodData md, ToplevelBlock block)
                {
                        if (block == null)
                                return;
                        
                        bool unreachable;
                        
-                       if (ResolveTopBlock (null, block, ip, md, out unreachable)){
-                               EmitMeta (block, ip);
+                       if (ResolveTopBlock (null, block, md.ParameterInfo, md, out unreachable)){
+                               EmitMeta (block);
 
                                current_phase = Phase.Emitting;
                                EmitResolvedTopBlock (block, unreachable);
@@ -596,7 +659,7 @@ namespace Mono.CSharp {
                bool resolved;
 
                public bool ResolveTopBlock (EmitContext anonymous_method_host, ToplevelBlock block,
-                                            InternalParameters ip, IMethodData md, out bool unreachable)
+                                            Parameters ip, IMethodData md, out bool unreachable)
                {
                        current_phase = Phase.Resolving;
                        
@@ -605,9 +668,7 @@ namespace Mono.CSharp {
                        if (resolved)
                                return true;
 
-                       capture_context = block.CaptureContext;
-                       
-                       if (!Location.IsNull (loc))
+                       if (!loc.IsNull)
                                CurrentFile = loc.File;
 
 #if PRODUCTION
@@ -616,42 +677,40 @@ namespace Mono.CSharp {
                                if (!block.ResolveMeta (this, ip))
                                        return false;
 
-                                       bool old_do_flow_analysis = DoFlowAnalysis;
-                                       DoFlowAnalysis = true;
+                               if ((md != null) && (md.Iterator != null)) {
+                                       if (!md.Iterator.Resolve (this))
+                                               return false;
+                               }
 
+                               using (this.With (EmitContext.Flags.DoFlowAnalysis, true)) {
+                                       FlowBranchingToplevel top_level;
                                        if (anonymous_method_host != null)
-                                               current_flow_branching = FlowBranching.CreateBranching (
-                                                       anonymous_method_host.CurrentBranching,
-                                                       FlowBranching.BranchingType.Block, block, loc);
+                                               top_level = new FlowBranchingToplevel (anonymous_method_host.CurrentBranching, block);
                                        else 
-                                               current_flow_branching = block.TopLevelBranching;
+                                               top_level = block.TopLevelBranching;
 
-                                       if (!block.Resolve (this)) {
-                                               current_flow_branching = null;
-                                               DoFlowAnalysis = old_do_flow_analysis;
-                                               return false;
-                                       }
-
-                                       FlowBranching.Reachability reachability = current_flow_branching.MergeTopBlock ();
+                                       current_flow_branching = top_level;
+                                       bool ok = block.Resolve (this);
                                        current_flow_branching = null;
-                                       
-                                       DoFlowAnalysis = old_do_flow_analysis;
 
-                                       if (reachability.AlwaysReturns ||
-                                           reachability.AlwaysThrows ||
-                                           reachability.IsUnreachable)
+                                       if (!ok)
+                                               return false;
+
+                                       FlowBranching.Reachability reachability = top_level.End ();
+                                       if (reachability.IsUnreachable)
                                                unreachable = true;
+                               }
 #if PRODUCTION
                        } catch (Exception e) {
-                                       Console.WriteLine ("Exception caught by the compiler while compiling:");
-                                       Console.WriteLine ("   Block that caused the problem begin at: " + loc);
-                                       
-                                       if (CurrentBlock != null){
-                                               Console.WriteLine ("                     Block being compiled: [{0},{1}]",
-                                                                  CurrentBlock.StartLocation, CurrentBlock.EndLocation);
-                                       }
-                                       Console.WriteLine (e.GetType ().FullName + ": " + e.Message);
-                                       throw;
+                               Console.WriteLine ("Exception caught by the compiler while compiling:");
+                               Console.WriteLine ("   Block that caused the problem begin at: " + loc);
+
+                               if (CurrentBlock != null){
+                                       Console.WriteLine ("                     Block being compiled: [{0},{1}]",
+                                                          CurrentBlock.StartLocation, CurrentBlock.EndLocation);
+                               }
+                               Console.WriteLine (e.GetType ().FullName + ": " + e.Message);
+                               throw;
                        }
 #endif
 
@@ -661,12 +720,14 @@ namespace Mono.CSharp {
                                        return false;
                                } else if (!CurrentAnonymousMethod.IsIterator) {
                                        Report.Error (1643, CurrentAnonymousMethod.Location, "Not all code paths return a value in anonymous method of type `{0}'",
-                                               CurrentAnonymousMethod.GetSignatureForError ());
+                                                     CurrentAnonymousMethod.GetSignatureForError ());
                                        return false;
                                }
                        }
 
-                       block.CompleteContexts ();
+                       if (!block.CompleteContexts (this))
+                               return false;
+
                        resolved = true;
                        return true;
                }
@@ -675,10 +736,10 @@ namespace Mono.CSharp {
                {
                        if (block != null)
                                block.Emit (this);
-                       
+
                        if (HasReturnLabel)
                                ig.MarkLabel (ReturnLabel);
-                       
+
                        if (return_value != null){
                                ig.Emit (OpCodes.Ldloc, return_value);
                                ig.Emit (OpCodes.Ret);
@@ -707,12 +768,6 @@ namespace Mono.CSharp {
                                        ig.Emit (OpCodes.Ret);
                                }
                        }
-
-                       //
-                       // Close pending helper classes if we are the toplevel
-                       //
-                       if (capture_context != null && capture_context.ParentToplevel == null)
-                               capture_context.CloseAnonymousHelperClasses ();
                }
 
                /// <summary>
@@ -721,13 +776,13 @@ namespace Mono.CSharp {
                /// </summary>
                public void Mark (Location loc, bool check_file)
                {
-                       if ((CodeGen.SymbolWriter == null) || Location.IsNull (loc))
+                       if ((CodeGen.SymbolWriter == null) || loc.IsNull)
                                return;
 
                        if (check_file && (CurrentFile != loc.File))
                                return;
 
-                       CodeGen.SymbolWriter.MarkSequencePoint (ig, loc.Row, 0);
+                       CodeGen.SymbolWriter.MarkSequencePoint (ig, loc.Row, loc.Column);
                }
 
                public void DefineLocalVariable (string name, LocalBuilder builder)
@@ -760,58 +815,44 @@ namespace Mono.CSharp {
                /// </summary>
                public LocalBuilder GetTemporaryLocal (Type t)
                {
-                       LocalBuilder location = null;
-                       
-                       if (temporary_storage != null){
+                       if (temporary_storage != null) {
                                object o = temporary_storage [t];
-                               if (o != null){
-                                       if (o is ArrayList){
-                                               ArrayList al = (ArrayList) o;
-                                               
-                                               for (int i = 0; i < al.Count; i++){
-                                                       if (al [i] != null){
-                                                               location = (LocalBuilder) al [i];
-                                                               al [i] = null;
-                                                               break;
-                                                       }
-                                               }
-                                       } else
-                                               location = (LocalBuilder) o;
-                                       if (location != null)
-                                               return location;
+                               if (o != null) {
+                                       if (o is Stack) {
+                                               Stack s = (Stack) o;
+                                               o = s.Count == 0 ? null : s.Pop ();
+                                       } else {
+                                               temporary_storage.Remove (t);
+                                       }
                                }
+                               if (o != null)
+                                       return (LocalBuilder) o;
                        }
-                       
                        return ig.DeclareLocal (t);
                }
 
                public void FreeTemporaryLocal (LocalBuilder b, Type t)
                {
-                       if (temporary_storage == null){
+                       Stack s;
+
+                       if (temporary_storage == null) {
                                temporary_storage = new Hashtable ();
                                temporary_storage [t] = b;
                                return;
                        }
                        object o = temporary_storage [t];
-                       if (o == null){
+                       if (o == null) {
                                temporary_storage [t] = b;
                                return;
                        }
-                       if (o is ArrayList){
-                               ArrayList al = (ArrayList) o;
-                               for (int i = 0; i < al.Count; i++){
-                                       if (al [i] == null){
-                                               al [i] = b;
-                                               return;
-                                       }
-                               }
-                               al.Add (b);
-                               return;
+                       if (o is Stack) {
+                               s = (Stack) o;
+                       } else {
+                               s = new Stack ();
+                               s.Push (o);
+                               temporary_storage [t] = s;
                        }
-                       ArrayList replacement = new ArrayList ();
-                       replacement.Add (o);
-                       temporary_storage.Remove (t);
-                       temporary_storage [t] = replacement;
+                       s.Push (b);
                }
 
                /// <summary>
@@ -873,54 +914,7 @@ namespace Mono.CSharp {
                                HasReturnLabel = true;
                }
 
-               //
-               // Emits the proper object to address fields on a remapped
-               // variable/parameter to field in anonymous-method/iterator proxy classes.
-               //
-               public void EmitThis ()
-               {
-                       ig.Emit (OpCodes.Ldarg_0);
-                       if (capture_context != null && CurrentAnonymousMethod != null){
-                               ScopeInfo si = CurrentAnonymousMethod.Scope;
-                               while (si != null){
-                                       if (si.ParentLink != null)
-                                               ig.Emit (OpCodes.Ldfld, si.ParentLink);
-                                       if (si.THIS != null){
-                                               ig.Emit (OpCodes.Ldfld, si.THIS);
-                                               break;
-                                       }
-                                       si = si.ParentScope;
-                               }
-                       } 
-               }
-
-               //
-               // Emits the code necessary to load the instance required
-               // to access the captured LocalInfo
-               //
-               public void EmitCapturedVariableInstance (LocalInfo li)
-               {
-                       if (capture_context == null)
-                               throw new Exception ("Calling EmitCapturedContext when there is no capture_context");
-                       
-                       capture_context.EmitCapturedVariableInstance (this, li, CurrentAnonymousMethod);
-               }
-
-               public void EmitParameter (string name)
-               {
-                       capture_context.EmitParameter (this, name);
-               }
-
-               public void EmitAssignParameter (string name, Expression source, bool leave_copy, bool prepare_for_load)
-               {
-                       capture_context.EmitAssignParameter (this, name, source, leave_copy, prepare_for_load);
-               }
 
-               public void EmitAddressOfParameter (string name)
-               {
-                       capture_context.EmitAddressOfParameter (this, name);
-               }
-               
                public Expression GetThis (Location loc)
                {
                        This my_this;
@@ -937,7 +931,8 @@ namespace Mono.CSharp {
        }
 
 
-       public abstract class CommonAssemblyModulClass: Attributable {
+       public abstract class CommonAssemblyModulClass : Attributable, IResolveContext {
+
                protected CommonAssemblyModulClass ():
                        base (null)
                {
@@ -945,11 +940,14 @@ namespace Mono.CSharp {
 
                public void AddAttributes (ArrayList attrs)
                {
-                       if (OptAttributes == null) {
-                               OptAttributes = new Attributes (attrs);
+                       foreach (Attribute a in attrs)
+                               a.AttachTo (this);
+
+                       if (attributes == null) {
+                               attributes = new Attributes (attrs);
                                return;
                        }
-                       OptAttributes.AddAttributes (attrs);
+                       attributes.AddAttributes (attrs);
                }
 
                public virtual void Emit (TypeContainer tc) 
@@ -957,42 +955,71 @@ namespace Mono.CSharp {
                        if (OptAttributes == null)
                                return;
 
-                       EmitContext ec = new EmitContext (tc, Mono.CSharp.Location.Null, null, null, 0, false);
-                       OptAttributes.Emit (ec, this);
+                       OptAttributes.Emit ();
                }
-                
+
                protected Attribute ResolveAttribute (Type a_type)
                {
-                       if (OptAttributes == null)
-                               return null;
-
-                       // Ensure that we only have GlobalAttributes, since the Search below isn't safe with other types.
-                       if (!OptAttributes.CheckTargets (this))
-                               return null;
-
-                       EmitContext temp_ec = new EmitContext (RootContext.Tree.Types, Mono.CSharp.Location.Null, null, null, 0, false);
-                       Attribute a = OptAttributes.Search (a_type, temp_ec);
+                       Attribute a = OptAttributes.Search (a_type);
                        if (a != null) {
-                               a.Resolve (temp_ec);
+                               a.Resolve ();
                        }
                        return a;
                }
+
+               public override IResolveContext ResolveContext {
+                       get { return this; }
+               }
+
+               #region IResolveContext Members
+
+               public DeclSpace DeclContainer {
+                       get { return RootContext.ToplevelTypes; }
+               }
+
+               public DeclSpace GenericDeclContainer {
+                       get { return DeclContainer; }
+               }
+
+               public bool IsInObsoleteScope {
+                       get { return false; }
+               }
+
+               public bool IsInUnsafeScope {
+                       get { return false; }
+               }
+
+               #endregion
        }
                 
-       public class AssemblyClass: CommonAssemblyModulClass {
+       public class AssemblyClass : CommonAssemblyModulClass {
                // TODO: make it private and move all builder based methods here
                public AssemblyBuilder Builder;
                bool is_cls_compliant;
+               bool wrap_non_exception_throws;
+               bool has_extension_method;
+
                public Attribute ClsCompliantAttribute;
 
                ListDictionary declarative_security;
+#if GMCS_SOURCE
+               public AssemblyName Name;
+               MethodInfo add_type_forwarder;
+               ListDictionary emitted_forwarders;
+#endif
 
                // Module is here just because of error messages
                static string[] attribute_targets = new string [] { "assembly", "module" };
 
                public AssemblyClass (): base ()
                {
-                       is_cls_compliant = false;
+#if GMCS_SOURCE
+                       wrap_non_exception_throws = true;
+#endif
+               }
+
+               public bool HasExtensionMethods {
+                       set { has_extension_method = value; }
                }
 
                public bool IsClsCompliant {
@@ -1001,24 +1028,45 @@ namespace Mono.CSharp {
                        }
                }
 
+               public bool WrapNonExceptionThrows {
+                       get {
+                               return wrap_non_exception_throws;
+                       }
+               }
+
                public override AttributeTargets AttributeTargets {
                        get {
                                return AttributeTargets.Assembly;
                        }
                }
 
-               public override bool IsClsCompliaceRequired(DeclSpace ds)
+               public override bool IsClsComplianceRequired ()
                {
                        return is_cls_compliant;
                }
 
-               public void ResolveClsCompliance ()
+               public void Resolve ()
                {
-                       ClsCompliantAttribute = ResolveAttribute (TypeManager.cls_compliant_attribute_type);
-                       if (ClsCompliantAttribute == null)
+                       if (OptAttributes == null)
                                return;
 
-                       is_cls_compliant = ClsCompliantAttribute.GetClsCompliantAttributeValue (null);
+                       // Ensure that we only have GlobalAttributes, since the Search isn't safe with other types.
+                       if (!OptAttributes.CheckTargets())
+                               return;
+
+                       ClsCompliantAttribute = ResolveAttribute (TypeManager.cls_compliant_attribute_type);
+                       if (ClsCompliantAttribute != null) {
+                               is_cls_compliant = ClsCompliantAttribute.GetClsCompliantAttributeValue ();
+                       }
+
+#if GMCS_SOURCE
+                       Attribute a = ResolveAttribute (TypeManager.runtime_compatibility_attr_type);
+                       if (a != null) {
+                               object val = a.GetPropertyValue ("WrapNonExceptionThrows");
+                               if (val != null)
+                                       wrap_non_exception_throws = (bool)val;
+                       }
+#endif
                }
 
                // fix bug #56621
@@ -1046,7 +1094,7 @@ namespace Mono.CSharp {
                                }
                        }
                        catch (Exception) {
-                               Error_AssemblySigning ("The speficied file `" + RootContext.StrongNameKeyFile + "' is incorrectly encoded");
+                               Error_AssemblySigning ("The specified file `" + RootContext.StrongNameKeyFile + "' is incorrectly encoded");
                                Environment.Exit (1);
                        }
                }
@@ -1070,12 +1118,12 @@ namespace Mono.CSharp {
                                                case "System.Reflection.AssemblyKeyFileAttribute":
                                                        if (RootContext.StrongNameKeyFile != null) {
                                                                Report.SymbolRelatedToPreviousError (a.Location, a.Name);
-                                                               Report.Warning (1616, "Option `{0}' overrides attribute `{1}' given in a source file or added module",
+                                                               Report.Warning (1616, 1, "Option `{0}' overrides attribute `{1}' given in a source file or added module",
                                     "keyfile", "System.Reflection.AssemblyKeyFileAttribute");
                                                        }
                                                        else {
                                                                string value = a.GetString ();
-                                                               if (value != String.Empty)
+                                                               if (value.Length != 0)
                                                                        RootContext.StrongNameKeyFile = value;
                                                        }
                                                        break;
@@ -1084,12 +1132,12 @@ namespace Mono.CSharp {
                                                case "System.Reflection.AssemblyKeyNameAttribute":
                                                        if (RootContext.StrongNameKeyContainer != null) {
                                                                Report.SymbolRelatedToPreviousError (a.Location, a.Name);
-                                                               Report.Warning (1616, "Option `{0}' overrides attribute `{1}' given in a source file or added module",
+                                                               Report.Warning (1616, 1, "Option `{0}' overrides attribute `{1}' given in a source file or added module",
                                                                        "keycontainer", "System.Reflection.AssemblyKeyNameAttribute");
                                                        }
                                                        else {
                                                                string value = a.GetString ();
-                                                               if (value != String.Empty)
+                                                               if (value.Length != 0)
                                                                        RootContext.StrongNameKeyContainer = value;
                                                        }
                                                        break;
@@ -1152,7 +1200,7 @@ namespace Mono.CSharp {
                                                                        "ECMA key can only be used to delay-sign assemblies");
                                                        }
                                                        else {
-                                                               Error_AssemblySigning ("The speficied file `" + RootContext.StrongNameKeyFile + "' does not have a private key");
+                                                               Error_AssemblySigning ("The specified file `" + RootContext.StrongNameKeyFile + "' does not have a private key");
                                                        }
                                                        return null;
                                                }
@@ -1160,7 +1208,7 @@ namespace Mono.CSharp {
                                }
                        }
                        else {
-                               Error_AssemblySigning ("The speficied file `" + RootContext.StrongNameKeyFile + "' does not exist");
+                               Error_AssemblySigning ("The specified file `" + RootContext.StrongNameKeyFile + "' does not exist");
                                return null;
                        }
                        return an;
@@ -1171,6 +1219,37 @@ namespace Mono.CSharp {
                        Report.Error (1548, "Error during assembly signing. " + text);
                }
 
+#if GMCS_SOURCE
+               bool CheckInternalsVisibleAttribute (Attribute a)
+               {
+                       string assembly_name = a.GetString ();
+                       if (assembly_name.Length == 0)
+                               return false;
+                               
+                       AssemblyName aname = null;
+                       try {
+                               aname = new AssemblyName (assembly_name);
+                       } catch (FileLoadException) {
+                       } catch (ArgumentException) {
+                       }
+                               
+                       // Bad assembly name format
+                       if (aname == null)
+                               Report.Warning (1700, 3, a.Location, "Assembly reference `" + assembly_name + "' is invalid and cannot be resolved");
+                       // Report error if we have defined Version or Culture
+                       else if (aname.Version != null || aname.CultureInfo != null)
+                               throw new Exception ("Friend assembly `" + a.GetString () + 
+                                               "' is invalid. InternalsVisibleTo cannot have version or culture specified.");
+                       else if (aname.GetPublicKey () == null && Name.GetPublicKey () != null) {
+                               Report.Error (1726, a.Location, "Friend assembly reference `" + aname.FullName + "' is invalid." +
+                                               " Strong named assemblies must specify a public key in their InternalsVisibleTo declarations");
+                               return false;
+                       }
+
+                       return true;
+               }
+#endif
+
                public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder customBuilder)
                {
                        if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (true)) {
@@ -1192,6 +1271,65 @@ namespace Mono.CSharp {
                                }
                        }
 
+#if GMCS_SOURCE
+                       if (a.Type == TypeManager.internals_visible_attr_type && !CheckInternalsVisibleAttribute (a))
+                               return;
+
+                       if (a.Type == TypeManager.type_forwarder_attr_type) {
+                               Type t = a.GetArgumentType ();
+                               if (t == null || TypeManager.HasElementType (t)) {
+                                       Report.Error (735, a.Location, "Invalid type specified as an argument for TypeForwardedTo attribute");
+                                       return;
+                               }
+
+                               if (emitted_forwarders == null) {
+                                       emitted_forwarders = new ListDictionary();
+                               } else if (emitted_forwarders.Contains(t)) {
+                                       Report.SymbolRelatedToPreviousError(((Attribute)emitted_forwarders[t]).Location, null);
+                                       Report.Error(739, a.Location, "A duplicate type forward of type `{0}'",
+                                               TypeManager.CSharpName(t));
+                                       return;
+                               }
+
+                               emitted_forwarders.Add(t, a);
+
+                               if (TypeManager.LookupDeclSpace (t) != null) {
+                                       Report.SymbolRelatedToPreviousError (t);
+                                       Report.Error (729, a.Location, "Cannot forward type `{0}' because it is defined in this assembly",
+                                               TypeManager.CSharpName (t));
+                                       return;
+                               }
+
+                               if (t.IsNested) {
+                                       Report.Error (730, a.Location, "Cannot forward type `{0}' because it is a nested type",
+                                               TypeManager.CSharpName (t));
+                                       return;
+                               }
+
+                               if (t.IsGenericType) {
+                                       Report.Error (733, a.Location, "Cannot forward generic type `{0}'", TypeManager.CSharpName (t));
+                                       return;
+                               }
+
+                               if (add_type_forwarder == null) {
+                                       add_type_forwarder = typeof (AssemblyBuilder).GetMethod ("AddTypeForwarder",
+                                               BindingFlags.NonPublic | BindingFlags.Instance);
+
+                                       if (add_type_forwarder == null) {
+                                               Report.RuntimeMissingSupport (a.Location, "TypeForwardedTo attribute");
+                                               return;
+                                       }
+                               }
+
+                               add_type_forwarder.Invoke (Builder, new object[] { t });
+                               return;
+                       }
+                       
+                       if (a.Type == TypeManager.extension_attribute_type) {
+                               a.Error_MisusedExtensionAttribute ();
+                               return;
+                       }
+#endif
                        Builder.SetCustomAttribute (customBuilder);
                }
 
@@ -1199,6 +1337,23 @@ namespace Mono.CSharp {
                {
                        base.Emit (tc);
 
+#if GMCS_SOURCE
+                       if (has_extension_method)
+                               Builder.SetCustomAttribute (TypeManager.extension_attribute_attr);
+
+                       // FIXME: Does this belong inside SRE.AssemblyBuilder instead?
+                       if (OptAttributes == null || !OptAttributes.Contains (TypeManager.runtime_compatibility_attr_type)) {
+                               ConstructorInfo ci = TypeManager.GetConstructor (
+                                       TypeManager.runtime_compatibility_attr_type, Type.EmptyTypes);
+                               PropertyInfo [] pis = new PropertyInfo [1];
+                               pis [0] = TypeManager.GetProperty (
+                                       TypeManager.runtime_compatibility_attr_type, "WrapNonExceptionThrows");
+                               object [] pargs = new object [1];
+                               pargs [0] = true;
+                               Builder.SetCustomAttribute (new CustomAttributeBuilder (ci, new object [0], pis, pargs));
+                       }
+#endif
+
                        if (declarative_security != null) {
 
                                MethodInfo add_permission = typeof (AssemblyBuilder).GetMethod ("AddPermissionRequests", BindingFlags.Instance | BindingFlags.NonPublic);
@@ -1230,12 +1385,37 @@ namespace Mono.CSharp {
                                return attribute_targets;
                        }
                }
+
+               // Wrapper for AssemblyBuilder.AddModule
+               static MethodInfo adder_method;
+               static public MethodInfo AddModule_Method {
+                       get {
+                               if (adder_method == null)
+                                       adder_method = typeof (AssemblyBuilder).GetMethod ("AddModule", BindingFlags.Instance|BindingFlags.NonPublic);
+                               return adder_method;
+                       }
+               }
+               public Module AddModule (string module)
+               {
+                       MethodInfo m = AddModule_Method;
+                       if (m == null) {
+                               Report.RuntimeMissingSupport (Location.Null, "/addmodule");
+                               Environment.Exit (1);
+                       }
+
+                       try {
+                               return (Module) m.Invoke (Builder, new object [] { module });
+                       } catch (TargetInvocationException ex) {
+                               throw ex.InnerException;
+                       }
+               }               
        }
 
-       public class ModuleClass: CommonAssemblyModulClass {
+       public class ModuleClass : CommonAssemblyModulClass {
                // TODO: make it private and move all builder based methods here
                public ModuleBuilder Builder;
                bool m_module_is_unsafe;
+               bool has_default_charset;
 
                public CharSet DefaultCharSet = CharSet.Ansi;
                public TypeAttributes DefaultCharSetType = TypeAttributes.AnsiClass;
@@ -1253,7 +1433,7 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override bool IsClsCompliaceRequired(DeclSpace ds)
+               public override bool IsClsComplianceRequired ()
                {
                        return CodeGen.Assembly.IsClsCompliant;
                }
@@ -1277,7 +1457,7 @@ namespace Mono.CSharp {
                {
                        if (a.Type == TypeManager.cls_compliant_attribute_type) {
                                if (CodeGen.Assembly.ClsCompliantAttribute == null) {
-                                       Report.Warning (3012, a.Location, "You must specify the CLSCompliant attribute on the assembly, not the module, to enable CLS compliance checking");
+                                       Report.Warning (3012, 1, a.Location, "You must specify the CLSCompliant attribute on the assembly, not the module, to enable CLS compliance checking");
                                }
                                else if (CodeGen.Assembly.IsClsCompliant != a.GetBoolean ()) {
                                        Report.SymbolRelatedToPreviousError (CodeGen.Assembly.ClsCompliantAttribute.Location, CodeGen.Assembly.ClsCompliantAttribute.GetSignatureForError ());
@@ -1289,14 +1469,27 @@ namespace Mono.CSharp {
                        Builder.SetCustomAttribute (customBuilder);
                }
 
+               public bool HasDefaultCharSet {
+                       get {
+                               return has_default_charset;
+                       }
+               }
+
                /// <summary>
                /// It is called very early therefore can resolve only predefined attributes
                /// </summary>
-               public void ResolveAttributes ()
+               public void Resolve ()
                {
-#if NET_2_0
+#if GMCS_SOURCE
+                       if (OptAttributes == null)
+                               return;
+
+                       if (!OptAttributes.CheckTargets())
+                               return;
+
                        Attribute a = ResolveAttribute (TypeManager.default_charset_type);
                        if (a != null) {
+                               has_default_charset = true;
                                DefaultCharSet = a.GetCharSetValue ();
                                switch (DefaultCharSet) {
                                        case CharSet.Ansi: